incorporate drawable and annotations
authorDiane Trout <diane@caltech.edu>
Fri, 30 Mar 2007 18:36:28 +0000 (18:36 +0000)
committerDiane Trout <diane@caltech.edu>
Fri, 30 Mar 2007 18:36:28 +0000 (18:36 +0000)
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<thing>) 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.

15 files changed:
alg/CMakeLists.txt
alg/annotation_colors.hpp
alg/color.cpp
alg/color.hpp
alg/glseqbrowser.cpp
alg/glsequence.cpp
alg/glsequence.hpp
alg/seq_span.cpp
alg/seq_span.hpp
alg/sequence.cpp
alg/sequence.hpp
alg/test/test_glsequence.cpp
alg/test/test_seq_span.cpp
alg/test/test_sequence.cpp
mussa_exceptions.hpp

index 13448bca3cf5baab7e05b4e157a960d504d256c9..0234d943f14f8dbd761248239c59c4b5b2292459 100644 (file)
@@ -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 
index 2fdb4f1ad3391326c19dc3d324a3651b0bcb103e..eaabc1784635f84725c74d832c37d42df909be2a 100644 (file)
@@ -4,8 +4,8 @@
 #include <map>
 #include <string>
 
-#include "alg/color.hpp"
-#include "alg/sequence.hpp"
+#include "color.hpp"
+#include "sequence.hpp"
 
 struct DefaultColorMap;
 struct DefaultColorMap
index 64eb7821e941f2ae0ad203b6fb2f621559e2b40f..ffc974cb3e6068c08e3d285fb1c2623c80347885 100644 (file)
@@ -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;
index abf8b686994ff12c775ce32a3301a51dcada84ec..0c4f3c76759c0c07f1580dcb868ac7f08925a65c 100644 (file)
@@ -1,12 +1,17 @@
 #ifndef _GLCOLOR_H_
 #define _GLCOLOR_H_
 
+#include <boost/shared_ptr.hpp>
+
 #include <boost/serialization/export.hpp>
 #include <boost/serialization/nvp.hpp>
 #include <boost/serialization/version.hpp>
 
 #include <ostream>
 
+class Color;
+typedef boost::shared_ptr<Color> 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
 
index e9d55b985571fa2785fca31c10ee480bc8cefbd6..03afaf56c4fac3707735f9afa90752d96fea19ab 100644 (file)
@@ -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<Sequence> s)
+void GlSeqBrowser::push_sequence(SequenceRef s)
 {
-  boost::shared_ptr<GlSequence> 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<GlSequence> new_gs(new GlSequence(gs));
+  GlSequenceRef new_gs(new GlSequence(gs));
   push_sequence(new_gs);
 }
 
-void GlSeqBrowser::push_sequence(boost::shared_ptr<GlSequence> 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());
index 73fc4daaeeac20b95fe27769ca2c613748cd0534..17fb561c830c5cf3fc241a01e8de2353c4cc8691 100644 (file)
@@ -9,83 +9,96 @@ using namespace std;
 GlSequence::GlSequence(const Sequence &s, 
                        boost::shared_ptr<AnnotationColors> 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<Color> &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<Color> 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<annot>& annots = Sequence::annotations();
   const std::list<motif>& motifs = Sequence::motifs();
   for (std::list<annot>::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<motif>::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()));
 }
 
index 62014b4fc7175c5a1abbcb5699912617184faf74..cbb933c6d3836717e4340e97aac5451bb55b8f12 100644 (file)
@@ -13,6 +13,9 @@
 #include <GL/gl.h>
 #endif
 
+class GlSequence;
+typedef boost::shared_ptr<GlSequence> 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<AnnotationColors> 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<Color> &);
-  boost::shared_ptr<Color> 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<AnnotationColors> color_mapper;
-  boost::shared_ptr<Color> drawColor;
   const GLfloat char_pix_per_world_unit;
 
   //! Return the pixel width of the opengl viewport.
index 1eb5e9344982cce4cf04b1b6ce364a14149de3a9..581ef830c43711e0ca5423502eb50faac791bb07 100644 (file)
@@ -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;
 }
index 5a2da1268d3a62cf807f323d7e39bb450fea5841..f5e574814c532b7ea95246695fc837e7d534bd40 100644 (file)
@@ -2,6 +2,7 @@
 #define SEQ_SPAN_HPP_
 
 #include <string>
+#include <map>
 
 #include <boost/serialization/base_object.hpp>
 #include <boost/serialization/export.hpp>
@@ -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<SeqSpan> 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<class Archive>
index 68fa01460542956a6dabf5864786a50f47080737..608ddd3b2059ba808c283e7726b181bfb27e0ce2 100644 (file)
@@ -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;
index 80aa49f75e17bcf9ca572de2d9b8c53658ea31af..fbd753fb46dc7d0142de209ece821626bd2e2577 100644 (file)
@@ -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<Sequence> 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&);
index 37b76ee06f2fe65fe322b871ce0b5f2e23818e74..bd528d30ffe75d5df7aff874ab24446bed8f8ff2 100644 (file)
@@ -14,7 +14,6 @@ using namespace std;
 BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment )
 {
   boost::shared_ptr<AnnotationColors> 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<AnnotationColors> 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<AnnotationColors> cm(new AnnotationColors);
index b646c1fe41480573598014f59476ba04731338dc..49558677cff21f2270a54e62a1cabe4df565c644 100644 (file)
@@ -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");
index cf417d95348496025280c6eadf28825ced652f0b..38852a5d6f90096ea17944374e25173845656af7 100644 (file)
@@ -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;
index 1c577f4198bc210986822ccfd47bc1a77bf39810..e85b2d98687e5a50304b09cc654c2f8349f1b0f9 100644 (file)
@@ -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
 {