libStatGen Software 1
Loading...
Searching...
No Matches
WriteFiles.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 "SamFile.h"
19#include "WriteFiles.h"
20#include "TestValidate.h"
21
22#include <assert.h>
23#include <stdio.h>
24
25void testWrite()
26{
27 testHeaderWrite();
28 testWriteCopiedHeader("testFiles/testSam.sam");
29#ifdef __ZLIB_AVAILABLE__
30 testWriteCopiedHeader("testFiles/testBam.bam");
31#endif
32}
33
34void testHeaderWrite()
35{
36 SamFile samOut;
37
38 samOut.OpenForWrite("results/MyTestOut.sam");
39
40 // Create a sam header.
41 SamFileHeader samHeader;
42
43 std::string headerString = "";
44
45 // Test getting HD & PG and the HD-SO tag when they do not exist.
46 assert(samHeader.getHD() == NULL);
47 assert(samHeader.getPG("1") == NULL);
48 assert(strcmp(samHeader.getTagSO(), "") == 0);
49
50 // Test removing the HD tag that does not exist.
51 assert(samHeader.removeHD() == true);
52 assert(samHeader.getHD() == NULL);
53 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
54 assert(samHeader.getHeaderString(headerString) == true);
55 assert(headerString == "");
56
57 char type[3] = "HD";
58 char tag[3] = "VN";
59 // Verify it has not yet been added to the parsed header.
60 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
61 assert(samHeader.addHeaderLine(type, tag, "1.0") == true);
62 assert(samHeader.getHeaderString(headerString) == true);
63 assert(headerString == "@HD\tVN:1.0\n");
64
65 // Verify it was added to the parsed header.
66 assert(strcmp(samHeader.getHDTagValue("VN"), "1.0") == 0);
67
68 type[0] = 'S';
69 type[1] = 'Q';
70 tag[0] = 'L';
71 tag[1] = 'N';
72 // Cannot add SQ LN tag without adding the SN tag also.
73 assert(samHeader.addHeaderLine(type, tag, "123") == false);
74 assert(samHeader.getHeaderString(headerString) == true);
75 assert(headerString == "@HD\tVN:1.0\n");
76
77 // Has not yet been added, so returns blank.
78 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "") == 0);
79
80 // Can't add the SQ type without a LN.
81 std::string line = "@SQ\tSN:123";
82 assert(samHeader.addHeaderLine(line.c_str()) == false);
83 assert(samHeader.getHeaderString(headerString) == true);
84 assert(headerString == "@HD\tVN:1.0\n");
85
86 // Successfully add a SQ line.
87 line = "@SQ\tLN:123\tSN:chr20";
88 assert(samHeader.addHeaderLine(line.c_str()) == true);
89 assert(samHeader.getHeaderString(headerString) == true);
90 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
91 // Verify it was added to the parsed header.
92 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
93
94 // Test to make sure nothing changes if try to copy into self.
95 samHeader = samHeader;
96 assert(samHeader.addHeaderLine(line.c_str()) == false);
97 assert(samHeader.getHeaderString(headerString) == true);
98 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
99 // Verify it was added to the parsed header.
100 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
101
102 samHeader.copy(samHeader);
103 assert(samHeader.addHeaderLine(line.c_str()) == false);
104 assert(samHeader.getHeaderString(headerString) == true);
105 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
106 // Verify it was added to the parsed header.
107 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
108
109 // Test adding an HD that is already there.
110 assert(samHeader.addHeaderLine("@HD\tVN:1.1") == false);
111 assert(samHeader.getHeaderString(headerString) == true);
112 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
113 // Verify it was added to the parsed header.
114 assert(strcmp(samHeader.getHDTagValue("VN"), "1.0") == 0);
115
116 // Test copying the header.
117 SamFileHeader newHeader = samHeader;
118 assert(newHeader.getHeaderString(headerString) == true);
119 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
120 // Verify it was added to the parsed header.
121 assert(strcmp(newHeader.getSQTagValue("LN", "chr20"), "123") == 0);
122
123
124 // Modify one of the tags.
125 assert(samHeader.setHDTag("VN", "1.1") == true);
126 assert(samHeader.getHeaderString(headerString) == true);
127 assert(headerString == "@HD\tVN:1.1\n@SQ\tLN:123\tSN:chr20\n");
128 // Verify it was modified.
129 assert(strcmp(samHeader.getHDTagValue("VN"), "1.1") == 0);
130
131 // Remove the version.
132 assert(samHeader.setHDTag("VN", "") == true);
133 assert(samHeader.getHeaderString(headerString) == true);
134 assert(headerString == "@SQ\tLN:123\tSN:chr20\n");
135 // Verify it was removed.
136 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
137
138 // Remove the SN from the SQ type - fails because SN is the key.
139 assert(samHeader.setSQTag("SN", "", "chr20") == false);
140 assert(samHeader.getHeaderString(headerString) == true);
141 assert(headerString == "@SQ\tLN:123\tSN:chr20\n");
142 // Verify it was not removed.
143 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "chr20") == 0);
144 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
145
146 // Can't remove the LN from the SQ type
147 assert(samHeader.setSQTag("LN", "", "chr20") == false);
148 assert(samHeader.getHeaderString(headerString) == true);
149 assert(headerString == "@SQ\tLN:123\tSN:chr20\n");
150 // Verify it was not removed.
151 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
152 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "chr20") == 0);
153
154 // Delete the SQ line.
155 assert(samHeader.removeSQ("chr20") == true);
156 // There is no header string.
157 assert(samHeader.getHeaderString(headerString) == true);
158 assert(headerString == "");
159 // Verify it was removed.
160 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "") == 0);
161 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "") == 0);
162
163 // Create an SQ record and add it back in.
164 SamHeaderSQ* sq = new SamHeaderSQ();
165 assert(sq->setTag("LN", "123") == true);
166 assert(sq->setTag("SN", "chr20") == true);
167 assert(samHeader.addSQ(sq) == true);
168 assert(samHeader.getHeaderString(headerString) == true);
169 assert(headerString == "@SQ\tLN:123\tSN:chr20\n");
170 // Verify it was added.
171 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "chr20") == 0);
172 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "123") == 0);
173
174 // Modify a tag.
175 assert(sq->setTag("LN", "222") == true);
176 assert(samHeader.getHeaderString(headerString) == true);
177 assert(headerString == "@SQ\tLN:222\tSN:chr20\n");
178 // Verify it was modified.
179 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "chr20") == 0);
180 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "222") == 0);
181
182
183 // Test adding another SQ with the same key.
184 SamHeaderSQ* sq2 = new SamHeaderSQ();
185 assert(sq2->setTag("LN", "333") == true);
186 assert(sq2->setTag("SN", "chr20") == true);
187 assert(samHeader.addSQ(sq2) == false);
188 assert(samHeader.getHeaderString(headerString) == true);
189 assert(headerString == "@SQ\tLN:222\tSN:chr20\n");
190 // Verify it was not added.
191 assert(strcmp(samHeader.getSQTagValue("SN", "chr20"), "chr20") == 0);
192 assert(strcmp(samHeader.getSQTagValue("LN", "chr20"), "222") == 0);
193 delete sq2;
194
195 // Add a new tag to the SQ tag.
196 assert(samHeader.setSQTag("AS", "HG18", "chr20") == true);
197 assert(samHeader.getHeaderString(headerString) == true);
198 assert(headerString == "@SQ\tLN:222\tSN:chr20\tAS:HG18\n");
199 // Verify it was added.
200 assert(strcmp(samHeader.getSQTagValue("AS", "chr20"), "HG18") == 0);
201
202 // Modify the AS tag.
203 assert(samHeader.setSQTag("AS", "HG19", "chr20") == true);
204 assert(samHeader.getHeaderString(headerString) == true);
205 assert(headerString == "@SQ\tLN:222\tSN:chr20\tAS:HG19\n");
206 // Verify it was added.
207 assert(strcmp(samHeader.getSQTagValue("AS", "chr20"), "HG19") == 0);
208
209 // Add a new tag .
210 sq2 = new SamHeaderSQ();
211 assert(sq2->setTag("LN", "333") == true);
212 assert(sq2->setTag("SN", "chr1") == true);
213 assert(samHeader.addSQ(sq2) == true);
214 assert(samHeader.getHeaderString(headerString) == true);
215 assert(headerString ==
216 "@SQ\tLN:222\tSN:chr20\tAS:HG19\n@SQ\tLN:333\tSN:chr1\n");
217 // Verify it was added.
218 assert(strcmp(samHeader.getSQTagValue("SN", "chr1"), "chr1") == 0);
219 assert(strcmp(samHeader.getSQTagValue("LN", "chr1"), "333") == 0);
220
221 // Test removing an SQ tag that does not exist.
222 assert(samHeader.removeSQ("chr100") == true);
223 assert(samHeader.getHeaderString(headerString) == true);
224 assert(headerString ==
225 "@SQ\tLN:222\tSN:chr20\tAS:HG19\n@SQ\tLN:333\tSN:chr1\n");
226
227 // Remove the newly added sq2 by resetting it.
228 sq2->reset();
229 // Verify it was removed.
230 assert(samHeader.getHeaderString(headerString) == true);
231 assert(headerString == "@SQ\tLN:222\tSN:chr20\tAS:HG19\n");
232 assert(strcmp(samHeader.getSQTagValue("SN", "chr1"), "") == 0);
233 assert(strcmp(samHeader.getSQTagValue("LN", "chr1"), "") == 0);
234
235 // Test getting HD which does exist since it was set before. Even
236 // though the VN was removed so it doesn't appear in the header string,
237 // it was never actually removed.
238 SamHeaderHD* hd = samHeader.getHD();
239 assert(hd != NULL);
240 // Blank since the sort order was never set.
241 assert(strcmp(samHeader.getTagSO(), "") == 0);
242
243 // Set the version number.
244 assert(hd->setTag("VN", "2.1") == true);
245 // Verify it was added.
246 assert(samHeader.getHeaderString(headerString) == true);
247 assert(headerString == "@HD\tVN:2.1\n@SQ\tLN:222\tSN:chr20\tAS:HG19\n");
248 assert(strcmp(samHeader.getHDTagValue("VN"), "2.1") == 0);
249
250 // Set the SO
251 assert(hd->setTag("SO", "coordinate") == true);
252 // Verify it was added.
253 assert(samHeader.getHeaderString(headerString) == true);
254 assert(headerString ==
255 "@HD\tVN:2.1\tSO:coordinate\n@SQ\tLN:222\tSN:chr20\tAS:HG19\n");
256 assert(strcmp(samHeader.getHDTagValue("SO"), "coordinate") == 0);
257
258 // Reset the header.
259 samHeader.resetHeader();
260 assert(samHeader.getHeaderString(headerString) == true);
261 assert(headerString == "");
262
263 // Add a new HD tag.
264 assert(samHeader.setHDTag("SO", "queryname") == true);
265 assert(strcmp(samHeader.getHDTagValue("SO"), "queryname") == 0);
266 assert(samHeader.getHeaderString(headerString) == true);
267 // Blank since missing VN.
268 assert(headerString == "");
269
270 // Set the VN.
271 assert(samHeader.setHDTag("VN", "3.1") == true);
272 assert(strcmp(samHeader.getHDTagValue("SO"), "queryname") == 0);
273 assert(strcmp(samHeader.getHDTagValue("VN"), "3.1") == 0);
274 assert(samHeader.getHeaderString(headerString) == true);
275 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n");
276
277 //////////////////////////////////////////////////////////////
278 // Test removing a non-existent PG.
279 assert(samHeader.removePG("1") == true);
280 assert(samHeader.getHeaderString(headerString) == true);
281 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n");
282
283 // Test adding a null PG.
284 SamHeaderPG* pg = NULL;
285 assert(samHeader.addPG(pg) == false);
286 assert(samHeader.getHeaderString(headerString) == true);
287 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n");
288
289 // Add a PG tag.
290 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "") == 0);
291 assert(samHeader.setPGTag("ID", "pid", "pid") == true);
292 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
293 assert(samHeader.getHeaderString(headerString) == true);
294 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
295
296 // Verify can't modify the key.
297 assert(samHeader.setPGTag("ID", "pid1", "pid") == false);
298 assert(samHeader.getHeaderString(headerString) == true);
299 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
300 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
301
302 // Test adding a null PG.
303 pg = NULL;
304 assert(samHeader.addPG(pg) == false);
305 assert(samHeader.getHeaderString(headerString) == true);
306 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
307
308 // Test adding a PG header when it already exists.
309 pg = new SamHeaderPG();
310 assert(pg->setTag("ID", "pid") == true);
311 assert(samHeader.addPG(pg) == false);
312 assert(samHeader.getHeaderString(headerString) == true);
313 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
314 delete pg;
315
316 // Get a PG that does not exist.
317 pg = samHeader.getPG("pid1");
318 assert(pg == NULL);
319
320 // Get a PG tag that does not exist.
321 assert(strcmp(samHeader.getPGTagValue("CL", "pid"), "") == 0);
322
323 // Get the PG tag.
324 pg = samHeader.getPG("pid");
325 assert(pg != NULL);
326 assert(strcmp(pg->getTagValue("ID"), "pid") == 0);
327 // Add a tag to the PG.
328 assert(pg->setTag("VN", "pg1") == true);
329 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "pg1") == 0);
330 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
331 assert(samHeader.getHeaderString(headerString) == true);
332 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\tVN:pg1\n");
333
334 // Test modifying the key tag - fails.
335 assert(pg->setTag("ID", "pid1") == false);
336 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "pg1") == 0);
337 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
338 assert(samHeader.getHeaderString(headerString) == true);
339 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\tVN:pg1\n");
340
341 // Test modifying the VN tag.
342 assert(samHeader.setPGTag("VN", "pg", "pid") == true);
343 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "pg") == 0);
344 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
345 assert(samHeader.getHeaderString(headerString) == true);
346 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\tVN:pg\n");
347
348 // Test removing the VN tag.
349 assert(pg->setTag("VN", "") == true);
350 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "") == 0);
351 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
352 assert(samHeader.getHeaderString(headerString) == true);
353 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
354
355 // Test removing a PG that does not exist.
356 assert(samHeader.removePG("pid1") == true);
357 assert(samHeader.getHeaderString(headerString) == true);
358 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:pid\n");
359 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "") == 0);
360 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "pid") == 0);
361
362 // Test removing the PG.
363 assert(samHeader.removePG("pid") == true);
364 assert(samHeader.getHeaderString(headerString) == true);
365 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n");
366 assert(strcmp(samHeader.getPGTagValue("VN", "pid"), "") == 0);
367 assert(strcmp(samHeader.getPGTagValue("ID", "pid"), "") == 0);
368
369 // Test adding a PG header.
370 pg = new SamHeaderPG();
371 assert(pg->setTag("ID", "newID") == true);
372 assert(samHeader.addPG(pg) == true);
373 assert(samHeader.getHeaderString(headerString) == true);
374 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
375
376 // Test adding a PG that is already there.
377 assert(samHeader.addHeaderLine("@PG\tID:newID") == false);
378 assert(samHeader.getHeaderString(headerString) == true);
379 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
380 // Verify it was added to the parsed header.
381 assert(strcmp(samHeader.getPGTagValue("ID", "newID"), "newID") == 0);
382
383 // Test adding another PG header.
384 pg = new SamHeaderPG();
385 assert(pg->setTag("ID", "newID1") == true);
386 assert(samHeader.addPG(pg) == true);
387 assert(samHeader.getHeaderString(headerString) == true);
388 assert(headerString ==
389 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@PG\tID:newID1\n");
390
391 // Test adding another PG header.
392 pg = new SamHeaderPG();
393 assert(pg->setTag("ID", "pid") == true);
394 assert(samHeader.addPG(pg) == true);
395 assert(samHeader.getHeaderString(headerString) == true);
396 assert(headerString ==
397 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@PG\tID:newID1\n@PG\tID:pid\n");
398
399 // Test removing the new pg.
400 assert(samHeader.removePG("newID1") == true);
401 assert(samHeader.getHeaderString(headerString) == true);
402 assert(headerString ==
403 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@PG\tID:pid\n");
404
405 // Test removing the other new pg.
406 assert(samHeader.removePG("pid") == true);
407 assert(samHeader.getHeaderString(headerString) == true);
408 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
409
410 // Test adding a tag
411 assert(samHeader.setPGTag("VN", "1.0", "newID") == true);
412 assert(strcmp(samHeader.getPGTagValue("VN", "newID"), "1.0") == 0);
413 assert(strcmp(samHeader.getPGTagValue("ID", "newID"), "newID") == 0);
414 assert(samHeader.getHeaderString(headerString) == true);
415 assert(headerString ==
416 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\tVN:1.0\n");
417
418 // Test removing a tag
419 assert(samHeader.setPGTag("VN", "", "newID") == true);
420 assert(strcmp(samHeader.getPGTagValue("VN", "newID"), "") == 0);
421 assert(strcmp(samHeader.getPGTagValue("ID", "newID"), "newID") == 0);
422 assert(samHeader.getHeaderString(headerString) == true);
423 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
424
425 ////////////////////////////////////////////////////////////////////
426 // Add an SQ, but fail since LN is not specified.
427 assert(samHeader.setSQTag("AS", "HG18", "newName") == false);
428 assert(samHeader.getHeaderString(headerString) == true);
429 // SQ does not show up since it is missing the LN field.
430 assert(headerString ==
431 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
432 // Add the SQ's SN, but fail since LN is not specified.
433 assert(samHeader.setSQTag("SN", "newName", "newName") == false);
434 assert(samHeader.getHeaderString(headerString) == true);
435 assert(headerString ==
436 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n");
437 sq = samHeader.getSQ("newName");
438 assert(sq == NULL);
439 // Add the SQ with the LN tag.
440 assert(samHeader.setSQTag("LN", "111", "newName") == true);
441 assert(strcmp(samHeader.getSQTagValue("SN", "newName"), "newName") == 0);
442 assert(strcmp(samHeader.getSQTagValue("AS", "newName"), "") == 0);
443 assert(strcmp(samHeader.getSQTagValue("LN", "newName"), "111") == 0);
444 assert(samHeader.getHeaderString(headerString) == true);
445 assert(headerString ==
446 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\n");
447 // Add the AS.
448 assert(samHeader.setSQTag("AS", "HG18", "newName") == true);
449 assert(strcmp(samHeader.getSQTagValue("AS", "newName"), "HG18") == 0);
450 assert(strcmp(samHeader.getSQTagValue("SN", "newName"), "newName") == 0);
451 assert(strcmp(samHeader.getSQTagValue("LN", "newName"), "111") == 0);
452 assert(samHeader.getHeaderString(headerString) == true);
453 assert(headerString ==
454 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\n");
455
456 // Get the SQ.
457 sq = samHeader.getSQ("newName");
458 assert(sq != NULL);
459 // Modify the SQ
460 assert(sq->setTag("SP", "species") == true);
461 assert(strcmp(samHeader.getSQTagValue("SN", "newName"), "newName") == 0);
462 assert(strcmp(samHeader.getSQTagValue("AS", "newName"), "HG18") == 0);
463 assert(strcmp(samHeader.getSQTagValue("LN", "newName"), "111") == 0);
464 assert(strcmp(samHeader.getSQTagValue("SP", "newName"), "species") == 0);
465 assert(samHeader.getHeaderString(headerString) == true);
466 assert(headerString ==
467 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n");
468
469 //////////////////////////////////////////////////////////////////////
470 // Add a new RG Tag
471// Remove this test since SM is no longer required, the RG would be added
472// assert(samHeader.setRGTag("ID", "rgID", "rgID") == true);
473// assert(samHeader.getHeaderString(headerString) == true);
474// // New RG does not show up since it is still missing a required field.
475// assert(headerString ==
476// "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n");
477// assert(strcmp(samHeader.getRGTagValue("ID", "rgID"), "rgID") == 0);
478
479 // Add the missing SM field.
480 assert(samHeader.setRGTag("SM", "sm1", "rgID") == true);
481 assert(samHeader.getHeaderString(headerString) == true);
482 assert(headerString ==
483 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n");
484 assert(strcmp(samHeader.getRGTagValue("ID", "rgID"), "rgID") == 0);
485
486 // Verify can't modify the key.
487 assert(samHeader.setRGTag("ID", "rgID1", "rgID") == false);
488 assert(samHeader.getHeaderString(headerString) == true);
489 assert(headerString ==
490 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n");
491 assert(strcmp(samHeader.getRGTagValue("ID", "rgID"), "rgID") == 0);
492
493 // Verify that the copied header did not change.
494 assert(newHeader.getHeaderString(headerString) == true);
495 assert(headerString == "@HD\tVN:1.0\n@SQ\tLN:123\tSN:chr20\n");
496 // Verify it was added to the parsed header.
497 assert(strcmp(newHeader.getSQTagValue("LN", "chr20"), "123") == 0);
498
499 // Add a new RG Tag
500 assert(samHeader.setRGTag("SM", "sample1", "rgID1") == true);
501 assert(samHeader.getHeaderString(headerString) == true);
502 // String does not show the tag until all required fields are there.
503 assert(headerString ==
504 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n");
505 assert(strcmp(samHeader.getRGTagValue("ID", "rgID1"), "rgID1") == 0);
506 assert(strcmp(samHeader.getRGTagValue("SM", "rgID1"), "sample1") == 0);
507
508 // Modify an RG tag.
509 assert(samHeader.setRGTag("SM", "sample", "rgID1") == true);
510 assert(samHeader.getHeaderString(headerString) == true);
511 assert(headerString ==
512 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
513 assert(strcmp(samHeader.getRGTagValue("ID", "rgID1"), "rgID1") == 0);
514 assert(strcmp(samHeader.getRGTagValue("SM", "rgID1"), "sample") == 0);
515
516 // Test removing an rg that does not exist.
517 assert(samHeader.removeRG("rgID2") == true);
518 assert(samHeader.getHeaderString(headerString) == true);
519 assert(headerString ==
520 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
521
522 // Create a new RG, set some values and add it.
523 SamHeaderRG* rg = new SamHeaderRG();
524 // Try adding it without a key.
525 assert(samHeader.addRG(rg) == false);
526 assert(samHeader.getHeaderString(headerString) == true);
527 assert(headerString ==
528 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
529 // Set some values in rg.
530 assert(rg->setTag("ID", "rgID2") == true);
531 assert(rg->setTag("SM", "sm2") == true);
532 assert(samHeader.getHeaderString(headerString) == true);
533 assert(headerString ==
534 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
535 // Add the new RG.
536 assert(samHeader.addRG(rg) == true);
537 assert(samHeader.getHeaderString(headerString) == true);
538 assert(headerString ==
539 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n@RG\tID:rgID2\tSM:sm2\n");
540 assert(strcmp(samHeader.getRGTagValue("ID", "rgID2"), "rgID2") == 0);
541
542 // Test trying to add another one with the same key.
543 rg = new SamHeaderRG();
544 assert(rg->setTag("ID", "rgID2") == true);
545 assert(samHeader.addRG(rg) == false);
546 assert(samHeader.getHeaderString(headerString) == true);
547 assert(headerString ==
548 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n@RG\tID:rgID2\tSM:sm2\n");
549
550
551 // Test removing the rg again.
552 assert(samHeader.removeRG("rgID2") == true);
553 assert(samHeader.getHeaderString(headerString) == true);
554 assert(headerString ==
555 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
556
557 // Test getting an rg tag that doesn't exist
558 assert(strcmp(samHeader.getRGTagValue("DS", "rgID"), "") == 0);
559 assert(samHeader.getHeaderString(headerString) == true);
560 assert(headerString ==
561 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
562
563 // Test getting an rg tag from a removed key
564 assert(strcmp(samHeader.getRGTagValue("ID", "rgID2"), "") == 0);
565 assert(samHeader.getHeaderString(headerString) == true);
566 assert(headerString ==
567 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
568
569 // Test getting an rg tag from an key that doesn't exist
570 assert(strcmp(samHeader.getRGTagValue("ID", "rgID22"), "") == 0);
571 assert(samHeader.getHeaderString(headerString) == true);
572 assert(headerString ==
573 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
574
575 // Test adding a null header.
576 rg = NULL;
577 assert(samHeader.addRG(rg) == false);
578 assert(samHeader.getHeaderString(headerString) == true);
579 assert(headerString ==
580 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n");
581
582 // Test adding the deleted header back in.
583 rg = new SamHeaderRG();
584 assert(rg->setTag("ID", "rgID2") == true);
585 assert(rg->setTag("SM", "sm2") == true);
586 assert(samHeader.addRG(rg) == true);
587 assert(samHeader.getHeaderString(headerString) == true);
588 assert(headerString ==
589 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n@RG\tID:rgID2\tSM:sm2\n");
590
591 // Test adding an RG that is already there.
592 assert(samHeader.addHeaderLine("@RG\tID:rgID\tSM:sm5") == false);
593 assert(samHeader.getHeaderString(headerString) == true);
594 assert(headerString == "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample\n@RG\tID:rgID2\tSM:sm2\n");
595 // Verify it was added to the parsed header.
596 assert(strcmp(samHeader.getRGTagValue("SM", "rgID"), "sm1") == 0);
597
598
599 // Get an RG record then modify it.
600 rg = samHeader.getRG("rgID1");
601 assert(rg != NULL);
602 assert(rg->setTag("SM", "sample1") == true);
603 assert(samHeader.getHeaderString(headerString) == true);
604 assert(headerString ==
605 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n");
606
607 // Try to modify the key.
608 assert(rg->setTag("ID", "rgID111") == false);
609 assert(samHeader.getHeaderString(headerString) == true);
610 assert(headerString ==
611 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n");
612
613 ////////////////////////////////////////////////////////////////////////////
614 // Test getting a comment when there aren't any.
615 assert(strcmp(samHeader.getNextComment(), "") == 0);
616 assert(samHeader.getHeaderString(headerString) == true);
617 assert(headerString ==
618 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n");
619
620 // Test getting each headerline when there are no comments.
621 const char* hdrlinechar;
622 std::string hdrline;
623 assert(samHeader.getNextHeaderLine(hdrline));
624 hdrlinechar = hdrline.c_str();
625 // Test to make sure there is not memory corruption.
626 std::string tmpString = "@SQ\tSN:queryname\tVN:3.1\n";
627 assert(hdrline == "@HD\tSO:queryname\tVN:3.1\n");
628 assert(strcmp(hdrlinechar,
629 "@HD\tSO:queryname\tVN:3.1\n") == 0);
630
631 assert(samHeader.getNextHeaderLine(hdrline));
632 assert(hdrline == "@PG\tID:newID\n");
633 assert(samHeader.getNextHeaderLine(hdrline));
634 assert(hdrline == "@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n");
635 assert(samHeader.getNextHeaderLine(hdrline));
636 assert(hdrline == "@RG\tID:rgID\tSM:sm1\n");
637 assert(samHeader.getNextHeaderLine(hdrline));
638 assert(hdrline == "@RG\tID:rgID1\tSM:sample1\n");
639 assert(samHeader.getNextHeaderLine(hdrline));
640 assert(hdrline == "@RG\tID:rgID2\tSM:sm2\n");
641 assert(!samHeader.getNextHeaderLine(hdrline));
642 assert(hdrline == "");
643 assert(!samHeader.getNextHeaderLine(hdrline));
644 assert(hdrline == "");
645 assert(samHeader.getHeaderString(headerString) == true);
646 assert(headerString ==
647 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n");
648
649 // Verify that getHeaderRecord returns nothing.
650 assert(samHeader.getNextHeaderRecord() == NULL);
651
652 // Reset the header record iter.
653 samHeader.resetHeaderRecordIter();
654
655 // Test getting each headerrecord when there are no comments.
656 SamHeaderRecord* hdrRec = samHeader.getNextHeaderRecord();
657 assert(hdrRec != NULL);
658 assert(strcmp(hdrRec->getTypeString(), "HD") == 0);
659 assert(hdrRec->getType() == SamHeaderRecord::HD);
660 assert(strcmp(hdrRec->getTagValue("SO"), "queryname") == 0);
661 assert(strcmp(hdrRec->getTagValue("VN"), "3.1") == 0);
662 hdrRec = samHeader.getNextHeaderRecord();
663 assert(hdrRec != NULL);
664 assert(strcmp(hdrRec->getTypeString(), "PG") == 0);
665 assert(hdrRec->getType() == SamHeaderRecord::PG);
666 assert(strcmp(hdrRec->getTagValue("ID"), "newID") == 0);
667 hdrRec = samHeader.getNextHeaderRecord();
668 assert(hdrRec != NULL);
669 assert(strcmp(hdrRec->getTypeString(), "SQ") == 0);
670 assert(hdrRec->getType() == SamHeaderRecord::SQ);
671 assert(strcmp(hdrRec->getTagValue("SN"), "newName") == 0);
672 assert(strcmp(hdrRec->getTagValue("AS"), "HG18") == 0);
673 assert(strcmp(hdrRec->getTagValue("LN"), "111") == 0);
674 hdrRec = samHeader.getNextHeaderRecord();
675 assert(hdrRec != NULL);
676 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
677 assert(hdrRec->getType() == SamHeaderRecord::RG);
678 assert(strcmp(hdrRec->getTagValue("ID"), "rgID") == 0);
679 assert(strcmp(hdrRec->getTagValue("SM"), "sm1") == 0);
680
681 // Get the SQ Header Record (should have no affect on the general
682 // getNextHeaderRecord calls).
683 hdrRec = samHeader.getNextSQRecord();
684 assert(hdrRec != NULL);
685 assert(strcmp(hdrRec->getTypeString(), "SQ") == 0);
686 assert(hdrRec->getType() == SamHeaderRecord::SQ);
687 assert(strcmp(hdrRec->getTagValue("SN"), "newName") == 0);
688 assert(strcmp(hdrRec->getTagValue("AS"), "HG18") == 0);
689 assert(strcmp(hdrRec->getTagValue("LN"), "111") == 0);
690 // Only one SQ Header Record.
691 hdrRec = samHeader.getNextSQRecord();
692 assert(hdrRec == NULL);
693
694 // Get the RG/PG Header Records (should have no affect on the general
695 // getNextHeaderRecord calls).
696 hdrRec = samHeader.getNextRGRecord();
697 assert(hdrRec != NULL);
698 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
699 assert(hdrRec->getType() == SamHeaderRecord::RG);
700 assert(strcmp(hdrRec->getTagValue("ID"), "rgID") == 0);
701 assert(strcmp(hdrRec->getTagValue("SM"), "sm1") == 0);
702 // Get the next RG record.
703 hdrRec = samHeader.getNextRGRecord();
704 assert(hdrRec != NULL);
705 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
706 assert(hdrRec->getType() == SamHeaderRecord::RG);
707 assert(strcmp(hdrRec->getTagValue("ID"), "rgID1") == 0);
708 assert(strcmp(hdrRec->getTagValue("SM"), "sample1") == 0);
709 // Get the PG record.
710 hdrRec = samHeader.getNextPGRecord();
711 assert(hdrRec != NULL);
712 assert(strcmp(hdrRec->getTypeString(), "PG") == 0);
713 assert(hdrRec->getType() == SamHeaderRecord::PG);
714 assert(strcmp(hdrRec->getTagValue("ID"), "newID") == 0);
715 // Get the last RG record.
716 hdrRec = samHeader.getNextRGRecord();
717 assert(hdrRec != NULL);
718 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
719 assert(hdrRec->getType() == SamHeaderRecord::RG);
720 assert(strcmp(hdrRec->getTagValue("ID"), "rgID2") == 0);
721 assert(strcmp(hdrRec->getTagValue("SM"), "sm2") == 0);
722 // Already got all RG Records.
723 hdrRec = samHeader.getNextRGRecord();
724 assert(hdrRec == NULL);
725 // Reset the RG record.
726 samHeader.resetRGRecordIter();
727 // Get the RG record.
728 hdrRec = samHeader.getNextRGRecord();
729 assert(hdrRec != NULL);
730 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
731 assert(hdrRec->getType() == SamHeaderRecord::RG);
732 assert(strcmp(hdrRec->getTagValue("ID"), "rgID") == 0);
733 assert(strcmp(hdrRec->getTagValue("SM"), "sm1") == 0);
734 // No more PG records.
735 hdrRec = samHeader.getNextPGRecord();
736 assert(hdrRec == NULL);
737 // No more SQ records.
738 hdrRec = samHeader.getNextSQRecord();
739 assert(hdrRec == NULL);
740 // Reset the SQ record iterator.
741 samHeader.resetSQRecordIter();
742 // No more PG records.
743 hdrRec = samHeader.getNextPGRecord();
744 assert(hdrRec == NULL);
745 // Get the now reset SQ record.
746 hdrRec = samHeader.getNextSQRecord();
747 assert(hdrRec != NULL);
748 assert(strcmp(hdrRec->getTypeString(), "SQ") == 0);
749 assert(hdrRec->getType() == SamHeaderRecord::SQ);
750 assert(strcmp(hdrRec->getTagValue("SN"), "newName") == 0);
751 assert(strcmp(hdrRec->getTagValue("AS"), "HG18") == 0);
752 assert(strcmp(hdrRec->getTagValue("LN"), "111") == 0);
753 // Only one SQ Header Record.
754 hdrRec = samHeader.getNextSQRecord();
755 assert(hdrRec == NULL);
756 // Reset the PG record iterator.
757 samHeader.resetPGRecordIter();
758 // No more SQ records.
759 hdrRec = samHeader.getNextSQRecord();
760 assert(hdrRec == NULL);
761 // Get the next RG record.
762 hdrRec = samHeader.getNextRGRecord();
763 assert(hdrRec != NULL);
764 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
765 assert(hdrRec->getType() == SamHeaderRecord::RG);
766 assert(strcmp(hdrRec->getTagValue("ID"), "rgID1") == 0);
767 assert(strcmp(hdrRec->getTagValue("SM"), "sample1") == 0);
768 // Get the PG record.
769 hdrRec = samHeader.getNextPGRecord();
770 assert(hdrRec != NULL);
771 assert(strcmp(hdrRec->getTypeString(), "PG") == 0);
772 assert(hdrRec->getType() == SamHeaderRecord::PG);
773 assert(strcmp(hdrRec->getTagValue("ID"), "newID") == 0);
774
775
776 hdrRec = samHeader.getNextHeaderRecord();
777 assert(hdrRec != NULL);
778 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
779 assert(hdrRec->getType() == SamHeaderRecord::RG);
780 assert(strcmp(hdrRec->getTagValue("ID"), "rgID1") == 0);
781 assert(strcmp(hdrRec->getTagValue("SM"), "sample1") == 0);
782 hdrRec = samHeader.getNextHeaderRecord();
783 assert(hdrRec != NULL);
784 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
785 assert(hdrRec->getType() == SamHeaderRecord::RG);
786 assert(strcmp(hdrRec->getTagValue("ID"), "rgID2") == 0);
787 assert(strcmp(hdrRec->getTagValue("SM"), "sm2") == 0);
788 hdrRec = samHeader.getNextHeaderRecord();
789 assert(hdrRec == NULL);
790 hdrRec = samHeader.getNextHeaderRecord();
791 assert(hdrRec == NULL);
792 assert(!samHeader.getNextHeaderLine(hdrline));
793 assert(hdrline == "");
794 assert(!samHeader.getNextHeaderLine(hdrline));
795 assert(hdrline == "");
796
797 assert(samHeader.getHeaderString(headerString) == true);
798 assert(headerString ==
799 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n");
800
801 // Add some comments.
802 assert(samHeader.addComment("My Comment") == true);
803 assert(samHeader.getHeaderString(headerString) == true);
804 assert(headerString ==
805 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n@CO\tMy Comment\n");
806
807 // Call getNextHeaderRecord - still nothing.
808 hdrRec = samHeader.getNextHeaderRecord();
809 assert(hdrRec == NULL);
810
811 // Call getNextHeaderLine - should return the comment.
812 assert(samHeader.getNextHeaderLine(hdrline));
813 assert(hdrline == "@CO\tMy Comment\n");
814 assert(!samHeader.getNextHeaderLine(hdrline));
815 assert(hdrline == "");
816 assert(!samHeader.getNextHeaderLine(hdrline));
817 assert(hdrline == "");
818
819 // Call getNextCommentLine - should return the comment.
820 assert(strcmp(samHeader.getNextComment(), "My Comment") == 0);
821 assert(strcmp(samHeader.getNextComment(), "") == 0);
822 assert(strcmp(samHeader.getNextComment(), "") == 0);
823
824 // Add another comment.
825 assert(samHeader.addComment("My Comment2") == true);
826 assert(samHeader.getHeaderString(headerString) == true);
827 assert(headerString ==
828 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n@CO\tMy Comment\n@CO\tMy Comment2\n");
829
830 newHeader = samHeader;
831 assert(newHeader.getHeaderString(headerString) == true);
832 assert(headerString ==
833 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n@CO\tMy Comment\n@CO\tMy Comment2\n");
834
835 // Call getNextHeaderLine - should return the comment.
836 assert(samHeader.getNextHeaderLine(hdrline));
837 assert(hdrline == "@CO\tMy Comment2\n");
838 assert(!samHeader.getNextHeaderLine(hdrline));
839 assert(hdrline == "");
840 assert(!samHeader.getNextHeaderLine(hdrline));
841 assert(hdrline == "");
842
843 // Call getNextCommentLine - should return the comment.
844 assert(strcmp(samHeader.getNextComment(), "My Comment2") == 0);
845 assert(strcmp(samHeader.getNextComment(), "") == 0);
846 assert(strcmp(samHeader.getNextComment(), "") == 0);
847
848 // Reset the header record iter.
849 samHeader.resetHeaderRecordIter();
850
851 // Recall getNextCommentLine - should not return anything.
852 assert(strcmp(samHeader.getNextComment(), "") == 0);
853 assert(strcmp(samHeader.getNextComment(), "") == 0);
854
855 // Reset the next comment iter.
856 samHeader.resetCommentIter();
857
858 // Call the get next headerLine, record, comment interspersed with
859 // each other.
860 hdrRec = samHeader.getNextHeaderRecord();
861 assert(hdrRec != NULL);
862 assert(strcmp(hdrRec->getTypeString(), "HD") == 0);
863 assert(hdrRec->getType() == SamHeaderRecord::HD);
864 assert(strcmp(hdrRec->getTagValue("SO"), "queryname") == 0);
865 assert(strcmp(hdrRec->getTagValue("VN"), "3.1") == 0);
866 assert(samHeader.getNextHeaderLine(hdrline));
867 assert(hdrline == "@PG\tID:newID\n");
868 assert(samHeader.getNextHeaderLine(hdrline));
869 assert(hdrline == "@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n");
870 hdrRec = samHeader.getNextHeaderRecord();
871 assert(hdrRec != NULL);
872 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
873 assert(hdrRec->getType() == SamHeaderRecord::RG);
874 assert(strcmp(hdrRec->getTagValue("ID"), "rgID") == 0);
875 hdrRec = samHeader.getNextHeaderRecord();
876 assert(hdrRec != NULL);
877 assert(strcmp(samHeader.getNextComment(), "My Comment") == 0);
878 assert(strcmp(hdrRec->getTypeString(), "RG") == 0);
879 assert(hdrRec->getType() == SamHeaderRecord::RG);
880 assert(strcmp(hdrRec->getTagValue("ID"), "rgID1") == 0);
881 assert(strcmp(hdrRec->getTagValue("SM"), "sample1") == 0);
882 assert(samHeader.getNextHeaderLine(hdrline));
883 assert(hdrline == "@RG\tID:rgID2\tSM:sm2\n");
884 hdrRec = samHeader.getNextHeaderRecord();
885 assert(hdrRec == NULL);
886 assert(samHeader.getNextHeaderLine(hdrline));
887 assert(hdrline == "@CO\tMy Comment\n");
888 hdrRec = samHeader.getNextHeaderRecord();
889 assert(hdrRec == NULL);
890 assert(samHeader.getNextHeaderLine(hdrline));
891 assert(hdrline == "@CO\tMy Comment2\n");
892 assert(!samHeader.getNextHeaderLine(hdrline));
893 assert(hdrline == "");
894 assert(strcmp(samHeader.getNextComment(), "My Comment2") == 0);
895 assert(!samHeader.getNextHeaderLine(hdrline));
896 assert(hdrline == "");
897 hdrRec = samHeader.getNextHeaderRecord();
898 assert(hdrRec == NULL);
899 assert(strcmp(samHeader.getNextComment(), "") == 0);
900 assert(strcmp(samHeader.getNextComment(), "") == 0);
901
902 samOut.WriteHeader(samHeader);
903
904 // Reset the header.
905 samHeader.resetHeader();
906 assert(samHeader.getHeaderString(headerString) == true);
907 assert(headerString == "");
908 assert(!samHeader.getNextHeaderLine(hdrline));
909 assert(hdrline == "");
910 assert(strcmp(samHeader.getHDTagValue("SO"), "") == 0);
911 assert(strcmp(samHeader.getHDTagValue("VN"), "") == 0);
912
913 // Try adding a key to the HD tag.
914 hd = new SamHeaderHD();
915 assert(hd->addKey("3.1") == false);
916 assert(strcmp(hd->getTagValue("VN"), "") == 0);
917 assert(hd->isActiveHeaderRecord() == false);
918
919 assert(hd->setTag("VN", "3.1") == true);
920 assert(hd->isActiveHeaderRecord() == true);
921 assert(strcmp(hd->getTagValue("VN"), "3.1") == 0);
922
923 // Verify the copied header did not change.
924 assert(newHeader.getHeaderString(headerString) == true);
925 assert(headerString ==
926 "@HD\tSO:queryname\tVN:3.1\n@PG\tID:newID\n@SQ\tSN:newName\tLN:111\tAS:HG18\tSP:species\n@RG\tID:rgID\tSM:sm1\n@RG\tID:rgID1\tSM:sample1\n@RG\tID:rgID2\tSM:sm2\n@CO\tMy Comment\n@CO\tMy Comment2\n");
927 // Verify it was added to the parsed header.
928 assert(strcmp(newHeader.getSQTagValue("LN", "chr20"), "") == 0);
929}
930
931
932void testWriteCopiedHeader(const char* fileName)
933{
934 SamFile samIn;
935 assert(samIn.OpenForRead(fileName));
936
937 SamFile samOut;
938 assert(samOut.OpenForWrite("results/MyTestOut2.bam"));
939 SamFile samOut2;
940 assert(samOut2.OpenForWrite("results/MyTestOut2.sam"));
941
942 // Read the sam header.
943 SamFileHeader samHeader;
944 assert(samIn.ReadHeader(samHeader));
945 validateHeader(samHeader);
946
947 SamFileHeader newHeader;
948
949 std::string hdrLine;
950 assert(samHeader.getNextHeaderLine(hdrLine));
951 newHeader.addHeaderLine("@HD\tVN:1.02");
952 bool hdrStatus = true;
953 while(hdrStatus)
954 {
955 newHeader.addHeaderLine(hdrLine.c_str());
956 hdrStatus = samHeader.getNextHeaderLine(hdrLine);
957 }
958
959 // Write the sam header.
960 assert(samOut.WriteHeader(newHeader));
961 assert(samOut2.WriteHeader(newHeader));
962
963 SamRecord samRecord;
964
965 // Keep reading records until ReadRecord returns false.
966 while(samIn.ReadRecord(samHeader, samRecord))
967 {
968 // Successfully read a record from the file, so write it.
969 assert(samOut.WriteRecord(newHeader, samRecord));
970 assert(samOut2.WriteRecord(newHeader, samRecord));
971 }
972
973 assert(samIn.GetStatus() == SamStatus::NO_MORE_RECS);
974
975 // Close the output files.
976 samOut.Close();
977 samOut2.Close();
978
979 SamFileReader bamRead("results/MyTestOut2.bam");
980 SamFileReader samRead("results/MyTestOut2.sam");
981
982 // Read and check the header.
983 assert(samRead.ReadHeader(samHeader));
984 validateHeaderFields(samHeader);
985 std::string headerString = "";
986 assert(samHeader.getHeaderString(headerString) == true);
987 assert(headerString == "@HD\tVN:1.02\n@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");
988
989 assert(bamRead.ReadHeader(samHeader));
990 validateHeaderFields(samHeader);
991 headerString = "";
992 assert(samHeader.getHeaderString(headerString) == true);
993 assert(headerString == "@HD\tVN:1.02\n@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");
994
995 assert(samHeader.getNextHeaderLine(hdrLine));
996 std::string expectedString = "@HD\tVN:1.02\n";
997
998 assert(expectedString == hdrLine);
999
1000
1001 // TODO - validate reading these written records back in.
1002
1003}
1004
This class allows a user to get/set the fields in a SAM/BAM Header.
SamHeaderPG * getPG(const char *id)
Get the PG object with the specified id, returning NULL if there is no PG object with that key.
bool addPG(SamHeaderPG *pg)
Add the PG record to the 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,...
SamHeaderSQ * getSQ(const char *name)
Get the SQ object with the specified sequence name, returning NULL if there is no SQ object with that...
SamHeaderHD * getHD()
Get the HD object, returning NULL if there is no HD record.
void resetRGRecordIter()
Reset to the beginning of the header records so the next call to getNextRGRecord returns the first RG...
bool setPGTag(const char *tag, const char *value, const char *id)
Set the specified tag to the specified value in the PG header with the specified id,...
const char * getHDTagValue(const char *tag)
Returns the value associated with the specified HD tag, returning "" if the tag does not exist in the...
bool addRG(SamHeaderRG *rg)
Add the RG record to the header.
bool getNextHeaderLine(std::string &headerLine)
Set the passed in string to the next header line, overwritting the passed in string.
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...
SamHeaderRecord * getNextPGRecord()
Get the next PG header record.
bool removePG(const char *id)
Remove PG record with the specified key.
bool addSQ(SamHeaderSQ *sq)
Add the SQ record to the header.
bool removeRG(const char *id)
Remove RG record with the specified key.
bool setSQTag(const char *tag, const char *value, const char *name)
Set the specified tag to the specified value in the SQ header with the specified name,...
bool addComment(const char *comment)
Add the specified comment to the header (do not include "@CO" or "\n").
const char * getTagSO()
DEPRECATED.
const char * getNextComment()
Returns the comment on the next comment line.
const char * getRGTagValue(const char *tag, const char *id)
Get the value associated with the specified tag on the RG line with the specified read group identifi...
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.
void resetSQRecordIter()
Reset to the beginning of the header records so the next call to getNextSQRecord returns the first SQ...
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 copy(const SamFileHeader &header)
Copy method copies the passed in header into this header.
void resetHeaderRecordIter()
Reset to the beginning of the header records so the next call to getNextHeaderRecord returns the firs...
SamHeaderRecord * getNextRGRecord()
Get the next RG header record.
SamHeaderRecord * getNextSQRecord()
Get the next SQ header record.
void resetHeader()
Initialize the header.
bool removeSQ(const char *name)
Remove SQ record with the specified key.
const char * getPGTagValue(const char *tag, const char *id)
Get the value associated with the specified tag on the RG line with the specified id,...
void resetPGRecordIter()
Reset to the beginning of the header records so the next call to getNextPGRecord returns the first PG...
SamHeaderRG * getRG(const char *id)
Get the RG object with the specified read group identifier, returning NULL if there is no RG object w...
bool setHDTag(const char *tag, const char *value)
Set the specified tag to the specified value in the HD header, remove the tag by specifying value="".
void resetCommentIter()
Resets to the beginning of the comments so getNextComment returns the first comment.
Child class of SamFile for reading files.
Definition SamFile.h:461
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
bool ReadRecord(SamFileHeader &header, SamRecord &record)
Reads the next record from the file & stores it in the passed in record.
Definition SamFile.cpp:514
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
SamStatus::Status GetStatus()
Get the Status of the last call that sets status.
Definition SamFile.h:212
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
This class encapsulates the tag value pairs contained with a SAM Header line with accessors for getti...
const char * getTagValue(const char *tag) const
Return the value associated with the specified tag.
const char * getTypeString()
Return the type of this header record (HD, SQ, RG, or PG) as a string.
void reset()
Reset this header record to an empty state with no tags.
SamHeaderRecordType getType()
Return the type of this header record (HD, SQ, RG, or PG) as an enum.
bool isActiveHeaderRecord()
This record is active (true) if there is at least one tag set.
bool addKey(const char *value)
Add the key tag with the specified value (not for HD headers).
@ SQ
Sequence Dictionary.
@ RG
Read Group.
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
@ NO_MORE_RECS
NO_MORE_RECS: failed to read a record since there are no more to read either in the file or section i...