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;
56 bool IsSupplementaryAlignment(
void)
const;
60 void SetIsDuplicate(
bool ok);
61 void SetIsFailedQC(
bool ok);
62 void SetIsFirstMate(
bool ok);
63 void SetIsMapped(
bool ok);
64 void SetIsMateMapped(
bool ok);
65 void SetIsMateReverseStrand(
67 void SetIsPaired(
bool ok);
68 void SetIsPrimaryAlignment(
bool ok);
72 void SetIsReverseStrand(
bool ok);
73 void SetIsSecondMate(
bool ok);
79 bool AddTag(
const std::string& tag,
const std::string& type,
const T& value);
81 bool AddTag(
const std::string& tag,
const std::vector<T>& values);
85 bool EditTag(
const std::string& tag,
const std::string& type,
const T& value);
87 bool EditTag(
const std::string& tag,
const std::vector<T>& values);
91 bool GetTag(
const std::string& tag, T& destination)
const;
93 bool GetTag(
const std::string& tag, std::vector<T>& destination)
const;
96 std::vector<std::string> GetTagNames()
const;
99 bool GetTagType(
const std::string& tag,
char& type)
const;
102 bool GetArrayTagType(
const std::string& tag,
char& type)
const;
105 bool HasTag(
const std::string& tag)
const;
108 void RemoveTag(
const std::string& tag);
113 bool BuildCharData();
116 int GetEndPosition(
bool usePadded =
false,
bool closedInterval =
false)
const;
119 std::string GetErrorString()
const;
122 bool GetSoftClips(std::vector<int>& clipSizes, std::vector<int>& readPositions,
123 std::vector<int>& genomePositions,
bool usePadded =
false)
const;
148 bool FindTag(
const std::string& tag,
char*& pTagData,
const unsigned int& tagDataLength,
149 unsigned int& numBytesParsed)
const;
150 bool IsValidSize(
const std::string& tag,
const std::string& type)
const;
151 void SetErrorString(
const std::string& where,
const std::string& what)
const;
152 bool SkipToNextTag(
const char storageType,
char*& pTagData,
unsigned int& numBytesParsed)
const;
156 struct BamAlignmentSupportData
161 std::string AllCharData;
162 uint32_t BlockLength;
163 uint32_t NumCigarOperations;
164 uint32_t QueryNameLength;
165 uint32_t QuerySequenceLength;
170 BamAlignmentSupportData()
172 , NumCigarOperations(0)
174 , QuerySequenceLength(0)
178 BamAlignmentSupportData SupportData;
179 friend class Internal::BamReaderPrivate;
180 friend class Internal::BamWriterPrivate;
182 mutable std::string ErrorString;
199 template <
typename T>
207 if (!IsValidSize(tag, type)) {
213 if (!TagTypeHelper<T>::CanConvertTo(type.at(0))) {
219 char* pTagData = (
char*)
TagData.data();
220 const unsigned int tagDataLength =
TagData.size();
221 unsigned int numBytesParsed = 0;
225 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
234 char valueBuffer[
sizeof(T)];
239 const std::string newTag = tag + type;
240 const std::size_t newTagDataLength =
241 tagDataLength + newTag.size() +
sizeof(T);
242 RaiiBuffer originalTagData(newTagDataLength);
243 memcpy(originalTagData.Buffer,
TagData.c_str(),
247 strcat(originalTagData.Buffer + tagDataLength, newTag.data());
248 memcpy(originalTagData.Buffer + tagDataLength + newTag.size(), un.valueBuffer,
sizeof(T));
251 const char* newTagData = (
const char*)originalTagData.Buffer;
252 TagData.assign(newTagData, newTagDataLength);
257 inline bool BamAlignment::AddTag<std::string>(
const std::string& tag,
const std::string& type,
258 const std::string& value)
261 if (SupportData.HasCoreOnly) BuildCharData();
264 if (!IsValidSize(tag, type)) {
270 if (!TagTypeHelper<std::string>::CanConvertTo(type.at(0))) {
276 char* pTagData = (
char*)TagData.data();
277 const unsigned int tagDataLength = TagData.size();
278 unsigned int numBytesParsed = 0;
282 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
288 const std::string newTag = tag + type + value;
289 const std::size_t newTagDataLength =
290 tagDataLength + newTag.size() + 1;
291 RaiiBuffer originalTagData(newTagDataLength);
292 memcpy(originalTagData.Buffer, TagData.c_str(),
296 strcat(originalTagData.Buffer + tagDataLength, newTag.data());
299 const char* newTagData = (
const char*)originalTagData.Buffer;
300 TagData.assign(newTagData, newTagDataLength);
314 template <
typename T>
325 char* pTagData = (
char*)
TagData.data();
326 const unsigned int tagDataLength =
TagData.size();
327 unsigned int numBytesParsed = 0;
331 if (FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
340 newTagBase[3] = TagTypeHelper<T>::TypeCode();
343 const int32_t numElements = values.size();
344 memcpy(newTagBase + 4, &numElements,
sizeof(int32_t));
347 const std::size_t newTagDataLength =
349 RaiiBuffer originalTagData(newTagDataLength);
350 memcpy(originalTagData.Buffer,
TagData.c_str(),
354 strcat(originalTagData.Buffer + tagDataLength, (
const char*)newTagBase);
358 for (
int i = 0; i < numElements; ++i) {
359 const T& value = values.at(i);
360 memcpy(originalTagData.Buffer + elementsBeginOffset + i *
sizeof(T), &value,
sizeof(T));
364 const char* newTagData = (
const char*)originalTagData.Buffer;
365 TagData.assign(newTagData, newTagDataLength);
383 template <
typename T>
392 return AddTag(tag, type, value);
406 template <
typename T>
415 return AddTag(tag, values);
425 template <
typename T>
430 if (SupportData.HasCoreOnly) {
442 char* pTagData = (
char*)
TagData.data();
443 const unsigned int tagDataLength =
TagData.size();
444 unsigned int numBytesParsed = 0;
447 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
453 const char type = *(pTagData - 1);
454 if (!TagTypeHelper<T>::CanConvertFrom(type)) {
460 int destinationLength = 0;
467 destinationLength = 1;
473 destinationLength = 2;
480 destinationLength = 4;
487 SetErrorString(
"BamAlignment::GetTag",
488 "cannot store variable length tag data into a numeric destination");
493 const std::string message = std::string(
"invalid tag type: ") + type;
494 SetErrorString(
"BamAlignment::GetTag", message);
500 memcpy(&destination, pTagData, destinationLength);
507 inline bool BamAlignment::GetTag<std::string>(
const std::string& tag,
508 std::string& destination)
const
511 if (SupportData.HasCoreOnly) {
517 if (TagData.empty()) {
523 char* pTagData = (
char*)TagData.data();
524 const unsigned int tagDataLength = TagData.size();
525 unsigned int numBytesParsed = 0;
528 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
534 const unsigned int dataLength = strlen(pTagData);
536 destination.resize(dataLength);
537 memcpy((
char*)destination.data(), pTagData, dataLength);
550 template <
typename T>
555 if (SupportData.HasCoreOnly) {
567 char* pTagData = (
char*)
TagData.data();
568 const unsigned int tagDataLength =
TagData.size();
569 unsigned int numBytesParsed = 0;
572 if (!FindTag(tag, pTagData, tagDataLength, numBytesParsed)) {
578 const char tagType = *(pTagData - 1);
580 SetErrorString(
"BamAlignment::GetTag",
"cannot store a non-array tag in array destination");
585 const char elementType = *pTagData;
586 if (!TagTypeHelper<T>::CanConvertFrom(elementType)) {
593 switch (elementType) {
612 SetErrorString(
"BamAlignment::GetTag",
613 "invalid array data, variable-length elements are not allowed");
618 const std::string message = std::string(
"invalid array element type: ") + elementType;
619 SetErrorString(
"BamAlignment::GetTag", message);
625 memcpy(&numElements, pTagData,
sizeof(int32_t));
628 destination.reserve(numElements);
632 for (
int i = 0; i < numElements; ++i) {
633 memcpy(&value, pTagData,
sizeof(T));
634 pTagData +=
sizeof(T);
635 destination.push_back(value);
#define API_EXPORT
Definition: api_global.h:18