]> git.donarmstrong.com Git - bamtools.git/blobdiff - src/toolkit/bamtools_random.cpp
Major update to BamTools version 1.0
[bamtools.git] / src / toolkit / bamtools_random.cpp
index fe8914f6768fddbcf2faf756ea73148826d8b6dc..bca98611b135a5f6be622ab56f6f90a7d10b1fd3 100644 (file)
@@ -3,23 +3,25 @@
 // Marth Lab, Department of Biology, Boston College
 // All rights reserved.
 // ---------------------------------------------------------------------------
-// Last modified: 3 September 2010 (DB)
+// Last modified: 21 March 2011 (DB)
 // ---------------------------------------------------------------------------
 // Grab a random subset of alignments.
 // ***************************************************************************
 
+#include "bamtools_random.h"
+
+#include <api/BamMultiReader.h>
+#include <api/BamWriter.h>
+#include <utils/bamtools_options.h>
+#include <utils/bamtools_utilities.h>
+using namespace BamTools;
+
 #include <ctime>
 #include <cstdlib>
 #include <iostream>
 #include <string>
 #include <vector>
-#include "bamtools_random.h"
-#include "bamtools_options.h"
-#include "bamtools_utilities.h"
-#include "BamMultiReader.h"
-#include "BamWriter.h"
 using namespace std;
-using namespace BamTools; 
   
 namespace BamTools {
   
@@ -27,7 +29,7 @@ namespace BamTools {
 const unsigned int RANDOM_MAX_ALIGNMENT_COUNT = 10000;
 
 // utility methods for RandomTool
-const int getRandomInt(const int& lowerBound, const int& upperBound) {
+int getRandomInt(const int& lowerBound, const int& upperBound) {
     const int range = (upperBound - lowerBound) + 1;
     return ( lowerBound + (int)(range * (double)rand()/((double)RAND_MAX + 1)) );
 }
@@ -79,10 +81,10 @@ RandomTool::RandomTool(void)
     Options::AddValueOption("-in",  "BAM filename", "the input BAM file",  "", m_settings->HasInput,  m_settings->InputFiles,     IO_Opts, Options::StandardIn());
     Options::AddValueOption("-out", "BAM filename", "the output BAM file", "", m_settings->HasOutput, m_settings->OutputFilename, IO_Opts, Options::StandardOut());
     Options::AddOption("-forceCompression", "if results are sent to stdout (like when piping to another tool), default behavior is to leave output uncompressed. Use this flag to override and force compression", m_settings->IsForceCompression, IO_Opts);
+    Options::AddValueOption("-region", "REGION", "only pull random alignments from within this genomic region. Index file is recommended for better performance, and is used automatically if it exists. See \'bamtools help index\' for more details on creating one", "", m_settings->HasRegion, m_settings->Region, IO_Opts);
     
-    OptionGroup* FilterOpts = Options::CreateOptionGroup("Filters");
-    Options::AddValueOption("-n", "count", "number of alignments to grab.  Note - no duplicate checking is performed", "", m_settings->HasAlignmentCount, m_settings->AlignmentCount, FilterOpts, RANDOM_MAX_ALIGNMENT_COUNT);
-    Options::AddValueOption("-region", "REGION", "limit source of random alignment subset to a particular genomic region. Index file is recommended for better performance, and is read automatically if it exists as <filename>.bai or <filename>.bti. See \'bamtools help index\' for more details on creating one", "", m_settings->HasRegion, m_settings->Region, FilterOpts);
+    OptionGroup* SettingsOpts = Options::CreateOptionGroup("Settings");
+    Options::AddValueOption("-n", "count", "number of alignments to grab. Note - no duplicate checking is performed", "", m_settings->HasAlignmentCount, m_settings->AlignmentCount, SettingsOpts, RANDOM_MAX_ALIGNMENT_COUNT);
 }
 
 RandomTool::~RandomTool(void) { 
@@ -107,33 +109,40 @@ int RandomTool::Run(int argc, char* argv[]) {
     // open our reader
     BamMultiReader reader;
     if ( !reader.Open(m_settings->InputFiles) ) {
-        cerr << "ERROR: Could not open input BAM file(s)." << endl;
+        cerr << "bamtools random ERROR: could not open input BAM file(s)... Aborting." << endl;
         return 1;
     }
      
+    // look up index files for all BAM files
+    reader.LocateIndexes();
+
     // make sure index data is available
-    if ( !reader.IsIndexLoaded() ) {
-        cerr << "ERROR: Could not load index data for all input BAM file(s)." << endl;
-        cerr << "\'bamtools random\' requires valid index files to provide efficient performance." << endl;
+    if ( !reader.HasIndexes() ) {
+        cerr << "bamtools random ERROR: could not load index data for all input BAM file(s)... Aborting." << endl;
         reader.Close();
         return 1;
-      
     }
      
     // get BamReader metadata  
     const string headerText = reader.GetHeaderText();
     const RefVector references = reader.GetReferenceData();
     if ( references.empty() ) {
-        cerr << "ERROR: No reference data available - required to perform random access throughtout input file(s)." << endl;
+        cerr << "bamtools random ERROR: no reference data available... Aborting." << endl;
         reader.Close();
         return 1;
     }
     
-    // open our writer
+    // determine compression mode for BamWriter
+    bool writeUncompressed = ( m_settings->OutputFilename == Options::StandardOut() &&
+                              !m_settings->IsForceCompression );
+    BamWriter::CompressionMode compressionMode = BamWriter::Compressed;
+    if ( writeUncompressed ) compressionMode = BamWriter::Uncompressed;
+
+    // open BamWriter
     BamWriter writer;
-    bool writeUncompressed = ( m_settings->OutputFilename == Options::StandardOut() && !m_settings->IsForceCompression );
-    if ( !writer.Open(m_settings->OutputFilename, headerText, references, writeUncompressed) ) {
-        cerr << "ERROR: Could not open BamWriter." << endl;
+    writer.SetCompressionMode(compressionMode);
+    if ( !writer.Open(m_settings->OutputFilename, headerText, references) ) {
+        cerr << "bamtools random ERROR: could not open " << m_settings->OutputFilename << " for writing... Aborting." << endl;
         reader.Close();
         return 1;
     }
@@ -141,8 +150,9 @@ int RandomTool::Run(int argc, char* argv[]) {
     // if user specified a REGION constraint, attempt to parse REGION string 
     BamRegion region; 
     if ( m_settings->HasRegion && !Utilities::ParseRegionString(m_settings->Region, reader, region) ) {
-        cerr << "ERROR: Could not parse REGION: " << m_settings->Region << endl;
-        cerr << "Be sure REGION is in valid format (see README) and that coordinates are valid for selected references" << endl;
+        cerr << "bamtools random ERROR: could not parse REGION: " << m_settings->Region << endl;
+        cerr << "Check that REGION is in valid format (see documentation) and that the coordinates are valid"
+             << endl;
         reader.Close();
         writer.Close();
         return 1;
@@ -199,4 +209,4 @@ int RandomTool::Run(int argc, char* argv[]) {
     reader.Close();
     writer.Close();
     return 0;
-}
\ No newline at end of file
+}