fix motif loader under release build
[mussa.git] / alg / mussa.cpp
index 19591914e50beeb933cc196d550b11f6d5847ff7..6978ef24356f0775ead016f6deabb8aabe9bbca1 100644 (file)
 #include <boost/filesystem/fstream.hpp>
 namespace fs = boost::filesystem;
 
-#include <boost/spirit/core.hpp>
-#include <boost/spirit/actor/push_back_actor.hpp>
-#include <boost/spirit/iterator/file_iterator.hpp>
-#include <boost/spirit/utility/chset.hpp>
-namespace spirit = boost::spirit;
-
 #include <iostream>
 #include <sstream>
 
 #include "mussa_exceptions.hpp"
-#include "alg/mussa.hpp"
 #include "alg/flp.hpp"
+#include "alg/mussa.hpp"
+#include "alg/motif_parser.hpp"
 
 using namespace std;
 
@@ -775,73 +770,18 @@ void Mussa::set_motifs(const vector<Sequence>& motifs,
   update_sequences_motifs();
 }
 
-// Helper functor to append created motifs to our Mussa analysis
-struct push_back_motif {
-  Mussa::motif_set& motifs;
-  boost::shared_ptr<AnnotationColors> color_mapper;
-  std::string& seq_string;
-  std::string& name;
-  float& red;
-  float& green;
-  float& blue;
-  float& alpha;
-  int& parsed;
-
-  push_back_motif(Mussa::motif_set& motifs_,
-                  boost::shared_ptr<AnnotationColors> color_mapper_,
-                  std::string& seq_, 
-                  std::string& name_,
-                  float &red_, float &green_, float &blue_, float &alpha_,
-                  int &parsed_)
-    : motifs(motifs_),
-      color_mapper(color_mapper_),
-      seq_string(seq_),
-      name(name_),
-      red(red_),
-      green(green_),
-      blue(blue_),
-      alpha(alpha_),
-      parsed(parsed_)
-  {
-  }
-
-  void operator()(std::string::const_iterator, 
-                  std::string::const_iterator) const 
-  {
-    Sequence seq(seq_string, Sequence::nucleic_alphabet);
-    // shouldn't we have a better field than "fasta header" and speices?
-    seq.set_fasta_header(name);
-    // we need to clear the name in case the next motif doesn't have one.
-    name.clear();
-    // be nice if glsequence was a subclass of sequence so we could
-    // just attach colors directly to the motif.
-    Color c(red, green, blue, alpha);
-    color_mapper->appendInstanceColor("motif", seq.c_str(), c);
-    alpha = 1.0;
-    motifs.insert(seq);
-    ++parsed;
-  };
-};
-
 void Mussa::load_motifs(fs::path filename)
 {
   fs::ifstream f;
   f.open(filename, ifstream::in);
   load_motifs(f);
 }
-
-// I mostly split the ifstream out so I can use a stringstream to test it.
+  
 void Mussa::load_motifs(std::istream &in)
 {
   std::string data;
-  const char *alphabet = Alphabet::nucleic_alphabet.c_str();
-  string seq;
-  string name;
-  float red = 1.0;
-  float green = 0.0;
-  float blue = 0.0;
-  float alpha = 1.0;
-  int parsed = 1;
+  const char *alphabet = Alphabet::nucleic_cstr;
+  motif_parser::ParsedMotifs parsed_motifs(motif_sequences, color_mapper);
 
   // slurp our data into a string
   std::streamsize bytes_read = 1;
@@ -851,40 +791,7 @@ void Mussa::load_motifs(std::istream &in)
     bytes_read = in.readsome(buf, bufsiz);
     data.append(buf, buf+bytes_read);
   }
-  // parse our string
-  bool ok = spirit::parse(data.begin(), data.end(),
-     *(
-       ( 
-        (
-         (+spirit::chset<>(alphabet))[spirit::assign_a(seq)] >> 
-         +spirit::space_p
-        ) >>
-        !(
-          (
-            // names can either be letter followed by non-space characters
-            (spirit::alpha_p >> *spirit::graph_p)[spirit::assign_a(name)]
-            |
-            // or a quoted string
-            (
-             spirit::ch_p('"') >> 
-               (+(~spirit::ch_p('"')))[spirit::assign_a(name)] >>
-             spirit::ch_p('"')
-            )
-          ) >> +spirit::space_p
-        ) >>
-        spirit::real_p[spirit::assign_a(red)] >> +spirit::space_p >>
-        spirit::real_p[spirit::assign_a(green)] >> +spirit::space_p >>
-        spirit::real_p[spirit::assign_a(blue)] >> +spirit::space_p >>
-        !(spirit::real_p[spirit::assign_a(alpha)] >> +spirit::space_p)
-       )[push_back_motif(motif_sequences, color_mapper, seq, name, red, green, blue, alpha, parsed)]
-     )).full;
-  if (not ok) {
-    stringstream msg;
-    msg << "Error parsing motif #" << parsed;
-    // erase our potentially broken motif list
-    motif_sequences.clear();
-    throw motif_load_error(msg.str());
-  }
+  parsed_motifs.parse(data);
   update_sequences_motifs();
 }