load and display a motif list
authorDiane Trout <diane@caltech.edu>
Tue, 14 Mar 2006 07:57:20 +0000 (07:57 +0000)
committerDiane Trout <diane@caltech.edu>
Tue, 14 Mar 2006 07:57:20 +0000 (07:57 +0000)
Mussagl can now load a motif list from a text file in the form
AAGGGCCTT 1.0 0.5 0.0
(The trailing numbers are the red, green, blue channels)
and motifs are properly displayed on the sequence tracks.

I did this by attaching an AnnotationColors color mapper to the mussa
analysis and passing it to the glsequence class for rendering.

19 files changed:
alg/annotation_colors.cpp
alg/annotation_colors.hpp
alg/glsequence.cpp
alg/glsequence.hpp
alg/mussa.cpp
alg/mussa.hpp
alg/sequence.cpp
alg/sequence.hpp
alg/test/test_annotation_color.cpp
alg/test/test_glsequence.cpp
alg/test/test_mussa.cpp
alg/test/test_sequence.cpp
examples/test_motif.txt [new file with mode: 0644]
mussa_exceptions.hpp
py/glsequence.cpp
qui/PathScene.cpp
qui/PathScene.hpp
qui/PathWindow.cpp
qui/PathWindow.hpp

index aab22d1b9b2d85258a36cf7da577922b78c88b92..a84d4591d125c40c0841a7d8216f0f666b0f50e5 100644 (file)
@@ -22,11 +22,17 @@ AnnotationColors::AnnotationColors()
 {
 }
 
-AnnotationColors::AnnotationColors(AnnotationColors &ac)
+AnnotationColors::AnnotationColors(const AnnotationColors &ac)
   : root_map(ac.root_map)
 {
 }
 
