1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2015, 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 // This specialization is used to navigate through the traceback matrix
35 // of any standard dp-alignment algorithm. The DPTraceMatrix gets the
36 // traceback flag TracebackOn or TracebackOff. A traceback is only computed
37 // if the traceback is switched on. If this is not the case, the void
38 // functions will be compiled as no-op functions, while in functions that try
39 // to access a value of the underlying matrix via the navigator an assertion
40 // is thrown.
41 // ==========================================================================
42 
43 #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_MATRIX_NAVIGATOR_TRACE_MATRIX_H_
44 #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_MATRIX_NAVIGATOR_TRACE_MATRIX_H_
45 
46 namespace seqan {
47 
48 // ============================================================================
49 // Forwards
50 // ============================================================================
51 
52 // ============================================================================
53 // Tags, Classes, Enums
54 // ============================================================================
55 
56 // ----------------------------------------------------------------------------
57 // Class DPMatrixNavigator                        [FullDPMatrix, DPTraceMatrix]
58 // ----------------------------------------------------------------------------
59 
60 // The matrix navigator for the trace-back matrix.
61 //
62 // It takes three types to be specialized. The first type defines the underlying
63 // dp-matrix it is working on. This has to be a FullDPMatrix. The second type,
64 // specifies that this is a trace-matrix navigator while the TTraceFlag can either
65 // be TracebackOn to enable the navigator or TracebackOff to disable it.
66 // The last parameter specifies the kind of navigation.
67 template <typename TValue, typename TTraceFlag>
68 class DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise>
69 {
70 public:
71 
72     typedef  DPMatrix_<TValue, FullDPMatrix> TDPMatrix_;
73     typedef typename Pointer_<TDPMatrix_>::Type TDPMatrixPointer_;
74     typedef typename Iterator<TDPMatrix_, Standard>::Type TDPMatrixIterator;
75 
76     TDPMatrixPointer_ _ptrDataContainer;        // The pointer to the underlying Matrix.
77     int _laneLeap;                              // Keeps track of the jump size from one column to another.
78     TDPMatrixIterator _activeColIterator;       // The current column iterator.
79 
80 
DPMatrixNavigator_()81     DPMatrixNavigator_() :
82         _ptrDataContainer(TDPMatrixPointer_(0)),
83         _laneLeap(0),
84         _activeColIterator()
85     {}
86 };
87 
88 // ============================================================================
89 // Metafunctions
90 // ============================================================================
91 
92 // ============================================================================
93 // Functions
94 // ============================================================================
95 
96 // ----------------------------------------------------------------------------
97 // Function _init()
98 // ----------------------------------------------------------------------------
99 
100 // Initializes the navigator for unbanded alignments.
101 template <typename TValue, typename TTraceFlag>
102 inline void
_init(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & navigator,DPMatrix_<TValue,FullDPMatrix> & dpMatrix,DPBandConfig<BandOff> const &)103 _init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & navigator,
104       DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
105       DPBandConfig<BandOff> const &)
106 {
107     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
108         return;  // Leave navigator uninitialized because it is never used.
109 
110     navigator._ptrDataContainer = &dpMatrix;
111     navigator._activeColIterator = begin(dpMatrix, Standard());
112     navigator._laneLeap = 1;
113     assignValue(navigator._activeColIterator, TValue());
114 }
115 
116 // Initializes the navigator for banded alignments.
117 // Note, the band size has a maximal width of length of the vertical sequence.
118 template <typename TValue, typename TTraceFlag>
119 inline void
_init(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & navigator,DPMatrix_<TValue,FullDPMatrix> & dpMatrix,DPBandConfig<BandOn> const & band)120 _init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & navigator,
121       DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
122       DPBandConfig<BandOn> const & band)
123 {
124     typedef typename Size<DPMatrix_<TValue, FullDPMatrix> >::Type TMatrixSize;
125     typedef typename MakeSigned<TMatrixSize>::Type TSignedSize;
126 
127     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
128         return;  // Leave navigator as is because it should never be used.
129 
130     navigator._ptrDataContainer = &dpMatrix;
131 
132     // Band begins within the first row.
133     if (lowerDiagonal(band) >= 0)
134     {
135         // The first cell of the first column starts at the last cell in the matrix of the current column.
136         navigator._laneLeap = _min(length(dpMatrix, DPMatrixDimension_::VERTICAL), bandSize(band));
137         navigator._activeColIterator = begin(dpMatrix, Standard()) + _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL] - 1;
138     }
139     else if (upperDiagonal(band) <= 0)  // Band begins within the first column.
140     {
141         // The first cell starts at the beginning of the current column.
142         navigator._laneLeap = 1;
143         navigator._activeColIterator = begin(dpMatrix, Standard());
144     }
145     else  // Band intersects with the point of origin.
146     {
147         // First cell starts at position i, such that i + abs(lowerDiagonal) = length(seqV).
148         TMatrixSize lengthVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL);
149         int lastPos = _max(-static_cast<TSignedSize>(lengthVertical - 1), lowerDiagonal(band));
150         navigator._laneLeap = lengthVertical + lastPos;
151         navigator._activeColIterator = begin(dpMatrix, Standard()) + navigator._laneLeap - 1;
152     }
153     assignValue(navigator._activeColIterator, TValue());
154 }
155 
156 // ----------------------------------------------------------------------------
157 // Function _goNextCell()                          [DPInitialColumn, FirstCell]
158 // ----------------------------------------------------------------------------
159 
160 // In the initial column we don't need to do anything because, the navigagtor is already initialized.
161 template <typename TValue, typename TTraceFlag>
162 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> &,MetaColumnDescriptor<DPInitialColumn,PartialColumnTop> const &,FirstCell const &)163 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & /*dpNavigator*/,
164             MetaColumnDescriptor<DPInitialColumn, PartialColumnTop> const &,
165             FirstCell const &)
166 {
167     // no-op
168 }
169 
170 template <typename TValue, typename TTraceFlag, typename TColumnLocation>
171 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> &,MetaColumnDescriptor<DPInitialColumn,TColumnLocation> const &,FirstCell const &)172 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & /*dpNavigator*/,
173             MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
174             FirstCell const &)
175 {
176     // no-op
177 }
178 
179 // ----------------------------------------------------------------------------
180 // Function _goNextCell()                         [PartialColumnTop, FirstCell]
181 // ----------------------------------------------------------------------------
182 
183 // We are in the banded case, where the band crosses the first row.
184 // The left cell of the active cell is not valid, beacause we only can come from horizontal direction.
185 // The lower left cell of the active cell is the horizontal direction.
186 
187 template <typename TValue, typename TTraceFlag, typename TColumnType>
188 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<TColumnType,PartialColumnTop> const &,FirstCell const &)189 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
190             MetaColumnDescriptor<TColumnType, PartialColumnTop> const &,
191             FirstCell const &)
192 {
193     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
194         return;  // Do nothing since no trace back is computed.
195 
196     --dpNavigator._laneLeap;
197     dpNavigator._activeColIterator += dpNavigator._laneLeap;
198 }
199 
200 // ----------------------------------------------------------------------------
201 // Function _goNextCell()                       [other column types, FirstCell]
202 // ----------------------------------------------------------------------------
203 
204 // We are in the banded case.
205 // The left cell of the active cell represents diagonal direction. The lower left diagonal represents the horizontal direction.
206 
207 template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
208 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<TColumnType,TColumnLocation> const &,FirstCell const &)209 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
210             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
211             FirstCell const &)
212 {
213     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
214         return;  // Do nothing since no trace back is computed.
215 
216     dpNavigator._activeColIterator += dpNavigator._laneLeap;
217 }
218 
219 // ----------------------------------------------------------------------------
220 // Function _goNextCell                                 [any column, InnerCell]
221 // ----------------------------------------------------------------------------
222 
223 // For any other column type and location we can use the same navigation procedure.
224 template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
225 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<TColumnType,TColumnLocation> const &,InnerCell const &)226 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
227             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
228             InnerCell const &)
229 {
230     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
231         return;  // Do nothing since no trace back is computed.
232 
233     ++dpNavigator._activeColIterator;
234 }
235 
236 // ----------------------------------------------------------------------------
237 // Function _goNextCell                         [PartialColumnBottom, LastCell]
238 // ----------------------------------------------------------------------------
239 
240 template <typename TValue, typename TTraceFlag>
241 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<DPInitialColumn,PartialColumnBottom> const &,LastCell const &)242 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
243             MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> const &,
244             LastCell const &)
245 {
246     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
247         return;  // Do nothing since no trace back is computed.
248 
249     ++dpNavigator._activeColIterator;
250 }
251 
252 // If we are in banded case and the band crosses the last row, we have to update
253 // the additional leap for the current track.
254 template <typename TValue, typename TTraceFlag, typename TColumnType>
255 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<TColumnType,PartialColumnBottom> const &,LastCell const &)256 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
257             MetaColumnDescriptor<TColumnType, PartialColumnBottom> const &,
258             LastCell const &)
259 {
260     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
261         return;  // Do nothing since no trace back is computed.
262 
263     ++dpNavigator._activeColIterator;
264     ++dpNavigator._laneLeap;
265 }
266 
267 // ----------------------------------------------------------------------------
268 // Function _goNextCell                            [any other column, LastCell]
269 // ----------------------------------------------------------------------------
270 
271 // If we are in the banded case the left cell of the active represents the diagonal direction.
272 template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
273 inline void
_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,MetaColumnDescriptor<TColumnType,TColumnLocation> const &,LastCell const &)274 _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
275             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
276             LastCell const &)
277 {
278     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
279         return;  // Do nothing since no trace back is computed.
280 
281     ++dpNavigator._activeColIterator;
282 }
283 
284 // ----------------------------------------------------------------------------
285 // Function _traceHorizontal()
286 // ----------------------------------------------------------------------------
287 
288 template <typename TValue, typename TTraceFlag>
289 inline void
_traceHorizontal(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,bool isBandShift)290 _traceHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
291                  bool isBandShift)
292 {
293     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
294         return;  // Do nothing since no trace back is computed.
295 
296     if (isBandShift)
297         dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::HORIZONTAL] - 1;
298     else
299         dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::HORIZONTAL];
300 
301 }
302 
303 // ----------------------------------------------------------------------------
304 // Function _traceDiagonal()
305 // ----------------------------------------------------------------------------
306 
307 template <typename TValue, typename TTraceFlag>
308 inline void
_traceDiagonal(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,bool isBandShift)309 _traceDiagonal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
310                bool isBandShift)
311 {
312     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
313         return;  // Do nothing since no trace back is computed.
314 
315     if (isBandShift)
316         dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::HORIZONTAL];
317     else
318         dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::HORIZONTAL] + 1;
319 
320 }
321 
322 // ----------------------------------------------------------------------------
323 // Function _traceVertical()
324 // ----------------------------------------------------------------------------
325 
326 template <typename TValue, typename TTraceFlag>
327 inline void
_traceVertical(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,bool)328 _traceVertical(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
329                bool /*isBandShift*/)
330 {
331     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
332         return;  // Do nothing since no trace back is computed.
333 
334     dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::VERTICAL];
335 }
336 
337 // ----------------------------------------------------------------------------
338 // Function setToPosition()
339 // ----------------------------------------------------------------------------
340 
341 template <typename TValue, typename TTraceFlag, typename TPosition>
342 inline void
_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,TPosition const & hostPosition)343 _setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
344               TPosition const & hostPosition)
345 {
346     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
347         return;
348 
349     dpNavigator._activeColIterator = begin(*dpNavigator._ptrDataContainer, Standard()) + hostPosition;
350 }
351 
352 
353 // Sets the host position based on the given horizontal and vertical position. Note that the horizontal and
354 // vertical positions must correspond to the correct size of the underlying matrix.
355 // For banded matrices the vertical dimension might not equal the length of the vertical sequence.
356 template <typename TValue, typename TTraceFlag, typename TPositionH, typename TPositionV>
357 inline void
_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue,FullDPMatrix>,DPTraceMatrix<TTraceFlag>,NavigateColumnWise> & dpNavigator,TPositionH const & horizontalPosition,TPositionV const & verticalPosition)358 _setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
359               TPositionH const & horizontalPosition,
360               TPositionV const & verticalPosition)
361 {
362     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
363         return;
364 
365     TPositionH  hostPosition = horizontalPosition * _dataFactors(container(dpNavigator))[+DPMatrixDimension_::HORIZONTAL] + verticalPosition;
366     dpNavigator._activeColIterator = begin(*dpNavigator._ptrDataContainer, Standard()) + hostPosition;
367 }
368 
369 // ----------------------------------------------------------------------------
370 // Function assignValue()
371 // ----------------------------------------------------------------------------
372 
373 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TValue>
374 inline void
assignValue(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> & dpNavigator,TValue const & element)375 assignValue(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator,
376             TValue const & element)
377 {
378     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
379         return;  // Do nothing since no trace back is computed.
380 
381     assignValue(dpNavigator._activeColIterator, element);
382 }
383 
384 // ----------------------------------------------------------------------------
385 // Function value()
386 // ----------------------------------------------------------------------------
387 
388 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
389 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> >::Type
value(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> & dpNavigator)390 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator)
391 {
392     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
393         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
394 
395     return value(dpNavigator._activeColIterator);
396 }
397 
398 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
399 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const>::Type
value(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> const & dpNavigator)400 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator)
401 {
402     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
403         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
404 
405     return value(dpNavigator._activeColIterator);
406 }
407 
408 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TPosition>
409 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> >::Type
value(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> & dpNavigator,TPosition const & postition)410 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator,
411       TPosition const & postition)
412 {
413     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
414         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
415 
416     return value(begin(*dpNavigator._ptrDataContainer) + postition);
417 }
418 
419 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TPosition>
420 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const>::Type
value(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> const & dpNavigator,TPosition const & position)421 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator,
422       TPosition const & position)
423 {
424     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
425         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
426 
427     return value(begin(*dpNavigator._ptrDataContainer) + position);
428 }
429 
430 // ----------------------------------------------------------------------------
431 // Function coordinate()
432 // ----------------------------------------------------------------------------
433 
434 // Returns the coordinate of the given dimension for the current position of the
435 // navigator within the matrix.
436 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
437 inline typename DPMatrixDimension_::TValue
coordinate(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> const & dpNavigator,typename DPMatrixDimension_::TValue const & dimension)438 coordinate(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator,
439            typename DPMatrixDimension_::TValue const & dimension)
440 {
441     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
442         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
443     SEQAN_ASSERT_EQ(_checkCorrectDimension(dimension), true);
444 
445     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
446         return _dataLengths(*dpNavigator._ptrDataContainer)[dimension];  // Return lengths of given dimension.
447 
448     return coordinate(value(dpNavigator._ptrDataContainer), position(dpNavigator), dimension); // Simply delegate to coordinate of underlying matrix.
449 }
450 
451 // ----------------------------------------------------------------------------
452 // Function position()
453 // ----------------------------------------------------------------------------
454 
455 // Returns the current position of the navigator within the matrix.
456 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
457 inline typename Position<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> >::Type
position(DPMatrixNavigator_<TDPMatrix,DPTraceMatrix<TTraceFlag>,TNavigationSpec> const & dpNavigator)458 position(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator)
459 {
460     // Return 0 when traceback is not enabled. This is necessary to still track the score even
461     // the traceback is not enabled.
462     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
463         return 0;
464 
465     return position(dpNavigator._activeColIterator, *dpNavigator._ptrDataContainer);
466 }
467 
468 }  // namespace seqan
469 
470 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_MATRIX_NAVIGATOR_TRACE_MATRIX_H_
471