QT4_WRAP_CPP(MOC_SOURCES ${MOC_HEADERS})
SET(SOURCES alphabet.cpp
+ annotations.cpp
annotation_colors.cpp
color.cpp
conserved_path.cpp
#include <map>
#include <string>
-#include "alg/color.hpp"
-#include "alg/sequence.hpp"
+#include "color.hpp"
+#include "sequence.hpp"
struct DefaultColorMap;
struct DefaultColorMap
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;
#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
{
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);
}
};
BOOST_CLASS_EXPORT(Color)
-
#endif
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());
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
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() )
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)
{
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()
{
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) {
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();
++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();
++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);
}
}
// 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);
{
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':
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()));
}
#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
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;
//! 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)
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.
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)
{
}
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)
{
}
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;
}
#define SEQ_SPAN_HPP_
#include <string>
+#include <map>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
//! 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;
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() {};
//! 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>
{
}
+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(""),
new_seq.annots.push_back(new_annot);
}
}
-
}
+
Sequence
Sequence::subseq(size_type start, size_type count, SeqSpan::strand_type strand) const
{
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;
{
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();
};
BOOST_CLASS_EXPORT(motif);
+class Sequence;
+typedef boost::shared_ptr<Sequence> SequenceRef;
//! sequence track for mussa.
class Sequence
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&);
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);
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);
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");
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;
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
{