+void AnnotationColors::clear()
+{
+  root_map.cm.clear();
+  root_map.defaultColor = Color(0.0, 0.0, 0.0);
+}
+
 void AnnotationColors::setColor(Color &c)
 {
   root_map.defaultColor = c;
@@ -71,19 +77,19 @@ void AnnotationColors::erase(const string &type,
   root_map.cm[type].cm.erase(instance);
 }
 
-Color AnnotationColors::lookup(const annot &a)
+Color AnnotationColors::lookup(const annot &a) const
 {
   return lookup(a.type, a.name);
 }
 
-Color AnnotationColors::lookup(const string &type, const string &instance)
+Color AnnotationColors::lookup(const string &type, const string &instance) const
 {
   // Yeah, there's probably a nicer looking recursive solution
   // to this problem.
-  DefaultColorMap::iterator type_map = root_map.cm.find(type);
+  DefaultColorMap::const_iterator type_map = root_map.cm.find(type);
   if (type_map != root_map.cm.end() ) {
     // found lookup instance
-    DefaultColorMap::iterator instance_map = type_map->second.cm.find(instance);
+    DefaultColorMap::const_iterator instance_map = type_map->second.cm.find(instance);
     if (instance_map != type_map->second.cm.end() ) {
       return instance_map->second.defaultColor;
     } else {
index 96efa250453543047471c32c57dc651863407da8..2fdb4f1ad3391326c19dc3d324a3651b0bcb103e 100644 (file)
@@ -12,6 +12,7 @@ struct DefaultColorMap
 {
   typedef std::map<std::string, DefaultColorMap> color_map_type;
   typedef color_map_type::iterator iterator;
+  typedef color_map_type::const_iterator const_iterator;
   DefaultColorMap();
   //! initialize color map with a default color
   DefaultColorMap(const Color &);
@@ -27,8 +28,10 @@ class AnnotationColors
 {
 public:
   AnnotationColors();
-  AnnotationColors(AnnotationColors &);
+  AnnotationColors(const AnnotationColors &);
 
+  // clear all the contents of our mappers
+  void clear();
   //! set default color
   void setColor(Color &);
   //! retreive default color
@@ -52,8 +55,8 @@ public:
   void erase(const std::string &type, const std::string& instance);
 
   //! lookup an annotation color
-  Color lookup(const annot &);
-  Color lookup(const std::string &, const std::string &);
+  Color lookup(const annot &) const;
+  Color lookup(const std::string &, const std::string &) const;
 private:
   // nested maps, with default?
   DefaultColorMap root_map;
index 62896aaea62674578cdb167848048f2baa13ef9b..674dcb0ea819a319d9b95d3c734e258f0cbf0f04 100644 (file)
@@ -6,23 +6,25 @@
 #include <stdexcept>
 using namespace std;
 
-GlSequence::GlSequence(const Sequence &s) 
+GlSequence::GlSequence(const Sequence &s, AnnotationColors& cm
   : seq(s),
     seq_x(0.0), 
     seq_y(0.0), 
     seq_z(1.0), 
     seq_height(12.0),
+    color_mapper(cm),
     drawColor(0.0, 0.0, 0.0),
     char_pix_per_world_unit(5.0)
 {
 }
 
-GlSequence::GlSequence(const GlSequence &s) 
+GlSequence::GlSequence(const GlSequence &s)
   : seq(s.seq),
     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)
 {
@@ -36,6 +38,7 @@ GlSequence &GlSequence::operator=(const GlSequence & s)
     seq_y = s.seq_y;
     seq_z = s.seq_z;
     seq_height = s.seq_height;
+    color_mapper = s.color_mapper;
     drawColor = s.drawColor;
     assert(char_pix_per_world_unit == s.char_pix_per_world_unit);
   }
@@ -203,7 +206,8 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
   // draw annotations
   glLineWidth(seq_height);
   GLfloat annotation_z = seq_z + 1.0;
-  std::list<annot> annots = seq.annotations();
+  const std::list<annot>& annots = seq.annotations();
+  const std::list<motif>& motifs = seq.motifs();
   for (std::list<annot>::const_iterator annot_itor = annots.begin();
        annot_itor != annots.end();
        ++annot_itor, ++annotation_z)
@@ -212,8 +216,19 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
     draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end, 
              seq_height, annotation_z);
   }
+  // if motifs?
+  for (std::list<motif>::const_iterator motifs_itor = motifs.begin();
+       motifs_itor != motifs.end();
+       ++motifs_itor, ++annotation_z)
+  {
+    glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get());
+    draw_box(seq_x+motifs_itor->start, seq_x+motifs_itor->end, 
+             seq_height, annotation_z);
+  }
+
 }
 
+
 const int PT = 1;
 const int STROKE = 2;
 const int END =3;
index aeedf47f75f58e52f2c7a637faed1dc40b6d4bee..c8c9b2b7eb58c41f1fe819c0f2670ffa32aabcb3 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _GL_SEQUENCE_H_
 #define _GL_SEQUENCE_H_
 
+#include "alg/annotation_colors.hpp"
 #include "alg/sequence.hpp"
 #include "alg/color.hpp"
 #include <GL/gl.h>
@@ -11,7 +12,7 @@
 class GlSequence
 {
 public: 
-  GlSequence(const Sequence & s);
+  GlSequence(const Sequence & s, AnnotationColors &cm);
   GlSequence(const GlSequence & s);
   GlSequence &operator=(const GlSequence &s);
 
@@ -73,6 +74,7 @@ protected:
   GLfloat seq_y;
   GLfloat seq_z;
   GLfloat seq_height;
+  AnnotationColors& color_mapper;
   Color drawColor;
   const GLfloat char_pix_per_world_unit;
 
index 224daa7de006227689c2d886cb0166ed04f86c3b..fa54eb2f83eed17b58960d4a6cfd3c3f9ccb195e 100644 (file)
@@ -27,6 +27,19 @@ Mussa::Mussa()
   clear();
 }
 
+Mussa::Mussa(const Mussa& m)
+  : analysis_name(m.analysis_name),
+    window(m.window),
+    threshold(m.threshold),
+    soft_thres(m.soft_thres),
+    ana_mode(m.ana_mode),
+    win_append(m.win_append),
+    thres_append(m.thres_append),
+    motif_sequences(m.motif_sequences),
+    color_mapper(m.color_mapper)
+{
+}
+
 // set all parameters to null state
 void
 Mussa::clear()
@@ -38,6 +51,8 @@ Mussa::clear()
   soft_thres = 0;
   win_append = false;
   thres_append = false;
+  motif_sequences.clear();
+  color_mapper.clear();
 }
 
 // these 5 simple methods manually set the parameters for doing an analysis
@@ -628,3 +643,81 @@ Mussa::load_old(char * load_file_path, int s_num)
 
   //the_paths.save("tmp.save");
 }
