X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=SamParser.h;h=4747ef4281af593f714450d68ccfc65090662891;hp=c5a503554b8c9cf4716b722d47da5f8c5db8540c;hb=refs%2Fheads%2Fmaster;hpb=237bbdf363c9e42ee24e2fd63106dccf20d9bf2f diff --git a/SamParser.h b/SamParser.h index c5a5035..4747ef4 100644 --- a/SamParser.h +++ b/SamParser.h @@ -25,7 +25,7 @@ class SamParser { public: - SamParser(char, const char*, Transcripts&, const char* = 0); + SamParser(char, const char*, const char*, Transcripts&, const char*); ~SamParser(); /** @@ -62,7 +62,7 @@ private: } std::string getName(const bam1_t* b) { - return std::string((char*)bam1_qname(b)); + return std::string(bam1_qname(b)); } std::string getReadSeq(const bam1_t*); @@ -80,7 +80,7 @@ private: char SamParser::rtTag[STRLEN] = ""; // default : no tag, thus no Type 2 reads // aux, if not 0, points to the file name of fn_list -SamParser::SamParser(char inpType, const char* inpF, Transcripts& transcripts, const char* aux) +SamParser::SamParser(char inpType, const char* inpF, const char* aux, Transcripts& transcripts, const char* imdName) : transcripts(transcripts) { switch(inpType) { @@ -93,7 +93,7 @@ SamParser::SamParser(char inpType, const char* inpF, Transcripts& transcripts, c header = sam_in->header; general_assert(header != 0, "Fail to parse sam header!"); - transcripts.buildMappings(header->n_targets, header->target_name); + transcripts.buildMappings(header->n_targets, header->target_name, imdName); b = bam_init1(); b2 = bam_init1(); @@ -112,8 +112,7 @@ int SamParser::parseNext(SingleRead& read, SingleHit& hit) { bool canR = (samread(sam_in, b) >= 0); if (!canR) return -1; - if (b->core.flag & 0x0001) { fprintf(stderr, "Find a paired end read in the file!\n"); exit(-1); } - //(b->core.flag & 0x0100) && && !(b->core.flag & 0x0004) + general_assert(!(b->core.flag & 0x0001), "Find a paired end read in the file!"); int readType = getReadType(b); std::string name = getName(b); @@ -143,8 +142,7 @@ int SamParser::parseNext(SingleReadQ& read, SingleHit& hit) { bool canR = (samread(sam_in, b) >= 0); if (!canR) return -1; - if (b->core.flag & 0x0001) { fprintf(stderr, "Find a paired end read in the file!\n"); exit(-1); } - //assert(!(b->core.flag & 0x0001)); //(b->core.flag & 0x0100) && && !(b->core.flag & 0x0004) + general_assert(!(b->core.flag & 0x0001), "Find a paired end read in the file!"); int readType = getReadType(b); std::string name = getName(b); @@ -175,21 +173,24 @@ int SamParser::parseNext(PairedEndRead& read, PairedEndHit& hit) { bool canR = ((samread(sam_in, b) >= 0) && (samread(sam_in, b2) >= 0)); if (!canR) return -1; - if (!((b->core.flag & 0x0001) && (b2->core.flag & 0x0001))) { - fprintf(stderr, "One of the mate is not paired-end! (RSEM assumes the two mates of a paired-end read should be adjacent)\n"); - exit(-1); - } - //assert((b->core.flag & 0x0001) && (b2->core.flag & 0x0001)); + general_assert((b->core.flag & 0x0001) && (b2->core.flag & 0x0001), \ + "One of the mate is not paired-end! (RSEM assumes the two mates of a paired-end read should be adjacent)"); bam1_t *mp1 = NULL, *mp2 = NULL; - if ((b->core.flag & 0x0040) && (b2->core.flag & 0x0080)) { + // If lose mate info, discard. is it necessary? + if (!((b->core.flag & 0x0040) && (b2->core.flag & 0x0080)) && !((b->core.flag & 0x0080) && (b2->core.flag & 0x0040))) return 4; + // If only one mate is mapped, discard + if (((b->core.flag & 0x0004) && !(b2->core.flag & 0x0004)) || (!(b->core.flag & 0x0004) && (b2->core.flag & 0x0004))) return 4; + + if (b->core.flag & 0x0040) { mp1 = b; mp2 = b2; } - else if ((b->core.flag & 0x0080) && (b2->core.flag & 0x0040)) { + else { mp1 = b2; mp2 = b; } - else return 4; // If lose mate info, discard. is it necessary? + + general_assert(!strcmp(bam1_qname(mp1), bam1_qname(mp2)), "Detected a read pair whose two mates have different names: " + getName(mp1) + " , " + getName(mp2) + " !"); int readType = getReadType(mp1, mp2); std::string name = getName(mp1); @@ -226,21 +227,24 @@ int SamParser::parseNext(PairedEndReadQ& read, PairedEndHit& hit) { bool canR = ((samread(sam_in, b) >= 0) && (samread(sam_in, b2) >= 0)); if (!canR) return -1; - if (!((b->core.flag & 0x0001) && (b2->core.flag & 0x0001))) { - fprintf(stderr, "One of the mate is not paired-end! (RSEM assumes the two mates of a paired-end read should be adjacent)\n"); - exit(-1); - } - //assert((b->core.flag & 0x0001) && (b2->core.flag & 0x0001)); + general_assert((b->core.flag & 0x0001) && (b2->core.flag & 0x0001), \ + "One of the mate is not paired-end! (RSEM assumes the two mates of a paired-end read should be adjacent)"); bam1_t *mp1 = NULL, *mp2 = NULL; - if ((b->core.flag & 0x0040) && (b2->core.flag & 0x0080)) { + // If lose mate info, discard. is it necessary? + if (!((b->core.flag & 0x0040) && (b2->core.flag & 0x0080)) && !((b->core.flag & 0x0080) && (b2->core.flag & 0x0040))) return 4; + // If only one mate is mapped, discard + if (((b->core.flag & 0x0004) && !(b2->core.flag & 0x0004)) || (!(b->core.flag & 0x0004) && (b2->core.flag & 0x0004))) return 4; + + if (b->core.flag & 0x0040) { mp1 = b; mp2 = b2; } - else if ((b->core.flag & 0x0080) && (b2->core.flag & 0x0040)) { + else { mp1 = b2; mp2 = b; } - else return 4; + + general_assert(!strcmp(bam1_qname(mp1), bam1_qname(mp2)), "Detected a read pair whose two mates have different names: " + getName(mp1) + " , " + getName(mp2) + " !"); int readType = getReadType(mp1, mp2); std::string name = getName(mp1); @@ -341,10 +345,17 @@ inline int SamParser::getReadType(const bam1_t* b) { return (bam_aux2i(p) > 0 ? 2 : 0); } - //For paired-end reads, do not print out type 2 reads inline int SamParser::getReadType(const bam1_t* b, const bam1_t* b2) { - if ((b->core.flag & 0x0002) && (b2->core.flag & 0x0002)) return 1; + if (!(b->core.flag & 0x0004) && !(b2->core.flag & 0x0004)) return 1; + + if (!strcmp(rtTag, "")) return 0; + + uint8_t *p = bam_aux_get(b, rtTag); + if (p != NULL && bam_aux2i(p) > 0) return 2; + + p = bam_aux_get(b2, rtTag); + if (p != NULL && bam_aux2i(p) > 0) return 2; return 0; }