]> git.donarmstrong.com Git - bamtools.git/commitdiff
Implemented bamtools sam. Required new unpack methods in BGZF.h. Seems to pass all...
authorDerek <derekwbarnett@gmail.com>
Thu, 3 Jun 2010 03:52:07 +0000 (23:52 -0400)
committerDerek <derekwbarnett@gmail.com>
Thu, 3 Jun 2010 03:52:07 +0000 (23:52 -0400)
BGZF.h
bamtools_count.cpp
bamtools_sam.cpp

diff --git a/BGZF.h b/BGZF.h
index e1adf25dc11de1fed2c70a4c2033134156157b6b..0cca24ccc344b893a04705f791d0de06d50ce090 100644 (file)
--- a/BGZF.h
+++ b/BGZF.h
@@ -108,12 +108,32 @@ struct BgzfData {
     static inline void PackUnsignedInt(char* buffer, unsigned int value);\r
     // packs an unsigned short into the specified buffer\r
     static inline void PackUnsignedShort(char* buffer, unsigned short value);\r
+    \r
     // unpacks a buffer into a signed int\r
     static inline signed int UnpackSignedInt(char* buffer);\r
-    // unpacks a buffer into a unsigned int\r
+    // unpacks a buffer into an unsigned int\r
     static inline unsigned int UnpackUnsignedInt(char* buffer);\r
-    // unpacks a buffer into a unsigned short\r
+    // unpacks a buffer into a signed short\r
+    static inline signed short UnpackSignedShort(char* buffer);\r
+    // unpacks a buffer into an unsigned short\r
     static inline unsigned short UnpackUnsignedShort(char* buffer);\r
+    // unpacks a buffer into a double\r
+    static inline double UnpackDouble(char* buffer);\r
+    // unpacks a buffer into a float\r
+    static inline float UnpackFloat(char* buffer); \r
+    \r
+    // unpacks a buffer into a signed int\r
+    static inline signed int UnpackSignedInt(const char* buffer);\r
+    // unpacks a buffer into an unsigned int\r
+    static inline unsigned int UnpackUnsignedInt(const char* buffer);\r
+    // unpacks a buffer into a signed short\r
+    static inline signed short UnpackSignedShort(const char* buffer);\r
+    // unpacks a buffer into an unsigned short\r
+    static inline unsigned short UnpackUnsignedShort(const char* buffer);\r
+    // unpacks a buffer into a double\r
+    static inline double UnpackDouble(const char* buffer);\r
+    // unpacks a buffer into a float\r
+    static inline float UnpackFloat(const char* buffer); \r
 };\r
 \r
 // -------------------------------------------------------------\r
@@ -170,6 +190,16 @@ unsigned int BgzfData::UnpackUnsignedInt(char* buffer) {
     return un.value;\r
 }\r
 \r
