annotate spp/src/BamAlignment.cpp @ 6:ce08b0efa3fd draft

Uploaded
author zzhou
date Tue, 27 Nov 2012 16:11:40 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
1 // ***************************************************************************
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
2 // BamAlignment.cpp (c) 2009 Derek Barnett
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
3 // Marth Lab, Department of Biology, Boston College
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
4 // All rights reserved.
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
5 // ---------------------------------------------------------------------------
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
6 // Last modified: 13 December 2010 (DB)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
7 // ---------------------------------------------------------------------------
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
8 // Provides the BamAlignment data structure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
9 // ***************************************************************************
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
10
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
11 #include <BamAlignment.h>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
12 using namespace BamTools;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
13
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
14 #include <cctype>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
15 #include <cstdio>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
16 #include <cstdlib>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
17 #include <cstring>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
18 #include <exception>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
19 #include <map>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
20 #include <utility>
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
21 using namespace std;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
22
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
23 // default ctor
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
24 BamAlignment::BamAlignment(void)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
25 : RefID(-1)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
26 , Position(-1)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
27 , MateRefID(-1)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
28 , MatePosition(-1)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
29 , InsertSize(0)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
30 { }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
31
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
32 // copy ctor
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
33 BamAlignment::BamAlignment(const BamAlignment& other)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
34 : Name(other.Name)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
35 , Length(other.Length)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
36 , QueryBases(other.QueryBases)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
37 , AlignedBases(other.AlignedBases)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
38 , Qualities(other.Qualities)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
39 , TagData(other.TagData)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
40 , RefID(other.RefID)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
41 , Position(other.Position)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
42 , Bin(other.Bin)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
43 , MapQuality(other.MapQuality)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
44 , AlignmentFlag(other.AlignmentFlag)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
45 , CigarData(other.CigarData)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
46 , MateRefID(other.MateRefID)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
47 , MatePosition(other.MatePosition)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
48 , InsertSize(other.InsertSize)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
49 , SupportData(other.SupportData)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
50 { }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
51
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
52 // dtor
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
53 BamAlignment::~BamAlignment(void) { }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
54
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
55 // Queries against alignment flags
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
56 bool BamAlignment::IsDuplicate(void) const { return ( (AlignmentFlag & DUPLICATE) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
57 bool BamAlignment::IsFailedQC(void) const { return ( (AlignmentFlag & QC_FAILED) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
58 bool BamAlignment::IsFirstMate(void) const { return ( (AlignmentFlag & READ_1) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
59 bool BamAlignment::IsMapped(void) const { return ( (AlignmentFlag & UNMAPPED) == 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
60 bool BamAlignment::IsMateMapped(void) const { return ( (AlignmentFlag & MATE_UNMAPPED) == 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
61 bool BamAlignment::IsMateReverseStrand(void) const { return ( (AlignmentFlag & MATE_REVERSE) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
62 bool BamAlignment::IsPaired(void) const { return ( (AlignmentFlag & PAIRED) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
63 bool BamAlignment::IsPrimaryAlignment(void) const { return ( (AlignmentFlag & SECONDARY) == 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
64 bool BamAlignment::IsProperPair(void) const { return ( (AlignmentFlag & PROPER_PAIR) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
65 bool BamAlignment::IsReverseStrand(void) const { return ( (AlignmentFlag & REVERSE) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
66 bool BamAlignment::IsSecondMate(void) const { return ( (AlignmentFlag & READ_2) != 0 ); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
67
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
68 // Manipulate alignment flags
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
69 void BamAlignment::SetIsDuplicate(bool ok) { if (ok) AlignmentFlag |= DUPLICATE; else AlignmentFlag &= ~DUPLICATE; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
70 void BamAlignment::SetIsFailedQC(bool ok) { if (ok) AlignmentFlag |= QC_FAILED; else AlignmentFlag &= ~QC_FAILED; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
71 void BamAlignment::SetIsFirstMate(bool ok) { if (ok) AlignmentFlag |= READ_1; else AlignmentFlag &= ~READ_1; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
72 void BamAlignment::SetIsMapped(bool ok) { SetIsUnmapped(!ok); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
73 void BamAlignment::SetIsMateMapped(bool ok) { SetIsMateUnmapped(!ok); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
74 void BamAlignment::SetIsMateUnmapped(bool ok) { if (ok) AlignmentFlag |= MATE_UNMAPPED; else AlignmentFlag &= ~MATE_UNMAPPED; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
75 void BamAlignment::SetIsMateReverseStrand(bool ok) { if (ok) AlignmentFlag |= MATE_REVERSE; else AlignmentFlag &= ~MATE_REVERSE; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
76 void BamAlignment::SetIsPaired(bool ok) { if (ok) AlignmentFlag |= PAIRED; else AlignmentFlag &= ~PAIRED; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
77 void BamAlignment::SetIsPrimaryAlignment(bool ok) { SetIsSecondaryAlignment(!ok); }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
78 void BamAlignment::SetIsProperPair(bool ok) { if (ok) AlignmentFlag |= PROPER_PAIR; else AlignmentFlag &= ~PROPER_PAIR; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
79 void BamAlignment::SetIsReverseStrand(bool ok) { if (ok) AlignmentFlag |= REVERSE; else AlignmentFlag &= ~REVERSE; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
80 void BamAlignment::SetIsSecondaryAlignment(bool ok) { if (ok) AlignmentFlag |= SECONDARY; else AlignmentFlag &= ~SECONDARY; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
81 void BamAlignment::SetIsSecondMate(bool ok) { if (ok) AlignmentFlag |= READ_2; else AlignmentFlag &= ~READ_2; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
82 void BamAlignment::SetIsUnmapped(bool ok) { if (ok) AlignmentFlag |= UNMAPPED; else AlignmentFlag &= ~UNMAPPED; }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
83
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
84 // calculates alignment end position, based on starting position and CIGAR operations
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
85 int BamAlignment::GetEndPosition(bool usePadded, bool zeroBased) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
86
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
87 // initialize alignment end to starting position
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
88 int alignEnd = Position;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
89
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
90 // iterate over cigar operations
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
91 vector<CigarOp>::const_iterator cigarIter = CigarData.begin();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
92 vector<CigarOp>::const_iterator cigarEnd = CigarData.end();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
93 for ( ; cigarIter != cigarEnd; ++cigarIter) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
94 const char cigarType = (*cigarIter).Type;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
95 if ( cigarType == 'M' || cigarType == 'D' || cigarType == 'N' )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
96 alignEnd += (*cigarIter).Length;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
97 else if ( usePadded && cigarType == 'I' )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
98 alignEnd += (*cigarIter).Length;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
99 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
100
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
101 // adjust for zeroBased, if necessary
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
102 if (zeroBased)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
103 return alignEnd - 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
104 else
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
105 return alignEnd;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
106 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
107
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
108 bool BamAlignment::AddTag(const string& tag, const string& type, const string& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
109
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
110 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
111 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
112 if ( type != "Z" && type != "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
113
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
114 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
115 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
116 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
117 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
118
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
119 // if tag already exists, return false
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
120 // use EditTag explicitly instead
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
121 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
122
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
123 // otherwise, copy tag data to temp buffer
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
124 string newTag = tag + type + value;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
125 const int newTagDataLength = tagDataLength + newTag.size() + 1; // leave room for null-term
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
126 char originalTagData[newTagDataLength];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
127 memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
128
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
129 // append newTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
130 strcat(originalTagData + tagDataLength, newTag.data()); // removes original null-term, appends newTag + null-term
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
131
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
132 // store temp buffer back in TagData
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
133 const char* newTagData = (const char*)originalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
134 TagData.assign(newTagData, newTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
135
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
136 // return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
137 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
138 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
139
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
140 bool BamAlignment::AddTag(const string& tag, const string& type, const uint32_t& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
141
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
142 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
143 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
144 if ( type == "f" || type == "Z" || type == "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
145
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
146 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
147 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
148 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
149 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
150
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
151 // if tag already exists, return false
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
152 // use EditTag explicitly instead
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
153 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
154
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
155 // otherwise, convert value to string
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
156 union { unsigned int value; char valueBuffer[sizeof(unsigned int)]; } un;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
157 un.value = value;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
158
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
159 // copy original tag data to temp buffer
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
160 string newTag = tag + type;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
161 const int newTagDataLength = tagDataLength + newTag.size() + 4; // leave room for new integer
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
162 char originalTagData[newTagDataLength];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
163 memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
164
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
165 // append newTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
166 strcat(originalTagData + tagDataLength, newTag.data());
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
167 memcpy(originalTagData + tagDataLength + newTag.size(), un.valueBuffer, sizeof(unsigned int));
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
168
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
169 // store temp buffer back in TagData
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
170 const char* newTagData = (const char*)originalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
171 TagData.assign(newTagData, newTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
172
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
173 // return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
174 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
175 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
176
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
177 bool BamAlignment::AddTag(const string& tag, const string& type, const int32_t& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
178 return AddTag(tag, type, (const uint32_t&)value);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
179 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
180
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
181 bool BamAlignment::AddTag(const string& tag, const string& type, const float& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
182
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
183 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
184 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
185 if ( type == "Z" || type == "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
186
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
187 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
188 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
189 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
190 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
191
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
192 // if tag already exists, return false
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
193 // use EditTag explicitly instead
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
194 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
195
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
196 // otherwise, convert value to string
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
197 union { float value; char valueBuffer[sizeof(float)]; } un;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
198 un.value = value;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
199
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
200 // copy original tag data to temp buffer
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
201 string newTag = tag + type;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
202 const int newTagDataLength = tagDataLength + newTag.size() + 4; // leave room for new float
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
203 char originalTagData[newTagDataLength];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
204 memcpy(originalTagData, TagData.c_str(), tagDataLength + 1); // '+1' for TagData null-term
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
205
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
206 // append newTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
207 strcat(originalTagData + tagDataLength, newTag.data());
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
208 memcpy(originalTagData + tagDataLength + newTag.size(), un.valueBuffer, sizeof(float));
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
209
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
210 // store temp buffer back in TagData
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
211 const char* newTagData = (const char*)originalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
212 TagData.assign(newTagData, newTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
213
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
214 // return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
215 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
216 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
217
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
218 bool BamAlignment::EditTag(const string& tag, const string& type, const string& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
219
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
220 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
221 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
222 if ( type != "Z" && type != "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
223
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
224 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
225 char* pOriginalTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
226 char* pTagData = pOriginalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
227 const unsigned int originalTagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
228
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
229 unsigned int newTagDataLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
230 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
231
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
232 // if tag found, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
233 if ( FindTag(tag, pTagData, originalTagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
234
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
235 // make sure array is more than big enough
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
236 char newTagData[originalTagDataLength + value.size()];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
237
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
238 // copy original tag data up til desired tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
239 const unsigned int beginningTagDataLength = numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
240 newTagDataLength += beginningTagDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
241 memcpy(newTagData, pOriginalTagData, numBytesParsed);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
242
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
243 // copy new VALUE in place of current tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
244 const unsigned int dataLength = strlen(value.c_str());
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
245 memcpy(newTagData + beginningTagDataLength, (char*)value.c_str(), dataLength+1 );
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
246
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
247 // skip to next tag (if tag for removal is last, return true)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
248 const char* pTagStorageType = pTagData - 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
249 if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
250
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
251 // copy everything from current tag (the next one after tag for removal) to end
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
252 const unsigned int skippedDataLength = (numBytesParsed - beginningTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
253 const unsigned int endTagOffset = beginningTagDataLength + dataLength + 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
254 const unsigned int endTagDataLength = originalTagDataLength - beginningTagDataLength - skippedDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
255 memcpy(newTagData + endTagOffset, pTagData, endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
256
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
257 // ensure null-terminator
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
258 newTagData[ endTagOffset + endTagDataLength + 1 ] = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
259
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
260 // save new tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
261 TagData.assign(newTagData, endTagOffset + endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
262 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
263 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
264
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
265 // tag not found, attempt AddTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
266 else return AddTag(tag, type, value);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
267 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
268
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
269 bool BamAlignment::EditTag(const string& tag, const string& type, const uint32_t& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
270
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
271 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
272 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
273 if ( type == "f" || type == "Z" || type == "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
274
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
275 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
276 char* pOriginalTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
277 char* pTagData = pOriginalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
278 const unsigned int originalTagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
279
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
280 unsigned int newTagDataLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
281 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
282
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
283 // if tag found, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
284 if ( FindTag(tag, pTagData, originalTagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
285
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
286 // make sure array is more than big enough
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
287 char newTagData[originalTagDataLength + sizeof(value)];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
288
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
289 // copy original tag data up til desired tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
290 const unsigned int beginningTagDataLength = numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
291 newTagDataLength += beginningTagDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
292 memcpy(newTagData, pOriginalTagData, numBytesParsed);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
293
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
294 // copy new VALUE in place of current tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
295 union { unsigned int value; char valueBuffer[sizeof(unsigned int)]; } un;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
296 un.value = value;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
297 memcpy(newTagData + beginningTagDataLength, un.valueBuffer, sizeof(unsigned int));
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
298
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
299 // skip to next tag (if tag for removal is last, return true)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
300 const char* pTagStorageType = pTagData - 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
301 if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
302
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
303 // copy everything from current tag (the next one after tag for removal) to end
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
304 const unsigned int skippedDataLength = (numBytesParsed - beginningTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
305 const unsigned int endTagOffset = beginningTagDataLength + sizeof(unsigned int);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
306 const unsigned int endTagDataLength = originalTagDataLength - beginningTagDataLength - skippedDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
307 memcpy(newTagData + endTagOffset, pTagData, endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
308
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
309 // ensure null-terminator
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
310 newTagData[ endTagOffset + endTagDataLength + 1 ] = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
311
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
312 // save new tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
313 TagData.assign(newTagData, endTagOffset + endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
314 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
315 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
316
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
317 // tag not found, attempt AddTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
318 else return AddTag(tag, type, value);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
319 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
320
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
321 bool BamAlignment::EditTag(const string& tag, const string& type, const int32_t& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
322 return EditTag(tag, type, (const uint32_t&)value);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
323 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
324
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
325 bool BamAlignment::EditTag(const string& tag, const string& type, const float& value) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
326
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
327 if ( SupportData.HasCoreOnly ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
328 if ( tag.size() != 2 || type.size() != 1 ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
329 if ( type == "Z" || type == "H" ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
330
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
331 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
332 char* pOriginalTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
333 char* pTagData = pOriginalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
334 const unsigned int originalTagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
335
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
336 unsigned int newTagDataLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
337 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
338
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
339 // if tag found, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
340 if ( FindTag(tag, pTagData, originalTagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
341
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
342 // make sure array is more than big enough
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
343 char newTagData[originalTagDataLength + sizeof(value)];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
344
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
345 // copy original tag data up til desired tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
346 const unsigned int beginningTagDataLength = numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
347 newTagDataLength += beginningTagDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
348 memcpy(newTagData, pOriginalTagData, numBytesParsed);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
349
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
350 // copy new VALUE in place of current tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
351 union { float value; char valueBuffer[sizeof(float)]; } un;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
352 un.value = value;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
353 memcpy(newTagData + beginningTagDataLength, un.valueBuffer, sizeof(float));
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
354
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
355 // skip to next tag (if tag for removal is last, return true)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
356 const char* pTagStorageType = pTagData - 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
357 if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
358
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
359 // copy everything from current tag (the next one after tag for removal) to end
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
360 const unsigned int skippedDataLength = (numBytesParsed - beginningTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
361 const unsigned int endTagOffset = beginningTagDataLength + sizeof(float);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
362 const unsigned int endTagDataLength = originalTagDataLength - beginningTagDataLength - skippedDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
363 memcpy(newTagData + endTagOffset, pTagData, endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
364
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
365 // ensure null-terminator
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
366 newTagData[ endTagOffset + endTagDataLength + 1 ] = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
367
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
368 // save new tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
369 TagData.assign(newTagData, endTagOffset + endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
370 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
371 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
372
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
373 // tag not found, attempt AddTag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
374 else return AddTag(tag, type, value);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
375 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
376
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
377 // get "NM" tag data - originally contributed by Aaron Quinlan
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
378 // stores data in 'editDistance', returns success/fail
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
379 bool BamAlignment::GetEditDistance(uint32_t& editDistance) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
380 return GetTag("NM", (uint32_t&)editDistance);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
381 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
382
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
383 // get "RG" tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
384 // stores data in 'readGroup', returns success/fail
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
385 bool BamAlignment::GetReadGroup(string& readGroup) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
386 return GetTag("RG", readGroup);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
387 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
388
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
389 bool BamAlignment::GetTag(const string& tag, string& destination) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
390
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
391 // make sure tag data exists
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
392 if ( SupportData.HasCoreOnly || TagData.empty() )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
393 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
394
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
395 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
396 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
397 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
398 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
399
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
400 // if tag found, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
401 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
402 const unsigned int dataLength = strlen(pTagData);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
403 destination.clear();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
404 destination.resize(dataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
405 memcpy( (char*)destination.data(), pTagData, dataLength );
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
406 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
407 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
408
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
409 // tag not found, return failure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
410 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
411 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
412
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
413 bool BamAlignment::GetTag(const string& tag, uint32_t& destination) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
414
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
415 // make sure tag data exists
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
416 if ( SupportData.HasCoreOnly || TagData.empty() )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
417 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
418
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
419 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
420 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
421 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
422 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
423
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
424 // if tag found, determine data byte-length, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
425 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
426
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
427 // determine data byte-length
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
428 const char type = *(pTagData - 1);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
429 int destinationLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
430 switch (type) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
431
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
432 // 1 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
433 case 'A':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
434 case 'c':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
435 case 'C':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
436 destinationLength = 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
437 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
438
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
439 // 2 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
440 case 's':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
441 case 'S':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
442 destinationLength = 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
443 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
444
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
445 // 4 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
446 case 'i':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
447 case 'I':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
448 destinationLength = 4;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
449 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
450
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
451 // unsupported type for integer destination (float or var-length strings)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
452 case 'f':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
453 case 'Z':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
454 case 'H':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
455 fprintf(stderr, "ERROR: Cannot store tag of type %c in integer destination\n", type);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
456 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
457
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
458 // unknown tag type
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
459 default:
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
460 fprintf(stderr, "ERROR: Unknown tag storage class encountered: [%c]\n", type);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
461 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
462 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
463
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
464 // store in destination
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
465 destination = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
466 memcpy(&destination, pTagData, destinationLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
467 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
468 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
469
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
470 // tag not found, return failure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
471 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
472 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
473
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
474 bool BamAlignment::GetTag(const string& tag, int32_t& destination) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
475 return GetTag(tag, (uint32_t&)destination);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
476 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
477
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
478 bool BamAlignment::GetTag(const string& tag, float& destination) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
479
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
480 // make sure tag data exists
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
481 if ( SupportData.HasCoreOnly || TagData.empty() )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
482 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
483
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
484 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
485 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
486 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
487 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
488
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
489 // if tag found, determine data byte-length, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
490 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
491
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
492 // determine data byte-length
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
493 const char type = *(pTagData - 1);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
494 int destinationLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
495 switch(type) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
496
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
497 // 1 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
498 case 'A':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
499 case 'c':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
500 case 'C':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
501 destinationLength = 1;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
502 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
503
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
504 // 2 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
505 case 's':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
506 case 'S':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
507 destinationLength = 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
508 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
509
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
510 // 4 byte data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
511 case 'f':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
512 case 'i':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
513 case 'I':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
514 destinationLength = 4;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
515 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
516
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
517 // unsupported type (var-length strings)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
518 case 'Z':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
519 case 'H':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
520 fprintf(stderr, "ERROR: Cannot store tag of type %c in integer destination\n", type);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
521 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
522
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
523 // unknown tag type
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
524 default:
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
525 fprintf(stderr, "ERROR: Unknown tag storage class encountered: [%c]\n", type);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
526 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
527 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
528
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
529 // store in destination
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
530 destination = 0.0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
531 memcpy(&destination, pTagData, destinationLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
532 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
533 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
534
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
535 // tag not found, return failure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
536 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
537 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
538
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
539 bool BamAlignment::GetTagType(const string& tag, char& type) const {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
540
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
541 // make sure tag data exists
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
542 if ( SupportData.HasCoreOnly || TagData.empty() )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
543 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
544
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
545 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
546 char* pTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
547 const unsigned int tagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
548 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
549
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
550 // lookup tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
551 if ( FindTag(tag, pTagData, tagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
552
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
553 // retrieve tag type code
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
554 type = *(pTagData - 1);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
555
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
556 // validate that type is a proper BAM tag type
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
557 switch(type) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
558 case 'A':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
559 case 'c':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
560 case 'C':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
561 case 's':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
562 case 'S':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
563 case 'f':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
564 case 'i':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
565 case 'I':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
566 case 'Z':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
567 case 'H':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
568 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
569
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
570 // unknown tag type
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
571 default:
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
572 fprintf(stderr, "ERROR: Unknown tag storage class encountered: [%c]\n", type);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
573 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
574 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
575 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
576
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
577 // tag not found, return failure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
578 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
579 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
580
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
581 bool BamAlignment::RemoveTag(const string& tag) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
582
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
583 // BamAlignments fetched using BamReader::GetNextAlignmentCore() are not allowed
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
584 // also, return false if no data present to remove
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
585 if ( SupportData.HasCoreOnly || TagData.empty() ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
586
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
587 // localize the tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
588 char* pOriginalTagData = (char*)TagData.data();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
589 char* pTagData = pOriginalTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
590 const unsigned int originalTagDataLength = TagData.size();
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
591 unsigned int newTagDataLength = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
592 unsigned int numBytesParsed = 0;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
593
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
594 // if tag found, store data in readGroup, return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
595 if ( FindTag(tag, pTagData, originalTagDataLength, numBytesParsed) ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
596
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
597 char newTagData[originalTagDataLength];
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
598
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
599 // copy original tag data up til desired tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
600 pTagData -= 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
601 numBytesParsed -= 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
602 const unsigned int beginningTagDataLength = numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
603 newTagDataLength += beginningTagDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
604 memcpy(newTagData, pOriginalTagData, numBytesParsed);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
605
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
606 // skip to next tag (if tag for removal is last, return true)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
607 const char* pTagStorageType = pTagData + 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
608 pTagData += 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
609 numBytesParsed += 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
610 if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
611
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
612 // copy everything from current tag (the next one after tag for removal) to end
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
613 const unsigned int skippedDataLength = (numBytesParsed - beginningTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
614 const unsigned int endTagDataLength = originalTagDataLength - beginningTagDataLength - skippedDataLength;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
615 memcpy(newTagData + beginningTagDataLength, pTagData, endTagDataLength );
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
616
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
617 // save new tag data
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
618 TagData.assign(newTagData, beginningTagDataLength + endTagDataLength);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
619 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
620 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
621
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
622 // tag not found, no removal - return failure
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
623 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
624 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
625
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
626 bool BamAlignment::FindTag(const string& tag,
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
627 char* &pTagData,
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
628 const unsigned int& tagDataLength,
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
629 unsigned int& numBytesParsed)
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
630 {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
631
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
632 while ( numBytesParsed < tagDataLength ) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
633
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
634 const char* pTagType = pTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
635 const char* pTagStorageType = pTagData + 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
636 pTagData += 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
637 numBytesParsed += 3;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
638
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
639 // check the current tag, return true on match
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
640 if ( strncmp(pTagType, tag.c_str(), 2) == 0 )
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
641 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
642
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
643 // get the storage class and find the next tag
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
644 if ( *pTagStorageType == '\0' ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
645 if ( !SkipToNextTag(*pTagStorageType, pTagData, numBytesParsed) ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
646 if ( *pTagData == '\0' ) return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
647 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
648
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
649 // checked all tags, none match
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
650 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
651 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
652
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
653 bool BamAlignment::SkipToNextTag(const char storageType, char* &pTagData, unsigned int& numBytesParsed) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
654
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
655 switch(storageType) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
656
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
657 case 'A':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
658 case 'c':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
659 case 'C':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
660 ++numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
661 ++pTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
662 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
663
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
664 case 's':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
665 case 'S':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
666 numBytesParsed += 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
667 pTagData += 2;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
668 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
669
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
670 case 'f':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
671 case 'i':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
672 case 'I':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
673 numBytesParsed += 4;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
674 pTagData += 4;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
675 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
676
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
677 case 'Z':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
678 case 'H':
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
679 while(*pTagData) {
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
680 ++numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
681 ++pTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
682 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
683 // increment for null-terminator
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
684 ++numBytesParsed;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
685 ++pTagData;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
686 break;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
687
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
688 default:
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
689 // error case
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
690 fprintf(stderr, "ERROR: Unknown tag storage class encountered: [%c]\n", storageType);
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
691 return false;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
692 }
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
693
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
694 // return success
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
695 return true;
ce08b0efa3fd Uploaded
zzhou
parents:
diff changeset
696 }