From: Diane Trout Date: Sun, 12 Mar 2006 01:25:23 +0000 (+0000) Subject: There can be only one (filename convention) X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=198f7c18fd0b5fa84528e9b28a84269c3a856cc4 There can be only one (filename convention) So I was used to using .cxx/.h, tristan used .cc/.hh, neither are really that great, so after some consultation we're going to use the boost convention of .cpp/.hpp, we assume that the boost people know what they're doing. --- diff --git a/Makefile.noqt b/Makefile.noqt index b2aaecc..5431ab1 100644 --- a/Makefile.noqt +++ b/Makefile.noqt @@ -26,7 +26,7 @@ include gui/module.mk include module.mk # process what the module.mks defined -OBJ := $(patsubst %.cxx,%.o, $(filter %.cxx,$(SRC))) +OBJ := $(patsubst %.cpp,%.o, $(filter %.cpp,$(SRC))) DEPS := $(OBJ:.o=.d) targets: $(TARGETLIBS) $(TARGETBINS) @@ -38,11 +38,11 @@ define make-depend $(CXX) -MM -MF $3 -MP -MT $2 $(CFLAGS) $(CXXFLAGS) $1 endef -%.d: %.cxx +%.d: %.cpp $(call make-depend,$<,$@,$(subst .o,.d,$@)) # makedepend -o.d $(dirname $^) $(CFLAGS) $(CXXFILAGS) $^ -f- > $@ -%.o: %.cxx +%.o: %.cpp $(CXX) -c -o $@ $(CXXFLAGS) $^ include $(DEPS) diff --git a/alg/color.cpp b/alg/color.cpp new file mode 100644 index 0000000..1c01f89 --- /dev/null +++ b/alg/color.cpp @@ -0,0 +1,97 @@ +#include "alg/color.hpp" +#include + +Color::Color() +{ + set(0.0, 0.0, 0.0, 0.0); +} + +Color::Color(const Color &c) +{ + set(c.colors[RedChannel], + c.colors[GreenChannel], + c.colors[BlueChannel], + c.colors[AlphaChannel]); +} + +Color::Color(float red, float green, float blue, float alpha) +{ + set(red, green, blue, alpha); +} + +void Color::set(float r, float g, float b, float a) +{ + colors[RedChannel] = r; + colors[GreenChannel] = g; + colors[BlueChannel] = b; + colors[AlphaChannel] = a; +} + +const float *const Color::get() const +{ + return colors; +} + +void Color::setR(float r) +{ + colors[RedChannel] = r; +} + +float Color::r() const +{ + return colors[RedChannel]; +} + +void Color::setG(float g) +{ + colors[GreenChannel] = g; +} + +float Color::g() const +{ + return colors[GreenChannel]; +} + +void Color::setB(float b) +{ + colors[BlueChannel] = b; +} + +float Color::b() const +{ + return colors[BlueChannel]; +} + +void Color::setA(float a) +{ + colors[AlphaChannel] = a; +} + +float Color::a() const +{ + return colors[AlphaChannel]; +} + +static bool close(float l, float r, float t=1e-6) +{ + float difference = fabsf(l-r); + l = fabsf(l); + r = fabsf(r); + + return (difference <= (t*l) or difference <= (t*r)); +} +bool operator==(const Color &x, const Color &y) +{ + return (close(x.colors[Color::RedChannel] ,y.colors[Color::RedChannel]) and + close(x.colors[Color::GreenChannel],y.colors[Color::GreenChannel]) and + close(x.colors[Color::BlueChannel] ,y.colors[Color::BlueChannel]) and + close(x.colors[Color::AlphaChannel],y.colors[Color::AlphaChannel])); +} + +std::ostream &operator<<(std::ostream &out, const Color &c) +{ + out << "Color(" << c.r() << ", " + << c.g() << ", " + << c.b() << ", " + << c.a() << ")"; +} diff --git a/alg/color.cxx b/alg/color.cxx deleted file mode 100644 index 61342fc..0000000 --- a/alg/color.cxx +++ /dev/null @@ -1,97 +0,0 @@ -#include "alg/color.h" -#include - -Color::Color() -{ - set(0.0, 0.0, 0.0, 0.0); -} - -Color::Color(const Color &c) -{ - set(c.colors[RedChannel], - c.colors[GreenChannel], - c.colors[BlueChannel], - c.colors[AlphaChannel]); -} - -Color::Color(float red, float green, float blue, float alpha) -{ - set(red, green, blue, alpha); -} - -void Color::set(float r, float g, float b, float a) -{ - colors[RedChannel] = r; - colors[GreenChannel] = g; - colors[BlueChannel] = b; - colors[AlphaChannel] = a; -} - -const float *const Color::get() const -{ - return colors; -} - -void Color::setR(float r) -{ - colors[RedChannel] = r; -} - -float Color::r() const -{ - return colors[RedChannel]; -} - -void Color::setG(float g) -{ - colors[GreenChannel] = g; -} - -float Color::g() const -{ - return colors[GreenChannel]; -} - -void Color::setB(float b) -{ - colors[BlueChannel] = b; -} - -float Color::b() const -{ - return colors[BlueChannel]; -} - -void Color::setA(float a) -{ - colors[AlphaChannel] = a; -} - -float Color::a() const -{ - return colors[AlphaChannel]; -} - -static bool close(float l, float r, float t=1e-6) -{ - float difference = fabsf(l-r); - l = fabsf(l); - r = fabsf(r); - - return (difference <= (t*l) or difference <= (t*r)); -} -bool operator==(const Color &x, const Color &y) -{ - return (close(x.colors[Color::RedChannel] ,y.colors[Color::RedChannel]) and - close(x.colors[Color::GreenChannel],y.colors[Color::GreenChannel]) and - close(x.colors[Color::BlueChannel] ,y.colors[Color::BlueChannel]) and - close(x.colors[Color::AlphaChannel],y.colors[Color::AlphaChannel])); -} - -std::ostream &operator<<(std::ostream &out, const Color &c) -{ - out << "Color(" << c.r() << ", " - << c.g() << ", " - << c.b() << ", " - << c.a() << ")"; -} diff --git a/alg/color.h b/alg/color.h deleted file mode 100644 index 3e4def5..0000000 --- a/alg/color.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _GLCOLOR_H_ -#define _GLCOLOR_H_ - -#include - -//! convienece class for handling opengl colors -class Color -{ -public: - Color(); - Color(const Color &); - //! initialize with red, green, blue, alpha - Color(float r, float g, float b, float a=0.0); - - //! set all channels simultaneously - void set(float r, float g, float b, float a=0.0); - //! return an array of 4 colors (stored by class) - const float* const get() const; - void setR(float); - float r() const; - void setG(float); - float g() const; - void setB(float); - float b() const; - void setA(float); - float a() const; - - enum color_channels { RedChannel, GreenChannel, BlueChannel, AlphaChannel }; - friend bool operator==(const Color&, const Color&); - friend std::ostream& operator<<(std::ostream&, const Color&); - -protected: - float colors[4]; -}; - -#endif - diff --git a/alg/color.hpp b/alg/color.hpp new file mode 100644 index 0000000..3e4def5 --- /dev/null +++ b/alg/color.hpp @@ -0,0 +1,37 @@ +#ifndef _GLCOLOR_H_ +#define _GLCOLOR_H_ + +#include + +//! convienece class for handling opengl colors +class Color +{ +public: + Color(); + Color(const Color &); + //! initialize with red, green, blue, alpha + Color(float r, float g, float b, float a=0.0); + + //! set all channels simultaneously + void set(float r, float g, float b, float a=0.0); + //! return an array of 4 colors (stored by class) + const float* const get() const; + void setR(float); + float r() const; + void setG(float); + float g() const; + void setB(float); + float b() const; + void setA(float); + float a() const; + + enum color_channels { RedChannel, GreenChannel, BlueChannel, AlphaChannel }; + friend bool operator==(const Color&, const Color&); + friend std::ostream& operator<<(std::ostream&, const Color&); + +protected: + float colors[4]; +}; + +#endif + diff --git a/alg/conserved_path.cpp b/alg/conserved_path.cpp new file mode 100644 index 0000000..af2a4a0 --- /dev/null +++ b/alg/conserved_path.cpp @@ -0,0 +1,173 @@ +#include "alg/conserved_path.hpp" +#include + +using namespace std; + +///////////////////// + +ConservedPath::ConservedPath() + : score(0.0), + track_indexes() +{ +} + +ConservedPath::ConservedPath(const ConservedPath::ConservedPath& other) + : score(other.score), + track_indexes(other.track_indexes) +{ +} + +ConservedPath::ConservedPath(double s, ConservedPath::path_type path) + : score(s), + track_indexes(path) +{ +} + +void ConservedPath::clear() +{ + score = 0.0; + track_indexes.clear(); +} + +ConservedPath::path_element& +ConservedPath::operator[](ConservedPath::size_type index) +{ + return track_indexes[index]; +} + +bool operator==(const ConservedPath::ConservedPath& a, + const ConservedPath::ConservedPath& b) +{ + // this isn't good as score is now a double + return ( (a.score == b.score) + and (a.track_indexes.size() == b.track_indexes.size()) + and (a.track_indexes == b.track_indexes)); +} + +bool operator!=(const ConservedPath::ConservedPath& a, + const ConservedPath::ConservedPath& b) +{ + return not (a == b); +} + +std::ostream& operator<<(std::ostream& out, const ConservedPath& path) +{ + out << "" << *itor; + // print the remaining elements + for (; + itor != path.end(); + ++itor) + { + out << ", " << *itor; + } + out << ""; + } + else + { + // if we had no elements just close the block + out << "/>"; + } + return out; +} + +void ConservedPath::push_back(const ConservedPath::path_element& element) +{ + track_indexes.push_back(element); +} + +void ConservedPath::pop_back() +{ + track_indexes.pop_back(); +} + +ConservedPath::size_type ConservedPath::size() const +{ + return track_indexes.size(); +} + +ConservedPath::iterator ConservedPath::begin() +{ + return track_indexes.begin(); +} + +ConservedPath::const_iterator ConservedPath::begin() const +{ + return track_indexes.begin(); +} + +ConservedPath::iterator ConservedPath::end() +{ + return track_indexes.end(); +} + +ConservedPath::const_iterator ConservedPath::end() const +{ + return track_indexes.end(); +} + +bool ConservedPath::nextTo(const ConservedPath& next) const +{ + if (size() != next.size() ) { + throw runtime_error("paths must be the same length"); + } + ConservedPath::const_iterator this_itor = begin(); + ConservedPath::const_iterator next_itor = next.begin(); + for (; this_itor != end(); ++this_itor, ++next_itor) + { + if ( (*this_itor + 1) != *next_itor ) + return false; + } + return true; +} + +///////////////////// +ExtendedConservedPath::ExtendedConservedPath() + : ConservedPath(), + window_size(0) +{ +} + +ExtendedConservedPath::ExtendedConservedPath(const ExtendedConservedPath& other) + : ConservedPath(other), + window_size(other.window_size) +{ +} + +ExtendedConservedPath::ExtendedConservedPath(int win_size, ConservedPath other) + : ConservedPath(other), + window_size(win_size) +{ +} + +ExtendedConservedPath::ExtendedConservedPath(int win_size, + double s, + ConservedPath::path_type p) + : ConservedPath(s, p), + window_size(win_size) +{ +} + +ExtendedConservedPath& ExtendedConservedPath::extend(int growth) +{ + window_size += growth; + + // What does this actually do? Tristan's code was doing this operation + // but I don't understand how it properly adjusts reverse compliment + // windows? + for(ConservedPath::iterator path_i = begin(); + path_i != end(); + ++path_i) + { + if (*path_i < 0) + *path_i += growth; + } + return *this; +} + + diff --git a/alg/conserved_path.cxx b/alg/conserved_path.cxx deleted file mode 100644 index bf845ad..0000000 --- a/alg/conserved_path.cxx +++ /dev/null @@ -1,173 +0,0 @@ -#include "alg/conserved_path.h" -#include - -using namespace std; - -///////////////////// - -ConservedPath::ConservedPath() - : score(0.0), - track_indexes() -{ -} - -ConservedPath::ConservedPath(const ConservedPath::ConservedPath& other) - : score(other.score), - track_indexes(other.track_indexes) -{ -} - -ConservedPath::ConservedPath(double s, ConservedPath::path_type path) - : score(s), - track_indexes(path) -{ -} - -void ConservedPath::clear() -{ - score = 0.0; - track_indexes.clear(); -} - -ConservedPath::path_element& -ConservedPath::operator[](ConservedPath::size_type index) -{ - return track_indexes[index]; -} - -bool operator==(const ConservedPath::ConservedPath& a, - const ConservedPath::ConservedPath& b) -{ - // this isn't good as score is now a double - return ( (a.score == b.score) - and (a.track_indexes.size() == b.track_indexes.size()) - and (a.track_indexes == b.track_indexes)); -} - -bool operator!=(const ConservedPath::ConservedPath& a, - const ConservedPath::ConservedPath& b) -{ - return not (a == b); -} - -std::ostream& operator<<(std::ostream& out, const ConservedPath& path) -{ - out << "" << *itor; - // print the remaining elements - for (; - itor != path.end(); - ++itor) - { - out << ", " << *itor; - } - out << ""; - } - else - { - // if we had no elements just close the block - out << "/>"; - } - return out; -} - -void ConservedPath::push_back(const ConservedPath::path_element& element) -{ - track_indexes.push_back(element); -} - -void ConservedPath::pop_back() -{ - track_indexes.pop_back(); -} - -ConservedPath::size_type ConservedPath::size() const -{ - return track_indexes.size(); -} - -ConservedPath::iterator ConservedPath::begin() -{ - return track_indexes.begin(); -} - -ConservedPath::const_iterator ConservedPath::begin() const -{ - return track_indexes.begin(); -} - -ConservedPath::iterator ConservedPath::end() -{ - return track_indexes.end(); -} - -ConservedPath::const_iterator ConservedPath::end() const -{ - return track_indexes.end(); -} - -bool ConservedPath::nextTo(const ConservedPath& next) const -{ - if (size() != next.size() ) { - throw runtime_error("paths must be the same length"); - } - ConservedPath::const_iterator this_itor = begin(); - ConservedPath::const_iterator next_itor = next.begin(); - for (; this_itor != end(); ++this_itor, ++next_itor) - { - if ( (*this_itor + 1) != *next_itor ) - return false; - } - return true; -} - -///////////////////// -ExtendedConservedPath::ExtendedConservedPath() - : ConservedPath(), - window_size(0) -{ -} - -ExtendedConservedPath::ExtendedConservedPath(const ExtendedConservedPath& other) - : ConservedPath(other), - window_size(other.window_size) -{ -} - -ExtendedConservedPath::ExtendedConservedPath(int win_size, ConservedPath other) - : ConservedPath(other), - window_size(win_size) -{ -} - -ExtendedConservedPath::ExtendedConservedPath(int win_size, - double s, - ConservedPath::path_type p) - : ConservedPath(s, p), - window_size(win_size) -{ -} - -ExtendedConservedPath& ExtendedConservedPath::extend(int growth) -{ - window_size += growth; - - // What does this actually do? Tristan's code was doing this operation - // but I don't understand how it properly adjusts reverse compliment - // windows? - for(ConservedPath::iterator path_i = begin(); - path_i != end(); - ++path_i) - { - if (*path_i < 0) - *path_i += growth; - } - return *this; -} - - diff --git a/alg/conserved_path.h b/alg/conserved_path.h deleted file mode 100644 index f5f4953..0000000 --- a/alg/conserved_path.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _CONSERVED_PATH_H -#define _CONSERVED_PATH_H -#include -#include - -struct ConservedPath -{ - typedef int path_element; - typedef std::vector path_type; - typedef path_type::iterator iterator; - typedef path_type::const_iterator const_iterator; - typedef path_type::size_type size_type; - - ConservedPath(); - ConservedPath(const ConservedPath& ); - ConservedPath(double score, path_type path); - - //! reset our path to be empty (including setting threshold to 0) - void clear(); - path_element& operator[](size_type index); - void push_back(const path_element& ); - void pop_back(); - - size_type size() const; - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - - friend bool operator==(const ConservedPath& a, const ConservedPath &b); - friend bool operator!=(const ConservedPath& a, const ConservedPath &b); - friend std::ostream& operator<<(std::ostream&, const ConservedPath&); - - //! return true if all elements of the path are "next to" our current path. - /*! Next to is defined as being window index + 1 - * that definition may not properly track reverse compliment - */ - bool nextTo(const ConservedPath& next) const; - - //! either number of conserved bases or average entropy - double score; - //! offsets into each of our sequences representing the start of our window - std::vector track_indexes; -}; - -struct ExtendedConservedPath : public ConservedPath -{ - ExtendedConservedPath(); - ExtendedConservedPath(const ExtendedConservedPath& other); - ExtendedConservedPath(int win_size, ConservedPath conserved_path); - ExtendedConservedPath(int win_size, double score, std::vector path); - - //! extend our current path - /*! (aka increment our window size by growth) - */ - ExtendedConservedPath& extend(int growth=1); - - //! size of extended window - int window_size; -}; -#endif diff --git a/alg/conserved_path.hpp b/alg/conserved_path.hpp new file mode 100644 index 0000000..f5f4953 --- /dev/null +++ b/alg/conserved_path.hpp @@ -0,0 +1,61 @@ +#ifndef _CONSERVED_PATH_H +#define _CONSERVED_PATH_H +#include +#include + +struct ConservedPath +{ + typedef int path_element; + typedef std::vector path_type; + typedef path_type::iterator iterator; + typedef path_type::const_iterator const_iterator; + typedef path_type::size_type size_type; + + ConservedPath(); + ConservedPath(const ConservedPath& ); + ConservedPath(double score, path_type path); + + //! reset our path to be empty (including setting threshold to 0) + void clear(); + path_element& operator[](size_type index); + void push_back(const path_element& ); + void pop_back(); + + size_type size() const; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + friend bool operator==(const ConservedPath& a, const ConservedPath &b); + friend bool operator!=(const ConservedPath& a, const ConservedPath &b); + friend std::ostream& operator<<(std::ostream&, const ConservedPath&); + + //! return true if all elements of the path are "next to" our current path. + /*! Next to is defined as being window index + 1 + * that definition may not properly track reverse compliment + */ + bool nextTo(const ConservedPath& next) const; + + //! either number of conserved bases or average entropy + double score; + //! offsets into each of our sequences representing the start of our window + std::vector track_indexes; +}; + +struct ExtendedConservedPath : public ConservedPath +{ + ExtendedConservedPath(); + ExtendedConservedPath(const ExtendedConservedPath& other); + ExtendedConservedPath(int win_size, ConservedPath conserved_path); + ExtendedConservedPath(int win_size, double score, std::vector path); + + //! extend our current path + /*! (aka increment our window size by growth) + */ + ExtendedConservedPath& extend(int growth=1); + + //! size of extended window + int window_size; +}; +#endif diff --git a/alg/flp.cpp b/alg/flp.cpp new file mode 100644 index 0000000..3076e7b --- /dev/null +++ b/alg/flp.cpp @@ -0,0 +1,268 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- flp.cc ----------- +// ---------------------------------------- + +#include "alg/flp.hpp" + +#include +#include +#include +#include +#include + +using namespace std; + +bool operator==(const FLPs::match& a, const FLPs::match& b) +{ + return (a.index == b.index && a.score == b.score); +} + +ostream &operator<<(ostream& out, const FLPs::match& m) +{ + out << "(" << m.score << ", " << m.index << ")"; + return out; +} + +FLPs::FLPs() : + window_size(0), + hard_threshold(0), + all_matches(0) +{ +} + +void +FLPs::setup(int win_size, int hard_thres) +{ + window_size = win_size; + hard_threshold = hard_thres; +} + +void FLPs::alloc_matches(string::size_type len1) +{ + if (all_matches != 0) { + // if we're being called again its likely because + // seqcomp is being called to do the reverse compliment + // so we shouldn't reallocate ourselves. + return; + } + all_matches = new std::vector >; + + list empty_match_list; + std::vector >::size_type window_count; + if (len1 > 0) { + // we actually know how much to preallocate + window_count = len1 - window_size+1; + } else { + // we have no idea, so don't allocate anything + window_count = 0; + } + + for (std::vector >::size_type i=0; i < window_count; ++i) { + all_matches->push_back(empty_match_list); + } + assert (all_matches->size() == window_count); +} + + +int +FLPs::size() const +{ + if (all_matches != 0) { + return all_matches->size(); + } else { + return 0; + } +} + + +/* +bool +FLPs::match_less(match *match1, match *match2) +{ + if (match1->score < match2->score) + return true; + else if ( (match1->score == match2->score) && + (match1->index < match2->index) ) + return true; + else + return false; +} + +void +FLPs::sort() +{ + int i; + + for(i = 0; i < seq1_win_num; i++) + if (!all_matches[i].empty()) + all_matches[i].sort(&FLPs::match_less); +} +*/ + +list +FLPs::matches(int index) const +{ + if (all_matches == 0) + throw runtime_error("please call FLPs.seqcomp first"); + + list::iterator list_i, list_end; + + index = abs(index); + list_i = (*all_matches)[index].begin(); + list_end = (*all_matches)[index].end(); + list these_matches(list_i, list_end); + return these_matches; +} + +list +FLPs::match_locations(int index) const +{ + if (all_matches == 0) + throw runtime_error("please call FLPs.seqcomp first"); + + list these_matches; + list::iterator list_i, list_end; + + index = abs(index); + list_i = (*all_matches)[index].begin(); + list_end = (*all_matches)[index].end(); + while (list_i != list_end) + { + these_matches.push_back(list_i->index); + ++list_i; + } + return these_matches; +} + +list +FLPs::thres_matches(int index, int thres) const +{ + if (all_matches == 0) + throw runtime_error("please call FLPs.seqcomp first"); + + list thres_matches; + list::iterator list_i, list_end; + + index = abs(index); + list_i = (*all_matches)[index].begin(); + list_end = (*all_matches)[index].end(); + thres_matches.clear(); + + while (list_i != list_end) + { + if (list_i->score >= thres) + thres_matches.push_back(list_i->index); + ++list_i; + } + return thres_matches; +} + +void +FLPs::save(string save_file_path) +{ + if (all_matches == 0) + throw runtime_error("please call FLPs.seqcomp first"); + + fstream save_file; + save_file.open(save_file_path.c_str(), ios::out); + + save_file << "score << " "; + } + } + save_file << endl; + } + + save_file << "\n"; + + save_file.close(); +} + +void +FLPs::load(string file_path) +{ + fstream data_file; + string file_data, file_data_line, pair_data, index_data, score_data; + match a_match; + string::size_type split_index, comma_index; + bool tag_open = false; + list a_match_list; + // initialize our all_matches pointer + alloc_matches(); + + + data_file.open(file_path.c_str(), ios::in); + + getline(data_file,file_data_line); + // parse seqcomp open tag and parameters + // eg + // if parse successful... + tag_open = true; + + while ((!data_file.eof()) && tag_open) + { + // intialize list to empty + a_match_list.clear(); + + getline(data_file,file_data_line); + if (file_data_line == "") + { + tag_open = false; + } + // parse line of matches + else if (file_data_line == "") + { + //cout << "empty line\n"; + all_matches->push_back(a_match_list); + } + else + { + split_index = file_data_line.find(" "); + + while (split_index != string::npos) + { + pair_data = file_data_line.substr(0,split_index); + file_data_line = file_data_line.substr(split_index+1); + //cout << "pair_data = " << pair_data << "..."; + // parse out the 2 pieces of data, index and score of pair match + comma_index = pair_data.find(","); + index_data = pair_data.substr(0, comma_index); + a_match.index = atoi(index_data.c_str() ); + score_data = pair_data.substr(comma_index+1); + a_match.score = atoi(score_data.c_str() ); + //cout << a_match.index << "," << a_match.score << " "; + + a_match_list.push_back(a_match); + + split_index = file_data_line.find(" "); + } + all_matches->push_back(a_match_list); + //cout << all_matches->size() << "\n"; + } + } + //cout << "windows in flp = " << all_matches->size() << endl; + data_file.close(); +} + diff --git a/alg/flp.cxx b/alg/flp.cxx deleted file mode 100644 index 88a2fb6..0000000 --- a/alg/flp.cxx +++ /dev/null @@ -1,268 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- flp.cc ----------- -// ---------------------------------------- - -#include "flp.hh" - -#include -#include -#include -#include -#include - -using namespace std; - -bool operator==(const FLPs::match& a, const FLPs::match& b) -{ - return (a.index == b.index && a.score == b.score); -} - -ostream &operator<<(ostream& out, const FLPs::match& m) -{ - out << "(" << m.score << ", " << m.index << ")"; - return out; -} - -FLPs::FLPs() : - window_size(0), - hard_threshold(0), - all_matches(0) -{ -} - -void -FLPs::setup(int win_size, int hard_thres) -{ - window_size = win_size; - hard_threshold = hard_thres; -} - -void FLPs::alloc_matches(string::size_type len1) -{ - if (all_matches != 0) { - // if we're being called again its likely because - // seqcomp is being called to do the reverse compliment - // so we shouldn't reallocate ourselves. - return; - } - all_matches = new std::vector >; - - list empty_match_list; - std::vector >::size_type window_count; - if (len1 > 0) { - // we actually know how much to preallocate - window_count = len1 - window_size+1; - } else { - // we have no idea, so don't allocate anything - window_count = 0; - } - - for (std::vector >::size_type i=0; i < window_count; ++i) { - all_matches->push_back(empty_match_list); - } - assert (all_matches->size() == window_count); -} - - -int -FLPs::size() const -{ - if (all_matches != 0) { - return all_matches->size(); - } else { - return 0; - } -} - - -/* -bool -FLPs::match_less(match *match1, match *match2) -{ - if (match1->score < match2->score) - return true; - else if ( (match1->score == match2->score) && - (match1->index < match2->index) ) - return true; - else - return false; -} - -void -FLPs::sort() -{ - int i; - - for(i = 0; i < seq1_win_num; i++) - if (!all_matches[i].empty()) - all_matches[i].sort(&FLPs::match_less); -} -*/ - -list -FLPs::matches(int index) const -{ - if (all_matches == 0) - throw runtime_error("please call FLPs.seqcomp first"); - - list::iterator list_i, list_end; - - index = abs(index); - list_i = (*all_matches)[index].begin(); - list_end = (*all_matches)[index].end(); - list these_matches(list_i, list_end); - return these_matches; -} - -list -FLPs::match_locations(int index) const -{ - if (all_matches == 0) - throw runtime_error("please call FLPs.seqcomp first"); - - list these_matches; - list::iterator list_i, list_end; - - index = abs(index); - list_i = (*all_matches)[index].begin(); - list_end = (*all_matches)[index].end(); - while (list_i != list_end) - { - these_matches.push_back(list_i->index); - ++list_i; - } - return these_matches; -} - -list -FLPs::thres_matches(int index, int thres) const -{ - if (all_matches == 0) - throw runtime_error("please call FLPs.seqcomp first"); - - list thres_matches; - list::iterator list_i, list_end; - - index = abs(index); - list_i = (*all_matches)[index].begin(); - list_end = (*all_matches)[index].end(); - thres_matches.clear(); - - while (list_i != list_end) - { - if (list_i->score >= thres) - thres_matches.push_back(list_i->index); - ++list_i; - } - return thres_matches; -} - -void -FLPs::save(string save_file_path) -{ - if (all_matches == 0) - throw runtime_error("please call FLPs.seqcomp first"); - - fstream save_file; - save_file.open(save_file_path.c_str(), ios::out); - - save_file << "score << " "; - } - } - save_file << endl; - } - - save_file << "\n"; - - save_file.close(); -} - -void -FLPs::load(string file_path) -{ - fstream data_file; - string file_data, file_data_line, pair_data, index_data, score_data; - match a_match; - string::size_type split_index, comma_index; - bool tag_open = false; - list a_match_list; - // initialize our all_matches pointer - alloc_matches(); - - - data_file.open(file_path.c_str(), ios::in); - - getline(data_file,file_data_line); - // parse seqcomp open tag and parameters - // eg - // if parse successful... - tag_open = true; - - while ((!data_file.eof()) && tag_open) - { - // intialize list to empty - a_match_list.clear(); - - getline(data_file,file_data_line); - if (file_data_line == "") - { - tag_open = false; - } - // parse line of matches - else if (file_data_line == "") - { - //cout << "empty line\n"; - all_matches->push_back(a_match_list); - } - else - { - split_index = file_data_line.find(" "); - - while (split_index != string::npos) - { - pair_data = file_data_line.substr(0,split_index); - file_data_line = file_data_line.substr(split_index+1); - //cout << "pair_data = " << pair_data << "..."; - // parse out the 2 pieces of data, index and score of pair match - comma_index = pair_data.find(","); - index_data = pair_data.substr(0, comma_index); - a_match.index = atoi(index_data.c_str() ); - score_data = pair_data.substr(comma_index+1); - a_match.score = atoi(score_data.c_str() ); - //cout << a_match.index << "," << a_match.score << " "; - - a_match_list.push_back(a_match); - - split_index = file_data_line.find(" "); - } - all_matches->push_back(a_match_list); - //cout << all_matches->size() << "\n"; - } - } - //cout << "windows in flp = " << all_matches->size() << endl; - data_file.close(); -} - diff --git a/alg/flp.hh b/alg/flp.hh deleted file mode 100644 index ed9c02b..0000000 --- a/alg/flp.hh +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef _MUSSA_FLP_H_ -#define _MUSSA_FLP_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- flp.hh ----------- -// ---------------------------------------- - -#include -#include -#include -#include - -//! FLP = Fixed Length Pairs (Data) -/*! - * vector of linked lists of the match type struct - */ -class FLPs -{ - public: - FLPs(); - //! Setup a FLP and reserve space for the match lists - /*! - * Initialize the all_matches structure with a list of matches - * for enough windows for the size of sequence 1 - */ - - struct match - { - int index; - int score; - - friend bool operator==(const match&, const match& ); - friend std::ostream &operator<<(std::ostream&, const match&); - }; - - void setup(int win_size, int hard_thres); - //! compare two sequences and store the list of results in all_matches - void seqcomp(std::string seq1, std::string seq2, bool is_RC); - //bool FLPs::match_less(match *match1, match *match2); - //void FLPs::sort(); - //! Return all the matches for a particular window? - std::list matches(int index) const; - //! Return all the match indexes for a particular window? - std::list match_locations(int index) const; - //! Return all the match indexes for a particular window above a threshold - std::list thres_matches(int index, int thres) const; - //! Return the number of windows stored in this FLPs - /*! (this is should be the same as seq1_len-window_size+1 - */ - int size() const; - //! Save all the FLPs to save_file_path - void save(std::string save_file_path); - //! Load a vector of a lists of FLPs - void load(std::string file_path); - private: - //! the number of base pairs in the sliding window - int window_size; - //! the minimum tnumber of base pairs need for this window to be saved. - int hard_threshold; - - //! add a match from location seq1_i to seq2_i with a threshold of a_score - /*! i2_offset is used to shift the window start when doing a reverse - * compliment. (This is called by seqcomp() ) - */ - inline void add(int seq1_i, int seq2_i, int a_score, int i2_offset); - //! this list of matches between the two sequences - /*! All of the matches are stored here, it appears each window position - * in sequence 1 gets an entry in the vector, the list contains matches - * between sequence 1 and sequence 2 - */ - std::vector > *all_matches; - //! reserve space for the appropriate number of windows. - /*! this is mostly so seqcomp can use operator[] - */ - void alloc_matches(std::string::size_type len1=0); - - -}; -#endif diff --git a/alg/flp.hpp b/alg/flp.hpp new file mode 100644 index 0000000..ed9c02b --- /dev/null +++ b/alg/flp.hpp @@ -0,0 +1,88 @@ +#ifndef _MUSSA_FLP_H_ +#define _MUSSA_FLP_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- flp.hh ----------- +// ---------------------------------------- + +#include +#include +#include +#include + +//! FLP = Fixed Length Pairs (Data) +/*! + * vector of linked lists of the match type struct + */ +class FLPs +{ + public: + FLPs(); + //! Setup a FLP and reserve space for the match lists + /*! + * Initialize the all_matches structure with a list of matches + * for enough windows for the size of sequence 1 + */ + + struct match + { + int index; + int score; + + friend bool operator==(const match&, const match& ); + friend std::ostream &operator<<(std::ostream&, const match&); + }; + + void setup(int win_size, int hard_thres); + //! compare two sequences and store the list of results in all_matches + void seqcomp(std::string seq1, std::string seq2, bool is_RC); + //bool FLPs::match_less(match *match1, match *match2); + //void FLPs::sort(); + //! Return all the matches for a particular window? + std::list matches(int index) const; + //! Return all the match indexes for a particular window? + std::list match_locations(int index) const; + //! Return all the match indexes for a particular window above a threshold + std::list thres_matches(int index, int thres) const; + //! Return the number of windows stored in this FLPs + /*! (this is should be the same as seq1_len-window_size+1 + */ + int size() const; + //! Save all the FLPs to save_file_path + void save(std::string save_file_path); + //! Load a vector of a lists of FLPs + void load(std::string file_path); + private: + //! the number of base pairs in the sliding window + int window_size; + //! the minimum tnumber of base pairs need for this window to be saved. + int hard_threshold; + + //! add a match from location seq1_i to seq2_i with a threshold of a_score + /*! i2_offset is used to shift the window start when doing a reverse + * compliment. (This is called by seqcomp() ) + */ + inline void add(int seq1_i, int seq2_i, int a_score, int i2_offset); + //! this list of matches between the two sequences + /*! All of the matches are stored here, it appears each window position + * in sequence 1 gets an entry in the vector, the list contains matches + * between sequence 1 and sequence 2 + */ + std::vector > *all_matches; + //! reserve space for the appropriate number of windows. + /*! this is mostly so seqcomp can use operator[] + */ + void alloc_matches(std::string::size_type len1=0); + + +}; +#endif diff --git a/alg/flp_seqcomp.cpp b/alg/flp_seqcomp.cpp new file mode 100644 index 0000000..6db57bc --- /dev/null +++ b/alg/flp_seqcomp.cpp @@ -0,0 +1,150 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- flp_seqcomp.cc ----------- +// ---------------------------------------- + +#include "alg/flp.hpp" +#include +using namespace std; + +// Note one recording RC matches. This version of 'seqcomp' records RC matches +// as index of the window start in its nonRC form. However, past versions of +// the analysis recorded it as the index of the rear of the window, as the +// following legacy comment indicates. FR still uses this method + +// Titus thinks the start of an RC window should be its "rear" in the +// normal version of the sequence. He's wrong, of course, and in the +// future my followers will annihilate his in the Final Battle, but for +// now I'll let him have his way. + +// note seq2_i is actually the index of the leaving bp, so need to +1 + +inline void +FLPs::add(int seq1_i, int seq2_i, int a_score, int i2_offset) +{ + match a_match; + + + if (a_score >= hard_threshold) + { + a_match.index = seq2_i + i2_offset; + a_match.score = a_score; + + (*all_matches)[seq1_i].push_back(a_match); + } +} + + +void +FLPs::seqcomp(string sseq1, string sseq2, bool is_RC) +{ + int start_i, seq1_i, seq2_i, win_i; // loop variables + int matches; // number of matches in to a window + int i2_offset; + char * seq1, * seq2; + int seq1_win_num = sseq1.size() - window_size + 1; + int seq2_win_num = sseq2.size() - window_size + 1; + alloc_matches(sseq1.size()); + assert(seq1_win_num == size()); + + seq1 = (char *) sseq1.c_str(); + seq2 = (char *) sseq2.c_str(); + + + if (is_RC) + i2_offset = window_size - sseq2.size(); + else + i2_offset = 0; + + + // this does the "upper diagonals" of the search + + // loop thru the start positions for sequence 1 + for(start_i = 0; start_i < size(); start_i++) + { + matches = 0; + // compare initial window + for(win_i = 0; win_i < window_size; win_i++) + if ((seq1[start_i+win_i] == seq2[win_i]) && + (seq1[start_i+win_i] != 'N')) // N's match nothing ** + matches++; + + //seq2_i is always 0 for initial win + seq2_i = 0; + + // call inlined function that adds match if it is above threshold + add(start_i, seq2_i, matches, i2_offset); + + // run through rest of seq1 and seq2 with current seq1 offset (ie start_i) + // compare the bps leaving and entering the window and modify matches count + seq1_i = start_i; + while( (seq1_i < seq1_win_num-1) && (seq2_i < seq2_win_num-1) ) + { + // copmpare the bp leaving the window + if ((seq1[seq1_i] == seq2[seq2_i]) && (seq1[seq1_i] != 'N')) { + // N's match nothing + matches = matches -1; + } + + // compare the bp entering the window + if ((seq1[seq1_i+window_size] == seq2[seq2_i+window_size]) && + (seq1[seq1_i+window_size] != 'N')) { // N's match nothing + matches = matches + 1; + } + add(seq1_i + 1, seq2_i + 1, matches, i2_offset); + + seq1_i = seq1_i + 1; // increment seq1_i to next window + seq2_i = seq2_i + 1; // increment seq2_i to next window + } // end of loop thru the current offset sequence + } // end of loop thru the start positions of seq1 sequence + + + // this does the "lower diagonals" of the search + + // loop thru the start positions for sequence 1 + for(start_i = 1; start_i < seq2_win_num; start_i++) + { + matches = 0; + + // compare initial window + for(win_i = 0; win_i < window_size; win_i++) + if ((seq2[start_i+win_i] == seq1[win_i]) && + (seq2[start_i+win_i] != 'N')) // N's match nothing + matches++; + + //seq2_i is always start_i for initial window + seq2_i = start_i; + + add(0, seq2_i, matches, i2_offset); + + // run through rest of seq1 and seq2 with current seq1 offset (ie start_i) + // compare the bps leaving and entering the window and modify matches count + seq1_i = 0; + while( (seq1_i < seq1_win_num-1) && (seq2_i < seq2_win_num-1) ) + { + // copmpare the bp leaving the window + if ((seq1[seq1_i] == seq2[seq2_i]) && + (seq1[seq1_i] != 'N')) // N's match nothing + matches = matches - 1; + + // compare the bp entering the window + if ((seq1[seq1_i+window_size] == seq2[seq2_i+window_size]) && + (seq1[seq1_i+window_size] != 'N')) // N's match nothing + matches = matches + 1; + + add(seq1_i + 1, seq2_i + 1, matches, i2_offset); + + seq1_i = seq1_i + 1; // increment seq1_i to next window + seq2_i = seq2_i + 1; // increment seq2_i to next window + } // end of loop thru the current offset sequence + } // end of loop thru the start positions of seq2 sequence +} diff --git a/alg/flp_seqcomp.cxx b/alg/flp_seqcomp.cxx deleted file mode 100644 index 68df520..0000000 --- a/alg/flp_seqcomp.cxx +++ /dev/null @@ -1,150 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- flp_seqcomp.cc ----------- -// ---------------------------------------- - -#include "alg/flp.hh" -#include -using namespace std; - -// Note one recording RC matches. This version of 'seqcomp' records RC matches -// as index of the window start in its nonRC form. However, past versions of -// the analysis recorded it as the index of the rear of the window, as the -// following legacy comment indicates. FR still uses this method - -// Titus thinks the start of an RC window should be its "rear" in the -// normal version of the sequence. He's wrong, of course, and in the -// future my followers will annihilate his in the Final Battle, but for -// now I'll let him have his way. - -// note seq2_i is actually the index of the leaving bp, so need to +1 - -inline void -FLPs::add(int seq1_i, int seq2_i, int a_score, int i2_offset) -{ - match a_match; - - - if (a_score >= hard_threshold) - { - a_match.index = seq2_i + i2_offset; - a_match.score = a_score; - - (*all_matches)[seq1_i].push_back(a_match); - } -} - - -void -FLPs::seqcomp(string sseq1, string sseq2, bool is_RC) -{ - int start_i, seq1_i, seq2_i, win_i; // loop variables - int matches; // number of matches in to a window - int i2_offset; - char * seq1, * seq2; - int seq1_win_num = sseq1.size() - window_size + 1; - int seq2_win_num = sseq2.size() - window_size + 1; - alloc_matches(sseq1.size()); - assert(seq1_win_num == size()); - - seq1 = (char *) sseq1.c_str(); - seq2 = (char *) sseq2.c_str(); - - - if (is_RC) - i2_offset = window_size - sseq2.size(); - else - i2_offset = 0; - - - // this does the "upper diagonals" of the search - - // loop thru the start positions for sequence 1 - for(start_i = 0; start_i < size(); start_i++) - { - matches = 0; - // compare initial window - for(win_i = 0; win_i < window_size; win_i++) - if ((seq1[start_i+win_i] == seq2[win_i]) && - (seq1[start_i+win_i] != 'N')) // N's match nothing ** - matches++; - - //seq2_i is always 0 for initial win - seq2_i = 0; - - // call inlined function that adds match if it is above threshold - add(start_i, seq2_i, matches, i2_offset); - - // run through rest of seq1 and seq2 with current seq1 offset (ie start_i) - // compare the bps leaving and entering the window and modify matches count - seq1_i = start_i; - while( (seq1_i < seq1_win_num-1) && (seq2_i < seq2_win_num-1) ) - { - // copmpare the bp leaving the window - if ((seq1[seq1_i] == seq2[seq2_i]) && (seq1[seq1_i] != 'N')) { - // N's match nothing - matches = matches -1; - } - - // compare the bp entering the window - if ((seq1[seq1_i+window_size] == seq2[seq2_i+window_size]) && - (seq1[seq1_i+window_size] != 'N')) { // N's match nothing - matches = matches + 1; - } - add(seq1_i + 1, seq2_i + 1, matches, i2_offset); - - seq1_i = seq1_i + 1; // increment seq1_i to next window - seq2_i = seq2_i + 1; // increment seq2_i to next window - } // end of loop thru the current offset sequence - } // end of loop thru the start positions of seq1 sequence - - - // this does the "lower diagonals" of the search - - // loop thru the start positions for sequence 1 - for(start_i = 1; start_i < seq2_win_num; start_i++) - { - matches = 0; - - // compare initial window - for(win_i = 0; win_i < window_size; win_i++) - if ((seq2[start_i+win_i] == seq1[win_i]) && - (seq2[start_i+win_i] != 'N')) // N's match nothing - matches++; - - //seq2_i is always start_i for initial window - seq2_i = start_i; - - add(0, seq2_i, matches, i2_offset); - - // run through rest of seq1 and seq2 with current seq1 offset (ie start_i) - // compare the bps leaving and entering the window and modify matches count - seq1_i = 0; - while( (seq1_i < seq1_win_num-1) && (seq2_i < seq2_win_num-1) ) - { - // copmpare the bp leaving the window - if ((seq1[seq1_i] == seq2[seq2_i]) && - (seq1[seq1_i] != 'N')) // N's match nothing - matches = matches - 1; - - // compare the bp entering the window - if ((seq1[seq1_i+window_size] == seq2[seq2_i+window_size]) && - (seq1[seq1_i+window_size] != 'N')) // N's match nothing - matches = matches + 1; - - add(seq1_i + 1, seq2_i + 1, matches, i2_offset); - - seq1_i = seq1_i + 1; // increment seq1_i to next window - seq2_i = seq2_i + 1; // increment seq2_i to next window - } // end of loop thru the current offset sequence - } // end of loop thru the start positions of seq2 sequence -} diff --git a/alg/glsequence.cpp b/alg/glsequence.cpp new file mode 100644 index 0000000..62896aa --- /dev/null +++ b/alg/glsequence.cpp @@ -0,0 +1,326 @@ +#include "alg/glsequence.hpp" + +#include +#include +#include +#include +using namespace std; + +GlSequence::GlSequence(const Sequence &s) + : seq(s), + seq_x(0.0), + seq_y(0.0), + seq_z(1.0), + seq_height(12.0), + drawColor(0.0, 0.0, 0.0), + char_pix_per_world_unit(5.0) +{ +} + +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), + drawColor(s.drawColor), + char_pix_per_world_unit(s.char_pix_per_world_unit) +{ +} + +GlSequence &GlSequence::operator=(const GlSequence & s) +{ + if (this != &s) { + const_cast(seq) = s.seq; + seq_x = s.seq_x; + seq_y = s.seq_y; + seq_z = s.seq_z; + seq_height = s.seq_height; + drawColor = s.drawColor; + assert(char_pix_per_world_unit == s.char_pix_per_world_unit); + } + return *this; +} + +const Sequence& GlSequence::sequence() const +{ + return seq; +} + +void GlSequence::setX(GLfloat value) +{ + seq_x = value; +} + +GLfloat GlSequence::x() const +{ + return seq_x; +} + +void GlSequence::setY(GLfloat value) +{ + seq_y = value; +} + +GLfloat GlSequence::y() const +{ + return seq_y; +} + +GLfloat GlSequence::length() const +{ + return seq.size(); +} + +Sequence::size_type GlSequence::leftbase(GLfloat left) const +{ + assert (seq_x == 0); + left = ceil(left); + if (left < seq_x) + return 0; + else + return (Sequence::size_type)left; +} + +Sequence::size_type GlSequence::rightbase(GLfloat right) const +{ + assert (seq_x == 0); + right = floor(right); + if (right > seq.size()) + return seq.size(); + else + return (Sequence::size_type)right; +} + +Sequence::const_iterator GlSequence::sequence_begin() const +{ + return seq.begin(); +} + +Sequence::const_iterator GlSequence::sequence_end() const +{ + return seq.end(); +} + +Sequence::const_iterator +GlSequence::sequence_begin(GLfloat left, GLfloat right) const +{ + // the following code will be wrong when sequences can be slid around + // so make sure we break. + assert (seq_x == 0); + + if ( leftbase(left) > seq.size() or left > right ) + return seq.end(); + else + return seq.begin() + leftbase(left); +} + +Sequence::const_iterator +GlSequence::sequence_end(GLfloat left, GLfloat right) const +{ + // the following code will be wrong when sequences can be slid around + // so make sure we break. + assert (seq_x == 0); + + if ( rightbase(right) > seq.size() or left > right ) + return seq.end(); + else + return seq.begin() + rightbase(right); +} + + +//! set default track draw color +void GlSequence::setColor(Color &c) +{ + drawColor = c; +} + +//! get default track draw color +Color GlSequence::color() +{ + return drawColor; +} + + +int GlSequence::get_viewport_pixel_width() +{ + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + return viewport[3]; // grab the viewport width +} + +bool GlSequence::is_sequence_renderable(GLfloat left, + GLfloat right, + int viewport_width) const +{ + // if called with default argument, go get the viewable width + if (viewport_width == -1) { + viewport_width = get_viewport_pixel_width(); + } + GLfloat world_width = right - left; + GLfloat pixels_needed = (char_pix_per_world_unit * world_width); + + // if the number of pixels taken up by rendering the characters + // that'd show up in the current ortho width is less than the window + // width we can actually draw something + return pixels_needed < viewport_width; +} + + +void GlSequence::draw(GLfloat left, GLfloat right) const +{ + if ( not is_sequence_renderable(left, right) ) { + draw_track(left, right); + } else { + draw_sequence(left, right); + } + draw_annotations(left, right); +} + +void GlSequence::draw_box(GLfloat left, GLfloat right, + GLfloat height, GLfloat z) const +{ + GLfloat offset = height/2.0; + GLfloat top = seq_y + offset; + GLfloat bottom = seq_y - offset; + + glBegin(GL_QUADS); + glVertex3f(left, top, z); + glVertex3f(left, bottom, z); + glVertex3f(right, bottom, z); + glVertex3f(right, top, z); + glEnd(); +} +void GlSequence::draw_track(GLfloat left, GLfloat right) const +{ + glColor3fv(drawColor.get()); + // draw main sequence track + draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0); +} + +void GlSequence::draw_annotations(GLfloat left, GLfloat right) const +{ + // draw annotations + glLineWidth(seq_height); + GLfloat annotation_z = seq_z + 1.0; + std::list annots = seq.annotations(); + for (std::list::const_iterator annot_itor = annots.begin(); + annot_itor != annots.end(); + ++annot_itor, ++annotation_z) + { + glColor3f(0.0, 0.5, 0.0); + draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end, + seq_height, annotation_z); + } +} + +const int PT = 1; +const int STROKE = 2; +const int END =3; + +typedef struct charpoint { + GLfloat x, y; + int type; +} CP; + +CP Adata[] = { + {0, -5, PT}, {2.5, 5, PT}, {5, -5, STROKE}, + {0.75, -2, PT}, {4.25, -2, END} +}; + +CP Tdata[] = { + {2.5, -5, PT}, {2.5,5, STROKE}, {0, 5, PT}, {5, 5, END} +}; + +CP Gdata[] = { + {5, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT}, + {2, -5, PT}, {3, -5, PT}, {5, -3, STROKE}, + {2.5, -1, PT}, {5, -1,PT}, {5, -5, END} +}; + +CP Cdata[] = { + {4.9, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT}, + {2, -5, PT}, {3, -5, PT}, {5, -3, END} +}; + +CP Xdata[] = {{ 0, 5, PT}, {5, -5,STROKE},{0,-5,PT},{5, 5, END}}; +CP Ndata[] = {{ 0, -5, PT}, {0, 5, PT}, {5, -5, PT}, {5, 5, END}}; + +static void drawLetter(CP *l, GLfloat z) +{ + glBegin(GL_LINE_STRIP); + while(1) { + switch (l->type) { + case PT: + glVertex3f(l->x, l->y, z); + break; + case STROKE: + glVertex3f(l->x, l->y, z); + glEnd(); + glBegin(GL_LINE_STRIP); + break; + case END: + glVertex3f(l->x, l->y, z); + glEnd(); + return; + break; + default: + throw runtime_error("data structure failure"); + } + l++; + } +} + +void GlSequence::draw_sequence(GLfloat left, GLfloat right) const +{ + // FIXME: basically this needs to be greater than the number of annotations + const GLfloat z = 30; + glLineWidth(0.3); + glColor3fv(drawColor.get()); + + Sequence::const_iterator seq_itor = sequence_begin(left, right); + Sequence::const_iterator seq_end = sequence_end(left, right); + Sequence::size_type basepair = 0; + + assert(seq_end - seq_itor >= 0); + while(seq_itor != seq_end) + { + assert ( basepair < seq.size() ); + glPushMatrix(); + glTranslatef( leftbase(left) + basepair, seq_y, 1.0 ); + glScalef(0.1, 1.0, 1.0); + switch (*seq_itor) { + case 'A': case 'a': + drawLetter(Adata, z); + break; + case 'T': case 't': + drawLetter(Tdata, z); + break; + case 'G': case 'g': + drawLetter(Gdata, z); + break; + case 'C': case 'c': + drawLetter(Cdata, z); + break; + case 'N': case 'n': + drawLetter(Ndata, z); + break; + default: + drawLetter(Xdata, z); + break; + } + glPopMatrix(); + ++seq_itor; + ++basepair; + } +} + +bool operator==(const GlSequence &left, const GlSequence &right) +{ + return ( (left.seq_x == right.seq_x) and + (left.seq_y == right.seq_y) and + (left.seq_z == right.seq_z) and + (left.seq_height == right.seq_height) and + (left.drawColor == right.drawColor)); +} + diff --git a/alg/glsequence.cxx b/alg/glsequence.cxx deleted file mode 100644 index 3aad53a..0000000 --- a/alg/glsequence.cxx +++ /dev/null @@ -1,326 +0,0 @@ -#include "alg/glsequence.h" - -#include -#include -#include -#include -using namespace std; - -GlSequence::GlSequence(const Sequence &s) - : seq(s), - seq_x(0.0), - seq_y(0.0), - seq_z(1.0), - seq_height(12.0), - drawColor(0.0, 0.0, 0.0), - char_pix_per_world_unit(5.0) -{ -} - -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), - drawColor(s.drawColor), - char_pix_per_world_unit(s.char_pix_per_world_unit) -{ -} - -GlSequence &GlSequence::operator=(const GlSequence & s) -{ - if (this != &s) { - const_cast(seq) = s.seq; - seq_x = s.seq_x; - seq_y = s.seq_y; - seq_z = s.seq_z; - seq_height = s.seq_height; - drawColor = s.drawColor; - assert(char_pix_per_world_unit == s.char_pix_per_world_unit); - } - return *this; -} - -const Sequence& GlSequence::sequence() const -{ - return seq; -} - -void GlSequence::setX(GLfloat value) -{ - seq_x = value; -} - -GLfloat GlSequence::x() const -{ - return seq_x; -} - -void GlSequence::setY(GLfloat value) -{ - seq_y = value; -} - -GLfloat GlSequence::y() const -{ - return seq_y; -} - -GLfloat GlSequence::length() const -{ - return seq.size(); -} - -Sequence::size_type GlSequence::leftbase(GLfloat left) const -{ - assert (seq_x == 0); - left = ceil(left); - if (left < seq_x) - return 0; - else - return (Sequence::size_type)left; -} - -Sequence::size_type GlSequence::rightbase(GLfloat right) const -{ - assert (seq_x == 0); - right = floor(right); - if (right > seq.size()) - return seq.size(); - else - return (Sequence::size_type)right; -} - -Sequence::const_iterator GlSequence::sequence_begin() const -{ - return seq.begin(); -} - -Sequence::const_iterator GlSequence::sequence_end() const -{ - return seq.end(); -} - -Sequence::const_iterator -GlSequence::sequence_begin(GLfloat left, GLfloat right) const -{ - // the following code will be wrong when sequences can be slid around - // so make sure we break. - assert (seq_x == 0); - - if ( leftbase(left) > seq.size() or left > right ) - return seq.end(); - else - return seq.begin() + leftbase(left); -} - -Sequence::const_iterator -GlSequence::sequence_end(GLfloat left, GLfloat right) const -{ - // the following code will be wrong when sequences can be slid around - // so make sure we break. - assert (seq_x == 0); - - if ( rightbase(right) > seq.size() or left > right ) - return seq.end(); - else - return seq.begin() + rightbase(right); -} - - -//! set default track draw color -void GlSequence::setColor(Color &c) -{ - drawColor = c; -} - -//! get default track draw color -Color GlSequence::color() -{ - return drawColor; -} - - -int GlSequence::get_viewport_pixel_width() -{ - int viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - return viewport[3]; // grab the viewport width -} - -bool GlSequence::is_sequence_renderable(GLfloat left, - GLfloat right, - int viewport_width) const -{ - // if called with default argument, go get the viewable width - if (viewport_width == -1) { - viewport_width = get_viewport_pixel_width(); - } - GLfloat world_width = right - left; - GLfloat pixels_needed = (char_pix_per_world_unit * world_width); - - // if the number of pixels taken up by rendering the characters - // that'd show up in the current ortho width is less than the window - // width we can actually draw something - return pixels_needed < viewport_width; -} - - -void GlSequence::draw(GLfloat left, GLfloat right) const -{ - if ( not is_sequence_renderable(left, right) ) { - draw_track(left, right); - } else { - draw_sequence(left, right); - } - draw_annotations(left, right); -} - -void GlSequence::draw_box(GLfloat left, GLfloat right, - GLfloat height, GLfloat z) const -{ - GLfloat offset = height/2.0; - GLfloat top = seq_y + offset; - GLfloat bottom = seq_y - offset; - - glBegin(GL_QUADS); - glVertex3f(left, top, z); - glVertex3f(left, bottom, z); - glVertex3f(right, bottom, z); - glVertex3f(right, top, z); - glEnd(); -} -void GlSequence::draw_track(GLfloat left, GLfloat right) const -{ - glColor3fv(drawColor.get()); - // draw main sequence track - draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0); -} - -void GlSequence::draw_annotations(GLfloat left, GLfloat right) const -{ - // draw annotations - glLineWidth(seq_height); - GLfloat annotation_z = seq_z + 1.0; - std::list annots = seq.annotations(); - for (std::list::const_iterator annot_itor = annots.begin(); - annot_itor != annots.end(); - ++annot_itor, ++annotation_z) - { - glColor3f(0.0, 0.5, 0.0); - draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end, - seq_height, annotation_z); - } -} - -const int PT = 1; -const int STROKE = 2; -const int END =3; - -typedef struct charpoint { - GLfloat x, y; - int type; -} CP; - -CP Adata[] = { - {0, -5, PT}, {2.5, 5, PT}, {5, -5, STROKE}, - {0.75, -2, PT}, {4.25, -2, END} -}; - -CP Tdata[] = { - {2.5, -5, PT}, {2.5,5, STROKE}, {0, 5, PT}, {5, 5, END} -}; - -CP Gdata[] = { - {5, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT}, - {2, -5, PT}, {3, -5, PT}, {5, -3, STROKE}, - {2.5, -1, PT}, {5, -1,PT}, {5, -5, END} -}; - -CP Cdata[] = { - {4.9, 3, PT}, {3, 5, PT}, {2, 5, PT}, {0, 3, PT}, {0, -3, PT}, - {2, -5, PT}, {3, -5, PT}, {5, -3, END} -}; - -CP Xdata[] = {{ 0, 5, PT}, {5, -5,STROKE},{0,-5,PT},{5, 5, END}}; -CP Ndata[] = {{ 0, -5, PT}, {0, 5, PT}, {5, -5, PT}, {5, 5, END}}; - -static void drawLetter(CP *l, GLfloat z) -{ - glBegin(GL_LINE_STRIP); - while(1) { - switch (l->type) { - case PT: - glVertex3f(l->x, l->y, z); - break; - case STROKE: - glVertex3f(l->x, l->y, z); - glEnd(); - glBegin(GL_LINE_STRIP); - break; - case END: - glVertex3f(l->x, l->y, z); - glEnd(); - return; - break; - default: - throw runtime_error("data structure failure"); - } - l++; - } -} - -void GlSequence::draw_sequence(GLfloat left, GLfloat right) const -{ - // FIXME: basically this needs to be greater than the number of annotations - const GLfloat z = 30; - glLineWidth(0.3); - glColor3fv(drawColor.get()); - - Sequence::const_iterator seq_itor = sequence_begin(left, right); - Sequence::const_iterator seq_end = sequence_end(left, right); - Sequence::size_type basepair = 0; - - assert(seq_end - seq_itor >= 0); - while(seq_itor != seq_end) - { - assert ( basepair < seq.size() ); - glPushMatrix(); - glTranslatef( leftbase(left) + basepair, seq_y, 1.0 ); - glScalef(0.1, 1.0, 1.0); - switch (*seq_itor) { - case 'A': case 'a': - drawLetter(Adata, z); - break; - case 'T': case 't': - drawLetter(Tdata, z); - break; - case 'G': case 'g': - drawLetter(Gdata, z); - break; - case 'C': case 'c': - drawLetter(Cdata, z); - break; - case 'N': case 'n': - drawLetter(Ndata, z); - break; - default: - drawLetter(Xdata, z); - break; - } - glPopMatrix(); - ++seq_itor; - ++basepair; - } -} - -bool operator==(const GlSequence &left, const GlSequence &right) -{ - return ( (left.seq_x == right.seq_x) and - (left.seq_y == right.seq_y) and - (left.seq_z == right.seq_z) and - (left.seq_height == right.seq_height) and - (left.drawColor == right.drawColor)); -} - diff --git a/alg/glsequence.h b/alg/glsequence.h deleted file mode 100644 index 9ccc4e3..0000000 --- a/alg/glsequence.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _GL_SEQUENCE_H_ -#define _GL_SEQUENCE_H_ - -#include "alg/sequence.hh" -#include "alg/color.h" -#include -//! Manage rendering a mussa sequence track -/*! The idea is this will keep track of the location of where the sequence - * is being rendered, and handle displaying annotations on that track - */ -class GlSequence -{ -public: - GlSequence(const Sequence & s); - GlSequence(const GlSequence & s); - GlSequence &operator=(const GlSequence &s); - - //! draw a track - /*! left and right are the edges of the current viewport - */ - void draw(GLfloat left, GLfloat right) const; - - const Sequence& sequence() const; - //! set our starting x (horizontal) coordinate - void setX(GLfloat); - //! get our starting x (horizontal) coordinate - GLfloat x() const; - //! set our current y (vertical) position - void setY(GLfloat); - //! get our current y (vertical) position - GLfloat y() const; - //! how long is our sequence track? (computed from the sequence) - GLfloat length() const; - - //! return the left (lowest) base index that is fully visible - Sequence::size_type GlSequence::leftbase(GLfloat left) const; - //! return one past rightmost (highest ) base index that is fully visible - /*! done mostly so all the iterator logic continues to work correctly. - */ - Sequence::size_type GlSequence::rightbase(GLfloat right) const; - - //! return iterator to the start of the stored sequence - Sequence::const_iterator sequence_begin() const; - //! return iterator to the end of the stored sequence - Sequence::const_iterator sequence_end() const; - //! provide an iterator to the sequence starting at world coordinate left - Sequence::const_iterator sequence_begin(GLfloat left, GLfloat right) const; - //! provide an iterator to the sequence ending at world coordinate right - Sequence::const_iterator sequence_end(GLfloat left, GLfloat right) const; - - //! set track color - void setColor(Color &); - Color color(); - - //! are we close enough that it would make sense to view the base pairs? - /*! though we don't actually check to see if there's sequence in our - * view, just that there's enough pixels to render something if - * there were. - * \param[in] left the left edge of the viewable region in world coordinates - * \param[in] right the right edge of the viewable region in world - * coordinates - * \param[in] pixel_width allow setting the current viewport pixel width - */ - bool is_sequence_renderable(GLfloat left, - GLfloat right, - int pixel_width=-1) const; - - friend bool operator==(const GlSequence &left, const GlSequence &right); - -protected: - const Sequence& seq; - GLfloat seq_x; - GLfloat seq_y; - GLfloat seq_z; - GLfloat seq_height; - Color drawColor; - const GLfloat char_pix_per_world_unit; - - //! Return the pixel width of the opengl viewport. - static int get_viewport_pixel_width(); - //! draw a from left to right +/- height/2 - void draw_box(GLfloat left, GLfloat right, GLfloat height, GLfloat z) const; - //! draw sequence as a bar - void draw_track(GLfloat, GLfloat) const; - void draw_annotations(GLfloat, GLfloat) const; - //! render a sequence as ATGC - /*! left and right are the current edges of the viewable world - */ - void draw_sequence(GLfloat, GLfloat) const; -}; -#endif diff --git a/alg/glsequence.hpp b/alg/glsequence.hpp new file mode 100644 index 0000000..aeedf47 --- /dev/null +++ b/alg/glsequence.hpp @@ -0,0 +1,91 @@ +#ifndef _GL_SEQUENCE_H_ +#define _GL_SEQUENCE_H_ + +#include "alg/sequence.hpp" +#include "alg/color.hpp" +#include +//! Manage rendering a mussa sequence track +/*! The idea is this will keep track of the location of where the sequence + * is being rendered, and handle displaying annotations on that track + */ +class GlSequence +{ +public: + GlSequence(const Sequence & s); + GlSequence(const GlSequence & s); + GlSequence &operator=(const GlSequence &s); + + //! draw a track + /*! left and right are the edges of the current viewport + */ + void draw(GLfloat left, GLfloat right) const; + + const Sequence& sequence() const; + //! set our starting x (horizontal) coordinate + void setX(GLfloat); + //! get our starting x (horizontal) coordinate + GLfloat x() const; + //! set our current y (vertical) position + void setY(GLfloat); + //! get our current y (vertical) position + GLfloat y() const; + //! how long is our sequence track? (computed from the sequence) + GLfloat length() const; + + //! return the left (lowest) base index that is fully visible + Sequence::size_type GlSequence::leftbase(GLfloat left) const; + //! return one past rightmost (highest ) base index that is fully visible + /*! done mostly so all the iterator logic continues to work correctly. + */ + Sequence::size_type GlSequence::rightbase(GLfloat right) const; + + //! return iterator to the start of the stored sequence + Sequence::const_iterator sequence_begin() const; + //! return iterator to the end of the stored sequence + Sequence::const_iterator sequence_end() const; + //! provide an iterator to the sequence starting at world coordinate left + Sequence::const_iterator sequence_begin(GLfloat left, GLfloat right) const; + //! provide an iterator to the sequence ending at world coordinate right + Sequence::const_iterator sequence_end(GLfloat left, GLfloat right) const; + + //! set track color + void setColor(Color &); + Color color(); + + //! are we close enough that it would make sense to view the base pairs? + /*! though we don't actually check to see if there's sequence in our + * view, just that there's enough pixels to render something if + * there were. + * \param[in] left the left edge of the viewable region in world coordinates + * \param[in] right the right edge of the viewable region in world + * coordinates + * \param[in] pixel_width allow setting the current viewport pixel width + */ + bool is_sequence_renderable(GLfloat left, + GLfloat right, + int pixel_width=-1) const; + + friend bool operator==(const GlSequence &left, const GlSequence &right); + +protected: + const Sequence& seq; + GLfloat seq_x; + GLfloat seq_y; + GLfloat seq_z; + GLfloat seq_height; + Color drawColor; + const GLfloat char_pix_per_world_unit; + + //! Return the pixel width of the opengl viewport. + static int get_viewport_pixel_width(); + //! draw a from left to right +/- height/2 + void draw_box(GLfloat left, GLfloat right, GLfloat height, GLfloat z) const; + //! draw sequence as a bar + void draw_track(GLfloat, GLfloat) const; + void draw_annotations(GLfloat, GLfloat) const; + //! render a sequence as ATGC + /*! left and right are the current edges of the viewable world + */ + void draw_sequence(GLfloat, GLfloat) const; +}; +#endif diff --git a/alg/module.mk b/alg/module.mk index bc52a6b..ba925db 100644 --- a/alg/module.mk +++ b/alg/module.mk @@ -1,22 +1,22 @@ CURDIR := $(BASEDIR)alg/ -SOURCES.cxx := color.cxx \ - conserved_path.cxx \ - flp.cxx \ - flp_seqcomp.cxx \ - mussa_class.cxx \ - nway_paths.cxx \ - nway_entropy.cxx \ - nway_other.cxx \ - sequence.cxx - # mussa_nway_refine.cxx (broken) +SOURCES.cpp := color.cpp \ + conserved_path.cpp \ + flp.cpp \ + flp_seqcomp.cpp \ + mussa.cpp \ + nway_paths.cpp \ + nway_entropy.cpp \ + nway_other.cpp \ + sequence.cpp + # mussa_nway_refine.cpp (broken) -MUSSA_ALG_SRC := $(addprefix $(CURDIR), $(SOURCES.cxx)) -MUSSA_ALG_OBJ := $(MUSSA_ALG_SRC:.cxx=$(OBJEXT)) +MUSSA_ALG_SRC := $(addprefix $(CURDIR), $(SOURCES.cpp)) +MUSSA_ALG_OBJ := $(MUSSA_ALG_SRC:.cpp=$(OBJEXT)) -GLSOURCES.cxx := glsequence.cxx -MUSSA_ALG_GL_SRC := $(addprefix $(CURDIR), $(GLSOURCES.cxx)) -MUSSA_ALG_GL_OBJ := $(MUSSA_ALG_GL_SRC:.cxx=$(OBJEXT)) +GLSOURCES.cpp := glsequence.cpp +MUSSA_ALG_GL_SRC := $(addprefix $(CURDIR), $(GLSOURCES.cpp)) +MUSSA_ALG_GL_OBJ := $(MUSSA_ALG_GL_SRC:.cpp=$(OBJEXT)) SRC += $(MUSSA_ALG_SRC) $(MUSSA_ALG_GL_SRC) CXXFLAGS += diff --git a/alg/mussa.cpp b/alg/mussa.cpp new file mode 100644 index 0000000..47794ef --- /dev/null +++ b/alg/mussa.cpp @@ -0,0 +1,684 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- mussa_class.cc ----------- +// ---------------------------------------- + +#include +#include +#include + +#include "mussa_exceptions.hpp" +#include "alg/mussa.hpp" +#include "alg/flp.hpp" + +using namespace std; + +Mussa::Mussa() +{ + clear(); +} + +// set all parameters to null state +void +Mussa::clear() +{ + analysis_name = ""; + ana_mode = TransitiveNway; + window = 0; + threshold = 0; + soft_thres = 0; + win_append = false; + thres_append = false; + seq_files.clear(); + fasta_indices.clear(); + annot_files.clear(); + sub_seq_starts.clear(); + sub_seq_ends.clear(); +} + +// these 5 simple methods manually set the parameters for doing an analysis +// used so that the gui can take input from user and setup the analysis +// note - still need a set_append(bool, bool) method... +void +Mussa::set_name(string a_name) +{ + analysis_name = a_name; +} + +string Mussa::get_name() +{ + return analysis_name; +} + +int +Mussa::size() const +{ + if (the_seqs.size() > 0) + return the_seqs.size(); + else if (seq_files.size() > 0) + return seq_files.size(); + else + return 0; +} + +void +Mussa::set_window(int a_window) +{ + window = a_window; +} + +int Mussa::get_window() const +{ + return window; +} + +void +Mussa::set_threshold(int a_threshold) +{ + threshold = a_threshold; + //soft_thres = a_threshold; +} + +int Mussa::get_threshold() const +{ + return threshold; +} + +void +Mussa::set_soft_thres(int sft_thres) +{ + soft_thres = sft_thres; +} + +void +Mussa::set_analysis_mode(enum analysis_modes new_ana_mode) +{ + ana_mode = new_ana_mode; +} + +enum Mussa::analysis_modes Mussa::get_analysis_mode() const +{ + return ana_mode; +} + +string Mussa::get_analysis_mode_name() const +{ + switch (ana_mode) + { + case TransitiveNway: + return string("Transitive"); + break; + case RadialNway: + return string("Radial"); + break; + case EntropyNway: + return string("Entropy"); + break; + case RecursiveNway: + return string("[deprecated] Recursive"); + break; + default: + throw runtime_error("invalid analysis mode type"); + break; + } +} + +const NwayPaths& Mussa::paths() const +{ + return the_paths; +} + +// takes a string and sets it as the next seq +void +Mussa::add_a_seq(string a_seq) +{ + Sequence aSeq; + + aSeq.set_seq(a_seq); + the_seqs.push_back(aSeq); +} + + +// sets info for just 1 seq at a time +void +Mussa::set_seq_info(string seq_file, string annot_file, int fa_i, int a_start, int the_end) +{ + seq_files.push_back(seq_file); + fasta_indices.push_back(fa_i); + annot_files.push_back(annot_file); + sub_seq_starts.push_back(a_start); + sub_seq_ends.push_back(the_end); +} + +const vector& +Mussa::sequences() const +{ + return the_seqs; +} + +void +Mussa::load_mupa_file(string para_file_path) +{ + ifstream para_file; + string file_data_line; + string param, value, annot_file; + int split_index, fasta_index; + int sub_seq_start, sub_seq_end; + bool seq_params, did_seq; + string err_msg; + bool parsing_path; + string::size_type new_index, dir_index; + + // initialize values + clear(); + + para_file.open(para_file_path.c_str(), ios::in); + + // if file was opened, read the parameter values + if (para_file) + { + // need to find the path to the .mupa file + parsing_path = true; + dir_index = 0; + while (parsing_path) + { + new_index = (para_file_path.substr(dir_index)).find("/"); + if (new_index != string::npos) + dir_index += new_index + 1; + else + parsing_path = false; + } + + file_path_base = para_file_path.substr(0,dir_index); + + // setup loop by getting file's first line + getline(para_file,file_data_line); + split_index = file_data_line.find(" "); + param = file_data_line.substr(0,split_index); + value = file_data_line.substr(split_index+1); + + while (!para_file.eof()) + { + did_seq = false; + if (param == "ANA_NAME") + analysis_name = value; + else if (param == "APPEND_WIN") + win_append = true; + else if (param == "APPEND_THRES") + thres_append = true; + else if (param == "SEQUENCE_NUM") + ; // ignore sequence_num now + else if (param == "WINDOW") + window = atoi(value.c_str()); + else if (param == "THRESHOLD") + threshold = atoi(value.c_str()); + else if (param == "SEQUENCE") + { + seq_files.push_back(file_path_base + value); + //cout << "seq_file_name " << seq_files.back() << endl; + fasta_index = 1; + annot_file = ""; + sub_seq_start = 0; + sub_seq_end = 0; + seq_params = true; + + while ((!para_file.eof()) && seq_params) + { + getline(para_file,file_data_line); + split_index = file_data_line.find(" "); + param = file_data_line.substr(0,split_index); + value = file_data_line.substr(split_index+1); + + if (param == "FASTA_INDEX") + fasta_index = atoi(value.c_str()); + else if (param == "ANNOTATION") + annot_file = file_path_base + value; + else if (param == "SEQ_START") + sub_seq_start = atoi(value.c_str()); + else if (param == "SEQ_END") + { + sub_seq_end = atoi(value.c_str()); + } + //ignore empty lines or that start with '#' + else if ((param == "") || (param == "#")) {} + else seq_params = false; + } + + fasta_indices.push_back(fasta_index); + annot_files.push_back(annot_file); + sub_seq_starts.push_back(sub_seq_start); + sub_seq_ends.push_back(sub_seq_end); + did_seq = true; + } + //ignore empty lines or that start with '#' + else if ((param == "") || (param == "#")) {} + else + { + clog << "Illegal/misplaced mussa parameter in file\n"; + clog << param << "\n"; + } + + if (!did_seq) + { + getline(para_file,file_data_line); + split_index = file_data_line.find(" "); + param = file_data_line.substr(0,split_index); + value = file_data_line.substr(split_index+1); + did_seq = false; + } + } + + para_file.close(); + + soft_thres = threshold; + //cout << "nway mupa: analysis_name = " << analysis_name + // << " window = " << window + // << " threshold = " << threshold << endl; + } + // no file was loaded, signal error + else + { + throw mussa_load_error("Config File: " + para_file_path + " not found"); + } +} + + +void +Mussa::analyze(int w, int t, enum Mussa::analysis_modes the_ana_mode, double new_ent_thres) +{ + time_t t1, t2, begin, end; + double seqloadtime, seqcomptime, nwaytime, savetime, totaltime; + + begin = time(NULL); + + ana_mode = the_ana_mode; + ent_thres = new_ent_thres; + if (w > 0) + window = w; + if (t > 0) + { + threshold = t; + soft_thres = t; + } + + t1 = time(NULL); + load_sequence_data(); + + if (the_seqs.size() < 2) { + throw mussa_analysis_error("you need to have at least 2 sequences to " + "do an analysis."); + } + //cout << "nway ana: seq_num = " << the_seqs.size() << endl; + + t2 = time(NULL); + seqloadtime = difftime(t2, t1); + + t1 = time(NULL); + seqcomp(); + t2 = time(NULL); + seqcomptime = difftime(t2, t1); + + + t1 = time(NULL); + the_paths.setup(window, threshold); + nway(); + t2 = time(NULL); + nwaytime = difftime(t2, t1); + + t1 = time(NULL); + save(); + t2 = time(NULL); + savetime = difftime(t2, t1); + + end = time(NULL); + totaltime = difftime(end, begin); + + + //cout << "seqload\tseqcomp\tnway\tsave\ttotal\n"; + //cout << seqloadtime << "\t"; + //cout << seqcomptime << "\t"; + //cout << nwaytime << "\t"; + //cout << savetime << "\t"; + //cout << totaltime << "\n"; +} + + +void +Mussa::load_sequence_data() +{ + list::iterator seq_files_i, annot_files_i; + list::iterator fasta_indices_i, seq_starts_i, seq_ends_i; + Sequence aSeq; + string err_msg; + + + seq_files_i = seq_files.begin(); + fasta_indices_i = fasta_indices.begin(); + annot_files_i = annot_files.begin(); + seq_starts_i = sub_seq_starts.begin(); + seq_ends_i = sub_seq_ends.begin(); + + while ( (seq_files_i != seq_files.end()) && (err_msg == "") ) + /* it should be guarenteed that each of the following exist + should I bother checking, and how to deal with if not true... + && + (fasta_indices_i != fasta_indices.end()) && + (annot_files_i != annot_files.end()) && + (seq_starts_i != sub_seq_starts.end()) && + (seq_ends_i != sub_seq_ends.end()) ) + */ + { + aSeq.load_fasta(*seq_files_i, *fasta_indices_i,*seq_starts_i, *seq_ends_i); + if (annot_files_i->size() > 0) + aSeq.load_annot(*annot_files_i, *seq_starts_i, *seq_ends_i); + + the_seqs.push_back(aSeq); + //cout << aSeq.get_header() << endl; + //cout << aSeq.get_seq() << endl; + aSeq.clear(); + ++seq_files_i; // advance all the iterators + ++fasta_indices_i; + ++annot_files_i; + ++seq_starts_i; + ++seq_ends_i; + } +} + + +void +Mussa::seqcomp() +{ + vector seq_lens; + vector empty_FLP_vector; + FLPs dummy_comp; + string save_file_string; + + empty_FLP_vector.clear(); + for(vector::size_type i = 0; i < the_seqs.size(); i++) + { + all_comps.push_back(empty_FLP_vector); + for(vector::size_type i2 = 0; i2 < the_seqs.size(); i2++) + all_comps[i].push_back(dummy_comp); + } + for(vector::size_type i = 0; i < the_seqs.size(); i++) + seq_lens.push_back(the_seqs[i].size()); + + for(vector::size_type i = 0; i < the_seqs.size(); i++) + for(vector::size_type i2 = i+1; i2 < the_seqs.size(); i2++) + { + //cout << "seqcomping: " << i << " v. " << i2 << endl; + all_comps[i][i2].setup(window, threshold); + all_comps[i][i2].seqcomp(the_seqs[i].get_seq(), the_seqs[i2].get_seq(), false); + all_comps[i][i2].seqcomp(the_seqs[i].get_seq(),the_seqs[i2].rev_comp(),true); + } +} + +void +Mussa::nway() +{ + vector some_Seqs; + + the_paths.set_soft_thres(soft_thres); + + if (ana_mode == TransitiveNway) { + the_paths.trans_path_search(all_comps); + } + else if (ana_mode == RadialNway) { + the_paths.radiate_path_search(all_comps); + } + else if (ana_mode == EntropyNway) + { + //unlike other methods, entropy needs to look at the sequence at this stage + some_Seqs.clear(); + for(vector::size_type i = 0; i < the_seqs.size(); i++) + { + some_Seqs.push_back(the_seqs[i].get_seq()); + } + + the_paths.setup_ent(ent_thres, some_Seqs); // ent analysis extra setup + the_paths.entropy_path_search(all_comps); + } + + // old recursive transitive analysis function + else if (ana_mode == RecursiveNway) + the_paths.find_paths_r(all_comps); + + the_paths.simple_refine(); +} + +void +Mussa::save() +{ + string save_name, save_path, create_dir_cmd, flp_filepath; + fstream save_file; + ostringstream append_info; + int dir_create_status; + + + // not sure why, but gotta close file each time since can't pass file streams + + save_name = analysis_name; + + // gotta do bit with adding win & thres if to be appended + if (win_append) + { + append_info.str(""); + append_info << "_w" << window; + save_name += append_info.str(); + } + + if (thres_append) + { + append_info.str(""); + append_info << "_t" << threshold; + save_name += append_info.str(); + } + +//#include + // ******* use appropriate for os ------- 1 of 4 + // the additions for osX make it more sane where it saves the analysis + // will come up with a cleaner sol'n later... + create_dir_cmd = "mkdir " + save_name; //linux + //create_dir_cmd = "mkdir " + file_path_base + save_name; //osX + + dir_create_status = system( (const char*) create_dir_cmd.c_str()); + //cout << "action: " << dir_create_status << endl; + + // save sequence and annots to a special mussa file + + // ******** use appropriate for OS ---------- 2 of 4 + save_path = save_name + "/" + save_name + ".museq"; //linux + //save_path = file_path_base + save_name + "/" + save_name + ".museq"; //osX + + save_file.open(save_path.c_str(), ios::out); + save_file << "" << endl; + //save_file.close(); + + for(vector::size_type i = 0; i < the_seqs.size(); i++) + { + the_seqs[i].save(save_file); + } + + //save_file.open(save_path.c_str(), ios::app); + save_file << "" << endl; + save_file.close(); + + // save nway paths to its mussa save file + + // ******** use appropriate for OS -------- 3 of 4 + save_path = save_name + "/" + save_name + ".muway"; //linux + //save_path = file_path_base + save_name + "/" + save_name + ".muway"; //os X + the_paths.save(save_path); + + for(vector::size_type i = 0; i < the_seqs.size(); i++) + for(vector::size_type i2 = i+1; i2 < the_seqs.size(); i2++) + { + append_info.str(""); + append_info << "_sp_" << i << "v" << i2; + // ******** use appropriate for OS --------- 4 of 4 + //linux + save_path = save_name + "/" + save_name + append_info.str() + ".flp"; + //osX + //save_path = file_path_base + save_name + "/" + save_name + append_info.str() + ".flp"; + all_comps[i][i2].save(save_path); + } +} + +void +Mussa::save_muway(string save_path) +{ + the_paths.save(save_path); +} + +void +Mussa::load(string ana_file) +{ + int i, i2; + string::size_type start_index, end_index; + string file_path_base, a_file_path, ana_path; + bool parsing_path; + Sequence tmp_seq; + string err_msg; + ostringstream append_info; + vector empty_FLP_vector; + FLPs dummy_comp; + + //cout << "ana_file name " << ana_file << endl; + ana_path = ana_file; + parsing_path = true; + end_index = ana_path.size()-1; + if (ana_path[end_index] == '/') { + --end_index; + } + start_index = ana_path.rfind('/', end_index); + if (start_index == string::npos) { + // no / to be found + start_index = 0; + } else { + // skip the / we found + ++start_index; + } + analysis_name = ana_path.substr(start_index, end_index-start_index+1); + //cout << " ana_name " << analysis_name << endl; + file_path_base = ana_path.substr(0, start_index) + analysis_name + + "/" + analysis_name; + a_file_path = file_path_base + ".muway"; + //cout << " loading museq: " << a_file_path << endl; + the_paths.load(a_file_path); + + int seq_num = the_paths.sequence_count(); + + a_file_path = file_path_base + ".museq"; + + // this is a bit of a hack due to C++ not acting like it should with files + for (i = 1; i <= seq_num; i++) + { + tmp_seq.clear(); + //cout << "mussa_class: loading museq frag... " << a_file_path << endl; + tmp_seq.load_museq(a_file_path, i); + the_seqs.push_back(tmp_seq); + } + + empty_FLP_vector.clear(); + for(i = 0; i < seq_num; i++) + { + all_comps.push_back(empty_FLP_vector); + for(i2 = 0; i2 < seq_num; i2++) + all_comps[i].push_back(dummy_comp); + } + + for(i = 0; i < seq_num; i++) + { + for(i2 = i+1; i2 < seq_num; i2++) + { + append_info.str(""); + append_info << "_sp_" << i << "v" << i2; + //cout << append_info.str() << endl; + a_file_path = file_path_base + append_info.str() + ".flp"; + all_comps[i][i2].load(a_file_path); + //cout << "real size = " << all_comps[i][i2].size() << endl; + } + } +} + + +void +Mussa::save_old() +{ + fstream save_file; + + save_file.open(analysis_name.c_str(), ios::out); + + for(vector::size_type i = 0; i < the_seqs.size(); i++) + save_file << the_seqs[i].get_seq() << endl; + + save_file << window << endl; + save_file.close(); + //note more complex eventually since analysis_name may need to have + //window size, threshold and other stuff to modify it... + the_paths.save_old(analysis_name); +} + + +void +Mussa::load_old(char * load_file_path, int s_num) +{ + fstream save_file; + string file_data_line; + int i, space_split_i, comma_split_i; + vector loaded_path; + string node_pair, node; + Sequence a_seq; + + int seq_num = s_num; + the_paths.setup(0, 0); + save_file.open(load_file_path, ios::in); + + // currently loads old mussa format + + // get sequences + for(i = 0; i < seq_num; i++) + { + getline(save_file, file_data_line); + a_seq.set_seq(file_data_line); + the_seqs.push_back(a_seq); + } + + // get window size + getline(save_file, file_data_line); + window = atoi(file_data_line.c_str()); + // get paths + + while (!save_file.eof()) + { + loaded_path.clear(); + getline(save_file, file_data_line); + if (file_data_line != "") + for(i = 0; i < seq_num; i++) + { + space_split_i = file_data_line.find(" "); + node_pair = file_data_line.substr(0,space_split_i); + //cout << "np= " << node_pair; + comma_split_i = node_pair.find(","); + node = node_pair.substr(comma_split_i+1); + //cout << "n= " << node << " "; + loaded_path.push_back(atoi (node.c_str())); + file_data_line = file_data_line.substr(space_split_i+1); + } + //cout << endl; + // FIXME: do we have any information about what the threshold should be? + the_paths.add_path(0, loaded_path); + } + save_file.close(); + + //the_paths.save("tmp.save"); +} diff --git a/alg/mussa.hpp b/alg/mussa.hpp new file mode 100644 index 0000000..805b09d --- /dev/null +++ b/alg/mussa.hpp @@ -0,0 +1,129 @@ +#ifndef _MUSSA_CLASS_H_ +#define _MUSSA_CLASS_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- mussa_class.hh ----------- +// ---------------------------------------- + +#include +#include +#include + +#include "alg/nway_paths.hpp" +#include "alg/sequence.hpp" + +std::string int_to_str(int an_int); + +class Mussa +{ + friend class ConnWindow; + public: + enum analysis_modes { TransitiveNway, RadialNway, EntropyNway, + RecursiveNway }; + + Mussa(); + + void save(); + void save_muway(std::string save_path); + //! load a saved analysis directory + void load(std::string ana_path); + + //! clear parameters and initialize data lists + void clear(); + + // set parameters from a file - 'mupa' ~ mussa parameters + void load_mupa_file(std::string para_file_path); + + // set parameters individually (eg from user input into gui classes) + //! set analysis name + void set_name(std::string a_name); + //! return name for this analysis + std::string get_name(); + + //! return number of sequences in this analyzis + /*! this returns either the_seqs.size() or seq_files.size() + * depending on which has data loaded in + * (silly delayed loading of sequence data) + */ + int size() const; + //! set number of bases for this window size + void set_window(int a_window); + //! get number of bases for the sliding window + int get_window() const; + //! set number of bases that must match for a window to be saved + void set_threshold(int a_threshold); + //! get number of bases that must match for a window to be saved + int get_threshold() const; + void set_soft_thres(int sft_thres); + + void set_analysis_mode(enum analysis_modes new_ana_mode); + enum analysis_modes get_analysis_mode() const; + //! return a string name for an analysis mode + std::string get_analysis_mode_name() const; + + //! return the refined paths found by the nway analysis. + const NwayPaths& paths() const; + + //! run seqcomp and the nway filtering algorithm. + /*!analyze will run seqcomp and then the nway algorithm + * on whatever sequences have been loaded into this mussa instance. + * w & t are for command line override functionality, set to 0 to ignore + * \throws mussa_analysis_error + */ + void analyze(int w=0, int t=0, + enum analysis_modes ana_mode=TransitiveNway, + double ent_thres=0.0); + /*! Run the nway filtering algorithm, + * this might be used when changing the soft threshhold? + */ + void nway(); + + //! appends a string sequence to the list of the_seqs + void add_a_seq(std::string a_seq); + // sets info to load a seq and annotations from a fasta file + void set_seq_info(std::string seq_file, std::string annot_file, + int fa_i, int a_start, int the_end); + //! allow examining the sequences we have loaded + const std::vector& sequences() const; + + // deprecated - support bridge for python version of mussa + // these save & load from the old file format + void save_old(); + void load_old(char * load_file_path, int s_num); + + private: + // Private variables + // parameters needed for a mussa analysis + std::string analysis_name; + std::string file_path_base; + int window, threshold, soft_thres; + enum analysis_modes ana_mode; + double ent_thres; + std::list seq_files, annot_files; + std::list fasta_indices, sub_seq_starts, sub_seq_ends; + bool win_override, thres_override; + bool win_append, thres_append; + + //! sequence data + std::vector the_seqs; + //! the seqcomp data + std::vector > all_comps; + //! N-way data, ie the mussa results + NwayPaths the_paths; + + // Private methods + //! loads sequence and annotations from fasta and annotation file + void load_sequence_data(); + void seqcomp(); + +}; +#endif diff --git a/alg/mussa_class.cxx b/alg/mussa_class.cxx deleted file mode 100644 index 389ef1b..0000000 --- a/alg/mussa_class.cxx +++ /dev/null @@ -1,683 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- mussa_class.cc ----------- -// ---------------------------------------- - -#include "mussa_exceptions.hh" -#include "mussa_class.hh" -#include "flp.hh" -#include -#include -#include - -using namespace std; - -Mussa::Mussa() -{ - clear(); -} - -// set all parameters to null state -void -Mussa::clear() -{ - analysis_name = ""; - ana_mode = TransitiveNway; - window = 0; - threshold = 0; - soft_thres = 0; - win_append = false; - thres_append = false; - seq_files.clear(); - fasta_indices.clear(); - annot_files.clear(); - sub_seq_starts.clear(); - sub_seq_ends.clear(); -} - -// these 5 simple methods manually set the parameters for doing an analysis -// used so that the gui can take input from user and setup the analysis -// note - still need a set_append(bool, bool) method... -void -Mussa::set_name(string a_name) -{ - analysis_name = a_name; -} - -string Mussa::get_name() -{ - return analysis_name; -} - -int -Mussa::size() const -{ - if (the_seqs.size() > 0) - return the_seqs.size(); - else if (seq_files.size() > 0) - return seq_files.size(); - else - return 0; -} - -void -Mussa::set_window(int a_window) -{ - window = a_window; -} - -int Mussa::get_window() const -{ - return window; -} - -void -Mussa::set_threshold(int a_threshold) -{ - threshold = a_threshold; - //soft_thres = a_threshold; -} - -int Mussa::get_threshold() const -{ - return threshold; -} - -void -Mussa::set_soft_thres(int sft_thres) -{ - soft_thres = sft_thres; -} - -void -Mussa::set_analysis_mode(enum analysis_modes new_ana_mode) -{ - ana_mode = new_ana_mode; -} - -enum Mussa::analysis_modes Mussa::get_analysis_mode() const -{ - return ana_mode; -} - -string Mussa::get_analysis_mode_name() const -{ - switch (ana_mode) - { - case TransitiveNway: - return string("Transitive"); - break; - case RadialNway: - return string("Radial"); - break; - case EntropyNway: - return string("Entropy"); - break; - case RecursiveNway: - return string("[deprecated] Recursive"); - break; - default: - throw runtime_error("invalid analysis mode type"); - break; - } -} - -const NwayPaths& Mussa::paths() const -{ - return the_paths; -} - -// takes a string and sets it as the next seq -void -Mussa::add_a_seq(string a_seq) -{ - Sequence aSeq; - - aSeq.set_seq(a_seq); - the_seqs.push_back(aSeq); -} - - -// sets info for just 1 seq at a time -void -Mussa::set_seq_info(string seq_file, string annot_file, int fa_i, int a_start, int the_end) -{ - seq_files.push_back(seq_file); - fasta_indices.push_back(fa_i); - annot_files.push_back(annot_file); - sub_seq_starts.push_back(a_start); - sub_seq_ends.push_back(the_end); -} - -const vector& -Mussa::sequences() const -{ - return the_seqs; -} - -void -Mussa::load_mupa_file(string para_file_path) -{ - ifstream para_file; - string file_data_line; - string param, value, annot_file; - int split_index, fasta_index; - int sub_seq_start, sub_seq_end; - bool seq_params, did_seq; - string err_msg; - bool parsing_path; - string::size_type new_index, dir_index; - - // initialize values - clear(); - - para_file.open(para_file_path.c_str(), ios::in); - - // if file was opened, read the parameter values - if (para_file) - { - // need to find the path to the .mupa file - parsing_path = true; - dir_index = 0; - while (parsing_path) - { - new_index = (para_file_path.substr(dir_index)).find("/"); - if (new_index != string::npos) - dir_index += new_index + 1; - else - parsing_path = false; - } - - file_path_base = para_file_path.substr(0,dir_index); - - // setup loop by getting file's first line - getline(para_file,file_data_line); - split_index = file_data_line.find(" "); - param = file_data_line.substr(0,split_index); - value = file_data_line.substr(split_index+1); - - while (!para_file.eof()) - { - did_seq = false; - if (param == "ANA_NAME") - analysis_name = value; - else if (param == "APPEND_WIN") - win_append = true; - else if (param == "APPEND_THRES") - thres_append = true; - else if (param == "SEQUENCE_NUM") - ; // ignore sequence_num now - else if (param == "WINDOW") - window = atoi(value.c_str()); - else if (param == "THRESHOLD") - threshold = atoi(value.c_str()); - else if (param == "SEQUENCE") - { - seq_files.push_back(file_path_base + value); - //cout << "seq_file_name " << seq_files.back() << endl; - fasta_index = 1; - annot_file = ""; - sub_seq_start = 0; - sub_seq_end = 0; - seq_params = true; - - while ((!para_file.eof()) && seq_params) - { - getline(para_file,file_data_line); - split_index = file_data_line.find(" "); - param = file_data_line.substr(0,split_index); - value = file_data_line.substr(split_index+1); - - if (param == "FASTA_INDEX") - fasta_index = atoi(value.c_str()); - else if (param == "ANNOTATION") - annot_file = file_path_base + value; - else if (param == "SEQ_START") - sub_seq_start = atoi(value.c_str()); - else if (param == "SEQ_END") - { - sub_seq_end = atoi(value.c_str()); - } - //ignore empty lines or that start with '#' - else if ((param == "") || (param == "#")) {} - else seq_params = false; - } - - fasta_indices.push_back(fasta_index); - annot_files.push_back(annot_file); - sub_seq_starts.push_back(sub_seq_start); - sub_seq_ends.push_back(sub_seq_end); - did_seq = true; - } - //ignore empty lines or that start with '#' - else if ((param == "") || (param == "#")) {} - else - { - clog << "Illegal/misplaced mussa parameter in file\n"; - clog << param << "\n"; - } - - if (!did_seq) - { - getline(para_file,file_data_line); - split_index = file_data_line.find(" "); - param = file_data_line.substr(0,split_index); - value = file_data_line.substr(split_index+1); - did_seq = false; - } - } - - para_file.close(); - - soft_thres = threshold; - //cout << "nway mupa: analysis_name = " << analysis_name - // << " window = " << window - // << " threshold = " << threshold << endl; - } - // no file was loaded, signal error - else - { - throw mussa_load_error("Config File: " + para_file_path + " not found"); - } -} - - -void -Mussa::analyze(int w, int t, enum Mussa::analysis_modes the_ana_mode, double new_ent_thres) -{ - time_t t1, t2, begin, end; - double seqloadtime, seqcomptime, nwaytime, savetime, totaltime; - - begin = time(NULL); - - ana_mode = the_ana_mode; - ent_thres = new_ent_thres; - if (w > 0) - window = w; - if (t > 0) - { - threshold = t; - soft_thres = t; - } - - t1 = time(NULL); - load_sequence_data(); - - if (the_seqs.size() < 2) { - throw mussa_analysis_error("you need to have at least 2 sequences to " - "do an analysis."); - } - //cout << "nway ana: seq_num = " << the_seqs.size() << endl; - - t2 = time(NULL); - seqloadtime = difftime(t2, t1); - - t1 = time(NULL); - seqcomp(); - t2 = time(NULL); - seqcomptime = difftime(t2, t1); - - - t1 = time(NULL); - the_paths.setup(window, threshold); - nway(); - t2 = time(NULL); - nwaytime = difftime(t2, t1); - - t1 = time(NULL); - save(); - t2 = time(NULL); - savetime = difftime(t2, t1); - - end = time(NULL); - totaltime = difftime(end, begin); - - - //cout << "seqload\tseqcomp\tnway\tsave\ttotal\n"; - //cout << seqloadtime << "\t"; - //cout << seqcomptime << "\t"; - //cout << nwaytime << "\t"; - //cout << savetime << "\t"; - //cout << totaltime << "\n"; -} - - -void -Mussa::load_sequence_data() -{ - list::iterator seq_files_i, annot_files_i; - list::iterator fasta_indices_i, seq_starts_i, seq_ends_i; - Sequence aSeq; - string err_msg; - - - seq_files_i = seq_files.begin(); - fasta_indices_i = fasta_indices.begin(); - annot_files_i = annot_files.begin(); - seq_starts_i = sub_seq_starts.begin(); - seq_ends_i = sub_seq_ends.begin(); - - while ( (seq_files_i != seq_files.end()) && (err_msg == "") ) - /* it should be guarenteed that each of the following exist - should I bother checking, and how to deal with if not true... - && - (fasta_indices_i != fasta_indices.end()) && - (annot_files_i != annot_files.end()) && - (seq_starts_i != sub_seq_starts.end()) && - (seq_ends_i != sub_seq_ends.end()) ) - */ - { - aSeq.load_fasta(*seq_files_i, *fasta_indices_i,*seq_starts_i, *seq_ends_i); - if (annot_files_i->size() > 0) - aSeq.load_annot(*annot_files_i, *seq_starts_i, *seq_ends_i); - - the_seqs.push_back(aSeq); - //cout << aSeq.get_header() << endl; - //cout << aSeq.get_seq() << endl; - aSeq.clear(); - ++seq_files_i; // advance all the iterators - ++fasta_indices_i; - ++annot_files_i; - ++seq_starts_i; - ++seq_ends_i; - } -} - - -void -Mussa::seqcomp() -{ - vector seq_lens; - vector empty_FLP_vector; - FLPs dummy_comp; - string save_file_string; - - empty_FLP_vector.clear(); - for(vector::size_type i = 0; i < the_seqs.size(); i++) - { - all_comps.push_back(empty_FLP_vector); - for(vector::size_type i2 = 0; i2 < the_seqs.size(); i2++) - all_comps[i].push_back(dummy_comp); - } - for(vector::size_type i = 0; i < the_seqs.size(); i++) - seq_lens.push_back(the_seqs[i].size()); - - for(vector::size_type i = 0; i < the_seqs.size(); i++) - for(vector::size_type i2 = i+1; i2 < the_seqs.size(); i2++) - { - //cout << "seqcomping: " << i << " v. " << i2 << endl; - all_comps[i][i2].setup(window, threshold); - all_comps[i][i2].seqcomp(the_seqs[i].get_seq(), the_seqs[i2].get_seq(), false); - all_comps[i][i2].seqcomp(the_seqs[i].get_seq(),the_seqs[i2].rev_comp(),true); - } -} - -void -Mussa::nway() -{ - vector some_Seqs; - - the_paths.set_soft_thres(soft_thres); - - if (ana_mode == TransitiveNway) { - the_paths.trans_path_search(all_comps); - } - else if (ana_mode == RadialNway) { - the_paths.radiate_path_search(all_comps); - } - else if (ana_mode == EntropyNway) - { - //unlike other methods, entropy needs to look at the sequence at this stage - some_Seqs.clear(); - for(vector::size_type i = 0; i < the_seqs.size(); i++) - { - some_Seqs.push_back(the_seqs[i].get_seq()); - } - - the_paths.setup_ent(ent_thres, some_Seqs); // ent analysis extra setup - the_paths.entropy_path_search(all_comps); - } - - // old recursive transitive analysis function - else if (ana_mode == RecursiveNway) - the_paths.find_paths_r(all_comps); - - the_paths.simple_refine(); -} - -void -Mussa::save() -{ - string save_name, save_path, create_dir_cmd, flp_filepath; - fstream save_file; - ostringstream append_info; - int dir_create_status; - - - // not sure why, but gotta close file each time since can't pass file streams - - save_name = analysis_name; - - // gotta do bit with adding win & thres if to be appended - if (win_append) - { - append_info.str(""); - append_info << "_w" << window; - save_name += append_info.str(); - } - - if (thres_append) - { - append_info.str(""); - append_info << "_t" << threshold; - save_name += append_info.str(); - } - -//#include - // ******* use appropriate for os ------- 1 of 4 - // the additions for osX make it more sane where it saves the analysis - // will come up with a cleaner sol'n later... - create_dir_cmd = "mkdir " + save_name; //linux - //create_dir_cmd = "mkdir " + file_path_base + save_name; //osX - - dir_create_status = system( (const char*) create_dir_cmd.c_str()); - //cout << "action: " << dir_create_status << endl; - - // save sequence and annots to a special mussa file - - // ******** use appropriate for OS ---------- 2 of 4 - save_path = save_name + "/" + save_name + ".museq"; //linux - //save_path = file_path_base + save_name + "/" + save_name + ".museq"; //osX - - save_file.open(save_path.c_str(), ios::out); - save_file << "" << endl; - //save_file.close(); - - for(vector::size_type i = 0; i < the_seqs.size(); i++) - { - the_seqs[i].save(save_file); - } - - //save_file.open(save_path.c_str(), ios::app); - save_file << "" << endl; - save_file.close(); - - // save nway paths to its mussa save file - - // ******** use appropriate for OS -------- 3 of 4 - save_path = save_name + "/" + save_name + ".muway"; //linux - //save_path = file_path_base + save_name + "/" + save_name + ".muway"; //os X - the_paths.save(save_path); - - for(vector::size_type i = 0; i < the_seqs.size(); i++) - for(vector::size_type i2 = i+1; i2 < the_seqs.size(); i2++) - { - append_info.str(""); - append_info << "_sp_" << i << "v" << i2; - // ******** use appropriate for OS --------- 4 of 4 - //linux - save_path = save_name + "/" + save_name + append_info.str() + ".flp"; - //osX - //save_path = file_path_base + save_name + "/" + save_name + append_info.str() + ".flp"; - all_comps[i][i2].save(save_path); - } -} - -void -Mussa::save_muway(string save_path) -{ - the_paths.save(save_path); -} - -void -Mussa::load(string ana_file) -{ - int i, i2; - string::size_type start_index, end_index; - string file_path_base, a_file_path, ana_path; - bool parsing_path; - Sequence tmp_seq; - string err_msg; - ostringstream append_info; - vector empty_FLP_vector; - FLPs dummy_comp; - - //cout << "ana_file name " << ana_file << endl; - ana_path = ana_file; - parsing_path = true; - end_index = ana_path.size()-1; - if (ana_path[end_index] == '/') { - --end_index; - } - start_index = ana_path.rfind('/', end_index); - if (start_index == string::npos) { - // no / to be found - start_index = 0; - } else { - // skip the / we found - ++start_index; - } - analysis_name = ana_path.substr(start_index, end_index-start_index+1); - //cout << " ana_name " << analysis_name << endl; - file_path_base = ana_path.substr(0, start_index) + analysis_name - + "/" + analysis_name; - a_file_path = file_path_base + ".muway"; - //cout << " loading museq: " << a_file_path << endl; - the_paths.load(a_file_path); - - int seq_num = the_paths.sequence_count(); - - a_file_path = file_path_base + ".museq"; - - // this is a bit of a hack due to C++ not acting like it should with files - for (i = 1; i <= seq_num; i++) - { - tmp_seq.clear(); - //cout << "mussa_class: loading museq frag... " << a_file_path << endl; - tmp_seq.load_museq(a_file_path, i); - the_seqs.push_back(tmp_seq); - } - - empty_FLP_vector.clear(); - for(i = 0; i < seq_num; i++) - { - all_comps.push_back(empty_FLP_vector); - for(i2 = 0; i2 < seq_num; i2++) - all_comps[i].push_back(dummy_comp); - } - - for(i = 0; i < seq_num; i++) - { - for(i2 = i+1; i2 < seq_num; i2++) - { - append_info.str(""); - append_info << "_sp_" << i << "v" << i2; - //cout << append_info.str() << endl; - a_file_path = file_path_base + append_info.str() + ".flp"; - all_comps[i][i2].load(a_file_path); - //cout << "real size = " << all_comps[i][i2].size() << endl; - } - } -} - - -void -Mussa::save_old() -{ - fstream save_file; - - save_file.open(analysis_name.c_str(), ios::out); - - for(vector::size_type i = 0; i < the_seqs.size(); i++) - save_file << the_seqs[i].get_seq() << endl; - - save_file << window << endl; - save_file.close(); - //note more complex eventually since analysis_name may need to have - //window size, threshold and other stuff to modify it... - the_paths.save_old(analysis_name); -} - - -void -Mussa::load_old(char * load_file_path, int s_num) -{ - fstream save_file; - string file_data_line; - int i, space_split_i, comma_split_i; - vector loaded_path; - string node_pair, node; - Sequence a_seq; - - int seq_num = s_num; - the_paths.setup(0, 0); - save_file.open(load_file_path, ios::in); - - // currently loads old mussa format - - // get sequences - for(i = 0; i < seq_num; i++) - { - getline(save_file, file_data_line); - a_seq.set_seq(file_data_line); - the_seqs.push_back(a_seq); - } - - // get window size - getline(save_file, file_data_line); - window = atoi(file_data_line.c_str()); - // get paths - - while (!save_file.eof()) - { - loaded_path.clear(); - getline(save_file, file_data_line); - if (file_data_line != "") - for(i = 0; i < seq_num; i++) - { - space_split_i = file_data_line.find(" "); - node_pair = file_data_line.substr(0,space_split_i); - //cout << "np= " << node_pair; - comma_split_i = node_pair.find(","); - node = node_pair.substr(comma_split_i+1); - //cout << "n= " << node << " "; - loaded_path.push_back(atoi (node.c_str())); - file_data_line = file_data_line.substr(space_split_i+1); - } - //cout << endl; - // FIXME: do we have any information about what the threshold should be? - the_paths.add_path(0, loaded_path); - } - save_file.close(); - - //the_paths.save("tmp.save"); -} diff --git a/alg/mussa_class.hh b/alg/mussa_class.hh deleted file mode 100644 index f0ed884..0000000 --- a/alg/mussa_class.hh +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef _MUSSA_CLASS_H_ -#define _MUSSA_CLASS_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- mussa_class.hh ----------- -// ---------------------------------------- - -#include -#include -#include - -#include "nway_paths.hh" -#include "sequence.hh" - -std::string int_to_str(int an_int); - -class Mussa -{ - friend class ConnWindow; - public: - enum analysis_modes { TransitiveNway, RadialNway, EntropyNway, - RecursiveNway }; - - Mussa(); - - void save(); - void save_muway(std::string save_path); - //! load a saved analysis directory - void load(std::string ana_path); - - //! clear parameters and initialize data lists - void clear(); - - // set parameters from a file - 'mupa' ~ mussa parameters - void load_mupa_file(std::string para_file_path); - - // set parameters individually (eg from user input into gui classes) - //! set analysis name - void set_name(std::string a_name); - //! return name for this analysis - std::string get_name(); - - //! return number of sequences in this analyzis - /*! this returns either the_seqs.size() or seq_files.size() - * depending on which has data loaded in - * (silly delayed loading of sequence data) - */ - int size() const; - //! set number of bases for this window size - void set_window(int a_window); - //! get number of bases for the sliding window - int get_window() const; - //! set number of bases that must match for a window to be saved - void set_threshold(int a_threshold); - //! get number of bases that must match for a window to be saved - int get_threshold() const; - void set_soft_thres(int sft_thres); - - void set_analysis_mode(enum analysis_modes new_ana_mode); - enum analysis_modes get_analysis_mode() const; - //! return a string name for an analysis mode - std::string get_analysis_mode_name() const; - - //! return the refined paths found by the nway analysis. - const NwayPaths& paths() const; - - //! run seqcomp and the nway filtering algorithm. - /*!analyze will run seqcomp and then the nway algorithm - * on whatever sequences have been loaded into this mussa instance. - * w & t are for command line override functionality, set to 0 to ignore - * \throws mussa_analysis_error - */ - void analyze(int w=0, int t=0, - enum analysis_modes ana_mode=TransitiveNway, - double ent_thres=0.0); - /*! Run the nway filtering algorithm, - * this might be used when changing the soft threshhold? - */ - void nway(); - - //! appends a string sequence to the list of the_seqs - void add_a_seq(std::string a_seq); - // sets info to load a seq and annotations from a fasta file - void set_seq_info(std::string seq_file, std::string annot_file, - int fa_i, int a_start, int the_end); - //! allow examining the sequences we have loaded - const std::vector& sequences() const; - - // deprecated - support bridge for python version of mussa - // these save & load from the old file format - void save_old(); - void load_old(char * load_file_path, int s_num); - - private: - // Private variables - // parameters needed for a mussa analysis - std::string analysis_name; - std::string file_path_base; - int window, threshold, soft_thres; - enum analysis_modes ana_mode; - double ent_thres; - std::list seq_files, annot_files; - std::list fasta_indices, sub_seq_starts, sub_seq_ends; - bool win_override, thres_override; - bool win_append, thres_append; - - //! sequence data - std::vector the_seqs; - //! the seqcomp data - std::vector > all_comps; - //! N-way data, ie the mussa results - NwayPaths the_paths; - - // Private methods - //! loads sequence and annotations from fasta and annotation file - void load_sequence_data(); - void seqcomp(); - -}; -#endif diff --git a/alg/nway_entropy.cpp b/alg/nway_entropy.cpp new file mode 100644 index 0000000..13a42c5 --- /dev/null +++ b/alg/nway_entropy.cpp @@ -0,0 +1,262 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + + +#include "alg/nway_paths.hpp" +#include +#include +using namespace std; + +// vars that will be availble to entropy function when in its nway class +//vector c_sequences; +//int window = 5, seq_num; + + +void +NwayPaths::setup_ent(double new_entropy_thres, vector some_seqs) +{ + ent_thres = new_entropy_thres; + + c_sequences.clear(); + for (vector::size_type i = 0; i < some_seqs.size(); i++) + c_sequences.push_back((char *)some_seqs[i].c_str()); +} + + +double +NwayPaths::path_entropy(vector path) +{ + int bp_occurences[5]; + double bp_prob, frac_ent, avg_entropy; + vector entropies; + int i, i2; + int window = win_size; + + for(i = 0; i < window; i++) // loop thru all bp positions + { + for(i2 = 0; i2 < 5; i2++) // clear old occurences + bp_occurences[i2] = 0; + + //loop thru all sequences at pos i + for(vector::size_type seq_i = 0; seq_i != path.size(); seq_i++) + { + if (path[seq_i] > -1) + { + switch (c_sequences[seq_i][i+path[seq_i]]) + { + case 'A': + ++bp_occurences[0]; + break; + case 'T': + ++bp_occurences[1]; + break; + case 'G': + ++bp_occurences[2]; + break; + case 'C': + ++bp_occurences[3]; + break; + case 'N': + ++bp_occurences[4]; + break; + default: + cout << "error, nonAGCTN on seq: " << seq_i << " at index: "; + cout << i+path[seq_i] << endl; + } + } + else + { + switch (c_sequences[seq_i][-1 * (i + path[seq_i] - window + 1) ]) + { + case 'A': + ++bp_occurences[1]; + break; + case 'T': + ++bp_occurences[0]; + break; + case 'G': + ++bp_occurences[3]; + break; + case 'C': + ++bp_occurences[2]; + break; + case 'N': + ++bp_occurences[4]; + break; + default: + cout << "error, nonAGCTN on seq: " << seq_i << " at index: "; + cout << (i + path[seq_i] - window + 1) << endl; + } + } + } + + entropies.push_back(0.000); + for(i2 = 0; i2 < 5; i2++) //calculate entropies + { + bp_prob = (double) bp_occurences[i2] / (double) path.size(); + //cout << bp_prob << "::"; + if (bp_prob == 0.0000) + frac_ent = 0.0000; + else + frac_ent = bp_prob * ( log10(bp_prob) / log10(2.0) ); + //cout << frac_ent << " "; + entropies[i] += frac_ent; + } + //cout << endl; + } + + avg_entropy = 0; + for(i = 0; i < window; i++) + { + avg_entropy += entropies[i]; + //cout << entropies[i] << endl; + } + + avg_entropy = -1.00 * (avg_entropy / (double) window); + //cout << "average entropy: " << avg_entropy << endl; + return avg_entropy; +} + +void +NwayPaths::entropy_path_search(vector > all_comparisons) +{ + vector path; + double avg_entropy; + int win_i, sp_depth, window_num; + unsigned int sp_i; + bool some_matches, still_paths, not_advanced; + list new_nodes, trans_check_nodes; + vector > all_matches; + vector::iterator> sp_nodes, sp_nodes_end; + list::iterator debug_i; + + + pathz.clear(); + window_num = all_comparisons[0][1].size(); + cout << window_num << endl; // just a sanity check + + sp_nodes.reserve(all_comparisons.size()); + sp_nodes_end.reserve(all_comparisons.size()); + + // loop thru all windows in first species + for (win_i = 0; win_i < window_num; win_i++) + { + // first we see if the first seq has matches to all other seqs at this win + some_matches = true; + sp_i = 1; + all_matches.clear(); + while ( (sp_i < all_comparisons.size()) && (some_matches) ) + { + new_nodes.clear(); + new_nodes = all_comparisons[0][sp_i].match_locations(win_i); + if (new_nodes.empty()) + some_matches = false; + + all_matches.push_back(new_nodes); + sp_i++; + } + //cout << "fee\n"; + + // if 1st seq does match to all others, make all possible paths + // out of all these matches + if (some_matches) + { + sp_nodes.clear(); + sp_nodes_end.clear(); + // set each species list of matches to beginning + for (sp_i = 0; sp_i < all_comparisons.size()-1; sp_i++) + { + sp_nodes.push_back(all_matches[sp_i].begin()); + sp_nodes_end.push_back(all_matches[sp_i].end()); + } + + still_paths = true; + //cout << "fie\n"; + while (still_paths) + { + // add path that each species iterator is pointing to + path.clear(); + path.push_back(win_i); + + //cout << win_i; + for (sp_i = 0; sp_i < all_comparisons.size()-1; sp_i++) + { + //cout << ", " << *(sp_nodes[sp_i]); + path.push_back(*(sp_nodes[sp_i])); + } + //cout << endl; + + // check entropy <--------------------------------------------------- + avg_entropy = path_entropy(path); + if (avg_entropy <= ent_thres) + pathz.push_back(ConservedPath(avg_entropy, path)); + + // now advance the right iterator + not_advanced = true; + sp_depth = all_comparisons.size()- 2; // this roves up & down species list + while ( (not_advanced) && (sp_depth != -1) ) + { + //cout << "foe\n"; + //cout << sp_depth << ".." << *(sp_nodes[sp_depth]) << endl; + (sp_nodes[sp_depth])++; // advance iter at current depth + //cout << sp_depth << ".." << *(sp_nodes[sp_depth]) << endl; + + // if we reached the end of the list, reset iter & go up one depth + if (sp_nodes[sp_depth] == sp_nodes_end[sp_depth]) + { + //cout << "fum\n"; + sp_nodes[sp_depth] = all_matches[sp_depth].begin(); + sp_depth--; + //cout << "depth = " << sp_depth << endl; + } + else + not_advanced = false; + } + + if (sp_depth == -1) // jumped up to first species, all paths searched + still_paths = false; + else // otherwise just reset to max depth and continue + sp_depth = all_comparisons.size() - 2; + } + } + } +} + + +//initial coding testing +/* +int main(int argc, char **argv) +{ + vector sequences; + vector i_starts; + double avg_entropy; + int seq_i; + + sequences.clear(); + sequences.push_back("AAAAA"); + sequences.push_back("AAAAT"); + sequences.push_back("AATTG"); + sequences.push_back("ATTGC"); + + seq_num = 4; + + c_sequences.clear(); + i_starts.clear(); + for(seq_i = 0; seq_i < seq_num; seq_i++) //loop thru all sequences at pos i + { + c_sequences.push_back((char *)sequences[seq_i].c_str()); + i_starts.push_back(0); + } + + avg_entropy = Window_Entropy(i_starts); + + cout << "average entropy: " << avg_entropy << endl; +} +*/ diff --git a/alg/nway_entropy.cxx b/alg/nway_entropy.cxx deleted file mode 100644 index b8dcc7f..0000000 --- a/alg/nway_entropy.cxx +++ /dev/null @@ -1,262 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - - -#include "nway_paths.hh" -#include -#include -using namespace std; - -// vars that will be availble to entropy function when in its nway class -//vector c_sequences; -//int window = 5, seq_num; - - -void -NwayPaths::setup_ent(double new_entropy_thres, vector some_seqs) -{ - ent_thres = new_entropy_thres; - - c_sequences.clear(); - for (vector::size_type i = 0; i < some_seqs.size(); i++) - c_sequences.push_back((char *)some_seqs[i].c_str()); -} - - -double -NwayPaths::path_entropy(vector path) -{ - int bp_occurences[5]; - double bp_prob, frac_ent, avg_entropy; - vector entropies; - int i, i2; - int window = win_size; - - for(i = 0; i < window; i++) // loop thru all bp positions - { - for(i2 = 0; i2 < 5; i2++) // clear old occurences - bp_occurences[i2] = 0; - - //loop thru all sequences at pos i - for(vector::size_type seq_i = 0; seq_i != path.size(); seq_i++) - { - if (path[seq_i] > -1) - { - switch (c_sequences[seq_i][i+path[seq_i]]) - { - case 'A': - ++bp_occurences[0]; - break; - case 'T': - ++bp_occurences[1]; - break; - case 'G': - ++bp_occurences[2]; - break; - case 'C': - ++bp_occurences[3]; - break; - case 'N': - ++bp_occurences[4]; - break; - default: - cout << "error, nonAGCTN on seq: " << seq_i << " at index: "; - cout << i+path[seq_i] << endl; - } - } - else - { - switch (c_sequences[seq_i][-1 * (i + path[seq_i] - window + 1) ]) - { - case 'A': - ++bp_occurences[1]; - break; - case 'T': - ++bp_occurences[0]; - break; - case 'G': - ++bp_occurences[3]; - break; - case 'C': - ++bp_occurences[2]; - break; - case 'N': - ++bp_occurences[4]; - break; - default: - cout << "error, nonAGCTN on seq: " << seq_i << " at index: "; - cout << (i + path[seq_i] - window + 1) << endl; - } - } - } - - entropies.push_back(0.000); - for(i2 = 0; i2 < 5; i2++) //calculate entropies - { - bp_prob = (double) bp_occurences[i2] / (double) path.size(); - //cout << bp_prob << "::"; - if (bp_prob == 0.0000) - frac_ent = 0.0000; - else - frac_ent = bp_prob * ( log10(bp_prob) / log10(2.0) ); - //cout << frac_ent << " "; - entropies[i] += frac_ent; - } - //cout << endl; - } - - avg_entropy = 0; - for(i = 0; i < window; i++) - { - avg_entropy += entropies[i]; - //cout << entropies[i] << endl; - } - - avg_entropy = -1.00 * (avg_entropy / (double) window); - //cout << "average entropy: " << avg_entropy << endl; - return avg_entropy; -} - -void -NwayPaths::entropy_path_search(vector > all_comparisons) -{ - vector path; - double avg_entropy; - int win_i, sp_depth, window_num; - unsigned int sp_i; - bool some_matches, still_paths, not_advanced; - list new_nodes, trans_check_nodes; - vector > all_matches; - vector::iterator> sp_nodes, sp_nodes_end; - list::iterator debug_i; - - - pathz.clear(); - window_num = all_comparisons[0][1].size(); - cout << window_num << endl; // just a sanity check - - sp_nodes.reserve(all_comparisons.size()); - sp_nodes_end.reserve(all_comparisons.size()); - - // loop thru all windows in first species - for (win_i = 0; win_i < window_num; win_i++) - { - // first we see if the first seq has matches to all other seqs at this win - some_matches = true; - sp_i = 1; - all_matches.clear(); - while ( (sp_i < all_comparisons.size()) && (some_matches) ) - { - new_nodes.clear(); - new_nodes = all_comparisons[0][sp_i].match_locations(win_i); - if (new_nodes.empty()) - some_matches = false; - - all_matches.push_back(new_nodes); - sp_i++; - } - //cout << "fee\n"; - - // if 1st seq does match to all others, make all possible paths - // out of all these matches - if (some_matches) - { - sp_nodes.clear(); - sp_nodes_end.clear(); - // set each species list of matches to beginning - for (sp_i = 0; sp_i < all_comparisons.size()-1; sp_i++) - { - sp_nodes.push_back(all_matches[sp_i].begin()); - sp_nodes_end.push_back(all_matches[sp_i].end()); - } - - still_paths = true; - //cout << "fie\n"; - while (still_paths) - { - // add path that each species iterator is pointing to - path.clear(); - path.push_back(win_i); - - //cout << win_i; - for (sp_i = 0; sp_i < all_comparisons.size()-1; sp_i++) - { - //cout << ", " << *(sp_nodes[sp_i]); - path.push_back(*(sp_nodes[sp_i])); - } - //cout << endl; - - // check entropy <--------------------------------------------------- - avg_entropy = path_entropy(path); - if (avg_entropy <= ent_thres) - pathz.push_back(ConservedPath(avg_entropy, path)); - - // now advance the right iterator - not_advanced = true; - sp_depth = all_comparisons.size()- 2; // this roves up & down species list - while ( (not_advanced) && (sp_depth != -1) ) - { - //cout << "foe\n"; - //cout << sp_depth << ".." << *(sp_nodes[sp_depth]) << endl; - (sp_nodes[sp_depth])++; // advance iter at current depth - //cout << sp_depth << ".." << *(sp_nodes[sp_depth]) << endl; - - // if we reached the end of the list, reset iter & go up one depth - if (sp_nodes[sp_depth] == sp_nodes_end[sp_depth]) - { - //cout << "fum\n"; - sp_nodes[sp_depth] = all_matches[sp_depth].begin(); - sp_depth--; - //cout << "depth = " << sp_depth << endl; - } - else - not_advanced = false; - } - - if (sp_depth == -1) // jumped up to first species, all paths searched - still_paths = false; - else // otherwise just reset to max depth and continue - sp_depth = all_comparisons.size() - 2; - } - } - } -} - - -//initial coding testing -/* -int main(int argc, char **argv) -{ - vector sequences; - vector i_starts; - double avg_entropy; - int seq_i; - - sequences.clear(); - sequences.push_back("AAAAA"); - sequences.push_back("AAAAT"); - sequences.push_back("AATTG"); - sequences.push_back("ATTGC"); - - seq_num = 4; - - c_sequences.clear(); - i_starts.clear(); - for(seq_i = 0; seq_i < seq_num; seq_i++) //loop thru all sequences at pos i - { - c_sequences.push_back((char *)sequences[seq_i].c_str()); - i_starts.push_back(0); - } - - avg_entropy = Window_Entropy(i_starts); - - cout << "average entropy: " << avg_entropy << endl; -} -*/ diff --git a/alg/nway_other.cpp b/alg/nway_other.cpp new file mode 100644 index 0000000..5e23936 --- /dev/null +++ b/alg/nway_other.cpp @@ -0,0 +1,263 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "nway_paths.hpp" +#include + +using namespace std; + +//! dump the matches for a particular window +void dump_matches_win(int win_i, vector > all_matches) +{ + cout << "" << endl; + for (vector >::const_iterator sp_i = all_matches.begin(); + sp_i != all_matches.end(); + ++sp_i) + { + for(list::const_iterator debug_i = sp_i->begin(); + debug_i != sp_i->end(); + ++debug_i) + { + cout << *debug_i << " "; + } + cout << endl; + } + cout << ""<< endl; +} + +/*! (re-)initialize all_matches with the list of matches between + * species (sequence) 0 and all the other sequences + * \return true if there were matches against all the species, false otherwise + */ +bool +make_all_seq_win_matches(const vector >& all_comparisons, + vector >& all_matches, + int window_index, int soft_threshold) +{ + list new_nodes; + bool some_matches=true; + all_matches.clear(); + for(vector::size_type sp_i=1; + (sp_i < all_comparisons.size()) && (some_matches); sp_i++ ) + { + new_nodes.clear(); + // --thres + //new_nodes = all_comparisons[0][sp_i].matches(win_i); + new_nodes = all_comparisons[0][sp_i].thres_matches(window_index, + soft_threshold); + if (new_nodes.empty()) + some_matches = false; + else + all_matches.push_back(new_nodes); + } + // we only record matches from seq 0 to another seq, so we should have seq-1 + // matches if there were enough matches. + // if there weren't enough we should have even fewer matches + // (this complicated boolean hides all the logic in one assert call, + // hopefully allowing the assert to be optimized away) + assert(( some_matches && (all_matches.size() == (all_comparisons.size()-1))) + ||(!some_matches && (all_matches.size() < (all_comparisons.size()-1)))); + return some_matches; +} + +/*! reset all the speces begin and end iterators to the start and end + * of the match pairs stored in all_matches + */ +void reset_species_iterators(vector >& all_matches, + vector::iterator>& sp_itor_begin, + vector::iterator>& sp_itor_end) +{ + sp_itor_begin.clear(); + sp_itor_end.clear(); + // set each species list of matches to beginning + for (list::size_type sp_i = 0; sp_i < all_matches.size(); sp_i++) + { + sp_itor_begin.push_back(all_matches[sp_i].begin()); + sp_itor_end.push_back(all_matches[sp_i].end()); + } +} + +/*! Set the path vector to be the list of window positions from + * the current locations of our species beginning iterators + */ +void set_path_to_cur_sp_itor_track( + vector& path, + int base_window_index, + const vector::iterator>& sp_itor_begin) +{ + // add path that each species iterator is pointing to + path.clear(); + path.push_back(base_window_index); + + for (vector::size_type sp_i = 0; sp_i < sp_itor_begin.size(); sp_i++) + { + path.push_back(*(sp_itor_begin[sp_i])); + } +} + +/*! advance the species iterator track + * if we were able to advance the track return true + * if we weren't able to advance, we've looked at every track so return false + */ +bool advance_sp_itor_track(vector::iterator>& sp_itor_begin, + const vector::iterator>& sp_itor_end, + vector >& all_matches) +{ + bool not_advanced = true; + int sp_depth = all_matches.size() - 1; // this roves up & down species list + while ( (not_advanced) && (sp_depth != -1) ) + { + //cout << sp_depth << ".." << *(sp_itor_begin[sp_depth]) << endl; + (sp_itor_begin[sp_depth])++; // advance iter at current depth + //cout << sp_depth << ".." << *(sp_itor_begin[sp_depth]) << endl; + + // if we reached the end of the list, reset iter & go up one depth + if (sp_itor_begin[sp_depth] == sp_itor_end[sp_depth]) + { + sp_itor_begin[sp_depth] = all_matches[sp_depth].begin(); + sp_depth--; + //cout << "depth = " << sp_depth << endl; + } + else + not_advanced = false; + } + if (sp_depth == -1) // jumped up to first species, all paths searched + return false; + else + return true; +} + +void +NwayPaths::radiate_path_search(vector > all_comparisons) +{ + vector path; + int win_i, window_num; + bool still_paths; + vector > all_matches; + vector::iterator> sp_itor_begin(all_comparisons.size()); + vector::iterator> sp_itor_end(all_comparisons.size()); + + pathz.clear(); + window_num = all_comparisons[0][1].size(); + + // loop thru all windows in first species + for (win_i = 0; win_i < window_num; win_i++) + { + // if 1st seq does have match to all the others, then make all possible + // paths out of all these matches (in all_matches) + if(make_all_seq_win_matches(all_comparisons, all_matches, win_i, soft_thres)) + { + //debug dump_matches_win(win_i, all_matches); + reset_species_iterators(all_matches, sp_itor_begin, sp_itor_end); + + still_paths = true; + while (still_paths) + { + // add path that each species iterator is pointing to + set_path_to_cur_sp_itor_track(path, win_i, sp_itor_begin); + + pathz.push_back(ConservedPath(soft_thres, path)); + + // now advance the right iterator + still_paths = advance_sp_itor_track(sp_itor_begin, + sp_itor_end, + all_matches); + } + } + } +} + +bool is_transitive_path(const vector& path, + const vector >& all_comparisons, + const int soft_threshold) +{ + int cur_node; + list trans_check_nodes; + + for (vector::size_type sp_depth=1; sp_depth != path.size()-1; ++sp_depth) + { + cur_node = path[sp_depth]; + for(vector::size_type i = sp_depth+1; i != path.size()-1; i++) + { + // --thres + //trans_check_nodes = all_comparisons[sp_depth][i].matches(cur_node); + trans_check_nodes = + all_comparisons[sp_depth][i].thres_matches(cur_node, soft_threshold); + + if ( (trans_check_nodes.end() == find(trans_check_nodes.begin(), + trans_check_nodes.end(), + path[i]) ) + &&(trans_check_nodes.end() == find(trans_check_nodes.begin(), + trans_check_nodes.end(), + path[i] * -1) ) ) + return false; + } + } + return true; +} + +void +NwayPaths::trans_path_search(vector > all_comparisons) +{ + if (all_comparisons.size() == 0 or all_comparisons[0].size() == 0) + return; + vector path; + int win_i, window_num; + bool still_paths; + list trans_check_nodes; + vector > all_matches; + vector::iterator> sp_itor_begin(all_comparisons.size()); + vector::iterator> sp_itor_end(all_comparisons.size()); + + + //cout << "trans: softhres = " << soft_thres; + //cout << ", window = " << win_size << ", "; + + pathz.clear(); + window_num = all_comparisons[0][1].size(); + //cout << "window number = " << window_num << endl; // just a sanity check + //cout << "trans: comparison size= " << all_comparisons.size() << endl; + // loop thru all windows in first species + for (win_i = 0; win_i != window_num; win_i++) + { + // if 1st seq has a match to all the others for this window, + // then make all possible paths out of all these matches (in all_matches) + if(make_all_seq_win_matches(all_comparisons, all_matches, win_i, soft_thres)) + { + //debug? //dump_matches_win(win_i, all_matches); + reset_species_iterators(all_matches, sp_itor_begin, sp_itor_end); + still_paths = true; + while (still_paths) + { + // initialize a path to however far each species iterator has been + // advanced. + set_path_to_cur_sp_itor_track(path, win_i, sp_itor_begin); + + // if the path is transitive, save the path + if (is_transitive_path(path, all_comparisons, soft_thres)) + pathz.push_back(ConservedPath(soft_thres, path)); + + // now advance the right iterator + still_paths = advance_sp_itor_track(sp_itor_begin, + sp_itor_end, + all_matches); + } + } + } + //clog << "all_cmp=" << all_comparisons.size(); + //if (pathz.begin() != pathz.end()) + // clog << " path_size=" << pathz.begin()->size(); + //else + // clog << " path empty"; + //clog << endl; + assert ( (pathz.begin() == pathz.end()) + || (pathz.begin()->size() == 0) + || (all_comparisons.size() == pathz.begin()->size())); +} diff --git a/alg/nway_other.cxx b/alg/nway_other.cxx deleted file mode 100644 index cc00036..0000000 --- a/alg/nway_other.cxx +++ /dev/null @@ -1,263 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "nway_paths.hh" -#include - -using namespace std; - -//! dump the matches for a particular window -void dump_matches_win(int win_i, vector > all_matches) -{ - cout << "" << endl; - for (vector >::const_iterator sp_i = all_matches.begin(); - sp_i != all_matches.end(); - ++sp_i) - { - for(list::const_iterator debug_i = sp_i->begin(); - debug_i != sp_i->end(); - ++debug_i) - { - cout << *debug_i << " "; - } - cout << endl; - } - cout << ""<< endl; -} - -/*! (re-)initialize all_matches with the list of matches between - * species (sequence) 0 and all the other sequences - * \return true if there were matches against all the species, false otherwise - */ -bool -make_all_seq_win_matches(const vector >& all_comparisons, - vector >& all_matches, - int window_index, int soft_threshold) -{ - list new_nodes; - bool some_matches=true; - all_matches.clear(); - for(vector::size_type sp_i=1; - (sp_i < all_comparisons.size()) && (some_matches); sp_i++ ) - { - new_nodes.clear(); - // --thres - //new_nodes = all_comparisons[0][sp_i].matches(win_i); - new_nodes = all_comparisons[0][sp_i].thres_matches(window_index, - soft_threshold); - if (new_nodes.empty()) - some_matches = false; - else - all_matches.push_back(new_nodes); - } - // we only record matches from seq 0 to another seq, so we should have seq-1 - // matches if there were enough matches. - // if there weren't enough we should have even fewer matches - // (this complicated boolean hides all the logic in one assert call, - // hopefully allowing the assert to be optimized away) - assert(( some_matches && (all_matches.size() == (all_comparisons.size()-1))) - ||(!some_matches && (all_matches.size() < (all_comparisons.size()-1)))); - return some_matches; -} - -/*! reset all the speces begin and end iterators to the start and end - * of the match pairs stored in all_matches - */ -void reset_species_iterators(vector >& all_matches, - vector::iterator>& sp_itor_begin, - vector::iterator>& sp_itor_end) -{ - sp_itor_begin.clear(); - sp_itor_end.clear(); - // set each species list of matches to beginning - for (list::size_type sp_i = 0; sp_i < all_matches.size(); sp_i++) - { - sp_itor_begin.push_back(all_matches[sp_i].begin()); - sp_itor_end.push_back(all_matches[sp_i].end()); - } -} - -/*! Set the path vector to be the list of window positions from - * the current locations of our species beginning iterators - */ -void set_path_to_cur_sp_itor_track( - vector& path, - int base_window_index, - const vector::iterator>& sp_itor_begin) -{ - // add path that each species iterator is pointing to - path.clear(); - path.push_back(base_window_index); - - for (vector::size_type sp_i = 0; sp_i < sp_itor_begin.size(); sp_i++) - { - path.push_back(*(sp_itor_begin[sp_i])); - } -} - -/*! advance the species iterator track - * if we were able to advance the track return true - * if we weren't able to advance, we've looked at every track so return false - */ -bool advance_sp_itor_track(vector::iterator>& sp_itor_begin, - const vector::iterator>& sp_itor_end, - vector >& all_matches) -{ - bool not_advanced = true; - int sp_depth = all_matches.size() - 1; // this roves up & down species list - while ( (not_advanced) && (sp_depth != -1) ) - { - //cout << sp_depth << ".." << *(sp_itor_begin[sp_depth]) << endl; - (sp_itor_begin[sp_depth])++; // advance iter at current depth - //cout << sp_depth << ".." << *(sp_itor_begin[sp_depth]) << endl; - - // if we reached the end of the list, reset iter & go up one depth - if (sp_itor_begin[sp_depth] == sp_itor_end[sp_depth]) - { - sp_itor_begin[sp_depth] = all_matches[sp_depth].begin(); - sp_depth--; - //cout << "depth = " << sp_depth << endl; - } - else - not_advanced = false; - } - if (sp_depth == -1) // jumped up to first species, all paths searched - return false; - else - return true; -} - -void -NwayPaths::radiate_path_search(vector > all_comparisons) -{ - vector path; - int win_i, window_num; - bool still_paths; - vector > all_matches; - vector::iterator> sp_itor_begin(all_comparisons.size()); - vector::iterator> sp_itor_end(all_comparisons.size()); - - pathz.clear(); - window_num = all_comparisons[0][1].size(); - - // loop thru all windows in first species - for (win_i = 0; win_i < window_num; win_i++) - { - // if 1st seq does have match to all the others, then make all possible - // paths out of all these matches (in all_matches) - if(make_all_seq_win_matches(all_comparisons, all_matches, win_i, soft_thres)) - { - //debug dump_matches_win(win_i, all_matches); - reset_species_iterators(all_matches, sp_itor_begin, sp_itor_end); - - still_paths = true; - while (still_paths) - { - // add path that each species iterator is pointing to - set_path_to_cur_sp_itor_track(path, win_i, sp_itor_begin); - - pathz.push_back(ConservedPath(soft_thres, path)); - - // now advance the right iterator - still_paths = advance_sp_itor_track(sp_itor_begin, - sp_itor_end, - all_matches); - } - } - } -} - -bool is_transitive_path(const vector& path, - const vector >& all_comparisons, - const int soft_threshold) -{ - int cur_node; - list trans_check_nodes; - - for (vector::size_type sp_depth=1; sp_depth != path.size()-1; ++sp_depth) - { - cur_node = path[sp_depth]; - for(vector::size_type i = sp_depth+1; i != path.size()-1; i++) - { - // --thres - //trans_check_nodes = all_comparisons[sp_depth][i].matches(cur_node); - trans_check_nodes = - all_comparisons[sp_depth][i].thres_matches(cur_node, soft_threshold); - - if ( (trans_check_nodes.end() == find(trans_check_nodes.begin(), - trans_check_nodes.end(), - path[i]) ) - &&(trans_check_nodes.end() == find(trans_check_nodes.begin(), - trans_check_nodes.end(), - path[i] * -1) ) ) - return false; - } - } - return true; -} - -void -NwayPaths::trans_path_search(vector > all_comparisons) -{ - if (all_comparisons.size() == 0 or all_comparisons[0].size() == 0) - return; - vector path; - int win_i, window_num; - bool still_paths; - list trans_check_nodes; - vector > all_matches; - vector::iterator> sp_itor_begin(all_comparisons.size()); - vector::iterator> sp_itor_end(all_comparisons.size()); - - - //cout << "trans: softhres = " << soft_thres; - //cout << ", window = " << win_size << ", "; - - pathz.clear(); - window_num = all_comparisons[0][1].size(); - //cout << "window number = " << window_num << endl; // just a sanity check - //cout << "trans: comparison size= " << all_comparisons.size() << endl; - // loop thru all windows in first species - for (win_i = 0; win_i != window_num; win_i++) - { - // if 1st seq has a match to all the others for this window, - // then make all possible paths out of all these matches (in all_matches) - if(make_all_seq_win_matches(all_comparisons, all_matches, win_i, soft_thres)) - { - //debug? //dump_matches_win(win_i, all_matches); - reset_species_iterators(all_matches, sp_itor_begin, sp_itor_end); - still_paths = true; - while (still_paths) - { - // initialize a path to however far each species iterator has been - // advanced. - set_path_to_cur_sp_itor_track(path, win_i, sp_itor_begin); - - // if the path is transitive, save the path - if (is_transitive_path(path, all_comparisons, soft_thres)) - pathz.push_back(ConservedPath(soft_thres, path)); - - // now advance the right iterator - still_paths = advance_sp_itor_track(sp_itor_begin, - sp_itor_end, - all_matches); - } - } - } - //clog << "all_cmp=" << all_comparisons.size(); - //if (pathz.begin() != pathz.end()) - // clog << " path_size=" << pathz.begin()->size(); - //else - // clog << " path empty"; - //clog << endl; - assert ( (pathz.begin() == pathz.end()) - || (pathz.begin()->size() == 0) - || (all_comparisons.size() == pathz.begin()->size())); -} diff --git a/alg/nway_paths.cpp b/alg/nway_paths.cpp new file mode 100644 index 0000000..b82cff6 --- /dev/null +++ b/alg/nway_paths.cpp @@ -0,0 +1,441 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- mussa_nway.cc ----------- +// ---------------------------------------- + +#include "alg/nway_paths.hpp" +#include "alg/conserved_path.hpp" +#include "mussa_exceptions.hpp" + +#include +#include +#include + +using namespace std; + +NwayPaths::NwayPaths() +{ +} + +void +NwayPaths::setup(int w, int t) +{ + threshold = t; + soft_thres = threshold; + win_size = w; + pathz.clear(); + + //cout << "nway: thres = " << threshold + // << ", soft threo = " << soft_thres << endl; +} + +void +NwayPaths::set_soft_thres(int sft_thres) +{ + soft_thres = sft_thres; +} + + +// dumbly goes thru and combines path windows exactly adjacent (ie + 1 index) +// doesn't deal with interleaved adjacency +void +NwayPaths::simple_refine() +{ + // ext_path remembers the first window set in an extending path + ExtendedConservedPath ext_path, new_path; + list::iterator cur_path, next_path; + list::iterator pathz_i; + int win_ext_len = 0; + bool extending, end = false; + + refined_pathz.clear(); + + //cout << "path number is: " << pathz.size() << endl; + pathz_i = pathz.begin(); + + // only try to extend when pathz isn't empty. + if (pathz_i != pathz.end()) + { + ext_path = ExtendedConservedPath( win_size, *pathz_i); + + while(pathz_i != pathz.end()) + { + // keep track of current path and advance to next path + cur_path = pathz_i; + ++pathz_i; + if (pathz_i == pathz.end()) + end = true; + else + next_path = pathz_i; + + if (not end) + { + // if node for each seq is equal to the next node+1 then for all + // sequences then we are extending + extending = cur_path->nextTo(*next_path); + } + else + extending = false; + + if (extending) + { + win_ext_len++; + } + else + { + // add the extend window length as first element and add as refined + // now that we have the path to extend save it + new_path = ext_path; + new_path.extend(win_ext_len); + refined_pathz.push_back(new_path); + // reset stuff + win_ext_len = 0; + ext_path = ExtendedConservedPath( win_size, *next_path); + } + } + } + //cout << "r_path number is: " << refined_pathz.size() << endl; +} + + +void +NwayPaths::add_path(int threshold, vector& loaded_path) +{ + pathz.push_back(ConservedPath(threshold, loaded_path)); +} + +void +NwayPaths::add_path(ConservedPath loaded_path) +{ + pathz.push_back(loaded_path); +} + + +void +NwayPaths::save(string save_file_path) +{ + fstream save_file; + list::iterator path_i, paths_end; + + save_file.open(save_file_path.c_str(), ios::out); + + save_file << "\n"; + + path_i = refined_pathz.begin(); + paths_end = refined_pathz.end(); + //path_i = pathz.begin(); + //paths_end = pathz.end(); + while (path_i != paths_end) + { + ExtendedConservedPath& a_path = *path_i; + //cout << a_path.size() << endl; + //first entry is the window length of the windows in the path + save_file << a_path.window_size << ":"; + for(size_t i = 0; i != sequence_count(); ++i) + { + save_file << a_path[i]; + if (i != sequence_count()) + save_file << ","; + } + save_file << endl; + ++path_i; + } + + save_file << "\n"; + save_file.close(); +} + + +size_t +NwayPaths::sequence_count() +{ + if (refined_pathz.begin() == refined_pathz.end() ) + return 0; + else + return refined_pathz.begin()->size(); +} + + +void +NwayPaths::load(string load_file_path) +{ + fstream load_file; + string file_data_line, header_data, data, path_node, path_width; + int space_split_i, equal_split_i, comma_split_i, colon_split_i; + vector loaded_path; + + load_file.open(load_file_path.c_str(), ios::in); + + if (!load_file) + { + throw mussa_load_error("Sequence File: " + load_file_path + " not found"); + } + else + { + // get header data + // grab mussa tag - discard for now...maybe check in future... + getline(load_file,file_data_line); + space_split_i = file_data_line.find(" "); + file_data_line = file_data_line.substr(space_split_i+1); + // grab type tag - need in future to distinguish between flp and vlp paths + space_split_i = file_data_line.find(" "); + file_data_line = file_data_line.substr(space_split_i+1); + // get species/seq number + space_split_i = file_data_line.find(" "); + header_data = file_data_line.substr(0,space_split_i); + equal_split_i = header_data.find("="); + data = file_data_line.substr(equal_split_i+1); + unsigned int species_num = atoi (data.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + // get window size + space_split_i = file_data_line.find(" "); + header_data = file_data_line.substr(0,space_split_i); + equal_split_i = header_data.find("="); + data = file_data_line.substr(equal_split_i+1); + win_size = atoi (data.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + // get window size + space_split_i = file_data_line.find(" "); + header_data = file_data_line.substr(0,space_split_i); + equal_split_i = header_data.find("="); + data = file_data_line.substr(equal_split_i+1); + threshold = atoi (data.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + + //cout << "seq_num=" << species_num << " win=" << win_size; + //cout << " thres=" << threshold << endl; + + // clear out the current data + refined_pathz.clear(); + + int temp; + + getline(load_file,file_data_line); + while ( (!load_file.eof()) && (file_data_line != "") ) + { + if (file_data_line != "") + { + loaded_path.clear(); + colon_split_i = file_data_line.find(":"); + // whats our window size? + path_width = file_data_line.substr(0,colon_split_i); + file_data_line = file_data_line.substr(colon_split_i+1); + for(size_t i = 0; i < species_num; i++) + { + comma_split_i = file_data_line.find(","); + path_node = file_data_line.substr(0, comma_split_i); + temp = atoi (path_node.c_str()); + loaded_path.push_back(temp); + file_data_line = file_data_line.substr(comma_split_i+1); + } + assert (loaded_path.size() == species_num ); + refined_pathz.push_back(ExtendedConservedPath(atoi(path_width.c_str()), + threshold, + loaded_path)); + } + getline(load_file,file_data_line); + } + load_file.close(); + } +} + + +void +NwayPaths::path_search(vector > all_comparisons, ConservedPath path, int depth) +{ + list new_nodes, trans_check_nodes; + list::iterator new_nodes_i, new_nodes_end; + int i; + bool trans_check_good; + + new_nodes = all_comparisons[depth - 1][depth].match_locations(path[depth-1]); + new_nodes_i = new_nodes.begin(); + new_nodes_end = new_nodes.end(); + while(new_nodes_i != new_nodes_end) + { + //cout << " * species " << depth << " node: " << *new_nodes_i << endl; + // check transitivity with previous nodes in path + trans_check_good = true; + for(i = 0; i < depth - 1; i++) + { + trans_check_nodes = all_comparisons[i][depth].match_locations(path[i]); + if ( (trans_check_nodes.end() == find(trans_check_nodes.begin(), + trans_check_nodes.end(), + *new_nodes_i) ) && + (trans_check_nodes.end() == find(trans_check_nodes.begin(), + trans_check_nodes.end(), + *new_nodes_i * -1) ) ) + trans_check_good = false; + } + + if (trans_check_good) + { + // this makes sure path nodes are recorded with RC status relative to + // the base species + if ( path[depth-1] >= 0) + path.push_back(*new_nodes_i); + else + path.push_back(*new_nodes_i * -1); + + if (depth < all_comparisons.size() - 1) + path_search(all_comparisons, path, depth + 1); + else + pathz.push_back(path); + path.pop_back(); + } + ++new_nodes_i; + } +} +/* use this if I ever get the friggin seqcomp match lists to sort... + if (binary_search(trans_check_nodes.begin(), trans_check_nodes.end(), + *new_nodes_i)) +*/ + +void +NwayPaths::find_paths_r(vector > all_comparisons) +{ + ConservedPath path; + int win_i, window_num; + list new_nodes; + list::iterator new_nodes_i, new_nodes_end; + + pathz.clear(); + window_num = all_comparisons[0][1].size(); + // loop thru all windows in first species + for (win_i = 0; win_i < window_num; win_i++) + { + path.clear(); + path.push_back(win_i); + new_nodes = all_comparisons[0][1].match_locations(path[0]); + new_nodes_i = new_nodes.begin(); + new_nodes_end = new_nodes.end(); + //if (new_nodes_i != new_nodes_end) + //cout << "* species 0 node: " << win_i << endl; + path.push_back(0); + while(new_nodes_i != new_nodes_end) + { + //cout << " * species 1 node: " << *new_nodes_i << endl; + path[1] = *new_nodes_i; + path_search(all_comparisons, path, 2); + ++new_nodes_i; + } + } +} + + +void +NwayPaths::save_old(string save_file_path) +{ + fstream save_file; + list::iterator path_i, paths_end; + int i; + + save_file.open(save_file_path.c_str(), ios::app); + + path_i = pathz.begin(); + paths_end = pathz.end(); + while(path_i != paths_end) + { + ConservedPath& a_path = *path_i; + //cout << a_path.size() << endl; + for(i = 0; i < path_i->size(); ++i) + save_file << i << "," << a_path[i] << " "; + save_file << endl; + ++path_i; + } + save_file.close(); +} + + +/* +void +NwayPaths::find_paths(vector > all_comparisons) +{ + int win_i, sp_i; + vector > > path_src_tree; + list new_nodes; + list::iterator node_i, node_end; + > >::iterator branch_i, branch_end; + + pathz.clear(); + path_src_tree.reserve(all_comparisons.size()- 1); + + + // loop thru all windows in first species + for (win_i = 0; win_i < window_num; win_i++) + { + // clear the path search tree + for(i = 0; i < all_comparisons.size(); i++) + path_src_tree[i].clear(); + + // top level kept empty even tho implicity has one entry of the first + // species at this window - why bother, adds a little speed + + // get connection list for first species, creating a list of nodes + // of second species connected to the first species at this window + new_nodes = all_comparisons[0][1]; + path_src_tree[1].push_back(new_nodes); + + // loop thru rest of species for this window to see if any paths of matches + // go across all species + // if path search tree becomes empty, break out of loop, no reason to search further + sp_i = 1; + while ((sp_i < all_comparisons.size()) && (path tree not empty)) + { + branch_i = path_src_tree[1].begin(); + branch_end = path_src_tree[1].end(); + while (branch_i != branch_end) + { + node_i = branch_i->begin(); + node_end = branch_i->end(); + } + + + // loop over all current nodes + // get connection list for each node + // loop over each previous node in list + // get those nodes connection list + // intersect previous node connections with current + + ++sp_i; + } + + // insert any of the paths found into the master list of paths + + // add no paths if tmp_pathz is empty... + } +} + +void NwayPaths::refine() +{ +} +*/ + + +void NwayPaths::print(list >& dump_path) +{ + list >::iterator pathz_i; + vector::iterator path_i; + + cout << "printing list of lists\n"; + for (pathz_i = dump_path.begin(); pathz_i != dump_path.end(); ++pathz_i) + { + for (path_i = pathz_i->begin(); path_i != pathz_i->end(); ++path_i) + cout << *path_i << " "; + cout << endl; + } +} diff --git a/alg/nway_paths.cxx b/alg/nway_paths.cxx deleted file mode 100644 index 9471d72..0000000 --- a/alg/nway_paths.cxx +++ /dev/null @@ -1,441 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- mussa_nway.cc ----------- -// ---------------------------------------- - -#include "alg/nway_paths.hh" -#include "alg/conserved_path.h" -#include "mussa_exceptions.hh" - -#include -#include -#include - -using namespace std; - -NwayPaths::NwayPaths() -{ -} - -void -NwayPaths::setup(int w, int t) -{ - threshold = t; - soft_thres = threshold; - win_size = w; - pathz.clear(); - - //cout << "nway: thres = " << threshold - // << ", soft threo = " << soft_thres << endl; -} - -void -NwayPaths::set_soft_thres(int sft_thres) -{ - soft_thres = sft_thres; -} - - -// dumbly goes thru and combines path windows exactly adjacent (ie + 1 index) -// doesn't deal with interleaved adjacency -void -NwayPaths::simple_refine() -{ - // ext_path remembers the first window set in an extending path - ExtendedConservedPath ext_path, new_path; - list::iterator cur_path, next_path; - list::iterator pathz_i; - int win_ext_len = 0; - bool extending, end = false; - - refined_pathz.clear(); - - //cout << "path number is: " << pathz.size() << endl; - pathz_i = pathz.begin(); - - // only try to extend when pathz isn't empty. - if (pathz_i != pathz.end()) - { - ext_path = ExtendedConservedPath( win_size, *pathz_i); - - while(pathz_i != pathz.end()) - { - // keep track of current path and advance to next path - cur_path = pathz_i; - ++pathz_i; - if (pathz_i == pathz.end()) - end = true; - else - next_path = pathz_i; - - if (not end) - { - // if node for each seq is equal to the next node+1 then for all - // sequences then we are extending - extending = cur_path->nextTo(*next_path); - } - else - extending = false; - - if (extending) - { - win_ext_len++; - } - else - { - // add the extend window length as first element and add as refined - // now that we have the path to extend save it - new_path = ext_path; - new_path.extend(win_ext_len); - refined_pathz.push_back(new_path); - // reset stuff - win_ext_len = 0; - ext_path = ExtendedConservedPath( win_size, *next_path); - } - } - } - //cout << "r_path number is: " << refined_pathz.size() << endl; -} - - -void -NwayPaths::add_path(int threshold, vector& loaded_path) -{ - pathz.push_back(ConservedPath(threshold, loaded_path)); -} - -void -NwayPaths::add_path(ConservedPath loaded_path) -{ - pathz.push_back(loaded_path); -} - - -void -NwayPaths::save(string save_file_path) -{ - fstream save_file; - list::iterator path_i, paths_end; - - save_file.open(save_file_path.c_str(), ios::out); - - save_file << "\n"; - - path_i = refined_pathz.begin(); - paths_end = refined_pathz.end(); - //path_i = pathz.begin(); - //paths_end = pathz.end(); - while (path_i != paths_end) - { - ExtendedConservedPath& a_path = *path_i; - //cout << a_path.size() << endl; - //first entry is the window length of the windows in the path - save_file << a_path.window_size << ":"; - for(size_t i = 0; i != sequence_count(); ++i) - { - save_file << a_path[i]; - if (i != sequence_count()) - save_file << ","; - } - save_file << endl; - ++path_i; - } - - save_file << "\n"; - save_file.close(); -} - - -size_t -NwayPaths::sequence_count() -{ - if (refined_pathz.begin() == refined_pathz.end() ) - return 0; - else - return refined_pathz.begin()->size(); -} - - -void -NwayPaths::load(string load_file_path) -{ - fstream load_file; - string file_data_line, header_data, data, path_node, path_width; - int space_split_i, equal_split_i, comma_split_i, colon_split_i; - vector loaded_path; - - load_file.open(load_file_path.c_str(), ios::in); - - if (!load_file) - { - throw mussa_load_error("Sequence File: " + load_file_path + " not found"); - } - else - { - // get header data - // grab mussa tag - discard for now...maybe check in future... - getline(load_file,file_data_line); - space_split_i = file_data_line.find(" "); - file_data_line = file_data_line.substr(space_split_i+1); - // grab type tag - need in future to distinguish between flp and vlp paths - space_split_i = file_data_line.find(" "); - file_data_line = file_data_line.substr(space_split_i+1); - // get species/seq number - space_split_i = file_data_line.find(" "); - header_data = file_data_line.substr(0,space_split_i); - equal_split_i = header_data.find("="); - data = file_data_line.substr(equal_split_i+1); - unsigned int species_num = atoi (data.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - // get window size - space_split_i = file_data_line.find(" "); - header_data = file_data_line.substr(0,space_split_i); - equal_split_i = header_data.find("="); - data = file_data_line.substr(equal_split_i+1); - win_size = atoi (data.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - // get window size - space_split_i = file_data_line.find(" "); - header_data = file_data_line.substr(0,space_split_i); - equal_split_i = header_data.find("="); - data = file_data_line.substr(equal_split_i+1); - threshold = atoi (data.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - - //cout << "seq_num=" << species_num << " win=" << win_size; - //cout << " thres=" << threshold << endl; - - // clear out the current data - refined_pathz.clear(); - - int temp; - - getline(load_file,file_data_line); - while ( (!load_file.eof()) && (file_data_line != "") ) - { - if (file_data_line != "") - { - loaded_path.clear(); - colon_split_i = file_data_line.find(":"); - // whats our window size? - path_width = file_data_line.substr(0,colon_split_i); - file_data_line = file_data_line.substr(colon_split_i+1); - for(size_t i = 0; i < species_num; i++) - { - comma_split_i = file_data_line.find(","); - path_node = file_data_line.substr(0, comma_split_i); - temp = atoi (path_node.c_str()); - loaded_path.push_back(temp); - file_data_line = file_data_line.substr(comma_split_i+1); - } - assert (loaded_path.size() == species_num ); - refined_pathz.push_back(ExtendedConservedPath(atoi(path_width.c_str()), - threshold, - loaded_path)); - } - getline(load_file,file_data_line); - } - load_file.close(); - } -} - - -void -NwayPaths::path_search(vector > all_comparisons, ConservedPath path, int depth) -{ - list new_nodes, trans_check_nodes; - list::iterator new_nodes_i, new_nodes_end; - int i; - bool trans_check_good; - - new_nodes = all_comparisons[depth - 1][depth].match_locations(path[depth-1]); - new_nodes_i = new_nodes.begin(); - new_nodes_end = new_nodes.end(); - while(new_nodes_i != new_nodes_end) - { - //cout << " * species " << depth << " node: " << *new_nodes_i << endl; - // check transitivity with previous nodes in path - trans_check_good = true; - for(i = 0; i < depth - 1; i++) - { - trans_check_nodes = all_comparisons[i][depth].match_locations(path[i]); - if ( (trans_check_nodes.end() == find(trans_check_nodes.begin(), - trans_check_nodes.end(), - *new_nodes_i) ) && - (trans_check_nodes.end() == find(trans_check_nodes.begin(), - trans_check_nodes.end(), - *new_nodes_i * -1) ) ) - trans_check_good = false; - } - - if (trans_check_good) - { - // this makes sure path nodes are recorded with RC status relative to - // the base species - if ( path[depth-1] >= 0) - path.push_back(*new_nodes_i); - else - path.push_back(*new_nodes_i * -1); - - if (depth < all_comparisons.size() - 1) - path_search(all_comparisons, path, depth + 1); - else - pathz.push_back(path); - path.pop_back(); - } - ++new_nodes_i; - } -} -/* use this if I ever get the friggin seqcomp match lists to sort... - if (binary_search(trans_check_nodes.begin(), trans_check_nodes.end(), - *new_nodes_i)) -*/ - -void -NwayPaths::find_paths_r(vector > all_comparisons) -{ - ConservedPath path; - int win_i, window_num; - list new_nodes; - list::iterator new_nodes_i, new_nodes_end; - - pathz.clear(); - window_num = all_comparisons[0][1].size(); - // loop thru all windows in first species - for (win_i = 0; win_i < window_num; win_i++) - { - path.clear(); - path.push_back(win_i); - new_nodes = all_comparisons[0][1].match_locations(path[0]); - new_nodes_i = new_nodes.begin(); - new_nodes_end = new_nodes.end(); - //if (new_nodes_i != new_nodes_end) - //cout << "* species 0 node: " << win_i << endl; - path.push_back(0); - while(new_nodes_i != new_nodes_end) - { - //cout << " * species 1 node: " << *new_nodes_i << endl; - path[1] = *new_nodes_i; - path_search(all_comparisons, path, 2); - ++new_nodes_i; - } - } -} - - -void -NwayPaths::save_old(string save_file_path) -{ - fstream save_file; - list::iterator path_i, paths_end; - int i; - - save_file.open(save_file_path.c_str(), ios::app); - - path_i = pathz.begin(); - paths_end = pathz.end(); - while(path_i != paths_end) - { - ConservedPath& a_path = *path_i; - //cout << a_path.size() << endl; - for(i = 0; i < path_i->size(); ++i) - save_file << i << "," << a_path[i] << " "; - save_file << endl; - ++path_i; - } - save_file.close(); -} - - -/* -void -NwayPaths::find_paths(vector > all_comparisons) -{ - int win_i, sp_i; - vector > > path_src_tree; - list new_nodes; - list::iterator node_i, node_end; - > >::iterator branch_i, branch_end; - - pathz.clear(); - path_src_tree.reserve(all_comparisons.size()- 1); - - - // loop thru all windows in first species - for (win_i = 0; win_i < window_num; win_i++) - { - // clear the path search tree - for(i = 0; i < all_comparisons.size(); i++) - path_src_tree[i].clear(); - - // top level kept empty even tho implicity has one entry of the first - // species at this window - why bother, adds a little speed - - // get connection list for first species, creating a list of nodes - // of second species connected to the first species at this window - new_nodes = all_comparisons[0][1]; - path_src_tree[1].push_back(new_nodes); - - // loop thru rest of species for this window to see if any paths of matches - // go across all species - // if path search tree becomes empty, break out of loop, no reason to search further - sp_i = 1; - while ((sp_i < all_comparisons.size()) && (path tree not empty)) - { - branch_i = path_src_tree[1].begin(); - branch_end = path_src_tree[1].end(); - while (branch_i != branch_end) - { - node_i = branch_i->begin(); - node_end = branch_i->end(); - } - - - // loop over all current nodes - // get connection list for each node - // loop over each previous node in list - // get those nodes connection list - // intersect previous node connections with current - - ++sp_i; - } - - // insert any of the paths found into the master list of paths - - // add no paths if tmp_pathz is empty... - } -} - -void NwayPaths::refine() -{ -} -*/ - - -void NwayPaths::print(list >& dump_path) -{ - list >::iterator pathz_i; - vector::iterator path_i; - - cout << "printing list of lists\n"; - for (pathz_i = dump_path.begin(); pathz_i != dump_path.end(); ++pathz_i) - { - for (path_i = pathz_i->begin(); path_i != pathz_i->end(); ++path_i) - cout << *path_i << " "; - cout << endl; - } -} diff --git a/alg/nway_paths.hh b/alg/nway_paths.hh deleted file mode 100644 index ee1f07c..0000000 --- a/alg/nway_paths.hh +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _MUSSA_NWAY_H_ -#define _MUSSA_NWAY_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- mussa_nway.hh ----------- -// ---------------------------------------- - -#include -#include -#include - -#include "alg/flp.hh" -#include "alg/conserved_path.h" - -class NwayPaths -{ - friend class ConnView; - friend class SeqView; - protected: - int threshold; - int win_size; - int soft_thres; - - double ent_thres; - std::vector c_sequences; //used by entropy_path_search - - public: - NwayPaths(); - //! setup an nway comparison, initialize # of species, window size, - //! threshold - void setup(int w, int t); - void setup_ent(double new_entropy_thres, std::vector some_Seqs); - void set_soft_thres(int soft_thres); - - void radiate_path_search(std::vector > all_comparisons); - void trans_path_search(std::vector > all_comparisons); - void entropy_path_search(std::vector > all_comparisons); - double path_entropy(std::vector path); - - // old recursive transitive nway ... has issues checking all links? - void find_paths_r(std::vector > all_comparisons); - void path_search(std::vector > all_comparisons, ConservedPath path, int depth); - - void simple_refine(); - void save(std::string save_file_path); - //! load a muway file, \throws mussa_load_error - void load(std::string load_file_path); - void add_path(int threshold, std::vector& loaded_path); - void add_path(ConservedPath loaded_path); - //! how many sequences are in our comparison - size_t sequence_count(); - - void find_paths(std::vector > all_comparisons); - void refine(); - - void save_old(std::string save_file_path); - void print(std::list >&); - - std::list::iterator pbegin() { return pathz.begin() ; } - std::list::iterator pend() { return pathz.end() ; } - std::list::iterator rpbegin() { return refined_pathz.begin() ; } - std::list::iterator rpend() { return refined_pathz.end() ; } - // these probably shouldn't be public, but lets start - // simple - std::list pathz; - std::list refined_pathz; -}; -#endif diff --git a/alg/nway_paths.hpp b/alg/nway_paths.hpp new file mode 100644 index 0000000..23f7698 --- /dev/null +++ b/alg/nway_paths.hpp @@ -0,0 +1,77 @@ +#ifndef _MUSSA_NWAY_H_ +#define _MUSSA_NWAY_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- mussa_nway.hh ----------- +// ---------------------------------------- + +#include +#include +#include + +#include "alg/flp.hpp" +#include "alg/conserved_path.hpp" + +class NwayPaths +{ + friend class ConnView; + friend class SeqView; + protected: + int threshold; + int win_size; + int soft_thres; + + double ent_thres; + std::vector c_sequences; //used by entropy_path_search + + public: + NwayPaths(); + //! setup an nway comparison, initialize # of species, window size, + //! threshold + void setup(int w, int t); + void setup_ent(double new_entropy_thres, std::vector some_Seqs); + void set_soft_thres(int soft_thres); + + void radiate_path_search(std::vector > all_comparisons); + void trans_path_search(std::vector > all_comparisons); + void entropy_path_search(std::vector > all_comparisons); + double path_entropy(std::vector path); + + // old recursive transitive nway ... has issues checking all links? + void find_paths_r(std::vector > all_comparisons); + void path_search(std::vector > all_comparisons, ConservedPath path, int depth); + + void simple_refine(); + void save(std::string save_file_path); + //! load a muway file, \throws mussa_load_error + void load(std::string load_file_path); + void add_path(int threshold, std::vector& loaded_path); + void add_path(ConservedPath loaded_path); + //! how many sequences are in our comparison + size_t sequence_count(); + + void find_paths(std::vector > all_comparisons); + void refine(); + + void save_old(std::string save_file_path); + void print(std::list >&); + + std::list::iterator pbegin() { return pathz.begin() ; } + std::list::iterator pend() { return pathz.end() ; } + std::list::iterator rpbegin() { return refined_pathz.begin() ; } + std::list::iterator rpend() { return refined_pathz.end() ; } + // these probably shouldn't be public, but lets start + // simple + std::list pathz; + std::list refined_pathz; +}; +#endif diff --git a/alg/nway_refine.cpp b/alg/nway_refine.cpp new file mode 100644 index 0000000..b5d665c --- /dev/null +++ b/alg/nway_refine.cpp @@ -0,0 +1,144 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +PathList +ExtendPathWindows(PathList raw_list) +{ + // to keep track of everything, this function acts like a finite state + // automata: 3 bitfields: reset, extending, scanning - ie 8 states + int reset = 0, extending = 0, scanning = 0; + + int species_num = raw_list.SpeciesNum(); + int win_num = raw_list.WinNum(); + + int *cur_path, *next_path; + + cur_path = new int[species_num]; + next_path = new int[species_num]; + + raw_list.ResetIndex(); + + while (no more windows avaible) + { + //cur_indices[0] + ref_ext == next_indices[0] + 1: + + // state 000 - start/nominal search + // + if !reset && !extending && !scanning + { + if cur_path[0] == next_path[0] + { + scanning = 1; // go to state 001 + raw_list.IncreIndex(); + } + else if cur_path[0] + 1 == next_path[0] + { + extending = 1; // go to state 010 + win_ext = 1; + raw_list.SetDirty(); + raw_list.IncreIndex(); + } + else + reset = 1; // go to state 100 + } + + // state 001 - scanning for ext window thru possible interleaving + // + else if !reset && !extending && scanning + { + if cur_path[0] == next_path[0] + raw_list.IncreIndex(); + else if cur_path[0] + 1 == next_path[0] + { + extending = 1; // go to state 011 + win_ext = 1; + raw_list.SetDirty(); + raw_list.IncreIndex(); + } + else + reset = 1; // go to state 101 + } + + // state 010 - extending window with no interleaving + // + else if !reset && extending && !scanning + { + if (cur_path[0] + win_ext) == next_path[0] + { + extending = 1; // go to state 011 + raw_list.IncreIndex(); + } + else if (cur_path[0] + win_ext + 1) == next_path[0] + { + win_ext++; + raw_list.SetDirty(); + raw_list.IncreIndex(); + } + else + reset = 1; // go to state 110 + } + + // state 011 - extending window with interleaving + // + else if !reset && extending && scanning + { + if (cur_path[0] + win_ext) == next_path[0] + raw_list.IncreIndex(); + else if (cur_path[0] + win_ext + 1) == next_path[0] + { + win_ext++; + raw_list.SetDirty(); + raw_list.IncreIndex(); + } + else + reset = 1; // go to state 111 + } + + + // reset condition states, return to 000 after taking appropiate action + + // state 100 - no extended window, no scanning happened + // save basic window to extended window list + if reset && !extending && !scanning + { + // return to start/nominal search state + reset = 0; + } + + // state 101 - no extended window, scanned for interleaving + // save basic window to extended window list, return to first clean + else if reset && !extending && scanning + { + // return to start/nominal search state + reset = 0; + scanning = 0; + } + + // state 110 - extended window, no interleaving + // calc extended window, save to extended window list + else if reset && extending && !scanning + { + // return to start/nominal search state + reset = 0; + extending = 0; + } + + // state 111 - extended window, interleaved + // calc extended window, save to ext win list, return to first clean + else if reset && extending && scanning + { + // return to start/nominal search state + reset = 0; + extending = 0; + scanning = 0; + } + + return ext_win; +} diff --git a/alg/nway_refine.cxx b/alg/nway_refine.cxx deleted file mode 100644 index b5d665c..0000000 --- a/alg/nway_refine.cxx +++ /dev/null @@ -1,144 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -PathList -ExtendPathWindows(PathList raw_list) -{ - // to keep track of everything, this function acts like a finite state - // automata: 3 bitfields: reset, extending, scanning - ie 8 states - int reset = 0, extending = 0, scanning = 0; - - int species_num = raw_list.SpeciesNum(); - int win_num = raw_list.WinNum(); - - int *cur_path, *next_path; - - cur_path = new int[species_num]; - next_path = new int[species_num]; - - raw_list.ResetIndex(); - - while (no more windows avaible) - { - //cur_indices[0] + ref_ext == next_indices[0] + 1: - - // state 000 - start/nominal search - // - if !reset && !extending && !scanning - { - if cur_path[0] == next_path[0] - { - scanning = 1; // go to state 001 - raw_list.IncreIndex(); - } - else if cur_path[0] + 1 == next_path[0] - { - extending = 1; // go to state 010 - win_ext = 1; - raw_list.SetDirty(); - raw_list.IncreIndex(); - } - else - reset = 1; // go to state 100 - } - - // state 001 - scanning for ext window thru possible interleaving - // - else if !reset && !extending && scanning - { - if cur_path[0] == next_path[0] - raw_list.IncreIndex(); - else if cur_path[0] + 1 == next_path[0] - { - extending = 1; // go to state 011 - win_ext = 1; - raw_list.SetDirty(); - raw_list.IncreIndex(); - } - else - reset = 1; // go to state 101 - } - - // state 010 - extending window with no interleaving - // - else if !reset && extending && !scanning - { - if (cur_path[0] + win_ext) == next_path[0] - { - extending = 1; // go to state 011 - raw_list.IncreIndex(); - } - else if (cur_path[0] + win_ext + 1) == next_path[0] - { - win_ext++; - raw_list.SetDirty(); - raw_list.IncreIndex(); - } - else - reset = 1; // go to state 110 - } - - // state 011 - extending window with interleaving - // - else if !reset && extending && scanning - { - if (cur_path[0] + win_ext) == next_path[0] - raw_list.IncreIndex(); - else if (cur_path[0] + win_ext + 1) == next_path[0] - { - win_ext++; - raw_list.SetDirty(); - raw_list.IncreIndex(); - } - else - reset = 1; // go to state 111 - } - - - // reset condition states, return to 000 after taking appropiate action - - // state 100 - no extended window, no scanning happened - // save basic window to extended window list - if reset && !extending && !scanning - { - // return to start/nominal search state - reset = 0; - } - - // state 101 - no extended window, scanned for interleaving - // save basic window to extended window list, return to first clean - else if reset && !extending && scanning - { - // return to start/nominal search state - reset = 0; - scanning = 0; - } - - // state 110 - extended window, no interleaving - // calc extended window, save to extended window list - else if reset && extending && !scanning - { - // return to start/nominal search state - reset = 0; - extending = 0; - } - - // state 111 - extended window, interleaved - // calc extended window, save to ext win list, return to first clean - else if reset && extending && scanning - { - // return to start/nominal search state - reset = 0; - extending = 0; - scanning = 0; - } - - return ext_win; -} diff --git a/alg/parse_options.cpp b/alg/parse_options.cpp new file mode 100644 index 0000000..3282dc7 --- /dev/null +++ b/alg/parse_options.cpp @@ -0,0 +1,47 @@ +#include +namespace po = boost::program_options; + +#include +#include + +#include "alg/mussa.hpp" +#include "alg/parse_options.hpp" + +Mussa *initialize_mussa(int argc, char **argv) +{ + po::options_description options("Mussa options"); + po::positional_options_description pos_options; + pos_options.add("run-analysis", -1); + + options.add_options() + ("help", "help message") + ("run-analysis,p", po::value(), + "run an analysis defined by the mussa parameter file") + ("view-analysis", po::value(), + "load a previously run analysis") + ; + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv).options(options).positional(pos_options).run(), vm); + po::notify(vm); + + if (vm.count("help")) { + std::cout << options << std::endl; + return 0; + } + + Mussa *m = new Mussa(); + // currently we can only have one analysis loaded, so + // running trumps viewing. + if (vm.count("run-analysis")) { + m->load_mupa_file( vm["run-analysis"].as< std::string >() ); + std::cout << "I apologize for blocking the gui while running the analysis" + << std::endl; + m->analyze(); + } + else if (vm.count("view-analysis")) { + m->load( vm["view-analysis"].as< std::string >() ); + } + return m; +} + diff --git a/alg/parse_options.cxx b/alg/parse_options.cxx deleted file mode 100644 index 2d44498..0000000 --- a/alg/parse_options.cxx +++ /dev/null @@ -1,47 +0,0 @@ -#include -namespace po = boost::program_options; - -#include -#include - -#include "alg/mussa_class.hh" -#include "alg/parse_options.h" - -Mussa *initialize_mussa(int argc, char **argv) -{ - po::options_description options("Mussa options"); - po::positional_options_description pos_options; - pos_options.add("run-analysis", -1); - - options.add_options() - ("help", "help message") - ("run-analysis,p", po::value(), - "run an analysis defined by the mussa parameter file") - ("view-analysis", po::value(), - "load a previously run analysis") - ; - - po::variables_map vm; - po::store(po::command_line_parser(argc, argv).options(options).positional(pos_options).run(), vm); - po::notify(vm); - - if (vm.count("help")) { - std::cout << options << std::endl; - return 0; - } - - Mussa *m = new Mussa(); - // currently we can only have one analysis loaded, so - // running trumps viewing. - if (vm.count("run-analysis")) { - m->load_mupa_file( vm["run-analysis"].as< std::string >() ); - std::cout << "I apologize for blocking the gui while running the analysis" - << std::endl; - m->analyze(); - } - else if (vm.count("view-analysis")) { - m->load( vm["view-analysis"].as< std::string >() ); - } - return m; -} - diff --git a/alg/parse_options.h b/alg/parse_options.h deleted file mode 100644 index 1dd3291..0000000 --- a/alg/parse_options.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _PARSE_OPTIONS_H_ -#define _PARSE_OPTIONS_H_ - -class Mussa; - -//! initialize a mussa analysis from command line arguments -Mussa *initialize_mussa(int argc, char** argv); -#endif - diff --git a/alg/parse_options.hpp b/alg/parse_options.hpp new file mode 100644 index 0000000..1dd3291 --- /dev/null +++ b/alg/parse_options.hpp @@ -0,0 +1,9 @@ +#ifndef _PARSE_OPTIONS_H_ +#define _PARSE_OPTIONS_H_ + +class Mussa; + +//! initialize a mussa analysis from command line arguments +Mussa *initialize_mussa(int argc, char** argv); +#endif + diff --git a/alg/sequence.cpp b/alg/sequence.cpp new file mode 100644 index 0000000..b05349e --- /dev/null +++ b/alg/sequence.cpp @@ -0,0 +1,721 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- sequence.cc ----------- +// ---------------------------------------- + +#include "alg/sequence.hpp" +#include "mussa_exceptions.hpp" + +#include +#include + +using namespace std; + +Sequence::Sequence() +{ +} + +Sequence::Sequence(string seq) +{ + set_filtered_sequence(seq); +} + +Sequence &Sequence::operator=(const Sequence& s) +{ + if (this != &s) { + sequence = s.sequence; + header = s.header; + species = s.species; + annots = s.annots; + } + return *this; +} + +Sequence &Sequence::operator=(const std::string& s) +{ + set_filtered_sequence(s); + return *this; +} + +//! load a fasta file into a sequence +/*! + * \param file_path the location of the fasta file in the filesystem + * \param seq_num which sequence in the file to load + * \param start_index starting position in the fasta sequence, 0 for beginning + * \param end_index ending position in the fasta sequence, 0 for end + * \return error message, empty string if no error. (gag!) + */ +void +Sequence::load_fasta(string file_path, int seq_num, + int start_index, int end_index) +{ + fstream data_file; + string file_data_line; + int header_counter = 0; + bool read_seq = true; + string rev_comp; + string sequence_raw; + string seq_tmp; // holds sequence during basic filtering + + data_file.open(file_path.c_str(), ios::in); + + if (!data_file) + { + throw mussa_load_error("Sequence File: " + file_path + " not found"); + } + // if file opened okay, read it + else + { + // search for the header of the fasta sequence we want + while ( (!data_file.eof()) && (header_counter < seq_num) ) + { + getline(data_file,file_data_line); + if (file_data_line.substr(0,1) == ">") + header_counter++; + } + + header = file_data_line.substr(1); + + sequence_raw = ""; + + while ( !data_file.eof() && read_seq ) + { + getline(data_file,file_data_line); + if (file_data_line.substr(0,1) == ">") + read_seq = false; + else sequence_raw += file_data_line; + } + + data_file.close(); + + // Lastly, if subselection of the sequence was specified we keep cut out + // and only keep that part + // end_index = 0 means no end was specified, so cut to the end + if (end_index == 0) + end_index = sequence_raw.size(); + + // sequence filtering for upcasing agctn and convert non AGCTN to N + set_filtered_sequence(sequence_raw, start_index, end_index-start_index); + } +} + +void Sequence::set_filtered_sequence(const string &old_seq, + string::size_type start, + string::size_type count) +{ + char conversionTable[257]; + + if ( count == 0) + count = old_seq.size() - start; + sequence.clear(); + sequence.reserve(count); + + // Make a conversion table + + // everything we don't specify below will become 'N' + for(int table_i=0; table_i < 256; table_i++) + { + conversionTable[table_i] = 'N'; + } + // add end of string character for printing out table for testing purposes + conversionTable[256] = '\0'; + + // we want these to map to themselves - ie not to change + conversionTable[(int)'A'] = 'A'; + conversionTable[(int)'T'] = 'T'; + conversionTable[(int)'G'] = 'G'; + conversionTable[(int)'C'] = 'C'; + // this is to upcase + conversionTable[(int)'a'] = 'A'; + conversionTable[(int)'t'] = 'T'; + conversionTable[(int)'g'] = 'G'; + conversionTable[(int)'c'] = 'C'; + + // finally, the actual conversion loop + for(string::size_type seq_index = 0; seq_index < count; seq_index++) + { + sequence += conversionTable[ (int)old_seq[seq_index+start]]; + } +} + + // this doesn't work properly under gcc 3.x ... it can't recognize toupper + //transform(sequence.begin(), sequence.end(), sequence.begin(), toupper); + + +void +Sequence::load_annot(string file_path, int start_index, int end_index) +{ + fstream data_file; + string file_data_line; + annot an_annot; + string::size_type space_split_i; + string annot_value; + list::iterator list_i; + string err_msg; + + + annots.clear(); + data_file.open(file_path.c_str(), ios::in); + + if (!data_file) + { + throw mussa_load_error("Sequence File: " + file_path + " not found"); + } + // if file opened okay, read it + else + { + getline(data_file,file_data_line); + species = file_data_line; + + // end_index = 0 means no end was specified, so cut to the end + if (end_index == 0) + end_index = sequence.length(); + + //cout << "START: " << start_index << " END: " << end_index << endl; + + while ( !data_file.eof() ) + { + getline(data_file,file_data_line); + if (file_data_line != "") + { + // need to get 4 values...almost same code 4 times... + // get annot start index + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.start = atoi (annot_value.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + // get annot end index + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.end = atoi (annot_value.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + + //cout << "seq, annots: " << an_annot.start << ", " << an_annot.end + // << endl; + + // get annot name + space_split_i = file_data_line.find(" "); + if (space_split_i == string::npos) // no entries for name & type + { + cout << "seq, annots - no name or type\n"; + an_annot.name = ""; + an_annot.type = ""; + } + else + { + annot_value = file_data_line.substr(0,space_split_i); + an_annot.name = annot_value; + file_data_line = file_data_line.substr(space_split_i+1); + // get annot type + space_split_i = file_data_line.find(" "); + if (space_split_i == string::npos) // no entry for type + an_annot.type = ""; + else + { + annot_value = file_data_line.substr(0,space_split_i); + an_annot.type = annot_value; + } + } + + + // add annot to list if it falls within the range of sequence specified + if ((start_index <= an_annot.start) && (end_index >= an_annot.end)) + { + an_annot.start -= start_index; + an_annot.end -= start_index; + annots.push_back(an_annot); + } + else + cout << "FAILED!!!!!!\n"; + } + } + + data_file.close(); + /* + // debugging check + for(list_i = annots.begin(); list_i != annots.end(); ++list_i) + { + cout << (*list_i).start << "," << (*list_i).end << "\t"; + cout << (*list_i).name << "\t" << (*list_i).type << endl; + } + */ + } +} + +bool Sequence::empty() const +{ + return (size() == 0); +} + +const std::list Sequence::annotations() const +{ + return annots; +} + +string::size_type Sequence::length() const +{ + return size(); +} + +string::size_type Sequence::size() const +{ + return sequence.size(); +} + +Sequence::iterator Sequence::begin() +{ + return sequence.begin(); +} + +Sequence::const_iterator Sequence::begin() const +{ + return sequence.begin(); +} + +Sequence::iterator Sequence::end() +{ + return sequence.end(); +} + +Sequence::const_iterator Sequence::end() const +{ + return sequence.end(); +} + + +const string& +Sequence::get_seq() const +{ + return sequence; +} + + +string +Sequence::subseq(int start, int end) const +{ + return sequence.substr(start, end); +} + + +const char * +Sequence::c_seq() const +{ + return sequence.c_str(); +} + +string +Sequence::rev_comp() const +{ + string rev_comp; + char conversionTable[257]; + int seq_i, table_i, len; + + len = sequence.length(); + rev_comp.reserve(len); + // make a conversion table + // init all parts of conversion table to '~' character + // '~' I doubt will ever appear in a sequence file (jeez, I hope) + // and may the fleas of 1000 camels infest the genitals of any biologist (and + // seven generations of their progeny) who decides to make it mean + // something special!!! + // PS - double the curse for any smartass non-biologist who tries it as well + for(table_i=0; table_i < 256; table_i++) + { + conversionTable[table_i] = '~'; + } + // add end of string character for printing out table for testing purposes + conversionTable[256] = '\0'; + + // add in the characters for the bases we want to convert + conversionTable[(int)'A'] = 'T'; + conversionTable[(int)'T'] = 'A'; + conversionTable[(int)'G'] = 'C'; + conversionTable[(int)'C'] = 'G'; + conversionTable[(int)'N'] = 'N'; + + // finally, the actual conversion loop + for(seq_i = len - 1; seq_i >= 0; seq_i--) + { + table_i = (int) sequence[seq_i]; + rev_comp += conversionTable[table_i]; + } + + return rev_comp; +} + + +const string& +Sequence::get_header() const +{ + return header; +} +/* +//FIXME: i don't think this code is callable +string +Sequence::sp_name() const +{ + return species; +} +*/ + +void +Sequence::set_seq(const string& a_seq) +{ + set_filtered_sequence(a_seq); +} + + +/* +string +Sequence::species() +{ + return species; +} +*/ + +void +Sequence::clear() +{ + sequence = ""; + header = ""; + species = ""; + annots.clear(); +} + +void +Sequence::save(fstream &save_file) + //string save_file_path) +{ + //fstream save_file; + list::iterator annots_i; + + // not sure why, or if i'm doing something wrong, but can't seem to pass + // file pointers down to this method from the mussa control class + // so each call to save a sequence appends to the file started by mussa_class + //save_file.open(save_file_path.c_str(), ios::app); + + save_file << "" << endl; + save_file << sequence << endl; + save_file << "" << endl; + + save_file << "" << endl; + save_file << species << endl; + for (annots_i = annots.begin(); annots_i != annots.end(); ++annots_i) + { + save_file << annots_i->start << " " << annots_i->end << " " ; + save_file << annots_i->name << " " << annots_i->type << endl; + } + save_file << "" << endl; + //save_file.close(); +} + +void +Sequence::load_museq(string load_file_path, int seq_num) +{ + fstream load_file; + string file_data_line; + int seq_counter; + annot an_annot; + string::size_type space_split_i; + string annot_value; + + annots.clear(); + load_file.open(load_file_path.c_str(), ios::in); + + seq_counter = 0; + // search for the seq_num-th sequence + while ( (!load_file.eof()) && (seq_counter < seq_num) ) + { + getline(load_file,file_data_line); + if (file_data_line == "") + seq_counter++; + } + getline(load_file, file_data_line); + sequence = file_data_line; + getline(load_file, file_data_line); + getline(load_file, file_data_line); + if (file_data_line == "") + { + getline(load_file, file_data_line); + species = file_data_line; + while ( (!load_file.eof()) && (file_data_line != "") ) + { + getline(load_file,file_data_line); + if ((file_data_line != "") && (file_data_line != "")) + { + // need to get 4 values...almost same code 4 times... + // get annot start index + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.start = atoi (annot_value.c_str()); + file_data_line = file_data_line.substr(space_split_i+1); + // get annot end index + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.end = atoi (annot_value.c_str()); + + if (space_split_i == string::npos) // no entry for type or name + { + cout << "seq, annots - no type or name\n"; + an_annot.type = ""; + an_annot.name = ""; + } + else // else get annot type + { + file_data_line = file_data_line.substr(space_split_i+1); + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.type = annot_value; + if (space_split_i == string::npos) // no entry for name + { + cout << "seq, annots - no name\n"; + an_annot.name = ""; + } + else // get annot name + { + file_data_line = file_data_line.substr(space_split_i+1); + space_split_i = file_data_line.find(" "); + annot_value = file_data_line.substr(0,space_split_i); + an_annot.type = annot_value; + } + } + annots.push_back(an_annot); // don't forget to actually add the annot + } + //cout << "seq, annots: " << an_annot.start << ", " << an_annot.end + // << "-->" << an_annot.type << "::" << an_annot.name << endl; + } + } + load_file.close(); +} + + +string +Sequence::rc_motif(string a_motif) +{ + string rev_comp; + char conversionTable[257]; + int seq_i, table_i, len; + + len = a_motif.length(); + rev_comp.reserve(len); + + for(table_i=0; table_i < 256; table_i++) + { + conversionTable[table_i] = '~'; + } + // add end of string character for printing out table for testing purposes + conversionTable[256] = '\0'; + + // add in the characters for the bases we want to convert (IUPAC) + conversionTable[(int)'A'] = 'T'; + conversionTable[(int)'T'] = 'A'; + conversionTable[(int)'G'] = 'C'; + conversionTable[(int)'C'] = 'G'; + conversionTable[(int)'N'] = 'N'; + conversionTable[(int)'M'] = 'K'; + conversionTable[(int)'R'] = 'Y'; + conversionTable[(int)'W'] = 'W'; + conversionTable[(int)'S'] = 'S'; + conversionTable[(int)'Y'] = 'R'; + conversionTable[(int)'K'] = 'M'; + conversionTable[(int)'V'] = 'B'; + conversionTable[(int)'H'] = 'D'; + conversionTable[(int)'D'] = 'H'; + conversionTable[(int)'B'] = 'V'; + + // finally, the actual conversion loop + for(seq_i = len - 1; seq_i >= 0; seq_i--) + { + //cout << "** i = " << seq_i << " bp = " << + table_i = (int) a_motif[seq_i]; + rev_comp += conversionTable[table_i]; + } + + //cout << "seq: " << a_motif << endl; + //cout << "rc: " << rev_comp << endl; + + return rev_comp; +} + +string +Sequence::motif_validate(string a_motif) +{ + string valid_motif; + int seq_i, len; + + len = a_motif.length(); + valid_motif.reserve(len); + + // this just upcases IUPAC symbols. Eventually should return an error if non IUPAC is present. + // 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')) + valid_motif += 'A'; + else if ((a_motif[seq_i] == 't') || (a_motif[seq_i] == 'T')) + valid_motif += 'T'; + else if ((a_motif[seq_i] == 'g') || (a_motif[seq_i] == 'G')) + valid_motif += 'G'; + else if ((a_motif[seq_i] == 'c') || (a_motif[seq_i] == 'C')) + valid_motif += 'C'; + else if ((a_motif[seq_i] == 'n') || (a_motif[seq_i] == 'N')) + valid_motif += 'N'; + else if ((a_motif[seq_i] == 'm') || (a_motif[seq_i] == 'M')) + valid_motif += 'M'; + else if ((a_motif[seq_i] == 'r') || (a_motif[seq_i] == 'R')) + valid_motif += 'R'; + else if ((a_motif[seq_i] == 'w') || (a_motif[seq_i] == 'W')) + valid_motif += 'W'; + else if ((a_motif[seq_i] == 's') || (a_motif[seq_i] == 'S')) + valid_motif += 'S'; + else if ((a_motif[seq_i] == 'y') || (a_motif[seq_i] == 'Y')) + valid_motif += 'Y'; + else if ((a_motif[seq_i] == 'k') || (a_motif[seq_i] == 'K')) + valid_motif += 'G'; + else if ((a_motif[seq_i] == 'v') || (a_motif[seq_i] == 'V')) + valid_motif += 'V'; + else if ((a_motif[seq_i] == 'h') || (a_motif[seq_i] == 'H')) + valid_motif += 'H'; + else if ((a_motif[seq_i] == 'd') || (a_motif[seq_i] == 'D')) + valid_motif += 'D'; + else if ((a_motif[seq_i] == 'b') || (a_motif[seq_i] == 'B')) + valid_motif += 'B'; + } + + //cout << "valid_motif is: " << valid_motif << endl; + + return valid_motif; +} + + +vector +Sequence::find_motif(string a_motif) +{ + vector motif_match_starts; + string a_motif_rc; + + + motif_match_starts.clear(); + + //cout << "motif is: " << a_motif << endl; + a_motif = motif_validate(a_motif); + //cout << "motif is: " << a_motif << endl; + + + if (a_motif != "") + { + //cout << "Sequence: none blank motif\n"; + motif_scan(a_motif, &motif_match_starts); + + a_motif_rc = rc_motif(a_motif); + // make sure not to do search again if it is a palindrome + if (a_motif_rc != a_motif) + motif_scan(a_motif_rc, &motif_match_starts); + } + return motif_match_starts; +} + +void +Sequence::motif_scan(string a_motif, vector * motif_match_starts) +{ + char * seq_c; + string::size_type seq_i; + int motif_i, motif_len; + + // faster to loop thru the sequence as a old c string (ie char array) + seq_c = (char*)sequence.c_str(); + //cout << "Sequence: motif, seq len = " << sequence.length() << endl; + motif_len = a_motif.length(); + + //cout << "motif_length: " << motif_len << endl; + //cout << "RAAARRRRR\n"; + + motif_i = 0; + + //cout << "motif: " << a_motif << endl; + + //cout << "Sequence: motif, length= " << length << endl; + seq_i = 0; + while (seq_i < sequence.length()) + { + //cout << seq_c[seq_i]; + //cout << seq_c[seq_i] << "?" << a_motif[motif_i] << ":" << motif_i << " "; + // this is pretty much a straight translation of Nora's python code + // to match iupac letter codes + if (a_motif[motif_i] =='N') + motif_i++; + else if (a_motif[motif_i] == seq_c[seq_i]) + motif_i++; + else if ((a_motif[motif_i] =='M') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C'))) + motif_i++; + else if ((a_motif[motif_i] =='R') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='G'))) + motif_i++; + else if ((a_motif[motif_i] =='W') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='T'))) + motif_i++; + else if ((a_motif[motif_i] =='S') && + ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='G'))) + motif_i++; + else if ((a_motif[motif_i] =='Y') && + ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='T'))) + motif_i++; + else if ((a_motif[motif_i] =='K') && + ((seq_c[seq_i]=='G') || (seq_c[seq_i]=='T'))) + motif_i++; + else if ((a_motif[motif_i] =='V') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C') || + (seq_c[seq_i]=='G'))) + motif_i++; + else if ((a_motif[seq_i] =='H') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C') || + (seq_c[seq_i]=='T'))) + motif_i++; + else if ((a_motif[motif_i] =='D') && + ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='G') || + (seq_c[seq_i]=='T'))) + motif_i++; + else if ((a_motif[motif_i] =='B') && + ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='G') || + (seq_c[seq_i]=='T'))) + motif_i++; + + else + { + seq_i -= motif_i; + motif_i = 0; + } + + // end Nora stuff, now we see if a match is found this pass + if (motif_i == motif_len) + { + //cout << "!!"; + motif_match_starts->push_back(seq_i - motif_len + 1); + motif_i = 0; + } + + seq_i++; + } + cout << endl; +} + diff --git a/alg/sequence.cxx b/alg/sequence.cxx deleted file mode 100644 index 8afe8f0..0000000 --- a/alg/sequence.cxx +++ /dev/null @@ -1,721 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- sequence.cc ----------- -// ---------------------------------------- - -#include "sequence.hh" -#include "mussa_exceptions.hh" - -#include -#include - -using namespace std; - -Sequence::Sequence() -{ -} - -Sequence::Sequence(string seq) -{ - set_filtered_sequence(seq); -} - -Sequence &Sequence::operator=(const Sequence& s) -{ - if (this != &s) { - sequence = s.sequence; - header = s.header; - species = s.species; - annots = s.annots; - } - return *this; -} - -Sequence &Sequence::operator=(const std::string& s) -{ - set_filtered_sequence(s); - return *this; -} - -//! load a fasta file into a sequence -/*! - * \param file_path the location of the fasta file in the filesystem - * \param seq_num which sequence in the file to load - * \param start_index starting position in the fasta sequence, 0 for beginning - * \param end_index ending position in the fasta sequence, 0 for end - * \return error message, empty string if no error. (gag!) - */ -void -Sequence::load_fasta(string file_path, int seq_num, - int start_index, int end_index) -{ - fstream data_file; - string file_data_line; - int header_counter = 0; - bool read_seq = true; - string rev_comp; - string sequence_raw; - string seq_tmp; // holds sequence during basic filtering - - data_file.open(file_path.c_str(), ios::in); - - if (!data_file) - { - throw mussa_load_error("Sequence File: " + file_path + " not found"); - } - // if file opened okay, read it - else - { - // search for the header of the fasta sequence we want - while ( (!data_file.eof()) && (header_counter < seq_num) ) - { - getline(data_file,file_data_line); - if (file_data_line.substr(0,1) == ">") - header_counter++; - } - - header = file_data_line.substr(1); - - sequence_raw = ""; - - while ( !data_file.eof() && read_seq ) - { - getline(data_file,file_data_line); - if (file_data_line.substr(0,1) == ">") - read_seq = false; - else sequence_raw += file_data_line; - } - - data_file.close(); - - // Lastly, if subselection of the sequence was specified we keep cut out - // and only keep that part - // end_index = 0 means no end was specified, so cut to the end - if (end_index == 0) - end_index = sequence_raw.size(); - - // sequence filtering for upcasing agctn and convert non AGCTN to N - set_filtered_sequence(sequence_raw, start_index, end_index-start_index); - } -} - -void Sequence::set_filtered_sequence(const string &old_seq, - string::size_type start, - string::size_type count) -{ - char conversionTable[257]; - - if ( count == 0) - count = old_seq.size() - start; - sequence.clear(); - sequence.reserve(count); - - // Make a conversion table - - // everything we don't specify below will become 'N' - for(int table_i=0; table_i < 256; table_i++) - { - conversionTable[table_i] = 'N'; - } - // add end of string character for printing out table for testing purposes - conversionTable[256] = '\0'; - - // we want these to map to themselves - ie not to change - conversionTable[(int)'A'] = 'A'; - conversionTable[(int)'T'] = 'T'; - conversionTable[(int)'G'] = 'G'; - conversionTable[(int)'C'] = 'C'; - // this is to upcase - conversionTable[(int)'a'] = 'A'; - conversionTable[(int)'t'] = 'T'; - conversionTable[(int)'g'] = 'G'; - conversionTable[(int)'c'] = 'C'; - - // finally, the actual conversion loop - for(string::size_type seq_index = 0; seq_index < count; seq_index++) - { - sequence += conversionTable[ (int)old_seq[seq_index+start]]; - } -} - - // this doesn't work properly under gcc 3.x ... it can't recognize toupper - //transform(sequence.begin(), sequence.end(), sequence.begin(), toupper); - - -void -Sequence::load_annot(string file_path, int start_index, int end_index) -{ - fstream data_file; - string file_data_line; - annot an_annot; - string::size_type space_split_i; - string annot_value; - list::iterator list_i; - string err_msg; - - - annots.clear(); - data_file.open(file_path.c_str(), ios::in); - - if (!data_file) - { - throw mussa_load_error("Sequence File: " + file_path + " not found"); - } - // if file opened okay, read it - else - { - getline(data_file,file_data_line); - species = file_data_line; - - // end_index = 0 means no end was specified, so cut to the end - if (end_index == 0) - end_index = sequence.length(); - - //cout << "START: " << start_index << " END: " << end_index << endl; - - while ( !data_file.eof() ) - { - getline(data_file,file_data_line); - if (file_data_line != "") - { - // need to get 4 values...almost same code 4 times... - // get annot start index - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.start = atoi (annot_value.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - // get annot end index - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.end = atoi (annot_value.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - - //cout << "seq, annots: " << an_annot.start << ", " << an_annot.end - // << endl; - - // get annot name - space_split_i = file_data_line.find(" "); - if (space_split_i == string::npos) // no entries for name & type - { - cout << "seq, annots - no name or type\n"; - an_annot.name = ""; - an_annot.type = ""; - } - else - { - annot_value = file_data_line.substr(0,space_split_i); - an_annot.name = annot_value; - file_data_line = file_data_line.substr(space_split_i+1); - // get annot type - space_split_i = file_data_line.find(" "); - if (space_split_i == string::npos) // no entry for type - an_annot.type = ""; - else - { - annot_value = file_data_line.substr(0,space_split_i); - an_annot.type = annot_value; - } - } - - - // add annot to list if it falls within the range of sequence specified - if ((start_index <= an_annot.start) && (end_index >= an_annot.end)) - { - an_annot.start -= start_index; - an_annot.end -= start_index; - annots.push_back(an_annot); - } - else - cout << "FAILED!!!!!!\n"; - } - } - - data_file.close(); - /* - // debugging check - for(list_i = annots.begin(); list_i != annots.end(); ++list_i) - { - cout << (*list_i).start << "," << (*list_i).end << "\t"; - cout << (*list_i).name << "\t" << (*list_i).type << endl; - } - */ - } -} - -bool Sequence::empty() const -{ - return (size() == 0); -} - -const std::list Sequence::annotations() const -{ - return annots; -} - -string::size_type Sequence::length() const -{ - return size(); -} - -string::size_type Sequence::size() const -{ - return sequence.size(); -} - -Sequence::iterator Sequence::begin() -{ - return sequence.begin(); -} - -Sequence::const_iterator Sequence::begin() const -{ - return sequence.begin(); -} - -Sequence::iterator Sequence::end() -{ - return sequence.end(); -} - -Sequence::const_iterator Sequence::end() const -{ - return sequence.end(); -} - - -const string& -Sequence::get_seq() const -{ - return sequence; -} - - -string -Sequence::subseq(int start, int end) const -{ - return sequence.substr(start, end); -} - - -const char * -Sequence::c_seq() const -{ - return sequence.c_str(); -} - -string -Sequence::rev_comp() const -{ - string rev_comp; - char conversionTable[257]; - int seq_i, table_i, len; - - len = sequence.length(); - rev_comp.reserve(len); - // make a conversion table - // init all parts of conversion table to '~' character - // '~' I doubt will ever appear in a sequence file (jeez, I hope) - // and may the fleas of 1000 camels infest the genitals of any biologist (and - // seven generations of their progeny) who decides to make it mean - // something special!!! - // PS - double the curse for any smartass non-biologist who tries it as well - for(table_i=0; table_i < 256; table_i++) - { - conversionTable[table_i] = '~'; - } - // add end of string character for printing out table for testing purposes - conversionTable[256] = '\0'; - - // add in the characters for the bases we want to convert - conversionTable[(int)'A'] = 'T'; - conversionTable[(int)'T'] = 'A'; - conversionTable[(int)'G'] = 'C'; - conversionTable[(int)'C'] = 'G'; - conversionTable[(int)'N'] = 'N'; - - // finally, the actual conversion loop - for(seq_i = len - 1; seq_i >= 0; seq_i--) - { - table_i = (int) sequence[seq_i]; - rev_comp += conversionTable[table_i]; - } - - return rev_comp; -} - - -const string& -Sequence::get_header() const -{ - return header; -} -/* -//FIXME: i don't think this code is callable -string -Sequence::sp_name() const -{ - return species; -} -*/ - -void -Sequence::set_seq(const string& a_seq) -{ - set_filtered_sequence(a_seq); -} - - -/* -string -Sequence::species() -{ - return species; -} -*/ - -void -Sequence::clear() -{ - sequence = ""; - header = ""; - species = ""; - annots.clear(); -} - -void -Sequence::save(fstream &save_file) - //string save_file_path) -{ - //fstream save_file; - list::iterator annots_i; - - // not sure why, or if i'm doing something wrong, but can't seem to pass - // file pointers down to this method from the mussa control class - // so each call to save a sequence appends to the file started by mussa_class - //save_file.open(save_file_path.c_str(), ios::app); - - save_file << "" << endl; - save_file << sequence << endl; - save_file << "" << endl; - - save_file << "" << endl; - save_file << species << endl; - for (annots_i = annots.begin(); annots_i != annots.end(); ++annots_i) - { - save_file << annots_i->start << " " << annots_i->end << " " ; - save_file << annots_i->name << " " << annots_i->type << endl; - } - save_file << "" << endl; - //save_file.close(); -} - -void -Sequence::load_museq(string load_file_path, int seq_num) -{ - fstream load_file; - string file_data_line; - int seq_counter; - annot an_annot; - string::size_type space_split_i; - string annot_value; - - annots.clear(); - load_file.open(load_file_path.c_str(), ios::in); - - seq_counter = 0; - // search for the seq_num-th sequence - while ( (!load_file.eof()) && (seq_counter < seq_num) ) - { - getline(load_file,file_data_line); - if (file_data_line == "") - seq_counter++; - } - getline(load_file, file_data_line); - sequence = file_data_line; - getline(load_file, file_data_line); - getline(load_file, file_data_line); - if (file_data_line == "") - { - getline(load_file, file_data_line); - species = file_data_line; - while ( (!load_file.eof()) && (file_data_line != "") ) - { - getline(load_file,file_data_line); - if ((file_data_line != "") && (file_data_line != "")) - { - // need to get 4 values...almost same code 4 times... - // get annot start index - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.start = atoi (annot_value.c_str()); - file_data_line = file_data_line.substr(space_split_i+1); - // get annot end index - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.end = atoi (annot_value.c_str()); - - if (space_split_i == string::npos) // no entry for type or name - { - cout << "seq, annots - no type or name\n"; - an_annot.type = ""; - an_annot.name = ""; - } - else // else get annot type - { - file_data_line = file_data_line.substr(space_split_i+1); - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.type = annot_value; - if (space_split_i == string::npos) // no entry for name - { - cout << "seq, annots - no name\n"; - an_annot.name = ""; - } - else // get annot name - { - file_data_line = file_data_line.substr(space_split_i+1); - space_split_i = file_data_line.find(" "); - annot_value = file_data_line.substr(0,space_split_i); - an_annot.type = annot_value; - } - } - annots.push_back(an_annot); // don't forget to actually add the annot - } - //cout << "seq, annots: " << an_annot.start << ", " << an_annot.end - // << "-->" << an_annot.type << "::" << an_annot.name << endl; - } - } - load_file.close(); -} - - -string -Sequence::rc_motif(string a_motif) -{ - string rev_comp; - char conversionTable[257]; - int seq_i, table_i, len; - - len = a_motif.length(); - rev_comp.reserve(len); - - for(table_i=0; table_i < 256; table_i++) - { - conversionTable[table_i] = '~'; - } - // add end of string character for printing out table for testing purposes - conversionTable[256] = '\0'; - - // add in the characters for the bases we want to convert (IUPAC) - conversionTable[(int)'A'] = 'T'; - conversionTable[(int)'T'] = 'A'; - conversionTable[(int)'G'] = 'C'; - conversionTable[(int)'C'] = 'G'; - conversionTable[(int)'N'] = 'N'; - conversionTable[(int)'M'] = 'K'; - conversionTable[(int)'R'] = 'Y'; - conversionTable[(int)'W'] = 'W'; - conversionTable[(int)'S'] = 'S'; - conversionTable[(int)'Y'] = 'R'; - conversionTable[(int)'K'] = 'M'; - conversionTable[(int)'V'] = 'B'; - conversionTable[(int)'H'] = 'D'; - conversionTable[(int)'D'] = 'H'; - conversionTable[(int)'B'] = 'V'; - - // finally, the actual conversion loop - for(seq_i = len - 1; seq_i >= 0; seq_i--) - { - //cout << "** i = " << seq_i << " bp = " << - table_i = (int) a_motif[seq_i]; - rev_comp += conversionTable[table_i]; - } - - //cout << "seq: " << a_motif << endl; - //cout << "rc: " << rev_comp << endl; - - return rev_comp; -} - -string -Sequence::motif_validate(string a_motif) -{ - string valid_motif; - int seq_i, len; - - len = a_motif.length(); - valid_motif.reserve(len); - - // this just upcases IUPAC symbols. Eventually should return an error if non IUPAC is present. - // 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')) - valid_motif += 'A'; - else if ((a_motif[seq_i] == 't') || (a_motif[seq_i] == 'T')) - valid_motif += 'T'; - else if ((a_motif[seq_i] == 'g') || (a_motif[seq_i] == 'G')) - valid_motif += 'G'; - else if ((a_motif[seq_i] == 'c') || (a_motif[seq_i] == 'C')) - valid_motif += 'C'; - else if ((a_motif[seq_i] == 'n') || (a_motif[seq_i] == 'N')) - valid_motif += 'N'; - else if ((a_motif[seq_i] == 'm') || (a_motif[seq_i] == 'M')) - valid_motif += 'M'; - else if ((a_motif[seq_i] == 'r') || (a_motif[seq_i] == 'R')) - valid_motif += 'R'; - else if ((a_motif[seq_i] == 'w') || (a_motif[seq_i] == 'W')) - valid_motif += 'W'; - else if ((a_motif[seq_i] == 's') || (a_motif[seq_i] == 'S')) - valid_motif += 'S'; - else if ((a_motif[seq_i] == 'y') || (a_motif[seq_i] == 'Y')) - valid_motif += 'Y'; - else if ((a_motif[seq_i] == 'k') || (a_motif[seq_i] == 'K')) - valid_motif += 'G'; - else if ((a_motif[seq_i] == 'v') || (a_motif[seq_i] == 'V')) - valid_motif += 'V'; - else if ((a_motif[seq_i] == 'h') || (a_motif[seq_i] == 'H')) - valid_motif += 'H'; - else if ((a_motif[seq_i] == 'd') || (a_motif[seq_i] == 'D')) - valid_motif += 'D'; - else if ((a_motif[seq_i] == 'b') || (a_motif[seq_i] == 'B')) - valid_motif += 'B'; - } - - //cout << "valid_motif is: " << valid_motif << endl; - - return valid_motif; -} - - -vector -Sequence::find_motif(string a_motif) -{ - vector motif_match_starts; - string a_motif_rc; - - - motif_match_starts.clear(); - - //cout << "motif is: " << a_motif << endl; - a_motif = motif_validate(a_motif); - //cout << "motif is: " << a_motif << endl; - - - if (a_motif != "") - { - //cout << "Sequence: none blank motif\n"; - motif_scan(a_motif, &motif_match_starts); - - a_motif_rc = rc_motif(a_motif); - // make sure not to do search again if it is a palindrome - if (a_motif_rc != a_motif) - motif_scan(a_motif_rc, &motif_match_starts); - } - return motif_match_starts; -} - -void -Sequence::motif_scan(string a_motif, vector * motif_match_starts) -{ - char * seq_c; - string::size_type seq_i; - int motif_i, motif_len; - - // faster to loop thru the sequence as a old c string (ie char array) - seq_c = (char*)sequence.c_str(); - //cout << "Sequence: motif, seq len = " << sequence.length() << endl; - motif_len = a_motif.length(); - - //cout << "motif_length: " << motif_len << endl; - //cout << "RAAARRRRR\n"; - - motif_i = 0; - - //cout << "motif: " << a_motif << endl; - - //cout << "Sequence: motif, length= " << length << endl; - seq_i = 0; - while (seq_i < sequence.length()) - { - //cout << seq_c[seq_i]; - //cout << seq_c[seq_i] << "?" << a_motif[motif_i] << ":" << motif_i << " "; - // this is pretty much a straight translation of Nora's python code - // to match iupac letter codes - if (a_motif[motif_i] =='N') - motif_i++; - else if (a_motif[motif_i] == seq_c[seq_i]) - motif_i++; - else if ((a_motif[motif_i] =='M') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C'))) - motif_i++; - else if ((a_motif[motif_i] =='R') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='G'))) - motif_i++; - else if ((a_motif[motif_i] =='W') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='T'))) - motif_i++; - else if ((a_motif[motif_i] =='S') && - ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='G'))) - motif_i++; - else if ((a_motif[motif_i] =='Y') && - ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='T'))) - motif_i++; - else if ((a_motif[motif_i] =='K') && - ((seq_c[seq_i]=='G') || (seq_c[seq_i]=='T'))) - motif_i++; - else if ((a_motif[motif_i] =='V') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C') || - (seq_c[seq_i]=='G'))) - motif_i++; - else if ((a_motif[seq_i] =='H') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='C') || - (seq_c[seq_i]=='T'))) - motif_i++; - else if ((a_motif[motif_i] =='D') && - ((seq_c[seq_i]=='A') || (seq_c[seq_i]=='G') || - (seq_c[seq_i]=='T'))) - motif_i++; - else if ((a_motif[motif_i] =='B') && - ((seq_c[seq_i]=='C') || (seq_c[seq_i]=='G') || - (seq_c[seq_i]=='T'))) - motif_i++; - - else - { - seq_i -= motif_i; - motif_i = 0; - } - - // end Nora stuff, now we see if a match is found this pass - if (motif_i == motif_len) - { - //cout << "!!"; - motif_match_starts->push_back(seq_i - motif_len + 1); - motif_i = 0; - } - - seq_i++; - } - cout << endl; -} - diff --git a/alg/sequence.hh b/alg/sequence.hh deleted file mode 100644 index 39313be..0000000 --- a/alg/sequence.hh +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef _MUSSA_SEQUENCE_H_ -#define _MUSSA_SEQUENCE_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -// ---------------------------------------- -// ---------- sequence.hh ----------- -// ---------------------------------------- - - -#include -#include -#include -#include - -// Sequence data class - -//! Attach annotation information to a sequence track -struct annot -{ - int start, end; - std::string name, type; -}; - -//! sequence track for mussa. -class Sequence -{ - friend class ConnView; - friend class SeqView; - private: - std::string sequence; - std::string header; - std::string species; - - std::list annots; - - void motif_scan(std::string a_motif, std::vector * 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; - typedef std::string::size_type size_type; - - Sequence(); - Sequence(std::string seq); - //! assignment to constant sequences - Sequence &operator=(const Sequence&); - Sequence &operator=(const std::string &); - - //! set sequence to a (sub)string containing nothing but AGCTN - void set_filtered_sequence(const std::string& seq, - std::string::size_type start=0, - std::string::size_type count=0); - - //! load sequence AGCT from fasta file - /*! \throws mussa_load_error - */ - void load_fasta(const std::string file_path, int seq_num=1, - int start_index=0, int end_index=0); - //! load sequence annotations - /*! \throws mussa_load_error - */ - void load_annot(const std::string file_path, int start_index, int end_index); - const std::list annotations() const; - - // simple access functions - void set_seq(const std::string& a_seq); - const std::string& get_seq() const; - const char *c_seq() const; - std::string subseq(int start, int end) const; - std::string rev_comp() const; - - // string-like functions - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - bool empty() const; - //! alias for size, (included as this is much like a string) - std::string::size_type length() const; - //! the number of base pairs in this sequence - std::string::size_type size() const; - void clear(); - - const std::string& get_header() const; - std::vector find_motif(std::string a_motif); - void save(std::fstream &save_file); - void load_museq(std::string load_file_path, int seq_num); -}; -#endif diff --git a/alg/sequence.hpp b/alg/sequence.hpp new file mode 100644 index 0000000..39313be --- /dev/null +++ b/alg/sequence.hpp @@ -0,0 +1,98 @@ +#ifndef _MUSSA_SEQUENCE_H_ +#define _MUSSA_SEQUENCE_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +// ---------------------------------------- +// ---------- sequence.hh ----------- +// ---------------------------------------- + + +#include +#include +#include +#include + +// Sequence data class + +//! Attach annotation information to a sequence track +struct annot +{ + int start, end; + std::string name, type; +}; + +//! sequence track for mussa. +class Sequence +{ + friend class ConnView; + friend class SeqView; + private: + std::string sequence; + std::string header; + std::string species; + + std::list annots; + + void motif_scan(std::string a_motif, std::vector * 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; + typedef std::string::size_type size_type; + + Sequence(); + Sequence(std::string seq); + //! assignment to constant sequences + Sequence &operator=(const Sequence&); + Sequence &operator=(const std::string &); + + //! set sequence to a (sub)string containing nothing but AGCTN + void set_filtered_sequence(const std::string& seq, + std::string::size_type start=0, + std::string::size_type count=0); + + //! load sequence AGCT from fasta file + /*! \throws mussa_load_error + */ + void load_fasta(const std::string file_path, int seq_num=1, + int start_index=0, int end_index=0); + //! load sequence annotations + /*! \throws mussa_load_error + */ + void load_annot(const std::string file_path, int start_index, int end_index); + const std::list annotations() const; + + // simple access functions + void set_seq(const std::string& a_seq); + const std::string& get_seq() const; + const char *c_seq() const; + std::string subseq(int start, int end) const; + std::string rev_comp() const; + + // string-like functions + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + bool empty() const; + //! alias for size, (included as this is much like a string) + std::string::size_type length() const; + //! the number of base pairs in this sequence + std::string::size_type size() const; + void clear(); + + const std::string& get_header() const; + std::vector find_motif(std::string a_motif); + void save(std::fstream &save_file); + void load_museq(std::string load_file_path, int seq_num); +}; +#endif diff --git a/alg/test/module.mk b/alg/test/module.mk index e1a5626..c02382d 100644 --- a/alg/test/module.mk +++ b/alg/test/module.mk @@ -1,16 +1,16 @@ CURDIR := $(BASEDIR)alg/test/ -SOURCES.cxx := test_conserved_path.cxx \ - test_flp.cxx \ - test_glsequence.cxx \ - test_color.cxx \ - test_main.cxx \ - test_mussa.cxx \ - test_nway.cxx \ - test_sequence.cxx +SOURCES.cpp := test_conserved_path.cpp \ + test_flp.cpp \ + test_glsequence.cpp \ + test_color.cpp \ + test_main.cpp \ + test_mussa.cpp \ + test_nway.cpp \ + test_sequence.cpp -TESTSRC := $(addprefix $(CURDIR), $(SOURCES.cxx)) -TESTOBJ := $(TESTSRC:.cxx=$(OBJEXT)) +TESTSRC := $(addprefix $(CURDIR), $(SOURCES.cpp)) +TESTOBJ := $(TESTSRC:.cpp=$(OBJEXT)) SRC += $(TESTSRC) CXXFLAGS += diff --git a/alg/test/test_color.cpp b/alg/test/test_color.cpp new file mode 100644 index 0000000..a3d4134 --- /dev/null +++ b/alg/test/test_color.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "alg/color.hpp" + +using namespace std; + +BOOST_AUTO_TEST_CASE ( color ) +{ + const float tolerance = 1e-6; + const float zero = 0.0; + const float dotone = 0.1; + const float dottwo = 0.2; + const float dotthree = 0.3; + const float dotfour = 0.4; + Color c1; + BOOST_CHECK_CLOSE (c1.r(), zero, tolerance ); + BOOST_CHECK_CLOSE (c1.g(), zero, tolerance ); + BOOST_CHECK_CLOSE (c1.b(), zero, tolerance ); + BOOST_CHECK_CLOSE (c1.a(), zero, tolerance ); + + Color c2(dotone, dottwo, dotthree, dotfour); + BOOST_CHECK_CLOSE (c2.r(), dotone, tolerance ); + BOOST_CHECK_CLOSE (c2.g(), dottwo, tolerance ); + BOOST_CHECK_CLOSE (c2.b(), dotthree, tolerance ); + BOOST_CHECK_CLOSE (c2.a(), dotfour, tolerance ); + + Color c3(c2); + BOOST_CHECK_CLOSE (c3.r(), dotone, tolerance ); + BOOST_CHECK_CLOSE (c3.g(), dottwo, tolerance ); + BOOST_CHECK_CLOSE (c3.b(), dotthree, tolerance ); + BOOST_CHECK_CLOSE (c3.a(), dotfour, tolerance ); + BOOST_CHECK_EQUAL ( c2, c3 ); + + const float *colors = c3.get(); + BOOST_CHECK_CLOSE (colors[Color::RedChannel ], dotone, tolerance ); + BOOST_CHECK_CLOSE (colors[Color::GreenChannel ], dottwo, tolerance ); + BOOST_CHECK_CLOSE (colors[Color::BlueChannel ], dotthree, tolerance ); + BOOST_CHECK_CLOSE (colors[Color::AlphaChannel ], dotfour, tolerance ); +} + + diff --git a/alg/test/test_color.cxx b/alg/test/test_color.cxx deleted file mode 100644 index e457bd0..0000000 --- a/alg/test/test_color.cxx +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "alg/color.h" - -using namespace std; - -BOOST_AUTO_TEST_CASE ( color ) -{ - const float tolerance = 1e-6; - const float zero = 0.0; - const float dotone = 0.1; - const float dottwo = 0.2; - const float dotthree = 0.3; - const float dotfour = 0.4; - Color c1; - BOOST_CHECK_CLOSE (c1.r(), zero, tolerance ); - BOOST_CHECK_CLOSE (c1.g(), zero, tolerance ); - BOOST_CHECK_CLOSE (c1.b(), zero, tolerance ); - BOOST_CHECK_CLOSE (c1.a(), zero, tolerance ); - - Color c2(dotone, dottwo, dotthree, dotfour); - BOOST_CHECK_CLOSE (c2.r(), dotone, tolerance ); - BOOST_CHECK_CLOSE (c2.g(), dottwo, tolerance ); - BOOST_CHECK_CLOSE (c2.b(), dotthree, tolerance ); - BOOST_CHECK_CLOSE (c2.a(), dotfour, tolerance ); - - Color c3(c2); - BOOST_CHECK_CLOSE (c3.r(), dotone, tolerance ); - BOOST_CHECK_CLOSE (c3.g(), dottwo, tolerance ); - BOOST_CHECK_CLOSE (c3.b(), dotthree, tolerance ); - BOOST_CHECK_CLOSE (c3.a(), dotfour, tolerance ); - BOOST_CHECK_EQUAL ( c2, c3 ); - - const float *colors = c3.get(); - BOOST_CHECK_CLOSE (colors[Color::RedChannel ], dotone, tolerance ); - BOOST_CHECK_CLOSE (colors[Color::GreenChannel ], dottwo, tolerance ); - BOOST_CHECK_CLOSE (colors[Color::BlueChannel ], dotthree, tolerance ); - BOOST_CHECK_CLOSE (colors[Color::AlphaChannel ], dotfour, tolerance ); -} - - diff --git a/alg/test/test_conserved_path.cpp b/alg/test/test_conserved_path.cpp new file mode 100644 index 0000000..b28c635 --- /dev/null +++ b/alg/test/test_conserved_path.cpp @@ -0,0 +1,119 @@ +#include +#include +using namespace boost::assign; + +#include +using namespace std; + +#include "alg/conserved_path.hpp" + +//! write tests for our conserved path types (just to make sure they +//! don't change on us. +BOOST_AUTO_TEST_CASE ( conserved_path_simple ) +{ + vector path; + path += 3,4,5,1; // magic from boost assign + + ConservedPath cp1; + BOOST_CHECK_EQUAL( cp1.size(), 0 ); //empty + BOOST_CHECK( cp1.begin() == cp1.end() ); + + cp1.score = 18; + cp1.track_indexes = path; + BOOST_CHECK_EQUAL( cp1.size(), path.size() ); + + ConservedPath cp2(18, path); + BOOST_CHECK_EQUAL (cp1, cp2); + BOOST_CHECK_EQUAL( cp2.size(), path.size() ); + + ConservedPath::iterator cp2_itor; + vector::iterator path_itor; + for (cp2_itor = cp2.begin(), path_itor = path.begin(); + cp2_itor != cp2.end() && path_itor != path.end(); + ++cp2_itor, ++path_itor) + { + BOOST_CHECK_EQUAL( *cp2_itor, *path_itor ); + } + + ConservedPath cp3( cp2 ); + BOOST_CHECK_EQUAL( cp3.size(), cp2.size() ); + ConservedPath::iterator cp3_itor; + for (cp2_itor = cp2.begin(), cp3_itor = cp3.begin(); + cp2_itor != cp2.end() && cp3_itor != cp3.end(); + ++cp2_itor, ++cp3_itor) + { + BOOST_CHECK_EQUAL( *cp2_itor, *cp3_itor ); + } +} + +//! do vector like operations work? +BOOST_AUTO_TEST_CASE ( conserved_path_vector ) +{ + ConservedPath cp; + cp.score = 21.0; + + BOOST_CHECK_EQUAL( cp.size(), 0 ); + cp.push_back( 3 ); + BOOST_CHECK_EQUAL( cp.size(), 1); + BOOST_CHECK_EQUAL( cp[0], 3 ); + cp.push_back( 4 ); + BOOST_CHECK_EQUAL( cp.size(), 2); + BOOST_CHECK_EQUAL( cp[1], 4 ); + cp.pop_back(); + BOOST_CHECK_EQUAL( cp.size(), 1 ); +} + +BOOST_AUTO_TEST_CASE ( extended_conserved_path_simple ) +{ + vector path; + path += 3,4,5,1; // magic from boost assign + + ExtendedConservedPath ecp1; + ecp1.window_size = 30; + ecp1.score = 18; + ecp1.track_indexes = path; + BOOST_CHECK_EQUAL ( ecp1.size(), path.size() ); + + ExtendedConservedPath ecp2(30, 18.0, path); + BOOST_CHECK_EQUAL ( ecp1, ecp2 ); + BOOST_CHECK_EQUAL ( ecp2.size(), path.size() ); + + ExtendedConservedPath ecp_ne(35, 20.0, path); + BOOST_CHECK(ecp2 != ecp_ne); + + ConservedPath cp1; + cp1.score = 18; + cp1.track_indexes = path; + + ExtendedConservedPath ecp3(30, cp1); + BOOST_CHECK_EQUAL( ecp2, ecp3 ); + BOOST_CHECK_EQUAL( ecp3.size(), path.size() ); +} + +//! Can we grow succesfully? +BOOST_AUTO_TEST_CASE ( extended_conserved_path_growth ) +{ + vector path_base; + path_base += 3,4,5,1; // magic from boost assign + vector path_next; + path_next += 4,5,6,2; + vector path_next_reversed; + path_next_reversed += 4,5,6,-2; + vector path_not_next; + path_not_next += 4,5,6,5; + const int window_size = 4; + + ExtendedConservedPath ecp_base(window_size, 20, path_base); + ConservedPath cp_next(25, path_next); + ConservedPath cp_next_reversed(25, path_next_reversed); + ConservedPath cp_not_next(22, path_not_next); + + BOOST_CHECK(ecp_base.nextTo(cp_next)); + BOOST_CHECK(!ecp_base.nextTo(cp_not_next)); + // FIXME: should something like this actually extend? + BOOST_CHECK(!ecp_base.nextTo(cp_next_reversed)); + + const int growth = 2; + ecp_base.extend(growth); + BOOST_CHECK_EQUAL( ecp_base.window_size, window_size + growth ); +} diff --git a/alg/test/test_conserved_path.cxx b/alg/test/test_conserved_path.cxx deleted file mode 100644 index b248470..0000000 --- a/alg/test/test_conserved_path.cxx +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -using namespace boost::assign; - -#include -using namespace std; - -#include "alg/conserved_path.h" - -//! write tests for our conserved path types (just to make sure they -//! don't change on us. -BOOST_AUTO_TEST_CASE ( conserved_path_simple ) -{ - vector path; - path += 3,4,5,1; // magic from boost assign - - ConservedPath cp1; - BOOST_CHECK_EQUAL( cp1.size(), 0 ); //empty - BOOST_CHECK( cp1.begin() == cp1.end() ); - - cp1.score = 18; - cp1.track_indexes = path; - BOOST_CHECK_EQUAL( cp1.size(), path.size() ); - - ConservedPath cp2(18, path); - BOOST_CHECK_EQUAL (cp1, cp2); - BOOST_CHECK_EQUAL( cp2.size(), path.size() ); - - ConservedPath::iterator cp2_itor; - vector::iterator path_itor; - for (cp2_itor = cp2.begin(), path_itor = path.begin(); - cp2_itor != cp2.end() && path_itor != path.end(); - ++cp2_itor, ++path_itor) - { - BOOST_CHECK_EQUAL( *cp2_itor, *path_itor ); - } - - ConservedPath cp3( cp2 ); - BOOST_CHECK_EQUAL( cp3.size(), cp2.size() ); - ConservedPath::iterator cp3_itor; - for (cp2_itor = cp2.begin(), cp3_itor = cp3.begin(); - cp2_itor != cp2.end() && cp3_itor != cp3.end(); - ++cp2_itor, ++cp3_itor) - { - BOOST_CHECK_EQUAL( *cp2_itor, *cp3_itor ); - } -} - -//! do vector like operations work? -BOOST_AUTO_TEST_CASE ( conserved_path_vector ) -{ - ConservedPath cp; - cp.score = 21.0; - - BOOST_CHECK_EQUAL( cp.size(), 0 ); - cp.push_back( 3 ); - BOOST_CHECK_EQUAL( cp.size(), 1); - BOOST_CHECK_EQUAL( cp[0], 3 ); - cp.push_back( 4 ); - BOOST_CHECK_EQUAL( cp.size(), 2); - BOOST_CHECK_EQUAL( cp[1], 4 ); - cp.pop_back(); - BOOST_CHECK_EQUAL( cp.size(), 1 ); -} - -BOOST_AUTO_TEST_CASE ( extended_conserved_path_simple ) -{ - vector path; - path += 3,4,5,1; // magic from boost assign - - ExtendedConservedPath ecp1; - ecp1.window_size = 30; - ecp1.score = 18; - ecp1.track_indexes = path; - BOOST_CHECK_EQUAL ( ecp1.size(), path.size() ); - - ExtendedConservedPath ecp2(30, 18.0, path); - BOOST_CHECK_EQUAL ( ecp1, ecp2 ); - BOOST_CHECK_EQUAL ( ecp2.size(), path.size() ); - - ExtendedConservedPath ecp_ne(35, 20.0, path); - BOOST_CHECK(ecp2 != ecp_ne); - - ConservedPath cp1; - cp1.score = 18; - cp1.track_indexes = path; - - ExtendedConservedPath ecp3(30, cp1); - BOOST_CHECK_EQUAL( ecp2, ecp3 ); - BOOST_CHECK_EQUAL( ecp3.size(), path.size() ); -} - -//! Can we grow succesfully? -BOOST_AUTO_TEST_CASE ( extended_conserved_path_growth ) -{ - vector path_base; - path_base += 3,4,5,1; // magic from boost assign - vector path_next; - path_next += 4,5,6,2; - vector path_next_reversed; - path_next_reversed += 4,5,6,-2; - vector path_not_next; - path_not_next += 4,5,6,5; - const int window_size = 4; - - ExtendedConservedPath ecp_base(window_size, 20, path_base); - ConservedPath cp_next(25, path_next); - ConservedPath cp_next_reversed(25, path_next_reversed); - ConservedPath cp_not_next(22, path_not_next); - - BOOST_CHECK(ecp_base.nextTo(cp_next)); - BOOST_CHECK(!ecp_base.nextTo(cp_not_next)); - // FIXME: should something like this actually extend? - BOOST_CHECK(!ecp_base.nextTo(cp_next_reversed)); - - const int growth = 2; - ecp_base.extend(growth); - BOOST_CHECK_EQUAL( ecp_base.window_size, window_size + growth ); -} diff --git a/alg/test/test_flp.cpp b/alg/test/test_flp.cpp new file mode 100644 index 0000000..c3c9437 --- /dev/null +++ b/alg/test/test_flp.cpp @@ -0,0 +1,98 @@ +#include +#include + +#include +#include +#include + +#include "alg/flp.hpp" +#include "alg/sequence.hpp" +#include +#include + +BOOST_AUTO_TEST_CASE( flp_simple ) +{ + FLPs f; + f.setup(5, 4); + f.seqcomp("AAGGTAAGGT", "AAGGTAAGGT", false); + + // are the match_locations correct? + for (int i=0; i != f.size(); i++) + { + std::list window_locations = f.match_locations(i); + std::list window_matches = f.matches(i); + std::list::iterator loc_i = window_locations.begin(); + std::list::iterator match_i = window_matches.begin(); + for (; loc_i != window_locations.end(); ++loc_i, ++match_i) + { + // I'm missing pythons easy lists and in operator here. + if (i == 0) BOOST_CHECK( *loc_i == 0 || *loc_i == 5); + else if (i == 1) BOOST_CHECK( *loc_i == 1 || *loc_i == 6); + else if (i == 2) BOOST_CHECK( *loc_i == 2 ); + else if (i == 3) BOOST_CHECK( *loc_i == 3 ); + else if (i == 4) BOOST_CHECK( *loc_i == 4 ); + else if (i == 6) BOOST_CHECK( *loc_i == 5 || *loc_i == 0); + BOOST_CHECK_EQUAL( *loc_i, match_i->index ); + } + } +} + +BOOST_AUTO_TEST_CASE( flp_save ) +{ + std::string seq("AAGGCCTTAAGGCCTT"); + int win_size = 4; + FLPs f1; + FLPs f2; + f1.setup(win_size,3); + f1.seqcomp(seq, seq, false); + std::string fname("flp_save_this_is_a_horrible_filename_because_" + "im_too_lazy_to_write_a_portable_mktmp.flp"); + + f1.save(fname); + f2.load(fname); + boost::filesystem::remove( boost::filesystem::path(fname) ); + + BOOST_CHECK_EQUAL( f1.size(), seq.size()-win_size+1); + BOOST_CHECK_EQUAL( f2.size(), seq.size()-win_size+1); + BOOST_CHECK_EQUAL( f1.size(), f2.size() ); + for (int win=0; win < f1.size(); ++win) + { + std::list f1_matches = f1.matches(win); + std::list f2_matches = f2.matches(win); + std::list::const_iterator f1_match_i = f1_matches.begin(); + std::list::const_iterator f2_match_i = f2_matches.begin(); + for( ; + f1_match_i != f1_matches.end() && f2_match_i != f2_matches.end(); + ++f1_match_i, ++f2_match_i) + { + BOOST_CHECK_EQUAL( *f1_match_i, *f2_match_i); + } + } +} + +/*! Apparently when we run multiple seqcomps we want to + * save all the FLPs generated + */ +BOOST_AUTO_TEST_CASE( flp_reverse_compliment ) +{ + FLPs f1; + Sequence s1("AAAATTTT"); + Sequence s2("AACAGGGG"); + f1.setup(4,3); + f1.seqcomp(s1.get_seq(), s2.get_seq(), false); + f1.seqcomp(s1.get_seq(), s2.rev_comp(), true); + + FLPs f2; + f2.setup(4,3); + f2.seqcomp(s1.get_seq(), s2.rev_comp(), true); + f2.seqcomp(s1.get_seq(), s2.get_seq(), false); + + // The order of doing the reverse compliment search shouldn't matter + // when we're using exactly the same sequence + BOOST_CHECK_EQUAL( f1.size(), f2.size() ); + for (int i = 0; i < f1.size(); ++i ) + { + BOOST_CHECK_EQUAL( f1.matches(i).size(), f2.matches(i).size() ); + // FIXME: should we test the individual lists? + } +} diff --git a/alg/test/test_flp.cxx b/alg/test/test_flp.cxx deleted file mode 100644 index a89fc70..0000000 --- a/alg/test/test_flp.cxx +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "alg/flp.hh" -#include "alg/sequence.hh" -#include -#include - -BOOST_AUTO_TEST_CASE( flp_simple ) -{ - FLPs f; - f.setup(5, 4); - f.seqcomp("AAGGTAAGGT", "AAGGTAAGGT", false); - - // are the match_locations correct? - for (int i=0; i != f.size(); i++) - { - std::list window_locations = f.match_locations(i); - std::list window_matches = f.matches(i); - std::list::iterator loc_i = window_locations.begin(); - std::list::iterator match_i = window_matches.begin(); - for (; loc_i != window_locations.end(); ++loc_i, ++match_i) - { - // I'm missing pythons easy lists and in operator here. - if (i == 0) BOOST_CHECK( *loc_i == 0 || *loc_i == 5); - else if (i == 1) BOOST_CHECK( *loc_i == 1 || *loc_i == 6); - else if (i == 2) BOOST_CHECK( *loc_i == 2 ); - else if (i == 3) BOOST_CHECK( *loc_i == 3 ); - else if (i == 4) BOOST_CHECK( *loc_i == 4 ); - else if (i == 6) BOOST_CHECK( *loc_i == 5 || *loc_i == 0); - BOOST_CHECK_EQUAL( *loc_i, match_i->index ); - } - } -} - -BOOST_AUTO_TEST_CASE( flp_save ) -{ - std::string seq("AAGGCCTTAAGGCCTT"); - int win_size = 4; - FLPs f1; - FLPs f2; - f1.setup(win_size,3); - f1.seqcomp(seq, seq, false); - std::string fname("flp_save_this_is_a_horrible_filename_because_" - "im_too_lazy_to_write_a_portable_mktmp.flp"); - - f1.save(fname); - f2.load(fname); - boost::filesystem::remove( boost::filesystem::path(fname) ); - - BOOST_CHECK_EQUAL( f1.size(), seq.size()-win_size+1); - BOOST_CHECK_EQUAL( f2.size(), seq.size()-win_size+1); - BOOST_CHECK_EQUAL( f1.size(), f2.size() ); - for (int win=0; win < f1.size(); ++win) - { - std::list f1_matches = f1.matches(win); - std::list f2_matches = f2.matches(win); - std::list::const_iterator f1_match_i = f1_matches.begin(); - std::list::const_iterator f2_match_i = f2_matches.begin(); - for( ; - f1_match_i != f1_matches.end() && f2_match_i != f2_matches.end(); - ++f1_match_i, ++f2_match_i) - { - BOOST_CHECK_EQUAL( *f1_match_i, *f2_match_i); - } - } -} - -/*! Apparently when we run multiple seqcomps we want to - * save all the FLPs generated - */ -BOOST_AUTO_TEST_CASE( flp_reverse_compliment ) -{ - FLPs f1; - Sequence s1("AAAATTTT"); - Sequence s2("AACAGGGG"); - f1.setup(4,3); - f1.seqcomp(s1.get_seq(), s2.get_seq(), false); - f1.seqcomp(s1.get_seq(), s2.rev_comp(), true); - - FLPs f2; - f2.setup(4,3); - f2.seqcomp(s1.get_seq(), s2.rev_comp(), true); - f2.seqcomp(s1.get_seq(), s2.get_seq(), false); - - // The order of doing the reverse compliment search shouldn't matter - // when we're using exactly the same sequence - BOOST_CHECK_EQUAL( f1.size(), f2.size() ); - for (int i = 0; i < f1.size(); ++i ) - { - BOOST_CHECK_EQUAL( f1.matches(i).size(), f2.matches(i).size() ); - // FIXME: should we test the individual lists? - } -} diff --git a/alg/test/test_glsequence.cpp b/alg/test/test_glsequence.cpp new file mode 100644 index 0000000..220b455 --- /dev/null +++ b/alg/test/test_glsequence.cpp @@ -0,0 +1,106 @@ +#include + +#include + +#include "alg/glsequence.hpp" +#include "alg/sequence.hpp" + +using namespace std; + +BOOST_AUTO_TEST_CASE ( glsequence_operator_equal ) +{ + // 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); + BOOST_CHECK (glseq0.sequence().get_seq() == s0); + GlSequence glseq1(seq1); + GlSequence glseq_copy0(glseq0); + + BOOST_CHECK(glseq_copy0.sequence().get_seq() == glseq0.sequence().get_seq()); + BOOST_CHECK( &(glseq_copy0.sequence()) == &(glseq0.sequence())); + + glseq0 = glseq1; + + BOOST_CHECK( glseq0.sequence().get_seq() == s1 ); +} + +BOOST_AUTO_TEST_CASE( glsequence_color ) +{ + 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); + + BOOST_CHECK_EQUAL(s.color(), black ); + s.setColor( c ); + BOOST_CHECK_EQUAL( s.color(), c ); +} + +BOOST_AUTO_TEST_CASE( glsequence_renderable ) +{ + Sequence seq("AAGGCCTT"); + GlSequence s(seq); + + // way more base pairs than viewport pixel width + BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false ); + // way fewer basepairs than viewport pixel width + BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true); +} + +BOOST_AUTO_TEST_CASE( glsequence_sequence ) +{ + string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN"); + string::size_type seqlen = seq_string.size(); + Sequence seq(seq_string); + GlSequence glseq(seq); + + BOOST_CHECK( glseq.sequence_begin(0, 50) == seq.begin() ); + // always make sure we return seq.end() regardless of how much extra + // is asked for + BOOST_CHECK( glseq.sequence_end(0, seqlen+10) == seq.end() ); + // do we get the right end pointer? + BOOST_CHECK( glseq.sequence_end(0, 5) == seq.begin()+5 ); + + // when we request far too much sequence what do we get? + BOOST_CHECK( glseq.sequence_begin(seqlen+10, seqlen+20) == seq.end() ); + BOOST_CHECK( glseq.sequence_end(seqlen+10, seqlen+20) == seq.end() ); + + // we cant ask for reversed sequences with sequence_begin/end + BOOST_CHECK( glseq.sequence_begin(10, 5) == seq.end() ); + BOOST_CHECK( glseq.sequence_end(10, 5) == seq.end() ); + + Sequence::const_iterator seq_itor; + + // if we as for an empty segment? start and end should equal + seq_itor = glseq.sequence_begin(10, 10); + BOOST_CHECK( seq_itor == glseq.sequence_end(10, 10) ); + + // reuse seq_itor downhere + string::const_iterator str_itor; + for(str_itor = seq.begin(), + seq_itor = glseq.sequence_begin(); + str_itor != seq.end() and + seq_itor != glseq.sequence_end(); + ++str_itor, ++seq_itor) + { + BOOST_CHECK_EQUAL( *str_itor, *seq_itor ); + } +} + +// make sure the computation of the leftmost and rightmost base is correct +BOOST_AUTO_TEST_CASE( glsequence_leftright_base ) +{ + std::string seq_string = "AAGGCCTT"; + Sequence seq(seq_string); + GlSequence glseq(seq); + + BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 ); + BOOST_CHECK_EQUAL( glseq.leftbase( 0.5 ), 1 ); + BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() ); + BOOST_CHECK_EQUAL( glseq.rightbase( seq_string.size()-0.5), + seq_string.size()-1); +} diff --git a/alg/test/test_glsequence.cxx b/alg/test/test_glsequence.cxx deleted file mode 100644 index 62f39e3..0000000 --- a/alg/test/test_glsequence.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#include - -#include - -#include "alg/glsequence.h" -#include "alg/sequence.hh" - -using namespace std; - -BOOST_AUTO_TEST_CASE ( glsequence_operator_equal ) -{ - // 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); - BOOST_CHECK (glseq0.sequence().get_seq() == s0); - GlSequence glseq1(seq1); - GlSequence glseq_copy0(glseq0); - - BOOST_CHECK(glseq_copy0.sequence().get_seq() == glseq0.sequence().get_seq()); - BOOST_CHECK( &(glseq_copy0.sequence()) == &(glseq0.sequence())); - - glseq0 = glseq1; - - BOOST_CHECK( glseq0.sequence().get_seq() == s1 ); -} - -BOOST_AUTO_TEST_CASE( glsequence_color ) -{ - 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); - - BOOST_CHECK_EQUAL(s.color(), black ); - s.setColor( c ); - BOOST_CHECK_EQUAL( s.color(), c ); -} - -BOOST_AUTO_TEST_CASE( glsequence_renderable ) -{ - Sequence seq("AAGGCCTT"); - GlSequence s(seq); - - // way more base pairs than viewport pixel width - BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false ); - // way fewer basepairs than viewport pixel width - BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true); -} - -BOOST_AUTO_TEST_CASE( glsequence_sequence ) -{ - string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN"); - string::size_type seqlen = seq_string.size(); - Sequence seq(seq_string); - GlSequence glseq(seq); - - BOOST_CHECK( glseq.sequence_begin(0, 50) == seq.begin() ); - // always make sure we return seq.end() regardless of how much extra - // is asked for - BOOST_CHECK( glseq.sequence_end(0, seqlen+10) == seq.end() ); - // do we get the right end pointer? - BOOST_CHECK( glseq.sequence_end(0, 5) == seq.begin()+5 ); - - // when we request far too much sequence what do we get? - BOOST_CHECK( glseq.sequence_begin(seqlen+10, seqlen+20) == seq.end() ); - BOOST_CHECK( glseq.sequence_end(seqlen+10, seqlen+20) == seq.end() ); - - // we cant ask for reversed sequences with sequence_begin/end - BOOST_CHECK( glseq.sequence_begin(10, 5) == seq.end() ); - BOOST_CHECK( glseq.sequence_end(10, 5) == seq.end() ); - - Sequence::const_iterator seq_itor; - - // if we as for an empty segment? start and end should equal - seq_itor = glseq.sequence_begin(10, 10); - BOOST_CHECK( seq_itor == glseq.sequence_end(10, 10) ); - - // reuse seq_itor downhere - string::const_iterator str_itor; - for(str_itor = seq.begin(), - seq_itor = glseq.sequence_begin(); - str_itor != seq.end() and - seq_itor != glseq.sequence_end(); - ++str_itor, ++seq_itor) - { - BOOST_CHECK_EQUAL( *str_itor, *seq_itor ); - } -} - -// make sure the computation of the leftmost and rightmost base is correct -BOOST_AUTO_TEST_CASE( glsequence_leftright_base ) -{ - std::string seq_string = "AAGGCCTT"; - Sequence seq(seq_string); - GlSequence glseq(seq); - - BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 ); - BOOST_CHECK_EQUAL( glseq.leftbase( 0.5 ), 1 ); - BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() ); - BOOST_CHECK_EQUAL( glseq.rightbase( seq_string.size()-0.5), - seq_string.size()-1); -} diff --git a/alg/test/test_main.cpp b/alg/test/test_main.cpp new file mode 100644 index 0000000..39987f2 --- /dev/null +++ b/alg/test/test_main.cpp @@ -0,0 +1,3 @@ +#define BOOST_AUTO_TEST_MAIN +#include + diff --git a/alg/test/test_main.cxx b/alg/test/test_main.cxx deleted file mode 100644 index 39987f2..0000000 --- a/alg/test/test_main.cxx +++ /dev/null @@ -1,3 +0,0 @@ -#define BOOST_AUTO_TEST_MAIN -#include - diff --git a/alg/test/test_mussa.cpp b/alg/test/test_mussa.cpp new file mode 100644 index 0000000..6d9036f --- /dev/null +++ b/alg/test/test_mussa.cpp @@ -0,0 +1,108 @@ +#include + +#include + +#include "alg/mussa.hpp" + +//! can we initialize a mussa object? +BOOST_AUTO_TEST_CASE( mussa_simple ) +{ + Mussa m; + BOOST_CHECK_EQUAL(m.get_name(), "" ); + BOOST_CHECK_EQUAL(m.get_window(), 0); + BOOST_CHECK_EQUAL(m.get_threshold(), 0); + BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::TransitiveNway); + m.set_name( "hello" ); + BOOST_CHECK_EQUAL(m.get_name(), "hello" ); + m.set_window(30); + BOOST_CHECK_EQUAL(m.get_window(), 30); + m.set_threshold(21); + BOOST_CHECK_EQUAL(m.get_threshold(), 21); + m.set_analysis_mode(Mussa::RadialNway); + BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::RadialNway); + + m.clear(); + BOOST_CHECK_EQUAL(m.get_name(), "" ); + BOOST_CHECK_EQUAL(m.get_window(), 0); + BOOST_CHECK_EQUAL(m.get_threshold(), 0); + BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::TransitiveNway); +} + +BOOST_AUTO_TEST_CASE( mussa_analysis_name ) +{ + Mussa m; + m.set_analysis_mode( Mussa::TransitiveNway ); + BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Transitive" ); + m.set_analysis_mode( Mussa::RadialNway ); + BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Radial" ); + m.set_analysis_mode( Mussa::EntropyNway ); + BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Entropy" ); + m.set_analysis_mode( Mussa::RecursiveNway); + BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "[deprecated] Recursive" ); +} + +BOOST_AUTO_TEST_CASE( mussa_sequences ) +{ + std::string s0("AAAANNNN"); + std::string s1("GGGGNNNN"); + std::string s2("TTTTNNNN"); + + Mussa analysis; + analysis.add_a_seq(s0); + analysis.add_a_seq(s1); + analysis.add_a_seq(s2); + + BOOST_CHECK_EQUAL( analysis.sequences().size(), 3 ); + BOOST_CHECK_EQUAL( analysis.sequences()[0].get_seq(), s0); + BOOST_CHECK_EQUAL( analysis.sequences()[1].get_seq(), s1); + BOOST_CHECK_EQUAL( analysis.sequences()[2].get_seq(), s2); +} + +// for some reason we can call nway once safely but it +// somehow changed things and caused a segfault +// fixed by adding a return statement in trans_path_search +BOOST_AUTO_TEST_CASE ( empty_mussa_set_threshold ) +{ + Mussa m; + m.set_soft_thres(15); + m.nway(); + + m.set_soft_thres(25); + m.nway(); +} + +#include +BOOST_AUTO_TEST_CASE( mussa_load_mupa ) +{ + Mussa m1; + chdir( "examples" ); + m1.load_mupa_file( "mck3test.mupa" ); + m1.analyze(0, 0); + BOOST_CHECK_EQUAL( m1.get_name(), std::string("mck3test") ); + BOOST_CHECK( m1.size() > 0 ); + + Mussa m2; + std::string saved_analysis_path("mck3test_w30_t20"); + m2.load( saved_analysis_path ); + chdir( ".." ); + + BOOST_CHECK_EQUAL( m2.get_name(), saved_analysis_path ); + BOOST_CHECK_EQUAL( m1.size(), m2.size() ); + +} + +BOOST_AUTO_TEST_CASE( mussa_load_full_path ) +{ + Mussa m1; + chdir( "examples" ); + const int bufsize = 1024; + char path_buf[bufsize]; + getcwd(path_buf, bufsize); + std::string path(path_buf); + chdir( ".." ); + path += "/mck3test.mupa"; + m1.load_mupa_file( path ); + m1.analyze(0, 0); + + BOOST_CHECK( m1.size() > 0); +} diff --git a/alg/test/test_mussa.cxx b/alg/test/test_mussa.cxx deleted file mode 100644 index 00cae24..0000000 --- a/alg/test/test_mussa.cxx +++ /dev/null @@ -1,108 +0,0 @@ -#include - -#include - -#include "alg/mussa_class.hh" - -//! can we initialize a mussa object? -BOOST_AUTO_TEST_CASE( mussa_simple ) -{ - Mussa m; - BOOST_CHECK_EQUAL(m.get_name(), "" ); - BOOST_CHECK_EQUAL(m.get_window(), 0); - BOOST_CHECK_EQUAL(m.get_threshold(), 0); - BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::TransitiveNway); - m.set_name( "hello" ); - BOOST_CHECK_EQUAL(m.get_name(), "hello" ); - m.set_window(30); - BOOST_CHECK_EQUAL(m.get_window(), 30); - m.set_threshold(21); - BOOST_CHECK_EQUAL(m.get_threshold(), 21); - m.set_analysis_mode(Mussa::RadialNway); - BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::RadialNway); - - m.clear(); - BOOST_CHECK_EQUAL(m.get_name(), "" ); - BOOST_CHECK_EQUAL(m.get_window(), 0); - BOOST_CHECK_EQUAL(m.get_threshold(), 0); - BOOST_CHECK_EQUAL(m.get_analysis_mode(), Mussa::TransitiveNway); -} - -BOOST_AUTO_TEST_CASE( mussa_analysis_name ) -{ - Mussa m; - m.set_analysis_mode( Mussa::TransitiveNway ); - BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Transitive" ); - m.set_analysis_mode( Mussa::RadialNway ); - BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Radial" ); - m.set_analysis_mode( Mussa::EntropyNway ); - BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "Entropy" ); - m.set_analysis_mode( Mussa::RecursiveNway); - BOOST_CHECK_EQUAL( m.get_analysis_mode_name(), "[deprecated] Recursive" ); -} - -BOOST_AUTO_TEST_CASE( mussa_sequences ) -{ - std::string s0("AAAANNNN"); - std::string s1("GGGGNNNN"); - std::string s2("TTTTNNNN"); - - Mussa analysis; - analysis.add_a_seq(s0); - analysis.add_a_seq(s1); - analysis.add_a_seq(s2); - - BOOST_CHECK_EQUAL( analysis.sequences().size(), 3 ); - BOOST_CHECK_EQUAL( analysis.sequences()[0].get_seq(), s0); - BOOST_CHECK_EQUAL( analysis.sequences()[1].get_seq(), s1); - BOOST_CHECK_EQUAL( analysis.sequences()[2].get_seq(), s2); -} - -// for some reason we can call nway once safely but it -// somehow changed things and caused a segfault -// fixed by adding a return statement in trans_path_search -BOOST_AUTO_TEST_CASE ( empty_mussa_set_threshold ) -{ - Mussa m; - m.set_soft_thres(15); - m.nway(); - - m.set_soft_thres(25); - m.nway(); -} - -#include -BOOST_AUTO_TEST_CASE( mussa_load_mupa ) -{ - Mussa m1; - chdir( "examples" ); - m1.load_mupa_file( "mck3test.mupa" ); - m1.analyze(0, 0); - BOOST_CHECK_EQUAL( m1.get_name(), std::string("mck3test") ); - BOOST_CHECK( m1.size() > 0 ); - - Mussa m2; - std::string saved_analysis_path("mck3test_w30_t20"); - m2.load( saved_analysis_path ); - chdir( ".." ); - - BOOST_CHECK_EQUAL( m2.get_name(), saved_analysis_path ); - BOOST_CHECK_EQUAL( m1.size(), m2.size() ); - -} - -BOOST_AUTO_TEST_CASE( mussa_load_full_path ) -{ - Mussa m1; - chdir( "examples" ); - const int bufsize = 1024; - char path_buf[bufsize]; - getcwd(path_buf, bufsize); - std::string path(path_buf); - chdir( ".." ); - path += "/mck3test.mupa"; - m1.load_mupa_file( path ); - m1.analyze(0, 0); - - BOOST_CHECK( m1.size() > 0); -} diff --git a/alg/test/test_nway.cpp b/alg/test/test_nway.cpp new file mode 100644 index 0000000..d67753c --- /dev/null +++ b/alg/test/test_nway.cpp @@ -0,0 +1,58 @@ +#include + +#include +#include + +#include "alg/mussa.hpp" +#include "alg/nway_paths.hpp" +#include "alg/sequence.hpp" + +using namespace std; + +//! there should be no matches +BOOST_AUTO_TEST_CASE( nway_null ) +{ + string s0("AAAANNNN"); + string s1("GGGGNNNN"); + string s2("TTTTNNNN"); + + Mussa analysis; + analysis.add_a_seq(s0); + analysis.add_a_seq(s1); + analysis.add_a_seq(s2); + analysis.analyze(4,3); + NwayPaths npath = analysis.paths(); + // there should be no paths for these sequences + for (std::list::iterator pathz_i = npath.pathz.begin(); + pathz_i != npath.pathz.end(); + ++pathz_i) + { + BOOST_CHECK_EQUAL( pathz_i->size(), 0); + } +} + +BOOST_AUTO_TEST_CASE( nway_test ) +{ + string s0("ATATGCGC"); + string s1("GGGGGGGC"); + Sequence seq1(s1); + + Mussa analysis; + analysis.add_a_seq(s0); + analysis.add_a_seq(s1); + analysis.analyze(4,3); + NwayPaths npath = analysis.paths(); + for (std::list::iterator pathz_i = npath.pathz.begin(); + pathz_i != npath.pathz.end(); + ++pathz_i) + { + for( ConservedPath::iterator path_i = pathz_i->begin(); + path_i != pathz_i->end(); + ++path_i) + { + BOOST_CHECK( *path_i == 4 || *path_i == -4); + } + } +} + + diff --git a/alg/test/test_nway.cxx b/alg/test/test_nway.cxx deleted file mode 100644 index b472213..0000000 --- a/alg/test/test_nway.cxx +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include -#include - -#include "alg/mussa_class.hh" -#include "alg/nway_paths.hh" -#include "alg/sequence.hh" - -using namespace std; - -//! there should be no matches -BOOST_AUTO_TEST_CASE( nway_null ) -{ - string s0("AAAANNNN"); - string s1("GGGGNNNN"); - string s2("TTTTNNNN"); - - Mussa analysis; - analysis.add_a_seq(s0); - analysis.add_a_seq(s1); - analysis.add_a_seq(s2); - analysis.analyze(4,3); - NwayPaths npath = analysis.paths(); - // there should be no paths for these sequences - for (std::list::iterator pathz_i = npath.pathz.begin(); - pathz_i != npath.pathz.end(); - ++pathz_i) - { - BOOST_CHECK_EQUAL( pathz_i->size(), 0); - } -} - -BOOST_AUTO_TEST_CASE( nway_test ) -{ - string s0("ATATGCGC"); - string s1("GGGGGGGC"); - Sequence seq1(s1); - - Mussa analysis; - analysis.add_a_seq(s0); - analysis.add_a_seq(s1); - analysis.analyze(4,3); - NwayPaths npath = analysis.paths(); - for (std::list::iterator pathz_i = npath.pathz.begin(); - pathz_i != npath.pathz.end(); - ++pathz_i) - { - for( ConservedPath::iterator path_i = pathz_i->begin(); - path_i != pathz_i->end(); - ++path_i) - { - BOOST_CHECK( *path_i == 4 || *path_i == -4); - } - } -} - - diff --git a/alg/test/test_sequence.cpp b/alg/test/test_sequence.cpp new file mode 100644 index 0000000..6b06b46 --- /dev/null +++ b/alg/test/test_sequence.cpp @@ -0,0 +1,90 @@ +#include + +#include "alg/sequence.hpp" +#include "mussa_exceptions.hpp" + +//! when we try to load a missing file, do we get an error? +BOOST_AUTO_TEST_CASE( sequence_load_exception ) +{ + Sequence s; + // there should be errors when we try to load something that doesn't exist + BOOST_CHECK_THROW( s.load_fasta("alkejralk", 1, 0, 0), mussa_load_error); + BOOST_CHECK_THROW( s.load_annot("alkejralk", 0, 0), mussa_load_error); +} + +//! Do simple operations work correctly? +BOOST_AUTO_TEST_CASE( sequence_filter ) +{ + Sequence s1("AATTGGCC"); + BOOST_CHECK_EQUAL(s1.get_seq(), "AATTGGCC"); + + Sequence s2("aattggcc"); + BOOST_CHECK_EQUAL(s2.get_seq(), "AATTGGCC"); + BOOST_CHECK_EQUAL(s2.rev_comp(), "GGCCAATT"); + BOOST_CHECK_EQUAL(s2.size(), s2.get_seq().size()); + BOOST_CHECK_EQUAL(s2.c_seq(), s2.get_seq().c_str()); + + Sequence s3("asdfg"); + BOOST_CHECK_EQUAL(s3.get_seq(), "ANNNG"); + BOOST_CHECK_EQUAL(s3.subseq(0,2), "AN"); + + s3.set_filtered_sequence("AAGGCCTT", 0, 2); + BOOST_CHECK_EQUAL(s3.get_seq(), "AA"); + s3.set_filtered_sequence("AAGGCCTT", 2, 2); + BOOST_CHECK_EQUAL( s3.get_seq(), "GG"); + s3.set_filtered_sequence("AAGGCCTT", 4); + BOOST_CHECK_EQUAL( s3.get_seq(), "CCTT"); + + s3.clear(); + BOOST_CHECK_EQUAL(s3.get_seq(), ""); + + s3.set_seq("AAGGFF"); + BOOST_CHECK_EQUAL(s3.get_seq(), "AAGGNN"); +} + +//! Can we load data from a file +BOOST_AUTO_TEST_CASE( sequence_load ) +{ + Sequence s; + s.load_fasta("examples/seq/human_mck_pro.fa"); + BOOST_CHECK_EQUAL(s.subseq(0, 5), "GGATC"); // first few chars of fasta file + BOOST_CHECK_EQUAL(s.get_header(), "gi|180579|gb|M21487.1|HUMCKMM1 Human " + "muscle creatine kinase gene (CKMM), " + "5' flank"); +} + +BOOST_AUTO_TEST_CASE ( sequence_empty ) +{ + Sequence s; + BOOST_CHECK_EQUAL( s.empty(), true ); + s = "AAAGGG"; + BOOST_CHECK_EQUAL( s.empty(), false ); +} + +BOOST_AUTO_TEST_CASE ( sequence_iterators ) +{ + std::string seq_string = "AAGGCCTTNNTATA"; + Sequence s(seq_string); + const Sequence cs(s); + std::string::size_type count = 0; + + std::string::iterator str_itor; + Sequence::iterator s_itor; + Sequence::const_iterator cs_itor; + + for( str_itor = seq_string.begin(), + s_itor = s.begin(), + cs_itor = cs.begin(); + str_itor != seq_string.end() and + s_itor != s.end() and + cs_itor != cs.end(); + ++str_itor, ++s_itor, ++cs_itor, ++count) + { + BOOST_CHECK_EQUAL ( *str_itor, *s_itor ); + BOOST_CHECK_EQUAL ( *s_itor, *cs_itor ); + BOOST_CHECK_EQUAL ( *cs_itor, *str_itor ); + } + BOOST_CHECK_EQUAL( seq_string.size(), count ); + BOOST_CHECK_EQUAL( s.size(), count ); + BOOST_CHECK_EQUAL( cs.size(), count ); +} diff --git a/alg/test/test_sequence.cxx b/alg/test/test_sequence.cxx deleted file mode 100644 index 17c021d..0000000 --- a/alg/test/test_sequence.cxx +++ /dev/null @@ -1,90 +0,0 @@ -#include - -#include "alg/sequence.hh" -#include "mussa_exceptions.hh" - -//! when we try to load a missing file, do we get an error? -BOOST_AUTO_TEST_CASE( sequence_load_exception ) -{ - Sequence s; - // there should be errors when we try to load something that doesn't exist - BOOST_CHECK_THROW( s.load_fasta("alkejralk", 1, 0, 0), mussa_load_error); - BOOST_CHECK_THROW( s.load_annot("alkejralk", 0, 0), mussa_load_error); -} - -//! Do simple operations work correctly? -BOOST_AUTO_TEST_CASE( sequence_filter ) -{ - Sequence s1("AATTGGCC"); - BOOST_CHECK_EQUAL(s1.get_seq(), "AATTGGCC"); - - Sequence s2("aattggcc"); - BOOST_CHECK_EQUAL(s2.get_seq(), "AATTGGCC"); - BOOST_CHECK_EQUAL(s2.rev_comp(), "GGCCAATT"); - BOOST_CHECK_EQUAL(s2.size(), s2.get_seq().size()); - BOOST_CHECK_EQUAL(s2.c_seq(), s2.get_seq().c_str()); - - Sequence s3("asdfg"); - BOOST_CHECK_EQUAL(s3.get_seq(), "ANNNG"); - BOOST_CHECK_EQUAL(s3.subseq(0,2), "AN"); - - s3.set_filtered_sequence("AAGGCCTT", 0, 2); - BOOST_CHECK_EQUAL(s3.get_seq(), "AA"); - s3.set_filtered_sequence("AAGGCCTT", 2, 2); - BOOST_CHECK_EQUAL( s3.get_seq(), "GG"); - s3.set_filtered_sequence("AAGGCCTT", 4); - BOOST_CHECK_EQUAL( s3.get_seq(), "CCTT"); - - s3.clear(); - BOOST_CHECK_EQUAL(s3.get_seq(), ""); - - s3.set_seq("AAGGFF"); - BOOST_CHECK_EQUAL(s3.get_seq(), "AAGGNN"); -} - -//! Can we load data from a file -BOOST_AUTO_TEST_CASE( sequence_load ) -{ - Sequence s; - s.load_fasta("examples/seq/human_mck_pro.fa"); - BOOST_CHECK_EQUAL(s.subseq(0, 5), "GGATC"); // first few chars of fasta file - BOOST_CHECK_EQUAL(s.get_header(), "gi|180579|gb|M21487.1|HUMCKMM1 Human " - "muscle creatine kinase gene (CKMM), " - "5' flank"); -} - -BOOST_AUTO_TEST_CASE ( sequence_empty ) -{ - Sequence s; - BOOST_CHECK_EQUAL( s.empty(), true ); - s = "AAAGGG"; - BOOST_CHECK_EQUAL( s.empty(), false ); -} - -BOOST_AUTO_TEST_CASE ( sequence_iterators ) -{ - std::string seq_string = "AAGGCCTTNNTATA"; - Sequence s(seq_string); - const Sequence cs(s); - std::string::size_type count = 0; - - std::string::iterator str_itor; - Sequence::iterator s_itor; - Sequence::const_iterator cs_itor; - - for( str_itor = seq_string.begin(), - s_itor = s.begin(), - cs_itor = cs.begin(); - str_itor != seq_string.end() and - s_itor != s.end() and - cs_itor != cs.end(); - ++str_itor, ++s_itor, ++cs_itor, ++count) - { - BOOST_CHECK_EQUAL ( *str_itor, *s_itor ); - BOOST_CHECK_EQUAL ( *s_itor, *cs_itor ); - BOOST_CHECK_EQUAL ( *cs_itor, *str_itor ); - } - BOOST_CHECK_EQUAL( seq_string.size(), count ); - BOOST_CHECK_EQUAL( s.size(), count ); - BOOST_CHECK_EQUAL( cs.size(), count ); -} diff --git a/gui/AnnotWindow.cpp b/gui/AnnotWindow.cpp new file mode 100644 index 0000000..9ab0b0e --- /dev/null +++ b/gui/AnnotWindow.cpp @@ -0,0 +1,185 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/AnnotWindow.hpp" +#include +#include + +using namespace std; + +annot_color +new_blank_annot() +{ + annot_color *a_annot; + + a_annot = new annot_color; + a_annot->type = ""; + a_annot->color = (Fl_Color) 5; + //cout << "type: " << a_annot->type << endl; + + return *a_annot; +} + + +void +cb_annot_color(Fl_Button* o, void* v) +{ + annot_instance * blah = (annot_instance *) v; + AnnotWindow* T= blah->mw_ptr; + T->cb_annot_color_i(o,blah->index); +} + +AnnotWindow::AnnotWindow(int w, int h, const char* title, + vector * some_annots):Fl_Window(w,h,title) +{ + int i, annot_num; + + the_annots = some_annots; + annot_count = 0; + + annot_color_buttons.clear(); + + begin(); + annot_input_pack = new Fl_Pack(0, 0, w, h); + annot_input_pack->spacing(4); + + // button to add new annot inputs + add_annot = new Fl_Button(0,0,100,24,"Add Annot Slot"); + add_annot->callback((Fl_Callback*)add_annot_cb, this); + annot_input_pack->add(add_annot); + // test button to make sure annot data is being stored + test = new Fl_Button(0,0,100,24,"show annots"); + test->callback((Fl_Callback*)print_cb, this); + annot_input_pack->add(test); + + // creat an initial set of annot input widgets and attach to annot vector + annot_num = some_annots->size(); + for (i = 0; i < annot_num; i++) + { + add_annot_input(i); + annot_count++; + } + + add(annot_input_pack); + + end(); + resizable(this); + show(); +} + + //tmp_input->user_data((void*) i); + +AnnotWindow::~AnnotWindow(){} + +void +AnnotWindow::add_annot_input(int index) +{ + Fl_Output * new_input; + Fl_Button *new_color_button; + annot_instance * something; + Fl_Pack * annot_hor_pack; + + + something = new annot_instance; + something->mw_ptr = this; + something->index = index; + + annot_hor_pack = new Fl_Pack(0, 0, w(), 24); + annot_hor_pack->type(Fl_Pack::HORIZONTAL); + annot_hor_pack->spacing(4); + + // setup the color display/selection button + new_color_button = new Fl_Button(0, 0, 24, 24, ""); + new_color_button->color((*the_annots)[index].color); + new_color_button->box(FL_FLAT_BOX); + new_color_button->callback((Fl_Callback*)cb_annot_color, (void*) something); + annot_color_buttons.push_back(new_color_button); + annot_hor_pack->add(new_color_button); + + + // setup the annot inputs + new_input = new Fl_Output(0, 0, 200, 24, ""); + new_input->value( ((*the_annots)[index].type).c_str() ); + //new_input->callback((Fl_Callback*)cb_annot_in, (void*) something); + annot_ins.push_back(new_input); + annot_hor_pack->add(new_input); + + annot_input_pack->add(annot_hor_pack); +} +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ + +void +AnnotWindow::cb_annot_in_i(Fl_Input* o, int i) +{ + (*the_annots)[i].type = o->value(); +} + +void +AnnotWindow::cb_annot_color_i(Fl_Button* o, int i) +{ + //Fl_Color new_color; + + (*the_annots)[i].color = fl_show_colormap((*the_annots)[i].color); + //annot_color_buttons[i]-> + o->color((*the_annots)[i].color); + redraw(); +} + +void AnnotWindow::add_annot_cb(Fl_Button* o, void* v) +{ + AnnotWindow* T=(AnnotWindow*)v; + T->add_annot_cb_real(o,v); +} + + +void AnnotWindow::add_annot_cb_real(Fl_Button* , void*) +{ + annot_color blank_annot; + + //blank_annot.name = ""; + //blank_annot.seq = ""; + blank_annot = new_blank_annot(); + (*the_annots).push_back(blank_annot); + add_annot_input(annot_count++); + redraw(); +} + + +void AnnotWindow::print_cb(Fl_Button* o, void* v) +{ + AnnotWindow* T=(AnnotWindow*)v; + T->print_cb_real(o,v); +} + + +void AnnotWindow::print_cb_real(Fl_Button* , void*) +{ + int i; + + for (i = 0; i < annot_count; i++) + cout << (*the_annots)[i].type << endl; +} + +/* +void +cb_annot_in(Fl_Input* o, void* v) +{ + annot_instance * blah = (annot_instance *) v; + AnnotWindow* T= blah->mw_ptr; + T->cb_annot_in_i(o,blah->index); +} + + +*/ diff --git a/gui/AnnotWindow.cxx b/gui/AnnotWindow.cxx deleted file mode 100644 index e82a51a..0000000 --- a/gui/AnnotWindow.cxx +++ /dev/null @@ -1,185 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "AnnotWindow.hh" -#include -#include - -using namespace std; - -annot_color -new_blank_annot() -{ - annot_color *a_annot; - - a_annot = new annot_color; - a_annot->type = ""; - a_annot->color = (Fl_Color) 5; - //cout << "type: " << a_annot->type << endl; - - return *a_annot; -} - - -void -cb_annot_color(Fl_Button* o, void* v) -{ - annot_instance * blah = (annot_instance *) v; - AnnotWindow* T= blah->mw_ptr; - T->cb_annot_color_i(o,blah->index); -} - -AnnotWindow::AnnotWindow(int w, int h, const char* title, - vector * some_annots):Fl_Window(w,h,title) -{ - int i, annot_num; - - the_annots = some_annots; - annot_count = 0; - - annot_color_buttons.clear(); - - begin(); - annot_input_pack = new Fl_Pack(0, 0, w, h); - annot_input_pack->spacing(4); - - // button to add new annot inputs - add_annot = new Fl_Button(0,0,100,24,"Add Annot Slot"); - add_annot->callback((Fl_Callback*)add_annot_cb, this); - annot_input_pack->add(add_annot); - // test button to make sure annot data is being stored - test = new Fl_Button(0,0,100,24,"show annots"); - test->callback((Fl_Callback*)print_cb, this); - annot_input_pack->add(test); - - // creat an initial set of annot input widgets and attach to annot vector - annot_num = some_annots->size(); - for (i = 0; i < annot_num; i++) - { - add_annot_input(i); - annot_count++; - } - - add(annot_input_pack); - - end(); - resizable(this); - show(); -} - - //tmp_input->user_data((void*) i); - -AnnotWindow::~AnnotWindow(){} - -void -AnnotWindow::add_annot_input(int index) -{ - Fl_Output * new_input; - Fl_Button *new_color_button; - annot_instance * something; - Fl_Pack * annot_hor_pack; - - - something = new annot_instance; - something->mw_ptr = this; - something->index = index; - - annot_hor_pack = new Fl_Pack(0, 0, w(), 24); - annot_hor_pack->type(Fl_Pack::HORIZONTAL); - annot_hor_pack->spacing(4); - - // setup the color display/selection button - new_color_button = new Fl_Button(0, 0, 24, 24, ""); - new_color_button->color((*the_annots)[index].color); - new_color_button->box(FL_FLAT_BOX); - new_color_button->callback((Fl_Callback*)cb_annot_color, (void*) something); - annot_color_buttons.push_back(new_color_button); - annot_hor_pack->add(new_color_button); - - - // setup the annot inputs - new_input = new Fl_Output(0, 0, 200, 24, ""); - new_input->value( ((*the_annots)[index].type).c_str() ); - //new_input->callback((Fl_Callback*)cb_annot_in, (void*) something); - annot_ins.push_back(new_input); - annot_hor_pack->add(new_input); - - annot_input_pack->add(annot_hor_pack); -} -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ - -void -AnnotWindow::cb_annot_in_i(Fl_Input* o, int i) -{ - (*the_annots)[i].type = o->value(); -} - -void -AnnotWindow::cb_annot_color_i(Fl_Button* o, int i) -{ - //Fl_Color new_color; - - (*the_annots)[i].color = fl_show_colormap((*the_annots)[i].color); - //annot_color_buttons[i]-> - o->color((*the_annots)[i].color); - redraw(); -} - -void AnnotWindow::add_annot_cb(Fl_Button* o, void* v) -{ - AnnotWindow* T=(AnnotWindow*)v; - T->add_annot_cb_real(o,v); -} - - -void AnnotWindow::add_annot_cb_real(Fl_Button* , void*) -{ - annot_color blank_annot; - - //blank_annot.name = ""; - //blank_annot.seq = ""; - blank_annot = new_blank_annot(); - (*the_annots).push_back(blank_annot); - add_annot_input(annot_count++); - redraw(); -} - - -void AnnotWindow::print_cb(Fl_Button* o, void* v) -{ - AnnotWindow* T=(AnnotWindow*)v; - T->print_cb_real(o,v); -} - - -void AnnotWindow::print_cb_real(Fl_Button* , void*) -{ - int i; - - for (i = 0; i < annot_count; i++) - cout << (*the_annots)[i].type << endl; -} - -/* -void -cb_annot_in(Fl_Input* o, void* v) -{ - annot_instance * blah = (annot_instance *) v; - AnnotWindow* T= blah->mw_ptr; - T->cb_annot_in_i(o,blah->index); -} - - -*/ diff --git a/gui/AnnotWindow.hh b/gui/AnnotWindow.hh deleted file mode 100644 index 0303139..0000000 --- a/gui/AnnotWindow.hh +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _MUSSA_GUI_ANNOT_WINDOW_H_ -#define _MUSSA_GUI_ANNOT_WINDOW_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "MotifWindow.hh" - -struct annot_color -{ - std::string type; - Fl_Color color; -}; - -//typedef annot_ptr *annot; - - -class AnnotWindow : public Fl_Window -{ - public: - AnnotWindow(int w, int h, const char* title, - std::vector * some_annots); - ~AnnotWindow(); - Fl_Pack * annot_input_pack; - std::list annot_ins; - std::vector annot_color_buttons; - std::list name_ins; - Fl_Button* test; - Fl_Button* add_annot; - - void cb_annot_in_i(Fl_Input*, int i); - void cb_annot_color_i(Fl_Button* o, int i); - - private: - std::vector * the_annots; - int annot_count; - - void add_annot_input(int index); - - static void add_annot_cb(Fl_Button*, void*); - inline void add_annot_cb_real(Fl_Button*, void*); - - static void print_cb(Fl_Button*, void*); - inline void print_cb_real(Fl_Button*, void*); -}; - -// crazy whacked shite Titus taught me to do to get an index value associated -// with each instance of an input associated with the callback... -struct annot_instance -{ - AnnotWindow * mw_ptr; - int index; -}; - -annot_color new_blank_annot(); -#endif diff --git a/gui/AnnotWindow.hpp b/gui/AnnotWindow.hpp new file mode 100644 index 0000000..3ad0fbd --- /dev/null +++ b/gui/AnnotWindow.hpp @@ -0,0 +1,72 @@ +#ifndef _MUSSA_GUI_ANNOT_WINDOW_H_ +#define _MUSSA_GUI_ANNOT_WINDOW_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "gui/MotifWindow.hpp" + +struct annot_color +{ + std::string type; + Fl_Color color; +}; + +//typedef annot_ptr *annot; + + +class AnnotWindow : public Fl_Window +{ + public: + AnnotWindow(int w, int h, const char* title, + std::vector * some_annots); + ~AnnotWindow(); + Fl_Pack * annot_input_pack; + std::list annot_ins; + std::vector annot_color_buttons; + std::list name_ins; + Fl_Button* test; + Fl_Button* add_annot; + + void cb_annot_in_i(Fl_Input*, int i); + void cb_annot_color_i(Fl_Button* o, int i); + + private: + std::vector * the_annots; + int annot_count; + + void add_annot_input(int index); + + static void add_annot_cb(Fl_Button*, void*); + inline void add_annot_cb_real(Fl_Button*, void*); + + static void print_cb(Fl_Button*, void*); + inline void print_cb_real(Fl_Button*, void*); +}; + +// crazy whacked shite Titus taught me to do to get an index value associated +// with each instance of an input associated with the callback... +struct annot_instance +{ + AnnotWindow * mw_ptr; + int index; +}; + +annot_color new_blank_annot(); +#endif diff --git a/gui/ConnView.cpp b/gui/ConnView.cpp new file mode 100644 index 0000000..178a8ea --- /dev/null +++ b/gui/ConnView.cpp @@ -0,0 +1,704 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/ConnView.hpp" + +#include +#include + +#include +#include + +using namespace std; + +void +ConnView::setup(string name, int sq_num, int win_len, + vector *some_seqs, + NwayPaths *some_paths) +{ + int i, i2, seq_length; + Sequence a_seq; + motif blank_motif; + annot_color new_annot; + + + analysis_name = name; + seq_num = sq_num; + window = win_len; + S = some_seqs; + P = some_paths; + + cout << "num of paths = " << some_paths->refined_pathz.size() << endl; + + cout << "x()=" << x() << " y()=" << y() << " w()=" << w() << " h()=" << h(); + cout << endl; + + max_seq_len = 0; + for(i = 0; i < seq_num; ++i) + { + a_seq = (*S)[i]; + cout << a_seq.size() << endl; + seq_length = a_seq.size(); + seq_lens.push_back(seq_length); + if (seq_length > max_seq_len) + max_seq_len = seq_length; + if (seq_length < 1000) + seq_scales.push_back(1); + else if (seq_length < 1000000) + seq_scales.push_back(2); + else + seq_scales.push_back(3); + } + + name_pad = 80; + y_pad = 20; + + x_scale_factor = (float) max_seq_len / (w() - name_pad); + cout << "scale factor is " << x_scale_factor << endl; + y_seq_incre = (h()-(y_pad*2)) / (seq_num - 1); + + + drag_start = -1000; + drag_end = -1000; + ref_seq_num = 0; + + dragging = false; + selected = false; + + highlight.clear(); + show_bars = false; + show_lines = false; + bar_interval = max_seq_len / 20; + line_interval = max_seq_len / 20; + ref_seq_num = 0; + + + some_motifs.clear(); + for(i = 0; i < 5; ++i) + { + blank_motif = new_blank_motif(); + some_motifs.push_back(blank_motif); + } + + // find all unique annotation type ids + some_annots.clear(); + vector::iterator annot_type_i; + list::iterator annot_i; + + // loop thru all sequences + for(i2 = 0; i2 < seq_num; i2++) + { + cout << "ConnView: annotation loop\n"; + // loop thru all annotation entries in this sequence + for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i) + { + cout << annot_i->start << ", " << annot_i->end << " : "; + cout << annot_i->name << " " << annot_i->type << endl; + // loop thru annotation types + annot_type_i = some_annots.begin(); + bool type_unfound = true; + while ((annot_type_i != some_annots.end()) && type_unfound) + { + if (annot_i->type == annot_type_i->type) + type_unfound = false; // stop search if found + ++annot_type_i; + } + //if unfound, then add to list + if (type_unfound) + { + new_annot = new_blank_annot(); + new_annot.type = annot_i->type; + some_annots.push_back(new_annot); + } + } + } +} + + +void +ConnView::scale_paths() +{ + ExtendedConservedPath a_path; + list::iterator pathz_i; + int i2; + + + scaled_pathz.clear(); + + for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i) + { + a_path = *pathz_i; + a_path.window_size = (int)(a_path.window_size / x_scale_factor); + for(i2 = 0; i2 != a_path.size(); i2++) + { + a_path[i2] = (int) (a_path[i2] / x_scale_factor); + } + scaled_pathz.push_back(a_path); + } +} + +void +ConnView::toggle_bars() +{ + show_bars = !show_bars; + redraw(); +} + +void +ConnView::set_bar_interval(int new_bar_len) +{ + bar_interval = new_bar_len; + cout << "bar interval = " << bar_interval << endl; + redraw(); +} + +void +ConnView::toggle_lines() +{ + show_lines = !show_lines; + redraw(); +} + +void +ConnView::set_line_interval(int new_line_len) +{ + line_interval = new_line_len; + cout << "line interval = " << line_interval << endl; + redraw(); +} + + +void +ConnView::draw() +{ + // this is temporary - check if new motifs have been added + check_new_motifs(); + + // clear drawing area and set background to white + fl_color(FL_WHITE); + fl_rectf(x(), y(), w(), h()); + + // draw the scale indicators if they are on + // put into own method soon... + int i, div_num, x_loc; + float div_len_scaled; + + if (show_bars) + { + div_num = max_seq_len / bar_interval; + div_len_scaled = ((float) bar_interval) / x_scale_factor; + fl_color(230,230,230); + for(i = 0; i <= div_num; i+=2) + { + x_loc = (int)(i * div_len_scaled+x()); + fl_rectf(x_loc, y(), (int) div_len_scaled, h()); + } + } + + if (show_lines) + { + div_num = max_seq_len / line_interval; + div_len_scaled = ((float) line_interval) / x_scale_factor; + fl_color(0,0,0); + fl_line_style(FL_SOLID, 1, NULL); + for(i = 0; i <= div_num; i++) + { + x_loc = (int)(i * div_len_scaled+x()); + fl_line(x_loc, y(), x_loc, h()+y()); + } + } + + + // divide up the space with some light blue lines + fl_color(150,200,255); + fl_line_style(FL_SOLID, 2, NULL); + fl_rect(x(), y(), w(), h()); + fl_line(w()+x()-name_pad, y(), w()+x()-name_pad, h()+y()); + + draw_paths(); + + // white out any overdraw from path area into name/info area + fl_color(FL_WHITE); + fl_rectf(w()+x()-name_pad, y(), w()+x(), h()); + + draw_sequence_stuff(); + + // draw selection box + /* + if (selected) + { + fl_color(FL_BLACK); + fl_line_style(FL_SOLID, 1, NULL); + fl_rect(drag_start,(ref_seq_num*y_seq_incre)+y(),drag_end-drag_start, + 16); + } + */ +} + + +void +ConnView::draw_paths() +{ + list::iterator i; + int i2, i3, y_loc, x_loc, x_start, x_end; + list::iterator highlight_i; + int window_size; + bool rc_color; + int path_start, path_end; + + // determine which paths to highlight + highlight.clear(); + for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) + { + ExtendedConservedPath& a_path = *i; + // determine if path falls within the selected region and mark it for + // highlighted color + path_start = abs(a_path[ref_seq_num]); + path_end = path_start + a_path[0]; + if ( ( (path_start >= drag_start-x()) && (path_end <= drag_end-x()) ) || + ( (path_start < drag_start-x()) && (path_end > drag_end-x()) ) || + ( (path_start < drag_start-x()) && (path_end > drag_start-x()) ) || + ( (path_start < drag_end-x()) && (path_end > drag_end-x()) ) ) + highlight.push_back(true); + else + highlight.push_back(false); + } + + fl_line_style(FL_SOLID, 1, NULL); + // draw non-highlight paths (ie not in the selection box) + highlight_i = highlight.begin(); + for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) + { + ExtendedConservedPath& a_path = *i; + y_loc = y()+y_pad; + + window_size = a_path.window_size; + // make sure width is at least 1 - might be zero to my slack rounding + if (window_size == 0) + window_size = 1; + + if (!(*highlight_i)) + for(i2 = 0; i2 < a_path.size()-1; i2++) + { + // RC case handling + // ugh, an xor...only want blue if one of the nodes is rc + if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) && + !((a_path[i2] < 0) && (a_path[i2+1] < 0)) ) + fl_color(200,200,255); + else + fl_color(255,200,200); + + fl_line_style(FL_SOLID, 1, NULL); + fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3, + (int)abs(a_path[i2])+window_size+x(), y_loc + 3, + (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3, + (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3); + + y_loc += y_seq_incre; + } + ++highlight_i; + } + + // draw highlighted paths (ie in or partially in selection) + // drawing these separately and after other paths so they are on top + highlight_i = highlight.begin(); + for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) + { + ExtendedConservedPath& a_path = *i; + y_loc = y()+y_pad; + + // get window size to determine line width + window_size = a_path.window_size; + // make sure width is at least 1 - might be zero to my slack rounding + if (window_size == 0) + window_size = 1; + + if (*highlight_i) + for(i2 = 0; i2 != a_path.size()-1 ; i2++) + { + // RC case handling + // ugh, an xor...only want blue if one of the nodes is rc + if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) && + !((a_path[i2] < 0) && (a_path[i2+1] < 0)) ) + fl_color(FL_BLUE); + else + fl_color(FL_RED); + + fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3, + (int)abs(a_path[i2])+window_size+x(), y_loc + 3, + (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3, + (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3); + + y_loc += y_seq_incre; + } + ++highlight_i; + } +} + +/* + list >::iterator i; + int window_size; + bool rc_color; + int path_start, path_end; + Sequence a_seq; + vector a_path; +*/ + +void +ConnView::draw_sequence_stuff() +{ + int i2, i3, y_loc, y_offset, x_loc, x_start, x_end, mv_offset; + list::iterator annot_i; + string species_name, seq_length; + stringstream raw_length; + + + // draw sequence representation lines + fl_font(FL_COURIER, 14); + //fl_color(FL_BLACK); + fl_color(100,100,100); + // normally size 7, adjust for various screenshotage + fl_line_style(FL_SOLID, 11, NULL); + y_loc = y()+y_pad; + y_offset = 5; + for(i2 = 0; i2 < seq_num; i2++) + { + if (i2 == seq_num - 1) + y_offset = -10; + x_loc = (int)(seq_lens[i2] / x_scale_factor) + x(); + //report_float("seq scaled len", x_loc); + fl_line(x(),y_loc,x_loc,y_loc); + + species_name = (*S)[i2].species; + fl_draw(species_name.c_str(), x()+w()-name_pad+5, y_loc+y_offset); + + // funkiness to figure out which genomic scale to report size in + if (seq_scales[i2] == 1) + raw_length << setprecision(3) << seq_lens[i2] << " bp"; + else if (seq_scales[i2] == 2) + raw_length << setprecision(3) << seq_lens[i2] / 1000.0 << " Kb"; + else if (seq_scales[i2] == 3) + raw_length << setprecision(3) << seq_lens[i2] /1000000.0<< " Mb"; + seq_length = raw_length.str(); + fl_draw(seq_length.c_str(), x()+w()-name_pad+5, y_loc+y_offset+15); + raw_length.str(""); + + y_loc += y_seq_incre; + } + + //fl_line(x(),y()+y_pad/2,w()-name_pad,y()+y_pad/2); + //fl_line(x(),y()+h()-y_pad/2,w()-name_pad,y()+h()-y_pad/2); + + // draw annotations + vector::iterator annot_type_i; + + fl_color(FL_GREEN); + fl_line_style(FL_SOLID, 3, NULL); + y_loc = y()+y_pad; + for(i2 = 0; i2 < seq_num; i2++) + { + // loop thru all annotation entries + for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i) + { + fl_line_style(FL_SOLID, 7, NULL); + mv_offset = 0; + + // loop thru annotation types to determine color + annot_type_i = some_annots.begin(); + bool type_unfound = true; + while ((annot_type_i != some_annots.end()) && type_unfound) + { + if (annot_i->type == annot_type_i->type) + { + fl_color(annot_type_i->color); + type_unfound = false; + } + else + fl_color(FL_GREEN); + ++annot_type_i; + } + + // calculate scaled start and end, and draw + x_start = (int)(annot_i->start / x_scale_factor) + x(); + x_end = (int)(annot_i->end / x_scale_factor) + x(); + fl_line(x_start,y_loc+mv_offset,x_end,y_loc+mv_offset); + } + y_loc += y_seq_incre; + } + + + // draw motifs found + vector::iterator motif_i; + vector some_motif_locs; + vector::iterator i_locs; + int scale_len, motif_len; + + fl_color(255,0,255); + fl_line_style(FL_SOLID, 9, NULL); + motif_i = some_motifs.begin(); + while (motif_i != some_motifs.end()) + { + fl_color(motif_i->color); + motif_len = motif_i->seq.length(); + scale_len = (int) (motif_len / x_scale_factor); + if (scale_len == 0) + scale_len = 1; + y_loc = y()+y_pad; + if (!motif_i->locations.empty()) + for(i2 = 0; i2 < seq_num; i2++) + { + some_motif_locs = (*motif_i).locations[i2]; + + i_locs = some_motif_locs.begin(); + while (i_locs != some_motif_locs.end()) + { + x_start = (int)(*i_locs / x_scale_factor) + x(); + fl_line(x_start,y_loc,x_start+scale_len,y_loc); + ++i_locs; + } + y_loc += y_seq_incre; + } + ++motif_i; + } +} + + +void +ConnView::resize(int new_x, int new_y, int new_w, int new_h) +{ + + x(new_x); + y(new_y); + w(new_w); + h(new_h); + + x_scale_factor = (float) max_seq_len / (w() - name_pad); + cout << "scale factor is " << x_scale_factor << endl; + y_seq_incre = (h()-(2*y_pad)) / (seq_num - 1); + + scale_paths(); +} + + +void +ConnView::reporter(string var, int value) +{ + cout << var << " : " << value << endl; +} + + +void +ConnView::report_float(string var, float value) +{ + cout << var << " : " << value << endl; +} + +int +ConnView::handle(int e) +{ + int return_value; + float y_calc_tmp; + + // this empty string needs to be put on cout, otherwise the -O optimize + // compile option seems to throw this function away with the following: + // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) + cout << ""; + + // why do I need a -O for this module? Well, originally I just used the + // same compile flags for all modules. I changed that. However, on debian + // systems I need the -O otherwise the behavior I observe on redhat machines + // with above compiler happens if I don't have that empty cout. WTF + + switch(e) + { + case FL_PUSH: + if (Fl::event_button3()) + { + spawnSeq(); + return_value = 1; + } + else if (Fl::event_button2()) + { + find_motifs(); + return_value = 1; + } + break; + case FL_DRAG: + if (!dragging) + { + drag_start = Fl::event_x(); + y_drag_start = (float) Fl::event_y(); + ref_seq_num = (int) (round ( (y_drag_start/y_seq_incre) ) ); + dragging = true; + selected = false; + return_value = 1; + } + fl_line_style(FL_SOLID, 1, NULL); + fl_overlay_rect(drag_start, (ref_seq_num*y_seq_incre)+y(), + Fl::event_x()-drag_start, 16); + + break; + case FL_RELEASE: + if (dragging) + { + drag_end = Fl::event_x(); + dragging = false; + selected = true; + redraw(); + return_value = 1; + } + break; + default: + return_value = Fl_Widget::handle(e); + } + + return return_value; +} + + + +void +ConnView::check_new_motifs() +{ + vector::iterator i; + int i2; + vector some_motif_locs; + vector::iterator i_locs; + + i = some_motifs.begin(); + while (i != some_motifs.end()) + { + if (i->dirty) + { + cout << i->seq << " is new\n"; + i->locations.clear(); + //i_locs = i->locations; + for(i2 = 0; i2 < seq_num; i2++) + { + some_motif_locs = (*S)[i2].find_motif(i->seq); + (*i).locations.push_back(some_motif_locs); + + + i_locs = some_motif_locs.begin(); + while (i_locs != some_motif_locs.end()) + { + cout << *i_locs << " "; + ++i_locs; + } + cout << endl; + + } + + i->dirty = false; + } + ++i; + } +} + + +void +ConnView::spawnSeq() +{ + list selected_paths; + list::iterator pathz_i; + int i2, i3, y_loc, x_loc, x_start, x_end; + list::iterator highlight_i; + int y_max; + string window_name; + + if (selected) + { + // make new list of connections that are highlighted + selected_paths.clear(); + highlight_i = highlight.begin(); + for(pathz_i = P->refined_pathz.begin(); + pathz_i != P->refined_pathz.end(); ++pathz_i) + { + if (*highlight_i) + { + ExtendedConservedPath& a_path = *pathz_i; + selected_paths.push_back(a_path); + } + ++highlight_i; + } + + // give 50 pixels of height per sequence + y_max = seq_num * 50; + window_name = "Mussa Sequence: " + analysis_name; + + a_seq_win = new SeqWindow(800, y_max, (const char*) window_name.c_str(), + seq_num, S, selected_paths, seq_lens, + &some_motifs); + } +} + + +void +ConnView::find_motifs() +{ + motif_find_window = new MotifWindow(300, 300, "Motifs", &some_motifs); +} + +void +ConnView::annot_win() +{ + annot_color_window = new AnnotWindow(300, 300, "Annotations", &some_annots); +} + +// @!@! special hacked in color coding for the myf5/6 region annots + +/* + if (annot_i->type == "mvista") + { + fl_color(255,230,0); + fl_line_style(FL_SOLID, 8, NULL); + mv_offset = -4; + } + else if (annot_i->type == "reg") + { + fl_line_style(FL_SOLID, 10, NULL); + mv_offset = -8; + + if (annot_i->name == "CNS") + fl_color(255,150,0); + else if (annot_i->name == "ELA") + fl_color(0,200,120); + else if (annot_i->name == "ES") + fl_color(0,200,200); + else if (annot_i->name == "NA") + fl_color(120,120,120); + else if (annot_i->name == "EA") + { + fl_line_style(FL_SOLID, 7, NULL); + mv_offset = -13; + fl_color(0,200,120); + } + else if (annot_i->name == "VS") + { + fl_line_style(FL_SOLID, 7, NULL); + mv_offset = -6; + fl_color(255,255,0); + } + else if (annot_i->name == "SP") + { + fl_line_style(FL_SOLID, 7, NULL); + mv_offset = -13; + fl_color(255,230,150); + } + else if (annot_i->name == "L") + { + fl_line_style(FL_SOLID, 7, NULL); + mv_offset = -6; + fl_color(0,0,100); + } + else if (annot_i->name == "TCM") + fl_color(0,130,230); + } +*/ diff --git a/gui/ConnView.cxx b/gui/ConnView.cxx deleted file mode 100644 index 2888fdb..0000000 --- a/gui/ConnView.cxx +++ /dev/null @@ -1,704 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "ConnView.hh" - -#include -#include - -#include -#include - -using namespace std; - -void -ConnView::setup(string name, int sq_num, int win_len, - vector *some_seqs, - NwayPaths *some_paths) -{ - int i, i2, seq_length; - Sequence a_seq; - motif blank_motif; - annot_color new_annot; - - - analysis_name = name; - seq_num = sq_num; - window = win_len; - S = some_seqs; - P = some_paths; - - cout << "num of paths = " << some_paths->refined_pathz.size() << endl; - - cout << "x()=" << x() << " y()=" << y() << " w()=" << w() << " h()=" << h(); - cout << endl; - - max_seq_len = 0; - for(i = 0; i < seq_num; ++i) - { - a_seq = (*S)[i]; - cout << a_seq.size() << endl; - seq_length = a_seq.size(); - seq_lens.push_back(seq_length); - if (seq_length > max_seq_len) - max_seq_len = seq_length; - if (seq_length < 1000) - seq_scales.push_back(1); - else if (seq_length < 1000000) - seq_scales.push_back(2); - else - seq_scales.push_back(3); - } - - name_pad = 80; - y_pad = 20; - - x_scale_factor = (float) max_seq_len / (w() - name_pad); - cout << "scale factor is " << x_scale_factor << endl; - y_seq_incre = (h()-(y_pad*2)) / (seq_num - 1); - - - drag_start = -1000; - drag_end = -1000; - ref_seq_num = 0; - - dragging = false; - selected = false; - - highlight.clear(); - show_bars = false; - show_lines = false; - bar_interval = max_seq_len / 20; - line_interval = max_seq_len / 20; - ref_seq_num = 0; - - - some_motifs.clear(); - for(i = 0; i < 5; ++i) - { - blank_motif = new_blank_motif(); - some_motifs.push_back(blank_motif); - } - - // find all unique annotation type ids - some_annots.clear(); - vector::iterator annot_type_i; - list::iterator annot_i; - - // loop thru all sequences - for(i2 = 0; i2 < seq_num; i2++) - { - cout << "ConnView: annotation loop\n"; - // loop thru all annotation entries in this sequence - for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i) - { - cout << annot_i->start << ", " << annot_i->end << " : "; - cout << annot_i->name << " " << annot_i->type << endl; - // loop thru annotation types - annot_type_i = some_annots.begin(); - bool type_unfound = true; - while ((annot_type_i != some_annots.end()) && type_unfound) - { - if (annot_i->type == annot_type_i->type) - type_unfound = false; // stop search if found - ++annot_type_i; - } - //if unfound, then add to list - if (type_unfound) - { - new_annot = new_blank_annot(); - new_annot.type = annot_i->type; - some_annots.push_back(new_annot); - } - } - } -} - - -void -ConnView::scale_paths() -{ - ExtendedConservedPath a_path; - list::iterator pathz_i; - int i2; - - - scaled_pathz.clear(); - - for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i) - { - a_path = *pathz_i; - a_path.window_size = (int)(a_path.window_size / x_scale_factor); - for(i2 = 0; i2 != a_path.size(); i2++) - { - a_path[i2] = (int) (a_path[i2] / x_scale_factor); - } - scaled_pathz.push_back(a_path); - } -} - -void -ConnView::toggle_bars() -{ - show_bars = !show_bars; - redraw(); -} - -void -ConnView::set_bar_interval(int new_bar_len) -{ - bar_interval = new_bar_len; - cout << "bar interval = " << bar_interval << endl; - redraw(); -} - -void -ConnView::toggle_lines() -{ - show_lines = !show_lines; - redraw(); -} - -void -ConnView::set_line_interval(int new_line_len) -{ - line_interval = new_line_len; - cout << "line interval = " << line_interval << endl; - redraw(); -} - - -void -ConnView::draw() -{ - // this is temporary - check if new motifs have been added - check_new_motifs(); - - // clear drawing area and set background to white - fl_color(FL_WHITE); - fl_rectf(x(), y(), w(), h()); - - // draw the scale indicators if they are on - // put into own method soon... - int i, div_num, x_loc; - float div_len_scaled; - - if (show_bars) - { - div_num = max_seq_len / bar_interval; - div_len_scaled = ((float) bar_interval) / x_scale_factor; - fl_color(230,230,230); - for(i = 0; i <= div_num; i+=2) - { - x_loc = (int)(i * div_len_scaled+x()); - fl_rectf(x_loc, y(), (int) div_len_scaled, h()); - } - } - - if (show_lines) - { - div_num = max_seq_len / line_interval; - div_len_scaled = ((float) line_interval) / x_scale_factor; - fl_color(0,0,0); - fl_line_style(FL_SOLID, 1, NULL); - for(i = 0; i <= div_num; i++) - { - x_loc = (int)(i * div_len_scaled+x()); - fl_line(x_loc, y(), x_loc, h()+y()); - } - } - - - // divide up the space with some light blue lines - fl_color(150,200,255); - fl_line_style(FL_SOLID, 2, NULL); - fl_rect(x(), y(), w(), h()); - fl_line(w()+x()-name_pad, y(), w()+x()-name_pad, h()+y()); - - draw_paths(); - - // white out any overdraw from path area into name/info area - fl_color(FL_WHITE); - fl_rectf(w()+x()-name_pad, y(), w()+x(), h()); - - draw_sequence_stuff(); - - // draw selection box - /* - if (selected) - { - fl_color(FL_BLACK); - fl_line_style(FL_SOLID, 1, NULL); - fl_rect(drag_start,(ref_seq_num*y_seq_incre)+y(),drag_end-drag_start, - 16); - } - */ -} - - -void -ConnView::draw_paths() -{ - list::iterator i; - int i2, i3, y_loc, x_loc, x_start, x_end; - list::iterator highlight_i; - int window_size; - bool rc_color; - int path_start, path_end; - - // determine which paths to highlight - highlight.clear(); - for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) - { - ExtendedConservedPath& a_path = *i; - // determine if path falls within the selected region and mark it for - // highlighted color - path_start = abs(a_path[ref_seq_num]); - path_end = path_start + a_path[0]; - if ( ( (path_start >= drag_start-x()) && (path_end <= drag_end-x()) ) || - ( (path_start < drag_start-x()) && (path_end > drag_end-x()) ) || - ( (path_start < drag_start-x()) && (path_end > drag_start-x()) ) || - ( (path_start < drag_end-x()) && (path_end > drag_end-x()) ) ) - highlight.push_back(true); - else - highlight.push_back(false); - } - - fl_line_style(FL_SOLID, 1, NULL); - // draw non-highlight paths (ie not in the selection box) - highlight_i = highlight.begin(); - for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) - { - ExtendedConservedPath& a_path = *i; - y_loc = y()+y_pad; - - window_size = a_path.window_size; - // make sure width is at least 1 - might be zero to my slack rounding - if (window_size == 0) - window_size = 1; - - if (!(*highlight_i)) - for(i2 = 0; i2 < a_path.size()-1; i2++) - { - // RC case handling - // ugh, an xor...only want blue if one of the nodes is rc - if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) && - !((a_path[i2] < 0) && (a_path[i2+1] < 0)) ) - fl_color(200,200,255); - else - fl_color(255,200,200); - - fl_line_style(FL_SOLID, 1, NULL); - fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3, - (int)abs(a_path[i2])+window_size+x(), y_loc + 3, - (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3, - (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3); - - y_loc += y_seq_incre; - } - ++highlight_i; - } - - // draw highlighted paths (ie in or partially in selection) - // drawing these separately and after other paths so they are on top - highlight_i = highlight.begin(); - for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i) - { - ExtendedConservedPath& a_path = *i; - y_loc = y()+y_pad; - - // get window size to determine line width - window_size = a_path.window_size; - // make sure width is at least 1 - might be zero to my slack rounding - if (window_size == 0) - window_size = 1; - - if (*highlight_i) - for(i2 = 0; i2 != a_path.size()-1 ; i2++) - { - // RC case handling - // ugh, an xor...only want blue if one of the nodes is rc - if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) && - !((a_path[i2] < 0) && (a_path[i2+1] < 0)) ) - fl_color(FL_BLUE); - else - fl_color(FL_RED); - - fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3, - (int)abs(a_path[i2])+window_size+x(), y_loc + 3, - (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3, - (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3); - - y_loc += y_seq_incre; - } - ++highlight_i; - } -} - -/* - list >::iterator i; - int window_size; - bool rc_color; - int path_start, path_end; - Sequence a_seq; - vector a_path; -*/ - -void -ConnView::draw_sequence_stuff() -{ - int i2, i3, y_loc, y_offset, x_loc, x_start, x_end, mv_offset; - list::iterator annot_i; - string species_name, seq_length; - stringstream raw_length; - - - // draw sequence representation lines - fl_font(FL_COURIER, 14); - //fl_color(FL_BLACK); - fl_color(100,100,100); - // normally size 7, adjust for various screenshotage - fl_line_style(FL_SOLID, 11, NULL); - y_loc = y()+y_pad; - y_offset = 5; - for(i2 = 0; i2 < seq_num; i2++) - { - if (i2 == seq_num - 1) - y_offset = -10; - x_loc = (int)(seq_lens[i2] / x_scale_factor) + x(); - //report_float("seq scaled len", x_loc); - fl_line(x(),y_loc,x_loc,y_loc); - - species_name = (*S)[i2].species; - fl_draw(species_name.c_str(), x()+w()-name_pad+5, y_loc+y_offset); - - // funkiness to figure out which genomic scale to report size in - if (seq_scales[i2] == 1) - raw_length << setprecision(3) << seq_lens[i2] << " bp"; - else if (seq_scales[i2] == 2) - raw_length << setprecision(3) << seq_lens[i2] / 1000.0 << " Kb"; - else if (seq_scales[i2] == 3) - raw_length << setprecision(3) << seq_lens[i2] /1000000.0<< " Mb"; - seq_length = raw_length.str(); - fl_draw(seq_length.c_str(), x()+w()-name_pad+5, y_loc+y_offset+15); - raw_length.str(""); - - y_loc += y_seq_incre; - } - - //fl_line(x(),y()+y_pad/2,w()-name_pad,y()+y_pad/2); - //fl_line(x(),y()+h()-y_pad/2,w()-name_pad,y()+h()-y_pad/2); - - // draw annotations - vector::iterator annot_type_i; - - fl_color(FL_GREEN); - fl_line_style(FL_SOLID, 3, NULL); - y_loc = y()+y_pad; - for(i2 = 0; i2 < seq_num; i2++) - { - // loop thru all annotation entries - for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i) - { - fl_line_style(FL_SOLID, 7, NULL); - mv_offset = 0; - - // loop thru annotation types to determine color - annot_type_i = some_annots.begin(); - bool type_unfound = true; - while ((annot_type_i != some_annots.end()) && type_unfound) - { - if (annot_i->type == annot_type_i->type) - { - fl_color(annot_type_i->color); - type_unfound = false; - } - else - fl_color(FL_GREEN); - ++annot_type_i; - } - - // calculate scaled start and end, and draw - x_start = (int)(annot_i->start / x_scale_factor) + x(); - x_end = (int)(annot_i->end / x_scale_factor) + x(); - fl_line(x_start,y_loc+mv_offset,x_end,y_loc+mv_offset); - } - y_loc += y_seq_incre; - } - - - // draw motifs found - vector::iterator motif_i; - vector some_motif_locs; - vector::iterator i_locs; - int scale_len, motif_len; - - fl_color(255,0,255); - fl_line_style(FL_SOLID, 9, NULL); - motif_i = some_motifs.begin(); - while (motif_i != some_motifs.end()) - { - fl_color(motif_i->color); - motif_len = motif_i->seq.length(); - scale_len = (int) (motif_len / x_scale_factor); - if (scale_len == 0) - scale_len = 1; - y_loc = y()+y_pad; - if (!motif_i->locations.empty()) - for(i2 = 0; i2 < seq_num; i2++) - { - some_motif_locs = (*motif_i).locations[i2]; - - i_locs = some_motif_locs.begin(); - while (i_locs != some_motif_locs.end()) - { - x_start = (int)(*i_locs / x_scale_factor) + x(); - fl_line(x_start,y_loc,x_start+scale_len,y_loc); - ++i_locs; - } - y_loc += y_seq_incre; - } - ++motif_i; - } -} - - -void -ConnView::resize(int new_x, int new_y, int new_w, int new_h) -{ - - x(new_x); - y(new_y); - w(new_w); - h(new_h); - - x_scale_factor = (float) max_seq_len / (w() - name_pad); - cout << "scale factor is " << x_scale_factor << endl; - y_seq_incre = (h()-(2*y_pad)) / (seq_num - 1); - - scale_paths(); -} - - -void -ConnView::reporter(string var, int value) -{ - cout << var << " : " << value << endl; -} - - -void -ConnView::report_float(string var, float value) -{ - cout << var << " : " << value << endl; -} - -int -ConnView::handle(int e) -{ - int return_value; - float y_calc_tmp; - - // this empty string needs to be put on cout, otherwise the -O optimize - // compile option seems to throw this function away with the following: - // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) - cout << ""; - - // why do I need a -O for this module? Well, originally I just used the - // same compile flags for all modules. I changed that. However, on debian - // systems I need the -O otherwise the behavior I observe on redhat machines - // with above compiler happens if I don't have that empty cout. WTF - - switch(e) - { - case FL_PUSH: - if (Fl::event_button3()) - { - spawnSeq(); - return_value = 1; - } - else if (Fl::event_button2()) - { - find_motifs(); - return_value = 1; - } - break; - case FL_DRAG: - if (!dragging) - { - drag_start = Fl::event_x(); - y_drag_start = (float) Fl::event_y(); - ref_seq_num = (int) (round ( (y_drag_start/y_seq_incre) ) ); - dragging = true; - selected = false; - return_value = 1; - } - fl_line_style(FL_SOLID, 1, NULL); - fl_overlay_rect(drag_start, (ref_seq_num*y_seq_incre)+y(), - Fl::event_x()-drag_start, 16); - - break; - case FL_RELEASE: - if (dragging) - { - drag_end = Fl::event_x(); - dragging = false; - selected = true; - redraw(); - return_value = 1; - } - break; - default: - return_value = Fl_Widget::handle(e); - } - - return return_value; -} - - - -void -ConnView::check_new_motifs() -{ - vector::iterator i; - int i2; - vector some_motif_locs; - vector::iterator i_locs; - - i = some_motifs.begin(); - while (i != some_motifs.end()) - { - if (i->dirty) - { - cout << i->seq << " is new\n"; - i->locations.clear(); - //i_locs = i->locations; - for(i2 = 0; i2 < seq_num; i2++) - { - some_motif_locs = (*S)[i2].find_motif(i->seq); - (*i).locations.push_back(some_motif_locs); - - - i_locs = some_motif_locs.begin(); - while (i_locs != some_motif_locs.end()) - { - cout << *i_locs << " "; - ++i_locs; - } - cout << endl; - - } - - i->dirty = false; - } - ++i; - } -} - - -void -ConnView::spawnSeq() -{ - list selected_paths; - list::iterator pathz_i; - int i2, i3, y_loc, x_loc, x_start, x_end; - list::iterator highlight_i; - int y_max; - string window_name; - - if (selected) - { - // make new list of connections that are highlighted - selected_paths.clear(); - highlight_i = highlight.begin(); - for(pathz_i = P->refined_pathz.begin(); - pathz_i != P->refined_pathz.end(); ++pathz_i) - { - if (*highlight_i) - { - ExtendedConservedPath& a_path = *pathz_i; - selected_paths.push_back(a_path); - } - ++highlight_i; - } - - // give 50 pixels of height per sequence - y_max = seq_num * 50; - window_name = "Mussa Sequence: " + analysis_name; - - a_seq_win = new SeqWindow(800, y_max, (const char*) window_name.c_str(), - seq_num, S, selected_paths, seq_lens, - &some_motifs); - } -} - - -void -ConnView::find_motifs() -{ - motif_find_window = new MotifWindow(300, 300, "Motifs", &some_motifs); -} - -void -ConnView::annot_win() -{ - annot_color_window = new AnnotWindow(300, 300, "Annotations", &some_annots); -} - -// @!@! special hacked in color coding for the myf5/6 region annots - -/* - if (annot_i->type == "mvista") - { - fl_color(255,230,0); - fl_line_style(FL_SOLID, 8, NULL); - mv_offset = -4; - } - else if (annot_i->type == "reg") - { - fl_line_style(FL_SOLID, 10, NULL); - mv_offset = -8; - - if (annot_i->name == "CNS") - fl_color(255,150,0); - else if (annot_i->name == "ELA") - fl_color(0,200,120); - else if (annot_i->name == "ES") - fl_color(0,200,200); - else if (annot_i->name == "NA") - fl_color(120,120,120); - else if (annot_i->name == "EA") - { - fl_line_style(FL_SOLID, 7, NULL); - mv_offset = -13; - fl_color(0,200,120); - } - else if (annot_i->name == "VS") - { - fl_line_style(FL_SOLID, 7, NULL); - mv_offset = -6; - fl_color(255,255,0); - } - else if (annot_i->name == "SP") - { - fl_line_style(FL_SOLID, 7, NULL); - mv_offset = -13; - fl_color(255,230,150); - } - else if (annot_i->name == "L") - { - fl_line_style(FL_SOLID, 7, NULL); - mv_offset = -6; - fl_color(0,0,100); - } - else if (annot_i->name == "TCM") - fl_color(0,130,230); - } -*/ diff --git a/gui/ConnView.hh b/gui/ConnView.hh deleted file mode 100644 index d58995d..0000000 --- a/gui/ConnView.hh +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _MUSSA_GUI_CONN_VIEW_H_ -#define _MUSSA_GUI_CONN_VIEW_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include -#include -#include - -#include "alg/sequence.hh" -#include "alg/nway_paths.hh" -#include "SeqView.hh" -#include "SeqWindow.hh" -#include "MotifWindow.hh" -#include "AnnotWindow.hh" // aparently for annot_color - -#include - -class NwayPaths; -class ConnView : public Fl_Box -{ - public: - ConnView(int x_top,int y_top,int x_bot,int y_bot) : - Fl_Box(x_top,y_top,x_bot,y_bot) - {} - - void setup(std::string name, int sq_num, int win_len, - std::vector *, NwayPaths *); - void scale_paths(); - - void spawnSeq(); - void find_motifs(); - void annot_win(); - - void toggle_bars(); - void set_bar_interval(int new_bar_len); - void toggle_lines(); - void set_line_interval(int new_line_len); - - - private: - std::string analysis_name; - int seq_num, window, threshold; - bool win_append, thres_append; - - //this data is passed as pointers to the instantiated classes - std::vector *S; - //! Store the nway paths our analysis did, we mostly need the refined paths - NwayPaths *P; - - int name_pad, y_pad; - float x_scale_factor; - int y_seq_incre; - int drag_start, drag_end; - float y_drag_start; - int ref_seq_num, max_seq_len; - bool dragging, selected; - std::list highlight; - - //path data scaled for current view size - std::list scaled_pathz; - std::vector seq_lens; - std::vector seq_scales; - int bar_interval, line_interval; - bool show_bars, show_lines; - - //keeps track of all the motifs the user has inputed - std::vector some_motifs; - MotifWindow *motif_find_window; - - //keeps track of the colors assigned to each motif type - std::vector some_annots; - AnnotWindow *annot_color_window; - - SeqWindow *a_seq_win; - - void draw(); - void draw_paths(); - void draw_sequence_stuff(); - - void resize(int x, int y, int w, int h); - int handle(int e); - void check_new_motifs(); - - //for drawing function debugging - void reporter(std::string var, int value); - void report_float(std::string var, float value); -}; -#endif diff --git a/gui/ConnView.hpp b/gui/ConnView.hpp new file mode 100644 index 0000000..f5a95c4 --- /dev/null +++ b/gui/ConnView.hpp @@ -0,0 +1,96 @@ +#ifndef _MUSSA_GUI_CONN_VIEW_H_ +#define _MUSSA_GUI_CONN_VIEW_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include +#include +#include + +#include "alg/sequence.hpp" +#include "alg/nway_paths.hpp" +#include "gui/SeqView.hpp" +#include "gui/SeqWindow.hpp" +#include "gui/MotifWindow.hpp" +#include "gui/AnnotWindow.hpp" // aparently for annot_color + +#include + +class NwayPaths; +class ConnView : public Fl_Box +{ + public: + ConnView(int x_top,int y_top,int x_bot,int y_bot) : + Fl_Box(x_top,y_top,x_bot,y_bot) + {} + + void setup(std::string name, int sq_num, int win_len, + std::vector *, NwayPaths *); + void scale_paths(); + + void spawnSeq(); + void find_motifs(); + void annot_win(); + + void toggle_bars(); + void set_bar_interval(int new_bar_len); + void toggle_lines(); + void set_line_interval(int new_line_len); + + + private: + std::string analysis_name; + int seq_num, window, threshold; + bool win_append, thres_append; + + //this data is passed as pointers to the instantiated classes + std::vector *S; + //! Store the nway paths our analysis did, we mostly need the refined paths + NwayPaths *P; + + int name_pad, y_pad; + float x_scale_factor; + int y_seq_incre; + int drag_start, drag_end; + float y_drag_start; + int ref_seq_num, max_seq_len; + bool dragging, selected; + std::list highlight; + + //path data scaled for current view size + std::list scaled_pathz; + std::vector seq_lens; + std::vector seq_scales; + int bar_interval, line_interval; + bool show_bars, show_lines; + + //keeps track of all the motifs the user has inputed + std::vector some_motifs; + MotifWindow *motif_find_window; + + //keeps track of the colors assigned to each motif type + std::vector some_annots; + AnnotWindow *annot_color_window; + + SeqWindow *a_seq_win; + + void draw(); + void draw_paths(); + void draw_sequence_stuff(); + + void resize(int x, int y, int w, int h); + int handle(int e); + void check_new_motifs(); + + //for drawing function debugging + void reporter(std::string var, int value); + void report_float(std::string var, float value); +}; +#endif diff --git a/gui/ConnWindow.cpp b/gui/ConnWindow.cpp new file mode 100644 index 0000000..bd32682 --- /dev/null +++ b/gui/ConnWindow.cpp @@ -0,0 +1,421 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/ConnWindow.hpp" +#include "mussa_exceptions.hpp" + +#include +using namespace std; + +void +load_ana_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_load_ana_cb(); +} + + +void +ConnWindow::real_load_ana_cb() +{ + char *picked_file; + string a_file_path; + string err_msg; + + cout << "Load! Load! Load, ye yellow-bellied seadogs!\n"; + //picked_file = fl_file_chooser("Find an Analysis", "", "", 1); + picked_file = fl_dir_chooser("Find an Analysis", "", 1); + if (picked_file != NULL) + { + a_file_path = picked_file; + cout << "doo wah diddy diddy dum diddy doo\n"; + cout << a_file_path << endl; + + // load the analysis + an_analysis = new Mussa(); + try { + an_analysis->load(a_file_path); + } catch (mussa_load_error e) { + fl_alert(e.what()); + return; + } + //.substr(0,a_file_path.find(".mu"))); + + // relabel window with the analysis name + window_name = "Mussa: " + an_analysis->get_name(); + label((const char*)window_name.c_str()); + // show the user the analysis + conn_box->setup(an_analysis->get_name(), an_analysis->size(), + an_analysis->get_window(), &(an_analysis->the_seqs), + &(an_analysis->the_paths)); + conn_box->scale_paths(); + } +} + + +void +do_ana_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_do_ana_cb(); +} + + +void +ConnWindow::real_do_ana_cb() +{ + char *picked_file; + string a_file_path; + string err_msg; + + picked_file = fl_file_chooser("Analysis Config File", "", "", 1); + if (picked_file != NULL) + { + a_file_path = picked_file; + + an_analysis = new Mussa(); + try { + an_analysis->load_mupa_file(a_file_path); + } catch (mussa_load_error e) { + fl_alert(e.what()); + return; + } + + try { + an_analysis->analyze(0, 0, Mussa::TransitiveNway, 0.0); + // relabel window with the analysis name + window_name = "Mussa: " + an_analysis->get_name(); + label((const char*)window_name.c_str()); + // show the user the analysis + conn_box->setup(an_analysis->get_name(), an_analysis->size(), + an_analysis->get_window(), &(an_analysis->the_seqs), + &(an_analysis->the_paths)); + conn_box->scale_paths(); + } catch (mussa_analysis_error e) { + fl_alert(e.what()); + } + } + conn_box->redraw(); +} + + +void +setup_ana_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_setup_ana_cb(); +} + +void +ConnWindow::real_setup_ana_cb() +{ + an_analysis = new Mussa(); + setup_win = new SetupWindow(650,700,"Analysis Setup", an_analysis); + + while(setup_win->visible()) + Fl::wait(.1); + cout << "Like a warm summer day\n"; + + if (setup_win->done()) + { + // relabel window with the analysis name + window_name = "Mussa: " + an_analysis->get_name(); + label((const char*)window_name.c_str()); + // is it this easy? what if setup window encounters an error...?? + conn_box->setup(an_analysis->get_name(), an_analysis->size(), + an_analysis->get_window(), &(an_analysis->the_seqs), + &(an_analysis->the_paths)); + + conn_box->scale_paths(); + } +} + + +void +subana_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_subana_cb(); +} + +void +ConnWindow::real_subana_cb() +{ + string subana_name; + + if (an_analysis == 0 || an_analysis->the_seqs.size() == 0) { + fl_message("please load an analysis before creating a subanalysis"); + return; + } + + sub_analysis = new Mussa(); + subana_win = new SubAnalysisWindow(500,400,"Sub Analysis Setup", sub_analysis, + an_analysis->the_seqs); + + while(subana_win->visible()) + Fl::wait(.1); + cout << "Like a warm summer day\n"; + + if (subana_win->done()) + { + subana_name = "SubMussa: " + sub_analysis->get_name(); + sub_conn_win = new ConnWindow(w(), h(), (const char*) subana_name.c_str()); + cout << "Like a warm day in may\n"; + sub_conn_win->add_ana(sub_analysis); + //Fl::visual(FL_DOUBLE|FL_INDEX); + //sub_conn_box->show(); + } +} + + +void +seq_show_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_seq_show_cb(); +} + +void +ConnWindow::real_seq_show_cb() +{ + show_seq_win = new SeqTextWindow(500,400,"Seq Show", an_analysis->the_seqs); +} + +void +seq_win_spawn_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_seq_win_spawn_cb(); +} + +void +ConnWindow::real_seq_win_spawn_cb() +{ + conn_box->spawnSeq(); +} + +void +motif_find_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_motif_find_cb(); +} + +void +ConnWindow::real_motif_find_cb() +{ + conn_box->find_motifs(); +} + +void +annot_win_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_annot_win_cb(); +} + +void +ConnWindow::real_annot_win_cb() +{ + conn_box->annot_win(); +} + + +// all the crap needed for dealing with the scale bars +void +toggle_scale_bars_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_toggle_bars_cb(); +} + +void +ConnWindow::real_toggle_bars_cb() +{ + conn_box->toggle_bars(); +} + +void +set_bar_len_cb(Fl_Input* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + cout << "WAAAAAAAAA\n"; + T->real_set_bar_len_cb(o); +} + +void +ConnWindow::real_set_bar_len_cb(Fl_Input* o) +{ + int new_bar_len; + + new_bar_len = atoi(o->value()); + cout << "new bar len = " << new_bar_len << endl; + conn_box->set_bar_interval(new_bar_len); +} + + +// all the crap needed for dealing with the scale lines +void +toggle_scale_lines_cb(Fl_Button* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + T->real_toggle_lines_cb(); +} + +void +ConnWindow::real_toggle_lines_cb() +{ + conn_box->toggle_lines(); +} + +void +set_line_len_cb(Fl_Input* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + cout << "WAAAAAAAAA\n"; + T->real_set_line_len_cb(o); +} + +void +ConnWindow::real_set_line_len_cb(Fl_Input* o) +{ + int new_line_len; + + new_line_len = atoi(o->value()); + cout << "new line len = " << new_line_len << endl; + conn_box->set_line_interval(new_line_len); +} + + +// setting new soft threshold + +void +set_soft_thres_cb(Fl_Input* o, void* v) +{ + ConnWindow* T=(ConnWindow*)v; + cout << "WAAAAAAAAA\n"; + T->real_set_soft_thres_cb(o); +} + +void +ConnWindow::real_set_soft_thres_cb(Fl_Input* o) +{ + int new_soft_thres; + + new_soft_thres = atoi(o->value()); + cout << "new soft thres = " << new_soft_thres << endl; + + an_analysis->set_soft_thres(new_soft_thres); + an_analysis->set_analysis_mode(Mussa::TransitiveNway); + an_analysis->nway(); + conn_box->scale_paths(); + conn_box->redraw(); + + // hacked in stuff to save muway files at different thresholds + string save_path; + ostringstream append_info; + + save_path = an_analysis->get_name() + "/" + + an_analysis->get_name().substr(0,an_analysis->get_name().find("_t")); + append_info.str(""); + append_info << "_t" << new_soft_thres << ".muway"; + //<< "_w" << an_analysis->window + save_path += append_info.str(); + cout << "saving as: " << save_path << endl; + an_analysis->save_muway(save_path); +} + + + + +ConnWindow::ConnWindow(int w, int h, const char* title): + Fl_Double_Window(w,h,title) +{ + int button_len = 120; + Fl_Color a_color = fl_rgb_color(150, 200, 255); + + padding = 5; + + begin(); + //fl_color(150,200,255); + color(FL_WHITE); + resizable(this); + + + // create file menu button + file_menu = new Fl_Menu_Button(padding, 2, button_len, 30, "Analysis"); + file_menu->color(FL_WHITE,a_color); + file_menu->box(FL_BORDER_BOX); + file_menu->clear(); + + // add menu items + file_menu->add("Do Analysis", 0, (Fl_Callback *) do_ana_cb, this); + file_menu->add("Load Analysis", 0, (Fl_Callback *) load_ana_cb, this); + file_menu->add("Setup Analysis", 0, (Fl_Callback *) setup_ana_cb, this); + file_menu->add("Sub Analysis", 0, (Fl_Callback *) subana_cb, this); + + + view_menu = new Fl_Menu_Button(padding+button_len,2, button_len, 30, "View"); + view_menu->color(FL_WHITE,a_color); + view_menu->box(FL_BORDER_BOX); + view_menu->clear(); + view_menu->add("Sequence Zoom", 0, (Fl_Callback*) seq_win_spawn_cb, this); + view_menu->add("Motif Finder", 0, (Fl_Callback*) motif_find_cb, this); + view_menu->add("Annotations", 0, (Fl_Callback*) annot_win_cb, this); + view_menu->add("Copy Seq", 0, (Fl_Callback*) seq_show_cb, this); + view_menu->add("Toggle Bars", 0, (Fl_Callback*) toggle_scale_bars_cb, this, + FL_MENU_TOGGLE|FL_MENU_VALUE); + view_menu->add("Toggle Lines", 0, (Fl_Callback*) toggle_scale_lines_cb, this, + FL_MENU_TOGGLE|FL_MENU_VALUE); + + bar_input = new Fl_Input(padding+3*button_len, 2, button_len, 30, "Bar Length (bp)"); + bar_input->value(""); + bar_input->when(FL_WHEN_ENTER_KEY); + bar_input->callback((Fl_Callback*)set_bar_len_cb, this); + + line_input = new Fl_Input(padding+5*button_len, 2, button_len, 30, "Line Interval (bp)"); + line_input->value(""); + line_input->when(FL_WHEN_ENTER_KEY); + line_input->callback((Fl_Callback*)set_line_len_cb, this); + + + thres_input = new Fl_Input(padding+7*button_len, 2, button_len, 30, "Threshold"); + thres_input->value(""); + thres_input->when(FL_WHEN_ENTER_KEY); + thres_input->callback((Fl_Callback*)set_soft_thres_cb, this); + + + // create the connections box + conn_box = new ConnView(padding, padding + 30, w-2*padding, h-2*padding-30); + //conn_box = new ConnView(padding, padding, w-2*padding, h-2*padding); + + end(); + show(); +} + + +ConnWindow::~ConnWindow() +{} + + +void +ConnWindow::add_ana(Mussa *the_ana) +{ + an_analysis = the_ana; + + // relabel window with the analysis name + window_name = "Mussa: " + an_analysis->get_name(); + label((const char*)window_name.c_str()); + + conn_box->setup(an_analysis->get_name(), an_analysis->size(), + an_analysis->get_window(), &(an_analysis->the_seqs), + &(an_analysis->the_paths)); + conn_box->scale_paths(); +} diff --git a/gui/ConnWindow.cxx b/gui/ConnWindow.cxx deleted file mode 100644 index 0f06bea..0000000 --- a/gui/ConnWindow.cxx +++ /dev/null @@ -1,421 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "ConnWindow.hh" -#include "mussa_exceptions.hh" - -#include -using namespace std; - -void -load_ana_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_load_ana_cb(); -} - - -void -ConnWindow::real_load_ana_cb() -{ - char *picked_file; - string a_file_path; - string err_msg; - - cout << "Load! Load! Load, ye yellow-bellied seadogs!\n"; - //picked_file = fl_file_chooser("Find an Analysis", "", "", 1); - picked_file = fl_dir_chooser("Find an Analysis", "", 1); - if (picked_file != NULL) - { - a_file_path = picked_file; - cout << "doo wah diddy diddy dum diddy doo\n"; - cout << a_file_path << endl; - - // load the analysis - an_analysis = new Mussa(); - try { - an_analysis->load(a_file_path); - } catch (mussa_load_error e) { - fl_alert(e.what()); - return; - } - //.substr(0,a_file_path.find(".mu"))); - - // relabel window with the analysis name - window_name = "Mussa: " + an_analysis->get_name(); - label((const char*)window_name.c_str()); - // show the user the analysis - conn_box->setup(an_analysis->get_name(), an_analysis->size(), - an_analysis->get_window(), &(an_analysis->the_seqs), - &(an_analysis->the_paths)); - conn_box->scale_paths(); - } -} - - -void -do_ana_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_do_ana_cb(); -} - - -void -ConnWindow::real_do_ana_cb() -{ - char *picked_file; - string a_file_path; - string err_msg; - - picked_file = fl_file_chooser("Analysis Config File", "", "", 1); - if (picked_file != NULL) - { - a_file_path = picked_file; - - an_analysis = new Mussa(); - try { - an_analysis->load_mupa_file(a_file_path); - } catch (mussa_load_error e) { - fl_alert(e.what()); - return; - } - - try { - an_analysis->analyze(0, 0, Mussa::TransitiveNway, 0.0); - // relabel window with the analysis name - window_name = "Mussa: " + an_analysis->get_name(); - label((const char*)window_name.c_str()); - // show the user the analysis - conn_box->setup(an_analysis->get_name(), an_analysis->size(), - an_analysis->get_window(), &(an_analysis->the_seqs), - &(an_analysis->the_paths)); - conn_box->scale_paths(); - } catch (mussa_analysis_error e) { - fl_alert(e.what()); - } - } - conn_box->redraw(); -} - - -void -setup_ana_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_setup_ana_cb(); -} - -void -ConnWindow::real_setup_ana_cb() -{ - an_analysis = new Mussa(); - setup_win = new SetupWindow(650,700,"Analysis Setup", an_analysis); - - while(setup_win->visible()) - Fl::wait(.1); - cout << "Like a warm summer day\n"; - - if (setup_win->done()) - { - // relabel window with the analysis name - window_name = "Mussa: " + an_analysis->get_name(); - label((const char*)window_name.c_str()); - // is it this easy? what if setup window encounters an error...?? - conn_box->setup(an_analysis->get_name(), an_analysis->size(), - an_analysis->get_window(), &(an_analysis->the_seqs), - &(an_analysis->the_paths)); - - conn_box->scale_paths(); - } -} - - -void -subana_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_subana_cb(); -} - -void -ConnWindow::real_subana_cb() -{ - string subana_name; - - if (an_analysis == 0 || an_analysis->the_seqs.size() == 0) { - fl_message("please load an analysis before creating a subanalysis"); - return; - } - - sub_analysis = new Mussa(); - subana_win = new SubAnalysisWindow(500,400,"Sub Analysis Setup", sub_analysis, - an_analysis->the_seqs); - - while(subana_win->visible()) - Fl::wait(.1); - cout << "Like a warm summer day\n"; - - if (subana_win->done()) - { - subana_name = "SubMussa: " + sub_analysis->get_name(); - sub_conn_win = new ConnWindow(w(), h(), (const char*) subana_name.c_str()); - cout << "Like a warm day in may\n"; - sub_conn_win->add_ana(sub_analysis); - //Fl::visual(FL_DOUBLE|FL_INDEX); - //sub_conn_box->show(); - } -} - - -void -seq_show_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_seq_show_cb(); -} - -void -ConnWindow::real_seq_show_cb() -{ - show_seq_win = new SeqTextWindow(500,400,"Seq Show", an_analysis->the_seqs); -} - -void -seq_win_spawn_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_seq_win_spawn_cb(); -} - -void -ConnWindow::real_seq_win_spawn_cb() -{ - conn_box->spawnSeq(); -} - -void -motif_find_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_motif_find_cb(); -} - -void -ConnWindow::real_motif_find_cb() -{ - conn_box->find_motifs(); -} - -void -annot_win_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_annot_win_cb(); -} - -void -ConnWindow::real_annot_win_cb() -{ - conn_box->annot_win(); -} - - -// all the crap needed for dealing with the scale bars -void -toggle_scale_bars_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_toggle_bars_cb(); -} - -void -ConnWindow::real_toggle_bars_cb() -{ - conn_box->toggle_bars(); -} - -void -set_bar_len_cb(Fl_Input* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - cout << "WAAAAAAAAA\n"; - T->real_set_bar_len_cb(o); -} - -void -ConnWindow::real_set_bar_len_cb(Fl_Input* o) -{ - int new_bar_len; - - new_bar_len = atoi(o->value()); - cout << "new bar len = " << new_bar_len << endl; - conn_box->set_bar_interval(new_bar_len); -} - - -// all the crap needed for dealing with the scale lines -void -toggle_scale_lines_cb(Fl_Button* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - T->real_toggle_lines_cb(); -} - -void -ConnWindow::real_toggle_lines_cb() -{ - conn_box->toggle_lines(); -} - -void -set_line_len_cb(Fl_Input* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - cout << "WAAAAAAAAA\n"; - T->real_set_line_len_cb(o); -} - -void -ConnWindow::real_set_line_len_cb(Fl_Input* o) -{ - int new_line_len; - - new_line_len = atoi(o->value()); - cout << "new line len = " << new_line_len << endl; - conn_box->set_line_interval(new_line_len); -} - - -// setting new soft threshold - -void -set_soft_thres_cb(Fl_Input* o, void* v) -{ - ConnWindow* T=(ConnWindow*)v; - cout << "WAAAAAAAAA\n"; - T->real_set_soft_thres_cb(o); -} - -void -ConnWindow::real_set_soft_thres_cb(Fl_Input* o) -{ - int new_soft_thres; - - new_soft_thres = atoi(o->value()); - cout << "new soft thres = " << new_soft_thres << endl; - - an_analysis->set_soft_thres(new_soft_thres); - an_analysis->set_analysis_mode(Mussa::TransitiveNway); - an_analysis->nway(); - conn_box->scale_paths(); - conn_box->redraw(); - - // hacked in stuff to save muway files at different thresholds - string save_path; - ostringstream append_info; - - save_path = an_analysis->get_name() + "/" - + an_analysis->get_name().substr(0,an_analysis->get_name().find("_t")); - append_info.str(""); - append_info << "_t" << new_soft_thres << ".muway"; - //<< "_w" << an_analysis->window - save_path += append_info.str(); - cout << "saving as: " << save_path << endl; - an_analysis->save_muway(save_path); -} - - - - -ConnWindow::ConnWindow(int w, int h, const char* title): - Fl_Double_Window(w,h,title) -{ - int button_len = 120; - Fl_Color a_color = fl_rgb_color(150, 200, 255); - - padding = 5; - - begin(); - //fl_color(150,200,255); - color(FL_WHITE); - resizable(this); - - - // create file menu button - file_menu = new Fl_Menu_Button(padding, 2, button_len, 30, "Analysis"); - file_menu->color(FL_WHITE,a_color); - file_menu->box(FL_BORDER_BOX); - file_menu->clear(); - - // add menu items - file_menu->add("Do Analysis", 0, (Fl_Callback *) do_ana_cb, this); - file_menu->add("Load Analysis", 0, (Fl_Callback *) load_ana_cb, this); - file_menu->add("Setup Analysis", 0, (Fl_Callback *) setup_ana_cb, this); - file_menu->add("Sub Analysis", 0, (Fl_Callback *) subana_cb, this); - - - view_menu = new Fl_Menu_Button(padding+button_len,2, button_len, 30, "View"); - view_menu->color(FL_WHITE,a_color); - view_menu->box(FL_BORDER_BOX); - view_menu->clear(); - view_menu->add("Sequence Zoom", 0, (Fl_Callback*) seq_win_spawn_cb, this); - view_menu->add("Motif Finder", 0, (Fl_Callback*) motif_find_cb, this); - view_menu->add("Annotations", 0, (Fl_Callback*) annot_win_cb, this); - view_menu->add("Copy Seq", 0, (Fl_Callback*) seq_show_cb, this); - view_menu->add("Toggle Bars", 0, (Fl_Callback*) toggle_scale_bars_cb, this, - FL_MENU_TOGGLE|FL_MENU_VALUE); - view_menu->add("Toggle Lines", 0, (Fl_Callback*) toggle_scale_lines_cb, this, - FL_MENU_TOGGLE|FL_MENU_VALUE); - - bar_input = new Fl_Input(padding+3*button_len, 2, button_len, 30, "Bar Length (bp)"); - bar_input->value(""); - bar_input->when(FL_WHEN_ENTER_KEY); - bar_input->callback((Fl_Callback*)set_bar_len_cb, this); - - line_input = new Fl_Input(padding+5*button_len, 2, button_len, 30, "Line Interval (bp)"); - line_input->value(""); - line_input->when(FL_WHEN_ENTER_KEY); - line_input->callback((Fl_Callback*)set_line_len_cb, this); - - - thres_input = new Fl_Input(padding+7*button_len, 2, button_len, 30, "Threshold"); - thres_input->value(""); - thres_input->when(FL_WHEN_ENTER_KEY); - thres_input->callback((Fl_Callback*)set_soft_thres_cb, this); - - - // create the connections box - conn_box = new ConnView(padding, padding + 30, w-2*padding, h-2*padding-30); - //conn_box = new ConnView(padding, padding, w-2*padding, h-2*padding); - - end(); - show(); -} - - -ConnWindow::~ConnWindow() -{} - - -void -ConnWindow::add_ana(Mussa *the_ana) -{ - an_analysis = the_ana; - - // relabel window with the analysis name - window_name = "Mussa: " + an_analysis->get_name(); - label((const char*)window_name.c_str()); - - conn_box->setup(an_analysis->get_name(), an_analysis->size(), - an_analysis->get_window(), &(an_analysis->the_seqs), - &(an_analysis->the_paths)); - conn_box->scale_paths(); -} diff --git a/gui/ConnWindow.hh b/gui/ConnWindow.hh deleted file mode 100644 index 35c9e05..0000000 --- a/gui/ConnWindow.hh +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _MUSSA_GUI_CONN_WINDOW_H_ -#define _MUSSA_GUI_CONN_WINDOW_H_ - -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include - -#include -#include -#include - -#include "ConnView.hh" -#include "SetupWindow.hh" -#include "SubAnalysisWindow.hh" -#include "SeqTextWindow.hh" - -//! Window for showing the lines connecting the various sequences together -class ConnWindow : public Fl_Double_Window -{ - private: - Mussa *an_analysis, *sub_analysis; - ConnWindow *sub_conn_win; - - Fl_Menu_Button *file_menu; - Fl_Menu_Button *view_menu; - Fl_Menu_Bar *menu_bar; - Fl_Input *bar_input; - Fl_Input *line_input; - Fl_Input *thres_input; - ConnView *conn_box; - SetupWindow *setup_win; - SubAnalysisWindow *subana_win; - SeqTextWindow *show_seq_win; - int padding, name_pad; - std::string window_name; - - public: - ConnWindow(int w, int h, const char* title); - ~ConnWindow(); - void add_ana(Mussa *the_ana); - - void real_load_ana_cb(); - void real_do_ana_cb(); - void real_setup_ana_cb(); - void real_subana_cb(); - void real_resthres(); - void real_seq_show_cb(); - - void real_seq_win_spawn_cb(); - void real_motif_find_cb(); - void real_annot_win_cb(); - - void real_toggle_bars_cb(); - void real_set_bar_len_cb(Fl_Input* o); - void real_toggle_lines_cb(); - void real_set_line_len_cb(Fl_Input* o); - void real_set_soft_thres_cb(Fl_Input* o); -}; - -#endif diff --git a/gui/ConnWindow.hpp b/gui/ConnWindow.hpp new file mode 100644 index 0000000..cef4de0 --- /dev/null +++ b/gui/ConnWindow.hpp @@ -0,0 +1,67 @@ +#ifndef _MUSSA_GUI_CONN_WINDOW_H_ +#define _MUSSA_GUI_CONN_WINDOW_H_ + +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include + +#include +#include +#include + +#include "gui/ConnView.hpp" +#include "gui/SetupWindow.hpp" +#include "gui/SubAnalysisWindow.hpp" +#include "gui/SeqTextWindow.hpp" + +//! Window for showing the lines connecting the various sequences together +class ConnWindow : public Fl_Double_Window +{ + private: + Mussa *an_analysis, *sub_analysis; + ConnWindow *sub_conn_win; + + Fl_Menu_Button *file_menu; + Fl_Menu_Button *view_menu; + Fl_Menu_Bar *menu_bar; + Fl_Input *bar_input; + Fl_Input *line_input; + Fl_Input *thres_input; + ConnView *conn_box; + SetupWindow *setup_win; + SubAnalysisWindow *subana_win; + SeqTextWindow *show_seq_win; + int padding, name_pad; + std::string window_name; + + public: + ConnWindow(int w, int h, const char* title); + ~ConnWindow(); + void add_ana(Mussa *the_ana); + + void real_load_ana_cb(); + void real_do_ana_cb(); + void real_setup_ana_cb(); + void real_subana_cb(); + void real_resthres(); + void real_seq_show_cb(); + + void real_seq_win_spawn_cb(); + void real_motif_find_cb(); + void real_annot_win_cb(); + + void real_toggle_bars_cb(); + void real_set_bar_len_cb(Fl_Input* o); + void real_toggle_lines_cb(); + void real_set_line_len_cb(Fl_Input* o); + void real_set_soft_thres_cb(Fl_Input* o); +}; + +#endif diff --git a/gui/MotifWindow.cpp b/gui/MotifWindow.cpp new file mode 100644 index 0000000..7a7708b --- /dev/null +++ b/gui/MotifWindow.cpp @@ -0,0 +1,191 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/MotifWindow.hpp" + +#include + +#include + +using namespace std; + +motif +new_blank_motif() +{ + motif *a_motif; + + a_motif = new motif; + a_motif->name = ""; + a_motif->seq = ""; + a_motif->color = (Fl_Color) 5; + a_motif->locations.clear(); + a_motif->dirty = false; + + cout << "name: " << a_motif->name << " seq: " << a_motif->seq << endl; + + return *a_motif; +} + + +void +cb_motif_in(Fl_Input* o, void* v) +{ + motif_instance * blah = (motif_instance *) v; + MotifWindow* T= blah->mw_ptr; + T->cb_motif_in_i(o,blah->index); +} + + +void +cb_motif_color(Fl_Button* o, void* v) +{ + motif_instance * blah = (motif_instance *) v; + MotifWindow* T= blah->mw_ptr; + T->cb_motif_color_i(o,blah->index); +} + + +MotifWindow::MotifWindow(int w, int h, const char* title, + vector * some_motifs):Fl_Window(w,h,title) +{ + int i; + + the_motifs = some_motifs; + motif_count = 0; + + motif_color_buttons.clear(); + + begin(); + motif_input_pack = new Fl_Pack(0, 0, w, h); + motif_input_pack->spacing(4); + + // button to add new motif inputs + add_motif = new Fl_Button(0,0,100,24,"Add Motif Slot"); + add_motif->callback((Fl_Callback*)add_motif_cb, this); + motif_input_pack->add(add_motif); + // test button to make sure motif data is being stored + test = new Fl_Button(0,0,100,24,"show motifs"); + test->callback((Fl_Callback*)print_cb, this); + motif_input_pack->add(test); + // creat an initial set of motif input widgets and attach to motif vector + for (i = 0; i < 5; i++) + { + add_motif_input(i); + motif_count++; + } + + + + + add(motif_input_pack); + + end(); + resizable(this); + show(); +} + + //tmp_input->user_data((void*) i); + +MotifWindow::~MotifWindow(){} + +void +MotifWindow::add_motif_input(int index) +{ + Fl_Input * new_input; + Fl_Button *new_color_button; + motif_instance * something; + Fl_Pack * motif_hor_pack; + + + something = new motif_instance; + something->mw_ptr = this; + something->index = index; + + motif_hor_pack = new Fl_Pack(0, 0, w(), 24); + motif_hor_pack->type(Fl_Pack::HORIZONTAL); + motif_hor_pack->spacing(4); + + // setup the color display/selection button + new_color_button = new Fl_Button(0, 0, 24, 24, ""); + new_color_button->color((*the_motifs)[index].color); + new_color_button->box(FL_FLAT_BOX); + new_color_button->callback((Fl_Callback*)cb_motif_color, (void*) something); + motif_color_buttons.push_back(new_color_button); + motif_hor_pack->add(new_color_button); + + + // setup the motif inputs + new_input = new Fl_Input(0, 0, 200, 24, ""); + new_input->value( ((*the_motifs)[index].seq).c_str() ); + new_input->callback((Fl_Callback*)cb_motif_in, (void*) something); + motif_ins.push_back(new_input); + motif_hor_pack->add(new_input); + + motif_input_pack->add(motif_hor_pack); +} +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ + +void +MotifWindow::cb_motif_in_i(Fl_Input* o, int i) +{ + (*the_motifs)[i].seq = o->value(); + (*the_motifs)[i].dirty = true; +} + +void +MotifWindow::cb_motif_color_i(Fl_Button* o, int i) +{ + //Fl_Color new_color; + + (*the_motifs)[i].color = fl_show_colormap((*the_motifs)[i].color); + //motif_color_buttons[i]-> + o->color((*the_motifs)[i].color); + redraw(); +} + +void MotifWindow::add_motif_cb(Fl_Button* o, void* v) +{ + MotifWindow* T=(MotifWindow*)v; + T->add_motif_cb_real(o,v); +} + + +void MotifWindow::add_motif_cb_real(Fl_Button* , void*) +{ + motif blank_motif; + + //blank_motif.name = ""; + //blank_motif.seq = ""; + blank_motif = new_blank_motif(); + (*the_motifs).push_back(blank_motif); + add_motif_input(motif_count++); + redraw(); +} + + +void MotifWindow::print_cb(Fl_Button* o, void* v) +{ + MotifWindow* T=(MotifWindow*)v; + T->print_cb_real(o,v); +} + + +void MotifWindow::print_cb_real(Fl_Button* , void*) +{ + int i; + + for (i = 0; i < motif_count; i++) + cout << (*the_motifs)[i].seq << endl; +} diff --git a/gui/MotifWindow.cxx b/gui/MotifWindow.cxx deleted file mode 100644 index 7667ec1..0000000 --- a/gui/MotifWindow.cxx +++ /dev/null @@ -1,191 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "MotifWindow.hh" - -#include - -#include - -using namespace std; - -motif -new_blank_motif() -{ - motif *a_motif; - - a_motif = new motif; - a_motif->name = ""; - a_motif->seq = ""; - a_motif->color = (Fl_Color) 5; - a_motif->locations.clear(); - a_motif->dirty = false; - - cout << "name: " << a_motif->name << " seq: " << a_motif->seq << endl; - - return *a_motif; -} - - -void -cb_motif_in(Fl_Input* o, void* v) -{ - motif_instance * blah = (motif_instance *) v; - MotifWindow* T= blah->mw_ptr; - T->cb_motif_in_i(o,blah->index); -} - - -void -cb_motif_color(Fl_Button* o, void* v) -{ - motif_instance * blah = (motif_instance *) v; - MotifWindow* T= blah->mw_ptr; - T->cb_motif_color_i(o,blah->index); -} - - -MotifWindow::MotifWindow(int w, int h, const char* title, - vector * some_motifs):Fl_Window(w,h,title) -{ - int i; - - the_motifs = some_motifs; - motif_count = 0; - - motif_color_buttons.clear(); - - begin(); - motif_input_pack = new Fl_Pack(0, 0, w, h); - motif_input_pack->spacing(4); - - // button to add new motif inputs - add_motif = new Fl_Button(0,0,100,24,"Add Motif Slot"); - add_motif->callback((Fl_Callback*)add_motif_cb, this); - motif_input_pack->add(add_motif); - // test button to make sure motif data is being stored - test = new Fl_Button(0,0,100,24,"show motifs"); - test->callback((Fl_Callback*)print_cb, this); - motif_input_pack->add(test); - // creat an initial set of motif input widgets and attach to motif vector - for (i = 0; i < 5; i++) - { - add_motif_input(i); - motif_count++; - } - - - - - add(motif_input_pack); - - end(); - resizable(this); - show(); -} - - //tmp_input->user_data((void*) i); - -MotifWindow::~MotifWindow(){} - -void -MotifWindow::add_motif_input(int index) -{ - Fl_Input * new_input; - Fl_Button *new_color_button; - motif_instance * something; - Fl_Pack * motif_hor_pack; - - - something = new motif_instance; - something->mw_ptr = this; - something->index = index; - - motif_hor_pack = new Fl_Pack(0, 0, w(), 24); - motif_hor_pack->type(Fl_Pack::HORIZONTAL); - motif_hor_pack->spacing(4); - - // setup the color display/selection button - new_color_button = new Fl_Button(0, 0, 24, 24, ""); - new_color_button->color((*the_motifs)[index].color); - new_color_button->box(FL_FLAT_BOX); - new_color_button->callback((Fl_Callback*)cb_motif_color, (void*) something); - motif_color_buttons.push_back(new_color_button); - motif_hor_pack->add(new_color_button); - - - // setup the motif inputs - new_input = new Fl_Input(0, 0, 200, 24, ""); - new_input->value( ((*the_motifs)[index].seq).c_str() ); - new_input->callback((Fl_Callback*)cb_motif_in, (void*) something); - motif_ins.push_back(new_input); - motif_hor_pack->add(new_input); - - motif_input_pack->add(motif_hor_pack); -} -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ - -void -MotifWindow::cb_motif_in_i(Fl_Input* o, int i) -{ - (*the_motifs)[i].seq = o->value(); - (*the_motifs)[i].dirty = true; -} - -void -MotifWindow::cb_motif_color_i(Fl_Button* o, int i) -{ - //Fl_Color new_color; - - (*the_motifs)[i].color = fl_show_colormap((*the_motifs)[i].color); - //motif_color_buttons[i]-> - o->color((*the_motifs)[i].color); - redraw(); -} - -void MotifWindow::add_motif_cb(Fl_Button* o, void* v) -{ - MotifWindow* T=(MotifWindow*)v; - T->add_motif_cb_real(o,v); -} - - -void MotifWindow::add_motif_cb_real(Fl_Button* , void*) -{ - motif blank_motif; - - //blank_motif.name = ""; - //blank_motif.seq = ""; - blank_motif = new_blank_motif(); - (*the_motifs).push_back(blank_motif); - add_motif_input(motif_count++); - redraw(); -} - - -void MotifWindow::print_cb(Fl_Button* o, void* v) -{ - MotifWindow* T=(MotifWindow*)v; - T->print_cb_real(o,v); -} - - -void MotifWindow::print_cb_real(Fl_Button* , void*) -{ - int i; - - for (i = 0; i < motif_count; i++) - cout << (*the_motifs)[i].seq << endl; -} diff --git a/gui/MotifWindow.hh b/gui/MotifWindow.hh deleted file mode 100644 index ac1e60a..0000000 --- a/gui/MotifWindow.hh +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _MUSSA_GUI_MOTIF_WINDOW_H_ -#define _MUSSA_GUI_MOTIF_WINDOW_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include -#include - -#include -#include - -#include -#include - -#include "alg/mussa_class.hh" - -struct motif -{ - std::string name, seq; - Fl_Color color; - std::vector > locations; - bool dirty; -}; - -//typedef motif_ptr *motif; - - -class MotifWindow : public Fl_Window -{ - public: - MotifWindow(int w, int h, const char* title, std::vector * some_motifs); - ~MotifWindow(); - Fl_Pack * motif_input_pack; - std::list motif_ins; - std::vector motif_color_buttons; - std::list name_ins; - Fl_Button* test; - Fl_Button* add_motif; - - void cb_motif_in_i(Fl_Input*, int i); - void cb_motif_color_i(Fl_Button* o, int i); - - private: - std::vector * the_motifs; - int motif_count; - - void add_motif_input(int index); - - static void add_motif_cb(Fl_Button*, void*); - inline void add_motif_cb_real(Fl_Button*, void*); - - static void print_cb(Fl_Button*, void*); - inline void print_cb_real(Fl_Button*, void*); -}; - -// crazy whacked shite Titus taught me to do to get an index value associated -// with each instance of an input associated with the callback... -struct motif_instance -{ - MotifWindow * mw_ptr; - int index; -}; - -motif new_blank_motif(); -#endif diff --git a/gui/MotifWindow.hpp b/gui/MotifWindow.hpp new file mode 100644 index 0000000..84f5de2 --- /dev/null +++ b/gui/MotifWindow.hpp @@ -0,0 +1,72 @@ +#ifndef _MUSSA_GUI_MOTIF_WINDOW_H_ +#define _MUSSA_GUI_MOTIF_WINDOW_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include +#include + +#include +#include + +#include +#include + +#include "alg/mussa.hpp" + +struct motif +{ + std::string name, seq; + Fl_Color color; + std::vector > locations; + bool dirty; +}; + +//typedef motif_ptr *motif; + + +class MotifWindow : public Fl_Window +{ + public: + MotifWindow(int w, int h, const char* title, std::vector * some_motifs); + ~MotifWindow(); + Fl_Pack * motif_input_pack; + std::list motif_ins; + std::vector motif_color_buttons; + std::list name_ins; + Fl_Button* test; + Fl_Button* add_motif; + + void cb_motif_in_i(Fl_Input*, int i); + void cb_motif_color_i(Fl_Button* o, int i); + + private: + std::vector * the_motifs; + int motif_count; + + void add_motif_input(int index); + + static void add_motif_cb(Fl_Button*, void*); + inline void add_motif_cb_real(Fl_Button*, void*); + + static void print_cb(Fl_Button*, void*); + inline void print_cb_real(Fl_Button*, void*); +}; + +// crazy whacked shite Titus taught me to do to get an index value associated +// with each instance of an input associated with the callback... +struct motif_instance +{ + MotifWindow * mw_ptr; + int index; +}; + +motif new_blank_motif(); +#endif diff --git a/gui/SeqTextWindow.cpp b/gui/SeqTextWindow.cpp new file mode 100644 index 0000000..857e49b --- /dev/null +++ b/gui/SeqTextWindow.cpp @@ -0,0 +1,146 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/SeqTextWindow.hpp" + +#include +using namespace std; +void +get_seq_cb(Fl_Button* o, void* v) +{ + SeqTextWindow* T=(SeqTextWindow*)v; + T->real_get_seq_cb(); +} + +void +SeqTextWindow::real_get_seq_cb() +{ + string sub_seq_formatted; + int seq_len, i, line_len; + + + cout << "length = " << seq_end-seq_start << endl; + + // make sure inputed values within valid ranges + if ((seq_end > seq_start) && (seq_id > -1) && (seq_id < the_seqs.size()) ) + { + sub_sequence = the_seqs[seq_id].subseq(seq_start, seq_end-seq_start); + + sub_seq_formatted = ""; + seq_len = sub_sequence.size(); + line_len = 40; + for (i = 0; i < seq_len; i += line_len) + { + sub_seq_formatted.append(sub_sequence.substr(i,line_len)); + sub_seq_formatted.append("\n"); + } + + seq_display->value((const char *)sub_seq_formatted.c_str()); + } +} + + +// *** input seq index id + +void +set_seq_id_cb(Fl_Input* o, void* v) +{ + SeqTextWindow* T=(SeqTextWindow*)v; + T->real_set_seq_id_cb(o); +} + +void +SeqTextWindow::real_set_seq_id_cb(Fl_Input* o) +{ + seq_id = atoi(o->value()) - 1; // -1 since arrays start at 0 +} + + +// *** input seq start index + +void +set_seq_start_cb(Fl_Input* o, void* v) +{ + SeqTextWindow* T=(SeqTextWindow*)v; + T->real_set_seq_start_cb(o); +} + +void +SeqTextWindow::real_set_seq_start_cb(Fl_Input* o) +{ + seq_start = atoi(o->value()); +} + +// *** input seq end index + +void +set_seq_end_cb(Fl_Input* o, void* v) +{ + SeqTextWindow* T=(SeqTextWindow*)v; + T->real_set_seq_end_cb(o); +} + +void +SeqTextWindow::real_set_seq_end_cb(Fl_Input* o) +{ + seq_end = atoi(o->value()); +} + + +SeqTextWindow::SeqTextWindow(int w, int h, const char* title, + vector some_Seqs):Fl_Window(w,h,title) +{ + string a_name; + color(FL_WHITE); + the_seqs = some_Seqs; + + + seq_id = -1; + seq_start = 1000000; + seq_end = -1000000; + + begin(); + + seq_id_input = new Fl_Input(80,10,30,30, "Seq num: "); + seq_id_input->value(""); + seq_id_input->callback((Fl_Callback*)set_seq_id_cb, this); + + seq_start_input = new Fl_Input(160,10,100,30, " start: "); + seq_start_input->value(""); + seq_start_input->callback((Fl_Callback*)set_seq_start_cb, this); + + seq_end_input = new Fl_Input(310,10,100,30, "end: "); + seq_end_input->value(""); + seq_end_input->callback((Fl_Callback*)set_seq_end_cb, this); + + seq_display = new Fl_Multiline_Output(10, 50, w-20, h-60, ""); + seq_display->value(""); + + //seq_display2 = new Fl_Text_Display(10,100, w-20, h-110,""); + + // button to get the sequence + get_seq_but = new Fl_Button(w-80,10,80,30,"Get Seq"); + get_seq_but->callback((Fl_Callback*)get_seq_cb, this); + + + end(); + //resizable(this); + show(); +} + + +SeqTextWindow::~SeqTextWindow(){} + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ diff --git a/gui/SeqTextWindow.cxx b/gui/SeqTextWindow.cxx deleted file mode 100644 index 614a065..0000000 --- a/gui/SeqTextWindow.cxx +++ /dev/null @@ -1,146 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "gui/SeqTextWindow.hh" - -#include -using namespace std; -void -get_seq_cb(Fl_Button* o, void* v) -{ - SeqTextWindow* T=(SeqTextWindow*)v; - T->real_get_seq_cb(); -} - -void -SeqTextWindow::real_get_seq_cb() -{ - string sub_seq_formatted; - int seq_len, i, line_len; - - - cout << "length = " << seq_end-seq_start << endl; - - // make sure inputed values within valid ranges - if ((seq_end > seq_start) && (seq_id > -1) && (seq_id < the_seqs.size()) ) - { - sub_sequence = the_seqs[seq_id].subseq(seq_start, seq_end-seq_start); - - sub_seq_formatted = ""; - seq_len = sub_sequence.size(); - line_len = 40; - for (i = 0; i < seq_len; i += line_len) - { - sub_seq_formatted.append(sub_sequence.substr(i,line_len)); - sub_seq_formatted.append("\n"); - } - - seq_display->value((const char *)sub_seq_formatted.c_str()); - } -} - - -// *** input seq index id - -void -set_seq_id_cb(Fl_Input* o, void* v) -{ - SeqTextWindow* T=(SeqTextWindow*)v; - T->real_set_seq_id_cb(o); -} - -void -SeqTextWindow::real_set_seq_id_cb(Fl_Input* o) -{ - seq_id = atoi(o->value()) - 1; // -1 since arrays start at 0 -} - - -// *** input seq start index - -void -set_seq_start_cb(Fl_Input* o, void* v) -{ - SeqTextWindow* T=(SeqTextWindow*)v; - T->real_set_seq_start_cb(o); -} - -void -SeqTextWindow::real_set_seq_start_cb(Fl_Input* o) -{ - seq_start = atoi(o->value()); -} - -// *** input seq end index - -void -set_seq_end_cb(Fl_Input* o, void* v) -{ - SeqTextWindow* T=(SeqTextWindow*)v; - T->real_set_seq_end_cb(o); -} - -void -SeqTextWindow::real_set_seq_end_cb(Fl_Input* o) -{ - seq_end = atoi(o->value()); -} - - -SeqTextWindow::SeqTextWindow(int w, int h, const char* title, - vector some_Seqs):Fl_Window(w,h,title) -{ - string a_name; - color(FL_WHITE); - the_seqs = some_Seqs; - - - seq_id = -1; - seq_start = 1000000; - seq_end = -1000000; - - begin(); - - seq_id_input = new Fl_Input(80,10,30,30, "Seq num: "); - seq_id_input->value(""); - seq_id_input->callback((Fl_Callback*)set_seq_id_cb, this); - - seq_start_input = new Fl_Input(160,10,100,30, " start: "); - seq_start_input->value(""); - seq_start_input->callback((Fl_Callback*)set_seq_start_cb, this); - - seq_end_input = new Fl_Input(310,10,100,30, "end: "); - seq_end_input->value(""); - seq_end_input->callback((Fl_Callback*)set_seq_end_cb, this); - - seq_display = new Fl_Multiline_Output(10, 50, w-20, h-60, ""); - seq_display->value(""); - - //seq_display2 = new Fl_Text_Display(10,100, w-20, h-110,""); - - // button to get the sequence - get_seq_but = new Fl_Button(w-80,10,80,30,"Get Seq"); - get_seq_but->callback((Fl_Callback*)get_seq_cb, this); - - - end(); - //resizable(this); - show(); -} - - -SeqTextWindow::~SeqTextWindow(){} - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ diff --git a/gui/SeqTextWindow.hh b/gui/SeqTextWindow.hh deleted file mode 100644 index 810879c..0000000 --- a/gui/SeqTextWindow.hh +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _MUSSA_GUI_SEQ_TEXT_H_ -#define _MUSSA_GUI_SEQ_TEXT_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "alg/sequence.hh" - -class SeqTextWindow : public Fl_Window -{ - public: - SeqTextWindow(int w, int h, const char* title, std::vector some_Seqs); - ~SeqTextWindow(); - - Fl_Button* get_seq_but; - Fl_Multiline_Output* seq_display; - Fl_Text_Buffer* seq_buffer; - Fl_Text_Display* seq_display2; - Fl_Input *seq_id_input; - Fl_Input *seq_start_input; - Fl_Input *seq_end_input; - - // callback receiver functions - - void real_get_seq_cb(); - void real_set_seq_id_cb(Fl_Input* o); - void real_set_seq_start_cb(Fl_Input* o); - void real_set_seq_end_cb(Fl_Input* o); - - private: - // sequence data - std::vector the_seqs; - std::string sub_sequence; - int seq_id, seq_start, seq_end; -}; -#endif diff --git a/gui/SeqTextWindow.hpp b/gui/SeqTextWindow.hpp new file mode 100644 index 0000000..30030a5 --- /dev/null +++ b/gui/SeqTextWindow.hpp @@ -0,0 +1,51 @@ +#ifndef _MUSSA_GUI_SEQ_TEXT_H_ +#define _MUSSA_GUI_SEQ_TEXT_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "alg/sequence.hpp" + +class SeqTextWindow : public Fl_Window +{ + public: + SeqTextWindow(int w, int h, const char* title, std::vector some_Seqs); + ~SeqTextWindow(); + + Fl_Button* get_seq_but; + Fl_Multiline_Output* seq_display; + Fl_Text_Buffer* seq_buffer; + Fl_Text_Display* seq_display2; + Fl_Input *seq_id_input; + Fl_Input *seq_start_input; + Fl_Input *seq_end_input; + + // callback receiver functions + + void real_get_seq_cb(); + void real_set_seq_id_cb(Fl_Input* o); + void real_set_seq_start_cb(Fl_Input* o); + void real_set_seq_end_cb(Fl_Input* o); + + private: + // sequence data + std::vector the_seqs; + std::string sub_sequence; + int seq_id, seq_start, seq_end; +}; +#endif diff --git a/gui/SeqView.cpp b/gui/SeqView.cpp new file mode 100644 index 0000000..30c1dd3 --- /dev/null +++ b/gui/SeqView.cpp @@ -0,0 +1,520 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/SeqView.hpp" +#include +#include + +#include +#include + +using namespace std; + +void +SeqView::setup(string name, int sq_num, + vector *some_seqs, + list some_paths, vector some_lens, + vector *some_motifs) +{ + int seq_i; + list::iterator pathz_i; + + analysis_name = name; + seq_num = sq_num; + S = some_seqs; + P = some_paths; + seq_lens = some_lens; + the_motifs = some_motifs; + + y_seq_incre = (y_max-10-10) / (seq_num - 1); + + fl_font(FL_COURIER, 14); + cout << "font width: " << fl_width('A') << endl; + + index_pad = 6 * (int) fl_width('A') + 5; + + align_offsets(0); + + raw_sequence.clear(); + for(seq_i = 0; seq_i < seq_num; ++seq_i) + raw_sequence.push_back( (*S)[seq_i].get_seq() ); + + for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) + { + show_aligns.push_back(true); + } + + dragging = false; + scroll_offset = 0; + //scroll_pos = 0; + drag_change = 0; + + cout << "waaaaa!\n"; + cout << x() << " " << y() << " " << w() << " " << h() << endl; +} + +void +SeqView::resize(int new_x, int new_y, int new_w, int new_h) +{ + x(new_x); + y(new_y); + w(new_w); + h(new_h); + + // hmmm, why do I use these values on the the widgets inherent ones? + // I think there was a reason...once? + x_max = new_w; + y_max = new_h; + x_min = new_x; + y_min = new_y; + + // things that need to be recalculated + y_seq_incre = (y_max-10-10) / (seq_num - 1); +} + + +void +SeqView::draw() +{ + double ch_width; + + + // clear drawing area and set background to white + fl_color(FL_WHITE); + fl_rectf(x(), y(), w(), h()); + + fl_font(FL_COURIER, 14); + //blatantly stolen from FR2 + ch_width = fl_width('A'); // monospaced: all characters are same width + + + if (show_bars) + { + int grey_box_num, grey_box_len; + int i; + // draw in some light grey boxes every 10bp to delineate for user + //fl_color(200,235,235); + fl_color(180,180,180); + grey_box_num = (((x_max - index_pad) / (int) ch_width) / 10) + 1; + grey_box_len = 10 * (int) ch_width; + for(i = 0; i < grey_box_num; i++) + if ((i % 2) != 0) + fl_rectf(x()+index_pad-1 + (i * grey_box_len), y(), grey_box_len, h()); + } + + if (show_motifs) + draw_motifs(ch_width); + + draw_sequence(ch_width); + + draw_match_lines(ch_width); + + draw_indices(ch_width); + + + // draw some bounding boxes to visually separate things + fl_color(150,200,255); + fl_line_style(FL_SOLID, 2, NULL); + fl_rect(x(), y(), w(), h()); + fl_rect(x()+index_pad-1, y(), w()-2*(index_pad-1), h()); +} + +void +SeqView::draw_motifs(double ch_width) +{ + vector::iterator motif_i; + vector some_motif_locs; + vector::iterator i_locs; + int scale_len, motif_len, i2; + int y_loc, x_start; + + //fl_color(255,0,255); + fl_line_style(FL_SOLID, 10, NULL); + motif_i = the_motifs->begin(); + while (motif_i != the_motifs->end()) + { + fl_color(motif_i->color); + motif_len = motif_i->seq.length(); + scale_len = (int) (motif_len * ch_width); + y_loc = y_min + 10; + if (!motif_i->locations.empty()) + for(i2 = 0; i2 < seq_num; i2++) + { + some_motif_locs = (*motif_i).locations[i2]; + + i_locs = some_motif_locs.begin(); + while (i_locs != some_motif_locs.end()) + { + x_start = (int) ((*i_locs +scroll_offset - seq_align_offsets[i2]) + * ch_width) + index_pad + x(); + + //cout << *i_locs << ":" << x_start << " "; + // don't draw highlights outside of box range, they can wraparound past some boundry + if ((x_start > 0) && (x_start < w())) + fl_line(x_start,y_loc,x_start+scale_len,y_loc); + ++i_locs; + } + //cout << endl; + y_loc += y_seq_incre; + } + ++motif_i; + } +} + +void +SeqView::draw_sequence(double ch_width) +{ + int i, seq_i, y_loc; + Sequence a_seq; + string sub_seq; + int seq_len, sub_seq_start, sub_seq_len; + + + + fl_color(FL_BLACK); + y_loc = y_min + 10 + 5; + + for(seq_i = 0; seq_i < seq_num; seq_i++) + { + seq_len = raw_sequence[seq_i].length(); + sub_seq_start = seq_align_offsets[seq_i] - scroll_offset; + sub_seq_len = (x_max - index_pad) / (int) ch_width; + //cout << x_max << " index_pad: " << index_pad << " y - ip: " << (x_max - index_pad) << endl; + + // gotta check thru boundary conditions to make sure we're producing the + // right string for the current position (otherwise gonna crash due to + // illegal indexing into substr + if (sub_seq_start < 0) + { + sub_seq_len = sub_seq_len - sub_seq_start; + if (sub_seq_len < 0) + sub_seq_len = 0; + sub_seq_start = 0; + } + else if (sub_seq_start >= seq_len) + { + sub_seq_start = seq_len; + sub_seq_len = 0; + } + else if ((sub_seq_start + sub_seq_len) >= seq_len) + sub_seq_len = seq_len - sub_seq_start; + + sub_seq = raw_sequence[seq_i].substr(sub_seq_start, sub_seq_len); + fl_draw(sub_seq.c_str(), index_pad, y_loc); + y_loc += y_seq_incre; + } +} + + +void +SeqView::draw_match_lines(double ch_width) +{ + int i, y_loc; + list::iterator pathz_i; + int i2, i3; + int x_start, y_start, x_end, y_end; + int window_length, win_i; + int rc_1 = 0; + int rc_2 = 0; + int offset1, offset2; + float center1, center2; + bool rc_color; + vector rc_list; + bool full_match; + vector matched; + int align_counter; + + + align_counter = 0; + for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) + { + if (show_aligns[align_counter]) + { + ExtendedConservedPath& a_path = *pathz_i; + window_length = a_path.window_size; + + // determine which parts of the path are RC relative to first species + rc_list.clear(); + for(i2 = 0; i2 < a_path.size()-1; i2++) + { + if (a_path[i2] < 0) + rc_list.push_back(true); + else + rc_list.push_back(false); + } + + // loop over each bp in the conserved region for all sequences + for(win_i = 0; win_i < window_length; win_i++) + { + // determine which exact base pairs match between the sequences + full_match = true; + for(i2 = 0; i2 < a_path.size()-1; i2++) + { + // assume not rc as most likely, adjust below + rc_1 = 0; + rc_2 = 0; + // no matter the case, any RC node needs adjustments + if (a_path[i2] < 0) + rc_1 = window_length-1; + if (a_path[i2+1] < 0) + rc_2 = window_length-1; + + x_start = (abs(a_path[i2]-rc_1+win_i)); + x_end = (abs(a_path[i2+1]-rc_2+win_i)); + + // RC case handling + // ugh, and xor...only want rc coloring if just one of the nodes is rc + // if both nodes are rc, then they are 'normal' relative to each other + if ( ( rc_list[i2] || rc_list[i2+1] ) && + !(rc_list[i2] && rc_list[i2+1] ) ) + { //the hideous rc matching logic - not complex, but annoying + if ( !( ( (raw_sequence[i2][x_start] == 'A') && + (raw_sequence[i2+1][x_end] == 'T') ) || + ( (raw_sequence[i2][x_start] == 'T') && + (raw_sequence[i2+1][x_end] == 'A') ) || + ( (raw_sequence[i2][x_start] == 'G') && + (raw_sequence[i2+1][x_end] == 'C') ) || + ( (raw_sequence[i2][x_start] == 'C') && + (raw_sequence[i2+1][x_end] == 'G') ) ) ) + full_match = false; + } + else + { + if (!( (raw_sequence[i2][x_start] == raw_sequence[i2+1][x_end]) && + (raw_sequence[i2][x_start] != 'N') && + (raw_sequence[i2+1][x_end] != 'N') ) ) + full_match = false; + } + } + + // draw for matches stretching across all sequences + if (full_match) + { + fl_line_style(FL_SOLID, 1, NULL); + + // now can draw the line for each bp in this window that matches + // grrr, need to ask if anyone cares if I switch the seq + // top-bot order... + i3 = 0; + y_loc = y_min + 5; + for(i2 = 0; i2 < a_path.size()-1; i2++) + { + // assume not rc as most likely, adjust below + rc_1 = 0; + rc_2 = 0; + // this makes the lines start in the middle of the drawn char/bp + center1 = 0.5; + center2 = 0.5; + // no matter the case, any RC node needs adjustments + if (a_path[i2] < 0) + { + rc_1 = window_length; + center1 = -center1; + } + if (a_path[i2] < 0) + { + rc_2 = window_length; + center2 = -center2; + } + + // set offset based on current alignment for which bp to show + offset1 = seq_align_offsets[i2]; + offset2 = seq_align_offsets[i2+1]; + + if ( ( rc_list[i2] || rc_list[i2+1] ) && + !(rc_list[i2] && rc_list[i2+1] ) ) + fl_color(FL_BLUE); + else + fl_color(FL_RED); + + // maybe shouldn't recalc these, but store values from first loop + x_start = (abs((int) (a_path[i2]-rc_1+win_i))); + x_end = (abs((int) (a_path[i2+1]-rc_2+win_i))); + + fl_line( (int)((x_start+center1-offset1+scroll_offset)*ch_width) + + index_pad, y_loc + 10, + (int)((x_end+center2-offset2+scroll_offset)*ch_width) + + index_pad, y_loc+y_seq_incre ); + y_loc += y_seq_incre; + } + } + } + } + align_counter++; + } +} + +void +SeqView::draw_indices(double ch_width) +{ + int seq_i; + Sequence a_seq; + int y_loc; + ostringstream an_index; + int shown_seq_len; + + + // clear out space on sides to draw in index values + // I block out the sides rather than adding offsets to the drawing of seq + // and conservation lines since the lines need to draw off the 'edge' + fl_color(FL_WHITE); + fl_rectf(0, y_min, index_pad, h()+y_min); + fl_rectf(w()-index_pad, y_min, index_pad, h()+y_min); + + // now can draw in the indices of the start and end of the shown sequence + fl_color(FL_BLACK); + y_loc = y_min + 10 + 5; + for(seq_i = 0; seq_i < seq_num; seq_i++) + { + an_index.str(""); + an_index << (seq_align_offsets[seq_i]-scroll_offset); + fl_draw((an_index.str()).c_str(), 2, y_loc); + + shown_seq_len = (w() - 2 * index_pad) / (int) ch_width; + an_index.str(""); + an_index << (seq_align_offsets[seq_i]-scroll_offset+shown_seq_len); + fl_draw((an_index.str()).c_str(), w()-index_pad+2, y_loc); + y_loc += y_seq_incre; + } +} + + +void +SeqView::toggle_align(int align_num) +{ + //cout << align_num << endl; + //cout << show_aligns[align_num] << endl; + show_aligns[align_num] = !show_aligns[align_num]; + //cout << show_aligns[align_num] << endl; +} + + +void +SeqView::align_offsets(int align_num) +{ + list::iterator pathz_i; + int i; + int window_length; + + cout << "alignment: " << align_num << endl; + + if (P.begin() == P.end()) + cout << "crud....\n"; + else + { + pathz_i = P.begin(); + + while(pathz_i != P.end()) + ++pathz_i; + + // find the path specified + i = 0; + pathz_i = P.begin(); + while( (i < align_num) && (pathz_i != P.end()) ) + { + ++i; + ++pathz_i; + } + + // now set the alignment offsets - basically where the path starts + seq_align_offsets.clear(); + for(i = 0; i < seq_num ; i++) + { + //cout << (*pathz_i)[i+1] << endl; + seq_align_offsets.push_back( abs((*pathz_i)[i+1]) ); + // for testing purposes: to see everything in the short test sequences + //seq_align_offsets.push_back(0); + } + // reset any dragging done, otherwise might be hard to find selected align + scroll_offset = 0; + } +} + + + +int +SeqView::handle(int e) +{ + int return_value; + + // this empty string needs to be put on cout, otherwise the -O optimize + // compile option seems to throw this function away with the following: + // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) + cout << ""; + + switch(e) + { + case FL_PUSH: + if (Fl::event_button3()) + { + cout << "menu menu menu!\n"; + return_value = 1; + } + break; + case FL_DRAG: + if (!dragging) + { + drag_change = Fl::event_x(); + dragging = true; + return_value = 1; + } + drag_change = Fl::event_x() - drag_change; + scroll_offset += drag_change; + drag_change = Fl::event_x(); + redraw(); + break; + case FL_RELEASE: + if (dragging) + { + //scroll_offset += Fl::event_x() - drag_start; + //scroll_dist = Fl::event_x() - drag_start; + //scroll_offset += scroll_dist; + //scroll_offset += scroll_pos; + dragging = false; + redraw(); + return_value = 1; + } + break; + default: + return_value = Fl_Widget::handle(e); + } + + return return_value; +} + +void +SeqView::toggle_bars() +{ + show_bars = !show_bars; + redraw(); +} + + +void +SeqView::toggle_motifs() +{ + show_motifs = !show_motifs; + redraw(); +} + + +void +SeqView::reporter(string id, int value) +{ + cout << id << " : " << value << endl; +} + + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ diff --git a/gui/SeqView.cxx b/gui/SeqView.cxx deleted file mode 100644 index 8f6d9d5..0000000 --- a/gui/SeqView.cxx +++ /dev/null @@ -1,520 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "SeqView.hh" -#include -#include - -#include -#include - -using namespace std; - -void -SeqView::setup(string name, int sq_num, - vector *some_seqs, - list some_paths, vector some_lens, - vector *some_motifs) -{ - int seq_i; - list::iterator pathz_i; - - analysis_name = name; - seq_num = sq_num; - S = some_seqs; - P = some_paths; - seq_lens = some_lens; - the_motifs = some_motifs; - - y_seq_incre = (y_max-10-10) / (seq_num - 1); - - fl_font(FL_COURIER, 14); - cout << "font width: " << fl_width('A') << endl; - - index_pad = 6 * (int) fl_width('A') + 5; - - align_offsets(0); - - raw_sequence.clear(); - for(seq_i = 0; seq_i < seq_num; ++seq_i) - raw_sequence.push_back( (*S)[seq_i].get_seq() ); - - for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) - { - show_aligns.push_back(true); - } - - dragging = false; - scroll_offset = 0; - //scroll_pos = 0; - drag_change = 0; - - cout << "waaaaa!\n"; - cout << x() << " " << y() << " " << w() << " " << h() << endl; -} - -void -SeqView::resize(int new_x, int new_y, int new_w, int new_h) -{ - x(new_x); - y(new_y); - w(new_w); - h(new_h); - - // hmmm, why do I use these values on the the widgets inherent ones? - // I think there was a reason...once? - x_max = new_w; - y_max = new_h; - x_min = new_x; - y_min = new_y; - - // things that need to be recalculated - y_seq_incre = (y_max-10-10) / (seq_num - 1); -} - - -void -SeqView::draw() -{ - double ch_width; - - - // clear drawing area and set background to white - fl_color(FL_WHITE); - fl_rectf(x(), y(), w(), h()); - - fl_font(FL_COURIER, 14); - //blatantly stolen from FR2 - ch_width = fl_width('A'); // monospaced: all characters are same width - - - if (show_bars) - { - int grey_box_num, grey_box_len; - int i; - // draw in some light grey boxes every 10bp to delineate for user - //fl_color(200,235,235); - fl_color(180,180,180); - grey_box_num = (((x_max - index_pad) / (int) ch_width) / 10) + 1; - grey_box_len = 10 * (int) ch_width; - for(i = 0; i < grey_box_num; i++) - if ((i % 2) != 0) - fl_rectf(x()+index_pad-1 + (i * grey_box_len), y(), grey_box_len, h()); - } - - if (show_motifs) - draw_motifs(ch_width); - - draw_sequence(ch_width); - - draw_match_lines(ch_width); - - draw_indices(ch_width); - - - // draw some bounding boxes to visually separate things - fl_color(150,200,255); - fl_line_style(FL_SOLID, 2, NULL); - fl_rect(x(), y(), w(), h()); - fl_rect(x()+index_pad-1, y(), w()-2*(index_pad-1), h()); -} - -void -SeqView::draw_motifs(double ch_width) -{ - vector::iterator motif_i; - vector some_motif_locs; - vector::iterator i_locs; - int scale_len, motif_len, i2; - int y_loc, x_start; - - //fl_color(255,0,255); - fl_line_style(FL_SOLID, 10, NULL); - motif_i = the_motifs->begin(); - while (motif_i != the_motifs->end()) - { - fl_color(motif_i->color); - motif_len = motif_i->seq.length(); - scale_len = (int) (motif_len * ch_width); - y_loc = y_min + 10; - if (!motif_i->locations.empty()) - for(i2 = 0; i2 < seq_num; i2++) - { - some_motif_locs = (*motif_i).locations[i2]; - - i_locs = some_motif_locs.begin(); - while (i_locs != some_motif_locs.end()) - { - x_start = (int) ((*i_locs +scroll_offset - seq_align_offsets[i2]) - * ch_width) + index_pad + x(); - - //cout << *i_locs << ":" << x_start << " "; - // don't draw highlights outside of box range, they can wraparound past some boundry - if ((x_start > 0) && (x_start < w())) - fl_line(x_start,y_loc,x_start+scale_len,y_loc); - ++i_locs; - } - //cout << endl; - y_loc += y_seq_incre; - } - ++motif_i; - } -} - -void -SeqView::draw_sequence(double ch_width) -{ - int i, seq_i, y_loc; - Sequence a_seq; - string sub_seq; - int seq_len, sub_seq_start, sub_seq_len; - - - - fl_color(FL_BLACK); - y_loc = y_min + 10 + 5; - - for(seq_i = 0; seq_i < seq_num; seq_i++) - { - seq_len = raw_sequence[seq_i].length(); - sub_seq_start = seq_align_offsets[seq_i] - scroll_offset; - sub_seq_len = (x_max - index_pad) / (int) ch_width; - //cout << x_max << " index_pad: " << index_pad << " y - ip: " << (x_max - index_pad) << endl; - - // gotta check thru boundary conditions to make sure we're producing the - // right string for the current position (otherwise gonna crash due to - // illegal indexing into substr - if (sub_seq_start < 0) - { - sub_seq_len = sub_seq_len - sub_seq_start; - if (sub_seq_len < 0) - sub_seq_len = 0; - sub_seq_start = 0; - } - else if (sub_seq_start >= seq_len) - { - sub_seq_start = seq_len; - sub_seq_len = 0; - } - else if ((sub_seq_start + sub_seq_len) >= seq_len) - sub_seq_len = seq_len - sub_seq_start; - - sub_seq = raw_sequence[seq_i].substr(sub_seq_start, sub_seq_len); - fl_draw(sub_seq.c_str(), index_pad, y_loc); - y_loc += y_seq_incre; - } -} - - -void -SeqView::draw_match_lines(double ch_width) -{ - int i, y_loc; - list::iterator pathz_i; - int i2, i3; - int x_start, y_start, x_end, y_end; - int window_length, win_i; - int rc_1 = 0; - int rc_2 = 0; - int offset1, offset2; - float center1, center2; - bool rc_color; - vector rc_list; - bool full_match; - vector matched; - int align_counter; - - - align_counter = 0; - for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) - { - if (show_aligns[align_counter]) - { - ExtendedConservedPath& a_path = *pathz_i; - window_length = a_path.window_size; - - // determine which parts of the path are RC relative to first species - rc_list.clear(); - for(i2 = 0; i2 < a_path.size()-1; i2++) - { - if (a_path[i2] < 0) - rc_list.push_back(true); - else - rc_list.push_back(false); - } - - // loop over each bp in the conserved region for all sequences - for(win_i = 0; win_i < window_length; win_i++) - { - // determine which exact base pairs match between the sequences - full_match = true; - for(i2 = 0; i2 < a_path.size()-1; i2++) - { - // assume not rc as most likely, adjust below - rc_1 = 0; - rc_2 = 0; - // no matter the case, any RC node needs adjustments - if (a_path[i2] < 0) - rc_1 = window_length-1; - if (a_path[i2+1] < 0) - rc_2 = window_length-1; - - x_start = (abs(a_path[i2]-rc_1+win_i)); - x_end = (abs(a_path[i2+1]-rc_2+win_i)); - - // RC case handling - // ugh, and xor...only want rc coloring if just one of the nodes is rc - // if both nodes are rc, then they are 'normal' relative to each other - if ( ( rc_list[i2] || rc_list[i2+1] ) && - !(rc_list[i2] && rc_list[i2+1] ) ) - { //the hideous rc matching logic - not complex, but annoying - if ( !( ( (raw_sequence[i2][x_start] == 'A') && - (raw_sequence[i2+1][x_end] == 'T') ) || - ( (raw_sequence[i2][x_start] == 'T') && - (raw_sequence[i2+1][x_end] == 'A') ) || - ( (raw_sequence[i2][x_start] == 'G') && - (raw_sequence[i2+1][x_end] == 'C') ) || - ( (raw_sequence[i2][x_start] == 'C') && - (raw_sequence[i2+1][x_end] == 'G') ) ) ) - full_match = false; - } - else - { - if (!( (raw_sequence[i2][x_start] == raw_sequence[i2+1][x_end]) && - (raw_sequence[i2][x_start] != 'N') && - (raw_sequence[i2+1][x_end] != 'N') ) ) - full_match = false; - } - } - - // draw for matches stretching across all sequences - if (full_match) - { - fl_line_style(FL_SOLID, 1, NULL); - - // now can draw the line for each bp in this window that matches - // grrr, need to ask if anyone cares if I switch the seq - // top-bot order... - i3 = 0; - y_loc = y_min + 5; - for(i2 = 0; i2 < a_path.size()-1; i2++) - { - // assume not rc as most likely, adjust below - rc_1 = 0; - rc_2 = 0; - // this makes the lines start in the middle of the drawn char/bp - center1 = 0.5; - center2 = 0.5; - // no matter the case, any RC node needs adjustments - if (a_path[i2] < 0) - { - rc_1 = window_length; - center1 = -center1; - } - if (a_path[i2] < 0) - { - rc_2 = window_length; - center2 = -center2; - } - - // set offset based on current alignment for which bp to show - offset1 = seq_align_offsets[i2]; - offset2 = seq_align_offsets[i2+1]; - - if ( ( rc_list[i2] || rc_list[i2+1] ) && - !(rc_list[i2] && rc_list[i2+1] ) ) - fl_color(FL_BLUE); - else - fl_color(FL_RED); - - // maybe shouldn't recalc these, but store values from first loop - x_start = (abs((int) (a_path[i2]-rc_1+win_i))); - x_end = (abs((int) (a_path[i2+1]-rc_2+win_i))); - - fl_line( (int)((x_start+center1-offset1+scroll_offset)*ch_width) - + index_pad, y_loc + 10, - (int)((x_end+center2-offset2+scroll_offset)*ch_width) - + index_pad, y_loc+y_seq_incre ); - y_loc += y_seq_incre; - } - } - } - } - align_counter++; - } -} - -void -SeqView::draw_indices(double ch_width) -{ - int seq_i; - Sequence a_seq; - int y_loc; - ostringstream an_index; - int shown_seq_len; - - - // clear out space on sides to draw in index values - // I block out the sides rather than adding offsets to the drawing of seq - // and conservation lines since the lines need to draw off the 'edge' - fl_color(FL_WHITE); - fl_rectf(0, y_min, index_pad, h()+y_min); - fl_rectf(w()-index_pad, y_min, index_pad, h()+y_min); - - // now can draw in the indices of the start and end of the shown sequence - fl_color(FL_BLACK); - y_loc = y_min + 10 + 5; - for(seq_i = 0; seq_i < seq_num; seq_i++) - { - an_index.str(""); - an_index << (seq_align_offsets[seq_i]-scroll_offset); - fl_draw((an_index.str()).c_str(), 2, y_loc); - - shown_seq_len = (w() - 2 * index_pad) / (int) ch_width; - an_index.str(""); - an_index << (seq_align_offsets[seq_i]-scroll_offset+shown_seq_len); - fl_draw((an_index.str()).c_str(), w()-index_pad+2, y_loc); - y_loc += y_seq_incre; - } -} - - -void -SeqView::toggle_align(int align_num) -{ - //cout << align_num << endl; - //cout << show_aligns[align_num] << endl; - show_aligns[align_num] = !show_aligns[align_num]; - //cout << show_aligns[align_num] << endl; -} - - -void -SeqView::align_offsets(int align_num) -{ - list::iterator pathz_i; - int i; - int window_length; - - cout << "alignment: " << align_num << endl; - - if (P.begin() == P.end()) - cout << "crud....\n"; - else - { - pathz_i = P.begin(); - - while(pathz_i != P.end()) - ++pathz_i; - - // find the path specified - i = 0; - pathz_i = P.begin(); - while( (i < align_num) && (pathz_i != P.end()) ) - { - ++i; - ++pathz_i; - } - - // now set the alignment offsets - basically where the path starts - seq_align_offsets.clear(); - for(i = 0; i < seq_num ; i++) - { - //cout << (*pathz_i)[i+1] << endl; - seq_align_offsets.push_back( abs((*pathz_i)[i+1]) ); - // for testing purposes: to see everything in the short test sequences - //seq_align_offsets.push_back(0); - } - // reset any dragging done, otherwise might be hard to find selected align - scroll_offset = 0; - } -} - - - -int -SeqView::handle(int e) -{ - int return_value; - - // this empty string needs to be put on cout, otherwise the -O optimize - // compile option seems to throw this function away with the following: - // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) - cout << ""; - - switch(e) - { - case FL_PUSH: - if (Fl::event_button3()) - { - cout << "menu menu menu!\n"; - return_value = 1; - } - break; - case FL_DRAG: - if (!dragging) - { - drag_change = Fl::event_x(); - dragging = true; - return_value = 1; - } - drag_change = Fl::event_x() - drag_change; - scroll_offset += drag_change; - drag_change = Fl::event_x(); - redraw(); - break; - case FL_RELEASE: - if (dragging) - { - //scroll_offset += Fl::event_x() - drag_start; - //scroll_dist = Fl::event_x() - drag_start; - //scroll_offset += scroll_dist; - //scroll_offset += scroll_pos; - dragging = false; - redraw(); - return_value = 1; - } - break; - default: - return_value = Fl_Widget::handle(e); - } - - return return_value; -} - -void -SeqView::toggle_bars() -{ - show_bars = !show_bars; - redraw(); -} - - -void -SeqView::toggle_motifs() -{ - show_motifs = !show_motifs; - redraw(); -} - - -void -SeqView::reporter(string id, int value) -{ - cout << id << " : " << value << endl; -} - - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ diff --git a/gui/SeqView.hh b/gui/SeqView.hh deleted file mode 100644 index e124e17..0000000 --- a/gui/SeqView.hh +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _MUSSA_GUI_SEQ_VIEW_H_ -#define _MUSSA_GUI_SEQ_VIEW_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include -#include - -#include - -#include "MotifWindow.hh" -#include "SetupWindow.hh" - -class SeqView : public Fl_Box -{ - public: - SeqView(int x_top,int y_top,int x_bot,int y_bot) : - Fl_Box(x_top,y_top,x_bot,y_bot) - { - x_max = x_bot; - y_max = y_bot; - x_min = x_top; - y_min = y_top; - show_bars = true; - show_motifs = true; - } - - void setup(std::string name, int sq_num, std::vector *some_seqs, - std::list some_paths, - std::vector some_lens, std::vector *some_motifs); - void align_offsets(int align_num); - void toggle_align(int align_num); - void toggle_bars(); - void toggle_motifs(); - - private: - std::string analysis_name; - int seq_num; - int base_window_len; - - //this data is passed as pointers to the instantiated classes - std::vector *S; - //list of paths in selection box - std::list P; - std::vector seq_lens; - //pointer to passed motif data - std::vector *the_motifs; - - int x_max, y_max, x_min, y_min; - int y_seq_incre; - int index_pad; - std::vector seq_align_offsets; - std::vector raw_sequence; - bool dragging; - int drag_change, scroll_offset; - bool show_bars, show_motifs; - std::vector show_aligns; - - void resize(int new_x, int new_y, int new_w, int new_h); - void draw(); - void draw_motifs(double ch_width); - void draw_sequence(double ch_width); - void draw_match_lines(double ch_width); - void draw_indices(double ch_width); - int handle(int e); - void reporter(std::string id, int value); -}; -#endif diff --git a/gui/SeqView.hpp b/gui/SeqView.hpp new file mode 100644 index 0000000..40a43dd --- /dev/null +++ b/gui/SeqView.hpp @@ -0,0 +1,75 @@ +#ifndef _MUSSA_GUI_SEQ_VIEW_H_ +#define _MUSSA_GUI_SEQ_VIEW_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include +#include + +#include + +#include "gui/MotifWindow.hpp" +#include "gui/SetupWindow.hpp" + +class SeqView : public Fl_Box +{ + public: + SeqView(int x_top,int y_top,int x_bot,int y_bot) : + Fl_Box(x_top,y_top,x_bot,y_bot) + { + x_max = x_bot; + y_max = y_bot; + x_min = x_top; + y_min = y_top; + show_bars = true; + show_motifs = true; + } + + void setup(std::string name, int sq_num, std::vector *some_seqs, + std::list some_paths, + std::vector some_lens, std::vector *some_motifs); + void align_offsets(int align_num); + void toggle_align(int align_num); + void toggle_bars(); + void toggle_motifs(); + + private: + std::string analysis_name; + int seq_num; + int base_window_len; + + //this data is passed as pointers to the instantiated classes + std::vector *S; + //list of paths in selection box + std::list P; + std::vector seq_lens; + //pointer to passed motif data + std::vector *the_motifs; + + int x_max, y_max, x_min, y_min; + int y_seq_incre; + int index_pad; + std::vector seq_align_offsets; + std::vector raw_sequence; + bool dragging; + int drag_change, scroll_offset; + bool show_bars, show_motifs; + std::vector show_aligns; + + void resize(int new_x, int new_y, int new_w, int new_h); + void draw(); + void draw_motifs(double ch_width); + void draw_sequence(double ch_width); + void draw_match_lines(double ch_width); + void draw_indices(double ch_width); + int handle(int e); + void reporter(std::string id, int value); +}; +#endif diff --git a/gui/SeqWindow.cpp b/gui/SeqWindow.cpp new file mode 100644 index 0000000..0e011e2 --- /dev/null +++ b/gui/SeqWindow.cpp @@ -0,0 +1,206 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/SeqWindow.hpp" + +#include + +#include + +using namespace std; + +void +set_align_cb(Fl_Widget* widg, void* the_data) +{ + menu_align_data_bundle * blah = (menu_align_data_bundle *) the_data; + SeqWindow* T= blah->swm_ptr; + T->real_set_align_cb(blah->which_align); +} + + +void +SeqWindow::real_set_align_cb(int which_align) +{ + seq_box->align_offsets(which_align); + seq_box->redraw(); +} + + +void +show_align_cb(Fl_Widget* widg, void* the_data) +{ + menu_align_data_bundle * blah = (menu_align_data_bundle *) the_data; + SeqWindow* T= blah->swm_ptr; + T->real_show_align_cb(blah->which_align); +} + + +void +SeqWindow::real_show_align_cb(int which_align) +{ + vector a_path; + int window_length; + + + cout << "fumish\n"; + seq_box->toggle_align(which_align); + seq_box->redraw(); +} + + +void +toggle_bars_cb(Fl_Button* o, void* v) +{ + SeqWindow* T=(SeqWindow*)v; + T->real_toggle_bars_cb(); +} + + +void +SeqWindow::real_toggle_bars_cb() +{ + seq_box->toggle_bars(); +} + + +void +toggle_motifs_cb(Fl_Button* o, void* v) +{ + SeqWindow* T=(SeqWindow*)v; + T->real_toggle_motifs_cb(); +} + + +void +SeqWindow::real_toggle_motifs_cb() +{ + seq_box->toggle_motifs(); +} + + +// main code, window creation + +SeqWindow::SeqWindow(int w, int h, const char* title, int sq_num, + vector *some_seqs, + list some_paths, + vector some_lens, + vector *some_motifs): + Fl_Double_Window(w,h,title) +{ + menu_align_data_bundle * some_menu_data; + int window_length, align_number; + int i; + ostringstream align_id_ostr; + string align_id_string; + list::iterator align_iter; + + // most of this stuff is here just to pass to SeqView object + // some is needed to setup the window menus + seq_num = sq_num; + S = some_seqs; + P = some_paths; + seq_lens = some_lens; + the_motifs = some_motifs; + + + begin(); + color(FL_WHITE); + resizable(this); + + // make the menu that allows alignment selection + choose_align_menu = new Fl_Menu_Button(5, 2, 180, 30, "Choose Alignment"); + choose_align_menu->color(FL_WHITE,FL_BLUE); + choose_align_menu->box(FL_BORDER_BOX); + choose_align_menu->clear(); + + // make the menu that allows alignment selection + show_align_menu = new Fl_Menu_Button(190, 2, 180, 30, "Show Alignment"); + show_align_menu->color(FL_WHITE,FL_BLUE); + show_align_menu->box(FL_BORDER_BOX); + show_align_menu->clear(); + + + // adds menu items for each path + align_iter = P.begin(); + align_number = 0; + while(align_iter != P.end()) + { + some_menu_data = new menu_align_data_bundle; + some_menu_data->swm_ptr = this; + some_menu_data->which_align = align_number; + align_id_ostr << (*align_iter)[0] << ": "; + for(i = 1; i <= seq_num; i++) + align_id_ostr << (*align_iter)[i] << ", "; + align_id_string = align_id_ostr.str(); + choose_align_menu->add((const char*)align_id_string.c_str(), 0, + (Fl_Callback *) set_align_cb, + (void*) some_menu_data); + show_align_menu->add((const char*)align_id_string.c_str(), 0, + (Fl_Callback *) show_align_cb, + (void*) some_menu_data, FL_MENU_TOGGLE|FL_MENU_VALUE); + + align_id_ostr.str(""); + ++align_number; + ++align_iter; + } + + /* + show_align_menu->add("f&ee"); + show_align_menu->add("f&ie"); + show_align_menu->add("f&oe"); + show_align_menu->add("f&um"); + */ + + Fl_Button *test_but = new Fl_Button(375, 2, 150, 30, "Toggle Motifs"); + test_but->color(FL_WHITE,FL_BLUE); + test_but->box(FL_BORDER_BOX); + test_but->callback((Fl_Callback*) toggle_motifs_cb, this); + + toggle_bars = new Fl_Button(530, 2, 150, 30, "Toggle 10bp bars"); + toggle_bars->color(FL_WHITE,FL_BLUE); + toggle_bars->box(FL_BORDER_BOX); + toggle_bars->callback((Fl_Callback*) toggle_bars_cb, this); + + + // make the view of the sequence + seq_box = new SeqView(0, 34, w, h-34); + seq_box->setup(analysis_name, seq_num, S, P, seq_lens, the_motifs); + //real_set_align_cb(2); + + end(); + Fl::visual(FL_DOUBLE|FL_INDEX); + show(); +} + + + +/* + some_menu_data = new menu_align_data_bundle; + some_menu_data->swm_ptr = this; + some_menu_data->which_align = 2; + choose_align_menu->add("f&ie", FL_ALT+'i', (Fl_Callback *) set_align_cb, + (void*) some_menu_data); + + some_menu_data = new menu_align_data_bundle; + some_menu_data->swm_ptr = this; + some_menu_data->which_align = 3; + choose_align_menu->add("f&oe", FL_ALT+'o', (Fl_Callback *) set_align_cb, + (void*) some_menu_data); + + some_menu_data = new menu_align_data_bundle; + some_menu_data->swm_ptr = this; + some_menu_data->which_align = 4; + choose_align_menu->add("f&um", FL_ALT+'u', (Fl_Callback *) set_align_cb, + (void*) some_menu_data); +*/ + + + + diff --git a/gui/SeqWindow.cxx b/gui/SeqWindow.cxx deleted file mode 100644 index dc65148..0000000 --- a/gui/SeqWindow.cxx +++ /dev/null @@ -1,206 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "SeqWindow.hh" - -#include - -#include - -using namespace std; - -void -set_align_cb(Fl_Widget* widg, void* the_data) -{ - menu_align_data_bundle * blah = (menu_align_data_bundle *) the_data; - SeqWindow* T= blah->swm_ptr; - T->real_set_align_cb(blah->which_align); -} - - -void -SeqWindow::real_set_align_cb(int which_align) -{ - seq_box->align_offsets(which_align); - seq_box->redraw(); -} - - -void -show_align_cb(Fl_Widget* widg, void* the_data) -{ - menu_align_data_bundle * blah = (menu_align_data_bundle *) the_data; - SeqWindow* T= blah->swm_ptr; - T->real_show_align_cb(blah->which_align); -} - - -void -SeqWindow::real_show_align_cb(int which_align) -{ - vector a_path; - int window_length; - - - cout << "fumish\n"; - seq_box->toggle_align(which_align); - seq_box->redraw(); -} - - -void -toggle_bars_cb(Fl_Button* o, void* v) -{ - SeqWindow* T=(SeqWindow*)v; - T->real_toggle_bars_cb(); -} - - -void -SeqWindow::real_toggle_bars_cb() -{ - seq_box->toggle_bars(); -} - - -void -toggle_motifs_cb(Fl_Button* o, void* v) -{ - SeqWindow* T=(SeqWindow*)v; - T->real_toggle_motifs_cb(); -} - - -void -SeqWindow::real_toggle_motifs_cb() -{ - seq_box->toggle_motifs(); -} - - -// main code, window creation - -SeqWindow::SeqWindow(int w, int h, const char* title, int sq_num, - vector *some_seqs, - list some_paths, - vector some_lens, - vector *some_motifs): - Fl_Double_Window(w,h,title) -{ - menu_align_data_bundle * some_menu_data; - int window_length, align_number; - int i; - ostringstream align_id_ostr; - string align_id_string; - list::iterator align_iter; - - // most of this stuff is here just to pass to SeqView object - // some is needed to setup the window menus - seq_num = sq_num; - S = some_seqs; - P = some_paths; - seq_lens = some_lens; - the_motifs = some_motifs; - - - begin(); - color(FL_WHITE); - resizable(this); - - // make the menu that allows alignment selection - choose_align_menu = new Fl_Menu_Button(5, 2, 180, 30, "Choose Alignment"); - choose_align_menu->color(FL_WHITE,FL_BLUE); - choose_align_menu->box(FL_BORDER_BOX); - choose_align_menu->clear(); - - // make the menu that allows alignment selection - show_align_menu = new Fl_Menu_Button(190, 2, 180, 30, "Show Alignment"); - show_align_menu->color(FL_WHITE,FL_BLUE); - show_align_menu->box(FL_BORDER_BOX); - show_align_menu->clear(); - - - // adds menu items for each path - align_iter = P.begin(); - align_number = 0; - while(align_iter != P.end()) - { - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = align_number; - align_id_ostr << (*align_iter)[0] << ": "; - for(i = 1; i <= seq_num; i++) - align_id_ostr << (*align_iter)[i] << ", "; - align_id_string = align_id_ostr.str(); - choose_align_menu->add((const char*)align_id_string.c_str(), 0, - (Fl_Callback *) set_align_cb, - (void*) some_menu_data); - show_align_menu->add((const char*)align_id_string.c_str(), 0, - (Fl_Callback *) show_align_cb, - (void*) some_menu_data, FL_MENU_TOGGLE|FL_MENU_VALUE); - - align_id_ostr.str(""); - ++align_number; - ++align_iter; - } - - /* - show_align_menu->add("f&ee"); - show_align_menu->add("f&ie"); - show_align_menu->add("f&oe"); - show_align_menu->add("f&um"); - */ - - Fl_Button *test_but = new Fl_Button(375, 2, 150, 30, "Toggle Motifs"); - test_but->color(FL_WHITE,FL_BLUE); - test_but->box(FL_BORDER_BOX); - test_but->callback((Fl_Callback*) toggle_motifs_cb, this); - - toggle_bars = new Fl_Button(530, 2, 150, 30, "Toggle 10bp bars"); - toggle_bars->color(FL_WHITE,FL_BLUE); - toggle_bars->box(FL_BORDER_BOX); - toggle_bars->callback((Fl_Callback*) toggle_bars_cb, this); - - - // make the view of the sequence - seq_box = new SeqView(0, 34, w, h-34); - seq_box->setup(analysis_name, seq_num, S, P, seq_lens, the_motifs); - //real_set_align_cb(2); - - end(); - Fl::visual(FL_DOUBLE|FL_INDEX); - show(); -} - - - -/* - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 2; - choose_align_menu->add("f&ie", FL_ALT+'i', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); - - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 3; - choose_align_menu->add("f&oe", FL_ALT+'o', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); - - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 4; - choose_align_menu->add("f&um", FL_ALT+'u', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); -*/ - - - - diff --git a/gui/SeqWindow.hh b/gui/SeqWindow.hh deleted file mode 100644 index 71432e3..0000000 --- a/gui/SeqWindow.hh +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _MUSSA_GUI_SEQ_H_ -#define _MUSSA_GUI_SEQ_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include -#include -#include - -#include "SeqView.hh" - -#include -#include -#include -#include - -class SeqWindow : public Fl_Double_Window -{ - private: - std::string analysis_name; - int base_window_len; - - //this data is passed as pointers to the instantiated classes - std::vector *S; - // list of paths in selection box - std::list P; - std::vector seq_lens; - //pointer to passed motif data - std::vector *the_motifs; - - int x_max, y_max; - Fl_Menu_Button *choose_align_menu; - Fl_Menu_Button *show_align_menu; - Fl_Button *toggle_bars; - SeqView *seq_box; - - public: - int seq_num; - - SeqWindow(int w, int h, const char* title, int sq_num, - std::vector *some_seqs, - std::list some_paths, - std::vector some_lens, - std::vector *some_motifs); - virtual ~SeqWindow(){ std::cout << "dying\n"; } - - void make_choose_menu(); - void make_show_menu(); - void real_set_align_cb(int which_align); - void real_show_align_cb(int which_align); - void real_toggle_bars_cb(); - void real_toggle_motifs_cb(); -}; - - -struct menu_align_data_bundle -{ - SeqWindow * swm_ptr; - int which_align; -}; -#endif diff --git a/gui/SeqWindow.hpp b/gui/SeqWindow.hpp new file mode 100644 index 0000000..467445c --- /dev/null +++ b/gui/SeqWindow.hpp @@ -0,0 +1,68 @@ +#ifndef _MUSSA_GUI_SEQ_H_ +#define _MUSSA_GUI_SEQ_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include +#include +#include + +#include "gui/SeqView.hpp" + +#include +#include +#include +#include + +class SeqWindow : public Fl_Double_Window +{ + private: + std::string analysis_name; + int base_window_len; + + //this data is passed as pointers to the instantiated classes + std::vector *S; + // list of paths in selection box + std::list P; + std::vector seq_lens; + //pointer to passed motif data + std::vector *the_motifs; + + int x_max, y_max; + Fl_Menu_Button *choose_align_menu; + Fl_Menu_Button *show_align_menu; + Fl_Button *toggle_bars; + SeqView *seq_box; + + public: + int seq_num; + + SeqWindow(int w, int h, const char* title, int sq_num, + std::vector *some_seqs, + std::list some_paths, + std::vector some_lens, + std::vector *some_motifs); + virtual ~SeqWindow(){ std::cout << "dying\n"; } + + void make_choose_menu(); + void make_show_menu(); + void real_set_align_cb(int which_align); + void real_show_align_cb(int which_align); + void real_toggle_bars_cb(); + void real_toggle_motifs_cb(); +}; + + +struct menu_align_data_bundle +{ + SeqWindow * swm_ptr; + int which_align; +}; +#endif diff --git a/gui/SetupWindow.cpp b/gui/SetupWindow.cpp new file mode 100644 index 0000000..7b57abd --- /dev/null +++ b/gui/SetupWindow.cpp @@ -0,0 +1,421 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/SetupWindow.hpp" +#include "alg/mussa.hpp" +#include "mussa_exceptions.hpp" +#include +#include + +using namespace std; + +bool +SetupWindow::done() +{ + return all_done; +} + + +void +do_analysis_cb(Fl_Button* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->real_do_analysis(); +} + + +// passes the parameters to the mussa class object and orders it to run +void +SetupWindow::real_do_analysis() +{ + int i; + string err_msg; + + // <-- need a check here to make sure all vars have a valid value + + an_analysis->clear(); + an_analysis->set_name(analysis_name); + an_analysis->set_window(window); + an_analysis->set_threshold(threshold); + + for(i=0; i < seq_num; i++) + an_analysis->set_seq_info(seq_files[i], annot_files[i], fasta_indices[i], + sub_seq_starts[i], sub_seq_ends[i]); + + try { + an_analysis->analyze(); + } catch (mussa_analysis_error e) { + fl_alert(e.what()); + } + + all_done = true; + + hide(); +} + + +void +choose_seq_file_cb(Fl_Button* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_choose_seq_file_cb(blah->index); +} + + +void +SetupWindow::real_choose_seq_file_cb(int i) +{ + char *picked_file; + string a_file_path; + + picked_file = fl_file_chooser("Find an Analysis", "", "", 1); + a_file_path = picked_file; + seq_files[i] = a_file_path; + seq_inputs[i]->value((const char *)picked_file); +} + + +void +seq_file_in_cb(Fl_Input* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_seq_file_in_cb(o,blah->index); +} + + +void +SetupWindow::real_seq_file_in_cb(Fl_Input* o, int i) +{ + seq_files[i] = o->value(); + // leaving this as a reminder that bools will need to be set to determine + // if all needed fields have been filled with some value before an analysis + // is attempted + //(*the_motifs)[i].dirty = true; +} + +//char *picked_file; +//picked_file = fl_file_chooser("Find an Analysis", "", "", 1); + +// *** Annot file selection + +void +choose_annot_file_cb(Fl_Button* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_choose_annot_file_cb(blah->index); +} + + +void +SetupWindow::real_choose_annot_file_cb(int i) +{ + char *picked_file; + string a_file_path; + + picked_file = fl_file_chooser("Find an Analysis", "", "", 1); + a_file_path = picked_file; + annot_files[i] = a_file_path; + annot_inputs[i]->value((const char *)picked_file); +} + +void +annot_file_in_cb(Fl_Input* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_annot_file_in_cb(o,blah->index); +} + +void +SetupWindow::real_annot_file_in_cb(Fl_Input* o, int i) +{ + annot_files[i] = o->value(); +} + + +// *** fasta index selection + +void +fa_index_in_cb(Fl_Input* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_fa_index_in_cb(o,blah->index); +} + +void +SetupWindow::real_fa_index_in_cb(Fl_Input* o, int i) +{ + fasta_indices[i] = atoi(o->value()); +} + +// *** subsequence start select + +void +sub_start_in_cb(Fl_Input* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_sub_start_in_cb(o,blah->index); +} + +void +SetupWindow::real_sub_start_in_cb(Fl_Input* o, int i) +{ + sub_seq_starts[i] = atoi(o->value()); +} + +// *** subsequence end select + +void +sub_end_in_cb(Fl_Input* o, void* v) +{ + seq_data_instance * blah = (seq_data_instance *) v; + SetupWindow* T= blah->sw_ptr; + T->real_sub_end_in_cb(o,blah->index); +} + +void +SetupWindow::real_sub_end_in_cb(Fl_Input* o, int i) +{ + sub_seq_ends[i] = atoi(o->value()); + +} + +// *** input analysis name + +void +set_ana_name_cb(Fl_Input* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->real_set_ana_name_cb(o); +} + +void +SetupWindow::real_set_ana_name_cb(Fl_Input* o) +{ + analysis_name = o->value(); +} + +// *** input window size + +void +set_win_size_cb(Fl_Input* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->real_set_win_size_cb(o); +} + +void +SetupWindow::real_set_win_size_cb(Fl_Input* o) +{ + window = atoi(o->value()); +} + +// *** input threshold + +void +set_threshold_cb(Fl_Input* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->real_set_threshold_cb(o); +} + +void +SetupWindow::real_set_threshold_cb(Fl_Input* o) +{ + threshold = atoi(o->value()); +} + +void +set_seq_num_cb(Fl_Input* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->real_set_seq_num_cb(o); +} + +// *** input number of sequences, add appropriate inputs for each sequence + +void +SetupWindow::real_set_seq_num_cb(Fl_Input* o) +{ + int i; + + seq_num = atoi(o->value()); + seq_inputs.clear(); + annot_inputs.clear(); + + seq_scroll = new Fl_Scroll(5,80,w()-10,h()-115); + seq_scroll->color(FL_WHITE); + + for (i = 0; i < seq_num; i++) + { + seq_files.push_back(""); + annot_files.push_back(""); + fasta_indices.push_back(1); + sub_seq_starts.push_back(0); + sub_seq_ends.push_back(0); + add_seq_input(i); + } + seq_scroll->box(FL_DOWN_FRAME); + add(seq_scroll); + redraw(); +} + + +SetupWindow::SetupWindow(int w, int h, const char* title, Mussa *the_analysis):Fl_Window(w,h,title) +{ + color(FL_WHITE); + + an_analysis = the_analysis; + all_done = false; + + begin(); + + name_input = new Fl_Input(110, 10, w-120, 30, "Analysis Name "); + name_input->value(""); + //name_input->when(FL_WHEN_ENTER_KEY); + name_input->box(FL_BORDER_BOX); + name_input->callback((Fl_Callback*)set_ana_name_cb, this); + + // add in radio buttons for win_append and thres_append eventually + win_append = true; + thres_append = true; + + win_input = new Fl_Input(65,45,100,30, "Window "); + win_input->value(""); + win_input->callback((Fl_Callback*)set_win_size_cb, this); + + thres_input = new Fl_Input(250,45,100,30, "Threshold "); + thres_input->value(""); + thres_input->callback((Fl_Callback*)set_threshold_cb, this); + + seq_num_input = new Fl_Input(480,45,100, 30, "Number of Seqs"); + seq_num_input->value(""); + seq_num_input->callback((Fl_Callback*)set_seq_num_cb, this); + + // button to launch the analysis + test = new Fl_Button(w-100,h-30,100,30,"Do Analysis"); + test->callback((Fl_Callback*)do_analysis_cb, this); + + // test button to make sure setup data is being stored + test = new Fl_Button(w-200,h-30,100,30,"show setup"); + test->callback((Fl_Callback*)print_cb, this); + + // generic input, keeping around as template for future additions + //_input = new Fl_Input(0, , 30, ""); + //_input->value(""); + //_input->when(FL_WHEN_ENTER_KEY); + //_input->callback((Fl_Callback*)set__cb, this); + + end(); + //resizable(this); + show(); +} + + +SetupWindow::~SetupWindow(){} + + +void +SetupWindow::add_seq_input(int i) +{ + Fl_Input *fasta_input, *start_input, *end_input; + Fl_Button *seq_browse, *annot_browse; + + + // this remembers what seq index each input is associated with + seq_data_instance * something; + something = new seq_data_instance; + something->sw_ptr = this; + something->index = i; + + + // setup sequence file input for text input or file browsing + seq_inputs.push_back(new Fl_Input(55, 85+(i*105), w()-165, 30, "seq ")); + seq_inputs[i]->value(""); + seq_inputs[i]->callback((Fl_Callback*)seq_file_in_cb, (void*) something); + + seq_browse = new Fl_Button(w()-105, 85+(i*105), 80, 30, "Browse"); + seq_browse->callback((Fl_Callback*)choose_seq_file_cb, (void*) something); + + // setup annotation file input for text input or file browsing + annot_inputs.push_back(new Fl_Input(55, 120+(i*105), w()-165, 30, "annot ")); + annot_inputs[i]->value(""); + annot_inputs[i]->callback((Fl_Callback*)annot_file_in_cb,(void*)something); + + annot_browse = new Fl_Button(w()-105, 120+(i*105), 80, 30, "Browse"); + annot_browse->callback((Fl_Callback*)choose_annot_file_cb, (void*)something); + + // index of fasta seq wanted if more than 1 seq in file + fasta_input = new Fl_Input(90, 155+(i*105), 50, 30, "fasta index"); + fasta_input->value(""); + fasta_input->callback((Fl_Callback*)fa_index_in_cb, (void*) something); + + // subsequence select, index of first bp wanted + start_input = new Fl_Input(225, 155+(i*105), 50, 30, "start index"); + start_input->value(""); + start_input->callback((Fl_Callback*)sub_start_in_cb, (void*) something); + + // subsequence select, index of last bp wanted + end_input = new Fl_Input(355, 155+(i*105), 50, 30, "end index"); + end_input->value(""); + end_input->callback((Fl_Callback*)sub_end_in_cb, (void*) something); + + seq_scroll->add(seq_inputs[i]); + seq_scroll->add(seq_browse); + seq_scroll->add(annot_inputs[i]); + seq_scroll->add(annot_browse); + seq_scroll->add(fasta_input); + seq_scroll->add(start_input); + seq_scroll->add(end_input); +} + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ + +void SetupWindow::print_cb(Fl_Button* o, void* v) +{ + SetupWindow* T=(SetupWindow*)v; + T->print_cb_real(o,v); +} + + +void SetupWindow::print_cb_real(Fl_Button* , void*) +{ + cout << "analysis_name: " << analysis_name << endl; + cout << "win: " << window << endl; + cout << "thres: " << threshold << endl; + cout << "seq_num: " << seq_num << endl; + //cout << "win_add: " << win_append << end; + //cout << "thres_add: " << thres_append << endl; + + int i; + + + + for (i = 0; i < seq_num; i++) + { + cout << seq_files[i] << endl; + cout << annot_files[i] << endl; + cout << "fasta: " << fasta_indices[i]; + cout << " start: " << sub_seq_starts[i]; + cout << " end: " << sub_seq_ends[i] << endl; + cout << "blargle!\n"; + } + cout << "end of inputs\n" << endl; +} diff --git a/gui/SetupWindow.cxx b/gui/SetupWindow.cxx deleted file mode 100644 index 4115218..0000000 --- a/gui/SetupWindow.cxx +++ /dev/null @@ -1,421 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "SetupWindow.hh" -#include "alg/mussa_class.hh" -#include "mussa_exceptions.hh" -#include -#include - -using namespace std; - -bool -SetupWindow::done() -{ - return all_done; -} - - -void -do_analysis_cb(Fl_Button* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->real_do_analysis(); -} - - -// passes the parameters to the mussa class object and orders it to run -void -SetupWindow::real_do_analysis() -{ - int i; - string err_msg; - - // <-- need a check here to make sure all vars have a valid value - - an_analysis->clear(); - an_analysis->set_name(analysis_name); - an_analysis->set_window(window); - an_analysis->set_threshold(threshold); - - for(i=0; i < seq_num; i++) - an_analysis->set_seq_info(seq_files[i], annot_files[i], fasta_indices[i], - sub_seq_starts[i], sub_seq_ends[i]); - - try { - an_analysis->analyze(); - } catch (mussa_analysis_error e) { - fl_alert(e.what()); - } - - all_done = true; - - hide(); -} - - -void -choose_seq_file_cb(Fl_Button* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_choose_seq_file_cb(blah->index); -} - - -void -SetupWindow::real_choose_seq_file_cb(int i) -{ - char *picked_file; - string a_file_path; - - picked_file = fl_file_chooser("Find an Analysis", "", "", 1); - a_file_path = picked_file; - seq_files[i] = a_file_path; - seq_inputs[i]->value((const char *)picked_file); -} - - -void -seq_file_in_cb(Fl_Input* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_seq_file_in_cb(o,blah->index); -} - - -void -SetupWindow::real_seq_file_in_cb(Fl_Input* o, int i) -{ - seq_files[i] = o->value(); - // leaving this as a reminder that bools will need to be set to determine - // if all needed fields have been filled with some value before an analysis - // is attempted - //(*the_motifs)[i].dirty = true; -} - -//char *picked_file; -//picked_file = fl_file_chooser("Find an Analysis", "", "", 1); - -// *** Annot file selection - -void -choose_annot_file_cb(Fl_Button* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_choose_annot_file_cb(blah->index); -} - - -void -SetupWindow::real_choose_annot_file_cb(int i) -{ - char *picked_file; - string a_file_path; - - picked_file = fl_file_chooser("Find an Analysis", "", "", 1); - a_file_path = picked_file; - annot_files[i] = a_file_path; - annot_inputs[i]->value((const char *)picked_file); -} - -void -annot_file_in_cb(Fl_Input* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_annot_file_in_cb(o,blah->index); -} - -void -SetupWindow::real_annot_file_in_cb(Fl_Input* o, int i) -{ - annot_files[i] = o->value(); -} - - -// *** fasta index selection - -void -fa_index_in_cb(Fl_Input* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_fa_index_in_cb(o,blah->index); -} - -void -SetupWindow::real_fa_index_in_cb(Fl_Input* o, int i) -{ - fasta_indices[i] = atoi(o->value()); -} - -// *** subsequence start select - -void -sub_start_in_cb(Fl_Input* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_sub_start_in_cb(o,blah->index); -} - -void -SetupWindow::real_sub_start_in_cb(Fl_Input* o, int i) -{ - sub_seq_starts[i] = atoi(o->value()); -} - -// *** subsequence end select - -void -sub_end_in_cb(Fl_Input* o, void* v) -{ - seq_data_instance * blah = (seq_data_instance *) v; - SetupWindow* T= blah->sw_ptr; - T->real_sub_end_in_cb(o,blah->index); -} - -void -SetupWindow::real_sub_end_in_cb(Fl_Input* o, int i) -{ - sub_seq_ends[i] = atoi(o->value()); - -} - -// *** input analysis name - -void -set_ana_name_cb(Fl_Input* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->real_set_ana_name_cb(o); -} - -void -SetupWindow::real_set_ana_name_cb(Fl_Input* o) -{ - analysis_name = o->value(); -} - -// *** input window size - -void -set_win_size_cb(Fl_Input* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->real_set_win_size_cb(o); -} - -void -SetupWindow::real_set_win_size_cb(Fl_Input* o) -{ - window = atoi(o->value()); -} - -// *** input threshold - -void -set_threshold_cb(Fl_Input* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->real_set_threshold_cb(o); -} - -void -SetupWindow::real_set_threshold_cb(Fl_Input* o) -{ - threshold = atoi(o->value()); -} - -void -set_seq_num_cb(Fl_Input* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->real_set_seq_num_cb(o); -} - -// *** input number of sequences, add appropriate inputs for each sequence - -void -SetupWindow::real_set_seq_num_cb(Fl_Input* o) -{ - int i; - - seq_num = atoi(o->value()); - seq_inputs.clear(); - annot_inputs.clear(); - - seq_scroll = new Fl_Scroll(5,80,w()-10,h()-115); - seq_scroll->color(FL_WHITE); - - for (i = 0; i < seq_num; i++) - { - seq_files.push_back(""); - annot_files.push_back(""); - fasta_indices.push_back(1); - sub_seq_starts.push_back(0); - sub_seq_ends.push_back(0); - add_seq_input(i); - } - seq_scroll->box(FL_DOWN_FRAME); - add(seq_scroll); - redraw(); -} - - -SetupWindow::SetupWindow(int w, int h, const char* title, Mussa *the_analysis):Fl_Window(w,h,title) -{ - color(FL_WHITE); - - an_analysis = the_analysis; - all_done = false; - - begin(); - - name_input = new Fl_Input(110, 10, w-120, 30, "Analysis Name "); - name_input->value(""); - //name_input->when(FL_WHEN_ENTER_KEY); - name_input->box(FL_BORDER_BOX); - name_input->callback((Fl_Callback*)set_ana_name_cb, this); - - // add in radio buttons for win_append and thres_append eventually - win_append = true; - thres_append = true; - - win_input = new Fl_Input(65,45,100,30, "Window "); - win_input->value(""); - win_input->callback((Fl_Callback*)set_win_size_cb, this); - - thres_input = new Fl_Input(250,45,100,30, "Threshold "); - thres_input->value(""); - thres_input->callback((Fl_Callback*)set_threshold_cb, this); - - seq_num_input = new Fl_Input(480,45,100, 30, "Number of Seqs"); - seq_num_input->value(""); - seq_num_input->callback((Fl_Callback*)set_seq_num_cb, this); - - // button to launch the analysis - test = new Fl_Button(w-100,h-30,100,30,"Do Analysis"); - test->callback((Fl_Callback*)do_analysis_cb, this); - - // test button to make sure setup data is being stored - test = new Fl_Button(w-200,h-30,100,30,"show setup"); - test->callback((Fl_Callback*)print_cb, this); - - // generic input, keeping around as template for future additions - //_input = new Fl_Input(0, , 30, ""); - //_input->value(""); - //_input->when(FL_WHEN_ENTER_KEY); - //_input->callback((Fl_Callback*)set__cb, this); - - end(); - //resizable(this); - show(); -} - - -SetupWindow::~SetupWindow(){} - - -void -SetupWindow::add_seq_input(int i) -{ - Fl_Input *fasta_input, *start_input, *end_input; - Fl_Button *seq_browse, *annot_browse; - - - // this remembers what seq index each input is associated with - seq_data_instance * something; - something = new seq_data_instance; - something->sw_ptr = this; - something->index = i; - - - // setup sequence file input for text input or file browsing - seq_inputs.push_back(new Fl_Input(55, 85+(i*105), w()-165, 30, "seq ")); - seq_inputs[i]->value(""); - seq_inputs[i]->callback((Fl_Callback*)seq_file_in_cb, (void*) something); - - seq_browse = new Fl_Button(w()-105, 85+(i*105), 80, 30, "Browse"); - seq_browse->callback((Fl_Callback*)choose_seq_file_cb, (void*) something); - - // setup annotation file input for text input or file browsing - annot_inputs.push_back(new Fl_Input(55, 120+(i*105), w()-165, 30, "annot ")); - annot_inputs[i]->value(""); - annot_inputs[i]->callback((Fl_Callback*)annot_file_in_cb,(void*)something); - - annot_browse = new Fl_Button(w()-105, 120+(i*105), 80, 30, "Browse"); - annot_browse->callback((Fl_Callback*)choose_annot_file_cb, (void*)something); - - // index of fasta seq wanted if more than 1 seq in file - fasta_input = new Fl_Input(90, 155+(i*105), 50, 30, "fasta index"); - fasta_input->value(""); - fasta_input->callback((Fl_Callback*)fa_index_in_cb, (void*) something); - - // subsequence select, index of first bp wanted - start_input = new Fl_Input(225, 155+(i*105), 50, 30, "start index"); - start_input->value(""); - start_input->callback((Fl_Callback*)sub_start_in_cb, (void*) something); - - // subsequence select, index of last bp wanted - end_input = new Fl_Input(355, 155+(i*105), 50, 30, "end index"); - end_input->value(""); - end_input->callback((Fl_Callback*)sub_end_in_cb, (void*) something); - - seq_scroll->add(seq_inputs[i]); - seq_scroll->add(seq_browse); - seq_scroll->add(annot_inputs[i]); - seq_scroll->add(annot_browse); - seq_scroll->add(fasta_input); - seq_scroll->add(start_input); - seq_scroll->add(end_input); -} - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ - -void SetupWindow::print_cb(Fl_Button* o, void* v) -{ - SetupWindow* T=(SetupWindow*)v; - T->print_cb_real(o,v); -} - - -void SetupWindow::print_cb_real(Fl_Button* , void*) -{ - cout << "analysis_name: " << analysis_name << endl; - cout << "win: " << window << endl; - cout << "thres: " << threshold << endl; - cout << "seq_num: " << seq_num << endl; - //cout << "win_add: " << win_append << end; - //cout << "thres_add: " << thres_append << endl; - - int i; - - - - for (i = 0; i < seq_num; i++) - { - cout << seq_files[i] << endl; - cout << annot_files[i] << endl; - cout << "fasta: " << fasta_indices[i]; - cout << " start: " << sub_seq_starts[i]; - cout << " end: " << sub_seq_ends[i] << endl; - cout << "blargle!\n"; - } - cout << "end of inputs\n" << endl; -} diff --git a/gui/SetupWindow.hh b/gui/SetupWindow.hh deleted file mode 100644 index c776449..0000000 --- a/gui/SetupWindow.hh +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _MUSSA_GUI_LOAD_WINDOW_H_ -#define _MUSSA_GUI_LOAD_WINDOW_H_ - -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include - -#include -#include -#include -#include - -class Mussa; -#include "SetupWindow.hh" - -class SetupWindow : public Fl_Window -{ - public: - SetupWindow(int w, int h, const char* title, Mussa *an_analysis); - ~SetupWindow(); - - bool done(); - - //did I put these in public for a reason? - Fl_Button* test; - Fl_Input *name_input; - Fl_Input *win_input; - Fl_Input *thres_input; - Fl_Input *seq_num_input; - Fl_Scroll *seq_scroll; - // need to keep track of these so a browsed file search can set the input - // fields to teh selected file - std::vector seq_inputs, annot_inputs; - - - // callback receiver functions - - void real_do_analysis(); - - void real_set_ana_name_cb(Fl_Input* o); - void real_set_win_size_cb(Fl_Input* o); - void real_set_threshold_cb(Fl_Input* o); - void real_set_seq_num_cb(Fl_Input* o); - - void real_seq_file_in_cb(Fl_Input* o, int i); - void real_choose_seq_file_cb(int i); - void real_annot_file_in_cb(Fl_Input* o, int i); - void real_choose_annot_file_cb(int i); - - void real_fa_index_in_cb(Fl_Input* o, int i); - void real_sub_start_in_cb(Fl_Input* o, int i); - void real_sub_end_in_cb(Fl_Input* o, int i); - - private: - Mussa *an_analysis; - std::string analysis_name; - int window, threshold, seq_num; - std::vector seq_files, annot_files; - std::vector fasta_indices, sub_seq_starts, sub_seq_ends; - bool win_append, thres_append; - - bool all_done; - static void print_cb(Fl_Button*, void*); - inline void print_cb_real(Fl_Button*, void*); - - void add_seq_input(int index); -}; - -// crazy whacked shite Titus taught me to do to get an index value associated -// with each instance of an input associated with the callback... - -struct seq_data_instance -{ - SetupWindow * sw_ptr; - int index; -}; - -#endif diff --git a/gui/SetupWindow.hpp b/gui/SetupWindow.hpp new file mode 100644 index 0000000..532a62e --- /dev/null +++ b/gui/SetupWindow.hpp @@ -0,0 +1,86 @@ +#ifndef _MUSSA_GUI_LOAD_WINDOW_H_ +#define _MUSSA_GUI_LOAD_WINDOW_H_ + +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include + +#include +#include +#include +#include + +class Mussa; +#include "gui/SetupWindow.hpp" + +class SetupWindow : public Fl_Window +{ + public: + SetupWindow(int w, int h, const char* title, Mussa *an_analysis); + ~SetupWindow(); + + bool done(); + + //did I put these in public for a reason? + Fl_Button* test; + Fl_Input *name_input; + Fl_Input *win_input; + Fl_Input *thres_input; + Fl_Input *seq_num_input; + Fl_Scroll *seq_scroll; + // need to keep track of these so a browsed file search can set the input + // fields to teh selected file + std::vector seq_inputs, annot_inputs; + + + // callback receiver functions + + void real_do_analysis(); + + void real_set_ana_name_cb(Fl_Input* o); + void real_set_win_size_cb(Fl_Input* o); + void real_set_threshold_cb(Fl_Input* o); + void real_set_seq_num_cb(Fl_Input* o); + + void real_seq_file_in_cb(Fl_Input* o, int i); + void real_choose_seq_file_cb(int i); + void real_annot_file_in_cb(Fl_Input* o, int i); + void real_choose_annot_file_cb(int i); + + void real_fa_index_in_cb(Fl_Input* o, int i); + void real_sub_start_in_cb(Fl_Input* o, int i); + void real_sub_end_in_cb(Fl_Input* o, int i); + + private: + Mussa *an_analysis; + std::string analysis_name; + int window, threshold, seq_num; + std::vector seq_files, annot_files; + std::vector fasta_indices, sub_seq_starts, sub_seq_ends; + bool win_append, thres_append; + + bool all_done; + static void print_cb(Fl_Button*, void*); + inline void print_cb_real(Fl_Button*, void*); + + void add_seq_input(int index); +}; + +// crazy whacked shite Titus taught me to do to get an index value associated +// with each instance of an input associated with the callback... + +struct seq_data_instance +{ + SetupWindow * sw_ptr; + int index; +}; + +#endif diff --git a/gui/SubAnalysisWindow.cpp b/gui/SubAnalysisWindow.cpp new file mode 100644 index 0000000..4ec72d9 --- /dev/null +++ b/gui/SubAnalysisWindow.cpp @@ -0,0 +1,283 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/SubAnalysisWindow.hpp" +#include "alg/mussa.hpp" +#include "mussa_exceptions.hpp" + +#include +using namespace std; + +void +do_subana_cb(Fl_Button* o, void* v) +{ + SubAnalysisWindow* T=(SubAnalysisWindow*)v; + T->real_do_subana(); +} + + +// passes the parameters to the mussa class object and orders it to run +void +SubAnalysisWindow::real_do_subana() +{ + int i; + string a_sequence, err_msg; + + // <-- need a check here to make sure all vars have a valid value + + an_analysis->clear(); + an_analysis->set_name(analysis_name); + an_analysis->set_window(window); + an_analysis->set_threshold(threshold); + + for(i=0; i < seq_num; i++) + { + a_sequence = the_seqs[i].get_seq(); + cout << a_sequence.length() << endl; + a_sequence = a_sequence.substr(sub_seq_starts[i], + sub_seq_ends[i] - sub_seq_starts[i] ); + cout << a_sequence.length() << endl; + an_analysis->add_a_seq(a_sequence); + } + + try { + an_analysis->analyze(); + } catch( mussa_analysis_error e) { + fl_alert( e.what() ); + } + + all_done = true; + + hide(); +} + + + +// *** subsequence start select + +void +sub_start_in_cb1(Fl_Input* o, void* v) +{ + sub_seq_data_instance * blah = (sub_seq_data_instance *) v; + SubAnalysisWindow* T= blah->sw_ptr; + T->real_sub_start_in_cb(o,blah->index); +} + +void +SubAnalysisWindow::real_sub_start_in_cb(Fl_Input* o, int i) +{ + sub_seq_starts[i] = atoi(o->value()); +} + +// *** subsequence end select + +void +sub_end_in_cb1(Fl_Input* o, void* v) +{ + sub_seq_data_instance * blah = (sub_seq_data_instance *) v; + SubAnalysisWindow* T= blah->sw_ptr; + T->real_sub_end_in_cb(o,blah->index); +} + +void +SubAnalysisWindow::real_sub_end_in_cb(Fl_Input* o, int i) +{ + sub_seq_ends[i] = atoi(o->value()); + +} + +// *** input analysis name + +void +set_ana_name_cb1(Fl_Input* o, void* v) +{ + SubAnalysisWindow* T=(SubAnalysisWindow*)v; + T->real_set_ana_name_cb(o); +} + +void +SubAnalysisWindow::real_set_ana_name_cb(Fl_Input* o) +{ + analysis_name = o->value(); +} + +// *** input window size + +void +set_win_size_cb1(Fl_Input* o, void* v) +{ + SubAnalysisWindow* T=(SubAnalysisWindow*)v; + T->real_set_win_size_cb(o); +} + +void +SubAnalysisWindow::real_set_win_size_cb(Fl_Input* o) +{ + window = atoi(o->value()); +} + +// *** input threshold + +void +set_threshold_cb1(Fl_Input* o, void* v) +{ + SubAnalysisWindow* T=(SubAnalysisWindow*)v; + T->real_set_threshold_cb(o); +} + +void +SubAnalysisWindow::real_set_threshold_cb(Fl_Input* o) +{ + threshold = atoi(o->value()); +} + + +bool +SubAnalysisWindow::done() +{ + return all_done; +} + + +SubAnalysisWindow::SubAnalysisWindow(int w, int h, const char* title,Mussa *the_analysis, + vector some_Seqs):Fl_Window(w,h,title) +{ + string a_name; + + color(FL_WHITE); + + an_analysis = the_analysis; + the_seqs = some_Seqs; + all_done = false; + + // initialize parameters + analysis_name = ""; + window = -1; + threshold = -1; + + begin(); + + name_input = new Fl_Input(135, 10, w-140, 30, "SubAnalysis Name "); + name_input->value(""); + //name_input->when(FL_WHEN_ENTER_KEY); + name_input->box(FL_BORDER_BOX); + name_input->callback((Fl_Callback*)set_ana_name_cb1, this); + + // add in radio buttons for win_append and thres_append eventually + win_append = true; + thres_append = true; + + win_input = new Fl_Input(135,45,100,30, "Window: "); + win_input->value(""); + win_input->callback((Fl_Callback*)set_win_size_cb1, this); + + thres_input = new Fl_Input(320,45,100,30, "Threshold: "); + thres_input->value(""); + thres_input->callback((Fl_Callback*)set_threshold_cb1, this); + + // button to launch the analysis + test = new Fl_Button(w-100,h-30,100,30,"Do Analysis"); + test->callback((Fl_Callback*)do_subana_cb, this); + + // test button to make sure setup data is being stored + test = new Fl_Button(w-200,h-30,100,30,"show setup"); + test->callback((Fl_Callback*)print_cb, this); + + // add all the inputs for the sub sequence starts & ends + int i; + + seq_num = the_seqs.size(); + + seq_scroll = new Fl_Scroll(5,80,w-10,h-115); + seq_scroll->color(FL_WHITE); + + for (i = 0; i < seq_num; i++) + { + sub_seq_starts.push_back(0); + sub_seq_ends.push_back(0); + //a_name = the_seqs[i].sp_name(); + //cout << a_name << endl; + add_seq_input(i, a_name); + } + seq_scroll->box(FL_DOWN_FRAME); + //add(seq_scroll); + //redraw(); + + end(); + //resizable(this); + show(); +} + + +SubAnalysisWindow::~SubAnalysisWindow(){} + + +void +SubAnalysisWindow::add_seq_input(int i, string a_name) +{ + Fl_Input *start_input, *end_input; + + + // this remembers what seq index each input is associated with + sub_seq_data_instance * something; + something = new sub_seq_data_instance; + something->sw_ptr = this; + something->index = i; + + + // subsequence select, index of first bp wanted + start_input = new Fl_Input(150, 85+(i*35), 70, 30, "start index: "); + start_input->value(""); + start_input->callback((Fl_Callback*)sub_start_in_cb1, (void*) something); + + // subsequence select, index of last bp wanted + end_input = new Fl_Input(300, 85+(i*35), 70, 30, "end index: "); + end_input->value(""); + end_input->callback((Fl_Callback*)sub_end_in_cb1, (void*) something); + + seq_scroll->add(start_input); + seq_scroll->add(end_input); +} + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ + +void SubAnalysisWindow::print_cb(Fl_Button* o, void* v) +{ + SubAnalysisWindow* T=(SubAnalysisWindow*)v; + T->print_cb_real(o,v); +} + + +void SubAnalysisWindow::print_cb_real(Fl_Button* , void*) +{ + cout << "analysis_name: " << analysis_name << endl; + cout << "win: " << window << endl; + cout << "thres: " << threshold << endl; + cout << "seq_num: " << seq_num << endl; + //cout << "win_add: " << win_append << end; + //cout << "thres_add: " << thres_append << endl; + + int i; + + + + for (i = 0; i < seq_num; i++) + { + cout << " start: " << sub_seq_starts[i]; + cout << " end: " << sub_seq_ends[i] << endl; + cout << "blargle!\n"; + } + cout << "end of inputs\n" << endl; +} diff --git a/gui/SubAnalysisWindow.cxx b/gui/SubAnalysisWindow.cxx deleted file mode 100644 index b808f4a..0000000 --- a/gui/SubAnalysisWindow.cxx +++ /dev/null @@ -1,283 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "SubAnalysisWindow.hh" -#include "alg/mussa_class.hh" -#include "mussa_exceptions.hh" - -#include -using namespace std; - -void -do_subana_cb(Fl_Button* o, void* v) -{ - SubAnalysisWindow* T=(SubAnalysisWindow*)v; - T->real_do_subana(); -} - - -// passes the parameters to the mussa class object and orders it to run -void -SubAnalysisWindow::real_do_subana() -{ - int i; - string a_sequence, err_msg; - - // <-- need a check here to make sure all vars have a valid value - - an_analysis->clear(); - an_analysis->set_name(analysis_name); - an_analysis->set_window(window); - an_analysis->set_threshold(threshold); - - for(i=0; i < seq_num; i++) - { - a_sequence = the_seqs[i].get_seq(); - cout << a_sequence.length() << endl; - a_sequence = a_sequence.substr(sub_seq_starts[i], - sub_seq_ends[i] - sub_seq_starts[i] ); - cout << a_sequence.length() << endl; - an_analysis->add_a_seq(a_sequence); - } - - try { - an_analysis->analyze(); - } catch( mussa_analysis_error e) { - fl_alert( e.what() ); - } - - all_done = true; - - hide(); -} - - - -// *** subsequence start select - -void -sub_start_in_cb1(Fl_Input* o, void* v) -{ - sub_seq_data_instance * blah = (sub_seq_data_instance *) v; - SubAnalysisWindow* T= blah->sw_ptr; - T->real_sub_start_in_cb(o,blah->index); -} - -void -SubAnalysisWindow::real_sub_start_in_cb(Fl_Input* o, int i) -{ - sub_seq_starts[i] = atoi(o->value()); -} - -// *** subsequence end select - -void -sub_end_in_cb1(Fl_Input* o, void* v) -{ - sub_seq_data_instance * blah = (sub_seq_data_instance *) v; - SubAnalysisWindow* T= blah->sw_ptr; - T->real_sub_end_in_cb(o,blah->index); -} - -void -SubAnalysisWindow::real_sub_end_in_cb(Fl_Input* o, int i) -{ - sub_seq_ends[i] = atoi(o->value()); - -} - -// *** input analysis name - -void -set_ana_name_cb1(Fl_Input* o, void* v) -{ - SubAnalysisWindow* T=(SubAnalysisWindow*)v; - T->real_set_ana_name_cb(o); -} - -void -SubAnalysisWindow::real_set_ana_name_cb(Fl_Input* o) -{ - analysis_name = o->value(); -} - -// *** input window size - -void -set_win_size_cb1(Fl_Input* o, void* v) -{ - SubAnalysisWindow* T=(SubAnalysisWindow*)v; - T->real_set_win_size_cb(o); -} - -void -SubAnalysisWindow::real_set_win_size_cb(Fl_Input* o) -{ - window = atoi(o->value()); -} - -// *** input threshold - -void -set_threshold_cb1(Fl_Input* o, void* v) -{ - SubAnalysisWindow* T=(SubAnalysisWindow*)v; - T->real_set_threshold_cb(o); -} - -void -SubAnalysisWindow::real_set_threshold_cb(Fl_Input* o) -{ - threshold = atoi(o->value()); -} - - -bool -SubAnalysisWindow::done() -{ - return all_done; -} - - -SubAnalysisWindow::SubAnalysisWindow(int w, int h, const char* title,Mussa *the_analysis, - vector some_Seqs):Fl_Window(w,h,title) -{ - string a_name; - - color(FL_WHITE); - - an_analysis = the_analysis; - the_seqs = some_Seqs; - all_done = false; - - // initialize parameters - analysis_name = ""; - window = -1; - threshold = -1; - - begin(); - - name_input = new Fl_Input(135, 10, w-140, 30, "SubAnalysis Name "); - name_input->value(""); - //name_input->when(FL_WHEN_ENTER_KEY); - name_input->box(FL_BORDER_BOX); - name_input->callback((Fl_Callback*)set_ana_name_cb1, this); - - // add in radio buttons for win_append and thres_append eventually - win_append = true; - thres_append = true; - - win_input = new Fl_Input(135,45,100,30, "Window: "); - win_input->value(""); - win_input->callback((Fl_Callback*)set_win_size_cb1, this); - - thres_input = new Fl_Input(320,45,100,30, "Threshold: "); - thres_input->value(""); - thres_input->callback((Fl_Callback*)set_threshold_cb1, this); - - // button to launch the analysis - test = new Fl_Button(w-100,h-30,100,30,"Do Analysis"); - test->callback((Fl_Callback*)do_subana_cb, this); - - // test button to make sure setup data is being stored - test = new Fl_Button(w-200,h-30,100,30,"show setup"); - test->callback((Fl_Callback*)print_cb, this); - - // add all the inputs for the sub sequence starts & ends - int i; - - seq_num = the_seqs.size(); - - seq_scroll = new Fl_Scroll(5,80,w-10,h-115); - seq_scroll->color(FL_WHITE); - - for (i = 0; i < seq_num; i++) - { - sub_seq_starts.push_back(0); - sub_seq_ends.push_back(0); - //a_name = the_seqs[i].sp_name(); - //cout << a_name << endl; - add_seq_input(i, a_name); - } - seq_scroll->box(FL_DOWN_FRAME); - //add(seq_scroll); - //redraw(); - - end(); - //resizable(this); - show(); -} - - -SubAnalysisWindow::~SubAnalysisWindow(){} - - -void -SubAnalysisWindow::add_seq_input(int i, string a_name) -{ - Fl_Input *start_input, *end_input; - - - // this remembers what seq index each input is associated with - sub_seq_data_instance * something; - something = new sub_seq_data_instance; - something->sw_ptr = this; - something->index = i; - - - // subsequence select, index of first bp wanted - start_input = new Fl_Input(150, 85+(i*35), 70, 30, "start index: "); - start_input->value(""); - start_input->callback((Fl_Callback*)sub_start_in_cb1, (void*) something); - - // subsequence select, index of last bp wanted - end_input = new Fl_Input(300, 85+(i*35), 70, 30, "end index: "); - end_input->value(""); - end_input->callback((Fl_Callback*)sub_end_in_cb1, (void*) something); - - seq_scroll->add(start_input); - seq_scroll->add(end_input); -} - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ - -void SubAnalysisWindow::print_cb(Fl_Button* o, void* v) -{ - SubAnalysisWindow* T=(SubAnalysisWindow*)v; - T->print_cb_real(o,v); -} - - -void SubAnalysisWindow::print_cb_real(Fl_Button* , void*) -{ - cout << "analysis_name: " << analysis_name << endl; - cout << "win: " << window << endl; - cout << "thres: " << threshold << endl; - cout << "seq_num: " << seq_num << endl; - //cout << "win_add: " << win_append << end; - //cout << "thres_add: " << thres_append << endl; - - int i; - - - - for (i = 0; i < seq_num; i++) - { - cout << " start: " << sub_seq_starts[i]; - cout << " end: " << sub_seq_ends[i] << endl; - cout << "blargle!\n"; - } - cout << "end of inputs\n" << endl; -} diff --git a/gui/SubAnalysisWindow.hh b/gui/SubAnalysisWindow.hh deleted file mode 100644 index d0fb150..0000000 --- a/gui/SubAnalysisWindow.hh +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _MUSSA_GUI_SUBANA_H_ -#define _MUSSA_GUI_SUBANA_H_ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - -#include -#include - -#include -#include -#include -#include -#include - -#include "alg/mussa_class.hh" -#include "SeqTextWindow.hh" - -class SubAnalysisWindow : public Fl_Window -{ - public: - SubAnalysisWindow(int w, int h, const char* title, Mussa *an_analysis, - std::vector some_Seqs); - ~SubAnalysisWindow(); - bool done(); - - - Fl_Button* test; - - Fl_Input *name_input; - Fl_Input *win_input; - Fl_Input *thres_input; - Fl_Input *seq_num_input; - Fl_Scroll *seq_scroll; - // need to keep track of these so a browsed file search can set the input - // fields to the selected file - std::vector seq_inputs, annot_inputs; - - - // callback receiver functions - - void real_do_subana(); - - void real_set_ana_name_cb(Fl_Input* o); - void real_set_win_size_cb(Fl_Input* o); - void real_set_threshold_cb(Fl_Input* o); - - void real_sub_start_in_cb(Fl_Input* o, int i); - void real_sub_end_in_cb(Fl_Input* o, int i); - - private: - // sequence data - std::vector the_seqs; - Mussa *an_analysis; - std::string analysis_name; - int window, threshold, seq_num; - std::vector sub_seq_starts, sub_seq_ends; - bool win_append, thres_append; - bool all_done; - - static void print_cb(Fl_Button*, void*); - inline void print_cb_real(Fl_Button*, void*); - - void add_seq_input(int index, std::string a_name); -}; - -// crazy whacked shite Titus taught me to do to get an index value associated -// with each instance of an input associated with the callback... - - -struct sub_seq_data_instance -{ - SubAnalysisWindow * sw_ptr; - int index; -}; -#endif diff --git a/gui/SubAnalysisWindow.hpp b/gui/SubAnalysisWindow.hpp new file mode 100644 index 0000000..8bcaaa6 --- /dev/null +++ b/gui/SubAnalysisWindow.hpp @@ -0,0 +1,81 @@ +#ifndef _MUSSA_GUI_SUBANA_H_ +#define _MUSSA_GUI_SUBANA_H_ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + +#include +#include + +#include +#include +#include +#include +#include + +#include "alg/mussa.hpp" +#include "gui/SeqTextWindow.hpp" + +class SubAnalysisWindow : public Fl_Window +{ + public: + SubAnalysisWindow(int w, int h, const char* title, Mussa *an_analysis, + std::vector some_Seqs); + ~SubAnalysisWindow(); + bool done(); + + + Fl_Button* test; + + Fl_Input *name_input; + Fl_Input *win_input; + Fl_Input *thres_input; + Fl_Input *seq_num_input; + Fl_Scroll *seq_scroll; + // need to keep track of these so a browsed file search can set the input + // fields to the selected file + std::vector seq_inputs, annot_inputs; + + + // callback receiver functions + + void real_do_subana(); + + void real_set_ana_name_cb(Fl_Input* o); + void real_set_win_size_cb(Fl_Input* o); + void real_set_threshold_cb(Fl_Input* o); + + void real_sub_start_in_cb(Fl_Input* o, int i); + void real_sub_end_in_cb(Fl_Input* o, int i); + + private: + // sequence data + std::vector the_seqs; + Mussa *an_analysis; + std::string analysis_name; + int window, threshold, seq_num; + std::vector sub_seq_starts, sub_seq_ends; + bool win_append, thres_append; + bool all_done; + + static void print_cb(Fl_Button*, void*); + inline void print_cb_real(Fl_Button*, void*); + + void add_seq_input(int index, std::string a_name); +}; + +// crazy whacked shite Titus taught me to do to get an index value associated +// with each instance of an input associated with the callback... + + +struct sub_seq_data_instance +{ + SubAnalysisWindow * sw_ptr; + int index; +}; +#endif diff --git a/gui/module.mk b/gui/module.mk index f65a212..255f172 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -1,17 +1,17 @@ CURDIR := $(BASEDIR)gui/ -SOURCES.cxx := AnnotWindow.cxx \ - ConnView.cxx \ - ConnWindow.cxx \ - MotifWindow.cxx \ - SeqTextWindow.cxx \ - SeqView.cxx \ - SeqWindow.cxx \ - SetupWindow.cxx \ - SubAnalysisWindow.cxx +SOURCES.cpp := AnnotWindow.cpp \ + ConnView.cpp \ + ConnWindow.cpp \ + MotifWindow.cpp \ + SeqTextWindow.cpp \ + SeqView.cpp \ + SeqWindow.cpp \ + SetupWindow.cpp \ + SubAnalysisWindow.cpp -MUSSA_FLTK_SRC := $(addprefix $(CURDIR), $(SOURCES.cxx)) -MUSSA_FLTK_OBJ := $(MUSSA_FLTK_SRC:.cxx=$(OBJEXT)) +MUSSA_FLTK_SRC := $(addprefix $(CURDIR), $(SOURCES.cpp)) +MUSSA_FLTK_OBJ := $(MUSSA_FLTK_SRC:.cpp=$(OBJEXT)) SRC += $(MUSSA_FLTK_SRC) CXXFLAGS += diff --git a/mussa.cpp b/mussa.cpp new file mode 100644 index 0000000..92fe0b1 --- /dev/null +++ b/mussa.cpp @@ -0,0 +1,190 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "gui/ConnWindow.hpp" +#include "alg/mussa.hpp" +#include "mussa_exceptions.hpp" +#include +using namespace std; + +char +parse_args(int argc, char **argv, string *a_file_path, int *window, + int *threshold, enum Mussa::analysis_modes *ana_mode, float *ent_thres); + + +int main(int argc, char **argv) +{ + Mussa an_analysis; + string a_file_path; + char * picked_file; + int window, threshold; + float ent_thres; + char run_mode; + enum Mussa::analysis_modes ana_mode; + int x_max=1000; + int y_max=500; + string err_msg; + + + err_msg = ""; + + // yeah, its horrible to be passing these by reference, but I just don't see + // any other way without making parse_args part of MussaClass, which just + // seems wrong (args are after all, an io type thing, and the gui only mode + // will have it own way as well... + run_mode = parse_args(argc, argv, &a_file_path, &window, &threshold, + &ana_mode, &ent_thres); + + cout << "mussa: run mode = " << run_mode; + cout << "\tfile_path = "<< a_file_path << endl; + cout << "mussa: ent_thres = " << ent_thres << endl; + + // if no error from parse args (run_mode = 'e', ie error), run in proper mode + if (run_mode != 'e') + { + if ((run_mode == 'f') || (run_mode == 'n')) + { + an_analysis.load_mupa_file(a_file_path); + an_analysis.analyze(window, threshold, ana_mode, ent_thres); + //an_overlord.do_analysis(); + } + + if (run_mode == 'v') + an_analysis.load(a_file_path); + //an_overlord.get_analysis(); + + // no longer needed, but still semi-useful reality check... + if (run_mode == 'g') + { + cout << "GTV - All Gui, All the Time\n"; + } + + if (err_msg == "") + { + if ((run_mode == 'f') || (run_mode == 'v') || (run_mode == 'g')) + { + //an_overlord.spawnConnView(1000,500); + ConnWindow *a_conn_win = new ConnWindow(x_max, y_max, "Mussa"); + + // we have an analysis already if in these 2 modes + if ((run_mode == 'f') || (run_mode == 'v')) + a_conn_win->add_ana(&an_analysis); + + Fl::run(); + } + } + else + cout << err_msg << endl; + } +} + + +// minimal arg reading function, not very robust to errors +char +parse_args(int argc, char **argv, string *a_file_path, int *window, + int *threshold, enum Mussa::analysis_modes *ana_mode, float *ent_thres) +{ + int i, else_i; + string an_arg; + char run_mode; + + // initialize these to 0 as flag if they are not changed + *window = 0; + *threshold = 0; + *ent_thres = 0.0; + run_mode = 'e'; //error default if no run mode set implicitly or explicitly + *ana_mode = Mussa::TransitiveNway; // default to transitivie analyses mode + + // no args means gui only mode + if (argc == 1) + run_mode = 'g'; + else + { + else_i = 0; + i = 1; + while (i < argc) + { + an_arg = * ++argv; + i++; + + // see what alternate mode the user wants to run in + if (an_arg == "-m") + { + an_arg = * ++argv; + i++; + if ( (an_arg == "v") || (an_arg == "n") ) //only 2 valid modes so far + run_mode = an_arg[0]; + else + { + cout << "Error: \'" << an_arg; + cout << "\' is not a valid analysis mode for -a argument" << endl; + throw cmdline_error("not valid -a argument"); + } + *a_file_path = * ++argv; + i++; + } + // alternate analyses modes + else if (an_arg == "-a") + { + an_arg = * ++argv; + i++; + // t = transitive, r = radial, e = entropy + if (an_arg == "t") *ana_mode = Mussa::TransitiveNway; + else if (an_arg == "r") *ana_mode = Mussa::RadialNway; + else if (an_arg == "e") *ana_mode = Mussa::EntropyNway; + else + { + cout << "Error: \'" << an_arg; + cout << "\' is not a valid run mode for -m argument" << endl; + throw cmdline_error("bad argument -m"); + } + } + else if (an_arg == "-w") // alternate window size arg + { + *window = atoi(* ++argv); + i++; + } + else if (an_arg == "-t") // alternate threshold arg + { + *threshold = atoi(* ++argv); + i++; + } + else if (an_arg == "-et") // alternate entropy threshold arg + { + *ent_thres = atof(* ++argv); + i++; + } + else + { + if (else_i == 0) + { + *a_file_path = an_arg; + run_mode = 'f'; + else_i++; + } + else + { + //cout << "Error, unknown arg: \'" << an_arg << "\'" << endl; + cout << "Error, too many filenames: \'" << an_arg << "\'" << endl; + run_mode == 'e'; + } + } + } + } + return run_mode; +} + + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe\n"; + cout << "fum\n"; +*/ diff --git a/mussa.cxx b/mussa.cxx deleted file mode 100644 index 34ee333..0000000 --- a/mussa.cxx +++ /dev/null @@ -1,190 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "gui/ConnWindow.hh" -#include "alg/mussa_class.hh" -#include "mussa_exceptions.hh" -#include -using namespace std; - -char -parse_args(int argc, char **argv, string *a_file_path, int *window, - int *threshold, enum Mussa::analysis_modes *ana_mode, float *ent_thres); - - -int main(int argc, char **argv) -{ - Mussa an_analysis; - string a_file_path; - char * picked_file; - int window, threshold; - float ent_thres; - char run_mode; - enum Mussa::analysis_modes ana_mode; - int x_max=1000; - int y_max=500; - string err_msg; - - - err_msg = ""; - - // yeah, its horrible to be passing these by reference, but I just don't see - // any other way without making parse_args part of MussaClass, which just - // seems wrong (args are after all, an io type thing, and the gui only mode - // will have it own way as well... - run_mode = parse_args(argc, argv, &a_file_path, &window, &threshold, - &ana_mode, &ent_thres); - - cout << "mussa: run mode = " << run_mode; - cout << "\tfile_path = "<< a_file_path << endl; - cout << "mussa: ent_thres = " << ent_thres << endl; - - // if no error from parse args (run_mode = 'e', ie error), run in proper mode - if (run_mode != 'e') - { - if ((run_mode == 'f') || (run_mode == 'n')) - { - an_analysis.load_mupa_file(a_file_path); - an_analysis.analyze(window, threshold, ana_mode, ent_thres); - //an_overlord.do_analysis(); - } - - if (run_mode == 'v') - an_analysis.load(a_file_path); - //an_overlord.get_analysis(); - - // no longer needed, but still semi-useful reality check... - if (run_mode == 'g') - { - cout << "GTV - All Gui, All the Time\n"; - } - - if (err_msg == "") - { - if ((run_mode == 'f') || (run_mode == 'v') || (run_mode == 'g')) - { - //an_overlord.spawnConnView(1000,500); - ConnWindow *a_conn_win = new ConnWindow(x_max, y_max, "Mussa"); - - // we have an analysis already if in these 2 modes - if ((run_mode == 'f') || (run_mode == 'v')) - a_conn_win->add_ana(&an_analysis); - - Fl::run(); - } - } - else - cout << err_msg << endl; - } -} - - -// minimal arg reading function, not very robust to errors -char -parse_args(int argc, char **argv, string *a_file_path, int *window, - int *threshold, enum Mussa::analysis_modes *ana_mode, float *ent_thres) -{ - int i, else_i; - string an_arg; - char run_mode; - - // initialize these to 0 as flag if they are not changed - *window = 0; - *threshold = 0; - *ent_thres = 0.0; - run_mode = 'e'; //error default if no run mode set implicitly or explicitly - *ana_mode = Mussa::TransitiveNway; // default to transitivie analyses mode - - // no args means gui only mode - if (argc == 1) - run_mode = 'g'; - else - { - else_i = 0; - i = 1; - while (i < argc) - { - an_arg = * ++argv; - i++; - - // see what alternate mode the user wants to run in - if (an_arg == "-m") - { - an_arg = * ++argv; - i++; - if ( (an_arg == "v") || (an_arg == "n") ) //only 2 valid modes so far - run_mode = an_arg[0]; - else - { - cout << "Error: \'" << an_arg; - cout << "\' is not a valid analysis mode for -a argument" << endl; - throw cmdline_error("not valid -a argument"); - } - *a_file_path = * ++argv; - i++; - } - // alternate analyses modes - else if (an_arg == "-a") - { - an_arg = * ++argv; - i++; - // t = transitive, r = radial, e = entropy - if (an_arg == "t") *ana_mode = Mussa::TransitiveNway; - else if (an_arg == "r") *ana_mode = Mussa::RadialNway; - else if (an_arg == "e") *ana_mode = Mussa::EntropyNway; - else - { - cout << "Error: \'" << an_arg; - cout << "\' is not a valid run mode for -m argument" << endl; - throw cmdline_error("bad argument -m"); - } - } - else if (an_arg == "-w") // alternate window size arg - { - *window = atoi(* ++argv); - i++; - } - else if (an_arg == "-t") // alternate threshold arg - { - *threshold = atoi(* ++argv); - i++; - } - else if (an_arg == "-et") // alternate entropy threshold arg - { - *ent_thres = atof(* ++argv); - i++; - } - else - { - if (else_i == 0) - { - *a_file_path = an_arg; - run_mode = 'f'; - else_i++; - } - else - { - //cout << "Error, unknown arg: \'" << an_arg << "\'" << endl; - cout << "Error, too many filenames: \'" << an_arg << "\'" << endl; - run_mode == 'e'; - } - } - } - } - return run_mode; -} - - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe\n"; - cout << "fum\n"; -*/ diff --git a/mussa_exceptions.hh b/mussa_exceptions.hh deleted file mode 100644 index 701c5e5..0000000 --- a/mussa_exceptions.hh +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _MUSSA_EXCEPTIONS_H_ -#define _MUSSA_EXCEPTIONS_H_ -#include - -//! Error processing commandline arguments -class cmdline_error : public std::runtime_error -{ -public: - explicit cmdline_error(const std::string& msg): std::runtime_error(msg) {}; -}; - -//! Error loading information -class mussa_load_error : public std::runtime_error -{ -public: - explicit mussa_load_error(const std::string& msg) : - std::runtime_error(msg) {}; -}; - -//! failure running analysis -class mussa_analysis_error : public std::runtime_error -{ -public: - explicit mussa_analysis_error(const std::string& msg) : - std::runtime_error(msg) {}; -}; -#endif diff --git a/mussa_exceptions.hpp b/mussa_exceptions.hpp new file mode 100644 index 0000000..701c5e5 --- /dev/null +++ b/mussa_exceptions.hpp @@ -0,0 +1,27 @@ +#ifndef _MUSSA_EXCEPTIONS_H_ +#define _MUSSA_EXCEPTIONS_H_ +#include + +//! Error processing commandline arguments +class cmdline_error : public std::runtime_error +{ +public: + explicit cmdline_error(const std::string& msg): std::runtime_error(msg) {}; +}; + +//! Error loading information +class mussa_load_error : public std::runtime_error +{ +public: + explicit mussa_load_error(const std::string& msg) : + std::runtime_error(msg) {}; +}; + +//! failure running analysis +class mussa_analysis_error : public std::runtime_error +{ +public: + explicit mussa_analysis_error(const std::string& msg) : + std::runtime_error(msg) {}; +}; +#endif diff --git a/mussagl.cpp b/mussagl.cpp new file mode 100644 index 0000000..1447b7d --- /dev/null +++ b/mussagl.cpp @@ -0,0 +1,19 @@ +#include + +#include "qui/PathWindow.hpp" +#include "alg/parse_options.hpp" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Mussa *analysis = initialize_mussa(argc, argv); + + if (analysis == 0) { + return 1; + } + + PathWindow win(analysis); + win.show(); + app.exec(); + return 0; +} diff --git a/mussagl.cxx b/mussagl.cxx deleted file mode 100644 index f0ddc88..0000000 --- a/mussagl.cxx +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#include "qui/PathWindow.h" -#include "alg/parse_options.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - Mussa *analysis = initialize_mussa(argc, argv); - - if (analysis == 0) { - return 1; - } - - PathWindow win(analysis); - win.show(); - app.exec(); - return 0; -} diff --git a/mussagl.pro b/mussagl.pro index 7ec4364..24e1124 100644 --- a/mussagl.pro +++ b/mussagl.pro @@ -11,45 +11,45 @@ DEPENDPATH += . \ INCLUDEPATH += . alg qui # Input -HEADERS += mussa_exceptions.hh \ - qui/PathWidget.h \ - qui/PathWindow.h \ - qui/PathScene.h \ - qui/ThresholdWidget.h \ - qui/ImageScaler.h \ - qui/ImageSaveDialog.h \ - alg/color.h \ - alg/conserved_path.h \ - alg/flp.hh \ - alg/glsequence.h \ - alg/mussa_class.hh \ - alg/nway_paths.hh \ - alg/parse_options.h \ - alg/sequence.hh -SOURCES += mussagl.cxx \ - qui/PathWidget.cxx \ - qui/PathWindow.cxx \ - qui/PathScene.cxx \ - qui/ThresholdWidget.cxx \ - qui/ImageScaler.cxx \ - qui/ImageSaveDialog.cxx \ - alg/color.cxx \ - alg/conserved_path.cxx \ - alg/flp.cxx \ - alg/flp_seqcomp.cxx \ - alg/glsequence.cxx \ - alg/mussa_class.cxx \ - alg/nway_entropy.cxx \ - alg/nway_other.cxx \ - alg/nway_paths.cxx \ - alg/parse_options.cxx \ -# alg/nway_refine.cxx \ - alg/sequence.cxx -# test/test_flp.cxx \ -# test/test_main.cxx \ -# test/test_mussa.cxx \ -# test/test_nway.cxx \ -# test/test_sequence.cxx +HEADERS += mussa_exceptions.hpp \ + qui/PathWidget.hpp \ + qui/PathWindow.hpp \ + qui/PathScene.hpp \ + qui/ThresholdWidget.hpp \ + qui/ImageScaler.hpp \ + qui/ImageSaveDialog.hpp \ + alg/color.hpp \ + alg/conserved_path.hpp \ + alg/flp.hpp \ + alg/glsequence.hpp \ + alg/mussa.hpp \ + alg/nway_paths.hpp \ + alg/parse_options.hpp \ + alg/sequence.hpp +SOURCES += mussagl.cpp \ + qui/PathWidget.cpp \ + qui/PathWindow.cpp \ + qui/PathScene.cpp \ + qui/ThresholdWidget.cpp \ + qui/ImageScaler.cpp \ + qui/ImageSaveDialog.cpp \ + alg/color.cpp \ + alg/conserved_path.cpp \ + alg/flp.cpp \ + alg/flp_seqcomp.cpp \ + alg/glsequence.cpp \ + alg/mussa.cpp \ + alg/nway_entropy.cpp \ + alg/nway_other.cpp \ + alg/nway_paths.cpp \ + alg/parse_options.cpp \ +# alg/nway_refine.cpp \ + alg/sequence.cpp +# test/test_flp.cpp \ +# test/test_main.cpp \ +# test/test_mussa.cpp \ +# test/test_nway.cpp \ +# test/test_sequence.cpp LIBS += -lm QT += opengl diff --git a/py/conserved_path.cpp b/py/conserved_path.cpp new file mode 100644 index 0000000..65a5d06 --- /dev/null +++ b/py/conserved_path.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +using namespace boost::python; + +#include "alg/conserved_path.hpp" + +void export_conserved_path() +{ + + class_ >("intvec") + .def(vector_indexing_suite >()) + ; + + class_("ConservedPath") + .def_readwrite("score", &ConservedPath::score) + .def_readwrite("track_indexes", &ConservedPath::track_indexes) + //.add_property("track_indexes", //iterator >()) + // range(&ConservedPath::track_indexes.begin(), + // &ConservedPath::track_indexes.end())) + ; + + class_ >("ExtendedConservedPath") + .def_readwrite("window_size", &ExtendedConservedPath::window_size) + ; +} diff --git a/py/conserved_path.cxx b/py/conserved_path.cxx deleted file mode 100644 index 2b23428..0000000 --- a/py/conserved_path.cxx +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include -using namespace boost::python; - -#include "alg/conserved_path.h" - -void export_conserved_path() -{ - - class_ >("intvec") - .def(vector_indexing_suite >()) - ; - - class_("ConservedPath") - .def_readwrite("score", &ConservedPath::score) - .def_readwrite("track_indexes", &ConservedPath::track_indexes) - //.add_property("track_indexes", //iterator >()) - // range(&ConservedPath::track_indexes.begin(), - // &ConservedPath::track_indexes.end())) - ; - - class_ >("ExtendedConservedPath") - .def_readwrite("window_size", &ExtendedConservedPath::window_size) - ; -} diff --git a/py/glsequence.cpp b/py/glsequence.cpp new file mode 100644 index 0000000..213ce63 --- /dev/null +++ b/py/glsequence.cpp @@ -0,0 +1,18 @@ +#include +using namespace boost::python; + +#include "alg/glsequence.hpp" +#include "alg/sequence.hpp" + +void export_glsequence() +{ + class_("GlSequence", init()) + .def(init()) + .def("draw", &GlSequence::draw) + .def("sequence", &GlSequence::sequence, + return_internal_reference<>()) + .add_property("x", &GlSequence::x, &GlSequence::setX) + .add_property("y", &GlSequence::y, &GlSequence::setY) + .add_property("length", &GlSequence::length) + ; +} diff --git a/py/glsequence.cxx b/py/glsequence.cxx deleted file mode 100644 index dd8c7ea..0000000 --- a/py/glsequence.cxx +++ /dev/null @@ -1,18 +0,0 @@ -#include -using namespace boost::python; - -#include "alg/glsequence.h" -#include "alg/sequence.hh" - -void export_glsequence() -{ - class_("GlSequence", init()) - .def(init()) - .def("draw", &GlSequence::draw) - .def("sequence", &GlSequence::sequence, - return_internal_reference<>()) - .add_property("x", &GlSequence::x, &GlSequence::setX) - .add_property("y", &GlSequence::y, &GlSequence::setY) - .add_property("length", &GlSequence::length) - ; -} diff --git a/py/module.cpp b/py/module.cpp new file mode 100644 index 0000000..1f6fd02 --- /dev/null +++ b/py/module.cpp @@ -0,0 +1,17 @@ +#include +using namespace boost::python; + +void export_conserved_path(); +void export_glsequence(); +void export_mussa(); +void export_nway_paths(); +void export_sequence(); + +BOOST_PYTHON_MODULE(mussa) +{ + export_conserved_path(); + export_glsequence(); + export_mussa(); + export_nway_paths(); + export_sequence(); +} diff --git a/py/module.cxx b/py/module.cxx deleted file mode 100644 index 1f6fd02..0000000 --- a/py/module.cxx +++ /dev/null @@ -1,17 +0,0 @@ -#include -using namespace boost::python; - -void export_conserved_path(); -void export_glsequence(); -void export_mussa(); -void export_nway_paths(); -void export_sequence(); - -BOOST_PYTHON_MODULE(mussa) -{ - export_conserved_path(); - export_glsequence(); - export_mussa(); - export_nway_paths(); - export_sequence(); -} diff --git a/py/module.mk b/py/module.mk index d129a1a..015ca2b 100644 --- a/py/module.mk +++ b/py/module.mk @@ -1,14 +1,14 @@ CURDIR := $(BASEDIR)py/ -SOURCES.cxx := module.cxx \ - conserved_path.cxx \ - glsequence.cxx \ - mussa.cxx \ - nway_paths.cxx \ - sequence.cxx +SOURCES.cpp := module.cpp \ + conserved_path.cpp \ + glsequence.cpp \ + mussa.cpp \ + nway_paths.cpp \ + sequence.cpp -MUSSA_PY_SRC := $(addprefix $(CURDIR), $(SOURCES.cxx)) -MUSSA_PY_OBJ := $(MUSSA_PY_SRC:.cxx=$(OBJEXT)) +MUSSA_PY_SRC := $(addprefix $(CURDIR), $(SOURCES.cpp)) +MUSSA_PY_OBJ := $(MUSSA_PY_SRC:.cpp=$(OBJEXT)) SRC += $(MUSSA_PY_SRC) CXXFLAGS += diff --git a/py/mussa.cpp b/py/mussa.cpp new file mode 100644 index 0000000..cf34041 --- /dev/null +++ b/py/mussa.cpp @@ -0,0 +1,39 @@ +#include + +using namespace boost::python; + +#include "alg/mussa.hpp" + +void export_mussa() +{ + //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(mussa_analyze_overloads, + // &Mussa::analyze, 0, 4); + + class_("Mussa") + .def("save", &Mussa::save) + .def("load", &Mussa::load, "Load previous run analysis") + .def("load_mupa", &Mussa::load_mupa_file, "Load mussa parameter file") + .def("clear", &Mussa::clear, "Clear the current analysis") + .add_property("name", &Mussa::get_name, &Mussa::set_name) + .def("size", &Mussa::size, "Number of sequences to be used " + "in this analysis") + .add_property("window", &Mussa::get_window, &Mussa::set_window, + "the number of base pairs in the sliding window") + .add_property("threshold", &Mussa::get_threshold, &Mussa::set_threshold, + "how many base pairs must match between two windows") + .def("softThreshold", &Mussa::set_soft_thres) + .add_property("analysisMode", &Mussa::get_analysis_mode, + &Mussa::set_analysis_mode) + .add_property("analysisModeName", &Mussa::get_analysis_mode_name) + .def("analyze", &Mussa::analyze) + .def("paths", &Mussa::paths, return_internal_reference<>()) + //.def("sequences", &Mussa::sequences) + .def("addSequence", &Mussa::add_a_seq) ; + + enum_("analysis_modes") + .value("TransitiveNway", Mussa::TransitiveNway ) + .value("RadialNway", Mussa::RadialNway ) + .value("EntropyNway", Mussa::EntropyNway ) + .value("RecursiveNway", Mussa::RecursiveNway ) + ; +} diff --git a/py/mussa.cxx b/py/mussa.cxx deleted file mode 100644 index 690928f..0000000 --- a/py/mussa.cxx +++ /dev/null @@ -1,39 +0,0 @@ -#include - -using namespace boost::python; - -#include "alg/mussa_class.hh" - -void export_mussa() -{ - //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(mussa_analyze_overloads, - // &Mussa::analyze, 0, 4); - - class_("Mussa") - .def("save", &Mussa::save) - .def("load", &Mussa::load, "Load previous run analysis") - .def("load_mupa", &Mussa::load_mupa_file, "Load mussa parameter file") - .def("clear", &Mussa::clear, "Clear the current analysis") - .add_property("name", &Mussa::get_name, &Mussa::set_name) - .def("size", &Mussa::size, "Number of sequences to be used " - "in this analysis") - .add_property("window", &Mussa::get_window, &Mussa::set_window, - "the number of base pairs in the sliding window") - .add_property("threshold", &Mussa::get_threshold, &Mussa::set_threshold, - "how many base pairs must match between two windows") - .def("softThreshold", &Mussa::set_soft_thres) - .add_property("analysisMode", &Mussa::get_analysis_mode, - &Mussa::set_analysis_mode) - .add_property("analysisModeName", &Mussa::get_analysis_mode_name) - .def("analyze", &Mussa::analyze) - .def("paths", &Mussa::paths, return_internal_reference<>()) - //.def("sequences", &Mussa::sequences) - .def("addSequence", &Mussa::add_a_seq) ; - - enum_("analysis_modes") - .value("TransitiveNway", Mussa::TransitiveNway ) - .value("RadialNway", Mussa::RadialNway ) - .value("EntropyNway", Mussa::EntropyNway ) - .value("RecursiveNway", Mussa::RecursiveNway ) - ; -} diff --git a/py/nway_paths.cpp b/py/nway_paths.cpp new file mode 100644 index 0000000..73a13a9 --- /dev/null +++ b/py/nway_paths.cpp @@ -0,0 +1,15 @@ +#include +using namespace boost::python; + +#include "alg/nway_paths.hpp" + +void export_nway_paths() +{ + class_("NwayPaths") + .add_property("pathz", range(&NwayPaths::pbegin, + &NwayPaths::pend)) + .add_property("refinedPathz", range(&NwayPaths::rpbegin, + &NwayPaths::rpend)) + ; +} + diff --git a/py/nway_paths.cxx b/py/nway_paths.cxx deleted file mode 100644 index 3a03323..0000000 --- a/py/nway_paths.cxx +++ /dev/null @@ -1,15 +0,0 @@ -#include -using namespace boost::python; - -#include "alg/nway_paths.hh" - -void export_nway_paths() -{ - class_("NwayPaths") - .add_property("pathz", range(&NwayPaths::pbegin, - &NwayPaths::pend)) - .add_property("refinedPathz", range(&NwayPaths::rpbegin, - &NwayPaths::rpend)) - ; -} - diff --git a/py/sequence.cpp b/py/sequence.cpp new file mode 100644 index 0000000..68fc0ba --- /dev/null +++ b/py/sequence.cpp @@ -0,0 +1,16 @@ +#include +using namespace boost::python; + +#include +#include "alg/glsequence.hpp" + +void export_sequence() +{ + class_("Sequence") + .def(init()) + //.add_property("seq", &Sequence::get_seq, &Sequence::set_seq) + .def("size", &Sequence::size) + .def("__len__", &Sequence::size) + //.add_property("header", &Sequence::get_header) + ; +} diff --git a/py/sequence.cxx b/py/sequence.cxx deleted file mode 100644 index 39542fa..0000000 --- a/py/sequence.cxx +++ /dev/null @@ -1,16 +0,0 @@ -#include -using namespace boost::python; - -#include -#include "alg/glsequence.h" - -void export_sequence() -{ - class_("Sequence") - .def(init()) - //.add_property("seq", &Sequence::get_seq, &Sequence::set_seq) - .def("size", &Sequence::size) - .def("__len__", &Sequence::size) - //.add_property("header", &Sequence::get_header) - ; -} diff --git a/qui/ImageSaveDialog.cpp b/qui/ImageSaveDialog.cpp new file mode 100644 index 0000000..3c5b009 --- /dev/null +++ b/qui/ImageSaveDialog.cpp @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +//#include +#include + +#include "ImageSaveDialog.hpp" +#include "ImageScaler.hpp" + +#include + +ImageSaveDialog::ImageSaveDialog(QGLWidget *newglwidget, QWidget *parent) + : QDialog(parent) +{ + setWindowTitle(tr("Save Mussa Image")); + + // Init + glwidget = newglwidget; + //pixmap = 0; + imageScaler = new ImageScaler(); + + if (glwidget) + { + QSize tmpSize; + tmpSize = glwidget->size(); + imageScaler->setWidth(tmpSize.width()); + imageScaler->setHeight(tmpSize.height()); + } + + // File Path Label + filePathLabel = new QLabel(); + filePathLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken); + filePathLabel->setMinimumWidth(30); + + // Browse Button + browseButton = new QPushButton(tr("Browse...")); + connect(browseButton, SIGNAL(clicked()), + this, SLOT(promptFileDialog())); + + // Save Button + saveButton = new QPushButton(tr("Save")); + saveButton->setDefault(true); + connect(saveButton, SIGNAL(clicked()), + this, SLOT(accept())); + + // Cancel Button + cancelButton = new QPushButton(tr("Cancel")); + connect(cancelButton, SIGNAL(clicked()), + this, SLOT(reject())); + + // Layout + QGridLayout *layout = new QGridLayout; + layout->addWidget(imageScaler, 0, 0, 1, 0, Qt::AlignCenter); + layout->addWidget(filePathLabel, 1, 0); + layout->addWidget(browseButton, 1, 1); + layout->addWidget(saveButton, 2, 0); + layout->addWidget(cancelButton, 2, 1); + setLayout(layout); +} + + +void ImageSaveDialog::accept() +{ + std::cout << "Accepted!\n"; + savePixmap(); + done(1); +} + +void ImageSaveDialog::reject() +{ + std::cout << "Rejected!\n"; + done(0); +} + +void ImageSaveDialog::setSize(int width, int height) +{ + imageScaler->setWidth(width); + imageScaler->setHeight(height); +} + +//int ImageSaveDialog::exec() +//{ +// if (glwidget) +// { +// QSize tmpSize; +// tmpSize = glwidget->size(); +// imageScaler->setWidth(tmpSize.width()); +// imageScaler->setHeight(tmpSize.height()); +// } +// return QDialog::exec(); +//} + + +void ImageSaveDialog::promptFileDialog() +{ + QString filePath; + filePath = QFileDialog::getSaveFileName(this, + "Choose a filename to save image", + ".", + "Images (*.png *.jpg)"); + if (filePath.isEmpty()) + return; + + filePathLabel->setText(filePath); +} + +QSize ImageSaveDialog::getOpenGlPixmapSize() +{ + int width = imageScaler->getWidth(); + int height = imageScaler->getHeight(); + + if (height > 0 && width > 0) + { + return QSize(width, height); + } + + return QSize(); +} + +QPixmap ImageSaveDialog::renderOpenGlPixmap() +{ + if (!glwidget) + return QPixmap(); + + + QSize size = getOpenGlPixmapSize(); + if (size.isValid()) + { + QPixmap pixmap = glwidget->renderPixmap(size.width(), size.height()); + return pixmap; + } + return QPixmap(); +} + +void ImageSaveDialog::savePixmap() +{ + QString filePath; + filePath = filePathLabel->text(); + + if (filePath.isEmpty()) + //FIXME: Include prompt telling user of failure + return; + + QPixmap pixmap; + pixmap = renderOpenGlPixmap(); + + //Save pixelmap to file! + if (filePath.endsWith(".png")) + pixmap.save(filePath, "PNG"); + else if (filePath.endsWith(".jpg")) + pixmap.save(filePath, "JPG"); + else + //FIXME: Include prompt telling user of failure + return; + return; +} diff --git a/qui/ImageSaveDialog.cxx b/qui/ImageSaveDialog.cxx deleted file mode 100644 index 06bd0a0..0000000 --- a/qui/ImageSaveDialog.cxx +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include -#include -#include -#include -#include -//#include -#include - -#include "ImageSaveDialog.h" -#include "ImageScaler.h" - -#include - -ImageSaveDialog::ImageSaveDialog(QGLWidget *newglwidget, QWidget *parent) - : QDialog(parent) -{ - setWindowTitle(tr("Save Mussa Image")); - - // Init - glwidget = newglwidget; - //pixmap = 0; - imageScaler = new ImageScaler(); - - if (glwidget) - { - QSize tmpSize; - tmpSize = glwidget->size(); - imageScaler->setWidth(tmpSize.width()); - imageScaler->setHeight(tmpSize.height()); - } - - // File Path Label - filePathLabel = new QLabel(); - filePathLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken); - filePathLabel->setMinimumWidth(30); - - // Browse Button - browseButton = new QPushButton(tr("Browse...")); - connect(browseButton, SIGNAL(clicked()), - this, SLOT(promptFileDialog())); - - // Save Button - saveButton = new QPushButton(tr("Save")); - saveButton->setDefault(true); - connect(saveButton, SIGNAL(clicked()), - this, SLOT(accept())); - - // Cancel Button - cancelButton = new QPushButton(tr("Cancel")); - connect(cancelButton, SIGNAL(clicked()), - this, SLOT(reject())); - - // Layout - QGridLayout *layout = new QGridLayout; - layout->addWidget(imageScaler, 0, 0, 1, 0, Qt::AlignCenter); - layout->addWidget(filePathLabel, 1, 0); - layout->addWidget(browseButton, 1, 1); - layout->addWidget(saveButton, 2, 0); - layout->addWidget(cancelButton, 2, 1); - setLayout(layout); -} - - -void ImageSaveDialog::accept() -{ - std::cout << "Accepted!\n"; - savePixmap(); - done(1); -} - -void ImageSaveDialog::reject() -{ - std::cout << "Rejected!\n"; - done(0); -} - -void ImageSaveDialog::setSize(int width, int height) -{ - imageScaler->setWidth(width); - imageScaler->setHeight(height); -} - -//int ImageSaveDialog::exec() -//{ -// if (glwidget) -// { -// QSize tmpSize; -// tmpSize = glwidget->size(); -// imageScaler->setWidth(tmpSize.width()); -// imageScaler->setHeight(tmpSize.height()); -// } -// return QDialog::exec(); -//} - - -void ImageSaveDialog::promptFileDialog() -{ - QString filePath; - filePath = QFileDialog::getSaveFileName(this, - "Choose a filename to save image", - ".", - "Images (*.png *.jpg)"); - if (filePath.isEmpty()) - return; - - filePathLabel->setText(filePath); -} - -QSize ImageSaveDialog::getOpenGlPixmapSize() -{ - int width = imageScaler->getWidth(); - int height = imageScaler->getHeight(); - - if (height > 0 && width > 0) - { - return QSize(width, height); - } - - return QSize(); -} - -QPixmap ImageSaveDialog::renderOpenGlPixmap() -{ - if (!glwidget) - return QPixmap(); - - - QSize size = getOpenGlPixmapSize(); - if (size.isValid()) - { - QPixmap pixmap = glwidget->renderPixmap(size.width(), size.height()); - return pixmap; - } - return QPixmap(); -} - -void ImageSaveDialog::savePixmap() -{ - QString filePath; - filePath = filePathLabel->text(); - - if (filePath.isEmpty()) - //FIXME: Include prompt telling user of failure - return; - - QPixmap pixmap; - pixmap = renderOpenGlPixmap(); - - //Save pixelmap to file! - if (filePath.endsWith(".png")) - pixmap.save(filePath, "PNG"); - else if (filePath.endsWith(".jpg")) - pixmap.save(filePath, "JPG"); - else - //FIXME: Include prompt telling user of failure - return; - return; -} diff --git a/qui/ImageSaveDialog.h b/qui/ImageSaveDialog.h deleted file mode 100644 index beda6ee..0000000 --- a/qui/ImageSaveDialog.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _IMAGESAVEDIALOG_H_ -#define _IMAGESAVEDIALOG_H_ - -#include - -class ImageScaler; -class QLabel; -class QPixmap; -class QPushButton; -class QGLWidget; - -class ImageSaveDialog : public QDialog -{ - Q_OBJECT - -public: - ImageSaveDialog(QGLWidget *qlwidget = 0, QWidget *parent = 0); - -public slots: - void accept(); - void reject(); - // int exec(); - void promptFileDialog(); - void setSize(int width, int height); - -signals: - -private: - void savePixmap(); - QSize getOpenGlPixmapSize(); - QPixmap renderOpenGlPixmap(); - - ImageScaler *imageScaler; - //QPixmap *pixmap; - QLabel *filePathLabel; - QPushButton *browseButton; - QPushButton *saveButton; - QPushButton *cancelButton; - QGLWidget *glwidget; - -}; - -#endif diff --git a/qui/ImageSaveDialog.hpp b/qui/ImageSaveDialog.hpp new file mode 100644 index 0000000..beda6ee --- /dev/null +++ b/qui/ImageSaveDialog.hpp @@ -0,0 +1,43 @@ +#ifndef _IMAGESAVEDIALOG_H_ +#define _IMAGESAVEDIALOG_H_ + +#include + +class ImageScaler; +class QLabel; +class QPixmap; +class QPushButton; +class QGLWidget; + +class ImageSaveDialog : public QDialog +{ + Q_OBJECT + +public: + ImageSaveDialog(QGLWidget *qlwidget = 0, QWidget *parent = 0); + +public slots: + void accept(); + void reject(); + // int exec(); + void promptFileDialog(); + void setSize(int width, int height); + +signals: + +private: + void savePixmap(); + QSize getOpenGlPixmapSize(); + QPixmap renderOpenGlPixmap(); + + ImageScaler *imageScaler; + //QPixmap *pixmap; + QLabel *filePathLabel; + QPushButton *browseButton; + QPushButton *saveButton; + QPushButton *cancelButton; + QGLWidget *glwidget; + +}; + +#endif diff --git a/qui/ImageScaler.cpp b/qui/ImageScaler.cpp new file mode 100644 index 0000000..dbf9d58 --- /dev/null +++ b/qui/ImageScaler.cpp @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include + +//#include +#include + +#include "ImageScaler.hpp" + +ImageScaler::ImageScaler(QWidget *parent) + : QWidget(parent) +{ + lockAspectRatio = false; + aspectRatio = 1.0; + minWidth = 1; + minHeight = 1; + curWidth = 1; + curHeight = 1; + + //lockAspectAction = new QAction( + //lockAspectAction->setCheckable(true); + + lockButton = new QCheckBox(); + lockButton->setIcon(QIcon(tr("icons/lock.png"))); + lockButton->setToolTip(tr("Lock aspect ratio")); + lockButton->setWhatsThis(tr("Lock aspect ratio")); + connect(lockButton, SIGNAL(stateChanged(int)), + this, SLOT(setLockAspectRatio(int))); + + + + widthBox = new QSpinBox(); + widthBox->setMinimum(minWidth); + setMaxWidth(4048); + connect(this, SIGNAL(widthChanged(int)), + widthBox, SLOT(setValue(int))); + connect(widthBox, SIGNAL(valueChanged(int)), + this, SLOT(setWidth(int))); + + widthLabel = new QLabel(tr("Width:")); + //widthLabel.setBuddy(widthBox); + + heightBox = new QSpinBox(); + heightBox->setMinimum(1); + setMaxHeight(4048); + connect(this, SIGNAL(heightChanged(int)), + heightBox, SLOT(setValue(int))); + connect(heightBox, SIGNAL(valueChanged(int)), + this, SLOT(setHeight(int))); + + heightLabel = new QLabel(tr("Height:")); + //heightLabel.setBuddy(heightBox); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(widthLabel, 0, 0); + layout->addWidget(widthBox, 0, 1); + layout->addWidget(heightLabel, 1, 0); + layout->addWidget(heightBox, 1, 1); + layout->addWidget(lockButton, 0, 2, 1, 2, Qt::AlignCenter); + setLayout(layout); + + setWidth(curWidth); + setHeight(curHeight); +} + + +int ImageScaler::getMaxWidth() const +{ + return maxWidth; +} + +int ImageScaler::getMaxHeight() const +{ + return maxHeight; +} + +int ImageScaler::getWidth() const +{ + return widthBox->value(); +} + +int ImageScaler::getHeight() const +{ + return heightBox->value(); +} + + +void ImageScaler::setMaxWidth(int newValue) +{ + maxWidth = newValue; + widthBox->setMaximum(maxWidth); + emit maxWidthChanged(maxWidth); +} + +void ImageScaler::setMaxHeight(int newValue) +{ + maxHeight = newValue; + heightBox->setMaximum(maxHeight); + emit maxHeightChanged(maxHeight); +} + +void ImageScaler::setLockAspectRatio(int state) +{ + if (state == Qt::Checked) + { + setLockAspectRatio(true); + } + else if (state == Qt::Unchecked) + { + setLockAspectRatio(false); + } +} + +void ImageScaler::setLockAspectRatio(bool state) +{ + if (state == true) + { + lockAspectRatio = true; + aspectRatio = (float) curHeight / (float) curWidth; + } + else if (state == false) + { + lockAspectRatio = false; + } +} + +void ImageScaler::setWidth(int newValue) +{ + + if (curWidth == newValue) + { + return; + } + + // Make sure newValue is within legal range. + if (newValue < minWidth || newValue > maxWidth) + { + return; + } + + if (!lockAspectRatio) + { + curWidth = newValue; + emit widthChanged(newValue); + return; + } + else if (lockAspectRatio) + { + + if (curHeight <= 0) + { + curWidth = newValue; + emit widthChanged(newValue); + return; + } + + int newHeight = (int) rint((double) aspectRatio * (double) newValue); + + if (newValue != curWidth) + { + curWidth = newValue; + emit widthChanged(newValue); + } + curHeight = newHeight; + emit heightChanged(newHeight); + } +} + +void ImageScaler::setHeight(int newValue) +{ + + if (curHeight == newValue) + { + return; + } + + // Make sure newValue is within legal range. + if (newValue < minHeight || newValue > maxHeight) + { + return; + } + + // Just change current height if not in locked + // aspect ratio mode. + if (!lockAspectRatio) + { + curHeight = newValue; + emit heightChanged(newValue); + return; + } + // Handle locked aspect ratio mode. + else if (lockAspectRatio) + { + if (curWidth <= 0) + { + curHeight = newValue; + emit heightChanged(newValue); + return; + } + + int newWidth = (int) rint( (1.0 /(double) aspectRatio) * (double) newValue); + + if (newValue != curHeight) + { + curHeight = newValue; + emit heightChanged(newValue); + } + curWidth = newWidth; + emit widthChanged(newWidth); + } +} diff --git a/qui/ImageScaler.cxx b/qui/ImageScaler.cxx deleted file mode 100644 index db5cac6..0000000 --- a/qui/ImageScaler.cxx +++ /dev/null @@ -1,213 +0,0 @@ -#include -#include -#include -#include -#include - -//#include -#include - -#include "ImageScaler.h" - -ImageScaler::ImageScaler(QWidget *parent) - : QWidget(parent) -{ - lockAspectRatio = false; - aspectRatio = 1.0; - minWidth = 1; - minHeight = 1; - curWidth = 1; - curHeight = 1; - - //lockAspectAction = new QAction( - //lockAspectAction->setCheckable(true); - - lockButton = new QCheckBox(); - lockButton->setIcon(QIcon(tr("icons/lock.png"))); - lockButton->setToolTip(tr("Lock aspect ratio")); - lockButton->setWhatsThis(tr("Lock aspect ratio")); - connect(lockButton, SIGNAL(stateChanged(int)), - this, SLOT(setLockAspectRatio(int))); - - - - widthBox = new QSpinBox(); - widthBox->setMinimum(minWidth); - setMaxWidth(4048); - connect(this, SIGNAL(widthChanged(int)), - widthBox, SLOT(setValue(int))); - connect(widthBox, SIGNAL(valueChanged(int)), - this, SLOT(setWidth(int))); - - widthLabel = new QLabel(tr("Width:")); - //widthLabel.setBuddy(widthBox); - - heightBox = new QSpinBox(); - heightBox->setMinimum(1); - setMaxHeight(4048); - connect(this, SIGNAL(heightChanged(int)), - heightBox, SLOT(setValue(int))); - connect(heightBox, SIGNAL(valueChanged(int)), - this, SLOT(setHeight(int))); - - heightLabel = new QLabel(tr("Height:")); - //heightLabel.setBuddy(heightBox); - - QGridLayout *layout = new QGridLayout; - layout->addWidget(widthLabel, 0, 0); - layout->addWidget(widthBox, 0, 1); - layout->addWidget(heightLabel, 1, 0); - layout->addWidget(heightBox, 1, 1); - layout->addWidget(lockButton, 0, 2, 1, 2, Qt::AlignCenter); - setLayout(layout); - - setWidth(curWidth); - setHeight(curHeight); -} - - -int ImageScaler::getMaxWidth() const -{ - return maxWidth; -} - -int ImageScaler::getMaxHeight() const -{ - return maxHeight; -} - -int ImageScaler::getWidth() const -{ - return widthBox->value(); -} - -int ImageScaler::getHeight() const -{ - return heightBox->value(); -} - - -void ImageScaler::setMaxWidth(int newValue) -{ - maxWidth = newValue; - widthBox->setMaximum(maxWidth); - emit maxWidthChanged(maxWidth); -} - -void ImageScaler::setMaxHeight(int newValue) -{ - maxHeight = newValue; - heightBox->setMaximum(maxHeight); - emit maxHeightChanged(maxHeight); -} - -void ImageScaler::setLockAspectRatio(int state) -{ - if (state == Qt::Checked) - { - setLockAspectRatio(true); - } - else if (state == Qt::Unchecked) - { - setLockAspectRatio(false); - } -} - -void ImageScaler::setLockAspectRatio(bool state) -{ - if (state == true) - { - lockAspectRatio = true; - aspectRatio = (float) curHeight / (float) curWidth; - } - else if (state == false) - { - lockAspectRatio = false; - } -} - -void ImageScaler::setWidth(int newValue) -{ - - if (curWidth == newValue) - { - return; - } - - // Make sure newValue is within legal range. - if (newValue < minWidth || newValue > maxWidth) - { - return; - } - - if (!lockAspectRatio) - { - curWidth = newValue; - emit widthChanged(newValue); - return; - } - else if (lockAspectRatio) - { - - if (curHeight <= 0) - { - curWidth = newValue; - emit widthChanged(newValue); - return; - } - - int newHeight = (int) rint((double) aspectRatio * (double) newValue); - - if (newValue != curWidth) - { - curWidth = newValue; - emit widthChanged(newValue); - } - curHeight = newHeight; - emit heightChanged(newHeight); - } -} - -void ImageScaler::setHeight(int newValue) -{ - - if (curHeight == newValue) - { - return; - } - - // Make sure newValue is within legal range. - if (newValue < minHeight || newValue > maxHeight) - { - return; - } - - // Just change current height if not in locked - // aspect ratio mode. - if (!lockAspectRatio) - { - curHeight = newValue; - emit heightChanged(newValue); - return; - } - // Handle locked aspect ratio mode. - else if (lockAspectRatio) - { - if (curWidth <= 0) - { - curHeight = newValue; - emit heightChanged(newValue); - return; - } - - int newWidth = (int) rint( (1.0 /(double) aspectRatio) * (double) newValue); - - if (newValue != curHeight) - { - curHeight = newValue; - emit heightChanged(newValue); - } - curWidth = newWidth; - emit widthChanged(newWidth); - } -} diff --git a/qui/ImageScaler.h b/qui/ImageScaler.h deleted file mode 100644 index 86c2696..0000000 --- a/qui/ImageScaler.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _IMAGESCALER_H_ -#define _IMAGESCALER_H_ - -#include - -class QSpinBox; -class QLabel; -class QAction; -class QCheckBox; - -class ImageScaler : public QWidget -{ - Q_OBJECT - -public: - ImageScaler(QWidget *parent = 0); - - int getMaxHeight() const; - int getMaxWidth() const; - int getWidth() const; - int getHeight() const; - -public slots: - void setMaxWidth(int newValue); - void setMaxHeight(int newValue); - - //! Locks apsect ratio with true/false. - void setLockAspectRatio(bool state); - //! Locks aspect ratio with parameter Qt::Checked or Qt::Unchecked. - void setLockAspectRatio(int state); - - - void setWidth(int newValue); - void setHeight(int newValue); - -signals: - void maxWidthChanged(int newWidth); - void maxHeightChanged(int newHeight); - void widthChanged(int newWidth); - void heightChanged(int newHeight); - -private: - QSpinBox *widthBox; - QSpinBox *heightBox; - QLabel *widthLabel; - QLabel *heightLabel; - QAction *lockAspectAction; - QCheckBox *lockButton; - - bool lockAspectRatio; - float aspectRatio; - int maxWidth; - int minWidth; - int curWidth; - int maxHeight; - int minHeight; - int curHeight; - -}; - -#endif diff --git a/qui/ImageScaler.hpp b/qui/ImageScaler.hpp new file mode 100644 index 0000000..86c2696 --- /dev/null +++ b/qui/ImageScaler.hpp @@ -0,0 +1,61 @@ +#ifndef _IMAGESCALER_H_ +#define _IMAGESCALER_H_ + +#include + +class QSpinBox; +class QLabel; +class QAction; +class QCheckBox; + +class ImageScaler : public QWidget +{ + Q_OBJECT + +public: + ImageScaler(QWidget *parent = 0); + + int getMaxHeight() const; + int getMaxWidth() const; + int getWidth() const; + int getHeight() const; + +public slots: + void setMaxWidth(int newValue); + void setMaxHeight(int newValue); + + //! Locks apsect ratio with true/false. + void setLockAspectRatio(bool state); + //! Locks aspect ratio with parameter Qt::Checked or Qt::Unchecked. + void setLockAspectRatio(int state); + + + void setWidth(int newValue); + void setHeight(int newValue); + +signals: + void maxWidthChanged(int newWidth); + void maxHeightChanged(int newHeight); + void widthChanged(int newWidth); + void heightChanged(int newHeight); + +private: + QSpinBox *widthBox; + QSpinBox *heightBox; + QLabel *widthLabel; + QLabel *heightLabel; + QAction *lockAspectAction; + QCheckBox *lockButton; + + bool lockAspectRatio; + float aspectRatio; + int maxWidth; + int minWidth; + int curWidth; + int maxHeight; + int minHeight; + int curHeight; + +}; + +#endif diff --git a/qui/PathScene.cpp b/qui/PathScene.cpp new file mode 100644 index 0000000..3f0e335 --- /dev/null +++ b/qui/PathScene.cpp @@ -0,0 +1,505 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "qui/PathScene.hpp" +#include "alg/glsequence.hpp" +#include "mussa_exceptions.hpp" + +using namespace std; + +PathScene::PathScene(Mussa* analysis, QWidget *parent) : + QGLWidget(parent), + viewport_height(0), + viewport_width(0), + clipZ(30.0), + zoom(2), + maxOrtho2d(-50.0, -50, 3000000.0, 300.0), + curOrtho2d(maxOrtho2d), + viewport_center(((curOrtho2d.right()-curOrtho2d.left())/2)+curOrtho2d.left()), + selectedMode(false), + rubberBand(0), + drawingBand(false) +{ + if (analysis == 0) + { + mussaAnalysis = new Mussa; + } + else + { + mussaAnalysis = analysis; + } + updateScene(); +} + +QSize PathScene::sizeHint() const +{ + return QSize(400, 400); +} + +float PathScene::left() +{ + return maxOrtho2d.left(); +} + +float PathScene::right() +{ + return maxOrtho2d.right(); +} + +float PathScene::viewportLeft() +{ + return curOrtho2d.left(); +} + +float PathScene::viewportRight() +{ + return curOrtho2d.right(); +} + +float PathScene::viewportCenter() +{ + return viewport_center; +} + +void PathScene::updateViewport(float center, int new_zoom) +{ + float max_width = maxOrtho2d.width(); + if (new_zoom < 1) new_zoom = 1; + float new_max_width = max_width / new_zoom; + //curOrtho2d.setLeft(max(center-new_max_width, maxOrtho2d.left())); + //curOrtho2d.setRight(min(center+new_max_width, maxOrtho2d.right())); + curOrtho2d.setLeft(center-new_max_width); + curOrtho2d.setRight(center+new_max_width); + emit viewportChanged(); +} + +void PathScene::setViewportX(float x) +{ + //hopefully this calculates a sufficiently reasonable == for a float + if (x != viewport_center ) + { + updateViewport(x, zoom); + viewport_center = x; + update(); + } +} + +void PathScene::setZoom(int new_zoom) +{ + if (zoom != new_zoom) { + // try to figure out where we should be now? + updateViewport(viewport_center, new_zoom); + zoom = new_zoom; + update(); + } +} + +void PathScene::setClipPlane(int newZ) +{ + if (clipZ != (double) newZ){ + clipZ = (double) newZ; + update(); + } +} + +void PathScene::loadMupa() +{ + QString caption("Load a mussa parameter file"); + QString filter("Mussa Parameters (*.mupa)"); + QString mupa_path = QFileDialog::getOpenFileName(this, + caption, + QDir::currentPath(), + filter); + // user hit cancel? + if (mupa_path.isNull()) + return; + // try to load safely + try { + Mussa *m = new Mussa; + m->load_mupa_file(mupa_path.toStdString()); + m->analyze(0, 0, Mussa::TransitiveNway, 0.0); + // only switch mussas if we loaded without error + delete mussaAnalysis; + mussaAnalysis = m; + updateScene(); + } catch (mussa_load_error e) { + QString msg("Unable to load "); + msg += mupa_path; + msg += "\n"; + msg += e.what(); + QMessageBox::warning(this, "Load Parameter", msg); + } + assert (mussaAnalysis != 0); +} + +void PathScene::loadSavedAnalysis() +{ + QString caption("Load a previously run analysis"); + QString muway_dir = QFileDialog::getExistingDirectory(this, + caption, + QDir::currentPath()); + // user hit cancel? + if (muway_dir.isNull()) + return; + // try to safely load + try { + Mussa *m = new Mussa; + m->load(muway_dir.toStdString()); + // only switch mussas if we loaded without error + delete mussaAnalysis; + mussaAnalysis = m; + updateScene(); + } catch (mussa_load_error e) { + QString msg("Unable to load "); + msg += muway_dir; + msg += "\n"; + msg += e.what(); + QMessageBox::warning(this, "Load Parameter", msg); + } + assert (mussaAnalysis != 0); +} + +void PathScene::setSoftThreshold(int threshold) +{ + if (mussaAnalysis->get_threshold() != threshold) { + mussaAnalysis->set_soft_thres(threshold); + mussaAnalysis->nway(); + update(); + } +} + +//////////////////// +// Rendering code +void PathScene::initializeGL() +{ + glEnable(GL_DEPTH_TEST); + glClearColor(1.0, 1.0, 1.0, 0.0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_FLAT); +} + +void PathScene::resizeGL(int width, int height) +{ + viewport_width = width; + viewport_height = height; + assert (geometry().width() == width); + assert (geometry().height() == height); + glViewport(0, 0, (GLsizei)width, (GLsizei)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // I'm abusing this as Qt and OpenGL disagree about the direction of the + // y axis + glOrtho(curOrtho2d.left(), curOrtho2d.right(), + curOrtho2d.top(), curOrtho2d.bottom(), + -50.0, clipZ); +} + +void PathScene::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(curOrtho2d.left(), curOrtho2d.right(), + curOrtho2d.top(), curOrtho2d.bottom(), + -50.0, clipZ); + glMatrixMode(GL_MODELVIEW); + mussaesque(); + glEnable(GL_BLEND); + glDepthMask(GL_FALSE); + if (selectedMode && !drawingBand) { + glColor4f(0.6, 0.6, 0.6, 0.9); + glRectf(previousBand.x(), previousBand.y(), + previousBand.right(), previousBand.bottom()); + } + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glPopMatrix(); + glFlush(); +} + +void PathScene::updateScene() +{ + // Delete old glsequences + // FIXME: does this actually free the memory from the new'ed GlSequences? + tracks.clear(); + + // save a reference to our GlSequences + GlSequence *gl_seq; + float y = mussaAnalysis->sequences().size() * 100 ; + float max_base_pairs = 0; + typedef vector::const_iterator seqs_itor_t; + for(seqs_itor_t seq_itor = mussaAnalysis->sequences().begin(); + seq_itor != mussaAnalysis->sequences().end(); + ++seq_itor) + { + y = y - 100; + gl_seq = new GlSequence(*seq_itor); + gl_seq->setX(0); + gl_seq->setY(y); + if (gl_seq->length() > max_base_pairs ) max_base_pairs = gl_seq->length(); + tracks.push_back( *gl_seq ); + } + maxOrtho2d.setWidth(max_base_pairs + 100.0); + maxOrtho2d.setHeight((mussaAnalysis->sequences().size()) * 100 ); + curOrtho2d = maxOrtho2d; + viewport_center = (curOrtho2d.right()-curOrtho2d.left())/2+curOrtho2d.left(); +} + +void PathScene::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize) +{ + const size_t pathz_count = mussaAnalysis->paths().refined_pathz.size(); + GLuint *ptr; + GLuint names; + float z1; + float z2; + GLuint objtype; + GLuint objid; + + selectedPaths.clear(); + selectedPaths.reserve(pathz_count); + selectedPaths.insert(selectedPaths.begin(), pathz_count, false); + selectedTrack = 0x7fffffff; + + std::cout << "hits = " << hits << " " << pathz_count << std::endl; + ptr = (GLuint *) buffer; + if (hits > 0) + selectedMode = true; + for (GLuint i=0; i < hits; ++i) + { + if ((i + 5) > bufsize) { + std::clog << "*** selection overflow***" << std::endl; + } else { + names = *ptr++; + z1 = ((float)*ptr++)/0x7fffffff; + z2 = ((float)*ptr++)/0x7fffffff; + objtype = *ptr++; + objid = *ptr++; + if (names != 2) { + std::clog << "wrong number of glNames, selection is having trouble "; + std::clog << " got " << names << std::endl; + std::clog << " names: " ; + for (GLuint j = 0 ; j < names-2; ++j) { + std::clog << *ptr++ << " "; + } + std::clog << endl; + return; + } + switch (objtype) { + case MussaPaths: + selectedPaths[objid] = true; + break; + case MussaTracks: + if (objid < selectedTrack) { + selectedTrack = objid; + } + break; + } + } + } +} + +void PathScene::mousePressEvent( QMouseEvent *e) +{ + drawingBand = true; + std::cout << "x=" << e->x() << " y=" << e->y() << std::endl; + + selectedMode = false; + bandOrigin = e->pos(); + if (!rubberBand) + rubberBand = new QRubberBand(QRubberBand::Rectangle, this); + + rubberBand->setGeometry(QRect(bandOrigin, QSize())); + rubberBand->show(); +} + +void PathScene::mouseMoveEvent( QMouseEvent *e) +{ + if (drawingBand) + rubberBand->setGeometry(QRect(bandOrigin, e->pos()).normalized()); +} + +void dumpRect(const QRect &r) +{ + std::cout << "x=" << r.x() << " y=" << r.y() + << " w=" << r.width() << " h=" << r.height() << std::endl; +} + +void PathScene::mouseReleaseEvent( QMouseEvent *e) +{ + drawingBand = false; + rubberBand->hide(); + QRect r = QRect(bandOrigin, e->pos()).normalized(); + bandOrigin = r.topLeft(); + std::cout << "band "; + dumpRect(r); + + std::cout << "window "; + dumpRect(geometry()); + + GLfloat x_scale = curOrtho2d.width()/((float)geometry().width()); + GLfloat y_scale = curOrtho2d.height()/((float)geometry().height()); + GLfloat x_left = curOrtho2d.left() + (r.x()*x_scale); + GLfloat x_right = x_left + r.width() * x_scale; + // using QRectF with Y axis swapped + GLfloat y_top = curOrtho2d.bottom()-(r.y()*y_scale); + GLfloat y_bottom = y_top - r.height() * y_scale; + previousBand.setCoords(x_left, y_top, x_right, y_bottom); + std::cout << x_left << " " << x_right << " " << y_top << " " << y_bottom + << std::endl; + + // hopefully this will make a buffer big enough to receive + // everything being selected + const size_t pathz_count = mussaAnalysis->paths().refined_pathz.size(); + const GLuint select_buf_size = 1 + 5 * (pathz_count + tracks.size()) ; + GLuint selectBuf[select_buf_size]; + glSelectBuffer(select_buf_size, selectBuf); + GLint hits; + + (void)glRenderMode(GL_SELECT); + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(x_left, x_right, y_top, y_bottom, -50.0, 50.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + mussaesque(); + glFlush(); + + glPopMatrix(); + hits = glRenderMode(GL_RENDER); + processSelection(hits, selectBuf, select_buf_size); + + resizeGL(geometry().width(), geometry().height()); +} + + +////// +// openGl rendering code + +void PathScene::draw_tracks() const +{ + glPushMatrix(); + glPushName(0); + for (vector::size_type i = 0; i != tracks.size(); ++i ) + { + glLoadName(i); + tracks[i].draw(curOrtho2d.left(), curOrtho2d.right()); + } + glPopName(); + glPopMatrix(); +} + +void PathScene::draw_lines() const +{ + GLfloat x; + GLfloat y; + GLuint pathid=0; + GLint objid=0; + bool reversed = false; + bool prevReversed = false; + const NwayPaths& nway = mussaAnalysis->paths(); + + glPushName(pathid); + glLineWidth(2); + vector::const_iterator track_itor; + + typedef list conserved_paths; + typedef conserved_paths::const_iterator const_conserved_paths_itor; + for(const_conserved_paths_itor path_itor = nway.refined_pathz.begin(); + path_itor != nway.refined_pathz.end(); + ++path_itor, ++objid) + { + track_itor = tracks.begin(); + // since we were drawing to the start of a window, and opengl lines + // are centered around the two connecting points our lines were slightly + // offset. the idea of window_offset is to adjust them to the + // right for forward compliment or left for reverse compliment + // FIXME: figure out how to unit test these computations + GLfloat window_offset = (path_itor->window_size)/2.0; + + glBegin(GL_LINE_STRIP); + for (vector::const_iterator sp_itor = path_itor->begin(); + sp_itor != path_itor->end(); + ++sp_itor, ++track_itor) + { + x = *sp_itor; + y = track_itor->y(); + // at some point when we modify the pathz data structure to keep + // track of the score we can put grab the depth here. + // + // are we reverse complimented? + if ( x>=0) { + reversed = false; + } else { + reversed = true; + x = -x; // make positive + } + if (!reversed) + x += window_offset; // move right for forward compliment + else + x -= window_offset; // move left for reverse compliment + // the following boolean implements logical xor + if ( (reversed || prevReversed) && (!reversed || !prevReversed)) { + // we have a different orientation + if (not selectedMode or selectedPaths[objid] == true) { + // if we have nothing selected, or we're the highlight, be bright + glColor3f(0.0, 0.0, 1.0); + } else { + // else be dim + glColor3f(0.7, 0.7, 1.0); + } + } else { + // both current and previous path have the same orientation + if (not selectedMode or selectedPaths[objid] == true) { + glColor3f(1.0, 0.0, 0.0); + } else { + glColor3f(1.0, 0.7, 0.7); + } + } + prevReversed = reversed; + glVertex3f(x, y, -1.0); + } + glEnd(); + glLoadName(++pathid); + } + glPopName(); +} + +GLuint PathScene::make_line_list() +{ + GLuint line_list = glGenLists(1); + glNewList(line_list, GL_COMPILE); + + draw_lines(); + + glEndList(); + return line_list; + +} + +void PathScene::mussaesque() +{ + //static GLuint theLines = make_line_list(); + + glInitNames(); + glPushName(MussaPaths); + //glCallList(theLines); + draw_lines(); + glLoadName(MussaTracks); + draw_tracks(); + glPopName(); +} + diff --git a/qui/PathScene.cxx b/qui/PathScene.cxx deleted file mode 100644 index 175915e..0000000 --- a/qui/PathScene.cxx +++ /dev/null @@ -1,506 +0,0 @@ -#include "PathScene.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "alg/glsequence.h" -#include "mussa_exceptions.hh" - -using namespace std; - -PathScene::PathScene(Mussa* analysis, QWidget *parent) : - QGLWidget(parent), - viewport_height(0), - viewport_width(0), - clipZ(30.0), - zoom(2), - maxOrtho2d(-50.0, -50, 3000000.0, 300.0), - curOrtho2d(maxOrtho2d), - viewport_center(((curOrtho2d.right()-curOrtho2d.left())/2)+curOrtho2d.left()), - selectedMode(false), - rubberBand(0), - drawingBand(false) -{ - if (analysis == 0) - { - mussaAnalysis = new Mussa; - } - else - { - mussaAnalysis = analysis; - } - updateScene(); -} - -QSize PathScene::sizeHint() const -{ - return QSize(400, 400); -} - -float PathScene::left() -{ - return maxOrtho2d.left(); -} - -float PathScene::right() -{ - return maxOrtho2d.right(); -} - -float PathScene::viewportLeft() -{ - return curOrtho2d.left(); -} - -float PathScene::viewportRight() -{ - return curOrtho2d.right(); -} - -float PathScene::viewportCenter() -{ - return viewport_center; -} - -void PathScene::updateViewport(float center, int new_zoom) -{ - float max_width = maxOrtho2d.width(); - if (new_zoom < 1) new_zoom = 1; - float new_max_width = max_width / new_zoom; - //curOrtho2d.setLeft(max(center-new_max_width, maxOrtho2d.left())); - //curOrtho2d.setRight(min(center+new_max_width, maxOrtho2d.right())); - curOrtho2d.setLeft(center-new_max_width); - curOrtho2d.setRight(center+new_max_width); - emit viewportChanged(); -} - -void PathScene::setViewportX(float x) -{ - //hopefully this calculates a sufficiently reasonable == for a float - if (x != viewport_center ) - { - updateViewport(x, zoom); - viewport_center = x; - update(); - } -} - -void PathScene::setZoom(int new_zoom) -{ - if (zoom != new_zoom) { - // try to figure out where we should be now? - updateViewport(viewport_center, new_zoom); - zoom = new_zoom; - update(); - } -} - -void PathScene::setClipPlane(int newZ) -{ - if (clipZ != (double) newZ){ - clipZ = (double) newZ; - update(); - } -} - -void PathScene::loadMupa() -{ - QString caption("Load a mussa parameter file"); - QString filter("Mussa Parameters (*.mupa)"); - QString mupa_path = QFileDialog::getOpenFileName(this, - caption, - QDir::currentPath(), - filter); - // user hit cancel? - if (mupa_path.isNull()) - return; - // try to load safely - try { - Mussa *m = new Mussa; - m->load_mupa_file(mupa_path.toStdString()); - m->analyze(0, 0, Mussa::TransitiveNway, 0.0); - // only switch mussas if we loaded without error - delete mussaAnalysis; - mussaAnalysis = m; - updateScene(); - } catch (mussa_load_error e) { - QString msg("Unable to load "); - msg += mupa_path; - msg += "\n"; - msg += e.what(); - QMessageBox::warning(this, "Load Parameter", msg); - } - assert (mussaAnalysis != 0); -} - -void PathScene::loadSavedAnalysis() -{ - QString caption("Load a previously run analysis"); - QString muway_dir = QFileDialog::getExistingDirectory(this, - caption, - QDir::currentPath()); - // user hit cancel? - if (muway_dir.isNull()) - return; - // try to safely load - try { - Mussa *m = new Mussa; - m->load(muway_dir.toStdString()); - // only switch mussas if we loaded without error - delete mussaAnalysis; - mussaAnalysis = m; - updateScene(); - } catch (mussa_load_error e) { - QString msg("Unable to load "); - msg += muway_dir; - msg += "\n"; - msg += e.what(); - QMessageBox::warning(this, "Load Parameter", msg); - } - assert (mussaAnalysis != 0); -} - -void PathScene::setSoftThreshold(int threshold) -{ - if (mussaAnalysis->get_threshold() != threshold) { - mussaAnalysis->set_soft_thres(threshold); - mussaAnalysis->nway(); - update(); - } -} - -//////////////////// -// Rendering code -void PathScene::initializeGL() -{ - glEnable(GL_DEPTH_TEST); - glClearColor(1.0, 1.0, 1.0, 0.0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glShadeModel(GL_FLAT); -} - -void PathScene::resizeGL(int width, int height) -{ - viewport_width = width; - viewport_height = height; - assert (geometry().width() == width); - assert (geometry().height() == height); - glViewport(0, 0, (GLsizei)width, (GLsizei)height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - // I'm abusing this as Qt and OpenGL disagree about the direction of the - // y axis - glOrtho(curOrtho2d.left(), curOrtho2d.right(), - curOrtho2d.top(), curOrtho2d.bottom(), - -50.0, clipZ); -} - -void PathScene::paintGL() -{ - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(curOrtho2d.left(), curOrtho2d.right(), - curOrtho2d.top(), curOrtho2d.bottom(), - -50.0, clipZ); - glMatrixMode(GL_MODELVIEW); - mussaesque(); - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - if (selectedMode && !drawingBand) { - glColor4f(0.6, 0.6, 0.6, 0.9); - glRectf(previousBand.x(), previousBand.y(), - previousBand.right(), previousBand.bottom()); - } - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); - glPopMatrix(); - glFlush(); -} - -void PathScene::updateScene() -{ - // Delete old glsequences - // FIXME: does this actually free the memory from the new'ed GlSequences? - tracks.clear(); - - // save a reference to our GlSequences - GlSequence *gl_seq; - float y = mussaAnalysis->sequences().size() * 100 ; - float max_base_pairs = 0; - typedef vector::const_iterator seqs_itor_t; - for(seqs_itor_t seq_itor = mussaAnalysis->sequences().begin(); - seq_itor != mussaAnalysis->sequences().end(); - ++seq_itor) - { - y = y - 100; - gl_seq = new GlSequence(*seq_itor); - gl_seq->setX(0); - gl_seq->setY(y); - if (gl_seq->length() > max_base_pairs ) max_base_pairs = gl_seq->length(); - tracks.push_back( *gl_seq ); - } - maxOrtho2d.setWidth(max_base_pairs + 100.0); - maxOrtho2d.setHeight((mussaAnalysis->sequences().size()) * 100 ); - curOrtho2d = maxOrtho2d; - viewport_center = (curOrtho2d.right()-curOrtho2d.left())/2+curOrtho2d.left(); -} - -void PathScene::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize) -{ - const size_t pathz_count = mussaAnalysis->paths().refined_pathz.size(); - GLuint *ptr; - GLuint names; - float z1; - float z2; - GLuint objtype; - GLuint objid; - - selectedPaths.clear(); - selectedPaths.reserve(pathz_count); - selectedPaths.insert(selectedPaths.begin(), pathz_count, false); - selectedTrack = 0x7fffffff; - - std::cout << "hits = " << hits << " " << pathz_count << std::endl; - ptr = (GLuint *) buffer; - if (hits > 0) - selectedMode = true; - for (GLuint i=0; i < hits; ++i) - { - if ((i + 5) > bufsize) { - std::clog << "*** selection overflow***" << std::endl; - } else { - names = *ptr++; - z1 = ((float)*ptr++)/0x7fffffff; - z2 = ((float)*ptr++)/0x7fffffff; - objtype = *ptr++; - objid = *ptr++; - if (names != 2) { - std::clog << "wrong number of glNames, selection is having trouble "; - std::clog << " got " << names << std::endl; - std::clog << " names: " ; - for (GLuint j = 0 ; j < names-2; ++j) { - std::clog << *ptr++ << " "; - } - std::clog << endl; - return; - } - switch (objtype) { - case MussaPaths: - selectedPaths[objid] = true; - break; - case MussaTracks: - if (objid < selectedTrack) { - selectedTrack = objid; - } - break; - } - } - } -} - -void PathScene::mousePressEvent( QMouseEvent *e) -{ - drawingBand = true; - std::cout << "x=" << e->x() << " y=" << e->y() << std::endl; - - selectedMode = false; - bandOrigin = e->pos(); - if (!rubberBand) - rubberBand = new QRubberBand(QRubberBand::Rectangle, this); - - rubberBand->setGeometry(QRect(bandOrigin, QSize())); - rubberBand->show(); -} - -void PathScene::mouseMoveEvent( QMouseEvent *e) -{ - if (drawingBand) - rubberBand->setGeometry(QRect(bandOrigin, e->pos()).normalized()); -} - -void dumpRect(const QRect &r) -{ - std::cout << "x=" << r.x() << " y=" << r.y() - << " w=" << r.width() << " h=" << r.height() << std::endl; -} - -void PathScene::mouseReleaseEvent( QMouseEvent *e) -{ - drawingBand = false; - rubberBand->hide(); - QRect r = QRect(bandOrigin, e->pos()).normalized(); - bandOrigin = r.topLeft(); - std::cout << "band "; - dumpRect(r); - - std::cout << "window "; - dumpRect(geometry()); - - GLfloat x_scale = curOrtho2d.width()/((float)geometry().width()); - GLfloat y_scale = curOrtho2d.height()/((float)geometry().height()); - GLfloat x_left = curOrtho2d.left() + (r.x()*x_scale); - GLfloat x_right = x_left + r.width() * x_scale; - // using QRectF with Y axis swapped - GLfloat y_top = curOrtho2d.bottom()-(r.y()*y_scale); - GLfloat y_bottom = y_top - r.height() * y_scale; - previousBand.setCoords(x_left, y_top, x_right, y_bottom); - std::cout << x_left << " " << x_right << " " << y_top << " " << y_bottom - << std::endl; - - // hopefully this will make a buffer big enough to receive - // everything being selected - const size_t pathz_count = mussaAnalysis->paths().refined_pathz.size(); - const GLuint select_buf_size = 1 + 5 * (pathz_count + tracks.size()) ; - GLuint selectBuf[select_buf_size]; - glSelectBuffer(select_buf_size, selectBuf); - GLint hits; - - (void)glRenderMode(GL_SELECT); - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(x_left, x_right, y_top, y_bottom, -50.0, 50.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - mussaesque(); - glFlush(); - - glPopMatrix(); - hits = glRenderMode(GL_RENDER); - processSelection(hits, selectBuf, select_buf_size); - - resizeGL(geometry().width(), geometry().height()); -} - - -////// -// openGl rendering code - -void PathScene::draw_tracks() const -{ - glPushMatrix(); - glPushName(0); - for (vector::size_type i = 0; i != tracks.size(); ++i ) - { - glLoadName(i); - tracks[i].draw(curOrtho2d.left(), curOrtho2d.right()); - } - glPopName(); - glPopMatrix(); -} - -void PathScene::draw_lines() const -{ - GLfloat x; - GLfloat y; - GLuint pathid=0; - GLint objid=0; - bool reversed = false; - bool prevReversed = false; - const NwayPaths& nway = mussaAnalysis->paths(); - - glPushName(pathid); - glLineWidth(2); - vector::const_iterator track_itor; - - typedef list conserved_paths; - typedef conserved_paths::const_iterator const_conserved_paths_itor; - for(const_conserved_paths_itor path_itor = nway.refined_pathz.begin(); - path_itor != nway.refined_pathz.end(); - ++path_itor, ++objid) - { - track_itor = tracks.begin(); - // since we were drawing to the start of a window, and opengl lines - // are centered around the two connecting points our lines were slightly - // offset. the idea of window_offset is to adjust them to the - // right for forward compliment or left for reverse compliment - // FIXME: figure out how to unit test these computations - GLfloat window_offset = (path_itor->window_size)/2.0; - - glBegin(GL_LINE_STRIP); - for (vector::const_iterator sp_itor = path_itor->begin(); - sp_itor != path_itor->end(); - ++sp_itor, ++track_itor) - { - x = *sp_itor; - y = track_itor->y(); - // at some point when we modify the pathz data structure to keep - // track of the score we can put grab the depth here. - // - // are we reverse complimented? - if ( x>=0) { - reversed = false; - } else { - reversed = true; - x = -x; // make positive - } - if (!reversed) - x += window_offset; // move right for forward compliment - else - x -= window_offset; // move left for reverse compliment - // the following boolean implements logical xor - if ( (reversed || prevReversed) && (!reversed || !prevReversed)) { - // we have a different orientation - if (not selectedMode or selectedPaths[objid] == true) { - // if we have nothing selected, or we're the highlight, be bright - glColor3f(0.0, 0.0, 1.0); - } else { - // else be dim - glColor3f(0.7, 0.7, 1.0); - } - } else { - // both current and previous path have the same orientation - if (not selectedMode or selectedPaths[objid] == true) { - glColor3f(1.0, 0.0, 0.0); - } else { - glColor3f(1.0, 0.7, 0.7); - } - } - prevReversed = reversed; - glVertex3f(x, y, -1.0); - } - glEnd(); - glLoadName(++pathid); - } - glPopName(); -} - -GLuint PathScene::make_line_list() -{ - GLuint line_list = glGenLists(1); - glNewList(line_list, GL_COMPILE); - - draw_lines(); - - glEndList(); - return line_list; - -} - -void PathScene::mussaesque() -{ - //static GLuint theLines = make_line_list(); - - glInitNames(); - glPushName(MussaPaths); - //glCallList(theLines); - draw_lines(); - glLoadName(MussaTracks); - draw_tracks(); - glPopName(); -} - diff --git a/qui/PathScene.h b/qui/PathScene.h deleted file mode 100644 index 4819c67..0000000 --- a/qui/PathScene.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef _PATHSCENE_H_ -#define _PATHSCENE_H_ - -#include -#include -#include -#include - -#include "alg/mussa_class.hh" -#include "alg/glsequence.h" -#include "GL/gl.h" - -class QMouseEvent; -class QRubberBand; - -/*! \brief Render mussa sequences and paths - */ -class PathScene: public QGLWidget -{ - Q_OBJECT - -public: - PathScene(Mussa *analysis=0, QWidget *parent=0); - - QSize sizeHint() const; - - Mussa* mussaAnalysis; - std::vector tracks; - - float left(); - float right(); - float viewportLeft(); - float viewportRight(); - float viewportCenter(); - -public slots: - void setClipPlane(int z); - //! set the center of the current viewport - void setViewportX(float x); - //! set our magnification level - void setZoom(int); - //! load a mussa parameter file (which specifies an analysis to run) - void loadMupa( ); - //! load a previously run analysis - void loadSavedAnalysis(); - //! set the soft threshold used by the Nway_Path algorithm - void setSoftThreshold(int thres); - //! indicate that we should update our scene - void updateScene(); - -signals: - //! emitted when our analysis has changed - void analysisUpdated(); - void viewportChanged(); - -protected: - int viewport_height; - int viewport_width; - double clipZ; - int zoom; - QRectF maxOrtho2d; - QRectF curOrtho2d; - //! where the "center" of the viewport is - float viewport_center; - //! true if we have a selection - bool selectedMode; - //! indicate which paths are selected - std::vector selectedPaths; - //! which track is selected (it only makes sense to have one track selected). - unsigned int selectedTrack; - - void initializeGL(); - void resizeGL(int width, int height); - void paintGL(); - // recompute our current viewport dimensions, used by setViewportX & setZoom - void updateViewport(float left, int new_zoom); - - void mussaesque(); - //! draw all of our sequence tracks - void draw_tracks() const; - void draw_lines() const; - GLuint make_line_list(); - //! convert opengl selections into the list of paths we should highlight - void processSelection(GLuint hits, GLuint buffer[], GLuint bufsize); - //! Provide a logical name for a type discriminator for our glName stack - enum FeatureType { MussaTracks, MussaPaths }; - - //! \defgroup Selection - QRubberBand *rubberBand; - QPoint bandOrigin; - QRectF previousBand; - bool drawingBand; - void mousePressEvent(QMouseEvent *); - void mouseMoveEvent(QMouseEvent *); - void mouseReleaseEvent(QMouseEvent *); - -}; -#endif diff --git a/qui/PathScene.hpp b/qui/PathScene.hpp new file mode 100644 index 0000000..98e5ad5 --- /dev/null +++ b/qui/PathScene.hpp @@ -0,0 +1,98 @@ +#ifndef _PATHSCENE_H_ +#define _PATHSCENE_H_ + +#include +#include +#include +#include +#include + +#include "alg/mussa.hpp" +#include "alg/glsequence.hpp" + +class QMouseEvent; +class QRubberBand; + +/*! \brief Render mussa sequences and paths + */ +class PathScene: public QGLWidget +{ + Q_OBJECT + +public: + PathScene(Mussa *analysis=0, QWidget *parent=0); + + QSize sizeHint() const; + + Mussa* mussaAnalysis; + std::vector tracks; + + float left(); + float right(); + float viewportLeft(); + float viewportRight(); + float viewportCenter(); + +public slots: + void setClipPlane(int z); + //! set the center of the current viewport + void setViewportX(float x); + //! set our magnification level + void setZoom(int); + //! load a mussa parameter file (which specifies an analysis to run) + void loadMupa( ); + //! load a previously run analysis + void loadSavedAnalysis(); + //! set the soft threshold used by the Nway_Path algorithm + void setSoftThreshold(int thres); + //! indicate that we should update our scene + void updateScene(); + +signals: + //! emitted when our analysis has changed + void analysisUpdated(); + void viewportChanged(); + +protected: + int viewport_height; + int viewport_width; + double clipZ; + int zoom; + QRectF maxOrtho2d; + QRectF curOrtho2d; + //! where the "center" of the viewport is + float viewport_center; + //! true if we have a selection + bool selectedMode; + //! indicate which paths are selected + std::vector selectedPaths; + //! which track is selected (it only makes sense to have one track selected). + unsigned int selectedTrack; + + void initializeGL(); + void resizeGL(int width, int height); + void paintGL(); + // recompute our current viewport dimensions, used by setViewportX & setZoom + void updateViewport(float left, int new_zoom); + + void mussaesque(); + //! draw all of our sequence tracks + void draw_tracks() const; + void draw_lines() const; + GLuint make_line_list(); + //! convert opengl selections into the list of paths we should highlight + void processSelection(GLuint hits, GLuint buffer[], GLuint bufsize); + //! Provide a logical name for a type discriminator for our glName stack + enum FeatureType { MussaTracks, MussaPaths }; + + //! \defgroup Selection + QRubberBand *rubberBand; + QPoint bandOrigin; + QRectF previousBand; + bool drawingBand; + void mousePressEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + +}; +#endif diff --git a/qui/PathWidget.cpp b/qui/PathWidget.cpp new file mode 100644 index 0000000..6d9565b --- /dev/null +++ b/qui/PathWidget.cpp @@ -0,0 +1,53 @@ +#include + +#include +#include + +#include "qui/PathScene.hpp" +#include "qui/PathWidget.hpp" + +#include +using namespace std; + +// whats the maximum reasonable range for a scrollbar +const float max_scrollbar_range = 100000; + +PathWidget::PathWidget(PathScene *scene, QWidget *parent) : + QWidget(parent), + scene(scene), + viewportBar(Qt::Horizontal) +{ + QVBoxLayout *layout = new QVBoxLayout; + + layout->addWidget(scene); + layout->addWidget(&viewportBar); + + connect(&viewportBar, SIGNAL(valueChanged(int)), this, SLOT(setViewportX(int))); + connect(scene, SIGNAL(viewportChanged()), this, SLOT(updateScrollBar())); + setLayout(layout); + + // sets range & scale + updateScrollBar(); +} + +void PathWidget::updateScrollBar() +{ + float max_right = scene->right(); + float max_left = scene->left(); + float max_range = max_right - max_left; + float cur_left = scene->viewportLeft(); + float cur_right = scene->viewportRight(); + float cur_center = ((cur_right-cur_left)/2)+cur_left; + // set range to min + thumb = (int)cur_center; + viewportBar.setRange((int)max_left, (int)max_right); + viewportBar.setValue(thumb); +} + +void PathWidget::setViewportX(int x) +{ + if (x != thumb) { + thumb = x; + scene->setViewportX(thumb); + } +} diff --git a/qui/PathWidget.cxx b/qui/PathWidget.cxx deleted file mode 100644 index 3f32770..0000000 --- a/qui/PathWidget.cxx +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include -#include - -#include "qui/PathScene.h" -#include "qui/PathWidget.h" - -#include -using namespace std; - -// whats the maximum reasonable range for a scrollbar -const float max_scrollbar_range = 100000; - -PathWidget::PathWidget(PathScene *scene, QWidget *parent) : - QWidget(parent), - scene(scene), - viewportBar(Qt::Horizontal) -{ - QVBoxLayout *layout = new QVBoxLayout; - - layout->addWidget(scene); - layout->addWidget(&viewportBar); - - connect(&viewportBar, SIGNAL(valueChanged(int)), this, SLOT(setViewportX(int))); - connect(scene, SIGNAL(viewportChanged()), this, SLOT(updateScrollBar())); - setLayout(layout); - - // sets range & scale - updateScrollBar(); -} - -void PathWidget::updateScrollBar() -{ - float max_right = scene->right(); - float max_left = scene->left(); - float max_range = max_right - max_left; - float cur_left = scene->viewportLeft(); - float cur_right = scene->viewportRight(); - float cur_center = ((cur_right-cur_left)/2)+cur_left; - // set range to min - thumb = (int)cur_center; - viewportBar.setRange((int)max_left, (int)max_right); - viewportBar.setValue(thumb); -} - -void PathWidget::setViewportX(int x) -{ - if (x != thumb) { - thumb = x; - scene->setViewportX(thumb); - } -} diff --git a/qui/PathWidget.h b/qui/PathWidget.h deleted file mode 100644 index 32c1396..0000000 --- a/qui/PathWidget.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _PATH_WIDGET_H_ -#define _PATH_WIDGET_H_ - -#include -#include -class PathScene; - -class PathWidget : public QWidget -{ - Q_OBJECT - -public: - PathWidget(PathScene *, QWidget *parent=0); - -public slots: - //! update the scrollbar with current viewport information - void updateScrollBar(); - //! update scene with the properly scalled scrollbar offset - void setViewportX(int x); - -private: - PathScene *scene; - QScrollBar viewportBar; - int thumb; - - float range; - float scale; - - -}; - -#endif diff --git a/qui/PathWidget.hpp b/qui/PathWidget.hpp new file mode 100644 index 0000000..32c1396 --- /dev/null +++ b/qui/PathWidget.hpp @@ -0,0 +1,32 @@ +#ifndef _PATH_WIDGET_H_ +#define _PATH_WIDGET_H_ + +#include +#include +class PathScene; + +class PathWidget : public QWidget +{ + Q_OBJECT + +public: + PathWidget(PathScene *, QWidget *parent=0); + +public slots: + //! update the scrollbar with current viewport information + void updateScrollBar(); + //! update scene with the properly scalled scrollbar offset + void setViewportX(int x); + +private: + PathScene *scene; + QScrollBar viewportBar; + int thumb; + + float range; + float scale; + + +}; + +#endif diff --git a/qui/PathWindow.cpp b/qui/PathWindow.cpp new file mode 100644 index 0000000..5a7c47f --- /dev/null +++ b/qui/PathWindow.cpp @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qui/PathScene.hpp" +#include "qui/PathWidget.hpp" +#include "qui/PathWindow.hpp" +#include "qui/ThresholdWidget.hpp" +#include "qui/ImageSaveDialog.hpp" + +#include + +PathWindow::PathWindow(Mussa *analysis, QWidget *) : + closeAction(0) // initialize one of the pointers to null as a saftey flag +{ + scene = new PathScene(analysis, this); + + setupActions(); + setupMainMenu(); + + //This next setWhatsThis function prevents + // a segfault when using WhatsThis feature with + // opengl widget. + scene->setWhatsThis(tr("Mussa in OpenGL!")); + // make a widget so we can have a scroll bar + PathWidget *path_widget = new PathWidget(scene, this); + setCentralWidget(path_widget); + + mussaViewTB = new QToolBar("Path Views"); + mussaViewTB->addAction(toggleMotifsAction); + + QSpinBox *zoom = new QSpinBox(); + zoom->setWhatsThis("zoom magnification factor"); + zoom->setRange(2,1000); + mussaViewTB->addWidget(zoom); + connect(zoom, SIGNAL(valueChanged(int)), scene, SLOT(setZoom(int))); + + ThresholdWidget *threshold = new ThresholdWidget; + threshold->setRange(19, 30); + threshold->setThreshold(19); + scene->setClipPlane(20); + // FIXME: for when we get the paths drawn at the appropriate depth + //connect(threshold, SIGNAL(thresholdChanged(int)), + // scene, SLOT(setClipPlane(int))); + connect(threshold, SIGNAL(thresholdChanged(int)), + scene, SLOT(setSoftThreshold(int))); + mussaViewTB->addWidget(threshold); + + //Image Save Dialog + imageSaveDialog = new ImageSaveDialog(scene, this); + + addToolBar(mussaViewTB); + + statusBar()->showMessage("Welcome to mussa", 2000); +} + +void PathWindow::setupActions() +{ + // we really don't want to run this more than once. + assert (closeAction == 0); + + // the ever popular about box + aboutAction = new QAction(tr("&About"), this); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); + aboutAction->setIcon(QIcon("icons/info.png")); + + // add exit + closeAction = new QAction(tr("&Close"), this); + closeAction->setStatusTip(tr("Close this window")); + connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); + closeAction->setIcon(QIcon("icons/exit.png")); + + createNewAnalysisAction = new QAction(tr("Define Analysis"), this); + connect(createNewAnalysisAction, SIGNAL(triggered()), + this, SLOT(createNewAnalysis())); + createNewAnalysisAction->setIcon(QIcon("icons/filenew.png")); + + createSubAnalysisAction = new QAction(tr("Define SubAnalysis"), this); + connect(createSubAnalysisAction, SIGNAL(triggered()), + this, SLOT(createSubAnalysis())); + + loadMotifListAction = new QAction(tr("Load Motif List"), this); + connect(loadMotifListAction, SIGNAL(triggered()), + this, SLOT(loadMotifList())); + + loadMupaAction = new QAction(tr("Load Mussa Parameters"), this); + connect(loadMupaAction, SIGNAL(triggered()), + scene, SLOT(loadMupa())); + + loadSavedAnalysisAction = new QAction(tr("Load &Analysis"), this); + connect(loadSavedAnalysisAction, SIGNAL(triggered()), + scene, SLOT(loadSavedAnalysis())); + loadSavedAnalysisAction->setIcon(QIcon("icons/fileopen.png")); + + saveMotifListAction = new QAction(tr("Save Motifs"), this); + connect(saveMotifListAction, SIGNAL(triggered()), + this, SLOT(saveMotifList())); + saveMotifListAction->setIcon(QIcon("icons/filesave.png")); + + showMussaViewToolbarAction = new QAction(tr("Show Toolbar"), this); + connect(showMussaViewToolbarAction, SIGNAL(triggered()), + this, SLOT(showMussaToolbar())); + showMussaViewToolbarAction->setCheckable(true); + showMussaViewToolbarAction->setChecked(true); + + toggleMotifsAction = new QAction(tr("Toggle Motifs"), this); + connect(toggleMotifsAction, SIGNAL(triggered()), + this, SLOT(toggleMotifs())); + toggleMotifsAction->setCheckable(true); + toggleMotifsAction->setIcon(QIcon("icons/motif_icon.png")); + toggleMotifsAction->setWhatsThis(tr("Toggle motif annotations on/off\n\n" + "You can load motif annotations via " + "'File->Load Motif List' menu option.")); + + whatsThisAction = QWhatsThis::createAction(this); + whatsThisAction->setIcon(QIcon("icons/help.png")); + + //Save pixel map action + saveOpenGlPixmapAction = new QAction(tr("Save to image..."), this); + connect(saveOpenGlPixmapAction, (SIGNAL(triggered())), + this, SLOT(promptSaveOpenGlPixmap())); + saveOpenGlPixmapAction->setIcon(QIcon("icons/image2.png")); +} + +void PathWindow::setupMainMenu() +{ + // we need to run setupActions first + assert (closeAction != 0); + + QMenu *newMenu; + newMenu = menuBar()->addMenu(tr("&File")); + newMenu->addAction(createNewAnalysisAction); + newMenu->addAction(loadMupaAction); + newMenu->addAction(loadSavedAnalysisAction); + newMenu->addAction(createSubAnalysisAction); + newMenu->addSeparator(); + newMenu->addAction(loadMotifListAction); + newMenu->addAction(saveMotifListAction); + newMenu->addSeparator(); + newMenu->addAction(saveOpenGlPixmapAction); + newMenu->addSeparator(); + newMenu->addAction(closeAction); + + newMenu = menuBar()->addMenu(tr("&View")); + newMenu->addAction(showMussaViewToolbarAction); + + newMenu = menuBar()->addMenu(tr("&Help")); + newMenu->addAction(whatsThisAction); + newMenu->addSeparator(); + newMenu->addAction(aboutAction); +} + +void PathWindow::about() +{ + QMessageBox::about(this, tr("About mussa"), + tr("Welcome to Multiple Species Sequence Analysis\n" + "(c) 2005-2006 California Institute of Technology\n" + "Tristan De Buysscher, Diane Trout\n")); +} + +void PathWindow::createNewAnalysis() +{ + NotImplementedBox(); +} + +void PathWindow::createSubAnalysis() +{ + NotImplementedBox(); +} + +void PathWindow::loadMotifList() +{ + NotImplementedBox(); +} + +void PathWindow::saveMotifList() +{ + NotImplementedBox(); +} + +void PathWindow::showMussaToolbar() +{ + std::clog << "isVis?" << mussaViewTB->isVisible() <isVisible()) + mussaViewTB->hide(); + else + mussaViewTB->show(); + std::clog << "isVis?" << mussaViewTB->isVisible() <size(); + imageSaveDialog->setSize(size.width(), size.height()); + int result = imageSaveDialog->exec(); + std::cout << "Result: " << result << "\n"; +} + diff --git a/qui/PathWindow.cxx b/qui/PathWindow.cxx deleted file mode 100644 index 3048dec..0000000 --- a/qui/PathWindow.cxx +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qui/PathScene.h" -#include "qui/PathWidget.h" -#include "qui/PathWindow.h" -#include "qui/ThresholdWidget.h" -#include "qui/ImageSaveDialog.h" - -#include - -PathWindow::PathWindow(Mussa *analysis, QWidget *) : - closeAction(0) // initialize one of the pointers to null as a saftey flag -{ - scene = new PathScene(analysis, this); - - setupActions(); - setupMainMenu(); - - //This next setWhatsThis function prevents - // a segfault when using WhatsThis feature with - // opengl widget. - scene->setWhatsThis(tr("Mussa in OpenGL!")); - // make a widget so we can have a scroll bar - PathWidget *path_widget = new PathWidget(scene, this); - setCentralWidget(path_widget); - - mussaViewTB = new QToolBar("Path Views"); - mussaViewTB->addAction(toggleMotifsAction); - - QSpinBox *zoom = new QSpinBox(); - zoom->setWhatsThis("zoom magnification factor"); - zoom->setRange(2,1000); - mussaViewTB->addWidget(zoom); - connect(zoom, SIGNAL(valueChanged(int)), scene, SLOT(setZoom(int))); - - ThresholdWidget *threshold = new ThresholdWidget; - threshold->setRange(19, 30); - threshold->setThreshold(19); - scene->setClipPlane(20); - // FIXME: for when we get the paths drawn at the appropriate depth - //connect(threshold, SIGNAL(thresholdChanged(int)), - // scene, SLOT(setClipPlane(int))); - connect(threshold, SIGNAL(thresholdChanged(int)), - scene, SLOT(setSoftThreshold(int))); - mussaViewTB->addWidget(threshold); - - //Image Save Dialog - imageSaveDialog = new ImageSaveDialog(scene, this); - - addToolBar(mussaViewTB); - - statusBar()->showMessage("Welcome to mussa", 2000); -} - -void PathWindow::setupActions() -{ - // we really don't want to run this more than once. - assert (closeAction == 0); - - // the ever popular about box - aboutAction = new QAction(tr("&About"), this); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); - aboutAction->setIcon(QIcon("icons/info.png")); - - // add exit - closeAction = new QAction(tr("&Close"), this); - closeAction->setStatusTip(tr("Close this window")); - connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); - closeAction->setIcon(QIcon("icons/exit.png")); - - createNewAnalysisAction = new QAction(tr("Define Analysis"), this); - connect(createNewAnalysisAction, SIGNAL(triggered()), - this, SLOT(createNewAnalysis())); - createNewAnalysisAction->setIcon(QIcon("icons/filenew.png")); - - createSubAnalysisAction = new QAction(tr("Define SubAnalysis"), this); - connect(createSubAnalysisAction, SIGNAL(triggered()), - this, SLOT(createSubAnalysis())); - - loadMotifListAction = new QAction(tr("Load Motif List"), this); - connect(loadMotifListAction, SIGNAL(triggered()), - this, SLOT(loadMotifList())); - - loadMupaAction = new QAction(tr("Load Mussa Parameters"), this); - connect(loadMupaAction, SIGNAL(triggered()), - scene, SLOT(loadMupa())); - - loadSavedAnalysisAction = new QAction(tr("Load &Analysis"), this); - connect(loadSavedAnalysisAction, SIGNAL(triggered()), - scene, SLOT(loadSavedAnalysis())); - loadSavedAnalysisAction->setIcon(QIcon("icons/fileopen.png")); - - saveMotifListAction = new QAction(tr("Save Motifs"), this); - connect(saveMotifListAction, SIGNAL(triggered()), - this, SLOT(saveMotifList())); - saveMotifListAction->setIcon(QIcon("icons/filesave.png")); - - showMussaViewToolbarAction = new QAction(tr("Show Toolbar"), this); - connect(showMussaViewToolbarAction, SIGNAL(triggered()), - this, SLOT(showMussaToolbar())); - showMussaViewToolbarAction->setCheckable(true); - showMussaViewToolbarAction->setChecked(true); - - toggleMotifsAction = new QAction(tr("Toggle Motifs"), this); - connect(toggleMotifsAction, SIGNAL(triggered()), - this, SLOT(toggleMotifs())); - toggleMotifsAction->setCheckable(true); - toggleMotifsAction->setIcon(QIcon("icons/motif_icon.png")); - toggleMotifsAction->setWhatsThis(tr("Toggle motif annotations on/off\n\n" - "You can load motif annotations via " - "'File->Load Motif List' menu option.")); - - whatsThisAction = QWhatsThis::createAction(this); - whatsThisAction->setIcon(QIcon("icons/help.png")); - - //Save pixel map action - saveOpenGlPixmapAction = new QAction(tr("Save to image..."), this); - connect(saveOpenGlPixmapAction, (SIGNAL(triggered())), - this, SLOT(promptSaveOpenGlPixmap())); - saveOpenGlPixmapAction->setIcon(QIcon("icons/image2.png")); -} - -void PathWindow::setupMainMenu() -{ - // we need to run setupActions first - assert (closeAction != 0); - - QMenu *newMenu; - newMenu = menuBar()->addMenu(tr("&File")); - newMenu->addAction(createNewAnalysisAction); - newMenu->addAction(loadMupaAction); - newMenu->addAction(loadSavedAnalysisAction); - newMenu->addAction(createSubAnalysisAction); - newMenu->addSeparator(); - newMenu->addAction(loadMotifListAction); - newMenu->addAction(saveMotifListAction); - newMenu->addSeparator(); - newMenu->addAction(saveOpenGlPixmapAction); - newMenu->addSeparator(); - newMenu->addAction(closeAction); - - newMenu = menuBar()->addMenu(tr("&View")); - newMenu->addAction(showMussaViewToolbarAction); - - newMenu = menuBar()->addMenu(tr("&Help")); - newMenu->addAction(whatsThisAction); - newMenu->addSeparator(); - newMenu->addAction(aboutAction); -} - -void PathWindow::about() -{ - QMessageBox::about(this, tr("About mussa"), - tr("Welcome to Multiple Species Sequence Analysis\n" - "(c) 2005-2006 California Institute of Technology\n" - "Tristan De Buysscher, Diane Trout\n")); -} - -void PathWindow::createNewAnalysis() -{ - NotImplementedBox(); -} - -void PathWindow::createSubAnalysis() -{ - NotImplementedBox(); -} - -void PathWindow::loadMotifList() -{ - NotImplementedBox(); -} - -void PathWindow::saveMotifList() -{ - NotImplementedBox(); -} - -void PathWindow::showMussaToolbar() -{ - std::clog << "isVis?" << mussaViewTB->isVisible() <isVisible()) - mussaViewTB->hide(); - else - mussaViewTB->show(); - std::clog << "isVis?" << mussaViewTB->isVisible() <size(); - imageSaveDialog->setSize(size.width(), size.height()); - int result = imageSaveDialog->exec(); - std::cout << "Result: " << result << "\n"; -} - diff --git a/qui/PathWindow.h b/qui/PathWindow.h deleted file mode 100644 index ce63d18..0000000 --- a/qui/PathWindow.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _PATHWINDOW_H_ -#define _PATHWINDOW_H_ - -#include -#include -class QAction; -class PathScene; -class ImageSaveDialog; -class Mussa; - -class PathWindow : public QMainWindow -{ - Q_OBJECT - -public: - PathWindow(Mussa* analysis=0, QWidget *parent=0); - -public slots: - //! display an about box, contemplating the politics of the author list - void about(); - - //! \defgroup AnalysisFunctions Components related to running analyses - //\@{ - //! open a window to collect the information needed to create a new analysis - void createNewAnalysis(); - //! launch a sub analysis - void createSubAnalysis(); - //\@} - - //! \defgroup MotifHandling Handling of motif lists - //\@{ - void loadMotifList(); - void saveMotifList(); - void toggleMotifs(); - //\@} - - void showMussaToolbar(); - - void promptSaveOpenGlPixmap(); - -protected: - // display our wonderful mussa output - PathScene *scene; - QToolBar *mussaViewTB; - ImageSaveDialog *imageSaveDialog; - - QAction *aboutAction; - QAction *closeAction; - QAction *createNewAnalysisAction; - QAction *createSubAnalysisAction; - QAction *loadMotifListAction; - QAction *loadMupaAction; - QAction *loadSavedAnalysisAction; - QAction *saveMotifListAction; - QAction *showMussaViewToolbarAction; - QAction *toggleMotifsAction; - QAction *whatsThisAction; - QAction *saveOpenGlPixmapAction; - - //! initialze the actions - void setupActions(); - //! initialize this windows menu object - void setupMainMenu(); - //! stub function to fill in QActions - void NotImplementedBox(); -}; - -#endif diff --git a/qui/PathWindow.hpp b/qui/PathWindow.hpp new file mode 100644 index 0000000..ce63d18 --- /dev/null +++ b/qui/PathWindow.hpp @@ -0,0 +1,68 @@ +#ifndef _PATHWINDOW_H_ +#define _PATHWINDOW_H_ + +#include +#include +class QAction; +class PathScene; +class ImageSaveDialog; +class Mussa; + +class PathWindow : public QMainWindow +{ + Q_OBJECT + +public: + PathWindow(Mussa* analysis=0, QWidget *parent=0); + +public slots: + //! display an about box, contemplating the politics of the author list + void about(); + + //! \defgroup AnalysisFunctions Components related to running analyses + //\@{ + //! open a window to collect the information needed to create a new analysis + void createNewAnalysis(); + //! launch a sub analysis + void createSubAnalysis(); + //\@} + + //! \defgroup MotifHandling Handling of motif lists + //\@{ + void loadMotifList(); + void saveMotifList(); + void toggleMotifs(); + //\@} + + void showMussaToolbar(); + + void promptSaveOpenGlPixmap(); + +protected: + // display our wonderful mussa output + PathScene *scene; + QToolBar *mussaViewTB; + ImageSaveDialog *imageSaveDialog; + + QAction *aboutAction; + QAction *closeAction; + QAction *createNewAnalysisAction; + QAction *createSubAnalysisAction; + QAction *loadMotifListAction; + QAction *loadMupaAction; + QAction *loadSavedAnalysisAction; + QAction *saveMotifListAction; + QAction *showMussaViewToolbarAction; + QAction *toggleMotifsAction; + QAction *whatsThisAction; + QAction *saveOpenGlPixmapAction; + + //! initialze the actions + void setupActions(); + //! initialize this windows menu object + void setupMainMenu(); + //! stub function to fill in QActions + void NotImplementedBox(); +}; + +#endif diff --git a/qui/ThresholdWidget.cpp b/qui/ThresholdWidget.cpp new file mode 100644 index 0000000..5837b4b --- /dev/null +++ b/qui/ThresholdWidget.cpp @@ -0,0 +1,75 @@ +#include +#include +#include + +#include "qui/ThresholdWidget.hpp" + +// This is completely and totally derived from the Qt example +// LCDRange.cpp +ThresholdWidget::ThresholdWidget(QWidget *parent, int min, int max) + : QWidget(parent) +{ + QLCDNumber *lcd = new QLCDNumber(threshold_max_display_digits); + lcd->setSegmentStyle(QLCDNumber::Flat); + + slider = new QSlider(Qt::Horizontal); + slider->setRange(min, max); + + connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int))); + connect(slider, SIGNAL(valueChanged(int)), + this, SIGNAL(thresholdChanged(int))); + + slider->setValue(min); + lcd->display(min); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(slider); + layout->addWidget(lcd); + setLayout(layout); +} +/* +void ThresholdWidget::setMinimumThreshold(int min) +{ + slider->setMinimum(min); +} + +int ThresholdWidget::getMinimumThreshold() +{ + return slider->minimum(); +} + +void ThresholdWidget::setMaximumThreshold(int max) +{ + slider->setMaximum(max); +} + +int ThresholdWidget::getMaximumThreshold() +{ + return slider->maximum(); +} +*/ +void ThresholdWidget::setRange(int min, int max) +{ + slider->setRange(min, max); +} + +float ThresholdWidget::percent() const +{ + return ((float)threshold())/((float)slider->maximum()); +} + +void ThresholdWidget::setThreshold(int threshold) +{ + if (slider->value() != threshold) + { + slider->setValue(threshold); + emit thresholdChanged(threshold); + } +} + +int ThresholdWidget::threshold() const +{ + return slider->value(); +} + + diff --git a/qui/ThresholdWidget.cxx b/qui/ThresholdWidget.cxx deleted file mode 100644 index 3974d95..0000000 --- a/qui/ThresholdWidget.cxx +++ /dev/null @@ -1,75 +0,0 @@ -#include "qui/ThresholdWidget.h" - -#include -#include -#include - -// This is completely and totally derived from the Qt example -// LCDRange.cpp -ThresholdWidget::ThresholdWidget(QWidget *parent, int min, int max) - : QWidget(parent) -{ - QLCDNumber *lcd = new QLCDNumber(threshold_max_display_digits); - lcd->setSegmentStyle(QLCDNumber::Flat); - - slider = new QSlider(Qt::Horizontal); - slider->setRange(min, max); - - connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int))); - connect(slider, SIGNAL(valueChanged(int)), - this, SIGNAL(thresholdChanged(int))); - - slider->setValue(min); - lcd->display(min); - - QHBoxLayout *layout = new QHBoxLayout; - layout->addWidget(slider); - layout->addWidget(lcd); - setLayout(layout); -} -/* -void ThresholdWidget::setMinimumThreshold(int min) -{ - slider->setMinimum(min); -} - -int ThresholdWidget::getMinimumThreshold() -{ - return slider->minimum(); -} - -void ThresholdWidget::setMaximumThreshold(int max) -{ - slider->setMaximum(max); -} - -int ThresholdWidget::getMaximumThreshold() -{ - return slider->maximum(); -} -*/ -void ThresholdWidget::setRange(int min, int max) -{ - slider->setRange(min, max); -} - -float ThresholdWidget::percent() const -{ - return ((float)threshold())/((float)slider->maximum()); -} - -void ThresholdWidget::setThreshold(int threshold) -{ - if (slider->value() != threshold) - { - slider->setValue(threshold); - emit thresholdChanged(threshold); - } -} - -int ThresholdWidget::threshold() const -{ - return slider->value(); -} - - diff --git a/qui/ThresholdWidget.h b/qui/ThresholdWidget.h deleted file mode 100644 index 320858f..0000000 --- a/qui/ThresholdWidget.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _THRESHOLD_WIDGET_H_ -#define _THRESHOLD_WIDGET_H_ - -#include - -class QSlider; - -class ThresholdWidget : public QWidget -{ - Q_OBJECT - -public: - ThresholdWidget(QWidget *parent = 0, int min=21, int max=30); - - //! return what percent of our maximum threshold we are. - float percent() const; - //! return our current threshold - int threshold() const; - -public slots: - void setThreshold(int threshold); - void setRange(int min, int max); - -signals: - void thresholdChanged(int new_threshold); - -protected: - QSlider *slider; - -}; -const int threshold_max_display_digits = 2; - -#endif diff --git a/qui/ThresholdWidget.hpp b/qui/ThresholdWidget.hpp new file mode 100644 index 0000000..320858f --- /dev/null +++ b/qui/ThresholdWidget.hpp @@ -0,0 +1,33 @@ +#ifndef _THRESHOLD_WIDGET_H_ +#define _THRESHOLD_WIDGET_H_ + +#include + +class QSlider; + +class ThresholdWidget : public QWidget +{ + Q_OBJECT + +public: + ThresholdWidget(QWidget *parent = 0, int min=21, int max=30); + + //! return what percent of our maximum threshold we are. + float percent() const; + //! return our current threshold + int threshold() const; + +public slots: + void setThreshold(int threshold); + void setRange(int min, int max); + +signals: + void thresholdChanged(int new_threshold); + +protected: + QSlider *slider; + +}; +const int threshold_max_display_digits = 2; + +#endif diff --git a/seqcomp.cpp b/seqcomp.cpp new file mode 100644 index 0000000..ea0f3e6 --- /dev/null +++ b/seqcomp.cpp @@ -0,0 +1,97 @@ +// This file is part of the Mussa source distribution. +// http://mussa.caltech.edu/ +// Contact author: Tristan De Buysscher, tristan@caltech.edu + +// This program and all associated source code files are Copyright (C) 2005 +// the California Institute of Technology, Pasadena, CA, 91125 USA. It is +// under the GNU Public License; please see the included LICENSE.txt +// file for more information, or contact Tristan directly. + + +#include "flp.hh" +#include "sequence.hh" +#include +#include + +using namespace std; + +int main(int argc, char **argv) +{ + Sequence seqA, seqB; + FLPs analysis; + string seqA_file, seqB_file, output_file; + string ana_type; + int window, threshold; + int seqA_len, seqB_len; + + time_t t1, t2, begin, end; + double setuptime, comp1time, comp2time, sorttime, savetime, totaltime; + + begin = time(NULL); + + cout << "fee fie foe fum" << endl; + + ana_type = * ++argv; + seqA_file = * ++argv; + seqB_file = * ++argv; + window = atoi(* ++argv); + threshold = atoi(* ++argv); + output_file = * ++argv; + + t1 = time(NULL); + + seqA.load_fasta(seqA_file, 1, 0, 0); + seqA_len = seqA.len(); + //cout << setw(60) << seqA.hdr() << "\n"; + + seqB.load_fasta(seqB_file, 1, 0, 0); + seqB_len = seqB.len(); + //cout << seqB.hdr() << "\n"; + + + cout << "Length: Seq A = " << seqA_len; + cout << "; Seq B = " << seqB_len << "\n"; + + analysis.setup(ana_type, window, threshold, seqA_len, seqB_len); + + t2 = time(NULL); + setuptime = difftime(t2, t1); + + t1 = time(NULL); + analysis.seqcomp(seqA.seq(), seqB.seq(), false); + t2 = time(NULL); + comp1time = difftime(t2, t1); + + t1 = time(NULL); + analysis.seqcomp(seqA.seq(), seqB.rev_comp(), true); + t2 = time(NULL); + comp2time = difftime(t2, t1); + /* + t1 = time(NULL); + analysis.sort(); + t2 = time(NULL); + sorttime = difftime(t2, t1); + */ + t1 = time(NULL); + analysis.save(output_file); + t2 = time(NULL); + savetime = difftime(t2, t1); + + end = time(NULL); + totaltime = difftime(end, begin); + + cout << "setup\tcomp\trc_comp\tsave\ttotal\n"; + cout << setuptime << "\t"; + cout << comp1time << "\t"; + cout << comp2time << "\t"; + //cout << sorttime << "\t"; + cout << savetime << "\t"; + cout << totaltime << "\n"; +} + +/* + cout << "fee\n"; + cout << "fie\n"; + cout << "foe "; + cout << "fum\n"; +*/ diff --git a/seqcomp.cxx b/seqcomp.cxx deleted file mode 100644 index ea0f3e6..0000000 --- a/seqcomp.cxx +++ /dev/null @@ -1,97 +0,0 @@ -// This file is part of the Mussa source distribution. -// http://mussa.caltech.edu/ -// Contact author: Tristan De Buysscher, tristan@caltech.edu - -// This program and all associated source code files are Copyright (C) 2005 -// the California Institute of Technology, Pasadena, CA, 91125 USA. It is -// under the GNU Public License; please see the included LICENSE.txt -// file for more information, or contact Tristan directly. - - -#include "flp.hh" -#include "sequence.hh" -#include -#include - -using namespace std; - -int main(int argc, char **argv) -{ - Sequence seqA, seqB; - FLPs analysis; - string seqA_file, seqB_file, output_file; - string ana_type; - int window, threshold; - int seqA_len, seqB_len; - - time_t t1, t2, begin, end; - double setuptime, comp1time, comp2time, sorttime, savetime, totaltime; - - begin = time(NULL); - - cout << "fee fie foe fum" << endl; - - ana_type = * ++argv; - seqA_file = * ++argv; - seqB_file = * ++argv; - window = atoi(* ++argv); - threshold = atoi(* ++argv); - output_file = * ++argv; - - t1 = time(NULL); - - seqA.load_fasta(seqA_file, 1, 0, 0); - seqA_len = seqA.len(); - //cout << setw(60) << seqA.hdr() << "\n"; - - seqB.load_fasta(seqB_file, 1, 0, 0); - seqB_len = seqB.len(); - //cout << seqB.hdr() << "\n"; - - - cout << "Length: Seq A = " << seqA_len; - cout << "; Seq B = " << seqB_len << "\n"; - - analysis.setup(ana_type, window, threshold, seqA_len, seqB_len); - - t2 = time(NULL); - setuptime = difftime(t2, t1); - - t1 = time(NULL); - analysis.seqcomp(seqA.seq(), seqB.seq(), false); - t2 = time(NULL); - comp1time = difftime(t2, t1); - - t1 = time(NULL); - analysis.seqcomp(seqA.seq(), seqB.rev_comp(), true); - t2 = time(NULL); - comp2time = difftime(t2, t1); - /* - t1 = time(NULL); - analysis.sort(); - t2 = time(NULL); - sorttime = difftime(t2, t1); - */ - t1 = time(NULL); - analysis.save(output_file); - t2 = time(NULL); - savetime = difftime(t2, t1); - - end = time(NULL); - totaltime = difftime(end, begin); - - cout << "setup\tcomp\trc_comp\tsave\ttotal\n"; - cout << setuptime << "\t"; - cout << comp1time << "\t"; - cout << comp2time << "\t"; - //cout << sorttime << "\t"; - cout << savetime << "\t"; - cout << totaltime << "\n"; -} - -/* - cout << "fee\n"; - cout << "fie\n"; - cout << "foe "; - cout << "fum\n"; -*/