From 42444d414d2ab2e7831e4224c81165f2905f7096 Mon Sep 17 00:00:00 2001 From: derek Date: Mon, 17 Jan 2011 14:42:42 -0500 Subject: [PATCH] Added UNSORTED to BamMultiReader::SortOrder types. Unsorted BAMs are 'merged' through a simple reader queue. --- src/api/BamMultiReader.h | 7 ++-- src/api/internal/BamMultiMerger_p.h | 47 +++++++++++++++++++++++++- src/api/internal/BamMultiReader_p.cpp | 48 ++++++++++++++------------- src/api/internal/BamMultiReader_p.h | 7 ++-- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/api/BamMultiReader.h b/src/api/BamMultiReader.h index 6de7373..cc36efc 100644 --- a/src/api/BamMultiReader.h +++ b/src/api/BamMultiReader.h @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 23 December 2010 (DB) +// Last modified: 17 January 2011 (DB) // --------------------------------------------------------------------------- // Functionality for simultaneously reading multiple BAM files // *************************************************************************** @@ -82,7 +82,10 @@ class API_EXPORT BamMultiReader { bool HasOpenReaders(void); // set sort order for merging BAM files (i.e. which alignment from the files is 'next'?) // default behavior is to sort by position, use this method to handle BAMs sorted by read name - enum SortOrder { SortedByPosition = 0, SortedByReadName}; + enum SortOrder { SortedByPosition = 0 + , SortedByReadName + , Unsorted + }; void SetSortOrder(const SortOrder& order); // ---------------------- diff --git a/src/api/internal/BamMultiMerger_p.h b/src/api/internal/BamMultiMerger_p.h index 5d1e058..c9d1286 100644 --- a/src/api/internal/BamMultiMerger_p.h +++ b/src/api/internal/BamMultiMerger_p.h @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 19 November 2010 (DB) +// Last modified: 17 January 2011 (DB) // --------------------------------------------------------------------------- // Provides merging functionality for BamMultiReader. At this point, supports // sorting results by (refId, position) or by read name. @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,25 @@ class ReadNameMultiMerger : public IBamMultiMerger { IndexType m_data; }; +// IBamMultiMerger implementation - unsorted BAM file(s) +class UnsortedMultiMerger : public IBamMultiMerger { + + public: + UnsortedMultiMerger(void) : IBamMultiMerger() { } + ~UnsortedMultiMerger(void) { } + + public: + void Add(const ReaderAlignment& value); + void Clear(void); + const ReaderAlignment& First(void) const; + const int Size(void) const; + ReaderAlignment TakeFirst(void); + + private: + typedef std::queue IndexType; + IndexType m_data; +}; + // ------------------------------------------ // PositionMultiMerger implementation @@ -152,6 +172,31 @@ inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) { return next; } +// ------------------------------------------ +// UnsortedMultiMerger implementation + +inline void UnsortedMultiMerger::Add(const ReaderAlignment& value) { + m_data.push(value); +} + +inline void UnsortedMultiMerger::Clear(void) { + m_data.clear(); +} + +inline const ReaderAlignment& UnsortedMultiMerger::First(void) const { + return m_data.front(); +} + +inline const int UnsortedMultiMerger::Size(void) const { + return m_data.size(); +} + +inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) { + ReaderAlignment first = m_data.front(); + m_data.pop(); + return first; +} + } // namespace Internal } // namespace BamTools diff --git a/src/api/internal/BamMultiReader_p.cpp b/src/api/internal/BamMultiReader_p.cpp index 01cdf8f..bfec6bb 100644 --- a/src/api/internal/BamMultiReader_p.cpp +++ b/src/api/internal/BamMultiReader_p.cpp @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 23 December 2010 (DB) +// Last modified: 17 January 2011 (DB) // --------------------------------------------------------------------------- // Functionality for simultaneously reading multiple BAM files // ************************************************************************* @@ -26,7 +26,7 @@ using namespace std; BamMultiReaderPrivate::BamMultiReaderPrivate(void) : m_alignments(0) , m_isCoreMode(false) - , m_isSortedByPosition(true) + , m_sortOrder(BamMultiReader::SortedByPosition) { } // dtor @@ -66,9 +66,9 @@ void BamMultiReaderPrivate::Close(void) { // clear out readers m_readers.clear(); - // reset flags + // reset default flags m_isCoreMode = false; - m_isSortedByPosition = true; + m_sortOrder = BamMultiReader::SortedByPosition; } // saves index data to BAM index files (".bai"/".bti") where necessary, returns success/fail @@ -84,6 +84,16 @@ bool BamMultiReaderPrivate::CreateIndexes(bool useStandardIndex) { return result; } +IBamMultiMerger* BamMultiReaderPrivate::CreateMergerForCurrentSortOrder(void) const { + switch ( m_sortOrder ) { + case ( BamMultiReader::SortedByPosition ) : return new PositionMultiMerger; + case ( BamMultiReader::SortedByReadName ) : return new ReadNameMultiMerger; + case ( BamMultiReader::Unsorted ) : return new UnsortedMultiMerger; + default : //print error + return 0; + } +} + const string BamMultiReaderPrivate::ExtractReadGroup(const string& headerLine) const { string readGroup(""); @@ -305,10 +315,8 @@ bool BamMultiReaderPrivate::Open(const vector& filenames, } // create alignment cache based on sorting mode - if ( m_isSortedByPosition ) - m_alignments = new PositionMultiMerger; - else - m_alignments = new ReadNameMultiMerger; + m_alignments = CreateMergerForCurrentSortOrder(); + if ( m_alignments == 0 ) return false; // iterate over filenames vector::const_iterator filenameIter = filenames.begin(); @@ -382,8 +390,8 @@ bool BamMultiReaderPrivate::Rewind(void) { void BamMultiReaderPrivate::SaveNextAlignment(BamReader* reader, BamAlignment* alignment) { - // must be in core mode && sorting by position to call GNACore() - if ( m_isCoreMode && m_isSortedByPosition ) { + // must be in core mode && NOT sorting by read name to call GNACore() + if ( m_isCoreMode && m_sortOrder != BamMultiReader::SortedByReadName ) { if ( reader->GetNextAlignmentCore(*alignment) ) m_alignments->Add( make_pair(reader, alignment) ); } @@ -432,21 +440,15 @@ bool BamMultiReaderPrivate::SetRegion(const BamRegion& region) { void BamMultiReaderPrivate::SetSortOrder(const BamMultiReader::SortOrder& order) { - const BamMultiReader::SortOrder oldSortOrder = ( m_isSortedByPosition ? BamMultiReader::SortedByPosition - : BamMultiReader::SortedByReadName ) ; // skip if no change needed - if ( oldSortOrder == order ) return; + if ( m_sortOrder == order ) return; - // create new alignment cache - IBamMultiMerger* newAlignmentCache(0); - if ( order == BamMultiReader::SortedByPosition ) { - newAlignmentCache = new PositionMultiMerger; - m_isSortedByPosition = true; - } - else { - newAlignmentCache = new ReadNameMultiMerger; - m_isSortedByPosition = false; - } + // set new sort order + m_sortOrder = order; + + // create new alignment cache based on sort order + IBamMultiMerger* newAlignmentCache = CreateMergerForCurrentSortOrder(); + if ( newAlignmentCache == 0 ) return; // print error? // copy old cache contents to new cache while ( m_alignments->Size() > 0 ) { diff --git a/src/api/internal/BamMultiReader_p.h b/src/api/internal/BamMultiReader_p.h index 971acda..942f60b 100644 --- a/src/api/internal/BamMultiReader_p.h +++ b/src/api/internal/BamMultiReader_p.h @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 23 December 2010 (DB) +// Last modified: 17 January 2011 (DB) // --------------------------------------------------------------------------- // Functionality for simultaneously reading multiple BAM files // ************************************************************************* @@ -70,6 +70,7 @@ class BamMultiReaderPrivate { // internal methods private: + IBamMultiMerger* CreateMergerForCurrentSortOrder(void) const; const std::string ExtractReadGroup(const std::string& headerLine) const; bool LoadNextAlignment(BamAlignment& al, bool coreMode); void SaveNextAlignment(BamTools::BamReader* reader, BamTools::BamAlignment* alignment); @@ -86,10 +87,10 @@ class BamMultiReaderPrivate { IBamMultiMerger* m_alignments; bool m_isCoreMode; - bool m_isSortedByPosition; + BamMultiReader::SortOrder m_sortOrder; }; -} // namesapce Internal +} // namespace Internal } // namespace BamTools #endif // BAMMULTIREADER_P_H -- 2.39.5