]> git.donarmstrong.com Git - bamtools.git/blob - src/toolkit/bamtools_revert.cpp
Major update to BamTools version 1.0
[bamtools.git] / src / toolkit / bamtools_revert.cpp
1 // ***************************************************************************
2 // bamtools_cpp (c) 2010 Derek Barnett, Alistair Ward
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 21 March 2011
7 // ---------------------------------------------------------------------------
8 // Prints general alignment statistics for BAM file(s).
9 // ***************************************************************************
10
11 #include "bamtools_revert.h"
12
13 #include <api/BamReader.h>
14 #include <api/BamWriter.h>
15 #include <utils/bamtools_options.h>
16 #include <utils/bamtools_utilities.h>
17 using namespace BamTools;
18
19 #include <iostream>
20 #include <string>
21 using namespace std;
22
23 // ---------------------------------------------
24 // RevertSettings implementation
25
26 struct RevertTool::RevertSettings {
27
28     // flags
29     bool HasInput;
30     bool HasOutput;
31     bool IsForceCompression;
32     bool IsKeepDuplicateFlag;
33     bool IsKeepQualities;
34
35     // filenames
36     string InputFilename;
37     string OutputFilename;
38     
39     // constructor
40     RevertSettings(void)
41         : HasInput(false)
42         , HasOutput(false)
43         , IsForceCompression(false)
44         , IsKeepDuplicateFlag(false)
45         , IsKeepQualities(false)
46         , InputFilename(Options::StandardIn())
47         , OutputFilename(Options::StandardOut())
48     { }
49 };  
50
51 // ---------------------------------------------
52 // RevertToolPrivate implementation
53
54 struct RevertTool::RevertToolPrivate {
55   
56     // ctor & dtor
57     public:
58         RevertToolPrivate(RevertTool::RevertSettings* settings);
59         ~RevertToolPrivate(void);
60   
61     // 'public' interface
62     public:
63         bool Run(void);
64         
65     // internal methods
66     private:
67         void RevertAlignment(BamAlignment& al);
68         
69     // data members
70     private:
71         RevertTool::RevertSettings* m_settings;
72         string m_OQ;
73 };
74
75 RevertTool::RevertToolPrivate::RevertToolPrivate(RevertTool::RevertSettings* settings)
76     : m_settings(settings)
77     , m_OQ("OQ")
78 { }
79
80 RevertTool::RevertToolPrivate::~RevertToolPrivate(void) { }
81
82 // reverts a BAM alignment
83 // default behavior (for now) is : replace Qualities with OQ, clear IsDuplicate flag
84 // can override default behavior using command line options
85 void RevertTool::RevertToolPrivate::RevertAlignment(BamAlignment& al) {
86
87     // replace Qualities with OQ, if requested
88     if ( !m_settings->IsKeepQualities ) {
89         string originalQualities;
90         if ( al.GetTag(m_OQ, originalQualities) ) {
91             al.Qualities = originalQualities;
92             al.RemoveTag(m_OQ);
93         }
94     }
95
96     // clear duplicate flag, if requested
97     if ( !m_settings->IsKeepDuplicateFlag )
98         al.SetIsDuplicate(false);
99 }
100
101 bool RevertTool::RevertToolPrivate::Run(void) {
102   
103     // opens the BAM file without checking for indexes
104     BamReader reader;
105     if ( !reader.Open(m_settings->InputFilename) ) {
106         cerr << "bamtools revert ERROR: could not open " << m_settings->InputFilename
107              << " for reading... Aborting." << endl;
108         return false;
109     }
110
111     // get BAM file metadata
112     const string& headerText = reader.GetHeaderText();
113     const RefVector& references = reader.GetReferenceData();
114     
115     // determine compression mode for BamWriter
116     bool writeUncompressed = ( m_settings->OutputFilename == Options::StandardOut() &&
117                               !m_settings->IsForceCompression );
118     BamWriter::CompressionMode compressionMode = BamWriter::Compressed;
119     if ( writeUncompressed ) compressionMode = BamWriter::Uncompressed;
120
121     // open BamWriter
122     BamWriter writer;
123     writer.SetCompressionMode(compressionMode);
124     if ( !writer.Open(m_settings->OutputFilename, headerText, references) ) {
125         cerr << "bamtools revert ERROR: could not open " << m_settings->OutputFilename
126              << " for writing... Aborting." << endl;
127         reader.Close();
128         return false;
129     }
130
131     // plow through file, reverting alignments
132     BamAlignment al;
133     while ( reader.GetNextAlignment(al) ) {
134         RevertAlignment(al);
135         writer.SaveAlignment(al);
136     }
137     
138     // clean and exit
139     reader.Close();
140     writer.Close();
141     return true; 
142 }
143
144 // ---------------------------------------------
145 // RevertTool implementation
146
147 RevertTool::RevertTool(void)
148     : AbstractTool()
149     , m_settings(new RevertSettings)
150     , m_impl(0)
151 {
152     // set program details
153     Options::SetProgramInfo("bamtools revert", "removes duplicate marks and restores original (non-recalibrated) base qualities", "[-in <filename> -in <filename> ...] [-out <filename> | [-forceCompression]] [revertOptions]");
154     
155     // set up options 
156     OptionGroup* IO_Opts = Options::CreateOptionGroup("Input & Output");
157     Options::AddValueOption("-in",  "BAM filename", "the input BAM file",  "", m_settings->HasInput,  m_settings->InputFilename,  IO_Opts, Options::StandardIn());
158     Options::AddValueOption("-out", "BAM filename", "the output BAM file", "", m_settings->HasOutput, m_settings->OutputFilename, IO_Opts, Options::StandardOut());
159     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);
160
161     OptionGroup* RevertOpts = Options::CreateOptionGroup("Revert Options");
162     Options::AddOption("-keepDuplicate", "keep duplicates marked", m_settings->IsKeepDuplicateFlag, RevertOpts);
163     Options::AddOption("-keepQualities", "keep base qualities (do not replace with OQ contents)", m_settings->IsKeepQualities, RevertOpts);
164 }
165
166 RevertTool::~RevertTool(void) {
167     delete m_settings;
168     m_settings = 0;
169     
170     delete m_impl;
171     m_impl = 0;
172 }
173
174 int RevertTool::Help(void) {
175     Options::DisplayHelp();
176     return 0;
177 }
178
179 int RevertTool::Run(int argc, char* argv[]) {
180   
181     // parse command line arguments
182     Options::Parse(argc, argv, 1);
183
184     // run internal RevertTool implementation, return success/fail
185     m_impl = new RevertToolPrivate(m_settings);
186     
187     if ( m_impl->Run() ) return 0;
188     else return 1;
189 }