source: trunk/test/bam.cc @ 3201

Last change on this file since 3201 was 3201, checked in by Peter, 9 years ago

add #define YAT_HAVE_LIBBAM to API and replace HAVE_LIBBAM accordingly.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1// $Id: bam.cc 3201 2014-05-03 12:57:59Z peter $
2//
3// Copyright (C) 2013, 2014 Peter Johansson
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18#include <config.h>
19
20#include "Suite.h"
21
22#ifdef YAT_HAVE_LIBBAM
23#include "yat/omic/BamFile.h"
24#include "yat/omic/BamRead.h"
25#endif
26
27#include <cassert>
28#include <string>
29
30using namespace theplu::yat;
31
32void test1(test::Suite& suite);
33
34int main(int argc, char* argv[])
35{
36  test::Suite suite(argc, argv, true);
37#ifdef YAT_HAVE_LIBBAM
38  test1(suite);
39#endif
40  return suite.return_value();
41}
42
43#ifdef YAT_HAVE_LIBBAM
44using namespace omic;
45
46void test_aux(test::Suite& suite, const BamRead& b)
47{
48  suite.out() << "test aux\n";
49  BamRead bam(b);
50
51  char c = 'h';
52  int size = bam.aux_size();
53  bam.aux_append("ZZ", 'A', 1, (uint8_t*)(&c));
54  suite.out() << "size: " << size << " " << bam.aux_size() << "\n";
55  suite.add(bam.aux_size() == size+4);
56  bam.aux("ZZ");
57  char c1 = bam_aux2A(bam.aux("ZZ"));
58  suite.out() << c << "==" << c1 << "\n";
59  suite.add(c==c1);
60  bam.aux_del("ZZ");
61  if (!suite.add(bam.aux_size() == size))
62    suite.err() << "error: incorrect size: " << bam.aux_size() << "\n";
63}
64
65
66void test_cigar(test::Suite& suite, const BamRead& b, const BamHeader& hdr)
67{
68  BamRead bam(b);
69
70  suite.out() << "test cigar:\n";
71  suite.out() << bam.cigar_str() << "\n";
72  OutBamFile os("cigar_test.bam", hdr);
73  std::vector<uint32_t> cig;
74
75  bam.cigar(cig);
76  suite.out() << bam.cigar_str() << "\n";
77  suite.add(bam.cigar_str()=="");
78  os.write(bam);
79
80  cig.resize(1);
81  cig[0] = bam_cigar_gen(bam.sequence_length(), BAM_CMATCH);
82  bam.cigar(cig);
83  suite.out() << bam.cigar_str() << "\n";
84  suite.add(bam.cigar_str()=="100M");
85  os.write(bam);
86
87  cig.resize(3);
88  cig[0] = bam_cigar_gen(50, BAM_CMATCH);
89  cig[1] = bam_cigar_gen(2, BAM_CDEL);
90  cig[2] = bam_cigar_gen(50, BAM_CMATCH);
91  bam.cigar(cig);
92  suite.out() << bam.cigar_str() << "\n";
93  suite.add(bam.cigar_str()=="50M2D50M");
94  os.write(bam);
95
96  // check that other elements in data* is preserved
97  if (!suite.add(same_query_name(b, bam)))
98    suite.err() << "error: \n'" << b.name() << "'\n'" << bam.name() << "'\n";
99
100  if (!suite.add(b.sequence()==bam.sequence()))
101    suite.err() << "error: \n'" << b.sequence() << "'\n'"
102                << bam.sequence() << "'\n";
103
104  for (int32_t i=0; i<b.core().l_qseq; ++i)
105    if (bam.qual(i) != b.qual(i)) {
106      suite.err() << "error: qual: " << i << " " << bam.qual(i)
107                  << " not euqal " << b.qual(i) << "\n";
108      suite.add(false);
109    }
110
111  os.close();
112}
113
114
115void test_sequence(test::Suite& suite, const BamRead& b)
116{
117  suite.out() << "test sequence\n";
118  BamRead bam(b);
119  std::string seq = b.sequence();
120  std::vector<uint8_t> qual;
121  qual.reserve(seq.size());
122  for (size_t i=0; i<seq.size(); ++i)
123    qual.push_back(bam.qual(i));
124  assert(seq.size()==100);
125  bam.sequence(seq, qual);
126
127  if (bam.sequence()!=seq) {
128    suite.add(false);
129    suite.err() << "incorrect sequence:" << bam.sequence() << "\n";
130    suite.err() << "expected: " << seq << "\n";
131  }
132
133  // just for consistency
134  std::vector<uint32_t> cig;
135  bam.cigar(cig);
136  bam.core().flag &= ~BAM_FUNMAP;
137
138  // trim off one base
139  seq.resize(seq.size()-1);
140  qual.resize(qual.size()-1);
141  bam.sequence(seq, qual);
142
143  if (bam.sequence()!=seq) {
144    suite.add(false);
145    suite.err() << "incorrect sequence:" << bam.sequence() << "\n";
146    suite.err() << "expected: " << seq << "\n";
147  }
148
149  // extend sequence
150  seq.resize(120, 'A');
151  qual.resize(120, 0);
152  bam.sequence(seq, qual);
153  if (bam.sequence()!=seq) {
154    suite.add(false);
155    suite.err() << "incorrect sequence:" << bam.sequence() << "\n";
156    suite.err() << "expected: " << seq << "\n";
157  }
158}
159
160
161void test_name(test::Suite& suite, const BamRead& b)
162{
163  suite.out() << "test name\n";
164  BamRead bam(b);
165  std::string name = "my-new-name";
166  bam.name(name);
167  if (bam.name() != name) {
168    suite.add(false);
169    suite.err() << "error: name: '" << bam.name()
170                << "' expected: '" << name << "'\n";
171  }
172  // check that other fields are not changed
173  if (bam.cigar_str()!=b.cigar_str()) {
174    suite.add(false);
175    suite.err() << "error: cigar str:" << bam.cigar_str() << " != "
176                << b.cigar_str() << "\n";
177  }
178  if (bam.sequence()!=b.sequence()) {
179    suite.add(false);
180    suite.err() << "error: sequence:" << bam.sequence() << " != "
181                << b.sequence() << "\n";
182  }
183}
184
185
186void test_open3(test::Suite& suite, const BamHeader& header)
187{
188  OutBamFile out("yaya.bam", header, 0);
189  out.close();
190  out.open("yaya.bam", header, 9);
191  out.close();
192  try {
193    out.open("yaya.bam", header, 10);
194    suite.add(false);
195    suite.err() << "open(\"yaya.bam\", header, 10): did not throw\n";
196  }
197  catch (std::invalid_argument& e) {
198    suite.err() << "expected exception: " << e.what() << "\n";
199  }
200  out.close();
201}
202
203
204void test_write(test::Suite& suite, const BamHeader& header)
205{
206  OutBamFile out;
207  BamRead read;
208  try {
209    // trying to write to a file not open
210    out.write(read);
211    suite.add(false);
212    suite.err() << "write(BamRead): did not throw\n";
213  }
214  catch (utility::runtime_error& e) {
215    suite.err() << "expected exception: " << e.what() << "\n";
216  }
217}
218
219
220void test1(test::Suite& suite)
221{
222  std::string file = "../../data/foo.sorted.bam";
223
224  InBamFile in;
225  in.open(file);
226  BamRead bam;
227  in.read(bam);
228  std::string str = "AGCTTTGTTATTATTTGAGGGTGTGGTTCAGTTGTAAACAGTGTATG"
229    "TTTTAGAATTTGTGTTATTGTGATGGCGATGACCAAGTACAACATATTTCCCA";
230  std::string seq = bam.sequence();
231  if (str!=seq) {
232    suite.err() << "incorrect sequence: '" << bam.sequence() << "'\n";
233    suite.err() << "expected:           '" << str << "'\n";
234    suite.add(false);
235  }
236  uint8_t c = bam.sequence(24);
237  if (c != 4) {
238    suite.add(false);
239    suite.err() << "error: sequence: " << static_cast<int>(c)
240                << " expected " << 4 << "\n";
241  }
242  bam.sequence(24, 8);
243  c = bam.sequence(24);
244  if (c != 8) {
245    suite.add(false);
246    suite.err() << "error: sequence: " << static_cast<int>(c)
247                << " expected " << 8 << "\n";
248  }
249  uint8_t q = bam.qual(24);
250  if (q != 72) {
251    suite.add(false);
252    suite.err() << "error: quality: " << static_cast<int>(q)
253                << " expected " << 72 << "\n";
254  }
255  uint8_t new_q = 60;
256  bam.qual(24, new_q);
257  q = bam.qual(24);
258  if (q != new_q) {
259    suite.add(false);
260    suite.err() << "error: quality: " << static_cast<int>(q)
261                << " expected " << new_q << "\n";
262  }
263  test_cigar(suite, bam, in.header());
264  test_aux(suite, bam);
265  test_sequence(suite, bam);
266  test_name(suite, bam);
267  test_open3(suite, in.header());
268  test_write(suite, in.header());
269}
270#endif
Note: See TracBrowser for help on using the repository browser.