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