1 // ***************************************************************************
2 // bamtools_revert.cpp (c) 2010 Derek Barnett, Alistair Ward
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 7 April 2011
6 // ---------------------------------------------------------------------------
7 // Removes duplicate marks and restores original base qualities
8 // ***************************************************************************
10 #include "bamtools_revert.h"
12 #include <api/BamReader.h>
13 #include <api/BamWriter.h>
14 #include <utils/bamtools_options.h>
15 #include <utils/bamtools_utilities.h>
16 using namespace BamTools;
24 static const string OQ_TAG = "OQ";
26 } // namespace BamTools;
28 // ---------------------------------------------
29 // RevertSettings implementation
31 struct RevertTool::RevertSettings {
36 bool IsForceCompression;
37 bool IsKeepDuplicateFlag;
42 string OutputFilename;
48 , IsForceCompression(false)
49 , IsKeepDuplicateFlag(false)
50 , IsKeepQualities(false)
51 , InputFilename(Options::StandardIn())
52 , OutputFilename(Options::StandardOut())
56 // ---------------------------------------------
57 // RevertToolPrivate implementation
59 struct RevertTool::RevertToolPrivate {
63 RevertToolPrivate(RevertTool::RevertSettings* settings)
64 : m_settings(settings)
66 ~RevertToolPrivate(void) { }
74 void RevertAlignment(BamAlignment& al);
78 RevertTool::RevertSettings* m_settings;
81 // 'reverts' a BAM alignment
82 // default behavior (for now) is:
83 // 1 - replace Qualities with OQ contents
84 // 2 - clear IsDuplicate flag
85 // can override default behavior using command line options
86 void RevertTool::RevertToolPrivate::RevertAlignment(BamAlignment& al) {
88 // replace Qualities with OQ contents, if requested
89 if ( !m_settings->IsKeepQualities ) {
90 string originalQualities;
91 if ( al.GetTag(OQ_TAG, originalQualities) ) {
92 al.Qualities = originalQualities;
97 // clear duplicate flag, if requested
98 if ( !m_settings->IsKeepDuplicateFlag )
99 al.SetIsDuplicate(false);
102 bool RevertTool::RevertToolPrivate::Run(void) {
104 // opens the BAM file without checking for indexes
106 if ( !reader.Open(m_settings->InputFilename) ) {
107 cerr << "bamtools revert ERROR: could not open " << m_settings->InputFilename
108 << " for reading... Aborting." << endl;
112 // get BAM file metadata
113 const string& headerText = reader.GetHeaderText();
114 const RefVector& references = reader.GetReferenceData();
116 // determine compression mode for BamWriter
117 bool writeUncompressed = ( m_settings->OutputFilename == Options::StandardOut() &&
118 !m_settings->IsForceCompression );
119 BamWriter::CompressionMode compressionMode = BamWriter::Compressed;
120 if ( writeUncompressed ) compressionMode = BamWriter::Uncompressed;
124 writer.SetCompressionMode(compressionMode);
125 if ( !writer.Open(m_settings->OutputFilename, headerText, references) ) {
126 cerr << "bamtools revert ERROR: could not open " << m_settings->OutputFilename
127 << " for writing... Aborting." << endl;
132 // plow through file, reverting alignments
134 while ( reader.GetNextAlignment(al) ) {
136 writer.SaveAlignment(al);
145 // ---------------------------------------------
146 // RevertTool implementation
148 RevertTool::RevertTool(void)
150 , m_settings(new RevertSettings)
153 // set program details
154 Options::SetProgramInfo("bamtools revert", "removes duplicate marks and restores original (non-recalibrated) base qualities", "[-in <filename> -in <filename> ...] [-out <filename> | [-forceCompression]] [revertOptions]");
157 OptionGroup* IO_Opts = Options::CreateOptionGroup("Input & Output");
158 Options::AddValueOption("-in", "BAM filename", "the input BAM file", "", m_settings->HasInput, m_settings->InputFilename, IO_Opts, Options::StandardIn());
159 Options::AddValueOption("-out", "BAM filename", "the output BAM file", "", m_settings->HasOutput, m_settings->OutputFilename, IO_Opts, Options::StandardOut());
160 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);
162 OptionGroup* RevertOpts = Options::CreateOptionGroup("Revert Options");
163 Options::AddOption("-keepDuplicate", "keep duplicates marked", m_settings->IsKeepDuplicateFlag, RevertOpts);
164 Options::AddOption("-keepQualities", "keep base qualities (do not replace with OQ contents)", m_settings->IsKeepQualities, RevertOpts);
167 RevertTool::~RevertTool(void) {
176 int RevertTool::Help(void) {
177 Options::DisplayHelp();
181 int RevertTool::Run(int argc, char* argv[]) {
183 // parse command line arguments
184 Options::Parse(argc, argv, 1);
186 // intialize RevertTool with settings
187 m_impl = new RevertToolPrivate(m_settings);
189 // run RevertTool, return success/fail