10 #ifndef BAMALIGNMENT_H
11 #define BAMALIGNMENT_H
27 class BamReaderPrivate;
28 class BamWriterPrivate;
44 bool IsDuplicate()
const;
45 bool IsFailedQC()
const;
46 bool IsFirstMate()
const;
47 bool IsMapped()
const;
48 bool IsMateMapped()
const;
49 bool IsMateReverseStrand()
const;
50 bool IsPaired()
const;
51 bool IsPrimaryAlignment()
const;
54 bool IsReverseStrand()
const;
55 bool IsSecondMate()
const;
59 void SetIsDuplicate(
bool ok);
60 void SetIsFailedQC(
bool ok);
61 void SetIsFirstMate(
bool ok);
62 void SetIsMapped(
bool ok);
63 void SetIsMateMapped(
bool ok);
64 void SetIsMateReverseStrand(
66 void SetIsPaired(
bool ok);
67 void SetIsPrimaryAlignment(
bool ok);
71 void SetIsReverseStrand(
bool ok);
72 void SetIsSecondMate(
bool ok);
78 bool AddTag(
const std::string& tag,
const std::string& type,
const T& value);
80 bool AddTag(
const std::string& tag,
const std::vector<T>& values);
84 bool EditTag(
const std::string& tag,
const std::string& type,
const T& value);
86 bool EditTag(
const std::string& tag,
const std::vector<T>& values);
90 bool GetTag(
const std::string& tag, T& destination)
const;
92 bool GetTag(
const std::string& tag, std::vector<T>& destination)
const;
95 std::vector<std::string> GetTagNames()
const;
98 bool GetTagType(
const std::string& tag,
char& type)
const;
101 bool GetArrayTagType(
const std::string& tag,
char& type)
const;
104 bool HasTag(
const std::string& tag)
const;
107 void RemoveTag(
const std::string& tag);
112 bool BuildCharData();
115 int GetEndPosition(
bool usePadded =
false,
bool closedInterval =
false)
const;
118 std::string GetErrorString()
const;
121 bool GetSoftClips(std::vector<int>& clipSizes, std::vector<int>& readPositions,
122 std::vector<int>& genomePositions,
bool usePadded =
false)
const;
147 bool FindTag(
const std::string& tag,
char*& pTagData,
const unsigned int& tagDataLength,
148 unsigned int& numBytesParsed)
const;
149 bool IsValidSize(
const std::string& tag,
const std::string& type)
const;
150 void SetErrorString(
const std::string& where,
const std::string& what)
const;
151 bool SkipToNextTag(
const char storageType,
char*& pTagData,
unsigned int& numBytesParsed)
const;
155 struct BamAlignmentSupportData
160 std::string AllCharData;
161 uint32_t BlockLength;
162 uint32_t NumCigarOperations;
163 uint32_t QueryNameLength;
164 uint32_t QuerySequenceLength;
169 BamAlignmentSupportData()
171 , NumCigarOperations(0)
173 , QuerySequenceLength(0)
177 BamAlignmentSupportData SupportData;
178 friend class Internal::BamReaderPrivate;
179 friend class Internal::BamWriterPrivate;
181 mutable std::string ErrorString;
198 template <
typename T>
206 if (!IsValidSize(tag, type)) {
212 if (!TagTypeHelper<T>::CanConvertTo(type.at(0))) {
218 char* pTagData = (
char*)
TagData.data();
219 const unsigned int tagDataLength =
TagData.size();
220 unsigned int numBytesParsed = 0;
224 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
233 char valueBuffer[
sizeof(T)];
238 const std::string newTag = tag + type;
239 const std::size_t newTagDataLength =
240 tagDataLength + newTag.size() +
sizeof(T);
241 RaiiBuffer originalTagData(newTagDataLength);
242 memcpy(originalTagData.Buffer,
TagData.c_str(),
246 strcat(originalTagData.Buffer + tagDataLength, newTag.data());
247 memcpy(originalTagData.Buffer + tagDataLength + newTag.size(), un.valueBuffer,
sizeof(T));
250 const char* newTagData = (
const char*)originalTagData.Buffer;
251 TagData.assign(newTagData, newTagDataLength);
256 inline bool BamAlignment::AddTag<std::string>(
const std::string& tag,
const std::string& type,
257 const std::string& value)
260 if (SupportData.HasCoreOnly) BuildCharData();
263 if (!IsValidSize(tag, type)) {
269 if (!TagTypeHelper<std::string>::CanConvertTo(type.at(0))) {
275 char* pTagData = (
char*)TagData.data();
276 const unsigned int tagDataLength = TagData.size();
277 unsigned int numBytesParsed = 0;
281 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
287 const std::string newTag = tag + type + value;
288 const std::size_t newTagDataLength =
289 tagDataLength + newTag.size() + 1;
290 RaiiBuffer originalTagData(newTagDataLength);
291 memcpy(originalTagData.Buffer, TagData.c_str(),
295 strcat(originalTagData.Buffer + tagDataLength, newTag.data());
298 const char* newTagData = (
const char*)originalTagData.Buffer;
299 TagData.assign(newTagData, newTagDataLength);
313 template <
typename T>
324 char* pTagData = (
char*)
TagData.data();
325 const unsigned int tagDataLength =
TagData.size();
326 unsigned int numBytesParsed = 0;
330 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
339 newTagBase[3] = TagTypeHelper<T>::TypeCode();
342 const int32_t numElements = values.size();
343 memcpy(newTagBase + 4, &numElements,
sizeof(int32_t));
346 const std::size_t newTagDataLength =
348 RaiiBuffer originalTagData(newTagDataLength);
349 memcpy(originalTagData.Buffer,
TagData.c_str(),
353 strcat(originalTagData.Buffer + tagDataLength, (
const char*)newTagBase);
357 for (
int i = 0; i < numElements; ++i) {
358 const T& value = values.at(i);
359 memcpy(originalTagData.Buffer + elementsBeginOffset + i *
sizeof(T), &value,
sizeof(T));
363 const char* newTagData = (
const char*)originalTagData.Buffer;
364 TagData.assign(newTagData, newTagDataLength);
382 template <
typename T>
391 return AddTag(tag, type, value);
405 template <
typename T>
414 return AddTag(tag, values);
424 template <
typename T>
429 if (SupportData.HasCoreOnly) {
441 char* pTagData = (
char*)
TagData.data();
442 const unsigned int tagDataLength =
TagData.size();
443 unsigned int numBytesParsed = 0;
446 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
452 const char type = *(pTagData - 1);
453 if (!TagTypeHelper<T>::CanConvertFrom(type)) {
459 int destinationLength = 0;
466 destinationLength = 1;
472 destinationLength = 2;
479 destinationLength = 4;
486 SetErrorString(
"BamAlignment::GetTag",
487 "cannot store variable length tag data into a numeric destination");
492 const std::string message = std::string(
"invalid tag type: ") + type;
493 SetErrorString(
"BamAlignment::GetTag", message);
499 memcpy(&destination, pTagData, destinationLength);
506 inline bool BamAlignment::GetTag<std::string>(
const std::string& tag,
507 std::string& destination)
const
510 if (SupportData.HasCoreOnly) {
516 if (TagData.empty()) {
522 char* pTagData = (
char*)TagData.data();
523 const unsigned int tagDataLength = TagData.size();
524 unsigned int numBytesParsed = 0;
527 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
533 const unsigned int dataLength = strlen(pTagData);
535 destination.resize(dataLength);
536 memcpy((
char*)destination.data(), pTagData, dataLength);
549 template <
typename T>
554 if (SupportData.HasCoreOnly) {
566 char* pTagData = (
char*)
TagData.data();
567 const unsigned int tagDataLength =
TagData.size();
568 unsigned int numBytesParsed = 0;
571 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
577 const char tagType = *(pTagData - 1);
579 SetErrorString(
"BamAlignment::GetTag",
"cannot store a non-array tag in array destination");
584 const char elementType = *pTagData;
585 if (!TagTypeHelper<T>::CanConvertFrom(elementType)) {
592 switch (elementType) {
611 SetErrorString(
"BamAlignment::GetTag",
612 "invalid array data, variable-length elements are not allowed");
617 const std::string message = std::string(
"invalid array element type: ") + elementType;
618 SetErrorString(
"BamAlignment::GetTag", message);
624 memcpy(&numElements, pTagData,
sizeof(int32_t));
627 destination.reserve(numElements);
631 for (
int i = 0; i < numElements; ++i) {
632 memcpy(&value, pTagData,
sizeof(T));
633 pTagData +=
sizeof(T);
634 destination.push_back(value);
645 #endif // BAMALIGNMENT_H