Skip to content

Commit

Permalink
reformat
Browse files Browse the repository at this point in the history
  • Loading branch information
lh3 authored and pezmaster31 committed Dec 1, 2017
1 parent 3705ed2 commit 0a02bb6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 51 deletions.
77 changes: 43 additions & 34 deletions src/api/internal/bam/BamReader_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,80 +248,90 @@ void BamReaderPrivate::LoadHeaderData()

static inline int bam_aux_type2size(int x)
{
if (x == 'C' || x == 'c' || x == 'A') return 1;
else if (x == 'S' || x == 's') return 2;
else if (x == 'I' || x == 'i' || x == 'f') return 4;
else return 0;
if (x == 'C' || x == 'c' || x == 'A')
return 1;
else if (x == 'S' || x == 's')
return 2;
else if (x == 'I' || x == 'i' || x == 'f')
return 4;
else
return 0;
}

static unsigned char *bam_aux_get(int aux_data_len, const unsigned char *aux_start, const char *tag)
static unsigned char* bam_aux_get(int aux_data_len, const unsigned char* aux_start, const char* tag)
{
const unsigned char *p = aux_start;
const unsigned char* p = aux_start;
while (p < aux_start + aux_data_len) {
if (p[0] == tag[0] && p[1] == tag[1]) return (unsigned char*)(p + 2);
p += 2; // skip tag
int type = *p++; // read type
p += 2; // skip tag
int type = *p++; // read type
if (type == 'B') {
int size = bam_aux_type2size(*p++); // read array type
unsigned len = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24;
p += 4; // skip the size field
p += len * size; // skip array
int size = bam_aux_type2size(*p++); // read array type
unsigned len =
(unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24;
p += 4; // skip the size field
p += len * size; // skip array
} else if (type == 'Z' || type == 'H') {
while (*p++ != 0) {} // skip NULL terminated string
while (*p++ != 0) {
} // skip NULL terminated string
} else {
p += bam_aux_type2size(type); // skip value
p += bam_aux_type2size(type); // skip value
}
}
return NULL;
}

static inline int hts_reg2bin(int64_t beg, int64_t end, int min_shift, int n_lvls)
{
int l, s = min_shift, t = ((1<<((n_lvls<<1) + n_lvls)) - 1) / 7;
for (--end, l = n_lvls; l > 0; --l, s += 3, t -= 1<<((l<<1)+l))
if (beg>>s == end>>s) return t + (beg>>s);
int l, s = min_shift, t = ((1 << ((n_lvls << 1) + n_lvls)) - 1) / 7;
for (--end, l = n_lvls; l > 0; --l, s += 3, t -= 1 << ((l << 1) + l))
if (beg >> s == end >> s) return t + (beg >> s);
return 0;
}

bool BamReaderPrivate::Tag2Cigar(BamAlignment &a, RaiiBuffer &buf)
bool BamReaderPrivate::Tag2Cigar(BamAlignment& a, RaiiBuffer& buf)
{
if (a.RefID < 0 || a.Position < 0 || a.SupportData.NumCigarOperations == 0) return false;

const unsigned char *data = (const unsigned char*)buf.Buffer;
const unsigned char* data = (const unsigned char*)buf.Buffer;
const unsigned data_len = a.SupportData.BlockLength - Constants::BAM_CORE_SIZE;
const unsigned char *p = data + a.SupportData.QueryNameLength; // the original CIGAR
unsigned cigar1 = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24;
if ((cigar1&0xf) != 4 || cigar1>>4 != a.SupportData.QuerySequenceLength) return false;
const unsigned char* p = data + a.SupportData.QueryNameLength; // the original CIGAR
unsigned cigar1 =
(unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24;
if ((cigar1 & 0xf) != 4 || cigar1 >> 4 != a.SupportData.QuerySequenceLength) return false;

const int seq_offset = a.SupportData.QueryNameLength + a.SupportData.NumCigarOperations * 4;
const int aux_offset = seq_offset + (a.SupportData.QuerySequenceLength + 1) / 2 + a.SupportData.QuerySequenceLength;
unsigned char *CG = bam_aux_get(data_len - aux_offset, data + aux_offset, "CG");
const int aux_offset = seq_offset + (a.SupportData.QuerySequenceLength + 1) / 2 +
a.SupportData.QuerySequenceLength;
unsigned char* CG = bam_aux_get(data_len - aux_offset, data + aux_offset, "CG");
if (CG == NULL || CG[0] != 'B' || CG[1] != 'I') return false;

const unsigned tag_cigar_len = (unsigned)CG[2] | (unsigned)CG[3]<<8 | (unsigned)CG[4]<<16 | (unsigned)CG[5]<<24;
const unsigned tag_cigar_len =
(unsigned)CG[2] | (unsigned)CG[3] << 8 | (unsigned)CG[4] << 16 | (unsigned)CG[5] << 24;
if (tag_cigar_len == 0) return false;

// recalculate bin, as it may be incorrect if it was calculated by a tool unaware of the real CIGAR in tag
const unsigned tag_cigar_offset = CG - data + 6;
unsigned alignment_end = a.Position;
p = data + tag_cigar_offset;
for (unsigned i = 0; i < tag_cigar_len * 4; i += 4, p += 4) {
unsigned cigar1 = (unsigned)p[0] | (unsigned)p[1]<<8 | (unsigned)p[2]<<16 | (unsigned)p[3]<<24;
unsigned cigar1 =
(unsigned)p[0] | (unsigned)p[1] << 8 | (unsigned)p[2] << 16 | (unsigned)p[3] << 24;
int op = cigar1 & 0xf;
if (op == 0 || op == 2 || op == 3 || op == 7 || op == 8)
alignment_end += cigar1 >> 4;
if (op == 0 || op == 2 || op == 3 || op == 7 || op == 8) alignment_end += cigar1 >> 4;
}
a.Bin = hts_reg2bin(a.Position, alignment_end, 14, 5);

// populate new AllCharData
int fake_bytes = a.SupportData.NumCigarOperations * 4;
std::string new_data;
new_data.reserve(data_len - 8 - fake_bytes + 1);
new_data.append((char*)data, a.SupportData.QueryNameLength); // query name
new_data.append((char*)data + tag_cigar_offset, tag_cigar_len * 4); // real CIGAR
new_data.append((char*)data + seq_offset, tag_cigar_offset - 8 - seq_offset); // seq, qual and tags before CG
new_data.append((char*)data, a.SupportData.QueryNameLength); // query name
new_data.append((char*)data + tag_cigar_offset, tag_cigar_len * 4); // real CIGAR
new_data.append((char*)data + seq_offset,
tag_cigar_offset - 8 - seq_offset); // seq, qual and tags before CG
const unsigned tag_cigar_end_offset = tag_cigar_offset + tag_cigar_len * 4;
if (tag_cigar_end_offset < data_len) // tags after CG, if there is any
if (tag_cigar_end_offset < data_len) // tags after CG, if there is any
new_data.append((char*)data + tag_cigar_end_offset, data_len - tag_cigar_end_offset);

// update member variables
Expand Down Expand Up @@ -382,8 +392,7 @@ bool BamReaderPrivate::LoadNextAlignment(BamAlignment& alignment)
if (m_stream.Read(allCharData.Buffer, dataLength) == dataLength) {

int OldNumCigarOperations = alignment.SupportData.NumCigarOperations;
if (Tag2Cigar(alignment, allCharData))
dataLength -= 8 + OldNumCigarOperations * 4;
if (Tag2Cigar(alignment, allCharData)) dataLength -= 8 + OldNumCigarOperations * 4;

// store 'allCharData' in supportData structure
alignment.SupportData.AllCharData.assign((const char*)allCharData.Buffer, dataLength);
Expand Down
2 changes: 1 addition & 1 deletion src/api/internal/bam/BamReader_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class BamReaderPrivate
// access alignment data
bool GetNextAlignment(BamAlignment& alignment);
bool GetNextAlignmentCore(BamAlignment& alignment);
bool Tag2Cigar(BamAlignment &alignment, RaiiBuffer &buf);
bool Tag2Cigar(BamAlignment& alignment, RaiiBuffer& buf);

// access auxiliary data
std::string GetHeaderText() const;
Expand Down
30 changes: 14 additions & 16 deletions src/api/internal/bam/BamWriter_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al)
queryLength + // here referring to quality length
tagDataLength;
unsigned int blockSize = Constants::BAM_CORE_SIZE + dataBlockSize;
if (numCigarOperations >= 65536)
blockSize += 16;
if (numCigarOperations >= 65536) blockSize += 16;
if (m_isBigEndian) BamTools::SwapEndian_32(blockSize);
m_stream.Write((char*)&blockSize, Constants::BAM_SIZEOF_INT);

Expand All @@ -305,7 +304,7 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al)
buffer[0] = al.RefID;
buffer[1] = al.Position;
buffer[2] = (alignmentBin << 16) | (al.MapQuality << 8) | nameLength;
buffer[3] = (al.AlignmentFlag << 16) | (numCigarOperations < 65536? numCigarOperations : 2);
buffer[3] = (al.AlignmentFlag << 16) | (numCigarOperations < 65536 ? numCigarOperations : 2);
buffer[4] = queryLength;
buffer[5] = al.MateRefID;
buffer[6] = al.MatePosition;
Expand Down Expand Up @@ -333,9 +332,8 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al)
BamTools::SwapEndian_32p(&cigarData[i]);
}
m_stream.Write(cigarData, packedCigarLength);
delete[] cigarData; // TODO: cleanup on Write exception thrown?
}
else
delete[] cigarData; // TODO: cleanup on Write exception thrown?
} else
m_stream.Write(packedCigar.data(), packedCigarLength);
} else {
unsigned int cigar[2];
Expand Down Expand Up @@ -467,21 +465,21 @@ void BamWriterPrivate::WriteAlignment(const BamAlignment& al)

if (numCigarOperations >= 65536) {
m_stream.Write("CGBI", 4);
if ( m_isBigEndian ) {
if (m_isBigEndian) {
unsigned int cigar_len_buf = numCigarOperations;
BamTools::SwapEndian_32(cigar_len_buf);
m_stream.Write((char*)&cigar_len_buf, 4);

char* cigarData = new char[packedCigarLength]();
memcpy(cigarData, packedCigar.data(), packedCigarLength);
if ( m_isBigEndian ) {
for ( size_t i = 0; i < packedCigarLength; ++i ) // FIXME: similarly, this should be "i += 4", not "++i"
if (m_isBigEndian) {
for (size_t i = 0; i < packedCigarLength;
++i) // FIXME: similarly, this should be "i += 4", not "++i"
BamTools::SwapEndian_32p(&cigarData[i]);
}
m_stream.Write(cigarData, packedCigarLength);
delete[] cigarData; // TODO: cleanup on Write exception thrown?
}
else {
delete[] cigarData; // TODO: cleanup on Write exception thrown?
} else {
m_stream.Write((char*)&numCigarOperations, 4);
m_stream.Write(packedCigar.data(), packedCigarLength);
}
Expand All @@ -493,8 +491,7 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al)

// write the block size
unsigned int blockSize = al.SupportData.BlockLength;
if (al.SupportData.NumCigarOperations >= 65536)
blockSize += 16;
if (al.SupportData.NumCigarOperations >= 65536) blockSize += 16;
if (m_isBigEndian) BamTools::SwapEndian_32(blockSize);
m_stream.Write((char*)&blockSize, Constants::BAM_SIZEOF_INT);

Expand All @@ -506,7 +503,8 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al)
buffer[0] = al.RefID;
buffer[1] = al.Position;
buffer[2] = (alignmentBin << 16) | (al.MapQuality << 8) | al.SupportData.QueryNameLength;
buffer[3] = (al.AlignmentFlag << 16) | (al.SupportData.NumCigarOperations < 65536? al.SupportData.NumCigarOperations : 2);
buffer[3] = (al.AlignmentFlag << 16) |
(al.SupportData.NumCigarOperations < 65536 ? al.SupportData.NumCigarOperations : 2);
buffer[4] = al.SupportData.QuerySequenceLength;
buffer[5] = al.MateRefID;
buffer[6] = al.MatePosition;
Expand All @@ -526,7 +524,7 @@ void BamWriterPrivate::WriteCoreAlignment(const BamAlignment& al)
m_stream.Write((char*)al.SupportData.AllCharData.data(),
al.SupportData.BlockLength - Constants::BAM_CORE_SIZE);
} else {
const char *data = al.SupportData.AllCharData.c_str();
const char* data = al.SupportData.AllCharData.c_str();
const unsigned data_len = al.SupportData.BlockLength - Constants::BAM_CORE_SIZE;
const unsigned cigar_offset = al.SupportData.QueryNameLength;
const unsigned seq_offset = cigar_offset + al.SupportData.NumCigarOperations * 4;
Expand Down

0 comments on commit 0a02bb6

Please sign in to comment.