// ***************************************************************************
// bamtools_convert.cpp (c) 2010 Derek Barnett, Erik Garrison
// Marth Lab, Department of Biology, Boston College
-// All rights reserved.
// ---------------------------------------------------------------------------
-// Last modified: 21 March 2011
+// Last modified: 11 November 2012
// ---------------------------------------------------------------------------
// Converts between BAM and a number of other formats
// ***************************************************************************
namespace BamTools {
- // ---------------------------------------------
- // ConvertTool constants
-
- // supported conversion format command-line names
- static const string FORMAT_BED = "bed";
- static const string FORMAT_FASTA = "fasta";
- static const string FORMAT_FASTQ = "fastq";
- static const string FORMAT_JSON = "json";
- static const string FORMAT_SAM = "sam";
- static const string FORMAT_PILEUP = "pileup";
- static const string FORMAT_YAML = "yaml";
-
- // other constants
- static const unsigned int FASTA_LINE_MAX = 50;
-
- // ---------------------------------------------
- // ConvertPileupFormatVisitor declaration
-
- class ConvertPileupFormatVisitor : public PileupVisitor {
-
- // ctor & dtor
- public:
- ConvertPileupFormatVisitor(const RefVector& references,
- const string& fastaFilename,
- const bool isPrintingMapQualities,
- ostream* out);
- ~ConvertPileupFormatVisitor(void);
-
- // PileupVisitor interface implementation
- public:
- void Visit(const PileupPosition& pileupData);
-
- // data members
- private:
- Fasta m_fasta;
- bool m_hasFasta;
- bool m_isPrintingMapQualities;
- ostream* m_out;
- RefVector m_references;
- };
+// ---------------------------------------------
+// ConvertTool constants
+
+// supported conversion format command-line names
+static const string FORMAT_BED = "bed";
+static const string FORMAT_FASTA = "fasta";
+static const string FORMAT_FASTQ = "fastq";
+static const string FORMAT_JSON = "json";
+static const string FORMAT_SAM = "sam";
+static const string FORMAT_PILEUP = "pileup";
+static const string FORMAT_YAML = "yaml";
+
+// other constants
+static const unsigned int FASTA_LINE_MAX = 50;
+
+// ---------------------------------------------
+// ConvertPileupFormatVisitor declaration
+
+class ConvertPileupFormatVisitor : public PileupVisitor {
+
+ // ctor & dtor
+ public:
+ ConvertPileupFormatVisitor(const RefVector& references,
+ const string& fastaFilename,
+ const bool isPrintingMapQualities,
+ ostream* out);
+ ~ConvertPileupFormatVisitor(void);
+
+ // PileupVisitor interface implementation
+ public:
+ void Visit(const PileupPosition& pileupData);
+
+ // data members
+ private:
+ Fasta m_fasta;
+ bool m_hasFasta;
+ bool m_isPrintingMapQualities;
+ ostream* m_out;
+ RefVector m_references;
+};
} // namespace BamTools
struct ConvertTool::ConvertSettings {
- // flags
+ // flag
bool HasInput;
bool HasOutput;
bool HasFormat;
// ctor & dtor
public:
- ConvertToolPrivate(ConvertTool::ConvertSettings* settings);
- ~ConvertToolPrivate(void);
+ ConvertToolPrivate(ConvertTool::ConvertSettings* settings)
+ : m_settings(settings)
+ , m_out(cout.rdbuf())
+ { }
+
+ ~ConvertToolPrivate(void) { }
// interface
public:
ostream m_out;
};
-ConvertTool::ConvertToolPrivate::ConvertToolPrivate(ConvertTool::ConvertSettings* settings)
- : m_settings(settings)
- , m_out(cout.rdbuf()) // default output to cout
-{ }
-
-ConvertTool::ConvertToolPrivate::~ConvertToolPrivate(void) { }
-
bool ConvertTool::ConvertToolPrivate::Run(void) {
// ------------------------------------
m_out << m_references.at(a.RefID).RefName << "\t"
<< a.Position << "\t"
- << a.GetEndPosition() + 1 << "\t"
+ << a.GetEndPosition() << "\t"
<< a.Name << "\t"
<< a.MapQuality << "\t"
<< (a.IsReverseStrand() ? "-" : "+") << endl;
// N.B. - QueryBases are reverse-complemented if aligned to reverse strand
// print header
- m_out << "> " << a.Name << endl;
+ m_out << ">" << a.Name << endl;
// handle reverse strand alignment - bases
string sequence = a.QueryBases;
m_out << "\"queryBases\":\"" << a.QueryBases << "\",";
// write qualities
- if ( !a.Qualities.empty() ) {
+ if ( !a.Qualities.empty() && a.Qualities.at(0) != (char)0xFF ) {
string::const_iterator s = a.Qualities.begin();
m_out << "\"qualities\":[" << static_cast<short>(*s) - 33;
++s;
++index;
break;
- case (Constants::BAM_TAG_TYPE_INT8) :
+ case (Constants::BAM_TAG_TYPE_INT8) :
+ // force value into integer-type (instead of char value)
+ m_out << static_cast<int16_t>(tagData[index]);
+ ++index;
+ break;
+
case (Constants::BAM_TAG_TYPE_UINT8) :
- m_out << (int)tagData[index];
+ // force value into integer-type (instead of char value)
+ m_out << static_cast<uint16_t>(tagData[index]);
++index;
break;
// <QNAME> <FLAG> <RNAME> <POS> <MAPQ> <CIGAR> <MRNM> <MPOS> <ISIZE> <SEQ> <QUAL> [ <TAG>:<VTYPE>:<VALUE> [...] ]
// write name & alignment flag
- m_out << a.Name << "\t" << a.AlignmentFlag << "\t";
-
+ m_out << a.Name << "\t" << a.AlignmentFlag << "\t";
+
// write reference name
if ( (a.RefID >= 0) && (a.RefID < (int)m_references.size()) )
m_out << m_references[a.RefID].RefName << "\t";
if ( a.MateRefID == a.RefID )
m_out << "=\t";
else
- m_out << m_references[a.MateRefID].RefName << "\t";
+ m_out << m_references[a.MateRefID].RefName << "\t";
m_out << a.MatePosition+1 << "\t" << a.InsertSize << "\t";
}
else
m_out << a.QueryBases << "\t";
// write qualities
- if ( a.Qualities.empty() )
+ if ( a.Qualities.empty() || (a.Qualities.at(0) == (char)0xFF) )
m_out << "*";
else
m_out << a.Qualities;
++index;
break;
- case (Constants::BAM_TAG_TYPE_INT8) :
+ case (Constants::BAM_TAG_TYPE_INT8) :
+ // force value into integer-type (instead of char value)
+ m_out << "i:" << static_cast<int16_t>(tagData[index]);
+ ++index;
+ break;
+
case (Constants::BAM_TAG_TYPE_UINT8) :
- m_out << "i:" << (int)tagData[index];
+ // force value into integer-type (instead of char value)
+ m_out << "i:" << static_cast<uint16_t>(tagData[index]);
++index;
break;
index += sizeof(float);
break;
- case (Constants::BAM_TAG_TYPE_HEX) :
+ case (Constants::BAM_TAG_TYPE_HEX) : // fall-through
case (Constants::BAM_TAG_TYPE_STRING) :
m_out << type << ":";
while (tagData[index]) {
break;
}
- if ( tagData[index] == '\0')
+ if ( tagData[index] == '\0' )
break;
}
}
ConvertTool::~ConvertTool(void) {
+
delete m_settings;
m_settings = 0;
// parse command line arguments
Options::Parse(argc, argv, 1);
- // run internal ConvertTool implementation, return success/fail
+ // initialize ConvertTool with settings
m_impl = new ConvertToolPrivate(m_settings);
+ // run ConvertTool, return success/fail
if ( m_impl->Run() )
return 0;
else