// ***************************************************************************
// bamtools_split.cpp (c) 2010 Derek Barnett, Erik Garrison
// Marth Lab, Department of Biology, Boston College
-// All rights reserved.
// ---------------------------------------------------------------------------
-// Last modified: 19 September 2010 (DB)
+// Last modified: 8 December 2011 (DB)
// ---------------------------------------------------------------------------
-//
+// Splits a BAM file on user-specified property, creating a new BAM output
+// file for each value found
// ***************************************************************************
+#include "bamtools_split.h"
+
+#include <api/BamConstants.h>
+#include <api/BamReader.h>
+#include <api/BamWriter.h>
+#include <utils/bamtools_options.h>
+#include <utils/bamtools_variant.h>
+using namespace BamTools;
+
#include <ctime>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
-#include "bamtools_split.h"
-#include "bamtools_options.h"
-#include "bamtools_variant.h"
-#include "BamReader.h"
-#include "BamWriter.h"
using namespace std;
-using namespace BamTools;
namespace BamTools {
- // string constants
- static const string SPLIT_MAPPED_TOKEN = ".MAPPED";
- static const string SPLIT_UNMAPPED_TOKEN = ".UNMAPPED";
- static const string SPLIT_PAIRED_TOKEN = ".PAIRED_END";
- static const string SPLIT_SINGLE_TOKEN = ".SINGLE_END";
- static const string SPLIT_REFERENCE_TOKEN = ".REF_";
-
- string GetTimestampString(void) {
-
- // get human readable timestamp
- time_t currentTime;
- time(¤tTime);
- stringstream timeStream("");
- timeStream << ctime(¤tTime);
-
- // convert whitespace to '_'
- string timeString = timeStream.str();
- size_t found = timeString.find(" ");
- while (found != string::npos) {
- timeString.replace(found, 1, "_");
- found = timeString.find(" ", found+1);
- }
- return timeString;
- }
-
- // remove copy of filename without extension
- // (so /path/to/file.txt becomes /path/to/file )
- string RemoveFilenameExtension(const string& filename) {
- size_t found = filename.rfind(".");
- return filename.substr(0, found);
+// string constants
+static const string SPLIT_MAPPED_TOKEN = ".MAPPED";
+static const string SPLIT_UNMAPPED_TOKEN = ".UNMAPPED";
+static const string SPLIT_PAIRED_TOKEN = ".PAIRED_END";
+static const string SPLIT_SINGLE_TOKEN = ".SINGLE_END";
+static const string SPLIT_REFERENCE_TOKEN = ".REF_";
+
+string GetTimestampString(void) {
+
+ // get human readable timestamp
+ time_t currentTime;
+ time(¤tTime);
+ stringstream timeStream("");
+ timeStream << ctime(¤tTime);
+
+ // convert whitespace to '_'
+ string timeString = timeStream.str();
+ size_t found = timeString.find(" ");
+ while (found != string::npos) {
+ timeString.replace(found, 1, "_");
+ found = timeString.find(" ", found+1);
}
+ return timeString;
+}
+
+// remove copy of filename without extension
+// (so /path/to/file.txt becomes /path/to/file )
+string RemoveFilenameExtension(const string& filename) {
+ size_t found = filename.rfind(".");
+ return filename.substr(0, found);
+}
} // namespace BamTools
// flags
bool HasInputFilename;
bool HasCustomOutputStub;
+ bool HasCustomRefPrefix;
bool IsSplittingMapped;
bool IsSplittingPaired;
bool IsSplittingReference;
// string args
string CustomOutputStub;
+ string CustomRefPrefix;
string InputFilename;
string TagToSplit;
SplitSettings(void)
: HasInputFilename(false)
, HasCustomOutputStub(false)
+ , HasCustomRefPrefix(false)
, IsSplittingMapped(false)
, IsSplittingPaired(false)
, IsSplittingReference(false)
, IsSplittingTag(false)
, CustomOutputStub("")
+ , CustomRefPrefix("")
, InputFilename(Options::StandardIn())
, TagToSplit("")
{ }
// ctor & dtor
public:
- SplitToolPrivate(SplitTool::SplitSettings* settings);
- ~SplitToolPrivate(void);
+ SplitToolPrivate(SplitTool::SplitSettings* settings)
+ : m_settings(settings)
+ { }
+
+ ~SplitToolPrivate(void) {
+ m_reader.Close();
+ }
// 'public' interface
public:
// internal methods
private:
+ // close & delete BamWriters in map
+ template<typename T>
+ void CloseWriters(map<T, BamWriter*>& writers);
+ // calculate output stub based on IO args given
void DetermineOutputFilenameStub(void);
+ // open our BamReader
bool OpenReader(void);
+ // split alignments in BAM file based on isMapped property
bool SplitMapped(void);
+ // split alignments in BAM file based on isPaired property
bool SplitPaired(void);
+ // split alignments in BAM file based on refID property
bool SplitReference(void);
+ // finds first alignment and calls corresponding SplitTagImpl<>
+ // depending on tag type
bool SplitTag(void);
- bool SplitTag_Int(BamAlignment& al);
- bool SplitTag_UInt(BamAlignment& al);
- bool SplitTag_Real(BamAlignment& al);
- bool SplitTag_String(BamAlignment& al);
+ // templated split tag implementation
+ // handle the various types that are possible for tags
+ template<typename T>
+ bool SplitTagImpl(BamAlignment& al);
// data members
private:
RefVector m_references;
};
-// constructor
-SplitTool::SplitToolPrivate::SplitToolPrivate(SplitTool::SplitSettings* settings)
- : m_settings(settings)
-{ }
-
-// destructor
-SplitTool::SplitToolPrivate::~SplitToolPrivate(void) {
- m_reader.Close();
-}
-
void SplitTool::SplitToolPrivate::DetermineOutputFilenameStub(void) {
// if user supplied output filename stub, use that
}
bool SplitTool::SplitToolPrivate::OpenReader(void) {
+
+ // attempt to open BAM file
if ( !m_reader.Open(m_settings->InputFilename) ) {
- cerr << "ERROR: SplitTool could not open BAM file: " << m_settings->InputFilename << endl;
+ cerr << "bamtools split ERROR: could not open BAM file: " << m_settings->InputFilename << endl;
return false;
}
+
+ // save file 'metadata' & return success
m_header = m_reader.GetHeaderText();
m_references = m_reader.GetReferenceData();
return true;
DetermineOutputFilenameStub();
// open up BamReader
- if ( !OpenReader() ) return false;
+ if ( !OpenReader() )
+ return false;
// determine split type from settings
if ( m_settings->IsSplittingMapped ) return SplitMapped();
if ( m_settings->IsSplittingTag ) return SplitTag();
// if we get here, no property was specified
- cerr << "No property given to split on... Please use -mapped, -paired, -reference, or -tag TAG to specifiy split behavior." << endl;
+ cerr << "bamtools split ERROR: no property given to split on... " << endl
+ << "Please use -mapped, -paired, -reference, or -tag TAG to specifiy desired split behavior." << endl;
return false;
}
if ( writerIter == outputFiles.end() ) {
// open new BamWriter
+ const string outputFilename = m_outputFilenameStub + ( isCurrentAlignmentMapped
+ ? SPLIT_MAPPED_TOKEN
+ : SPLIT_UNMAPPED_TOKEN ) + ".bam";
writer = new BamWriter;
- const string outputFilename = m_outputFilenameStub + ( isCurrentAlignmentMapped ? SPLIT_MAPPED_TOKEN : SPLIT_UNMAPPED_TOKEN ) + ".bam";
- writer->Open(outputFilename, m_header, m_references);
+ if ( !writer->Open(outputFilename, m_header, m_references) ) {
+ cerr << "bamtools split ERROR: could not open " << outputFilename
+ << " for writing." << endl;
+ return false;
+ }
// store in map
outputFiles.insert( make_pair(isCurrentAlignmentMapped, writer) );
else writer = (*writerIter).second;
// store alignment in proper BAM output file
- if ( writer )
+ if ( writer )
writer->SaveAlignment(al);
}
// clean up BamWriters
- map<bool, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin() ; writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if ( writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
+ CloseWriters(outputFiles);
// return success
return true;
if ( writerIter == outputFiles.end() ) {
// open new BamWriter
+ const string outputFilename = m_outputFilenameStub + ( isCurrentAlignmentPaired
+ ? SPLIT_PAIRED_TOKEN
+ : SPLIT_SINGLE_TOKEN ) + ".bam";
writer = new BamWriter;
- const string outputFilename = m_outputFilenameStub + ( isCurrentAlignmentPaired ? SPLIT_PAIRED_TOKEN : SPLIT_SINGLE_TOKEN ) + ".bam";
- writer->Open(outputFilename, m_header, m_references);
+ if ( !writer->Open(outputFilename, m_header, m_references) ) {
+ cerr << "bamtool split ERROR: could not open " << outputFilename
+ << " for writing." << endl;
+ return false;
+ }
// store in map
outputFiles.insert( make_pair(isCurrentAlignmentPaired, writer) );
}
// clean up BamWriters
- map<bool, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin() ; writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
+ CloseWriters(outputFiles);
// return success
return true;
map<int32_t, BamWriter*> outputFiles;
map<int32_t, BamWriter*>::iterator writerIter;
+ // determine reference prefix
+ string refPrefix = SPLIT_REFERENCE_TOKEN;
+ if ( m_settings->HasCustomRefPrefix )
+ refPrefix = m_settings->CustomRefPrefix;
+
+ // make sure prefix starts with '.'
+ const size_t dotFound = refPrefix.find('.');
+ if ( dotFound != 0 )
+ refPrefix = string(".") + refPrefix;
+
// iterate through alignments
BamAlignment al;
BamWriter* writer;
// if no writer associated with this value
if ( writerIter == outputFiles.end() ) {
+ // fetch reference name for ID
+ string refName;
+ if ( currentRefId == -1 )
+ refName = "unmapped";
+ else
+ refName = m_references.at(currentRefId).RefName;
+
+ // construct new output filename
+ const string outputFilename = m_outputFilenameStub + refPrefix + refName + ".bam";
+
// open new BamWriter
writer = new BamWriter;
- const string refName = m_references.at(currentRefId).RefName;
- const string outputFilename = m_outputFilenameStub + SPLIT_REFERENCE_TOKEN + refName + ".bam";
- writer->Open(outputFilename, m_header, m_references);
-
+ if ( !writer->Open(outputFilename, m_header, m_references) ) {
+ cerr << "bamtools split ERROR: could not open " << outputFilename
+ << " for writing." << endl;
+ return false;
+ }
+
// store in map
outputFiles.insert( make_pair(currentRefId, writer) );
}
}
// clean up BamWriters
- map<int32_t, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin(); writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
+ CloseWriters(outputFiles);
// return success
return true;
}
+// finds first alignment and calls corresponding SplitTagImpl<>() depending on tag type
bool SplitTool::SplitToolPrivate::SplitTag(void) {
// iterate through alignments, until we hit TAG
// look for tag in this alignment and get tag type
char tagType(0);
- if ( !al.GetTagType(m_settings->TagToSplit, tagType) ) continue;
+ if ( !al.GetTagType(m_settings->TagToSplit, tagType) )
+ continue;
// request split method based on tag type
// pass it the current alignment found
- switch (tagType) {
+ switch ( tagType ) {
- case 'c' :
- case 's' :
- case 'i' :
- return SplitTag_Int(al);
+ case (Constants::BAM_TAG_TYPE_INT8) :
+ case (Constants::BAM_TAG_TYPE_INT16) :
+ case (Constants::BAM_TAG_TYPE_INT32) :
+ return SplitTagImpl<int32_t>(al);
- case 'C' :
- case 'S' :
- case 'I' :
- return SplitTag_UInt(al);
+ case (Constants::BAM_TAG_TYPE_UINT8) :
+ case (Constants::BAM_TAG_TYPE_UINT16) :
+ case (Constants::BAM_TAG_TYPE_UINT32) :
+ return SplitTagImpl<uint32_t>(al);
- case 'f' :
- return SplitTag_Real(al);
+ case (Constants::BAM_TAG_TYPE_FLOAT) :
+ return SplitTagImpl<float>(al);
- case 'A':
- case 'Z':
- case 'H':
- return SplitTag_String(al);
+ case (Constants::BAM_TAG_TYPE_ASCII) :
+ case (Constants::BAM_TAG_TYPE_STRING) :
+ case (Constants::BAM_TAG_TYPE_HEX) :
+ return SplitTagImpl<string>(al);
+
+ case (Constants::BAM_TAG_TYPE_ARRAY) :
+ cerr << "bamtools split ERROR: array tag types are not supported" << endl;
+ return false;
default:
- fprintf(stderr, "ERROR: Unknown tag storage class encountered: [%c]\n", tagType);
+ cerr << "bamtools split ERROR: unknown tag type encountered: " << tagType << endl;
return false;
}
}
return true;
}
-bool SplitTool::SplitToolPrivate::SplitTag_Int(BamAlignment& al) {
-
- // set up splitting data structure
- map<int32_t, BamWriter*> outputFiles;
- map<int32_t, BamWriter*>::iterator writerIter;
+// --------------------------------------------------------------------------------
+// template method implementation
+// *Technical Note* - use of template methods declared & defined in ".cpp" file
+// goes against normal practices, but works here because these
+// are purely internal (no one can call from outside this file)
- // local variables
- const string tag = m_settings->TagToSplit;
- BamWriter* writer;
- stringstream outputFilenameStream("");
- int32_t currentValue;
-
- // retrieve first alignment tag value
- if ( al.GetTag(tag, currentValue) ) {
-
- // open new BamWriter, save first alignment
- writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
- writer->SaveAlignment(al);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- }
-
- // iterate through remaining alignments
- while ( m_reader.GetNextAlignment(al) ) {
-
- // skip if this alignment doesn't have TAG
- if ( !al.GetTag(tag, currentValue) ) continue;
-
- // look up tag value in map
- writerIter = outputFiles.find(currentValue);
-
- // if no writer associated with this value
- if ( writerIter == outputFiles.end() ) {
-
- // open new BamWriter
- writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- }
-
- // else grab corresponding writer
- else writer = (*writerIter).second;
-
- // store alignment in proper BAM output file
- if ( writer )
- writer->SaveAlignment(al);
- }
-
- // clean up BamWriters
- map<int32_t, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin(); writerIter != writerEnd; ++writerIter ) {
+// close BamWriters & delete pointers
+template<typename T>
+void SplitTool::SplitToolPrivate::CloseWriters(map<T, BamWriter*>& writers) {
+
+ typedef map<T, BamWriter*> WriterMap;
+ typedef typename WriterMap::iterator WriterMapIterator;
+
+ // iterate over writers
+ WriterMapIterator writerIter = writers.begin();
+ WriterMapIterator writerEnd = writers.end();
+ for ( ; writerIter != writerEnd; ++writerIter ) {
BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
+ if ( writer == 0 ) continue;
+
+ // close BamWriter
writer->Close();
+
+ // destroy BamWriter
delete writer;
writer = 0;
}
-
- // return success
- return true;
+
+ // clear the container (destroying the items doesn't remove them)
+ writers.clear();
}
-bool SplitTool::SplitToolPrivate::SplitTag_UInt(BamAlignment& al) {
+// handle the various types that are possible for tags
+template<typename T>
+bool SplitTool::SplitToolPrivate::SplitTagImpl(BamAlignment& al) {
+
+ typedef T TagValueType;
+ typedef map<TagValueType, BamWriter*> WriterMap;
+ typedef typename WriterMap::iterator WriterMapIterator;
// set up splitting data structure
- map<uint32_t, BamWriter*> outputFiles;
- map<uint32_t, BamWriter*>::iterator writerIter;
+ WriterMap outputFiles;
+ WriterMapIterator writerIter;
// local variables
const string tag = m_settings->TagToSplit;
BamWriter* writer;
stringstream outputFilenameStream("");
- uint32_t currentValue;
-
- int alignmentsIgnored = 0;
+ TagValueType currentValue;
// retrieve first alignment tag value
if ( al.GetTag(tag, currentValue) ) {
// open new BamWriter, save first alignment
- writer = new BamWriter;
outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
- writer->SaveAlignment(al);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- } else ++alignmentsIgnored;
-
- // iterate through remaining alignments
- while ( m_reader.GetNextAlignment(al) ) {
-
- // skip if this alignment doesn't have TAG
- if ( !al.GetTag(tag, currentValue) ) { ++alignmentsIgnored; continue; }
-
- // look up tag value in map
- writerIter = outputFiles.find(currentValue);
-
- // if no writer associated with this value
- if ( writerIter == outputFiles.end() ) {
-
- // open new BamWriter
- writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- }
-
- // else grab corresponding writer
- else writer = (*writerIter).second;
-
- // store alignment in proper BAM output file
- if ( writer )
- writer->SaveAlignment(al);
- }
-
- // clean up BamWriters
- map<uint32_t, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin(); writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
-
- // return success
- return true;
-}
-
-bool SplitTool::SplitToolPrivate::SplitTag_Real(BamAlignment& al) {
-
- // set up splitting data structure
- map<float, BamWriter*> outputFiles;
- map<float, BamWriter*>::iterator writerIter;
-
- // local variables
- const string tag = m_settings->TagToSplit;
- BamWriter* writer;
- stringstream outputFilenameStream("");
- float currentValue;
-
- // retrieve first alignment tag value
- if ( al.GetTag(tag, currentValue) ) {
-
- // open new BamWriter, save first alignment
writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
+ if ( !writer->Open(outputFilenameStream.str(), m_header, m_references) ) {
+ cerr << "bamtools split ERROR: could not open " << outputFilenameStream.str()
+ << " for writing." << endl;
+ return false;
+ }
writer->SaveAlignment(al);
// store in map
if ( writerIter == outputFiles.end() ) {
// open new BamWriter
- writer = new BamWriter;
outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- }
-
- // else grab corresponding writer
- else writer = (*writerIter).second;
-
- // store alignment in proper BAM output file
- if ( writer )
- writer->SaveAlignment(al);
- }
-
- // clean up BamWriters
- map<float, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin(); writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
-
- // return success
- return true;
-}
-
-bool SplitTool::SplitToolPrivate::SplitTag_String(BamAlignment& al) {
-
- // set up splitting data structure
- map<string, BamWriter*> outputFiles;
- map<string, BamWriter*>::iterator writerIter;
-
- // local variables
- const string tag = m_settings->TagToSplit;
- BamWriter* writer;
- stringstream outputFilenameStream("");
- string currentValue;
-
- // retrieve first alignment tag value
- if ( al.GetTag(tag, currentValue) ) {
-
- // open new BamWriter, save first alignment
- writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
- writer->SaveAlignment(al);
-
- // store in map
- outputFiles.insert( make_pair(currentValue, writer) );
-
- // reset stream
- outputFilenameStream.str("");
- }
-
- // iterate through remaining alignments
- while ( m_reader.GetNextAlignment(al) ) {
-
- // skip if this alignment doesn't have TAG
- if ( !al.GetTag(tag, currentValue) ) continue;
-
- // look up tag value in map
- writerIter = outputFiles.find(currentValue);
-
- // if no writer associated with this value
- if ( writerIter == outputFiles.end() ) {
-
- // open new BamWriter
writer = new BamWriter;
- outputFilenameStream << m_outputFilenameStub << ".TAG_" << tag << "_" << currentValue << ".bam";
- writer->Open(outputFilenameStream.str(), m_header, m_references);
-
+ if ( !writer->Open(outputFilenameStream.str(), m_header, m_references) ) {
+ cerr << "bamtool split ERROR: could not open " << outputFilenameStream.str()
+ << " for writing." << endl;
+ return false;
+ }
+
// store in map
outputFiles.insert( make_pair(currentValue, writer) );
writer->SaveAlignment(al);
}
- // clean up BamWriters
- map<string, BamWriter*>::iterator writerEnd = outputFiles.end();
- for ( writerIter = outputFiles.begin(); writerIter != writerEnd; ++writerIter ) {
- BamWriter* writer = (*writerIter).second;
- if (writer == 0 ) continue;
- writer->Close();
- delete writer;
- writer = 0;
- }
+ // clean up BamWriters
+ CloseWriters(outputFiles);
// return success
- return true;
+ return true;
}
// ---------------------------------------------
, m_impl(0)
{
// set program details
- Options::SetProgramInfo("bamtools split", "splits a BAM file on user-specified property, creating a new BAM output file for each value found", "[-in <filename>] [-stub <filename>] < -mapped | -paired | -reference | -tag <TAG> > ");
+ const string name = "bamtools split";
+ const string description = "splits a BAM file on user-specified property, creating a new BAM output file for each value found";
+ const string args = "[-in <filename>] [-stub <filename stub>] < -mapped | -paired | -reference [-refPrefix <prefix>] | -tag <TAG> > ";
+ Options::SetProgramInfo(name, description, args);
// set up options
OptionGroup* IO_Opts = Options::CreateOptionGroup("Input & Output");
- Options::AddValueOption("-in", "BAM filename", "the input BAM file", "", m_settings->HasInputFilename, m_settings->InputFilename, IO_Opts, Options::StandardIn());
- Options::AddValueOption("-stub", "filename stub", "prefix stub for output BAM files (default behavior is to use input filename, without .bam extension, as stub). If input is stdin and no stub provided, a timestamp is generated as the stub.", "", m_settings->HasCustomOutputStub, m_settings->CustomOutputStub, IO_Opts);
+ Options::AddValueOption("-in", "BAM filename", "the input BAM file", "", m_settings->HasInputFilename, m_settings->InputFilename, IO_Opts, Options::StandardIn());
+ Options::AddValueOption("-refPrefix", "string", "custom prefix for splitting by references. Currently files end with REF_<refName>.bam. This option allows you to replace \"REF_\" with a prefix of your choosing.", "",
+ m_settings->HasCustomRefPrefix, m_settings->CustomRefPrefix, IO_Opts);
+ Options::AddValueOption("-stub", "filename stub", "prefix stub for output BAM files (default behavior is to use input filename, without .bam extension, as stub). If input is stdin and no stub provided, a timestamp is generated as the stub.", "",
+ m_settings->HasCustomOutputStub, m_settings->CustomOutputStub, IO_Opts);
OptionGroup* SplitOpts = Options::CreateOptionGroup("Split Options");
Options::AddOption("-mapped", "split mapped/unmapped alignments", m_settings->IsSplittingMapped, SplitOpts);
// parse command line arguments
Options::Parse(argc, argv, 1);
- // initialize internal implementation
+ // initialize SplitTool with settings
m_impl = new SplitToolPrivate(m_settings);
- // run tool, return success/fail
+ // run SplitTool, return success/fail
if ( m_impl->Run() )
return 0;
else