TestValidate.cpp
/*
* Copyright (C) 2010 Regents of the University of Michigan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TestValidate.h"
#include "BaseUtilities.h"
const std::string TestValidate::READ1_CIGAR = "5M2D";
const std::string TestValidate::READ1_SEQ = "CCGAA";
const std::string TestValidate::READ1_QUAL = "6>6+4";
const std::string TestValidate::READ6_CIGAR = "3S2H5M";
const std::string TestValidate::READ6_SEQ = "TGCACGTN";
const std::string TestValidate::READ6_QUAL = "453;>>>>";
const std::string TestValidate::READ7_CIGAR = "3S5M1S3H";
const std::string TestValidate::READ7_SEQ = "TGCACGTNG";
const std::string TestValidate::READ7_QUAL = "453;>>>>5";
void validateRead1(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 1
// Create record structure for validating.
int expectedBlockSize = 89;
const char* expectedReferenceName = "1";
const char* expectedMateReferenceName = "1";
const char* expectedMateReferenceNameOrEqual = "=";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
const bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 0;
expectedRecordPtr->myPosition = TestValidate::READ1_POS;
expectedRecordPtr->myReadNameLength = 23;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 2;
expectedRecordPtr->myFlag = 73;
expectedRecordPtr->myReadLength = 5;
expectedRecordPtr->myMateReferenceID = 0;
expectedRecordPtr->myMatePosition = 1010;
expectedRecordPtr->myInsertSize = 0;
assert(samRecord.getString("MD") == "37");
assert(samRecord.getString("YZ") == "");
assert(samRecord.getInteger("YZ") == -1);
float tmpFloat = -1;
assert(samRecord.getFloatTag("YZ", tmpFloat) == false);
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == TestValidate::READ1_ALIGN_END);
assert(samRecord.get1BasedAlignmentEnd() == (TestValidate::READ1_ALIGN_END + 1));
assert(samRecord.getAlignmentLength() == TestValidate::READ1_ALIGN_LEN);
assert(samRecord.get1BasedUnclippedStart() == (TestValidate::READ1_UNCLIP_START + 1));
assert(samRecord.get0BasedUnclippedStart() == TestValidate::READ1_UNCLIP_START);
assert(samRecord.get1BasedUnclippedEnd() == (TestValidate::READ1_UNCLIP_END + 1));
assert(samRecord.get0BasedUnclippedEnd() == TestValidate::READ1_UNCLIP_END);
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "1:1011:F:255+17M15D20M") == 0);
assert(samRecord.getCigar() == TestValidate::READ1_CIGAR);
assert(samRecord.getSequence() == TestValidate::READ1_SEQ);
assert(samRecord.getQuality() == TestValidate::READ1_QUAL);
assert(samRecord.getSequence(0) == 'C');
assert(samRecord.getQuality(0) == '6');
assert(samRecord.getSequence(1) == 'C');
assert(samRecord.getQuality(1) == '>');
assert(samRecord.getSequence(2) == 'G');
assert(samRecord.getQuality(2) == '6');
assert(samRecord.getSequence(3) == 'A');
assert(samRecord.getQuality(3) == '+');
assert(samRecord.getSequence(4) == 'A');
assert(samRecord.getQuality(4) == '4');
bool caught = false;
try
{
samRecord.getSequence(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(-1) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(-1) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getSequence(5);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(5) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(5);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(5) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
assert(samRecord.getNumOverlaps(1010, 1017) == 5);
assert(samRecord.getNumOverlaps(1010, 1016) == 5);
assert(samRecord.getNumOverlaps(1012, 1017) == 3);
assert(samRecord.getNumOverlaps(1015, 1017) == 0);
assert(samRecord.getNumOverlaps(1017, 1010) == 0);
assert(samRecord.getNumOverlaps(1013, 1011) == 0);
assert(samRecord.getNumOverlaps(-1, 1017) == 5);
assert(samRecord.getNumOverlaps(1010, -1) == 5);
// Check the tags.
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'A');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 0);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'M');
assert(tag[1] == 'D');
assert(type == 'Z');
assert(*(String*)value == "37");
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'N');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 0);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'X');
assert(tag[1] == 'T');
assert(type == 'A');
assert(*(char*)value == 'R');
// No more tags, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (const bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The First cigar is 5M which is 5 << 4 | 0 = 80
assert(*(unsigned int*)varPtr == 80);
// Increment the varptr the size of an int.
varPtr += 4;
// The 2nd cigar is 2D which is 2 << 4 | 2 = 34
assert(*(unsigned int*)varPtr == 34);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// CC = 0x22
assert(*varPtr == 0x22);
varPtr++;
// GA = 0x41
assert(*varPtr == 0x41);
varPtr++;
// A = 0x10
assert(*varPtr == 0x10);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
// Validate the tags.
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'D');
varPtr++;
assert(*varPtr == 'Z');
varPtr++;
assert(*varPtr == '3');
varPtr++;
assert(*varPtr == '7');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'N');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'X');
varPtr++;
assert(*varPtr == 'T');
varPtr++;
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'R');
varPtr++;
}
void validateRead2(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 2
// Create record structure for validating.
int expectedBlockSize = 61;
const char* expectedReferenceName = "1";
const char* expectedMateReferenceName = "1";
const char* expectedMateReferenceNameOrEqual = "=";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 0;
expectedRecordPtr->myPosition = TestValidate::READ2_POS;
expectedRecordPtr->myReadNameLength = 23;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 0;
expectedRecordPtr->myFlag = 133;
expectedRecordPtr->myReadLength = 4;
expectedRecordPtr->myMateReferenceID = 0;
expectedRecordPtr->myMatePosition = 1010;
expectedRecordPtr->myInsertSize = 0;
// Check the fields.
bamRecordStruct retrieveRecord;
String retrieveReadName;
String retrieveCigar;
String retrieveSequence;
String retrieveQuality;
assert(samRecord.getFields(retrieveRecord, retrieveReadName,
retrieveCigar, retrieveSequence,
retrieveQuality) == true);
assert(retrieveRecord.myBlockSize == expectedRecordPtr->myBlockSize);
assert(retrieveRecord.myReferenceID == expectedRecordPtr->myReferenceID);
assert(retrieveRecord.myPosition == expectedRecordPtr->myPosition);
assert(retrieveRecord.myReadNameLength ==
expectedRecordPtr->myReadNameLength);
assert(retrieveRecord.myMapQuality == expectedRecordPtr->myMapQuality);
assert(retrieveRecord.myBin == expectedRecordPtr->myBin);
assert(retrieveRecord.myCigarLength == expectedRecordPtr->myCigarLength);
assert(retrieveRecord.myFlag == expectedRecordPtr->myFlag);
assert(retrieveRecord.myReadLength == expectedRecordPtr->myReadLength);
assert(retrieveRecord.myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(retrieveRecord.myMatePosition == expectedRecordPtr->myMatePosition);
assert(retrieveRecord.myInsertSize == expectedRecordPtr->myInsertSize);
// Check the alignment end
assert(samRecord.getAlignmentLength() == 0);
assert(samRecord.get0BasedAlignmentEnd() == 1011);
assert(samRecord.get1BasedAlignmentEnd() == 1012);
assert(samRecord.get0BasedUnclippedStart() == 1011);
assert(samRecord.get1BasedUnclippedStart() == 1012);
assert(samRecord.get0BasedUnclippedEnd() == 1011);
assert(samRecord.get1BasedUnclippedEnd() == 1012);
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "1:1011:F:255+17M15D20M") == 0);
assert(strcmp(samRecord.getCigar(), "*") == 0);
assert(strcmp(samRecord.getSequence(), "CTGT") == 0);
assert(strcmp(samRecord.getQuality(), ">>9>") == 0);
assert(samRecord.getSequence(0) == 'C');
assert(samRecord.getQuality(0) == '>');
assert(samRecord.getSequence(1) == 'T');
assert(samRecord.getQuality(1) == '>');
assert(samRecord.getSequence(2) == 'G');
assert(samRecord.getQuality(2) == '9');
assert(samRecord.getSequence(3) == 'T');
assert(samRecord.getQuality(3) == '>');
bool caught = false;
try
{
samRecord.getSequence(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(-1) is out of range. Index must be between 0 and 3") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(-1) is out of range. Index must be between 0 and 3") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getSequence(4);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(4) is out of range. Index must be between 0 and 3") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(4);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(4) is out of range. Index must be between 0 and 3") == 0);
}
assert(caught == true);
assert(samRecord.getNumOverlaps(1011, 1017) == 0);
assert(samRecord.getNumOverlaps(0, 1116) == 0);
// No Tags to check, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// No cigar to validate.
// Validate the sequence.
// CT = 0x28
assert(*varPtr == 0x28);
varPtr++;
// GT = 0x48
assert(*varPtr == 0x48);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
// No tags.
}
void validateRead3(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 3
// Create record structure for validating.
int expectedBlockSize = 87;
const char* expectedReferenceName = "1";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 0;
expectedRecordPtr->myPosition = 74;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 1;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 5;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:295") == 0);
assert(strcmp(samRecord.getCigar(), "5M") == 0);
assert(strcmp(samRecord.getSequence(), "ACGTN") == 0);
assert(strcmp(samRecord.getQuality(), ";>>>>") == 0);
assert(samRecord.getNumOverlaps(74, 79) == 5);
assert(samRecord.getNumOverlaps(74, 78) == 4);
assert(samRecord.getNumOverlaps(73, 79) == 5);
assert(samRecord.getNumOverlaps(75, 79) == 4);
assert(samRecord.getNumOverlaps(0, 179) == 5);
assert(samRecord.getNumOverlaps(0, 19) == 0);
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == 78);
assert(samRecord.get1BasedAlignmentEnd() == 79);
assert(samRecord.getAlignmentLength() == 5);
assert(samRecord.get0BasedUnclippedStart() == 74);
assert(samRecord.get1BasedUnclippedStart() == 75);
assert(samRecord.get0BasedUnclippedEnd() == 78);
assert(samRecord.get1BasedUnclippedEnd() == 79);
// Check the tags.
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'A');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 0);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'M');
assert(tag[1] == 'D');
assert(type == 'Z');
assert(*(String*)value == "30A0C5");
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'N');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 2);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'X');
assert(tag[1] == 'T');
assert(type == 'A');
assert(*(char*)value == 'R');
// No more tags, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The cigar is 5M which is 5 << 4 | 0 = 80
assert(*(unsigned int*)varPtr == 80);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// AC = 0x12
assert(*varPtr == 0x12);
varPtr++;
// GT = 0x48
assert(*varPtr == 0x48);
varPtr++;
// N = 0xF0
assert(*varPtr == 0xF0);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
// Validate the tags.
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'D');
varPtr++;
assert(*varPtr == 'Z');
varPtr++;
assert(*varPtr == '3');
varPtr++;
assert(*varPtr == '0');
varPtr++;
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == '0');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == '5');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'N');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 2);
varPtr++;
assert(*varPtr == 'X');
varPtr++;
assert(*varPtr == 'T');
varPtr++;
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'R');
varPtr++;
}
void validateRead4(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 4
// Create record structure for validating.
int expectedBlockSize = 57;
const char* expectedReferenceName = "1";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 0;
expectedRecordPtr->myPosition = 74;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 0;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 0;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the alignment end
assert(samRecord.get1BasedUnclippedEnd() == 75);
assert(samRecord.get0BasedUnclippedEnd() == 74);
assert(samRecord.get0BasedUnclippedStart() == 74);
assert(samRecord.get1BasedUnclippedStart() == 75);
assert(samRecord.get1BasedAlignmentEnd() == 75);
assert(samRecord.get0BasedAlignmentEnd() == 74);
assert(samRecord.getAlignmentLength() == 0);
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:295") == 0);
assert(strcmp(samRecord.getCigar(), "*") == 0);
assert(strcmp(samRecord.getSequence(), "*") == 0);
assert(strcmp(samRecord.getQuality(), "*") == 0);
bool caught = false;
try
{
samRecord.getSequence(0);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(0) is not allowed since sequence = '*'") == 0);
}
assert(caught == true);
caught = false;
try
{
assert(samRecord.getQuality(0) == BaseUtilities::UNKNOWN_QUALITY_CHAR);
}
catch (std::exception& e)
{
caught = true;
}
assert(caught == false);
try
{
samRecord.getSequence(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(-1) is not allowed since sequence = '*'") == 0);
}
assert(caught == true);
caught = false;
try
{
assert(samRecord.getQuality(-1) == BaseUtilities::UNKNOWN_QUALITY_CHAR);
}
catch (std::exception& e)
{
caught = true;
}
assert(caught == false);
caught = false;
try
{
samRecord.getSequence(5);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(5) is not allowed since sequence = '*'") == 0);
}
assert(caught == true);
caught = false;
try
{
assert(samRecord.getQuality(5) == BaseUtilities::UNKNOWN_QUALITY_CHAR);
}
catch (std::exception& e)
{
caught = true;
}
assert(caught == false);
assert(samRecord.getNumOverlaps(74, 79) == 0);
assert(samRecord.getNumOverlaps(74, 78) == 0);
assert(samRecord.getNumOverlaps(73, 79) == 0);
assert(samRecord.getNumOverlaps(75, 79) == 0);
assert(samRecord.getNumOverlaps(0, 179) == 0);
assert(samRecord.getNumOverlaps(0, 19) == 0);
// Check the tag.
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'A');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 0);
// No more Tags to check, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// No cigar to validate.
// Validate the sequence.
// No sequence.
// No Quality.
// Validate the tags.
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 0);
varPtr++;
}
void validateRead5(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 5
int expectedBlockSize = 87;
const char* expectedReferenceName = "2";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 1;
expectedRecordPtr->myPosition = 74;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 1;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 5;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:295") == 0);
assert(strcmp(samRecord.getCigar(), "5M") == 0);
assert(strcmp(samRecord.getSequence(), "ACGTN") == 0);
assert(strcmp(samRecord.getQuality(), "*") == 0);
assert(samRecord.getNumOverlaps(74, 79) == 5);
assert(samRecord.getNumOverlaps(74, 78) == 4);
assert(samRecord.getNumOverlaps(73, 79) == 5);
assert(samRecord.getNumOverlaps(75, 79) == 4);
assert(samRecord.getNumOverlaps(0, 179) == 5);
assert(samRecord.getNumOverlaps(0, 19) == 0);
assert(samRecord.getSequence(0) == 'A');
char expChar = BaseUtilities::UNKNOWN_QUALITY_CHAR;
assert(samRecord.getQuality(0) == expChar);
assert(samRecord.getSequence(1) == 'C');
assert(samRecord.getQuality(1) == expChar);
assert(samRecord.getSequence(2) == 'G');
assert(samRecord.getQuality(2) == expChar);
assert(samRecord.getSequence(3) == 'T');
assert(samRecord.getQuality(3) == expChar);
assert(samRecord.getSequence(4) == 'N');
assert(samRecord.getQuality(4) == expChar);
bool caught = false;
try
{
samRecord.getSequence(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(-1) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(-1);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(-1) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getSequence(5);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getSequence(5) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
caught = false;
try
{
samRecord.getQuality(5);
}
catch (std::exception& e)
{
caught = true;
assert(strcmp(e.what(), "SamRecord::getQuality(5) is out of range. Index must be between 0 and 4") == 0);
}
assert(caught == true);
// Check the tags.
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'A');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 0);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'M');
assert(tag[1] == 'D');
assert(type == 'Z');
assert(*(String*)value == "30A0C5");
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'N');
assert(tag[1] == 'M');
assert(type == 'i');
assert(*(char*)value == 2);
assert(samRecord.getNextSamTag(tag, type, &value) == true);
assert(tag[0] == 'X');
assert(tag[1] == 'T');
assert(type == 'A');
assert(*(char*)value == 'R');
// No more tags, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The cigar is 5M which is 5 << 4 | 0 = 80
assert(*(unsigned int*)varPtr == 80);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// AC = 0x12
assert(*varPtr == 0x12);
varPtr++;
// GT = 0x48
assert(*varPtr == 0x48);
varPtr++;
// N = 0xF0
assert(*varPtr == 0xF0);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == 0xFF);
varPtr++;
}
// Validate the tags.
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'D');
varPtr++;
assert(*varPtr == 'Z');
varPtr++;
assert(*varPtr == '3');
varPtr++;
assert(*varPtr == '0');
varPtr++;
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == '0');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == '5');
varPtr++;
assert(*varPtr == 0);
varPtr++;
assert(*varPtr == 'N');
varPtr++;
assert(*varPtr == 'M');
varPtr++;
assert(*varPtr == 'C');
varPtr++;
assert(*varPtr == 2);
varPtr++;
assert(*varPtr == 'X');
varPtr++;
assert(*varPtr == 'T');
varPtr++;
assert(*varPtr == 'A');
varPtr++;
assert(*varPtr == 'R');
varPtr++;
}
void validateRead6(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 6
// Create record structure for validating.
int expectedBlockSize = 77;
const char* expectedReferenceName = "1";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 0;
expectedRecordPtr->myPosition = TestValidate::READ6_POS;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 3;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 8;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:296") == 0);
assert(samRecord.getCigar() == TestValidate::READ6_CIGAR);
assert(samRecord.getSequence() == TestValidate::READ6_SEQ);
assert(samRecord.getQuality() == TestValidate::READ6_QUAL);
assert(samRecord.getNumOverlaps(1750, 1755) == 5);
assert(samRecord.getNumOverlaps(1750, 1754) == 4);
assert(samRecord.getNumOverlaps(0, 2000) == 5);
assert(samRecord.getNumOverlaps(1749, 1755) == 5);
assert(samRecord.getNumOverlaps(1751, 1755) == 4);
assert(samRecord.getNumOverlaps(0, 1752) == 2);
assert(samRecord.getNumOverlaps(0, 19) == 0);
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == TestValidate::READ6_ALIGN_END);
assert(samRecord.get1BasedAlignmentEnd() == (TestValidate::READ6_ALIGN_END + 1));
assert(samRecord.getAlignmentLength() == TestValidate::READ6_ALIGN_LEN);
assert(samRecord.get0BasedUnclippedStart() == TestValidate::READ6_UNCLIP_START);
assert(samRecord.get1BasedUnclippedStart() == (TestValidate::READ6_UNCLIP_START + 1));
assert(samRecord.get0BasedUnclippedEnd() == TestValidate::READ6_UNCLIP_END);
assert(samRecord.get1BasedUnclippedEnd() == (TestValidate::READ6_UNCLIP_END + 1));
// No tags.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The cigar is 3S2H5M which is:
// 3S: 3 << 4 | 4 = 0x34
assert(*(unsigned int*)varPtr == 0x34);
// Increment the varptr the size of an int.
varPtr += 4;
// 2H: 2 << 4 | 5 = 0x25
assert(*(unsigned int*)varPtr == 0x25);
// Increment the varptr the size of an int.
varPtr += 4;
// 5M: 5 << 4 | 0 = 0x50
assert(*(unsigned int*)varPtr == 0x50);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// TG = 0x84
assert(*varPtr == 0x84);
varPtr++;
// CA = 0x21
assert(*varPtr == 0x21);
varPtr++;
// CG = 0x24
assert(*varPtr == 0x24);
varPtr++;
// TN = 0x8F
assert(*varPtr == 0x8F);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
}
void validateRead7(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 7
// Create record structure for validating.
int expectedBlockSize = 83;
const char* expectedReferenceName = "2";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 1;
expectedRecordPtr->myPosition = TestValidate::READ7_POS;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 4;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 9;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:297") == 0);
assert(samRecord.getCigar() == TestValidate::READ7_CIGAR);
assert(samRecord.getSequence() == TestValidate::READ7_SEQ);
assert(samRecord.getQuality() == TestValidate::READ7_QUAL);
assert(samRecord.getNumOverlaps(1750, 1755) == 5);
assert(samRecord.getNumOverlaps(1750, 1754) == 4);
assert(samRecord.getNumOverlaps(0, 2000) == 5);
assert(samRecord.getNumOverlaps(1749, 1755) == 5);
assert(samRecord.getNumOverlaps(1751, 1755) == 4);
assert(samRecord.getNumOverlaps(0, 1752) == 2);
assert(samRecord.getNumOverlaps(0, 19) == 0);
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == TestValidate::READ7_ALIGN_END);
assert(samRecord.get1BasedAlignmentEnd() == (TestValidate::READ7_ALIGN_END + 1));
assert(samRecord.getAlignmentLength() == TestValidate::READ7_ALIGN_LEN);
assert(samRecord.get0BasedUnclippedStart() == TestValidate::READ7_UNCLIP_START);
assert(samRecord.get1BasedUnclippedStart() == (TestValidate::READ7_UNCLIP_START + 1));
assert(samRecord.get0BasedUnclippedEnd() == TestValidate::READ7_UNCLIP_END);
assert(samRecord.get1BasedUnclippedEnd() == (TestValidate::READ7_UNCLIP_END + 1));
// No tags.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The cigar is 3S5M1S3H which is:
// 3S: 3 << 4 | 4 = 0x34
assert(*(unsigned int*)varPtr == 0x34);
// Increment the varptr the size of an int.
varPtr += 4;
// 5M: 5 << 4 | 0 = 0x50
assert(*(unsigned int*)varPtr == 0x50);
// Increment the varptr the size of an int.
varPtr += 4;
// 1S: 1 << 4 | 4 = 0x14
assert(*(unsigned int*)varPtr == 0x14);
// Increment the varptr the size of an int.
varPtr += 4;
// 3H: 3 << 4 | 5 = 0x35
assert(*(unsigned int*)varPtr == 0x35);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// TG = 0x84
assert(*varPtr == 0x84);
varPtr++;
// CA = 0x21
assert(*varPtr == 0x21);
varPtr++;
// CG = 0x24
assert(*varPtr == 0x24);
varPtr++;
// TN = 0x8F
assert(*varPtr == 0x8F);
varPtr++;
// G = 0x40
assert(*varPtr == 0x40);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
}
void validateRead8(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 8
// Create record structure for validating.
int expectedBlockSize = 65;
const char* expectedReferenceName = "*";
const char* expectedMateReferenceName = "*";
const char* expectedMateReferenceNameOrEqual = "*";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = -1;
expectedRecordPtr->myPosition = -1;
expectedRecordPtr->myReadNameLength = 27;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4680;
expectedRecordPtr->myCigarLength = 0;
expectedRecordPtr->myFlag = 141;
expectedRecordPtr->myReadLength = 4;
expectedRecordPtr->myMateReferenceID = -1;
expectedRecordPtr->myMatePosition = -1;
expectedRecordPtr->myInsertSize = 0;
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == -1);
assert(samRecord.get1BasedAlignmentEnd() == 0);
assert(samRecord.getAlignmentLength() == 0);
assert(samRecord.get0BasedUnclippedStart() == -1);
assert(samRecord.get1BasedUnclippedStart() == 0);
assert(samRecord.get0BasedUnclippedEnd() == -1);
assert(samRecord.get1BasedUnclippedEnd() == 0);
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "Y:16597235+13M13I11M:F:181") == 0);
assert(strcmp(samRecord.getCigar(), "*") == 0);
assert(strcmp(samRecord.getSequence(), "AACT") == 0);
assert(strcmp(samRecord.getQuality(), "==;;") == 0);
assert(samRecord.getNumOverlaps(1750, 1755) == 0);
assert(samRecord.getNumOverlaps(1750, 1754) == 0);
assert(samRecord.getNumOverlaps(0, 2000) == 0);
assert(samRecord.getNumOverlaps(1749, 1755) == 0);
assert(samRecord.getNumOverlaps(1751, 1755) == 0);
assert(samRecord.getNumOverlaps(0, 1752) == 0);
assert(samRecord.getNumOverlaps(0, 19) == 0);
assert(samRecord.getNumOverlaps(-1, 4) == 0);
// No Tags to check, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// No cigar to validate.
// Validate the sequence.
// AA = 0x11
assert(*varPtr == 0x11);
varPtr++;
// CT = 0x28
assert(*varPtr == 0x28);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
// No tags.
}
void validateRead9(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 9
// Create record structure for validating.
int expectedBlockSize = 77;
const char* expectedReferenceName = "3";
const char* expectedMateReferenceName = "18";
const char* expectedMateReferenceNameOrEqual = "18";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = 2;
expectedRecordPtr->myPosition = 74;
expectedRecordPtr->myReadNameLength = 21;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4681;
expectedRecordPtr->myCigarLength = 3;
expectedRecordPtr->myFlag = 97;
expectedRecordPtr->myReadLength = 8;
expectedRecordPtr->myMateReferenceID = 17;
expectedRecordPtr->myMatePosition = 756;
expectedRecordPtr->myInsertSize = 0;
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getStatus() == SamStatus::SUCCESS);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "18:462+29M5I3M:F:298") == 0);
assert(strcmp(samRecord.getCigar(), "3S5M4H") == 0);
assert((strcmp(samRecord.getSequence(), "TGCACGTN") == 0) ||
(strcmp(samRecord.getSequence(), "tgcacgtn") == 0));
assert(strcmp(samRecord.getQuality(), "453;>>>>") == 0);
assert(samRecord.getNumOverlaps(74, 79) == 5);
assert(samRecord.getNumOverlaps(73, 79) == 5);
assert(samRecord.getNumOverlaps(75, 78) == 3);
assert(samRecord.getNumOverlaps(0, 1017) == 5);
assert(samRecord.getNumOverlaps(79, 85) == 0);
assert(samRecord.getNumOverlaps(78, 85) == 1);
assert(samRecord.getNumOverlaps(-1, 1017) == 5);
// Check the alignment end
assert(samRecord.get0BasedAlignmentEnd() == 78);
assert(samRecord.get1BasedAlignmentEnd() == 79);
assert(samRecord.getAlignmentLength() == 5);
assert(samRecord.get0BasedUnclippedStart() == 71);
assert(samRecord.get1BasedUnclippedStart() == 72);
assert(samRecord.get0BasedUnclippedEnd() == 82);
assert(samRecord.get1BasedUnclippedEnd() == 83);
// No tags.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
assert(bufferPtr != NULL);
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// Validate the cigar.
// The cigar is 3S5M1S3H which is:
// 3S: 3 << 4 | 4 = 0x34
assert(*(unsigned int*)varPtr == 0x34);
// Increment the varptr the size of an int.
varPtr += 4;
// 5M: 5 << 4 | 0 = 0x50
assert(*(unsigned int*)varPtr == 0x50);
// Increment the varptr the size of an int.
varPtr += 4;
// 4H: 4 << 4 | 5 = 0x45
assert(*(unsigned int*)varPtr == 0x45);
// Increment the varptr the size of an int.
varPtr += 4;
// Validate the sequence.
// TG = 0x84
assert(*varPtr == 0x84);
varPtr++;
// CA = 0x21
assert(*varPtr == 0x21);
varPtr++;
// CG = 0x24
assert(*varPtr == 0x24);
varPtr++;
// TN = 0x8F
assert(*varPtr == 0x8F);
varPtr++;
// Validate the Quality
for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
{
assert(*varPtr == samRecord.getQuality()[i] - 33);
varPtr++;
}
}
void validateRead10(SamRecord& samRecord)
{
//////////////////////////////////////////
// Validate Record 10
// Create record structure for validating.
int expectedBlockSize = 59;
const char* expectedReferenceName = "*";
const char* expectedMateReferenceName = "*";
const char* expectedMateReferenceNameOrEqual = "*";
bamRecordStruct* expectedRecordPtr =
(bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
char tag[3];
char type;
void* value;
bamRecordStruct* bufferPtr;
unsigned char* varPtr;
expectedRecordPtr->myBlockSize = expectedBlockSize;
expectedRecordPtr->myReferenceID = -1;
expectedRecordPtr->myPosition = -1;
expectedRecordPtr->myReadNameLength = 27;
expectedRecordPtr->myMapQuality = 0;
expectedRecordPtr->myBin = 4680;
expectedRecordPtr->myCigarLength = 0;
expectedRecordPtr->myFlag = 141;
expectedRecordPtr->myReadLength = 0;
expectedRecordPtr->myMateReferenceID = -1;
expectedRecordPtr->myMatePosition = -1;
expectedRecordPtr->myInsertSize = 0;
// Check the alignment end
assert(samRecord.get0BasedUnclippedStart() == -1);
assert(samRecord.get1BasedUnclippedStart() == 0);
assert(samRecord.get0BasedUnclippedEnd() == -1);
assert(samRecord.get1BasedUnclippedEnd() == 0);
assert(samRecord.get1BasedAlignmentEnd() == 0);
assert(samRecord.get0BasedAlignmentEnd() == -1);
assert(samRecord.getAlignmentLength() == 0);
// Check the accessors.
assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
assert(samRecord.getReadNameLength() ==
expectedRecordPtr->myReadNameLength);
assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
assert(samRecord.getBin() == expectedRecordPtr->myBin);
assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
assert(samRecord.getMateReferenceID() ==
expectedRecordPtr->myMateReferenceID);
assert(strcmp(samRecord.getMateReferenceName(),
expectedMateReferenceName) == 0);
assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
expectedMateReferenceNameOrEqual) == 0);
assert(samRecord.get1BasedMatePosition() ==
expectedRecordPtr->myMatePosition + 1);
assert(samRecord.get0BasedMatePosition() ==
expectedRecordPtr->myMatePosition);
assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
assert(strcmp(samRecord.getReadName(), "Y:16597235+13M13I11M:F:181") == 0);
assert(strcmp(samRecord.getCigar(), "*") == 0);
assert(strcmp(samRecord.getSequence(), "*") == 0);
assert(strcmp(samRecord.getQuality(), "*") == 0);
assert(samRecord.getNumOverlaps(74, 79) == 0);
assert(samRecord.getNumOverlaps(73, 79) == 0);
assert(samRecord.getNumOverlaps(75, 78) == 0);
assert(samRecord.getNumOverlaps(0, 1017) == 0);
assert(samRecord.getNumOverlaps(79, 85) == 0);
assert(samRecord.getNumOverlaps(78, 85) == 0);
assert(samRecord.getNumOverlaps(-1, 1017) == 0);
// No Tags to check, should return false.
assert(samRecord.getNextSamTag(tag, type, &value) == false);
assert(samRecord.getNextSamTag(tag, type, &value) == false);
// Get the record ptr.
bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
// Validate the buffers match.
assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
assert(bufferPtr->myBin == expectedRecordPtr->myBin);
assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
assert(bufferPtr->myMateReferenceID ==
expectedRecordPtr->myMateReferenceID);
assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
// Validate the variable length fields in the buffer.
// Set the pointer to the start of the variable fields.
varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
// Validate the readname.
for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
{
assert(*varPtr == samRecord.getReadName()[i]);
varPtr++;
}
// No cigar to validate.
// No sequence.
// No Quality.
// No Tags.
}
void validateHeader(SamFileHeader& samHeader)
{
validateHeaderFields(samHeader);
validateHeaderString(samHeader);
}
void validateHeaderFields(SamFileHeader& samHeader)
{
const char* value;
////////////////////////////////////////////////////////
// Test getting a specific HD Tag value from the header
// that does not exist.
value = samHeader.getHDTagValue("GO");
assert(strcmp(value, "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific PG Tag value from the header
// that does not exist.
value = samHeader.getPGTagValue("CL", "1");
assert(strcmp(value, "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific SQ Tag value from the header
value = samHeader.getSQTagValue("LN", "1");
assert(value != NULL);
assert(strcmp(value, "247249719") == 0);
value = samHeader.getSQTagValue("LN", "22");
assert(value != NULL);
assert(strcmp(value, "49691432") == 0);
////////////////////////////////////////////////////////
// Test getting a specific SQ Tag value from the header
// that does not exist.
value = samHeader.getSQTagValue("LN", "1000");
assert(strcmp(value, "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific SQ Tag value from the header
// that does not exist - sq exists, but not with that tag.
value = samHeader.getSQTagValue("AS", "1");
assert(strcmp(value, "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific RG Tag value from the header
value = samHeader.getRGTagValue("LB", "myID2");
assert(value != NULL);
assert(strcmp(value, "library2") == 0);
value = samHeader.getRGTagValue("LB", "myID");
assert(value != NULL);
assert(strcmp(value, "library") == 0);
////////////////////////////////////////////////////////
// Test getting a specific SQ from the header
// Then pulling the tags out of it.
SamHeaderSQ* sq = samHeader.getSQ("10");
assert(strcmp(sq->getTagValue("SN"), "10") == 0);
assert(strcmp(sq->getTagValue("LN"), "135374737") == 0);
// Test pulling a tag that does not exist.
assert(strcmp(sq->getTagValue("DD"), "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific RG from the header
// Then pulling the tags out of it.
const SamHeaderRG* rg = samHeader.getRG("myID");
assert(strcmp(rg->getTagValue("ID"), "myID") == 0);
assert(strcmp(rg->getTagValue("SM"), "sample") == 0);
assert(strcmp(rg->getTagValue("LB"), "library") == 0);
// Test pulling a tag that does not exist.
assert(strcmp(rg->getTagValue("DD"), "") == 0);
////////////////////////////////////////////////////////
// Test getting a specific RG from the header that does not exist.
rg = samHeader.getRG("noExist");
assert(rg == NULL);
////////////////////////////////////////////////////////
// Test getting a specific SQ from the header that does not exist.
sq = samHeader.getSQ("noExist");
assert(sq == NULL);
////////////////////////////////////////////////////////
// Test getting the reference ID.
assert(samHeader.getReferenceID("2") == 1);
std::string refIDStdString = "X";
assert(samHeader.getReferenceID(refIDStdString.c_str()) == 22);
String refIDString = "22";
assert(samHeader.getReferenceID(refIDString) == 21);
assert(samHeader.getReferenceID(refIDString.c_str()) == 21);
assert(samHeader.getReferenceID("Z") == SamReferenceInfo::NO_REF_ID);
assert(samHeader.getReferenceID("Z", true) == 23);
assert(samHeader.getReferenceID("*") == -1);
refIDString = "*";
assert(samHeader.getReferenceID(refIDString) == -1);
assert(samHeader.getReferenceID(refIDString.c_str()) == -1);
}
void validateHeaderString(SamFileHeader& samHeader)
{
// Check the header line.
std::string headerString = "";
assert(samHeader.getHeaderString(headerString) == true);
assert(headerString == "@SQ\tSN:1\tLN:247249719\n@SQ\tSN:2\tLN:242951149\n@SQ\tSN:3\tLN:199501827\n@SQ\tSN:4\tLN:191273063\n@SQ\tSN:5\tLN:180857866\n@SQ\tSN:6\tLN:170899992\n@SQ\tSN:7\tLN:158821424\n@SQ\tSN:8\tLN:146274826\n@SQ\tSN:9\tLN:140273252\n@SQ\tSN:10\tLN:135374737\n@SQ\tSN:11\tLN:134452384\n@SQ\tSN:12\tLN:132349534\n@SQ\tSN:13\tLN:114142980\n@SQ\tSN:14\tLN:106368585\n@SQ\tSN:15\tLN:100338915\n@SQ\tSN:16\tLN:88827254\n@SQ\tSN:17\tLN:78774742\n@SQ\tSN:18\tLN:76117153\n@SQ\tSN:19\tLN:63811651\n@SQ\tSN:20\tLN:62435964\n@SQ\tSN:21\tLN:46944323\n@SQ\tSN:22\tLN:49691432\n@SQ\tSN:X\tLN:154913754\n@RG\tID:myID\tLB:library\tSM:sample\n@RG\tID:myID2\tSM:sample2\tLB:library2\n@CO\tComment 1\n@CO\tComment 2\n");
}
BaseUtilities::UNKNOWN_QUALITY_CHAR
static const char UNKNOWN_QUALITY_CHAR
Character used when the quality is unknown.
Definition: BaseUtilities.h:49
SamFileHeader
This class allows a user to get/set the fields in a SAM/BAM Header.
Definition: SamFileHeader.h:35
SamFileHeader::getSQTagValue
const char * getSQTagValue(const char *tag, const char *name)
Get the value associated with the specified tag on the SQ line with the specified sequence name,...
Definition: SamFileHeader.cpp:696
SamFileHeader::getSQ
SamHeaderSQ * getSQ(const char *name)
Get the SQ object with the specified sequence name, returning NULL if there is no SQ object with that...
Definition: SamFileHeader.cpp:775
SamFileHeader::getHDTagValue
const char * getHDTagValue(const char *tag)
Returns the value associated with the specified HD tag, returning "" if the tag does not exist in the...
Definition: SamFileHeader.cpp:683
SamFileHeader::getReferenceID
int getReferenceID(const String &referenceName, bool addID=false)
Get the reference ID for the specified reference name (chromosome).
Definition: SamFileHeader.cpp:146
SamFileHeader::getRGTagValue
const char * getRGTagValue(const char *tag, const char *id)
Get the value associated with the specified tag on the RG line with the specified read group identifi...
Definition: SamFileHeader.cpp:714
SamFileHeader::getHeaderString
bool getHeaderString(std::string &header) const
Set the passed in string to the entire header string, clearing its current contents.
Definition: SamFileHeader.cpp:131
SamFileHeader::getPGTagValue
const char * getPGTagValue(const char *tag, const char *id)
Get the value associated with the specified tag on the RG line with the specified id,...
Definition: SamFileHeader.cpp:730
SamFileHeader::getRG
SamHeaderRG * getRG(const char *id)
Get the RG object with the specified read group identifier, returning NULL if there is no RG object w...
Definition: SamFileHeader.cpp:782
SamHeaderRG
Definition: SamHeaderRG.h:24
SamHeaderRecord::getTagValue
const char * getTagValue(const char *tag) const
Return the value associated with the specified tag.
Definition: SamHeaderRecord.cpp:100
SamHeaderSQ
Definition: SamHeaderSQ.h:24
SamRecord
Class providing an easy to use interface to get/set/operate on the fields in a SAM/BAM record.
Definition: SamRecord.h:52
SamRecord::getBlockSize
int32_t getBlockSize()
Get the block size of the record (BAM format).
Definition: SamRecord.cpp:1281
SamRecord::getCigarLength
uint16_t getCigarLength()
Get the length of the BAM formatted CIGAR.
Definition: SamRecord.cpp:1362
SamRecord::getReferenceName
const char * getReferenceName()
Get the reference sequence name (RNAME) of the record.
Definition: SamRecord.cpp:1298
SamRecord::getInsertSize
int32_t getInsertSize()
Get the inferred insert size of the read pair (ISIZE) or observed template length (TLEN).
Definition: SamRecord.cpp:1459
SamRecord::get0BasedMatePosition
int32_t get0BasedMatePosition()
Get the 0-based(BAM) leftmost mate/next fragment's position.
Definition: SamRecord.cpp:1452
SamRecord::get1BasedPosition
int32_t get1BasedPosition()
Get the 1-based(SAM) leftmost position (POS) of the record.
Definition: SamRecord.cpp:1312
SamRecord::getReferenceID
int32_t getReferenceID()
Get the reference sequence id of the record (BAM format rid).
Definition: SamRecord.cpp:1305
SamRecord::getAlignmentLength
int32_t getAlignmentLength()
Returns the length of the clipped sequence, returning 0 if the cigar is '*'.
Definition: SamRecord.cpp:1493
SamRecord::getInteger
int & getInteger(const char *tag)
Get the integer value for the specified tag, DEPRECATED, use getIntegerTag that returns a bool.
Definition: SamRecord.cpp:2350
SamRecord::get1BasedAlignmentEnd
int32_t get1BasedAlignmentEnd()
Returns the 1-based inclusive rightmost position of the clipped sequence.
Definition: SamRecord.cpp:1486
SamRecord::getReadNameLength
uint8_t getReadNameLength()
Get the length of the readname (QNAME) including the null.
Definition: SamRecord.cpp:1326
SamRecord::getFloatTag
bool getFloatTag(const char *tag, float &tagVal)
Get the float value for the specified tag.
Definition: SamRecord.cpp:2281
SamRecord::getMateReferenceNameOrEqual
const char * getMateReferenceNameOrEqual()
Get the mate/next fragment's reference sequence name (RNEXT), returning "=" if it is the same as the ...
Definition: SamRecord.cpp:1420
SamRecord::get1BasedUnclippedStart
int32_t get1BasedUnclippedStart()
Returns the 1-based inclusive left-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1519
SamRecord::getBin
uint16_t getBin()
Get the BAM bin for the record.
Definition: SamRecord.cpp:1347
SamRecord::getMateReferenceID
int32_t getMateReferenceID()
Get the mate reference id of the record (BAM format: mate_rid/next_refID).
Definition: SamRecord.cpp:1438
SamRecord::getFields
bool getFields(bamRecordStruct &recStruct, String &readName, String &cigar, String &sequence, String &quality)
Returns the values of all fields except the tags.
Definition: SamRecord.cpp:1866
SamRecord::getFlag
uint16_t getFlag()
Get the flag (FLAG).
Definition: SamRecord.cpp:1384
SamRecord::getRecordBuffer
const void * getRecordBuffer()
Get a const pointer to the buffer that contains the BAM representation of the record.
Definition: SamRecord.cpp:1204
SamRecord::get1BasedMatePosition
int32_t get1BasedMatePosition()
Get the 1-based(SAM) leftmost mate/next fragment's position (PNEXT).
Definition: SamRecord.cpp:1445
SamRecord::get0BasedUnclippedEnd
int32_t get0BasedUnclippedEnd()
Returns the 0-based inclusive right-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1526
SamRecord::getStatus
const SamStatus & getStatus()
Returns the status associated with the last method that sets the status.
Definition: SamRecord.cpp:2403
SamRecord::get1BasedUnclippedEnd
int32_t get1BasedUnclippedEnd()
Returns the 1-based inclusive right-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1535
SamRecord::getNumOverlaps
uint32_t getNumOverlaps(int32_t start, int32_t end)
Return the number of bases in this read that overlap the passed in region.
Definition: SamRecord.cpp:1853
SamRecord::getMateReferenceName
const char * getMateReferenceName()
Get the mate/next fragment's reference sequence name (RNEXT).
Definition: SamRecord.cpp:1410
SamRecord::getNextSamTag
bool getNextSamTag(char *tag, char &vtype, void **value)
Get the next tag from the record.
Definition: SamRecord.cpp:1962
SamRecord::get0BasedUnclippedStart
int32_t get0BasedUnclippedStart()
Returns the 0-based inclusive left-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1506
SamRecord::getReadLength
int32_t getReadLength()
Get the length of the read.
Definition: SamRecord.cpp:1391
SamRecord::get0BasedAlignmentEnd
int32_t get0BasedAlignmentEnd()
Returns the 0-based inclusive rightmost position of the clipped sequence.
Definition: SamRecord.cpp:1467
SamRecord::get0BasedPosition
int32_t get0BasedPosition()
Get the 0-based(BAM) leftmost position of the record.
Definition: SamRecord.cpp:1319
SamRecord::getCigar
const char * getCigar()
Returns the SAM formatted CIGAR string.
Definition: SamRecord.cpp:1555
SamRecord::getMapQuality
uint8_t getMapQuality()
Get the mapping quality (MAPQ) of the record.
Definition: SamRecord.cpp:1340
SamRecord::getString
const String & getString(const char *tag)
Get the string value for the specified tag.
Definition: SamRecord.cpp:2314
SamRecord::getReadName
const char * getReadName()
Returns the SAM formatted Read Name (QNAME).
Definition: SamRecord.cpp:1542
SamRecord::getQuality
const char * getQuality()
Returns the SAM formatted quality string (QUAL).
Definition: SamRecord.cpp:1638
SamRecord::getSequence
const char * getSequence()
Returns the SAM formatted sequence string (SEQ), translating the base as specified by setSequenceTran...
Definition: SamRecord.cpp:1568
SamReferenceInfo::NO_REF_ID
static const int NO_REF_ID
Constant for the value returned if a reference id does not exist for a queried reference name.
Definition: SamReferenceInfo.h:77
StatGenStatus::SUCCESS
@ SUCCESS
method completed successfully.
Definition: StatGenStatus.h:32
String
Definition: StringBasics.h:39
bamRecordStruct
Structure of a BAM record.
Definition: SamRecord.h:34