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