diff --git a/.gitmodules b/.gitmodules index 7efde0357..103b249b8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,8 +3,8 @@ url = https://github.com/jwalabroad/fermi-lite [submodule "htslib"] path = htslib - url = https://github.com/walaj/htslib - branch = develop + url = https://github.com/samtools/htslib + branch = master [submodule "bwa"] path = bwa url = https://github.com/jwalabroad/bwa diff --git a/SeqLib/BamRecord.h b/SeqLib/BamRecord.h index 60575f2ce..6820f8f9b 100644 --- a/SeqLib/BamRecord.h +++ b/SeqLib/BamRecord.h @@ -672,6 +672,13 @@ class BamRecord { */ bool GetZTag(const std::string& tag, std::string& s) const; + /** Get a string of either Z, f or i type. Useful if tag type not known at compile time. + * @param tag Name of the tag. eg "XP" + * @param s The string to be filled in with the tag information + * @return Returns true if the tag is present and is either Z or i, even if empty. Return false if no tag or not Z or i. + */ + bool GetTag(const std::string& tag, std::string& s) const; + /** Get a vector of type int from a Z tag delimited by "^" * Smart-tags allow one to store vectors of strings, ints or doubles in the alignment tags, and * do not require an additional data structure on top of bseq1_t. @@ -711,6 +718,19 @@ class BamRecord { return true; } + /** Get a float (f) tag + * @param tag Name of the tag. eg "AS" + * @param t Value to be filled in with the tag value. + * @return Return true if the tag exists. + */ + inline bool GetFloatTag(const std::string& tag, float& t) const { + uint8_t* p = bam_aux_get(b.get(),tag.c_str()); + if (!p) + return false; + t = bam_aux2f(p); + return true; + } + /** Add a string (Z) tag * @param tag Name of the tag. eg "XP" * @param val Value for the tag diff --git a/htslib b/htslib index 293a426d2..5163833ed 160000 --- a/htslib +++ b/htslib @@ -1 +1 @@ -Subproject commit 293a426d2348229d3fede23d3b212c6c9bedaeb8 +Subproject commit 5163833ede355f8c2a6788780c55d7598279e767 diff --git a/src/BamReader.cpp b/src/BamReader.cpp index f253298b4..279e109c9 100644 --- a/src/BamReader.cpp +++ b/src/BamReader.cpp @@ -230,7 +230,7 @@ bool BamReader::GetNextRecord(BamRecord& r) { // try and get the next read int32_t status = m_bams.begin()->second.load_read(r); - if (status == 0) + if (status >= 0) return true; if (status == -1) { // didn't find anything, clear it @@ -270,7 +270,7 @@ bool BamReader::GetNextRecord(BamRecord& r) { tb->empty = true; tb->mark_for_closure = true; // no more reads in this BAM continue; - } else if (status != 0) { // error sent back from sam_read1 + } else if (status < 0) { // error sent back from sam_read1 // run time error std::stringstream ss; ss << "sam_read1 return status: " << status << " file: " << bam->first; @@ -328,6 +328,7 @@ std::string BamReader::PrintRegions() const { if (hts_itr.get() == NULL) { valid = sam_read1(fp.get(), m_hdr.get_(), b); + if (valid < 0) { #ifdef DEBUG_WALKER diff --git a/src/BamRecord.cpp b/src/BamRecord.cpp index 2ec6f2632..ef3ed2121 100644 --- a/src/BamRecord.cpp +++ b/src/BamRecord.cpp @@ -452,6 +452,26 @@ namespace SeqLib { bam_aux_append(b.get(), tag.data(), 'Z', val.length()+1, (uint8_t*)val.c_str()); } + bool BamRecord::GetTag(const std::string& tag, std::string& s) const { + if (GetZTag(tag, s)) + return true; + int32_t t; + if (GetIntTag(tag, t)) { + std::stringstream ss; + ss << t; + s = ss.str(); + return true; + } + float f; + if (GetFloatTag(tag, f)) { + std::stringstream ss; + ss << f; + s = ss.str(); + return true; + } + return false; + } + bool BamRecord::GetZTag(const std::string& tag, std::string& s) const { uint8_t* p = bam_aux_get(b.get(),tag.c_str()); if (!p)