+// 'unpacks' a buffer into a signed short\r
+inline\r
+signed short BgzfData::UnpackSignedShort(char* buffer) {\r
+    union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    return un.value;\r
+}\r
+\r
 // 'unpacks' a buffer into an unsigned short\r
 inline\r
 unsigned short BgzfData::UnpackUnsignedShort(char* buffer) {\r
@@ -180,6 +210,108 @@ unsigned short BgzfData::UnpackUnsignedShort(char* buffer) {
     return un.value;\r
 }\r
 \r
+// 'unpacks' a buffer into a double\r
+inline\r
+double BgzfData::UnpackDouble(char* buffer) {\r
+    union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    un.valueBuffer[4] = buffer[4];\r
+    un.valueBuffer[5] = buffer[5];\r
+    un.valueBuffer[6] = buffer[6];\r
+    un.valueBuffer[7] = buffer[7];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into a float\r
+inline\r
+float BgzfData::UnpackFloat(char* buffer) {\r
+    union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    return un.value;\r
+}\r
+\r
+// ---------\r
+\r
+// 'unpacks' a buffer into a signed int\r
+inline\r
+signed int BgzfData::UnpackSignedInt(const char* buffer) {\r
+    union { signed int value; unsigned char valueBuffer[sizeof(signed int)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into an unsigned int\r
+inline\r
+unsigned int BgzfData::UnpackUnsignedInt(const char* buffer) {\r
+    union { unsigned int value; unsigned char valueBuffer[sizeof(unsigned int)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into a signed short\r
+inline\r
+signed short BgzfData::UnpackSignedShort(const char* buffer) {\r
+    union { signed short value; unsigned char valueBuffer[sizeof(signed short)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into an unsigned short\r
+inline\r
+unsigned short BgzfData::UnpackUnsignedShort(const char* buffer) {\r
+    union { unsigned short value; unsigned char valueBuffer[sizeof(unsigned short)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into a double\r
+inline\r
+double BgzfData::UnpackDouble(const char* buffer) {\r
+    union { double value; unsigned char valueBuffer[sizeof(double)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    un.valueBuffer[4] = buffer[4];\r
+    un.valueBuffer[5] = buffer[5];\r
+    un.valueBuffer[6] = buffer[6];\r
+    un.valueBuffer[7] = buffer[7];\r
+    return un.value;\r
+}\r
+\r
+// 'unpacks' a buffer into a float\r
+inline\r
+float BgzfData::UnpackFloat(const char* buffer) {\r
+    union { float value; unsigned char valueBuffer[sizeof(float)]; } un;\r
+    un.value = 0;\r
+    un.valueBuffer[0] = buffer[0];\r
+    un.valueBuffer[1] = buffer[1];\r
+    un.valueBuffer[2] = buffer[2];\r
+    un.valueBuffer[3] = buffer[3];\r
+    return un.value;\r
+}\r
+\r
 } // namespace BamTools\r
 \r
 #endif // BGZF_H\r
index 7a2de0da210b40844e2528f6b64076078c6884fb..dad30e63993b87a8408672d7ab39ad9df8234bb8 100644 (file)
@@ -98,7 +98,10 @@ int CountTool::Run(int argc, char* argv[]) {
         BamAlignment al;
         while ( reader.GetNextAlignment(al) ) 
             ++alignmentCount;
-    } else {
+    } 
+    
+    // more complicated - region specified
+    else {
         
         // parse region string for desired region
         string startChrom;
@@ -199,7 +202,7 @@ int CountTool::Run(int argc, char* argv[]) {
                 }
                 
                 // -----------------------------
-                // count alignments until 
+                // count alignments until stop hit
                 
                 if ( !foundError ) {
                     // while valid alignment AND
index b14d1287dd74922a5d82cb10ed39731864af3b42..89da132e065d2a93b1471185d101bdd7ff558765 100644 (file)
@@ -1,25 +1,27 @@
 // ***************************************************************************
-// bamtools_sam.h (c) 2010 Derek Barnett, Erik Garrison
+// bamtools_sam.cpp (c) 2010 Derek Barnett, Erik Garrison
 // Marth Lab, Department of Biology, Boston College
 // All rights reserved.
 // ---------------------------------------------------------------------------
-// Last modified: 1 June 2010
+// Last modified: 2 June 2010
 // ---------------------------------------------------------------------------
 // Prints a BAM file in the text-based SAM format.
 // ***************************************************************************
 
 #include <cstdlib>
 #include <iostream>
+#include <sstream>
 #include <string>
 
 #include "bamtools_sam.h"
 #include "bamtools_options.h"
 #include "BamReader.h"
+#include "BGZF.h"
 
 using namespace std;
 using namespace BamTools;
 
-RefVector references;
+static RefVector references;
 
 // ---------------------------------------------
 // print BamAlignment in SAM format
@@ -29,39 +31,121 @@ void PrintSAM(const BamAlignment& a) {
     // tab-delimited
     // <QNAME> <FLAG> <RNAME> <POS> <MAPQ> <CIGAR> <MRNM> <MPOS> <ISIZE> <SEQ> <QUAL> [ <TAG>:<VTYPE>:<VALUE> [...] ]
   
-    // ******************************* //
-    // ** NOT FULLY IMPLEMENTED YET ** //
-    //******************************** //
-    //
-    // Todo : build CIGAR string
-    //        build TAG string
-    //        there are some quirks, per the spec, regarding when to use '=' or not
-    //
-    // ******************************* //
-    
-    //
-    // do validity check on RefID / MateRefID ??
-    //
-  
-    // build CIGAR string
-    string cigarString("CIGAR:NOT YET");
-  
-    // build TAG string
-    string tagString("TAG:NOT YET");
-  
-    // print BamAlignment to stdout in SAM format
-    cout << a.Name << '\t' 
-         << a.AlignmentFlag << '\t'
-         << references[a.RefID].RefName << '\t'
-         << a.Position << '\t'
-         << a.MapQuality << '\t'
-         << cigarString << '\t'
-         << ( a.IsPaired() ? references[a.MateRefID].RefName : "*" ) << '\t'
-         << ( a.IsPaired() ? a.MatePosition : 0 ) << '\t'
-         << ( a.IsPaired() ? a.InsertSize : 0 ) << '\t'
-         << a.QueryBases << '\t'
-         << a.Qualities << '\t'
-         << tagString << endl;
+    ostringstream sb("");
+    
+    // write name & alignment flag
+    cout << a.Name << "\t" << a.AlignmentFlag << "\t";
+    
+    // write reference name
+    if ( (a.RefID >= 0) && (a.RefID < (int)references.size()) ) cout << references[a.RefID].RefName << "\t";
+    else cout << "*\t";
+    
+    // write position & map quality
+    cout << a.Position+1 << "\t" << a.MapQuality << "\t";
+    
+    // write CIGAR
+    const vector<CigarOp>& cigarData = a.CigarData;
+    if ( cigarData.empty() ) cout << "*\t";
+    else {
+        vector<CigarOp>::const_iterator cigarIter = cigarData.begin();
+        vector<CigarOp>::const_iterator cigarEnd  = cigarData.end();
+        for ( ; cigarIter != cigarEnd; ++cigarIter ) {
+            const CigarOp& op = (*cigarIter);
+            cout << op.Length << op.Type;
+        }
+        cout << "\t";
+    }
+    
+    // write mate reference name, mate position, & insert size
+    if ( a.IsPaired() && (a.MateRefID >= 0) && (a.MateRefID < (int)references.size()) ) {
+        if ( a.MateRefID == a.RefID ) cout << "=\t";
+        else cout << references[a.MateRefID].RefName << "\t";
+        cout << a.MatePosition+1 << "\t" << a.InsertSize << "\t";
+    } 
+    else cout << "*\t0\t0\t";
+    
+    // write sequence
+    if ( a.QueryBases.empty() ) cout << "*\t";
+    else cout << a.QueryBases << "\t";
+    
+    // write qualities
+    if ( a.Qualities.empty() ) cout << "*";
+    else cout << a.Qualities;
+    
+    // write tag data
+    const char* tagData = a.TagData.c_str();
+    const size_t tagDataLength = a.TagData.length();
+    size_t index = 0;
+    while ( index < tagDataLength ) {
+        
+        // write tag name
+        cout << "\t" << a.TagData.substr(index, 2) << ":";
+        index += 2;
+        
+        // get data type
+        char type = a.TagData.at(index);
+        ++index;
+        
+        switch (type) {
+            case('A') : 
+                cout << "A:" << tagData[index]; 
+                ++index; 
+                break;
+            
+            case('C') : 
+                cout << "i:" << atoi(&tagData[index]); 
+                ++index; 
+                break;
+            
+            case('c') : 
+                cout << "i:" << atoi(&tagData[index]);
+                ++index; 
+                break;
+            
+            case('S') : 
+                cout << "i:" << BgzfData::UnpackUnsignedShort(&tagData[index]); 
+                index += 2; 
+                break;
+                
+            case('s') : 
+                cout << "i:" << BgzfData::UnpackSignedShort(&tagData[index]);
+                index += 2; 
+                break;
+            
+            case('I') : 
+                cout << "i:" << BgzfData::UnpackUnsignedInt(&tagData[index]);
+                index += 4; 
+                break;
+            
+            case('i') : 
+                cout << "i:" << BgzfData::UnpackSignedInt(&tagData[index]);
+                index += 4; 
+                break;
+            
+            case('f') : 
+                cout << "f:" << BgzfData::UnpackFloat(&tagData[index]);
+                index += 4; 
+                break;
+            
+            case('d') : 
+                cout << "d:" << BgzfData::UnpackDouble(&tagData[index]);
+                index += 8; 
+                break;
+            
+            case('Z') :
+            case('H') : 
+                cout << type << ":"; 
+                while (tagData[index]) {
+                    cout << tagData[index];
+                    ++index;
+                }
+                ++index; 
+                break;      
+        }
+    }
+    
+    // write stream to stdout
+    cout << sb.str() << endl;
 }
 
 // ---------------------------------------------