X-Git-Url: https://git.donarmstrong.com/?p=bamtools.git;a=blobdiff_plain;f=src%2Fapi%2Finternal%2FBamRandomAccessController_p.cpp;h=437b609940455c2907061e2e2f9ec7003d5b508a;hp=a44563f5489952fb13a1f0e7d8fc0cac35db1b8c;hb=8a90b7aefffaf186053ef4da96c8663bf528274a;hpb=c1fc1c5423ca73a1b5bcbe790650821d73e5959c diff --git a/src/api/internal/BamRandomAccessController_p.cpp b/src/api/internal/BamRandomAccessController_p.cpp index a44563f..437b609 100644 --- a/src/api/internal/BamRandomAccessController_p.cpp +++ b/src/api/internal/BamRandomAccessController_p.cpp @@ -2,19 +2,21 @@ // BamRandomAccessController_p.cpp (c) 2011 Derek Barnett // Marth Lab, Department of Biology, Boston College // --------------------------------------------------------------------------- -// Last modified: 5 April 2011(DB) +// Last modified: 7 October 2011(DB) // --------------------------------------------------------------------------- // Manages random access operations in a BAM file // ************************************************************************** #include +#include #include #include #include using namespace BamTools; using namespace BamTools::Internal; -#include +#include +#include using namespace std; BamRandomAccessController::BamRandomAccessController(void) @@ -133,10 +135,10 @@ void BamRandomAccessController::Close(void) { } void BamRandomAccessController::ClearIndex(void) { - if ( m_index == 0 ) - return; - delete m_index; - m_index = 0; + if ( m_index ) { + delete m_index; + m_index = 0; + } } void BamRandomAccessController::ClearRegion(void) { @@ -145,23 +147,30 @@ void BamRandomAccessController::ClearRegion(void) { } bool BamRandomAccessController::CreateIndex(BamReaderPrivate* reader, - const BamIndex::IndexType& type) { - + const BamIndex::IndexType& type) +{ // skip if reader is invalid - if ( reader == 0 ) + assert(reader); + if ( !reader->IsOpen() ) { + SetErrorString("BamRandomAccessController::CreateIndex", + "cannot create index for unopened reader"); return false; + } // create new index of requested type BamIndex* newIndex = BamIndexFactory::CreateIndexOfType(type, reader); if ( newIndex == 0 ) { - cerr << "BamRandomAccessController ERROR: could not create index of type " << type << endl; + stringstream s(""); + s << "could not create index of type: " << type; + SetErrorString("BamRandomAccessController::CreateIndex", s.str()); return false; } // attempt to build index from current BamReader file if ( !newIndex->Create() ) { - cerr << "BamRandomAccessController ERROR: could not create index for BAM file: " - << reader->Filename() << endl; + const string indexError = newIndex->GetErrorString(); + const string message = "could not create index: \n\t" + indexError; + SetErrorString("BamRandomAccessController::CreateIndex", message); return false; } @@ -173,6 +182,10 @@ bool BamRandomAccessController::CreateIndex(BamReaderPrivate* reader, return true; } +string BamRandomAccessController::GetErrorString(void) const { + return m_errorString; +} + bool BamRandomAccessController::HasIndex(void) const { return ( m_index != 0 ); } @@ -189,13 +202,13 @@ bool BamRandomAccessController::LocateIndex(BamReaderPrivate* reader, const BamIndex::IndexType& preferredType) { // look up index filename, deferring to preferredType if possible + assert(reader); const string& indexFilename = BamIndexFactory::FindIndexFilename(reader->Filename(), preferredType); // if no index file found (of any type) if ( indexFilename.empty() ) { - cerr << "BamRandomAccessController WARNING: " - << "could not find index file for BAM: " - << reader->Filename() << endl; + const string message = string("could not find index file for:") + reader->Filename(); + SetErrorString("BamRandomAccessController::LocateIndex", message); return false; } @@ -208,7 +221,8 @@ bool BamRandomAccessController::OpenIndex(const string& indexFilename, BamReader // attempt create new index of type based on filename BamIndex* index = BamIndexFactory::CreateIndexFromFilename(indexFilename, reader); if ( index == 0 ) { - cerr << "BamRandomAccessController ERROR: could not create index for file: " << indexFilename << endl; + const string message = string("could not open index file: ") + indexFilename; + SetErrorString("BamRandomAccessController::OpenIndex", message); return false; } @@ -217,7 +231,10 @@ bool BamRandomAccessController::OpenIndex(const string& indexFilename, BamReader // attempt to load data from index file if ( !index->Load(indexFilename) ) { - cerr << "BamRandomAccessController ERROR: could not load index data from file: " << indexFilename << endl; + const string indexError = index->GetErrorString(); + const string message = string("could not load index data from file: ") + indexFilename + + "\n\t" + indexError; + SetErrorString("BamRandomAccessController::OpenIndex", message); return false; } @@ -230,6 +247,10 @@ bool BamRandomAccessController::RegionHasAlignments(void) const { return m_hasAlignmentsInRegion; } +void BamRandomAccessController::SetErrorString(const string& where, const string& what) { + m_errorString = where + ": " + what; +} + void BamRandomAccessController::SetIndex(BamIndex* index) { if ( m_index ) ClearIndex(); @@ -242,16 +263,16 @@ void BamRandomAccessController::SetIndexCacheMode(const BamIndex::IndexCacheMode m_index->SetCacheMode(mode); } -bool BamRandomAccessController::SetRegion(BamReaderPrivate* reader, - const BamRegion& region, - const int& referenceCount) -{ +bool BamRandomAccessController::SetRegion(const BamRegion& region, const int& referenceCount) { + // store region m_region = region; // cannot jump when no index is available - if ( !HasIndex() ) + if ( !HasIndex() ) { + SetErrorString("BamRandomAccessController", "cannot jump if no index data available"); return false; + } // adjust region as necessary to reflect where data actually begins AdjustRegion(referenceCount); @@ -259,7 +280,7 @@ bool BamRandomAccessController::SetRegion(BamReaderPrivate* reader, // if no data present, return true // * Not an error, but future attempts to access alignments in this region will not return data // Returning true is useful in a BamMultiReader setting where some BAM files may - // lack alignments in regions where other BAMs do have data. + // lack alignments in regions where other files still have data available. if ( !m_hasAlignmentsInRegion ) return true; @@ -269,6 +290,13 @@ bool BamRandomAccessController::SetRegion(BamReaderPrivate* reader, // This covers 'corner case' where a region is requested that lies beyond the last // alignment on a reference. If this occurs, any subsequent calls to GetNextAlignment[Core] // will not return data. BamMultiReader will still be able to successfully pull alignments - // from a region from multiple files even if one or more have no data. - return m_index->Jump(m_region, &m_hasAlignmentsInRegion); + // from a region from other files even if this one has no data. + if ( !m_index->Jump(m_region, &m_hasAlignmentsInRegion) ) { + const string indexError = m_index->GetErrorString(); + const string message = string("could not set region\n\t") + indexError; + SetErrorString("BamRandomAccessController::OpenIndex", message); + return false; + } + else + return true; }