libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "ReadFiles.h" 00019 #include "TestValidate.h" 00020 #include "SamTags.h" 00021 #include <assert.h> 00022 00023 void testReadSam() 00024 { 00025 SamFile inSam; 00026 assert(inSam.OpenForRead("testFiles/testSam.sam")); 00027 00028 // Call generic test which since the sam and bam are identical, should 00029 // contain the same results. 00030 testRead(inSam); 00031 00032 inSam.Close(); 00033 00034 testFlagRead("testFiles/testSam.sam"); 00035 } 00036 00037 void testReadBam() 00038 { 00039 SamFile inSam; 00040 assert(inSam.OpenForRead("testFiles/testBam.bam")); 00041 00042 // Call generic test which since the sam and bam are identical, should 00043 // contain the same results. 00044 testRead(inSam); 00045 00046 inSam.Close(); 00047 00048 testFlagRead("testFiles/testBam.bam"); 00049 } 00050 00051 void testRead(SamFile &inSam) 00052 { 00053 // Read the SAM Header. 00054 SamFileHeader samHeader; 00055 assert(inSam.ReadHeader(samHeader)); 00056 00057 validateHeader(samHeader); 00058 00059 testCopyHeader(samHeader); 00060 00061 testModHeader(samHeader); 00062 00063 SamRecord samRecord; 00064 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00065 validateRead1(samRecord); 00066 00067 // Set a new quality and get the buffer. 00068 samRecord.setQuality("ABCDE"); 00069 validateRead1ModQuality(samRecord); 00070 // void* buffer = samRecord.getRecordBuffer(); 00071 00072 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00073 validateRead2(samRecord); 00074 00075 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00076 validateRead3(samRecord); 00077 00078 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00079 validateRead4(samRecord); 00080 00081 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00082 validateRead5(samRecord); 00083 00084 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00085 validateRead6(samRecord); 00086 00087 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00088 validateRead7(samRecord); 00089 00090 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00091 validateRead8(samRecord); 00092 00093 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00094 validateRead9(samRecord); 00095 00096 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00097 validateRead10(samRecord); 00098 } 00099 00100 00101 void testAddHeaderAndTagToFile(const char* inputName, const char* outputName) 00102 { 00103 SamFile inSam, outSam; 00104 assert(inSam.OpenForRead(inputName)); 00105 assert(outSam.OpenForWrite(outputName)); 00106 00107 // Read the SAM Header. 00108 SamFileHeader samHeader; 00109 assert(inSam.ReadHeader(samHeader)); 00110 00111 // Add a header line. 00112 assert(samHeader.addHeaderLine("@RG\tID:myID\tSM:mySM") == false); 00113 assert(samHeader.addHeaderLine("@RG\tID:myID3\tSM:mySM") == true); 00114 00115 // Write Header 00116 assert(outSam.WriteHeader(samHeader)); 00117 00118 SamRecord samRecord; 00119 assert(inSam.ReadRecord(samHeader, samRecord)); 00120 // validateRead1(samRecord); 00121 // Add two tags. 00122 assert(samRecord.addIntTag("XA", 123)); 00123 assert(samRecord.addIntTag("XA", 456)); 00124 assert(samRecord.addTag("RR", 'Z', "myID1")); 00125 assert(samRecord.addTag("RR", 'Z', "myID2")); 00126 00127 // Write as Sam. 00128 assert(outSam.WriteRecord(samHeader, samRecord)); 00129 00130 // TODO, add test to verify it was written correctly. 00131 00132 // Read a couple of records to make sure it properly can read them even 00133 // if they are bigger than the original. 00134 assert(inSam.ReadRecord(samHeader, samRecord)); 00135 assert(inSam.ReadRecord(samHeader, samRecord)); 00136 00137 // Check the MD tag, which requires the reference. 00138 GenomeSequence reference("testFiles/chr1_partial.fa"); 00139 assert(SamTags::isMDTagCorrect(samRecord, reference) == false); 00140 String newMDTag; 00141 SamTags::createMDTag(newMDTag, samRecord, reference); 00142 assert(newMDTag == "2T1N0"); 00143 assert(SamTags::updateMDTag(samRecord, reference)); 00144 // Write as Sam. 00145 assert(outSam.WriteRecord(samHeader, samRecord)); 00146 } 00147 00148 00149 // Test reading a file, validating it is sorted. 00150 void testValidateSortedRead() 00151 { 00152 // Open a file for reading. 00153 SamFile inSam(ErrorHandler::RETURN); 00154 assert(inSam.OpenForRead("testFiles/testSam.sam")); 00155 00156 // Set the validation to COORDINATE. 00157 inSam.setSortedValidation(SamFile::COORDINATE); 00158 00159 // Read the SAM Header. 00160 SamFileHeader samHeader; 00161 assert(inSam.ReadHeader(samHeader)); 00162 00163 SamRecord samRecord; 00164 // Succeed, first record. 00165 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00166 validateRead1(samRecord); 00167 00168 // Succeed, higher coordinate. 00169 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00170 validateRead2(samRecord); 00171 00172 // Failed sort order - due to coord. 00173 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00174 validateRead3(samRecord); 00175 00176 // Failed sort order - due to coord. 00177 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00178 validateRead4(samRecord); 00179 00180 // Succeed, new reference id 00181 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00182 validateRead5(samRecord); 00183 00184 // Fail, previous reference id. 00185 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00186 validateRead6(samRecord); 00187 00188 // Succeed, same reference id, higher coord. 00189 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00190 validateRead7(samRecord); 00191 00192 // Succeed, *, new reference id. 00193 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00194 validateRead8(samRecord); 00195 00196 // Fail, reference id is not * 00197 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00198 validateRead9(samRecord); 00199 00200 // Succeed, valid reference id, and no coordinate. 00201 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00202 validateRead10(samRecord); 00203 00204 00205 //////////////////////////////////////////// 00206 // Reopen the file for reading 00207 assert(inSam.OpenForRead("testFiles/testSam.sam")); 00208 00209 // Set the validation to QUERY_NAME. 00210 inSam.setSortedValidation(SamFile::QUERY_NAME); 00211 00212 // Read the SAM Header. 00213 assert(inSam.ReadHeader(samHeader)); 00214 00215 // Succeed, first record. 00216 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00217 validateRead1(samRecord); 00218 00219 // Succeed, same name. 00220 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00221 validateRead2(samRecord); 00222 00223 // Succeeds - numeric sort 00224 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00225 validateRead3(samRecord); 00226 00227 // Succeeds - numeric sort 00228 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00229 validateRead4(samRecord); 00230 00231 // Succeeds - numeric sort 00232 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00233 validateRead5(samRecord); 00234 00235 // Succeeds - numeric sort 00236 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00237 validateRead6(samRecord); 00238 00239 // Succeeds - numeric sort 00240 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00241 validateRead7(samRecord); 00242 00243 // Succeed - std sort 00244 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00245 validateRead8(samRecord); 00246 00247 // Succeed - numeric sort (Y<18) 00248 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00249 validateRead9(samRecord); 00250 00251 // Succeed - std sort 00252 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00253 validateRead10(samRecord); 00254 00255 //////////////////////////////////////////// 00256 // Reopen the file for reading 00257 assert(inSam.OpenForRead("testFiles/testSam.sam")); 00258 00259 // Set the validation to the SO Flag. Not set, so it is UNSORTED, so 00260 // all reads should pass. 00261 inSam.setSortedValidation(SamFile::FLAG); 00262 00263 // Read the SAM Header. 00264 assert(inSam.ReadHeader(samHeader)); 00265 00266 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00267 validateRead1(samRecord); 00268 00269 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00270 validateRead2(samRecord); 00271 00272 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00273 validateRead3(samRecord); 00274 00275 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00276 validateRead4(samRecord); 00277 00278 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00279 validateRead5(samRecord); 00280 00281 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00282 validateRead6(samRecord); 00283 00284 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00285 validateRead7(samRecord); 00286 00287 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00288 validateRead8(samRecord); 00289 00290 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00291 validateRead9(samRecord); 00292 00293 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00294 validateRead10(samRecord); 00295 00296 //////////////////////////////////////////// 00297 // Reopen for reading SO FLAG set to coordinate. 00298 assert(inSam.OpenForRead("testFiles/testSamSOcoord.sam")); 00299 00300 // Set the validation to SO FLAG which is set to coordinate. 00301 inSam.setSortedValidation(SamFile::FLAG); 00302 00303 // Read the SAM Header. 00304 assert(inSam.ReadHeader(samHeader)); 00305 00306 // Succeed, first record. 00307 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00308 validateRead1(samRecord); 00309 00310 // Succeed, higher coordinate. 00311 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00312 validateRead2(samRecord); 00313 00314 // Failed sort order - due to coord. 00315 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00316 validateRead3(samRecord); 00317 00318 // Failed sort order - due to coord. 00319 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00320 validateRead4(samRecord); 00321 00322 // Succeed, new reference id 00323 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00324 validateRead5(samRecord); 00325 00326 // Fail, previous reference id. 00327 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00328 validateRead6(samRecord); 00329 00330 // Succeed, same reference id, higher coord. 00331 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00332 validateRead7(samRecord); 00333 00334 // Succeed, *, new reference id. 00335 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00336 validateRead8(samRecord); 00337 00338 // Fail, reference id is not * 00339 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00340 validateRead9(samRecord); 00341 00342 // Succeed, valid reference id, and no coordinate. 00343 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00344 validateRead10(samRecord); 00345 00346 00347 //////////////////////////////////////////// 00348 // Reopen the file for reading 00349 assert(inSam.OpenForRead("testFiles/testSamSOquery.sam")); 00350 00351 // Set the validation to FLAG, SO set to queryname. 00352 inSam.setSortedValidation(SamFile::FLAG); 00353 00354 // Read the SAM Header. 00355 assert(inSam.ReadHeader(samHeader)); 00356 00357 // Succeed, first record. 00358 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00359 validateRead1(samRecord); 00360 00361 // Succeed, same name. 00362 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00363 validateRead2(samRecord); 00364 00365 // Succeeds - numeric sort 00366 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00367 validateRead3(samRecord); 00368 00369 // Succeeds - numeric sort 00370 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00371 validateRead4(samRecord); 00372 00373 // Succeeds - numeric sort 00374 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00375 validateRead5(samRecord); 00376 00377 // Succeeds - numeric sort 00378 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00379 validateRead6(samRecord); 00380 00381 // Succeeds - numeric sort 00382 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00383 validateRead7(samRecord); 00384 00385 // Succeed - std sort 00386 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00387 validateRead8(samRecord); 00388 00389 // Succeed - numeric sort (Y<18) 00390 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00391 validateRead9(samRecord); 00392 00393 // Succeed - std sort 00394 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00395 validateRead10(samRecord); 00396 00397 //////////////////////////////////////////// 00398 // Reopen the file for reading, SO flag set to junk. 00399 assert(inSam.OpenForRead("testFiles/testSamSOinvalid.sam")); 00400 00401 // Set the validation to the SO Flag. Not set to anything valid, 00402 // so it is considered UNSORTED, so all reads should pass. 00403 inSam.setSortedValidation(SamFile::FLAG); 00404 00405 // Read the SAM Header. 00406 assert(inSam.ReadHeader(samHeader)); 00407 00408 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00409 validateRead1(samRecord); 00410 00411 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00412 validateRead2(samRecord); 00413 00414 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00415 validateRead3(samRecord); 00416 00417 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00418 validateRead4(samRecord); 00419 00420 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00421 validateRead5(samRecord); 00422 00423 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00424 validateRead6(samRecord); 00425 00426 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00427 validateRead7(samRecord); 00428 00429 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00430 validateRead8(samRecord); 00431 00432 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00433 validateRead9(samRecord); 00434 00435 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00436 validateRead10(samRecord); 00437 } 00438 00439 00440 00441 void validateRead1ModQuality(SamRecord& samRecord) 00442 { 00443 ////////////////////////////////////////// 00444 // Validate Record 1 00445 // Create record structure for validating. 00446 int expectedBlockSize = 89; 00447 const char* expectedReferenceName = "1"; 00448 const char* expectedMateReferenceName = "1"; 00449 const char* expectedMateReferenceNameOrEqual = "="; 00450 00451 bamRecordStruct* expectedRecordPtr = 00452 (bamRecordStruct *) malloc(expectedBlockSize + sizeof(int)); 00453 00454 char tag[3]; 00455 char type; 00456 void* value; 00457 bamRecordStruct* bufferPtr; 00458 unsigned char* varPtr; 00459 00460 expectedRecordPtr->myBlockSize = expectedBlockSize; 00461 expectedRecordPtr->myReferenceID = 0; 00462 expectedRecordPtr->myPosition = 1010; 00463 expectedRecordPtr->myReadNameLength = 23; 00464 expectedRecordPtr->myMapQuality = 0; 00465 expectedRecordPtr->myBin = 4681; 00466 expectedRecordPtr->myCigarLength = 2; 00467 expectedRecordPtr->myFlag = 73; 00468 expectedRecordPtr->myReadLength = 5; 00469 expectedRecordPtr->myMateReferenceID = 0; 00470 expectedRecordPtr->myMatePosition = 1010; 00471 expectedRecordPtr->myInsertSize = 0; 00472 00473 // Check the alignment end 00474 assert(samRecord.get0BasedAlignmentEnd() == 1016); 00475 assert(samRecord.get1BasedAlignmentEnd() == 1017); 00476 assert(samRecord.getAlignmentLength() == 7); 00477 assert(samRecord.get0BasedUnclippedStart() == 1010); 00478 assert(samRecord.get1BasedUnclippedStart() == 1011); 00479 assert(samRecord.get0BasedUnclippedEnd() == 1016); 00480 assert(samRecord.get1BasedUnclippedEnd() == 1017); 00481 00482 // Check the accessors. 00483 assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize); 00484 assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID); 00485 assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0); 00486 assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1); 00487 assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition); 00488 assert(samRecord.getReadNameLength() == 00489 expectedRecordPtr->myReadNameLength); 00490 assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality); 00491 assert(samRecord.getBin() == expectedRecordPtr->myBin); 00492 assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength); 00493 assert(samRecord.getFlag() == expectedRecordPtr->myFlag); 00494 assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength); 00495 assert(samRecord.getMateReferenceID() == 00496 expectedRecordPtr->myMateReferenceID); 00497 assert(strcmp(samRecord.getMateReferenceName(), 00498 expectedMateReferenceName) == 0); 00499 assert(strcmp(samRecord.getMateReferenceNameOrEqual(), 00500 expectedMateReferenceNameOrEqual) == 0); 00501 assert(samRecord.get1BasedMatePosition() == 00502 expectedRecordPtr->myMatePosition + 1); 00503 assert(samRecord.get0BasedMatePosition() == 00504 expectedRecordPtr->myMatePosition); 00505 assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize); 00506 assert(strcmp(samRecord.getReadName(), "1:1011:F:255+17M15D20M") == 0); 00507 assert(strcmp(samRecord.getCigar(), "5M2D") == 0); 00508 assert(strcmp(samRecord.getSequence(), "CCGAA") == 0); 00509 assert(strcmp(samRecord.getQuality(), "ABCDE") == 0); 00510 assert(samRecord.getNumOverlaps(1010, 1017) == 5); 00511 assert(samRecord.getNumOverlaps(1010, 1016) == 5); 00512 assert(samRecord.getNumOverlaps(1012, 1017) == 3); 00513 assert(samRecord.getNumOverlaps(1015, 1017) == 0); 00514 assert(samRecord.getNumOverlaps(1017, 1010) == 0); 00515 assert(samRecord.getNumOverlaps(1013, 1011) == 0); 00516 assert(samRecord.getNumOverlaps(-1, 1017) == 5); 00517 00518 // Reset the tag iter, since the tags have already been read. 00519 samRecord.resetTagIter(); 00520 00521 // Check the tags. 00522 assert(samRecord.getNextSamTag(tag, type, &value) == true); 00523 assert(tag[0] == 'A'); 00524 assert(tag[1] == 'M'); 00525 assert(type == 'i'); 00526 assert(*(char*)value == 0); 00527 assert(samRecord.getNextSamTag(tag, type, &value) == true); 00528 assert(tag[0] == 'M'); 00529 assert(tag[1] == 'D'); 00530 assert(type == 'Z'); 00531 assert(*(String*)value == "37"); 00532 assert(samRecord.getNextSamTag(tag, type, &value) == true); 00533 assert(tag[0] == 'N'); 00534 assert(tag[1] == 'M'); 00535 assert(type == 'i'); 00536 assert(*(char*)value == 0); 00537 assert(samRecord.getNextSamTag(tag, type, &value) == true); 00538 assert(tag[0] == 'X'); 00539 assert(tag[1] == 'T'); 00540 assert(type == 'A'); 00541 assert(*(char*)value == 'R'); 00542 // No more tags, should return false. 00543 assert(samRecord.getNextSamTag(tag, type, &value) == false); 00544 assert(samRecord.getNextSamTag(tag, type, &value) == false); 00545 00546 // Get the record ptr. 00547 bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer(); 00548 // Validate the buffers match. 00549 assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize); 00550 assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID); 00551 assert(bufferPtr->myPosition == expectedRecordPtr->myPosition); 00552 assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength); 00553 assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality); 00554 assert(bufferPtr->myBin == expectedRecordPtr->myBin); 00555 assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength); 00556 assert(bufferPtr->myFlag == expectedRecordPtr->myFlag); 00557 assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength); 00558 assert(bufferPtr->myMateReferenceID == 00559 expectedRecordPtr->myMateReferenceID); 00560 assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition); 00561 assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize); 00562 00563 // Validate the variable length fields in the buffer. 00564 // Set the pointer to the start of the variable fields. 00565 varPtr = (unsigned char*)(&(bufferPtr->myData[0])); 00566 00567 // Validate the readname. 00568 for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++) 00569 { 00570 assert(*varPtr == samRecord.getReadName()[i]); 00571 varPtr++; 00572 } 00573 00574 // Validate the cigar. 00575 // The First cigar is 5M which is 5 << 4 | 0 = 80 00576 assert(*(unsigned int*)varPtr == 80); 00577 // Increment the varptr the size of an int. 00578 varPtr += 4; 00579 // The 2nd cigar is 2D which is 2 << 4 | 2 = 34 00580 assert(*(unsigned int*)varPtr == 34); 00581 // Increment the varptr the size of an int. 00582 varPtr += 4; 00583 00584 // Validate the sequence. 00585 // CC = 0x22 00586 assert(*varPtr == 0x22); 00587 varPtr++; 00588 // GA = 0x41 00589 assert(*varPtr == 0x41); 00590 varPtr++; 00591 // A = 0x10 00592 assert(*varPtr == 0x10); 00593 varPtr++; 00594 00595 // Validate the Quality 00596 for(int i = 0; i < expectedRecordPtr->myReadLength; i++) 00597 { 00598 assert(*varPtr == samRecord.getQuality()[i] - 33); 00599 varPtr++; 00600 } 00601 00602 // Validate the tags. 00603 assert(*varPtr == 'A'); 00604 varPtr++; 00605 assert(*varPtr == 'M'); 00606 varPtr++; 00607 assert(*varPtr == 'C'); 00608 varPtr++; 00609 assert(*varPtr == 0); 00610 varPtr++; 00611 assert(*varPtr == 'M'); 00612 varPtr++; 00613 assert(*varPtr == 'D'); 00614 varPtr++; 00615 assert(*varPtr == 'Z'); 00616 varPtr++; 00617 assert(*varPtr == '3'); 00618 varPtr++; 00619 assert(*varPtr == '7'); 00620 varPtr++; 00621 assert(*varPtr == 0); 00622 varPtr++; 00623 assert(*varPtr == 'N'); 00624 varPtr++; 00625 assert(*varPtr == 'M'); 00626 varPtr++; 00627 assert(*varPtr == 'C'); 00628 varPtr++; 00629 assert(*varPtr == 0); 00630 varPtr++; 00631 assert(*varPtr == 'X'); 00632 varPtr++; 00633 assert(*varPtr == 'T'); 00634 varPtr++; 00635 assert(*varPtr == 'A'); 00636 varPtr++; 00637 assert(*varPtr == 'R'); 00638 varPtr++; 00639 } 00640 00641 00642 void testModHeader(SamFileHeader& samHeader) 00643 { 00644 // Check the header line. 00645 std::string headerString = ""; 00646 assert(samHeader.getHeaderString(headerString) == true); 00647 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"); 00648 00649 // Remove a tag - by setting it to "". 00650 assert(samHeader.setRGTag("LB", "", "myID2") == true); 00651 00652 00653 // Check the header line. 00654 assert(samHeader.getHeaderString(headerString) == true); 00655 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\n@CO\tComment 1\n@CO\tComment 2\n"); 00656 00657 // Add an HD tag. 00658 SamHeaderHD* hd = new SamHeaderHD(); 00659 assert(hd->setTag("VN", "1.3") == true); 00660 assert(samHeader.addHD(hd) == true); 00661 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") == 0); 00662 assert(samHeader.getHeaderString(headerString) == true); 00663 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\n@HD\tVN:1.3\n@CO\tComment 1\n@CO\tComment 2\n"); 00664 00665 // Try adding another HD tag. 00666 SamHeaderHD* hd2 = new SamHeaderHD(); 00667 assert(hd2->setTag("VN", "1.4") == true); 00668 assert(samHeader.addHD(hd2) == false); 00669 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") != 0); 00670 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") == 0); 00671 assert(samHeader.getHeaderString(headerString) == true); 00672 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\n@HD\tVN:1.3\n@CO\tComment 1\n@CO\tComment 2\n"); 00673 00674 // Remove the entire HD Tag. 00675 assert(samHeader.removeHD() == true); 00676 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0); 00677 assert(samHeader.getHeaderString(headerString) == true); 00678 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\n@CO\tComment 1\n@CO\tComment 2\n"); 00679 00680 // Remove an entire SQ Tag. 00681 assert(strcmp(samHeader.getSQTagValue("LN", "11"), "134452384") == 0); 00682 assert(samHeader.removeSQ("11") == true); 00683 assert(strcmp(samHeader.getSQTagValue("LN", "11"), "") == 0); 00684 assert(samHeader.getHeaderString(headerString) == true); 00685 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: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\n@CO\tComment 1\n@CO\tComment 2\n"); 00686 00687 // Try adding a null HD tag. 00688 hd = NULL; 00689 assert(samHeader.addHD(hd) == false); 00690 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0); 00691 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") != 0); 00692 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") != 0); 00693 assert(samHeader.getHeaderString(headerString) == true); 00694 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: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\n@CO\tComment 1\n@CO\tComment 2\n"); 00695 00696 // Try adding a null SQ tag. 00697 SamHeaderSQ* sq = NULL; 00698 assert(samHeader.addSQ(sq) == false); 00699 assert(samHeader.getHeaderString(headerString) == true); 00700 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: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\n@CO\tComment 1\n@CO\tComment 2\n"); 00701 00702 // Try adding an HD tag again. 00703 assert(samHeader.addHD(hd2) == true); 00704 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") == 0); 00705 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") != 0); 00706 assert(samHeader.getHeaderString(headerString) == true); 00707 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: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\n@HD\tVN:1.4\n@CO\tComment 1\n@CO\tComment 2\n"); 00708 00709 00710 // TODO Get the comments. 00711 00712 } 00713 00714 00715 00716 void testFlagRead(const char* fileName) 00717 { 00718 SamFile inSam; 00719 SamFileHeader samHeader; 00720 SamRecord samRecord; 00721 00722 //////////////////////////////////////////////////////////// 00723 // Required flag 0x48 (only flag 73 matches) 00724 // Exclude nothing 00725 assert(inSam.OpenForRead(fileName)); 00726 assert(inSam.ReadHeader(samHeader)); 00727 validateHeader(samHeader); 00728 inSam.SetReadFlags(0x48, 0x0); 00729 00730 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00731 validateRead1(samRecord); 00732 00733 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00734 00735 inSam.Close(); 00736 00737 //////////////////////////////////////////////////////////// 00738 // No required flags. 00739 // Exclude 0x48. This leaves just the one read with flag 133. 00740 assert(inSam.OpenForRead(fileName)); 00741 assert(inSam.ReadHeader(samHeader)); 00742 validateHeader(samHeader); 00743 inSam.SetReadFlags(0x0, 0x48); 00744 00745 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00746 validateRead2(samRecord); 00747 00748 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00749 00750 inSam.Close(); 00751 00752 //////////////////////////////////////////////////////////// 00753 // Required flag 0x40 00754 // Exclude 0x48. 00755 // This will not find any records since the exclude and required conflict. 00756 assert(inSam.OpenForRead(fileName)); 00757 assert(inSam.ReadHeader(samHeader)); 00758 validateHeader(samHeader); 00759 inSam.SetReadFlags(0x40, 0x48); 00760 00761 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00762 00763 inSam.Close(); 00764 00765 //////////////////////////////////////////////////////////// 00766 // Required flag 0x4 00767 // Exclude 0x8. 00768 // Only finds flag 133. 00769 assert(inSam.OpenForRead(fileName)); 00770 assert(inSam.ReadHeader(samHeader)); 00771 validateHeader(samHeader); 00772 inSam.SetReadFlags(0x4, 0x8); 00773 00774 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00775 validateRead2(samRecord); 00776 00777 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00778 00779 inSam.Close(); 00780 00781 //////////////////////////////////////////////////////////// 00782 // Required flag 0x4 00783 // Exclude nothing 00784 // Finds flags 133 & 141. 00785 assert(inSam.OpenForRead(fileName)); 00786 assert(inSam.ReadHeader(samHeader)); 00787 validateHeader(samHeader); 00788 inSam.SetReadFlags(0x4, 0x0); 00789 00790 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00791 validateRead2(samRecord); 00792 00793 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00794 validateRead8(samRecord); 00795 00796 assert(inSam.ReadRecord(samHeader, samRecord) == true); 00797 validateRead10(samRecord); 00798 00799 assert(inSam.ReadRecord(samHeader, samRecord) == false); 00800 00801 inSam.Close(); 00802 } 00803 00804 00805 void testCopyHeader(SamFileHeader& samHeader) 00806 { 00807 // Copy the header. 00808 SamFileHeader samHeader2; 00809 00810 SamHeaderRecord* recPtr = samHeader.getNextHeaderRecord(); 00811 while(recPtr != NULL) 00812 { 00813 samHeader2.addRecordCopy(*recPtr); 00814 recPtr = samHeader.getNextHeaderRecord(); 00815 } 00816 // Add the comments. 00817 std::string nextComment = samHeader.getNextComment(); 00818 while(nextComment != SamFileHeader::EMPTY_RETURN) 00819 { 00820 samHeader2.addComment(nextComment.c_str()); 00821 nextComment = samHeader.getNextComment(); 00822 } 00823 // Validate the header. 00824 validateHeader(samHeader2); 00825 }