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