1 // ==========================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de>
33 // Author: Anne-Katrin Emde <anne-katrin.emde@fu-berlin.de>
34 // ==========================================================================
35 // Implementation of the Waterman-Eggert algorithm, sometimes also called
36 // Smith-Waterman algorithm with declumping.
37 // ==========================================================================
38
39 #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_WATERMAN_EGGERT_IMPL_H_
40 #define SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_WATERMAN_EGGERT_IMPL_H_
41
42 namespace seqan {
43
44 // ============================================================================
45 // Forwards
46 // ============================================================================
47
48 // ============================================================================
49 // Tags, Classes, Enums
50 // ============================================================================
51
52 // ----------------------------------------------------------------------------
53 // Helper Class ScoreAndID
54 // ----------------------------------------------------------------------------
55
56 // TODO(holtgrew): Why is Pair<> not enough?
57 // TODO(holtgrew): Rename to ScoreAndID_ (with trailing underscore)
58
59 // Simple class that stores a value with an ID.
60 template <typename TValue, typename TID>
61 class ScoreAndID
62 {
63 public:
64 TValue value_;
65 TID id_;
66
ScoreAndID()67 ScoreAndID() : value_(std::numeric_limits<TValue>::min()), id_(std::numeric_limits<TValue>::max())
68 {}
69
ScoreAndID(TValue score,TID id_pos)70 ScoreAndID(TValue score, TID id_pos)
71 {
72 value_ = score;
73 id_ = id_pos;
74 }
75
76 inline bool operator>(ScoreAndID const & other) const
77 {
78 return value_ > other.value_;
79 }
80
81 inline bool operator<(ScoreAndID const & other) const
82 {
83 return value_ < other.value_;
84 }
85 };
86
87 // ----------------------------------------------------------------------------
88 // Class LocalAlignmentFinder
89 // ----------------------------------------------------------------------------
90
91 template <typename TScoreValue = int>
92 class LocalAlignmentFinder
93 {
94 public:
95 typedef Matrix<TScoreValue> TMatrix;
96 typedef typename Position<TMatrix>::Type TMatrixPosition;
97 typedef typename Size<TMatrix>::Type TSize;
98 typedef ScoreAndID<TScoreValue,TMatrixPosition> TPQEntry;
99
100 typedef Iter<TMatrix,PositionIterator> TMatrixIterator;
101 typedef PriorityType<TPQEntry> TPriorityQ;
102 typedef String<bool> TBoolMatrix;
103
104 //DP-matrix
105 TMatrix matrix;
106 //matrix that memorizes the cells from which not to go diagonal
107 TBoolMatrix forbidden;
108 //priority queue for quickly finding the maximum score in the DP-matrix
109 TPriorityQ pQ;
110 //position of maximum score (where traceback is started from)
111 TMatrixPosition bestEndPos;
112 //position where traceback ended and where declumping begins
113 TMatrixPosition bestBeginPos;
114 //traceback path that is set to forbidden while declumping
115 AlignTraceback<TSize> trace;
116
117 bool needReinit; //true: call "smithWaterman", false: call "smithWatermanGetNext"
118
LocalAlignmentFinder()119 LocalAlignmentFinder() : bestEndPos(0), bestBeginPos(0), needReinit(true)
120 {}
121
122 // TODO(holtgrew): Remove and replace all occurrences with default constructor.
123 template<typename TAlign>
LocalAlignmentFinder(TAlign const &)124 LocalAlignmentFinder(TAlign const &) : bestEndPos(0), bestBeginPos(0), needReinit(true)
125 {}
126 };
127
128 // ============================================================================
129 // Metafunctions
130 // ============================================================================
131
132 // ============================================================================
133 // Functions
134 // ============================================================================
135
136 // ----------------------------------------------------------------------------
137 // Function _initLocalAlignmentFinder()
138 // ----------------------------------------------------------------------------
139
140 template<typename TSequenceH, typename TSequenceV, typename TScoreValue, typename TTag>
141 void
_initLocalAlignmentFinder(TSequenceH const & seqH,TSequenceV const & seqV,LocalAlignmentFinder<TScoreValue> & finder,TTag)142 _initLocalAlignmentFinder(TSequenceH const & seqH,
143 TSequenceV const & seqV,
144 LocalAlignmentFinder<TScoreValue> & finder,
145 TTag) {
146 typedef LocalAlignmentFinder<TScoreValue> TFinder;
147 typedef typename TFinder::TMatrix TMatrix;
148 typedef typename Size<TMatrix>::Type TSize;
149
150 TSize len0 = length(seqH);
151 TSize len1 = length(seqV);
152
153 setDimension(finder.matrix, 2);
154 setLength(finder.matrix, 0, len0 + 1);
155 setLength(finder.matrix, 1, len1 + 1);
156 resize(finder.matrix);
157
158 resize(finder.forbidden, (len0 + 1) * (len1 + 1), false);
159
160 finder.bestEndPos = std::numeric_limits<typename TFinder::TMatrixPosition>::max();
161 finder.bestBeginPos = std::numeric_limits<typename TFinder::TMatrixPosition>::max();
162 }
163
164 // ----------------------------------------------------------------------------
165 // Function clear()
166 // ----------------------------------------------------------------------------
167
168 template <typename TScoreValue>
clear(LocalAlignmentFinder<TScoreValue> & sw_finder)169 void clear(LocalAlignmentFinder<TScoreValue> & sw_finder)
170 {
171 sw_finder.needReinit = true;
172 }
173
174 // ----------------------------------------------------------------------------
175 // Function getScore()
176 // ----------------------------------------------------------------------------
177
178 template <typename TScoreValue>
getScore(LocalAlignmentFinder<TScoreValue> const & sw)179 TScoreValue getScore(LocalAlignmentFinder<TScoreValue> const & sw)
180 {
181 typedef LocalAlignmentFinder<TScoreValue> TFinder;
182 if(sw.bestEndPos != std::numeric_limits<typename TFinder::TMatrixPosition>::max())
183 return getValue(const_cast<typename TFinder::TMatrix &>(sw.matrix), sw.bestEndPos);
184 return 0;
185 }
186
187 // ----------------------------------------------------------------------------
188 // Function _smithWatermanGetMatrix()
189 // ----------------------------------------------------------------------------
190
191 template <typename TScoreValue, typename TScoreSpec, typename TStringH, typename TStringV>
192 TScoreValue
_smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,TStringH const & strH,TStringV const & strV,Score<TScoreValue,TScoreSpec> const & score_,TScoreValue cutoff)193 _smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,
194 TStringH const & strH,
195 TStringV const & strV,
196 Score<TScoreValue, TScoreSpec> const & score_,
197 TScoreValue cutoff)
198 {
199 // typedefs
200 typedef Matrix<TScoreValue> TMatrix;
201 typedef typename Position<TMatrix>::Type TMatrixPosition;
202 typedef Iter<TMatrix,PositionIterator> TMatrixIterator;
203
204 typedef typename Iterator<TStringH const, Rooted>::Type TStringIteratorH;
205 //typedef typename Value<TStringH const>::Type TValueH;
206 typedef typename Iterator<TStringV const, Rooted>::Type TStringIteratorV;
207 typedef typename Value<TStringV const>::Type TValueV;
208
209 //-------------------------------------------------------------------------
210 //define some variables
211
212
213 // TSize str1_length = length(strH);
214 // TSize str2_length = length(strV);
215 TStringIteratorH x_begin = begin(strH) - 1;
216 TStringIteratorH x_end = end(strH) - 1;
217 TStringIteratorV y_begin = begin(strV) - 1;
218 TStringIteratorV y_end = end(strV) - 1;
219
220 TStringIteratorH x = x_end;
221 TStringIteratorV y;
222
223 TScoreValue score_gap = scoreGapExtend(score_);
224
225 TScoreValue h = 0;
226 TScoreValue v = 0;
227
228 TMatrixIterator col_ = end(sw.matrix) - 1;
229 TMatrixIterator finger1;
230 TMatrixIterator finger2;
231
232 //-------------------------------------------------------------------------
233 // init
234
235 finger1 = col_;
236 *finger1 = 0;
237 //std::cout <<" ";
238 for (x = x_end; x != x_begin; --x)
239 {
240 goPrevious(finger1, 0);
241 *finger1 = 0;
242 }
243
244 //-------------------------------------------------------------------------
245 //fill matrix
246 for (y = y_end; y != y_begin; --y)
247 {
248 TValueV cy = *y;
249
250 h = 0;
251 v = 0;
252
253 finger2 = col_; //points to last column
254 goPrevious(col_, 1); //points to this column
255 finger1 = col_;
256
257 *finger1 = v;
258
259 for (x = x_end; x != x_begin; --x)
260 {
261 goPrevious(finger1, 0);
262 goPrevious(finger2, 0);
263
264 TScoreValue currScore = score(score_, *x, cy);
265 if (*x == cy)
266 {
267 v = h + currScore;
268 h = *finger2;
269 }
270 else
271 {
272 TScoreValue s1 = h + currScore;
273 h = *finger2;
274 TScoreValue s2 = score_gap + ((h > v) ? h : v);
275 v = (s1 > s2) ? s1 : s2;
276 if (v < 0) v = 0;
277
278 }
279 *finger1 = v;
280 if (v >= cutoff)
281 {
282 push(sw.pQ,ScoreAndID<TScoreValue,TMatrixPosition>(v,position(finger1)));
283 }
284 }
285 }
286
287 // check if any scores >= cutoff were found
288 if(!empty(sw.pQ))
289 {
290 ScoreAndID<TScoreValue,TMatrixPosition> best = top(sw.pQ);
291 v = getValue(sw.matrix,best.id_);
292 sw.bestEndPos = best.id_;
293 }
294 else
295 v=0;
296
297 return v;
298 }
299
300 // ----------------------------------------------------------------------------
301 // Function _smithWatermanDeclump()
302 // ----------------------------------------------------------------------------
303
304 // declumping
305 template <typename TScoreValue,
306 typename TSequenceH, typename TGapsSpecH,
307 typename TSequenceV, typename TGapsSpecV,
308 typename TScoreSpec>
309 void
_smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw,Gaps<TSequenceH,TGapsSpecH> & gapsH,Gaps<TSequenceV,TGapsSpecV> & gapsV,Score<TScoreValue,TScoreSpec> const & score_)310 _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
311 Gaps<TSequenceH, TGapsSpecH> & gapsH,
312 Gaps<TSequenceV, TGapsSpecV> & gapsV,
313 Score<TScoreValue, TScoreSpec> const & score_)
314 {
315 //-------------------------------------------------------------------------
316 //typedefs
317 //typedef typename LocalAlignmentFinder<TScoreValue>::TMatrixPosition TMatrixPosition;
318 typedef typename LocalAlignmentFinder<TScoreValue>::TMatrix TMatrix;
319 typedef Iter<TMatrix, PositionIterator> TMatrixIterator;
320
321 typedef Gaps<TSequenceH, TGapsSpecH> TGapsH;
322 typedef typename Iterator<TGapsH, Rooted>::Type TGapsHIter;
323 typedef typename Iterator<TSequenceH, Rooted>::Type TSequenceHIter;
324 //typedef typename Value<TSequenceH>::Type TValueH;
325
326 typedef Gaps<TSequenceV, TGapsSpecV> TGapsV;
327 typedef typename Iterator<TGapsV, Rooted>::Type TGapsVIter;
328 typedef typename Iterator<TSequenceV, Rooted>::Type TSequenceVIter;
329 typedef typename Value<TSequenceV>::Type TValueV;
330
331 //-------------------------------------------------------------------------
332 //variables
333 // TRow row0 = row(align_,0);
334 // TRow row1 = row(align_,1);
335
336 // beginPosition == # leading gaps
337 // endPosition == length of clipped region without trailing gaps
338 // clippedEndPosition == source position of clipping end.
339
340 // TAlignIterator ali_it0_stop = iter(row0,beginPosition(row0));
341 // TAlignIterator ali_it1_stop = iter(row1,beginPosition(row1));
342 TGapsHIter ali_it0_stop = begin(gapsH);
343 TGapsVIter ali_it1_stop = begin(gapsV);
344
345 // SEQAN_ASSERT( endPosition(row0)- beginPosition(row0) == endPosition(row1)- beginPosition(row1) );
346
347 // TAlignIterator ali_it0 = iter(row0,endPosition(row0));
348 // TAlignIterator ali_it1 = iter(row1,endPosition(row1));
349 TGapsHIter ali_it0 = end(gapsH);
350 TGapsVIter ali_it1 = end(gapsV);
351
352 // TStringIterator x_begin = begin(source(row0))-1;
353 // TStringIterator y_begin = begin(source(row1))-1;
354 // TStringIterator x_end = iter(source(row0),clippedEndPosition(row0))-1;
355 // TStringIterator y_end = iter(source(row1),clippedEndPosition(row1))-1;
356 TSequenceHIter x_begin = begin(source(gapsH))-1;
357 TSequenceVIter y_begin = begin(source(gapsV))-1;
358 TSequenceHIter x_end = iter(source(gapsH), endPosition(gapsH) - 1);
359 TSequenceVIter y_end = iter(source(gapsV), endPosition(gapsV) - 1);
360
361 // TStringIterator x = x_end;
362 // TStringIterator y = y_end;
363 // TStringIterator x_stop = x_end;
364 TSequenceHIter x = x_end;
365 TSequenceVIter y = y_end;
366 TSequenceHIter x_stop = x_end;
367
368
369 TScoreValue score_gap = scoreGapExtend(score_);
370 TScoreValue h,v;
371
372 TMatrixIterator finger0 = iter(sw.matrix,sw.bestBeginPos);
373 TMatrixIterator end_col = finger0;
374 TMatrixIterator finger1 = finger0;
375 TMatrixIterator forbidden = finger0;
376
377 bool different = true;
378 bool forbidden_reached = true;
379 bool end_reached = false;
380 bool skip_row = false;
381
382
383 /* int str0_length = length(source(row(align_,0)))+1;
384 int str1_length = length(source(row(align_,1)))+1;
385 for(int i = 0; i <str1_length; ++i){
386 for(int j=0;j<str0_length;++j){
387 std::cout << getValue(sw.matrix,(str0_length*i)+j);
388 if(sw.forbidden[(str0_length*i)+j]==true)
389 std::cout <<"(1) ";
390 else
391 std::cout <<"(0) ";
392 }
393 std::cout <<"\n";
394 }*/
395
396 clearClipping(gapsH);
397 clearClipping(gapsV);
398 // setClippedBeginPosition(row(align_, 0),0);
399 // setClippedBeginPosition(row(align_, 1),0);
400
401
402 for (y = y_end; (y != y_begin) ; --y)
403 {
404 different = true;
405 //compute next "forbidden" cell (where you are not allowed to go diagonal)
406 if(forbidden_reached && !end_reached)
407 {
408
409 if(ali_it0==ali_it0_stop && ali_it1==ali_it1_stop)
410 {
411 end_reached = true;
412 }
413
414 if(!end_reached)
415 {
416 --ali_it0;
417 goPrevious(forbidden,1);
418 while(isGap(ali_it0)&& ali_it0!=ali_it0_stop)
419 {
420 skip_row = true;
421 --ali_it0;
422 --ali_it1;
423 goPrevious(forbidden,1);
424 }
425
426 --ali_it1;
427 goPrevious(forbidden,0);
428 while(isGap(ali_it1)&& ali_it1!=ali_it1_stop)
429 {
430 --ali_it1;
431 --ali_it0;
432 goPrevious(forbidden,0);
433 }
434 // mark the forbidden cell
435 sw.forbidden[position(forbidden)]=true;
436 forbidden_reached = false;
437 }
438
439 }
440
441 TValueV cy = *y;
442
443 h = *end_col;
444
445 finger1 = end_col; //points to last column
446 goPrevious(end_col, 1); //points to this column
447 finger0 = end_col;
448
449 v = *finger0;
450 x = x_end;
451
452 // declump the current row until the cells in the declumped and
453 // the cells in the original matrix are the same (or the border is reached)
454 // indicated by bool different
455 while (x != x_begin && different)
456 {
457 goPrevious(finger0, 0);
458 goPrevious(finger1, 0);
459 TScoreValue currScore = score(score_, *x, cy);
460 if (*x == cy && !(sw.forbidden[position(finger0)]))
461 {
462 v = h + currScore;
463 h = *finger1;
464 }
465 else
466 {
467 TScoreValue s1;
468
469 if(finger0 == forbidden)
470 {
471 skip_row = false;
472 forbidden_reached = true;
473 s1 = 0;
474 }
475 else
476 {
477 if(sw.forbidden[position(finger0)]) s1 = 0;
478 else s1 = h + currScore;
479 }
480
481 h = *finger1;
482 TScoreValue s2 = score_gap + ((h > v) ? h : v);
483 v = (s1 > s2) ? s1 : s2;
484 if (v < 0) v = 0;
485
486 }
487
488 // value is the same as in the original matrix
489 if(*finger0==v)
490 {
491 //x_stop is as far as we have to go at least
492 if(x<x_stop)
493 {
494 different=false;
495 // x_stop=x;
496 }
497 else
498 {
499 // x_end indicates where to start in the next row
500 if(x==x_end && ((!forbidden_reached && !skip_row)||end_reached))
501 {
502 --x_end;
503 goPrevious(end_col, 0);
504 }
505 }
506 }
507 if(x<x_stop)// && different)
508 {
509 x_stop=x;
510 }
511 *finger0 = v;
512 --x;
513 }
514 if(x_end==x_begin)
515 break;
516 }
517
518 // cout <<"...declumped.\n";
519 }
520
521 // ----------------------------------------------------------------------------
522 // Function _smithWatermanTrace()
523 // ----------------------------------------------------------------------------
524
525 // Traceback.
526 template <typename TSourceH, typename TGapsSpecH,
527 typename TSourceV, typename TGapsSpecV,
528 typename TScoreValue, typename TScoreSpec,
529 unsigned DIMENSION>
530 typename Iterator<Matrix<TScoreValue, DIMENSION>, Standard >::Type
_smithWatermanTrace(Gaps<TSourceH,TGapsSpecH> & gapsH,Gaps<TSourceV,TGapsSpecV> & gapsV,typename LocalAlignmentFinder<TScoreValue>::TBoolMatrix & fb_matrix,Iter<Matrix<TScoreValue,DIMENSION>,PositionIterator> source_,Score<TScoreValue,TScoreSpec> const & scoring_)531 _smithWatermanTrace(Gaps<TSourceH, TGapsSpecH> & gapsH,
532 Gaps<TSourceV, TGapsSpecV> & gapsV,
533 typename LocalAlignmentFinder<TScoreValue>::TBoolMatrix & fb_matrix,
534 Iter< Matrix<TScoreValue, DIMENSION>, PositionIterator > source_,
535 Score<TScoreValue, TScoreSpec> const & scoring_) {
536 //typedefs
537 typedef Iter<Matrix<TScoreValue, DIMENSION>, PositionIterator > TMatrixIterator;
538 typedef typename Position<Matrix<TScoreValue, DIMENSION> >::Type TPosition;
539
540 // typedef Segment<TTargetSource, InfixSegment> TTargetSourceSegment;
541 typedef typename Iterator<TSourceH, Standard>::Type TSourceIteratorH;
542 typedef typename Iterator<TSourceV, Standard>::Type TSourceIteratorV;
543
544 typedef Gaps<TSourceH, TGapsSpecH> TGapsH;
545 typedef Gaps<TSourceV, TGapsSpecV> TGapsV;
546 typedef typename Iterator<TGapsH, Rooted>::Type TTargetIteratorH;
547 typedef typename Iterator<TGapsV, Rooted>::Type TTargetIteratorV;
548
549 //-------------------------------------------------------------------------
550 //variables
551 TPosition pos_0 = coordinate(source_, 0);
552 TPosition pos_1 = coordinate(source_, 1);
553
554 TSourceH strH = source(gapsH);
555 TSourceV strV = source(gapsV);
556
557 TTargetIteratorH target_0 = iter(gapsH, pos_0);
558 TTargetIteratorV target_1 = iter(gapsV, pos_1);
559
560 TSourceIteratorH it_0 = iter(strH, pos_0, Standard());
561 TSourceIteratorH it_0_end = end(strH);
562
563 TSourceIteratorV it_1 = iter(strV, pos_1, Standard());
564 TSourceIteratorV it_1_end = end(strV);
565
566 TScoreValue score_gap = scoreGapExtend(scoring_);
567
568 //-------------------------------------------------------------------------
569 //follow the trace until 0 is reached
570 while ((*source_!=0) && (it_0 != it_0_end) && (it_1 != it_1_end))
571 {
572 bool gv;
573 bool gh;
574 bool forbidden = fb_matrix[position(source_)];
575
576 if (*it_0 == *it_1 && !forbidden)
577 {
578 gv = gh = true;
579 }
580 else
581 {
582 TMatrixIterator it_ = source_;
583
584 goNext(it_, 0);
585 TScoreValue v = *it_ + score_gap;
586
587 TScoreValue d;
588 if(forbidden)
589 d = 0;
590 else{
591 goNext(it_, 1);
592 d = *it_ + score(scoring_, *it_0, *it_1);
593 }
594
595 it_ = source_;
596 goNext(it_, 1);
597 TScoreValue h = *it_ + score_gap;
598
599 gv = (v >= h) | (d >= h);
600 gh = (h > v) | (d >= v);
601 }
602
603 if (gv)
604 {
605 ++it_0;
606 goNext(source_, 0);
607 }
608 else
609 {
610 insertGap(target_0);
611 }
612
613 if (gh)
614 {
615 ++it_1;
616 goNext(source_, 1);
617 }
618 else
619 {
620 insertGap(target_1);
621 }
622 ++target_0;
623 ++target_1;
624 }
625
626 // We have removed all gaps and clippings from gapsH and gapsV in the calling functions, so the following works.
627 // Note that we have to set the end position first.
628 // TODO(holtgrew): Use setBegin/EndPosition().
629 setClippedEndPosition(gapsH, toViewPosition(gapsH, position(it_0, strH)));
630 setClippedEndPosition(gapsV, toViewPosition(gapsV, position(it_1, strV)));
631 setClippedBeginPosition(gapsH, toViewPosition(gapsH, pos_0));
632 setClippedBeginPosition(gapsV, toViewPosition(gapsV, pos_1));
633
634 return source_;
635 }
636
637 // ----------------------------------------------------------------------------
638 // Function _getNextBestEndPosition()
639 // ----------------------------------------------------------------------------
640
641 // Adjust the priority queue of scores until the true maximum is found.
642 template <typename TScoreValue>
643 typename LocalAlignmentFinder<TScoreValue>::TMatrixPosition
_getNextBestEndPosition(LocalAlignmentFinder<TScoreValue> & sw,TScoreValue cutoff)644 _getNextBestEndPosition(LocalAlignmentFinder<TScoreValue> & sw ,
645 TScoreValue cutoff)
646 {
647 // get maximal score from priority queue
648 TScoreValue topScore = 0;
649 if (!empty(sw.pQ))
650 topScore = getValue(sw.matrix, top(sw.pQ).id_);
651
652 // check if matrix entry of topScore did not change while declumping
653 if (!empty(sw.pQ)) {
654 while (top(sw.pQ).value_ != topScore) {
655 if (topScore >= cutoff) {
656 ((sw.pQ).heap[0]).value_ = topScore;
657 adjustTop(sw.pQ);
658 } else {
659 pop(sw.pQ);
660 }
661 if (!empty(sw.pQ)) topScore = getValue(sw.matrix, top(sw.pQ).id_);
662 else break;
663 }
664 }
665
666 // priority queue with top scores is empty
667 if(empty(sw.pQ)) {//||top(sw.pQ).value_<cutoff) {
668 sw.needReinit = true;
669 return 0;
670 }
671
672 typename LocalAlignmentFinder<TScoreValue>::TMatrixPosition ret_pos = top(sw.pQ).id_;
673 sw.bestEndPos = ret_pos;
674 pop(sw.pQ);
675
676 return ret_pos;
677 }
678
679 // ----------------------------------------------------------------------------
680 // Function _smithWaterman()
681 // ----------------------------------------------------------------------------
682
683 // Wrapper that computes the matrix and does the backtracking for the best alignment
684 template <typename TSourceH, typename TGapsSpecH,
685 typename TSourceV, typename TGapsSpecV,
686 typename TScoreValue, typename TScoreSpec>
687 TScoreValue
_smithWaterman(Gaps<TSourceH,TGapsSpecH> & gapsH,Gaps<TSourceV,TGapsSpecV> & gapsV,LocalAlignmentFinder<TScoreValue> & sw_finder,Score<TScoreValue,TScoreSpec> const & score_,TScoreValue cutoff)688 _smithWaterman(Gaps<TSourceH, TGapsSpecH> & gapsH,
689 Gaps<TSourceV, TGapsSpecV> & gapsV,
690 LocalAlignmentFinder<TScoreValue> & sw_finder,
691 Score<TScoreValue, TScoreSpec> const & score_,
692 TScoreValue cutoff)
693 {
694 // TODO(holtgrew): This sourceSegment() stuff is confusing... Do we *really* need this?
695 // Clear gaps and clipping from result Gaps structures.
696 clearGaps(gapsH);
697 clearGaps(gapsV);
698 clearClipping(gapsH);
699 clearClipping(gapsV);
700
701 _initLocalAlignmentFinder(sourceSegment(gapsH), sourceSegment(gapsV), sw_finder, WatermanEggert());
702
703 TScoreValue ret = _smithWatermanGetMatrix(sw_finder, sourceSegment(gapsH), sourceSegment(gapsV), score_,cutoff);
704
705 if(ret==0)
706 return ret;
707 sw_finder.needReinit = false;
708
709 typedef Iter<typename LocalAlignmentFinder<TScoreValue>::TMatrix,PositionIterator > TMatrixIterator;
710 TMatrixIterator best_begin;
711
712 // TODO(holtgrew): What does the following comment mean?
713 // TODO: sw_finder statt kram
714 best_begin = _smithWatermanTrace(gapsH, gapsV, sw_finder.forbidden,iter(sw_finder.matrix,(top(sw_finder.pQ)).id_), score_);
715
716 sw_finder.bestBeginPos = position(best_begin);
717
718 pop(sw_finder.pQ);
719
720 return ret;
721 }
722
723 // ----------------------------------------------------------------------------
724 // Function _smithWatermanGetNext()
725 // ----------------------------------------------------------------------------
726
727 // Wrapper that declumps the matrix and traces back the next best alignment
728 template <typename TSequenceH, typename TGapsSpecH, typename TSequenceV, typename TGapsSpecV, typename TScoreValue, typename TScoreSpec>
729 TScoreValue
_smithWatermanGetNext(Gaps<TSequenceH,TGapsSpecH> & gapsH,Gaps<TSequenceV,TGapsSpecV> & gapsV,LocalAlignmentFinder<TScoreValue> & sw_finder,Score<TScoreValue,TScoreSpec> const & score_,TScoreValue cutoff)730 _smithWatermanGetNext(Gaps<TSequenceH, TGapsSpecH> & gapsH,
731 Gaps<TSequenceV, TGapsSpecV> & gapsV,
732 LocalAlignmentFinder<TScoreValue> & sw_finder ,
733 Score<TScoreValue, TScoreSpec> const & score_,
734 TScoreValue cutoff)
735 {
736 _smithWatermanDeclump(sw_finder, gapsH, gapsV, score_);
737
738 clearGaps(gapsH);
739 clearGaps(gapsV);
740 clearClipping(gapsH);
741 clearClipping(gapsV);
742
743 typename LocalAlignmentFinder<TScoreValue>::TMatrixPosition next_best_end;
744 next_best_end = _getNextBestEndPosition(sw_finder,cutoff);
745 if(next_best_end==0)
746 return 0;
747 typename LocalAlignmentFinder<TScoreValue>::TMatrixIterator next_best_begin;
748 next_best_begin= _smithWatermanTrace(gapsH, gapsV, sw_finder.forbidden,iter(sw_finder.matrix,next_best_end), score_);
749 sw_finder.bestBeginPos = position(next_best_begin);
750
751 return getValue(sw_finder.matrix,next_best_end);
752 }
753
754 } // namespace seqan
755
756 #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_WATERMAN_EGGERT_IMPL_H_
757