// ValidateReaders checks that all the readers point to BAM files representing // alignments against the same set of reference sequences, and that the // sequences are identically ordered. If these checks fail the operation of // the multireader is undefined, so we force program exit. void BamMultiReader::ValidateReaders(void) const { int firstRefCount = readers.front().first->GetReferenceCount(); BamTools::RefVector firstRefData = readers.front().first->GetReferenceData(); for (vector<pair<BamReader*, BamAlignment*> >::const_iterator it = readers.begin(); it != readers.end(); ++it) { BamReader* reader = it->first; BamTools::RefVector currentRefData = reader->GetReferenceData(); BamTools::RefVector::const_iterator f = firstRefData.begin(); BamTools::RefVector::const_iterator c = currentRefData.begin(); if (reader->GetReferenceCount() != firstRefCount || firstRefData.size() != currentRefData.size()) { cerr << "ERROR: mismatched number of references in " << reader->GetFilename() << " expected " << firstRefCount << " reference sequences but only found " << reader->GetReferenceCount() << endl; exit(1); } // this will be ok; we just checked above that we have identically-sized sets of references // here we simply check if they are all, in fact, equal in content while (f != firstRefData.end()) { if (f->RefName != c->RefName || f->RefLength != c->RefLength) { cerr << "ERROR: mismatched references found in " << reader->GetFilename() << " expected: " << endl; for (BamTools::RefVector::const_iterator a = firstRefData.begin(); a != firstRefData.end(); ++a) cerr << a->RefName << " " << a->RefLength << endl; cerr << "but found: " << endl; for (BamTools::RefVector::const_iterator a = currentRefData.begin(); a != currentRefData.end(); ++a) cerr << a->RefName << " " << a->RefLength << endl; exit(1); } ++f; ++c; } } }
// ValidateReaders checks that all the readers point to BAM files representing // alignments against the same set of reference sequences, and that the // sequences are identically ordered. If these checks fail the operation of // the multireader is undefined, so we force program exit. bool BamMultiReaderPrivate::ValidateReaders() const { m_errorString.clear(); // skip if 0 or 1 readers opened if (m_readers.empty() || (m_readers.size() == 1)) return true; // retrieve first reader const MergeItem& firstItem = m_readers.front(); const BamReader* firstReader = firstItem.Reader; if (firstReader == 0) return false; // retrieve first reader's header data const SamHeader& firstReaderHeader = firstReader->GetHeader(); const std::string& firstReaderSortOrder = firstReaderHeader.SortOrder; // retrieve first reader's reference data const RefVector& firstReaderRefData = firstReader->GetReferenceData(); const int firstReaderRefCount = firstReader->GetReferenceCount(); const int firstReaderRefSize = firstReaderRefData.size(); // iterate over all readers std::vector<MergeItem>::const_iterator readerIter = m_readers.begin(); std::vector<MergeItem>::const_iterator readerEnd = m_readers.end(); for (; readerIter != readerEnd; ++readerIter) { const MergeItem& item = (*readerIter); BamReader* reader = item.Reader; if (reader == 0) continue; // get current reader's header data const SamHeader& currentReaderHeader = reader->GetHeader(); const std::string& currentReaderSortOrder = currentReaderHeader.SortOrder; // check compatible sort order if (currentReaderSortOrder != firstReaderSortOrder) { const std::string message = std::string("mismatched sort order in ") + reader->GetFilename() + ", expected " + firstReaderSortOrder + ", but found " + currentReaderSortOrder; SetErrorString("BamMultiReader::ValidateReaders", message); return false; } // get current reader's reference data const RefVector currentReaderRefData = reader->GetReferenceData(); const int currentReaderRefCount = reader->GetReferenceCount(); const int currentReaderRefSize = currentReaderRefData.size(); // init reference data iterators RefVector::const_iterator firstRefIter = firstReaderRefData.begin(); RefVector::const_iterator firstRefEnd = firstReaderRefData.end(); RefVector::const_iterator currentRefIter = currentReaderRefData.begin(); // compare reference counts from BamReader ( & container size, in case of BR error) if ((currentReaderRefCount != firstReaderRefCount) || (firstReaderRefSize != currentReaderRefSize)) { std::stringstream s; s << "mismatched reference count in " << reader->GetFilename() << ", expected " << firstReaderRefCount << ", but found " << currentReaderRefCount; SetErrorString("BamMultiReader::ValidateReaders", s.str()); return false; } // this will be ok; we just checked above that we have identically-sized sets of references // here we simply check if they are all, in fact, equal in content while (firstRefIter != firstRefEnd) { const RefData& firstRef = (*firstRefIter); const RefData& currentRef = (*currentRefIter); // compare reference name & length if ((firstRef.RefName != currentRef.RefName) || (firstRef.RefLength != currentRef.RefLength)) { std::stringstream s; s << "mismatched references found in" << reader->GetFilename() << "expected: " << std::endl; // print first reader's reference data RefVector::const_iterator refIter = firstReaderRefData.begin(); RefVector::const_iterator refEnd = firstReaderRefData.end(); for (; refIter != refEnd; ++refIter) { const RefData& entry = (*refIter); std::stringstream s; s << entry.RefName << ' ' << std::endl; } s << "but found: " << std::endl; // print current reader's reference data refIter = currentReaderRefData.begin(); refEnd = currentReaderRefData.end(); for (; refIter != refEnd; ++refIter) { const RefData& entry = (*refIter); s << entry.RefName << ' ' << entry.RefLength << std::endl; } SetErrorString("BamMultiReader::ValidateReaders", s.str()); return false; } // update iterators ++firstRefIter; ++currentRefIter; } } // if we get here, everything checks out return true; }