]> git.donarmstrong.com Git - bamtools.git/blobdiff - src/api/BamMultiReader.cpp
Added explicit merge order to BamMultiReader
[bamtools.git] / src / api / BamMultiReader.cpp
index d0315688ef4ef3595854ef751b3c92ac19b72533..57c826daa80ccd5368bc0cde3c7254d1f417f496 100644 (file)
@@ -2,7 +2,7 @@
 // BamMultiReader.cpp (c) 2010 Erik Garrison, Derek Barnett
 // Marth Lab, Department of Biology, Boston College
 // ---------------------------------------------------------------------------
 // BamMultiReader.cpp (c) 2010 Erik Garrison, Derek Barnett
 // Marth Lab, Department of Biology, Boston College
 // ---------------------------------------------------------------------------
-// Last modified: 8 October 2011 (DB)
+// Last modified: 14 January 2013 (DB)
 // ---------------------------------------------------------------------------
 // Convenience class for reading multiple BAM files.
 //
 // ---------------------------------------------------------------------------
 // Convenience class for reading multiple BAM files.
 //
 // precludes the need to sort merged files.
 // ***************************************************************************
 
 // precludes the need to sort merged files.
 // ***************************************************************************
 
-#include <api/BamMultiReader.h>
-#include <api/internal/BamMultiReader_p.h>
+#include "api/BamMultiReader.h"
+#include "api/internal/bam/BamMultiReader_p.h"
 using namespace BamTools;
 
 #include <string>
 #include <vector>
 using namespace std;
 
 using namespace BamTools;
 
 #include <string>
 #include <vector>
 using namespace std;
 
-/*! \class BamTools::BamReader
+/*! \class BamTools::BamMultiReader
     \brief Convenience class for reading multiple BAM files.
 */
 
     \brief Convenience class for reading multiple BAM files.
 */
 
+/*! \enum BamMultiReader::MergeOrder
+    \brief A description of the enum type.
+*/
+/*! \var BamMultiReader::MergeOrder BamMultiReader::MergeByCoordinate
+    \brief The description of the first enum value.
+*/
+/*! \var BamMultiReader::MergeOrder BamMultiReader::MergeByName
+    \brief BAM files are
+*/
+
+
+
 /*! \fn BamMultiReader::BamMultiReader(void)
     \brief constructor
 */
 /*! \fn BamMultiReader::BamMultiReader(void)
     \brief constructor
 */
