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