]> git.donarmstrong.com Git - bamtools.git/blob - bamtools_sam.cpp
Implemented Mosaik-style command line parser, instead of former GetOpt parser. Setup...
[bamtools.git] / bamtools_sam.cpp
1 // ***************************************************************************
2 // bamtools_sam.h (c) 2010 Derek Barnett, Erik Garrison
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 1 June 2010
7 // ---------------------------------------------------------------------------
8 // Prints a BAM file in the text-based SAM format.
9 // ***************************************************************************
10
11 #include <cstdlib>
12 #include <iostream>
13 #include <string>
14
15 #include "bamtools_sam.h"
16 #include "bamtools_options.h"
17 #include "BamReader.h"
18
19 using namespace std;
20 using namespace BamTools;
21
22 RefVector references;
23
24 // ---------------------------------------------
25 // print BamAlignment in SAM format
26
27 void PrintSAM(const BamAlignment& a) {
28   
29     // tab-delimited
30     // <QNAME> <FLAG> <RNAME> <POS> <MAPQ> <CIGAR> <MRNM> <MPOS> <ISIZE> <SEQ> <QUAL> [ <TAG>:<VTYPE>:<VALUE> [...] ]
31   
32     // ******************************* //
33     // ** NOT FULLY IMPLEMENTED YET ** //
34     //******************************** //
35     //
36     // Todo : build CIGAR string
37     //        build TAG string
38     //        there are some quirks, per the spec, regarding when to use '=' or not
39     //
40     // ******************************* //
41     
42     //
43     // do validity check on RefID / MateRefID ??
44     //
45   
46     // build CIGAR string
47     string cigarString("CIGAR:NOT YET");
48   
49     // build TAG string
50     string tagString("TAG:NOT YET");
51   
52     // print BamAlignment to stdout in SAM format
53     cout << a.Name << '\t' 
54          << a.AlignmentFlag << '\t'
55          << references[a.RefID].RefName << '\t'
56          << a.Position << '\t'
57          << a.MapQuality << '\t'
58          << cigarString << '\t'
59          << ( a.IsPaired() ? references[a.MateRefID].RefName : "*" ) << '\t'
60          << ( a.IsPaired() ? a.MatePosition : 0 ) << '\t'
61          << ( a.IsPaired() ? a.InsertSize : 0 ) << '\t'
62          << a.QueryBases << '\t'
63          << a.Qualities << '\t'
64          << tagString << endl;
65 }
66
67 // ---------------------------------------------
68 // SamSettings implementation
69
70 struct SamTool::SamSettings {
71
72     // flags
73     bool HasInputBamFilename;
74     bool HasMaximumOutput;
75     bool IsOmittingHeader;
76
77     // filenames
78     string InputBamFilename;
79     
80     // other parameters
81     int MaximumOutput;
82     
83     // constructor
84     SamSettings(void)
85         : HasInputBamFilename(false)
86         , HasMaximumOutput(false)
87         , IsOmittingHeader(false)
88         , InputBamFilename(Options::StandardIn())
89     { }
90 };  
91
92 // ---------------------------------------------
93 // SamTool implementation
94
95 SamTool::SamTool(void)
96     : AbstractTool()
97     , m_settings(new SamSettings)
98 {
99     // set program details
100     Options::SetProgramInfo("bamtools sam", "prints BAM file in SAM text format", "-in <filename>");
101     
102     // set up options 
103     OptionGroup* IO_Opts = Options::CreateOptionGroup("Input & Output");
104     Options::AddValueOption("-in", "BAM filename", "the input BAM file", "", m_settings->HasInputBamFilename, m_settings->InputBamFilename, IO_Opts, Options::StandardIn());
105     
106     OptionGroup* FilterOpts = Options::CreateOptionGroup("Filters");
107     Options::AddOption("-noheader", "omit the SAM header from output", m_settings->IsOmittingHeader, FilterOpts);
108     Options::AddValueOption("-num", "N", "maximum number of alignments to output", "", m_settings->HasMaximumOutput, m_settings->MaximumOutput, FilterOpts);
109 }
110
111 SamTool::~SamTool(void) {
112     delete m_settings;
113     m_settings = 0;
114 }
115
116 int SamTool::Help(void) {
117     Options::DisplayHelp();
118     return 0;
119 }
120
121 int SamTool::Run(int argc, char* argv[]) {
122   
123     // parse command line arguments
124     Options::Parse(argc, argv, 1);
125     
126     // open our BAM reader
127     BamReader reader;
128     reader.Open(m_settings->InputBamFilename);
129     
130     // if header desired, retrieve and print to stdout
131     if ( !m_settings->IsOmittingHeader ) {
132         string header = reader.GetHeaderText();
133         cout << header << endl;
134     }
135
136     // store reference data
137     references = reader.GetReferenceData();
138
139     // print all alignments to stdout in SAM format
140     if ( !m_settings->HasMaximumOutput ) {
141         BamAlignment ba;
142         while( reader.GetNextAlignment(ba) ) {
143             PrintSAM(ba);
144         }
145     }  
146     
147     // print first N alignments to stdout in SAM format
148     else {
149         BamAlignment ba;
150         int alignmentsPrinted = 0;
151         while ( reader.GetNextAlignment(ba) && (alignmentsPrinted < m_settings->MaximumOutput) ) {
152             PrintSAM(ba);
153             ++alignmentsPrinted;
154         }
155     }
156     
157     // clean & exit
158     reader.Close();
159     return 0;
160 }