+
+// I mostly split the ifstream out so I can use a stringstream to test it.
+void Mussa::load_motifs(std::istream &in)
+{
+  string seq;
+  float red;
+  float green;
+  float blue;
+
+  while(in.good())
+  {
+    in >> seq >> red >> green >> blue;
+    // if we couldn't read this line 'cause we're like at the end of the file
+    // try to exit the loop
+    if (!in.good())
+      break;
+    try {
+      seq = Sequence::motif_normalize(seq);
+    } catch(motif_normalize_error e) {
+      clog << "unable to parse " << seq << " skipping" << endl;
+      clog << e.what() << endl;
+      continue;
+    }
+    if (red < 0.0 or red > 1.0) {
+      clog << "invalid red value " << red << ". must be in range [0..1]" 
+           << endl;
+      continue;
+    }
+    if (green < 0.0 or green > 1.0) {
+      clog << "invalid green value " << green << ". must be in range [0..1]" 
+           << endl;
+      continue;
+    }
+    if (blue < 0.0 or blue > 1.0) {
+      clog << "invalid blue value " << blue << ". must be in range [0..1]" 
+           << endl;
+      continue;
+    }
+    if (motif_sequences.find(seq) == motif_sequences.end()) {
+      // sequence wasn't found
+      motif_sequences.insert(seq);
+      Color c(red, green, blue);
+      color_mapper.appendInstanceColor("motif", seq, c);
+    } else {
+      clog << "sequence " << seq << " was already defined skipping" 
+           << endl;
+      continue;
+    }
+  }
+  // once we've loaded all the motifs from the file, 
+  // lets attach them to the sequences
+  for(vector<Sequence>::iterator seq_i = the_seqs.begin();
+      seq_i != the_seqs.end();
+      ++seq_i)
+  {
+    // clear out old motifs
+    seq_i->clear_motifs();
+    // for all the motifs in our set, attach them to the current sequence
+    for(set<string>::iterator motif_i = motif_sequences.begin();
+        motif_i != motif_sequences.end();
+        ++motif_i)
+    {
+      seq_i->add_motif(*motif_i);
+    }
+  }
+}
+
+void Mussa::load_motifs(string filename)
+{
+  ifstream f;
+  f.open(filename.c_str(), ifstream::in);
+  load_motifs(f);
+}
+
+AnnotationColors& Mussa::colorMapper()
+{
+  return color_mapper;
+}
index c5a5ba00fe27af295202bd9bb3b50eb6ae019a11..ded2a8b77f62d3072a9f963eef8247127642c7e2 100644 (file)
 #include <list>
 #include <string>
 #include <vector>
+#include <set>
+#include <istream>
 
+#include "alg/annotation_colors.hpp"
 #include "alg/nway_paths.hpp"
 #include "alg/sequence.hpp"
 
@@ -30,7 +33,8 @@ class Mussa
     enum analysis_modes { TransitiveNway, RadialNway, EntropyNway, 
                           RecursiveNway };
 
-    Mussa();  
+    Mussa();
+    Mussa(const Mussa &);
 
     void save();
     void save_muway(std::string save_path);
@@ -110,6 +114,21 @@ class Mussa
     void save_old();
     void load_old(char * load_file_path, int s_num);
 
+    // manage motif lists
+    //! load motifs from an ifstream
+    /*! The file should look something like
+     *  <sequence> <red> <green> <blue>
+     *  where sequence is a string of IUPAC symbols
+     *  and red,green,blue are a white space separated list of floats
+     *  in the range [0.0, 1.0]
+     */
+    void load_motifs(std::istream &);
+    //! load a list of motifs from a file named filename
+    void load_motifs(std::string filename);
+
+    //! return color mapper
+    AnnotationColors& colorMapper();
+
   private:
     // Private variables
     // parameters needed for a mussa analysis
@@ -135,6 +154,11 @@ class Mussa
     //! N-way data, ie the mussa results  
     NwayPaths the_paths;
 
+    //! motif list
+    std::set<std::string> motif_sequences;
+    //! color manager
+    AnnotationColors color_mapper;
+
     // Private methods
     //! loads sequence and annotations from fasta and annotation file
     void seqcomp();
index 5c7f069efce30c738e84e8bec769ef8cfec96896..4161bfcd7d1f33ba62a941111bd3e18b0c984378 100644 (file)
@@ -584,7 +584,7 @@ Sequence::rc_motif(string a_motif)
 }
 
 string
