// -*- mode: c++; indent-tabs-mode: nil; -*- // // Copyright 2009 Illumina, Inc. // // This software is covered by the "Illumina Genome Analyzer Software // License Agreement" and the "Illumina Source Code License Agreement", // and certain third party copyright/licenses, and any user of this // source file is bound by the terms therein (see accompanying files // Illumina_Genome_Analyzer_Software_License_Agreement.pdf and // Illumina_Source_Code_License_Agreement.pdf and third party // copyright/license notices). // // /// \file /// /// \author Chris Saunders /// #include "starling_read_align_clipper.hh" #include //#define DEBUG_ALIGN_CLIP // extra info on ambiguous path clipping... #ifdef DEBUG_ALIGN_CLIP #include #endif struct ref_map_type { enum map_t { NONE, MATCH, INSERT, SOFT_CLIP, CONFLICT }; ref_map_type(const map_t t = NONE, const pos_t p = 0) : type(t), pos(p) {} static char get_type_label(const map_t t) { switch(t) { case NONE: return 'N'; case MATCH: return 'M'; case INSERT: return 'I'; case SOFT_CLIP: return 'S'; case CONFLICT: return 'X'; default: assert(0); } } map_t type; pos_t pos; }; #ifdef DEBUG_ALIGN_CLIP static void dump_ref_map(const std::vector& ref_map, std::ostream& os) { const unsigned rs(ref_map.size()); for(unsigned i(0);i& ref_map){ using namespace ALIGNPATH; ref_map.clear(); pos_t ref_head_pos(al.pos); const unsigned as(al.path.size()); for(unsigned i(0);i& ref_map){ using namespace ALIGNPATH; pos_t ref_head_pos(al.pos); pos_t read_head_pos(0); const unsigned as(al.path.size()); for(unsigned i(0);i(j)))){ rm.type=ref_map_type::CONFLICT; } } read_head_pos += ps.length; ref_head_pos += ps.length; } else if(ps.type == INSERT) { for(unsigned j(0);j read_head_pos) { const unsigned clip_length(std::min(ps.length,(leading_clip-read_head_pos))); extend_or_add_sc(new_al,clip_length); if(ps.type == MATCH) new_al.pos += static_cast(clip_length); if(clip_length < ps.length) { const unsigned frac_length(ps.length-clip_length); new_al.path.push_back(path_segment(ps.type,frac_length)); } } else if(trailing_clip < (read_head_pos+ps.length)) { const unsigned clip_length(std::min(ps.length,((read_head_pos+ps.length)-trailing_clip))); if(clip_length < ps.length) { const unsigned frac_length(ps.length-clip_length); new_al.path.push_back(path_segment(ps.type,frac_length)); } extend_or_add_sc(new_al,clip_length); } else { new_al.path.push_back(ps); } read_head_pos += ps.length; } else if((ps.type == DELETE) or (ps.type == SKIP)){ if(leading_clip >= read_head_pos) { new_al.pos += static_cast(ps.length); } else if(trailing_clip <= read_head_pos) { } else { new_al.path.push_back(ps); } } else if(ps.type == SOFT_CLIP){ extend_or_add_sc(new_al,ps.length); read_head_pos += ps.length; } else { assert(0); } } al=new_al; } typedef std::vector cal_pool_t; void get_clipped_alignment_from_cal_pool(const cal_pool_t& max_cal_pool, const unsigned best_cal_id, alignment& al){ const unsigned n_cal(max_cal_pool.size()); assert(n_cal>0); assert(best_cal_idal; if(n_cal==1) return; // create read_pos->ref_pos map for first alignment -- start // marking off the conflict positions in other alignments: std::vector ref_map; get_alignment_ref_map(al,ref_map); #ifdef DEBUG_ALIGN_CLIP std::cerr << "VARMIT: initial ref_map:\n"; dump_ref_map(ref_map,std::cerr); #endif for(unsigned i(0);ial,ref_map); #ifdef DEBUG_ALIGN_CLIP std::cerr << "VARMIT: modified ref_map round " << i << ":\n"; dump_ref_map(ref_map,std::cerr); #endif } // an internal ambiguous alignment path might be possible, but // very rare, so we'll ignore anything which doesn't occur on // the ends: // // from each end -- move in until a match is found, then move out // until a conflict (or the end) is found: const unsigned read_size(ref_map.size()); unsigned leading_clip(0); for(;leading_clip0;leading_clip--){ if((ref_map[leading_clip-1].type == ref_map_type::CONFLICT) or (ref_map[leading_clip-1].type == ref_map_type::SOFT_CLIP)) break; } unsigned trailing_clip(read_size); for(;trailing_clip>0;trailing_clip--){ if(ref_map[trailing_clip-1].type == ref_map_type::MATCH) break; } for(;trailing_clip=trailing_clip) { al.clear(); return; } if((leading_clip!=0) or (trailing_clip!=read_size)){ soft_clip_alignment(al,leading_clip,trailing_clip); } }