From: Diane Trout Date: Fri, 30 Mar 2007 18:36:28 +0000 (+0000) Subject: incorporate drawable and annotations X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=f3e6762bedaf3775619a36f4103c8cf35d2ca887 incorporate drawable and annotations this removes most of the contents of GlSequence in favor of drawable, and adds shared_ptrs to both drawable and annotations into SeqSpan. One problem is getting the code to do coping instead of sharing a reference at the right time. What I've got right now is I added some constructors that take ThingRefs (aka boost::shared_ptr) and those will create copies, while the more standard reference or pointer initializers just copy the shared_ptr. This was a bit problematic in the case of GlSeqBrowser, which really needs to make sure that its glsequences have their own drawable component. --- diff --git a/alg/CMakeLists.txt b/alg/CMakeLists.txt index 13448bc..0234d94 100644 --- a/alg/CMakeLists.txt +++ b/alg/CMakeLists.txt @@ -11,6 +11,7 @@ SET(MOC_HEADERS QT4_WRAP_CPP(MOC_SOURCES ${MOC_HEADERS}) SET(SOURCES alphabet.cpp + annotations.cpp annotation_colors.cpp color.cpp conserved_path.cpp diff --git a/alg/annotation_colors.hpp b/alg/annotation_colors.hpp index 2fdb4f1..eaabc17 100644 --- a/alg/annotation_colors.hpp +++ b/alg/annotation_colors.hpp @@ -4,8 +4,8 @@ #include #include -#include "alg/color.hpp" -#include "alg/sequence.hpp" +#include "color.hpp" +#include "sequence.hpp" struct DefaultColorMap; struct DefaultColorMap diff --git a/alg/color.cpp b/alg/color.cpp index 64eb782..ffc974c 100644 --- a/alg/color.cpp +++ b/alg/color.cpp @@ -19,6 +19,14 @@ Color::Color(float red, float green, float blue, float alpha) set(red, green, blue, alpha); } +Color::Color(const ColorRef c) +{ + set(c->colors[RedChannel], + c->colors[GreenChannel], + c->colors[BlueChannel], + c->colors[AlphaChannel]); +} + void Color::set(float r, float g, float b, float a) { colors[RedChannel] = r; diff --git a/alg/color.hpp b/alg/color.hpp index abf8b68..0c4f3c7 100644 --- a/alg/color.hpp +++ b/alg/color.hpp @@ -1,12 +1,17 @@ #ifndef _GLCOLOR_H_ #define _GLCOLOR_H_ +#include + #include #include #include #include +class Color; +typedef boost::shared_ptr ColorRef; + //! convienece class for handling opengl colors class Color { @@ -15,6 +20,7 @@ public: Color(const Color &); //! initialize with red, green, blue, alpha Color(float r, float g, float b, float a=1.0); + Color(const ColorRef); //! set all channels simultaneously void set(float r, float g, float b, float a=1.0); @@ -47,6 +53,5 @@ private: } }; BOOST_CLASS_EXPORT(Color) - #endif diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index e9d55b9..03afaf5 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -336,26 +336,27 @@ void GlSeqBrowser::clear_selection() void GlSeqBrowser::push_sequence(const Sequence& s) { - GlSequence gs(s, color_mapper); + GlSequenceRef gs(new GlSequence(s, color_mapper)); push_sequence(gs); } -void GlSeqBrowser::push_sequence(boost::shared_ptr s) +void GlSeqBrowser::push_sequence(SequenceRef s) { - boost::shared_ptr gs(new GlSequence(*s, color_mapper)); + GlSequenceRef gs(new GlSequence(*s, color_mapper)); push_sequence(gs); } void GlSeqBrowser::push_sequence(GlSequence gs) { - boost::shared_ptr new_gs(new GlSequence(gs)); + GlSequenceRef new_gs(new GlSequence(gs)); push_sequence(new_gs); } -void GlSeqBrowser::push_sequence(boost::shared_ptr gs) +void GlSeqBrowser::push_sequence(GlSequenceRef gs) { + GlSequenceRef new_gs(new GlSequence(gs)); clear_links(); - track_container.push_back(gs); + track_container.push_back(new_gs); update_layout(); if (track_container.size() > 1) path_segments.push_back(pair_segment_map()); diff --git a/alg/glsequence.cpp b/alg/glsequence.cpp index 73fc4da..17fb561 100644 --- a/alg/glsequence.cpp +++ b/alg/glsequence.cpp @@ -9,83 +9,96 @@ using namespace std; GlSequence::GlSequence(const Sequence &s, boost::shared_ptr cm) : Sequence(s), - seq_x(0.0), - seq_y(0.0), - seq_z(1.0), - seq_height(12.0), color_mapper(cm), - drawColor(new Color(0.0, 0.0, 0.0)), char_pix_per_world_unit(2.5) { + seq->setDrawable(default_drawable()); } GlSequence::GlSequence(const GlSequence &s) : Sequence(s), - seq_x(s.seq_x), - seq_y(s.seq_y), - seq_z(s.seq_z), - seq_height(s.seq_height), color_mapper(s.color_mapper), - drawColor(s.drawColor), char_pix_per_world_unit(s.char_pix_per_world_unit) { + seq->setDrawable(copy_drawable(s.seq->drawable())); } GlSequence::GlSequence(const GlSequence *s) : Sequence(s), - seq_x(s->seq_x), - seq_y(s->seq_y), - seq_z(s->seq_z), - seq_height(s->seq_height), color_mapper(s->color_mapper), - drawColor(s->drawColor), char_pix_per_world_unit(s->char_pix_per_world_unit) { + seq->setDrawable(copy_drawable(s->seq->drawable())); +} + +GlSequence::GlSequence(const GlSequenceRef s) + : Sequence( (SequenceRef)s ), + color_mapper(s->color_mapper), + char_pix_per_world_unit(s->char_pix_per_world_unit) +{ + seq->setDrawable(copy_drawable(s->seq->drawable())); } GlSequence &GlSequence::operator=(const GlSequence & s) { if (this != &s) { Sequence::operator=(s); - seq_x = s.seq_x; - seq_y = s.seq_y; - seq_z = s.seq_z; - seq_height = s.seq_height; + seq->setDrawable(copy_drawable(s.seq->drawable())); color_mapper = s.color_mapper; - drawColor = s.drawColor; assert(char_pix_per_world_unit == s.char_pix_per_world_unit); } return *this; } -void GlSequence::setX(GLfloat value) +DrawableRef GlSequence::default_drawable() { - seq_x = value; + ColorRef c(new Color(0.0, 0.0, 0.0)); + DrawableRef d(new Drawable(0.0, 0.0, 1.0, 12.0, c)); + return d; } -GLfloat GlSequence::x() const +DrawableRef GlSequence::copy_drawable(DrawableRef old_d) { - return seq_x; + ColorRef c(old_d->color()); + DrawableRef d(new Drawable(old_d)); + // use the same color + d->setColor(c); + return d; } -GLfloat GlSequence::right() const +void GlSequence::setX(float value) { - return size()+seq_x; + seq->drawable()->setX(value); +} + +float GlSequence::x() const +{ + return seq->drawable()->x(); } void GlSequence::setY(GLfloat value) { - seq_y = value; + seq->drawable()->setY(value); } -GLfloat GlSequence::y() const +float GlSequence::y() const { - return seq_y; + return seq->drawable()->y(); } -GLfloat GlSequence::height() const +float GlSequence::z() const { - return seq_height; + return seq->drawable()->z(); +} + +float GlSequence::height() const +{ + return seq->drawable()->height(); +} + +GLfloat GlSequence::right() const +{ + return size()+x(); } GLfloat GlSequence::size() const @@ -95,7 +108,7 @@ GLfloat GlSequence::size() const Sequence::size_type GlSequence::leftbase(GLfloat left) const { - left = ceil(left - seq_x); + left = ceil(left - x()); if (left < 0) return 0; else if (left > Sequence::size() ) @@ -106,7 +119,7 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const Sequence::size_type GlSequence::rightbase(GLfloat right) const { - right = floor(right) - seq_x; + right = floor(right) - x(); if (right > Sequence::size()) return Sequence::size(); else if ( right < 0) @@ -137,21 +150,31 @@ GlSequence GlSequence::subseq(size_type start, size_type count) const { GlSequence new_seq(*this); new_seq.seq = seq->subseq(start, count); + // make sure our subseq has a drawable attached to it + // perhaps we should figure out correct x,y,z,h coords + DrawableRef d(default_drawable()); + // and default to our current color + ColorRef c(color()); + d->setColor(c); + new_seq.seq->setDrawable(d); copy_children(new_seq, start, count); return new_seq; } -//! set default track draw color -void GlSequence::setColor(boost::shared_ptr &c) +void GlSequence::setColor(ColorRef &c) +{ + seq->drawable()->setColor(c); +} + +ColorRef GlSequence::color() { - drawColor = c; + return seq->drawable()->color(); } -//! get default track draw color -boost::shared_ptr GlSequence::color() +const ColorRef GlSequence::color() const { - return drawColor; + return seq->drawable()->color(); } int GlSequence::get_viewport_width_in_pixels() @@ -207,8 +230,8 @@ void GlSequence::draw_box(GLfloat world_left, GLfloat world_right, { GLfloat pixel_width = pixelWidth(world_left, world_right); GLfloat offset = height/2.0; - GLfloat top = seq_y + offset; - GLfloat bottom = seq_y - offset; + GLfloat top = y() + offset; + GLfloat bottom = y() - offset; // make our box be at least 1 pixel if ((right-left) < pixel_width) { @@ -224,15 +247,15 @@ void GlSequence::draw_box(GLfloat world_left, GLfloat world_right, void GlSequence::draw_track(GLfloat left, GLfloat right) const { - glColor3fv(drawColor->get()); + glColor3fv(color()->get()); // draw main sequence track - draw_box(left, right, seq_x, seq_x+Sequence::size(), seq_height, 0.0); + draw_box(left, right, x(), x()+Sequence::size(), height(), 0.0); } void GlSequence::draw_annotations(GLfloat left, GLfloat right) const { // draw annotations - GLfloat annotation_z = seq_z + 10.0; + GLfloat annotation_z = z() + 10.0; const std::list& annots = Sequence::annotations(); const std::list& motifs = Sequence::motifs(); for (std::list::const_iterator annot_itor = annots.begin(); @@ -240,8 +263,8 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const ++annot_itor) { glColor3f(0.0, 0.8, 0.0); - draw_box(left, right, seq_x+annot_itor->begin, seq_x+annot_itor->end, - seq_height, annotation_z); + draw_box(left, right, x()+annot_itor->begin, x()+annot_itor->end, + height(), annotation_z); } // if motifs? for (std::list::const_iterator motifs_itor = motifs.begin(); @@ -249,8 +272,8 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const ++motifs_itor) { glColor3fv(color_mapper->lookup("motif", motifs_itor->sequence).get()); - draw_box(left, right, seq_x+motifs_itor->begin, seq_x+motifs_itor->end, - seq_height, annotation_z+1.0); + draw_box(left, right, x()+motifs_itor->begin, x()+motifs_itor->end, + height(), annotation_z+1.0); } } @@ -321,7 +344,7 @@ void GlSequence::draw_sequence(GLfloat left, GLfloat right) const // FIXME: basically this needs to be greater than the number of annotations const GLfloat z = 30; glLineWidth(1); - glColor3fv(drawColor->get()); + glColor3fv(color()->get()); Sequence::const_iterator seq_itor = region_begin(left, right); Sequence::const_iterator seq_end = region_end(left, right); @@ -337,7 +360,7 @@ void GlSequence::draw_sequence(GLfloat left, GLfloat right) const { assert ( basepair < Sequence::size() ); glPushMatrix(); - glTranslatef( seq_x+leftbase(left) + basepair + glyph_margin, seq_y, 1.0 ); + glTranslatef( x()+leftbase(left) + basepair + glyph_margin, y(), 1.0 ); glScalef(glyph_x_scale, 1.0, 1.0); switch (*seq_itor) { case 'A': case 'a': @@ -367,10 +390,10 @@ void GlSequence::draw_sequence(GLfloat left, GLfloat right) const bool operator==(const GlSequence &left, const GlSequence &right) { - return ( (left.seq_x == right.seq_x) and - (left.seq_y == right.seq_y) and - (left.seq_z == right.seq_z) and - (left.seq_height == right.seq_height) and - (left.drawColor == right.drawColor)); + return ( (left.x() == right.x()) and + (left.y() == right.y()) and + (left.z() == right.z()) and + (left.height() == right.height()) and + (left.color() == right.color())); } diff --git a/alg/glsequence.hpp b/alg/glsequence.hpp index 62014b4..cbb933c 100644 --- a/alg/glsequence.hpp +++ b/alg/glsequence.hpp @@ -13,6 +13,9 @@ #include #endif +class GlSequence; +typedef boost::shared_ptr GlSequenceRef; + //! Manage rendering a mussa sequence track /*! The idea is this will keep track of the location of where the sequence * is being rendered, and handle displaying annotations on that track @@ -24,25 +27,41 @@ public: boost::shared_ptr cm); GlSequence(const GlSequence & s); GlSequence(const GlSequence *); + //! Make a new GlSequence, using a copy of SeqSpan + GlSequence(const GlSequenceRef); + GlSequence &operator=(const GlSequence &s); + static DrawableRef default_drawable(); + static DrawableRef copy_drawable(DrawableRef s); + + //! set our starting x (horizontal) coordinate + void setX(float x); + //! get our starting x (horizontal) coordinate + float x() const; + //! set our current y (vertical) position + void setY(float y); + //! get our current y (vertical) position + float y() const; + //! get our current z (depth) position + float z() const; + //! how thick (high) the track we're drawing is + float height() const; + + //! set our default draw color + void setColor(ColorRef &c ); + //! return our draw color + const ColorRef color() const; + //! return our draw color + ColorRef color(); + //! draw a track /*! left and right are the edges of the current viewport */ void draw(GLfloat left, GLfloat right) const; - //! set our starting x (horizontal) coordinate - void setX(GLfloat); - //! get our starting x (horizontal) coordinate - GLfloat x() const; //! get our right (horizontal) coordinate (size-x) - GLfloat right() const; - //! set our current y (vertical) position - void setY(GLfloat); - //! get our current y (vertical) position - GLfloat y() const; - //! how thick (high) the track we're drawing is - GLfloat height() const; + float right() const; //! how long is our sequence track? (computed from the sequence) GLfloat size() const; @@ -60,10 +79,6 @@ public: //! return a subsequence as a GlSequence (instead of a Sequence subsequence) GlSequence subseq(size_type start, size_type count) const; - //! set track color - void setColor(boost::shared_ptr &); - boost::shared_ptr color(); - //! how big is a pixel in world coordinats GLfloat pixelWidth(GLfloat, GLfloat) const; //! how big is a pixel in world coordinats (specifying viewport size) @@ -85,12 +100,7 @@ public: friend bool operator==(const GlSequence &left, const GlSequence &right); protected: - GLfloat seq_x; - GLfloat seq_y; - GLfloat seq_z; - GLfloat seq_height; boost::shared_ptr color_mapper; - boost::shared_ptr drawColor; const GLfloat char_pix_per_world_unit; //! Return the pixel width of the opengl viewport. diff --git a/alg/seq_span.cpp b/alg/seq_span.cpp index 1eb5e93..581ef83 100644 --- a/alg/seq_span.cpp +++ b/alg/seq_span.cpp @@ -10,7 +10,9 @@ SeqSpan::SeqSpan(const SeqSpan &o) seq_start(o.seq_start), seq_count(o.seq_count), parent(o.parent), - rc_seq(o.rc_seq) + rc_seq(o.rc_seq), + seq_annotations(o.seq_annotations), + seq_drawable(o.seq_drawable) { } @@ -19,7 +21,9 @@ SeqSpan::SeqSpan(const SeqSpan *p) seq_start(p->seq_start), seq_count(p->seq_count), parent(p->parent), - rc_seq(p->rc_seq) + rc_seq(p->rc_seq), + seq_annotations(p->seq_annotations), + seq_drawable(p->seq_drawable) { } @@ -133,6 +137,8 @@ SeqSpan &SeqSpan::operator=(const SeqSpan& s) seq_count = s.seq_count; parent = s.parent; rc_seq = s.rc_seq; + //seq_annotations.reset(s.seq_annotations); + //seq_drawable.reset(s.seq_drawable); } return *this; } diff --git a/alg/seq_span.hpp b/alg/seq_span.hpp index 5a2da12..f5e5748 100644 --- a/alg/seq_span.hpp +++ b/alg/seq_span.hpp @@ -2,6 +2,7 @@ #define SEQ_SPAN_HPP_ #include +#include #include #include @@ -18,6 +19,8 @@ //! These classes provide for the internal implementation for the Sequence class #include "seq.hpp" +#include "annotations.hpp" +#include "drawable.hpp" class SeqSpan; typedef boost::shared_ptr SeqSpanRef; @@ -128,11 +131,16 @@ public: std::string sequence() const; //! are both sequences derived from the same sequence tree? static bool isFamily(const SeqSpan& a, const SeqSpan& b); + + //! access annotations dictionary + AnnotationsRef annotations() const { return seq_annotations; } + //! set annotations dictionary + void setAnnotations(AnnotationsRef a) { seq_annotations = a; } + //! get data for drawing + DrawableRef drawable() const { return seq_drawable; } + //! store drawing data + void setDrawable(DrawableRef d) { seq_drawable = d; } - //! fill in our rc_seq variable - void initialize_rc_seq() const; - - friend class Sequence; private: //! do not statically initialize, only create with new SeqSpan() {}; @@ -148,10 +156,18 @@ protected: //! keep a reference to who our parent span is SeqSpanRef parent; - + //! hold a reverse complement version of our sequence if needed - SeqStringRef rc_seq; + SeqStringRef rc_seq; + //! fill in our rc_seq variable + void initialize_rc_seq() const; + //! annotations provides a python-dictionary like place for metadata + AnnotationsRef seq_annotations; + //! store information needed for drawing + DrawableRef seq_drawable; + + friend class Sequence; // boost::serialization support friend class boost::serialization::access; template diff --git a/alg/sequence.cpp b/alg/sequence.cpp index 68fa014..608ddd3 100644 --- a/alg/sequence.cpp +++ b/alg/sequence.cpp @@ -122,6 +122,15 @@ Sequence::Sequence(const Sequence* o) { } +Sequence::Sequence(const SequenceRef o) + : seq(new SeqSpan(o->seq)), + header(o->header), + species(o->species), + annots(o->annots), + motif_list(o->motif_list) +{ +} + Sequence::Sequence(const SeqSpanRef& seq_ref) : seq(seq_ref), header(""), @@ -538,8 +547,8 @@ void Sequence::copy_children(Sequence &new_seq, size_type start, size_type count new_seq.annots.push_back(new_annot); } } - } + Sequence Sequence::subseq(size_type start, size_type count, SeqSpan::strand_type strand) const { @@ -551,7 +560,10 @@ Sequence::subseq(size_type start, size_type count, SeqSpan::strand_type strand) Sequence new_seq = *this; new_seq.seq = seq->subseq(start, count, strand); - + if (seq->annotations()) { + AnnotationsRef a(new Annotations(*(seq->annotations()))); + new_seq.seq->setAnnotations(a); + } copy_children(new_seq, start, count); return new_seq; diff --git a/alg/sequence.hpp b/alg/sequence.hpp index 80aa49f..fbd753f 100644 --- a/alg/sequence.hpp +++ b/alg/sequence.hpp @@ -72,7 +72,7 @@ struct motif : public annot { std::string sequence; - motif() : annot(), sequence("") {}; + motif() : annot(), sequence("") {}; //! this constructor is for when we're adding motifs to our annotations motif(int begin, std::string motif); ~motif(); @@ -88,6 +88,8 @@ private: }; BOOST_CLASS_EXPORT(motif); +class Sequence; +typedef boost::shared_ptr SequenceRef; //! sequence track for mussa. class Sequence @@ -111,9 +113,13 @@ public: Sequence(const std::string& seq, AlphabetRef a = reduced_dna_alphabet, SeqSpan::strand_type strand = SeqSpan::PlusStrand); + //! make a new sequence, with the same SeqSpan Sequence(const Sequence& seq); + //! make a new sequence, with the same SeqSpan Sequence(const Sequence *); - Sequence(const SeqSpanRef&); + //! Make a new sequence using a copy of SeqSpan + Sequence(const SequenceRef); + Sequence(const SeqSpanRef&); ~Sequence(); //! assignment to constant sequences Sequence &operator=(const Sequence&); diff --git a/alg/test/test_glsequence.cpp b/alg/test/test_glsequence.cpp index 37b76ee..bd528d3 100644 --- a/alg/test/test_glsequence.cpp +++ b/alg/test/test_glsequence.cpp @@ -14,7 +14,6 @@ using namespace std; BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment ) { boost::shared_ptr cm(new AnnotationColors); - // I don't trust my operator= hack so lets make sure it works. string s0("AAGGCCTT"); string s1("TTGGCCAA"); Sequence seq0(s0); @@ -32,6 +31,36 @@ BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment ) BOOST_CHECK( glseq0.get_sequence() == s1 ); } +BOOST_AUTO_TEST_CASE( glsequence_copy_constructor ) +{ + boost::shared_ptr cm(new AnnotationColors); + string s0("AAAAAAGGGGGG"); + + GlSequenceRef glsp0(new GlSequence(s0, cm)); + glsp0->setY(100.0); + BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0); + BOOST_CHECK_EQUAL(glsp0->y(), 100.0); + + GlSequenceRef glsp0ref(glsp0); + GlSequenceRef glsp0copy(new GlSequence(glsp0)); + BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0); + BOOST_CHECK_EQUAL(glsp0->y(), 100.0); + BOOST_CHECK_EQUAL(glsp0ref->get_sequence(), s0); + BOOST_CHECK_EQUAL(glsp0ref->y(), 100.0); + BOOST_CHECK_EQUAL(glsp0copy->get_sequence(), s0); + BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0); + + glsp0ref->setY(50.0); + BOOST_CHECK_EQUAL(glsp0->y(), 50.0); + BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0); + BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0); + + glsp0copy->setY(75.0); + BOOST_CHECK_EQUAL(glsp0->y(), 50.0); + BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0); + BOOST_CHECK_EQUAL(glsp0copy->y(), 75.0); +} + BOOST_AUTO_TEST_CASE( glsequence_color ) { boost::shared_ptr cm(new AnnotationColors); diff --git a/alg/test/test_seq_span.cpp b/alg/test/test_seq_span.cpp index b646c1f..4955867 100644 --- a/alg/test/test_seq_span.cpp +++ b/alg/test/test_seq_span.cpp @@ -73,6 +73,23 @@ BOOST_AUTO_TEST_CASE( seqspan_from_seqspan ) BOOST_CHECK_EQUAL(span3->sequence(), str1); } +BOOST_AUTO_TEST_CASE( seqspan_copy ) +{ + SeqSpanRef span1(new SeqSpan("AAAAGGGG")); + SeqSpanRef span2 = span1->subseq(0,4); + SeqSpanRef span2ref(span2); + SeqSpanRef span2copy(new SeqSpan(span2)); + + BOOST_CHECK_EQUAL(span2->start(), 0); + BOOST_CHECK_EQUAL(span2ref->start(), 0); + BOOST_CHECK_EQUAL(span2copy->start(), 0); + + span2->setStart(2); + BOOST_CHECK_EQUAL(span2->start(), 2); + BOOST_CHECK_EQUAL(span2ref->start(), 2); + BOOST_CHECK_EQUAL(span2copy->start(), 0); +} + BOOST_AUTO_TEST_CASE( seqspan_equality ) { std::string str1("AAGGCCTT"); diff --git a/alg/test/test_sequence.cpp b/alg/test/test_sequence.cpp index cf417d9..38852a5 100644 --- a/alg/test/test_sequence.cpp +++ b/alg/test/test_sequence.cpp @@ -20,6 +20,19 @@ namespace fs=boost::filesystem; using namespace std; +BOOST_AUTO_TEST_CASE( sequence_copy_constructor ) +{ + SequenceRef s(new Sequence("AAAAGGGG")); + s->set_species("foo"); + BOOST_CHECK_EQUAL(s->get_species(), "foo"); + + SequenceRef c(new Sequence(s)); + BOOST_CHECK_EQUAL(c->get_species(), "foo"); + + c->set_species("bar"); + BOOST_CHECK_EQUAL(s->get_species(), "foo"); + BOOST_CHECK_EQUAL(c->get_species(), "bar"); +} BOOST_AUTO_TEST_CASE( sequence_get_sequence ) { Sequence s; diff --git a/mussa_exceptions.hpp b/mussa_exceptions.hpp index 1c577f4..e85b2d9 100644 --- a/mussa_exceptions.hpp +++ b/mussa_exceptions.hpp @@ -31,6 +31,13 @@ public: mussa_error(msg) {}; }; +//! error doing a key lookup in the annotations class +class annotations_key_error : public mussa_error { +public: + explicit annotations_key_error(const std::string& msg) : + mussa_error(msg) {}; +}; + //! Error loading sequence class sequence_load_error : public mussa_load_error {