]> git.donarmstrong.com Git - bamtools.git/blob - bamtools_sam.h
Mostly cleaned up help & usage messages. Added MIT license.
[bamtools.git] / bamtools_sam.h
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: 26 May 2010
7 // ---------------------------------------------------------------------------
8 // Prints a BAM file in the text-based SAM format.
9 // ***************************************************************************
10
11 #ifndef BAMTOOLS_SAM_H
12 #define BAMTOOLS_SAM_H
13
14 #include <cstdlib>
15 #include <iostream>
16 #include <string>
17
18 #include "BamReader.h"
19 #include "bamtools_getopt.h"
20
21 namespace BamTools {
22
23 int BamSamHelp(void) { 
24   
25     // '--head' makes more sense than '--num' from a Unix perspective, but could be confusing with header info ?? 
26     // but this is also only the default case (from the beginning of the file)
27     // do we want to add a region specifier, eg 'chr2:1000..1500'? In this case, '--num' still makes sense (give me up to N alignments from this region)
28   
29     std::cerr << std::endl;
30     std::cerr << "usage:\tbamtools sam [--in FILE] [--num N] [--no_header]" << std::endl;
31     std::cerr << std::endl;
32     std::cerr << "\t--in FILE    Input BAM file to generate SAM-format                       [stdin]" << std::endl;
33     std::cerr << "\t--num N      Only print up to N alignments from beginning of file        [50*]" << endl;  
34     std::cerr << "\t--no_header  Omits SAM header information from output (alignments only)  [off]" << std::endl;
35     std::cerr << std::endl;
36     std::cerr << "\t* - By default bamtools sam will print all alignments in SAM format." << std::endl;
37     std::cerr << "\t    However if '--num' is included with no N, the default of 50 is used." << std::endl;
38     std::cerr << std::endl;
39     return 0;
40 }
41
42 static RefVector references;
43
44 void PrintSAM(const BamAlignment& a) {
45   
46     // tab-delimited
47     // <QNAME> <FLAG> <RNAME> <POS> <MAPQ> <CIGAR> <MRNM> <MPOS> <ISIZE> <SEQ> <QUAL> [ <TAG>:<VTYPE>:<VALUE> [...] ]
48   
49     // ******************************* //
50     // ** NOT FULLY IMPLEMENTED YET ** //
51     //******************************** //
52     //
53     // Todo : build CIGAR string
54     //        build TAG string
55     //        there are some quirks, per the spec, regarding when to use '=' or not
56     //
57     // ******************************* //
58     
59     //
60     // do validity check on RefID / MateRefID ??
61     //
62   
63     // build CIGAR string
64     std::string cigarString("CIGAR:NOT YET");
65   
66     // build TAG string
67     std::string tagString("TAG:NOT YET");
68   
69     // print BamAlignment to stdout in SAM format
70     std::cout << a.Name << '\t' 
71               << a.AlignmentFlag << '\t'
72               << references[a.RefID].RefName << '\t'
73               << a.Position << '\t'
74               << a.MapQuality << '\t'
75               << cigarString << '\t'
76               << ( a.IsPaired() ? references[a.MateRefID].RefName : "*" ) << '\t'
77               << ( a.IsPaired() ? a.MatePosition : 0 ) << '\t'
78               << ( a.IsPaired() ? a.InsertSize : 0 ) << '\t'
79               << a.QueryBases << '\t'
80               << a.Qualities << '\t'
81               << tagString << std::endl;
82 }
83
84 int RunBamSam(int argc, char* argv[]) {
85   
86     // else parse command line for args  
87     GetOpt options(argc, argv, 1);
88     
89     std::string inputFilename;
90     options.addOption("in", &inputFilename);
91     
92     std::string numberString;
93     options.addOptionalOption("num", &numberString, "50");
94     
95     bool isOmittingHeader;
96     options.addSwitch("no_header", &isOmittingHeader);
97     
98     if ( !options.parse() ) return BamCoverageHelp();
99     if ( inputFilename.empty() ) { inputFilename = "stdin"; }
100     
101     // maxNumberOfAlignments = all (if nothing specified)
102     //                       = 50  (if '--num' but no N)
103     //                       = N   (if '--num N') 
104     int maxNumberOfAlignments = -1;
105     if ( !numberString.empty() ) { maxNumberOfAlignments = atoi(numberString.c_str()); }
106      
107     // open our BAM reader
108     BamReader reader;
109     reader.Open(inputFilename);
110     
111     // if header desired, retrieve and print to stdout
112     if ( !isOmittingHeader ) {
113         std::string header = reader.GetHeaderText();
114         std::cout << header << std::endl;
115     }
116
117     // store reference data
118     references = reader.GetReferenceData();
119
120     // print all alignments to stdout in SAM format
121     if ( maxNumberOfAlignments < 0 ) {
122         BamAlignment ba;
123         while( reader.GetNextAlignment(ba) ) {
124             PrintSAM(ba);
125         }
126     }  
127     
128     // print first N alignments to stdout in SAM format
129     else {
130         BamAlignment ba;
131         int alignmentsPrinted = 0;
132         while ( reader.GetNextAlignment(ba) && (alignmentsPrinted < maxNumberOfAlignments) ) {
133             PrintSAM(ba);
134             ++alignmentsPrinted;
135         }
136     }
137     
138     // clean & exit
139     reader.Close();
140     return 0;
141 }
142
143 } // namespace BamTools
144
145 #endif // BAMTOOLS_SAM_H