Update mussa to build on ubuntu 10.04 with qt 4.6.2 +boost 1.40.0.1
[mussa.git] / alg / conserved_path.cpp
1 #include "alg/conserved_path.hpp"
2 #include "mussa_exceptions.hpp"
3
4 using namespace std;
5
6 /////////////////////
7
8 ConservedPath::ConservedPath()
9   : window_size(0),
10     score(0.0),
11     track_indexes()
12 {
13 }
14
15 ConservedPath::ConservedPath(const ConservedPath::ConservedPath& other)
16   : window_size(other.window_size),
17     score(other.score),
18     track_indexes(other.track_indexes)
19 {
20 }
21
22 ConservedPath::ConservedPath(size_t win_size, double s, ConservedPath::path_type path)
23   : window_size(win_size),
24     score(s),
25     track_indexes(path)
26 {
27 }
28
29 void ConservedPath::clear()
30 {
31   window_size = 0;
32   score = 0.0;
33   track_indexes.clear();
34 }
35
36 ConservedPath::path_element&
37 ConservedPath::operator[](ConservedPath::size_type index)
38 {
39   return track_indexes[index];
40 }
41
42 bool operator==(const ConservedPath::ConservedPath& a,
43                 const ConservedPath::ConservedPath& b)
44 {
45   // this isn't good as score is now a double
46   return (     (a.score == b.score)
47            and (a.track_indexes.size() == b.track_indexes.size())
48            and (a.track_indexes == b.track_indexes));
49 }
50
51 bool operator!=(const ConservedPath::ConservedPath& a,
52                 const ConservedPath::ConservedPath& b)
53 {
54   return not (a == b);
55 }
56
57 bool operator<(const ConservedPath& a, const ConservedPath &b)
58 {
59   ConservedPath::const_iterator a_i = a.begin();
60   ConservedPath::const_iterator b_i = b.begin();
61   for(; a_i != a.end() and b_i != b.end(); ++a_i, ++b_i)
62   {
63     if (*a_i < *b_i) {
64       return true;
65     } else if (*a_i > *b_i) {
66       return false;
67     }
68     // else they're equal and we continue to loop
69   }
70   // now handle mismatched lengths
71   if (a_i == a.end() and b_i == b.end()) {
72     return false; // since the two paths are equal
73   } else if (a_i == a.end()) {
74     return true; // a is shorter than b
75   } else if (b_i == b.end()) {
76     return false; // b is shorter than a
77   } else {
78     // something went horribly wrong
79     throw std::runtime_error("ConservedPath operator< had a fatal logic error");
80   }
81 }
82
83 std::ostream& operator<<(std::ostream& out, const ConservedPath& path)
84 {
85   out << "<path win_size" << path.window_size 
86       << " score=" << path.score 
87       << " len=" << path.track_indexes.size();
88   if (path.track_indexes.size() > 0)
89   {
90     // print the first element
91     ConservedPath::const_iterator itor = path.begin();
92     out << ">" << *itor++;
93     // print the remaining elements
94     for (;
95         itor != path.end();
96         ++itor)
97     {
98       out << ", " << *itor;
99     }
100     out << "</path>";
101   }
102   else
103   {
104     // if we had no elements just close the block
105     out << "/>";
106   }
107   return out;
108 }
109
110 void ConservedPath::push_back(const ConservedPath::path_element& element)
111 {
112   track_indexes.push_back(element);
113 }
114
115 void ConservedPath::pop_back()
116 {
117   track_indexes.pop_back();
118 }
119
120 ConservedPath::size_type ConservedPath::size() const
121 {
122   return track_indexes.size();
123 }
124
125 ConservedPath::iterator ConservedPath::begin()
126 {
127   return track_indexes.begin();
128 }
129
130 ConservedPath::const_iterator ConservedPath::begin() const
131 {
132   return track_indexes.begin();
133 }
134
135 ConservedPath::iterator ConservedPath::end()
136 {
137   return track_indexes.end();
138 }
139
140 ConservedPath::const_iterator ConservedPath::end() const
141 {
142   return track_indexes.end();
143 }
144
145 bool ConservedPath::nextTo(const ConservedPath& next) const
146 {
147   if (size() != next.size() ) {
148     throw conserved_path_size_mismatch("paths must be the same length");
149   }    
150   ConservedPath::const_iterator this_itor = begin();
151   ConservedPath::const_iterator next_itor = next.begin();
152   for (; this_itor != end(); ++this_itor, ++next_itor)
153   {
154     if ( (*this_itor + 1) != *next_itor )
155       return false;
156   }
157   return true;
158 }
159
160 vector<bool> ConservedPath::reverseComplimented() const
161 {
162   vector<bool> reversed;
163   for (ConservedPath::const_iterator this_itor = begin(); 
164        this_itor != end(); 
165        ++this_itor)
166   {
167     if (*this_itor < 0) 
168       reversed.push_back(true);
169     else
170       reversed.push_back(false);
171   }
172   return reversed;
173
174 }
175
176 std::vector<ConservedPath::path_element> ConservedPath::normalizedIndexes() const
177 {
178   vector<path_element> paths;
179   for (ConservedPath::const_iterator this_itor = begin(); 
180        this_itor != end(); 
181        ++this_itor)
182   {
183     if (*this_itor < 0) {
184       paths.push_back(-(*this_itor)-window_size);
185     } else {
186       paths.push_back(*this_itor);
187     }
188   }
189   return paths;
190 }
191
192 ConservedPath& ConservedPath::extend(int growth)
193 {
194   window_size += growth;
195   
196   // What does this actually do? Tristan's code was doing this operation
197   // but I don't understand how it properly adjusts reverse compliment 
198   // windows?
199   for(ConservedPath::iterator path_i = begin();
200       path_i != end();
201       ++path_i)
202   {
203     if (*path_i < 0)
204       *path_i += growth;
205   }
206   return *this;
207 }
208