2953 |
16 Jan 13 |
peter |
// $Id$ |
2953 |
16 Jan 13 |
peter |
2 |
// |
4359 |
23 Aug 23 |
peter |
// Copyright (C) 2013, 2014, 2015, 2016, 2017, 2020, 2023 Peter Johansson |
2953 |
16 Jan 13 |
peter |
4 |
// |
2953 |
16 Jan 13 |
peter |
// This program is free software; you can redistribute it and/or modify |
2953 |
16 Jan 13 |
peter |
// it under the terms of the GNU General Public License as published by |
2953 |
16 Jan 13 |
peter |
// the Free Software Foundation; either version 3 of the License, or |
2953 |
16 Jan 13 |
peter |
// (at your option) any later version. |
2953 |
16 Jan 13 |
peter |
9 |
// |
2953 |
16 Jan 13 |
peter |
// This program is distributed in the hope that it will be useful, but |
2953 |
16 Jan 13 |
peter |
// WITHOUT ANY WARRANTY; without even the implied warranty of |
2953 |
16 Jan 13 |
peter |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2953 |
16 Jan 13 |
peter |
// General Public License for more details. |
2953 |
16 Jan 13 |
peter |
14 |
// |
2953 |
16 Jan 13 |
peter |
// You should have received a copy of the GNU General Public License |
2953 |
16 Jan 13 |
peter |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
2953 |
16 Jan 13 |
peter |
17 |
|
2953 |
16 Jan 13 |
peter |
18 |
#include <config.h> |
2953 |
16 Jan 13 |
peter |
19 |
|
2953 |
16 Jan 13 |
peter |
20 |
#include "Suite.h" |
2953 |
16 Jan 13 |
peter |
21 |
|
3883 |
24 Mar 20 |
peter |
22 |
#ifdef YAT_HAVE_HTSLIB |
2953 |
16 Jan 13 |
peter |
23 |
#include "yat/omic/BamFile.h" |
2953 |
16 Jan 13 |
peter |
24 |
#include "yat/omic/BamHeader.h" |
4290 |
03 Feb 23 |
peter |
25 |
#include <set> |
2953 |
16 Jan 13 |
peter |
26 |
#endif |
2953 |
16 Jan 13 |
peter |
27 |
|
4290 |
03 Feb 23 |
peter |
28 |
|
2953 |
16 Jan 13 |
peter |
29 |
using namespace theplu::yat; |
2953 |
16 Jan 13 |
peter |
30 |
|
4264 |
13 Jan 23 |
peter |
31 |
#ifdef YAT_HAVE_HTSLIB |
2953 |
16 Jan 13 |
peter |
32 |
void test1(test::Suite& suite); |
4264 |
13 Jan 23 |
peter |
33 |
#else |
4264 |
13 Jan 23 |
peter |
34 |
void test1(test::Suite& suite) {} |
4264 |
13 Jan 23 |
peter |
35 |
#endif |
2953 |
16 Jan 13 |
peter |
36 |
|
2953 |
16 Jan 13 |
peter |
37 |
int main(int argc, char* argv[]) |
2953 |
16 Jan 13 |
peter |
38 |
{ |
3201 |
03 May 14 |
peter |
39 |
test::Suite suite(argc, argv, true); |
2953 |
16 Jan 13 |
peter |
40 |
try { |
2953 |
16 Jan 13 |
peter |
41 |
test1(suite); |
2953 |
16 Jan 13 |
peter |
42 |
} |
2953 |
16 Jan 13 |
peter |
43 |
catch (std::runtime_error& e) { |
2953 |
16 Jan 13 |
peter |
44 |
suite.err() << "what: " << e.what() << "\n"; |
2953 |
16 Jan 13 |
peter |
45 |
suite.add(false); |
2953 |
16 Jan 13 |
peter |
46 |
} |
2953 |
16 Jan 13 |
peter |
47 |
|
2953 |
16 Jan 13 |
peter |
48 |
return suite.return_value(); |
2953 |
16 Jan 13 |
peter |
49 |
} |
2953 |
16 Jan 13 |
peter |
50 |
|
4264 |
13 Jan 23 |
peter |
51 |
|
4264 |
13 Jan 23 |
peter |
52 |
#ifdef YAT_HAVE_HTSLIB |
4264 |
13 Jan 23 |
peter |
53 |
using namespace omic; |
4264 |
13 Jan 23 |
peter |
54 |
|
4264 |
13 Jan 23 |
peter |
55 |
void test_copy_and_move(test::Suite& suite, const BamHeader& header) |
4264 |
13 Jan 23 |
peter |
56 |
{ |
4264 |
13 Jan 23 |
peter |
57 |
suite.out() << "test copy constructor\n"; |
4264 |
13 Jan 23 |
peter |
58 |
{ |
4264 |
13 Jan 23 |
peter |
59 |
if (true) { |
4264 |
13 Jan 23 |
peter |
60 |
BamHeader copy(header); |
4264 |
13 Jan 23 |
peter |
61 |
if (copy.text() != header.text()) { |
4264 |
13 Jan 23 |
peter |
62 |
suite.add(false); |
4264 |
13 Jan 23 |
peter |
63 |
suite.err() << "copy not identical\n"; |
4264 |
13 Jan 23 |
peter |
64 |
} |
4264 |
13 Jan 23 |
peter |
65 |
} |
4264 |
13 Jan 23 |
peter |
// test that copy destructor doesn't destroy header data |
4264 |
13 Jan 23 |
peter |
67 |
std::string str = header.text(); |
4264 |
13 Jan 23 |
peter |
68 |
suite.add(str.size()); |
4264 |
13 Jan 23 |
peter |
69 |
} |
4264 |
13 Jan 23 |
peter |
70 |
|
4264 |
13 Jan 23 |
peter |
71 |
suite.out() << "test move constructor\n"; |
4264 |
13 Jan 23 |
peter |
72 |
{ |
4264 |
13 Jan 23 |
peter |
73 |
if (true) { |
4264 |
13 Jan 23 |
peter |
74 |
BamHeader copy(header); |
4264 |
13 Jan 23 |
peter |
75 |
BamHeader hdr(std::move(copy)); |
4264 |
13 Jan 23 |
peter |
76 |
if (hdr.text() != header.text()) { |
4264 |
13 Jan 23 |
peter |
77 |
suite.add(false); |
4264 |
13 Jan 23 |
peter |
78 |
suite.err() << "copy constructed with move ctor not identical\n"; |
4264 |
13 Jan 23 |
peter |
79 |
} |
4264 |
13 Jan 23 |
peter |
80 |
} |
4264 |
13 Jan 23 |
peter |
81 |
std::string str = header.text(); |
4264 |
13 Jan 23 |
peter |
82 |
suite.add(str.size()); |
4264 |
13 Jan 23 |
peter |
83 |
} |
4264 |
13 Jan 23 |
peter |
84 |
|
4264 |
13 Jan 23 |
peter |
85 |
|
4264 |
13 Jan 23 |
peter |
86 |
suite.out() << "test copy assignment\n"; |
4264 |
13 Jan 23 |
peter |
87 |
{ |
4264 |
13 Jan 23 |
peter |
88 |
{ |
4264 |
13 Jan 23 |
peter |
89 |
BamHeader copy; |
4264 |
13 Jan 23 |
peter |
90 |
copy = header; |
4264 |
13 Jan 23 |
peter |
91 |
if (copy.text() != header.text()) { |
4264 |
13 Jan 23 |
peter |
92 |
suite.add(false); |
4264 |
13 Jan 23 |
peter |
93 |
suite.err() << "assigned copy not identical\n"; |
4264 |
13 Jan 23 |
peter |
94 |
} |
4264 |
13 Jan 23 |
peter |
95 |
} |
4264 |
13 Jan 23 |
peter |
96 |
std::string str = header.text(); |
4264 |
13 Jan 23 |
peter |
97 |
suite.add(str.size()); |
4264 |
13 Jan 23 |
peter |
98 |
} |
4264 |
13 Jan 23 |
peter |
99 |
|
4264 |
13 Jan 23 |
peter |
100 |
|
4264 |
13 Jan 23 |
peter |
101 |
suite.out() << "test move assignment\n"; |
4264 |
13 Jan 23 |
peter |
102 |
{ |
4264 |
13 Jan 23 |
peter |
103 |
{ |
4264 |
13 Jan 23 |
peter |
104 |
BamHeader copy(header); |
4264 |
13 Jan 23 |
peter |
105 |
BamHeader hdr; |
4264 |
13 Jan 23 |
peter |
106 |
hdr = std::move(copy); |
4264 |
13 Jan 23 |
peter |
107 |
if (hdr.text() != header.text()) { |
4264 |
13 Jan 23 |
peter |
108 |
suite.add(false); |
4264 |
13 Jan 23 |
peter |
109 |
suite.err() << "copy (from move assignment) not identical\n"; |
4264 |
13 Jan 23 |
peter |
110 |
} |
4264 |
13 Jan 23 |
peter |
111 |
} |
4264 |
13 Jan 23 |
peter |
112 |
std::string str = header.text(); |
4264 |
13 Jan 23 |
peter |
113 |
suite.add(str.size()); |
4264 |
13 Jan 23 |
peter |
114 |
} |
4264 |
13 Jan 23 |
peter |
115 |
} |
4264 |
13 Jan 23 |
peter |
116 |
|
4264 |
13 Jan 23 |
peter |
117 |
|
2953 |
16 Jan 13 |
peter |
118 |
void test1(test::Suite& suite) |
2953 |
16 Jan 13 |
peter |
119 |
{ |
2953 |
16 Jan 13 |
peter |
120 |
std::string file = "../../data/foo.sorted.bam"; |
2953 |
16 Jan 13 |
peter |
121 |
|
2953 |
16 Jan 13 |
peter |
122 |
InBamFile bam_stream(file); |
2953 |
16 Jan 13 |
peter |
123 |
BamHeader hdr = bam_stream.header(); |
4264 |
13 Jan 23 |
peter |
124 |
test_copy_and_move(suite, hdr); |
2953 |
16 Jan 13 |
peter |
125 |
suite.out() << hdr.n_targets() << "\n"; |
2953 |
16 Jan 13 |
peter |
126 |
suite.add(hdr.n_targets()==84); |
2953 |
16 Jan 13 |
peter |
127 |
suite.out() << hdr.target_name(0) << "\n"; |
2953 |
16 Jan 13 |
peter |
128 |
if (!suite.add(std::string("1")==hdr.target_name(0))) |
2953 |
16 Jan 13 |
peter |
129 |
suite.err() << "error\n"; |
2999 |
14 Mar 13 |
peter |
130 |
int32_t tid = hdr.tid("1"); |
2999 |
14 Mar 13 |
peter |
131 |
suite.out() << "tid: " << tid << "\n"; |
2999 |
14 Mar 13 |
peter |
132 |
if (!suite.add(tid==0)) |
2999 |
14 Mar 13 |
peter |
133 |
suite.err() << "error\n"; |
2999 |
14 Mar 13 |
peter |
134 |
|
2999 |
14 Mar 13 |
peter |
135 |
int begin, end; |
2999 |
14 Mar 13 |
peter |
136 |
hdr.parse_region("GL000197.1", tid, begin, end); |
2999 |
14 Mar 13 |
peter |
137 |
suite.out() << tid << " " << begin << " " << end << "\n"; |
2999 |
14 Mar 13 |
peter |
138 |
suite.add(tid==35); |
2999 |
14 Mar 13 |
peter |
139 |
hdr.parse_region("GL000197.1:1000-2000", tid, begin, end); |
2999 |
14 Mar 13 |
peter |
140 |
suite.out() << tid << " " << begin << " " << end << "\n"; |
2999 |
14 Mar 13 |
peter |
141 |
if (!suite.add(tid==35)) |
2999 |
14 Mar 13 |
peter |
142 |
suite.err() << "incorrect tid\n"; |
2999 |
14 Mar 13 |
peter |
143 |
if (!suite.add(begin==999)) |
2999 |
14 Mar 13 |
peter |
144 |
suite.err() << "incorrect begin\n"; |
2999 |
14 Mar 13 |
peter |
145 |
if (!suite.add(end==2000)) |
2999 |
14 Mar 13 |
peter |
146 |
suite.err() << "incorrect end\n"; |
2999 |
14 Mar 13 |
peter |
147 |
|
2953 |
16 Jan 13 |
peter |
148 |
suite.out() << hdr.target_name(35) << "\n"; |
2953 |
16 Jan 13 |
peter |
149 |
if (!suite.add(std::string("GL000197.1")==hdr.target_name(35))) |
2953 |
16 Jan 13 |
peter |
150 |
suite.err() << "error\n"; |
2953 |
16 Jan 13 |
peter |
151 |
suite.out() << hdr.target_length(0) << "\n"; |
2953 |
16 Jan 13 |
peter |
152 |
suite.add(hdr.target_length(0)==249250621); |
3408 |
16 Apr 15 |
peter |
153 |
|
3408 |
16 Apr 15 |
peter |
154 |
std::string str = hdr.text(); |
3408 |
16 Apr 15 |
peter |
155 |
std::string str1(str); |
3408 |
16 Apr 15 |
peter |
156 |
str1 += "@PG\tID:prog\tVN:1.0\n"; |
3408 |
16 Apr 15 |
peter |
157 |
omic::BamHeader hdr2(hdr); |
3408 |
16 Apr 15 |
peter |
158 |
hdr.text(str1); |
3408 |
16 Apr 15 |
peter |
159 |
std::string str2 = hdr.text(); |
3408 |
16 Apr 15 |
peter |
160 |
if (str2.substr(0, str.size()) != str) { |
3408 |
16 Apr 15 |
peter |
161 |
suite.add(false); |
3408 |
16 Apr 15 |
peter |
162 |
suite.err() << "incorrect text:\n" << str2 << "\nexpected:\n" |
3408 |
16 Apr 15 |
peter |
163 |
<< str1 << "\n"; |
3408 |
16 Apr 15 |
peter |
164 |
} |
3408 |
16 Apr 15 |
peter |
165 |
else if (str2 != str1) { |
3408 |
16 Apr 15 |
peter |
166 |
suite.add(false); |
3408 |
16 Apr 15 |
peter |
167 |
suite.err() << "error: line was not added to header\n"; |
3408 |
16 Apr 15 |
peter |
168 |
} |
3408 |
16 Apr 15 |
peter |
169 |
if (hdr2.text() != str) { |
3408 |
16 Apr 15 |
peter |
170 |
suite.add(false); |
3408 |
16 Apr 15 |
peter |
171 |
suite.err() << "function text(1) affects copies\n"; |
3408 |
16 Apr 15 |
peter |
172 |
} |
3408 |
16 Apr 15 |
peter |
173 |
|
3409 |
17 Apr 15 |
peter |
174 |
int32_t n_chr = hdr.n_targets(); |
3409 |
17 Apr 15 |
peter |
175 |
|
4290 |
03 Feb 23 |
peter |
// check that we can add another chromosome via a @SG field |
3409 |
17 Apr 15 |
peter |
177 |
std::stringstream ss(hdr.text()); |
3409 |
17 Apr 15 |
peter |
178 |
std::string str3; |
3409 |
17 Apr 15 |
peter |
179 |
std::string line; |
3409 |
17 Apr 15 |
peter |
180 |
int32_t n_targ = 0; |
3409 |
17 Apr 15 |
peter |
181 |
while (getline(ss, line)) { |
3409 |
17 Apr 15 |
peter |
182 |
str3 += line + "\n"; |
3409 |
17 Apr 15 |
peter |
183 |
if (line.substr(0,3) == "@SQ") { |
3409 |
17 Apr 15 |
peter |
184 |
++n_targ; |
3409 |
17 Apr 15 |
peter |
185 |
if (n_targ == n_chr) |
3409 |
17 Apr 15 |
peter |
186 |
str3 += "@SQ\tSN:Zbababababa\tLN:123\n"; |
3409 |
17 Apr 15 |
peter |
187 |
} |
3409 |
17 Apr 15 |
peter |
188 |
} |
3409 |
17 Apr 15 |
peter |
189 |
hdr.text(str3); |
3409 |
17 Apr 15 |
peter |
190 |
|
3409 |
17 Apr 15 |
peter |
191 |
int32_t n = hdr.n_targets(); |
3409 |
17 Apr 15 |
peter |
192 |
if (n != n_chr+1) { |
3409 |
17 Apr 15 |
peter |
193 |
suite.add(false); |
3409 |
17 Apr 15 |
peter |
194 |
suite.err() << "error: incorrect number of targets: " << n |
3409 |
17 Apr 15 |
peter |
195 |
<< " expected " << (n_chr+1) << "\n"; |
3409 |
17 Apr 15 |
peter |
196 |
suite.err() << "header text:\n" << hdr.text() << "===\n"; |
3409 |
17 Apr 15 |
peter |
197 |
} |
3409 |
17 Apr 15 |
peter |
198 |
|
3410 |
21 Apr 15 |
peter |
199 |
suite.err() << hdr.text() << "\n"; |
3410 |
21 Apr 15 |
peter |
200 |
try { |
3410 |
21 Apr 15 |
peter |
201 |
std::string sample_name = hdr.read_group("foo", "SM"); |
3410 |
21 Apr 15 |
peter |
202 |
if (sample_name!="Tumour") { |
3410 |
21 Apr 15 |
peter |
203 |
suite.add(false); |
3410 |
21 Apr 15 |
peter |
204 |
suite.err() << "error: incorrect sample name: '" << sample_name << "'\n"; |
3410 |
21 Apr 15 |
peter |
205 |
} |
3410 |
21 Apr 15 |
peter |
206 |
|
3477 |
09 Mar 16 |
peter |
207 |
typedef BamHeader::read_group_iterator iterator; |
3477 |
09 Mar 16 |
peter |
208 |
iterator it = hdr.read_group_begin(); |
3599 |
22 Jan 17 |
peter |
209 |
test::test_bidirectional_traversal_iterator(it); |
3599 |
22 Jan 17 |
peter |
210 |
test::test_readable_iterator(it); |
3477 |
09 Mar 16 |
peter |
211 |
if (it == hdr.read_group_end()) { |
3477 |
09 Mar 16 |
peter |
212 |
suite.add(false); |
3477 |
09 Mar 16 |
peter |
213 |
suite.err() << "it == hdr.read_group_end()\n"; |
3477 |
09 Mar 16 |
peter |
214 |
} |
3477 |
09 Mar 16 |
peter |
215 |
else { |
3477 |
09 Mar 16 |
peter |
216 |
if (!suite.add(*it == "foo")) |
3477 |
09 Mar 16 |
peter |
217 |
suite.err() << "*it != foo\n"; |
3477 |
09 Mar 16 |
peter |
218 |
std::map<std::string, std::string> m = hdr.read_group(*it); |
3477 |
09 Mar 16 |
peter |
219 |
std::string val = m["SM"]; |
3477 |
09 Mar 16 |
peter |
220 |
if (!suite.add(val == "Tumour")) |
3477 |
09 Mar 16 |
peter |
221 |
suite.err() << "incorrect val: " << val << " expected Tumour\n"; |
3477 |
09 Mar 16 |
peter |
222 |
val = m["PL"]; |
3477 |
09 Mar 16 |
peter |
223 |
if (!suite.add(val == "ILLUMINA")) |
3477 |
09 Mar 16 |
peter |
224 |
suite.err() << "incorrect val: " << val << " expected ILLUMINA\n"; |
3477 |
09 Mar 16 |
peter |
225 |
} |
3477 |
09 Mar 16 |
peter |
226 |
|
3410 |
21 Apr 15 |
peter |
227 |
std::string bwa_version = hdr.program_group("bwa", "VN"); |
3410 |
21 Apr 15 |
peter |
228 |
if (bwa_version!="0.6.1-r104") { |
3410 |
21 Apr 15 |
peter |
229 |
suite.add(false); |
3410 |
21 Apr 15 |
peter |
230 |
suite.err() << "error: incorrect bwa_version: '" << bwa_version << "'\n"; |
3410 |
21 Apr 15 |
peter |
231 |
} |
3410 |
21 Apr 15 |
peter |
232 |
} |
3410 |
21 Apr 15 |
peter |
233 |
catch (std::runtime_error& e) { |
3410 |
21 Apr 15 |
peter |
234 |
suite.add(false); |
3410 |
21 Apr 15 |
peter |
235 |
suite.err() << "error: exception: " << e.what() << "\n"; |
3410 |
21 Apr 15 |
peter |
236 |
} |
3412 |
22 Apr 15 |
peter |
237 |
|
3412 |
22 Apr 15 |
peter |
238 |
try { |
3412 |
22 Apr 15 |
peter |
// try calling unknown ID |
3412 |
22 Apr 15 |
peter |
240 |
hdr.read_group("banana", "SM"); |
3412 |
22 Apr 15 |
peter |
241 |
suite.add(false); |
3412 |
22 Apr 15 |
peter |
242 |
suite.err() << "read_group(\"banana\", \"SM\") didn't throw\n"; |
3412 |
22 Apr 15 |
peter |
243 |
} |
3412 |
22 Apr 15 |
peter |
244 |
catch (utility::runtime_error& e) { |
3412 |
22 Apr 15 |
peter |
245 |
suite.out() << "expected exception with what(): " << e.what() << "\n"; |
3412 |
22 Apr 15 |
peter |
246 |
} |
3412 |
22 Apr 15 |
peter |
247 |
|
3412 |
22 Apr 15 |
peter |
248 |
try { |
3412 |
22 Apr 15 |
peter |
// try calling unknown key |
3412 |
22 Apr 15 |
peter |
250 |
hdr.read_group("foo", "HM"); |
3412 |
22 Apr 15 |
peter |
251 |
suite.add(false); |
3412 |
22 Apr 15 |
peter |
252 |
suite.err() << "read_group(\"foo\", \"HM\") didn't throw\n"; |
3412 |
22 Apr 15 |
peter |
253 |
} |
3412 |
22 Apr 15 |
peter |
254 |
catch (utility::runtime_error& e) { |
3412 |
22 Apr 15 |
peter |
255 |
suite.out() << "expected exception with what(): " << e.what() << "\n"; |
3412 |
22 Apr 15 |
peter |
256 |
} |
4290 |
03 Feb 23 |
peter |
257 |
|
4290 |
03 Feb 23 |
peter |
258 |
|
4290 |
03 Feb 23 |
peter |
259 |
std::set<std::string> |
4290 |
03 Feb 23 |
peter |
260 |
programs(hdr.program_group_begin(), hdr.program_group_end()); |
4290 |
03 Feb 23 |
peter |
261 |
for (const auto& prog : programs) |
4290 |
03 Feb 23 |
peter |
262 |
suite.out() << prog << "\n"; |
4290 |
03 Feb 23 |
peter |
263 |
if (!programs.count("bwa") || !programs.count("samtools") || |
4290 |
03 Feb 23 |
peter |
264 |
programs.size()!=3) { |
4290 |
03 Feb 23 |
peter |
265 |
suite.add(false); |
4290 |
03 Feb 23 |
peter |
266 |
suite.err() << "incorrect programs\n"; |
4290 |
03 Feb 23 |
peter |
267 |
} |
4290 |
03 Feb 23 |
peter |
268 |
hdr.program_group("bwa"); |
4264 |
13 Jan 23 |
peter |
269 |
} |
2953 |
16 Jan 13 |
peter |
270 |
#endif |