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