From 946b9e9a4290b013533184f20fd1871c0a04e6ad Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Fri, 23 Jun 2006 01:56:58 +0000 Subject: [PATCH] Getting closer to a subanalysis mode This is a big patch, in order to create the subanalysis mode I wanted a class that'd hold a reference to a sequence and some start/stop locations which'd let the user edit what region they want to use in the subanalysis before creating the new analysis. I started setting up a SequenceLocation and SequenceLocationModel (for the qt MVC classes) but then I learned that C++ reference types aren't particularly good things to store in containers, as when the original variable that all the references are pointing to goes away you get invalid memory exceptions. So I went through and switched most of those references to the boost::shared_ptr which is a fairly simple reference counted pointer. This did make most of the C++ code happy, but my python wrapping is increasingly losing functionality. Also as a bonus this increased use of pointers I think will improve the sharing of the AnnotationColors color mappers. --- alg/CMakeLists.txt | 3 +- alg/glseqbrowser.cpp | 31 ++++--- alg/glseqbrowser.hpp | 21 ++--- alg/glsequence.cpp | 43 +++++----- alg/glsequence.hpp | 9 +- alg/mussa.cpp | 70 +++++++++------- alg/mussa.hpp | 16 ++-- alg/sequence.cpp | 14 +--- alg/sequence_location.cpp | 76 +++++++++++++++++ alg/sequence_location.hpp | 28 +++++++ alg/test/CMakeLists.txt | 3 +- alg/test/test_glseqbrowser.cpp | 10 ++- alg/test/test_glsequence.cpp | 100 +++++++++++++++-------- alg/test/test_mussa.cpp | 16 ++-- alg/test/test_sequence_location.cpp | 34 ++++++++ py/glsequence.cpp | 2 + py/mussa.cpp | 2 +- qui/CMakeLists.txt | 2 + qui/MussaWindow.cpp | 2 +- qui/SequenceLocationModel.cpp | 78 ++++++++++++++++++ qui/SequenceLocationModel.hpp | 34 ++++++++ qui/SubanalysisWindow.cpp | 12 +-- qui/SubanalysisWindow.hpp | 10 ++- qui/motif_editor/MotifEditor.cpp | 8 +- qui/seqbrowser/SequenceBrowserWidget.cpp | 9 +- qui/seqbrowser/SequenceBrowserWidget.hpp | 7 +- 26 files changed, 470 insertions(+), 170 deletions(-) create mode 100644 alg/sequence_location.cpp create mode 100644 alg/sequence_location.hpp create mode 100644 alg/test/test_sequence_location.cpp create mode 100644 qui/SequenceLocationModel.cpp create mode 100644 qui/SequenceLocationModel.hpp diff --git a/alg/CMakeLists.txt b/alg/CMakeLists.txt index 299a3f3..5eeb555 100644 --- a/alg/CMakeLists.txt +++ b/alg/CMakeLists.txt @@ -21,7 +21,8 @@ SET(SOURCES annotation_colors.cpp nway_other.cpp nway_paths.cpp parse_options.cpp - sequence.cpp) + sequence.cpp + sequence_location.cpp ) ADD_LIBRARY( mussa_core STATIC ${SOURCES} ${MOC_SOURCES}) INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR} diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index 2a159af..4e18733 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -7,14 +7,6 @@ using namespace std; -GlSeqBrowser::SequenceLocation::SequenceLocation( - const Sequence& s, - int l, - int c -) : sequence(s), left(l), count(c) -{ -} - GlSeqBrowser::GlSeqBrowser() : border_width(25), cur_ortho(400.0, 0.0, 600.0, 0.0), @@ -293,14 +285,14 @@ double GlSeqBrowser::zoom() const return zoom_level; } -void GlSeqBrowser::setColorMapper(AnnotationColors& cm) +void GlSeqBrowser::setColorMapper(boost::shared_ptr cm) { color_mapper = cm; } -AnnotationColors& GlSeqBrowser::colorMapper() +const AnnotationColors& GlSeqBrowser::colorMapper() { - return color_mapper; + return *color_mapper; } void GlSeqBrowser::clear() @@ -319,13 +311,21 @@ void GlSeqBrowser::clear_selection() selected_tracks.clear(); } -void GlSeqBrowser::push_sequence(const Sequence &s) +void GlSeqBrowser::push_sequence(const Sequence& s) +{ + boost::shared_ptr seq_copy(new Sequence(s)); + GlSequence gs(seq_copy, color_mapper); + push_sequence(gs); +} + + +void GlSeqBrowser::push_sequence(boost::shared_ptr s) { GlSequence gs(s, color_mapper); push_sequence(gs); } -void GlSeqBrowser::push_sequence(GlSequence &gs) +void GlSeqBrowser::push_sequence(GlSequence gs) { clear_links(); track_container.push_back(gs); @@ -466,11 +466,10 @@ void GlSeqBrowser::copySelectedTracksAsSequences(std::list& result) } void GlSeqBrowser::copySelectedTracksAsSeqLocation( - std::list& result) + std::list& result) { struct AsSeqLocation { - static GlSeqBrowser::SequenceLocation - formatter(const Sequence& seq, int left, int right) + static SequenceLocation formatter(const Sequence& seq, int left, int right) { return SequenceLocation(seq, left, right); } diff --git a/alg/glseqbrowser.hpp b/alg/glseqbrowser.hpp index 80d80a8..fab880f 100644 --- a/alg/glseqbrowser.hpp +++ b/alg/glseqbrowser.hpp @@ -1,5 +1,6 @@ #ifndef _GLTRACKS_H_ #define _GLTRACKS_H_ +#include #include #include @@ -8,6 +9,7 @@ #include "alg/annotation_colors.hpp" #include "alg/sequence.hpp" #include "alg/glsequence.hpp" +#include "alg/sequence_location.hpp" //! Manage rendering a collection of glSequences class GlSeqBrowser @@ -58,18 +60,20 @@ public: //! center the provided path in the current viewport void centerOnPath(const std::vector&); - void setColorMapper(AnnotationColors& cm); - AnnotationColors& colorMapper(); + void setColorMapper(boost::shared_ptr cm); + const AnnotationColors& colorMapper(); //! clear our tracks and connections void clear(); //! clear everything related to a selection void clear_selection(); + //! add a sequence to the back of our track container (makes copy of s) + void push_sequence(const Sequence& s); //! add a sequence to the back of our track container - void push_sequence(const Sequence &s); + void push_sequence(boost::shared_ptr s); //! add a glsequence to the back of our track container - void push_sequence(GlSequence &s); + void push_sequence(GlSequence s); //! return our track container const std::vector& sequences() const; @@ -90,13 +94,6 @@ public: //! copy sequence from selected tracks as plain sequences void copySelectedTracksAsString(std::string& copy_buffer); - //! convenience structure for holding selected track segments - struct SequenceLocation { - const Sequence& sequence; - int left; - int count; - SequenceLocation(const Sequence& s, int l, int c); - }; //! copy tracks as a sequence and its coordinates void copySelectedTracksAsSeqLocation(std::list& result); @@ -198,7 +195,7 @@ private: //! the center of our current viewport (world coord) (used for scrollbar) float viewport_center; double zoom_level; - AnnotationColors color_mapper; + boost::shared_ptr color_mapper; //! container of all the GlSequences loaded into our scene std::vector track_container; //! counter for each path added to us via connect diff --git a/alg/glsequence.cpp b/alg/glsequence.cpp index 8af0adb..54a13fa 100644 --- a/alg/glsequence.cpp +++ b/alg/glsequence.cpp @@ -6,7 +6,8 @@ #include using namespace std; -GlSequence::GlSequence(const Sequence &s, AnnotationColors& cm) +GlSequence::GlSequence(boost::shared_ptr s, + boost::shared_ptr cm) : seq(s), seq_x(0.0), seq_y(0.0), @@ -33,7 +34,7 @@ GlSequence::GlSequence(const GlSequence &s) GlSequence &GlSequence::operator=(const GlSequence & s) { if (this != &s) { - const_cast(seq) = s.seq; + seq = s.seq; seq_x = s.seq_x; seq_y = s.seq_y; seq_z = s.seq_z; @@ -47,7 +48,7 @@ GlSequence &GlSequence::operator=(const GlSequence & s) const Sequence& GlSequence::sequence() const { - return seq; + return *seq; } void GlSequence::setX(GLfloat value) @@ -82,7 +83,7 @@ GLfloat GlSequence::height() const GLfloat GlSequence::length() const { - return seq.size(); + return seq->size(); } Sequence::size_type GlSequence::leftbase(GLfloat left) const @@ -90,8 +91,8 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const left = ceil(left - seq_x); if (left < 0) return 0; - else if (left > seq.size() ) - return seq.size(); + else if (left > seq->size() ) + return seq->size(); else return (Sequence::size_type)left; } @@ -99,8 +100,8 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const Sequence::size_type GlSequence::rightbase(GLfloat right) const { right = floor(right) - seq_x; - if (right > seq.size()) - return seq.size(); + if (right > seq->size()) + return seq->size(); else if ( right < 0) return 0; else @@ -109,30 +110,30 @@ Sequence::size_type GlSequence::rightbase(GLfloat right) const Sequence::const_iterator GlSequence::sequence_begin() const { - return seq.begin(); + return seq->begin(); } Sequence::const_iterator GlSequence::sequence_end() const { - return seq.end(); + return seq->end(); } Sequence::const_iterator GlSequence::sequence_begin(GLfloat left, GLfloat right) const { - if ( leftbase(left) > seq.size() or left > right ) - return seq.end(); + if ( leftbase(left) > seq->size() or left > right ) + return seq->end(); else - return seq.begin() + leftbase(left); + return seq->begin() + leftbase(left); } Sequence::const_iterator GlSequence::sequence_end(GLfloat left, GLfloat right) const { - if ( rightbase(right) > seq.size() or left > right ) - return seq.end(); + if ( rightbase(right) > seq->size() or left > right ) + return seq->end(); else - return seq.begin() + rightbase(right); + return seq->begin() + rightbase(right); } @@ -221,15 +222,15 @@ void GlSequence::draw_track(GLfloat left, GLfloat right) const { glColor3fv(drawColor.get()); // draw main sequence track - draw_box(left, right, seq_x, seq_x+seq.size(), seq_height, 0.0); + draw_box(left, right, seq_x, seq_x+seq->size(), seq_height, 0.0); } void GlSequence::draw_annotations(GLfloat left, GLfloat right) const { // draw annotations GLfloat annotation_z = seq_z + 10.0; - const std::list& annots = seq.annotations(); - const std::list& motifs = seq.motifs(); + const std::list& annots = seq->annotations(); + const std::list& motifs = seq->motifs(); for (std::list::const_iterator annot_itor = annots.begin(); annot_itor != annots.end(); ++annot_itor) @@ -243,7 +244,7 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const motifs_itor != motifs.end(); ++motifs_itor) { - glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get()); + glColor3fv(color_mapper->lookup("motif", motifs_itor->sequence).get()); draw_box(left, right, seq_x+motifs_itor->start, seq_x+motifs_itor->end, seq_height, annotation_z+1.0); } @@ -321,7 +322,7 @@ void GlSequence::draw_sequence(GLfloat left, GLfloat right) const assert(seq_end - seq_itor >= 0); while(seq_itor != seq_end) { - assert ( basepair < seq.size() ); + assert ( basepair < seq->size() ); glPushMatrix(); glTranslatef( seq_x+leftbase(left) + basepair, seq_y, 1.0 ); glScalef(0.1, 1.0, 1.0); diff --git a/alg/glsequence.hpp b/alg/glsequence.hpp index c20e194..5b08fb3 100644 --- a/alg/glsequence.hpp +++ b/alg/glsequence.hpp @@ -1,6 +1,8 @@ #ifndef _GL_SEQUENCE_H_ #define _GL_SEQUENCE_H_ +#include + #include "alg/annotation_colors.hpp" #include "alg/sequence.hpp" #include "alg/color.hpp" @@ -18,7 +20,8 @@ class GlSequence { public: - GlSequence(const Sequence & s, AnnotationColors &cm); + GlSequence(boost::shared_ptr s, + boost::shared_ptr cm); GlSequence(const GlSequence & s); GlSequence &operator=(const GlSequence &s); @@ -83,12 +86,12 @@ public: friend bool operator==(const GlSequence &left, const GlSequence &right); protected: - const Sequence& seq; + boost::shared_ptr seq; GLfloat seq_x; GLfloat seq_y; GLfloat seq_z; GLfloat seq_height; - AnnotationColors& color_mapper; + boost::shared_ptr color_mapper; Color drawColor; const GLfloat char_pix_per_world_unit; diff --git a/alg/mussa.cpp b/alg/mussa.cpp index 4677a6c..79078b2 100644 --- a/alg/mussa.cpp +++ b/alg/mussa.cpp @@ -27,6 +27,7 @@ using namespace std; Mussa::Mussa() + : color_mapper(new AnnotationColors) { clear(); connect(&the_paths, SIGNAL(progress(const std::string&, int, int)), @@ -60,7 +61,7 @@ Mussa::clear() win_append = false; thres_append = false; motif_sequences.clear(); - color_mapper.clear(); + if(color_mapper) color_mapper->clear(); the_paths.clear(); } @@ -173,7 +174,7 @@ void Mussa::createLocalAlignment(std::list::iterator begin, std::list& result, std::list >& reversed) { - const vector& raw_seq = the_seqs; + const vector_sequence_type& raw_seq = the_seqs; ConservedPath::path_type aligned_path; size_t i2, i3; int x_start, x_end; @@ -213,15 +214,17 @@ void Mussa::createLocalAlignment(std::list::iterator begin, x_start = (abs(a_path[i2]-rc_1+win_i)); x_end = (abs(a_path[i2+1]-rc_2+win_i)); + boost::shared_ptr cur(raw_seq[i2]) ; + boost::shared_ptr next(raw_seq[i2+1]); // RC case handling // ugh, and xor...only want rc coloring if just one of the nodes is rc // if both nodes are rc, then they are 'normal' relative to each other if((rc_list[i2] || rc_list[i2+1] )&&!(rc_list[i2] && rc_list[i2+1])) { //the hideous rc matching logic - not complex, but annoying - if(!(( (raw_seq[i2][x_start]=='A')&&(raw_seq[i2+1][x_end]=='T')) || - ((raw_seq[i2][x_start]=='T')&&(raw_seq[i2+1][x_end]=='A')) || - ((raw_seq[i2][x_start]=='G')&&(raw_seq[i2+1][x_end]=='C')) || - ((raw_seq[i2][x_start]=='C')&&(raw_seq[i2+1][x_end]=='G'))) ) + if(!(( ((*cur)[x_start]=='A')&&((*next)[x_end]=='T')) || + (((*cur)[x_start]=='T')&&((*next)[x_end]=='A')) || + (((*cur)[x_start]=='G')&&((*next)[x_end]=='C')) || + (((*cur)[x_start]=='C')&&((*next)[x_end]=='G'))) ) { full_match = false; } else { @@ -230,9 +233,8 @@ void Mussa::createLocalAlignment(std::list::iterator begin, } else { // forward match - if (!( (raw_seq[i2][x_start] == raw_seq[i2+1][x_end]) && - (raw_seq[i2][x_start] != 'N') && - (raw_seq[i2+1][x_end] != 'N') ) ) { + if (!( ((*cur)[x_start] == (*next)[x_end]) && + ((*cur)[x_start] != 'N') && ((*next)[x_end] != 'N') ) ) { full_match = false; } else { aligned_path.push_back(x_start); @@ -253,12 +255,19 @@ void Mussa::createLocalAlignment(std::list::iterator begin, } -void Mussa::append_sequence(Sequence a_seq) +void Mussa::append_sequence(const Sequence& a_seq) +{ + boost::shared_ptr seq_copy(new Sequence(a_seq)); + the_seqs.push_back(seq_copy); +} + +void Mussa::append_sequence(boost::shared_ptr a_seq) { the_seqs.push_back(a_seq); } -const vector& + +const vector >& Mussa::sequences() const { return the_seqs; @@ -267,10 +276,10 @@ Mussa::sequences() const void Mussa::load_sequence(fs::path seq_file, fs::path annot_file, int fasta_index, int sub_seq_start, int sub_seq_end) { - Sequence aseq; - aseq.load_fasta(seq_file, fasta_index, sub_seq_start, sub_seq_end); + boost::shared_ptr aseq(new Sequence); + aseq->load_fasta(seq_file, fasta_index, sub_seq_start, sub_seq_end); if ( not annot_file.empty() ) { - aseq.load_annot(annot_file, sub_seq_start, sub_seq_end); + aseq->load_annot(annot_file, sub_seq_start, sub_seq_end); } the_seqs.push_back(aseq); } @@ -451,7 +460,7 @@ Mussa::seqcomp() all_comps[i].push_back(dummy_comp); } for(vector::size_type i = 0; i < the_seqs.size(); i++) { - seq_lens.push_back(the_seqs[i].size()); + seq_lens.push_back(the_seqs[i]->size()); } int seqcomps_done = 0; int seqcomps_todo = (the_seqs.size() * (the_seqs.size()-1)) / 2; @@ -462,8 +471,8 @@ Mussa::seqcomp() { //cout << "seqcomping: " << i << " v. " << i2 << endl; all_comps[i][i2].setup(window, threshold); - all_comps[i][i2].seqcomp(the_seqs[i], the_seqs[i2], false); - all_comps[i][i2].seqcomp(the_seqs[i], the_seqs[i2].rev_comp(),true); + all_comps[i][i2].seqcomp(*the_seqs[i], *the_seqs[i2], false); + all_comps[i][i2].seqcomp(*the_seqs[i], the_seqs[i2]->rev_comp(),true); ++seqcomps_done; emit progress("seqcomp", seqcomps_done, seqcomps_todo); } @@ -472,7 +481,6 @@ Mussa::seqcomp() void Mussa::nway() { - vector some_Seqs; the_paths.set_soft_threshold(soft_thres); @@ -484,11 +492,12 @@ Mussa::nway() } else if (ana_mode == EntropyNway) { + vector some_Seqs; //unlike other methods, entropy needs to look at the sequence at this stage some_Seqs.clear(); for(vector::size_type i = 0; i < the_seqs.size(); i++) { - some_Seqs.push_back(the_seqs[i]); + some_Seqs.push_back(*the_seqs[i]); } the_paths.setup_ent(ent_thres, some_Seqs); // ent analysis extra setup @@ -541,7 +550,7 @@ Mussa::save() for(vector::size_type i = 0; i < the_seqs.size(); i++) { - the_seqs[i].save(save_file); + the_seqs[i]->save(save_file); } save_file << "" << endl; @@ -574,7 +583,6 @@ Mussa::load(fs::path ana_file) fs::path a_file_path; fs::path ana_path(ana_file); bool parsing_path; - Sequence tmp_seq; string err_msg; ostringstream append_info; vector empty_FLP_vector; @@ -600,9 +608,9 @@ Mussa::load(fs::path ana_file) // this is a bit of a hack due to C++ not acting like it should with files for (i = 1; i <= seq_num; i++) { - tmp_seq.clear(); + boost::shared_ptr tmp_seq(new Sequence); //cout << "mussa_class: loading museq frag... " << a_file_path.string() << endl; - tmp_seq.load_museq(a_file_path, i); + tmp_seq->load_museq(a_file_path, i); the_seqs.push_back(tmp_seq); } @@ -638,7 +646,7 @@ Mussa::save_old() save_file.open(analysis_name, ios::out); for(vector::size_type i = 0; i < the_seqs.size(); i++) - save_file << the_seqs[i] << endl; + save_file << *(the_seqs[i]) << endl; save_file << window << endl; save_file.close(); @@ -668,7 +676,7 @@ Mussa::load_old(char * load_file_path, int s_num) for(i = 0; i < seq_num; i++) { getline(save_file, file_data_line); - a_seq = file_data_line; + boost::shared_ptr a_seq(new Sequence(file_data_line)); the_seqs.push_back(a_seq); } @@ -712,7 +720,7 @@ void Mussa::add_motifs(const vector& motifs, for(size_t i = 0; i != motifs.size(); ++i) { motif_sequences.insert(motifs[i]); - color_mapper.appendInstanceColor("motif", motifs[i], colors[i]); + color_mapper->appendInstanceColor("motif", motifs[i], colors[i]); } update_sequences_motifs(); } @@ -758,7 +766,7 @@ void Mussa::load_motifs(std::istream &in) // sequence wasn't found motif_sequences.insert(seq); Color c(red, green, blue); - color_mapper.appendInstanceColor("motif", seq, c); + color_mapper->appendInstanceColor("motif", seq, c); } else { clog << "sequence " << seq << " was already defined skipping" << endl; @@ -779,18 +787,18 @@ void Mussa::update_sequences_motifs() { // once we've loaded all the motifs from the file, // lets attach them to the sequences - for(vector::iterator seq_i = the_seqs.begin(); + for(vector >::iterator seq_i = the_seqs.begin(); seq_i != the_seqs.end(); ++seq_i) { // clear out old motifs - seq_i->clear_motifs(); + (*seq_i)->clear_motifs(); // for all the motifs in our set, attach them to the current sequence for(set::iterator motif_i = motif_sequences.begin(); motif_i != motif_sequences.end(); ++motif_i) { - seq_i->add_motif(*motif_i); + (*seq_i)->add_motif(*motif_i); } } } @@ -800,7 +808,7 @@ const set& Mussa::motifs() const return motif_sequences; } -AnnotationColors& Mussa::colorMapper() +boost::shared_ptr Mussa::colorMapper() { return color_mapper; } diff --git a/alg/mussa.hpp b/alg/mussa.hpp index 6f7d0a3..2566349 100644 --- a/alg/mussa.hpp +++ b/alg/mussa.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -113,8 +114,10 @@ public: //! appends a string sequence to the list of the_seqs // void append_sequence(std::string a_seq); - //! appends a sequence to the list of the_seqs - void append_sequence(Sequence a_seq); + //! appends a sequence to the list of the_seqs (makes copy) + void append_sequence(const Sequence& a_seq); + //! append a sequence to the list of seqs (shared) + void append_sequence(boost::shared_ptr a_seq); //! Load a sequence from a fasta file and any annotations /*! \param[in] seq_file the full path to the fasta file @@ -131,7 +134,8 @@ public: boost::filesystem::path annot_file, int fasta_index, int sub_seq_start=0, int sub_seq_end=0); //! allow examining the sequences we have loaded - const std::vector& sequences() const; + typedef std::vector > vector_sequence_type; + const vector_sequence_type& sequences() const; // deprecated - support bridge for python version of mussa // these save & load from the old file format @@ -160,7 +164,7 @@ public: const std::set& motifs() const; //! return color mapper - AnnotationColors& colorMapper(); + boost::shared_ptr colorMapper(); private: //! push motifs to our attached sequences @@ -184,7 +188,7 @@ public: bool thres_append; //! sequence data - std::vector the_seqs; + vector_sequence_type the_seqs; //! the seqcomp data std::vector > all_comps; //! N-way data, ie the mussa results @@ -193,7 +197,7 @@ public: //! motif list std::set motif_sequences; //! color manager - AnnotationColors color_mapper; + boost::shared_ptr color_mapper; // Private methods //! runs all the seqcomps needed to support the nway comparison diff --git a/alg/sequence.cpp b/alg/sequence.cpp index 56bad88..3863346 100644 --- a/alg/sequence.cpp +++ b/alg/sequence.cpp @@ -89,8 +89,6 @@ Sequence::Sequence() header(""), species("") { - annots.clear(); - motif_list.clear(); } Sequence::~Sequence() @@ -98,11 +96,15 @@ Sequence::~Sequence() } Sequence::Sequence(const char *seq) + : header(""), + species("") { set_filtered_sequence(seq); } Sequence::Sequence(const std::string& seq) + : header(""), + species("") { set_filtered_sequence(seq); } @@ -539,14 +541,6 @@ Sequence::get_header() const { return header; } -/* -//FIXME: i don't think this code is callable -std::string -Sequence::sp_name() const -{ - return species; -} -*/ /* std::string diff --git a/alg/sequence_location.cpp b/alg/sequence_location.cpp new file mode 100644 index 0000000..cc92c2f --- /dev/null +++ b/alg/sequence_location.cpp @@ -0,0 +1,76 @@ +#include "alg/sequence_location.hpp" + +SequenceLocation::SequenceLocation( + const boost::shared_ptr s, + int l, + int c +) : sequence(s), + left(l), + count(c) +{ +} + +SequenceLocation::SequenceLocation( + const Sequence& s, + int l, + int c +) : left(l), + count(c) +{ + boost::shared_ptr copy(new Sequence(s)); + sequence = copy; +} + + +SequenceLocation::SequenceLocation(const SequenceLocation& o) + : sequence(o.sequence), + left(o.left), + count(o.count) +{ +} + +SequenceLocation& SequenceLocation::operator=(const SequenceLocation& o) +{ + if (this != &o) { + sequence = o.sequence; + left = o.left; + count = o.count; + } + return *this; +} + + +const Sequence& SequenceLocation::getSequence() const +{ + return *sequence; +} + +void SequenceLocation::setLeft(int l) +{ + left = l; +} + +int SequenceLocation::getLeft() const +{ + return left; +} + +void SequenceLocation::setCount(int c) +{ + count = c; +} + +int SequenceLocation::getCount() const +{ + return count; +} + +void SequenceLocation::setRight(int r) +{ + count = r-left; +} + +int SequenceLocation::getRight() const +{ + return left+count; +} diff --git a/alg/sequence_location.hpp b/alg/sequence_location.hpp new file mode 100644 index 0000000..12830f7 --- /dev/null +++ b/alg/sequence_location.hpp @@ -0,0 +1,28 @@ +#ifndef _SEQUENCE_LOCATION_H_ +#define _SEQUENCE_LOCATION_H_ + +#include +#include "alg/sequence.hpp" + +//! convenience structure for holding selected track segments +class SequenceLocation { + public: + SequenceLocation(boost::shared_ptr s, int l, int c); + SequenceLocation(const Sequence& s, int l, int c); + SequenceLocation(const SequenceLocation& ); + SequenceLocation& operator=(const SequenceLocation&); + + const Sequence& getSequence() const; + void setLeft(int l); + int getLeft() const; + void setCount(int c); + int getCount() const ; + void setRight(int r); + int getRight() const; + + private: + boost::shared_ptr sequence; + int left; + int count; + }; +#endif diff --git a/alg/test/CMakeLists.txt b/alg/test/CMakeLists.txt index a8694e7..70e505a 100644 --- a/alg/test/CMakeLists.txt +++ b/alg/test/CMakeLists.txt @@ -1,6 +1,7 @@ SET(SOURCES test_annotation_color.cpp test_color.cpp test_conserved_path.cpp test_flp.cpp test_glseqbrowser.cpp test_glsequence.cpp - test_main.cpp test_mussa.cpp test_nway.cpp test_sequence.cpp) + test_main.cpp test_mussa.cpp test_nway.cpp + test_sequence.cpp test_sequence_location.cpp ) # dont you love the number of \ you need to make sure the " shows up in # the C compiler? diff --git a/alg/test/test_glseqbrowser.cpp b/alg/test/test_glseqbrowser.cpp index 0a3f8c9..336d005 100644 --- a/alg/test/test_glseqbrowser.cpp +++ b/alg/test/test_glseqbrowser.cpp @@ -2,6 +2,8 @@ #include using namespace boost::assign; +#include + #include #include #include @@ -50,10 +52,10 @@ BOOST_AUTO_TEST_CASE( glseqbrowser_center ) string s0("AAGGCCTT"); string s1("TTGGCCAA"); string s2("GATTACAA"); - Sequence seq0(s0); - Sequence seq1(s1); - Sequence seq2(s2); - AnnotationColors cm; + boost::shared_ptr seq0(new Sequence(s0)); + boost::shared_ptr seq1(new Sequence(s1)); + boost::shared_ptr seq2(new Sequence(s2)); + boost::shared_ptr cm(new AnnotationColors); GlSequence glseq0(seq0, cm); GlSequence glseq1(seq1, cm); GlSequence glseq2(seq2, cm); diff --git a/alg/test/test_glsequence.cpp b/alg/test/test_glsequence.cpp index 32fc0ad..b0aa6ad 100644 --- a/alg/test/test_glsequence.cpp +++ b/alg/test/test_glsequence.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -9,14 +10,14 @@ using namespace std; -BOOST_AUTO_TEST_CASE ( glsequence_operator_equal ) +BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment ) { - AnnotationColors cm; - // I don't trust my operator = hack so lets make sure it works. + 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); - Sequence seq1(s1); + boost::shared_ptr seq0(new Sequence(s0)); + boost::shared_ptr seq1(new Sequence(s1)); GlSequence glseq0(seq0, cm); BOOST_CHECK (glseq0.sequence() == s0); @@ -27,16 +28,15 @@ BOOST_AUTO_TEST_CASE ( glsequence_operator_equal ) BOOST_CHECK( &(glseq_copy0.sequence()) == &(glseq0.sequence())); glseq0 = glseq1; - BOOST_CHECK( glseq0.sequence() == s1 ); } BOOST_AUTO_TEST_CASE( glsequence_color ) { - AnnotationColors cm; + boost::shared_ptr cm(new AnnotationColors); Color black(0.0, 0.0, 0.0, 0.0); Color c(0.1, 0.2, 0.3, 0.4); - Sequence seq("AAGGCCTT"); + boost::shared_ptr seq(new Sequence("AAGGCCTT")); GlSequence s(seq, cm); BOOST_CHECK_EQUAL(s.color(), black ); @@ -46,8 +46,8 @@ BOOST_AUTO_TEST_CASE( glsequence_color ) BOOST_AUTO_TEST_CASE( glsequence_renderable ) { - AnnotationColors cm; - Sequence seq("AAGGCCTT"); + boost::shared_ptr cm(new AnnotationColors); + boost::shared_ptr seq(new Sequence("AAGGCCTT")); GlSequence s(seq, cm); // way more base pairs than viewport pixel width @@ -61,26 +61,26 @@ BOOST_AUTO_TEST_CASE( glsequence_renderable ) BOOST_AUTO_TEST_CASE( glsequence_sequence ) { - AnnotationColors cm; + boost::shared_ptr cm(new AnnotationColors); string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN"); string::size_type seqlen = seq_string.size(); - Sequence seq(seq_string); + boost::shared_ptr seq(new Sequence(seq_string)); GlSequence glseq(seq, cm); - BOOST_CHECK( glseq.sequence_begin(0, 50) == seq.begin() ); - // always make sure we return seq.end() regardless of how much extra + BOOST_CHECK( glseq.sequence_begin(0, 50) == seq->begin() ); + // always make sure we return seq->end() regardless of how much extra // is asked for - BOOST_CHECK( glseq.sequence_end(0, seqlen+10) == seq.end() ); + BOOST_CHECK( glseq.sequence_end(0, seqlen+10) == seq->end() ); // do we get the right end pointer? - BOOST_CHECK( glseq.sequence_end(0, 5) == seq.begin()+5 ); + BOOST_CHECK( glseq.sequence_end(0, 5) == seq->begin()+5 ); // when we request far too much sequence what do we get? - BOOST_CHECK( glseq.sequence_begin(seqlen+10, seqlen+20) == seq.end() ); - BOOST_CHECK( glseq.sequence_end(seqlen+10, seqlen+20) == seq.end() ); + BOOST_CHECK( glseq.sequence_begin(seqlen+10, seqlen+20) == seq->end() ); + BOOST_CHECK( glseq.sequence_end(seqlen+10, seqlen+20) == seq->end() ); // we cant ask for reversed sequences with sequence_begin/end - BOOST_CHECK( glseq.sequence_begin(10, 5) == seq.end() ); - BOOST_CHECK( glseq.sequence_end(10, 5) == seq.end() ); + BOOST_CHECK( glseq.sequence_begin(10, 5) == seq->end() ); + BOOST_CHECK( glseq.sequence_end(10, 5) == seq->end() ); Sequence::const_iterator seq_itor; @@ -90,9 +90,9 @@ BOOST_AUTO_TEST_CASE( glsequence_sequence ) // reuse seq_itor downhere string::const_iterator str_itor; - for(str_itor = seq.begin(), + for(str_itor = seq->begin(), seq_itor = glseq.sequence_begin(); - str_itor != seq.end() and + str_itor != seq->end() and seq_itor != glseq.sequence_end(); ++str_itor, ++seq_itor) { @@ -103,9 +103,9 @@ BOOST_AUTO_TEST_CASE( glsequence_sequence ) // make sure the computation of the leftmost and rightmost base is correct BOOST_AUTO_TEST_CASE( glsequence_leftright_base ) { - AnnotationColors cm; + boost::shared_ptr cm(new AnnotationColors); std::string seq_string = "AAGGCCTT"; - Sequence seq(seq_string); + boost::shared_ptr seq(new Sequence(seq_string)); GlSequence glseq(seq, cm); BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 ); @@ -122,9 +122,9 @@ BOOST_AUTO_TEST_CASE( glsequence_leftright_base ) // we move the sequence around? BOOST_AUTO_TEST_CASE( glsequence_movex ) { - AnnotationColors cm; + boost::shared_ptr cm(new AnnotationColors); std::string seq_string = "AAGGCCTTAAGGCCTT"; - Sequence seq(seq_string); + boost::shared_ptr seq(new Sequence(seq_string)); GlSequence glseq(seq, cm); glseq.setX(-5); @@ -140,23 +140,51 @@ BOOST_AUTO_TEST_CASE( glsequence_movex ) // Check iterators BOOST_AUTO_TEST_CASE( glsequence_check_iterators ) { - AnnotationColors cm; + boost::shared_ptr cm(new AnnotationColors); std::string seq_string = "AAGGCCTTAAGGCCTT"; - Sequence seq(seq_string); + boost::shared_ptr seq(new Sequence(seq_string)); GlSequence glseq(seq, cm); Sequence::const_iterator seq_begin_i; Sequence::const_iterator seq_end_i; - BOOST_CHECK(glseq.sequence_begin(5, -5) == seq.end()); - BOOST_CHECK(glseq.sequence_begin(0, 20) == seq.begin()); - BOOST_CHECK(glseq.sequence_begin(10,20) == seq.begin()+10); + BOOST_CHECK(glseq.sequence_begin(5, -5) == seq->end()); + BOOST_CHECK(glseq.sequence_begin(0, 20) == seq->begin()); + BOOST_CHECK(glseq.sequence_begin(10,20) == seq->begin()+10); - BOOST_CHECK(glseq.sequence_end(5, -5) == seq.end()); - BOOST_CHECK(glseq.sequence_end(0, 20) == seq.end()); - BOOST_CHECK(glseq.sequence_end(0, 10) == seq.begin()+10); + BOOST_CHECK(glseq.sequence_end(5, -5) == seq->end()); + BOOST_CHECK(glseq.sequence_end(0, 20) == seq->end()); + BOOST_CHECK(glseq.sequence_end(0, 10) == seq->begin()+10); glseq.setX(-5); - BOOST_CHECK(glseq.sequence_begin(0, 10) == seq.begin()+5); - BOOST_CHECK(glseq.sequence_end(0, 15) == seq.end()); + BOOST_CHECK(glseq.sequence_begin(0, 10) == seq->begin()+5); + BOOST_CHECK(glseq.sequence_end(0, 15) == seq->end()); } + +BOOST_AUTO_TEST_CASE ( shared_ptr_test ) +{ + 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"); + boost::shared_ptr seq0(new Sequence(s0)); + BOOST_CHECK_EQUAL( seq0.use_count(), 1 ); + boost::shared_ptr seq1(new Sequence(s1)); + BOOST_CHECK_EQUAL( seq0.use_count(), 1 ); + + // make a block to test deallocation + { + GlSequence glseq0(seq0, cm); + BOOST_CHECK_EQUAL(seq0.use_count(), 2); + GlSequence glseq1(seq1, cm); + BOOST_CHECK_EQUAL(seq1.use_count(), 2); + + glseq0 = glseq1; + BOOST_CHECK_EQUAL( seq0.use_count(), 1 ); + BOOST_CHECK_EQUAL( seq1.use_count(), 3 ); + } + BOOST_CHECK_EQUAL(seq0.use_count(), 1); + BOOST_CHECK_EQUAL(seq1.use_count(), 1); +} + + diff --git a/alg/test/test_mussa.cpp b/alg/test/test_mussa.cpp index 79356ab..2ab594a 100644 --- a/alg/test/test_mussa.cpp +++ b/alg/test/test_mussa.cpp @@ -70,9 +70,9 @@ BOOST_AUTO_TEST_CASE( mussa_sequences ) analysis.append_sequence(s2); BOOST_CHECK_EQUAL( analysis.sequences().size(), 3 ); - BOOST_CHECK_EQUAL( analysis.sequences()[0], s0); - BOOST_CHECK_EQUAL( analysis.sequences()[1], s1); - BOOST_CHECK_EQUAL( analysis.sequences()[2], s2); + BOOST_CHECK_EQUAL( *(analysis.sequences()[0]), s0); + BOOST_CHECK_EQUAL( *(analysis.sequences()[1]), s1); + BOOST_CHECK_EQUAL( *(analysis.sequences()[2]), s2); } // for some reason we can call nway once safely but it @@ -147,11 +147,11 @@ BOOST_AUTO_TEST_CASE( mussa_load_motif ) m1.append_sequence("GGGCCCCTTGGTT"); m1.load_motifs(test_istream); - for (vector::const_iterator seq_i = m1.sequences().begin(); + for (Mussa::vector_sequence_type::const_iterator seq_i = m1.sequences().begin(); seq_i != m1.sequences().end(); ++seq_i) { - BOOST_CHECK( seq_i->motifs().size() > 0 ); + BOOST_CHECK( (*seq_i)->motifs().size() > 0 ); } } @@ -173,7 +173,7 @@ BOOST_AUTO_TEST_CASE( mussa_add_motif ) } static void -local_align_test(const vector &seqs, +local_align_test(const Mussa::vector_sequence_type &seqs, const list& result, const list >& reversed) { @@ -193,8 +193,8 @@ local_align_test(const vector &seqs, BOOST_CHECK_EQUAL( (*rc_i)[0], false ); const int first_path_basepair_index = (*base_i)[0]; const int second_path_basepair_index = (*base_i)[1]; - const char first_basepair = seqs[0][first_path_basepair_index]; - const char second_basepair = seqs[1][second_path_basepair_index]; + const char first_basepair = (*seqs[0])[first_path_basepair_index]; + const char second_basepair = (*seqs[1])[second_path_basepair_index]; // get our index into our reverse compliment map m const int second_compliment_index = (*rc_i)[1]; // lookup the forward or reverse compliment depending on our rc flag diff --git a/alg/test/test_sequence_location.cpp b/alg/test/test_sequence_location.cpp new file mode 100644 index 0000000..7154652 --- /dev/null +++ b/alg/test/test_sequence_location.cpp @@ -0,0 +1,34 @@ +#include + +#include "alg/sequence_location.hpp" +#include "alg/sequence.hpp" + +BOOST_AUTO_TEST_CASE( basic_sequence_location ) +{ + Sequence s("AAGGCCTT"); + + SequenceLocation sl(s, 0, 2); + + BOOST_CHECK_EQUAL( sl.getLeft(), 0 ); + BOOST_CHECK_EQUAL( sl.getRight(), 2 ); + BOOST_CHECK_EQUAL( sl.getCount(), 2 ); + + sl.setLeft(1); + sl.setRight(3); + + BOOST_CHECK_EQUAL( sl.getLeft(), 1 ); + BOOST_CHECK_EQUAL( sl.getRight(), 3 ); + BOOST_CHECK_EQUAL( sl.getCount(), 2 ); +} + +BOOST_AUTO_TEST_CASE( memory_test ) +{ + SequenceLocation *sl; + // storing references is a bad idea + { + Sequence s("AAGGCCTT"); + sl = new SequenceLocation(s, 0, 2); + } + + BOOST_CHECK_EQUAL(sl->getSequence(), "AAGGCCTT"); +} diff --git a/py/glsequence.cpp b/py/glsequence.cpp index cd43244..811e0dc 100644 --- a/py/glsequence.cpp +++ b/py/glsequence.cpp @@ -7,6 +7,7 @@ using namespace boost::python; void export_glsequence() { + /* class_("GlSequence", init()) .def(init()) .def("draw", &GlSequence::draw) @@ -16,4 +17,5 @@ void export_glsequence() .add_property("y", &GlSequence::y, &GlSequence::setY) .add_property("length", &GlSequence::length) ; + */ } diff --git a/py/mussa.cpp b/py/mussa.cpp index e0efaae..f38063e 100644 --- a/py/mussa.cpp +++ b/py/mussa.cpp @@ -26,7 +26,7 @@ void export_mussa() .def("analyze", &Mussa::analyze, "Run the analysis") .def("paths", &Mussa::paths, py::return_internal_reference<>()) //.def("sequences", &Mussa::sequences) - .def("addSequence", &Mussa::append_sequence) + //.def("addSequence", &Mussa::append_sequence) ; py::enum_("analysis_modes") diff --git a/qui/CMakeLists.txt b/qui/CMakeLists.txt index 9a26178..b48cb33 100644 --- a/qui/CMakeLists.txt +++ b/qui/CMakeLists.txt @@ -19,6 +19,7 @@ SET(MOC_HEADERS IntAction.hpp MussaAlignedWindow.hpp MussaWindow.hpp + SequenceLocationModel.hpp SubanalysisWindow.hpp ThresholdWidget.hpp ZoomWidget.hpp @@ -42,6 +43,7 @@ SET(GUI_SOURCES IntAction.cpp MussaAlignedWindow.cpp MussaWindow.cpp + SequenceLocationModel.cpp SubanalysisWindow.cpp ThresholdWidget.cpp ZoomWidget.cpp diff --git a/qui/MussaWindow.cpp b/qui/MussaWindow.cpp index de33b9d..0fac525 100644 --- a/qui/MussaWindow.cpp +++ b/qui/MussaWindow.cpp @@ -510,7 +510,7 @@ void MussaWindow::updateAnalysis() { threshold.setRange(analysis->get_threshold(),analysis->get_window()); - const vector& seqs = analysis->sequences(); + const Mussa::vector_sequence_type& seqs = analysis->sequences(); browser.setSequences(seqs, analysis->colorMapper()); updateLinks(); browser.zoomOut(); diff --git a/qui/SequenceLocationModel.cpp b/qui/SequenceLocationModel.cpp new file mode 100644 index 0000000..ebf1185 --- /dev/null +++ b/qui/SequenceLocationModel.cpp @@ -0,0 +1,78 @@ +#include "qui/SequenceLocationModel.hpp" + +SequenceLocationModel::SequenceLocationModel(QObject *parent) + : QAbstractTableModel(parent) +{ + Sequence s("AGCT"); + sequence_locations.push_back(SequenceLocation(s, 0, 1)); + sequence_locations.push_back(SequenceLocation(s, 2, 2)); +} + +int +SequenceLocationModel::rowCount( const QModelIndex& parent) const +{ + return sequence_locations.size(); +} + +int +SequenceLocationModel::columnCount(const QModelIndex& parent) const +{ + return 3; +} + +QVariant +SequenceLocationModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= sequence_locations.size()) + return QVariant(); + + if (index.column() >= 3) + return QVariant(); + + if (role == Qt::DisplayRole) { + if (index.column() == 0 ) { + const Sequence& seq = sequence_locations[index.row()].getSequence(); + std::string header(seq.get_header()); + if (header.size() == 0) { + return QVariant(QString(tr("Sequence ")) + + QString().setNum(index.row()) + ); + } else { + return QVariant(QString(header.c_str())); + } + } else if (index.column() == 1) { + return QVariant(sequence_locations[index.row()].getLeft()); + } else if (index.column() == 2) { + return QVariant(sequence_locations[index.row()].getRight()); + } + } + return QVariant(); +} + +QVariant +SequenceLocationModel::headerData( + int section, + Qt::Orientation orentation, + int role +) +{ + switch(section) { + case 0: + return QString("Sequence"); + break; + case 1: + return QString("Left"); + break; + case 2: + return QString("Right"); + break; + default: + return QVariant(); + break; + } +} + + diff --git a/qui/SequenceLocationModel.hpp b/qui/SequenceLocationModel.hpp new file mode 100644 index 0000000..f8f7293 --- /dev/null +++ b/qui/SequenceLocationModel.hpp @@ -0,0 +1,34 @@ +#ifndef _SEQUENCE_LOCATION_MODEL_HPP_ +#define _SEQUENCE_LOCATION_MODEL_HPP_ + +#include +#include "alg/sequence_location.hpp" +#include + +class SequenceLocationModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + SequenceLocationModel(QObject *parent = 0); + + + int rowCount(const QModelIndex& parent=QModelIndex()) const; + int columnCount(const QModelIndex& parent=QModelIndex()) const; + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const; + + QVariant headerData(int section, Qt::Orientation orentation, int role=Qt::DisplayRole); + + //bool setData(const QModelIndex& index, const QVariant &value, + // int role=Qt::EditRole); + //Qt::ItemFlags flags(const QModelIndex& index) const; + + //bool insertRows(int row, int count, + // const QModelIndex& parent=QModelIndex()); + //bool removeRows(int row, int count); + // const QModelIndex& parent=QModelIndex()); + private: + std::vector sequence_locations; +}; + +#endif diff --git a/qui/SubanalysisWindow.cpp b/qui/SubanalysisWindow.cpp index bf32cd6..c6d0d13 100644 --- a/qui/SubanalysisWindow.cpp +++ b/qui/SubanalysisWindow.cpp @@ -1,27 +1,27 @@ #include "qui/SubanalysisWindow.hpp" -#include -#include - #include #include SubanalysisWindow::SubanalysisWindow(QWidget *parent) : QWidget(parent), - text(0), + table(0), ok(0), cancel(0) { + //model.setStringList(string_list); + QHBoxLayout *buttonLayout = new QHBoxLayout(); QVBoxLayout *verticalLayout = new QVBoxLayout(); ok = new QPushButton(tr("&OK"), this); cancel = new QPushButton(tr("Cancel"), this); - text = new QTextEdit(this); + table = new QTableView(this); + table->setModel(&model); buttonLayout->addWidget(ok); buttonLayout->addWidget(cancel); - verticalLayout->addWidget(text); + verticalLayout->addWidget(table); verticalLayout->addLayout(buttonLayout); setLayout(verticalLayout); } diff --git a/qui/SubanalysisWindow.hpp b/qui/SubanalysisWindow.hpp index 043c2dc..883dda8 100644 --- a/qui/SubanalysisWindow.hpp +++ b/qui/SubanalysisWindow.hpp @@ -1,10 +1,12 @@ #ifndef _SUBANALYSIS_H_ #define _SUBANALYSIS_H_ +#include +#include +#include #include -class QTextEdit; -class QPushButton; +#include "qui/SequenceLocationModel.hpp" class SubanalysisWindow : public QWidget { @@ -14,8 +16,10 @@ public: SubanalysisWindow(QWidget *parent = 0); private: - QTextEdit *text; + QTableView *table; QPushButton *ok; QPushButton *cancel; + + SequenceLocationModel model; }; #endif diff --git a/qui/motif_editor/MotifEditor.cpp b/qui/motif_editor/MotifEditor.cpp index c1df29e..b74826e 100644 --- a/qui/motif_editor/MotifEditor.cpp +++ b/qui/motif_editor/MotifEditor.cpp @@ -23,7 +23,7 @@ MotifEditor::MotifEditor(Mussa *m, QWidget *parent) MotifDetail *detail = new MotifDetail; if (i < motif_seq.size()) { detail->setMotif(motif_seq[i]); - detail->setColor(analysis->colorMapper().lookup("motif", motif_seq[i])); + detail->setColor(analysis->colorMapper()->lookup("motif", motif_seq[i])); } motif_details.push_back(detail); layout.addWidget(detail); @@ -42,9 +42,9 @@ void MotifEditor::updateMotifs() { // This function is _sooo_ not thread safe // erase motifs - Color motif_default = analysis->colorMapper().typeColor("motif"); - analysis->colorMapper().erase("motif"); - analysis->colorMapper().appendTypeColor("motif", motif_default); + Color motif_default = analysis->colorMapper()->typeColor("motif"); + analysis->colorMapper()->erase("motif"); + analysis->colorMapper()->appendTypeColor("motif", motif_default); // add our motifs back vector motifs; diff --git a/qui/seqbrowser/SequenceBrowserWidget.cpp b/qui/seqbrowser/SequenceBrowserWidget.cpp index 64bf051..7ed2b4d 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.cpp +++ b/qui/seqbrowser/SequenceBrowserWidget.cpp @@ -57,16 +57,17 @@ void SequenceBrowserWidget::copySelectedSequenceAsFasta() scrollable_browser.browser().copySelectedSequenceAsFasta(); } -void SequenceBrowserWidget::setSequences(const std::vector& sequences, - AnnotationColors& cm) +void SequenceBrowserWidget::setSequences( + const std::vector< boost::shared_ptr >& sequences, + boost::shared_ptr cm) { SequenceBrowser& browser = scrollable_browser.browser(); clear(); - for(vector::const_iterator seq_i = sequences.begin(); + for(Mussa::vector_sequence_type::const_iterator seq_i = sequences.begin(); seq_i != sequences.end(); ++seq_i) { - GlSequence *gs= new GlSequence(*seq_i, cm); + boost::shared_ptr gs(new GlSequence(*seq_i, cm)); converted_sequences.push_back(*gs); browser.push_sequence(*gs); } diff --git a/qui/seqbrowser/SequenceBrowserWidget.hpp b/qui/seqbrowser/SequenceBrowserWidget.hpp index cde9a33..0fa7bda 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.hpp +++ b/qui/seqbrowser/SequenceBrowserWidget.hpp @@ -1,8 +1,9 @@ #ifndef _PATH_WIDGET_H_ #define _PATH_WIDGET_H_ - #include +#include + #include #include "alg/sequence.hpp" @@ -35,7 +36,9 @@ public: * positions. */ //void push_sequences(std::vector& sequences); - void setSequences(const std::vector& sequences, AnnotationColors& cm); + void setSequences( + const std::vector< boost::shared_ptr >& sequences, + boost::shared_ptr cm); void setSequences(std::vector& sequences); const std::vector& sequences() const; -- 2.30.2