annotate ezBAMQC/src/htslib/test/sam.c @ 20:9de3bbec2479 draft default tip

Uploaded
author youngkim
date Thu, 31 Mar 2016 10:10:37 -0400
parents dfa3745e5fd8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
1 /* test/sam.c -- SAM/BAM/CRAM API test cases.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
2
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
3 Copyright (C) 2014-2015 Genome Research Ltd.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
4
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
5 Author: John Marshall <jm18@sanger.ac.uk>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
6
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
7 Permission is hereby granted, free of charge, to any person obtaining a copy
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
8 of this software and associated documentation files (the "Software"), to deal
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
9 in the Software without restriction, including without limitation the rights
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
11 copies of the Software, and to permit persons to whom the Software is
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
12 furnished to do so, subject to the following conditions:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
13
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
14 The above copyright notice and this permission notice shall be included in
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
15 all copies or substantial portions of the Software.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
16
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
23 DEALINGS IN THE SOFTWARE. */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
24
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
25 #include <stdarg.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
26 #include <stdio.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
27 #include <stdlib.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
28 #include <string.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
29 #include <math.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
30
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
31 #include "htslib/sam.h"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
32 #include "htslib/faidx.h"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
33 #include "htslib/kstring.h"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
34
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
35 int status;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
36
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
37 static void fail(const char *fmt, ...)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
38 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
39 va_list args;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
40
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
41 fprintf(stderr, "Failed: ");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
42 va_start(args, fmt);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
43 vfprintf(stderr, fmt, args);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
44 va_end(args);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
45 fprintf(stderr, "\n");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
46
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
47 status = EXIT_FAILURE;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
48 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
49
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
50 uint8_t *check_bam_aux_get(const bam1_t *aln, const char *tag, char type)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
51 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
52 uint8_t *p = bam_aux_get(aln, tag);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
53 if (p) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
54 if (*p == type) return p;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
55 else fail("%s field of type '%c', expected '%c'\n", tag, *p, type);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
56 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
57 else fail("can't find %s field\n", tag);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
58
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
59 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
60 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
61
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
62 #define PI 3.141592653589793
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
63 #define E 2.718281828459045
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
64 #define HELLO "Hello, world!"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
65 #define BEEF "DEADBEEF"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
66
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
67 #define str(x) #x
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
68 #define xstr(x) str(x)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
69
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
70 static int aux_fields1(void)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
71 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
72 static const char sam[] = "data:"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
73 "@SQ\tSN:one\tLN:1000\n"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
74 "@SQ\tSN:two\tLN:500\n"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
75 "r1\t0\tone\t500\t20\t8M\t*\t0\t0\tATGCATGC\tqqqqqqqq\tXA:A:k\tXi:i:37\tXf:f:" xstr(PI) "\tXd:d:" xstr(E) "\tXZ:Z:" HELLO "\tXH:H:" BEEF "\tXB:B:c,-2,0,+2\tZZ:i:1000000\tY1:i:-2147483648\tY2:i:-2147483647\tY3:i:-1\tY4:i:0\tY5:i:1\tY6:i:2147483647\tY7:i:2147483648\tY8:i:4294967295\n";
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
76
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
77 // Canonical form of the alignment record above, as output by sam_format1()
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
78 static const char r1[] = "r1\t0\tone\t500\t20\t8M\t*\t0\t0\tATGCATGC\tqqqqqqqq\tXA:A:k\tXi:i:37\tXf:f:3.14159\tXd:d:2.71828\tXZ:Z:" HELLO "\tXH:H:" BEEF "\tXB:B:c,-2,0,2\tZZ:i:1000000\tY1:i:-2147483648\tY2:i:-2147483647\tY3:i:-1\tY4:i:0\tY5:i:1\tY6:i:2147483647\tY7:i:2147483648\tY8:i:4294967295";
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
79
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
80 samFile *in = sam_open(sam, "r");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
81 bam_hdr_t *header = sam_hdr_read(in);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
82 bam1_t *aln = bam_init1();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
83 uint8_t *p;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
84 uint32_t n;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
85 kstring_t ks = { 0, 0, NULL };
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
86
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
87 if (sam_read1(in, header, aln) >= 0) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
88 if ((p = check_bam_aux_get(aln, "XA", 'A')) && bam_aux2A(p) != 'k')
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
89 fail("XA field is '%c', expected 'k'", bam_aux2A(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
90
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
91 if ((p = check_bam_aux_get(aln, "Xi", 'C')) && bam_aux2i(p) != 37)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
92 fail("Xi field is %d, expected 37", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
93
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
94 if ((p = check_bam_aux_get(aln, "Xf", 'f')) && fabs(bam_aux2f(p) - PI) > 1E-6)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
95 fail("Xf field is %.12f, expected pi", bam_aux2f(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
96
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
97 if ((p = check_bam_aux_get(aln, "Xd", 'd')) && fabs(bam_aux2f(p) - E) > 1E-6)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
98 fail("Xf field is %.12f, expected e", bam_aux2f(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
99
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
100 if ((p = check_bam_aux_get(aln, "XZ", 'Z')) && strcmp(bam_aux2Z(p), HELLO) != 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
101 fail("XZ field is \"%s\", expected \"%s\"", bam_aux2Z(p), HELLO);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
102
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
103 if ((p = check_bam_aux_get(aln, "XH", 'H')) && strcmp(bam_aux2Z(p), BEEF) != 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
104 fail("XH field is \"%s\", expected \"%s\"", bam_aux2Z(p), BEEF);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
105
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
106 // TODO Invent and use bam_aux2B()
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
107 if ((p = check_bam_aux_get(aln, "XB", 'B')) && ! (memcmp(p, "Bc", 2) == 0 && (memcpy(&n, p+2, 4), n) == 3 && memcmp(p+6, "\xfe\x00\x02", 3) == 0))
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
108 fail("XB field is %c,..., expected c,-2,0,+2", p[1]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
109
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
110 if ((p = check_bam_aux_get(aln, "ZZ", 'I')) && bam_aux2i(p) != 1000000)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
111 fail("ZZ field is %d, expected 1000000", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
112
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
113 if ((p = bam_aux_get(aln, "Y1")) && bam_aux2i(p) != -2147483647-1)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
114 fail("Y1 field is %d, expected -2^31", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
115
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
116 if ((p = bam_aux_get(aln, "Y2")) && bam_aux2i(p) != -2147483647)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
117 fail("Y2 field is %d, expected -2^31+1", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
118
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
119 if ((p = bam_aux_get(aln, "Y3")) && bam_aux2i(p) != -1)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
120 fail("Y3 field is %d, expected -1", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
121
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
122 if ((p = bam_aux_get(aln, "Y4")) && bam_aux2i(p) != 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
123 fail("Y4 field is %d, expected 0", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
124
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
125 if ((p = bam_aux_get(aln, "Y5")) && bam_aux2i(p) != 1)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
126 fail("Y5 field is %d, expected 1", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
127
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
128 if ((p = bam_aux_get(aln, "Y6")) && bam_aux2i(p) != 2147483647)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
129 fail("Y6 field is %d, expected 2^31-1", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
130
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
131 // TODO Checking these perhaps requires inventing bam_aux2u() or so
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
132 #if 0
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
133 if ((p = bam_aux_get(aln, "Y7")) && bam_aux2i(p) != 2147483648)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
134 fail("Y7 field is %d, expected 2^31", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
135
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
136 if ((p = bam_aux_get(aln, "Y8")) && bam_aux2i(p) != 4294967295)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
137 fail("Y8 field is %d, expected 2^32-1", bam_aux2i(p));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
138 #endif
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
139
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
140 if (sam_format1(header, aln, &ks) < 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
141 fail("can't format record");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
142
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
143 if (strcmp(ks.s, r1) != 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
144 fail("record formatted incorrectly: \"%s\"", ks.s);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
145
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
146 free(ks.s);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
147 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
148 else fail("can't read record");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
149
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
150 bam_destroy1(aln);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
151 bam_hdr_destroy(header);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
152 sam_close(in);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
153
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
154 return 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
155 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
156
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
157 static void iterators1(void)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
158 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
159 hts_itr_destroy(sam_itr_queryi(NULL, HTS_IDX_REST, 0, 0));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
160 hts_itr_destroy(sam_itr_queryi(NULL, HTS_IDX_NONE, 0, 0));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
161 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
162
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
163 static void faidx1(const char *filename)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
164 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
165 int n;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
166 faidx_t *fai = fai_load(filename);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
167 if (fai == NULL) fail("can't load faidx file");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
168
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
169 n = faidx_fetch_nseq(fai);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
170 if (n != 7) fail("faidx_fetch_nseq returned %d, expected 7", n);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
171
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
172 n = faidx_nseq(fai);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
173 if (n != 7) fail("faidx_nseq returned %d, expected 7", n);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
174
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
175 fai_destroy(fai);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
176 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
177
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
178 int main(int argc, char **argv)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
179 {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
180 status = EXIT_SUCCESS;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
181
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
182 aux_fields1();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
183 iterators1();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
184 if (argc >= 2) faidx1(argv[1]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
185
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
186 return status;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
187 }