libStatGen Software  1
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 
23 void 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 
44 void 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 
65 void 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 
116 void 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.
165 void 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 
456 void 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 
657 void 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 
731 void 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 
820 void 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
Definition: ErrorHandler.h:31
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.
Definition: SamFileHeader.h:35
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).
Definition: SamRecord.cpp:1281
uint16_t getCigarLength()
Get the length of the BAM formatted CIGAR.
Definition: SamRecord.cpp:1362
const char * getReferenceName()
Get the reference sequence name (RNAME) of the record.
Definition: SamRecord.cpp:1298
int32_t getInsertSize()
Get the inferred insert size of the read pair (ISIZE) or observed template length (TLEN).
Definition: SamRecord.cpp:1459
int32_t get0BasedMatePosition()
Get the 0-based(BAM) leftmost mate/next fragment's position.
Definition: SamRecord.cpp:1452
int32_t get1BasedPosition()
Get the 1-based(SAM) leftmost position (POS) of the record.
Definition: SamRecord.cpp:1312
bool addIntTag(const char *tag, int32_t value)
Add the specified integer tag to the record.
Definition: SamRecord.cpp:647
int32_t getReferenceID()
Get the reference sequence id of the record (BAM format rid).
Definition: SamRecord.cpp:1305
int32_t getAlignmentLength()
Returns the length of the clipped sequence, returning 0 if the cigar is '*'.
Definition: SamRecord.cpp:1493
int32_t get1BasedAlignmentEnd()
Returns the 1-based inclusive rightmost position of the clipped sequence.
Definition: SamRecord.cpp:1486
uint8_t getReadNameLength()
Get the length of the readname (QNAME) including the null.
Definition: SamRecord.cpp:1326
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
int32_t get1BasedUnclippedStart()
Returns the 1-based inclusive left-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1519
bool addTag(const char *tag, char vtype, const char *value)
Add the specified tag,vtype,value to the record.
Definition: SamRecord.cpp:791
uint16_t getBin()
Get the BAM bin for the record.
Definition: SamRecord.cpp:1347
int32_t getMateReferenceID()
Get the mate reference id of the record (BAM format: mate_rid/next_refID).
Definition: SamRecord.cpp:1438
uint16_t getFlag()
Get the flag (FLAG).
Definition: SamRecord.cpp:1384
const void * getRecordBuffer()
Get a const pointer to the buffer that contains the BAM representation of the record.
Definition: SamRecord.cpp:1204
int32_t get1BasedMatePosition()
Get the 1-based(SAM) leftmost mate/next fragment's position (PNEXT).
Definition: SamRecord.cpp:1445
int32_t get0BasedUnclippedEnd()
Returns the 0-based inclusive right-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1526
int32_t get1BasedUnclippedEnd()
Returns the 1-based inclusive right-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1535
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
const char * getMateReferenceName()
Get the mate/next fragment's reference sequence name (RNEXT).
Definition: SamRecord.cpp:1410
bool getNextSamTag(char *tag, char &vtype, void **value)
Get the next tag from the record.
Definition: SamRecord.cpp:1962
int32_t get0BasedUnclippedStart()
Returns the 0-based inclusive left-most position adjusted for clipped bases.
Definition: SamRecord.cpp:1506
int32_t getReadLength()
Get the length of the read.
Definition: SamRecord.cpp:1391
int32_t get0BasedAlignmentEnd()
Returns the 0-based inclusive rightmost position of the clipped sequence.
Definition: SamRecord.cpp:1467
int32_t get0BasedPosition()
Get the 0-based(BAM) leftmost position of the record.
Definition: SamRecord.cpp:1319
const char * getCigar()
Returns the SAM formatted CIGAR string.
Definition: SamRecord.cpp:1555
uint8_t getMapQuality()
Get the mapping quality (MAPQ) of the record.
Definition: SamRecord.cpp:1340
const char * getReadName()
Returns the SAM formatted Read Name (QNAME).
Definition: SamRecord.cpp:1542
void resetTagIter()
Reset the tag iterator to the beginning of the tags.
Definition: SamRecord.cpp:2034
bool setQuality(const char *quality)
Sets the quality (QUAL) to the specified SAM formatted quality string.
Definition: SamRecord.cpp:357
const char * getQuality()
Returns the SAM formatted quality string (QUAL).
Definition: SamRecord.cpp:1638
const char * getSequence()
Returns the SAM formatted sequence string (SEQ), translating the base as specified by setSequenceTran...
Definition: SamRecord.cpp:1568
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