@@ -55,6 +67,8 @@ bool BamMultiReader::Close(void) {
 
     Leaves any other file(s) open, along with header and reference data.
 
 
     Leaves any other file(s) open, along with header and reference data.
 
+    \param[in] filename name of specific BAM file to close
+
     \sa Close(), IsOpen(), Open(), BamReader::Close()
 */
 bool BamMultiReader::CloseFile(const std::string& filename) {
     \sa Close(), IsOpen(), Open(), BamReader::Close()
 */
 bool BamMultiReader::CloseFile(const std::string& filename) {
@@ -64,7 +78,7 @@ bool BamMultiReader::CloseFile(const std::string& filename) {
 /*! \fn bool BamMultiReader::CreateIndexes(const BamIndex::IndexType& type)
     \brief Creates index files for the current BAM files.
 
 /*! \fn bool BamMultiReader::CreateIndexes(const BamIndex::IndexType& type)
     \brief Creates index files for the current BAM files.
 
-    \param type file format to create, see BamIndex::IndexType for available formats
+    \param[in] type file format to create, see BamIndex::IndexType for available formats
     \return \c true if index files created OK
     \sa LocateIndexes(), OpenIndexes(), BamReader::CreateIndex()
 */
     \return \c true if index files created OK
     \sa LocateIndexes(), OpenIndexes(), BamReader::CreateIndex()
 */
@@ -86,7 +100,14 @@ const std::vector<std::string> BamMultiReader::Filenames(void) const {
     return d->Filenames();
 }
 
     return d->Filenames();
 }
 
-// returns a description of the last error that occurred
+/*! \fn std::string BamMultiReader::GetErrorString(void) const
+    \brief Returns a human-readable description of the last error that occurred
+
+    This method allows elimination of STDERR pollution. Developers of client code
+    may choose how the messages are displayed to the user, if at all.
+
+    \return error description
+*/
 std::string BamMultiReader::GetErrorString(void) const {
     return d->GetErrorString();
 }
 std::string BamMultiReader::GetErrorString(void) const {
     return d->GetErrorString();
 }
@@ -94,8 +115,8 @@ std::string BamMultiReader::GetErrorString(void) const {
 /*! \fn SamHeader BamMultiReader::GetHeader(void) const
     \brief Returns unified SAM-format header for all files
 
 /*! \fn SamHeader BamMultiReader::GetHeader(void) const
     \brief Returns unified SAM-format header for all files
 
-    N.B. - Modifying the retrieved text does NOT affect the current
-    BAM files. Thesse file have been opened in a read-only mode. However,
+    \note Modifying the retrieved text does NOT affect the current
+    BAM files. These files have been opened in a read-only mode. However,
     your modified header text can be used in conjunction with BamWriter
     to generate a new BAM file with the appropriate header information.
 
     your modified header text can be used in conjunction with BamWriter
     to generate a new BAM file with the appropriate header information.
 
@@ -109,8 +130,8 @@ SamHeader BamMultiReader::GetHeader(void) const {
 /*! \fn std::string BamMultiReader::GetHeaderText(void) const
     \brief Returns unified SAM-format header text for all files
 
 /*! \fn std::string BamMultiReader::GetHeaderText(void) const
     \brief Returns unified SAM-format header text for all files
 
-    N.B. - Modifying the retrieved text does NOT affect the current
-    BAM files. Thesse file have been opened in a read-only mode. However,
+    \note Modifying the retrieved text does NOT affect the current
+    BAM files. These files have been opened in a read-only mode. However,
     your modified header text can be used in conjunction with BamWriter
     to generate a new BAM file with the appropriate header information.
 
     your modified header text can be used in conjunction with BamWriter
     to generate a new BAM file with the appropriate header information.
 
@@ -121,6 +142,16 @@ std::string BamMultiReader::GetHeaderText(void) const {
     return d->GetHeaderText();
 }
 
     return d->GetHeaderText();
 }
 
+/*! \fn BamMultiReader::MergeOrder BamMultiReader::GetMergeOrder(void) const
+    \brief Returns curent merge order strategy.
+
+    \returns current merge order enum value
+    \sa BamMultiReader::MergeOrder, SetExplicitMergeOrder()
+*/
+BamMultiReader::MergeOrder BamMultiReader::GetMergeOrder(void) const {
+    return d->GetMergeOrder();
+}
+
 /*! \fn bool BamMultiReader::GetNextAlignment(BamAlignment& alignment)
     \brief Retrieves next available alignment.
 
 /*! \fn bool BamMultiReader::GetNextAlignment(BamAlignment& alignment)
     \brief Retrieves next available alignment.
 
@@ -128,11 +159,11 @@ std::string BamMultiReader::GetHeaderText(void) const {
     overlapping alignment and what data gets populated.
 
     This method takes care of determining which alignment actually is 'next'
     overlapping alignment and what data gets populated.
 
     This method takes care of determining which alignment actually is 'next'
-    across multiple files, depending on current SortOrder.
+    across multiple files, depending on their sort order.
 
 
-    \param alignment destination for alignment record data
+    \param[out] alignment destination for alignment record data
     \returns \c true if a valid alignment was found
     \returns \c true if a valid alignment was found
-    \sa GetNextAlignmentCore(), SetRegion(), SetSortOrder(), BamReader::GetNextAlignment()
+    \sa GetNextAlignmentCore(), SetExplicitMergeOrder(), SetRegion(), BamReader::GetNextAlignment()
 */
 bool BamMultiReader::GetNextAlignment(BamAlignment& nextAlignment) {
     return d->GetNextAlignment(nextAlignment);
 */
 bool BamMultiReader::GetNextAlignment(BamAlignment& nextAlignment) {
     return d->GetNextAlignment(nextAlignment);
@@ -145,11 +176,11 @@ bool BamMultiReader::GetNextAlignment(BamAlignment& nextAlignment) {
     overlapping alignment and what data gets populated.
 
     This method takes care of determining which alignment actually is 'next'
     overlapping alignment and what data gets populated.
 
     This method takes care of determining which alignment actually is 'next'
-    across multiple files, depending on current SortOrder.
+    across multiple files, depending on their sort order.
 
 
-    \param alignment destination for alignment record data
+    \param[out] alignment destination for alignment record data
     \returns \c true if a valid alignment was found
     \returns \c true if a valid alignment was found
-    \sa GetNextAlignment(), SetRegion(), SetSortOrder(), BamReader::GetNextAlignmentCore()
+    \sa GetNextAlignment(), SetExplicitMergeOrder(), SetRegion(), BamReader::GetNextAlignmentCore()
 */
 bool BamMultiReader::GetNextAlignmentCore(BamAlignment& nextAlignment) {
     return d->GetNextAlignmentCore(nextAlignment);
 */
 bool BamMultiReader::GetNextAlignmentCore(BamAlignment& nextAlignment) {
     return d->GetNextAlignmentCore(nextAlignment);
@@ -176,6 +207,7 @@ const BamTools::RefVector BamMultiReader::GetReferenceData(void) const {
 
     If \a refName is not found, returns -1.
 
 
     If \a refName is not found, returns -1.
 
+    \param[in] refName name of reference to look up
     \sa BamReader::GetReferenceID()
 */
 int BamMultiReader::GetReferenceID(const std::string& refName) const {
     \sa BamReader::GetReferenceID()
 */
 int BamMultiReader::GetReferenceID(const std::string& refName) const {
@@ -203,6 +235,9 @@ bool BamMultiReader::HasOpenReaders(void) const {
     This is a convenience method, equivalent to calling SetRegion()
     with only a left boundary specified.
 
     This is a convenience method, equivalent to calling SetRegion()
     with only a left boundary specified.
 
+    \param[in] refID    ID of reference to jump to
+    \param[in] position (0-based) left boundary
+
     \returns \c true if jump was successful
     \sa HasIndex(), BamReader::Jump()
 */
     \returns \c true if jump was successful
     \sa HasIndex(), BamReader::Jump()
 */
@@ -225,16 +260,15 @@ bool BamMultiReader::Jump(int refID, int position) {
 
     An example case would look this:
     \code
 
     An example case would look this:
     \code
-
         BamMultiReader reader;
         BamMultiReader reader;
-        // do setup
+
+        // do setup...
 
         // ensure that all files have an index
         if ( !reader.LocateIndexes() )      // opens any existing index files that match our BAM files
 
         // ensure that all files have an index
         if ( !reader.LocateIndexes() )      // opens any existing index files that match our BAM files
-            reader.CreateIndexes();         // creates index files for BAM files that still lack one
+            reader.CreateIndexes();         // creates index files for any BAM files that still lack one
 
 
-        // do interesting stuff
-        // ...
+        // do interesting stuff using random-access...
 
     \endcode
 
 
     \endcode
 
@@ -242,7 +276,7 @@ bool BamMultiReader::Jump(int refID, int position) {
     with the desired index filenames. If that function returns false, you can use
     CreateIndexes() to then build index files of the exact requested format.
 
     with the desired index filenames. If that function returns false, you can use
     CreateIndexes() to then build index files of the exact requested format.
 
-    \param preferredType desired index file format, see BamIndex::IndexType for available formats
+    \param[in] preferredType desired index file format, see BamIndex::IndexType for available formats
     \returns \c true if index files could be found for \b ALL open BAM files
     \sa BamReader::LocateIndex()
 */
     \returns \c true if index files could be found for \b ALL open BAM files
     \sa BamReader::LocateIndex()
 */
@@ -253,11 +287,11 @@ bool BamMultiReader::LocateIndexes(const BamIndex::IndexType& preferredType) {
 /*! \fn bool BamMultiReader::Open(const std::vector<std::string>& filenames)
     \brief Opens BAM files.
 
 /*! \fn bool BamMultiReader::Open(const std::vector<std::string>& filenames)
     \brief Opens BAM files.
 
-    N.B. - Opening BAM files will invalidate any current region set on the multireader.
-           All file pointers will be returned to the beginning of the alignment data.
-           Follow this with Jump() or SetRegion() to establish a region of interest.
+    \note Opening BAM files will invalidate any current region set on the multireader.
+    All file pointers will be returned to the beginning of the alignment data. Follow
+    this with Jump() or SetRegion() to establish a region of interest.
 
 
-    \param filenames list of BAM filenames to open
+    \param[in] filenames list of BAM filenames to open
     \returns \c true if BAM files were opened successfully
     \sa Close(), HasOpenReaders(), OpenFile(), OpenIndexes(), BamReader::Open()
 */
     \returns \c true if BAM files were opened successfully
     \sa Close(), HasOpenReaders(), OpenFile(), OpenIndexes(), BamReader::Open()
 */
@@ -270,11 +304,11 @@ bool BamMultiReader::Open(const std::vector<std::string>& filenames) {
 
     Adds another BAM file to multireader "on-the-fly".
 
 
     Adds another BAM file to multireader "on-the-fly".
 
-    N.B. - Opening a BAM file invalidates any current region set on the multireader.
-           All file pointers will be returned to the beginning of the alignment data.
-           Follow this with Jump() or SetRegion() to establish a region of interest.
+    \note Opening a BAM file will invalidate any current region set on the multireader.
+    All file pointers will be returned to the beginning of the alignment data. Follow
+    this with Jump() or SetRegion() to establish a region of interest.
 
 
-    \param filename BAM filename to open
+    \param[in] filename BAM filename to open
     \returns \c true if BAM file was opened successfully
     \sa Close(), HasOpenReaders(), Open(), OpenIndexes(), BamReader::Open()
 */
     \returns \c true if BAM file was opened successfully
     \sa Close(), HasOpenReaders(), Open(), OpenIndexes(), BamReader::Open()
 */
@@ -285,10 +319,10 @@ bool BamMultiReader::OpenFile(const std::string& filename) {
 /*! \fn bool BamMultiReader::OpenIndexes(const std::vector<std::string>& indexFilenames)
     \brief Opens index files for current BAM files.
 
 /*! \fn bool BamMultiReader::OpenIndexes(const std::vector<std::string>& indexFilenames)
     \brief Opens index files for current BAM files.
 
-    N.B. - Currently assumes that index filenames match the order (and number) of
+    \note Currently assumes that index filenames match the order (and number) of
     BAM files passed to Open().
 
     BAM files passed to Open().
 
-    \param indexFilenames list of BAM index file names
+    \param[in] indexFilenames list of BAM index file names
     \returns \c true if BAM index file was opened & data loaded successfully
     \sa LocateIndex(), Open(), SetIndex(), BamReader::OpenIndex()
 */
     \returns \c true if BAM index file was opened & data loaded successfully
     \sa LocateIndex(), Open(), SetIndex(), BamReader::OpenIndex()
 */
@@ -309,17 +343,32 @@ bool BamMultiReader::Rewind(void) {
     return d->Rewind();
 }
 
     return d->Rewind();
 }
 
-/*! \fn void BamMultiReader::SetIndexCacheMode(const BamIndex::IndexCacheMode& mode)
-    \brief Changes the caching behavior of the index data.
-
-    Default mode is BamIndex::LimitedIndexCaching.
-
-    \param mode desired cache mode for index, see BamIndex::IndexCacheMode for
-                description of the available cache modes
-    \sa HasIndex(), BamReader::SetIndexCacheMode()
+/*! \fn void BamMultiReader::SetExplicitMergeOrder(BamMultiReader::MergeOrder order)
+    \brief Sets an explicit merge order, regardless of the BAM files' SO header tag.
+
+    The default behavior of the BamMultiReader is to check the SO tag in the BAM files'
+    SAM header text to determine the merge strategy". The merge strategy is used to
+    determine from which BAM file the next alignment should come when either
+    GetNextAlignment() or GetNextAlignmentCore() are called. If files share a
+    'coordinate' or 'queryname' value for this tag, then the merge strategy is
+    selected accordingly. If any of them do not match, or if any fileis marked as
+    'unsorted', then the merge strategy is simply a round-robin.
+
+    This method allows client code to explicitly override the lookup behavior. This
+    method can be useful when you know, for example, that your BAM files are sorted
+    by coordinate but upstream processes did not set the header tag properly.
+
+    \note This method should \bold not be called while reading alignments via
+    GetNextAlignment() or GetNextAlignmentCore(). For proper results, you should
+    call this method before (or immediately after) opening files, rewinding,
+    jumping, etc. but \bold not once alignment fetching has started. There is
+    nothing in the API to prevent you from doing so, but the results may be
+    unexpected.
+
+    \sa BamMultiReader::MergeOrder, GetMergeOrder(), GetNextAlignment(), GetNextAlignmentCore()
 */
 */
-void BamMultiReader::SetIndexCacheMode(const BamIndex::IndexCacheMode& mode) {
-    d->SetIndexCacheMode(mode);
+void BamMultiReader::SetExplicitMergeOrder(BamMultiReader::MergeOrder order) {
+    d->SetExplicitMergeOrder(order);
 }
 
 /*! \fn bool BamMultiReader::SetRegion(const BamRegion& region)
 }
 
 /*! \fn bool BamMultiReader::SetRegion(const BamRegion& region)
@@ -327,7 +376,11 @@ void BamMultiReader::SetIndexCacheMode(const BamIndex::IndexCacheMode& mode) {
 
     Equivalent to calling BamReader::SetRegion() on all open BAM files.
 
 
     Equivalent to calling BamReader::SetRegion() on all open BAM files.
 
-    \param region desired region-of-interest to activate
+    \warning BamRegion now represents a zero-based, HALF-OPEN interval.
+    In previous versions of BamTools (0.x & 1.x) all intervals were treated
+    as zero-based, CLOSED.
+
+    \param[in] region desired region-of-interest to activate
     \returns \c true if ALL readers set the region successfully
     \sa HasIndexes(), Jump(), BamReader::SetRegion()
 */
     \returns \c true if ALL readers set the region successfully
     \sa HasIndexes(), Jump(), BamReader::SetRegion()
 */
@@ -341,14 +394,16 @@ bool BamMultiReader::SetRegion(const BamRegion& region) {
                                        const int& rightPosition)
     \brief Sets a target region of interest
 
                                        const int& rightPosition)
     \brief Sets a target region of interest
 
-    This is an overloaded function.
+    This is an overloaded function. Equivalent to calling BamReader::SetRegion() on all open BAM files.
 
 
-    Equivalent to calling BamReader::SetRegion() on all open BAM files.
+    \warning This function now expects a zero-based, HALF-OPEN interval.
+    In previous versions of BamTools (0.x & 1.x) all intervals were treated
+    as zero-based, CLOSED.
 
 
-    \param leftRefID     referenceID of region's left boundary
-    \param leftPosition  position of region's left boundary
-    \param rightRefID    reference ID of region's right boundary
-    \param rightPosition position of region's right boundary
+    \param[in] leftRefID     referenceID of region's left boundary
+    \param[in] leftPosition  position of region's left boundary
+    \param[in] rightRefID    reference ID of region's right boundary
+    \param[in] rightPosition position of region's right boundary
 
     \returns \c true if ALL readers set the region successfully
     \sa HasIndexes(), Jump(), BamReader::SetRegion()
 
     \returns \c true if ALL readers set the region successfully
     \sa HasIndexes(), Jump(), BamReader::SetRegion()