/** * From current edge, get all mates of the used reads. */ pool *get_mate_pool_from_edge(edge *eg, const hash_table *ht, const int ori) { int i = 0; bwa_seq_t *s = NULL, *mate = NULL, *seqs = NULL; pool *mate_pool = NULL; mate_pool = new_pool(); seqs = ht->seqs; for (i = 0; i < eg->reads->len; i++) { s = g_ptr_array_index(eg->reads, i); mate = get_mate(s, seqs); //p_query("READ", s); //p_query("MATE", mate); // If the mate should have been used. if (is_paired(s, ori)) continue; // If the insert size is not in the range if (abs(eg->len - s->shift) > (insert_size + sd_insert_size * SD_TIMES)) { continue; } // If the mate is already in use, either by current or another thread if (mate->tid != -1 || mate->status == USED || mate->status == DEAD) continue; // The read should be used by current edge already // and the mate has not been used by this template before. if (!(s->status == TRIED && s->contig_id == eg->id) || (mate->status == TRIED && mate->contig_id == eg->id)) continue; mate->rev_com = s->rev_com; mate_pool_add(mate_pool, mate, eg->tid); } return mate_pool; }
/** * Keep only those reads with its mates at the right direction and position * * ori = 0: For below, 'read' should be right, 'mate' should be left * ----------------------> * ----> ----> * mate read */ void keep_mates_in_pool(edge *eg, pool *cur_pool, const hash_table *ht, const int ori, const int remove_single) { bwa_seq_t *read = NULL, *mate = NULL; int i = 0, to_remove = 1; for (i = 0; i < cur_pool->reads->len; i++) { read = g_ptr_array_index(cur_pool->reads, i); mate = get_mate(read, ht->seqs); // // When extending to left, the initial mate pool and current pool overlap // if (read->is_in_m_pool == eg->tid) // continue; to_remove = 0; //p_query(__func__, mate); // The mate of 'read' should be used already //if (strcmp(read->name, "5896388") == 0) { // show_debug_msg(__func__, "ORI: %d \n", ori); // show_debug_msg(__func__, "Edge [%d, %d] \n", eg->id, eg->len); // p_query(__func__, mate); // p_query(__func__, read); //} if (is_paired(read, ori)) { // If the mate is not used, remove 'read' if ((read->rev_com != mate->rev_com) || (mate->status != TRIED) || eg->tid != mate->tid) { //p_query(__func__, read); //p_query(__func__, mate); to_remove = 1; } else { // If the distance is not within range, remove 'read' if (abs(eg->len - mate->shift) > (insert_size + sd_insert_size * SD_TIMES)) { to_remove = 1; } } } else { to_remove = remove_single; } // If the read is obtained by another thread, just remove it if (to_remove || read->is_in_c_pool != eg->tid) { read->status = TRIED; read->contig_id = eg->id; if (pool_rm_index(cur_pool, i)) { read->shift = eg->len - read->cursor + 1; i--; } } } }
Mapping(const bam_hdr_t * hdr_p, bam1_t * rec_p) : _rec_p(rec_p) { _query_name = bam_get_qname(rec_p); _flag = rec_p->core.flag; for (int i = 0; i < rec_p->core.l_qseq; ++i) { _seq += seq_nt16_str[bam_seqi(bam_get_seq(rec_p), i)]; } if (is_mapped()) { _chr_name = hdr_p->target_name[rec_p->core.tid]; _rf_start = rec_p->core.pos; _cigar = Cigar(bam_get_cigar(rec_p), rec_p->core.n_cigar); _rf_len = _cigar.rf_len(); } if (is_paired() and mp_is_mapped()) { _mp_chr_name = hdr_p->target_name[rec_p->core.mtid]; _mp_rf_start = rec_p->core.mpos; } }
bool treat_as_paired() const { return is_paired() and (not is_mapped() or not mp_is_mapped() or chr_name() == mp_chr_name()); }