47621af4eac63fe11154339bdb39aaa69fd1bfd8
[mussa.git] / alg / test / test_glsequence.cpp
1 #define BOOST_AUTO_TEST_MAIN
2 #include <boost/test/auto_unit_test.hpp>
3 #include <boost/test/floating_point_comparison.hpp>
4 #include <boost/shared_ptr.hpp>
5
6 #include <string>
7
8 #include "alg/annotation_colors.hpp"
9 #include "alg/glsequence.hpp"
10 #include "alg/sequence.hpp"
11
12 using namespace std;
13
14 BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment )
15 {
16   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
17   string s0("AAGGCCTT");
18   string s1("TTGGCCAA");
19   Sequence seq0(s0);
20   Sequence seq1(s1);
21
22   GlSequence glseq0(seq0, cm);
23   BOOST_CHECK (glseq0.get_sequence() == s0);
24   GlSequence glseq1(seq1, cm);
25   GlSequence glseq_copy0(glseq0);
26
27   BOOST_CHECK(glseq_copy0.get_sequence() == glseq0.get_sequence());
28   BOOST_CHECK( glseq_copy0.get_sequence() == glseq0.get_sequence());
29
30   glseq0 = glseq1;
31   BOOST_CHECK( glseq0.get_sequence() == s1 );
32 }
33
34 BOOST_AUTO_TEST_CASE( glsequence_copy_constructor )
35 {
36   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
37   string s0("AAAAAAGGGGGG");
38
39   GlSequenceRef glsp0(new GlSequence(s0, cm));
40   glsp0->setY(100.0);
41   BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0);
42   BOOST_CHECK_EQUAL(glsp0->y(), 100.0);
43   
44   GlSequenceRef glsp0ref(glsp0);
45   GlSequenceRef glsp0copy(new GlSequence(glsp0));
46   BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0);
47   BOOST_CHECK_EQUAL(glsp0->y(), 100.0);
48   BOOST_CHECK_EQUAL(glsp0ref->get_sequence(), s0);
49   BOOST_CHECK_EQUAL(glsp0ref->y(), 100.0);  
50   BOOST_CHECK_EQUAL(glsp0copy->get_sequence(), s0);
51   BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0);
52   
53   glsp0ref->setY(50.0);
54   BOOST_CHECK_EQUAL(glsp0->y(), 50.0);
55   BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0);  
56   BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0);
57   
58   glsp0copy->setY(75.0);
59   BOOST_CHECK_EQUAL(glsp0->y(), 50.0);
60   BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0);  
61   BOOST_CHECK_EQUAL(glsp0copy->y(), 75.0);
62 }
63
64 BOOST_AUTO_TEST_CASE( glsequence_color )
65 {
66   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
67   boost::shared_ptr<Color> black(new Color(0.0, 0.0, 0.0, 1.0));
68   boost::shared_ptr<Color> c(new Color(0.1, 0.2, 0.3, 0.4));
69   Sequence seq("AAGGCCTT");
70   GlSequence s(seq, cm);
71   
72   BOOST_CHECK_EQUAL(*s.color(), *black );
73   s.setColor( c );
74   BOOST_CHECK_EQUAL( *(s.color()), *c );
75 }
76
77 BOOST_AUTO_TEST_CASE( glsequence_find_real_sequence )
78 {
79   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
80   GlSequence s("AAAAAAAAAANNNNNANNA", cm);
81   //            0123456789012345678
82   s.add_annotations_for_defined_sequence();
83   
84   BOOST_CHECK_EQUAL(s.annotations().size(), 3);
85   std::vector<SeqSpanRef> annot(s.annotations().begin(), s.annotations().end());
86   BOOST_CHECK_EQUAL(annot[0]->start(), 0);
87   BOOST_CHECK_EQUAL(annot[0]->stop(), 10);
88   BOOST_CHECK_EQUAL(annot[1]->start(), 15);
89   BOOST_CHECK_EQUAL(annot[1]->size(), 1);
90   BOOST_CHECK_EQUAL(annot[2]->start(), 18);
91   BOOST_CHECK_EQUAL(annot[2]->size(), 1);
92 }
93
94 void dummy_draw_func(SeqSpanRef ref, float l, float r)
95 {
96 }
97   
98 BOOST_AUTO_TEST_CASE( glsequence_set_annotation_drawfunc_by_type )
99 {
100   ColorRef default_color(new Color(1.0, 0.0, 0.0));
101   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
102   GlSequence s("AAAAGGGGNNNNTTTTCCC", cm);
103   //            0123456789012345678
104   s.add_annotation("Aname", "value", 0, 4);
105   s.add_annotation("Gname", "value", 4, 4);
106   s.add_annotation("Tname", "gene", 12, 4);
107   s.update_annotation_draw_function("gene", dummy_draw_func, default_color);
108
109   BOOST_CHECK_EQUAL(s.annotations().size(), 3);
110   std::vector<SeqSpanRef> annot(s.annotations().begin(), s.annotations().end());
111   // the two not updated annotations shouldn't have a drawable attached to them yet 
112   BOOST_CHECK( not annot[0]->drawable());
113   BOOST_CHECK( not annot[1]->drawable());
114   // the annotation updated must be drawable
115   BOOST_REQUIRE(annot[2]->drawable());
116   // and it must have the right draw function
117   BOOST_CHECK_EQUAL(annot[2]->drawable()->drawFunction(), dummy_draw_func);
118   BOOST_CHECK_EQUAL(annot[2]->drawable()->color(), default_color);
119 }
120
121 BOOST_AUTO_TEST_CASE( glsequence_renderable )
122 {
123   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
124   Sequence seq("AAGGCCTT");
125   GlSequence s(seq, cm);
126
127   // way more base pairs than viewport pixel width 
128   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false );
129   // way fewer basepairs than viewport pixel width
130   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true);
131
132   BOOST_CHECK_CLOSE((double)s.pixelWidth(0, 100, 100), 1.0, 1e-6);
133   BOOST_CHECK_CLOSE((double)s.pixelWidth(0, 1000, 100), 10.0, 1e-6);
134 }
135
136 BOOST_AUTO_TEST_CASE( glsequence_sequence )
137 {
138   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
139   string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN");
140   string::size_type seqlen = seq_string.size();
141   Sequence seq(seq_string);
142   GlSequence glseq(seq, cm);
143
144   BOOST_CHECK( glseq.region_begin(0, 50) == seq.begin() );
145   // always make sure we return seq.end() regardless of how much extra
146   // is asked for
147   BOOST_CHECK( glseq.region_end(0, seqlen+10) == seq.end() );
148   // do we get the right end pointer?
149   BOOST_CHECK( glseq.region_end(0, 5) == seq.begin()+5 );
150
151   // when we request far too much sequence what do we get?
152   BOOST_CHECK( glseq.region_begin(seqlen+10, seqlen+20) == seq.end() );
153   BOOST_CHECK( glseq.region_end(seqlen+10, seqlen+20) == seq.end() );
154
155   // we cant ask for reversed sequences with region_begin/end
156   BOOST_CHECK( glseq.region_begin(10, 5) == seq.end() );
157   BOOST_CHECK( glseq.region_end(10, 5) == seq.end() );
158
159   Sequence::const_iterator seq_itor;
160
161   // if we as for an empty segment? start and end should equal
162   seq_itor = glseq.region_begin(10, 10);
163   BOOST_CHECK( seq_itor == glseq.region_end(10, 10) );
164
165   // reuse seq_itor downhere 
166   string::const_iterator str_itor;
167   for(str_itor = seq.begin(),
168       seq_itor = glseq.begin();
169       str_itor != seq.end() and 
170       seq_itor != glseq.end();
171       ++str_itor, ++seq_itor)
172   {
173     BOOST_CHECK_EQUAL( *str_itor, *seq_itor );
174   }
175 }
176
177 // make sure the computation of the leftmost and rightmost base is correct
178 BOOST_AUTO_TEST_CASE( glsequence_leftright_base )
179 {
180   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
181   std::string seq_string = "AAGGCCTT";
182   Sequence seq(seq_string);
183   GlSequence glseq(seq, cm);
184
185   BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 );
186   BOOST_CHECK_EQUAL( glseq.leftbase(   0.5 ), 1 );
187   BOOST_CHECK_EQUAL( glseq.leftbase(   5.0 ), 5 );
188   BOOST_CHECK_EQUAL( glseq.leftbase( 500.0 ), seq_string.size() );
189   BOOST_CHECK_EQUAL( glseq.rightbase(    0.0 ), 0 );
190   BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() );
191   BOOST_CHECK_EQUAL( glseq.rightbase( seq_string.size()-0.5),
192                      seq_string.size()-1);
193 }
194
195 // do our left and right most base computations still work if
196 // we move the sequence around?
197 BOOST_AUTO_TEST_CASE( glsequence_movex )
198 {
199   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
200   std::string seq_string = "AAGGCCTTAAGGCCTT";
201   Sequence seq(seq_string);
202   GlSequence glseq(seq, cm);
203
204   glseq.setX(-5);
205   BOOST_CHECK_EQUAL( glseq.leftbase(-100.0), 0 );
206   BOOST_CHECK_EQUAL( glseq.leftbase(   0.0), 5 );
207   BOOST_CHECK_EQUAL( glseq.leftbase(  -2.0), 3 );
208   BOOST_CHECK_EQUAL( glseq.leftbase( 100.0), seq_string.size() );
209   BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() );
210   BOOST_CHECK_EQUAL( glseq.rightbase(    8.0 ), 8+5 );
211   BOOST_CHECK_EQUAL( glseq.rightbase(   -7.0 ), 0 );
212 }
213
214 // Check iterators
215 BOOST_AUTO_TEST_CASE( glsequence_check_iterators )
216 {
217   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
218   std::string seq_string = "AAGGCCTTAAGGCCTT";
219   Sequence seq(seq_string);
220   GlSequence glseq(seq, cm);
221
222   Sequence::const_iterator seq_begin_i;
223   Sequence::const_iterator seq_end_i;
224
225   BOOST_CHECK(glseq.region_begin(5, -5) == seq.end());
226   BOOST_CHECK(glseq.region_begin(0, 20) == seq.begin());
227   BOOST_CHECK(glseq.region_begin(10,20) == seq.begin()+10);
228
229   BOOST_CHECK(glseq.region_end(5, -5) == seq.end());
230   BOOST_CHECK(glseq.region_end(0, 20) == seq.end());
231   BOOST_CHECK(glseq.region_end(0, 10) == seq.begin()+10);
232
233   glseq.setX(-5);
234   BOOST_CHECK(glseq.region_begin(0, 10) == seq.begin()+5);
235   BOOST_CHECK(glseq.region_end(0, 15) == seq.end());
236 }
237
238 BOOST_AUTO_TEST_CASE( glsequence_subseq ) 
239 {
240   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
241   boost::shared_ptr<Color> c(new Color(1.0, 0.5, 0.5));
242   
243   GlSequence seq("AAGGCCTT", cm);
244   seq.setColor(c);
245   
246   GlSequence subseq = seq.subseq(4,2);
247   BOOST_CHECK_EQUAL(subseq.get_sequence(), "CC");
248   BOOST_CHECK_EQUAL(subseq.color(), c);
249 }
250
251 /*
252 BOOST_AUTO_TEST_CASE ( shared_ptr_test )
253 {
254   boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
255   // I don't trust my operator= hack so lets make sure it works.
256   string s0("AAGGCCTT");
257   string s1("TTGGCCAA");
258   Sequence seq0(s0);
259   BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
260   Sequence seq1(s1);
261   BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
262
263   // make a block to test deallocation
264   {
265     GlSequence glseq0(seq0, cm);
266     BOOST_CHECK_EQUAL(seq0.use_count(), 2);
267     GlSequence glseq1(seq1, cm);
268     BOOST_CHECK_EQUAL(seq1.use_count(), 2);
269
270     glseq0 = glseq1;
271     BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
272     BOOST_CHECK_EQUAL( seq1.use_count(), 3 );
273   }
274   BOOST_CHECK_EQUAL(seq0.use_count(), 1);
275   BOOST_CHECK_EQUAL(seq1.use_count(), 1);
276 }
277 */