Augustus 3.4.0
Loading...
Searching...
No Matches
pp_hitseq.hh
1/*
2 * pp_hitseq.hh
3 *
4 * License: Artistic License, see file LICENSE.TXT or
5 * https://opensource.org/licenses/artistic-license-1.0
6 *
7 * Author : Oliver Keller
8 * Project : Gene Prediction with Protein Family Patterns
9 * Description: Data structures for storing ProteinProfile hit sequences
10 */
11
12#ifndef __PP_HITSEQ_HH
13#define __PP_HITSEQ_HH
14
15#include "pp_profile.hh"
16
17#include <algorithm>
18
19namespace PP {
20 /*
21 * HitSequence:
22 * consecutive sequence of block hits in the target sequence
23 * factor is the quotient of probabilities (block model vs. exon model)
24 * firstBlockIndex is the number of the first block of the sequence,
25 * posns contains positions from for block numbers first() to last()
26 */
27 struct HitSequence {
28 HitSequence(int b, int from, const Double& p) :
29 factor(p),
30 firstBlockIndex(b),
31 posns(1, from)
32 {}
33 int first() const {
34 return firstBlockIndex;
35 }
36 int last() const {
37 return firstBlockIndex + posns.size() - 1;
38 }
39 int firstValue() const {
40 return posns.front();
41 }
42 int lastValue() const {
43 return posns.back();
44 }
45
46 // append a single hit to the sequence
47 void add(int from, Double p) {
48 posns.push_back(from);
49 factor *= p;
50 }
51 // append all hits from another sequence
52 void add(const HitSequence& from) {
53 copy(from.posns.begin(), from.posns.end(), back_inserter(posns));
54 factor *= from.factor;
55 }
56
57 int operator[] (int b) const {
58 return posns[b - firstBlockIndex];
59 }
60 Double getFactor() const {
61 return factor;
62 }
63
64 // position in the profile for a base coordinate specified by offset; returns
65 // (b,i) where b is the last block and i is the distance of lastValue() to the
66 // offset. i equals (block length + distance of block end to offset). Usually
67 // offset is the dna coordinate of the exon end.
68 Position targetPosAt(int offset) const {
69 return Position(last(), (offset +1 - lastValue())/3);
70 }
71
72 Double factor;
73 int firstBlockIndex;
74 vector<int> posns;
75 }; // PP::HitSequence
76
77
78 /*
79 * HitSequenceNode: data structure for navigation through a
80 * collection of hit sequences
81 */
83 protected:
84 /*
85 * iterators for HitSequenceNode's
86 */
87 // ordinary iterator (ordering by first block)
88 class iterator {
89 public:
90 HitSequence& operator*() {
91#ifdef DEBUG
92 if (node->item == 0)
93 throw ProjectError("invalid iterator end() dereferenced");
94#endif
95 return *(node->item);
96 }
97 HitSequence* operator->() {
98#ifdef DEBUG
99 if (node->item == 0)
100 throw ProjectError("invalid iterator end() dereferenced");
101#endif
102 return node->item;
103 }
104 bool operator==(iterator other) {
105 return node==other.node;
106 }
107 iterator& operator=(iterator other) {
108 node=other.node;
109 return *this;
110 }
111 bool operator!=(iterator other) {
112 return node!=other.node;
113 }
114 iterator& operator++() {
115 node = node->next_by_first;
116 return *this;
117 }
118 iterator& operator--() {
119 node = node->previous_by_first;
120 return *this;
121 }
122 void erase() {
123#ifdef DEBUG
124 if (node->item == 0)
125 throw ProjectError("tried to delete root");
126#endif
127 node = node->next_by_first;
128 delete node->previous_by_first;
129 }
130 friend iterator createNode(const HitSequence&, iterator, iterator);
131 friend iterator createNode(int, int, const Double&, iterator, iterator);
132 iterator(HitSequenceNode* cur) : node(cur) {}
133 protected:
134 HitSequenceNode* node; // pointer to node containing current hit sequence
135 }; // PP::HitSequenceNode::iterator
136
137 // reverse iterator (ordering by first block)
139 reverse_iterator(const iterator& it) : iterator(it) {}
140 HitSequence& operator*() {
141#ifdef DEBUG
142 if (node->previous_by_first->item == 0)
143 throw ProjectError("invalid iterator rend() dereferenced");
144#endif
145 return *(node->previous_by_first->item);
146 }
147 HitSequence* operator->() {
148#ifdef DEBUG
149 if (node->previous_by_first->item == 0)
150 throw ProjectError("invalid iterator rend() dereferenced");
151#endif
152 return node->previous_by_first->item;
153 }
154 reverse_iterator& operator++() {
155 node = node->previous_by_first;
156 return *this;
157 }
158 reverse_iterator operator++(int) {
159 node = node->previous_by_first;
160 return reverse_iterator(node->next_by_first);
161 }
162 reverse_iterator& operator--() {
163 node = node->next_by_first;
164 return *this;
165 }
166 reverse_iterator operator--(int) {
167 node = node->next_by_first;
168 return iterator(node->previous_by_first);
169 }
170 void erase() {
171 delete node->previous_by_first;
172 }
173 }; // PP::HitSequenceNode::reverse_iterator
174
175 // iterator for ordering by last block
177 last_iterator(const iterator& it) : iterator(it) {}
178 last_iterator& operator++() {
179 node = node->next_by_last;
180 return *this;
181 }
182 last_iterator operator++(int) {
183 node = node->next_by_last;
184 return iterator(node->previous_by_last);
185 }
186 last_iterator& operator--() {
187 node = node->previous_by_last;
188 return *this;
189 }
190 void erase() {
191#ifdef DEBUG
192 if (node->item == 0)
193 throw ProjectError("tried to delete root");
194#endif
195 node = node->next_by_last;
196 delete node->previous_by_last;
197 }
198 }; // PP::HitSequenceNode::last_iterator
199
200 protected:
201 // constructors for HitSequenceNode
202 // can only be created by HitSequenceList
203 // or by createNode
204 HitSequenceNode() :
205 item(0),
206 previous_by_first(this),
207 next_by_first(this),
208 previous_by_last(this),
209 next_by_last(this) {
210#ifdef DEBUG
211 if (previous_by_first != this || next_by_first != this || previous_by_last != this)
212 throw ProjectError("This shouldn't happen.");
213#endif
214 }
215 HitSequenceNode(const HitSequence& seq,
216 HitSequenceNode* by_first, HitSequenceNode* by_last) :
217 item(new HitSequence(seq))
218 {
219 insert_this(by_first, by_last);
220 }
221 HitSequenceNode(int b, int i, const Double& p,
222 HitSequenceNode* by_first,
223 HitSequenceNode* by_last) :
224 item(new HitSequence(b,i,p))
225 {
226 insert_this(by_first, by_last);
227 }
228 // destructor
229 ~HitSequenceNode() {
230 remove_this();
231 delete item;
232 }
233
234 void insert_this(HitSequenceNode* by_first,
235 HitSequenceNode* by_last) {
236 previous_by_first = by_first->previous_by_first;
237 next_by_first = by_first;
238
239 previous_by_last = by_last->previous_by_last;
240 next_by_last = by_last;
241
242 by_first->previous_by_first
243 = previous_by_first->next_by_first
244 = by_last->previous_by_last
245 = previous_by_last->next_by_last
246 = this;
247 }
248 void remove_this() {
249 previous_by_first->next_by_first = next_by_first;
250 next_by_first->previous_by_first = previous_by_first;
251 previous_by_last->next_by_last = next_by_last;
252 next_by_last->previous_by_last = previous_by_last;
253 }
254#ifdef DEBUG
255 bool consistent() {
256 return
257 this == previous_by_first->next_by_first &&
258 this == next_by_first->previous_by_first &&
259 this == previous_by_last->next_by_last &&
260 this == next_by_last->previous_by_last;
261 }
262#endif
263
264
265 friend iterator createNode(const HitSequence& hs, iterator it, iterator lit) {
266 return new HitSequenceNode(hs, it.node, lit.node);
267 }
268 friend iterator createNode(int b, int i, const Double& p, iterator it, iterator lit) {
269 return new HitSequenceNode(b, i, p, it.node, lit.node);
270 }
271
272
273 HitSequence* item; // hit sequence of the node
274 HitSequenceNode* previous_by_first; // hit sequences ordered by first block
275 HitSequenceNode* next_by_first;
276 HitSequenceNode* previous_by_last; // hit sequences ordered by last block
277 HitSequenceNode* next_by_last;
278 }; // PP::HitSequenceNode
279
280
281 /*
282 * HitSequenceList:
283 * this class is an entry point to a hit sequence collection
284 * the base node of the list is without HitSequence
285 */
287// friend class HitSequenceCollection;
288 public:
292
293 // constructor and destructor
294 HitSequenceList() :
296 activeMax(this) {
297#ifdef DEBUG
298 if (previous_by_first != this)
299 throw ProjectError("This shouldn't happen!");
300#endif
301 }
303 while (next_by_first != this)
304 begin().erase();
305 while (next_by_last != this)
306 lbegin().erase();
307 }
308
309 // iterator methods
310 iterator begin() {
311 return next_by_first;
312 }
313 iterator end() {
314 return this;
315 }
316 reverse_iterator rbegin() {
317 return end();
318 }
319 reverse_iterator rend() {
320 return begin();
321 }
322 last_iterator lbegin() {
323 return iterator(next_by_last);
324 }
325 last_iterator lend() {
326 return end();
327 }
328
329 void init() {
330 activeMax = rbegin();
331 }
332 bool inactive() {
333 return activeMax == rend();
334 }
335 void setInactive(reverse_iterator it) {
336 activeMax = it;
337 }
338 reverse_iterator rbeginActive() {
339 return activeMax;
340 }
341
342 bool empty() {
343 return begin() == end();
344 }
345
346#ifdef DEBUG
347 bool inconsistent() {
348 return item != 0;
349 }
350#endif
351 private:
352 reverse_iterator activeMax; // end of the active elements of the list
353 }; // PP::HitSequenceList
354
355
356 /*
357 * HitSequenceCollection:
358 * this class contains all hit sequences for a given reading frame
359 * ordered by block number (one HitSequenceList for each block number
360 * to access them ordered by first and last block positions)
361 */
363 public:
364
365 HitSequenceCollection(int size=0) {
366 reset(size);
367 }
369 deleteNodes();
370 }
371 void addSingle(int b, int offset, const Double& val) {
372 createNode(b, offset, val, end(b), lbegin(b));
373 }
374 void addSingleFront(int b, int offset, const Double& val) {
375 createNode(b, offset, val, begin(b), lend(b));
376 }
377 void addHit(int b, int offset, Double val, DistanceType iBD, int blocksize);
378 void addHitFront(int b, int offset, Double val, DistanceType iBD);
379
380 void init() {
381 for (unsigned b=0; b<lists.size(); b++)
382 lists[b]->init();
383 }
384 void deleteNodes() {
385 for (unsigned b=0; b<lists.size(); b++)
386 delete lists[b];
387 }
388
389 private:
390 static HitSequenceList* newlist() {
391 return new HitSequenceList();
392 }
393 public:
394 void reset(int size) {
395 deleteNodes();
396 lists.resize(size);
397 generate_n(lists.begin(), size, &newlist);
398 }
399 void reset() {
400 deleteNodes();
401 generate(lists.begin(), lists.end(), &newlist);
402 }
403
404 // iterator methods
405 HitSequenceList::iterator begin(int b) {
406 return list(b).begin();
407 }
408 HitSequenceList::iterator end(int b) {
409 return list(b).end();
410 }
412 return list(b).rbegin();
413 }
415 return list(b).rend();
416 }
417 HitSequenceList::last_iterator lbegin(int b) {
418 return list(b).lbegin();
419 }
421 return list(b).lend();
422 }
423
424 HitSequenceList& list(int b) {
425#ifdef DEBUG
426 if (lists[b]->inconsistent())
427 throw ProjectError("root has nonzero item!");
428#endif
429 return *lists.at(b);
430 }
431 private:
432 vector<HitSequenceList*> lists;
433 }; // PP::HitSequenceCollection
434
435} // namespace PP
436
437#endif
This class implements a double object with a very large range.
Definition lldouble.hh:31
Definition pp_hitseq.hh:362
Definition pp_hitseq.hh:286
Definition pp_hitseq.hh:88
Definition pp_hitseq.hh:82
Definition types.hh:449
Definition pp_profile.hh:227
Definition pp_hitseq.hh:176
Definition pp_hitseq.hh:138
Definition pp_hitseq.hh:27
Definition pp_profile.hh:346