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: Rene Rahn <rene.rahn@fu-berlin.de>
33 // ==========================================================================
34 // Implements the core of the dp algorithms.
35 // This is the crucial part of the refactoring of the alignment algorithms.
36 // It implements - at the moment only a column wise approach - the core
37 // loop structure for all alignment profiles. We generally differ between an
38 // unbanded alignment which is very easy, a banded alignment and a special
39 // case of the banded alignment the Hamming distance, where upper diagonal
40 // equals lower diagonal.
41 //
42 // The unbanded alignment:
43 // The computation of the unbanded alignment is divided into three parts.
44 // In the following we refer to a track as the part where the inner loop
45 // is iterating (in case of column wise navigation a track is equivalent
46 // to a column).
47 // First we compute the initial track. Afterwards we continue with all
48 // inner tracks of the dp matrix and in the end we compute the last track
49 // separately. This is because all three types have a special property that
50 // is different from the other track types.
51 // Each track itself is further divided into three parts, namely the first cell
52 // the inner cell and the last cell, corresponding to the initial row,
53 // all inner rows and the last row of a typical dp matrix. This partition of
54 // the dp matrix allows us to easily change the behavior of different cells
55 // according to the chosen dp profile at compile time.
56 // See alignment_dp_meta_info.h to learn about the different meta objects
57 // that manage the characteristics of each cell of a particular track type.
58 //
59 // The banded alignment:
60 // In the banded alignment we generally divide the dp matrix into the same
61 // partition as for the unbanded alignment. The only difference is that we,
62 // additionally add a specific information of how the current track is
63 // located within the dp matrix. Since we only consider a band we do not
64 // necessarily span over the full matrix size for a particular column.
65 // We distinguish between the locations: PartialColumnTop,
66 // PartialColumnMiddle, PartialColumnBottom and FullColumn (which is the
67 // default location for unbanded alignments). Each location of the column
68 // implies a different composition of the cells contained within a
69 // particular track. Thus, we are able to set different recursion
70 // directions and tracking informations for each cell independent from the
71 // runtime. The only difference is that the outer for-loop (iterating over
72 // the tracks) is split up into three loops. The first loop then only
73 // iterates over these tracks that are located at the top of the matrix.
74 // The second for-loop iterates over the tracks that either are of type
75 // PartialColumnMiddle or FullColumn (wide bands, where the upper diagonal
76 // begins behind the track where the lower diagonal crosses the last row of
77 // the dp matrix). And the last for-loop iterates over the tail of the band
78 // which is located at the PartialColumnBottom.
79 //
80 // The Hamming distance:
81 // In the special case where upper diagonal equals lower diagonal we only
82 // have to parse one diagonal of the matrix so we have a special
83 // implementation for that, though it works for all dp profiles.
84 //
85 // Restricitons:
86 // At the moment we have implemented a restriction such that not all bands
87 // are accepted. If the dp profile consists of the standard global alignment
88 // algorithm (NeedlemanWunsch or Gotoh), the band is required to go through
89 // the sink and the source of the dp matrix. If this is not given the
90 // alignment algorithm is aborted and the score std::numeric_limits<TScoreValue>::min()
91 // is returned.
92 // There are no further restrictions.
93 //
94 // GapCosts:
95 // Another detail of the new module is the selection of the gap functions,
96 // which is also now part of the compile time configuration. Whenever an
97 // algorithm is implemented it would automatically work for both gap
98 // functions (linear gaps and affine gaps).
99 //
100 // Navigation:
101 // It is possible to a certain degree to change the behavior of how to parse
102 // through the dp matrix. Using the new navigators one can implement
103 // different behaviors for different matrices. At the moment we only support
104 // column wise navigation for full and sparse score matrices and for full
105 // traceback matrices. Another detail of this navigators comes into account,
106 // when we want to compute only the score. We actually create a navigator
107 // for the dp matrix but implemented it this way that it gets never actually
108 // called when the traceback is disabled. Thus we do not store the traceback
109 // matrix if it is not necessary.
110 //
111 // Traceback:
112 // The traceback is now implemented as a single function that is used by all
113 // alignment profiles. Here we prefer the diagonal direction before the
114 // vertical before the horizontal direction.
115 // All tracebacks are first stored within the String<TraceSegment> object
116 // and afterwards, when the traceback is finished adapted to its given
117 // target object such as Align, Graph, Fragments, etc.
118 //
119 // Tracing:
120 // We use now an object called DPScout to keep track of the maximal score.
121 // This object scouts for the best value and can be overloaded to implement
122 // different strategies of how the score should be traced. Togehter with
123 // the meta_info file it only traces thus cells that are allowed to be
124 // traced given the current dp profile. Since this is also a compile time
125 // property we do not need to track every cell for the global alignment,
126 // while we do in the local alignment.
127 //
128 // Structure:
129 // The sequences within the matrix are marked as horizontal and vertical
130 // sequence to determine there orientation within the matrix.
131 // ==========================================================================
132 
133 #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_ALGORITHM_IMPL_H_
134 #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_ALGORITHM_IMPL_H_
135 
136 namespace seqan {
137 
138 // ============================================================================
139 // Forwards
140 // ============================================================================
141 
142 // ============================================================================
143 // Tags, Classes, Enums
144 // ============================================================================
145 
146 // ============================================================================
147 // Metafunctions
148 // ============================================================================
149 
150 // ============================================================================
151 // Functions
152 // ============================================================================
153 
154 // ----------------------------------------------------------------------------
155 // Function prepareAlign()
156 // ----------------------------------------------------------------------------
157 
158 template<typename TSequence, typename TAlignSpec>
159 inline void
prepareAlign(StringSet<Align<TSequence,TAlignSpec>> & align,TSequence const & strH,StringSet<TSequence> const & setV)160 prepareAlign(StringSet<Align<TSequence, TAlignSpec> > & align,
161              TSequence const & strH,
162              StringSet<TSequence> const & setV)
163 {
164     size_t numAlignments = length(setV);
165 
166     SEQAN_ASSERT_EQ(length(align), 0u);
167     SEQAN_ASSERT_GT(numAlignments, 0u);
168 
169     resize(align, numAlignments);
170     for(size_t i = 0; i < numAlignments; ++i)
171     {
172         resize(rows(align[i]), 2);
173         assignSource(row(align[i], 0), strH);
174         assignSource(row(align[i], 1), setV[i]);
175     }
176 }
177 
178 // ----------------------------------------------------------------------------
179 // Function _checkBandProperties()
180 // ----------------------------------------------------------------------------
181 
182 // Checks whether the chosen band fits the dp profile.
183 template <typename TSequenceH, typename TSequenceV, typename TAlignmentProfile>
_checkBandProperties(TSequenceH const &,TSequenceV const &,DPBandConfig<BandOff> const &,TAlignmentProfile const &)184 inline bool _checkBandProperties(TSequenceH const & /*seqH*/,
185                                  TSequenceV const & /*seqV*/,
186                                  DPBandConfig<BandOff> const & /*band*/,
187                                  TAlignmentProfile const & /*alignProfile*/)
188 {
189     return true;
190 }
191 
192 template <typename TSequenceH, typename TSequenceV, typename TAlignmentProfile>
_checkBandProperties(TSequenceH const & seqH,TSequenceV const & seqV,DPBandConfig<BandOn> const & band,TAlignmentProfile const &)193 inline bool _checkBandProperties(TSequenceH const & seqH,
194                                  TSequenceV const & seqV,
195                                  DPBandConfig<BandOn> const & band,
196                                  TAlignmentProfile const & /*alignProfile*/)
197 {
198     typedef typename MakeSigned<typename Size<TSequenceH>::Type>::Type TSignedSize;
199 
200     // Check if the intersection between band and DP matrix is empty.
201     if (upperDiagonal(band) < (0 - static_cast<TSignedSize>(length(seqV))) ||
202         lowerDiagonal(band) > static_cast<TSignedSize>(length(seqH)))
203     {
204         return false;
205     }
206 
207     // If the band begins before the beginning of the horizontal sequence
208     // then check if free end-gaps are enabled at the beginning of the vertical sequence.
209     if (upperDiagonal(band) < 0 && !IsFreeEndGap_<TAlignmentProfile, DPFirstColumn>::VALUE)
210         return false;
211 
212     // If the band begins before the beginning of the vertical sequence
213     // then check if free end-gaps are enabled at the beginning of the horizontal sequence.
214     if (lowerDiagonal(band) > 0 && !IsFreeEndGap_<TAlignmentProfile, DPFirstRow>::VALUE)
215         return false;
216 
217     // If the band ends behind the end of the vertical sequence
218     // then check if free end-gaps are enabled at the end of the horizontal sequence.
219     if (upperDiagonal(band) + static_cast<TSignedSize>(length(seqV)) < static_cast<TSignedSize>(length(seqH)) &&
220         !IsFreeEndGap_<TAlignmentProfile, DPLastRow>::VALUE)
221     {
222         return false;
223     }
224 
225     // If the band ends behind the end of the horizontal sequence
226     // then check if free end-gaps are enabled at the end of the vertical sequence.
227     if (lowerDiagonal(band) + static_cast<TSignedSize>(length(seqV)) > static_cast<TSignedSize>(length(seqH)) &&
228         !IsFreeEndGap_<TAlignmentProfile, DPLastColumn>::VALUE)
229     {
230         return false;
231     }
232 
233     return true;
234 }
235 
236 // ----------------------------------------------------------------------------
237 // Function _invalidDPSettings()
238 // ----------------------------------------------------------------------------
239 
240 
241 // Checks if the settings for the dp algorithm are valid.
242 // Returns true if they are valid, false otherwise.
243 template <typename TSequenceH, typename TSequenceV, typename TBand, typename TAlignmentProfile>
_isValidDPSettings(TSequenceH const & seqH,TSequenceV const & seqV,TBand const & band,TAlignmentProfile const & alignProfile)244 inline bool _isValidDPSettings(TSequenceH const & seqH,
245                                TSequenceV const & seqV,
246                                TBand const & band,
247                                TAlignmentProfile const & alignProfile)
248 {
249     // Check if the sequences are empty.
250     if (empty(seqH) || empty(seqV))
251     {
252         return false;
253     }
254 
255     return _checkBandProperties(seqH, seqV, band, alignProfile);
256 }
257 
258 // ----------------------------------------------------------------------------
259 // Function _isBandEnabled()
260 // ----------------------------------------------------------------------------
261 
262 // Returns true if a band is selected, otherwise false.
263 template <typename TBandSpec>
264 inline bool
_isBandEnabled(DPBandConfig<TBandSpec> const &)265 _isBandEnabled(DPBandConfig<TBandSpec> const & /*band*/)
266 {
267     return IsSameType<TBandSpec, BandOn>::VALUE;
268 }
269 
270 // ----------------------------------------------------------------------------
271 // Function _computeCell()
272 // ----------------------------------------------------------------------------
273 
274 // Computes the score and tracks it if enabled.
275 template <typename TDPScout,
276           typename TTraceMatrixNavigator,
277           typename TDPCell,
278           typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme, typename TColumnDescriptor,
279           typename TCellDescriptor, typename TDPProfile>
280 inline void
_computeCell(TDPScout & scout,TTraceMatrixNavigator & traceMatrixNavigator,TDPCell & current,TDPCell & diagonal,TDPCell const & horizontal,TDPCell & vertical,TSequenceHValue const & seqHVal,TSequenceVValue const & seqVVal,TScoringScheme const & scoringScheme,TColumnDescriptor const &,TCellDescriptor const &,TDPProfile const &)281 _computeCell(TDPScout & scout,
282              TTraceMatrixNavigator & traceMatrixNavigator,
283              TDPCell & current,
284              TDPCell & diagonal,
285              TDPCell const & horizontal,
286              TDPCell & vertical,
287              TSequenceHValue const & seqHVal,
288              TSequenceVValue const & seqVVal,
289              TScoringScheme const & scoringScheme,
290              TColumnDescriptor const &,
291              TCellDescriptor const &,   // One of FirstCell, InnerCell or LastCell.
292              TDPProfile const &)
293 {
294     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumn;
295 
296     assignValue(traceMatrixNavigator,
297                 _computeScore(current, diagonal, horizontal, vertical, seqHVal, seqVVal, scoringScheme,
298                               typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
299                               TDPProfile()));
300 
301     if (TrackingEnabled_<TMetaColumn, TCellDescriptor>::VALUE)
302     {
303         typedef typename LastColumnEnabled_<TDPProfile, TColumnDescriptor>::Type TIsLastColumn;
304         typedef typename LastRowEnabled_<TDPProfile, TCellDescriptor, TColumnDescriptor>::Type TIsLastRow;
305 
306         // TODO(rrahn): Refactor to set vertical score only when max is updated.
307         if (IsTracebackEnabled_<TDPProfile>::VALUE)
308         {
309             _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical));
310         }
311         _scoutBestScore(scout, current, traceMatrixNavigator,
312                         TIsLastColumn(), TIsLastRow());
313     }
314 }
315 
316 // ----------------------------------------------------------------------------
317 // Function _precomputeScoreMatrixOffset()
318 // ----------------------------------------------------------------------------
319 
320 // Default fallback if scoring scheme is not a matrix.
321 template <typename TSeqValue,
322           typename TScoringScheme>
323 inline TSeqValue const &
_precomputeScoreMatrixOffset(TSeqValue const & seqVal,TScoringScheme const &)324 _precomputeScoreMatrixOffset(TSeqValue const & seqVal,
325                              TScoringScheme const & /*score*/)
326 {
327     return seqVal;
328 }
329 
330 // ----------------------------------------------------------------------------
331 // Function _computeTrack()
332 // ----------------------------------------------------------------------------
333 
334 template <typename TDPScout,
335           typename TDPScoreMatrixNavigator,
336           typename TDPTraceMatrixNavigator,
337           typename TSeqHValue,
338           typename TSeqVValue,
339           typename TSeqVIterator,
340           typename TScoringScheme,
341           typename TDPCell,
342           typename TColumnDescriptor,
343           typename TDPProfile>
344 inline void
_computeTrack(TDPScout & scout,TDPScoreMatrixNavigator & dpScoreMatrixNavigator,TDPTraceMatrixNavigator & dpTraceMatrixNavigator,TSeqHValue const & seqHValue,TSeqVValue const & seqVValue,TSeqVIterator const & seqBegin,TSeqVIterator const & seqEnd,TScoringScheme const & scoringScheme,TDPCell & cacheDiag,TDPCell & cacheVert,TColumnDescriptor const &,TDPProfile const &)345 _computeTrack(TDPScout & scout,
346               TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
347               TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
348               TSeqHValue const & seqHValue,
349               TSeqVValue const & seqVValue,
350               TSeqVIterator const & seqBegin,
351               TSeqVIterator const & seqEnd,
352               TScoringScheme const & scoringScheme,
353               TDPCell & cacheDiag,
354               TDPCell & cacheVert,
355               TColumnDescriptor const &,
356               TDPProfile const &)
357 {
358     _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), FirstCell());
359     _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), FirstCell());
360 
361     _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, TColumnDescriptor());
362 
363     // Precompute the row of the scoring matrix for future look-ups.
364     TSeqHValue tmpSeqH = _precomputeScoreMatrixOffset(seqHValue, scoringScheme);
365 
366     // Initilaize SIMD version with multiple end points.
367     _preInitScoutVertical(scout);
368 
369     // Compute the first cell.
370     _computeCell(scout,
371                  dpTraceMatrixNavigator,
372                  value(dpScoreMatrixNavigator),
373                            cacheDiag,
374                            previousCellHorizontal(dpScoreMatrixNavigator),
375                            cacheVert,
376                  tmpSeqH,
377                  seqVValue,
378                  scoringScheme,
379                  TColumnDescriptor(), FirstCell(), TDPProfile());
380 
381     TSeqVIterator iter = seqBegin;
382     for (; iter != seqEnd - 1; ++iter)
383     {
384         _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), InnerCell());
385         _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), InnerCell());
386 
387         _incVerticalPos(scout);
388         // Compute the inner cell.
389         if (SEQAN_UNLIKELY(_reachedVerticalEndPoint(scout, iter)))
390         {
391             _computeCell(scout,
392                          dpTraceMatrixNavigator,
393                          value(dpScoreMatrixNavigator),
394                          cacheDiag,
395                          previousCellHorizontal(dpScoreMatrixNavigator),
396                          cacheVert,
397                          tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
398                          scoringScheme, TColumnDescriptor(), LastCell(), TDPProfile());
399             _nextVerticalEndPos(scout);
400         }
401         else
402         {
403             _computeCell(scout,
404                          dpTraceMatrixNavigator,
405                          value(dpScoreMatrixNavigator),
406                          cacheDiag,
407                          previousCellHorizontal(dpScoreMatrixNavigator),
408                          cacheVert,
409                          tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
410                          scoringScheme, TColumnDescriptor(), InnerCell(), TDPProfile());
411         }
412     }
413     _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), LastCell());
414     _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), LastCell());
415     _incVerticalPos(scout);
416     _computeCell(scout,
417                  dpTraceMatrixNavigator,
418                  value(dpScoreMatrixNavigator),
419                            cacheDiag,
420                            previousCellHorizontal(dpScoreMatrixNavigator),
421                            cacheVert,
422                  tmpSeqH,
423                  sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
424                  scoringScheme,
425                  TColumnDescriptor(), LastCell(), TDPProfile());
426 }
427 
428 template <typename TDPScout,
429           typename TDPScoreMatrixNavigator,
430           typename TDPTraceMatrixNavigator,
431           typename TSeqHValue,
432           typename TSeqVValue,
433           typename TSeqVIterator,
434           typename TScoringScheme,
435           typename TColumnDescriptor,
436           typename TDPProfile>
437 inline void
_computeTrack(TDPScout & scout,TDPScoreMatrixNavigator & dpScoreMatrixNavigator,TDPTraceMatrixNavigator & dpTraceMatrixNavigator,TSeqHValue const & seqHValue,TSeqVValue const & seqVValue,TSeqVIterator const & seqBegin,TSeqVIterator const & seqEnd,TScoringScheme const & scoringScheme,TColumnDescriptor const &,TDPProfile const &)438 _computeTrack(TDPScout & scout,
439               TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
440               TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
441               TSeqHValue const & seqHValue,
442               TSeqVValue const & seqVValue,
443               TSeqVIterator const & seqBegin,
444               TSeqVIterator const & seqEnd,
445               TScoringScheme const & scoringScheme,
446               TColumnDescriptor const &,
447               TDPProfile const &)
448 {
449     using TDPCell = std::decay_t<decltype(value(dpScoreMatrixNavigator))>;
450 
451     TDPCell cacheDiag;
452     TDPCell cacheVert;
453     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqHValue, seqVValue, seqBegin, seqEnd,
454                   scoringScheme, cacheDiag, cacheVert, TColumnDescriptor{}, TDPProfile{});
455 }
456 
457 // ----------------------------------------------------------------------------
458 // Function _computeUnbandedAlignmentHelperTerminate()
459 // ----------------------------------------------------------------------------
460 
461 template <typename TDPCell, typename TSpec>
462 inline bool //TODO(C++11) constexpr
_computeAlignmentHelperCheckTerminate(DPScout_<TDPCell,TSpec> const &)463 _computeAlignmentHelperCheckTerminate(DPScout_<TDPCell, TSpec > const & /**/)
464 {
465     return false;
466 }
467 
468 template <typename TDPCell, typename TSpec>
469 inline bool
_computeAlignmentHelperCheckTerminate(DPScout_<TDPCell,Terminator_<TSpec>> const & s)470 _computeAlignmentHelperCheckTerminate(DPScout_<TDPCell,Terminator_<TSpec> > const & s)
471 {
472     return _terminationCriteriumIsMet(s);
473 }
474 
475 // ----------------------------------------------------------------------------
476 // Function _computeUnbandedAlignment()
477 // ----------------------------------------------------------------------------
478 
479 // Computes the standard DP-algorithm.
480 template <typename TDPScout,
481           typename TDPScoreMatrixNavigator,
482           typename TDPTraceMatrixNavigator,
483           typename TSequenceH,
484           typename TSequenceV,
485           typename TScoringScheme,
486           typename TBand,
487           typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
488 inline void
_computeAlignmentImpl(TDPScout & scout,TDPScoreMatrixNavigator & dpScoreMatrixNavigator,TDPTraceMatrixNavigator & dpTraceMatrixNavigator,TSequenceH const & seqH,TSequenceV const & seqV,TScoringScheme const & scoringScheme,TBand const &,DPProfile_<TAlignmentAlgo,TGapCosts,TTraceFlag,TExecPolicy> const & dpProfile,NavigateColumnWise const &)489 _computeAlignmentImpl(TDPScout & scout,
490                       TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
491                       TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
492                       TSequenceH const & seqH,
493                       TSequenceV const & seqV,
494                       TScoringScheme const & scoringScheme,
495                       TBand const & /*band*/,
496                       DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const & dpProfile,
497                       NavigateColumnWise const & /*tag*/)
498 {
499     typedef typename Iterator<TSequenceH const, Rooted>::Type TConstSeqHIterator;
500     typedef typename Iterator<TSequenceV const, Rooted>::Type TConstSeqVIterator;
501 
502     // Initilaize SIMD version with multiple end points.
503     _preInitScoutHorizontal(scout);
504 
505     // ============================================================================
506     // PREPROCESSING
507     // ============================================================================
508 
509     TConstSeqVIterator seqVBegin = begin(seqV, Rooted());
510     TConstSeqVIterator seqVEnd = end(seqV, Rooted());
511 
512     SEQAN_ASSERT_GT(length(seqH), 0u);
513     SEQAN_ASSERT_GT(length(seqV), 0u);
514 
515     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
516                   sequenceEntryForScore(scoringScheme, seqH, 0),
517                   sequenceEntryForScore(scoringScheme, seqV, 0),
518                   seqVBegin, seqVEnd, scoringScheme,
519                   MetaColumnDescriptor<DPInitialColumn, FullColumn>(), dpProfile);
520 
521     // ============================================================================
522     // MAIN DP
523     // ============================================================================
524 
525     TConstSeqHIterator seqHIter = begin(seqH, Rooted());
526     TConstSeqHIterator seqHIterEnd = end(seqH, Rooted()) - 1;
527     for (; seqHIter != seqHIterEnd; ++seqHIter)
528     {
529         _incHorizontalPos(scout);
530         // We might only select it if SIMD version is available.
531         if (SEQAN_UNLIKELY(_reachedHorizontalEndPoint(scout, seqHIter)))
532         {
533             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
534                           sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
535                           sequenceEntryForScore(scoringScheme, seqV, 0),
536                           seqVBegin, seqVEnd, scoringScheme,
537                           MetaColumnDescriptor<DPFinalColumn, FullColumn>(), dpProfile);
538             _nextHorizontalEndPos(scout);
539         }
540         else
541         {
542             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
543                           sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
544                           sequenceEntryForScore(scoringScheme, seqV, 0),
545                           seqVBegin, seqVEnd, scoringScheme,
546                           MetaColumnDescriptor<DPInnerColumn, FullColumn>(), dpProfile);
547         }
548         if (_computeAlignmentHelperCheckTerminate(scout))
549         {
550             return;
551         }
552     }
553 
554     // ============================================================================
555     // POSTPROCESSING
556     // ============================================================================
557 
558     _incHorizontalPos(scout);
559     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
560                   sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
561                   sequenceEntryForScore(scoringScheme, seqV, 0),
562                   seqVBegin, seqVEnd, scoringScheme,
563                   MetaColumnDescriptor<DPFinalColumn, FullColumn>(), dpProfile);
564 
565     // If we compute only the single option. we need to check if there are other possibilities at the end.
566     // Traceback only from Diagonal, but could also come from vertical or horizontal.
567 
568 //    for (unsigned i = 0; i < length(recMatrix); ++i)
569 //    {
570 //        std::cout << recMatrix[i]._score << "\t";
571 //    }
572 //    std::cout << std::endl;
573 }
574 
575 // ----------------------------------------------------------------------------
576 // Function _computeAlignment() banded
577 // ----------------------------------------------------------------------------
578 
579 // Computes the banded DP-algorithm.
580 template <typename TDPScout,
581           typename TDPScoreMatrixNavigator,
582           typename TDPTraceMatrixNavigator,
583           typename TSequenceH,
584           typename TSequenceV,
585           typename TScoringScheme,
586           typename TBand,
587           typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
588 inline void
_computeAlignmentImpl(TDPScout & scout,TDPScoreMatrixNavigator & dpScoreMatrixNavigator,TDPTraceMatrixNavigator & dpTraceMatrixNavigator,TSequenceH const & seqH,TSequenceV const & seqV,TScoringScheme const & scoringScheme,TBand const & band,DPProfile_<TAlignmentAlgo,TGapCosts,TTraceFlag,TExecPolicy> const & dpProfile,NavigateColumnWiseBanded const &)589 _computeAlignmentImpl(TDPScout & scout,
590                       TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
591                       TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
592                       TSequenceH const & seqH,
593                       TSequenceV const & seqV,
594                       TScoringScheme const & scoringScheme,
595                       TBand const & band,
596                       DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const & dpProfile,
597                       NavigateColumnWiseBanded const & /*tag*/)
598 {
599     typedef DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> TDPProfile;
600     typedef typename MakeSigned<typename Size<TSequenceH>::Type>::Type TSignedSizeSeqH;
601     typedef typename MakeSigned<typename Size<TSequenceV>::Type>::Type TSignedSizeSeqV;
602     typedef typename Iterator<TSequenceH const, Rooted>::Type TConstSeqHIterator;
603     typedef typename Iterator<TSequenceV const, Rooted>::Type TConstSeqVIterator;
604 
605     using TDPScoreValue = std::decay_t<decltype(value(dpScoreMatrixNavigator))>;
606     // Caching these cells improves performance significantly.
607     TDPScoreValue cacheDiag;
608     TDPScoreValue cacheVert;
609 
610     if (upperDiagonal(band) == lowerDiagonal(band))
611     {
612         _computeHammingDistance(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoringScheme, band,
613                                 dpProfile);
614         return;
615     }
616     // Now we have the problem of not knowing when we are in the last cell.
617 
618     // ============================================================================
619     // PREPROCESSING
620     // ============================================================================
621     TSignedSizeSeqH seqHlength = static_cast<TSignedSizeSeqH>(length(seqH));
622     TSignedSizeSeqH seqVlength = static_cast<TSignedSizeSeqV>(length(seqV));
623 
624     TConstSeqVIterator seqVBegin = begin(seqV, Rooted()) - _min(0, 1 + upperDiagonal(band));
625     TConstSeqVIterator seqVEnd = begin(seqV, Rooted()) - _min(0, _max(-seqVlength, lowerDiagonal(band)));
626 
627     // We have to distinguish two band sizes. Some which spans the whole matrix in between and thus who not.
628     // This can be distinguished, if UpperDiagonal > length(seqV) + LowerDiagonal
629 
630     // We start at least at the first position of the horizontal sequence or wherever the lower diagonal begins first.
631     TConstSeqHIterator seqHIterBegin = begin(seqH, Rooted()) + _max(0, _min(seqHlength - 1, lowerDiagonal(band)));
632 
633     // The horizontal initial phase ends after the upper diagonal but at most after the horizontal sequence, or there is no horizontal initialization phase.
634     TConstSeqHIterator seqHIterEndColumnTop = begin(seqH, Rooted()) + _min(seqHlength - 1, _max(0, upperDiagonal(band)));
635 
636     // The middle band phase ends after the lower diagonal crosses the bottom of the alignment matrix or after the horizontal sequence if it is smaller.
637     TConstSeqHIterator seqHIterEndColumnMiddle = begin(seqH, Rooted()) + _min(seqHlength - 1, _max(0, seqVlength + lowerDiagonal(band)));
638     // Swap the two iterators if we are in a band that spans over the full column.
639     if (upperDiagonal(band) > seqVlength + lowerDiagonal(band))
640         std::swap(seqHIterEndColumnTop, seqHIterEndColumnMiddle);
641 
642     // The bottom band phase ends after the upper diagonal of the band crosses the bottom of the matrix or after the horizontal sequence if it is smaller.
643     TConstSeqHIterator seqHIterEndColumnBottom = begin(seqH, Rooted()) + _max(0, _min(seqHlength,
644                                                                                       upperDiagonal(band) + seqVlength) - 1);
645 
646     // The Initial column can be PartialColumnTop which is given if the upper diagonal is >= 0,
647     // otherwise it only can be PartialColumnMiddle or PartialColumnBottom depending where the lower diagonal is.
648 
649     // Check for single initialization cells in InitialColumn and FinalColumn.
650     if (seqHIterBegin == end(seqH, Rooted()) - 1)
651     {
652         // Set the iterator to the begin of the track.
653         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
654         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
655         // Only one cell
656         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
657                      cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
658                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)),
659                      sequenceEntryForScore(scoringScheme, seqV, 0), scoringScheme,
660                      MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
661         // we might need to additionally track this point.
662         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop> >, FirstCell>::VALUE)
663             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), False());
664         return;
665     }
666     if (seqHIterEndColumnBottom == begin(seqH, Rooted()))
667     {
668         // Set the iterator to the begin of the track.
669         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
670         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
671         // Only one cell
672         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
673                      cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
674                      sequenceEntryForScore(scoringScheme, seqH, 0),
675                      sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)), scoringScheme,
676                      MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
677         // We might need to additionally track this point.
678         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> >, LastCell>::VALUE)
679             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True());
680         return;
681     }
682 
683     if (upperDiagonal(band) < 0)
684     {
685         ++seqVBegin;
686         if (lowerDiagonal(band) > -seqVlength)
687             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
688                           sequenceEntryForScore(scoringScheme, seqH, 0),
689                           sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
690                           seqVBegin, seqVEnd, scoringScheme,
691                           MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), dpProfile);
692         else
693             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
694                           sequenceEntryForScore(scoringScheme, seqH, 0),
695                           sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
696                           seqVBegin, seqVEnd, scoringScheme,
697                           MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), dpProfile);
698     }
699     else if (lowerDiagonal(band) >= 0)
700     {
701         // Set the iterator to the begin of the track.
702         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
703         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
704         //TODO(rrahn): We possibly need to set the cache values here?
705         // Should we not just compute the cell?
706         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
707                      cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
708                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)),
709                      sequenceEntryForScore(scoringScheme, seqV, 0),
710                      scoringScheme,
711                      MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
712         // we might need to additionally track this point.
713         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop> >, FirstCell>::VALUE)
714             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), False());
715     }
716     else  // Upper diagonal >= 0 and lower Diagonal < 0
717     {
718         if (lowerDiagonal(band) <= -seqVlength)      // The band is bounded by the top and bottom of the matrix.
719         {
720             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
721                           sequenceEntryForScore(scoringScheme, seqH, 0),
722                           sequenceEntryForScore(scoringScheme, seqV, 0),
723                           seqVBegin, seqVEnd, scoringScheme,
724                           MetaColumnDescriptor<DPInitialColumn, FullColumn>(), dpProfile);
725         }
726         else       // The band is bounded by the top but not the bottom of the matrix.
727         {
728             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
729                           sequenceEntryForScore(scoringScheme, seqH, 0),
730                           sequenceEntryForScore(scoringScheme, seqV, 0),
731                           seqVBegin, seqVEnd, scoringScheme,
732                           MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), dpProfile);
733         }
734     }
735     if (_computeAlignmentHelperCheckTerminate(scout))
736     {
737             return;
738     }
739 
740     // ============================================================================
741     // MAIN DP
742     // ============================================================================
743 
744     TConstSeqHIterator seqHIter = seqHIterBegin;
745     // Compute the first part of the band, where the band is bounded by the top but not by the bottom of the matrix.
746     for (; seqHIter != seqHIterEndColumnTop; ++seqHIter)
747     {
748         ++seqVEnd;
749         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
750                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
751                       sequenceEntryForScore(scoringScheme, seqV, 0),
752                       seqVBegin, seqVEnd, scoringScheme,
753                       MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), dpProfile);
754         if (_computeAlignmentHelperCheckTerminate(scout))
755         {
756                 return;
757         }
758     }
759 
760     // TODO(rmaerker): Check if putting the if-statement before the actual algorithm can speedup the code.
761     // Check whether the band spans over the full column or not at some point.
762     if (upperDiagonal(band) > seqVlength + lowerDiagonal(band))
763     {
764         // Compute the second part of the band, where the band is bounded by the top and the bottom of the matrix.
765         // We might want to track the current cell here, since this is the first cell that crosses the bottom but is
766         // not part of the FullColumn tracks.
767         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >, LastCell>::VALUE)
768             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True());
769         for (; seqHIter != seqHIterEndColumnMiddle; ++seqHIter)
770         {
771             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
772                           sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
773                           sequenceEntryForScore(scoringScheme, seqV, 0),
774                           seqVBegin, seqVEnd, scoringScheme,
775                           MetaColumnDescriptor<DPInnerColumn, FullColumn>(), dpProfile);
776 
777             if (_computeAlignmentHelperCheckTerminate(scout))
778             {
779                     return;
780             }
781         }
782     }
783     else  // Compute the second part of the band, where the band is not bounded by the top and bottom of the matrix
784     {
785         for (; seqHIter != seqHIterEndColumnMiddle; ++seqHIter)
786         {
787             ++seqVBegin;
788             ++seqVEnd;
789             _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
790                           sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
791                           sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
792                           seqVBegin, seqVEnd, scoringScheme,
793                           MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), dpProfile);
794             if (_computeAlignmentHelperCheckTerminate(scout))
795             {
796                     return;
797             }
798         }   // We might want to track the current cell here, since this is the first cell that crosses the bottom.
799         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom> >, LastCell>::VALUE)
800         {
801             if (lowerDiagonal(band) + seqVlength < seqHlength)
802             {
803                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True());
804             }
805         }
806 
807     }
808     // Compute the third part of the band, where the band, is bounded by the bottom but not by the top of the matrix.
809     for (; seqHIter != seqHIterEndColumnBottom; ++seqHIter)
810     {
811         ++seqVBegin;
812         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
813                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
814                       sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
815                       seqVBegin, seqVEnd, scoringScheme,
816                       MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), dpProfile);
817         if (_computeAlignmentHelperCheckTerminate(scout))
818         {
819                 return;
820         }
821     }
822 
823     // ============================================================================
824     // POSTPROCESSING
825     // ============================================================================
826 
827     // Check where the last track of the column is located.
828     if (seqHIter - begin(seqH, Rooted()) < seqHlength - 1)  // Case 1: The band ends before the final column is reached.
829     {
830         // Set the iterator to the begin of the track.
831         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
832         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
833 
834         _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>());
835 
836         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
837                      cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
838                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
839                      sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)),
840                      scoringScheme,
841                      MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
842         // We might need to additionally track this point.
843         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom> >, LastCell>::VALUE)
844         {
845             _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
846             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True());
847         }
848     }
849     else if (seqHIter == end(seqH, Rooted()) - 1) // Case 2: The band ends somewhere in the final column of the matrix.
850     {
851         // Case2a: The band ends in the last cell of the final column.
852         if (upperDiagonal(band) == seqHlength - seqVlength)
853         {
854             // Set the iterator to the begin of the track.
855             _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
856             _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
857 
858             _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>());
859 
860             _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
861                          cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
862                          sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
863                          sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)),
864                          scoringScheme,
865                          MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
866             // we might need to additionally track this point.
867             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
868             {
869                 _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
870                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
871             }
872         }
873         else  // Case2b: At least two cells intersect between the band and the matrix in the final column of the matrix.
874         {
875             if (upperDiagonal(band) >= seqHlength)  // The band is bounded by the top of the matrix only or by the top and the bottom.
876             {
877                 if (lowerDiagonal(band) + seqVlength > seqHlength) // The band is bounded by the top of the matrix
878                 {
879                     ++seqVEnd;
880                     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
881                                   sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
882                                   sequenceEntryForScore(scoringScheme, seqV, 0),
883                                   seqVBegin, seqVEnd, scoringScheme,
884                                   MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), dpProfile);
885                 }
886                 else  // The band is bounded by the top and the bottom of the matrix.
887                 {
888                     if (lowerDiagonal(band) + seqVlength + 1 > seqHlength)  // We have to go into the last cell.
889                     {
890                         ++seqVEnd;
891                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
892                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
893                                       sequenceEntryForScore(scoringScheme, seqV, 0),
894                                       seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert,
895                                       MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), dpProfile);
896                         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, LastCell>::VALUE)
897                         {
898                             _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
899                             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
900                         }
901                     }
902                     else
903                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
904                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
905                                       sequenceEntryForScore(scoringScheme, seqV, 0),
906                                       seqVBegin, seqVEnd, scoringScheme,
907                                       MetaColumnDescriptor<DPFinalColumn, FullColumn>(), dpProfile);
908                 }
909 
910             }
911             else  // The band is bounded by bottom of matrix or completely unbounded.
912             {
913                 ++seqVBegin;
914                 if (lowerDiagonal(band) + seqVlength <= seqHlength)  // The band is bounded by the bottom of the matrix.
915                 {
916                     if (lowerDiagonal(band) + seqVlength == seqHlength)  // We have to go into the last cell.
917                     {
918                         ++seqVEnd;
919                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
920                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
921                                       sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
922                                       seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert,
923                                       MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile);
924                         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
925                         {
926                             _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
927                             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
928                         }
929                     }
930                     else
931                     {
932                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
933                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
934                                       sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
935                                       seqVBegin, seqVEnd, scoringScheme,
936                                       MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), dpProfile);
937                     }
938                 }
939                 else  // The band is unbounded by the matrix.
940                 {
941                     ++seqVEnd;
942                     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
943                                   sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
944                                   sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
945                                   seqVBegin, seqVEnd, scoringScheme,
946                                   MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile);
947                 }
948             }
949         }
950     }
951 }
952 
953 // ----------------------------------------------------------------------------
954 // Function _computeHammingDistance()
955 // ----------------------------------------------------------------------------
956 
957 // Computes the Hamming-Distance if the band-size is 1.
958 template <typename TDPScout,
959           typename TDPScoreMatrixNavigator,
960           typename TDPTraceMatrixNavigator,
961           typename TSequenceH,
962           typename TSequenceV,
963           typename TScoringScheme,
964           typename TBand,
965           typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
966 inline void
_computeHammingDistance(TDPScout & scout,TDPScoreMatrixNavigator & dpScoreMatrixNavigator,TDPTraceMatrixNavigator & dpTraceMatrixNavigator,TSequenceH const & seqH,TSequenceV const & seqV,TScoringScheme const & scoringScheme,TBand const & band,DPProfile_<TAlignmentAlgo,TGapCosts,TTraceFlag,TExecPolicy> const &)967 _computeHammingDistance(TDPScout & scout,
968                         TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
969                         TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
970                         TSequenceH const & seqH,
971                         TSequenceV const & seqV,
972                         TScoringScheme const & scoringScheme,
973                         TBand const & band,
974                         DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const &)
975 {
976     typedef typename MakeSigned<typename Size<TSequenceH const>::Type>::Type TSignedSizeSeqH;
977     typedef typename MakeSigned<typename Size<TSequenceV const>::Type>::Type TSignedSizeSeqV;
978     typedef typename Iterator<TSequenceH const, Rooted>::Type TConstSeqHIterator;
979     typedef typename Iterator<TSequenceV const, Rooted>::Type TConstSeqVIterator;
980     typedef typename Value<TDPScoreMatrixNavigator>::Type TDPCell;
981     typedef DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> TDPProfile;
982 
983     // ============================================================================
984     // PREPROCESSING
985     // ============================================================================
986 
987     TSignedSizeSeqH seqHlength = static_cast<TSignedSizeSeqH>(length(seqH));
988     TSignedSizeSeqH seqVlength = static_cast<TSignedSizeSeqV>(length(seqV));
989 
990     TConstSeqHIterator itH = begin(seqH, Rooted()) + _max(0, _min(seqHlength - 1, upperDiagonal(band)));
991     TConstSeqHIterator itHEnd = begin(seqH, Rooted()) + _min(seqHlength - 1, upperDiagonal(band) + seqVlength);
992 
993     TConstSeqVIterator itV = begin(seqV, Rooted()) + _max(0, _min(seqVlength - 1, -lowerDiagonal(band)));
994     TConstSeqVIterator itVEnd = begin(seqV, Rooted()) + _min(seqVlength - 1, lowerDiagonal(band) + seqHlength);
995 
996     TDPCell dummy;
997     assignValue(dpTraceMatrixNavigator,
998                 _computeScore(value(dpScoreMatrixNavigator), dummy, dummy, dummy,
999                               sequenceEntryForScore(scoringScheme, seqH, position(itH)),
1000                               sequenceEntryForScore(scoringScheme, seqV, position(itV)),
1001                               scoringScheme, RecursionDirectionZero(), TDPProfile()));
1002 
1003     if (upperDiagonal(band) < 0)
1004     {
1005         if (upperDiagonal(band) == -seqVlength)
1006         {
1007             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, FullColumn> >, LastCell>::VALUE)
1008                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1009             return;
1010         }
1011         else
1012         {
1013             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, FullColumn> >, InnerCell>::VALUE)
1014                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1015         }
1016     }
1017     else if (lowerDiagonal(band) > 0)
1018     {
1019         if (lowerDiagonal(band) == seqHlength)
1020         {
1021             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, FirstCell>::VALUE)
1022                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1023             return;
1024         }
1025         else
1026         {
1027             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >, FirstCell>::VALUE)
1028                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1029         }
1030     }
1031     else
1032     {
1033         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, FullColumn> >, FirstCell>::VALUE)
1034             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1035     }
1036 
1037     TDPCell prevDiagonal = value(dpScoreMatrixNavigator);
1038 
1039     // ============================================================================
1040     // MAIN DP
1041     // ============================================================================
1042 
1043     while (itH != itHEnd && itV != itVEnd)
1044     {
1045         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
1046         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
1047         assignValue(dpTraceMatrixNavigator,
1048                     _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy,
1049                                   sequenceEntryForScore(scoringScheme, seqH, position(itH)),
1050                                   sequenceEntryForScore(scoringScheme, seqV, position(itV)),
1051                                   scoringScheme, RecursionDirectionDiagonal(), TDPProfile()));
1052         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >, InnerCell>::VALUE)
1053             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1054         prevDiagonal = value(dpScoreMatrixNavigator);
1055         ++itH;
1056         ++itV;
1057     }
1058 
1059     // ============================================================================
1060     // POSTPROCESSING
1061     // ============================================================================
1062 
1063     _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
1064     _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
1065 
1066     assignValue(dpTraceMatrixNavigator,
1067                 _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy,
1068                               sequenceEntryForScore(scoringScheme, seqH, position(itH)),
1069                               sequenceEntryForScore(scoringScheme, seqV, position(itV)),
1070                               scoringScheme, RecursionDirectionDiagonal(), TDPProfile()));
1071 
1072     if (itH == itHEnd)
1073     {
1074         if (itV == itVEnd)   // Is in the last cell of final column
1075         {
1076             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, LastCell>::VALUE)
1077                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1078         }
1079         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >, LastCell>::VALUE)
1080             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1081     }
1082     else
1083     {
1084         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, InnerCell>::VALUE)
1085             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator);
1086     }
1087 }
1088 
1089 // ----------------------------------------------------------------------------
1090 // Function _printScoreMatrix()
1091 // ----------------------------------------------------------------------------
1092 
1093 template <typename TTraceMatrix>
_printScoreMatrix(TTraceMatrix & scoreMatrix)1094 void _printScoreMatrix(TTraceMatrix & scoreMatrix)
1095 {
1096     typedef typename Size<TTraceMatrix>::Type TSize;
1097     TSize dimH = length(scoreMatrix, +DPMatrixDimension_::HORIZONTAL);
1098     TSize dimV = length(scoreMatrix, +DPMatrixDimension_::VERTICAL);
1099 
1100     for (unsigned row = 0; row < dimV; ++row)
1101     {
1102         for (unsigned column = 0; column < dimH; ++column)
1103             if (_scoreOfCell(value(scoreMatrix, row + column * dimV)) <= DPCellDefaultInfinity<DPCell_<int, LinearGaps>>::VALUE)
1104                 std::cout << "-∞\t";
1105             else
1106                 std::cout << _scoreOfCell(value(scoreMatrix, row + column * dimV)) << "\t";
1107         std::cout << std::endl;
1108     }
1109     std::cout << std::endl;
1110 }
1111 
1112 // ----------------------------------------------------------------------------
1113 // Function _printTracebackMatrix()
1114 // ----------------------------------------------------------------------------
1115 
1116 template <typename TTraceMatrix>
_printTracebackMatrix(TTraceMatrix & dpTraceMatrix)1117 void _printTracebackMatrix(TTraceMatrix & dpTraceMatrix)
1118 {
1119     typedef typename Size<TTraceMatrix>::Type TSize;
1120     TSize dimH = length(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL);
1121     TSize dimV = length(dpTraceMatrix, +DPMatrixDimension_::VERTICAL);
1122 
1123     for (unsigned row = 0; row < dimV; ++row)
1124     {
1125         for (unsigned column = 0; column < dimH; ++column)
1126             std::cout << _translateTraceValue(value(dpTraceMatrix, row + column * dimV)) << "\t";
1127         std::cout << std::endl;
1128     }
1129     std::cout << std::endl;
1130 }
1131 
1132 template <typename TTraceMatrix, typename TPosition>
_printTracebackMatrix(TTraceMatrix & dpTraceMatrix,TPosition const simdLane)1133 void _printTracebackMatrix(TTraceMatrix & dpTraceMatrix, TPosition const simdLane)
1134 {
1135     typedef typename Size<TTraceMatrix>::Type TSize;
1136     TSize dimH = length(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL);
1137     TSize dimV = length(dpTraceMatrix, +DPMatrixDimension_::VERTICAL);
1138 
1139     for (unsigned row = 0; row < dimV; ++row)
1140     {
1141         for (unsigned column = 0; column < dimH; ++column)
1142             std::cout << _translateTraceValue(value(dpTraceMatrix, row + column * dimV)[simdLane]) << "\t";
1143         std::cout << std::endl;
1144     }
1145     std::cout << std::endl;
1146 }
1147 
1148 // ----------------------------------------------------------------------------
1149 // Function _correctTraceValue()
1150 // ----------------------------------------------------------------------------
1151 
1152 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue>>>,void)1153 inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, void)
1154 _correctTraceValue(TTraceNavigator &,
1155                    DPScout_<DPCell_<TScoreValue, LinearGaps>, TDPScoutSpec> const &)
1156 {
1157     // Nothing to do.
1158 }
1159 
1160 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue>>,void)1161 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, void)
1162 _correctTraceValue(TTraceNavigator &,
1163                    DPScout_<DPCell_<TScoreValue, LinearGaps>, TDPScoutSpec> const &)
1164 {
1165     // Nothing to do.
1166 }
1167 
1168 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue>>>,void)1169 inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, void)
1170 _correctTraceValue(TTraceNavigator & traceNavigator,
1171                    DPScout_<DPCell_<TScoreValue, AffineGaps>, TDPScoutSpec>  const & dpScout)
1172 {
1173     _setToPosition(traceNavigator, maxHostPosition(dpScout));
1174 
1175     if (_verticalScoreOfCell(dpScout._maxScore) == _scoreOfCell(dpScout._maxScore))
1176     {
1177         value(traceNavigator) &= ~TraceBitMap_<TScoreValue>::DIAGONAL;
1178         value(traceNavigator) |= TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
1179     }
1180     else if (_horizontalScoreOfCell(dpScout._maxScore) == _scoreOfCell(dpScout._maxScore))
1181     {
1182         value(traceNavigator) &= ~TraceBitMap_<TScoreValue>::DIAGONAL;
1183         value(traceNavigator) |= TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
1184     }
1185 }
1186 
1187 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue>>,void)1188 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, void)
1189 _correctTraceValue(TTraceNavigator & traceNavigator,
1190                    DPScout_<DPCell_<TScoreValue, AffineGaps>, TDPScoutSpec>  const & dpScout)
1191 {
1192     using TMaskType = typename SimdMaskVector<TScoreValue>::Type;
1193     _setToPosition(traceNavigator, toGlobalPosition(traceNavigator,
1194                                                     maxHostCoordinate(dpScout, +DPMatrixDimension_::HORIZONTAL),
1195                                                     maxHostCoordinate(dpScout, +DPMatrixDimension_::VERTICAL)));
1196     TMaskType flag = createVector<TMaskType>(0);
1197     assignValue(flag, dpScout._simdLane, -1);
1198     auto cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
1199     auto cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
1200 
1201     value(traceNavigator) = blend(value(traceNavigator),
1202                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
1203                                   cmpV | cmpH);
1204     value(traceNavigator) = blend(value(traceNavigator),
1205                                   value(traceNavigator) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
1206                                   cmpV);
1207     value(traceNavigator) = blend(value(traceNavigator),
1208                                   value(traceNavigator) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
1209                                   cmpH);
1210 }
1211 
1212 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue>>>,void)1213 inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, void)
1214 _correctTraceValue(TTraceNavigator & traceNavigator,
1215                    DPScout_<DPCell_<TScoreValue, DynamicGaps>, TDPScoutSpec>  const & dpScout)
1216 {
1217     _setToPosition(traceNavigator, maxHostPosition(dpScout));
1218     if (isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()))
1219     {
1220         value(traceNavigator) &= ~TraceBitMap_<TScoreValue>::DIAGONAL;
1221         value(traceNavigator) |= TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
1222     }
1223     else if (isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()))
1224     {
1225         value(traceNavigator) &= ~TraceBitMap_<TScoreValue>::DIAGONAL;
1226         value(traceNavigator) |= TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
1227     }
1228 }
1229 
1230 template <typename TTraceNavigator, typename TScoreValue, typename TDPScoutSpec>
SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue>>,void)1231 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, void)
1232 _correctTraceValue(TTraceNavigator & traceNavigator,
1233                    DPScout_<DPCell_<TScoreValue, DynamicGaps>, TDPScoutSpec>  const & dpScout)
1234 {
1235     using TMaskType = typename SimdMaskVector<TScoreValue>::Type;
1236 
1237     _setToPosition(traceNavigator, maxHostPosition(dpScout));
1238     TMaskType flag = createVector<TMaskType>(0);
1239     assignValue(flag, dpScout._simdLane, -1);
1240     auto cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()) & flag;
1241     auto cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()) & flag;
1242     value(traceNavigator) = blend(value(traceNavigator),
1243                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
1244                                   cmpV | cmpH);
1245     value(traceNavigator) = blend(value(traceNavigator),
1246                                   value(traceNavigator) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
1247                                   cmpV);
1248     value(traceNavigator) = blend(value(traceNavigator),
1249                                   value(traceNavigator) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
1250                                   cmpH);
1251 }
1252 
1253 // ----------------------------------------------------------------------------
1254 // Function _finishAlignment()
1255 // ----------------------------------------------------------------------------
1256 
1257 template <typename TTraceTarget,
1258           typename TTraceMatNavigator,
1259           typename TScoreValue, typename TGapsModel, typename TDPScoutSpec,
1260           typename TSeqH,
1261           typename TSeqV,
1262           typename TBandSwitch,
1263           typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
SEQAN_FUNC_ENABLE_IF(Not<IsTracebackEnabled_<TTraceFlag>>,TScoreValue)1264 inline SEQAN_FUNC_ENABLE_IF(Not<IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
1265 _finishAlignment(TTraceTarget & /*traceSegments*/,
1266                  TTraceMatNavigator & /*dpTraceMatrixNavigator*/,
1267                  DPScout_<DPCell_<TScoreValue, TGapsModel>, TDPScoutSpec> & dpScout,
1268                  TSeqH const & /*seqH*/,
1269                  TSeqV const & /*seqV*/,
1270                  DPBandConfig<TBandSwitch> const & /*band*/,
1271                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & /*dpProfile*/)
1272 {
1273     return maxScore(dpScout);
1274 }
1275 
1276 template <typename TTraceTarget,
1277           typename TTraceMatNavigator,
1278           typename TScoreValue, typename TGapsModel, typename TDPScoutSpec,
1279           typename TSeqH,
1280           typename TSeqV,
1281           typename TBandSwitch,
1282           typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
SEQAN_FUNC_ENABLE_IF(And<Is<SimdVectorConcept<TScoreValue>>,IsTracebackEnabled_<TTraceFlag>>,TScoreValue)1283 inline SEQAN_FUNC_ENABLE_IF(And<Is<SimdVectorConcept<TScoreValue> >, IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
1284 _finishAlignment(TTraceTarget & traceSegments,
1285                  TTraceMatNavigator & dpTraceMatrixNavigator,
1286                  DPScout_<DPCell_<TScoreValue, TGapsModel>, TDPScoutSpec> & scout,
1287                  TSeqH const & seqH,
1288                  TSeqV const & seqV,
1289                  DPBandConfig<TBandSwitch> const & band,
1290                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
1291 {
1292     typedef typename Size<TTraceTarget>::Type TSize;
1293 
1294     for(TSize i = 0; i < length(traceSegments); ++i)
1295     {
1296         _setSimdLane(dpTraceMatrixNavigator, i);
1297         _setSimdLane(scout, i);
1298 
1299         if (IsSingleTrace_<TTraceFlag>::VALUE)
1300         {
1301             _correctTraceValue(dpTraceMatrixNavigator, scout);
1302         }
1303         _computeTraceback(traceSegments[i], dpTraceMatrixNavigator,
1304                           toGlobalPosition(dpTraceMatrixNavigator,
1305                                            maxHostCoordinate(scout, +DPMatrixDimension_::HORIZONTAL),
1306                                            maxHostCoordinate(scout, +DPMatrixDimension_::VERTICAL)),
1307                           _hostLengthH(scout, seqH),
1308                           _hostLengthV(scout, seqV), band, dpProfile);
1309     }
1310     return maxScore(scout);
1311 }
1312 
1313 template <typename TTraceTarget,
1314           typename TTraceMatNavigator,
1315           typename TScoreValue, typename TGapsModel, typename TDPScoutSpec,
1316           typename TSeqH,
1317           typename TSeqV,
1318           typename TBandSwitch,
1319           typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
SEQAN_FUNC_ENABLE_IF(And<Not<Is<SimdVectorConcept<TScoreValue>>>,IsTracebackEnabled_<TTraceFlag>>,TScoreValue)1320 inline SEQAN_FUNC_ENABLE_IF(And<Not<Is<SimdVectorConcept<TScoreValue> > >, IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
1321 _finishAlignment(TTraceTarget & traceSegments,
1322                  TTraceMatNavigator & dpTraceMatrixNavigator,
1323                  DPScout_<DPCell_<TScoreValue, TGapsModel>, TDPScoutSpec> & dpScout,
1324                  TSeqH const & seqH,
1325                  TSeqV const & seqV,
1326                  DPBandConfig<TBandSwitch> const & band,
1327                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
1328 {
1329     if (IsSingleTrace_<TTraceFlag>::VALUE)
1330         _correctTraceValue(dpTraceMatrixNavigator, dpScout);
1331 
1332     _computeTraceback(traceSegments, dpTraceMatrixNavigator, dpScout, seqH, seqV, band, dpProfile);
1333     return maxScore(dpScout);
1334 }
1335 
1336 // ----------------------------------------------------------------------------
1337 // Function _computeAligmnment()
1338 // ----------------------------------------------------------------------------
1339 
1340 template <typename TDPScoreValue, typename TTraceValue, typename TScoreMatHost, typename TTraceMatHost,
1341           typename TTraceTarget,
1342           typename TScoutState,
1343           typename TSequenceH,
1344           typename TSequenceV,
1345           typename TScoreScheme,
1346           typename TBandSwitch,
1347           typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
1348 inline typename Value<TScoreScheme>::Type
_computeAlignment(DPContext<TDPScoreValue,TTraceValue,TScoreMatHost,TTraceMatHost> & dpContext,TTraceTarget & traceSegments,TScoutState & scoutState,TSequenceH const & seqH,TSequenceV const & seqV,TScoreScheme const & scoreScheme,DPBandConfig<TBandSwitch> const & band,DPProfile_<TAlignmentAlgorithm,TGapScheme,TTraceFlag,TExecPolicy> const & dpProfile)1349 _computeAlignment(DPContext<TDPScoreValue, TTraceValue, TScoreMatHost, TTraceMatHost> & dpContext,
1350                   TTraceTarget & traceSegments,
1351                   TScoutState & scoutState,
1352                   TSequenceH const & seqH,
1353                   TSequenceV const & seqV,
1354                   TScoreScheme const & scoreScheme,
1355                   DPBandConfig<TBandSwitch> const & band,
1356                   DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
1357 {
1358 
1359     typedef typename DefaultScoreMatrixSpec_<TAlignmentAlgorithm>::Type TScoreMatrixSpec;
1360 
1361     typedef DPMatrix_<TDPScoreValue, TScoreMatrixSpec, TScoreMatHost>   TDPScoreMatrix;
1362     typedef DPMatrix_<TTraceValue, FullDPMatrix, TTraceMatHost>         TDPTraceMatrix;
1363 
1364     using TNavigationSpec = std::conditional_t<std::is_same<TBandSwitch, BandOff>::value,
1365                                                NavigateColumnWise,
1366                                                NavigateColumnWiseBanded>;
1367 
1368     typedef DPMatrixNavigator_<TDPScoreMatrix, DPScoreMatrix, TNavigationSpec> TDPScoreMatrixNavigator;
1369     typedef DPMatrixNavigator_<TDPTraceMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> TDPTraceMatrixNavigator;
1370 
1371     typedef typename ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm, TScoutState>::Type TDPScoutSpec;
1372     typedef DPScout_<TDPScoreValue, TDPScoutSpec> TDPScout;
1373 
1374     typedef typename Value<TScoreScheme>::Type TScoreValue;
1375 
1376     // Check if current dp settings are valid. If not return infinity value for dp score value.
1377     if (!_isValidDPSettings(seqH, seqV, band, dpProfile))
1378         return createVector<TScoreValue>(std::numeric_limits<typename Value<TScoreValue>::Type>::min());  // NOTE(rrahn): In case of non-simd version, createVector returns just a scalar.
1379 
1380     TDPScoreMatrix dpScoreMatrix;
1381     TDPTraceMatrix dpTraceMatrix;
1382 
1383     // TODO(rmaerker): Check whether the matrix allocation can be reduced if upperDiagonal < 0?
1384     setLength(dpScoreMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band)));
1385     setLength(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band)));
1386 
1387     SEQAN_IF_CONSTEXPR (IsSameType<TBandSwitch, BandOff>::VALUE)
1388     {
1389         setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
1390         setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
1391     }
1392     else
1393     {
1394         int bandSize = _min(static_cast<int>(length(seqH)), upperDiagonal(band)) - _max(lowerDiagonal(band), -static_cast<int>(length(seqV))) + 1;
1395         setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, _min(static_cast<int>(length(seqV)) + 1, bandSize));
1396         setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, _min(static_cast<int>(length(seqV)) + 1, bandSize));
1397     }
1398 
1399     // We set the host to the score matrix and the dp matrix.
1400     setHost(dpScoreMatrix, getDpScoreMatrix(dpContext));
1401     setHost(dpTraceMatrix, getDpTraceMatrix(dpContext));
1402 
1403     resize(dpScoreMatrix);
1404     // We do not need to allocate the memory for the trace matrix if the traceback is disabled.
1405     if (IsTracebackEnabled_<TTraceFlag>::VALUE)
1406         resize(dpTraceMatrix);
1407 
1408     TDPScoreMatrixNavigator dpScoreMatrixNavigator{dpScoreMatrix, band};
1409     TDPTraceMatrixNavigator dpTraceMatrixNavigator{dpTraceMatrix, band};
1410 
1411     TDPScout dpScout(scoutState);
1412 #if SEQAN_ALIGN_SIMD_PROFILE
1413     profile.preprTimer += sysTime() - timer;
1414     timer = sysTime();
1415 #endif
1416     // Execute the alignment.
1417     _computeAlignmentImpl(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, band,
1418                           dpProfile, TNavigationSpec{});
1419 
1420 #if SEQAN_ALIGN_SIMD_PROFILE
1421     profile.alignTimer += sysTime() - timer;
1422     timer = sysTime();
1423 #endif
1424     return _finishAlignment(traceSegments, dpTraceMatrixNavigator, dpScout, seqH, seqV, band, dpProfile);
1425 }
1426 
1427 }  // namespace seqan
1428 
1429 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_ALGORITHM_IMPL_H_
1430