-Sequence::motif_validate(string a_motif)
+Sequence::motif_normalize(string a_motif)
 {
   string valid_motif;
   int seq_i, len;
@@ -596,7 +596,7 @@ Sequence::motif_validate(string a_motif)
   // current nonIUPAC symbols are omitted, which is not reported atm
   for(seq_i = 0; seq_i < len; seq_i++)
   {
-     if ((a_motif[seq_i] == 'a') || (a_motif[seq_i] == 'A'))
+    if ((a_motif[seq_i] == 'a') || (a_motif[seq_i] == 'A'))
       valid_motif += 'A';
     else if ((a_motif[seq_i] == 't') || (a_motif[seq_i] == 'T'))
       valid_motif += 'T';
@@ -626,10 +626,14 @@ Sequence::motif_validate(string a_motif)
       valid_motif += 'D';
     else if ((a_motif[seq_i] == 'b') || (a_motif[seq_i] == 'B'))
       valid_motif += 'B';
-   }
-
+    else {
+      string msg = "Letter ";
+      msg += a_motif[seq_i];
+      msg += " is not a valid IUPAC symbol";
+      throw motif_normalize_error(msg);
+    }
+  }
   //cout << "valid_motif is: " << valid_motif << endl;
   return valid_motif;
 }
 
@@ -637,7 +641,6 @@ void Sequence::add_motif(string a_motif)
 {
   vector<int> motif_starts = find_motif(a_motif);
 
-
   for(vector<int>::iterator motif_start_i = motif_starts.begin();
       motif_start_i != motif_starts.end();
       ++motif_start_i)
@@ -646,6 +649,11 @@ void Sequence::add_motif(string a_motif)
   }
 }
 
+void Sequence::clear_motifs()
+{
+  motif_list.clear();
+}
+
 const list<motif>& Sequence::motifs() const
 {
   return motif_list;
@@ -660,10 +668,9 @@ Sequence::find_motif(string a_motif)
   motif_match_starts.clear();
 
   //cout << "motif is: " << a_motif << endl;
-  a_motif = motif_validate(a_motif);
+  a_motif = motif_normalize(a_motif);
   //cout << "motif is: " << a_motif << endl;
 
-
   if (a_motif != "")
   {
     //cout << "Sequence: none blank motif\n";
index 9b52497ea181dd752092295cf50e03ff82979caa..e4771f200c97960d44a5eaf89a89d4019c206601 100644 (file)
@@ -28,8 +28,10 @@ struct annot
   annot();
   annot(int start, int end, std::string type, std::string name);
   
-  int start, end;
-  std::string name, type;
+  int start;
+  int end;
+  std::string type;
+  std::string name;
 };
 
 /* The way that motifs are found currently doesn't really 
@@ -59,7 +61,6 @@ class Sequence
 
     void motif_scan(std::string a_motif, std::vector<int> * motif_match_starts);
     std::string rc_motif(std::string a_motif);
-    std::string motif_validate(std::string a_motif);
   public:
     typedef std::string::iterator iterator;
     typedef std::string::const_iterator const_iterator;
@@ -109,8 +110,19 @@ class Sequence
 
     const std::string& get_header() const;
     //! add a motif to our list of motifs
+    /*! \throws motif_normalize_error if there's something wrong with a_motif
+     */
     void add_motif(std::string a_motif);
+    //! clear our list of found motifs
+    void clear_motifs();
+    //! search a sequence for a_motif
+    /*! \throws motif_normalize_error if there's something wrong with a_motif
+     */
     std::vector<int> find_motif(std::string a_motif);
+    //! convert IUPAC symbols to upperase
+    /*! \throws motif_normalize_error if there is an invalid symbol
+     */
+    static std::string motif_normalize(std::string a_motif);
     void save(std::fstream &save_file);
     void load_museq(std::string load_file_path, int seq_num); 
 };
index af7035b3c1315cba062ea0334f491adf40de83fa..2e2a56ebaca41f5f7b170b7be2db65bd4f2eeeba 100644 (file)
@@ -36,5 +36,8 @@ BOOST_AUTO_TEST_CASE( simple_annot_colors )
   BOOST_CHECK_EQUAL( ac.lookup(a), black );
   a.type = "venchent";
   BOOST_CHECK_EQUAL( ac.lookup(a), white );
+
+  ac.clear();
+  BOOST_CHECK_EQUAL( ac.lookup("bleem", "a"), black);
 }
 
index 220b455487934d09fe62358eb9003c1ac473f654..563af535f4901b8f727e54ddcf44d92df110c892 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <string>
 
+#include "alg/annotation_colors.hpp"
 #include "alg/glsequence.hpp"
 #include "alg/sequence.hpp"
 
