1 #include "mussa_exceptions.hpp"
2 #include "alg/alphabet.hpp"
3 #include "alg/motif_parser.hpp"
5 #include <boost/spirit/core.hpp>
6 #include <boost/spirit/actor/push_back_actor.hpp>
7 #include <boost/spirit/iterator/file_iterator.hpp>
8 #include <boost/spirit/utility/chset.hpp>
9 namespace spirit = boost::spirit;
14 motif_parser::push_channel::push_channel( motif_parser::ParsedMotifs *parsed_ ) :
19 void motif_parser::push_channel::operator()(float f) const
21 parsed->channels.push_back(f);
24 motif_parser::push_sequence::push_sequence( ParsedMotifs *parsed_) :
29 template<typename Iterator>
30 void motif_parser::push_sequence::operator()(
34 std::copy(start, end, std::back_inserter(parsed->sequence));
37 motif_parser::push_name::push_name( ParsedMotifs *parsed_) :
42 template<typename Iterator>
43 void motif_parser::push_name::operator()(
47 std::copy(start, end, std::back_inserter(parsed->name));
50 motif_parser::push_motif::push_motif( ParsedMotifs *parsed_) :
53 template<typename Iterator>
54 void motif_parser::push_motif::operator()(
58 float red, green, blue, alpha;
59 Sequence seq(parsed->sequence, Sequence::nucleic_alphabet);
60 seq.set_fasta_header(parsed->name);
63 switch (parsed->channels.size()) {
65 alpha = parsed->channels[3];
68 red = parsed->channels[0];
69 green = parsed->channels[1];
70 blue = parsed->channels[2];
73 throw std::runtime_error("wrong number of channels");
76 Color c(red, green, blue, alpha);
77 parsed->color_mapper->appendInstanceColor("motif", seq.c_str(), c);
78 parsed->motifs.insert(seq);
80 parsed->sequence.clear();
82 parsed->channels.clear();
85 motif_parser::ParsedMotifs::ParsedMotifs(
86 Mussa::motif_set& motifs_,
87 boost::shared_ptr<AnnotationColors> color_mapper_) :
89 color_mapper(color_mapper_)
93 void motif_parser::ParsedMotifs::parse(const std::string &data)
95 const char *alphabet = Alphabet::nucleic_cstr;
98 spirit::parse_info<std::string::const_iterator> result;
99 result = spirit::parse(data.begin(), data.end(),
103 (+spirit::chset<>(alphabet))[motif_parser::push_sequence(this)] >>
108 // names can either be letter followed by non-space characters
109 (spirit::alpha_p >> *spirit::graph_p)[motif_parser::push_name(this)]
111 // or a quoted string
114 (+(~spirit::ch_p('"')))[motif_parser::push_name(this)] >>
117 ) >> +spirit::space_p
119 spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p >>
120 spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p >>
121 spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p >>
122 !(spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p)
125 if (not result.full) {
126 std::stringstream msg;
127 msg << "Error at character " << result.length;
128 // erase our potentially broken motif list
130 throw motif_load_error(msg.str());