]> git.donarmstrong.com Git - bamtools.git/blobdiff - src/api/BamIndex.cpp
Major update to BamTools version 1.0
[bamtools.git] / src / api / BamIndex.cpp
index dbfe1c939fdc42fd1256fbdd9a494fec02c85e3d..3e5f86e701e68baa9751781f687e012dab5223ee 100644 (file)
@@ -3,7 +3,7 @@
 // Marth Lab, Department of Biology, Boston College
 // All rights reserved.
 // ---------------------------------------------------------------------------
-// Last modified: 22 November 2010 (DB)
+// Last modified: 23 March 2011 (DB)
 // ---------------------------------------------------------------------------
 // Provides index functionality - both for the default (standardized) BAM 
 // index format (.bai) as well as a BamTools-specific (nonstandard) index 
@@ -12,7 +12,6 @@
 
 #include <api/BamIndex.h>
 #include <api/BamReader.h>
-#include <api/BGZF.h>
 #include <api/internal/BamStandardIndex_p.h>
 #include <api/internal/BamToolsIndex_p.h>
 using namespace BamTools;
@@ -25,83 +24,35 @@ using namespace BamTools::Internal;
 #include <map>
 using namespace std;
 
-// --------------------------------------------------
-// BamIndex factory methods
-
-// returns index based on BAM filename 'stub'
-// checks first for preferred type, returns that type if found
-// (if not found, attmempts to load other type(s), returns 0 if NONE found)
-//
-// ** default preferred type is BamToolsIndex ** use this anytime it exists
-BamIndex* BamIndex::FromBamFilename(const std::string& bamFilename,
-                                   BamTools::BgzfData* bgzf,
-                                   BamTools::BamReader* reader,
-                                   const BamIndex::PreferredIndexType& type)
-{
-    // ---------------------------------------------------
-    // attempt to load preferred type first
-
-    const std::string bamtoolsIndexFilename = bamFilename + ".bti";
-    const bool bamtoolsIndexExists = BamTools::FileExists(bamtoolsIndexFilename);
-    if ( (type == BamIndex::BAMTOOLS) && bamtoolsIndexExists )
-        return new BamToolsIndex(bgzf, reader);
-
-    const std::string standardIndexFilename = bamFilename + ".bai";
-    const bool standardIndexExists = BamTools::FileExists(standardIndexFilename);
-    if ( (type == BamIndex::STANDARD) && standardIndexExists )
-        return new BamStandardIndex(bgzf, reader);
-
-    // ----------------------------------------------------
-    // preferred type could not be found, try other (non-preferred) types
-    // if none found, return 0
-
-    if ( bamtoolsIndexExists ) return new BamToolsIndex(bgzf, reader);
-    if ( standardIndexExists ) return new BamStandardIndex(bgzf, reader);
-        return 0;
-}
-
-// returns index based on explicitly named index file (or 0 if not found)
-BamIndex* BamIndex::FromIndexFilename(const std::string&   indexFilename,
-                                     BamTools::BgzfData*  bgzf,
-                                     BamTools::BamReader* reader)
-{
-    // see if specified file exists
-    const bool indexExists = BamTools::FileExists(indexFilename);
-    if ( !indexExists ) return 0;
+/*! \class BamTools::BamIndex
+    \brief Provides methods for generating & loading BAM index files.
 
-    const std::string bamtoolsIndexExtension(".bti");
-    const std::string standardIndexExtension(".bai");
+    This class straddles the line between public API and internal
+    implementation detail. Most client code should never have to use this
+    class directly.
 
-    // if has bamtoolsIndexExtension
-    if ( indexFilename.find(bamtoolsIndexExtension) == (indexFilename.length() - bamtoolsIndexExtension.length()) )
-        return new BamToolsIndex(bgzf, reader);
+    It is exposed to the public API to allow advanced users to implement
+    their own custom indexing schemes.
 
-     // if has standardIndexExtension
-    if ( indexFilename.find(standardIndexExtension) == (indexFilename.length() - standardIndexExtension.length()) )
-        return new BamStandardIndex(bgzf, reader);
-
-    // otherwise, unsupported file type
-    return 0;
-}
-
-// -------------------------------
-// BamIndex implementation
+    N.B. - Please note that if you wish to derive your own subclass, you are
+           entering waters that are not well-documented at the moment and are
+           likely to be changing soon anyway. Implementing a custom index is
+           technically do-able at the moment, but the learning curve is (at the
+           moment) overly steep. Changes will be coming soon to alleviate some
+           of this headache.
+*/
 
 // ctor
-BamIndex::BamIndex(BamTools::BgzfData* bgzf, BamTools::BamReader* reader)
-    : m_BGZF(bgzf)
-    , m_reader(reader)
+BamIndex::BamIndex(void)
+    : m_indexStream(0)
+    , m_indexFilename("")
     , m_cacheMode(BamIndex::LimitedIndexCaching)
-    , m_indexStream(0)
-{ 
-    if ( m_reader && m_reader->IsOpen() ) 
-        m_references = m_reader->GetReferenceData();
-}
+{ }
 
 // dtor
 BamIndex::~BamIndex(void) {
-    if ( IsOpen() )
-        fclose(m_indexStream);
+    if ( IsOpen() ) fclose(m_indexStream);
+    m_indexFilename = "";
 }
 
 // return true if FILE* is open
@@ -114,7 +65,7 @@ bool BamIndex::Load(const string& filename)  {
 
     // open index file, abort on error
     if ( !OpenIndexFile(filename, "rb") ) {
-        fprintf(stderr, "ERROR: Unable to open the BAM index file %s for reading.\n", filename.c_str());
+        fprintf(stderr, "BamIndex ERROR: unable to open the BAM index file %s for reading.\n", filename.c_str());
         return false;
     }
 
@@ -140,8 +91,14 @@ bool BamIndex::Load(const string& filename)  {
 
 // opens index file for reading/writing, return true if opened OK
 bool BamIndex::OpenIndexFile(const string& filename, const string& mode) {
+
+    // attempt to open file, return false if error
     m_indexStream = fopen(filename.c_str(), mode.c_str());
-    return ( m_indexStream != 0 );
+    if ( m_indexStream == 0 )  return false;
+
+    // otherwise save filename & return sucess
+    m_indexFilename = filename;
+    return true;
 }
 
 // rewind index file to beginning of index data, return true if rewound OK
@@ -150,7 +107,7 @@ bool BamIndex::Rewind(void) {
 }
 
 // change the index caching behavior
-void BamIndex::SetCacheMode(const BamIndexCacheMode mode) {
+void BamIndex::SetCacheMode(const BamIndex::IndexCacheMode& mode) {
     if ( mode != m_cacheMode ) {
         m_cacheMode = mode;
         UpdateCache();
@@ -180,9 +137,11 @@ void BamIndex::UpdateCache(void) {
                 LoadFirstReference(true);
             }
             break;
+
         case(BamIndex::NoIndexCaching) :
             ClearAllData();
             break;
+
         default :
             // unreachable
             ;
@@ -195,13 +154,13 @@ bool BamIndex::Write(const string& bamFilename) {
     // open index file for writing
     string indexFilename = bamFilename + Extension();
     if ( !OpenIndexFile(indexFilename, "wb") ) {
-        fprintf(stderr, "ERROR: Could not open file to save index.\n");
+        fprintf(stderr, "BamIndex ERROR: could not open file to save index data.\n");
         return false;
     }
 
     // write index header data
     if ( !WriteHeader() ) {
-        fprintf(stderr, "ERROR: There was a problem writing index metadata to new index file.\n");
+        fprintf(stderr, "BamIndex ERROR: there was a problem writing index metadata to the new index file.\n");
         fflush(m_indexStream);
         fclose(m_indexStream);
         exit(1);
@@ -209,22 +168,23 @@ bool BamIndex::Write(const string& bamFilename) {
 
     // write main index data
     if ( !WriteAllReferences() ) {
-        fprintf(stderr, "ERROR: There was a problem writing index data to new index file.\n");
+        fprintf(stderr, "BamIndex ERROR: there was a problem writing index data to the new index file.\n");
         fflush(m_indexStream);
         fclose(m_indexStream);
         exit(1);
     }
 
-    // flush any remaining output, rewind file, and return success
+    // flush any remaining output
     fflush(m_indexStream);
     fclose(m_indexStream);
 
     // re-open index file for later reading
     if ( !OpenIndexFile(indexFilename, "rb") ) {
-        fprintf(stderr, "ERROR: Could not open newly created index file for reading.\n");
+        fprintf(stderr, "BamIndex ERROR: could not open newly created index file for reading.\n");
         return false;
     }
 
-    // return success/failure of write
+    // save index filename & return success
+    m_indexFilename = indexFilename;
     return true;
 }