diff --git a/src/include/document_writer.hpp b/src/include/document_writer.hpp index d4db31f..ab462a9 100644 --- a/src/include/document_writer.hpp +++ b/src/include/document_writer.hpp @@ -106,6 +106,10 @@ class document_writer std::string get_rna_subtree_formatted( rna_tree::iterator root) const; + std::string find_pseudoknots( + rna_tree::pre_post_order_iterator begin, + rna_tree::pre_post_order_iterator end) const; + public: /** * initialize new document_writer on document `filename`.`suffix` diff --git a/src/include/rna_tree_label.hpp b/src/include/rna_tree_label.hpp index 63e66bc..c88db07 100644 --- a/src/include/rna_tree_label.hpp +++ b/src/include/rna_tree_label.hpp @@ -39,6 +39,7 @@ struct rna_label std::string label; std::string tmp_label; //label used in the template (can be used to store information about the mapped nodes label in the template) point p; + size_t pseudoknot; }; /** @@ -63,6 +64,9 @@ class rna_pair_label : public node_base rna_pair_label() = default; rna_pair_label( const std::string& s); + + rna_pair_label(const std::string& s, size_t pseudoknot); + bool operator==( const rna_pair_label& other) const; rna_pair_label operator+( @@ -138,9 +142,9 @@ class rna_pair_label : public node_base public: status_type status = untouched; std::vector remake_ids; + std::vector labels; private: - std::vector labels; point parent_center; std::vector bounding_objects; diff --git a/src/tree/rna_tree.cpp b/src/tree/rna_tree.cpp index 491ec4b..2378ac5 100644 --- a/src/tree/rna_tree.cpp +++ b/src/tree/rna_tree.cpp @@ -32,6 +32,9 @@ using namespace std; inline static std::vector convert( const std::string& labels); +inline static std::vector convert(const std::string& labels, const std::string& brackets); + + inline static std::string trim( std::string s); @@ -41,7 +44,7 @@ rna_tree::rna_tree( const std::string& _labels, const std::string& _name) : tree_base( - trim(_brackets), convert(trim(_labels))), _name(_name) + trim(_brackets), convert(trim(_labels), trim(_brackets))), _name(_name) { set_postorder_ids(); distances = {0xBADF00D, 0xBADF00D, 0xBADF00D}; @@ -82,7 +85,34 @@ void rna_tree::set_name( return vec; } - +std::vector convert( + const std::string& labels, + const std::string& brackets) +{ + vector vec; + vec.reserve(labels.size()); + size_t pseudoknot = 1; + + for (size_t i = 0; i < labels.size(); ++i) + { + if(brackets[i] == '[' || brackets[i] == '{') + { + vec.emplace_back(labels.substr(i, 1), pseudoknot); + pseudoknot++; + } + else if(brackets[i] == ']' || brackets[i] == '}') + { + --pseudoknot; + vec.emplace_back(labels.substr(i, 1), pseudoknot); + } + else + { + vec.emplace_back(labels.substr(i, 1)); + } + } + + return vec; +} void rna_tree::update_points( diff --git a/src/tree/rna_tree_label.cpp b/src/tree/rna_tree_label.cpp index a809288..6b9209e 100644 --- a/src/tree/rna_tree_label.cpp +++ b/src/tree/rna_tree_label.cpp @@ -38,9 +38,15 @@ bool rna_label::operator==( rna_pair_label::rna_pair_label( const std::string& s) { - labels.push_back({s, "", point::bad_point()}); + labels.push_back({s, "", point::bad_point(), 0}); } +rna_pair_label::rna_pair_label(const std::string& s, size_t pseudoknot) +{ + labels.push_back({s, point::bad_point(), pseudoknot}); +} + + const rna_label& rna_pair_label::operator[]( size_t index) const { diff --git a/src/utils/document_writer.cpp b/src/utils/document_writer.cpp index f52b48a..01353fd 100644 --- a/src/utils/document_writer.cpp +++ b/src/utils/document_writer.cpp @@ -227,11 +227,45 @@ std::string document_writer::get_rna_background_formatted( return out.str(); } +std::string document_writer::find_pseudoknots(rna_tree::pre_post_order_iterator begin, rna_tree::pre_post_order_iterator end) const +{ + ostringstream out; + + while(begin != end) + { + for(auto&& l: begin->labels) + { + if(l.pseudoknot != 0) + { + auto rest = begin; + ++rest; + + while(rest != end) + { + for(auto&& ll: rest->labels) + { + if(ll.pseudoknot == l.pseudoknot) + { + out << get_line_formatted(l.p, ll.p, RGB::RED); + } + } + ++rest; + } + } + } + + ++begin; + } + + return out.str(); +} + std::string document_writer::get_rna_formatted( rna_tree rna) const { return get_rna_subtree_formatted(rna.begin()) - + get_rna_background_formatted(rna.begin_pre_post(), rna.end_pre_post()); + + get_rna_background_formatted(rna.begin_pre_post(), rna.end_pre_post()) + + find_pseudoknots(rna.begin_pre_post(), rna.end_pre_post()); } void document_writer::init(