1 #include "mussa_exceptions.hpp"
2 #include "alphabet.hpp"
3 #include "motif_parser.hpp"
6 #include <boost/spirit/core.hpp>
7 #include <boost/spirit/actor/push_back_actor.hpp>
8 #include <boost/spirit/iterator/file_iterator.hpp>
9 #include <boost/spirit/utility/chset.hpp>
10 namespace spirit = boost::spirit;
15 motif_parser::push_channel::push_channel( motif_parser::ParsedMotifs *parsed_ ) :
20 void motif_parser::push_channel::operator()(float f) const
22 parsed->channels.push_back(f);
25 motif_parser::push_sequence::push_sequence( ParsedMotifs *parsed_) :
30 template<typename Iterator>
31 void motif_parser::push_sequence::operator()(
35 std::copy(start, end, std::back_inserter(parsed->sequence));
38 motif_parser::push_name::push_name( ParsedMotifs *parsed_) :
43 template<typename Iterator>
44 void motif_parser::push_name::operator()(
48 std::copy(start, end, std::back_inserter(parsed->name));
51 motif_parser::push_motif::push_motif( ParsedMotifs *parsed_) :
54 template<typename Iterator>
55 void motif_parser::push_motif::operator()(
59 float red, green, blue, alpha;
60 Sequence seq(parsed->sequence, dna_alphabet, SeqSpan::PlusStrand);
61 seq.set_fasta_header(parsed->name);
64 switch (parsed->channels.size()) {
66 alpha = parsed->channels[3];
69 red = parsed->channels[0];
70 green = parsed->channels[1];
71 blue = parsed->channels[2];
74 throw std::runtime_error("wrong number of channels");
77 Color c(red, green, blue, alpha);
78 std::string motif_subseq(seq.begin(), seq.end());
79 parsed->color_mapper->appendInstanceColor("motif", motif_subseq, c);
80 parsed->motifs.insert(seq);
82 parsed->sequence.clear();
84 parsed->channels.clear();
87 motif_parser::ParsedMotifs::ParsedMotifs(
88 Mussa::motif_set& motifs_,
89 boost::shared_ptr<AnnotationColors> color_mapper_) :
91 color_mapper(color_mapper_)
95 void motif_parser::ParsedMotifs::parse(const std::string &data)
97 const char *alphabet = Alphabet::dna_cstr;
100 spirit::parse_info<std::string::const_iterator> result;
101 result = spirit::parse(data.begin(), data.end(),
105 (+spirit::chset<>(alphabet))[motif_parser::push_sequence(this)] >>
110 // names can either be letter followed by non-space characters
111 (spirit::alpha_p >> *spirit::graph_p)[motif_parser::push_name(this)]
113 // or a quoted string
116 (+(~spirit::ch_p('"')))[motif_parser::push_name(this)] >>
119 ) >> +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 >>
123 spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p >>
124 !(spirit::real_p[motif_parser::push_channel(this)] >> +spirit::space_p)
127 if (not result.full) {
128 std::stringstream msg;
129 msg << "Error at character " << result.length;
130 // erase our potentially broken motif list
132 throw motif_load_error(msg.str());