@@ -9,15 +10,16 @@ using namespace std;
 
 BOOST_AUTO_TEST_CASE ( glsequence_operator_equal )
 {
+  AnnotationColors cm;
   // 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);
 
-  GlSequence glseq0(seq0);
+  GlSequence glseq0(seq0, cm);
   BOOST_CHECK (glseq0.sequence().get_seq() == s0);
-  GlSequence glseq1(seq1);
+  GlSequence glseq1(seq1, cm);
   GlSequence glseq_copy0(glseq0);
 
   BOOST_CHECK(glseq_copy0.sequence().get_seq() == glseq0.sequence().get_seq());
@@ -30,10 +32,11 @@ BOOST_AUTO_TEST_CASE ( glsequence_operator_equal )
 
 BOOST_AUTO_TEST_CASE( glsequence_color )
 {
+  AnnotationColors cm;
   Color black(0.0, 0.0, 0.0, 0.0);
   Color c(0.1, 0.2, 0.3, 0.4);
   Sequence seq("AAGGCCTT");
-  GlSequence s(seq);
+  GlSequence s(seq, cm);
   
   BOOST_CHECK_EQUAL(s.color(), black );
   s.setColor( c );
@@ -42,8 +45,9 @@ BOOST_AUTO_TEST_CASE( glsequence_color )
 
 BOOST_AUTO_TEST_CASE( glsequence_renderable )
 {
+  AnnotationColors cm;
   Sequence seq("AAGGCCTT");
-  GlSequence s(seq);
+  GlSequence s(seq, cm);
 
   // way more base pairs than viewport pixel width 
   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false );
@@ -53,10 +57,11 @@ BOOST_AUTO_TEST_CASE( glsequence_renderable )
 
 BOOST_AUTO_TEST_CASE( glsequence_sequence )
 {
+  AnnotationColors cm;
   string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN");
   string::size_type seqlen = seq_string.size();
   Sequence seq(seq_string);
-  GlSequence glseq(seq);
+  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
@@ -94,9 +99,10 @@ 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;
   std::string seq_string = "AAGGCCTT";
   Sequence seq(seq_string);
-  GlSequence glseq(seq);
+  GlSequence glseq(seq, cm);
 
   BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 );
   BOOST_CHECK_EQUAL( glseq.leftbase(   0.5 ), 1 );
index 6d9036fdb05cb41e76a0c790ae73a836ed51904c..1ca85a4144fed65fc055b99fd4d2e75c7224cdf9 100644 (file)
@@ -1,9 +1,13 @@
 #include <boost/test/auto_unit_test.hpp>
 
 #include <string>
+#include <sstream>
+#include <vector>
 
 #include "alg/mussa.hpp"
 
+using namespace std;
+
 //! can we initialize a mussa object?
 BOOST_AUTO_TEST_CASE( mussa_simple )
 {
@@ -106,3 +110,24 @@ BOOST_AUTO_TEST_CASE( mussa_load_full_path )
 
   BOOST_CHECK( m1.size() > 0);
 }
+
+BOOST_AUTO_TEST_CASE( mussa_load_motif )
+{
+  string data = "AAGG 1.0 1.0 0.0\n"
+                "GGTT 0.0 0.1 1.0\n"
+                "ZXY 2 1.9 0\n";
+
+  istringstream test_istream(data);
+
+  Mussa m1;
+  m1.add_a_seq("AAAAGGGGTTTT");
+  m1.add_a_seq("GGGCCCCTTGGTT");
+  m1.load_motifs(test_istream);
+
+  for (vector<Sequence>::const_iterator seq_i = m1.sequences().begin();
+       seq_i != m1.sequences().end();
+       ++seq_i)
+  {
+    BOOST_CHECK( seq_i->motifs().size() > 0 );
+  }
+}
index 0a5cab28e87d11c06430b8cb7bd7d2dee64c683f..bbc5068d951390895bc9e79cee8373b3ffe819f5 100644 (file)
@@ -123,6 +123,8 @@ BOOST_AUTO_TEST_CASE( sequence_motifs )
     BOOST_CHECK_EQUAL( motif_i->sequence, m);
   }
 
+  s1.clear_motifs();
+  BOOST_CHECK( s1.motifs().begin() == s1.motifs().end() );
 }
 
 BOOST_AUTO_TEST_CASE( annot_test )
diff --git a/examples/test_motif.txt b/examples/test_motif.txt
new file mode 100644 (file)
index 0000000..3a692e1
--- /dev/null
@@ -0,0 +1,2 @@
+TATAAA 0.9 0 0.9
+GGCC 0.0 1 1
index 701c5e5d56f3bd96cc073bf4b9fc703d933d69d2..53c167c40147677ba80612927d3609f262411646 100644 (file)
@@ -24,4 +24,11 @@ public:
   explicit mussa_analysis_error(const std::string& msg) : 
     std::runtime_error(msg) {};
 };
