libStatGen Software 1
Loading...
Searching...
No Matches
ReadFiles.cpp
1/*
2 * Copyright (C) 2010 Regents of the University of Michigan
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ReadFiles.h"
19#include "TestValidate.h"
20#include "SamTags.h"
21#include <assert.h>
22
23void testReadSam()
24{
25 SamFileHeader samHdr;
26 SamFile inSam1("testFiles/testSam1.sam", SamFile::READ, &samHdr);
27 assert(!inSam1.IsEOF());
28 SamRecord rec;
29 assert(inSam1.ReadRecord(samHdr, rec) == true);
30 assert(inSam1.IsEOF());
31
32 SamFile inSam;
33 assert(inSam.OpenForRead("testFiles/testSam.sam"));
34
35 // Call generic test which since the sam and bam are identical, should
36 // contain the same results.
37 testRead(inSam);
38
39 inSam.Close();
40
41 testFlagRead("testFiles/testSam.sam");
42}
43
44void testReadBam()
45{
46 SamFileHeader samHdr;
47 SamFile inSam1("testFiles/testBam1.bam", SamFile::READ, &samHdr);
48 assert(!inSam1.IsEOF());
49 SamRecord rec;
50 assert(inSam1.ReadRecord(samHdr, rec) == true);
51 assert(inSam1.IsEOF());
52
53 SamFile inSam;
54 assert(inSam.OpenForRead("testFiles/testBam.bam"));
55
56 // Call generic test which since the sam and bam are identical, should
57 // contain the same results.
58 testRead(inSam);
59
60 inSam.Close();
61
62 testFlagRead("testFiles/testBam.bam");
63}
64
65void testRead(SamFile &inSam)
66{
67 // Read the SAM Header.
68 SamFileHeader samHeader;
69 assert(inSam.ReadHeader(samHeader));
70 assert(!inSam.IsEOF());
71
72 validateHeader(samHeader);
73
74 testCopyHeader(samHeader);
75
76 testModHeader(samHeader);
77
78 SamRecord samRecord;
79 assert(inSam.ReadRecord(samHeader, samRecord) == true);
80 validateRead1(samRecord);
81
82 // Set a new quality and get the buffer.
83 samRecord.setQuality("ABCDE");
84 validateRead1ModQuality(samRecord);
85 // void* buffer = samRecord.getRecordBuffer();
86
87 assert(inSam.ReadRecord(samHeader, samRecord) == true);
88 validateRead2(samRecord);
89
90 assert(inSam.ReadRecord(samHeader, samRecord) == true);
91 validateRead3(samRecord);
92
93 assert(inSam.ReadRecord(samHeader, samRecord) == true);
94 validateRead4(samRecord);
95
96 assert(inSam.ReadRecord(samHeader, samRecord) == true);
97 validateRead5(samRecord);
98
99 assert(inSam.ReadRecord(samHeader, samRecord) == true);
100 validateRead6(samRecord);
101
102 assert(inSam.ReadRecord(samHeader, samRecord) == true);
103 validateRead7(samRecord);
104
105 assert(inSam.ReadRecord(samHeader, samRecord) == true);
106 validateRead8(samRecord);
107
108 assert(inSam.ReadRecord(samHeader, samRecord) == true);
109 validateRead9(samRecord);
110
111 assert(inSam.ReadRecord(samHeader, samRecord) == true);
112 validateRead10(samRecord);
113}
114
115
116void testAddHeaderAndTagToFile(const char* inputName, const char* outputName)
117{
118 SamFile inSam, outSam;
119 assert(inSam.OpenForRead(inputName));
120 assert(outSam.OpenForWrite(outputName));
121
122 // Read the SAM Header.
123 SamFileHeader samHeader;
124 assert(inSam.ReadHeader(samHeader));
125
126 // Add a header line.
127 assert(samHeader.addHeaderLine("@RG\tID:myID\tSM:mySM") == false);
128 assert(samHeader.addHeaderLine("@RG\tID:myID3\tSM:mySM") == true);
129
130 // Write Header
131 assert(outSam.WriteHeader(samHeader));
132
133 SamRecord samRecord;
134 assert(inSam.ReadRecord(samHeader, samRecord));
135 // validateRead1(samRecord);
136 // Add two tags.
137 assert(samRecord.addIntTag("XA", 123));
138 assert(samRecord.addIntTag("XA", 456));
139 assert(samRecord.addTag("RR", 'Z', "myID1"));
140 assert(samRecord.addTag("RR", 'Z', "myID2"));
141
142 // Write as Sam.
143 assert(outSam.WriteRecord(samHeader, samRecord));
144
145 // TODO, add test to verify it was written correctly.
146
147 // Read a couple of records to make sure it properly can read them even
148 // if they are bigger than the original.
149 assert(inSam.ReadRecord(samHeader, samRecord));
150 assert(inSam.ReadRecord(samHeader, samRecord));
151
152 // Check the MD tag, which requires the reference.
153 GenomeSequence reference("testFiles/chr1_partial.fa");
154 assert(SamTags::isMDTagCorrect(samRecord, reference) == false);
155 String newMDTag;
156 SamTags::createMDTag(newMDTag, samRecord, reference);
157 assert(newMDTag == "2T1N0");
158 assert(SamTags::updateMDTag(samRecord, reference));
159 // Write as Sam.
160 assert(outSam.WriteRecord(samHeader, samRecord));
161}
162
163
164// Test reading a file, validating it is sorted.
165void testValidateSortedRead()
166{
167 // Open a file for reading.
169 assert(inSam.OpenForRead("testFiles/testSam.sam"));
170
171 // Set the validation to COORDINATE.
173
174 // Read the SAM Header.
175 SamFileHeader samHeader;
176 assert(inSam.ReadHeader(samHeader));
177
178 SamRecord samRecord;
179 // Succeed, first record.
180 assert(inSam.ReadRecord(samHeader, samRecord) == true);
181 validateRead1(samRecord);
182
183 // Succeed, higher coordinate.
184 assert(inSam.ReadRecord(samHeader, samRecord) == true);
185 validateRead2(samRecord);
186
187 // Failed sort order - due to coord.
188 assert(inSam.ReadRecord(samHeader, samRecord) == false);
189 validateRead3(samRecord);
190
191 // Failed sort order - due to coord.
192 assert(inSam.ReadRecord(samHeader, samRecord) == false);
193 validateRead4(samRecord);
194
195 // Succeed, new reference id
196 assert(inSam.ReadRecord(samHeader, samRecord) == true);
197 validateRead5(samRecord);
198
199 // Fail, previous reference id.
200 assert(inSam.ReadRecord(samHeader, samRecord) == false);
201 validateRead6(samRecord);
202
203 // Succeed, same reference id, higher coord.
204 assert(inSam.ReadRecord(samHeader, samRecord) == true);
205 validateRead7(samRecord);
206
207 // Succeed, *, new reference id.
208 assert(inSam.ReadRecord(samHeader, samRecord) == true);
209 validateRead8(samRecord);
210
211 // Fail, reference id is not *
212 assert(inSam.ReadRecord(samHeader, samRecord) == false);
213 validateRead9(samRecord);
214
215 // Succeed, valid reference id, and no coordinate.
216 assert(inSam.ReadRecord(samHeader, samRecord) == true);
217 validateRead10(samRecord);
218
219
220 ////////////////////////////////////////////
221 // Reopen the file for reading
222 assert(inSam.OpenForRead("testFiles/testSam.sam"));
223
224 // Set the validation to QUERY_NAME.
226
227 // Read the SAM Header.
228 assert(inSam.ReadHeader(samHeader));
229
230 // Succeed, first record.
231 assert(inSam.ReadRecord(samHeader, samRecord) == true);
232 validateRead1(samRecord);
233
234 // Succeed, same name.
235 assert(inSam.ReadRecord(samHeader, samRecord) == true);
236 validateRead2(samRecord);
237
238 // Succeeds - numeric sort
239 assert(inSam.ReadRecord(samHeader, samRecord) == true);
240 validateRead3(samRecord);
241
242 // Succeeds - numeric sort
243 assert(inSam.ReadRecord(samHeader, samRecord) == true);
244 validateRead4(samRecord);
245
246 // Succeeds - numeric sort
247 assert(inSam.ReadRecord(samHeader, samRecord) == true);
248 validateRead5(samRecord);
249
250 // Succeeds - numeric sort
251 assert(inSam.ReadRecord(samHeader, samRecord) == true);
252 validateRead6(samRecord);
253
254 // Succeeds - numeric sort
255 assert(inSam.ReadRecord(samHeader, samRecord) == true);
256 validateRead7(samRecord);
257
258 // Succeed - std sort
259 assert(inSam.ReadRecord(samHeader, samRecord) == true);
260 validateRead8(samRecord);
261
262 // Succeed - numeric sort (Y<18)
263 assert(inSam.ReadRecord(samHeader, samRecord) == true);
264 validateRead9(samRecord);
265
266 // Succeed - std sort
267 assert(inSam.ReadRecord(samHeader, samRecord) == true);
268 validateRead10(samRecord);
269
270 ////////////////////////////////////////////
271 // Reopen the file for reading
272 assert(inSam.OpenForRead("testFiles/testSam.sam"));
273
274 // Set the validation to the SO Flag. Not set, so it is UNSORTED, so
275 // all reads should pass.
277
278 // Read the SAM Header.
279 assert(inSam.ReadHeader(samHeader));
280
281 assert(inSam.ReadRecord(samHeader, samRecord) == true);
282 validateRead1(samRecord);
283
284 assert(inSam.ReadRecord(samHeader, samRecord) == true);
285 validateRead2(samRecord);
286
287 assert(inSam.ReadRecord(samHeader, samRecord) == true);
288 validateRead3(samRecord);
289
290 assert(inSam.ReadRecord(samHeader, samRecord) == true);
291 validateRead4(samRecord);
292
293 assert(inSam.ReadRecord(samHeader, samRecord) == true);
294 validateRead5(samRecord);
295
296 assert(inSam.ReadRecord(samHeader, samRecord) == true);
297 validateRead6(samRecord);
298
299 assert(inSam.ReadRecord(samHeader, samRecord) == true);
300 validateRead7(samRecord);
301
302 assert(inSam.ReadRecord(samHeader, samRecord) == true);
303 validateRead8(samRecord);
304
305 assert(inSam.ReadRecord(samHeader, samRecord) == true);
306 validateRead9(samRecord);
307
308 assert(inSam.ReadRecord(samHeader, samRecord) == true);
309 validateRead10(samRecord);
310
311 ////////////////////////////////////////////
312 // Reopen for reading SO FLAG set to coordinate.
313 assert(inSam.OpenForRead("testFiles/testSamSOcoord.sam"));
314
315 // Set the validation to SO FLAG which is set to coordinate.
317
318 // Read the SAM Header.
319 assert(inSam.ReadHeader(samHeader));
320
321 // Succeed, first record.
322 assert(inSam.ReadRecord(samHeader, samRecord) == true);
323 validateRead1(samRecord);
324
325 // Succeed, higher coordinate.
326 assert(inSam.ReadRecord(samHeader, samRecord) == true);
327 validateRead2(samRecord);
328
329 // Failed sort order - due to coord.
330 assert(inSam.ReadRecord(samHeader, samRecord) == false);
331 validateRead3(samRecord);
332
333 // Failed sort order - due to coord.
334 assert(inSam.ReadRecord(samHeader, samRecord) == false);
335 validateRead4(samRecord);
336
337 // Succeed, new reference id
338 assert(inSam.ReadRecord(samHeader, samRecord) == true);
339 validateRead5(samRecord);
340
341 // Fail, previous reference id.
342 assert(inSam.ReadRecord(samHeader, samRecord) == false);
343 validateRead6(samRecord);
344
345 // Succeed, same reference id, higher coord.
346 assert(inSam.ReadRecord(samHeader, samRecord) == true);
347 validateRead7(samRecord);
348
349 // Succeed, *, new reference id.
350 assert(inSam.ReadRecord(samHeader, samRecord) == true);
351 validateRead8(samRecord);
352
353 // Fail, reference id is not *
354 assert(inSam.ReadRecord(samHeader, samRecord) == false);
355 validateRead9(samRecord);
356
357 // Succeed, valid reference id, and no coordinate.
358 assert(inSam.ReadRecord(samHeader, samRecord) == true);
359 validateRead10(samRecord);
360
361
362 ////////////////////////////////////////////
363 // Reopen the file for reading
364 assert(inSam.OpenForRead("testFiles/testSamSOquery.sam"));
365
366 // Set the validation to FLAG, SO set to queryname.
368
369 // Read the SAM Header.
370 assert(inSam.ReadHeader(samHeader));
371
372 // Succeed, first record.
373 assert(inSam.ReadRecord(samHeader, samRecord) == true);
374 validateRead1(samRecord);
375
376 // Succeed, same name.
377 assert(inSam.ReadRecord(samHeader, samRecord) == true);
378 validateRead2(samRecord);
379
380 // Succeeds - numeric sort
381 assert(inSam.ReadRecord(samHeader, samRecord) == true);
382 validateRead3(samRecord);
383
384 // Succeeds - numeric sort
385 assert(inSam.ReadRecord(samHeader, samRecord) == true);
386 validateRead4(samRecord);
387
388 // Succeeds - numeric sort
389 assert(inSam.ReadRecord(samHeader, samRecord) == true);
390 validateRead5(samRecord);
391
392 // Succeeds - numeric sort
393 assert(inSam.ReadRecord(samHeader, samRecord) == true);
394 validateRead6(samRecord);
395
396 // Succeeds - numeric sort
397 assert(inSam.ReadRecord(samHeader, samRecord) == true);
398 validateRead7(samRecord);
399
400 // Succeed - std sort
401 assert(inSam.ReadRecord(samHeader, samRecord) == true);
402 validateRead8(samRecord);
403
404 // Succeed - numeric sort (Y<18)
405 assert(inSam.ReadRecord(samHeader, samRecord) == true);
406 validateRead9(samRecord);
407
408 // Succeed - std sort
409 assert(inSam.ReadRecord(samHeader, samRecord) == true);
410 validateRead10(samRecord);
411
412 ////////////////////////////////////////////
413 // Reopen the file for reading, SO flag set to junk.
414 assert(inSam.OpenForRead("testFiles/testSamSOinvalid.sam"));
415
416 // Set the validation to the SO Flag. Not set to anything valid,
417 // so it is considered UNSORTED, so all reads should pass.
419
420 // Read the SAM Header.
421 assert(inSam.ReadHeader(samHeader));
422
423 assert(inSam.ReadRecord(samHeader, samRecord) == true);
424 validateRead1(samRecord);
425
426 assert(inSam.ReadRecord(samHeader, samRecord) == true);
427 validateRead2(samRecord);
428
429 assert(inSam.ReadRecord(samHeader, samRecord) == true);
430 validateRead3(samRecord);
431
432 assert(inSam.ReadRecord(samHeader, samRecord) == true);
433 validateRead4(samRecord);
434
435 assert(inSam.ReadRecord(samHeader, samRecord) == true);
436 validateRead5(samRecord);
437
438 assert(inSam.ReadRecord(samHeader, samRecord) == true);
439 validateRead6(samRecord);
440
441 assert(inSam.ReadRecord(samHeader, samRecord) == true);
442 validateRead7(samRecord);
443
444 assert(inSam.ReadRecord(samHeader, samRecord) == true);
445 validateRead8(samRecord);
446
447 assert(inSam.ReadRecord(samHeader, samRecord) == true);
448 validateRead9(samRecord);
449
450 assert(inSam.ReadRecord(samHeader, samRecord) == true);
451 validateRead10(samRecord);
452}
453
454
455
456void validateRead1ModQuality(SamRecord& samRecord)
457{
458 //////////////////////////////////////////
459 // Validate Record 1
460 // Create record structure for validating.
461 int expectedBlockSize = 89;
462 const char* expectedReferenceName = "1";
463 const char* expectedMateReferenceName = "1";
464 const char* expectedMateReferenceNameOrEqual = "=";
465
466 bamRecordStruct* expectedRecordPtr =
467 (bamRecordStruct *) malloc(expectedBlockSize + sizeof(int));
468
469 char tag[3];
470 char type;
471 void* value;
472 bamRecordStruct* bufferPtr;
473 unsigned char* varPtr;
474
475 expectedRecordPtr->myBlockSize = expectedBlockSize;
476 expectedRecordPtr->myReferenceID = 0;
477 expectedRecordPtr->myPosition = 1010;
478 expectedRecordPtr->myReadNameLength = 23;
479 expectedRecordPtr->myMapQuality = 0;
480 expectedRecordPtr->myBin = 4681;
481 expectedRecordPtr->myCigarLength = 2;
482 expectedRecordPtr->myFlag = 73;
483 expectedRecordPtr->myReadLength = 5;
484 expectedRecordPtr->myMateReferenceID = 0;
485 expectedRecordPtr->myMatePosition = 1010;
486 expectedRecordPtr->myInsertSize = 0;
487
488 // Check the alignment end
489 assert(samRecord.get0BasedAlignmentEnd() == 1016);
490 assert(samRecord.get1BasedAlignmentEnd() == 1017);
491 assert(samRecord.getAlignmentLength() == 7);
492 assert(samRecord.get0BasedUnclippedStart() == 1010);
493 assert(samRecord.get1BasedUnclippedStart() == 1011);
494 assert(samRecord.get0BasedUnclippedEnd() == 1016);
495 assert(samRecord.get1BasedUnclippedEnd() == 1017);
496
497 // Check the accessors.
498 assert(samRecord.getBlockSize() == expectedRecordPtr->myBlockSize);
499 assert(samRecord.getReferenceID() == expectedRecordPtr->myReferenceID);
500 assert(strcmp(samRecord.getReferenceName(), expectedReferenceName) == 0);
501 assert(samRecord.get1BasedPosition() == expectedRecordPtr->myPosition + 1);
502 assert(samRecord.get0BasedPosition() == expectedRecordPtr->myPosition);
503 assert(samRecord.getReadNameLength() ==
504 expectedRecordPtr->myReadNameLength);
505 assert(samRecord.getMapQuality() == expectedRecordPtr->myMapQuality);
506 assert(samRecord.getBin() == expectedRecordPtr->myBin);
507 assert(samRecord.getCigarLength() == expectedRecordPtr->myCigarLength);
508 assert(samRecord.getFlag() == expectedRecordPtr->myFlag);
509 assert(samRecord.getReadLength() == expectedRecordPtr->myReadLength);
510 assert(samRecord.getMateReferenceID() ==
511 expectedRecordPtr->myMateReferenceID);
512 assert(strcmp(samRecord.getMateReferenceName(),
513 expectedMateReferenceName) == 0);
514 assert(strcmp(samRecord.getMateReferenceNameOrEqual(),
515 expectedMateReferenceNameOrEqual) == 0);
516 assert(samRecord.get1BasedMatePosition() ==
517 expectedRecordPtr->myMatePosition + 1);
518 assert(samRecord.get0BasedMatePosition() ==
519 expectedRecordPtr->myMatePosition);
520 assert(samRecord.getInsertSize() == expectedRecordPtr->myInsertSize);
521 assert(strcmp(samRecord.getReadName(), "1:1011:F:255+17M15D20M") == 0);
522 assert(strcmp(samRecord.getCigar(), "5M2D") == 0);
523 assert(strcmp(samRecord.getSequence(), "CCGAA") == 0);
524 assert(strcmp(samRecord.getQuality(), "ABCDE") == 0);
525 assert(samRecord.getNumOverlaps(1010, 1017) == 5);
526 assert(samRecord.getNumOverlaps(1010, 1016) == 5);
527 assert(samRecord.getNumOverlaps(1012, 1017) == 3);
528 assert(samRecord.getNumOverlaps(1015, 1017) == 0);
529 assert(samRecord.getNumOverlaps(1017, 1010) == 0);
530 assert(samRecord.getNumOverlaps(1013, 1011) == 0);
531 assert(samRecord.getNumOverlaps(-1, 1017) == 5);
532
533 // Reset the tag iter, since the tags have already been read.
534 samRecord.resetTagIter();
535
536 // Check the tags.
537 assert(samRecord.getNextSamTag(tag, type, &value) == true);
538 assert(tag[0] == 'A');
539 assert(tag[1] == 'M');
540 assert(type == 'i');
541 assert(*(char*)value == 0);
542 assert(samRecord.getNextSamTag(tag, type, &value) == true);
543 assert(tag[0] == 'M');
544 assert(tag[1] == 'D');
545 assert(type == 'Z');
546 assert(*(String*)value == "37");
547 assert(samRecord.getNextSamTag(tag, type, &value) == true);
548 assert(tag[0] == 'N');
549 assert(tag[1] == 'M');
550 assert(type == 'i');
551 assert(*(char*)value == 0);
552 assert(samRecord.getNextSamTag(tag, type, &value) == true);
553 assert(tag[0] == 'X');
554 assert(tag[1] == 'T');
555 assert(type == 'A');
556 assert(*(char*)value == 'R');
557 // No more tags, should return false.
558 assert(samRecord.getNextSamTag(tag, type, &value) == false);
559 assert(samRecord.getNextSamTag(tag, type, &value) == false);
560
561 // Get the record ptr.
562 bufferPtr = (bamRecordStruct*)samRecord.getRecordBuffer();
563 // Validate the buffers match.
564 assert(bufferPtr->myBlockSize == expectedRecordPtr->myBlockSize);
565 assert(bufferPtr->myReferenceID == expectedRecordPtr->myReferenceID);
566 assert(bufferPtr->myPosition == expectedRecordPtr->myPosition);
567 assert(bufferPtr->myReadNameLength == expectedRecordPtr->myReadNameLength);
568 assert(bufferPtr->myMapQuality == expectedRecordPtr->myMapQuality);
569 assert(bufferPtr->myBin == expectedRecordPtr->myBin);
570 assert(bufferPtr->myCigarLength == expectedRecordPtr->myCigarLength);
571 assert(bufferPtr->myFlag == expectedRecordPtr->myFlag);
572 assert(bufferPtr->myReadLength == expectedRecordPtr->myReadLength);
573 assert(bufferPtr->myMateReferenceID ==
574 expectedRecordPtr->myMateReferenceID);
575 assert(bufferPtr->myMatePosition == expectedRecordPtr->myMatePosition);
576 assert(bufferPtr->myInsertSize == expectedRecordPtr->myInsertSize);
577
578 // Validate the variable length fields in the buffer.
579 // Set the pointer to the start of the variable fields.
580 varPtr = (unsigned char*)(&(bufferPtr->myData[0]));
581
582 // Validate the readname.
583 for(int i = 0; i < expectedRecordPtr->myReadNameLength; i++)
584 {
585 assert(*varPtr == samRecord.getReadName()[i]);
586 varPtr++;
587 }
588
589 // Validate the cigar.
590 // The First cigar is 5M which is 5 << 4 | 0 = 80
591 assert(*(unsigned int*)varPtr == 80);
592 // Increment the varptr the size of an int.
593 varPtr += 4;
594 // The 2nd cigar is 2D which is 2 << 4 | 2 = 34
595 assert(*(unsigned int*)varPtr == 34);
596 // Increment the varptr the size of an int.
597 varPtr += 4;
598
599 // Validate the sequence.
600 // CC = 0x22
601 assert(*varPtr == 0x22);
602 varPtr++;
603 // GA = 0x41
604 assert(*varPtr == 0x41);
605 varPtr++;
606 // A = 0x10
607 assert(*varPtr == 0x10);
608 varPtr++;
609
610 // Validate the Quality
611 for(int i = 0; i < expectedRecordPtr->myReadLength; i++)
612 {
613 assert(*varPtr == samRecord.getQuality()[i] - 33);
614 varPtr++;
615 }
616
617 // Validate the tags.
618 assert(*varPtr == 'A');
619 varPtr++;
620 assert(*varPtr == 'M');
621 varPtr++;
622 assert(*varPtr == 'C');
623 varPtr++;
624 assert(*varPtr == 0);
625 varPtr++;
626 assert(*varPtr == 'M');
627 varPtr++;
628 assert(*varPtr == 'D');
629 varPtr++;
630 assert(*varPtr == 'Z');
631 varPtr++;
632 assert(*varPtr == '3');
633 varPtr++;
634 assert(*varPtr == '7');
635 varPtr++;
636 assert(*varPtr == 0);
637 varPtr++;
638 assert(*varPtr == 'N');
639 varPtr++;
640 assert(*varPtr == 'M');
641 varPtr++;
642 assert(*varPtr == 'C');
643 varPtr++;
644 assert(*varPtr == 0);
645 varPtr++;
646 assert(*varPtr == 'X');
647 varPtr++;
648 assert(*varPtr == 'T');
649 varPtr++;
650 assert(*varPtr == 'A');
651 varPtr++;
652 assert(*varPtr == 'R');
653 varPtr++;
654}
655
656
657void testModHeader(SamFileHeader& samHeader)
658{
659 // Check the header line.
660 std::string headerString = "";
661 assert(samHeader.getHeaderString(headerString) == true);
662 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");
663
664 // Remove a tag - by setting it to "".
665 assert(samHeader.setRGTag("LB", "", "myID2") == true);
666
667
668 // Check the header line.
669 assert(samHeader.getHeaderString(headerString) == true);
670 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");
671
672 // Add an HD tag.
673 SamHeaderHD* hd = new SamHeaderHD();
674 assert(hd->setTag("VN", "1.3") == true);
675 assert(samHeader.addHD(hd) == true);
676 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") == 0);
677 assert(samHeader.getHeaderString(headerString) == true);
678 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");
679
680 // Try adding another HD tag.
681 SamHeaderHD* hd2 = new SamHeaderHD();
682 assert(hd2->setTag("VN", "1.4") == true);
683 assert(samHeader.addHD(hd2) == false);
684 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") != 0);
685 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") == 0);
686 assert(samHeader.getHeaderString(headerString) == true);
687 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");
688
689 // Remove the entire HD Tag.
690 assert(samHeader.removeHD() == true);
691 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
692 assert(samHeader.getHeaderString(headerString) == true);
693 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");
694
695 // Remove an entire SQ Tag.
696 assert(strcmp(samHeader.getSQTagValue("LN", "11"), "134452384") == 0);
697 assert(samHeader.removeSQ("11") == true);
698 assert(strcmp(samHeader.getSQTagValue("LN", "11"), "") == 0);
699 assert(samHeader.getHeaderString(headerString) == true);
700 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");
701
702 // Try adding a null HD tag.
703 hd = NULL;
704 assert(samHeader.addHD(hd) == false);
705 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
706 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") != 0);
707 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") != 0);
708 assert(samHeader.getHeaderString(headerString) == true);
709 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");
710
711 // Try adding a null SQ tag.
712 SamHeaderSQ* sq = NULL;
713 assert(samHeader.addSQ(sq) == false);
714 assert(samHeader.getHeaderString(headerString) == true);
715 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");
716
717 // Try adding an HD tag again.
718 assert(samHeader.addHD(hd2) == true);
719 assert(strcmp(samHeader.getHDTagValue("VN"), "1.4") == 0);
720 assert(strcmp(samHeader.getHDTagValue("VN"), "1.3") != 0);
721 assert(samHeader.getHeaderString(headerString) == true);
722 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");
723
724
725 // TODO Get the comments.
726
727}
728
729
730
731void testFlagRead(const char* fileName)
732{
733 SamFile inSam;
734 SamFileHeader samHeader;
735 SamRecord samRecord;
736
737 ////////////////////////////////////////////////////////////
738 // Required flag 0x48 (only flag 73 matches)
739 // Exclude nothing
740 assert(inSam.OpenForRead(fileName));
741 assert(inSam.ReadHeader(samHeader));
742 validateHeader(samHeader);
743 inSam.SetReadFlags(0x48, 0x0);
744
745 assert(inSam.ReadRecord(samHeader, samRecord) == true);
746 validateRead1(samRecord);
747
748 assert(inSam.ReadRecord(samHeader, samRecord) == false);
749
750 inSam.Close();
751
752 ////////////////////////////////////////////////////////////
753 // No required flags.
754 // Exclude 0x48. This leaves just the one read with flag 133.
755 assert(inSam.OpenForRead(fileName));
756 assert(inSam.ReadHeader(samHeader));
757 validateHeader(samHeader);
758 inSam.SetReadFlags(0x0, 0x48);
759
760 assert(inSam.ReadRecord(samHeader, samRecord) == true);
761 validateRead2(samRecord);
762
763 assert(inSam.ReadRecord(samHeader, samRecord) == false);
764
765 inSam.Close();
766
767 ////////////////////////////////////////////////////////////
768 // Required flag 0x40
769 // Exclude 0x48.
770 // This will not find any records since the exclude and required conflict.
771 assert(inSam.OpenForRead(fileName));
772 assert(inSam.ReadHeader(samHeader));
773 validateHeader(samHeader);
774 inSam.SetReadFlags(0x40, 0x48);
775
776 assert(inSam.ReadRecord(samHeader, samRecord) == false);
777
778 inSam.Close();
779
780 ////////////////////////////////////////////////////////////
781 // Required flag 0x4
782 // Exclude 0x8.
783 // Only finds flag 133.
784 assert(inSam.OpenForRead(fileName));
785 assert(inSam.ReadHeader(samHeader));
786 validateHeader(samHeader);
787 inSam.SetReadFlags(0x4, 0x8);
788
789 assert(inSam.ReadRecord(samHeader, samRecord) == true);
790 validateRead2(samRecord);
791
792 assert(inSam.ReadRecord(samHeader, samRecord) == false);
793
794 inSam.Close();
795
796 ////////////////////////////////////////////////////////////
797 // Required flag 0x4
798 // Exclude nothing
799 // Finds flags 133 & 141.
800 assert(inSam.OpenForRead(fileName));
801 assert(inSam.ReadHeader(samHeader));
802 validateHeader(samHeader);
803 inSam.SetReadFlags(0x4, 0x0);
804
805 assert(inSam.ReadRecord(samHeader, samRecord) == true);
806 validateRead2(samRecord);
807
808 assert(inSam.ReadRecord(samHeader, samRecord) == true);
809 validateRead8(samRecord);
810
811 assert(inSam.ReadRecord(samHeader, samRecord) == true);
812 validateRead10(samRecord);
813
814 assert(inSam.ReadRecord(samHeader, samRecord) == false);
815
816 inSam.Close();
817}
818
819
820void testCopyHeader(SamFileHeader& samHeader)
821{
822 // Copy the header.
823 SamFileHeader samHeader2;
824
825 SamHeaderRecord* recPtr = samHeader.getNextHeaderRecord();
826 while(recPtr != NULL)
827 {
828 samHeader2.addRecordCopy(*recPtr);
829 recPtr = samHeader.getNextHeaderRecord();
830 }
831 // Add the comments.
832 std::string nextComment = samHeader.getNextComment();
833 while(nextComment != SamFileHeader::EMPTY_RETURN)
834 {
835 samHeader2.addComment(nextComment.c_str());
836 nextComment = samHeader.getNextComment();
837 }
838 // Validate the header.
839 validateHeader(samHeader2);
840}
@ RETURN
just return failure on the error
Create/Access/Modify/Load Genome Sequences stored as binary mapped files.
This class allows a user to get/set the fields in a SAM/BAM Header.
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,...
const char * getHDTagValue(const char *tag)
Returns the value associated with the specified HD tag, returning "" if the tag does not exist in the...
SamHeaderRecord * getNextHeaderRecord(uint32_t &index, SamHeaderRecord::SamHeaderRecordType headerType)
Get the next header record of the specified type starting from the specified index and update the ind...
bool addSQ(SamHeaderSQ *sq)
Add the SQ record to the header.
bool addComment(const char *comment)
Add the specified comment to the header (do not include "@CO" or "\n").
bool addHD(SamHeaderHD *hd)
Add the HD record to the header.
const char * getNextComment()
Returns the comment on the next comment line.
bool addHeaderLine(const char *type, const char *tag, const char *value)
Add a header line that is just one tag with a const char* value.
bool removeHD()
Remove the HD record.
bool setRGTag(const char *tag, const char *value, const char *id)
Set the specified tag to the specified value in the RG header with the specified id,...
bool getHeaderString(std::string &header) const
Set the passed in string to the entire header string, clearing its current contents.
bool removeSQ(const char *name)
Remove SQ record with the specified key.
bool addRecordCopy(const SamHeaderRecord &hdrRec)
Add a copy of the specified header record to the header.
Allows the user to easily read/write a SAM/BAM file.
Definition SamFile.h:36
bool ReadHeader(SamFileHeader &header)
Reads the header section from the file and stores it in the passed in header.
Definition SamFile.cpp:450
void Close()
Close the file if there is one open.
Definition SamFile.cpp:400
@ FLAG
SO flag from the header indicates the sort type.
Definition SamFile.h:48
@ QUERY_NAME
file is sorted by queryname.
Definition SamFile.h:50
@ COORDINATE
file is sorted by coordinate.
Definition SamFile.h:49
bool ReadRecord(SamFileHeader &header, SamRecord &record)
Reads the next record from the file & stores it in the passed in record.
Definition SamFile.cpp:514
void SetReadFlags(uint16_t requiredFlags, uint16_t excludedFlags)
Specify which reads should be returned by ReadRecord.
Definition SamFile.cpp:794
@ READ
open for reading.
Definition SamFile.h:40
bool OpenForRead(const char *filename, SamFileHeader *header=NULL)
Open a sam/bam file for reading with the specified filename, determing the type of file and SAM/BAM b...
Definition SamFile.cpp:93
bool IsEOF()
Returns whether or not the end of the file has been reached.
Definition SamFile.cpp:424
bool OpenForWrite(const char *filename, SamFileHeader *header=NULL)
Open a sam/bam file for writing with the specified filename, determining SAM/BAM from the extension (...
Definition SamFile.cpp:223
bool WriteHeader(SamFileHeader &header)
Writes the specified header into the file.
Definition SamFile.cpp:480
bool WriteRecord(SamFileHeader &header, SamRecord &record)
Writes the specified record into the file.
Definition SamFile.cpp:632
void setSortedValidation(SortedType sortType)
Set the flag to validate that the file is sorted as it is read/written.
Definition SamFile.cpp:682
This class encapsulates the tag value pairs contained with a SAM Header line with accessors for getti...
bool setTag(const char *tag, const char *value)
Set the value of the specified tag to the specified value, deletes the tag when value is NULL.
Class providing an easy to use interface to get/set/operate on the fields in a SAM/BAM record.
Definition SamRecord.h:52
int32_t getBlockSize()
Get the block size of the record (BAM format).
uint16_t getCigarLength()
Get the length of the BAM formatted CIGAR.
const char * getReferenceName()
Get the reference sequence name (RNAME) of the record.
int32_t getInsertSize()
Get the inferred insert size of the read pair (ISIZE) or observed template length (TLEN).
int32_t get0BasedMatePosition()
Get the 0-based(BAM) leftmost mate/next fragment's position.
int32_t get1BasedPosition()
Get the 1-based(SAM) leftmost position (POS) of the record.
bool addIntTag(const char *tag, int32_t value)
Add the specified integer tag to the record.
int32_t getReferenceID()
Get the reference sequence id of the record (BAM format rid).
int32_t getAlignmentLength()
Returns the length of the clipped sequence, returning 0 if the cigar is '*'.
int32_t get1BasedAlignmentEnd()
Returns the 1-based inclusive rightmost position of the clipped sequence.
uint8_t getReadNameLength()
Get the length of the readname (QNAME) including the null.
const char * getMateReferenceNameOrEqual()
Get the mate/next fragment's reference sequence name (RNEXT), returning "=" if it is the same as the ...
int32_t get1BasedUnclippedStart()
Returns the 1-based inclusive left-most position adjusted for clipped bases.
bool addTag(const char *tag, char vtype, const char *value)
Add the specified tag,vtype,value to the record.
uint16_t getBin()
Get the BAM bin for the record.
int32_t getMateReferenceID()
Get the mate reference id of the record (BAM format: mate_rid/next_refID).
uint16_t getFlag()
Get the flag (FLAG).
const void * getRecordBuffer()
Get a const pointer to the buffer that contains the BAM representation of the record.
int32_t get1BasedMatePosition()
Get the 1-based(SAM) leftmost mate/next fragment's position (PNEXT).
int32_t get0BasedUnclippedEnd()
Returns the 0-based inclusive right-most position adjusted for clipped bases.
int32_t get1BasedUnclippedEnd()
Returns the 1-based inclusive right-most position adjusted for clipped bases.
uint32_t getNumOverlaps(int32_t start, int32_t end)
Return the number of bases in this read that overlap the passed in region.
const char * getMateReferenceName()
Get the mate/next fragment's reference sequence name (RNEXT).
bool getNextSamTag(char *tag, char &vtype, void **value)
Get the next tag from the record.
int32_t get0BasedUnclippedStart()
Returns the 0-based inclusive left-most position adjusted for clipped bases.
int32_t getReadLength()
Get the length of the read.
int32_t get0BasedAlignmentEnd()
Returns the 0-based inclusive rightmost position of the clipped sequence.
int32_t get0BasedPosition()
Get the 0-based(BAM) leftmost position of the record.
const char * getCigar()
Returns the SAM formatted CIGAR string.
uint8_t getMapQuality()
Get the mapping quality (MAPQ) of the record.
const char * getReadName()
Returns the SAM formatted Read Name (QNAME).
void resetTagIter()
Reset the tag iterator to the beginning of the tags.
bool setQuality(const char *quality)
Sets the quality (QUAL) to the specified SAM formatted quality string.
const char * getQuality()
Returns the SAM formatted quality string (QUAL).
const char * getSequence()
Returns the SAM formatted sequence string (SEQ), translating the base as specified by setSequenceTran...
static bool isMDTagCorrect(SamRecord &inputRec, GenomeSequence &genome)
Check to see if the MD tag in the record is accurate.
Definition SamTags.cpp:126
static bool createMDTag(String &outputMDtag, SamRecord &inputRec, GenomeSequence &genome)
Create the MD tag for the specified input record and the genome.
Definition SamTags.cpp:34
Structure of a BAM record.
Definition SamRecord.h:34