// BamMultiReader_p.cpp (c) 2010 Derek Barnett, Erik Garrison
// Marth Lab, Department of Biology, Boston College
// ---------------------------------------------------------------------------
-// Last modified: 25 October 2011 (DB)
+// Last modified: 14 January 2013 (DB)
// ---------------------------------------------------------------------------
// Functionality for simultaneously reading multiple BAM files
// *************************************************************************
// ctor
BamMultiReaderPrivate::BamMultiReaderPrivate(void)
: m_alignmentCache(0)
+ , m_hasUserMergeOrder(false)
+ , m_mergeOrder(BamMultiReader::RoundRobinMerge)
{ }
// dtor
}
}
- // make sure alignment cache is cleaned up if all readers closed
- if ( m_readers.empty() && m_alignmentCache ) {
- m_alignmentCache->Clear();
- delete m_alignmentCache;
- m_alignmentCache = 0;
+ // make sure we clean up properly if all readers were closed
+ if ( m_readers.empty() ) {
+
+ // clean up merger
+ if ( m_alignmentCache ) {
+ m_alignmentCache->Clear();
+ delete m_alignmentCache;
+ m_alignmentCache = 0;
+ }
+
+ // reset merge flags
+ m_hasUserMergeOrder = false;
+ m_mergeOrder = BamMultiReader::RoundRobinMerge;
}
// return whether all readers closed OK
return true;
}
-IMultiMerger* BamMultiReaderPrivate::CreateAlignmentCache(void) const {
+IMultiMerger* BamMultiReaderPrivate::CreateAlignmentCache(void) {
+
+ // if no merge order set explicitly, use SAM header to lookup proper order
+ if ( !m_hasUserMergeOrder ) {
+
+ // fetch SamHeader from BAM files
+ SamHeader header = GetHeader();
+
+ // if BAM files are sorted by position
+ if ( header.SortOrder == Constants::SAM_HD_SORTORDER_COORDINATE )
+ m_mergeOrder = BamMultiReader::MergeByCoordinate;
+
+ // if BAM files are sorted by read name
+ if ( header.SortOrder == Constants::SAM_HD_SORTORDER_QUERYNAME )
+ m_mergeOrder = BamMultiReader::MergeByName;
+
+ // otherwise, sorting is either "unknown" or marked as "unsorted"
+ else
+ m_mergeOrder = BamMultiReader::RoundRobinMerge;
+ }
+
+ // use current merge order to create proper 'multi-merger'
+ switch ( m_mergeOrder ) {
- // fetch SamHeader
- SamHeader header = GetHeader();
+ // merge BAM files by position
+ case BamMultiReader::MergeByCoordinate :
+ return new MultiMerger<Algorithms::Sort::ByPosition>();
- // if BAM files are sorted by position
- if ( header.SortOrder == Constants::SAM_HD_SORTORDER_COORDINATE )
- return new MultiMerger<Algorithms::Sort::ByPosition>();
+ // merge BAM files by read name
+ case BamMultiReader::MergeByName :
+ return new MultiMerger<Algorithms::Sort::ByName>();
- // if BAM files are sorted by read name
- if ( header.SortOrder == Constants::SAM_HD_SORTORDER_QUERYNAME )
- return new MultiMerger<Algorithms::Sort::ByName>();
+ // sorting is "unknown", "unsorted" or "ignored"... so use unsorted merger
+ case BamMultiReader::RoundRobinMerge :
+ return new MultiMerger<Algorithms::Sort::Unsorted>();
- // otherwise "unknown" or "unsorted", use unsorted merger and just read in
- return new MultiMerger<Algorithms::Sort::Unsorted>();
+ // unknown merge order, can't create merger
+ default:
+ return 0;
+ }
}
const vector<string> BamMultiReaderPrivate::Filenames(void) const {
return mergedHeader.ToString();
}
+BamMultiReader::MergeOrder BamMultiReaderPrivate::GetMergeOrder(void) const {
+ return m_mergeOrder;
+}
+
// get next alignment among all files
bool BamMultiReaderPrivate::GetNextAlignment(BamAlignment& al) {
return PopNextCachedAlignment(al, true);
m_alignmentCache->Add( MergeItem(reader, alignment) );
}
+void BamMultiReaderPrivate::SetExplicitMergeOrder(BamMultiReader::MergeOrder order) {
+
+ // set new merge flags
+ m_hasUserMergeOrder = true;
+ m_mergeOrder = order;
+
+ // remove any existing merger
+ if ( m_alignmentCache ) {
+ m_alignmentCache->Clear();
+ delete m_alignmentCache;
+ m_alignmentCache = 0;
+ }
+
+ // update cache with new strategy
+ UpdateAlignmentCache();
+}
+
void BamMultiReaderPrivate::SetErrorString(const string& where, const string& what) const {
static const string SEPARATOR = ": ";
m_errorString = where + SEPARATOR + what;