]> git.donarmstrong.com Git - bamtools.git/blobdiff - BamMultiReader.cpp
Minor formatting cleanup in BamIndex.*
[bamtools.git] / BamMultiReader.cpp
index f0a8ceda8b2bc1bf8b43803e794be9e229357415..005b0b0adc7c6c22c12f4317791785803a974bd6 100644 (file)
@@ -3,7 +3,7 @@
 // Marth Lab, Department of Biology, Boston College
 // All rights reserved.
 // ---------------------------------------------------------------------------
-// Last modified: 23 Februrary 2010 (EG)
+// Last modified: 20 July 2010 (DB)
 // ---------------------------------------------------------------------------
 // Uses BGZF routines were adapted from the bgzf.c code developed at the Broad
 // Institute.
@@ -163,46 +163,103 @@ bool BamMultiReader::Jump(int refID, int position) {
             exit(1);
         }
     }
-    if (result) {
-        // Update Alignments
-        alignments.clear();
-        for (vector<pair<BamReader*, BamAlignment*> >::iterator it = readers.begin(); it != readers.end(); ++it) {
-            BamReader* br = it->first;
-            BamAlignment* ba = it->second;
-            if (br->GetNextAlignment(*ba)) {
-                alignments.insert(make_pair(make_pair(ba->RefID, ba->Position), 
-                                            make_pair(br, ba)));
-            } else {
-                // assume BamReader EOF
-            }
+    if (result) UpdateAlignments();
+    return result;
+}
+
+bool BamMultiReader::SetRegion(const int& leftRefID, const int& leftPosition, const int& rightRefID, const int& rightPosition) {
+
+    BamRegion region(leftRefID, leftPosition, rightRefID, rightPosition);
+
+    return SetRegion(region);
+
+}
+
+bool BamMultiReader::SetRegion(const BamRegion& region) {
+
+    Region = region;
+
+    // NB: While it may make sense to track readers in which we can
+    // successfully SetRegion, In practice a failure of SetRegion means "no
+    // alignments here."  It makes sense to simply accept the failure,
+    // UpdateAlignments(), and continue.
+
+    for (vector<pair<BamReader*, BamAlignment*> >::iterator it = readers.begin(); it != readers.end(); ++it) {
+        it->first->SetRegion(region);
+    }
+
+    UpdateAlignments();
+
+    return true;
+
+}
+
+void BamMultiReader::UpdateAlignments(void) {
+    // Update Alignments
+    alignments.clear();
+    for (vector<pair<BamReader*, BamAlignment*> >::iterator it = readers.begin(); it != readers.end(); ++it) {
+        BamReader* br = it->first;
+        BamAlignment* ba = it->second;
+        if (br->GetNextAlignment(*ba)) {
+            alignments.insert(make_pair(make_pair(ba->RefID, ba->Position), 
+                                        make_pair(br, ba)));
+        } else {
+            // assume BamReader end of region / EOF
         }
     }
-    return result;
 }
 
 // opens BAM files
-void BamMultiReader::Open(const vector<string> filenames, bool openIndexes, bool coreMode) {
+bool BamMultiReader::Open(const vector<string> filenames, bool openIndexes, bool coreMode, bool useDefaultIndex) {
+    
     // for filename in filenames
     fileNames = filenames; // save filenames in our multireader
     for (vector<string>::const_iterator it = filenames.begin(); it != filenames.end(); ++it) {
         string filename = *it;
         BamReader* reader = new BamReader;
+
+        bool openedOK = true;
         if (openIndexes) {
-            reader->Open(filename, filename + ".bai");
-        } else {
-            reader->Open(filename); // for merging, jumping is disallowed
-        }
-        BamAlignment* alignment = new BamAlignment;
-        if (coreMode) {
-            reader->GetNextAlignmentCore(*alignment);
+            if (useDefaultIndex)
+                openedOK = reader->Open(filename, filename + ".bai");
+            else 
+                openedOK = reader->Open(filename, filename + ".bti");
         } else {
-            reader->GetNextAlignment(*alignment);
+            openedOK = reader->Open(filename); // for merging, jumping is disallowed
         }
-        readers.push_back(make_pair(reader, alignment)); // store pointers to our readers for cleanup
-        alignments.insert(make_pair(make_pair(alignment->RefID, alignment->Position),
-                                    make_pair(reader, alignment)));
+        
+        // if file opened ok, check that it can be read
+        if ( openedOK ) {
+           
+            bool fileOK = true;
+            BamAlignment* alignment = new BamAlignment;
+            if (coreMode) {
+                fileOK &= reader->GetNextAlignmentCore(*alignment);
+            } else {
+                fileOK &= reader->GetNextAlignment(*alignment);
+            }
+            
+            if (fileOK) {
+                readers.push_back(make_pair(reader, alignment)); // store pointers to our readers for cleanup
+                alignments.insert(make_pair(make_pair(alignment->RefID, alignment->Position),
+                                            make_pair(reader, alignment)));
+            } else {
+                cerr << "WARNING: could not read first alignment in " << filename << ", ignoring file" << endl;
+                // if only file available & could not be read, return failure
+                if ( filenames.size() == 1 ) return false;
+            }
+        
+        } 
+       
+        // TODO; any more error handling on openedOK ??
+        else 
+            return false;
     }
+
+    // files opened ok, at least one alignment could be read,
+    // now need to check that all files use same reference data
     ValidateReaders();
+    return true;
 }
 
 void BamMultiReader::PrintFilenames(void) {
@@ -229,12 +286,12 @@ bool BamMultiReader::Rewind(void) {
     return result;
 }
 
-// saves index data to BAM index files (".bai") where necessary, returns success/fail
-bool BamMultiReader::CreateIndexes(void) {
+// saves index data to BAM index files (".bai"/".bti") where necessary, returns success/fail
+bool BamMultiReader::CreateIndexes(bool useDefaultIndex) {
     bool result = true;
     for (vector<pair<BamReader*, BamAlignment*> >::iterator it = readers.begin(); it != readers.end(); ++it) {
         BamReader* reader = it->first;
-        result &= reader->CreateIndex();
+        result &= reader->CreateIndex(useDefaultIndex);
     }
     return result;
 }