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