]> git.donarmstrong.com Git - bamtools.git/blob - src/toolkit/bamtools_coverage.cpp
c3eaa20451e1d382faad52bb4b2497f6cba9dd8b
[bamtools.git] / src / toolkit / bamtools_coverage.cpp
1 // ***************************************************************************
2 // bamtools_coverage.cpp (c) 2010 Derek Barnett, Erik Garrison
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 7 April 2011
7 // ---------------------------------------------------------------------------
8 // Prints coverage data for a single BAM file 
9 // ***************************************************************************
10
11 #include "bamtools_coverage.h"
12
13 #include <api/BamReader.h>
14 #include <utils/bamtools_options.h>
15 #include <utils/bamtools_pileup_engine.h>
16 using namespace BamTools;
17
18 #include <iostream>
19 #include <fstream>
20 #include <string>
21 #include <vector>
22 using namespace std;
23   
24 namespace BamTools {
25  
26 // ---------------------------------------------  
27 // CoverageVisitor implementation 
28   
29 class CoverageVisitor : public PileupVisitor {
30   
31     public:
32         CoverageVisitor(const RefVector& references, ostream* out)
33             : PileupVisitor()
34             , m_references(references)
35             , m_out(out)
36         { }
37         ~CoverageVisitor(void) { }
38   
39     // PileupVisitor interface implementation
40     public:
41         // prints coverage results ( tab-delimited )
42         void Visit(const PileupPosition& pileupData) {
43             *m_out << m_references[pileupData.RefId].RefName << "\t" 
44                    << pileupData.Position << "\t" 
45                    << pileupData.PileupAlignments.size() << endl;
46         }
47         
48     private:
49         RefVector m_references;
50         ostream*  m_out;
51 };
52
53 } // namespace BamTools
54
55 // ---------------------------------------------  
56 // CoverageSettings implementation
57
58 struct CoverageTool::CoverageSettings {
59
60     // flags
61     bool HasInputFile;
62     bool HasOutputFile;
63
64     // filenames
65     string InputBamFilename;
66     string OutputFilename;
67     
68     // constructor
69     CoverageSettings(void)
70         : HasInputFile(false)
71         , HasOutputFile(false)
72         , InputBamFilename(Options::StandardIn())
73         , OutputFilename(Options::StandardOut())
74     { } 
75 };  
76
77 // ---------------------------------------------
78 // CoverageToolPrivate implementation
79
80 struct CoverageTool::CoverageToolPrivate {
81   
82     // ctor & dtor
83     public:
84         CoverageToolPrivate(CoverageTool::CoverageSettings* settings)
85             : m_settings(settings)
86             , m_out(cout.rdbuf())
87         { }
88
89         ~CoverageToolPrivate(void) { }
90     
91     // interface
92     public:
93         bool Run(void);
94         
95     // data members
96     private: 
97         CoverageTool::CoverageSettings* m_settings;
98         ostream m_out;
99         RefVector m_references;
100 };  
101
102 bool CoverageTool::CoverageToolPrivate::Run(void) {  
103   
104     // if output filename given
105     ofstream outFile;
106     if ( m_settings->HasOutputFile ) {
107       
108         // open output file stream
109         outFile.open(m_settings->OutputFilename.c_str());
110         if ( !outFile ) {
111             cerr << "bamtools coverage ERROR: could not open " << m_settings->OutputFilename
112                  << " for output" << endl;
113             return false; 
114         }
115         
116         // set m_out to file's streambuf
117         m_out.rdbuf(outFile.rdbuf()); 
118     } 
119     
120     //open our BAM reader
121     BamReader reader;
122     if ( !reader.Open(m_settings->InputBamFilename) ) {
123         cerr << "bamtools coverage ERROR: could not open input BAM file: " << m_settings->InputBamFilename << endl;
124         return false;
125     }
126
127     // retrieve references
128     m_references = reader.GetReferenceData();
129     
130     // set up our output 'visitor'
131     CoverageVisitor* cv = new CoverageVisitor(m_references, &m_out);
132     
133     // set up pileup engine with 'visitor'
134     PileupEngine pileup;
135     pileup.AddVisitor(cv);
136     
137     // process input data
138     BamAlignment al;    
139     while ( reader.GetNextAlignment(al) ) 
140         pileup.AddAlignment(al);
141     
142     // clean up 
143     reader.Close();
144     if ( m_settings->HasOutputFile )
145         outFile.close();
146     delete cv;
147     cv = 0;
148     
149     // return success
150     return true;
151 }
152
153 // ---------------------------------------------
154 // CoverageTool implementation
155
156 CoverageTool::CoverageTool(void) 
157     : AbstractTool()
158     , m_settings(new CoverageSettings)
159     , m_impl(0)
160
161     // set program details
162     Options::SetProgramInfo("bamtools coverage", "prints coverage data for a single BAM file", "[-in <filename>] [-out <filename>]");
163     
164     // set up options 
165     OptionGroup* IO_Opts = Options::CreateOptionGroup("Input & Output");
166     Options::AddValueOption("-in",  "BAM filename", "the input BAM file", "", m_settings->HasInputFile,  m_settings->InputBamFilename, IO_Opts, Options::StandardIn());
167     Options::AddValueOption("-out", "filename",     "the output file",    "", m_settings->HasOutputFile, m_settings->OutputFilename,   IO_Opts, Options::StandardOut());
168 }
169
170 CoverageTool::~CoverageTool(void) { 
171
172     delete m_settings;
173     m_settings = 0;
174     
175     delete m_impl;
176     m_impl = 0;
177 }
178
179 int CoverageTool::Help(void) { 
180     Options::DisplayHelp();
181     return 0;
182
183
184 int CoverageTool::Run(int argc, char* argv[]) { 
185
186     // parse command line arguments
187     Options::Parse(argc, argv, 1);
188     
189     // initialize CoverageTool with settings
190     m_impl = new CoverageToolPrivate(m_settings);
191     
192     // run CoverageTool, return success/fail
193     if ( m_impl->Run() ) 
194         return 0;
195     else 
196         return 1;
197 }