+
+class motif_normalize_error : public std::runtime_error
+{
+public:
+  explicit motif_normalize_error(const std::string& msg) : 
+    std::runtime_error(msg) {};
+};
 #endif
index 213ce63fee3499f46ccb25deedde40e092e1582e..cd432443db3849cb52d33951ef8118d5b38798cb 100644 (file)
@@ -1,12 +1,13 @@
 #include <boost/python.hpp>
 using namespace boost::python;
 
+#include "alg/annotation_colors.hpp"
 #include "alg/glsequence.hpp"
 #include "alg/sequence.hpp"
 
 void export_glsequence()
 {
-  class_<GlSequence>("GlSequence", init<Sequence &>())
+  class_<GlSequence>("GlSequence", init<Sequence &, AnnotationColors &>())
     .def(init<GlSequence &>())
     .def("draw", &GlSequence::draw)
     .def("sequence", &GlSequence::sequence, 
index 3f0e3355de96facf70f0c7259d9c749ef0357aeb..7040b6969fd71667e284357122ed4cfffefbc95a 100644 (file)
@@ -112,6 +112,30 @@ void PathScene::setClipPlane(int newZ)
   }
 }
 
+void PathScene::loadMotifList()
+{
+  QString caption("Load a motif list");
+  QString filter("Motif list(*.txt *.mtl)");
+  QString path = QFileDialog::getOpenFileName(this,
+                                                   caption, 
+                                                   QDir::currentPath(),
+                                                   filter);
+  // user hit cancel?
+  if (path.isNull()) 
+    return;
+  // try to load safely
+  try {
+    mussaAnalysis->load_motifs(path.toStdString());
+    updateScene();
+  } catch (runtime_error e) {
+    QString msg("Unable to load ");
+    msg += path;
+    msg += "\n";
+    msg += e.what();
+    QMessageBox::warning(this, "Load Motifs", msg);
+  }
+  assert (mussaAnalysis != 0);
+}
 void PathScene::loadMupa()
 {
   QString caption("Load a mussa parameter file");
@@ -245,7 +269,7 @@ void PathScene::updateScene()
       ++seq_itor)
   {
     y = y - 100;
-    gl_seq = new GlSequence(*seq_itor);
+    gl_seq = new GlSequence(*seq_itor, mussaAnalysis->colorMapper());
     gl_seq->setX(0);
     gl_seq->setY(y);
     if (gl_seq->length() > max_base_pairs ) max_base_pairs = gl_seq->length();
index 98e5ad5f4fed92e8450bd9a56550858b8a3301c2..547e113270fd7459aa8389452dd91430b0993a20 100644 (file)
@@ -39,8 +39,10 @@ public slots:
   void setViewportX(float x);
   //! set our magnification level
   void setZoom(int);
+  //! load motifs
+  void loadMotifList();
   //! load a mussa parameter file (which specifies an analysis to run)
-  void loadMupa( );
+  void loadMupa();
   //! load a previously run analysis
   void loadSavedAnalysis();
   //! set the soft threshold used by the Nway_Path algorithm
index 5a7c47f157728ef25e823ea771a5b97694b24d7d..67ce139d267902c1f89187a1acb19bfc3385324c 100644 (file)
@@ -91,7 +91,7 @@ void PathWindow::setupActions()
 
   loadMotifListAction = new QAction(tr("Load Motif List"), this);
   connect(loadMotifListAction, SIGNAL(triggered()), 
-          this, SLOT(loadMotifList()));
+          scene, SLOT(loadMotifList()));
   
   loadMupaAction = new QAction(tr("Load Mussa Parameters"), this);
   connect(loadMupaAction, SIGNAL(triggered()), 
@@ -178,11 +178,6 @@ void PathWindow::createSubAnalysis()
   NotImplementedBox();
 }
 
-void PathWindow::loadMotifList()
-{
-  NotImplementedBox();
-}
-
 void PathWindow::saveMotifList()
 {
   NotImplementedBox();
index ce63d18f65e32af5d5d7154ba5104743f18baf09..96048b8b0f57c66b34ffed48134836290a5f20cb 100644 (file)
@@ -29,7 +29,6 @@ public slots:
 
   //! \defgroup MotifHandling Handling of motif lists
   //\@{
-  void loadMotifList();
   void saveMotifList();
   void toggleMotifs();
   //\@}