diff --git a/porechop/cpp_function_wrappers.py b/porechop/cpp_function_wrappers.py index ba3f993..56026c7 100644 --- a/porechop/cpp_function_wrappers.py +++ b/porechop/cpp_function_wrappers.py @@ -21,7 +21,7 @@ SO_FILE = 'cpp_functions.so' SO_FILE_FULL = os.path.join(os.path.dirname(os.path.realpath(__file__)), SO_FILE) if not os.path.isfile(SO_FILE_FULL): - sys.exit('could not find ' + SO_FILE + ' - please reinstall') + sys.exit('could not find ' + SO_FILE_FULL + ' - please reinstall') C_LIB = CDLL(SO_FILE_FULL) C_LIB.adapterAlignment.argtypes = [c_char_p, # Read sequence diff --git a/porechop/include/seqan/LICENSE b/porechop/include/seqan/LICENSE new file mode 100644 index 0000000..ab6e3bf --- /dev/null +++ b/porechop/include/seqan/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2006-2018, Knut Reinert, FU Berlin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Knut Reinert or the FU Berlin nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + diff --git a/porechop/include/seqan/align.h b/porechop/include/seqan/align.h index 8e5858e..db4eeba 100644 --- a/porechop/include/seqan/align.h +++ b/porechop/include/seqan/align.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -53,6 +53,7 @@ #include #include +#include #include // ModifiedAlphabet<>. #include #include // TODO(holtgrew): We should not have to depend on this. @@ -76,6 +77,8 @@ #include +#include + #include #include diff --git a/porechop/include/seqan/align/align_base.h b/porechop/include/seqan/align/align_base.h index a23afff..58c7345 100644 --- a/porechop/include/seqan/align/align_base.h +++ b/porechop/include/seqan/align/align_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -476,7 +476,7 @@ detach(Align & me) template inline void -write(TFile & target, +_write(TFile & target, Align const & source) { typedef Align const TAlign; @@ -557,6 +557,15 @@ write(TFile & target, writeValue(target, '\n'); } +template +[[deprecated("Old-style I/O. Use stream operator << instead.")]] +inline void +write(TFile & target, + Align const & source) +{ + _write(target, source); +} + // ---------------------------------------------------------------------------- // Function clearClipping() // ---------------------------------------------------------------------------- @@ -607,7 +616,7 @@ operator<<(TStream & target, Align const & source) { typename DirectionIterator::Type it = directionIterator(target, Output()); - write(it, source); + _write(it, source); return target; } diff --git a/porechop/include/seqan/align/align_cols.h b/porechop/include/seqan/align/align_cols.h index 00b625b..f0a9428 100644 --- a/porechop/include/seqan/align/align_cols.h +++ b/porechop/include/seqan/align/align_cols.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/align_config.h b/porechop/include/seqan/align/align_config.h index b76e683..0f3c261 100644 --- a/porechop/include/seqan/align/align_config.h +++ b/porechop/include/seqan/align/align_config.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/align_interface_wrapper.h b/porechop/include/seqan/align/align_interface_wrapper.h index 177d0ae..3c719ec 100644 --- a/porechop/include/seqan/align/align_interface_wrapper.h +++ b/porechop/include/seqan/align/align_interface_wrapper.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -58,14 +58,20 @@ namespace seqan // Function _alignWrapperSequential(); Score; StringSet vs. StringSet // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Is::Type>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSequential(StringSet const & stringsH, - StringSet const & stringsV, +_alignWrapperSequential(TSetH const & stringsH, + TSetV const & stringsV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) @@ -92,14 +98,20 @@ _alignWrapperSequential(StringSet const & stringsH, // Function _alignWrapperSequential(); Score; String vs. StringSet // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Not::Type>>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSequential(TString1 const & stringH, - StringSet const & stringsV, +_alignWrapperSequential(TSeqH const & stringH, + TSetV const & stringsV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) @@ -125,21 +137,27 @@ _alignWrapperSequential(TString1 const & stringH, // Function _alignWrapperSequential(); Gaps // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Is::Type>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSequential(StringSet, TSetSpecH> & gapSeqSetH, - StringSet, TSetSpecV> & gapSeqSetV, +_alignWrapperSequential(TSetH & gapSeqSetH, + TSetV & gapSeqSetV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) { - typedef typename Size::Type TSize; - typedef typename Position::Type TPosition; + typedef typename Size::Type TSize; + typedef typename Position::Type TPosition; typedef TraceSegment_ TTraceSegment; String results; @@ -167,7 +185,8 @@ _alignWrapperSequential(StringSet, TSetSpecH> & gap template inline auto _alignWrapper(TArgs && ...args) { -#ifdef SEQAN_SIMD_ENABLED +// NOTE(marehr): ume_simd is currently not working, thus falling back to sequential case +#if defined(SEQAN_SIMD_ENABLED) && !defined(SEQAN_UMESIMD_ENABLED) return _alignWrapperSimd(std::forward(args)...); #else return _alignWrapperSequential(std::forward(args)...); diff --git a/porechop/include/seqan/align/align_iterator_base.h b/porechop/include/seqan/align/align_iterator_base.h index 4eef6b5..b35c089 100644 --- a/porechop/include/seqan/align/align_iterator_base.h +++ b/porechop/include/seqan/align/align_iterator_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/align_metafunctions.h b/porechop/include/seqan/align/align_metafunctions.h index 5ae233c..aa8eb8a 100644 --- a/porechop/include/seqan/align/align_metafunctions.h +++ b/porechop/include/seqan/align/align_metafunctions.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/align_traceback.h b/porechop/include/seqan/align/align_traceback.h index 6b9ea34..0df78ce 100644 --- a/porechop/include/seqan/align/align_traceback.h +++ b/porechop/include/seqan/align/align_traceback.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/aligned_sequence_concept.h b/porechop/include/seqan/align/aligned_sequence_concept.h new file mode 100644 index 0000000..d458865 --- /dev/null +++ b/porechop/include/seqan/align/aligned_sequence_concept.h @@ -0,0 +1,65 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_ +#define INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +SEQAN_CONCEPT_REFINE(AlignedSequenceConcept, (TSequence), (ContainerConcept)) +{ + + SEQAN_CONCEPT_USAGE(AlignedSequenceConcept) + {} +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_ diff --git a/porechop/include/seqan/align/alignment_algorithm_tags.h b/porechop/include/seqan/align/alignment_algorithm_tags.h index 741645a..85561b7 100644 --- a/porechop/include/seqan/align/alignment_algorithm_tags.h +++ b/porechop/include/seqan/align/alignment_algorithm_tags.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/alignment_operations.h b/porechop/include/seqan/align/alignment_operations.h index fccc61a..af185fa 100644 --- a/porechop/include/seqan/align/alignment_operations.h +++ b/porechop/include/seqan/align/alignment_operations.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/dp_algorithm_impl.h b/porechop/include/seqan/align/dp_algorithm_impl.h index 451ffb1..53cb9cb 100644 --- a/porechop/include/seqan/align/dp_algorithm_impl.h +++ b/porechop/include/seqan/align/dp_algorithm_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -87,7 +87,7 @@ // are accepted. If the dp profile consists of the standard global alignment // algorithm (NeedlemanWunsch or Gotoh), the band is required to go through // the sink and the source of the dp matrix. If this is not given the -// alignment algorithm is aborted and the score MinValue::VALUE +// alignment algorithm is aborted and the score std::numeric_limits::min() // is returned. // There are no further restrictions. // @@ -272,16 +272,18 @@ _isBandEnabled(DPBandConfig const & /*band*/) // ---------------------------------------------------------------------------- // Computes the score and tracks it if enabled. -template inline void _computeCell(TDPScout & scout, TTraceMatrixNavigator & traceMatrixNavigator, - DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, + TDPCell & current, + TDPCell & diagonal, + TDPCell const & horizontal, + TDPCell & vertical, TSequenceHValue const & seqHVal, TSequenceVValue const & seqVVal, TScoringScheme const & scoringScheme, @@ -290,16 +292,23 @@ _computeCell(TDPScout & scout, TDPProfile const &) { typedef DPMetaColumn_ TMetaColumn; + assignValue(traceMatrixNavigator, - _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, seqVVal, - scoringScheme, typename RecursionDirection_::Type(), + _computeScore(current, diagonal, horizontal, vertical, seqHVal, seqVVal, scoringScheme, + typename RecursionDirection_::Type(), TDPProfile())); if (TrackingEnabled_::VALUE) { typedef typename LastColumnEnabled_::Type TIsLastColumn; typedef typename LastRowEnabled_::Type TIsLastRow; - _scoutBestScore(scout, activeCell, traceMatrixNavigator, + + // TODO(rrahn): Refactor to set vertical score only when max is updated. + if (IsTracebackEnabled_::VALUE) + { + _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical)); + } + _scoutBestScore(scout, current, traceMatrixNavigator, TIsLastColumn(), TIsLastRow()); } } @@ -322,10 +331,16 @@ _precomputeScoreMatrixOffset(TSeqValue const & seqVal, // Function _computeTrack() // ---------------------------------------------------------------------------- -// Computes one track of the dp algorithm. A track is defined as the area that is filled by the inner loop and -// iterated by the outer loop. For the column-wise navigation the track is equivalent with the column. -template +template inline void _computeTrack(TDPScout & scout, TDPScoreMatrixNavigator & dpScoreMatrixNavigator, @@ -335,13 +350,16 @@ _computeTrack(TDPScout & scout, TSeqVIterator const & seqBegin, TSeqVIterator const & seqEnd, TScoringScheme const & scoringScheme, + TDPCell & cacheDiag, + TDPCell & cacheVert, TColumnDescriptor const &, TDPProfile const &) { - // Set the iterator to the begin of the track. _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), FirstCell()); _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), FirstCell()); + _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, TColumnDescriptor()); + // Precompute the row of the scoring matrix for future look-ups. TSeqHValue tmpSeqH = _precomputeScoreMatrixOffset(seqHValue, scoringScheme); @@ -349,52 +367,93 @@ _computeTrack(TDPScout & scout, _preInitScoutVertical(scout); // Compute the first cell. - _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), tmpSeqH, seqVValue, scoringScheme, + _computeCell(scout, + dpTraceMatrixNavigator, + value(dpScoreMatrixNavigator), + cacheDiag, + previousCellHorizontal(dpScoreMatrixNavigator), + cacheVert, + tmpSeqH, + seqVValue, + scoringScheme, TColumnDescriptor(), FirstCell(), TDPProfile()); TSeqVIterator iter = seqBegin; - TSeqVIterator itEnd = (seqEnd - 1); - // Compute the inner cells of the current track. - for (; iter != itEnd; ++iter) + for (; iter != seqEnd - 1; ++iter) { - // Set the iterator to the next cell within the track. _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), InnerCell()); _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), InnerCell()); + + _incVerticalPos(scout); // Compute the inner cell. - // If we have variable length simd, we need to check if we reached the end of one of the sequences. - // For all other cases, the function returns always false. if (SEQAN_UNLIKELY(_reachedVerticalEndPoint(scout, iter))) { - _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), tmpSeqH, - sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme, - TColumnDescriptor(), LastCell(), TDPProfile()); + _computeCell(scout, + dpTraceMatrixNavigator, + value(dpScoreMatrixNavigator), + cacheDiag, + previousCellHorizontal(dpScoreMatrixNavigator), + cacheVert, + tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)), + scoringScheme, TColumnDescriptor(), LastCell(), TDPProfile()); _nextVerticalEndPos(scout); } else { - _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), tmpSeqH, - sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme, - TColumnDescriptor(), InnerCell(), TDPProfile()); + _computeCell(scout, + dpTraceMatrixNavigator, + value(dpScoreMatrixNavigator), + cacheDiag, + previousCellHorizontal(dpScoreMatrixNavigator), + cacheVert, + tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)), + scoringScheme, TColumnDescriptor(), InnerCell(), TDPProfile()); } - _incVerticalPos(scout); } - // Set the iterator to the last cell of the track. _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), LastCell()); _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), LastCell()); - // Compute the last cell. - _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), tmpSeqH, - sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme, + _incVerticalPos(scout); + _computeCell(scout, + dpTraceMatrixNavigator, + value(dpScoreMatrixNavigator), + cacheDiag, + previousCellHorizontal(dpScoreMatrixNavigator), + cacheVert, + tmpSeqH, + sequenceEntryForScore(scoringScheme, container(iter), position(iter)), + scoringScheme, TColumnDescriptor(), LastCell(), TDPProfile()); } +template +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 &) +{ + using TDPCell = std::decay_t; + + TDPCell cacheDiag; + TDPCell cacheVert; + _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqHValue, seqVValue, seqBegin, seqEnd, + scoringScheme, cacheDiag, cacheVert, TColumnDescriptor{}, TDPProfile{}); +} + // ---------------------------------------------------------------------------- // Function _computeUnbandedAlignmentHelperTerminate() // ---------------------------------------------------------------------------- @@ -418,16 +477,24 @@ _computeAlignmentHelperCheckTerminate(DPScout_ > cons // ---------------------------------------------------------------------------- // Computes the standard DP-algorithm. -template +template inline void -_computeUnbandedAlignment(TDPScout & scout, - TDPScoreMatrixNavigator & dpScoreMatrixNavigator, - TDPTraceMatrixNavigator & dpTraceMatrixNavigator, - TSequenceH const & seqH, - TSequenceV const & seqV, - TScoringScheme const & scoringScheme, - DPProfile_ const & dpProfile) +_computeAlignmentImpl(TDPScout & scout, + TDPScoreMatrixNavigator & dpScoreMatrixNavigator, + TDPTraceMatrixNavigator & dpTraceMatrixNavigator, + TSequenceH const & seqH, + TSequenceV const & seqV, + TScoringScheme const & scoringScheme, + TBand const & /*band*/, + DPProfile_ const & dpProfile, + NavigateColumnWise const & /*tag*/) { typedef typename Iterator::Type TConstSeqHIterator; typedef typename Iterator::Type TConstSeqVIterator; @@ -444,6 +511,7 @@ _computeUnbandedAlignment(TDPScout & scout, SEQAN_ASSERT_GT(length(seqH), 0u); SEQAN_ASSERT_GT(length(seqV), 0u); + _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, sequenceEntryForScore(scoringScheme, seqH, 0), sequenceEntryForScore(scoringScheme, seqV, 0), @@ -458,6 +526,7 @@ _computeUnbandedAlignment(TDPScout & scout, TConstSeqHIterator seqHIterEnd = end(seqH, Rooted()) - 1; for (; seqHIter != seqHIterEnd; ++seqHIter) { + _incHorizontalPos(scout); // We might only select it if SIMD version is available. if (SEQAN_UNLIKELY(_reachedHorizontalEndPoint(scout, seqHIter))) { @@ -480,13 +549,13 @@ _computeUnbandedAlignment(TDPScout & scout, { return; } - _incHorizontalPos(scout); } // ============================================================================ // POSTPROCESSING // ============================================================================ + _incHorizontalPos(scout); _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)), sequenceEntryForScore(scoringScheme, seqV, 0), @@ -504,22 +573,28 @@ _computeUnbandedAlignment(TDPScout & scout, } // ---------------------------------------------------------------------------- -// Function _computeBandedAlignment() +// Function _computeAlignment() banded // ---------------------------------------------------------------------------- // Computes the banded DP-algorithm. -template +template inline void -_computeBandedAlignment(TDPScout & scout, - TDPScoreMatrixNavigator & dpScoreMatrixNavigator, - TDPTraceMatrixNavigator & dpTraceMatrixNavigator, - TSequenceH const & seqH, - TSequenceV const & seqV, - TScoringScheme const & scoringScheme, - TBand const & band, - DPProfile_ const & dpProfile) +_computeAlignmentImpl(TDPScout & scout, + TDPScoreMatrixNavigator & dpScoreMatrixNavigator, + TDPTraceMatrixNavigator & dpTraceMatrixNavigator, + TSequenceH const & seqH, + TSequenceV const & seqV, + TScoringScheme const & scoringScheme, + TBand const & band, + DPProfile_ const & dpProfile, + NavigateColumnWiseBanded const & /*tag*/) { typedef DPProfile_ TDPProfile; typedef typename MakeSigned::Type>::Type TSignedSizeSeqH; @@ -527,7 +602,17 @@ _computeBandedAlignment(TDPScout & scout, typedef typename Iterator::Type TConstSeqHIterator; typedef typename Iterator::Type TConstSeqVIterator; + using TDPScoreValue = std::decay_t; + // Caching these cells improves performance significantly. + TDPScoreValue cacheDiag; + TDPScoreValue cacheVert; + if (upperDiagonal(band) == lowerDiagonal(band)) + { + _computeHammingDistance(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoringScheme, band, + dpProfile); + return; + } // Now we have the problem of not knowing when we are in the last cell. // ============================================================================ @@ -569,8 +654,7 @@ _computeBandedAlignment(TDPScout & scout, _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); // Only one cell _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), + cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert, sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)), sequenceEntryForScore(scoringScheme, seqV, 0), scoringScheme, MetaColumnDescriptor(), FirstCell(), TDPProfile()); @@ -586,8 +670,7 @@ _computeBandedAlignment(TDPScout & scout, _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); // Only one cell _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), + cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert, sequenceEntryForScore(scoringScheme, seqH, 0), sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)), scoringScheme, MetaColumnDescriptor(), FirstCell(), TDPProfile()); @@ -618,10 +701,10 @@ _computeBandedAlignment(TDPScout & scout, // Set the iterator to the begin of the track. _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); + //TODO(rrahn): We possibly need to set the cache values here? // Should we not just compute the cell? _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), + cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert, sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)), sequenceEntryForScore(scoringScheme, seqV, 0), scoringScheme, @@ -631,19 +714,24 @@ _computeBandedAlignment(TDPScout & scout, _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), False()); } else // Upper diagonal >= 0 and lower Diagonal < 0 - if (lowerDiagonal(band) <= -seqVlength) // The band is bounded by the top and bottom of the matrix. - _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, - sequenceEntryForScore(scoringScheme, seqH, 0), - sequenceEntryForScore(scoringScheme, seqV, 0), - seqVBegin, seqVEnd, scoringScheme, - MetaColumnDescriptor(), dpProfile); - else // The band is bounded by the top but not the bottom of the matrix. - _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, - sequenceEntryForScore(scoringScheme, seqH, 0), - sequenceEntryForScore(scoringScheme, seqV, 0), - seqVBegin, seqVEnd, scoringScheme, - MetaColumnDescriptor(), dpProfile); - + { + if (lowerDiagonal(band) <= -seqVlength) // The band is bounded by the top and bottom of the matrix. + { + _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, + sequenceEntryForScore(scoringScheme, seqH, 0), + sequenceEntryForScore(scoringScheme, seqV, 0), + seqVBegin, seqVEnd, scoringScheme, + MetaColumnDescriptor(), dpProfile); + } + else // The band is bounded by the top but not the bottom of the matrix. + { + _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, + sequenceEntryForScore(scoringScheme, seqH, 0), + sequenceEntryForScore(scoringScheme, seqV, 0), + seqVBegin, seqVEnd, scoringScheme, + MetaColumnDescriptor(), dpProfile); + } + } if (_computeAlignmentHelperCheckTerminate(scout)) { return; @@ -743,16 +831,20 @@ _computeBandedAlignment(TDPScout & scout, _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); + _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor()); + _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), + cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert, sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)), sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)), scoringScheme, MetaColumnDescriptor(), FirstCell(), TDPProfile()); // We might need to additionally track this point. if (TrackingEnabled_ >, LastCell>::VALUE) + { + _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert)); _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True()); + } } else if (seqHIter == end(seqH, Rooted()) - 1) // Case 2: The band ends somewhere in the final column of the matrix. { @@ -763,16 +855,20 @@ _computeBandedAlignment(TDPScout & scout, _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); + _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor()); + _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), - previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), - previousCellVertical(dpScoreMatrixNavigator), + cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert, sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)), sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)), scoringScheme, MetaColumnDescriptor(), FirstCell(), TDPProfile()); // we might need to additionally track this point. if (TrackingEnabled_ >, LastCell>::VALUE) + { + _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert)); _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True()); + } } else // Case2b: At least two cells intersect between the band and the matrix in the final column of the matrix. { @@ -795,10 +891,13 @@ _computeBandedAlignment(TDPScout & scout, _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)), sequenceEntryForScore(scoringScheme, seqV, 0), - seqVBegin, seqVEnd, scoringScheme, + seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert, MetaColumnDescriptor(), dpProfile); if (TrackingEnabled_ >, LastCell>::VALUE) + { + _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert)); _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True()); + } } else _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, @@ -820,10 +919,13 @@ _computeBandedAlignment(TDPScout & scout, _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)), sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1), - seqVBegin, seqVEnd, scoringScheme, + seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert, MetaColumnDescriptor(), dpProfile); if (TrackingEnabled_ >, LastCell>::VALUE) + { + _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert)); _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True()); + } } else { @@ -843,334 +945,24 @@ _computeBandedAlignment(TDPScout & scout, seqVBegin, seqVEnd, scoringScheme, MetaColumnDescriptor(), dpProfile); } - } } } } -// TODO(rmaerker): This is denbug code only. -//template -//inline void -//_debugBandedAlignment(TDPScout & scout, -// TDPScoreMatrixNavigator & dpScoreMatrixNavigator, -// TDPTraceMatrixNavigator & dpTraceMatrixNavigator, -// TSequenceH const & seqH, -// TSequenceV const & seqV, -// TScoringScheme const & scoringScheme, -// TBand const & band, -// DPProfile_ const & dpProfile) -//{ -// typedef DPProfile_ TDPProfile; -// typedef typename Value::Type TSeqHValue; -// typedef typename Value::Type TSeqVValue; -// typedef typename Iterator::Type TConstSeqHIterator; -// typedef typename Iterator::Type TConstSeqVIterator; -// -// -// String testMatrix; -// resize(testMatrix, (length(seqH) + 1) * (length(seqV)+1)); -// // Now we have the problem of not knowing when we are in the last cell. -// -// // INITIALIZATION -// TConstSeqVIterator seqVBegin = begin(seqV, Standard()) - _min(0, 1+upperDiagonal(band)); -// TConstSeqVIterator seqVEnd = begin(seqV, Standard()) - _min(0, _max(-static_cast(length(seqV)), lowerDiagonal(band))); -// -//// std::cout << "Begin Pos: " << seqVBegin - begin(seqV) << "\n"; -//// std::cout << "End Pos: " << seqVEnd - begin(seqV) << "\n"; -// -// // We have to distinguish two band sizes. Some which spans the whole matrix in between and thus who not. -// // This can be distinguished, if UpperDiagonal > length(seqV) + LowerDiagonal -// -// // We start at the least at the first sequence or wherever the lower diagonal begins first. -// TConstSeqHIterator seqHIterBegin = begin(seqH, Standard()) + _max(0, _min(static_cast(length(seqH) - 1), lowerDiagonal(band))); -// // TODO(rmaerker): Cehck if this assertion is correct. -//// SEQAN_ASSERT_NEQ(seqHIterBegin, end(seqH, Standard())); // The iterator never points to the end of the horizontal sequence. -// -// // The horizontal initial phase ends after the upper diagonal but at most after the horizontal sequence, or there is no horizontal initialization phase. -// TConstSeqHIterator seqHIterEndColumnTop = begin(seqH, Standard()) + _min(static_cast(length(seqH))-1, _max(0, upperDiagonal(band))); -// -// // 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. -// TConstSeqHIterator seqHIterEndColumnMiddle = begin(seqH, Standard()) + _min(static_cast(length(seqH))-1, _max(0,static_cast(length(seqV)) + lowerDiagonal(band))); -// // Swap the two iterators if we are in a band that spans over the full column. -// if (upperDiagonal(band) > static_cast(length(seqV)) + lowerDiagonal(band)) -// std::swap(seqHIterEndColumnTop, seqHIterEndColumnMiddle); -// -// // 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. -// TConstSeqHIterator seqHIterEndColumnBottom = begin(seqH, Standard()) + _max(0, _min(static_cast(length(seqH)), -// upperDiagonal(band) + static_cast(length(seqV))) -1); -// -//// std::cout << "seqHIterBegin Pos H: " << seqHIterBegin - begin(seqH) << "\n"; -//// std::cout << "seqHIterEndColumnTop Pos H: " << seqHIterEndColumnTop - begin(seqH) << "\n"; -//// std::cout << "seqHIterEndColumnMiddle Pos H: " << seqHIterEndColumnMiddle - begin(seqH) << "\n"; -//// std::cout << "seqHIterEndColumnBottom Pos H: " << seqHIterEndColumnBottom - begin(seqH) << "\n"; -//// -//// std::cout << "_activeColIterator Pos: " << dpScoreMatrixNavigator._activeColIterator - begin(*dpScoreMatrixNavigator._ptrDataContainer) << "\n"; -//// std::cout << "_prevColIterator Pos: " << dpScoreMatrixNavigator._prevColIterator - begin(*dpScoreMatrixNavigator._ptrDataContainer) << "\n"; -// -// // The Initial column can be PartialColumnTop which is given if the upper diagonal is >= 0, -// // otherwise it only can be PartialColumnMiddle or PartialColumnBottom depending where the lower diagonal is. -// -// // Have to check for single initialization cells in InitialColumn and FinalColumn. -// if (seqHIterBegin == end(seqH)-1) -// { -// // Set the iterator to the begin of the track. -// _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// // Only one cell -// _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), -// previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), -// previousCellVertical(dpScoreMatrixNavigator), value(seqHIterBegin), TSeqVValue(), scoringScheme, -// MetaColumnDescriptor(), FirstCell(), TDPProfile()); -//// std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n"; -// std::stringstream stream; -// stream << _scoreOfCell(value(dpScoreMatrixNavigator)); -// testMatrix[length(seqH) * length(seqV)] = stream.str(); -// // we might need to additionally track this point. -// if (TrackingEnabled_ >, FirstCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// return; -// } -// if (seqHIterEndColumnBottom == begin(seqH)) -// { -// // Set the iterator to the begin of the track. -// _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// // Only one cell -// _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), -// previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), -// previousCellVertical(dpScoreMatrixNavigator), TSeqHValue(), value(seqVBegin), scoringScheme, -// MetaColumnDescriptor(), FirstCell(), TDPProfile()); -//// std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n"; -// std::stringstream stream; -// stream << _scoreOfCell(value(dpScoreMatrixNavigator)); -// testMatrix[length(seqH) * length(seqV)] = stream.str(); -// // We might need to additionally track this point. -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// return; -// } -// -// if (upperDiagonal(band) < 0) -// { -// ++seqVBegin; -// if (lowerDiagonal(band) > -static_cast(length(seqV))) -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// TSeqHValue(), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, 0, seqVBegin - begin(seqV) + 1, testMatrix); -// else -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// TSeqHValue(), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, 0, seqVBegin - begin(seqV) + 1, testMatrix); -// } -// else if (lowerDiagonal(band) >= 0) -// { -// // Set the iterator to the begin of the track. -// _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// // Should we not just compute the cell? -// _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), -// previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), -// previousCellVertical(dpScoreMatrixNavigator), value(seqHIterBegin), TSeqVValue(), scoringScheme, -// MetaColumnDescriptor(), FirstCell(), TDPProfile()); -// // we might need to additionally track this point. -//// std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n"; -// int col = lowerDiagonal(band); -// std::stringstream stream; -// stream << _scoreOfCell(value(dpScoreMatrixNavigator)); -// testMatrix[col * (length(seqV) + 1)] = stream.str(); -// if (TrackingEnabled_ >, FirstCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// else // Upper diagonal >= 0 and lower Diagonal < 0 -// if (lowerDiagonal(band) <= -static_cast(length(seqV))) // The band is bounded by the top and bottom of the matrix. -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// TSeqHValue(), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, 0, 0, testMatrix); -// else // The band is bounded by the top but not the bottom of the matrix. -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// TSeqHValue(), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, 0,0, testMatrix); -// -// -// // RECURSION -// TConstSeqHIterator seqHIter = seqHIterBegin; -// // Compute the first part of the band, where the band is bounded by the top but not by the bottom of the matrix. -// for (;seqHIter != seqHIterEndColumnTop; ++seqHIter) -// { -//// std::cout << value(seqHIter) << ":\t"; -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, ((seqHIter - begin(seqH)) + 1)*(length(seqV) +1), 0, testMatrix); -// } -// -// // Check whether the band spans over the full column or not at some point. -// if (upperDiagonal(band) > static_cast(length(seqV)) + lowerDiagonal(band)) -// { -// // Compute the second part of the band, where the band is bounded by the top and the bottom of the matrix. -// // We might want to track the current cell here, since this is the first cell that crosses the bottom. -// // TODO(rmaerker): We have to check if the initial column/ row can be tracked!!! -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// for (;seqHIter != seqHIterEndColumnMiddle; ++seqHIter) -// { -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, (seqHIter - begin(seqH) + 1) * (length(seqV) + 1), 0, testMatrix); -// } -// } -// else // Compute the second part of the band, where the band is not bounded by the top and bottom of the matrix -// { -// for (;seqHIter != seqHIterEndColumnMiddle; ++seqHIter) -// { -// ++seqVBegin; -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, (seqHIter - begin(seqH) +1) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix); -// } // We might want to track the current cell here, since this is the first cell that crosses the bottom. -// if (TrackingEnabled_ >, LastCell>::VALUE) -// { -// // TODO(rmaerker): This is only a hot fix. -// if (lowerDiagonal(band) + length(seqV) < length(seqH)) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// } -// // Compute the third part of the band, where the band, is bounded by the bottom but not by the top of the matrix. -// for (;seqHIter != seqHIterEndColumnBottom; ++seqHIter) -// { -// ++seqVBegin; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, (seqHIter - begin(seqH) + 1) * (length(seqV) + 1), seqVBegin - begin(seqV), testMatrix); -// } -// -// // Where ends the last cell? -// if(seqHIter - begin(seqH) < static_cast(length(seqH))-1) // Case 1: The band ends before the final column is reached. -// { -// // Set the iterator to the begin of the track. -// _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// -// _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), -// previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), -// previousCellVertical(dpScoreMatrixNavigator), value(seqHIter), value(seqVBegin), scoringScheme, -// MetaColumnDescriptor(), FirstCell(), TDPProfile()); -//// std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n"; -// std::stringstream stream; -// stream << _scoreOfCell(value(dpScoreMatrixNavigator)); -// testMatrix[(seqHIter - begin(seqH) + 1) * (length(seqV) + 1) + length(seqV)] = stream.str(); -// // We might need to additionally track this point. -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// else if(seqHIter == end(seqH)-1) // Case 2: The band ends somewhere in the final column of the matrix. -// { -// if (upperDiagonal(band) == static_cast(length(seqH))-static_cast(length(seqV))) // Case2a: The band ends in the last cell of the final column. // He should be here.... -// { -// // Set the iterator to the begin of the track. -// _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); -// -// _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator), -// previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator), -// previousCellVertical(dpScoreMatrixNavigator), value(seqHIter), value(seqVBegin), scoringScheme, -// MetaColumnDescriptor(), FirstCell(), TDPProfile()); -//// std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n"; -// std::stringstream stream; -// stream << _scoreOfCell(value(dpScoreMatrixNavigator)); -// testMatrix[(length(seqH) * (length(seqV) + 1)) + length(seqV)] = stream.str(); -// // we might need to additionally track this point. -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// else // Case2b: At least two cells intersect between the band and the matrix in the final column of the matrix. -// { -// if (upperDiagonal(band) >= static_cast(length(seqH))) // The band is bounded by the top of the matrix only or by the top and the bottom. -// { -// if (lowerDiagonal(band) + static_cast(length(seqV)) > static_cast(length(seqH))) // The band is bounded by the top of the matrix -// { -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV) + 1), 0, testMatrix); -// } -// else // The band is bounded by the top and the bottom of the matrix. -// { -// if (lowerDiagonal(band) + static_cast(length(seqV)) + 1 > static_cast(length(seqH)) ) -// { -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV) + 1), 0, testMatrix); -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// else -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV) +1), 0, testMatrix); -// -// } -// -// } -// else // The band is bounded by bottom of matrix or completely unbounded. -// { -// ++seqVBegin; -// if (lowerDiagonal(band) + length(seqV) <= length(seqH)) // The band is bounded by the bottom of the matrix. -// { -// if (lowerDiagonal(band) + length(seqV) == length(seqH)) -// { -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix); -// if (TrackingEnabled_ >, LastCell>::VALUE) -// _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator); -// } -// else -// { -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV) + 1), seqVBegin - begin(seqV), testMatrix); -// } -// } -// else // The band is unbounded by the matrix. -// { -// ++seqVEnd; -// _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, -// value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme, -// MetaColumnDescriptor(), dpProfile, length(seqH) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix); -// } -// -// } -// } -// } -// -// for (unsigned i = 0; i <= length(seqV); ++i) -// { -// for (unsigned j = 0; j <= length(seqH); ++j) -// { -// unsigned pos = j * (length(seqV) + 1) + i; -// //if (!testMatrix[pos].empty()) -// std::cout << testMatrix[pos] << "\t" << std::flush; -// } -// std::cout << std::endl; -// } -// -//} - // ---------------------------------------------------------------------------- // Function _computeHammingDistance() // ---------------------------------------------------------------------------- // Computes the Hamming-Distance if the band-size is 1. -template +template inline void _computeHammingDistance(TDPScout & scout, TDPScoreMatrixNavigator & dpScoreMatrixNavigator, @@ -1179,7 +971,7 @@ _computeHammingDistance(TDPScout & scout, TSequenceV const & seqV, TScoringScheme const & scoringScheme, TBand const & band, - DPProfile_ const &) + DPProfile_ const &) { typedef typename MakeSigned::Type>::Type TSignedSizeSeqH; typedef typename MakeSigned::Type>::Type TSignedSizeSeqV; @@ -1201,8 +993,9 @@ _computeHammingDistance(TDPScout & scout, TConstSeqVIterator itV = begin(seqV, Rooted()) + _max(0, _min(seqVlength - 1, -lowerDiagonal(band))); TConstSeqVIterator itVEnd = begin(seqV, Rooted()) + _min(seqVlength - 1, lowerDiagonal(band) + seqHlength); + TDPCell dummy; assignValue(dpTraceMatrixNavigator, - _computeScore(value(dpScoreMatrixNavigator), TDPCell(), TDPCell(), TDPCell(), + _computeScore(value(dpScoreMatrixNavigator), dummy, dummy, dummy, sequenceEntryForScore(scoringScheme, seqH, position(itH)), sequenceEntryForScore(scoringScheme, seqV, position(itV)), scoringScheme, RecursionDirectionZero(), TDPProfile())); @@ -1252,7 +1045,7 @@ _computeHammingDistance(TDPScout & scout, _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor(), FirstCell()); _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); assignValue(dpTraceMatrixNavigator, - _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, TDPCell(), TDPCell(), + _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy, sequenceEntryForScore(scoringScheme, seqH, position(itH)), sequenceEntryForScore(scoringScheme, seqV, position(itV)), scoringScheme, RecursionDirectionDiagonal(), TDPProfile())); @@ -1271,7 +1064,7 @@ _computeHammingDistance(TDPScout & scout, _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor(), FirstCell()); assignValue(dpTraceMatrixNavigator, - _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, TDPCell(), TDPCell(), + _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy, sequenceEntryForScore(scoringScheme, seqH, position(itH)), sequenceEntryForScore(scoringScheme, seqV, position(itV)), scoringScheme, RecursionDirectionDiagonal(), TDPProfile())); @@ -1293,6 +1086,29 @@ _computeHammingDistance(TDPScout & scout, } } +// ---------------------------------------------------------------------------- +// Function _printScoreMatrix() +// ---------------------------------------------------------------------------- + +template +void _printScoreMatrix(TTraceMatrix & scoreMatrix) +{ + typedef typename Size::Type TSize; + TSize dimH = length(scoreMatrix, +DPMatrixDimension_::HORIZONTAL); + TSize dimV = length(scoreMatrix, +DPMatrixDimension_::VERTICAL); + + for (unsigned row = 0; row < dimV; ++row) + { + for (unsigned column = 0; column < dimH; ++column) + if (_scoreOfCell(value(scoreMatrix, row + column * dimV)) <= DPCellDefaultInfinity>::VALUE) + std::cout << "-∞\t"; + else + std::cout << _scoreOfCell(value(scoreMatrix, row + column * dimV)) << "\t"; + std::cout << std::endl; + } + std::cout << std::endl; +} + // ---------------------------------------------------------------------------- // Function _printTracebackMatrix() // ---------------------------------------------------------------------------- @@ -1373,9 +1189,15 @@ inline SEQAN_FUNC_ENABLE_IF(Is >, void) _correctTraceValue(TTraceNavigator & traceNavigator, DPScout_, TDPScoutSpec> const & dpScout) { - _setToPosition(traceNavigator, maxHostPosition(dpScout)); - TScoreValue cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)); - TScoreValue cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)); + using TMaskType = typename SimdMaskVector::Type; + _setToPosition(traceNavigator, toGlobalPosition(traceNavigator, + maxHostCoordinate(dpScout, +DPMatrixDimension_::HORIZONTAL), + maxHostCoordinate(dpScout, +DPMatrixDimension_::VERTICAL))); + TMaskType flag = createVector(0); + assignValue(flag, dpScout._simdLane, -1); + auto cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag; + auto cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag; + value(traceNavigator) = blend(value(traceNavigator), value(traceNavigator) & ~TraceBitMap_::DIAGONAL, cmpV | cmpH); @@ -1410,9 +1232,13 @@ inline SEQAN_FUNC_ENABLE_IF(Is >, void) _correctTraceValue(TTraceNavigator & traceNavigator, DPScout_, TDPScoutSpec> const & dpScout) { + using TMaskType = typename SimdMaskVector::Type; + _setToPosition(traceNavigator, maxHostPosition(dpScout)); - TScoreValue cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()); - TScoreValue cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()); + TMaskType flag = createVector(0); + assignValue(flag, dpScout._simdLane, -1); + auto cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()) & flag; + auto cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()) & flag; value(traceNavigator) = blend(value(traceNavigator), value(traceNavigator) & ~TraceBitMap_::DIAGONAL, cmpV | cmpH); @@ -1434,7 +1260,7 @@ template + typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy> inline SEQAN_FUNC_ENABLE_IF(Not >, TScoreValue) _finishAlignment(TTraceTarget & /*traceSegments*/, TTraceMatNavigator & /*dpTraceMatrixNavigator*/, @@ -1442,7 +1268,7 @@ _finishAlignment(TTraceTarget & /*traceSegments*/, TSeqH const & /*seqH*/, TSeqV const & /*seqV*/, DPBandConfig const & /*band*/, - DPProfile_ const & /*dpProfile*/) + DPProfile_ const & /*dpProfile*/) { return maxScore(dpScout); } @@ -1453,7 +1279,7 @@ template + typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy> inline SEQAN_FUNC_ENABLE_IF(And >, IsTracebackEnabled_ >, TScoreValue) _finishAlignment(TTraceTarget & traceSegments, TTraceMatNavigator & dpTraceMatrixNavigator, @@ -1461,7 +1287,7 @@ _finishAlignment(TTraceTarget & traceSegments, TSeqH const & seqH, TSeqV const & seqV, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { typedef typename Size::Type TSize; @@ -1474,7 +1300,11 @@ _finishAlignment(TTraceTarget & traceSegments, { _correctTraceValue(dpTraceMatrixNavigator, scout); } - _computeTraceback(traceSegments[i], dpTraceMatrixNavigator, scout, _hostLengthH(scout, seqH), + _computeTraceback(traceSegments[i], dpTraceMatrixNavigator, + toGlobalPosition(dpTraceMatrixNavigator, + maxHostCoordinate(scout, +DPMatrixDimension_::HORIZONTAL), + maxHostCoordinate(scout, +DPMatrixDimension_::VERTICAL)), + _hostLengthH(scout, seqH), _hostLengthV(scout, seqV), band, dpProfile); } return maxScore(scout); @@ -1486,7 +1316,7 @@ template + typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy> inline SEQAN_FUNC_ENABLE_IF(And > >, IsTracebackEnabled_ >, TScoreValue) _finishAlignment(TTraceTarget & traceSegments, TTraceMatNavigator & dpTraceMatrixNavigator, @@ -1494,7 +1324,7 @@ _finishAlignment(TTraceTarget & traceSegments, TSeqH const & seqH, TSeqV const & seqV, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { if (IsSingleTrace_::VALUE) _correctTraceValue(dpTraceMatrixNavigator, dpScout); @@ -1507,38 +1337,45 @@ _finishAlignment(TTraceTarget & traceSegments, // Function _computeAligmnment() // ---------------------------------------------------------------------------- -template +template inline typename Value::Type -_computeAlignment(DPContext & dpContext, +_computeAlignment(DPContext & dpContext, TTraceTarget & traceSegments, TScoutState & scoutState, TSequenceH const & seqH, TSequenceV const & seqV, TScoreScheme const & scoreScheme, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { - typedef typename GetDPScoreMatrix >::Type TDPScoreMatrixHost; - typedef typename Value::Type TDPScoreValue; - - typedef typename GetDPTraceMatrix >::Type TDPTraceMatrixHost; - typedef typename Value::Type TTraceValue; typedef typename DefaultScoreMatrixSpec_::Type TScoreMatrixSpec; - typedef DPMatrix_ TDPScoreMatrix; - typedef DPMatrix_ TDPTraceMatrix; + typedef DPMatrix_ TDPScoreMatrix; + typedef DPMatrix_ TDPTraceMatrix; + + using TNavigationSpec = std::conditional_t::value, + NavigateColumnWise, + NavigateColumnWiseBanded>; - typedef DPMatrixNavigator_ TDPScoreMatrixNavigator; - typedef DPMatrixNavigator_, NavigateColumnWise> TDPTraceMatrixNavigator; + typedef DPMatrixNavigator_ TDPScoreMatrixNavigator; + typedef DPMatrixNavigator_, TNavigationSpec> TDPTraceMatrixNavigator; typedef typename ScoutSpecForAlignmentAlgorithm_::Type TDPScoutSpec; typedef DPScout_ TDPScout; + typedef typename Value::Type TScoreValue; + // Check if current dp settings are valid. If not return infinity value for dp score value. if (!_isValidDPSettings(seqH, seqV, band, dpProfile)) - return createVector(MinValue::Type>::VALUE); // NOTE(rrahn): In case of non-simd version, createVector returns just a scalar. + return createVector(std::numeric_limits::Type>::min()); // NOTE(rrahn): In case of non-simd version, createVector returns just a scalar. TDPScoreMatrix dpScoreMatrix; TDPTraceMatrix dpTraceMatrix; @@ -1547,7 +1384,7 @@ _computeAlignment(DPContext & dpContext, setLength(dpScoreMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band))); setLength(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band))); - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) { setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1); setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1); @@ -1568,11 +1405,8 @@ _computeAlignment(DPContext & dpContext, if (IsTracebackEnabled_::VALUE) resize(dpTraceMatrix); - TDPScoreMatrixNavigator dpScoreMatrixNavigator; - TDPTraceMatrixNavigator dpTraceMatrixNavigator; - - _init(dpScoreMatrixNavigator, dpScoreMatrix, band); - _init(dpTraceMatrixNavigator, dpTraceMatrix, band); + TDPScoreMatrixNavigator dpScoreMatrixNavigator{dpScoreMatrix, band}; + TDPTraceMatrixNavigator dpTraceMatrixNavigator{dpTraceMatrix, band}; TDPScout dpScout(scoutState); #if SEQAN_ALIGN_SIMD_PROFILE @@ -1580,17 +1414,8 @@ _computeAlignment(DPContext & dpContext, timer = sysTime(); #endif // Execute the alignment. - if (!_isBandEnabled(band)) - _computeUnbandedAlignment(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, dpProfile); - else if (upperDiagonal(band) == lowerDiagonal(band)) - _computeHammingDistance(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, band, dpProfile); - else - _computeBandedAlignment(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, - band, dpProfile); - - // RRW: THROW AN EXCEPTION IF THE SCORE LOOKS BAD! - if (maxScore(dpScout) < -1000000) - throw std::runtime_error("Bad Seqan alignment score\n"); + _computeAlignmentImpl(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, band, + dpProfile, TNavigationSpec{}); #if SEQAN_ALIGN_SIMD_PROFILE profile.alignTimer += sysTime() - timer; diff --git a/porechop/include/seqan/align/dp_align_simd_helper.h b/porechop/include/seqan/align/dp_align_simd_helper.h index 8fd634a..124f7f0 100644 --- a/porechop/include/seqan/align/dp_align_simd_helper.h +++ b/porechop/include/seqan/align/dp_align_simd_helper.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -69,12 +69,13 @@ struct VectorLength_; // Tags, Classes, Enums // ============================================================================ -template +template struct SimdAlignVariableLengthTraits { using TSimdVector = TSimdVector_; using TSeqH = TSeqH_; using TSeqV = TSeqV_; + using TDPProfile = TDPProfile_; }; // ============================================================================ @@ -89,38 +90,27 @@ struct SimdAlignVariableLengthTraits // Function _createSimdRepImpl() // ---------------------------------------------------------------------------- -#define SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos, chrPos) getValue(data[strPos + 1], chrPos), getValue(data[strPos], chrPos) -#define SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos, chrPos) SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos + 2, chrPos), SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos, chrPos) -#define SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos, chrPos) SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos + 4, chrPos), SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos, chrPos) -#define SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos, chrPos) SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos + 8, chrPos), SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos, chrPos) -#define SEQAN_CREATE_SIMD_REP_IMPL_32(data, strPos, chrPos) SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos + 16, chrPos), SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos, chrPos) - -#define SEQAN_CREATE_SIMD_REP_FILL_IMPL_2(MACRO, data, chrPos) MACRO(data, 0, chrPos) -#define SEQAN_CREATE_SIMD_REP_FILL_IMPL(data, chrPos, SIZE) SEQAN_CREATE_SIMD_REP_FILL_IMPL_2(SEQAN_CREATE_SIMD_REP_IMPL_##SIZE, data, chrPos) - -#define SEQAN_CREATE_SIMD_REP_IMPL(SIZE) \ -template \ -inline void _createSimdRepImpl(TSimdVecs & simdStr, \ - TStrings const & strings, \ - VectorLength_ const & /*size*/) \ -{ \ - auto itB = begin(simdStr, Standard()); \ - auto itE = end(simdStr, Standard()); \ - for (auto it = itB; it != itE; ++it) \ - fillVector(*it, SEQAN_CREATE_SIMD_REP_FILL_IMPL(strings, it - itB, SIZE)); \ +template +inline void +_createSimdRepImpl(TSimdVecs & vecs, + TStrings const & strs, + std::index_sequence const & /*unsued*/) +{ + for (size_t pos = 0; pos < length(vecs); ++pos) + fillVector(vecs[pos], strs[I][pos]...); } -SEQAN_CREATE_SIMD_REP_IMPL(2) -SEQAN_CREATE_SIMD_REP_IMPL(4) -SEQAN_CREATE_SIMD_REP_IMPL(8) -SEQAN_CREATE_SIMD_REP_IMPL(16) -SEQAN_CREATE_SIMD_REP_IMPL(32) - -template -inline void _createSimdRepImpl(TSimdVecs & simdStr, - TStrings const & strings) +template +inline void +_createSimdRepImpl(TSimdVecs & simdStr, + TStrings const & strings) { - _createSimdRepImpl(simdStr, strings, VectorLength_::Type>::VALUE>()); + using TSimdVec = typename Value::Type; + constexpr auto length = LENGTH::VALUE; + _createSimdRepImpl(simdStr, strings, std::make_index_sequence()); } // Actually precompute value if scoring scheme is score matrix and simd version. @@ -137,96 +127,73 @@ _precomputeScoreMatrixOffset(TSeqValue const & seqVal, // Function _prepareAndRunSimdAlignment() // ---------------------------------------------------------------------------- -template + typename TSequencesV> inline void -_prepareAndRunSimdAlignment(TResult & results, - TTraces & traces, - TSequencesH const & seqH, - TSequencesV const & seqV, - TScore const & scoringScheme, - AlignConfig2 const & alignConfig, - TGapModel const & /*gapModel*/, - SimdAlignEqualLength const & /*tag*/) +_prepareSimdAlignment(TStringSimdH & stringSimdH, + TStringSimdV & stringSimdV, + TSequencesH const & seqH, + TSequencesV const & seqV, + DPScoutState_ const & /*unused*/) { - String > stringSimdH; - String > stringSimdV; - resize(stringSimdH, length(seqH[0])); resize(stringSimdV, length(seqV[0])); _createSimdRepImpl(stringSimdH, seqH); _createSimdRepImpl(stringSimdV, seqV); - - DPScoutState_ state; - results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel()); } -template inline void -_prepareAndRunSimdAlignment(TResult & results, - TTraces & traces, - TSequencesH const & seqH, - TSequencesV const & seqV, - TScore const & scoringScheme, - AlignConfig2 const & alignConfig, - TGapModel const & /*gapModel*/, - SimdAlignVariableLength const /*tag*/) +_prepareSimdAlignment(TStringSimdH & stringSimdH, + TStringSimdV & stringSimdV, + TSequencesH const & seqH, + TSequencesV const & seqV, + String & lengthsH, + String & lengthsV, + DPScoutState_ > & state) { SEQAN_ASSERT_EQ(length(seqH), length(seqV)); - SEQAN_ASSERT_EQ(static_cast(LENGTH::VALUE), length(seqH)); + SEQAN_ASSERT_EQ(static_cast(LENGTH::Type>::VALUE), length(seqH)); + + using TSimdVector = typename TTraits::TSimdVector; + using TSimdValueType = typename Value::Type; using TPadStringH = ModifiedString::Type, ModPadding>; using TPadStringV = ModifiedString::Type, ModPadding>; - String > stringSimdH; - String > stringSimdV; - - DPScoutState_ > > state; - - String lengthsH; - String lengthsV; - - resize(lengthsH, length(seqH)); - resize(lengthsV, length(seqV)); - resize(state.endsH, length(seqH)); - resize(state.endsV, length(seqV)); + resize(lengthsH, length(seqH), Exact{}); + resize(lengthsV, length(seqV), Exact{}); for (unsigned i = 0; i < length(seqH); ++i) { - lengthsH[i] = length(seqH[i]) - 1; - lengthsV[i] = length(seqV[i]) - 1; - state.endsH[i] = i; - state.endsV[i] = i; + lengthsH[i] = length(seqH[i]); + lengthsV[i] = length(seqV[i]); } - setHost(state.sortedEndsH, lengthsH); - setHost(state.sortedEndsV, lengthsV); - setCargo(state.sortedEndsH, state.endsH); - setCargo(state.sortedEndsV, state.endsV); - + // Sort and remove unique elements from length vectors. auto maxLengthLambda = [](auto& lengthLhs, auto& lengthRhs) { return lengthLhs < lengthRhs; }; - sort(state.sortedEndsH, maxLengthLambda, Serial()); - sort(state.sortedEndsV, maxLengthLambda, Serial()); + std::sort(begin(lengthsH, Standard{}), end(lengthsH, Standard{}), maxLengthLambda); + std::sort(begin(lengthsV, Standard{}), end(lengthsV, Standard{}), maxLengthLambda); - size_t maxH = back(state.sortedEndsH) + 1; - size_t maxV = back(state.sortedEndsV) + 1; + erase(lengthsH, + std::unique(begin(lengthsH, Standard{}), end(lengthsH, Standard{})) - begin(lengthsH, Standard{}), + length(lengthsH)); + erase(lengthsV, + std::unique(begin(lengthsV, Standard{}), end(lengthsV, Standard{})) - begin(lengthsV, Standard{}), + length(lengthsV)); - // and we have to prepare the bit masks of the DPScoutState - resize(state.masks, maxV, createVector(0)); - resize(state.masksV, maxV, createVector(0)); - resize(state.masksH, maxH, createVector(0)); + // Initialize iterator to the lengths vectors. + state.nextEndsH = begin(lengthsH, Rooted{}); + state.nextEndsV = begin(lengthsV, Rooted{}); + + size_t maxH = back(lengthsH); + size_t maxV = back(lengthsV); // Create Stringset with padded strings. StringSet paddedH; @@ -241,9 +208,9 @@ _prepareAndRunSimdAlignment(TResult & results, expand(paddedH[i], maxH); expand(paddedV[i], maxV); - // mark the original end position of the alignment in the masks (with -1, all bits set) - assignValue(state.masksH[lengthsH[i]], i, -1); - assignValue(state.masksV[lengthsV[i]], i, -1); + // Store the end points as vector in both dimensions. + assignValue(state.endPosVecH, i, static_cast(length(seqH[i]))); + assignValue(state.endPosVecV, i, static_cast(length(seqV[i]))); } // now create SIMD representation @@ -251,13 +218,6 @@ _prepareAndRunSimdAlignment(TResult & results, resize(stringSimdV, maxV); _createSimdRepImpl(stringSimdH, paddedH); _createSimdRepImpl(stringSimdV, paddedV); - - state.dimV = length(stringSimdV); - state.isLocalAlignment = IsLocalAlignment_::VALUE; - state.right = IsFreeEndGap_::VALUE; - state.bottom = IsFreeEndGap_::VALUE; - - results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel()); } template (param)) == seqLengthH) && - (length(std::get<1>(param)) == seqLengthV); + (length(std::get<1>(param)) == seqLengthV); }); + + String > stringSimdH; + String > stringSimdV; if(allSameLength) - _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(), SimdAlignEqualLength()); + { + DPScoutState_ state; + _prepareSimdAlignment(stringSimdH, stringSimdV, seqH, seqV, state); + results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel()); + } else - _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(), - SimdAlignVariableLength()); + { + using TDPProfile = typename SetupAlignmentProfile_::Type; + + DPScoutState_>> state; + String lengthsH; + String lengthsV; + _prepareSimdAlignment(stringSimdH, stringSimdV, seqH, seqV, lengthsH, lengthsV, state); + + results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel()); + } } // ---------------------------------------------------------------------------- // Function _alignWrapperSimd(); Score; StringSet vs. StringSet // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Is::Type>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSimd(StringSet const & stringsH, - StringSet const & stringsV, +_alignWrapperSimd(TSetH const & stringsH, + TSetV const & stringsV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) { - typedef typename SimdVector::Type TSimdAlign; + typedef typename SimdVector::Type TSimdAlign; unsigned const numAlignments = length(stringsV); unsigned const sizeBatch = LENGTH::VALUE; @@ -327,8 +311,8 @@ _alignWrapperSimd(StringSet const & stringsH, TSimdAlign resultsBatch; if (SEQAN_UNLIKELY(numAlignments < pos + sizeBatch)) { - StringSet > depSetH; - StringSet > depSetV; + StringSet::Type>, Dependent<> > depSetH; + StringSet::Type>, Dependent<> > depSetV; for (unsigned i = pos; i < fullSize; ++i) { if (i >= numAlignments) @@ -366,19 +350,25 @@ _alignWrapperSimd(StringSet const & stringsH, // Function _alignWrapperSimd(); Score; String vs. StringSet // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Not::Type>>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSimd(TString1 const & stringH, - StringSet const & stringsV, +_alignWrapperSimd(TSeqH const & stringH, + TSetV const & stringsV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) { - typedef typename SimdVector::Type TSimdAlign; + typedef typename SimdVector::Type TSimdAlign; unsigned const numAlignments = length(stringsV); unsigned const sizeBatch = LENGTH::VALUE; @@ -388,7 +378,7 @@ _alignWrapperSimd(TString1 const & stringH, resize(results, numAlignments); // Prepare strings. - StringSet > setH; + StringSet > setH; for (auto i = 0u; i < sizeBatch; ++i) appendValue(setH, stringH); @@ -402,7 +392,7 @@ _alignWrapperSimd(TString1 const & stringH, TSimdAlign resultsBatch; if (SEQAN_UNLIKELY(numAlignments < pos + sizeBatch)) { - StringSet > depSetV; + StringSet::Type>, Dependent<> > depSetV; for (unsigned i = pos; i < fullSize; ++i) { if (i >= numAlignments) @@ -430,25 +420,31 @@ _alignWrapperSimd(TString1 const & stringH, // Function _alignWrapperSimd(); Gaps // ---------------------------------------------------------------------------- -template + typename TGapModel, + std::enable_if_t>, + Is::Type>>>, + And>, + Is::Type>>> + >::VALUE, + int> = 0> inline auto -_alignWrapperSimd(StringSet, TSetSpecH> & gapSeqSetH, - StringSet, TSetSpecV> & gapSeqSetV, +_alignWrapperSimd(TSetH & gapSeqSetH, + TSetV & gapSeqSetV, Score const & scoringScheme, TAlignConfig const & config, TGapModel const & /*gaps*/) { - typedef Gaps TGapSequenceH; - typedef Gaps TGapSequenceV; + typedef typename Value::Type TGapSequenceH; + typedef typename Value::Type TGapSequenceV; typedef typename Size::Type TSize; typedef typename Position::Type TPosition; typedef TraceSegment_ TTraceSegment; - typedef typename SimdVector::Type TSimdAlign; + typedef typename SimdVector::Type TSimdAlign; #if SEQAN_ALIGN_SIMD_PROFILE timer = sysTime(); @@ -465,8 +461,8 @@ _alignWrapperSimd(StringSet, TSetSpecH> & gapSeqSet Score > > simdScoringScheme(scoringScheme); // Prepare string sets with sequences. - StringSet::Type, Dependent<> > depSetH; - StringSet::Type, Dependent<> > depSetV; + StringSet::Type>, Dependent<> > depSetH; + StringSet::Type>, Dependent<> > depSetV; reserve(depSetH, fullSize); reserve(depSetV, fullSize); for (unsigned i = 0; i < fullSize; ++i) @@ -514,4 +510,3 @@ _alignWrapperSimd(StringSet, TSetSpecH> & gapSeqSet } // namespace seqan #endif // #ifndef INCLUDE_SEQAN_ALIGN_DP_ALIGN_SIMD_HELPER_H_ - diff --git a/porechop/include/seqan/align/dp_band.h b/porechop/include/seqan/align/dp_band.h index b636d50..16c3c6b 100644 --- a/porechop/include/seqan/align/dp_band.h +++ b/porechop/include/seqan/align/dp_band.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/dp_cell.h b/porechop/include/seqan/align/dp_cell.h index 49f3b85..a73868c 100644 --- a/porechop/include/seqan/align/dp_cell.h +++ b/porechop/include/seqan/align/dp_cell.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -50,6 +50,12 @@ namespace seqan { // Tags, Classes, Enums // ============================================================================ +struct DynamicGapExtensionHorizontal_; +typedef Tag DynamicGapExtensionHorizontal; + +struct DynamicGapExtensionVertical_; +typedef Tag DynamicGapExtensionVertical; + // ---------------------------------------------------------------------------- // Class DPCell_ // ---------------------------------------------------------------------------- @@ -65,6 +71,21 @@ class DPCell_; // Metafunctions // ============================================================================ +// ---------------------------------------------------------------------------- +// Metafunction Spec +// ---------------------------------------------------------------------------- + +template +struct Spec > +{ + typedef TGapCostFunction Type; +}; + +template +struct Spec const> : + Spec > +{}; + // ---------------------------------------------------------------------------- // Metafunction Value // ---------------------------------------------------------------------------- @@ -109,7 +130,7 @@ struct DPCellDefaultInfinity }; template -const int DPCellDefaultInfinity::VALUE = MinValue::VALUE; +const int DPCellDefaultInfinity::VALUE = std::numeric_limits::min(); // We use the min value of the score type and shift it one bits to the left. This way we can use "infinity" without // checking for it during the computation. @@ -121,7 +142,7 @@ struct DPCellDefaultInfinity > template const TScoreValue DPCellDefaultInfinity >::VALUE = - createVector(MinValue::Type>::VALUE) / createVector(2); + createVector(std::numeric_limits::Type>::min()) / createVector(2); template struct DPCellDefaultInfinity const> : @@ -177,9 +198,16 @@ _setScoreOfCell(DPCell_ & dpCell, TScoreValue const & ne dpCell._score = newScore; } -template +template inline void -_setScoreOfCell(DPCell_ & dpCell, TScoreValue const & newScore, TScoreValue const & mask) +_setScoreOfCell(DPCell_ & dpCell, TScoreValue const & newScore) +{ + dpCell._score = newScore; +} + +template +inline void +_setScoreOfCell(DPCell_ & dpCell, TScoreValue const & newScore, TMask const & mask) { dpCell._score = blend(dpCell._score, newScore, mask); } @@ -215,9 +243,9 @@ _setVerticalScoreOfCell(DPCell_ & /*dpCell*/, TScoreValue // no-op } -template +template inline void -_setVerticalScoreOfCell(DPCell_ & /*dpCell*/, TScoreValue const & /*newVerticalScore*/, TScoreValue const & /*mask*/) +_setVerticalScoreOfCell(DPCell_ & /*dpCell*/, TScoreValue const & /*newVerticalScore*/, TMask const & /*mask*/) { // no-op } @@ -253,9 +281,9 @@ _setHorizontalScoreOfCell(DPCell_ & /*dpCell*/, TScoreVal // no-op } -template +template inline void -_setHorizontalScoreOfCell(DPCell_ & /*dpCell*/, TScoreValue const & /*newHorizontalScore*/, TScoreValue const & /*mask*/) +_setHorizontalScoreOfCell(DPCell_ & /*dpCell*/, TScoreValue const & /*newHorizontalScore*/, TMask const & /*mask*/) { // no-op } @@ -271,13 +299,79 @@ setGapExtension(DPCell_ & /*dpCell*/, TF1 , TF2) // no-op } -template +template inline void -setGapExtension(DPCell_ & /*dpCell*/, TF1 , TF2, TScoreValue) +setGapExtension(DPCell_ & /*dpCell*/, TF1 , TF2, TMask) { // no-op } +template +inline void +write(TTarget & target, DPCell_ const & cell) +{ + write(target, _scoreOfCell(cell)); +} + +// ---------------------------------------------------------------------------- +// Function isGapExtension() +// ---------------------------------------------------------------------------- + +template +inline bool +isGapExtension(DPCell_ const & /*cell*/, + TSpec const & /*spec*/) +{ + return false; +} + +// ---------------------------------------------------------------------------- +// Function operator==() +// ---------------------------------------------------------------------------- + +template +inline bool operator==(DPCell_ const & lhs, + DPCell_ const & rhs) +{ + return _scoreOfCell(lhs) == _scoreOfCell(rhs) && + _horizontalScoreOfCell(lhs) == _horizontalScoreOfCell(rhs) && + _verticalScoreOfCell(lhs) == _verticalScoreOfCell(rhs); +} + +// ---------------------------------------------------------------------------- +// Function operator!=() +// ---------------------------------------------------------------------------- + +template +inline bool operator!=(DPCell_ const & lhs, + DPCell_ const & rhs) +{ + return !(lhs == rhs); +} + +// ---------------------------------------------------------------------------- +// Function operator<<() +// ---------------------------------------------------------------------------- + +template +inline TStream& operator<<(TStream & stream, + DPCell_ const & cell) +{ + stream << "M: " << _scoreOfCell(cell); + if (std::is_same::value) + { + stream << " "; + } + else if (std::is_same::value) + { + stream << " "; + } + return stream; +} + } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_CELL_H_ diff --git a/porechop/include/seqan/align/dp_cell_affine.h b/porechop/include/seqan/align/dp_cell_affine.h index c12990c..c4c08d4 100644 --- a/porechop/include/seqan/align/dp_cell_affine.h +++ b/porechop/include/seqan/align/dp_cell_affine.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -62,7 +62,7 @@ class DPCell_ TScoreValue _score = DPCellDefaultInfinity::VALUE; TScoreValue _horizontalScore = DPCellDefaultInfinity::VALUE; TScoreValue _verticalScore = DPCellDefaultInfinity::VALUE; - + DPCell_() = default; // Copy c'tor. DPCell_(DPCell_ const & other) : @@ -70,7 +70,7 @@ class DPCell_ _horizontalScore(other._horizontalScore), _verticalScore(other._verticalScore) {} - + // Move c-tor DPCell_(DPCell_ && other) : DPCell_() { @@ -104,6 +104,19 @@ class DPCell_ // Functions // ============================================================================ +// ---------------------------------------------------------------------------- +// Function operator<<() +// ---------------------------------------------------------------------------- + +// Needed for banded chain alignment for the set. +template +inline TStream& operator<<(TStream & stream, + DPCell_ const & dpCell) +{ + stream << ""; + return stream; +} + // ---------------------------------------------------------------------------- // Function operator<() // ---------------------------------------------------------------------------- @@ -148,6 +161,13 @@ _setVerticalScoreOfCell(DPCell_ & dpCell, TScoreValue c dpCell._verticalScore = newVerticalScore; } +template +inline SEQAN_FUNC_ENABLE_IF(Is >,void) +_setVerticalScoreOfCell(DPCell_ & dpCell, TScoreValue const & newVerticalScore) +{ + dpCell._verticalScore = newVerticalScore; +} + template inline SEQAN_FUNC_ENABLE_IF(Is >,void) _setVerticalScoreOfCell(DPCell_ & dpCell, TScoreValue const & newVerticalScore, TScoreValue const & mask) @@ -186,6 +206,13 @@ _setHorizontalScoreOfCell(DPCell_ & dpCell, TScoreValue dpCell._horizontalScore = newHorizontalScore; } +template +inline SEQAN_FUNC_ENABLE_IF(Is >,void) +_setHorizontalScoreOfCell(DPCell_ & dpCell, TScoreValue const & newHorizontalScore) +{ + dpCell._horizontalScore = newHorizontalScore; +} + template inline SEQAN_FUNC_ENABLE_IF(Is >,void) _setHorizontalScoreOfCell(DPCell_ & dpCell, TScoreValue const & newHorizontalScore, TScoreValue const & mask) @@ -194,8 +221,8 @@ _setHorizontalScoreOfCell(DPCell_ & dpCell, TScoreValue } template -inline void -swap(DPCell_ & lhs, +inline void +swap(DPCell_ & lhs, DPCell_ & rhs) { std::swap(lhs._score, rhs._score); diff --git a/porechop/include/seqan/align/dp_cell_dynamic.h b/porechop/include/seqan/align/dp_cell_dynamic.h index 567d5f9..61c42b5 100644 --- a/porechop/include/seqan/align/dp_cell_dynamic.h +++ b/porechop/include/seqan/align/dp_cell_dynamic.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -67,12 +67,6 @@ struct FlagMaskType // Tags, Classes, Enums // ============================================================================ -struct DynamicGapExtensionHorizontal_; -typedef Tag DynamicGapExtensionHorizontal; - -struct DynamicGapExtensionVertical_; -typedef Tag DynamicGapExtensionVertical; - enum DynamicGapsMask { MASK_VERTICAL_GAP = 1, @@ -168,7 +162,7 @@ inline void _setBit(DPCell_ & cell, TFlag const & /*flag*/, DynamicGapExtensionVertical const & /*tag*/) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) cell._flagMask |= MASK_VERTICAL_GAP; else cell._flagMask &= ~MASK_VERTICAL_GAP; @@ -179,7 +173,7 @@ inline void _setBit(DPCell_ & cell, TFlag const & /*flag*/, DynamicGapExtensionHorizontal const & /*tag*/) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) cell._flagMask |= MASK_HORIZONTAL_GAP; else cell._flagMask &= ~MASK_HORIZONTAL_GAP; @@ -190,7 +184,7 @@ inline SEQAN_FUNC_ENABLE_IF(Not > >,bool) isGapExtension(DPCell_ const & cell, TSpec const & /*spec*/) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return cell._flagMask & MASK_HORIZONTAL_GAP; else return cell._flagMask & MASK_VERTICAL_GAP; diff --git a/porechop/include/seqan/align/dp_cell_linear.h b/porechop/include/seqan/align/dp_cell_linear.h index 1a46fbe..3fc4b07 100644 --- a/porechop/include/seqan/align/dp_cell_linear.h +++ b/porechop/include/seqan/align/dp_cell_linear.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/dp_context.h b/porechop/include/seqan/align/dp_context.h index 3049369..69a9618 100644 --- a/porechop/include/seqan/align/dp_context.h +++ b/porechop/include/seqan/align/dp_context.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -57,12 +57,11 @@ struct GetDPTraceMatrix // Tags, Classes, Enums // ============================================================================ -template +template , + typename TTraceMatrixHost = String > struct DPContext { - typedef typename GetDPScoreMatrix::Type TScoreMatrixHost; - typedef typename GetDPTraceMatrix::Type TTraceMatrixHost; - TScoreMatrixHost _scoreMatrix; TTraceMatrixHost _traceMatrix; @@ -74,50 +73,6 @@ struct DPContext // Metafunctions // ============================================================================ -// ---------------------------------------------------------------------------- -// Metafunction GetDPScoreMatrix -// ---------------------------------------------------------------------------- - -template -struct GetDPScoreMatrix > -{ - typedef DPCell_ TDPScoreValue_; - typedef DPMatrix_ TDPScoreMatrix_; - - typedef typename Host::Type Type; -}; - -template -struct GetDPScoreMatrix const > -{ - typedef DPCell_ TDPScoreValue_; - typedef DPMatrix_ TDPScoreMatrix_; - - typedef typename Host::Type const Type; -}; - -// ---------------------------------------------------------------------------- -// Metafunction GetDPTraceMatrix -// ---------------------------------------------------------------------------- - -template -struct GetDPTraceMatrix > -{ - typedef typename TraceBitMap_::Type TTraceValue_; - typedef DPMatrix_ TDPScoreMatrix_; - - typedef typename Host::Type Type; -}; - -template -struct GetDPTraceMatrix const > -{ - typedef typename TraceBitMap_::Type TTraceValue_; - typedef DPMatrix_ TDPScoreMatrix_; - - typedef typename Host::Type const Type; -}; - // ============================================================================ // Functions // ============================================================================ @@ -126,16 +81,16 @@ struct GetDPTraceMatrix const > // Function dpScoreMatrix() // ---------------------------------------------------------------------------- -template -inline typename GetDPScoreMatrix >::Type & -getDpScoreMatrix(DPContext & dpContext) +template +inline TScoreMatHost & +getDpScoreMatrix(DPContext & dpContext) { return dpContext._scoreMatrix; } -template -inline typename GetDPScoreMatrix const >::Type & -getDpScoreMatrix(DPContext const & dpContext) +template +inline TScoreMatHost const & +getDpScoreMatrix(DPContext const & dpContext) { return dpContext._scoreMatrix; } @@ -144,16 +99,16 @@ getDpScoreMatrix(DPContext const & dpContext) // Function dpTraceMatrix() // ---------------------------------------------------------------------------- -template -inline typename GetDPTraceMatrix >::Type & -getDpTraceMatrix(DPContext & dpContext) +template +inline TTraceMatHost & +getDpTraceMatrix(DPContext & dpContext) { return dpContext._traceMatrix; } -template -inline typename GetDPTraceMatrix const >::Type & -getDpTraceMatrix(DPContext const & dpContext) +template +inline TTraceMatHost const & +getDpTraceMatrix(DPContext const & dpContext) { return dpContext._traceMatrix; } @@ -162,10 +117,10 @@ getDpTraceMatrix(DPContext const & dpContext) // Function setDpScoreMatrix() // ---------------------------------------------------------------------------- -template +template inline void -setDpTraceMatrix(DPContext & dpContext, - typename GetDPScoreMatrix >::Type const & scoreMatrix) +setDpTraceMatrix(DPContext & dpContext, + TScoreMatHost const & scoreMatrix) { dpContext._scoreMatrix = scoreMatrix; } @@ -174,10 +129,10 @@ setDpTraceMatrix(DPContext & dpContext, // Function setDpTraceMatrix() // ---------------------------------------------------------------------------- -template +template inline void -setDpTraceMatrix(DPContext & dpContext, - typename GetDPTraceMatrix >::Type const & traceMatrix) +setDpTraceMatrix(DPContext & dpContext, + TTraceMatHost const & traceMatrix) { dpContext._tarceMatrix = traceMatrix; } diff --git a/porechop/include/seqan/align/dp_formula.h b/porechop/include/seqan/align/dp_formula.h index 9ecd0ab..2d0ddc9 100644 --- a/porechop/include/seqan/align/dp_formula.h +++ b/porechop/include/seqan/align/dp_formula.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -34,8 +34,6 @@ // Defines the recursion formula for the dp-alignment algorithms. // ========================================================================== -// TODO(holtgrew): Documentation in this header necessary or internal only? - #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_FORMULA_H_ #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_FORMULA_H_ @@ -102,116 +100,191 @@ typedef Tag RecursionDirectionZero; // Metafunctions // ============================================================================ +// Helper typedef to get the correct score value type from the score-matrix navigator. +template +using ExtractedScoreValueType_ = std::decay_t(std::declval())))>; + // ============================================================================ // Functions // ============================================================================ -// ---------------------------------------------------------------------------- -// Function _computeScore -// ---------------------------------------------------------------------------- +template +inline SEQAN_FUNC_ENABLE_IF(Not>>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceRight const /**/, + TTraceLeft const /**/, + TracebackOff const & /*tag*/) +{ + using std::max; + target = max(static_cast(srcLeft), static_cast(srcRight)); + return TraceBitMap_::NONE; +} -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_computeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - TRecursionDirection const & recDir, - TDPProfile const & dpProfile) +template +inline SEQAN_FUNC_ENABLE_IF(Is>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceRight const /**/, + TTraceLeft const /**/, + TracebackOff const & /*tag*/) { - typedef typename TraceBitMap_::Type TTraceValue; - - TTraceValue traceDir = _doComputeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, - seqVVal, scoringScheme, recDir, dpProfile); - if (IsLocalAlignment_::VALUE) - if (activeCell._score <= 0) - { - _setScoreOfCell(activeCell, static_cast(0)); - _setHorizontalScoreOfCell(activeCell, static_cast(0)); - _setVerticalScoreOfCell(activeCell, static_cast(0)); - return TraceBitMap_::NONE; - } - - return traceDir; + target = max(srcLeft, srcRight); + return TraceBitMap_::NONE; } -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_computeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - TRecursionDirection const & recDir, - TDPProfile const & dpProfile) +template +inline SEQAN_FUNC_ENABLE_IF(Not>>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceLeft const traceLeft, + TTraceRight const traceRight, + TracebackOn > const & /*tag*/) { - typedef typename TraceBitMap_::Type TTraceValue; + return (srcLeft < srcRight) + ? (target = srcRight, traceRight) + : (target = srcLeft, traceLeft); +} - TTraceValue traceDir = _doComputeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, - seqVVal, scoringScheme, recDir, dpProfile); - if (IsLocalAlignment_::VALUE) - { - TScoreValue cmp = cmpGt(createVector(1), activeCell._score); - _setScoreOfCell(activeCell, TraceBitMap_::NONE, cmp); - _setHorizontalScoreOfCell(activeCell, TraceBitMap_::NONE, cmp); - _setVerticalScoreOfCell(activeCell, TraceBitMap_::NONE, cmp); - return blend(traceDir, TraceBitMap_::NONE, cmp); - } +template +inline SEQAN_FUNC_ENABLE_IF(Is>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceLeft const traceLeft, + TTraceRight const traceRight, + TracebackOn > const & /*tag*/) +{ + auto cmp = cmpGt(srcRight, srcLeft); + target = blend(srcLeft, srcRight, cmp); + return blend(traceLeft, traceRight, cmp); +} + +template +inline SEQAN_FUNC_ENABLE_IF(Not>>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceLeft const traceLeft, + TTraceRight const traceRight, + TracebackOn > const & /*tag*/) +{ + return (srcLeft == srcRight) + ? (target = srcLeft, traceLeft | traceRight) + : (srcLeft < srcRight) + ? (target = srcRight, traceRight) + : (target = srcLeft, traceLeft); +} - return traceDir; +template +inline SEQAN_FUNC_ENABLE_IF(Is>, typename TraceBitMap_::Type) +_maxScore(TTarget & target, + TSourceLeft const & srcLeft, + TSourceRight const & srcRight, + TTraceLeft const traceLeft, + TTraceRight const traceRight, + TracebackOn > const & /*tag*/) +{ + auto cmpG = cmpGt(srcRight, srcLeft); + auto cmpE = cmpEq(srcRight, srcLeft); + target = blend(srcLeft, srcRight, cmpG); + auto result = blend(traceLeft, traceRight, cmpG); + return blend(result, traceLeft | traceRight, cmpE); } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionDiagonal] +// Function _computeScore [RecursionDirectionDiagonal] // ---------------------------------------------------------------------------- - -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionDiagonal const &, - TDPProfile const &) +// Independent of gap cost model. +template +inline auto +_computeScore(DPCell_ & current, + DPCell_ & diagonal, + DPCell_ const & /*horizontal*/, + DPCell_ const & /*vertical*/, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionDiagonal const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - setGapExtension(activeCell, False(), False(), createVector(-1)); + _scoreOfCell(current) = _scoreOfCell(diagonal) + score(scoringScheme, seqHVal, seqVVal); + setGapExtension(current, False(), False(), createVector(-1)); - if (!IsTracebackEnabled_::VALUE) - return TraceBitMap_::NONE; - - return TraceBitMap_::DIAGONAL; + if (IsLocalAlignment_::VALUE) + { + return _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + TraceBitMap_::DIAGONAL, + TTracebackConfig{}); + } + else + { + return TraceBitMap_::DIAGONAL; + } } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionZero] +// Function _computeScore [RecursionDirectionZero] // ---------------------------------------------------------------------------- -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & /*seqHVal*/, - TSequenceVValue const & /*seqVVal*/, - TScoringScheme const & /*scoringScheme*/, - RecursionDirectionZero const &, - DPProfile_ const &) +// Independent of gap cost model. +template +inline auto +_computeScore(DPCell_ & current, + DPCell_ & diagonal, + DPCell_ const & /*horizontal*/, + DPCell_ & vertical, + TSequenceHValue const & /*seqHVal*/, + TSequenceVValue const & /*seqVVal*/, + TScoringScheme const & /*scoringScheme*/, + RecursionDirectionZero const &, + DPProfile_ const &) { - _scoreOfCell(activeCell) = createVector(0); + _scoreOfCell(current) = TraceBitMap_::NONE; + _scoreOfCell(diagonal) = _scoreOfCell(current); + _scoreOfCell(vertical) = _scoreOfCell(current); return TraceBitMap_::NONE; } diff --git a/porechop/include/seqan/align/dp_formula_affine.h b/porechop/include/seqan/align/dp_formula_affine.h index 2e22c0c..1c78b38 100644 --- a/porechop/include/seqan/align/dp_formula_affine.h +++ b/porechop/include/seqan/align/dp_formula_affine.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -56,579 +56,272 @@ namespace seqan { // ============================================================================ // ---------------------------------------------------------------------------- -// Function _internalComputeScore [RecursionDirectionDiagonal, AffineGaps] +// Function _computeScore [RecursionAllDirection, AffineGaps] // ---------------------------------------------------------------------------- -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueGap, - TracebackOff const &, - RecursionDirectionDiagonal const &) -{ - if(activeCell._score < rightCompare) - activeCell._score = rightCompare; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueGap, - TracebackOff const &, - RecursionDirectionDiagonal const &) -{ - activeCell._score = blend(activeCell._score, rightCompare, cmpGt(rightCompare, activeCell._score)); - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueGap gapTrace, - TracebackOn > const &, - RecursionDirectionDiagonal const &) -{ - if(activeCell._score <= rightCompare) - { - activeCell._score = rightCompare; - return TraceBitMap_::DIAGONAL | leftTrace; - } - return leftTrace | gapTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueGap const & gapTrace, - TracebackOn > const &, - RecursionDirectionDiagonal const &) -{ - TScoreValue cmp = cmpGt(activeCell._score, rightCompare); - activeCell._score = blend(rightCompare, activeCell._score, cmp); - return blend(TraceBitMap_::DIAGONAL | leftTrace, - leftTrace | gapTrace, - cmp); -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueGap gapTrace, - TracebackOn > const &, - RecursionDirectionDiagonal const &) +template +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & current, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionAll const &, + DPProfile_ const &) { - if(activeCell._score < rightCompare) + // Compute intermediate diagonal result. + TScoreValue intermediate = static_cast(_scoreOfCell(previousDiagonal) + + score(scoringScheme, seqHVal, seqVVal)); + // Cache previous Diagonal + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); + // Compute horizontal direction. + auto tmp = _maxScore(_horizontalScoreOfCell(current), + _horizontalScoreOfCell(previousHorizontal) + + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousHorizontal) + + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::HORIZONTAL, + TraceBitMap_::HORIZONTAL_OPEN, + TTracebackConfig{}); + + // Compute vertical direction. + tmp |= _maxScore(_verticalScoreOfCell(previousVertical), + _verticalScoreOfCell(previousVertical) + + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousVertical) + + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::VERTICAL, + TraceBitMap_::VERTICAL_OPEN, + TTracebackConfig{}); + + auto tmp2 = _maxScore(_scoreOfCell(current), + _verticalScoreOfCell(previousVertical), + _horizontalScoreOfCell(current), + TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, + TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, + TTracebackConfig{}); + tmp = _maxScore(_scoreOfCell(current), + intermediate, + _scoreOfCell(current), + TraceBitMap_::DIAGONAL | tmp, + tmp2 | tmp, + TTracebackConfig{}); + if (IsLocalAlignment_::VALUE) { - activeCell._score = rightCompare; // Maximal score comes from diagonal. - return TraceBitMap_::DIAGONAL | leftTrace; // Return trace for Diagonal. + tmp = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tmp, + TTracebackConfig{}); } - if (activeCell._score == rightCompare) // Maximal score comes from previous computed directions and diagonal. - return leftTrace | TraceBitMap_::DIAGONAL | gapTrace; // Return all directions inclusively the flag indicating max from gap. - return leftTrace | gapTrace; // Maximum comes from gap. Return gap value inclusively the flag indicating max from gap. -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueGap const & gapTrace, - TracebackOn > const &, - RecursionDirectionDiagonal const &) -{ - TScoreValue cmpG = cmpGt(rightCompare, activeCell._score); - TScoreValue cmpE = cmpEq(rightCompare, activeCell._score); - TScoreValue result = leftTrace | gapTrace; - activeCell._score = blend(activeCell._score, rightCompare, cmpG); - result = blend(result, TraceBitMap_::DIAGONAL | leftTrace, cmpG); - return blend(result, leftTrace | TraceBitMap_::DIAGONAL | gapTrace, cmpE); + // Cache score for previous vertical. + _scoreOfCell(previousVertical) = _scoreOfCell(current); + return tmp; } // ---------------------------------------------------------------------------- -// Function _internalComputeScore [RecursionDirectionHorizontal, AffineGaps] +// Function _computeScore [RecursionUpperDiagonalDirection, AffineGaps] // ---------------------------------------------------------------------------- -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &, - RecursionDirectionHorizontal const &) -{ - if(activeCell._horizontalScore < rightCompare) - activeCell._score = activeCell._horizontalScore = rightCompare; - else - activeCell._score = activeCell._horizontalScore; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &, - RecursionDirectionHorizontal const &) -{ - TScoreValue cmp = cmpGt(rightCompare, activeCell._horizontalScore); - activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmp); - activeCell._score = activeCell._horizontalScore; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionHorizontal const &) -{ - if(activeCell._horizontalScore < rightCompare) - { - activeCell._score = activeCell._horizontalScore = rightCompare; - return rightTrace; - } - activeCell._score = activeCell._horizontalScore; - return leftTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionHorizontal const &) +template +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & current, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionUpperDiagonal const &, + DPProfile_ const &) { - TScoreValue cmp = cmpGt(rightCompare, activeCell._horizontalScore); - activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmp); - activeCell._score = activeCell._horizontalScore; - return blend(leftTrace, rightTrace, cmp); -} + typedef typename TraceBitMap_::Type TTraceValue; -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionHorizontal const &) -{ - if(activeCell._horizontalScore < rightCompare) + // Compute intermediate diagonal result. + TScoreValue intermediate = static_cast(_scoreOfCell(previousDiagonal) + + score(scoringScheme, seqHVal, seqVVal)); + // Cache previous Diagonal + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); + // Compute horiztonal direction. + // _horizontalScoreOfCell(current) = _horizontalScoreOfCell(previousHorizontal) + + // scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); + TTraceValue tv = _maxScore(_horizontalScoreOfCell(current), + _horizontalScoreOfCell(previousHorizontal) + + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousHorizontal) + + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::HORIZONTAL, + TraceBitMap_::HORIZONTAL_OPEN, + TTracebackConfig()); + // Ignore vertical direction in upper diagonal. + _verticalScoreOfCell(previousVertical) = DPCellDefaultInfinity >::VALUE; + // Compute diagonal direction and compare with horizontal. + // _scoreOfCell(current) = _horizontalScoreOfCell(current); + tv = _maxScore(_scoreOfCell(current), + intermediate, + _horizontalScoreOfCell(current), + tv | TraceBitMap_::DIAGONAL, + tv | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, + TTracebackConfig()); + if (IsLocalAlignment_::VALUE) { - activeCell._score = activeCell._horizontalScore = rightCompare; - return rightTrace; + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); } - activeCell._score = activeCell._horizontalScore; - if (activeCell._horizontalScore == rightCompare) - return leftTrace | rightTrace; - return leftTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueR const & rightTrace, - TracebackOn > const &, - RecursionDirectionHorizontal const &) -{ - TScoreValue cmpG = cmpGt(rightCompare, activeCell._horizontalScore); - TScoreValue cmpE = cmpEq(rightCompare, activeCell._horizontalScore); - activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmpG); - activeCell._score = activeCell._horizontalScore; - - TScoreValue result = leftTrace; - result = blend(result, rightTrace, cmpG); - return blend(result, leftTrace | rightTrace, cmpE); + _scoreOfCell(previousVertical) = _scoreOfCell(current); + return tv; } // ---------------------------------------------------------------------------- -// Function _internalComputeScore [RecursionDirectionVertical, AffineGaps] +// Function _computeScore [RecursionDirectionLowerDiagonal, AffineGaps] // ---------------------------------------------------------------------------- -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &, - RecursionDirectionVertical const &) -{ - if(activeCell._verticalScore < rightCompare) - activeCell._score = activeCell._verticalScore = rightCompare; - else - activeCell._score = activeCell._verticalScore; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &, - RecursionDirectionVertical const &) -{ - TScoreValue cmp = cmpGt(rightCompare, activeCell._verticalScore); - activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmp); - activeCell._score = activeCell._verticalScore; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionVertical const &) -{ - if(activeCell._verticalScore < rightCompare) - { - activeCell._score = activeCell._verticalScore = rightCompare; - return rightTrace; - } - activeCell._score = activeCell._verticalScore; - return leftTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueR const & rightTrace, - TracebackOn > const &, - RecursionDirectionVertical const &) +template +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & current, + DPCell_ const & previousDiagonal, + DPCell_ const & /*previousHorizontal*/, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionLowerDiagonal const &, + DPProfile_ const &) { - TScoreValue cmp = cmpGt(rightCompare, activeCell._verticalScore); - activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmp); - activeCell._score = activeCell._verticalScore; - return blend(leftTrace, rightTrace, cmp); -} + typedef typename TraceBitMap_::Type TTraceValue; -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionVertical const &) -{ - if(activeCell._verticalScore < rightCompare) + // Compute vertical direction. + TTraceValue tv = _maxScore(_verticalScoreOfCell(previousVertical), + _verticalScoreOfCell(previousVertical) + + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousVertical) + + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::VERTICAL, + TraceBitMap_::VERTICAL_OPEN, + TTracebackConfig()); + // Ignore horizontal direction in lower diagonal. + _horizontalScoreOfCell(current) = DPCellDefaultInfinity >::VALUE; + + // Compute diagonal direction and compare with vertical. + tv = _maxScore(_scoreOfCell(current), + _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal), + _verticalScoreOfCell(previousVertical), + tv | TraceBitMap_::DIAGONAL, + tv | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, + TTracebackConfig()); + if (IsLocalAlignment_::VALUE) { - activeCell._score = activeCell._verticalScore = rightCompare; - return rightTrace; + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); } - activeCell._score = activeCell._verticalScore; - if (activeCell._verticalScore == rightCompare) - return leftTrace | rightTrace; - return leftTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &, - RecursionDirectionVertical const &) -{ - TScoreValue cmpG = cmpGt(rightCompare, activeCell._verticalScore); - TScoreValue cmpE = cmpEq(rightCompare, activeCell._verticalScore); - activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmpG); - activeCell._score = activeCell._verticalScore; - - TScoreValue result = leftTrace; - result = blend(result, rightTrace, cmpG); - return blend(result, leftTrace | rightTrace, cmpE); + return tv; } // ---------------------------------------------------------------------------- -// Function _internalComputeScore [Vertical vs Horizontal, AffineGaps] +// Function _computeScore [RecursionHorizontalDirection] // ---------------------------------------------------------------------------- -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOff const &) -{ - if(activeCell._score < activeCell._horizontalScore) - activeCell._score = activeCell._horizontalScore; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOff const &) -{ - activeCell._score = blend(activeCell._score, activeCell._horizontalScore, - cmpGt(activeCell._horizontalScore, activeCell._score)); - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOn > const &) -{ - if(activeCell._score < activeCell._horizontalScore) - { - activeCell._score = activeCell._horizontalScore; - return TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; - } - return TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOn > const &) -{ - TScoreValue cmp = cmpGt(activeCell._horizontalScore, activeCell._score); - activeCell._score = blend(activeCell._score, activeCell._horizontalScore, cmp); - return blend(TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - cmp); -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOn > const &) +template +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & current, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionHorizontal const &, + DPProfile_ const &) { - if(activeCell._score < activeCell._horizontalScore) + // Cache previous diagonal value. + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); + // Compute horizontal direction. + auto traceDir = _maxScore(_horizontalScoreOfCell(current), + _horizontalScoreOfCell(previousHorizontal) + + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousHorizontal) + + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::HORIZONTAL, + TraceBitMap_::HORIZONTAL_OPEN, + TTracebackConfig()) | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + // Ignore vertical direction. + _verticalScoreOfCell(previousVertical) = DPCellDefaultInfinity >::VALUE; + _scoreOfCell(current) = _horizontalScoreOfCell(current); + + if (IsLocalAlignment_::VALUE) { - activeCell._score = activeCell._horizontalScore; - return TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + traceDir = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + traceDir, + TTracebackConfig{}); } - if (activeCell._score == activeCell._horizontalScore) - return TraceBitMap_::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; - return TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TracebackOn > const &) -{ - TScoreValue cmpG = cmpGt(activeCell._horizontalScore, activeCell._score); - TScoreValue cmpE = cmpEq(activeCell._horizontalScore, activeCell._score); - activeCell._score = blend(activeCell._score, activeCell._horizontalScore, cmpG); - - return blend(blend(TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - cmpG), - TraceBitMap_::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - cmpE); -} - -// ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionAllDirection, AffineGaps] -// ---------------------------------------------------------------------------- - -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionAll const &, - DPProfile_ const &) -{ - typedef typename TraceBitMap_::Type TTraceValue; - - // Now we have to find a smart version to solve this problem. Which is not as easy I would think. - activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal); - TTraceValue tvGap = _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::HORIZONTAL, - TraceBitMap_::HORIZONTAL_OPEN, - TTracebackConfig(), - RecursionDirectionHorizontal()); - - // Now we can decide for the optimal score in horizontal score or not? - activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - tmpScore = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal); - tvGap |= _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::VERTICAL, - TraceBitMap_::VERTICAL_OPEN, - TTracebackConfig(), - RecursionDirectionVertical()); - - // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction. - TTraceValue tvMax = _internalComputeScore(activeCell, TTracebackConfig()); // Stores from where the maximal score comes. - tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, tmpScore, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal()); -} - -// ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionUpperDiagonalDirection, AffineGaps] -// ---------------------------------------------------------------------------- - -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionUpperDiagonal const &, - DPProfile_ const &) -{ - typedef typename TraceBitMap_::Type TTraceValue; - - activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - activeCell._verticalScore = DPCellDefaultInfinity >::VALUE; - TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal); - TTraceValue tv = _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::HORIZONTAL, - TraceBitMap_::HORIZONTAL_OPEN, - TTracebackConfig(), - RecursionDirectionHorizontal()); - tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - tv, - TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - TTracebackConfig(), - RecursionDirectionDiagonal()); + _scoreOfCell(previousVertical) = _scoreOfCell(current); + return traceDir; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionLowerDiagonal, AffineGaps] +// Function _computeScore [RecursionVerticalDirection] // ---------------------------------------------------------------------------- -template +template inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionLowerDiagonal const &, - DPProfile_ const &) +_computeScore(DPCell_ & current, + DPCell_ const & /*previousDiagonal*/, + DPCell_ const & /*previousHorizontal*/, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionVertical const &, + DPProfile_ const &) { - typedef typename TraceBitMap_::Type TTraceValue; - - activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal); - - activeCell._horizontalScore = DPCellDefaultInfinity >::VALUE; - // This computes the difference between the vertical extend and vertical open. - TTraceValue tv = _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::VERTICAL, - TraceBitMap_::VERTICAL_OPEN, - TTracebackConfig(), - RecursionDirectionVertical()); - - // Up to here, activeCell stores the highest value of vertical or vertical open. - tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - tv, - TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TTracebackConfig(), - RecursionDirectionDiagonal()); // Now we have this problem. How do we determine if the max comes from the vertical distance. -} - -// ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionHorizontalDirection] -// ---------------------------------------------------------------------------- - -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionHorizontal const &, - DPProfile_ const &) -{ - TScoreValue tmpGapOpenHorizontal = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal); - activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - - activeCell._verticalScore = DPCellDefaultInfinity >::VALUE; - return _internalComputeScore(activeCell, - tmpGapOpenHorizontal, - TraceBitMap_::HORIZONTAL, - TraceBitMap_::HORIZONTAL_OPEN, - TTracebackConfig(), - RecursionDirectionHorizontal()) | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; -} - -// ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionVerticalDirection] -// ---------------------------------------------------------------------------- - -template -inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionVertical const &, - DPProfile_ const &) -{ - TScoreValue tmpGapOpenVertical = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal); - activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - - // Here we distinguish between vertical and vertical open. - activeCell._horizontalScore = DPCellDefaultInfinity >::VALUE; - return _internalComputeScore(activeCell, - tmpGapOpenVertical, - TraceBitMap_::VERTICAL, - TraceBitMap_::VERTICAL_OPEN, - TTracebackConfig(), - RecursionDirectionVertical()) | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + // Compute vertical direction. + auto traceDir = _maxScore(_verticalScoreOfCell(previousVertical), + _verticalScoreOfCell(previousVertical) + + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousVertical) + + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::VERTICAL, + TraceBitMap_::VERTICAL_OPEN, + TTracebackConfig()) | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + // Ignore horizontal direction. + _horizontalScoreOfCell(current) = DPCellDefaultInfinity >::VALUE; + _scoreOfCell(current) = _verticalScoreOfCell(previousVertical); + + if (IsLocalAlignment_::VALUE) + { + traceDir = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + traceDir, + TTracebackConfig{}); + } + _scoreOfCell(previousVertical) = _scoreOfCell(current); + return traceDir; } } // namespace seqan diff --git a/porechop/include/seqan/align/dp_formula_dynamic.h b/porechop/include/seqan/align/dp_formula_dynamic.h index 1c8fe8b..d87b229 100644 --- a/porechop/include/seqan/align/dp_formula_dynamic.h +++ b/porechop/include/seqan/align/dp_formula_dynamic.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -88,7 +88,7 @@ _internalComputeScore(DPCell_ & activeCell, TracebackOff const &, RecursionDirectionDiagonal const &) { - TScoreValue cmp = cmpGt(diagCompare, _scoreOfCell(activeCell)); + auto cmp = cmpGt(diagCompare, _scoreOfCell(activeCell)); activeCell._score = blend(activeCell._score, diagCompare, cmp); setGapExtension(activeCell, False(), False(), cmp); return TraceBitMap_::NONE; @@ -121,7 +121,7 @@ _internalComputeScore(DPCell_ & activeCell, TracebackOn > const &, RecursionDirectionDiagonal const &) { - TScoreValue cmp = cmpGt(_scoreOfCell(activeCell), diagCompare); + auto cmp = cmpGt(_scoreOfCell(activeCell), diagCompare); activeCell._score = blend(diagCompare, activeCell._score, cmp); setGapExtension(activeCell, False(), False(), cmp); return blend(TraceBitMap_::DIAGONAL | leftTrace, @@ -159,7 +159,7 @@ _internalComputeScore(DPCell_ & activeCell, TracebackOn > const &, RecursionDirectionDiagonal const &) { - TScoreValue cmp = cmpGt(diagCompare, _scoreOfCell(activeCell)); + auto cmp = cmpGt(diagCompare, _scoreOfCell(activeCell)); activeCell._score = blend(activeCell._score, diagCompare, cmp); setGapExtension(activeCell, False(), False(), cmp); return blend(blend(leftTrace | gapTrace, @@ -298,7 +298,7 @@ _internalComputeScore(DPCell_ & activeCell, TracebackOn const &, RecursionDirectionVertical const &) { - TScoreValue cmp = isGapExtension(prevCell, DynamicGapExtensionVertical()); + auto cmp = isGapExtension(prevCell, DynamicGapExtensionVertical()); activeCell._score = blend(_scoreOfCell(prevCell) + scoreGapOpenVertical(score, valH, valV), activeCell._score, cmp); return blend(TraceBitMap_::VERTICAL_OPEN, TraceBitMap_::VERTICAL, @@ -331,7 +331,7 @@ _internalComputeScore(DPCell_ & activeCell, TScoreValue const & horizontalComp, TracebackOff const &) { - TScoreValue cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell)); + auto cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell)); activeCell._score = blend(activeCell._score, horizontalComp, cmp); setGapExtension(activeCell, False(), True(), cmp); setGapExtension(activeCell, True(), False(), cmpEq(cmp, TraceBitMap_::NONE)); @@ -360,7 +360,7 @@ _internalComputeScore(DPCell_ & activeCell, TScoreValue const & horizontalComp, TracebackOn > const &) { - TScoreValue cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell)); + auto cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell)); activeCell._score = blend(activeCell._score, horizontalComp, cmp); setGapExtension(activeCell, False(), True(), cmp); setGapExtension(activeCell, True(), False(), cmpEq(cmp, TraceBitMap_::NONE)); @@ -396,8 +396,8 @@ _internalComputeScore(DPCell_ & activeCell, TScoreValue const & horizontalComp, TracebackOn > const &) { - TScoreValue cmpG = cmpGt(horizontalComp, _scoreOfCell(activeCell)); - TScoreValue cmpE = cmpEq(horizontalComp, _scoreOfCell(activeCell)); + auto cmpG = cmpGt(horizontalComp, _scoreOfCell(activeCell)); + auto cmpE = cmpEq(horizontalComp, _scoreOfCell(activeCell)); setGapExtension(activeCell, True(), False(), createVector(-1)); setGapExtension(activeCell, False(), True(), cmpG); setGapExtension(activeCell, True(), True(), cmpE); @@ -413,25 +413,30 @@ _internalComputeScore(DPCell_ & activeCell, } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionAllDirection, DynamicGaps] +// Function _computeScore [RecursionAllDirection, DynamicGaps] // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionAll const &, - DPProfile_ const &) + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & activeCell, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionAll const &, + DPProfile_ const &) { typedef typename TraceBitMap_::Type TTraceValue; - typedef typename std::decay::type TCell; + typedef DPCell_ TCell; + // Compute intermediate diagonal result. + TScoreValue intermediate = static_cast(_scoreOfCell(previousDiagonal) + + score(scoringScheme, seqHVal, seqVVal)); + // Cache previous Diagonal + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); // Compute best alignment from either horizontal open or extension. TCell tmpScore(_scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal)); TTraceValue tvGap = _internalComputeScore(tmpScore, previousHorizontal, seqHVal, seqVVal, scoringScheme, @@ -444,61 +449,45 @@ _doComputeScore(DPCell_ & activeCell, // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction. TTraceValue tvMax = _internalComputeScore(activeCell, tmpScore._score, TTracebackConfig()); // Stores from where the maximal score comes. - tmpScore._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal()); -} + tmpScore._score = intermediate; + tvMax = _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal()); -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionAll const &, - DPProfile_ const &) -{ - typedef typename TraceBitMap_::Type TTraceValue; - typedef typename std::decay::type TCell; - - // Compute best alignment from either horizontal open or extension. - TCell tmpScore = {_scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), - typename TCell::TFlagMaskType()}; - TTraceValue tvGap = _internalComputeScore(tmpScore, previousHorizontal, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), RecursionDirectionHorizontal()); - - // Compute best alignment between vertical and vertical open gap. - activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - tvGap |= _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), RecursionDirectionVertical()); - - // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction. - TTraceValue tvMax = _internalComputeScore(activeCell, tmpScore._score, TTracebackConfig()); // Stores from where the maximal score comes. - tmpScore._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal()); + if (IsLocalAlignment_::VALUE) + { + tvMax = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tvMax, + TTracebackConfig{}); + } + previousVertical = activeCell; + return tvMax; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionUpperDiagonalDirection, DynamicGaps] +// Function _computeScore [RecursionUpperDiagonalDirection, DynamicGaps] // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionUpperDiagonal const &, - DPProfile_ const &) + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> +typename TraceBitMap_::Type +_computeScore(DPCell_ & activeCell, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionUpperDiagonal const &, + DPProfile_ const &) { typedef typename TraceBitMap_::Type TTraceValue; + // Compute intermediate diagonal result. + TScoreValue intermediate = static_cast(_scoreOfCell(previousDiagonal) + + score(scoringScheme, seqHVal, seqVVal)); + // Cache previous Diagonal + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); // This computes the difference between the horizontal extend and horizontal open. activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); @@ -506,58 +495,38 @@ _doComputeScore(DPCell_ & activeCell, TTracebackConfig(), RecursionDirectionHorizontal()); setGapExtension(activeCell, False(), True()); - TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - TTracebackConfig(),RecursionDirectionDiagonal()); -} - - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionUpperDiagonal const &, - DPProfile_ const &) -{ - typedef typename TraceBitMap_::Type TTraceValue; - - // This computes the difference between the horizontal extend and horizontal open. - activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - TTraceValue tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), RecursionDirectionHorizontal()); + tv = _internalComputeScore(activeCell, intermediate, tv, TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, + TTracebackConfig(),RecursionDirectionDiagonal()); - setGapExtension(activeCell, False(), True(), createVector(-1)); - TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - tv, - TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - TTracebackConfig(), - RecursionDirectionDiagonal()); + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + previousVertical = activeCell; + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionLowerDiagonal, DynamicGaps] +// Function _computeScore [RecursionDirectionLowerDiagonal, DynamicGaps] // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionLowerDiagonal const &, - DPProfile_ const &) + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & activeCell, + DPCell_ const & previousDiagonal, + DPCell_ const & /*previousHorizontal*/, + DPCell_ const & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionLowerDiagonal const &, + DPProfile_ const &) { typedef typename TraceBitMap_::Type TTraceValue; @@ -567,121 +536,137 @@ _doComputeScore(DPCell_ & activeCell, TTracebackConfig(), RecursionDirectionVertical()); setGapExtension(activeCell, True(), False()); TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, + tv = _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, TTracebackConfig(), RecursionDirectionDiagonal()); -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionLowerDiagonal const &, - DPProfile_ const &) -{ - typedef typename TraceBitMap_::Type TTraceValue; - - // This computes the difference between the vertical extend and vertical open. - activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - TTraceValue tv = _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), RecursionDirectionVertical()); - setGapExtension(activeCell, True(), False(), createVector(-1)); - TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - tv, - TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TTracebackConfig(), - RecursionDirectionDiagonal()); + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionHorizontalDirection] +// Function _computeScore [RecursionHorizontalDirection] // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionHorizontal const & tag, - DPProfile_ const &) + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & activeCell, + DPCell_ & previousDiagonal, + DPCell_ const previousHorizontal, // NOTE(rrahn): We want the copy here. Don't change!!! + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionHorizontal const & tag, + DPProfile_ const &) { + // Cache previous diagonal value. + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); setGapExtension(activeCell, False(), True()); - return _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), tag) | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + auto tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme, + TTracebackConfig(), tag) | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + previousVertical = activeCell; + return tv; } +// NOTE(rrahn): Here we copy the previousCellHorizontal as it might refer to the same value as acticeCell. +// Since we cannot assure here to read the value before we write it, we have to take a copy from it. template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionHorizontal const & tag, - DPProfile_ const &) +_computeScore(DPCell_ & activeCell, + DPCell_ & previousDiagonal, + DPCell_ const previousHorizontal, // NOTE(rrahn): Don't change!!! + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionHorizontal const & tag, + DPProfile_ const &) { + // Cache previous diagonal value. + _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal); activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); setGapExtension(activeCell, False(), True(), createVector(-1)); - return _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme, + auto tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme, TTracebackConfig(), tag) | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + previousVertical = activeCell; + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionVerticalDirection] +// Function _computeScore [RecursionVerticalDirection] // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionVertical const & tag, - DPProfile_ const &) + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> +inline typename TraceBitMap_::Type +_computeScore(DPCell_ & activeCell, + DPCell_ & /*previousDiagonal*/, + DPCell_ const & /*previousHorizontal*/, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionVertical const & tag, + DPProfile_ const &) { activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); setGapExtension(activeCell, True(), False()); - return _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme, + auto tv = _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme, TTracebackConfig(), tag) | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + previousVertical = activeCell; + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + return tv; } -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionVertical const & tag, - DPProfile_ const &) +// Independent of gap cost model. +template +inline auto +_computeScore(DPCell_ & current, + DPCell_ & cacheDiagonal, + DPCell_ const & /*cacheHorizontal*/, + DPCell_ & cacheVertical, + TSequenceHValue const & /*seqHVal*/, + TSequenceVValue const & /*seqVVal*/, + TScoringScheme const & /*scoringScheme*/, + RecursionDirectionZero const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - setGapExtension(activeCell, True(), False(), createVector(-1)); - return _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme, - TTracebackConfig(), tag) | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + _scoreOfCell(current) = TraceBitMap_::NONE; + setGapExtension(current, False(), False()); + _scoreOfCell(cacheDiagonal) = _scoreOfCell(current); + cacheVertical = current; + return TraceBitMap_::NONE; } } // namespace seqan diff --git a/porechop/include/seqan/align/dp_formula_linear.h b/porechop/include/seqan/align/dp_formula_linear.h index 45ed936..595009a 100644 --- a/porechop/include/seqan/align/dp_formula_linear.h +++ b/porechop/include/seqan/align/dp_formula_linear.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -56,234 +56,200 @@ namespace seqan { // ============================================================================ // ---------------------------------------------------------------------------- -// Function _internalComputeScore() -// ---------------------------------------------------------------------------- - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &) -{ - if (activeCell._score < rightCompare) - activeCell._score = rightCompare; - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL, - TTraceValueR, - TracebackOff const &) -{ - TScoreValue cmp = cmpGt(rightCompare, activeCell._score); - activeCell._score = blend(activeCell._score, rightCompare, cmp); - return TraceBitMap_::NONE; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &) -{ - if (activeCell._score < rightCompare) - { - activeCell._score = rightCompare; - return rightTrace; - } - return leftTrace; -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueR const & rightTrace, - TracebackOn > const &) -{ - TScoreValue cmp = cmpGt(rightCompare, activeCell._score); - activeCell._score = blend(activeCell._score, rightCompare, cmp); - return blend(leftTrace, rightTrace, cmp); -} - -template - inline SEQAN_FUNC_ENABLE_IF(Not > >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL leftTrace, - TTraceValueR rightTrace, - TracebackOn > const &) -{ - if (activeCell._score < rightCompare) - { - activeCell._score = rightCompare; - return rightTrace; - } - return (activeCell._score == rightCompare) ? (rightTrace | leftTrace) : (leftTrace); -} - -template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_::Type) -_internalComputeScore(DPCell_ & activeCell, - TScoreValue const & rightCompare, - TTraceValueL const & leftTrace, - TTraceValueR const & rightTrace, - TracebackOn > const &) -{ - // Check for greater values. - TScoreValue cmp = cmpGt(activeCell._score, rightCompare); // cmp greater - activeCell._score = blend(rightCompare, activeCell._score, cmp); // activeCell._score - - // Check for equality. - return blend(blend(rightTrace, leftTrace, cmp), leftTrace | rightTrace, cmpEq(rightCompare, activeCell._score)); -} - -// ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionAll, LinearGaps] +// Function _computeScore [RecursionDirectionAll, LinearGaps] // ---------------------------------------------------------------------------- template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionAll const &, - DPProfile_ const &) +_computeScore(DPCell_ & current, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionAll const &, + DPProfile_ const &) { - typedef typename TraceBitMap_::Type TTraceValue; - activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - - TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - - TTraceValue tv = _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::DIAGONAL, - TraceBitMap_::VERTICAL | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TTracebackConfig()); - tmpScore = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - tv, - TraceBitMap_::HORIZONTAL | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - TTracebackConfig()); + // Cache next diagonal. + auto intermediate = static_cast(_scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal)); + previousDiagonal = _scoreOfCell(previousHorizontal); + + auto tv = _maxScore(_scoreOfCell(current), + _scoreOfCell(previousVertical)+ + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal), + _scoreOfCell(previousHorizontal) + + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::VERTICAL | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, + TraceBitMap_::HORIZONTAL | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, + TTracebackConfig{}); + // Compute the intermediate value. + tv = _maxScore(_scoreOfCell(current), + intermediate, + _scoreOfCell(current), + TraceBitMap_::DIAGONAL, + tv, + TTracebackConfig()); + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + previousVertical = current; + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionUpperDiagonal, LinearGaps] +// Function _computeScore [RecursionDirectionUpperDiagonal, LinearGaps] // ---------------------------------------------------------------------------- template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionUpperDiagonal const &, - DPProfile_ const &) +_computeScore(DPCell_ & current, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionUpperDiagonal const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - return _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::DIAGONAL, - TraceBitMap_::HORIZONTAL | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, - TTracebackConfig()); + // Precalculate diagonal direction. + auto intermediate = static_cast(_scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal)); + // Cache next diagonal value. + previousDiagonal = _scoreOfCell(previousHorizontal); + + auto tv = _maxScore(_scoreOfCell(current), + intermediate, + _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal), + TraceBitMap_::DIAGONAL, + TraceBitMap_::HORIZONTAL | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX, + TTracebackConfig()); + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + previousVertical = current; + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionLowerDiagonal, LinearGaps] +// Function _computeScore [RecursionDirectionLowerDiagonal, LinearGaps] // ---------------------------------------------------------------------------- template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionLowerDiagonal const &, - DPProfile_ const &) +_computeScore(DPCell_ & current, + DPCell_ const & previousDiagonal, + DPCell_ const & /*previousHorizontal*/, + DPCell_ const & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionLowerDiagonal const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal); - TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - - return _internalComputeScore(activeCell, - tmpScore, - TraceBitMap_::DIAGONAL, - TraceBitMap_::VERTICAL | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, - TTracebackConfig()); + auto tv = _maxScore(_scoreOfCell(current), + static_cast(_scoreOfCell(previousDiagonal) + + score(scoringScheme, seqHVal, seqVVal)), + static_cast(_scoreOfCell(previousVertical) + + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal)), + TraceBitMap_::DIAGONAL, + TraceBitMap_::VERTICAL | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX, + TTracebackConfig()); + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionHorizontal] +// Function _computeScore [RecursionDirectionHorizontal] // ---------------------------------------------------------------------------- template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & previousHorizontal, - DPCell_ const & /*previousVertical*/, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionHorizontal const &, - DPProfile_ const &) +_computeScore(DPCell_ & activeCell, + DPCell_ & previousDiagonal, + DPCell_ const & previousHorizontal, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionHorizontal const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); - - if (!IsTracebackEnabled_::VALUE) - return TraceBitMap_::NONE; - - return TraceBitMap_::HORIZONTAL - | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + // Cache previous diagonal. + previousDiagonal = previousHorizontal; + // Compute current value. + _scoreOfCell(activeCell) = _scoreOfCell(previousHorizontal) + + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal); + auto tv = TraceBitMap_::HORIZONTAL | TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX; + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(activeCell), + TraceBitMap_::NONE, + _scoreOfCell(activeCell), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + // Cache next vertical. + previousVertical = activeCell; + return tv; } // ---------------------------------------------------------------------------- -// Function _doComputeScore [RecursionDirectionVertical] +// Function _computeScore [RecursionDirectionVertical] // ---------------------------------------------------------------------------- template + typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy> inline typename TraceBitMap_::Type -_doComputeScore(DPCell_ & activeCell, - DPCell_ const & /*previousDiagonal*/, - DPCell_ const & /*previousHorizontal*/, - DPCell_ const & previousVertical, - TSequenceHValue const & seqHVal, - TSequenceVValue const & seqVVal, - TScoringScheme const & scoringScheme, - RecursionDirectionVertical const &, - DPProfile_ const &) +_computeScore(DPCell_ & current, + DPCell_ const & /*previousDiagonal*/, + DPCell_ const & /*previousHorizontal*/, + DPCell_ & previousVertical, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + RecursionDirectionVertical const &, + DPProfile_ const &) { - activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); - - if (!IsTracebackEnabled_::VALUE) - return TraceBitMap_::NONE; - - return TraceBitMap_::VERTICAL - | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + _scoreOfCell(current) = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal); + auto tv = TraceBitMap_::VERTICAL | TraceBitMap_::MAX_FROM_VERTICAL_MATRIX; + if (IsLocalAlignment_::VALUE) + { + tv = _maxScore(_scoreOfCell(current), + TraceBitMap_::NONE, + _scoreOfCell(current), + TraceBitMap_::NONE, + tv, + TTracebackConfig{}); + } + // Cache previous vertical. + previousVertical = current; + return tv; } } // namespace seqan diff --git a/porechop/include/seqan/align/dp_matrix.h b/porechop/include/seqan/align/dp_matrix.h index 1e853c5..fc66acb 100644 --- a/porechop/include/seqan/align/dp_matrix.h +++ b/porechop/include/seqan/align/dp_matrix.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -100,21 +100,21 @@ struct DPMatrixDimension_ // ---------------------------------------------------------------------------- // The dp matrix used as a score matrix and as a trace-back matrix. -template +template > class DPMatrix_ {}; // Default dp matrix implementation stores all cells of the dp matrix in the // underlying two-dimensional matrix. -template -class DPMatrix_ +template +class DPMatrix_ { public: - typedef typename Member::Type THost; + typedef typename Member::Type TMatrix; - Holder data_host; // The host containing the actual matrix. + Holder data_host; // The host containing the actual matrix. DPMatrix_() : data_host() @@ -151,16 +151,16 @@ struct DefaultScoreMatrixSpec_ > // ---------------------------------------------------------------------------- // Returns the type of the underlying matrix. -template -struct Member, DPMatrixMember> +template +struct Member, DPMatrixMember> { - typedef Matrix Type; + typedef Matrix Type; }; -template -struct Member const, DPMatrixMember> +template +struct Member const, DPMatrixMember> { - typedef Matrix const Type; + typedef Matrix const Type; }; // ---------------------------------------------------------------------------- @@ -172,18 +172,18 @@ struct Member const, DPMatrixMember> template struct SizeArr_ {}; -template -struct SizeArr_ > +template +struct SizeArr_ > { - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Member::Type TDataHost_; typedef typename SizeArr_::Type Type; }; -template -struct SizeArr_ const> +template +struct SizeArr_ const> { - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Member::Type TDataHost_; typedef typename SizeArr_::Type const Type; }; @@ -192,109 +192,59 @@ struct SizeArr_ const> // Metafunction Spec // ---------------------------------------------------------------------------- -template -struct Spec > +template +struct Spec > { typedef TMatrixSpec Type; }; -template -struct Spec const>: - Spec >{}; +template +struct Spec const>: + Spec >{}; // ---------------------------------------------------------------------------- // Metafunction Value // ---------------------------------------------------------------------------- -template -struct Value > +template +struct Value > { typedef TValue Type; }; -template -struct Value const> +template +struct Value const> { typedef TValue const Type; }; -// ---------------------------------------------------------------------------- -// Metafunction Reference -// ---------------------------------------------------------------------------- - -template -struct Reference > -{ - typedef TValue & Type; -}; - -template -struct Reference const> -{ - typedef TValue const & Type; -}; - -// ---------------------------------------------------------------------------- -// Metafunction GetValue -// ---------------------------------------------------------------------------- - -template -struct GetValue >: - Reference >{}; - -template -struct GetValue const>: - Reference const>{}; - -// ---------------------------------------------------------------------------- -// Metafunction Position -// ---------------------------------------------------------------------------- - -template -struct Position > -{ - typedef typename DPMatrix_::THost TDataMatrix_; - typedef typename Position::Type Type; -}; - -template -struct Position const>: - Position >{}; - // ---------------------------------------------------------------------------- // Metafunction Size // ---------------------------------------------------------------------------- -template -struct Size > +template +struct Size > { - typedef typename DPMatrix_::THost TDataMatrix_; + typedef typename DPMatrix_::TMatrix TDataMatrix_; typedef typename Size::Type Type; }; -template -struct Size const>: - Size >{}; // ---------------------------------------------------------------------------- // Metafunction Host // ---------------------------------------------------------------------------- -template -struct Host > +template +struct Host > { - typedef DPMatrix_ TDPMatrix_; - typedef typename Member::Type TDataMatrix_; - typedef typename Host::Type Type; + typedef THost Type; }; -template -struct Host const> +template +struct Host const> { - typedef DPMatrix_ TDPMatrix_; - typedef typename Member::Type TDataMatrix_; - typedef typename Host::Type const Type; + typedef THost const Type; }; // ---------------------------------------------------------------------------- @@ -305,34 +255,34 @@ struct Host const> // non-rooted iterator to the underlying vector of the hosted two-dimensional // matrix. The rooted iterator returns the iterator defined by the // hosted matrix object which is a position iterator. -template -struct Iterator, Standard const> +template +struct Iterator, Standard> { - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Host::Type THost_; typedef typename Iterator::Type Type; }; -template -struct Iterator const, Standard const> +template +struct Iterator const, Standard> { - typedef DPMatrix_ const TDPMatrix_; + typedef DPMatrix_ const TDPMatrix_; typedef typename Host::Type THost_; typedef typename Iterator::Type Type; }; -template -struct Iterator, Rooted const> +template +struct Iterator, Rooted> { - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Member::Type TDataMatrix_; typedef typename Iterator::Type Type; }; -template -struct Iterator const, Rooted const> +template +struct Iterator const, Rooted> { - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Member::Type TDataMatrix_; typedef typename Iterator::Type Type; }; @@ -356,16 +306,16 @@ inline bool _checkCorrectDimension(DPMatrixDimension_::TValue dim) // ---------------------------------------------------------------------------- // Returns a reference to the hosted matrix. -template -inline Holder >::Type> & -_dataHost(DPMatrix_& dpMatrix) +template +inline Holder >::Type> & +_dataHost(DPMatrix_ & dpMatrix) { return _dataHost(value(dpMatrix.data_host)); } -template -inline Holder >::Type> const & -_dataHost(DPMatrix_ const & dpMatrix) +template +inline Holder >::Type> const & +_dataHost(DPMatrix_ const & dpMatrix) { return _dataHost(value(dpMatrix.data_host)); } @@ -375,16 +325,16 @@ _dataHost(DPMatrix_ const & dpMatrix) // ---------------------------------------------------------------------------- // Returns a reference to the _dataLengths container of the hosted matrix. -template -inline typename SizeArr_ >::Type & -_dataLengths(DPMatrix_&dpMatrix) +template +inline typename SizeArr_ >::Type & +_dataLengths(DPMatrix_&dpMatrix) { return _dataLengths(value(dpMatrix.data_host)); } -template -inline typename SizeArr_ const>::Type & -_dataLengths(DPMatrix_ const & dpMatrix) +template +inline typename SizeArr_ const>::Type & +_dataLengths(DPMatrix_ const & dpMatrix) { return _dataLengths(value(dpMatrix.data_host)); } @@ -394,16 +344,16 @@ _dataLengths(DPMatrix_ const & dpMatrix) // ---------------------------------------------------------------------------- // Returns a reference to the _dataFactors container of the hosted matrix. -template -inline typename SizeArr_ >::Type & -_dataFactors(DPMatrix_&dpMatrix) +template +inline typename SizeArr_ >::Type & +_dataFactors(DPMatrix_&dpMatrix) { return _dataFactors(value(dpMatrix.data_host)); } -template -inline typename SizeArr_ const>::Type & -_dataFactors(DPMatrix_ const & dpMatrix) +template +inline typename SizeArr_ const>::Type & +_dataFactors(DPMatrix_ const & dpMatrix) { return _dataFactors(value(dpMatrix.data_host)); } @@ -413,35 +363,35 @@ _dataFactors(DPMatrix_ const & dpMatrix) // ---------------------------------------------------------------------------- // Returns the value of the matrix at the given host position. -template -inline typename Reference >::Type -value(DPMatrix_ & dpMatrix, +template +inline typename Reference >::Type +value(DPMatrix_ & dpMatrix, TPosition const & pos) { return value(value(dpMatrix.data_host), pos); } -template -inline typename Reference const>::Type -value(DPMatrix_ const & dpMatrix, +template +inline typename Reference const>::Type +value(DPMatrix_ const & dpMatrix, TPosition const & pos) { return value(value(dpMatrix.data_host), pos); } // Returns the value of the matrix at the two given coordinates. -template -inline typename Reference >::Type -value(DPMatrix_ & dpMatrix, +template +inline typename Reference >::Type +value(DPMatrix_ & dpMatrix, TPositionV const & posDimV, TPositionH const & posDimH) { return value(value(dpMatrix.data_host), posDimV, posDimH); } -template -inline typename Reference const>::Type -value(DPMatrix_ const & dpMatrix, +template +inline typename Reference const>::Type +value(DPMatrix_ const & dpMatrix, TPositionV const & posDimV, TPositionH const & posDimH) { @@ -453,9 +403,9 @@ value(DPMatrix_ const & dpMatrix, // ---------------------------------------------------------------------------- // Returns the length of a given dimension. -template -inline typename Size const>::Type -length(DPMatrix_ const & dpMatrix, +template +inline typename Size const>::Type +length(DPMatrix_ const & dpMatrix, unsigned int dimension) { SEQAN_ASSERT(_checkCorrectDimension(dimension)); @@ -464,9 +414,9 @@ length(DPMatrix_ const & dpMatrix, } // Returns the overall length of the underlying vector of the hosted matrix. -template -inline typename Size const>::Type -length(DPMatrix_ const & dpMatrix) +template +inline typename Size const>::Type +length(DPMatrix_ const & dpMatrix) { return length(value(dpMatrix.data_host)); // Note that even if the dimensional lengths are set but the matrix was not resized // this function returns 0 or the previous length of the host before the resize. @@ -476,9 +426,9 @@ length(DPMatrix_ const & dpMatrix) // Function clear() // ---------------------------------------------------------------------------- -template +template inline void -clear(DPMatrix_ & dpMatrix) +clear(DPMatrix_ & dpMatrix) { clear(_dataLengths(dpMatrix)); resize(_dataLengths(dpMatrix), 2, 0); @@ -492,9 +442,9 @@ clear(DPMatrix_ & dpMatrix) // Function empty() // ---------------------------------------------------------------------------- -template +template inline bool -empty(DPMatrix_ const & dpMatrix) +empty(DPMatrix_ const & dpMatrix) { return empty(host(dpMatrix)); } @@ -504,9 +454,9 @@ empty(DPMatrix_ const & dpMatrix) // ---------------------------------------------------------------------------- // Sets the new length of a given dimension. -template +template inline void -setLength(DPMatrix_ & dpMatrix, +setLength(DPMatrix_ & dpMatrix, unsigned int dimension, TSize const & newLength) { @@ -518,11 +468,11 @@ setLength(DPMatrix_ & dpMatrix, // Function updateFactors() // ---------------------------------------------------------------------------- -template -inline typename Size >::Type -updateFactors(DPMatrix_ & dpMatrix) +template +inline typename Size >::Type +updateFactors(DPMatrix_ & dpMatrix) { - typedef typename Size >::Type TSize; + typedef typename Size >::Type TSize; TSize factor_ = _dataFactors(dpMatrix)[0] * length(dpMatrix, 0); for (unsigned int i = 1; (factor_ > 0) && (i < dimension(value(dpMatrix.data_host))); ++i) @@ -538,26 +488,26 @@ updateFactors(DPMatrix_ & dpMatrix) // ---------------------------------------------------------------------------- // Resizes the matrix. Note, the lengths of the dimensions have to be set before. -template +template inline void -resize(DPMatrix_ & dpMatrix) +resize(DPMatrix_ & dpMatrix) { - typedef typename Size >::Type TSize; + typedef typename Size >::Type TSize; TSize reqSize = updateFactors(dpMatrix); - if (reqSize >= length(dpMatrix)) + if (reqSize > length(dpMatrix)) resize(host(dpMatrix), reqSize, Exact()); } -template +template inline void -resize(DPMatrix_ & dpMatrix, +resize(DPMatrix_ & dpMatrix, TValue const & fillValue) { - typedef typename Size >::Type TSize; + typedef typename Size >::Type TSize; TSize reqSize = updateFactors(dpMatrix); - if (reqSize >= length(dpMatrix)) + if (reqSize > length(dpMatrix)) resize(host(dpMatrix), reqSize, fillValue, Exact()); } @@ -565,30 +515,30 @@ resize(DPMatrix_ & dpMatrix, // Function begin() // ---------------------------------------------------------------------------- -template -inline typename Iterator, Standard const>::Type -begin(DPMatrix_ & dpMatrix, Standard const) +template +inline typename Iterator, Standard>::Type +begin(DPMatrix_ & dpMatrix, Standard) { return begin(host(dpMatrix)); } -template -inline typename Iterator const, Standard const>::Type -begin(DPMatrix_ const & dpMatrix, Standard const) +template +inline typename Iterator const, Standard>::Type +begin(DPMatrix_ const & dpMatrix, Standard) { return begin(host(dpMatrix)); } -template -inline typename Iterator, Rooted const>::Type -begin(DPMatrix_ & dpMatrix, Rooted const) +template +inline typename Iterator, Rooted>::Type +begin(DPMatrix_ & dpMatrix, Rooted) { return begin(value(dpMatrix.data_host)); } -template -inline typename Iterator const, Rooted const>::Type -begin(DPMatrix_ const & dpMatrix, Rooted const) +template +inline typename Iterator const, Rooted>::Type +begin(DPMatrix_ const & dpMatrix, Rooted) { return begin(value(dpMatrix.data_host)); } @@ -597,30 +547,30 @@ begin(DPMatrix_ const & dpMatrix, Rooted const) // Function end() // ---------------------------------------------------------------------------- -template -inline typename Iterator, Standard const>::Type -end(DPMatrix_ & dpMatrix, Standard const) +template +inline typename Iterator, Standard>::Type +end(DPMatrix_ & dpMatrix, Standard) { return end(host(dpMatrix)); } -template -inline typename Iterator const, Standard const>::Type -end(DPMatrix_ const & dpMatrix, Standard const) +template +inline typename Iterator const, Standard>::Type +end(DPMatrix_ const & dpMatrix, Standard) { return end(host(dpMatrix)); } -template -inline typename Iterator, Rooted const>::Type -end(DPMatrix_ & dpMatrix, Rooted const) +template +inline typename Iterator, Rooted>::Type +end(DPMatrix_ & dpMatrix, Rooted) { return end(value(dpMatrix.data_host)); } -template -inline typename Iterator const, Rooted const>::Type -end(DPMatrix_ const & dpMatrix, Rooted const) +template +inline typename Iterator, Rooted>::Type +end(DPMatrix_ const & dpMatrix, Rooted) { return end(value(dpMatrix.data_host)); } @@ -630,15 +580,31 @@ end(DPMatrix_ const & dpMatrix, Rooted const) // ---------------------------------------------------------------------------- // Returns the coordinate of a host positio in a given dimension. -template -inline typename Position >::Type -coordinate(DPMatrix_ const & dpMatrix, +template +inline typename Position >::Type +coordinate(DPMatrix_ const & dpMatrix, TPosition hostPos, typename DPMatrixDimension_::TValue dimension) { return coordinate(value(dpMatrix.data_host), hostPos, dimension); } +// ---------------------------------------------------------------------------- +// Function toGlobalPosition() +// ---------------------------------------------------------------------------- + +// Returns the current position of the navigator within the matrix. +template +inline typename Position >::Type +toGlobalPosition(DPMatrix_ const & dpMatrix, + TPosH const horizontalCoordinate, + TPosV const verticalCoordinate) +{ + return horizontalCoordinate * length(dpMatrix, DPMatrixDimension_::VERTICAL) + verticalCoordinate; +} + } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_MATRIX_H_ diff --git a/porechop/include/seqan/align/dp_matrix_navigator.h b/porechop/include/seqan/align/dp_matrix_navigator.h index a39100b..4b5fa44 100644 --- a/porechop/include/seqan/align/dp_matrix_navigator.h +++ b/porechop/include/seqan/align/dp_matrix_navigator.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -82,6 +82,14 @@ struct DPTraceMatrix {}; struct NavigateColumnWise_; typedef Tag NavigateColumnWise; +// ---------------------------------------------------------------------------- +// Tag NavigateColumnWiseBanded +// ---------------------------------------------------------------------------- + +// Facilitates banded column wise navigation through the dp-matrix. +struct NavigateColumnWiseBanded_; +typedef Tag NavigateColumnWiseBanded; + // ---------------------------------------------------------------------------- // Class DPMatrixNavigator_ // ---------------------------------------------------------------------------- @@ -93,6 +101,24 @@ class DPMatrixNavigator_; // Metafunctions // ============================================================================ +// ---------------------------------------------------------------------------- +// Metafunction MatrixType +// ---------------------------------------------------------------------------- + +template +struct MatrixType; + +template +struct MatrixType > +{ + using Type = TDPMatrixType; +}; + +template +struct MatrixType const> : + MatrixType > +{}; + // ---------------------------------------------------------------------------- // Metafunction Value // ---------------------------------------------------------------------------- @@ -141,6 +167,16 @@ struct Container c typedef TDPMatrix const Type; }; +// ---------------------------------------------------------------------------- +// Metafunction Position +// ---------------------------------------------------------------------------- + +template +struct Position > +{ + typedef typename Position::Type Type; +}; + // ============================================================================ // Functions // ============================================================================ @@ -154,7 +190,7 @@ inline void assignValue(DPMatrixNavigator_ & dpNavigator, TValue const & element) { - assignValue(dpNavigator._activeColIterator, element); + *dpNavigator._activeColIterator = element; } // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/align/dp_matrix_navigator_score_matrix.h b/porechop/include/seqan/align/dp_matrix_navigator_score_matrix.h index 9110b49..ef1b3cc 100644 --- a/porechop/include/seqan/align/dp_matrix_navigator_score_matrix.h +++ b/porechop/include/seqan/align/dp_matrix_navigator_score_matrix.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -56,21 +56,66 @@ namespace seqan { // The navigator for the score matrix. // // This navigator runs on a FullDPMatrix while it navigates column wise. -template -class DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> + +template +class DPMatrixNavigator_, DPScoreMatrix, TNavigationSpec> { public: - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Pointer_::Type TDPMatrixPointer_; typedef typename Iterator::Type TDPMatrixIterator; - TDPMatrixPointer_ _ptrDataContainer = nullptr; // Pointer to the matrix this navigator is working on. - int _laneLeap = 0; // Stores the jump to the next column - TDPMatrixIterator _activeColIterator = TDPMatrixIterator(); // The active column iterator. - TDPMatrixIterator _prevColIterator = TDPMatrixIterator(); // The previous column iterator. - TValue _prevCellDiagonal = TValue(); // The previous diagonal cell - TValue _prevCellHorizontal = TValue(); // The previous Horizontal cell - TValue _prevCellVertical = TValue(); // The previous Vertical cell + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & /*band*/) + { + _ptrDataContainer = &matrix; + _prevColIteratorOffset = _dataFactors(matrix)[DPMatrixDimension_::HORIZONTAL]; + _activeColIterator = begin(matrix, Standard()); + _prevColIterator = _activeColIterator - _prevColIteratorOffset; + _laneLeap = 1; + *_activeColIterator = TValue(); + } + + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & band) + { + using TMatrixSize = typename Size::Type; + using TSignedSize = std::make_signed_t; + + _ptrDataContainer = &matrix; + _prevColIteratorOffset = _dataFactors(matrix)[DPMatrixDimension_::HORIZONTAL]; + // Band begins within the first row. + if (lowerDiagonal(band) >= 0) + { + _laneLeap = _min(length(matrix, DPMatrixDimension_::VERTICAL), bandSize(band)); + _activeColIterator = begin(matrix, Standard()) + _dataLengths(matrix)[DPMatrixDimension_::VERTICAL] - 1; + } + else if (upperDiagonal(band) <= 0) // Band begins within the first column. + { + _laneLeap = 1; + _activeColIterator = begin(matrix, Standard()); + } + else // Band intersects with the point of origin. + { + TMatrixSize lengthVertical = length(matrix, DPMatrixDimension_::VERTICAL); + int lastPos = _max(-static_cast(lengthVertical - 1), lowerDiagonal(band)); + _laneLeap = lengthVertical + lastPos; + _activeColIterator = begin(matrix, Standard()) + _laneLeap - 1; + } + // Set previous iterator to same position, one column left. + _prevColIterator = _activeColIterator - _prevColIteratorOffset; + *_activeColIterator = TValue(); + } + + TDPMatrixPointer_ _ptrDataContainer{nullptr}; // Pointer to the matrix this navigator is working on. + int _laneLeap{0}; // Stores the jump to the next column + size_t _prevColIteratorOffset{0}; // Offset to reset the previous column iterator when going to the next cell. + TDPMatrixIterator _activeColIterator{}; // The active column iterator. + TDPMatrixIterator _prevColIterator{}; // The previous column iterator. }; // ============================================================================ @@ -82,324 +127,286 @@ class DPMatrixNavigator_, DPScoreMatrix, Navigat // ============================================================================ // ---------------------------------------------------------------------------- -// Function _init() +// Function _goNextCell [banded, FirstCell] // ---------------------------------------------------------------------------- -// Initializes the navigator for an unbanded alignment. -template +// Needed to avoid ambigious overload. +template inline void -_init(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const &) -{ - navigator._ptrDataContainer = &dpMatrix; - navigator._activeColIterator = begin(dpMatrix, Standard()); - navigator._prevColIterator = navigator._activeColIterator - _dataFactors(dpMatrix)[DPMatrixDimension_::HORIZONTAL]; - navigator._laneLeap = 1; - assignValue(navigator._activeColIterator, TValue()); -} - -// Initializes the navigator for a banded alignment. -template -inline void -_init(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const & band) -{ - typedef typename Size >::Type TMatrixSize; - typedef typename MakeSigned::Type TSignedSize; - navigator._ptrDataContainer = &dpMatrix; - - - // Band begins within the first row. - if (lowerDiagonal(band) >= 0) - { - navigator._laneLeap = _min(length(dpMatrix, DPMatrixDimension_::VERTICAL), bandSize(band)); - navigator._activeColIterator = begin(dpMatrix, Standard()) + _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL] - 1; - } - else if (upperDiagonal(band) <= 0) // Band begins within the first column. - { - navigator._laneLeap = 1; - navigator._activeColIterator = begin(dpMatrix, Standard()); - } - else // Band intersects with the point of origin. - { - TMatrixSize lengthVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL); - int lastPos = _max(-static_cast(lengthVertical - 1), lowerDiagonal(band)); - navigator._laneLeap = lengthVertical + lastPos; - navigator._activeColIterator = begin(dpMatrix, Standard()) + navigator._laneLeap - 1; - } - // Set previous iterator to same position, one column left. - navigator._prevColIterator = navigator._activeColIterator - _dataFactors(dpMatrix)[DPMatrixDimension_::HORIZONTAL]; - assignValue(navigator._activeColIterator, TValue()); -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [DPInitialColumn, FirstCell] -// ---------------------------------------------------------------------------- - -// In the initial column we don't need to do anything because, the navigagtor is already initialized. -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/, MetaColumnDescriptor const &, FirstCell const &) { // no-op } -template +// Needed to avoid ambigious overload. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/, MetaColumnDescriptor const &, FirstCell const &) { // no-op } -template +// specialized for initialization column and all other column locations. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/, MetaColumnDescriptor const &, FirstCell const &) { // no-op } -// ---------------------------------------------------------------------------- -// Function _goNextCell() [PartialColumnTop, FirstCell] -// ---------------------------------------------------------------------------- - -// We are in the banded case, where the band crosses the first row. -// The left cell of the active cell is not valid, beacause we only can come from horizontal direction. -// The lower left cell of the active cell is the horizontal direction. -template +// specialized for all other column types located at the top. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, FirstCell const &) { --dpNavigator._laneLeap; dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevColIterator += dpNavigator._laneLeap; - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); + dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset + 1; } -// ---------------------------------------------------------------------------- -// Function _goNextCell() [FullColumn, FirstCell] -// ---------------------------------------------------------------------------- - -// We are in the unbanded case or in the middle phase of the wide band. -// The left cell of the active cell represents horizontal direction. -template +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, FirstCell const &) { dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevColIterator += dpNavigator._laneLeap; - dpNavigator._prevCellHorizontal = value(dpNavigator._prevColIterator); + dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset; +} + +// version for all other column types and locations. +template +inline void +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, + MetaColumnDescriptor const &, + FirstCell const &) +{ + dpNavigator._activeColIterator += dpNavigator._laneLeap; + dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset + 1; } // ---------------------------------------------------------------------------- -// Function _goNextCell() [PartialColumnMiddle, PartialColumnBottom, FirstCell] +// Function _goNextCell [unbanded, FirstCell] // ---------------------------------------------------------------------------- -// We are in the banded case. -// The left cell of the active cell represents diagonal direction. The lower left diagonal represents the horizontal direction. +// specialized for initalization column. +template +inline void +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, + MetaColumnDescriptor const &, + FirstCell const &) +{ + // no-op +} -template +// all other column types. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, FirstCell const &) { + // Set to begin of column. dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevColIterator += dpNavigator._laneLeap; - dpNavigator._prevCellDiagonal = value(dpNavigator._prevColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); + dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset; + } // ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, InnerCell] +// Function _goNextCell [banded, InnerCell] // ---------------------------------------------------------------------------- -// If we are in the initial column, we only need to represent the vertical direction. -// But we still have to update the previous column iterator. -template +// specilized for the initialization column and all column locations. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, InnerCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; - ++dpNavigator._prevColIterator; // Do we have to increase the prevColIterator.... } -// ---------------------------------------------------------------------------- -// Function _goNextCell [AnyColumn, InnerCell] -// ---------------------------------------------------------------------------- - -// For any other column type and location we can use the same navigation procedure. -template +// specialized for the standard band processing. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, InnerCell const &) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); ++dpNavigator._activeColIterator; + ++dpNavigator._prevColIterator; } // ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, LastCell] +// Function _goNextCell [unbanded, InnerCell] // ---------------------------------------------------------------------------- -// If we are in the initial column we only need to represent the vertical direction. -// But we still have to update the previous column iterator. -template +// specialized for the initialization column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + InnerCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; - ++dpNavigator._prevColIterator; } -// We need this function to avoid ambiguous function calls. -template +// version for the all other column types. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + InnerCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; ++dpNavigator._prevColIterator; } -// We need this function to avoid ambiguous function calls. -template +// ---------------------------------------------------------------------------- +// Function _goNextCell [banded, LastCell] +// ---------------------------------------------------------------------------- + +// specilaized for initialization column and bottom column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, + MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; - ++dpNavigator._prevColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [FullColumn, LastCell] -// ---------------------------------------------------------------------------- - -// If we are in a full column the values correspond to standard dp directions. -template +// specilaized for initialization column and all other column locations. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, + MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); ++dpNavigator._activeColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [PartialColumnBottom, LastCell] -// ---------------------------------------------------------------------------- - -// If we are in banded case and are the band crosses the last row, we have to update -// the additional leap for the current track. -template +// specialized for all column types and bottom column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); ++dpNavigator._activeColIterator; + ++dpNavigator._prevColIterator; ++dpNavigator._laneLeap; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [PartialColumnTop & PartialColumnBottom, LastCell] -// ---------------------------------------------------------------------------- - -// If we are in the banded case the left cell of the active represents the diagonal direction. -template +// generic case for all other column types and column locations. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; + ++dpNavigator._prevColIterator; } // ---------------------------------------------------------------------------- -// Function previousCellDiagonal() +// Function _goNextCell [unbanded, LastCell] // ---------------------------------------------------------------------------- -template -inline typename Reference >::Type -previousCellDiagonal(DPMatrixNavigator_ & dpNavigator) +// specilaized for initialization column. +template +inline void +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + LastCell const &) { - return dpNavigator._prevCellDiagonal; + ++dpNavigator._activeColIterator; } -template -inline typename Reference const>::Type -previousCellDiagonal(DPMatrixNavigator_ const & dpNavigator) +// version for all other column types. +template +inline void +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + LastCell const &) { - return dpNavigator._prevCellDiagonal; + ++dpNavigator._activeColIterator; // go to next cell. + ++dpNavigator._prevColIterator; // go to next cell. } // ---------------------------------------------------------------------------- -// Function previousCellHorizontal() +// Function _preInitCacheDiagonal() // ---------------------------------------------------------------------------- -template -inline typename Reference >::Type -previousCellHorizontal(DPMatrixNavigator_ & dpNavigator) +template +inline void +_preInitCacheDiagonal(TDPCell & cacheDiagonal, + DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> const & dpNavigator, + MetaColumnDescriptor const & /*tag*/) { - return dpNavigator._prevCellHorizontal; + _scoreOfCell(cacheDiagonal) = _scoreOfCell(*(dpNavigator._prevColIterator - 1)); } -template -inline typename Reference const>::Type -previousCellHorizontal(DPMatrixNavigator_ const & dpNavigator) +template +inline void +_preInitCacheDiagonal(TDPCell & cacheDiagonal, + DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWiseBanded> const & dpNavigator, + MetaColumnDescriptor const & /*tag*/) { - return dpNavigator._prevCellHorizontal; + _scoreOfCell(cacheDiagonal) = _scoreOfCell(*(dpNavigator._prevColIterator - 1)); +} + +template +inline void +_preInitCacheDiagonal(TDPCell & /*cacheDiagonal*/, + DPMatrixNavigator_, DPScoreMatrix, TNavigationSpec> const & /*dpNavigator*/, + MetaColumnDescriptor const & /*tag*/) +{ + // no-op } // ---------------------------------------------------------------------------- -// Function previousCellVertical() +// Function previousCellHorizontal() // ---------------------------------------------------------------------------- template inline typename Reference >::Type -previousCellVertical(DPMatrixNavigator_ & dpNavigator) +previousCellHorizontal(DPMatrixNavigator_ & dpNavigator) { - return dpNavigator._prevCellVertical; + return *dpNavigator._prevColIterator; } template inline typename Reference const>::Type -previousCellVertical(DPMatrixNavigator_ const & dpNavigator) +previousCellHorizontal(DPMatrixNavigator_ const & dpNavigator) { - return dpNavigator._prevCellVertical; + return *dpNavigator._prevColIterator; } } // namespace seqan diff --git a/porechop/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h b/porechop/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h index acc3267..18fb974 100644 --- a/porechop/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h +++ b/porechop/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h @@ -1,7 +1,8 @@ + // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -54,21 +55,60 @@ namespace seqan { // ---------------------------------------------------------------------------- // Specialization of the score matrix navigator for a sparse dp matrix. -template -class DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> +template +class DPMatrixNavigator_, DPScoreMatrix, TNavigationSpec> { public: - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Pointer_::Type TDPMatrixPointer_; typedef typename Iterator::Type TDPMatrixIterator; - TDPMatrixPointer_ _ptrDataContainer = nullptr; // Pointer to the underlying matrix to navigate on. - int _laneLeap = 0; // The distance to leap when going to the next column. - TDPMatrixIterator _activeColIterator = TDPMatrixIterator(); // The iterator over the active column. - TDPMatrixIterator _prevColIterator = TDPMatrixIterator(); // The iterator over the previous column. - TValue _prevCellDiagonal = TValue(); // The previous value in diagonal direction. - TValue _prevCellHorizontal = TValue(); // The previous value in horizontal direction. - TValue _prevCellVertical = TValue(); // The previous value in vertical direction. + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & /*band*/) + { + _ptrDataContainer = &matrix; + _activeColIterator = begin(matrix, Standard()); + _prevColIterator = _activeColIterator; + _laneLeap = 1 - _dataLengths(matrix)[DPMatrixDimension_::VERTICAL]; + *_activeColIterator = TValue(); + } + + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & band) + { + typedef typename Size::Type TSize; + typedef std::make_signed_t TSignedSize; + _ptrDataContainer = &matrix; + + // Band begins within the first row. + if (lowerDiagonal(band) >= 0) + { + _laneLeap = 0; + _activeColIterator = begin(matrix, Standard()) + length(matrix, DPMatrixDimension_::VERTICAL) - 1; + } + else if (upperDiagonal(band) <= 0) // Band begins within the first column + { + _laneLeap = 1 - _dataLengths(matrix)[DPMatrixDimension_::VERTICAL]; + _activeColIterator = begin(matrix, Standard()); + } + else // Band intersects with the point of origin. + { + _laneLeap = _max(lowerDiagonal(band), 1 - static_cast(length(matrix, DPMatrixDimension_::VERTICAL))); + _activeColIterator = begin(matrix, Standard()) + length(matrix, DPMatrixDimension_::VERTICAL) + _laneLeap - 1; + } + _prevColIterator = _activeColIterator; + *_activeColIterator = TValue(); + } + + TDPMatrixPointer_ _ptrDataContainer{nullptr}; // Pointer to the underlying matrix to navigate on. + int _laneLeap{0}; // The distance to leap when going to the next column. + size_t _prevColIteratorOffset{0}; // Offset to reset the previous column iterator when going to the next cell. + TDPMatrixIterator _activeColIterator{}; // The iterator over the active column. + TDPMatrixIterator _prevColIterator{}; // The iterator over the previous column. Only needed in the banded case. }; // ============================================================================ @@ -80,288 +120,133 @@ class DPMatrixNavigator_, DPScoreMatrix, Navig // ============================================================================ // ---------------------------------------------------------------------------- -// Function _init() -// ---------------------------------------------------------------------------- - - -// Initializes the navigator for unbanded alignments -template -inline void -_init(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const &) -{ - navigator._ptrDataContainer = &dpMatrix; - navigator._activeColIterator = begin(dpMatrix, Standard()); - navigator._prevColIterator = navigator._activeColIterator; - navigator._laneLeap = 1 - _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL]; - assignValue(navigator._activeColIterator, TValue()); -} - -// Initializes the navigator for banded alignments -template -inline void -_init(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const & band) -{ - typedef DPMatrix_ TSparseDPMatrix; - typedef typename Size::Type TSize; - typedef typename MakeSigned::Type TSignedSize; - navigator._ptrDataContainer = &dpMatrix; - - // Band begins within the first row. - if (lowerDiagonal(band) >= 0) - { - navigator._laneLeap = 0; - navigator._activeColIterator = begin(dpMatrix, Standard()) + length(dpMatrix, DPMatrixDimension_::VERTICAL) - 1; - } - else if (upperDiagonal(band) <= 0) // Band begins within the first column - { - navigator._laneLeap = 1 - _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL]; - navigator._activeColIterator = begin(dpMatrix, Standard()); - } - else // Band intersects with the point of origin. - { - navigator._laneLeap = _max(lowerDiagonal(band), 1 - static_cast(length(dpMatrix, DPMatrixDimension_::VERTICAL))); - navigator._activeColIterator = begin(dpMatrix, Standard()) + length(dpMatrix, DPMatrixDimension_::VERTICAL) + navigator._laneLeap - 1; - } - navigator._prevColIterator = navigator._activeColIterator; - assignValue(navigator._activeColIterator, TValue()); -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [DPInitialColumn, PartialColumnTop, FirstCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, - MetaColumnDescriptor const &, - FirstCell const &) -{ - // no-op -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [DPInitialColumn, FullColumn, FirstCell] +// Function _goNextCell [unbanded, FirstCell] // ---------------------------------------------------------------------------- -template +// specialized for initalization column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, MetaColumnDescriptor const &, FirstCell const &) { // no-op } -// ---------------------------------------------------------------------------- -// Function _goNextCell() [DPInitialColumn, FirstCell] -// ---------------------------------------------------------------------------- - -template +// all other column types. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/, - MetaColumnDescriptor const &, - FirstCell const &) -{ - // no-op -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [PartialColumnTop, FirstCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - FirstCell const &) -{ - --dpNavigator._laneLeap; - dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevColIterator = dpNavigator._activeColIterator; - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [FullColumn, FirstCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, MetaColumnDescriptor const &, FirstCell const &) { + // Set to begin of column. dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevCellHorizontal = value(dpNavigator._activeColIterator); -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [FirstCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - FirstCell const &) -{ - dpNavigator._activeColIterator += dpNavigator._laneLeap; - dpNavigator._prevColIterator = dpNavigator._activeColIterator; - dpNavigator._prevCellDiagonal = value(dpNavigator._prevColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); } // ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, InnerCell] +// Function _goNextCell [unbanded, InnerCell] // ---------------------------------------------------------------------------- -template +// specialized for the initialization column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - InnerCell const &) -{ - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - ++dpNavigator._activeColIterator; -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, FullColumn, InnerCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, MetaColumnDescriptor const &, InnerCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - ++dpNavigator._activeColIterator; -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell [InnerCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - InnerCell const &) -{ - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); ++dpNavigator._activeColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [FullColumn, InnerCell] -// ---------------------------------------------------------------------------- - -template +// version for the all other column types. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, MetaColumnDescriptor const &, InnerCell const &) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._activeColIterator); + ++dpNavigator._activeColIterator; } // ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, LastCell] +// Function _goNextCell [unbanded, LastCell] // ---------------------------------------------------------------------------- -template +// specilaized for initialization column. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); ++dpNavigator._activeColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, PartialColumnBottom, LastCell] -// ---------------------------------------------------------------------------- - -template +// version for all other column types. +template inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, LastCell const &) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - ++dpNavigator._activeColIterator; + ++dpNavigator._activeColIterator; // go to next cell. } // ---------------------------------------------------------------------------- -// Function _goNextCell [DPInitialColumn, FullColumn, LastCell] +// Function previousCellHorizontal() // ---------------------------------------------------------------------------- -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +// unbanded. +template +inline typename Reference, + DPScoreMatrix, + NavigateColumnWise> + >::Type +previousCellHorizontal(DPMatrixNavigator_, + DPScoreMatrix, + NavigateColumnWise> & dpNavigator) { - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - ++dpNavigator._activeColIterator; + return *dpNavigator._activeColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [LastCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +template +inline typename Reference, + DPScoreMatrix, + NavigateColumnWise> const + >::Type +previousCellHorizontal(DPMatrixNavigator_, + DPScoreMatrix, + NavigateColumnWise> const & dpNavigator) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - ++dpNavigator._activeColIterator; + return *dpNavigator._activeColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [PartialColumnBottom, LastCell] -// ---------------------------------------------------------------------------- - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +// banded. +template +inline typename Reference, + DPScoreMatrix, + NavigateColumnWiseBanded> + >::Type +previousCellHorizontal(DPMatrixNavigator_, + DPScoreMatrix, + NavigateColumnWiseBanded> & dpNavigator) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator); - ++dpNavigator._activeColIterator; - ++dpNavigator._laneLeap; + return *dpNavigator._prevColIterator; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [FullColumn, LastCell] -// ---------------------------------------------------------------------------- - - -template -inline void -_goNextCell(DPMatrixNavigator_, DPScoreMatrix, NavigateColumnWise> & dpNavigator, - MetaColumnDescriptor const &, - LastCell const &) +template +inline typename Reference, + DPScoreMatrix, + NavigateColumnWiseBanded> const + >::Type +previousCellHorizontal(DPMatrixNavigator_, + DPScoreMatrix, + NavigateColumnWiseBanded> const & dpNavigator) { - dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal; - dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator); - dpNavigator._prevCellHorizontal = value(++dpNavigator._activeColIterator); + return *(dpNavigator._prevColIterator); } } // namespace seqan diff --git a/porechop/include/seqan/align/dp_matrix_navigator_trace_matrix.h b/porechop/include/seqan/align/dp_matrix_navigator_trace_matrix.h index 0fc7233..3735d2a 100644 --- a/porechop/include/seqan/align/dp_matrix_navigator_trace_matrix.h +++ b/porechop/include/seqan/align/dp_matrix_navigator_trace_matrix.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -64,19 +64,70 @@ namespace seqan { // specifies that this is a trace-matrix navigator while the TTraceFlag can either // be TracebackOn to enable the navigator or TracebackOff to disable it. // The last parameter specifies the kind of navigation. -template -class DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> +template +class DPMatrixNavigator_, DPTraceMatrix, TNavigationSpec> { public: - typedef DPMatrix_ TDPMatrix_; + typedef DPMatrix_ TDPMatrix_; typedef typename Pointer_::Type TDPMatrixPointer_; typedef typename Iterator::Type TDPMatrixIterator; - TDPMatrixPointer_ _ptrDataContainer = nullptr; // The pointer to the underlying Matrix. - int _laneLeap = 0; // Keeps track of the jump size from one column to another. - unsigned _simdLane = 0; // Used for tracing the correct cell in case of simd vectors. - TDPMatrixIterator _activeColIterator = TDPMatrixIterator(); // The current column iterator. + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & /*band*/) + { + if (IsSameType::VALUE) + return; // Leave navigator uninitialized because it is never used. + + _ptrDataContainer = &matrix; + _activeColIterator = begin(matrix, Standard()); + _laneLeap = 1; + *_activeColIterator = TValue(); + } + + template ::value, int> = 0> + DPMatrixNavigator_(TDPMatrix_ & matrix, + DPBandConfig const & band) + { + using TMatrixSize = typename Size::Type; + using TSignedSize = std::make_signed_t; + + if (std::is_same::value) + return; // Leave navigator as is because it should never be used. + + _ptrDataContainer = &matrix; + + // Band begins within the first row. + if (lowerDiagonal(band) >= 0) + { + // The first cell of the first column starts at the last cell in the matrix of the current column. + _laneLeap = _min(length(matrix, DPMatrixDimension_::VERTICAL), bandSize(band)); + _activeColIterator = begin(matrix, Standard()) + _dataLengths(matrix)[DPMatrixDimension_::VERTICAL] - 1; + } + else if (upperDiagonal(band) <= 0) // Band begins within the first column. + { + // The first cell starts at the beginning of the current column. + _laneLeap = 1; + _activeColIterator = begin(matrix, Standard()); + } + else // Band intersects with the point of origin. + { + // First cell starts at position i, such that i + abs(lowerDiagonal) = length(seqV). + TMatrixSize lengthVertical = length(matrix, DPMatrixDimension_::VERTICAL); + int lastPos = _max(-static_cast(lengthVertical - 1), lowerDiagonal(band)); + _laneLeap = lengthVertical + lastPos; + _activeColIterator = begin(matrix, Standard()) + _laneLeap - 1; + } + *_activeColIterator = TValue(); + } + + TDPMatrixPointer_ _ptrDataContainer{nullptr}; // The pointer to the underlying Matrix. + int _laneLeap{0}; // Keeps track of the jump size from one column to another. + unsigned _simdLane{0}; // Used for tracing the correct cell in case of simd vectors. + TDPMatrixIterator _activeColIterator{}; // The current column iterator. }; // ============================================================================ @@ -88,99 +139,43 @@ class DPMatrixNavigator_, DPTraceMatrix -inline void -_init(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const &) -{ - if (IsSameType::VALUE) - return; // Leave navigator uninitialized because it is never used. - - navigator._ptrDataContainer = &dpMatrix; - navigator._activeColIterator = begin(dpMatrix, Standard()); - navigator._laneLeap = 1; - assignValue(navigator._activeColIterator, TValue()); -} - -// Initializes the navigator for banded alignments. -// Note, the band size has a maximal width of length of the vertical sequence. -template -inline void -_init(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & navigator, - DPMatrix_ & dpMatrix, - DPBandConfig const & band) -{ - typedef typename Size >::Type TMatrixSize; - typedef typename MakeSigned::Type TSignedSize; - - if (IsSameType::VALUE) - return; // Leave navigator as is because it should never be used. - - navigator._ptrDataContainer = &dpMatrix; - - // Band begins within the first row. - if (lowerDiagonal(band) >= 0) - { - // The first cell of the first column starts at the last cell in the matrix of the current column. - navigator._laneLeap = _min(length(dpMatrix, DPMatrixDimension_::VERTICAL), bandSize(band)); - navigator._activeColIterator = begin(dpMatrix, Standard()) + _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL] - 1; - } - else if (upperDiagonal(band) <= 0) // Band begins within the first column. - { - // The first cell starts at the beginning of the current column. - navigator._laneLeap = 1; - navigator._activeColIterator = begin(dpMatrix, Standard()); - } - else // Band intersects with the point of origin. - { - // First cell starts at position i, such that i + abs(lowerDiagonal) = length(seqV). - TMatrixSize lengthVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL); - int lastPos = _max(-static_cast(lengthVertical - 1), lowerDiagonal(band)); - navigator._laneLeap = lengthVertical + lastPos; - navigator._activeColIterator = begin(dpMatrix, Standard()) + navigator._laneLeap - 1; - } - assignValue(navigator._activeColIterator, TValue()); -} - -// ---------------------------------------------------------------------------- -// Function _goNextCell() [DPInitialColumn, FirstCell] +// Function _goNextCell() [banded, FirstCell] // ---------------------------------------------------------------------------- // In the initial column we don't need to do anything because, the navigagtor is already initialized. -template +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & /*dpNavigator*/, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & /*dpNavigator*/, + MetaColumnDescriptor const &, FirstCell const &) { // no-op } -template +// overload needed to avoid ambigious overload. +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & /*dpNavigator*/, - MetaColumnDescriptor const &, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & /*dpNavigator*/, + MetaColumnDescriptor const &, FirstCell const &) { // no-op } -// ---------------------------------------------------------------------------- -// Function _goNextCell() [PartialColumnTop, FirstCell] -// ---------------------------------------------------------------------------- - // We are in the banded case, where the band crosses the first row. // The left cell of the active cell is not valid, beacause we only can come from horizontal direction. // The lower left cell of the active cell is the horizontal direction. - -template +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, FirstCell const &) { @@ -191,53 +186,108 @@ _goNextCell(DPMatrixNavigator_, DPTraceMatrix +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, FirstCell const &) { if (IsSameType::VALUE) return; // Do nothing since no trace back is computed. + // go to begin of next column. dpNavigator._activeColIterator += dpNavigator._laneLeap; } // ---------------------------------------------------------------------------- -// Function _goNextCell [any column, InnerCell] +// Function _goNextCell() [unbanded, FirstCell] +// ---------------------------------------------------------------------------- + +// +template +inline void +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWise> & /*dpNavigator*/, + MetaColumnDescriptor const &, + FirstCell const &) +{ + // no-op +} + +template +inline void +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + FirstCell const &) +{ + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) + return; // Do nothing since no trace back is computed. + + dpNavigator._activeColIterator += dpNavigator._laneLeap; +} + +// ---------------------------------------------------------------------------- +// Function _goNextCell [banded, InnerCell] // ---------------------------------------------------------------------------- // For any other column type and location we can use the same navigation procedure. -template +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, InnerCell const &) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. ++dpNavigator._activeColIterator; } // ---------------------------------------------------------------------------- -// Function _goNextCell [PartialColumnBottom, LastCell] +// Function _goNextCell [unbanded, InnerCell] // ---------------------------------------------------------------------------- -template +// For any other column type and location we can use the same navigation procedure. +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + InnerCell const &) +{ + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) + return; // Do nothing since no trace back is computed. + + ++dpNavigator._activeColIterator; +} + +// ---------------------------------------------------------------------------- +// Function _goNextCell [banded, LastCell] +// ---------------------------------------------------------------------------- + +template +inline void +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, LastCell const &) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. ++dpNavigator._activeColIterator; @@ -245,27 +295,29 @@ _goNextCell(DPMatrixNavigator_, DPTraceMatrix +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, LastCell const &) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. ++dpNavigator._activeColIterator; ++dpNavigator._laneLeap; } -// ---------------------------------------------------------------------------- -// Function _goNextCell [any other column, LastCell] -// ---------------------------------------------------------------------------- - // If we are in the banded case the left cell of the active represents the diagonal direction. -template +template inline void -_goNextCell(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWiseBanded> & dpNavigator, MetaColumnDescriptor const &, LastCell const &) { @@ -275,16 +327,37 @@ _goNextCell(DPMatrixNavigator_, DPTraceMatrix +inline void +_goNextCell(DPMatrixNavigator_, + DPTraceMatrix, + NavigateColumnWise> & dpNavigator, + MetaColumnDescriptor const &, + LastCell const &) +{ + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) + return; // Do nothing since no trace back is computed. + + ++dpNavigator._activeColIterator; +} + // ---------------------------------------------------------------------------- // Function _traceHorizontal() // ---------------------------------------------------------------------------- -template +template inline void -_traceHorizontal(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_traceHorizontal(DPMatrixNavigator_, + DPTraceMatrix, + TNavigationSpec> & dpNavigator, bool isBandShift) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. if (isBandShift) @@ -298,12 +371,14 @@ _traceHorizontal(DPMatrixNavigator_, DPTraceMatr // Function _traceDiagonal() // ---------------------------------------------------------------------------- -template +template inline void -_traceDiagonal(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_traceDiagonal(DPMatrixNavigator_, + DPTraceMatrix, + TNavigationSpec> & dpNavigator, bool isBandShift) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. if (isBandShift) @@ -317,12 +392,14 @@ _traceDiagonal(DPMatrixNavigator_, DPTraceMatrix // Function _traceVertical() // ---------------------------------------------------------------------------- -template +template inline void -_traceVertical(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_traceVertical(DPMatrixNavigator_, + DPTraceMatrix, + TNavigationSpec> & dpNavigator, bool /*isBandShift*/) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::VERTICAL]; @@ -332,12 +409,15 @@ _traceVertical(DPMatrixNavigator_, DPTraceMatrix // Function setToPosition() // ---------------------------------------------------------------------------- -template +template inline void -_setToPosition(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_setToPosition(DPMatrixNavigator_, + DPTraceMatrix, + TNavigationSpec> & dpNavigator, TPosition const & hostPosition) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; SEQAN_ASSERT_LT(hostPosition, static_cast(length(container(dpNavigator)))); @@ -349,13 +429,16 @@ _setToPosition(DPMatrixNavigator_, DPTraceMatrix // Sets the host position based on the given horizontal and vertical position. Note that the horizontal and // vertical positions must correspond to the correct size of the underlying matrix. // For banded matrices the vertical dimension might not equal the length of the vertical sequence. -template +template inline void -_setToPosition(DPMatrixNavigator_, DPTraceMatrix, NavigateColumnWise> & dpNavigator, +_setToPosition(DPMatrixNavigator_, + DPTraceMatrix, + TNavigationSpec> & dpNavigator, TPositionH const & horizontalPosition, TPositionV const & verticalPosition) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; SEQAN_ASSERT_LT(horizontalPosition, static_cast(length(container(dpNavigator), +DPMatrixDimension_::HORIZONTAL))); SEQAN_ASSERT_LT(verticalPosition, static_cast(length(container(dpNavigator), +DPMatrixDimension_::VERTICAL))); @@ -368,15 +451,16 @@ _setToPosition(DPMatrixNavigator_, DPTraceMatrix // Function assignValue() // ---------------------------------------------------------------------------- -template +template inline void assignValue(DPMatrixNavigator_, TNavigationSpec> & dpNavigator, TValue const & element) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Do nothing since no trace back is computed. - assignValue(dpNavigator._activeColIterator, element); + *dpNavigator._activeColIterator = element; } // ---------------------------------------------------------------------------- @@ -385,7 +469,7 @@ assignValue(DPMatrixNavigator_, TNavigation // SIMD Version. Returns always a copy and never a reference. template -inline SEQAN_FUNC_ENABLE_IF(Is >, typename Value::Type) +inline SEQAN_FUNC_ENABLE_IF(Is >, typename TraceBitMap_<>::Type) _scalarValue(TValue const & vec, TPos const pos) { @@ -394,7 +478,7 @@ _scalarValue(TValue const & vec, // Non-simd variant. Identity version. template -inline SEQAN_FUNC_ENABLE_IF(Not > >, TValue &) +inline SEQAN_FUNC_ENABLE_IF(Not > >, TValue) _scalarValue(TValue & val, TPos const /*pos*/) { @@ -406,7 +490,7 @@ template inline auto scalarValue(DPMatrixNavigator_, TNavigationSpec> const & dpNavigator) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); return _scalarValue(*dpNavigator._activeColIterator, dpNavigator._simdLane); @@ -421,7 +505,7 @@ template inline typename Reference, TNavigationSpec> >::Type value(DPMatrixNavigator_, TNavigationSpec> & dpNavigator) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); return *dpNavigator._activeColIterator; @@ -431,7 +515,7 @@ template inline typename Reference, TNavigationSpec> const >::Type value(DPMatrixNavigator_, TNavigationSpec> const & dpNavigator) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); return *dpNavigator._activeColIterator; @@ -443,18 +527,19 @@ inline typename Reference, TNavigationSpec> & dpNavigator, TPosition const & position) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); return *(begin(*dpNavigator._ptrDataContainer) + position); } -template +template inline typename Reference, TNavigationSpec> const >::Type value(DPMatrixNavigator_, TNavigationSpec> const & dpNavigator, TPosition const & position) { - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); return *(begin(*dpNavigator._ptrDataContainer) + position); @@ -467,20 +552,41 @@ value(DPMatrixNavigator_, TNavigationSpec> // Returns the coordinate of the given dimension for the current position of the // navigator within the matrix. template -inline typename DPMatrixDimension_::TValue +inline size_t coordinate(DPMatrixNavigator_, TNavigationSpec> const & dpNavigator, typename DPMatrixDimension_::TValue const & dimension) { if (IsSameType::VALUE) - SEQAN_ASSERT_FAIL("Try to access uninitialized object!"); + return 0; // Returns default 0, when traceback is set off. SEQAN_ASSERT_EQ(_checkCorrectDimension(dimension), true); - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return _dataLengths(*dpNavigator._ptrDataContainer)[dimension]; // Return lengths of given dimension. return coordinate(value(dpNavigator._ptrDataContainer), position(dpNavigator), dimension); // Simply delegate to coordinate of underlying matrix. } +// ---------------------------------------------------------------------------- +// Function toGlobalPosition() +// ---------------------------------------------------------------------------- + +// Returns the current position of the navigator within the matrix. +template +inline typename Position, TNavigationSpec> >::Type +toGlobalPosition(DPMatrixNavigator_, TNavigationSpec> const & dpNavigator, + TPosH const horizontalCoordinate, + TPosV const verticalCoordinate) +{ + // Return 0 when traceback is not enabled. This is necessary to still track the score even + // the traceback is not enabled. + if (IsSameType::VALUE) + return 0; + + return toGlobalPosition(*dpNavigator._ptrDataContainer, horizontalCoordinate, verticalCoordinate); +} + // ---------------------------------------------------------------------------- // Function position() // ---------------------------------------------------------------------------- @@ -492,7 +598,7 @@ position(DPMatrixNavigator_, TNavigationSpe { // Return 0 when traceback is not enabled. This is necessary to still track the score even // the traceback is not enabled. - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return 0; return position(dpNavigator._activeColIterator, *dpNavigator._ptrDataContainer); @@ -502,7 +608,8 @@ position(DPMatrixNavigator_, TNavigationSpe // Function _setSimdLane() // ---------------------------------------------------------------------------- -template +template inline void _setSimdLane(DPMatrixNavigator_, TNavigationSpec> & dpNavigator, TPos const pos) diff --git a/porechop/include/seqan/align/dp_matrix_sparse.h b/porechop/include/seqan/align/dp_matrix_sparse.h index 4666a46..53ea660 100644 --- a/porechop/include/seqan/align/dp_matrix_sparse.h +++ b/porechop/include/seqan/align/dp_matrix_sparse.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -49,14 +49,14 @@ namespace seqan { // Class DPMatrix [SparseDPMatrix] // ---------------------------------------------------------------------------- -template -class DPMatrix_ +template +class DPMatrix_ { public: - typedef typename Member::Type THost; + typedef typename Member::Type TMatrix; - Holder data_host; // The host containing the actual matrix. + Holder data_host; // The host containing the actual matrix. DPMatrix_() : data_host() @@ -77,11 +77,11 @@ class DPMatrix_ // Function resize() // ---------------------------------------------------------------------------- -template +template inline void -resize(DPMatrix_ & dpMatrix) +resize(DPMatrix_ & dpMatrix) { - typedef DPMatrix_ TDPMatrix; + typedef DPMatrix_ TDPMatrix; typedef typename Size::Type TSize; TSize _dimVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL); @@ -90,12 +90,12 @@ resize(DPMatrix_ & dpMatrix) resize(host(dpMatrix), _dimVertical, Exact()); } -template +template inline void -resize(DPMatrix_ & dpMatrix, +resize(DPMatrix_ & dpMatrix, TValue const & fillValue) { - typedef DPMatrix_ TDPMatrix; + typedef DPMatrix_ TDPMatrix; typedef typename Size::Type TSize; TSize _dimVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL); @@ -108,18 +108,18 @@ resize(DPMatrix_ & dpMatrix, // Function value() // ---------------------------------------------------------------------------- -template -inline typename Reference >::Type -value(DPMatrix_ & dpMatrix, +template +inline typename Reference >::Type +value(DPMatrix_ & dpMatrix, TPositionV const & posV, TPositionH const &) { return value(dpMatrix, posV); } -template -inline typename Reference const>::Type -value(DPMatrix_ const & dpMatrix, +template +inline typename Reference const>::Type +value(DPMatrix_ const & dpMatrix, TPositionV const & posV, TPositionH const &) { @@ -131,9 +131,9 @@ value(DPMatrix_ const & dpMatrix, // ---------------------------------------------------------------------------- -template -inline typename Position >::Type -coordinate(DPMatrix_ const & /*dpMatrix*/, +template +inline typename Position >::Type +coordinate(DPMatrix_ const & /*dpMatrix*/, TPosition hostPos, typename DPMatrixDimension_::TValue dimension) { diff --git a/porechop/include/seqan/align/dp_meta_info.h b/porechop/include/seqan/align/dp_meta_info.h index dab1bdc..f0e5219 100644 --- a/porechop/include/seqan/align/dp_meta_info.h +++ b/porechop/include/seqan/align/dp_meta_info.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -451,7 +451,7 @@ struct TrackingEnabled_: template struct LastColumnEnabled_ { - typedef typename IsSameType::Type Type; + typedef typename IsSameType::Type Type; }; template diff --git a/porechop/include/seqan/align/dp_profile.h b/porechop/include/seqan/align/dp_profile.h index f57e161..8085bca 100644 --- a/porechop/include/seqan/align/dp_profile.h +++ b/porechop/include/seqan/align/dp_profile.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -80,7 +80,7 @@ typedef Tag SplitBreakpointAlignment; // // Note, all global alignments have to be specialized versions of GlobalAlignment_<> template > -struct GlobalAlignment_; +struct GlobalAlignment_{}; typedef GlobalAlignment_<> DPGlobal; @@ -103,61 +103,82 @@ typedef Tag SuboptimalAlignment; // Note, all local alignments have to be specialized versions of LocalAlignment_<> template -struct LocalAlignment_; +struct LocalAlignment_{}; typedef LocalAlignment_<> DPLocal; typedef LocalAlignment_ DPLocalEnumerate; -// Use macro expansion to define all possible SIMD initialization types. - -template -struct InitSimdTrace_; - -#define SEQAN_SIMD_INIT_FILL_VALUE_2_ FILL_VALUE, FILL_VALUE -#define SEQAN_SIMD_INIT_FILL_VALUE_4_ SEQAN_SIMD_INIT_FILL_VALUE_2_, SEQAN_SIMD_INIT_FILL_VALUE_2_ -#define SEQAN_SIMD_INIT_FILL_VALUE_8_ SEQAN_SIMD_INIT_FILL_VALUE_4_, SEQAN_SIMD_INIT_FILL_VALUE_4_ -#define SEQAN_SIMD_INIT_FILL_VALUE_16_ SEQAN_SIMD_INIT_FILL_VALUE_8_, SEQAN_SIMD_INIT_FILL_VALUE_8_ -#define SEQAN_SIMD_INIT_FILL_VALUE_32_ SEQAN_SIMD_INIT_FILL_VALUE_16_, SEQAN_SIMD_INIT_FILL_VALUE_16_ - -#define SEQAN_SIMD_TRACE_SETUP_2_(SIZE, ...) \ -template \ -struct InitSimdTrace_ \ -{ \ - static const TVector VALUE; \ -}; \ - \ -template \ -const TVector InitSimdTrace_::VALUE = TVector{__VA_ARGS__}; - -#define SEQAN_SIMD_TRACE_SETUP_1_(SIZE, MACRO) SEQAN_SIMD_TRACE_SETUP_2_(SIZE, MACRO) -#define SEQAN_SIMD_TRACE_SETUP_(SIZE) SEQAN_SIMD_TRACE_SETUP_1_(SIZE, SEQAN_SIMD_INIT_FILL_VALUE_ ## SIZE ## _) - -SEQAN_SIMD_TRACE_SETUP_(2) -SEQAN_SIMD_TRACE_SETUP_(4) -SEQAN_SIMD_TRACE_SETUP_(8) -SEQAN_SIMD_TRACE_SETUP_(16) -SEQAN_SIMD_TRACE_SETUP_(32) - -// Scalar version. +// ---------------------------------------------------------------------------- +// Class TraceBitMap_ +// ---------------------------------------------------------------------------- + +// Defines static const/constexpr tables for the traceback directions. +// We use TraceValue_ as a helper to distinguish between vector and +// scalar version. +// For the vector version we use some compile time hackery to initialize the +// const vector values with the corresponding values generically for +// seqan simd vector types and UME::SIMD vector types. template struct TraceValue_ { typedef uint8_t Type; - static const Type NONE = 0u; //0000000 - static const Type DIAGONAL = 1u; //0000001 - static const Type HORIZONTAL = 2u; //0000010 - static const Type VERTICAL = 4u; //0000100 - static const Type HORIZONTAL_OPEN = 8u; //0001000 - static const Type VERTICAL_OPEN = 16u; //0010000 - static const Type MAX_FROM_HORIZONTAL_MATRIX = 32u; //0100000 - static const Type MAX_FROM_VERTICAL_MATRIX = 64u; //1000000 - static const Type NO_VERTICAL_TRACEBACK = ~(VERTICAL | VERTICAL_OPEN); - static const Type NO_HORIZONTAL_TRACEBACK = ~(HORIZONTAL | HORIZONTAL_OPEN); + static constexpr Type NONE = 0u; //0000000 + static constexpr Type DIAGONAL = 1u; //0000001 + static constexpr Type HORIZONTAL = 2u; //0000010 + static constexpr Type VERTICAL = 4u; //0000100 + static constexpr Type HORIZONTAL_OPEN = 8u; //0001000 + static constexpr Type VERTICAL_OPEN = 16u; //0010000 + static constexpr Type MAX_FROM_HORIZONTAL_MATRIX = 32u; //0100000 + static constexpr Type MAX_FROM_VERTICAL_MATRIX = 64u; //1000000 + static constexpr Type NO_VERTICAL_TRACEBACK = ~(VERTICAL | VERTICAL_OPEN); + static constexpr Type NO_HORIZONTAL_TRACEBACK = ~(HORIZONTAL | HORIZONTAL_OPEN); }; -// SIMD Vector version. -template -struct TraceValue_ +template +constexpr typename TraceValue_::Type TraceValue_::NONE; +template +constexpr typename TraceValue_::Type TraceValue_::DIAGONAL; +template +constexpr typename TraceValue_::Type TraceValue_::HORIZONTAL; +template +constexpr typename TraceValue_::Type TraceValue_::VERTICAL; +template +constexpr typename TraceValue_::Type TraceValue_::HORIZONTAL_OPEN; +template +constexpr typename TraceValue_::Type TraceValue_::VERTICAL_OPEN; +template +constexpr typename TraceValue_::Type TraceValue_::MAX_FROM_HORIZONTAL_MATRIX; +template +constexpr typename TraceValue_::Type TraceValue_::MAX_FROM_VERTICAL_MATRIX; +template +constexpr typename TraceValue_::Type TraceValue_::NO_VERTICAL_TRACEBACK; +template +constexpr typename TraceValue_::Type TraceValue_::NO_HORIZONTAL_TRACEBACK; + +// Recursion anchor to return the generated tuple with all fill values. +template +constexpr auto _fillTraceValueVector(std::index_sequence<0> const &, std::tuple const & t) +{ + return t; +} + +// Helper function to fill the vector with the correct number of values. +// We use the std::tuple (which supports constexpr functions) to make it evaluate at compile time. +template +constexpr auto _fillTraceValueVector(std::index_sequence const &, std::tuple const & t) +{ + // Expand the tuple by one and return the next tuple while reducing the number of elements to add. + return _fillTraceValueVector(std::make_index_sequence{}, + std::tuple_cat(std::make_tuple(std::get<0>(t)), t)); +} + +// Helper class to used to expand the elements from the returned tuple with the fill values. +// NOTE(rrahn): Might be easier to solve with fold expressions in SeqAn3. +template +struct TraceValueVectorBase_; + +template +struct TraceValueVectorBase_> { typedef TVector Type; static const Type NONE; @@ -172,26 +193,46 @@ struct TraceValue_ static const Type NO_VERTICAL_TRACEBACK; }; -// Macro expansion to define out-of-class initialization of static members. +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::NONE = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::NONE)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::DIAGONAL = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::DIAGONAL)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::HORIZONTAL = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::HORIZONTAL)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::VERTICAL = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::VERTICAL)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::HORIZONTAL_OPEN = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::HORIZONTAL_OPEN)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::VERTICAL_OPEN = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::VERTICAL_OPEN)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::MAX_FROM_HORIZONTAL_MATRIX = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::MAX_FROM_HORIZONTAL_MATRIX)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::MAX_FROM_VERTICAL_MATRIX = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::MAX_FROM_VERTICAL_MATRIX)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::NO_VERTICAL_TRACEBACK = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::NO_HORIZONTAL_TRACEBACK)))...}; +template +const typename TraceValueVectorBase_>::Type TraceValueVectorBase_>::NO_HORIZONTAL_TRACEBACK = + {std::get(_fillTraceValueVector(std::make_index_sequence::VALUE>{}, std::make_tuple(TraceValue_::NO_VERTICAL_TRACEBACK)))...}; -#define SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(TRACE_VALUE) \ - template \ - const TVector TraceValue_::TRACE_VALUE = InitSimdTrace_::TRACE_VALUE, LENGTH::VALUE>::VALUE; - -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NONE) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(DIAGONAL) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(HORIZONTAL) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(VERTICAL) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(HORIZONTAL_OPEN) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(VERTICAL_OPEN) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(MAX_FROM_HORIZONTAL_MATRIX) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(MAX_FROM_VERTICAL_MATRIX) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NO_HORIZONTAL_TRACEBACK) -SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NO_VERTICAL_TRACEBACK) +// SIMD Vector version. +// Simply delegates to the base class by passing the index_sequence with the corresponding length of the vector. +template +struct TraceValue_ : public TraceValueVectorBase_::VALUE>> +{}; // Type alias to choose between scalar and simd version of trace value. -template -using TraceBitMap_ = TraceValue_ >::Type >; +template +using TraceBitMap_ = TraceValue_ >::Type>; // ---------------------------------------------------------------------------- // Tag GapsLeft @@ -298,10 +339,9 @@ typedef Tag DynamicGaps; // TAlignment: The type to select the pairwise alignment algorithm. // TGapCosts: The gap cost function (LinearGaps or AffineGaps). // TTraceback: The traceback switch (TracebackOn or TracebackOff). -template +template struct DPProfile_ {}; - // ---------------------------------------------------------------------------- // Tag DPFirstRow // ---------------------------------------------------------------------------- @@ -351,6 +391,63 @@ class AlignConfig2 // Metafunctions // ============================================================================ +enum class DPProfileTypeId : uint8_t +{ + ALGORITHM = 0, + GAP_MODEL = 1, + TRACE_CONFIG = 2, + EXEC_POLICY = 3 +}; + +// ---------------------------------------------------------------------------- +// Metafunction DPContextSpec +// ---------------------------------------------------------------------------- + +template +struct DPProfileType; + +template +struct DPProfileType, DPProfileTypeId::ALGORITHM> +{ + using Type = TAlignment; +}; + +template +struct DPProfileType, DPProfileTypeId::GAP_MODEL> +{ + using Type = TGapCosts; +}; + +template +struct DPProfileType, DPProfileTypeId::TRACE_CONFIG> +{ + using Type = TTraceback; +}; + +template +struct DPProfileType, DPProfileTypeId::EXEC_POLICY> +{ + using Type = TExecPolicy; +}; + +// ---------------------------------------------------------------------------- +// Metafunction GapTraits +// ---------------------------------------------------------------------------- + +template +struct GapTraits; + +template +struct GapTraits : + GapTraits +{}; + +template +struct GapTraits > +{ + typedef TGapCosts Type; +}; + // ---------------------------------------------------------------------------- // Metafunction IsGlobalAlignment // ---------------------------------------------------------------------------- @@ -368,12 +465,12 @@ template struct IsGlobalAlignment_ const>: True {}; -template -struct IsGlobalAlignment_ >: +template +struct IsGlobalAlignment_ >: IsGlobalAlignment_{}; -template -struct IsGlobalAlignment_ const>: +template +struct IsGlobalAlignment_ const>: IsGlobalAlignment_{}; // ---------------------------------------------------------------------------- @@ -422,12 +519,12 @@ template struct IsLocalAlignment_ const>: True {}; -template -struct IsLocalAlignment_ >: +template +struct IsLocalAlignment_ >: IsLocalAlignment_{}; -template -struct IsLocalAlignment_ const>: +template +struct IsLocalAlignment_ const>: IsLocalAlignment_{}; // ---------------------------------------------------------------------------- @@ -447,12 +544,12 @@ template struct IsTracebackEnabled_ const>: True {}; -template -struct IsTracebackEnabled_ >: +template +struct IsTracebackEnabled_ >: IsTracebackEnabled_{}; -template -struct IsTracebackEnabled_ const>: +template +struct IsTracebackEnabled_ const>: IsTracebackEnabled_{}; // ---------------------------------------------------------------------------- @@ -466,8 +563,8 @@ template struct IsGapsLeft_ > > : True{}; -template -struct IsGapsLeft_ > +template +struct IsGapsLeft_ > : IsGapsLeft_{}; // ---------------------------------------------------------------------------- @@ -475,15 +572,16 @@ struct IsGapsLeft_ > // ---------------------------------------------------------------------------- template -struct IsSingleTrace_ : False{}; +struct IsSingleTrace_ : False +{}; template -struct IsSingleTrace_ > > -: True{}; +struct IsSingleTrace_ > > : True +{}; -template -struct IsSingleTrace_ > -: IsSingleTrace_{}; +template +struct IsSingleTrace_ > : IsSingleTrace_ +{}; // ---------------------------------------------------------------------------- // Metafunction IsFreeEndGap_ @@ -494,12 +592,12 @@ template struct IsFreeEndGap_ : False {}; -template -struct IsFreeEndGap_ const, TDPSide>: +template +struct IsFreeEndGap_ const, TDPSide>: IsFreeEndGap_{}; -template -struct IsFreeEndGap_, TDPSide>: +template +struct IsFreeEndGap_, TDPSide>: IsFreeEndGap_{}; template @@ -566,6 +664,27 @@ struct IsFreeEndGap_ const // Functions // ============================================================================ +namespace impl +{ + template + inline TStream & + printTraceValue(TStream & stream, char traceValue) + { + if (traceValue & (TraceBitMap_::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_::VERTICAL)) + { + stream << "|"; + } + if (traceValue & (TraceBitMap_::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_::HORIZONTAL)) + { + stream << "-"; + } + if (traceValue & TraceBitMap_::DIAGONAL) + { + stream << "\\"; + } + return stream; + } +} // namespace impl } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_PROFILE_H_ diff --git a/porechop/include/seqan/align/dp_scout.h b/porechop/include/seqan/align/dp_scout.h index 4642f9d..08aba5b 100644 --- a/porechop/include/seqan/align/dp_scout.h +++ b/porechop/include/seqan/align/dp_scout.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -93,10 +93,11 @@ template class DPScout_ { public: + using TBase = DPScout_; using TScoreValue = typename Value::Type; TDPCell _maxScore = TDPCell(); - uint32_t _maxHostPosition = DPCellDefaultInfinity::VALUE; // The corresponding host position within the underlying dp-matrix. + size_t _maxHostPosition = 0; // The corresponding host position within the underlying dp-matrix. DPScout_() = default; @@ -109,7 +110,7 @@ class DPScout_ > : public DPScout_ { public: - typedef DPScout_ TParent; + using TBase = DPScout_; DPScoutState_ > * state = nullptr; bool terminationCriteriumMet = false; @@ -117,7 +118,7 @@ class DPScout_ > DPScout_() = default; DPScout_(DPScoutState_ > & pState) : - DPScout_(), + TBase(), state(&pState) {} }; @@ -217,7 +218,7 @@ maxScore(DPScout_ const & dpScout) // Returns the host position that holds the current maximum score. template -inline unsigned int +inline auto maxHostPosition(DPScout_ const & dpScout) { return dpScout._maxHostPosition; @@ -335,6 +336,21 @@ _incVerticalPos(DPScout_ const & /*scout*/) // no-op. } +// ---------------------------------------------------------------------------- +// Function swapStateIf() +// ---------------------------------------------------------------------------- + +template +inline bool swapStateIf(TSingleMaxState && lhs, TSingleMaxState && rhs, TPredicate && p) +{ + using std::swap; + + if (!p(lhs.mMaxScore, rhs.mMaxScore)) + return false; + swap(lhs, rhs); + return true; +} + } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_TEST_ALIGNMENT_DP_SCOUT_H_ diff --git a/porechop/include/seqan/align/dp_scout_simd.h b/porechop/include/seqan/align/dp_scout_simd.h index bd5cf86..a39b152 100644 --- a/porechop/include/seqan/align/dp_scout_simd.h +++ b/porechop/include/seqan/align/dp_scout_simd.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2015, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -72,70 +72,16 @@ class DPScoutState_ > using TSizeH = typename Size::Type; using TSizeV = typename Size::Type; - String > masksH; - String > masksV; - String > masks; + using TIterator = typename Iterator, Rooted>::Type; - String endsH; - String endsV; - ModifiedString, ModPos > > sortedEndsH; - ModifiedString, ModPos > > sortedEndsV; + typename TTraits::TSimdVector endPosVecH; + typename TTraits::TSimdVector endPosVecV; - decltype(begin(sortedEndsH, Standard())) nextEndsH; - decltype(begin(sortedEndsV, Standard())) nextEndsV; - - size_t dimV; size_t posH; size_t posV; - bool right; - bool bottom; - bool isLocalAlignment; - - // ---------------------------------------------------------------------------- - // Function DPScout_#updateMasksRight() - // ---------------------------------------------------------------------------- - - inline void updateMasksRight() - { - for(size_t pos = dimV - 2; pos != MaxValue::VALUE; --pos) - masks[pos] |= masks[pos + 1]; - } - - // ---------------------------------------------------------------------------- - // Function DPScout_#updateMasksBottom() - // ---------------------------------------------------------------------------- - - inline void updateMasksBottom() - { - for (auto pos : sortedEndsV) - for (auto it = nextEndsH; it != end(sortedEndsH, Standard()); ++it) - { - masks[pos] |= (masksH[*it] & masksV[pos]); - } - } - - // ---------------------------------------------------------------------------- - // Function DPScout_#updateMasks() - // ---------------------------------------------------------------------------- - - inline void updateMasks() - { - for(size_t pos = 0; pos < dimV; ++pos) - masks[pos] = masksH[posH] & masksV[pos]; - //for local alignments the BOTTOM parameter must be checked first - if(isLocalAlignment) - { - updateMasksBottom(); - updateMasksRight(); - } - else - { - if(right && posH == *nextEndsH) - updateMasksRight(); - if(bottom) - updateMasksBottom(); - } - } + + TIterator nextEndsH; + TIterator nextEndsV; }; // ---------------------------------------------------------------------------- @@ -147,18 +93,14 @@ class DPScout_ > : public DPScout_ { public: + using TSimdVec = typename Value::Type; using TBase = DPScout_; using TScoutState = DPScoutState_; - //used in the SIMD version to keep track of all host positions - //SIMD register size divided by 16bit is the amount of alignments - //so we need two vectors of type 32bit to save the host for all alignments - - // TODO(rrahn): Abstract into a struct, so we can model different configurations. - SimdVector::Type _maxHostLow; //first half of alignments - SimdVector::Type _maxHostHigh; //other half - TScoutState * state = nullptr; - unsigned _simdLane = 0; + TSimdVec mHorizontalPos{}; + TSimdVec mVerticalPos{}; + TScoutState * state{nullptr}; + unsigned _simdLane{0}; DPScout_(TScoutState & pState) : TBase(), state(&pState) {} @@ -192,31 +134,40 @@ struct ScoutSpecForAlignmentAlgorithm_ +template inline void -_copySimdCell(DPScout_, SimdAlignmentScout > & dpScout, - DPCell_ const & activeCell, - TScoreValue const & cmp) +_copySimdCell(DPScout_, SimdAlignmentScout > & dpScout, + DPCell_ const & activeCell, + TScoreValue const & cmp, + DPTraceMatrix const & /**/) { dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp); } -template +template inline void _copySimdCell(DPScout_, SimdAlignmentScout > & dpScout, DPCell_ const & activeCell, - TScoreValue const & cmp) + TScoreValue const & cmp, + DPTraceMatrix> const & /**/) { dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp); dpScout._maxScore._horizontalScore = blend(dpScout._maxScore._horizontalScore, activeCell._horizontalScore, cmp); dpScout._maxScore._verticalScore = blend(dpScout._maxScore._verticalScore, activeCell._verticalScore, cmp); } -template +template inline void _copySimdCell(DPScout_, SimdAlignmentScout > & dpScout, DPCell_ const & activeCell, - TScoreValue const & cmp) + TScoreValue const & cmp, + DPTraceMatrix> const & /**/) { dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp); dpScout._maxScore._flagMask = blend(dpScout._maxScore._flagMask, activeCell._flagMask, cmp); @@ -226,31 +177,45 @@ _copySimdCell(DPScout_, SimdAlignmentScout > // Function _updateHostPositions() // ---------------------------------------------------------------------------- -template +// No trace needed, hence we do not track the max positions. +template +inline void +_updateHostPositions(DPScout_ & /*dpScout*/, + TMask const & /*cmp*/, + TNavigator const & /*navi*/, + DPTraceMatrix const & /**/) +{} + +template inline void _updateHostPositions(DPScout_ & dpScout, - TSimdVec & cmp, - SimdVector::Type positionNavigator) + TMask const & cmp, + TNavigator const & navi, + DPTraceMatrix const & /**/) { -// TODO(rrahn): Refactor! -#if defined(__AVX2__) - dpScout._maxHostLow = blend(dpScout._maxHostLow, positionNavigator, - _mm256_cvtepi16_epi32(_mm256_castsi256_si128(reinterpret_cast<__m256i&>(cmp)))); - dpScout._maxHostHigh = blend(dpScout._maxHostHigh, positionNavigator, - _mm256_cvtepi16_epi32(_mm256_extractf128_si256(reinterpret_cast<__m256i&>(cmp),1))); -#elif defined(__SSE3__) - dpScout._maxHostLow = blend(dpScout._maxHostLow, positionNavigator, - _mm_unpacklo_epi16(reinterpret_cast<__m128i&>(cmp), reinterpret_cast<__m128i&>(cmp))); - dpScout._maxHostHigh = blend(dpScout._maxHostHigh, positionNavigator, - _mm_unpackhi_epi16(reinterpret_cast<__m128i&>(cmp), reinterpret_cast<__m128i&>(cmp))); -#endif + using TSimdVector = typename Value::Type; + dpScout.mHorizontalPos = blend(dpScout.mHorizontalPos, + createVector(coordinate(navi, +DPMatrixDimension_::HORIZONTAL)), + cmp); + + dpScout.mVerticalPos = blend(dpScout.mVerticalPos, + createVector(coordinate(navi, +DPMatrixDimension_::VERTICAL)), + cmp); } // ---------------------------------------------------------------------------- -// Function _scoutBestScore() +// Function _scoutBestScore() [SimdAlignEqualLength] // ---------------------------------------------------------------------------- -template +template inline void _scoutBestScore(DPScout_ > & dpScout, TDPCell const & activeCell, @@ -258,11 +223,344 @@ _scoutBestScore(DPScout_ > & d TIsLastColumn const & /**/, TIsLastRow const & /**/) { + using TMatrixType = typename MatrixType::Type; auto cmp = cmpGt(_scoreOfCell(activeCell), _scoreOfCell(dpScout._maxScore)); - _copySimdCell(dpScout, activeCell, cmp); - _updateHostPositions(dpScout, cmp, createVector::Type>(position(navigator))); + _copySimdCell(dpScout, activeCell, cmp, TMatrixType()); + _updateHostPositions(dpScout, cmp, navigator, TMatrixType()); +} + +// ---------------------------------------------------------------------------- +// Function _getCompareMask() +// ---------------------------------------------------------------------------- + +// Helper functions to resolve the correct tracking of cells for different +// alignment modes. + +// Standard global alignment. +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return ((dpScout.state->endPosVecH) == createVector(dpScout.state->posH)) & + ((dpScout.state->endPosVecV) == createVector(dpScout.state->posV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// Tracking the last row is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV)); +} + +// ---------------------------------------------------------------------------- +// Function _getCompareMask() +// ---------------------------------------------------------------------------- + +// Helper functions to resolve the correct tracking of cells for different +// alignment modes. + +// Standard global alignment. +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return ((dpScout.state->endPosVecH) == createVector(dpScout.state->posH)) & + ((dpScout.state->endPosVecV) == createVector(dpScout.state->posV)); } +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// Tracking the last row is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + TIsLastColumn const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// Tracking if the last column is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + False const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// Tracking if the last column and last row is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return ((createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV))) | + ((createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV))); +} + +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + False const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + False const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// If local alignment. +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_, TGapModel, TTraceConfig> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +// ---------------------------------------------------------------------------- +// Function _scoutBestScore() [SimdAlignVariableLength] +// ---------------------------------------------------------------------------- + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + TIsLastColumn const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// Tracking if the last column is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + False const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return createVector(0); +} + +// Tracking if the last column and last row is enabled +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return ((createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV))) | + ((createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV))); +} + +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + False const & /*lastCol*/, + True const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) == (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + True const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) == (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +template +inline auto _getCompareMask(DPScout_ > > const & /*dpScout*/, + False const & /*lastCol*/, + False const & /*lastRow*/, + DPProfile_>, + TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdMaskVec = typename SimdMaskVector::Type; + return createVector(0); +} + +// If local alignment. +template +inline auto _getCompareMask(DPScout_ > > const & dpScout, + TIsLastColumn const & /*lastCol*/, + TIsLastRow const & /*lastRow*/, + DPProfile_, TGapModel, TTraceConfig, TExecPolicy> const &) +{ + using TSimdVec = typename TTraits::TSimdVector; + return (createVector(dpScout.state->posH) <= (dpScout.state->endPosVecH)) & + (createVector(dpScout.state->posV) <= (dpScout.state->endPosVecV)); +} + +// ---------------------------------------------------------------------------- +// Function _scoutBestScore() [SimdAlignVariableLength] +// ---------------------------------------------------------------------------- + template masks[dpScout.state->posV]; - _copySimdCell(dpScout, activeCell, cmp); - _updateHostPositions(dpScout, cmp, createVector::Type>(position(navigator))); + using TMatrixType = typename MatrixType::Type; + auto mask = cmpGt(_scoreOfCell(activeCell), _scoreOfCell(dpScout._maxScore)) & + _getCompareMask(dpScout, TIsLastColumn{}, TIsLastRow{}, typename TTraits::TDPProfile{}); + _copySimdCell(dpScout, activeCell, mask, TMatrixType()); + _updateHostPositions(dpScout, mask, navigator, TMatrixType()); } // ---------------------------------------------------------------------------- -// Function maxHostPosition() +// Function maxHostCoordinate() // ---------------------------------------------------------------------------- +template +inline auto +maxHostCoordinate(DPScout_ > const & dpScout, + TDimension const dimension) +{ + return (dimension == DPMatrixDimension_::HORIZONTAL) ? dpScout.mHorizontalPos[dpScout._simdLane] : + dpScout.mVerticalPos[dpScout._simdLane]; +} + template -inline unsigned int -maxHostPosition(DPScout_ > const & dpScout) +inline auto +maxHostCoordinates(DPScout_ > const & dpScout) { - if(dpScout._simdLane < LENGTH::Type>::VALUE) - return value(dpScout._maxHostLow, dpScout._simdLane); - else - return value(dpScout._maxHostHigh, dpScout._simdLane - LENGTH::Type>::VALUE); + return std::make_pair(maxHostCoordinate(dpScout, DPMatrixDimension_::HORIZONTAL), + maxHostCoordinate(dpScout, DPMatrixDimension_::VERTICAL)); } +// ---------------------------------------------------------------------------- +// Function maxScoreAt() +// ---------------------------------------------------------------------------- + +template +inline auto +maxScoreAt(DPScout_ > const & dpScout) +{ + return maxScore(dpScout)[dpScout._simdLane]; +} + +// ---------------------------------------------------------------------------- +// Function maxHostPosition() +// ---------------------------------------------------------------------------- + +template +[[deprecated("Use maxHostCoordinate instead!")]] auto +maxHostPosition(DPScout_ > const & /*unused*/) +{} + // ---------------------------------------------------------------------------- // Function _setSimdLane() // ---------------------------------------------------------------------------- @@ -313,7 +640,7 @@ template inline void _preInitScoutHorizontal(DPScout_ > > & scout) { - scout.state->nextEndsH = begin(scout.state->sortedEndsH, Standard()); + goBegin(scout.state->nextEndsH); scout.state->posH = 0; } @@ -325,8 +652,8 @@ template inline void _preInitScoutVertical(DPScout_ > > & scout) { - scout.state->updateMasks(); - scout.state->nextEndsV = begin(scout.state->sortedEndsV, Standard()); + // scout.state->updateMasks(); + goBegin(scout.state->nextEndsV); scout.state->posV = 0; } @@ -339,7 +666,7 @@ inline bool _reachedHorizontalEndPoint(DPScout_ > > & scout, TIter const & hIt) { - return *(scout.state->nextEndsH) == position(hIt); + return *(scout.state->nextEndsH) == position(hIt) + 1; } // ---------------------------------------------------------------------------- @@ -351,7 +678,7 @@ inline bool _reachedVerticalEndPoint(DPScout_ > > & scout, TIter const & vIt) { - return *(scout.state->nextEndsV) == position(vIt); + return *(scout.state->nextEndsV) == position(vIt) + 1; } // ---------------------------------------------------------------------------- @@ -362,12 +689,7 @@ template inline void _nextHorizontalEndPos(DPScout_ > > & scout) { - auto oldLength = *scout.state->nextEndsH; - while (scout.state->nextEndsH != end(scout.state->sortedEndsH, Standard()) && - *scout.state->nextEndsH == oldLength) - { - ++scout.state->nextEndsH; - } + ++scout.state->nextEndsH; } // ---------------------------------------------------------------------------- @@ -378,12 +700,7 @@ template inline void _nextVerticalEndPos(DPScout_ > > & scout) { - auto oldLength = *scout.state->nextEndsV; - while (scout.state->nextEndsV != end(scout.state->sortedEndsV, Standard()) && - *scout.state->nextEndsV == oldLength) - { - ++scout.state->nextEndsV; - } + ++scout.state->nextEndsV; } // ---------------------------------------------------------------------------- @@ -425,7 +742,8 @@ inline auto _hostLengthH(DPScout_ > > const & scout, TSeqH const & /*seqH*/) { - return host(scout.state->sortedEndsH)[scout._simdLane] + 1; + using TInnerValue = typename Value::Type; + return static_cast(scout.state->endPosVecH[scout._simdLane]); } // ---------------------------------------------------------------------------- @@ -445,10 +763,10 @@ inline auto _hostLengthV(DPScout_ > > const & scout, TSeqV const & /*seqV*/) { - return host(scout.state->sortedEndsV)[scout._simdLane] + 1; + using TInnerValue = typename Value::Type; + return static_cast(scout.state->endPosVecV[scout._simdLane]); } } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_SIMD_DP_SCOUT_SIMD_H_ - diff --git a/porechop/include/seqan/align/dp_setup.h b/porechop/include/seqan/align/dp_setup.h index 29bf429..a9ee724 100644 --- a/porechop/include/seqan/align/dp_setup.h +++ b/porechop/include/seqan/align/dp_setup.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -215,21 +215,21 @@ struct SetupAlignmentProfile_; template struct SetupAlignmentProfile_ { - typedef DPProfile_, TGapCosts, TTraceSwitch> Type; + typedef DPProfile_, TGapCosts, TTraceSwitch, Serial> Type; }; // Profile for Smith-Waterman algorithm. template struct SetupAlignmentProfile_ { - typedef DPProfile_, TGapCosts, TTraceSwitch> Type; + typedef DPProfile_, TGapCosts, TTraceSwitch, Serial> Type; }; // Profile for Waterman-Eggert algorithm template struct SetupAlignmentProfile_ { - typedef DPProfile_, TGapCosts, TracebackOn > > Type; + typedef DPProfile_, TGapCosts, TracebackOn >, Serial> Type; }; @@ -263,16 +263,17 @@ _usesAffineGaps(TScoringScheme const & scoringScheme, // Function _setUpAndRunAlignment() // ---------------------------------------------------------------------------- -template typename Value >::Type -_setUpAndRunAlignment(DPContext & dpContext, - TTrace & traceSegments, +_setUpAndRunAlignment(DPContext, TTraceValue, TScoreMat, TTraceMat> & dpContext, + String & traceSegments, DPScoutState_ & dpScoutState, TSequenceH const & seqH, TSequenceV const & seqV, @@ -282,12 +283,12 @@ _setUpAndRunAlignment(DPContext & dpContext, SEQAN_ASSERT_GEQ(length(seqH), 1u); SEQAN_ASSERT_GEQ(length(seqV), 1u); - typedef typename SetupAlignmentProfile_::Type TDPProfile; + typedef typename SetupAlignmentProfile_::Type TDPProfile; return _computeAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig._band, TDPProfile()); } -template typename Value >::Type -_setUpAndRunAlignment(TTrace & traceSegments, +_setUpAndRunAlignment(String & traceSegments, + DPScoutState_ & dpScoutState, + TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig2 const & alignConfig, + TGapModel const & /**/) +{ + DPContext, typename TraceBitMap_<>::Type> dpContext; + return _setUpAndRunAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig); +} + +template +typename Value >::Type +_setUpAndRunAlignment(String & traceSegments, + DPScoutState_ & dpScoutState, + TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig2 const & alignConfig) +{ + if (_usesAffineGaps(scoringScheme, seqH, seqV)) + return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig, AffineGaps()); + else + return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig, LinearGaps()); +} + +// SIMD aware implementation. +template +typename Value >::Type +_setUpAndRunAlignment(DPContext, TTraceValue, TScoreMat, TTraceMat> & dpContext, + StringSet > & traceSegments, + DPScoutState_ & dpScoutState, + TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig2 const & alignConfig) +{ + SEQAN_ASSERT_GEQ(length(seqH), 1u); + SEQAN_ASSERT_GEQ(length(seqV), 1u); + + typedef typename SetupAlignmentProfile_::Type TDPProfile; + return _computeAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig._band, + TDPProfile()); +} + +template +typename Value >::Type +_setUpAndRunAlignment(StringSet > & traceSegments, DPScoutState_ & dpScoutState, TSequenceH const & seqH, TSequenceV const & seqV, @@ -303,7 +362,12 @@ _setUpAndRunAlignment(TTrace & traceSegments, AlignConfig2 const & alignConfig, TGapModel const & /**/) { - DPContext dpContext; + typedef DPCell_ TDPCell; + typedef typename TraceBitMap_::Type TTraceValue; + typedef String > TScoreHost; + typedef String > TTraceHost; + + DPContext dpContext; return _setUpAndRunAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig); } diff --git a/porechop/include/seqan/align/dp_trace_segment.h b/porechop/include/seqan/align/dp_trace_segment.h index 2b591be..5bc8fe6 100644 --- a/porechop/include/seqan/align/dp_trace_segment.h +++ b/porechop/include/seqan/align/dp_trace_segment.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -69,7 +69,7 @@ class TraceSegment_ TTraceValue _traceValue; // the trace direction TraceSegment_() : - _horizontalBeginPos(0), _verticalBeginPos(0), _length(0), _traceValue(+TraceBitMap_::NONE){} + _horizontalBeginPos(0), _verticalBeginPos(0), _length(0), _traceValue(TraceBitMap_::NONE){} TraceSegment_(TraceSegment_ const & other) : _horizontalBeginPos(other._horizontalBeginPos), @@ -328,11 +328,11 @@ inline void _recordSegment(TTraceSegments & traceSegments, return; // we don't store empty segments if (traceValue & TraceBitMap_::DIAGONAL) - appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_::DIAGONAL)); + appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_::DIAGONAL)); else if (traceValue & TraceBitMap_::VERTICAL) - appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_::VERTICAL)); + appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_::VERTICAL)); else if (traceValue & TraceBitMap_::HORIZONTAL) - appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_::HORIZONTAL)); + appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_::HORIZONTAL)); // everything else is not tracked. } diff --git a/porechop/include/seqan/align/dp_traceback_adaptor.h b/porechop/include/seqan/align/dp_traceback_adaptor.h index f9e495f..b66283c 100644 --- a/porechop/include/seqan/align/dp_traceback_adaptor.h +++ b/porechop/include/seqan/align/dp_traceback_adaptor.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/dp_traceback_impl.h b/porechop/include/seqan/align/dp_traceback_impl.h index a2439f9..f2c8b6f 100644 --- a/porechop/include/seqan/align/dp_traceback_impl.h +++ b/porechop/include/seqan/align/dp_traceback_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -115,12 +115,11 @@ class TracebackCoordinator_ template struct PreferGapsAtEnd_ : False{}; -template -struct PreferGapsAtEnd_ > : True{}; - -template -struct PreferGapsAtEnd_ > > > : True{}; +template +struct PreferGapsAtEnd_ > : True{}; +template +struct PreferGapsAtEnd_ >, TExecSpec> > : True{}; // ============================================================================ // Functions @@ -143,13 +142,13 @@ _hasReachedEnd(TracebackCoordinator_ const & coordinator) template inline void -_initTracebackCoordinator(TracebackCoordinator_ & coordinator, - DPBandConfig const & band, - TSizeH seqHSize, - TSizeV seqVSize) +_initTracebackCoordinator(SEQAN_UNUSED TracebackCoordinator_ & coordinator, + SEQAN_UNUSED DPBandConfig const & band, + SEQAN_UNUSED TSizeH seqHSize, + SEQAN_UNUSED TSizeV seqVSize) { typedef typename Position >::Type TBandPosition; - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) { // Adapt the current column value when the lower diagonal is positive (shift right in horizontal direction). if (lowerDiagonal(band) >= 0) @@ -184,7 +183,6 @@ _isInBand(TracebackCoordinator_ const & coordinator) return (coordinator._currColumn > coordinator._breakpoint1 || coordinator._currColumn <= coordinator._breakpoint2); } - // ---------------------------------------------------------------------------- // Function _doTracebackGoDiagonal() // ---------------------------------------------------------------------------- @@ -239,9 +237,10 @@ _doTracebackGoVertical(TTarget & target, fragmentLength = 0; } // We are in a vertical gap. So continue after we reach the end of the vertical gap. - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) { - while ((!(traceValue & TraceBitMap_<>::VERTICAL_OPEN) || (traceValue & TraceBitMap_<>::VERTICAL)) && (tracebackCoordinator._currRow != 1)) + while ((!(traceValue & TraceBitMap_<>::VERTICAL_OPEN) || (traceValue & TraceBitMap_<>::VERTICAL)) && + tracebackCoordinator._currRow != 1) { _traceVertical(matrixNavigator, _isInBand(tracebackCoordinator)); traceValue = scalarValue(matrixNavigator); @@ -316,9 +315,10 @@ _doTracebackGoHorizontal(TTarget & target, lastTraceValue = TraceBitMap_<>::HORIZONTAL; fragmentLength = 0; } - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) { - while ((!(traceValue & TraceBitMap_<>::HORIZONTAL_OPEN) || (traceValue & TraceBitMap_<>::HORIZONTAL)) && (tracebackCoordinator._currColumn != 1)) + while ((!(traceValue & TraceBitMap_<>::HORIZONTAL_OPEN) || (traceValue & TraceBitMap_<>::HORIZONTAL)) && + tracebackCoordinator._currColumn != 1) { _traceHorizontal(matrixNavigator, _isInBand(tracebackCoordinator)); traceValue = scalarValue(matrixNavigator); @@ -487,52 +487,46 @@ _retrieveInitialTraceDirection(TTraceValue & traceValue, TDPProfile const & /*dp // ---------------------------------------------------------------------------- template -inline SEQAN_FUNC_DISABLE_IF(Is >, void) -_computeTraceback(TTarget & target, - TDPTraceMatrixNavigator & matrixNavigator, - unsigned maxHostPosition, - TSizeH const & seqHSize, - TSizeV const & seqVSize, - DPBandConfig const & band, - DPProfile_ const & dpProfile) + typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy, + typename TTraceHead, + typename TTraceTail> +void _computeTraceback(TTarget & target, + TTraceValue & traceValue, + TTraceValue & lastTraceValue, + TDPTraceMatrixNavigator & matrixNavigator, + TSizeH const & seqHSize, + TSizeV const & seqVSize, + DPBandConfig const & band, + DPProfile_ const & /*dpProfile*/, + TTraceHead const &, + TTraceTail const &) { - typedef typename Container::Type TContainer; - typedef typename Size::Type TSize; - typedef typename Position::Type TPosition; - typedef typename TraceBitMap_<>::Type TTraceValue; + typedef typename Size::Type TSize; + typedef typename Position::Type TPosition; - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) return; // Determine whether or not we place gaps to the left. typedef typename IsGapsLeft_::Type TIsGapsLeft; - // Set the navigator to the position where the maximum was found. - _setToPosition(matrixNavigator, maxHostPosition); - - SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), seqHSize); - SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), seqVSize); - - TTraceValue traceValue = scalarValue(matrixNavigator); - TTraceValue lastTraceValue = _retrieveInitialTraceDirection(traceValue, dpProfile); - TracebackCoordinator_ tracebackCoordinator(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), band, seqHSize, seqVSize); - if (TraceTail_::VALUE) + if (TTraceTail::VALUE) { - if (tracebackCoordinator._currRow != seqVSize) + if (tracebackCoordinator._currRow != static_cast(seqVSize)) _recordSegment(target, seqHSize, tracebackCoordinator._currRow, seqVSize - tracebackCoordinator._currRow, - +TraceBitMap_<>::VERTICAL); - if (tracebackCoordinator._currColumn != seqHSize) + TraceBitMap_<>::VERTICAL); + if (tracebackCoordinator._currColumn != static_cast(seqHSize)) _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, seqHSize - - tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL); + tracebackCoordinator._currColumn, TraceBitMap_<>::HORIZONTAL); } TSize fragmentLength = 0; @@ -541,59 +535,92 @@ _computeTraceback(TTarget & target, // Record last detected fragment. _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, fragmentLength, lastTraceValue); - if (TraceHead_::VALUE) + if (TTraceHead::VALUE) { // Record leading gaps if any. if (tracebackCoordinator._currRow != 0u) - _recordSegment(target, 0, 0, tracebackCoordinator._currRow, +TraceBitMap_<>::VERTICAL); + _recordSegment(target, 0, 0, tracebackCoordinator._currRow, TraceBitMap_<>::VERTICAL); if (tracebackCoordinator._currColumn != 0u) - _recordSegment(target, 0, 0, tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL); + _recordSegment(target, 0, 0, tracebackCoordinator._currColumn, TraceBitMap_<>::HORIZONTAL); } } -//// Needed as a delegation method to allow invocation of both methods with host position and dpScout. +// Needed as a delegation method to allow invocation of both methods with host position and dpScout. +// With sizes and maxHostPosition. template -inline SEQAN_FUNC_ENABLE_IF(Is >, void) + typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy> +inline SEQAN_FUNC_DISABLE_IF(Is >, void) _computeTraceback(TTarget & target, TDPTraceMatrixNavigator & matrixNavigator, unsigned maxHostPosition, - TSequenceH const & seqH, - TSequenceV const & seqV, + TSeqHSize const & seqHSize, + TSeqVSize const & seqVSize, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { - _computeTraceback(target, matrixNavigator, maxHostPosition, length(seqH), length(seqV), band, dpProfile); + using TSize SEQAN_TYPEDEF_FOR_DEBUG = typename Size::Type; + // Set the navigator to the position where the maximum was found. + _setToPosition(matrixNavigator, maxHostPosition); + + SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), static_cast(seqHSize)); + SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), static_cast(seqVSize)); + typename TraceBitMap_<>::Type traceValue = scalarValue(matrixNavigator); + typename TraceBitMap_<>::Type lastTraceValue = _retrieveInitialTraceDirection(traceValue, dpProfile); + _computeTraceback(target, traceValue, lastTraceValue, matrixNavigator, seqHSize, seqVSize, band, dpProfile, + TraceHead_(), TraceTail_()); } +// With sizes and dpScout. template -inline SEQAN_FUNC_DISABLE_IF(Is >, void) + typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy> +inline SEQAN_FUNC_DISABLE_IF(Is >, void) _computeTraceback(TTarget & target, TDPTraceMatrixNavigator & matrixNavigator, DPScout_ const & dpScout, - TSizeH const & seqHSize, - TSizeV const & seqVSize, + TSeqHSize const & seqHSize, + TSeqVSize const & seqVSize, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), seqHSize, seqVSize, band, dpProfile); } -template +// With sequences and maxHostPosition. +template +inline SEQAN_FUNC_ENABLE_IF(Is >, void) +_computeTraceback(TTarget & target, + TDPTraceMatrixNavigator & matrixNavigator, + unsigned maxHostPosition, + TSequenceH const & seqH, + TSequenceV const & seqV, + DPBandConfig const & band, + DPProfile_ const & dpProfile) +{ + _computeTraceback(target, matrixNavigator, maxHostPosition, length(seqH), length(seqV), band, dpProfile); +} + +// With sequences and dpScout. +template inline SEQAN_FUNC_ENABLE_IF(Is >, void) _computeTraceback(TTarget & target, TDPTraceMatrixNavigator & matrixNavigator, @@ -601,9 +628,9 @@ _computeTraceback(TTarget & target, TSequenceH const & seqH, TSequenceV const & seqV, DPBandConfig const & band, - DPProfile_ const & dpProfile) + DPProfile_ const & dpProfile) { - _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), length(seqH), length(seqV), band, dpProfile); + _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), seqH, seqV, band, dpProfile); } } // namespace seqan diff --git a/porechop/include/seqan/align/evaluate_alignment.h b/porechop/include/seqan/align/evaluate_alignment.h index e242f2e..5f7c486 100644 --- a/porechop/include/seqan/align/evaluate_alignment.h +++ b/porechop/include/seqan/align/evaluate_alignment.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -316,8 +316,8 @@ TScoreVal computeAlignmentStats(AlignmentStats & stats, return computeAlignmentStats(stats, row(align, 0), row(align, 1), scoringScheme); } -// NOTE(h-2): this interface is deprecated. Don't use it. template +[[deprecated("Use computeAlignmentStats(stats, align, scoringScheme) instead.")]] TScoreVal computeAlignmentStats(Align const & align, Score const & scoringScheme) { diff --git a/porechop/include/seqan/align/fragment.h b/porechop/include/seqan/align/fragment.h index de6ae1e..33cbcbc 100644 --- a/porechop/include/seqan/align/fragment.h +++ b/porechop/include/seqan/align/fragment.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/gap_anchor.h b/porechop/include/seqan/align/gap_anchor.h index 1a625fd..6c8d5cf 100644 --- a/porechop/include/seqan/align/gap_anchor.h +++ b/porechop/include/seqan/align/gap_anchor.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/gapped_value_type.h b/porechop/include/seqan/align/gapped_value_type.h index 855f1d3..3d8f41e 100644 --- a/porechop/include/seqan/align/gapped_value_type.h +++ b/porechop/include/seqan/align/gapped_value_type.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/gaps_anchor.h b/porechop/include/seqan/align/gaps_anchor.h index c75042d..5b65cf3 100644 --- a/porechop/include/seqan/align/gaps_anchor.h +++ b/porechop/include/seqan/align/gaps_anchor.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -301,8 +301,8 @@ template inline void _assignSourceLength(TSize & size, Gaps > const & me) { - if (IsSameType::VALUE) - size = maxValue() / 2; + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) + size = std::numeric_limits::max() / 2; else size = length(value(me.data_source)); } @@ -345,13 +345,13 @@ _getAnchor(TAnchor & anchor, Gaps > const & me, { // if there is no sequence but anchors -> assume infinite sequence if (anchor.seqPos == 0) - anchor.seqPos = maxValue(anchor.gapPos); + anchor.seqPos = std::numeric_limits::max(); // if the sequence has a length > 0, but there is an anchor behind the end // -> elongate sequence else if ((int64_t)anchor.seqPos < (int64_t)back(_dataAnchors(me)).seqPos) anchor.seqPos = back(_dataAnchors(me)).seqPos; } - anchor.gapPos = maxValue(anchor.gapPos); + anchor.gapPos = std::numeric_limits::max(); } } else if (idx > 0) @@ -362,7 +362,7 @@ _getAnchor(TAnchor & anchor, Gaps > const & me, if (idx == 0) anchor.gapPos = 0; else - anchor.gapPos = minValue(anchor.gapPos); + anchor.gapPos = std::numeric_limits::min(); } } diff --git a/porechop/include/seqan/align/gaps_array.h b/porechop/include/seqan/align/gaps_array.h index 840cbbb..513c76d 100644 --- a/porechop/include/seqan/align/gaps_array.h +++ b/porechop/include/seqan/align/gaps_array.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/gaps_base.h b/porechop/include/seqan/align/gaps_base.h index e187688..d37be91 100644 --- a/porechop/include/seqan/align/gaps_base.h +++ b/porechop/include/seqan/align/gaps_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -143,6 +143,12 @@ typedef Tag RightOfViewPos; template class Gaps; +template +SEQAN_CONCEPT_IMPL((Gaps), (AlignedSequenceConcept)); + +template +SEQAN_CONCEPT_IMPL((Gaps const), (AlignedSequenceConcept)); + // ============================================================================ // Metafunctions // ============================================================================ @@ -455,7 +461,7 @@ bool isGap(Gaps const & gaps, TPos clippedViewPos) * @fn Gaps#isCharacer * @brief Query positions in a Gaps object for being a character. * - * @signature bool isGap(gaps, viewPos); + * @signature bool isCharacter(gaps, viewPos); * * @param[in] gaps The Gaps object to query. * @param[in] viewPos The view position (including clipping and gaps). diff --git a/porechop/include/seqan/align/gaps_iterator_anchor.h b/porechop/include/seqan/align/gaps_iterator_anchor.h index 775af98..1591938 100644 --- a/porechop/include/seqan/align/gaps_iterator_anchor.h +++ b/porechop/include/seqan/align/gaps_iterator_anchor.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -180,7 +180,7 @@ getValue(Iter > > & me) typedef typename Value > >::Type TValue; if (isGap(me)) return gapValue(); else if (isUnknown(me)) return unknownValue(); - else return getValue(source(me)); + else return *source(me); } template @@ -190,7 +190,7 @@ getValue(Iter > > const & me) typedef typename Value > const>::Type TValue; if (isGap(me)) return gapValue(); else if (isUnknown(me)) return unknownValue(); - else return getValue(source(me)); + else return *source(me); } // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/align/gaps_iterator_array.h b/porechop/include/seqan/align/gaps_iterator_array.h index b32de15..e2cf056 100644 --- a/porechop/include/seqan/align/gaps_iterator_array.h +++ b/porechop/include/seqan/align/gaps_iterator_array.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/gaps_iterator_base.h b/porechop/include/seqan/align/gaps_iterator_base.h index 097943d..5718728 100644 --- a/porechop/include/seqan/align/gaps_iterator_base.h +++ b/porechop/include/seqan/align/gaps_iterator_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/global_alignment_banded.h b/porechop/include/seqan/align/global_alignment_banded.h index eab33c6..7b7632f 100644 --- a/porechop/include/seqan/align/global_alignment_banded.h +++ b/porechop/include/seqan/align/global_alignment_banded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -399,13 +399,17 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, - TSequenceV const & seqV, - Score const & scoringScheme, - AlignConfig const & /*alignConfig*/, - int lowerDiag, - int upperDiag, - TAlgoTag const & /*algoTag*/) +SEQAN_FUNC_DISABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, + TScoreValue) +globalAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig const & /*alignConfig*/, + int lowerDiag, + int upperDiag, + TAlgoTag const & /*algoTag*/) { typedef AlignConfig TAlignConfig; typedef typename SubstituteAlignConfig_::Type TFreeEndGaps; @@ -423,12 +427,12 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, - TSequenceV const & seqV, - Score const & scoringScheme, - int lowerDiag, - int upperDiag, - TAlgoTag const & algoTag) +auto globalAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + int lowerDiag, + int upperDiag, + TAlgoTag const & algoTag) { AlignConfig<> alignConfig; return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag, algoTag); @@ -439,12 +443,12 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, - TSequenceV const & seqV, - Score const & scoringScheme, - AlignConfig const & alignConfig, - int lowerDiag, - int upperDiag) +auto globalAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig const & alignConfig, + int lowerDiag, + int upperDiag) { if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag, NeedlemanWunsch()); @@ -456,11 +460,11 @@ TScoreValue globalAlignmentScore(TSequenceH const & seqH, template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, - TSequenceV const & seqV, - Score const & scoringScheme, - int lowerDiag, - int upperDiag) +auto globalAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + int lowerDiag, + int upperDiag) { AlignConfig<> alignConfig; return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag); @@ -551,17 +555,22 @@ TScoreValue globalAlignmentScore(StringSet const & strings, // Function globalAlignmentScore() [banded, SIMD version, 2x StringSet] // ---------------------------------------------------------------------------- -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - AlignConfig const & /*alignConfig*/, - int lowerDiag, - int upperDiag, - TAlgoTag const & /*algoTag*/) +SEQAN_FUNC_ENABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, + String) +globalAlignmentScore(TSeqH const & stringsH, + TSeqV const & stringsV, + Score const & scoringScheme, + AlignConfig const & /*alignConfig*/, + int lowerDiag, + int upperDiag, + TAlgoTag const & /*algoTag*/) { typedef AlignConfig TAlignConfig; typedef typename SubstituteAlignConfig_::Type TFreeEndGaps; @@ -572,51 +581,6 @@ String globalAlignmentScore(StringSet const & strin return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(lowerDiag, upperDiag), TGapModel()); } -// Interface without AlignConfig<>. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - int lowerDiag, - int upperDiag, - TAlgoTag const & algoTag) -{ - AlignConfig<> alignConfig; - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, algoTag); -} - -// Interface without algorithm tag. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - AlignConfig const & alignConfig, - int lowerDiag, - int upperDiag) -{ - if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, NeedlemanWunsch()); - else - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, Gotoh()); -} - -// Interface without AlignConfig<> and algorithm tag. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - int lowerDiag, - int upperDiag) -{ - AlignConfig<> alignConfig; - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag); -} - // ---------------------------------------------------------------------------- // Function globalAlignmentScore() [banded, SIMD version, String vs StringSet] // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/align/global_alignment_hirschberg_impl.h b/porechop/include/seqan/align/global_alignment_hirschberg_impl.h index 0497f7d..ab360bb 100644 --- a/porechop/include/seqan/align/global_alignment_hirschberg_impl.h +++ b/porechop/include/seqan/align/global_alignment_hirschberg_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/global_alignment_myers_hirschberg_impl.h b/porechop/include/seqan/align/global_alignment_myers_hirschberg_impl.h index 24e67ec..31955f6 100644 --- a/porechop/include/seqan/align/global_alignment_myers_hirschberg_impl.h +++ b/porechop/include/seqan/align/global_alignment_myers_hirschberg_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -257,7 +257,7 @@ _globalAlignment(Gaps & gapsH, String forwardBitMask; String reverseBitMask; - resize(VP, blockCount, maxValue()); + resize(VP, blockCount, std::numeric_limits::max()); resize(VN, blockCount, 0); // first bitMask will be constructed from the shorter sequence @@ -512,7 +512,7 @@ _globalAlignment(Gaps & gapsH, fSilencer <<= fOffSet; /* reset v-bitvectors */ - std::fill(begin(VP, Standard()) + fStartBlock, begin(VP, Standard()) + fEndBlock + 1, maxValue()); + std::fill(begin(VP, Standard()) + fStartBlock, begin(VP, Standard()) + fEndBlock + 1, std::numeric_limits::max()); std::fill(begin(VN, Standard()) + fStartBlock, begin(VN, Standard()) + fEndBlock + 1, 0); /* determine start-position and start-score */ @@ -622,7 +622,7 @@ _globalAlignment(Gaps & gapsH, rSilencer <<= rOffSet; /* reset v-bitvectors */ - std::fill(begin(VP, Standard()) + rStartBlock, begin(VP, Standard()) + rEndBlock + 1, maxValue()); + std::fill(begin(VP, Standard()) + rStartBlock, begin(VP, Standard()) + rEndBlock + 1, std::numeric_limits::max()); std::fill(begin(VN, Standard()) + rStartBlock, begin(VN, Standard()) + rEndBlock + 1, 0); /* determine start-position and start-score */ diff --git a/porechop/include/seqan/align/global_alignment_myers_impl.h b/porechop/include/seqan/align/global_alignment_myers_impl.h index 8082f3b..c6f0073 100644 --- a/porechop/include/seqan/align/global_alignment_myers_impl.h +++ b/porechop/include/seqan/align/global_alignment_myers_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -94,7 +94,7 @@ _globalAlignmentScore(String const & seqH, unsigned int scoreMask = 1 << ((len_y % BLOCK_SIZE) - 1); // the mask with a bit set at the position of the last active cell String VP; - resize(VP, blockCount, maxValue()); + resize(VP, blockCount, std::numeric_limits::max()); String VN; resize(VN, blockCount, 0); String bitMask; diff --git a/porechop/include/seqan/align/global_alignment_specialized.h b/porechop/include/seqan/align/global_alignment_specialized.h index 1fa2a4d..ac0139e 100644 --- a/porechop/include/seqan/align/global_alignment_specialized.h +++ b/porechop/include/seqan/align/global_alignment_specialized.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/global_alignment_unbanded.h b/porechop/include/seqan/align/global_alignment_unbanded.h index a58c539..8032898 100644 --- a/porechop/include/seqan/align/global_alignment_unbanded.h +++ b/porechop/include/seqan/align/global_alignment_unbanded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -457,13 +457,14 @@ TScoreValue globalAlignment(String, TStringSpec> * @headerfile * @brief Computes the best global pairwise alignment score. * - * @signature TScoreVal globalAlignmentScore(seqH, seqV, scoringScheme[, alignConfig][, lowerDiag, upperDiag][, algorithmTag]); + * @signature TScoreVal globalAlignmentScore([exec,] subject, query, scoringScheme[, alignConfig][, lowerDiag, upperDiag]); * @signature TScoreVal globalAlignmentScore(strings, scoringScheme[, alignConfig][, lowerDiag, upperDiag][, algorithmTag]); * @signature TScoreVal globalAlignmentScore(seqH, seqV, {MyersBitVector | MyersHirschberg}); * @signature TScoreVal globalAlignmentScore(strings, {MyersBitVector | MyersHirschberg}); * - * @param[in] seqH Horizontal gapped sequence in alignment matrix. Types: String - * @param[in] seqV Vertical gapped sequence in alignment matrix. Types: String + * @param[in] exec @link ExecutionPolicy Policy@endlink to select execution mode of alignment algorithm. + * @param[in] subject Subject sequence(s) (horizontal in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept. + * @param[in] query Query sequence(s) (vertical in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept. * @param[in] strings A @link StringSet @endlink containing two sequences. Type: StringSet. * @param[in] alignConfig The @link AlignConfig @endlink to use for the alignment. Type: AlignConfig * @param[in] scoringScheme The scoring scheme to use for the alignment. Note that the user is responsible for ensuring @@ -474,17 +475,36 @@ TScoreValue globalAlignment(String, TStringSpec> * @endlink. * * @return TScoreVal Score value of the resulting alignment (Metafunction: @link Score#Value @endlink of - * the type of scoringScheme). + * the type of scoringScheme). If subject and query are sets the function returns a + * set of scores representing the score for each pairwise alignment (subject[i] with query[i]). * * This function does not perform the (linear time) traceback step after the (mostly quadratic time) dynamic programming * step. Note that Myers' bit-vector algorithm does not compute an alignment (only in the Myers-Hirschberg variant) but * scores can be computed using globalAlignmentScore. + * Global alignment score can be either used with two sequences or two sets of sequences of equal size. * * The same limitations to algorithms as in @link globalAlignment @endlink apply. Furthermore, the * MyersBitVector and MyersHirschberg variants can only be used without any other parameter. * + * @section Parallel execution + * + * Some of the global alingment score functions are parallelized and vectorized and work on sets of sequences. + * The parallelization mode can be selected via the @link ExecutionPolicy @endlink as first argument. + * Following execution modes are possible: sequential, parallel, wave-front, vectorized, + * parallel+vectorized and wave-front+vectorized. + * + * The wave-front execution can be selected via the @link WavefrontExecutionPolicy @endlink, which can also be combined + * with a vectorized execution. In addition the wave-front execution parallelizes a single pairwise alignment, while the + * standard @link ParallelismTags#Parallel @endlink specialization does only parallelizes the sequence set via chunking. + * Note, the banded version is at the moment only supported for the following execution modes: sequential, + * parallel, vectorized and parallel+vectorized. At the moment the vectorized version only works + * reliable if all subject sequences and respectively all query sequences have the same length. + * * @see https://seqan.readthedocs.io/en/develop/Tutorial/Algorithms/Alignment/PairwiseSequenceAlignment.html * @see globalAlignment + * + * @datarace thread-safe. No shared state is modified during the execution and concurrent invocations of this function + * on the same data does not cause any race conditions. */ // ---------------------------------------------------------------------------- @@ -496,11 +516,15 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, - TSequenceV const & seqV, - Score const & scoringScheme, - AlignConfig const & /*alignConfig*/, - TAlgoTag const & /*algoTag*/) +SEQAN_FUNC_DISABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, + TScoreValue) +globalAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + AlignConfig const & /*alignConfig*/, + TAlgoTag const & /*algoTag*/) { typedef AlignConfig TAlignConfig; typedef typename SubstituteAlignConfig_::Type TFreeEndGaps; @@ -517,7 +541,7 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, +auto globalAlignmentScore(TSequenceH const & seqH, TSequenceV const & seqV, Score const & scoringScheme, TAlgoTag const & algoTag) @@ -531,7 +555,7 @@ template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, +auto globalAlignmentScore(TSequenceH const & seqH, TSequenceV const & seqV, Score const & scoringScheme, AlignConfig const & alignConfig) @@ -546,7 +570,7 @@ TScoreValue globalAlignmentScore(TSequenceH const & seqH, template -TScoreValue globalAlignmentScore(TSequenceH const & seqH, +auto globalAlignmentScore(TSequenceH const & seqH, TSequenceV const & seqV, Score const & scoringScheme) { @@ -626,15 +650,20 @@ TScoreValue globalAlignmentScore(StringSet const & strings, // Function globalAlignmentScore() [unbanded, SIMD version, 2x StringSet] // ---------------------------------------------------------------------------- -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - AlignConfig const & /*alignConfig*/, - TAlgoTag const & /*algoTag*/) +SEQAN_FUNC_ENABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, + String) +globalAlignmentScore(TSeqH const & stringsH, + TSeqV const & stringsV, + Score const & scoringScheme, + AlignConfig const & /*alignConfig*/, + TAlgoTag const & /*algoTag*/) { SEQAN_ASSERT_EQ(length(stringsH), length(stringsV)); typedef AlignConfig TAlignConfig; @@ -645,45 +674,6 @@ String globalAlignmentScore(StringSet const & stri return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(), TGapModel()); } -// Interface without AlignConfig<>. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - TAlgoTag const & algoTag) -{ - AlignConfig<> alignConfig; - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, algoTag); -} - -// Interface without algorithm tag. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme, - AlignConfig const & alignConfig) -{ - if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, NeedlemanWunsch()); - else - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, Gotoh()); -} - -// Interface without AlignConfig<> and algorithm tag. -template -String globalAlignmentScore(StringSet const & stringsH, - StringSet const & stringsV, - Score const & scoringScheme) -{ - AlignConfig<> alignConfig; - return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig); -} - // -------------------------------------------------------------------------------- // Function globalAlignmentScore() [unbanded, SIMD version, String vs StringSet] // -------------------------------------------------------------------------------- @@ -755,7 +745,7 @@ String globalAlignmentScore(TString1 const & stringH, template inline auto globalAlignment(StringSet, TSetSpecH> & gapSeqSetH, @@ -772,6 +762,34 @@ globalAlignment(StringSet, TSetSpecH> & gapSeqSetH, return _alignWrapper(gapSeqSetH, gapSeqSetV, scoringScheme, TAlignConfig2(), TGapModel()); } +// Interface without algorithm tag. +template +String globalAlignment(StringSet, TSetSpecH> & gapSeqSetH, + StringSet, TSetSpecV> & gapSeqSetV, + Score const & scoringScheme, + AlignConfig const & alignConfig) +{ + if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) + return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig, NeedlemanWunsch()); + else + return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig, Gotoh()); +} + +// Interface without AlignConfig<> and algorithm tag. +template +String globalAlignment(StringSet, TSetSpecH> & gapSeqSetH, + StringSet, TSetSpecV> & gapSeqSetV, + Score const & scoringScheme) +{ + AlignConfig<> alignConfig; + return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig); +} + // ---------------------------------------------------------------------------- // Function globalAlignment() [unbanded, SIMD version, StringSet] // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/align/local_alignment_banded.h b/porechop/include/seqan/align/local_alignment_banded.h index 8edcfd5..857f9b3 100644 --- a/porechop/include/seqan/align/local_alignment_banded.h +++ b/porechop/include/seqan/align/local_alignment_banded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -271,13 +271,13 @@ localAlignment(StringSet, TSetSpec> & alignSet, StringSet > gapSetV; reserve(gapSetH, length(alignSet)); reserve(gapSetV, length(alignSet)); - + for (auto & align : alignSet) { appendValue(gapSetH, row(align, 0)); appendValue(gapSetV, row(align, 1)); } - + return localAlignment(gapSetH, gapSetV, scoringScheme, lowerDiag, upperDiag, algoTag); } @@ -293,6 +293,75 @@ String localAlignment(StringSet > & al return localAlignment(align, scoringScheme, lowerDiag, upperDiag, LinearGaps()); } +// ---------------------------------------------------------------------------- +// Function localAlignmentScore() [banded, no-simd, TSequence] +// ---------------------------------------------------------------------------- + +template +SEQAN_FUNC_DISABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, TScoreValue) +localAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + int const lowerDiag, + int const upperDiag, + TAlgoTag const & /*algoTag*/) +{ + typedef AlignConfig2, FreeEndGaps_<>, TracebackOff> TAlignConfig2; + typedef typename SubstituteAlgoTag_::Type TGapModel; + + DPScoutState_ dpScoutState; + String > traceSegments; // Dummy segments. + return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, + TAlignConfig2{lowerDiag, upperDiag}, TGapModel{}); +} + +// ---------------------------------------------------------------------------- +// Function localAlignmentScore() [banded, Simd, TSequence] +// ---------------------------------------------------------------------------- + +template +inline +SEQAN_FUNC_ENABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, String) +localAlignmentScore(TSeqH const & stringsH, + TSeqV const & stringsV, + Score const & scoringScheme, + int const lowerDiag, + int const upperDiag, + TAlgoTag const & /*algoTag*/) +{ + typedef AlignConfig2, FreeEndGaps_<>, TracebackOff> TAlignConfig2; + typedef typename SubstituteAlgoTag_::Type TGapModel; + + SEQAN_ASSERT_EQ(length(stringsH), length(stringsV)); + return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2{lowerDiag, upperDiag}, TGapModel()); +} + +// Interface without algorithm tag. +template +auto localAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + int const lowerDiag, + int const upperDiag) +{ + if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) + return localAlignmentScore(seqH, seqV, scoringScheme, lowerDiag, upperDiag, NeedlemanWunsch()); + else + return localAlignmentScore(seqH, seqV, scoringScheme, lowerDiag, upperDiag, Gotoh()); +} + } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_BANDED_H_ diff --git a/porechop/include/seqan/align/local_alignment_banded_waterman_eggert_impl.h b/porechop/include/seqan/align/local_alignment_banded_waterman_eggert_impl.h index 3f42d50..c59ff28 100644 --- a/porechop/include/seqan/align/local_alignment_banded_waterman_eggert_impl.h +++ b/porechop/include/seqan/align/local_alignment_banded_waterman_eggert_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -498,8 +498,8 @@ _initLocalAlignmentFinder(TSequenceH const & seqH, resize(finder.forbidden, height * diagonalWidth, false); - finder.bestEndPos = minValue(); - finder.bestBeginPos = minValue(); + finder.bestEndPos = std::numeric_limits::min(); + finder.bestBeginPos = std::numeric_limits::min(); } // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/align/local_alignment_enumeration.h b/porechop/include/seqan/align/local_alignment_enumeration.h index 0dd6946..81d7802 100644 --- a/porechop/include/seqan/align/local_alignment_enumeration.h +++ b/porechop/include/seqan/align/local_alignment_enumeration.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/local_alignment_enumeration_banded.h b/porechop/include/seqan/align/local_alignment_enumeration_banded.h index 4172d79..0ca025f 100644 --- a/porechop/include/seqan/align/local_alignment_enumeration_banded.h +++ b/porechop/include/seqan/align/local_alignment_enumeration_banded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/local_alignment_enumeration_unbanded.h b/porechop/include/seqan/align/local_alignment_enumeration_unbanded.h index a5efcb8..978320b 100644 --- a/porechop/include/seqan/align/local_alignment_enumeration_unbanded.h +++ b/porechop/include/seqan/align/local_alignment_enumeration_unbanded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align/local_alignment_unbanded.h b/porechop/include/seqan/align/local_alignment_unbanded.h index a6a920f..24c2036 100644 --- a/porechop/include/seqan/align/local_alignment_unbanded.h +++ b/porechop/include/seqan/align/local_alignment_unbanded.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -355,13 +355,13 @@ localAlignment(StringSet > & alignSet, StringSet > gapSetV; reserve(gapSetH, length(alignSet)); reserve(gapSetV, length(alignSet)); - + for (auto & align : alignSet) { appendValue(gapSetH, row(align, 0)); appendValue(gapSetV, row(align, 1)); } - + return localAlignment(gapSetH, gapSetV, scoringScheme, algoTag); } @@ -376,6 +376,111 @@ String localAlignment(StringSet > & al return localAlignment(align, scoringScheme, LinearGaps()); } +// ---------------------------------------------------------------------------- +// Function localAlignmentScore() [unbanded, TSequence] +// ---------------------------------------------------------------------------- + +/*! + * @fn localAlignmentScore + * @headerfile + * @brief Computes the best global pairwise alignment score. + * + * @signature TScoreVal localAlignmentScore([exec,] subject, query, scoringScheme[, lowerDiag, upperDiag]); + * + * @param[in] exec @link ExecutionPolicy Policy@endlink to select execution mode of alignment algorithm. + * @param[in] subject Subject sequence(s) (horizontal in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept. + * @param[in] query Query sequence(s) (vertical in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept. + * @param[in] scoringScheme The scoring scheme to use for the alignment. Note that the user is responsible for ensuring + * that the scoring scheme is compatible with algorithmTag. Type: @link Score @endlink. + * @param[in] lowerDiag Optional lower diagonal. Types: int + * @param[in] upperDiag Optional upper diagonal. Types: int + * + * @return TScoreVal Score value of the resulting alignment (Metafunction: @link Score#Value @endlink of + * the type of scoringScheme). If subject and query are sets the function returns a + * set of scores representing the score for each pairwise alignment (subject[i] with query[i]). + * + * This function does not perform the (linear time) traceback step after the (mostly quadratic time) dynamic programming + * step. Local alignment score can be either used with two sequences or two sets of sequences of equal size. + * + * @section Parallel execution + * + * Some of the local alingment score functions are parallelized and vectorized. + * The parallelization mode can be selected via the @link ExecutionPolicy @endlink as first argument. + * Following execution modes are possible: sequential, parallel, wave-front, vectorized, + * parallel+vectorized and wave-front+vectorized. + * + * The wave-front execution can be selected via the @link WavefrontExecutionPolicy @endlink, which can also be combined + * with a vectorized execution. In addition the wave-front execution parallelizes a single pairwise alignment, while the + * standard @link ParallelismTags#Parallel @endlink specialization does only parallelizes the sequence set via chunking. + * Note, the banded version is at the moment only supported for the following execution modes: sequential, + * parallel, vectorized and parallel+vectorized. At the moment the vectorized version only works + * reliable if all subject sequences and respectively all query sequences have the same length. + * + * @see https://seqan.readthedocs.io/en/develop/Tutorial/Algorithms/Alignment/PairwiseSequenceAlignment.html + * @see localAlignment + * + * @datarace thread-safe. No shared state is modified during the execution and concurrent invocations of this function + * on the same data does not cause any race conditions. + */ + +template +SEQAN_FUNC_DISABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, TScoreValue) +localAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme, + TAlgoTag const & /*algoTag*/) +{ + typedef AlignConfig2, FreeEndGaps_<>, TracebackOff> TAlignConfig2; + typedef typename SubstituteAlgoTag_::Type TGapModel; + + DPScoutState_ dpScoutState; + String > traceSegments; // Dummy segments. + return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, TAlignConfig2{}, TGapModel{}); +} + +// ---------------------------------------------------------------------------- +// Function localAlignmentScore() [unbanded, Simd, TSequence] +// ---------------------------------------------------------------------------- + +template +inline +SEQAN_FUNC_ENABLE_IF(And>, Is::Type>>>, + And>, Is::Type>>> + >, String) +localAlignmentScore(TSeqH const & stringsH, + TSeqV const & stringsV, + Score const & scoringScheme, + TAlgoTag const & /*algoTag*/) +{ + SEQAN_ASSERT_EQ(length(stringsH), length(stringsV)); + typedef AlignConfig2, FreeEndGaps_<>, TracebackOff> TAlignConfig2; + typedef typename SubstituteAlgoTag_::Type TGapModel; + + return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(), TGapModel()); +} + +// Interface without algorithm tag. +template +auto localAlignmentScore(TSequenceH const & seqH, + TSequenceV const & seqV, + Score const & scoringScheme) +{ + if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) + return localAlignmentScore(seqH, seqV, scoringScheme, NeedlemanWunsch()); + else + return localAlignmentScore(seqH, seqV, scoringScheme, Gotoh()); +} + } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_UNBANDED_H_ diff --git a/porechop/include/seqan/align/local_alignment_waterman_eggert_impl.h b/porechop/include/seqan/align/local_alignment_waterman_eggert_impl.h index e78fc33..8062aea 100644 --- a/porechop/include/seqan/align/local_alignment_waterman_eggert_impl.h +++ b/porechop/include/seqan/align/local_alignment_waterman_eggert_impl.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ class ScoreAndID TValue value_; TID id_; - ScoreAndID() : value_(MinValue::VALUE), id_(MaxValue::VALUE) + ScoreAndID() : value_(std::numeric_limits::min()), id_(std::numeric_limits::max()) {} ScoreAndID(TValue score, TID id_pos) @@ -157,8 +157,8 @@ _initLocalAlignmentFinder(TSequenceH const & seqH, resize(finder.forbidden, (len0 + 1) * (len1 + 1), false); - finder.bestEndPos = maxValue(); - finder.bestBeginPos = maxValue(); + finder.bestEndPos = std::numeric_limits::max(); + finder.bestBeginPos = std::numeric_limits::max(); } // ---------------------------------------------------------------------------- @@ -179,7 +179,7 @@ template TScoreValue getScore(LocalAlignmentFinder const & sw) { typedef LocalAlignmentFinder TFinder; - if(sw.bestEndPos != maxValue()) + if(sw.bestEndPos != std::numeric_limits::max()) return getValue(const_cast(sw.matrix), sw.bestEndPos); return 0; } @@ -188,12 +188,12 @@ TScoreValue getScore(LocalAlignmentFinder const & sw) // Function _smithWatermanGetMatrix() // ---------------------------------------------------------------------------- -template +template TScoreValue _smithWatermanGetMatrix(LocalAlignmentFinder & sw, TStringH const & strH, TStringV const & strV, - Score const & score_, + Score const & score_, TScoreValue cutoff) { // typedefs @@ -220,8 +220,6 @@ _smithWatermanGetMatrix(LocalAlignmentFinder & sw, TStringIteratorH x = x_end; TStringIteratorV y; - TScoreValue score_match = scoreMatch(score_); - TScoreValue score_mismatch = scoreMismatch(score_); TScoreValue score_gap = scoreGapExtend(score_); TScoreValue h = 0; @@ -263,14 +261,15 @@ _smithWatermanGetMatrix(LocalAlignmentFinder & sw, goPrevious(finger1, 0); goPrevious(finger2, 0); + TScoreValue currScore = score(score_, *x, cy); if (*x == cy) { - v = h + score_match; + v = h + currScore; h = *finger2; } else { - TScoreValue s1 = h + score_mismatch; + TScoreValue s1 = h + currScore; h = *finger2; TScoreValue s2 = score_gap + ((h > v) ? h : v); v = (s1 > s2) ? s1 : s2; @@ -303,12 +302,15 @@ _smithWatermanGetMatrix(LocalAlignmentFinder & sw, // ---------------------------------------------------------------------------- // declumping -template +template void _smithWatermanDeclump(LocalAlignmentFinder & sw , Gaps & gapsH, Gaps & gapsV, - Score const & score_) + Score const & score_) { //------------------------------------------------------------------------- //typedefs @@ -364,8 +366,6 @@ _smithWatermanDeclump(LocalAlignmentFinder & sw , TSequenceHIter x_stop = x_end; - TScoreValue score_match = scoreMatch(score_); - TScoreValue score_mismatch = scoreMismatch(score_); TScoreValue score_gap = scoreGapExtend(score_); TScoreValue h,v; @@ -456,9 +456,10 @@ _smithWatermanDeclump(LocalAlignmentFinder & sw , { goPrevious(finger0, 0); goPrevious(finger1, 0); + TScoreValue currScore = score(score_, *x, cy); if (*x == cy && !(sw.forbidden[position(finger0)])) { - v = h + score_match; + v = h + currScore; h = *finger1; } else @@ -474,7 +475,7 @@ _smithWatermanDeclump(LocalAlignmentFinder & sw , else { if(sw.forbidden[position(finger0)]) s1 = 0; - else s1 = h + score_mismatch; + else s1 = h + currScore; } h = *finger1; @@ -522,13 +523,16 @@ _smithWatermanDeclump(LocalAlignmentFinder & sw , // ---------------------------------------------------------------------------- // Traceback. -template +template typename Iterator, Standard >::Type _smithWatermanTrace(Gaps & gapsH, Gaps & gapsV, typename LocalAlignmentFinder::TBoolMatrix & fb_matrix, Iter< Matrix, PositionIterator > source_, - Score const & scoring_) { + Score const & scoring_) { //typedefs typedef Iter, PositionIterator > TMatrixIterator; typedef typename Position >::Type TPosition; @@ -559,7 +563,6 @@ _smithWatermanTrace(Gaps & gapsH, TSourceIteratorV it_1 = iter(strV, pos_1, Standard()); TSourceIteratorV it_1_end = end(strV); - TScoreValue score_mismatch = scoreMismatch(scoring_); TScoreValue score_gap = scoreGapExtend(scoring_); //------------------------------------------------------------------------- @@ -586,7 +589,7 @@ _smithWatermanTrace(Gaps & gapsH, d = 0; else{ goNext(it_, 1); - d = *it_ + score_mismatch; + d = *it_ + score(scoring_, *it_0, *it_1); } it_ = source_; @@ -678,7 +681,9 @@ _getNextBestEndPosition(LocalAlignmentFinder & sw , // ---------------------------------------------------------------------------- // Wrapper that computes the matrix and does the backtracking for the best alignment -template +template TScoreValue _smithWaterman(Gaps & gapsH, Gaps & gapsV, diff --git a/porechop/include/seqan/align/matrix_base.h b/porechop/include/seqan/align/matrix_base.h index e5ca253..2238bf0 100644 --- a/porechop/include/seqan/align/matrix_base.h +++ b/porechop/include/seqan/align/matrix_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -45,34 +45,32 @@ namespace seqan struct NDimensional; -template +template > class Matrix; ////////////////////////////////////////////////////////////////////////////// template struct SizeArr_; -template -struct SizeArr_ > +template +struct SizeArr_ > { - typedef Matrix TMatrix_; + typedef Matrix TMatrix_; typedef typename Size::Type TSize_; typedef String Type; }; ////////////////////////////////////////////////////////////////////////////// -template -struct Host > +template +struct Host > { - typedef typename StringSpecForValue_::Type TSpec_; - typedef String Type; + typedef THost Type; }; -template -struct Host const> +template +struct Host const> { - typedef typename StringSpecForValue_::Type TSpec_; - typedef String Type; + typedef THost const Type; }; ////////////////////////////////////////////////////////////////////////////// @@ -94,15 +92,14 @@ struct Host const> */ -template -class Matrix +template +class Matrix { //____________________________________________________________________________ public: typedef typename Size::Type TSize; typedef String TSizeArr; - typedef typename Host::Type THost; TSizeArr data_lengths; //Length of every dimension TSizeArr data_factors; //used for positions of dimensions in host ("size of jumps" to get to next entry of specified dimension) @@ -158,15 +155,14 @@ class Matrix }; -template -class Matrix +template +class Matrix { //____________________________________________________________________________ public: typedef typename Size::Type TSize; typedef String TSizeArr; - typedef typename Host::Type THost; TSizeArr data_lengths; TSizeArr data_factors; @@ -219,15 +215,14 @@ class Matrix //____________________________________________________________________________ }; -template -class Matrix +template +class Matrix { //____________________________________________________________________________ public: typedef typename Size::Type TSize; - typedef String TSizeArr; - typedef typename Host::Type THost; + typedef String TSizeArr; TSizeArr data_lengths; TSizeArr data_factors; @@ -280,30 +275,30 @@ class Matrix //____________________________________________________________________________ }; -template -inline typename SizeArr_ >::Type & -_dataLengths(Matrix & me) +template +inline typename SizeArr_ >::Type & +_dataLengths(Matrix & me) { return me.data_lengths; } -template -inline typename SizeArr_ >::Type const & -_dataLengths(Matrix const & me) +template +inline typename SizeArr_ >::Type const & +_dataLengths(Matrix const & me) { return me.data_lengths; } -template -inline typename SizeArr_ >::Type & -_dataFactors(Matrix & me) +template +inline typename SizeArr_ >::Type & +_dataFactors(Matrix & me) { return me.data_factors; } -template -inline typename SizeArr_ >::Type const & -_dataFactors(Matrix const & me) +template +inline typename SizeArr_ >::Type const & +_dataFactors(Matrix const & me) { return me.data_factors; } @@ -311,25 +306,25 @@ _dataFactors(Matrix const & me) //____________________________________________________________________________ -template +template inline bool -dependent(Matrix & me) +dependent(Matrix & me) { return dependent(me.data_host); } //____________________________________________________________________________ -template -inline Holder >::Type> & -_dataHost(Matrix & matrix) +template +inline Holder >::Type> & +_dataHost(Matrix & matrix) { return matrix.data_host; } -template -inline Holder >::Type> const & -_dataHost(Matrix const & matrix) +template +inline Holder >::Type> const & +_dataHost(Matrix const & matrix) { return matrix.data_host; } @@ -338,7 +333,7 @@ _dataHost(Matrix const & matrix) template inline void -assignHost(Matrix & me, THost const & value_) +assignHost(Matrix & me, THost const & value_) { assignValue(me.data_host, value_); } @@ -347,48 +342,48 @@ assignHost(Matrix & me, THost const & value_) template inline void -moveHost(Matrix & me, THost const & value_) +moveHost(Matrix & me, THost const & value_) { moveValue(me.data_host, value_); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -template -struct Value< Matrix > +template +struct Value< Matrix > { typedef TValue Type; }; ////////////////////////////////////////////////////////////////////////////// -template -struct Iterator< Matrix, TIteratorSpec > +template +struct Iterator< Matrix, TIteratorSpec > { - typedef Iter, PositionIterator> Type; + typedef Iter, PositionIterator> Type; }; -template -struct Iterator< Matrix const, TIteratorSpec > +template +struct Iterator< Matrix const, TIteratorSpec > { - typedef Iter const, PositionIterator> Type; + typedef Iter const, PositionIterator> Type; }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -template -inline typename Size const>::Type -dimension(Matrix const & me) +template +inline typename Size const>::Type +dimension(Matrix const & me) { return length(_dataLengths(me)); } ////////////////////////////////////////////////////////////////////////////// -template +template inline void -setDimension(Matrix & me, +setDimension(Matrix & me, unsigned int dim_) { @@ -403,39 +398,39 @@ setDimension(Matrix & me, ////////////////////////////////////////////////////////////////////////////// -template -inline typename Size >::Type -length(Matrix const & me, +template +inline typename Size >::Type +length(Matrix const & me, unsigned int dim_) { return me.data_lengths[dim_]; } -template -inline typename Size >::Type -length(Matrix const & me) +template +inline typename Size >::Type +length(Matrix const & me) { return length(host(me)); } -template -inline bool empty(Matrix const & me) +template +inline bool empty(Matrix const & me) { return empty(host(me)); } ////////////////////////////////////////////////////////////////////////////// -template +template inline void -setLength(Matrix & me, +setLength(Matrix & me, unsigned int dim_, TLength length_) { SEQAN_ASSERT_GT(length_, static_cast(0)); SEQAN_ASSERT_LT(dim_, dimension(me)); - typedef typename SizeArr_ >::TSize_ TSize_; + typedef typename SizeArr_ >::TSize_ TSize_; _dataLengths(me)[dim_] = static_cast(length_); } @@ -453,11 +448,11 @@ setLength(Matrix & me, */ -template +template inline void -resize(Matrix & me) +resize(Matrix & me) { - typedef Matrix TMatrix; + typedef Matrix TMatrix; typedef typename Size::Type TSize; unsigned int dimension_ = dimension(me); @@ -479,11 +474,11 @@ resize(Matrix & me) ////////////////////////////////////////////////////////////////////////////// -template +template inline void -resize(Matrix & me, TFillValue myValue) //resize the matrix and fill with value +resize(Matrix & me, TFillValue myValue) //resize the matrix and fill with value { - typedef Matrix TMatrix; + typedef Matrix TMatrix; typedef typename Size::Type TSize; unsigned int dimension_ = dimension(me); @@ -504,36 +499,36 @@ resize(Matrix & me, TFillValue myValue) //resize the matri ////////////////////////////////////////////////////////////////////////////// -template -inline typename Position >::Type -nextPosition(Matrix & me, +template +inline typename Position >::Type +nextPosition(Matrix & me, TPosition position_, unsigned int dimension_) { return position_ + _dataFactors(me)[dimension_]; } -template -inline typename Position >::Type -nextPosition(Matrix const & me, +template +inline typename Position >::Type +nextPosition(Matrix const & me, TPosition position_, unsigned int dimension_) { return position_ + _dataFactors(me)[dimension_]; } -template -inline typename Position >::Type -previousPosition(Matrix & me, +template +inline typename Position >::Type +previousPosition(Matrix & me, TPosition position_, unsigned int dimension_) { return position_ - _dataFactors(me)[dimension_]; } -template -inline typename Position >::Type -previousPosition(Matrix const & me, +template +inline typename Position >::Type +previousPosition(Matrix const & me, TPosition position_, unsigned int dimension_) { @@ -542,9 +537,9 @@ previousPosition(Matrix const & me, ////////////////////////////////////////////////////////////////////////////// -template -inline typename Size< Matrix >::Type -coordinate(Matrix const & me, +template +inline typename Size< Matrix >::Type +coordinate(Matrix const & me, TPosition position_, unsigned int dimension_) { @@ -562,51 +557,51 @@ coordinate(Matrix const & me, ////////////////////////////////////////////////////////////////////////////// -template -inline typename Iterator, Tag const>::Type -begin(Matrix & me, +template +inline typename Iterator, Tag const>::Type +begin(Matrix & me, Tag const) { - return typename Iterator, Tag const >::Type(me, 0); + return typename Iterator, Tag const >::Type(me, 0); } -template -inline typename Iterator const, Tag const>::Type -begin(Matrix const & me, +template +inline typename Iterator const, Tag const>::Type +begin(Matrix const & me, Tag const) { - return typename Iterator const, Tag const >::Type(me, 0); + return typename Iterator const, Tag const >::Type(me, 0); } ////////////////////////////////////////////////////////////////////////////// -template -inline typename Iterator, Tag const >::Type -end(Matrix & me, +template +inline typename Iterator, Tag const >::Type +end(Matrix & me, Tag const) { - return typename Iterator, Tag const >::Type(me, length(host(me))); + return typename Iterator, Tag const >::Type(me, length(host(me))); } -template -inline typename Iterator const, Tag const >::Type -end(Matrix const & me, +template +inline typename Iterator const, Tag const >::Type +end(Matrix const & me, Tag const) { - return typename Iterator, Tag const >::Type(me, length(host(me))); + return typename Iterator, Tag const >::Type(me, length(host(me))); } ////////////////////////////////////////////////////////////////////////////// -template -inline typename Reference >::Type -value(Matrix & me, +template +inline typename Reference >::Type +value(Matrix & me, TPosition position_) { return value(host(me), position_); } -template -inline typename Reference const>::Type -value(Matrix const & me, +template +inline typename Reference const>::Type +value(Matrix const & me, TPosition position_) { return value(host(me), position_); @@ -615,18 +610,18 @@ value(Matrix const & me, //____________________________________________________________________________ //two dimensional value access -template -inline typename Reference >::Type -value(Matrix & me, +template +inline typename Reference >::Type +value(Matrix & me, TOrdinate1 i1, TOrdinate2 i2) { return value(host(me), i1 + i2 * _dataFactors(me)[1]); } -template -inline typename Reference const>::Type -value(Matrix const & me, +template +inline typename Reference const>::Type +value(Matrix const & me, TOrdinate1 i1, TOrdinate2 i2) { @@ -637,9 +632,9 @@ value(Matrix const & me, //3 dimensional value access -template -inline typename Reference >::Type -value(Matrix & me, +template +inline typename Reference >::Type +value(Matrix & me, TOrdinate1 i1, TOrdinate2 i2, TOrdinate3 i3) @@ -651,9 +646,9 @@ value(Matrix & me, //4 dimensional value access -template -inline typename Reference >::Type -value(Matrix & me, +template +inline typename Reference >::Type +value(Matrix & me, TOrdinate1 i1, TOrdinate2 i2, TOrdinate3 i3, @@ -667,32 +662,32 @@ value(Matrix & me, // Iterator: goNext ////////////////////////////////////////////////////////////////////////////// -template +template inline void -goNext(Iter, PositionIterator> & me, +goNext(Iter, PositionIterator> & me, unsigned int dimension_) { setPosition(me, nextPosition(container(me), position(me), dimension_)); } -template +template inline void -goNext(Iter const, PositionIterator> & me, +goNext(Iter const, PositionIterator> & me, unsigned int dimension_) { setPosition(me, nextPosition(container(me), position(me), dimension_)); } -template +template inline void -goNext(Iter, PositionIterator> & me) +goNext(Iter, PositionIterator> & me) { goNext(me, 0); } -template +template inline void -goNext(Iter const, PositionIterator> & me) +goNext(Iter const, PositionIterator> & me) { goNext(me, 0); } @@ -701,32 +696,32 @@ goNext(Iter const, PositionIterator> & me) // Iterator: goPrevious ////////////////////////////////////////////////////////////////////////////// -template +template inline void -goPrevious(Iter< Matrix, PositionIterator > & me, +goPrevious(Iter< Matrix, PositionIterator > & me, unsigned int dimension_) { setPosition(me, previousPosition(container(me), position(me), dimension_)); } -template +template inline void -goPrevious(Iter< Matrix const, PositionIterator > & me, +goPrevious(Iter< Matrix const, PositionIterator > & me, unsigned int dimension_) { setPosition(me, previousPosition(container(me), position(me), dimension_)); } -template +template inline void -goPrevious(Iter< Matrix, PositionIterator > & me) +goPrevious(Iter< Matrix, PositionIterator > & me) { goPrevious(me, 0); } -template +template inline void -goPrevious(Iter< Matrix const, PositionIterator > & me) +goPrevious(Iter< Matrix const, PositionIterator > & me) { goPrevious(me, 0); } @@ -735,33 +730,33 @@ goPrevious(Iter< Matrix const, PositionIterator > & me) // goTo ////////////////////////////////////////////////////////////////////////////// -template +template inline void -goTo(Iter, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1) +goTo(Iter, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1) { setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1]); } -template +template inline void -goTo(Iter const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1) +goTo(Iter const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1) { setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1]); } -template +template inline void -goTo(Iter, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2) +goTo(Iter, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2) { setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1] + pos2 * _dataFactors(container(me))[2]); } -template +template inline void -goTo(Iter const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2) +goTo(Iter const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2) { setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1] + pos2 * _dataFactors(container(me))[2]); } @@ -769,17 +764,17 @@ goTo(Iter const, PositionIterator> & me, TPosition0 po ////////////////////////////////////////////////////////////////////////////// // Iterator: coordinate -template -inline typename Size< Matrix >::Type -coordinate(Iter, PositionIterator > & me, +template +inline typename Size< Matrix >::Type +coordinate(Iter, PositionIterator > & me, unsigned int dimension_) { return coordinate(container(me), position(me), dimension_); } -template -inline typename Size< Matrix >::Type -coordinate(Iter const, PositionIterator > & me, +template +inline typename Size< Matrix >::Type +coordinate(Iter const, PositionIterator > & me, unsigned int dimension_) { return coordinate(container(me), position(me), dimension_); @@ -797,9 +792,9 @@ coordinate(Iter const, PositionIterator > & me, * @return TMatrix The resulting matrix of same type as lhs and rhs. */ -template +template Matrix -operator + (Matrix const & matrix1,Matrix const & matrix2) +operator + (Matrix const & matrix1, Matrix const & matrix2) { //the two matrices must have same dimension SEQAN_ASSERT(_dataLengths(matrix1) == _dataLengths(matrix2)); @@ -819,9 +814,9 @@ operator + (Matrix const & matrix1,Matrix co return result; } -template +template Matrix -operator - (Matrix const & matrix1,Matrix const & matrix2) +operator - (Matrix const & matrix1,Matrix const & matrix2) { //the two matrices must have same dimension SEQAN_ASSERT(_dataLengths(matrix1) == _dataLengths(matrix2)); @@ -841,9 +836,9 @@ operator - (Matrix const & matrix1,Matrix co return result; } -template +template Matrix -operator * (Matrix const & matrix1, Matrix const & matrix2) +operator * (Matrix const & matrix1, Matrix const & matrix2) { SEQAN_ASSERT_EQ(length(matrix1,1), length(matrix2,0)); @@ -871,9 +866,9 @@ operator * (Matrix const & matrix1, Matrix const & matrix2 } -template +template Matrix -operator * (TValue const & scalar, Matrix const & matrix) +operator * (TValue const & scalar, Matrix const & matrix) { Matrix result; result= matrix; @@ -886,9 +881,9 @@ operator * (TValue const & scalar, Matrix const & matrix) return result; } -template +template Matrix -operator * (Matrix const & matrix, TValue const & scalar) +operator * (Matrix const & matrix, TValue const & scalar) { Matrix result; result= matrix; @@ -902,9 +897,9 @@ operator * (Matrix const & matrix, TValue const & scalar) } -template +template bool -operator == (Matrix const & matrix1, Matrix const & matrix2) +operator == (Matrix const & matrix1, Matrix const & matrix2) { bool result; result= (matrix1.data_lengths==matrix2.data_lengths)&&(matrix1.data_factors==matrix2.data_factors)&&(value(matrix1.data_host)==value(matrix2.data_host))&&(DIMENSION1==DIMENSION2); @@ -1027,9 +1022,9 @@ matricialProduct(Matrix &matrix1, * @return TMatrix The resulting tranposed matrix. */ -template +template Matrix -transpose(Matrix const & matrix) +transpose(Matrix const & matrix) { unsigned int nrow=length(matrix,0); @@ -1057,8 +1052,8 @@ transpose(Matrix const & matrix) } -template < typename TValue > -std::ostream& operator<<(std::ostream &out, const Matrix &matrix) +template < typename TValue , typename THost> +std::ostream& operator<<(std::ostream &out, const Matrix &matrix) { for(unsigned int i1 = 0;i1< matrix.data_lengths[0];++i1) { diff --git a/porechop/include/seqan/align_extend.h b/porechop/include/seqan/align_extend.h index dcc7111..89bef49 100644 --- a/porechop/include/seqan/align_extend.h +++ b/porechop/include/seqan/align_extend.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align_extend/align_extend.h b/porechop/include/seqan/align_extend/align_extend.h index f5459fb..deb2cf8 100644 --- a/porechop/include/seqan/align_extend/align_extend.h +++ b/porechop/include/seqan/align_extend/align_extend.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -254,7 +254,7 @@ _extendAlignmentImpl(Gaps & row0, TPos newAlignLen = length(row0); // centerScore was set to "compute yourself" by interface function without score parameter - if (centerScore == minValue()) + if (centerScore == std::numeric_limits::min()) { centerScore = 0; @@ -416,7 +416,7 @@ _extendAlignmentImpl(Align & align, { if (scoreGapOpen(scoreScheme) == scoreGapExtend(scoreScheme)) { - typedef DPContext TDPContext; + typedef DPContext, typename TraceBitMap_::Type> TDPContext; typedef AliExtContext_, Gaps, TDPContext> TAliExtContext_; @@ -426,7 +426,7 @@ _extendAlignmentImpl(Align & align, } else { - typedef DPContext TDPContext; + typedef DPContext, typename TraceBitMap_::Type> TDPContext; typedef AliExtContext_, Gaps, TDPContext> TAliExtContext_; @@ -501,7 +501,7 @@ extendAlignment(Align & align, ExtensionDirection const & direction, Score const & scoreScheme) { - return _extendAlignmentImpl(align, minValue(), hSeq, vSeq, positions, direction, 0, 0, 0, scoreScheme, + return _extendAlignmentImpl(align, std::numeric_limits::min(), hSeq, vSeq, positions, direction, 0, 0, 0, scoreScheme, False(), False()); } @@ -533,7 +533,7 @@ extendAlignment(Align & align, int const upperDiag, Score const & scoreScheme) { - return _extendAlignmentImpl(align, minValue(), hSeq, vSeq, positions, direction, lowerDiag, upperDiag, + return _extendAlignmentImpl(align, std::numeric_limits::min(), hSeq, vSeq, positions, direction, lowerDiag, upperDiag, 0, scoreScheme, True(), False()); } @@ -566,7 +566,7 @@ extendAlignment(Align & align, TScoreValue const & xDrop, Score const & scoreScheme) { - return _extendAlignmentImpl(align, minValue(), hSeq, vSeq, positions, direction, 0, 0, xDrop, + return _extendAlignmentImpl(align, std::numeric_limits::min(), hSeq, vSeq, positions, direction, 0, 0, xDrop, scoreScheme, False(), True()); } @@ -600,7 +600,7 @@ extendAlignment(Align & align, TScoreValue const & xDrop, Score const & scoreScheme) { - return _extendAlignmentImpl(align, minValue(), hSeq, vSeq, positions, direction, lowerDiag, upperDiag, + return _extendAlignmentImpl(align, std::numeric_limits::min(), hSeq, vSeq, positions, direction, lowerDiag, upperDiag, xDrop, scoreScheme, True(), True()); } diff --git a/porechop/include/seqan/align_extend/align_extend_base.h b/porechop/include/seqan/align_extend/align_extend_base.h index 336daed..9823829 100644 --- a/porechop/include/seqan/align_extend/align_extend_base.h +++ b/porechop/include/seqan/align_extend/align_extend_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -86,10 +86,10 @@ struct IsFreeEndGap_, DPLastColumn> : True // Class DPMetaColumn_ [FullColumn] // ---------------------------------------------------------------------------- -template struct DPMetaColumn_, TGapCosts, - TTraceback>, + TTraceback, TExecPolicy>, MetaColumnDescriptor > { @@ -116,10 +116,10 @@ struct DPMetaColumn_, TGapCosts, // Class DPMetaColumn_ [PartialColumnTop] // ---------------------------------------------------------------------------- -template struct DPMetaColumn_, TGapCosts, - TTraceback>, + TTraceback, TExecPolicy>, MetaColumnDescriptor > { @@ -145,10 +145,10 @@ struct DPMetaColumn_, TGapCosts, // Class DPMetaColumn_ [PartialColumnMiddle] // ---------------------------------------------------------------------------- -template struct DPMetaColumn_, TGapCosts, - TTraceback>, + TTraceback, TExecPolicy>, MetaColumnDescriptor > { typedef typename If, TGapCosts, // Class DPMetaColumn_ [PartialColumnBottom] // ---------------------------------------------------------------------------- -template struct DPMetaColumn_, TGapCosts, - TTraceback>, + TTraceback, TExecPolicy>, MetaColumnDescriptor > { typedef typename If > > TScoreValue columnMax; DPScoutState_() : - terminationThreshold(MaxValue::VALUE), - columnMax(MinValue::VALUE) + terminationThreshold(std::numeric_limits::max()), + columnMax(std::numeric_limits::min()) { } DPScoutState_(TScoreValue const & _terminationThreshold) : terminationThreshold(_terminationThreshold), - columnMax(MinValue::VALUE) + columnMax(std::numeric_limits::min()) { } }; @@ -131,7 +131,7 @@ _scoutBestScore(DPScout_ > > & dpScout typedef typename Value::Type TScoreValue; typedef XDrop_ TXDrop; typedef DPScout_ > TDPScout; - typedef typename TDPScout::TParent TParent; + typedef typename TDPScout::TBase TParent; // global maximum _scoutBestScore(static_cast( dpScout ), activeCell, navigator); @@ -156,7 +156,7 @@ _scoutBestScore(DPScout_ > > & dpScout if (_scoreOfCell(dpScout._maxScore) - dpScout.state->columnMax >= dpScout.state->terminationThreshold) terminateScout(dpScout); else // reset columMax at end of column - dpScout.state->columnMax = MinValue::VALUE; + dpScout.state->columnMax = std::numeric_limits::min(); } // ---------------------------------------------------------------------------- @@ -164,16 +164,18 @@ _scoutBestScore(DPScout_ > > & dpScout // ---------------------------------------------------------------------------- // Computes the score and tracks it if enabled. -template inline void _computeCell(TDPScout & scout, TTraceMatrixNavigator & traceMatrixNavigator, - DPCell_ & activeCell, - DPCell_ const & previousDiagonal, - DPCell_ const & previousHorizontal, - DPCell_ const & previousVertical, + TDPCell & current, + TDPCell & diagonal, + TDPCell const & horizontal, + TDPCell & vertical, TSequenceHValue const & seqHVal, TSequenceVValue const & seqVVal, TScoringScheme const & scoringScheme, @@ -185,7 +187,7 @@ _computeCell(TDPScout & scout, typedef DPProfile_ >, TGapCosts, TTraceback> TDPProfile; typedef DPMetaColumn_ TMetaColumn; - assignValue(traceMatrixNavigator, _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, + assignValue(traceMatrixNavigator, _computeScore(current, diagonal, horizontal, vertical, seqHVal, seqVVal, scoringScheme, typename RecursionDirection_::Type(), TDPProfile())); @@ -196,8 +198,9 @@ _computeCell(TDPScout & scout, // the following is the only change to the regular _computeCell: // for the evaluation of the termination criterium we treat // all lastCells as lastRows + _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical)); typedef typename IsSameType::Type TIsLastRow; - _scoutBestScore(scout, activeCell, traceMatrixNavigator, TIsLastColumn(), TIsLastRow()); + _scoutBestScore(scout, current, traceMatrixNavigator, TIsLastColumn(), TIsLastRow()); } } diff --git a/porechop/include/seqan/align_parallel.h b/porechop/include/seqan/align_parallel.h new file mode 100644 index 0000000..8fd72b4 --- /dev/null +++ b/porechop/include/seqan/align_parallel.h @@ -0,0 +1,102 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_H_ + +// ============================================================================ +// STD Prerequisites +// ============================================================================ + +#if SEQAN_DEBUG_ENABLED +#include +#include +#include +#endif + +#include +#include +#include + +// ============================================================================ +// SeqAn Prerequisites +// ============================================================================ + +#include +#include +#include +#include + +// ============================================================================ +// Parallel DP Prerequisites and Adaptors +// ============================================================================ + +#include +#include +#include +#include +#include +#ifdef SEQAN_SIMD_ENABLED +#include +#endif + +// ============================================================================ +// Wavefront Task +// ============================================================================ + +#include +#include +#include +#include +#include +#include + +// ============================================================================ +// Wavefront Alignment Tasks +// ============================================================================ + +#include +#include // TODO(rrahn): rename! refactor! +#include +#include +#include + +// ============================================================================ +// Interfaces +// ============================================================================ + +#include +#include + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_H_ diff --git a/porechop/include/seqan/align_parallel/async_wave_execution_interface.h b/porechop/include/seqan/align_parallel/async_wave_execution_interface.h new file mode 100644 index 0000000..3ebb98a --- /dev/null +++ b/porechop/include/seqan/align_parallel/async_wave_execution_interface.h @@ -0,0 +1,252 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_ + +namespace seqan +{ +namespace impl +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +/* + * @class AsyncWaveAlignExecutor + * @brief Executor of the wave-front alignment mode with no SIMD vectorization. + * @headerfile + * + * Manges shared data for the wave-front execution before executing the alignments. + */ +template +class AsyncWaveAlignExecutor +{ +public: + + using TAlignmentTask = WavefrontAlignmentTask; + using TThreadLocal = typename WavefrontAlignmentTaskConfig::TThreadLocal; + using TStorage = EnumerableThreadLocal; + using TExecutor = WavefrontAlignmentExecutor; + + TSettings _settings; + // Initialize the alignment scheduler. + WavefrontAlignmentScheduler _alignScheduler; + + TStorage _threadLocalStorage{}; + TExecutor _executor{}; + unsigned _alignCounter{0}; + unsigned _blockSize{}; + + template + AsyncWaveAlignExecutor(TSettings settings, + ExecutionPolicy, Serial> const & execPolicy) : + _settings(std::move(settings)), + _alignScheduler(parallelAlignments(execPolicy), numThreads(execPolicy)), + _threadLocalStorage(TThreadLocal{parallelAlignments(execPolicy)}), + _blockSize(blockSize(execPolicy)) + { + _executor.ptrTaskScheduler = &taskScheduler(_alignScheduler); + _executor.ptrThreadLocal = &_threadLocalStorage; + setCount(storageManager(_threadLocalStorage), numThreads(execPolicy)); + } +}; + +/* + * @fn AsyncWaveAlignExecutor#submit + * @brief Submits a new alignment job asynchronosly. + */ +template +inline void +submit(AsyncWaveAlignExecutor & me, + TSeqH const & seqH, + TSeqV const & seqV, + TCallable && callback) +{ + using TAlignTask = typename AsyncWaveAlignExecutor::TAlignmentTask; + + std::function f = + [&, func = TAlignTask{me._alignCounter++, seqH, seqV, me._settings, me._blockSize}](uint16_t id) mutable + { + func(id, me._executor, std::forward(callback)); + }; + scheduleTask(me._alignScheduler, f); +} + +/* + * @fn AsyncWaveAlignExecutor#wait + * @brief Explicit barrier to wait for all submitted jobs to be finished. + */ +template +inline void +wait(AsyncWaveAlignExecutor & me) +{ + notify(me._alignScheduler); + wait(me._alignScheduler); +} + +/* + * @class AsyncWaveAlignExecutorSimd + * @brief Executor of the wave-front alignment mode with SIMD vectorization. + * @headerfile + * + * Manges shared data for the wave-front execution before executing the alignments. + */ +#ifdef SEQAN_SIMD_ENABLED +template +class AsyncWaveAlignExecutorSimd +{ +public: + + // Translate dp settings into simd settings. + using TSimdSettings = SimdDPSettings; + + using TAlignmentTask = WavefrontAlignmentTask>; + using TWavefrontTask = WavefrontTask; + using TSimdTaskQueue = WavefrontTaskQueue::VALUE>; + + using TThreadLocal = typename WavefrontAlignmentSimdTaskConfig::TThreadLocal; + using TStorage = EnumerableThreadLocal; + using TExecutor = WavefrontAlignmentExecutor; + + + TSimdSettings _settings; + // Initialize the alignment scheduler. + WavefrontAlignmentScheduler _alignScheduler; + + TStorage _threadLocalStorage; + TExecutor _executor{}; + TSimdTaskQueue _simdTaskQueue{}; + unsigned _alignCounter{0}; + unsigned _blockSize{}; + + template + AsyncWaveAlignExecutorSimd(TSettings const & settings, + ExecutionPolicy, Vectorial> const & execPolicy) : + _settings(settings.scoringScheme), + _alignScheduler(parallelAlignments(execPolicy), numThreads(execPolicy)), + _threadLocalStorage(TThreadLocal{parallelAlignments(execPolicy)}), + _blockSize(blockSize(execPolicy)) + { + _executor.ptrTaskScheduler = &taskScheduler(_alignScheduler); + _executor.ptrThreadLocal = &_threadLocalStorage; + setCount(storageManager(_threadLocalStorage), numThreads(execPolicy)); + } +}; + +/* + * @fn AsyncWaveAlignExecutorSimd#submit + * @brief Submits a new alignment job asynchronosly. + */ +template +inline void +submit(AsyncWaveAlignExecutorSimd & me, + TSeqH const & seqH, + TSeqV const & seqV, + TCallable && callback) +{ + using TAlignTask = typename AsyncWaveAlignExecutorSimd::TAlignmentTask; + + // Continuator for calling the alignment instance functor. + std::function f = + [&, func = TAlignTask{me._alignCounter++, seqH, seqV, me._settings, me._blockSize}](uint16_t id) mutable + { + func(id, me._executor, me._simdTaskQueue, std::forward(callback)); + }; + scheduleTask(me._alignScheduler, f); +} + +/* + * @fn AsyncWaveAlignExecutorSimd#wait + * @brief Explicit barrier to wait for all submitted jobs to be finished. + */ +template +inline void +wait(AsyncWaveAlignExecutorSimd & me) +{ + notify(me._alignScheduler); + wait2(me._alignScheduler, me._simdTaskQueue); +} +#endif // SEQAN_SIMD_ENABLED + +/* + * @fn alignExecBatch + * @brief Global interface for scheduling and running all alignment jobs with wave-front model. + */ +template +inline void +alignExecBatch(ExecutionPolicy, TSimdSpec> const & execPolicy, + TSetH const & setH, + TSetV const & setV, + TSettings const & settings, + TCallable && callback) +{ + using TSeqH = typename Value::Type; + using TSeqV = typename Value::Type; + +#ifdef SEQAN_SIMD_ENABLED + using TExecutor = std::conditional_t::value, + AsyncWaveAlignExecutorSimd, + AsyncWaveAlignExecutor>; +#else + using TExecutor = AsyncWaveAlignExecutor; +#endif + TExecutor executor(settings, execPolicy); + + for (size_t i = 0u; i < length(setH); ++i) + { + submit(executor, setH[i], setV[i], std::forward(callback)); + } + wait(executor); +} + +} // namespace impl +} // namespace seqan +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_ diff --git a/porechop/include/seqan/align_parallel/dp_kernel_adaptor.h b/porechop/include/seqan/align_parallel/dp_kernel_adaptor.h new file mode 100644 index 0000000..e4a3eb8 --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_kernel_adaptor.h @@ -0,0 +1,343 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// ============================================================================ +// Metafunctions +// ============================================================================ + +template +struct CorrectLastColumn_ : False +{}; + +template <> +struct CorrectLastColumn_ : True +{}; + +template +struct CorrectLastRow_ : False +{}; + +template <> +struct CorrectLastRow_ : True +{}; + +// ============================================================================ +// Functions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Function _computeCell(); InitialCol; +// ---------------------------------------------------------------------------- + +// The _computeCell function is the basic interface that is called to comute +// the score for each cell and to store the corresponding traceback. +// The MetaColumnDescriptor and the CellDescriptor describe which cell in the dp matrix +// is computed. We use this information to overload the functions in order +// to initialize from the passed buffer and to store the last row/column in the buffer. + +// Vertical initialization values are copied from buffer. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & /*cacheDiag*/, + TDPCell const & /*cacheHori*/, + TDPCell & /*cacheVert*/, + TSequenceHValue const & /*seqHVal*/, + TSequenceVValue const & /*seqVVal*/, + TScoringScheme const & /*scoringScheme*/, + MetaColumnDescriptor const &, + TCellDescriptor const &, // One of FirstCell, InnerCell or LastCell. + DPProfile_ const &) +{ + typedef DPProfile_ TDPProfile; + typedef DPMetaColumn_ > TMetaColumn; + + current = (*scout.state.ptrVerBuffer)[scout.verticalPos].i1; + assignValue(traceMatrixNavigator, (*scout.state.ptrVerBuffer)[scout.verticalPos].i2); + + if (TrackingEnabled_::VALUE) + { + _scoutBestScore(scout, current, traceMatrixNavigator, False(), False()); + } +} + +// ---------------------------------------------------------------------------- +// Function _computeCell(); InnerCol; FirstCell +// ---------------------------------------------------------------------------- + +// Horizontal initialization values are copied from buffer for all first cells. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & cacheDiag, + TDPCell const & cacheHori, + TDPCell & cacheVert, + TSequenceHValue const & /*seqHVal*/, + TSequenceVValue const & /*seqVVal*/, + TScoringScheme const & /*scoringScheme*/, + MetaColumnDescriptor const &, + FirstCell const &, // One of FirstCell, InnerCell or LastCell. + DPProfile_ const &) +{ + _scoreOfCell(cacheDiag) = _scoreOfCell(cacheHori); + current = (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1; + cacheVert = current; + assignValue(traceMatrixNavigator, (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2); +} + +// ---------------------------------------------------------------------------- +// Function _computeCell(); InnerCol; LastCell +// ---------------------------------------------------------------------------- + +// Values of last call are copied into the horizontal buffer for initializing next tile below. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & cacheDiag, + TDPCell const & cacheHori, + TDPCell & cacheVert, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + MetaColumnDescriptor const &, + LastCell const & /*cellDescriptor*/, + DPProfile_ const &) +{ + typedef DPProfile_ TDPProfile; + typedef DPMetaColumn_ > TMetaColumn; + + assignValue(traceMatrixNavigator, + _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal, + scoringScheme, typename RecursionDirection_::Type(), + TDPProfile())); + // Copy values into horizontal buffer for the tile below this tile in vertical direction. + // TODO(rrahn): We need to do this only for affine gaps? + _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert)); + (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1 = current; + if (IsTracebackEnabled_::VALUE) + { + (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2 = value(traceMatrixNavigator); + } + + if (TrackingEnabled_::VALUE) + { + _scoutBestScore(scout, current, traceMatrixNavigator, False(), True()); + } +} + + +// ---------------------------------------------------------------------------- +// Function _computeCell(); FinalCol; FirstCell +// ---------------------------------------------------------------------------- + +// Horizontal initialization values are copied from buffer for all first cells. +// Vertical buffer is filled with value. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & cacheDiag, + TDPCell const & cacheHori, + TDPCell & cacheVert, + TSequenceHValue const & /*seqHVal*/, + TSequenceVValue const & /*seqVVal*/, + TScoringScheme const & /*scoringScheme*/, + MetaColumnDescriptor const &, + FirstCell const &, // One of FirstCell, InnerCell or LastCell. + DPProfile_ const &) +{ + typedef DPProfile_ TDPProfile; + typedef DPMetaColumn_ > TMetaColumn; + + // cache previous diagonal. + _scoreOfCell(cacheDiag) = _scoreOfCell(cacheHori); + current = + front(*scout.state.ptrVerBuffer).i1 = (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1; // Copy horizontal buffer value in active cell and in + assignValue(traceMatrixNavigator, (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2); + cacheVert = current; + if (IsTracebackEnabled_::VALUE) + { + front(*scout.state.ptrVerBuffer).i2 = value(traceMatrixNavigator); // Store trace value in vertical buffer. + } + + if (TrackingEnabled_::VALUE) + { + _scoutBestScore(scout, current, traceMatrixNavigator, True(), False()); + } +} + +// ---------------------------------------------------------------------------- +// Function _computeCell(); FinalCol, InnerCell; +// ---------------------------------------------------------------------------- + +// Stores computed values in vertical buffer for initializing next tile right of the current. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & cacheDiag, + TDPCell const & cacheHori, + TDPCell & cacheVert, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + MetaColumnDescriptor const &, + InnerCell const &, + DPProfile_ const &) +{ + typedef DPProfile_ TDPProfile; + typedef DPMetaColumn_ > TMetaColumn; + + assignValue(traceMatrixNavigator, + _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal, + scoringScheme, typename RecursionDirection_::Type(), + TDPProfile())); + // Store values in vertical buffer. + _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert)); + (*scout.state.ptrVerBuffer)[scout.verticalPos].i1 = current; + if (IsTracebackEnabled_::VALUE) + { + (*scout.state.ptrVerBuffer)[scout.verticalPos].i2 = value(traceMatrixNavigator); + } + + if (TrackingEnabled_::VALUE) + { + _scoutBestScore(scout, current, traceMatrixNavigator, True(), False()); + } +} + +// ---------------------------------------------------------------------------- +// Function _computeCell(); FinalCol, LastCell; +// ---------------------------------------------------------------------------- + +// Stores computed values in vertical buffer for initializing next tile right of the current. +// Stores computed values in horizontal buffer for initializing next tile below. +template +inline void +_computeCell(TDPScout & scout, + TTraceMatrixNavigator & traceMatrixNavigator, + TDPCell & current, + TDPCell & cacheDiag, + TDPCell const & cacheHori, + TDPCell & cacheVert, + TSequenceHValue const & seqHVal, + TSequenceVValue const & seqVVal, + TScoringScheme const & scoringScheme, + MetaColumnDescriptor const &, + LastCell const &, + DPProfile_ const &) +{ + typedef DPProfile_ TDPProfile; + typedef DPMetaColumn_ > TMetaColumn; + + assignValue(traceMatrixNavigator, + _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal, + scoringScheme, typename RecursionDirection_::Type(), + TDPProfile())); + // Store values in vertical and horizontal buffer + _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert)); + (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1 = (*scout.state.ptrVerBuffer)[scout.verticalPos].i1 = current; + if (IsTracebackEnabled_::VALUE) + { + (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2 = + (*scout.state.ptrVerBuffer)[scout.verticalPos].i2 = value(traceMatrixNavigator); + } + if (TrackingEnabled_::VALUE) + { + _scoutBestScore(scout, current, traceMatrixNavigator, True(), True()); + } +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_ diff --git a/porechop/include/seqan/align_parallel/dp_parallel_execution_policies.h b/porechop/include/seqan/align_parallel/dp_parallel_execution_policies.h new file mode 100644 index 0000000..a2885ec --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_parallel_execution_policies.h @@ -0,0 +1,174 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== +// Policies used for parallel alignment computation. +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_ + +namespace seqan +{ +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +/*! + * @tag BlockOffsetOptimization + * @brief Optimization for vectorized wave-front execution model. + * @headerfile + * @see WavefrontExecutionPolicy + */ +struct BlockOffsetOptimization_; +using BlockOffsetOptimization = Tag; + +/*! + * @class WavefrontExecutionPolicy + * @headerfile + * @extends ExecutionPolicy + * @brief Policy to select runtime execution mode for algorithms. + * @signature template + * struct ExecutionPolicy, TVectorizationMode>; + * @tparam TWaveSpec Type specializing the wave-front threading model. + * Can be void (default) or @link BlockOffsetOptimization @endlink. + * @tparam TVectorizationMode Type specifying the vectorization model. + * Can be @link ParallelismTags#Vectorial @endlink or @link ParallelismTags#Serial @endlink (default). + * + * Special execution policy for computing sequence alignments with wave-front parallelization strategy. + * In the wave-front execution the DP matrix is partitioned into blocks which can be executed + * in parallel along the minor diagonal of the DP matrix. + * The execution policy can be further specialized if used in combination with the @link ParallelismTags#Vectorial @endlink + * execution mode (see @link WavefrontExecutionPolicy @endlink). + * + * @section Vectorization + * + * In the vectorization mode, the blocks are gathered into SIMD registers. + * The @link BlockOffsetOptimization @endlink can be used to always ensure that sizeof(SIMD) / 2 many blocks + * can be packed into one SIMD register. + * This requires, that the available instruction set supports 16 bit packed SIMD operations (e.g. SSE4, AVX2) + * and the score value type (@link Score @endlink) is bigger then 16 bit. + * In the default mode, the optimization is disabled and the number of packed alignment blocks is solely determined by + * the score value type passed to the algorithm as a parameter (e.g. see @link globalAlignmentScore @endlink). + */ + template + struct WavefrontAlignment; + +template +struct ExecutionPolicy, TVectorizationSpec> : + public ExecutionPolicy +{ + /*! + *@var size_t WavefrontExecutionPolicy::blockSize + * @brief The size of the blocks to use. Defaults to 100. + */ + size_t blockSize{100}; + /*! + * @var size_t WavefrontExecutionPolicy::parallelAlignments + * @brief Number of alignments scheduled concurrently. Defaults to std::thread::hardware_concurrency(). + */ + size_t parallelAlignments{std::thread::hardware_concurrency()}; +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +/*! + * @fn WavefrontExecutionPolicy#blockSize + * @brief Getter for the current block size. + * @signature size_t blockSize(exec); + * @param[in] exec The wave-front execution policy to query. + */ +template +inline auto +blockSize(ExecutionPolicy, TVectorizationSpec> const & p) +{ + return p.blockSize; +} + +/*! + * @fn WavefrontExecutionPolicy#setBlockSize + * @brief Setter for the current block size. + * @signature void setBlockSize(exec, bs); + * @param[in,out] exec The wave-front execution policy to update. + * @param[in] bs The new block size to set. Must be a positive integral number greater or equal than 5. + */ +template +inline void +setBlockSize(ExecutionPolicy, TVectorizationSpec> & p, + size_t const bs) +{ + SEQAN_ASSERT_GEQ(bs, static_cast(5)); + p.blockSize = bs; +} + +/*! + * @fn WavefrontExecutionPolicy#parallelAlignments + * @brief Getter for the current number of alignments executed in parallel. + * @signature void parallelAlignments(exec); + * @param[in] exec The wave-front execution policy to update. + */ +template +inline auto +parallelAlignments(ExecutionPolicy, TVectorizationSpec> const & p) +{ + return p.parallelAlignments; +} + +/*! + * @fn WavefrontExecutionPolicy#setParallelAlignments + * @brief Setter for the current number of alignments executed in parallel. + * @signature void setParallelAlignments(exec, pa); + * @param[in,out] exec The wave-front execution policy to update. + * @param[in] pa The number of alignments to execute in parallel. Must be a positive integral number greater than 0. + */ +template +inline void +setParallelAlignments(ExecutionPolicy, TVectorizationSpec> & p, + size_t const pi) +{ + SEQAN_ASSERT_GT(pi, static_cast(0)); + p.parallelAlignments = pi; +} + +} // namespace seqan + +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_ diff --git a/porechop/include/seqan/align_parallel/dp_parallel_scout.h b/porechop/include/seqan/align_parallel/dp_parallel_scout.h new file mode 100644 index 0000000..58a238d --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_parallel_scout.h @@ -0,0 +1,263 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_ +#define INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Class DPTileBuffer +// ---------------------------------------------------------------------------- + +// The structure owning the horizontal/vertical buffer. +template > +struct DPTileBuffer +{ + TBuffer horizontalBuffer; + TBuffer verticalBuffer; +}; + +// ---------------------------------------------------------------------------- +// Tag DPTiled +// ---------------------------------------------------------------------------- + +// Tag used to subclass DPScoutState and DPScout. +// T represents the buffer type. +template +struct DPTiled; + +// ---------------------------------------------------------------------------- +// Class DPScoutState_; DPTiled +// ---------------------------------------------------------------------------- + +// The overloaded DPScoutState which simply stores the pointers to the corresponding buffer. +template +class DPScoutState_ > +{ +public: + + using TDPCell = typename Value::Type, 1>::Type; + + TBuffer* ptrHorBuffer = nullptr; + TBuffer* ptrVerBuffer = nullptr; + TThreadContext threadContext{}; + + DPScoutState_() = default; + + DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer) : + ptrHorBuffer(&horBuffer), + ptrVerBuffer(&verBuffer) + {} + + DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer, TThreadContext pThreadContext) : + ptrHorBuffer(&horBuffer), + ptrVerBuffer(&verBuffer), + threadContext(std::move(pThreadContext)) + {} +}; + +// ---------------------------------------------------------------------------- +// Class DPScout_; DPTiled +// ---------------------------------------------------------------------------- + +// Overloaded DPScout to store the corresponding buffer for the current dp tile. +template +class DPScout_ > : + public DPScout_ +{ +public: + using TBase = DPScout_; + + DPScoutState_ > state; + + size_t horizontalPos; + size_t verticalPos; + bool forceTracking; + + DPScout_(DPScoutState_ > state, + bool pForceTracking = false) : + TBase(), + state(state), + forceTracking(pForceTracking) + {} +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Metafunction ScoutSpecForSimdAlignment_ +// ---------------------------------------------------------------------------- + +template +struct ScoutSpecForAlignmentAlgorithm_ > > +{ + using Type = DPTiled; +}; + +// ============================================================================ +// Functions +// ============================================================================ + +template +inline bool +isTrackingEnabled(DPScout_ > const & /*dpScout*/, + TIsLastColumn const & /*unused*/, + TIsLastRow const & /*unused*/) +{ + return false; +} + +template +inline bool +isTrackingEnabled(DPScout_ > const & dpScout, + True const & /*unused*/, + True const & /*unused*/) +{ + return (dpScout.forceTracking || (dpScout.state.threadContext.task._lastHBlock && + dpScout.state.threadContext.task._lastVBlock)); +} + +template +inline bool +isTrackingEnabled(DPScout_ > const & dpScout, + True const & /*unused*/, + False const & /*unused*/) +{ + return (dpScout.forceTracking || dpScout.state.threadContext.task._lastHBlock); +} + +template +inline bool +isTrackingEnabled(DPScout_ > const & dpScout, + False const & /*unused*/, + True const & /*unused*/) +{ + return (dpScout.forceTracking || dpScout.state.threadContext.task._lastVBlock); +} + +// ---------------------------------------------------------------------------- +// Function _scoutBestScore() +// ---------------------------------------------------------------------------- + +template +inline void +_scoutBestScore(DPScout_ > & dpScout, + TDPCell const & activeCell, + TTraceMatrixNavigator const & navigator, + TIsLastColumn const & isLastColumn, + TIsLastRow const & isLastRow) +{ + using TBaseScout = typename DPScout_ >::TBase; + _scoutBestScore(static_cast(dpScout), activeCell, navigator, isLastColumn, isLastRow); +} + +// Tracks the new score, if it is the new maximum. +template +inline void +_scoutBestScore(DPScout_ > & dpScout, + TDPCell const & activeCell, + TTraceMatrixNavigator const & navigator, + TIsLastColumn const & isLastColumn, + TIsLastRow const & isLastRow) +{ + using TBaseScout = typename DPScout_ >::TBase; + if (isTrackingEnabled(dpScout, isLastColumn, isLastRow)) + _scoutBestScore(static_cast(dpScout), activeCell, navigator, isLastColumn, isLastRow); +} + +// ---------------------------------------------------------------------------- +// Function _preInitScoutHorizontal() +// ---------------------------------------------------------------------------- + +template +inline void +_preInitScoutHorizontal(DPScout_ > & scout) +{ + scout.horizontalPos = 0; +} + +// ---------------------------------------------------------------------------- +// Function _preInitScoutVertical() +// ---------------------------------------------------------------------------- + +template +inline void +_preInitScoutVertical(DPScout_ > & scout) +{ + scout.verticalPos = 0; +} + +// ---------------------------------------------------------------------------- +// Function _incHorizontalPos() +// ---------------------------------------------------------------------------- + +template +inline void +_incHorizontalPos(DPScout_ > & scout) +{ + ++scout.horizontalPos; +} + +// ---------------------------------------------------------------------------- +// Function _incVerticalPos() +// ---------------------------------------------------------------------------- + +template +inline void +_incVerticalPos(DPScout_ > & scout) +{ + ++scout.verticalPos; +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_ diff --git a/porechop/include/seqan/align_parallel/dp_parallel_scout_simd.h b/porechop/include/seqan/align_parallel/dp_parallel_scout_simd.h new file mode 100644 index 0000000..4d977e1 --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_parallel_scout_simd.h @@ -0,0 +1,362 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_ +#define INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Class DPScoutState_; DPTiled +// ---------------------------------------------------------------------------- + +// The overloaded DPScoutState which simply stores the pointers to the corresponding buffer. +template +class DPScoutState_ > : + public DPScoutState_ >, + public DPScoutState_ +{ +public: + + DPScoutState_() = default; + + DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer) : + DPScoutState_ >(horBuffer, verBuffer), + DPScoutState_() + {} + + DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer, TThreadContext && pThreadContext) : + DPScoutState_ >(horBuffer, verBuffer, std::move(pThreadContext)), + DPScoutState_() + {} +}; + +// ---------------------------------------------------------------------------- +// Class DPScout_; DPTiled +// ---------------------------------------------------------------------------- + +// Overloaded DPScout to store the corresponding buffer for the current dp tile. +template +class DPScout_ > > : + public DPScout_> +{ +public: + using TBase = DPScout_ >; + + DPScoutState_ > state; + size_t horizontalPos; + size_t verticalPos; + bool forceTracking; + + DPScout_(DPScoutState_ > & state, + bool const pForceTracking) : + TBase(static_cast&>(state)), + state(state), + forceTracking(pForceTracking) + {} + + DPScout_(DPScoutState_ > & state) : DPScout_(state, false) + {} +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Metafunction ScoutSpecForSimdAlignment_ +// ---------------------------------------------------------------------------- + +template +struct ScoutSpecForAlignmentAlgorithm_ > > +{ + using Type = DPTiled >; +}; + +template +struct ScoutSpecForAlignmentAlgorithm_ > > > +{ + using Type = DPTiled > >; +}; + +// ============================================================================ +// Functions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Function isTrackingEnabled() +// ---------------------------------------------------------------------------- + +template +inline bool +isTrackingEnabled(DPScout_ > > const & dpScout, + True const & /*unused*/, + True const & /*unused*/) +{ + // TODO(rrahn): Implement me! + return (dpScout.forceTracking); +} + +template +inline bool +isTrackingEnabled(DPScout_ > > const & dpScout, + True const & /*unused*/, + False const & /*unused*/) +{ + // TODO(rrahn): Implement me! + return (dpScout.forceTracking); +} + +template +inline bool +isTrackingEnabled(DPScout_ > > const & dpScout, + False const & /*unused*/, + True const & /*unused*/) +{ + // TODO(rrahn): Implement me! + return (dpScout.forceTracking); +} + +// ---------------------------------------------------------------------------- +// Function _scoutBestScore() +// ---------------------------------------------------------------------------- + +template +inline void +_scoutBestScore(DPScout_ > > & dpScout, + TDPCell const & activeCell, + TTraceMatrixNavigator const & navigator, + TIsLastColumn const & isLastColumn, + TIsLastRow const & isLastRow) +{ + using TScoutBase = typename DPScout_>>::TBase; + _scoutBestScore(static_cast(dpScout), activeCell, navigator, isLastColumn, isLastRow); +} + +// ---------------------------------------------------------------------------- +// Function maxHostCoordinate() +// ---------------------------------------------------------------------------- + +template +inline auto +maxHostCoordinate(DPScout_ > > const & dpScout, + TDimension const dimension) +{ + using TScoutBase = typename DPScout_ > >::TBase; + return maxHostCoordinate(static_cast(dpScout), dimension); +} + +// ---------------------------------------------------------------------------- +// Function _setSimdLane() +// ---------------------------------------------------------------------------- + +template +inline void +_setSimdLane(DPScout_ > > & dpScout, + TPosition const pos) +{ + using TScoutBase = typename DPScout_ > >::TBase; + _setSimdLane(static_cast(dpScout), pos); +} + +// ---------------------------------------------------------------------------- +// Function _preInitScoutHorizontal() +// ---------------------------------------------------------------------------- + +template +inline void +_preInitScoutHorizontal(DPScout_ > > > & scout) +{ + using TScoutBase = typename DPScout_>>>::TBase; + _preInitScoutHorizontal(static_cast(scout)); + scout.horizontalPos = 0; +} + +// ---------------------------------------------------------------------------- +// Function _preInitScoutVertical() +// ---------------------------------------------------------------------------- + +template +inline void +_preInitScoutVertical(DPScout_>>> & scout) +{ + using TScoutBase = typename DPScout_>>>::TBase; + _preInitScoutVertical(static_cast(scout)); + scout.verticalPos = 0; +} + +// ---------------------------------------------------------------------------- +// Function _reachedHorizontalEndPoint() +// ---------------------------------------------------------------------------- + +template +inline bool +_reachedHorizontalEndPoint(DPScout_>>> & scout, + TIter const & hIt) +{ + using TScoutBase = typename DPScout_>>>::TBase; + return _reachedHorizontalEndPoint(static_cast(scout), hIt); +} + +// ---------------------------------------------------------------------------- +// Function _reachedVerticalEndPoint() +// ---------------------------------------------------------------------------- + +template +inline bool +_reachedVerticalEndPoint(DPScout_ > > > & scout, + TIter const & vIt) +{ + using TScoutBase = typename DPScout_ > > >::TBase; + return _reachedVerticalEndPoint(static_cast(scout), vIt); +} + +// ---------------------------------------------------------------------------- +// Function _nextHorizontalEndPos() +// ---------------------------------------------------------------------------- + +template +inline void +_nextHorizontalEndPos(DPScout_ > > > & scout) +{ + using TScoutBase = typename DPScout_ > > >::TBase; + _nextHorizontalEndPos(static_cast(scout)); +} + +// ---------------------------------------------------------------------------- +// Function _nextVerticalEndPos() +// ---------------------------------------------------------------------------- + +template +inline void +_nextVerticalEndPos(DPScout_ > > > & scout) +{ + using TScoutBase = typename DPScout_ > > >::TBase; + _nextVerticalEndPos(static_cast(scout)); +} + +// ---------------------------------------------------------------------------- +// Function _incHorizontalPos() +// ---------------------------------------------------------------------------- + +template +inline void +_incHorizontalPos(DPScout_ > > > & scout) +{ + using TScoutBase = typename DPScout_ > > >::TBase; + _incHorizontalPos(static_cast(scout)); + ++scout.horizontalPos; +} + +// ---------------------------------------------------------------------------- +// Function _incVerticalPos() +// ---------------------------------------------------------------------------- + +template +inline void +_incVerticalPos(DPScout_ > > > & scout) +{ + using TScoutBase = typename DPScout_ > > >::TBase; + _incVerticalPos(static_cast(scout)); + ++scout.verticalPos; +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_ diff --git a/porechop/include/seqan/align_parallel/dp_settings.h b/porechop/include/seqan/align_parallel/dp_settings.h new file mode 100644 index 0000000..6695391 --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_settings.h @@ -0,0 +1,109 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Translates global function interface into setting struct. +template +struct DPSettings +{ + using TTraits = TDPTraits; + using TScoringScheme = TScoringScheme_; + using TBandConfig = DPBandConfig; + + TScoringScheme scoringScheme; + TBandConfig bandScheme; + + DPSettings() = default; + + explicit DPSettings(TScoringScheme score) : scoringScheme(std::move(score)) + {} +}; + +#ifdef SEQAN_SIMD_ENABLED +// Simd version of DP settings. +template +struct SimdDPSettings : public TDPSettings +{ + //------------------------------------------------------------------------- + // Member Types. + + using TTraits = typename TDPSettings::TTraits; + using TScoringScheme = typename TDPSettings::TScoringScheme; + using TScoreValue = typename Value::Type; + using TScoreValueSimd = typename SimdVector< + std::conditional_t::value, + int16_t, + TScoreValue>>::Type; + using TSimdScoringScheme = Score>; + + //------------------------------------------------------------------------- + // Members. + + TSimdScoringScheme simdScoringScheme; + + //------------------------------------------------------------------------- + // Constructor. + + SimdDPSettings() = default; + + explicit SimdDPSettings(TScoringScheme score) : + TDPSettings(std::move(score)), + simdScoringScheme(score) + {} +}; +#endif // SEQAN_SIMD_ENABLED +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +} // namespace seqan + +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_ diff --git a/porechop/include/seqan/align_parallel/dp_traits.h b/porechop/include/seqan/align_parallel/dp_traits.h new file mode 100644 index 0000000..2606408 --- /dev/null +++ b/porechop/include/seqan/align_parallel/dp_traits.h @@ -0,0 +1,120 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Traits for DP configuration. Currently used only internally. +struct DPTraits +{ + // Gocal alignment with linear gap costs. + struct GlobalLinear + { + // The algorithm to choose. + using TAlgorithmType = GlobalAlignment_<>; + // The Gaps to choos + using TGapType = LinearGaps; + // The Band to choose. + using TBandType = BandOff; + // The traceback. + using TTracebackType = TracebackOn>; + // The output to choose. + using TFormat = ArrayGaps; + }; + + // Global alignment with affine gap costs. + struct GlobalAffine : public GlobalLinear + { + using TGapType = AffineGaps; + }; + + // Global alignment with affine gap costs. + struct SemiGlobalLinear : public GlobalLinear + { + using TAlgorithmType = GlobalAlignment_>; + }; + + // Global alignment with affine gap costs. + struct SemiGlobalAffine : public GlobalAffine + { + using TAlgorithmType = GlobalAlignment_>; + }; + + // Banded global alignment with linear gap costs. + struct BandedGlobalLinear : public GlobalLinear + { + using TBandType = BandOn; + }; + + // Banded global alignment with affine gap costs. + struct BandedGlobalAffine : public BandedGlobalLinear + { + using TGapType = AffineGaps; + }; + + // Local alignment with linear gap costs. + struct LocalLinear : public GlobalLinear + { + using TAlgorithmType = LocalAlignment_<>; + }; + + // Local alignment with affine gap costs. + struct LocalAffine : public LocalLinear + { + using TGapType = AffineGaps; + }; +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +} // namespace seqan + +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_ diff --git a/porechop/include/seqan/align_parallel/parallel_align_interface.h b/porechop/include/seqan/align_parallel/parallel_align_interface.h new file mode 100644 index 0000000..764aa2a --- /dev/null +++ b/porechop/include/seqan/align_parallel/parallel_align_interface.h @@ -0,0 +1,366 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +namespace impl +{ + +/* + * Executor class that implements the correct execution mode. + */ +struct ParallelAlignmentExecutor +{ + template + auto operator()(Sequential const & /*execPolicy*/, + TKernel && kernel, + TSetH const & setH, + TSetV const & setV, + TArgs && ...args) + { + SEQAN_ASSERT_EQ(length(setH), length(setV)); + + using TResult = decltype(kernel(setH, setV, std::forward(args)...)); + + TResult superSet; + resize(superSet, length(setH)); + + auto zipCont = makeZipView(setH, setV, superSet); +#ifdef DP_PARALLEL_SHOW_PROGRESS + ::impl::dp_parallel_progress::show_progress(length(setH)); +#endif // DP_PARALLEL_SHOW_PROGRESS + for (auto && pwInst : zipCont) + { + std::get<2>(pwInst) = kernel(std::get<0>(pwInst), std::get<1>(pwInst), std::forward(args)...); + } + return superSet; + } + + template + auto operator()(ExecutionPolicy const & /*execPolicy*/, + TKernel && kernel, + TSetH const & setH, + TArgs && ...args) + { +#ifdef DP_PARALLEL_SHOW_PROGRESS + ::impl::dp_parallel_progress::show_progress(length(setH)); +#endif // DP_PARALLEL_SHOW_PROGRESS + // Automaically chooses vectorized code, or falls back to sequential code. + return kernel(setH, std::forward(args)...); + } + + template + auto operator()(SEQAN_UNUSED ExecutionPolicy const & execPolicy, // maybe unused due to missing OMP support in clang. + TKernel && kernel, + TSetH const & setH, + TSetV const & setV, + TArgs && ...args) + + { + SEQAN_ASSERT_EQ(length(setH), length(setV)); + + using TPos = std::make_signed_t; + using TResult = decltype(kernel(setH, setV, std::forward(args)...)); + + TPos chunkSize = _min(static_cast(length(setH)), static_cast(256)); + String splitter; + computeSplitters(splitter, length(setH), static_cast(length(setH)/chunkSize)); + + std::vector superSet; + superSet.resize(length(splitter)); + +#ifdef DP_PARALLEL_SHOW_PROGRESS + ::impl::dp_parallel_progress::show_progress(length(setH)); +#endif // DP_PARALLEL_SHOW_PROGRESS + + SEQAN_OMP_PRAGMA(parallel for num_threads(numThreads(execPolicy)) schedule(guided)) + for (TPos job = 0; job < static_cast(length(splitter)) - 1; ++job) // TODO(rrahn): Why -1; Is there a bug in computeSplitters? + { + auto infSetH = infix(setH, splitter[job], splitter[job + 1]); + auto infSetV = infix(setV, splitter[job], splitter[job + 1]); + + superSet[job] = kernel(infSetH, infSetV, std::forward(args)...); + } + // Reduce the result. + TResult res; + resize(res, length(setH)); + auto it = begin(res, Standard()); + for (auto && set : superSet) + { + arrayMoveForward(begin(set, Standard()), end(set, Standard()), it); + it += length(set); + } + return res; + } + + template + auto operator()(ExecutionPolicy const & execPolicy, + TKernel && kernel, + TSetH const & setH, + TSetV const & setV, + TArgs && ...args) + + { + SEQAN_ASSERT_EQ(length(setH), length(setV)); + + using TPos = std::make_signed_t; + using TResult = decltype(kernel(setH, setV, std::forward(args)...)); + + Splitter splitter(0, length(setH), numThreads(execPolicy)); + + TResult superSet; + resize(superSet, length(setH)); + + auto zipCont = makeZipView(setH, setV, superSet); + +#ifdef DP_PARALLEL_SHOW_PROGRESS + ::impl::dp_parallel_progress::show_progress(length(setH)); +#endif // DP_PARALLEL_SHOW_PROGRESS + + SEQAN_OMP_PRAGMA(parallel for num_threads(length(splitter))) + for (TPos job = 0; job < static_cast(length(splitter)); ++job) + { + auto it = begin(zipCont, Standard()) + splitter[job]; + auto itEnd = begin(zipCont, Standard()) + splitter[job + 1]; + + // NOTE(marehr): auto && seqPair does not work, thus declaring the + // type explicitly, s.t. <=icpc 18.0.1 can compile the code (ticket + // #03204483) + using TSeqPair = decltype(*it); + std::for_each(it, itEnd, [&](TSeqPair && seqPair) + { + std::get<2>(seqPair) = kernel(std::get<0>(seqPair), std::get<1>(seqPair), std::forward(args)...); + }); + } + return superSet; + } +}; + +template , Serial>::value && + !std::is_same, Parallel>::value, + int> = 0> +inline auto +doWaveAlignment(ExecutionPolicy, TVectorizationPolicy> const & execPolicy, + TAlgorithmSpec const & /*tag*/, + TSetH const & setH, + TSetV const & setV, + TScore const & scoringScheme, + TArgs && .../*args*/) +{ + using TScoreValue = typename Value::Type; + + // The vector containing the scores. + std::vector res; + res.resize(length(setH)); + + auto dispatcher = [&res](auto && ...args) + { + alignExecBatch(std::forward(args)..., + [&res](auto const id, auto const score) + { + res[id] = score; + }); + }; + + // Differentiate between affine and linear gap costs. + // TODO(rrahn): Setup configuration cascade. + if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme)) + { + struct DPConfigTraits + { + using TAlgorithmType SEQAN_UNUSED = TAlgorithmSpec; + using TGapType SEQAN_UNUSED = LinearGaps; + using TBandType SEQAN_UNUSED = BandOff; + using TTracebackType SEQAN_UNUSED = TracebackOff; + using TFormat SEQAN_UNUSED = ArrayGaps; + }; + + using TDPSettings = seqan::DPSettings; + + TDPSettings settings; + settings.scoringScheme = scoringScheme; + dispatcher(execPolicy, setH, setV, settings); + } + else + { + struct DPConfigTraits + { + using TAlgorithmType SEQAN_UNUSED = TAlgorithmSpec; + using TGapType SEQAN_UNUSED = AffineGaps; + using TBandType SEQAN_UNUSED = BandOff; + using TTracebackType SEQAN_UNUSED = TracebackOff; + using TFormat SEQAN_UNUSED = ArrayGaps; + }; + + using TDPSettings = seqan::DPSettings; + + TDPSettings settings; + settings.scoringScheme = scoringScheme; + dispatcher(execPolicy, setH, setV, settings); + } + return res; +} + +} // namespace impl + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +/* + * Wrapper functions for calling globalAlignmentScore and localAlignmentScore with an ExecutionPolicy. + * Note the parallel interfaces are documented as part of the standard documentation in seqan/align module. + */ +template ::value || + std::is_same::value, + int> = 0> +inline auto +globalAlignmentScore(ExecutionPolicy const & execPolicy, + TArgs && ...args) +{ + auto kernel = [](auto && ...args) + { + return globalAlignmentScore(std::forward(args)...); + }; + return impl::ParallelAlignmentExecutor{}(execPolicy, kernel, std::forward(args)...); +} + +template ::value || + std::is_same::value, + int> = 0> +inline auto +localAlignmentScore(ExecutionPolicy const & execPolicy, + TArgs && ...args) +{ + auto kernel = [](auto && ...args) + { + return localAlignmentScore(std::forward(args)...); + }; + return impl::ParallelAlignmentExecutor{}(execPolicy, kernel, std::forward(args)...); +} + +// Wavefront execution of globalAlignmentScore w/ config. +template , Serial>::value && + !std::is_same, Parallel>::value, + int> = 0> + +inline auto +globalAlignmentScore(ExecutionPolicy, TVectorizationPolicy> const & execPolicy, + TSetH const & setH, + TSetV const & setV, + TScore const & scoringScheme, + TConfig const & /*config*/) +{ + return impl::doWaveAlignment(execPolicy, + GlobalAlignment_::Type>{}, + setH, + setV, + scoringScheme); +} + +// Wavefront execution of globalAlignmentScore w/o config. +template , Serial>::value && + !std::is_same, Parallel>::value, + int> = 0> + +inline auto +globalAlignmentScore(ExecutionPolicy, TVectorizationPolicy> const & execPolicy, + TSetH const & setH, + TSetV const & setV, + TScore const & scoringScheme) +{ + return globalAlignmentScore(execPolicy, setH, setV, scoringScheme, AlignConfig<>{}); +} + +template , Serial>::value && + !std::is_same, Parallel>::value, + int> = 0> +inline auto +localAlignmentScore(ExecutionPolicy, TVectorizationPolicy> const & execPolicy, + TArgs && ...args) +{ + return impl::doWaveAlignment(execPolicy, LocalAlignment_<>{}, std::forward(args)...); +} + +} // namespace seqan + +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_alignment_executor.h b/porechop/include/seqan/align_parallel/wavefront_alignment_executor.h new file mode 100644 index 0000000..00db124 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_alignment_executor.h @@ -0,0 +1,98 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Executor class for an alignment task in the wave-front model. +// Stores the scheduler and the thread local storage. +template +struct WavefrontAlignmentExecutor +{ + // Shared data in parallel context. + TScheduler * ptrTaskScheduler{nullptr}; + TThreadLocalStore * ptrThreadLocal{nullptr}; + + //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type. + WavefrontAlignmentExecutor() = default; + + WavefrontAlignmentExecutor(TScheduler * _ptrScheduler, + TThreadLocalStore * _ptrTls) : + ptrTaskScheduler{_ptrScheduler}, + ptrThreadLocal(_ptrTls) + {} +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +// Asynchronosly schedule a new alignment job. +template +inline void +spawn(WavefrontAlignmentExecutor & executor, + TTaskExecutor && taskExec) +{ + SEQAN_ASSERT(executor.ptrTaskScheduler != nullptr); + scheduleTask(*executor.ptrTaskScheduler, std::forward(taskExec)); +} + +// Access thread local storage. +template +inline auto & +local(WavefrontAlignmentExecutor & executor) +{ + SEQAN_ASSERT(executor.ptrThreadLocal != nullptr); + return local(*executor.ptrThreadLocal); +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_alignment_result.h b/porechop/include/seqan/align_parallel/wavefront_alignment_result.h new file mode 100644 index 0000000..e2e7900 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_alignment_result.h @@ -0,0 +1,165 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// The intermediate result stored by each thread independently. +// After an alignment has been finished, the intermediate results are reduced to a global result. +template +struct WavefrontAlignmentResult +{ + // ---------------------------------------------------------------------------- + // Member Types. + + using TState = std::pair; + + // ---------------------------------------------------------------------------- + // Member Variables + + TState _maxState{std::numeric_limits::min(), typename TTraits::THostPosition{}}; + size_t _tileCol{0}; + size_t _tileRow{0}; + + //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type. + // ---------------------------------------------------------------------------- + // Constructors. + + // Note: Although, this could be an aggregate type, the icpc-17 crashes, + // when compiling without the defaulted constructor. + WavefrontAlignmentResult() = default; + + WavefrontAlignmentResult(TState const maxState) : + _maxState(std::move(maxState)) + {} + + WavefrontAlignmentResult(TState const maxState, size_t const tileCol, size_t const tileRow) : + _maxState(std::move(maxState)), + _tileCol(tileCol), + _tileRow(tileRow) + {} + + // ---------------------------------------------------------------------------- + // Member Functions. +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +namespace impl +{ + +template +inline void +updateMax(TIntermediate & me, + TState const & state, + size_t const tileCol, + size_t const tileRow) +{ + if (state.first > me._maxState.first) + { + me._maxState = state; + me._tileCol = tileCol; + me._tileRow = tileRow; + } +} +} // namespace impl + +// Update the intermediate result if new optimum has been found. +template +inline void +updateMax(WavefrontAlignmentResult & me, + typename WavefrontAlignmentResult::TState const & state, + size_t const tileCol, + size_t const tileRow) +{ + impl::updateMax(me, state, tileCol, tileRow); +} + +template +inline void +updateMax(WavefrontAlignmentResult & lhs, + WavefrontAlignmentResult const & rhs) +{ + impl::updateMax(lhs, rhs._maxState, rhs._tileCol, rhs._tileRow); +} + +// Reset the intermediate result. +template +inline void +clear(WavefrontAlignmentResult & me) +{ + me = WavefrontAlignmentResult{}; +} + +// Get the intermediate result. +template +inline typename WavefrontAlignmentResult::TState const & +value(WavefrontAlignmentResult const & me) +{ + return me._maxState; +} + +// Swap two intermediate results. +template +inline void +swap(WavefrontAlignmentResult & lhs, + WavefrontAlignmentResult & rhs) +{ + // TODO (rrahn): report issue with Intel + WavefrontAlignmentResult tmp = std::move(lhs); + lhs = std::move(rhs); + rhs = std::move(tmp); +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_alignment_scheduler.h b/porechop/include/seqan/align_parallel/wavefront_alignment_scheduler.h new file mode 100644 index 0000000..b7cb246 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_alignment_scheduler.h @@ -0,0 +1,347 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Yet internal class. Might need some redesign to make it truly generic. +/* + * @class WavefrontAlignmentScheduler + * @headerfile + * @brief A generic scheduler allowing to execute callables with a ring buffer for the stored tasks. + * + * @signature class WavefrontAlignmentScheduler; + * + * This schedule is at the moment only used for the wave-front alignment execution but could be generalized later. + * It stores all scheduled callables in a @link ConcurrentSuspendableQueue @endlink which can hold a user defined + * number of callables at the same time. It then uses recycable ids to fill up the queue with waiting jobs. + * If the queue is full and a thread tries to add a new job, it will be suspended, until resources are freed by + * the scheduler. + */ +class WavefrontAlignmentScheduler +{ +public: + + //------------------------------------------------------------------------- + // Member Types. + + using TCallable = std::function; + using TAlignmentQueue = ConcurrentQueue>; + using TRecycleList = std::list; + + //------------------------------------------------------------------------- + // Private Member Variables. + + WavefrontTaskScheduler _taskScheduler; + ThreadPool _pool; + TRecycleList _recycableIds; + TAlignmentQueue _queue; + bool _receivedEndSignal; + + std::mutex _mutexRecycleId; + unsigned _numParallelAlignments; + + std::mutex _mutexPushException; + std::vector _exceptionPointers; + + std::atomic _isValid{true}; + + std::function job = [this] () + { + while (true) + { + TCallable callable; + if (!popFront(callable, _queue)) + break; // End of thread => No writers and queue is empty. + + uint16_t id = -1; + + { // Receive id. + std::lock_guard lck(_mutexRecycleId); + SEQAN_ASSERT_NOT(_recycableIds.empty()); + id = _recycableIds.front(); + _recycableIds.pop_front(); + } + + try + { + callable(id); // invokes the alignment with assigned id. + } + catch (...) + { // Catch any exception thrown by callable. Store exception, and set *this invalid. + // We still keep running until the queue is empty. The thread is cleaned either by, + // explicit wait or by destruction of *this. + _isValid.store(false, std::memory_order_release); + { + std::lock_guard lck(_mutexPushException); + _exceptionPointers.push_back(std::current_exception()); + } + } + + // Check if task scheduler is still valid. + // If not, something went wrong, and we should not continue adding new tasks. + // So we propagate the invalid state to *this and break exceution chain. + if (!isValid(_taskScheduler)) + { + _isValid.store(false, std::memory_order_release); + } + + { // recycle id, when done. + std::lock_guard lck(_mutexRecycleId); + _recycableIds.push_back(id); + } + } + unlockReading(_queue); // Notify that this reader is finished. + unlockWriting(_taskScheduler); // Notify that this writer is finished. + }; + + //------------------------------------------------------------------------- + // Constructors. + + // implicitly deleted default constructor. + + WavefrontAlignmentScheduler(size_t const numParallelAlignments, size_t const numParallelTasks) : + _taskScheduler(numParallelTasks), + _queue(numParallelAlignments), + _receivedEndSignal(false), + _numParallelAlignments(numParallelAlignments) + { + SEQAN_ASSERT_GT(numParallelAlignments, 0u); // Bad if reader is 0. + + // Setup recycable ids. + _recycableIds.resize(numParallelAlignments); + std::iota(std::begin(_recycableIds), std::end(_recycableIds), 0); + + setReaderWriterCount(_queue, numParallelAlignments, 1); + + _exceptionPointers.resize(numParallelAlignments, nullptr); + + try + { // Create the threads here, later we can try to make lazy thread creation. + for (unsigned i = 0; i < numParallelAlignments; ++i) + { + spawn(_pool, job); + } + } + catch (...) // Make sure all the spawned threads are safely stopped before re-throwing the exception. + { + unlockWriting(_queue); + waitForWriters(_taskScheduler); + join(_pool); + throw; + } + + setWriterCount(_taskScheduler, numParallelAlignments); + // Notify task scheduler, that everything was setup correctly. + for (unsigned i = 0; i < numParallelAlignments; ++i) + { + lockWriting(_taskScheduler); + } + waitForWriters(_taskScheduler); // Invoke task scheduler. + } + + // Default constructor. + WavefrontAlignmentScheduler() : WavefrontAlignmentScheduler(16, 8) + {} + + // Copy & Move C'tor + WavefrontAlignmentScheduler(WavefrontAlignmentScheduler const &) = delete; + WavefrontAlignmentScheduler(WavefrontAlignmentScheduler &&) = delete; + + ///------------------------------------------------------------------------- + // Destructor. + + ~WavefrontAlignmentScheduler() + { + // Signal that no more alignments will be added. + if (!_receivedEndSignal) + unlockWriting(_queue); + + SEQAN_ASSERT(_queue.writerCount == 0); + + // Wait until all remaining threads are finished with their execution. + join(_pool); + + // In destructor of thread pool we wait for the outstanding alignments to be finished + // and then continue destruction of the remaining members and cleaning up the stack. + } + + // ------------------------------------------------------------------------ + // Member Functions. + + // Copy & Move assignment + WavefrontAlignmentScheduler& operator=(WavefrontAlignmentScheduler const &) = delete; + WavefrontAlignmentScheduler& operator=(WavefrontAlignmentScheduler &&) = delete; +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +template<> +struct SchedulerTraits +{ + using TTask = typename WavefrontAlignmentScheduler::TCallable; +}; + +// ============================================================================ +// Functions +// ============================================================================ + +/* + * @fn WavefrontAlignmentScheduler#isValid + * @headerfile + * @brief Checks if scheduler is in a valid state. This means that no callable has terminated with an exception. + */ +inline bool +isValid(WavefrontAlignmentScheduler const & me) +{ + return me._isValid.load(std::memory_order_acquire); +} + +/* + * @fn WavefrontAlignmentScheduler#scheduleTask + * @headerfile + * @brief Adds a new task to the scheduler. Suspends until resources become available. + * @throws ExceptionType? + */ +// basic exception-safety guarantee. +// Throws if appendValue failed. +inline void +scheduleTask(WavefrontAlignmentScheduler & me, + typename SchedulerTraits::TTask && callable) +{ + if (!isValid(me)) + throw std::runtime_error("Invalid alignment scheduler!"); + + // Spins until there is enough space to add to the queue. + if (!appendValue(me._queue, std::forward(callable))) + throw std::runtime_error("Invalid alignment scheduler 2!"); +} + +inline void +scheduleTask(WavefrontAlignmentScheduler & me, + typename SchedulerTraits::TTask & callable) +{ + if (!isValid(me)) + throw std::runtime_error("Invalid alignment scheduler!"); + // Spins until there is enough space to add to the queue. + if(!appendValue(me._queue, callable)) + throw std::runtime_error("Invalid alignment scheduler 2!"); +} + +/* + * @fn WavefrontAlignmentScheduler#notify + * @headerfile + * @brief Notify the scheduler that no more jobs will follow. + */ +inline void +notify(WavefrontAlignmentScheduler & me) +{ + unlockWriting(me._queue); + me._receivedEndSignal = true; +} + +/* + * @fn WavefrontAlignmentScheduler#wait + * @headerfile + * @brief Explicit barrier on the scheduler. Suspends until all scheduled jobs have been finsihed. + * + * Note, can dead lock if notify is never called. + */ +// Only possible if some other thread is signaling the end of it. +inline void +wait(WavefrontAlignmentScheduler & me) +{ + join(me._pool); + wait(me._taskScheduler); +} + +/* + * @fn WavefrontAlignmentScheduler#wait2 + * @headerfile + * @brief Explicit barrier on the scheduler. Suspends until all scheduled jobs have been finsihed. + * + * Note, can dead lock if notify is never called. + */ +template +inline void +wait2(WavefrontAlignmentScheduler & me, TNotifiable & notifiable) +{ + join(me._pool); + notify(notifiable); + wait(me._taskScheduler); +} + +/* + * @fn WavefrontAlignmentScheduler#getExceptions + * @headerfile + * @brief Returns vector of captured exceptions if any was thrown by the callable. + * + * Note, can dead lock if notify is never called. + */ +inline auto +getExceptions(WavefrontAlignmentScheduler & me) +{ + auto vec = me._exceptionPointers; + auto innerExceptions = getExceptions(me._taskScheduler); + std::copy(std::begin(innerExceptions), std::end(innerExceptions), std::back_inserter(vec)); + return vec; +} + +/* + * @fn WavefrontAlignmentScheduler#taskScheduler + * @headerfile + * @brief Returns lvalue reference to the underlying task_scheduler. + */ +inline auto& +taskScheduler(WavefrontAlignmentScheduler & me) +{ + return me._taskScheduler; +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_alignment_task.h b/porechop/include/seqan/align_parallel/wavefront_alignment_task.h new file mode 100644 index 0000000..0334103 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_alignment_task.h @@ -0,0 +1,404 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_ + +namespace seqan +{ +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Config structre for the execution of one alignment using the wave-front model. +template +struct WavefrontAlignmentTaskConfig +{ + // ---------------------------------------------------------------------------- + // Member Typedefs. + + // DPTrait type forwarding. + using TDPTraits = typename TDPSettings::TTraits; + using TScoreValue = typename Value::Type; + using TAlgorithmType = typename TDPTraits::TAlgorithmType; + using TTracebackType = typename TDPTraits::TTracebackType; + using TGapType = typename TDPTraits::TGapType; + + // Wavefront Alignment Context. + using TDPCell = DPCell_; + using TBufferValue = Pair::Type>; + using TBuffer = String; + using TBlockBuffer = DPTileBuffer; + + // DP Execution Context. + using TDPProfile = DPProfile_; + using TDPCache = DPContext::Type>; + using TDPScout = DPScout_; + + // Parallel Context. + struct IntermediateTraits_ + { + using TScoreValue = decltype(maxScore(std::declval())); + using THostPosition = decltype(maxHostPosition(std::declval())); + }; + + using TDPIntermediate = WavefrontAlignmentResult; + + struct AlignThreadLocalConfig_ + { + using TIntermediate = TDPIntermediate; + using TCache = TDPCache; + + using TLocalHost = std::tuple; + }; + + using TThreadLocal = WavefrontAlignmentThreadLocalStorage; + using TAlignEvent = WavefrontTaskEvent; +}; + +#ifdef SEQAN_SIMD_ENABLED +template +struct WavefrontAlignmentSimdTaskConfig : public WavefrontAlignmentTaskConfig +{ + // ---------------------------------------------------------------------------- + // Member Typedefs. + + using TBase_ = WavefrontAlignmentTaskConfig; + + using TDPSimdCell = DPCell_; + using TDPSimdTraceValue = typename TraceBitMap_::Type; + + using TDPSimdScoreMatrix = String>; + using TDPSimdTraceMatrix = String>; + using TDPSimdCache = DPContext; + + using TDPScout_ = DPScout_ >; + using TDPIntermediate = WavefrontAlignmentResult; + + // Parallel Context. + struct SimdAlignThreadLocalConfig_ + { + + using TIntermediate = TDPIntermediate; + using TCache = typename TBase_::TDPCache; + using TSimdCache = TDPSimdCache; + + using TLocalHost = std::tuple; + }; + + using TThreadLocal = WavefrontAlignmentThreadLocalStorage; + using TAlignEvent = WavefrontTaskEvent; +}; +#endif + +// Incubator to setup the alignment job. +template +struct WavefrontAlignmentTaskIncubator +{ + using TWatc = WavefrontAlignmentTaskConfigConcept; + + // ---------------------------------------------------------------------------- + // Function createBlocks() + // ---------------------------------------------------------------------------- + + template + static auto createBlocks(TSeq const & seq, size_t const blockSize) + { + using TIter = typename Iterator::Type, Standard>::Type; + String> blocks; + resize(blocks, (length(seq) + blockSize - 1) / blockSize, Exact()); + + for (unsigned id = 0; id < length(blocks); ++id) + blocks[id] = toRange(infix(seq, id * blockSize, _min(length(seq),(id + 1) * blockSize))); + return blocks; + } + + // ---------------------------------------------------------------------------- + // Function createBlockBuffer() + // ---------------------------------------------------------------------------- + + template + static auto createBlockBuffer(TSeqHBlocks const & seqHBlocks, TSeqVBlovcks const & seqVBlocks, TScore const & score) + { + using TDPCell = typename TWatc::TDPCell; + typename TWatc::TBlockBuffer buffer; + resize(buffer.horizontalBuffer, length(seqHBlocks), Exact()); + resize(buffer.verticalBuffer, length(seqVBlocks), Exact()); + + typename TWatc::TBufferValue tmp; + + using TDPMetaColH = DPMetaColumn_>; + using TDPMetaColV = DPMetaColumn_>; + + TDPCell dummyCellD; + TDPCell dummyCellH; + TDPCell dummyCellV; + tmp.i2 = _computeScore(tmp.i1, dummyCellD, dummyCellH, dummyCellV, Nothing(), Nothing(), score, + RecursionDirectionZero(), typename TWatc::TDPProfile()); + for (auto itH = begin(buffer.horizontalBuffer, Standard()); + itH != end(buffer.horizontalBuffer, Standard()); + ++itH) + { + resize(*itH, length(front(seqHBlocks)), Exact()); + for (auto it = begin(*itH, Standard()); it != end(*itH, Standard()); ++it) + { + it->i2 = _computeScore(it->i1, dummyCellD, tmp.i1, dummyCellV, Nothing(), Nothing(), score, + typename RecursionDirection_::Type(), + typename TWatc::TDPProfile()); + tmp.i1 = it->i1; + } + } + tmp.i1 = decltype(tmp.i1){}; + tmp.i2 = _computeScore(tmp.i1, dummyCellD, dummyCellH, dummyCellV, Nothing(), Nothing(), score, + RecursionDirectionZero(), typename TWatc::TDPProfile()); + + for (auto itV = begin(buffer.verticalBuffer, Standard()); itV != end(buffer.verticalBuffer, Standard()); ++itV) + { + resize(*itV, length(front(seqVBlocks)) + 1, Exact()); + auto it = begin(*itV, Standard()); + it->i2 = tmp.i2; + it->i1 = tmp.i1; + ++it; + for (; it != end(*itV, Standard()); ++it) + { + it->i2 = _computeScore(it->i1, dummyCellD, dummyCellH, dummyCellV, Nothing(), Nothing(), score, + typename RecursionDirection_::Type(), + typename TWatc::TDPProfile()); + _setVerticalScoreOfCell(it->i1, _verticalScoreOfCell(dummyCellV)); + tmp.i1 = it->i1; + tmp.i2 = it->i2; // TODO(rrahn): Move out of loop. + } + } + return buffer; + } + + // ---------------------------------------------------------------------------- + // Function createTaskGraph() + // ---------------------------------------------------------------------------- + + template + static auto createTaskGraph(TWavefrontTaskContext & taskContext) + { + using TDagTask = WavefrontTask; + + std::vector>> graph; + + resize(graph, length(taskContext.seqHBlocks)); + for (int i = length(taskContext.seqHBlocks); --i >= 0;) + { + resize(graph[i], length(taskContext.seqVBlocks)); + for (int j = length(taskContext.seqVBlocks); --j >= 0;) + { + using TSize = decltype(length(taskContext.seqHBlocks)); + TDagTask * successorRight = (static_cast(i + 1) < length(taskContext.seqHBlocks)) + ? graph[i+1][j].get() + : nullptr; + TDagTask * successorDown = (static_cast(j + 1) < length(taskContext.seqVBlocks)) + ? graph[i][j+1].get() + : nullptr; + graph[i][j] = std::make_shared(taskContext, + std::array{{successorRight, successorDown}}, + static_cast(i), static_cast(j), + static_cast(((i > 0) ? 1 : 0) + ((j > 0) ? 1 : 0)), + (static_cast(i + 1) == length(taskContext.seqHBlocks)), + (static_cast(j + 1) == length(taskContext.seqVBlocks))); + } + } + return graph; + } +}; + +// The actual alignment task that is executed by the wave-front model. +template > +class WavefrontAlignmentTask +{ +public: + + using TIncubator = WavefrontAlignmentTaskIncubator; + + using TSeqHBlocks = decltype(TIncubator::createBlocks(std::declval(), std::declval())); + using TSeqVBlocks = decltype(TIncubator::createBlocks(std::declval(), std::declval())); + using TTileBuffer = decltype(TIncubator::createBlockBuffer(std::declval(), + std::declval(), + std::declval())); + + using TTaskContext = WavefrontAlignmentContext; + + // ---------------------------------------------------------------------------- + // Member Variables. + // ---------------------------------------------------------------------------- + + size_t alignmentId{0}; + TSeqH const & seqH; + TSeqV const & seqV; + TDPSettings const & dpSettings; + size_t blockSize; + + // ---------------------------------------------------------------------------- + // Constructors. + // ---------------------------------------------------------------------------- + + WavefrontAlignmentTask() = delete; + + WavefrontAlignmentTask(TSeqH const & seqH, + TSeqV const & seqV, + TDPSettings const & dpSetting, + size_t const & blockSize) : + seqH(seqH), + seqV(seqV), + dpSettings(dpSetting), + blockSize(blockSize) + {} + + + WavefrontAlignmentTask(size_t const id, + TSeqH const & seqH, + TSeqV const & seqV, + TDPSettings const & dpSetting, + size_t const & blockSize) : + alignmentId(id), + seqH(seqH), + seqV(seqV), + dpSettings(dpSetting), + blockSize(blockSize) + {} + + // ---------------------------------------------------------------------------- + // Member Functions. + // ---------------------------------------------------------------------------- + + // This function now run's in a separate thread. + template + inline void + operator()(uint16_t const instanceId, + TWavefrontExecutor & executor, + TCallback && callback) + { + // Initialize the strings. + auto seqHBlocks = TIncubator::createBlocks(seqH, blockSize); + auto seqVBlocks = TIncubator::createBlocks(seqV, blockSize); + + // Create the buffer for the matrix. + auto buffer = TIncubator::createBlockBuffer(seqHBlocks, seqVBlocks, dpSettings.scoringScheme); + + // Setup the task context and create task graph. + TTaskContext taskContext{instanceId, seqHBlocks, seqVBlocks, buffer, dpSettings}; + auto taskGraph = TIncubator::createTaskGraph(taskContext); + + // Prepare event. + WavefrontTaskEvent event; + context(*taskGraph.back().back()).ptrEvent = &event; + + // Kick off the execution. + using TWavefrontTaskExec = WavefrontTaskExecutor, TWavefrontExecutor>; + spawn(executor, TWavefrontTaskExec{taskGraph[0][0].get(), &executor}); + + // Wait for alignment to finish. + wait(event); + + // Reduce. + typename TConfig::TDPIntermediate interMax{}; + auto collectAndReset = [&](auto & threadLocalStorage) + { + updateMax(interMax, intermediate(threadLocalStorage, instanceId)); + clear(intermediate(threadLocalStorage, instanceId)); + }; + combineEach(*executor.ptrThreadLocal, collectAndReset); + // Continue execution. + callback(alignmentId, interMax._maxState.first); + } + + template + inline void + operator()(uint16_t const instanceId, + TWavefrontExecutor & executor, + TSimdTaskQueue & taskQueue, + TCallback && callback) + { + // Initialize the strings. + auto seqHBlocks = TIncubator::createBlocks(seqH, blockSize); + auto seqVBlocks = TIncubator::createBlocks(seqV, blockSize); + + // Create the buffer for the matrix. + auto buffer = TIncubator::createBlockBuffer(seqHBlocks, seqVBlocks, dpSettings.scoringScheme); + + // Setup the task context and create task graph. + TTaskContext taskContext{instanceId, seqHBlocks, seqVBlocks, buffer, dpSettings}; + auto taskGraph = TIncubator::createTaskGraph(taskContext); + + // Prepare event. + WavefrontTaskEvent event; + context(*taskGraph.back().back()).ptrEvent = &event; + + // Kick off the execution. + using TWavefrontTaskExec = WavefrontTaskExecutor; + appendValue(taskQueue, *taskGraph[0][0]); + spawn(executor, TWavefrontTaskExec{&taskQueue, &executor}); + + // Wait for alignment to finish. + wait(event); + + // Reduce. + typename TConfig::TDPIntermediate interMax{}; + auto collectAndReset = [&](auto & threadLocalStorage) + { + updateMax(interMax, intermediate(threadLocalStorage, instanceId)); + clear(intermediate(threadLocalStorage, instanceId)); + }; + combineEach(*executor.ptrThreadLocal, collectAndReset); + callback(alignmentId, interMax._maxState.first); + } +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h b/porechop/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h new file mode 100644 index 0000000..42f6aa2 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h @@ -0,0 +1,130 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_ +#define SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Shared thread local storage for the parallel alignment instances. +template +class WavefrontAlignmentThreadLocalStorage +{ +public: + //------------------------------------------------------------------------- + // Member Types. + + using TAlignmentLocal = typename TConfig::TLocalHost; + + //------------------------------------------------------------------------- + // Private Members. + + std::vector _multiAlignmentThreadLocal; + + //------------------------------------------------------------------------- + // Constructor. + + explicit WavefrontAlignmentThreadLocalStorage(size_t const numAlignments) : + _multiAlignmentThreadLocal(numAlignments) + {} + + // Delegating default constructor. + WavefrontAlignmentThreadLocalStorage() : WavefrontAlignmentThreadLocalStorage(1) + {} + + WavefrontAlignmentThreadLocalStorage(WavefrontAlignmentThreadLocalStorage const &) = default; + WavefrontAlignmentThreadLocalStorage(WavefrontAlignmentThreadLocalStorage &&) = default; + + //------------------------------------------------------------------------- + // Destructor. + + ~WavefrontAlignmentThreadLocalStorage() = default; + + //------------------------------------------------------------------------- + // Member Functions. + + WavefrontAlignmentThreadLocalStorage& operator=(WavefrontAlignmentThreadLocalStorage const &) = default; + WavefrontAlignmentThreadLocalStorage& operator=(WavefrontAlignmentThreadLocalStorage &&) = default; +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +// Gets the intermediate result for the specific alignment job. +template +inline typename TConfig::TIntermediate & +intermediate(WavefrontAlignmentThreadLocalStorage & me, + size_t const alignId) +{ + SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size()); + return std::get(me._multiAlignmentThreadLocal[alignId]); +} + +// Gets the chache for the specific alignment job. +template +inline typename TConfig::TCache & +cache(WavefrontAlignmentThreadLocalStorage & me, + size_t const alignId) +{ + SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size()); + return std::get(me._multiAlignmentThreadLocal[alignId]); +} + +// Gets the simd chache for the specific alignment job. +template +inline typename TConfig::TSimdCache & +simdCache(WavefrontAlignmentThreadLocalStorage & me, + size_t const alignId) +{ + SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size()); + return std::get(me._multiAlignmentThreadLocal[alignId]); +} + +} // namespace seqan + +#endif // SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task.h b/porechop/include/seqan/align_parallel/wavefront_task.h new file mode 100644 index 0000000..b9bd8a4 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task.h @@ -0,0 +1,365 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_ + +namespace seqan +{ +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Context used per task. Access information like the infixes of the sequences for this block and other. +template +struct WavefrontAlignmentContext +{ + size_t alignmentId{0}; + TSeqHBlocks const & seqHBlocks; + TSeqVBlocks const & seqVBlocks; + TTileBuffer & tileBuffer; + TDPSettings const & dpSettings; + TEvent * ptrEvent{nullptr}; + + //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type. + WavefrontAlignmentContext(size_t const _alignmentId, + TSeqHBlocks const & _seqHBlocks, + TSeqVBlocks const & _seqVBlocks, + TTileBuffer & _tileBuffer, + TDPSettings const & _dpSettings) : + alignmentId(_alignmentId), + seqHBlocks(_seqHBlocks), + seqVBlocks(_seqVBlocks), + tileBuffer(_tileBuffer), + dpSettings(_dpSettings) + {} +}; + +// The abstract task that is executed as separat alignment instance. +template +class WavefrontTask +{ +public: + + using TContext = TAlignmentContext; + + TContext & context; + std::array successor{{nullptr, nullptr}}; + size_t col{0}; + size_t row{0}; + std::atomic refCount{0}; + bool lastTileH{false}; + bool lastTileV{false}; + + + //------------------------------------------------------------------------- + // Constructor + WavefrontTask() = delete; + + WavefrontTask(TContext & context, std::array successor, + size_t const col, + size_t const row, + size_t const refCount, + bool const lastTileH, + bool const lastTileV) : + context(context), + successor(std::move(successor)), + col(col), row(row), + refCount(refCount), + lastTileH(lastTileH), lastTileV(lastTileV) + {} +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +template +struct TaskExecutionTraits; + +template +struct TaskExecutionTraits> +{ + using TaskContext_ = WavefrontAlignmentContext; + + using TSeqHBlocks = typename std::decay().seqHBlocks)>::type; + using TSeqVBlocks = typename std::decay().seqVBlocks)>::type; + using TWavefrontBuffer = typename std::decay().tileBuffer)>::type; + using TDPSettings = typename std::decay().dpSettings)>::type; + + using TTileBuffer = typename std::decay().horizontalBuffer[0])>::type; + using TDPScoutState = DPScoutState_>; + + // Sequence types. + using TSeqH = typename Value::Type; + using TSeqV = typename Value::Type; + + // DPTrait type forwarding. + using TDPTraits = typename TDPSettings::TTraits; + using TScoreValue = typename Value::Type; + using TAlgorithmType = typename TDPTraits::TAlgorithmType; + using TTracebackType = typename TDPTraits::TTracebackType; + using TGapType = typename TDPTraits::TGapType; + + // Wavefront Alignment Context. + using TDPCell = DPCell_; + + using TScoutSpec = typename ScoutSpecForAlignmentAlgorithm_::Type; + using TDPScout = DPScout_; +}; + +template +struct SimdTaskExecutionTraits : public TaskExecutionTraits +{ + using TBase = TaskExecutionTraits; + + using TScoreValue = typename TBase::TDPSettings::TScoreValueSimd; + using TDPCell = DPCell_; + using TTraceValue = typename TraceBitMap_::Type; + using TBufferValue = Pair; +}; + +// ============================================================================ +// Functions +// ============================================================================ + +template +inline void +setRefCount(WavefrontTask & me, size_t const count) +{ + me.refCount.store(count, std::memory_order_relaxed); +} + +template +inline unsigned +decrementRefCount(WavefrontTask & me) +{ + return --me.refCount; +} + +template +inline unsigned +incrementRefCount(WavefrontTask & me) +{ + return ++me.refCount; +} + +template +inline auto +column(TTask const & task) -> decltype(task.col) +{ + return task.col; +} + +template +inline auto +row(TTask const & task) -> decltype(task.row) +{ + return task.row; +} + +template +inline bool +inLastColumn(TTask const & task) +{ + return task.lastTileH; +} + +template +inline bool +inLastRow(TTask const & task) +{ + return task.lastTileV; +} + +template +inline bool +isLastTask(TTask const & task) +{ + return inLastColumn(task) && inLastRow(task); +} + +template +inline auto +successor(TTask & task) -> std::add_lvalue_reference_t +{ + return task.successor; +} + +template +inline auto +successor(TTask const & task) -> std::add_lvalue_reference_t> +{ + return task.successor; +} + +template +inline auto +context(TTask & task) -> std::add_lvalue_reference_t +{ + return task.context; +} + +template +inline auto +context(TTask const & task) -> std::add_lvalue_reference_t> +{ + return task.context; +} + +template +inline bool +isTrackTile(TTask const & task) +{ + return isLastColumn(task) && isLastRow(task); +} + +template +inline bool +isTrackTile(TTask const & task) +{ + return isLastColumn(task) && isLastRow(task); +} + +template +inline void +executeScalar(TTask & task, TDPLocalData & dpLocal) +{ + using TExecTraits = TaskExecutionTraits; + + auto & taskContext = context(task); + // Load the cache from the local data. + auto & dpCache = cache(dpLocal, taskContext.alignmentId); + auto & buffer = taskContext.tileBuffer; + + // Capture the buffer. + typename TExecTraits::TDPScoutState scoutState(buffer.horizontalBuffer[column(task)], + buffer.verticalBuffer[row(task)]); // Task local + + typename TExecTraits::TDPScout scout(scoutState); + + impl::computeTile(dpCache, scout, + taskContext.seqHBlocks[column(task)], + taskContext.seqVBlocks[row(task)], + taskContext.dpSettings.scoringScheme, + taskContext.dpSettings); + // We want to get the state here from the scout. + if(impl::AlgorithmProperty::isTrackingEnabled(task)) + { + // TODO(rrahn): Implement the interface. + // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here + updateMax(intermediate(dpLocal, taskContext.alignmentId), + {maxScore(scout), maxHostPosition(scout)}, + column(task), + row(task)); + } +} + +template +inline void +printSimdBuffer(TBuffer const & buffer, size_t const l) +{ + for (auto simdHolder : buffer) + { + std::cout << "<"; + unsigned i = 0; + for (; i < l - 1; ++i) + { + std::cout << simdHolder.i1._score[i] << ", "; + } + std::cout << simdHolder.i1._score[i] << ">\n"; + } +} + +#ifdef SEQAN_SIMD_ENABLED +template +inline void +executeSimd(TTasks & tasks, TDPLocalData & dpLocal) +{ + using TTask = typename std::remove_pointer::Type>::type; + using TExecTraits = SimdTaskExecutionTraits; + + auto offset = impl::computeOffset(tasks, TExecTraits{}); + // Has to be adapted to take the correct buffer from the corresponding task. + auto simdBufferH = impl::gatherSimdBuffer(tasks, + [] (auto & task) + { + return &context(task).tileBuffer.horizontalBuffer[column(task)]; + }, + offset, + TExecTraits{}); + auto simdBufferV = impl::gatherSimdBuffer(tasks, + [] (auto & task) + { + return &context(task).tileBuffer.verticalBuffer[row(task)]; + }, + offset, + TExecTraits{}); + + // Does not really make sense. + auto & cache = simdCache(dpLocal, 0); + // Run alignment. + impl::computeSimdBatch(cache, simdBufferH, simdBufferV, tasks, dpLocal, offset, TExecTraits{}); + + // Write back into buffer. + impl::scatterSimdBuffer(tasks, + simdBufferH, + [](auto & task) + { + return &context(task).tileBuffer.horizontalBuffer[column(task)]; + }, + offset, + TExecTraits{}); + impl::scatterSimdBuffer(tasks, + simdBufferV, + [](auto & task) + { + return &context(task).tileBuffer.verticalBuffer[row(task)]; + }, + offset, + TExecTraits{}); +} +#endif // SEQAN_SIMD_ENABLED + +} // namespace seqan + +#endif // INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task_event.h b/porechop/include/seqan/align_parallel/wavefront_task_event.h new file mode 100644 index 0000000..ccd18dc --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task_event.h @@ -0,0 +1,104 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Event to signal end of one alignment instance. +class WavefrontTaskEvent +{ +public: + std::mutex mutexLastTask{}; + std::condition_variable conditionLastTask{}; + bool readyLastTask{false}; + + WavefrontTaskEvent() = default; + + WavefrontTaskEvent(WavefrontTaskEvent const &) = delete; + WavefrontTaskEvent(WavefrontTaskEvent &&) = delete; + + WavefrontTaskEvent& operator=(WavefrontTaskEvent const &) = delete; + WavefrontTaskEvent& operator=(WavefrontTaskEvent &&) = delete; + + ~WavefrontTaskEvent() + { + if (!readyLastTask) + { + { + std::lock_guard lck(mutexLastTask); + readyLastTask = true; + } + conditionLastTask.notify_one(); + } + } +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +inline void +notify(WavefrontTaskEvent & event) +{ + std::lock_guard lck(event.mutexLastTask); + event.readyLastTask = true; + event.conditionLastTask.notify_one(); // We require a strict synchronization between waiting and notifying thread. +} + +inline void +wait(WavefrontTaskEvent & event) +{ + std::unique_lock lck(event.mutexLastTask); + if (!event.readyLastTask) + event.conditionLastTask.wait(lck, [&] { return event.readyLastTask; }); +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task_executor.h b/porechop/include/seqan/align_parallel/wavefront_task_executor.h new file mode 100644 index 0000000..ab0f933 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task_executor.h @@ -0,0 +1,146 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +template +struct WavefrontTaskExecutionPolicy; + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Task executor. Manages the execution of single alignment blocks. +template +struct WavefrontTaskExecutor +{ + TResource* _ptrResource{nullptr}; + TWavefrontExecutor * _ptrWavefrontExecutor{nullptr}; + + //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type. + WavefrontTaskExecutor() = default; + + WavefrontTaskExecutor(TResource * _resource, + TWavefrontExecutor * _wavefrontExecutor) : + _ptrResource{_resource}, + _ptrWavefrontExecutor(_wavefrontExecutor) + {} + + inline void operator()() + { + WavefrontTaskExecutionPolicy::execute(*_ptrResource, *_ptrWavefrontExecutor); + } +}; + +// Policy for no SIMD execution. +template +struct WavefrontTaskExecutionPolicy> +{ + + template + inline static void + execute(TResource & task, TWavefrontExecutor & wavefrontExec) + { + using TWaveTaskExec = WavefrontTaskExecutor; + + executeScalar(task, local(wavefrontExec)); + for (auto succ : successor(task)) + { + if (succ && decrementRefCount(*succ) == 0) + spawn(wavefrontExec, TWaveTaskExec{succ, &wavefrontExec}); + } + if (isLastTask(task)) + { + notify(*(context(task).ptrEvent)); + } + } +}; + +// Policy for SIMD execution. +template +struct WavefrontTaskExecutionPolicy> +{ + template + inline static void + execute(TResource & resource, TWavefrontExecutor & wavefrontExec) + { + using TWaveTaskExec = WavefrontTaskExecutor; + + typename TResource::ResultType tasks; + if (!tryPopTasks(tasks, resource)) + return; + + SEQAN_ASSERT(!empty(tasks)); + if (tasks.size() == 1) + executeScalar(*front(tasks), local(wavefrontExec)); + else + executeSimd(tasks, local(wavefrontExec)); + + for (auto task : tasks) + { + for (auto succ : successor(*task)) + { + if (succ && decrementRefCount(*succ) == 0) + { + appendValue(resource, *succ); + spawn(wavefrontExec, TWaveTaskExec{&resource, &wavefrontExec}); + } + } + if (isLastTask(*task)) + { + notify(*(context(*task).ptrEvent)); + } + } + } +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task_queue.h b/porechop/include/seqan/align_parallel/wavefront_task_queue.h new file mode 100644 index 0000000..d64b61f --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task_queue.h @@ -0,0 +1,139 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Central task queue used in simd mode to gather multiple blocks to gather full simd registers. +template +class WavefrontTaskQueue +{ +public: + + + // Member Types. + using TQueue = ConcurrentQueue; + using ResultType = std::vector; + using ValueType = TValue; + + // Members. + static constexpr size_t VECTOR_SIZE{VECTOR_SIZE_}; + + TQueue queue; + std::mutex mutexPopQueue; + bool hasNotified{false}; + + // Constructors. + WavefrontTaskQueue() + { + lockWriting(queue); + lockReading(queue); + } + + WavefrontTaskQueue(WavefrontTaskQueue const&) = delete; + WavefrontTaskQueue(WavefrontTaskQueue &&) = delete; + + WavefrontTaskQueue& operator=(WavefrontTaskQueue const &) = delete; + WavefrontTaskQueue& operator=(WavefrontTaskQueue &&) = delete; + + ~WavefrontTaskQueue() + { + if (!hasNotified) + unlockWriting(queue); + unlockReading(queue); + } +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// ============================================================================ +// Functions +// ============================================================================ + +template +inline bool +tryPopTasks(typename WavefrontTaskQueue::ResultType & tasks, + WavefrontTaskQueue & me) +{ + clear(tasks); + std::lock_guard lck(me.mutexPopQueue); + if (length(me.queue) < WavefrontTaskQueue::VECTOR_SIZE) + { + resize(tasks, 1); + if (!popFront(tasks[0], me.queue, Serial())) + { + return false; + } + } + else + { + for (size_t lane = 0u; lane < VECTOR_SIZE; ++lane) + tasks.push_back(popFront(me.queue, Serial())); + } + return true; +} + +template +inline void +appendValue(WavefrontTaskQueue & me, + TValue & newTask) +{ + appendValue(me.queue, &newTask); +} + +template +inline void +notify(WavefrontTaskQueue & me) +{ + me.hasNotified = true; + unlockWriting(me.queue); +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task_scheduler.h b/porechop/include/seqan/align_parallel/wavefront_task_scheduler.h new file mode 100644 index 0000000..c246796 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task_scheduler.h @@ -0,0 +1,218 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_ + +namespace seqan +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// Scheduler for wavefront tasks. +class WavefrontTaskScheduler +{ +public: + + //------------------------------------------------------------------------- + // Memeber Types + + using TWrapper = std::function; + using TTaskQueue = ConcurrentQueue; + + //------------------------------------------------------------------------- + // Member Variables + + ThreadPool _threadPool; + TTaskQueue _taskQueue; + + unsigned _writerCount; + + std::mutex _mutexPushException; + std::vector _exceptionPointers; + std::atomic _isValid{true}; + + std::function job = [this] () + { + lockReading(_taskQueue); + waitForFirstValue(_taskQueue); // Wait for all writers to be setup. + + std::function _dummy = [] () + { // TODO(rrahn): Could throw exception to signal something went terribly wrong. + SEQAN_ASSERT_FAIL("Trying to exceute empty wavefront task in a thread"); + }; + TWrapper task{_dummy}; + + while (true) + { + if (!popFront(task, _taskQueue)) + break; // Empty queue and no writer registered. + + try + { + task(); // Execute the task; + } + catch (...) + { // Catch exception, and signal failure. Continue running until queue is empty. + { + std::lock_guard lck(_mutexPushException); + _exceptionPointers.push_back(std::current_exception()); + } + _isValid.store(false, std::memory_order_release); + } + } + unlockReading(_taskQueue); + }; + + //------------------------------------------------------------------------- + // Constructor + + WavefrontTaskScheduler(size_t const threadCount, size_t const writerCount) : + _writerCount(writerCount) + { + + for (unsigned i = 0; i < threadCount; ++i) + { + spawn(_threadPool, job); + } + setCpuAffinity(_threadPool, 0, 1); + } + + WavefrontTaskScheduler(size_t const threadCount) : WavefrontTaskScheduler(threadCount, 0) + {} + + WavefrontTaskScheduler(WavefrontTaskScheduler const &) = delete; + WavefrontTaskScheduler(WavefrontTaskScheduler &&) = delete; + + //------------------------------------------------------------------------- + // Member Functions + + WavefrontTaskScheduler& operator=(WavefrontTaskScheduler const &) = delete; + WavefrontTaskScheduler& operator=(WavefrontTaskScheduler &&) = delete; + + //------------------------------------------------------------------------- + // Destructor + + ~WavefrontTaskScheduler() + {} + // In destructor of thread pool we wait for the outstanding alignments to be finished + // and then continue destruction of the remaining members and cleaning up the stack. + // Note the number of writers must be set to 0, for the queue to stop spinning. +}; + +// ============================================================================ +// Metafunctions +// ============================================================================ + +template +struct SchedulerTraits; + +template <> +struct SchedulerTraits +{ + using TWrapper_ = typename WavefrontTaskScheduler::TWrapper; + using TTask = TWrapper_; +}; + +// ============================================================================ +// Functions +// ============================================================================ + +inline void +setWriterCount(WavefrontTaskScheduler & me, size_t const count) noexcept +{ + me._writerCount = count; +} + +inline void +lockWriting(WavefrontTaskScheduler & me) noexcept +{ + lockWriting(me._taskQueue); +} + +inline void +unlockWriting(WavefrontTaskScheduler & me) noexcept +{ + unlockWriting(me._taskQueue); +} + +inline void +waitForWriters(WavefrontTaskScheduler & me) noexcept +{ + waitForWriters(me._taskQueue, me._writerCount); +} + +inline bool +isValid(WavefrontTaskScheduler & me) noexcept +{ + return me._isValid.load(std::memory_order_acquire); +} + +inline void +scheduleTask(WavefrontTaskScheduler & me, + typename SchedulerTraits::TTask task) +{ + if (!isValid(me)) + { // TODO(rrahn): Improve error handling. + throw std::runtime_error("Invalid Task Scheduler"); + } + appendValue(me._taskQueue, std::move(task)); +} + +inline void +wait(WavefrontTaskScheduler & me) +{ + SEQAN_ASSERT(me._taskQueue.writerCount == 0); + + join(me._threadPool); + + SEQAN_ASSERT(empty(me._taskQueue)); + SEQAN_ASSERT(me._taskQueue.readerCount == 0); +} + +inline auto +getExceptions(WavefrontTaskScheduler & me) +{ + return me._exceptionPointers; +} + +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_ diff --git a/porechop/include/seqan/align_parallel/wavefront_task_util.h b/porechop/include/seqan/align_parallel/wavefront_task_util.h new file mode 100644 index 0000000..1208055 --- /dev/null +++ b/porechop/include/seqan/align_parallel/wavefront_task_util.h @@ -0,0 +1,557 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Rene Rahn +// ========================================================================== + +#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_ +#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_ + +namespace seqan +{ +namespace impl +{ + +// ============================================================================ +// Forwards +// ============================================================================ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ + +// ============================================================================ +// Metafunctions +// ============================================================================ + +// Helper meta-function to extract the correct DP Property. +template +struct AlgorithmProperty +{ + template + inline static bool + isTrackingEnabled(TTask const & tile) + { + return isLastColumn(tile) && isLastRow(tile); + } +}; + +template +struct AlgorithmProperty> +{ + template + inline static bool + isTrackingEnabled(TTask const & tile) + { + return (IsFreeEndGap_::VALUE && inLastColumn(tile)) || + (IsFreeEndGap_::VALUE && inLastRow(tile)) || + (inLastColumn(tile) && inLastRow(tile)); + } +}; + +template +struct AlgorithmProperty> +{ + template + inline static bool + isTrackingEnabled(TTask const & /*tile*/) + { + return true; + } +}; + +// ============================================================================ +// Functions +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Function computeTile() +// ---------------------------------------------------------------------------- + +// Wrapper function to call alignment core for the specific block. +template +inline void +computeTile(DPContext & dpContext, + TDPScout & scout, + TSequenceH const & seqH, + TSequenceV const & seqV, + TScoringScheme const & scoringScheme, + TDPSettings const & /*settings*/) +{ + using TDPTraits = typename TDPSettings::TTraits; + + using TScoreMatrixSpec = typename DefaultScoreMatrixSpec_::Type; + + using TDPScoreMatrix = DPMatrix_; + using TDPTraceMatrix = DPMatrix_; + + using TDPScoreMatrixNavigator = DPMatrixNavigator_; + using TDPTraceMatrixNavigator = DPMatrixNavigator_, NavigateColumnWise>; + + using TDPProfile = DPProfile_; + + // Setup the score and trace matrix. + TDPScoreMatrix dpScoreMatrix; + TDPTraceMatrix dpTraceMatrix; + + setLength(dpScoreMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1); + setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1); + + setLength(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1); + setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1); + + // Resue the buffer from the cache. + setHost(dpScoreMatrix, getDpScoreMatrix(dpContext)); + setHost(dpTraceMatrix, getDpTraceMatrix(dpContext)); + + resize(dpScoreMatrix); + // We do not need to allocate the memory for the trace matrix if the traceback is disabled. + if /*constexpr*/(IsTracebackEnabled_::VALUE) + { + static_assert(std::is_same::value, "Traceback not implemented!"); + resize(dpTraceMatrix); + } + + // Initialize the navigators. + TDPScoreMatrixNavigator dpScoreMatrixNavigator{dpScoreMatrix, DPBandConfig{}}; + TDPTraceMatrixNavigator dpTraceMatrixNavigator{dpTraceMatrix, DPBandConfig{}}; + + // Execute the alignment. + _computeAlignmentImpl(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, + scoringScheme, DPBandConfig{}, TDPProfile(), NavigateColumnWise{}); +} + +#ifdef SEQAN_SIMD_ENABLED +// Some utility functions. +template +inline auto +doComputeOffset(TTasks const &tasks, + TScoreValueScalar const & /*scalarScore*/, + TScoreValueSimd const & /*simdScore*/) +{ + String offset; + resize(offset, length(tasks), std::numeric_limits::min(), Exact()); + + size_t pos = 0; + + for (auto task : tasks) + { + offset[pos] = front(context(*task).tileBuffer.horizontalBuffer[column(*task)]).i1._score; + ++pos; + } + + return offset; +} + +template +inline auto +doComputeOffset(TTasks const &tasks, + TScoreValue const & /*scalarScore*/, + TScoreValue const & /*simdScore*/) +{ + String offset; + resize(offset, length(tasks), 0, Exact()); + return offset; +} + +template +inline auto +computeOffset(TTasks const &tasks, TTaskTraits const & /*traits*/) +{ + using TDPSettings = typename TTaskTraits::TDPSettings; + using TScoreValueScalar = typename Value::Type; + using TScoreValueSimd = typename Value::Type; + using TDPSimdValue = typename Value::Type; + + return doComputeOffset(tasks, TScoreValueScalar{}, TDPSimdValue{}); +} + +template +inline void +loadIntoSimd(Pair & target, + TTasks const & tasks, + TPos const pos, + TFunc && getBuffer, + TOffset const & offset, + LinearGaps const & /*unsused*/) +{ + using TSimdVec = typename Value::Type; + using TVecVal = typename Value::Type; + + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> traceVec; + + auto zipCont = makeZipView(tasks, scoreVec, traceVec, offset); + + std::for_each(begin(zipCont), end(zipCont), + [&, getBuffer = std::move(getBuffer)](auto tuple) + { + auto & buffer = *getBuffer(*std::get<0>(tuple)); + auto val = (length(buffer) > pos) ? buffer[pos] : typename std::decay::type{}; + + // We might access values out of bounds here. + std::get<1>(tuple) = static_cast(val.i1._score - std::get<3>(tuple)); + std::get<2>(tuple) = val.i2; + }); + + target.i1._score = load(&scoreVec[0]); + target.i2 = load(&traceVec[0]); +} + +template +inline void +loadIntoSimd(Pair & target, + TTasks const & tasks, + TPos const pos, + TFunc && getBuffer, + TOffset const & offset, + AffineGaps const & /*unsused*/) +{ + using TSimdVec = typename Value::Type; + using TVecVal = typename Value::Type; + + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreHorVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVerVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> traceVec; + + auto zipCont = makeZipView(tasks, scoreVec, scoreHorVec, scoreVerVec, traceVec, offset); + + std::for_each(begin(zipCont), end(zipCont), + [&, getBuffer = std::move(getBuffer)](auto tuple) + { + auto & buffer = *getBuffer(*std::get<0>(tuple)); + auto val = (length(buffer) > pos) ? buffer[pos] : typename std::decay::type{}; + using TDPCellVar = decltype(val.i1); + using TDPCell16 = DPCell_; + + // We might access values out of bounds here. + std::get<1>(tuple) = static_cast(val.i1._score - std::get<5>(tuple)); + + std::get<2>(tuple) = + (val.i1._horizontalScore <= DPCellDefaultInfinity::VALUE) ? + DPCellDefaultInfinity::VALUE : + static_cast(val.i1._horizontalScore - std::get<5>(tuple)); + std::get<3>(tuple) = + (val.i1._verticalScore <= DPCellDefaultInfinity::VALUE) ? + DPCellDefaultInfinity::VALUE : + static_cast(val.i1._verticalScore - std::get<5>(tuple)); + std::get<4>(tuple) = val.i2; + }); + + target.i1._score = load(&scoreVec[0]); + target.i1._horizontalScore = load(&scoreHorVec[0]); + target.i1._verticalScore = load(&scoreVerVec[0]); + target.i2 = load(&traceVec[0]); +} + +template +inline void +storeIntoBuffer(TTasks & tasks, + Pair const & source, + TPos const pos, + TFunc && getBuffer, + TOffset const & offset, + LinearGaps const & /*unsused*/) +{ + using TSimdVec = typename Value::Type; + using TVecVal = typename Value::Type; + + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> traceVec; + + storeu(&scoreVec[0], source.i1._score); + storeu(&traceVec[0], source.i2); + + auto zipCont = makeZipView(tasks, scoreVec, traceVec, offset); + + std::for_each(begin(zipCont), end(zipCont), + [&, getBuffer = std::move(getBuffer)] (auto tuple) + { + auto & buffer = *getBuffer(*std::get<0>(tuple)); + if (length(buffer) > pos) + { + auto & pair = buffer[pos]; + pair.i1._score = std::get<1>(tuple) + std::get<3>(tuple); + pair.i2 = std::get<2>(tuple); + } + }); +} + +template +inline void +storeIntoBuffer(TTasks & tasks, + Pair const & source, + TPos const pos, + TFunc && getBuffer, + TOffset const & offset, + AffineGaps const & /*unsused*/) +{ + using TSimdVec = typename Value::Type; + using TVecVal = typename Value::Type; + + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreHorVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> scoreVerVec; + alignas(sizeof(TSimdVec)) std::array::VALUE> traceVec; + + storeu(&scoreVec[0], source.i1._score); + storeu(&scoreHorVec[0], source.i1._horizontalScore); + storeu(&scoreVerVec[0], source.i1._verticalScore); + storeu(&traceVec[0], source.i2); + + auto zipCont = makeZipView(tasks, scoreVec, scoreHorVec, scoreVerVec, traceVec, offset); + + std::for_each(begin(zipCont), end(zipCont), + [&, getBuffer = std::move(getBuffer)](auto tuple) + { + auto & buffer = *getBuffer(*std::get<0>(tuple)); + if (length(buffer) > pos) + { + auto & pair = buffer[pos]; + pair.i1._score = std::get<1>(tuple) + std::get<5>(tuple); + pair.i1._horizontalScore = std::get<2>(tuple) + std::get<5>(tuple); + pair.i1._verticalScore = std::get<3>(tuple) + std::get<5>(tuple); + pair.i2 = std::get<4>(tuple); + } + }); +} + +template +inline auto +gatherSimdBuffer(TTasks const & tasks, + TFunc && getBuffer, + TOffset const & offset, + TExecTraits const & /*traits*/) +{ + // Check for valid simd length. + SEQAN_ASSERT_EQ(LENGTH::VALUE, length(tasks)); + + String > simdSet; + + auto maxLength = length(*getBuffer(*tasks[0])); + std::for_each(begin(tasks, Standard()) + 1, end(tasks, Standard()), + [&](auto & task) + { + auto len = length(*getBuffer(*task)); + maxLength = (len > maxLength) ? len : maxLength; + }); + + resize(simdSet, maxLength, Exact()); + for (unsigned i = 0; i < length(simdSet); ++i) + { + loadIntoSimd(simdSet[i], tasks, i, std::forward(getBuffer), offset, typename TExecTraits::TGapType()); + } + return simdSet; +} + +template +inline void +scatterSimdBuffer(TTasks & tasks, + String const & simdSet, + TFunc && getBuffer, + TOffset const & offset, + TExecTraits const & /*traits*/) +{ + for (unsigned i = 0; i < length(simdSet); ++i) + { + storeIntoBuffer(tasks, simdSet[i], i, std::forward(getBuffer), offset, typename TExecTraits::TGapType()); + } +} + +// Compute tasks as simd alignment. +template +inline void +computeSimdBatch(DPContext & cache, + TSimdBufferH & bufferH, + TSimdBufferV & bufferV, + TTasks & tasks, + TDPLocal & dpLocal, + TOffset & offset, + TExecTraits const & /*traits*/) +{ + // Now what? + using TSeqH = typename TExecTraits::TSeqH; + using TSeqV = typename TExecTraits::TSeqV; + using TSimdVec = typename TExecTraits::TScoreValue; + + // Prepare sequence set. + StringSet > depSetH; + StringSet > depSetV; + bool allSameLength = true; + auto ptrTask = tasks[0]; + auto lenH = length(context(*ptrTask).seqHBlocks[column(*ptrTask)]); + auto lenV = length(context(*ptrTask).seqVBlocks[row(*ptrTask)]); + + for (auto ptrTask : tasks) + { + appendValue(depSetH, context(*ptrTask).seqHBlocks[column(*ptrTask)]); + appendValue(depSetV, context(*ptrTask).seqVBlocks[row(*ptrTask)]); + if (lenH != length(context(*ptrTask).seqHBlocks[column(*ptrTask)]) || + lenV != length(context(*ptrTask).seqVBlocks[row(*ptrTask)])) + { + allSameLength = false; + } + } + + // Dummy trace set. + StringSet > trace; // We need to instantiate it, but it will not be used. + + // We can compute with one simd score, but might collect them here. + auto const & scoringScheme = context(*tasks[0]).dpSettings.simdScoringScheme; + + // Preapare and run alingment. + String > stringSimdH; + String > stringSimdV; + + if (allSameLength) + { + using TScoutState = DPScoutState_>; + TScoutState scoutState(bufferH, bufferV); + _prepareSimdAlignment(stringSimdH, stringSimdV, depSetH, depSetV, scoutState); + + using TScoutSpec = typename ScoutSpecForAlignmentAlgorithm_::Type; + using TDPScout = DPScout_; + + TDPScout dpScout(scoutState); + // We rather want to set + computeTile(cache, dpScout, stringSimdH, stringSimdV, scoringScheme, context(*tasks[0]).dpSettings); + + // Now we need to run the scout check for all tasks. + + // We want to get the state here from the scout. + for (size_t pos = 0; pos < length(tasks); ++pos) + { + auto & task = *tasks[pos]; + if (AlgorithmProperty::isTrackingEnabled(task)) + { + // TODO(rrahn): Implement the interface. + // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here + _setSimdLane(dpScout, pos); + auto & taskContext = context(task); + updateMax(intermediate(dpLocal, taskContext.alignmentId), + {maxScoreAt(dpScout) + offset[pos], 0u}, + column(task), + row(task)); + } + } + } + else + { + using TDPSettings = std::decay_t; + using TDPTraits = typename TDPSettings::TTraits; + + using TDPProfile = DPProfile_; + + using TSimdScoutTrait = SimdAlignVariableLengthTraits; + using TScoutState = DPScoutState_>>; + + String lengthsH; + String lengthsV; + + TScoutState scoutState(bufferH, bufferV); + _prepareSimdAlignment(stringSimdH, stringSimdV, depSetH, depSetV, lengthsH, lengthsV, scoutState); + + using TScoutSpec = typename ScoutSpecForAlignmentAlgorithm_::Type; + using TDPScout = DPScout_; + + TDPScout dpScout(scoutState); + computeTile(cache, dpScout, stringSimdH, stringSimdV, scoringScheme, context(*tasks[0]).dpSettings); + // We want to get the state here from the scout. + for (size_t pos = 0; pos < length(tasks); ++pos) + { + auto & task = *tasks[pos]; + if (AlgorithmProperty::isTrackingEnabled(task)) + { + // TODO(rrahn): Implement the interface. + // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here + _setSimdLane(dpScout, pos); + auto & taskContext = context(task); + updateMax(intermediate(dpLocal, taskContext.alignmentId), + {maxScoreAt(dpScout) + offset[pos], 0u}, + column(task), + row(task)); + } + } + } +} +#endif // SEQAN_SIMD_ENABLED +} // namespace impl +} // namespace seqan + +#endif // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_ diff --git a/porechop/include/seqan/align_profile.h b/porechop/include/seqan/align_profile.h index f9436f8..794474e 100644 --- a/porechop/include/seqan/align_profile.h +++ b/porechop/include/seqan/align_profile.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align_profile/add_to_profile.h b/porechop/include/seqan/align_profile/add_to_profile.h index 76f035d..912c6b3 100644 --- a/porechop/include/seqan/align_profile/add_to_profile.h +++ b/porechop/include/seqan/align_profile/add_to_profile.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -83,8 +83,8 @@ namespace seqan { template void addToProfile(String > & profile, String /*const*/ & seq, - int lDiag = minValue(), - int uDiag = maxValue()) // non-const because of holder issues + int lDiag = std::numeric_limits::min(), + int uDiag = std::numeric_limits::max()) // non-const because of holder issues { typedef ProfileChar TProfileChar; @@ -97,7 +97,7 @@ void addToProfile(String > & profile, seqan::Score sScheme(profile); // Perform the global alignment. - if (lDiag == minValue() || uDiag == maxValue()) + if (lDiag == std::numeric_limits::min() || uDiag == std::numeric_limits::max()) globalAlignment(gapsH, gapsV, sScheme, Gotoh()); else globalAlignment(gapsH, gapsV, sScheme, lDiag, uDiag, Gotoh()); diff --git a/porechop/include/seqan/align_profile/score_profile_seq.h b/porechop/include/seqan/align_profile/score_profile_seq.h index 86b9a26..18cfcf7 100644 --- a/porechop/include/seqan/align_profile/score_profile_seq.h +++ b/porechop/include/seqan/align_profile/score_profile_seq.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align_split.h b/porechop/include/seqan/align_split.h index b08ac58..a0aa200 100644 --- a/porechop/include/seqan/align_split.h +++ b/porechop/include/seqan/align_split.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/align_split/align_split_interface.h b/porechop/include/seqan/align_split/align_split_interface.h index 658536a..5f2ee4d 100644 --- a/porechop/include/seqan/align_split/align_split_interface.h +++ b/porechop/include/seqan/align_split/align_split_interface.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -98,12 +98,12 @@ template struct IsSplitAlignment_ const>: True {}; -template -struct IsSplitAlignment_ >: +template +struct IsSplitAlignment_ >: IsSplitAlignment_ {}; -template -struct IsSplitAlignment_ const>: +template +struct IsSplitAlignment_ const>: IsSplitAlignment_ {}; // ---------------------------------------------------------------------------- @@ -176,10 +176,12 @@ struct LastRowEnabled_, LastCell, TColumnDescriptor> // Metafunction DPMetaColumn_ // ---------------------------------------------------------------------------- -template -struct DPMetaColumn_, TGapCosts, TTraceFlag>, MetaColumnDescriptor > +template +struct DPMetaColumn_, TGapCosts, TTraceFlag, TExecPolicy>, + MetaColumnDescriptor > { - typedef DPProfile_, TGapCosts, TTraceFlag> TDPProfile; + typedef DPProfile_, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile; typedef typename IsLocalAlignment_::Type TIsLocal; // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero // Within the algorithm we need to define the first row as only one cell if it is no initial column @@ -201,8 +203,10 @@ struct DPMetaColumn_, TGapCosts, TTraceFlag>, }; -template -struct DPMetaColumn_, TGapCosts, TTraceFlag>, MetaColumnDescriptor > +template +struct DPMetaColumn_, TGapCosts, TTraceFlag, TExecPolicy>, + MetaColumnDescriptor > { typedef DPProfile_, TGapCosts, TTraceFlag> TDPProfile; typedef typename IsLocalAlignment_::Type TIsLocal; @@ -227,10 +231,12 @@ struct DPMetaColumn_, TGapCosts, TTraceFlag>, typedef DPMetaCell_ TLastCell_; }; -template -struct DPMetaColumn_, TGapCosts, TTraceFlag>, MetaColumnDescriptor > +template +struct DPMetaColumn_, TGapCosts, TTraceFlag, TExecPolicy>, + MetaColumnDescriptor > { - typedef DPProfile_, TGapCosts, TTraceFlag> TDPProfile; + typedef DPProfile_, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile; typedef typename IsLocalAlignment_::Type TIsLocal; // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero // Within the algorithm we need to define the first row as only one cell if it is no initial column @@ -250,10 +256,12 @@ struct DPMetaColumn_, TGapCosts, TTraceFlag>, typedef DPMetaCell_ TLastCell_; }; -template -struct DPMetaColumn_, TGapCosts, TTraceFlag>, MetaColumnDescriptor > +template +struct DPMetaColumn_, TGapCosts, TTraceFlag, TExecPolicy>, + MetaColumnDescriptor > { - typedef DPProfile_, TGapCosts, TTraceFlag> TDPProfile; + typedef DPProfile_, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile; typedef typename IsLocalAlignment_::Type TIsLocal; // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero // Within the algorithm we need to define the first row as only one cell if it is no initial column @@ -280,7 +288,7 @@ struct DPMetaColumn_, TGapCosts, TTraceFlag>, template struct SetupAlignmentProfile_ { - typedef DPProfile_, TGapCosts, TTraceSwitch> Type; + typedef DPProfile_, TGapCosts, TTraceSwitch, Serial> Type; }; // ============================================================================ @@ -330,7 +338,7 @@ void _computeSplitTrace(TTarget & target, { typedef typename SetupAlignmentProfile_::Type TDPProfile; - typedef typename GetDPTraceMatrix::Type TDPTraceMatrixHost; + using TDPTraceMatrixHost = std::remove_reference_t; typedef typename Value::Type TTraceValue; typedef DPMatrix_ TDPTraceMatrix; @@ -339,7 +347,7 @@ void _computeSplitTrace(TTarget & target, TDPTraceMatrix matrix; setLength(matrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(config._band))); - if (IsSameType::VALUE) + SEQAN_IF_CONSTEXPR (IsSameType::VALUE) { setLength(matrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1); } @@ -353,8 +361,7 @@ void _computeSplitTrace(TTarget & target, setHost(matrix, getDpTraceMatrix(dpContext)); resize(matrix); SEQAN_ASSERT_EQ(length(getDpTraceMatrix(dpContext)), length(matrix)); - TDPTraceMatrixNavigator navi; - _init(navi, matrix, config._band); + TDPTraceMatrixNavigator navi{matrix, config._band}; _computeTraceback(target, navi, matPos, seqH, seqV, config._band, TDPProfile()); } @@ -387,9 +394,9 @@ auto _splitAlignmentImpl(Gaps & gapsContigL, // Compute trace and split score sequence for the left alignment. // We actually need to first compute the scores, than trace from the choosen split position. - DPContext dpContextL; + DPContext, typename TraceBitMap_::Type> dpContextL; DPScoutState_ scoutStateL; - resize(scoutStateL.splitScore, length(source(gapsContigL)) + 1, minValue() / 2); + resize(scoutStateL.splitScore, length(source(gapsContigL)) + 1, std::numeric_limits::min() / 2); resize(scoutStateL.splitPos, length(scoutStateL.splitScore)); String traceL; @@ -400,9 +407,9 @@ auto _splitAlignmentImpl(Gaps & gapsContigL, ModifiedString revReadR(source(gapsReadR)); // Compute trace and split score sequence for the right alignment. - DPContext dpContextR; + DPContext, typename TraceBitMap_::Type> dpContextR; DPScoutState_ scoutStateR; - resize(scoutStateR.splitScore, length(source(gapsContigR)) + 1, minValue() / 2); + resize(scoutStateR.splitScore, length(source(gapsContigR)) + 1, std::numeric_limits::min() / 2); resize(scoutStateR.splitPos, length(scoutStateR.splitScore)); String traceR; @@ -482,7 +489,7 @@ auto _splitAlignmentImpl(Gaps & gapsContigL, { typedef typename SubstituteAlignConfig_ >::Type TFreeEndGaps; // Check whether we need to run the banded versions. - if (lowerDiagonal != minValue() && upperDiagonal != maxValue()) + if (lowerDiagonal != std::numeric_limits::min() && upperDiagonal != std::numeric_limits::max()) { typedef AlignConfig2, TFreeEndGaps, TracebackOn > > TAlignConfigL; @@ -513,8 +520,8 @@ auto _splitAlignmentImpl(Gaps & gapsContigL, Gaps & gapsReadR, Score const & scoringScheme, AlignConfig const & config, - int lowerDiagonal = minValue(), - int upperDiagonal = maxValue()) + int lowerDiagonal = std::numeric_limits::min(), + int upperDiagonal = std::numeric_limits::max()) { if (_usesAffineGaps(scoringScheme, source(gapsContigL), source(gapsReadL))) return _splitAlignmentImpl(gapsContigL, gapsReadL, gapsContigR, gapsReadR, diff --git a/porechop/include/seqan/align_split/dp_scout_split.h b/porechop/include/seqan/align_split/dp_scout_split.h index b107e43..c525f21 100644 --- a/porechop/include/seqan/align_split/dp_scout_split.h +++ b/porechop/include/seqan/align_split/dp_scout_split.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free.h b/porechop/include/seqan/alignment_free.h index 8a68853..be44c79 100644 --- a/porechop/include/seqan/alignment_free.h +++ b/porechop/include/seqan/alignment_free.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/af_d2.h b/porechop/include/seqan/alignment_free/af_d2.h index 7e5bcbe..b9c9e4d 100644 --- a/porechop/include/seqan/alignment_free/af_d2.h +++ b/porechop/include/seqan/alignment_free/af_d2.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/af_d2star.h b/porechop/include/seqan/alignment_free/af_d2star.h index c6bf16f..0fcfaae 100644 --- a/porechop/include/seqan/alignment_free/af_d2star.h +++ b/porechop/include/seqan/alignment_free/af_d2star.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/af_d2z.h b/porechop/include/seqan/alignment_free/af_d2z.h index 6325af2..0cb88ff 100644 --- a/porechop/include/seqan/alignment_free/af_d2z.h +++ b/porechop/include/seqan/alignment_free/af_d2z.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/af_n2.h b/porechop/include/seqan/alignment_free/af_n2.h index ac2110a..5e98fa2 100644 --- a/porechop/include/seqan/alignment_free/af_n2.h +++ b/porechop/include/seqan/alignment_free/af_n2.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/alignment_free_base.h b/porechop/include/seqan/alignment_free/alignment_free_base.h index c3a7471..ba80f81 100644 --- a/porechop/include/seqan/alignment_free/alignment_free_base.h +++ b/porechop/include/seqan/alignment_free/alignment_free_base.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/alignment_free_comparison.h b/porechop/include/seqan/alignment_free/alignment_free_comparison.h index bf33fa0..ee6e65c 100644 --- a/porechop/include/seqan/alignment_free/alignment_free_comparison.h +++ b/porechop/include/seqan/alignment_free/alignment_free_comparison.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/alignment_free/kmer_functions.h b/porechop/include/seqan/alignment_free/kmer_functions.h index 118c7d8..222f0f3 100644 --- a/porechop/include/seqan/alignment_free/kmer_functions.h +++ b/porechop/include/seqan/alignment_free/kmer_functions.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse.h b/porechop/include/seqan/arg_parse.h index 06b2d8d..e806c27 100644 --- a/porechop/include/seqan/arg_parse.h +++ b/porechop/include/seqan/arg_parse.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/arg_parse_argument.h b/porechop/include/seqan/arg_parse/arg_parse_argument.h index e22d41f..91ef3fa 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_argument.h +++ b/porechop/include/seqan/arg_parse/arg_parse_argument.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -219,60 +219,44 @@ class ArgParseArgument inline std::string _typeToString(ArgParseArgument const & me) { - std::string typeName = ""; - switch (me._argumentType) { - case ArgParseArgument::BOOL: - typeName = "bool"; - break; + case ArgParseArgument::BOOL: + return "bool"; - case ArgParseArgument::DOUBLE: - typeName = "double"; - break; + case ArgParseArgument::DOUBLE: + return "double"; - case ArgParseArgument::INTEGER: - typeName = "integer"; - break; + case ArgParseArgument::INTEGER: + return "integer"; - case ArgParseArgument::INT64: - typeName = "int64"; - break; + case ArgParseArgument::INT64: + return "int64"; - case ArgParseArgument::STRING: - typeName = "string"; - break; + case ArgParseArgument::STRING: + return "string"; - case ArgParseArgument::INPUT_FILE: - typeName = "input_file"; - break; + case ArgParseArgument::INPUT_FILE: + return "input_file"; - case ArgParseArgument::OUTPUT_FILE: - typeName = "output_file"; - break; + case ArgParseArgument::OUTPUT_FILE: + return "output_file"; - case ArgParseArgument::INPUT_PREFIX: - typeName = "input_prefix"; - break; + case ArgParseArgument::INPUT_PREFIX: + return "input_prefix"; - case ArgParseArgument::OUTPUT_PREFIX: - typeName = "output_prefix"; - break; + case ArgParseArgument::OUTPUT_PREFIX: + return "output_prefix"; - case ArgParseArgument::INPUT_DIRECTORY: - typeName = "input_directory"; - break; + case ArgParseArgument::INPUT_DIRECTORY: + return "input_directory"; - case ArgParseArgument::OUTPUT_DIRECTORY: - typeName = "output_directory"; - break; + case ArgParseArgument::OUTPUT_DIRECTORY: + return "output_directory"; - default: - typeName = "unknown"; - break; + default: + return "unknown"; } - - return typeName; } // ---------------------------------------------------------------------------- @@ -453,6 +437,28 @@ inline bool isOutputFileArgument(ArgParseArgument const & me) me._argumentType == ArgParseArgument::OUTPUT_DIRECTORY; } +// ---------------------------------------------------------------------------- +// Function isDirectoryArgument() +// ---------------------------------------------------------------------------- + +/*! + * @fn ArgParseArgument#isDirectoryArgument + * @headerfile + * @brief Returns whether the argument is a directorz argument. + * + * @signature bool isDirectoryArgument(arg); + * + * @param[in] arg The ArgParseArgument to query. + * + * @return bool true if it is a directory argument, false otherwise. + */ + +inline bool isDirectoryArgument(ArgParseArgument const & me) +{ + return me._argumentType == ArgParseArgument::INPUT_DIRECTORY || + me._argumentType == ArgParseArgument::OUTPUT_DIRECTORY; +} + // ---------------------------------------------------------------------------- // Function isOutputPrefixArgument() // ---------------------------------------------------------------------------- @@ -939,7 +945,15 @@ inline void _checkValue(ArgParseArgument const & me) { unsigned i = 0; for (std::vector::const_iterator it = me.value.begin(); it != me.value.end(); ++it, ++i) - _checkValue(me, *it, i); + { + auto val = *it; + + if (isDirectoryArgument(me)) // strip trailing slash for directories + if (val[length(val) - 1] == '/') + val.resize(length(val) - 1); + + _checkValue(me, val, i); + } } // ---------------------------------------------------------------------------- @@ -1154,6 +1168,10 @@ inline std::string getFileExtension(ArgParseArgument const & me, unsigned pos = if (value.empty()) return ""; + if (isDirectoryArgument(me)) // strip trailing slash for directories + if (value[length(value) - 1] == '/') + value.resize(length(value) - 1); + // If there is a list of valid values then we look for each of these in the path. if (!me.validValues.empty()) { diff --git a/porechop/include/seqan/arg_parse/arg_parse_ctd_support.h b/porechop/include/seqan/arg_parse/arg_parse_ctd_support.h index 9442815..9125fd7 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_ctd_support.h +++ b/porechop/include/seqan/arg_parse/arg_parse_ctd_support.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -165,8 +165,14 @@ _getRestrictions(std::vector & restrictions, ArgParseArgument const { // we only extract non-file restrictions if (isOutputFileArgument(opt) || isInputFileArgument(opt) || isInputPrefixArgument(opt) || isOutputPrefixArgument(opt)) + { return; - + } + else if (isBooleanArgument(opt)) + { + appendValue(restrictions, "true,false"); + return; + } if (length(opt.validValues) != 0) { for (std::vector::const_iterator valid = opt.validValues.begin(); @@ -280,6 +286,50 @@ inline std::string _getManual(ArgumentParser const & me) return manual.str(); } +// ---------------------------------------------------------------------------- +// Function _toValidGKNTypeSpecifier() +// ---------------------------------------------------------------------------- +// TODO(dadi): similar to _typeToString() function. Differs only in the case of bool, integer, int64 and types +//. that has underscores in them. hyphens are used instead of underscores. e.g. input-file instead +// of input_file. This should be removed and _typeToString() should be used instead once GKN is +// modified to accept the results of _typeToString() functions directly. + +inline std::string _toValidGKNTypeSpecifier(ArgParseArgument const & me) +{ + switch (me._argumentType) + { + case ArgParseArgument::BOOL: + return "string"; + + case ArgParseArgument::INTEGER: + return "int"; + + case ArgParseArgument::INT64: + return "int"; + + case ArgParseArgument::INPUT_FILE: + return "input-file"; + + case ArgParseArgument::OUTPUT_FILE: + return "output-file"; + + case ArgParseArgument::INPUT_PREFIX: + return "input-prefix"; + + case ArgParseArgument::OUTPUT_PREFIX: + return "output-prefix"; + + case ArgParseArgument::INPUT_DIRECTORY: + return "input-prefix"; + + case ArgParseArgument::OUTPUT_DIRECTORY: + return "output-prefix"; + + default: + return _typeToString(me); + } +} + // ---------------------------------------------------------------------------- // Function writeCTD() // ---------------------------------------------------------------------------- @@ -391,7 +441,7 @@ writeCTD(ArgumentParser const & me, std::ostream & ctdfile) // prefer short name for options std::string optionName = _getOptionName(opt); - std::string type = _typeToString(opt); + std::string type = _toValidGKNTypeSpecifier(opt); // set up restrictions std::vector restrictions; @@ -464,7 +514,7 @@ writeCTD(ArgumentParser const & me, std::ostream & ctdfile) argumentNameStream << "argument-" << argIdx; std::string optionName = argumentNameStream.str(); - std::string type = _typeToString(arg); + std::string type = _toValidGKNTypeSpecifier(arg); // set up restrictions std::vector restrictions; diff --git a/porechop/include/seqan/arg_parse/arg_parse_doc.h b/porechop/include/seqan/arg_parse/arg_parse_doc.h index 528ce81..b81498f 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_doc.h +++ b/porechop/include/seqan/arg_parse/arg_parse_doc.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -669,7 +669,7 @@ inline void printLongCopyright(ArgumentParser const & me, std::ostream & stream) << "=============================================================================" << std::endl << "This program contains SeqAn code licensed under the following terms:" << std::endl << "-----------------------------------------------------------------------------" << std::endl - << " Copyright (c) 2006-2015, Knut Reinert, FU Berlin" << std::endl + << " Copyright (c) 2006-2018, Knut Reinert, FU Berlin" << std::endl << " All rights reserved." << std::endl << "" << std::endl << " Redistribution and use in source and binary forms, with or without" << std::endl diff --git a/porechop/include/seqan/arg_parse/arg_parse_exceptions.h b/porechop/include/seqan/arg_parse/arg_parse_exceptions.h index 5c6ffe1..4199bec 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_exceptions.h +++ b/porechop/include/seqan/arg_parse/arg_parse_exceptions.h @@ -1,7 +1,7 @@ // ========================================================================== // arg_parse_exceptions.h // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/arg_parse_option.h b/porechop/include/seqan/arg_parse/arg_parse_option.h index 7b6d8bd..770207e 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_option.h +++ b/porechop/include/seqan/arg_parse/arg_parse_option.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/arg_parse_parse.h b/porechop/include/seqan/arg_parse/arg_parse_parse.h index 5afe27a..b73f2b2 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_parse.h +++ b/porechop/include/seqan/arg_parse/arg_parse_parse.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/arg_parse_type_support.h b/porechop/include/seqan/arg_parse/arg_parse_type_support.h index 9b1192d..3343647 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_type_support.h +++ b/porechop/include/seqan/arg_parse/arg_parse_type_support.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/arg_parse_version_check.h b/porechop/include/seqan/arg_parse/arg_parse_version_check.h index 5a1f7cd..01bc176 100644 --- a/porechop/include/seqan/arg_parse/arg_parse_version_check.h +++ b/porechop/include/seqan/arg_parse/arg_parse_version_check.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -68,18 +68,18 @@ struct VersionControlTags_ static constexpr char const * const UNREGISTERED_APP = "UNREGISTERED_APP"; static constexpr char const * const MESSAGE_SEQAN_UPDATE = - "[SEQAN INFO] :: There is a newer SeqAn version available!\n" + "[SEQAN INFO] :: A new SeqAn version is available online.\n" "[SEQAN INFO] :: Please visit www.seqan.de for an update or inform the developer of this app.\n" - "[SEQAN INFO] :: If you don't want to recieve this message again set --version-check OFF\n\n"; + "[SEQAN INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n"; static constexpr char const * const MESSAGE_APP_UPDATE = - "[APP INFO] :: There is a newer version of this application available.\n" - "[APP INFO] :: If this app is developed by SeqAn, visit www.seqan.de for updates.\n" - "[APP INFO] :: If you don't want to recieve this message again set --version_check OFF\n\n"; + "[APP INFO] :: A new version of this application is now available.\n" + "[APP INFO] :: Visit www.seqan.de for updates of official SeqAn applications.\n" + "[APP INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n"; static constexpr char const * const MESSAGE_UNREGISTERED_APP = "[SEQAN INFO] :: Thank you for using SeqAn!\n" - "[SEQAN INFO] :: You might want to regsiter you app for support and version check features?\n" - "[SEQAN INFO] :: Just send us an email to seqan@team.fu-berlin.de with your app name and version number.\n" - "[SEQAN INFO] :: If you don't want to recieve this message anymore set --version_check OFF\n\n"; + "[SEQAN INFO] :: Do you wish to register your app for update notifications?\n" + "[SEQAN INFO] :: Just send an email to support@seqan.de with your app name and version number.\n" + "[SEQAN INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n"; static constexpr char const * const MESSAGE_REGISTERED_APP_UPDATE = "[APP INFO] :: We noticed the app version you use is newer than the one registered with us.\n" "[APP INFO] :: Please send us an email with the new version so we can correct it (support@seqan.de)\n\n"; @@ -109,6 +109,7 @@ struct VersionCheck std::string _program; std::string _command; std::string _path = _getPath(); + std::string _timestamp_filename; std::ostream & errorStream; // ---------------------------------------------------------------------------- @@ -122,6 +123,11 @@ struct VersionCheck errorStream(errorStream) { std::smatch versionMatch; +#if defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) + _timestamp_filename = _path + "/" + _name + "_usr.timestamp"; +#else + _timestamp_filename = _path + "/" + _name + "_dev.timestamp"; +#endif if (!version.empty() && std::regex_search(version, versionMatch, std::regex("^([[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+).*"))) { @@ -318,11 +324,11 @@ inline std::string _getPath() // Function _getFileTimeDiff() // ---------------------------------------------------------------------------- -inline double _getFileTimeDiff(std::string const & timestamp_filename) +inline double _getFileTimeDiff(VersionCheck const & me) { double curr = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); std::ifstream timestamp_file; - timestamp_file.open(timestamp_filename.c_str()); + timestamp_file.open(me._timestamp_filename.c_str()); if (timestamp_file.is_open()) { @@ -390,8 +396,7 @@ inline void _readVersionStrings(std::vector & versions, std::string inline void _callServer(VersionCheck const me, std::promise prom) { // update timestamp - std::string timestamp_filename(me._path + "/" + me._name + ".timestamp"); - std::ofstream timestamp_file(timestamp_filename.c_str()); + std::ofstream timestamp_file(me._timestamp_filename.c_str()); if (timestamp_file.is_open()) { timestamp_file << std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); @@ -419,9 +424,8 @@ inline void _checkForNewerVersion(VersionCheck & me, std::promise prom) } std::string version_filename(me._path + "/" + me._name + ".version"); - std::string timestamp_filename(me._path + "/" + me._name + ".timestamp"); double min_time_diff(86400); // one day = 86400 seonds - double file_time_diff(_getFileTimeDiff(timestamp_filename)); // time difference in seconds + double file_time_diff(_getFileTimeDiff(me)); // time difference in seconds if (file_time_diff < min_time_diff) { @@ -447,18 +451,20 @@ inline void _checkForNewerVersion(VersionCheck & me, std::promise prom) me.errorStream << VersionControlTags_<>::MESSAGE_UNREGISTERED_APP; #endif -#if defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) // only check app version in release or testing mode if (!str_server_versions[0].empty() & !(str_server_versions[0] == VersionControlTags_<>::UNREGISTERED_APP)) // app version { Lexical<> version_comp(_getNumbersFromString(me._version), _getNumbersFromString(str_server_versions[0])); +#if defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) // only check app version in release or testing mode if (isLess(version_comp)) me.errorStream << VersionControlTags_<>::MESSAGE_APP_UPDATE; +#endif // defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) - else if (isGreater(version_comp)) +#if !defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) // only notify developer that app version should be updated on server + if (isGreater(version_comp)) me.errorStream << VersionControlTags_<>::MESSAGE_REGISTERED_APP_UPDATE; +#endif // !defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) } -#endif // defined(NDEBUG) || defined(SEQAN_TEST_VERSION_CHECK_) if (me._program.empty()) { diff --git a/porechop/include/seqan/arg_parse/argument_parser.h b/porechop/include/seqan/arg_parse/argument_parser.h index 92467a3..101736e 100644 --- a/porechop/include/seqan/arg_parse/argument_parser.h +++ b/porechop/include/seqan/arg_parse/argument_parser.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/arg_parse/tool_doc.h b/porechop/include/seqan/arg_parse/tool_doc.h index a19a983..78f7db7 100644 --- a/porechop/include/seqan/arg_parse/tool_doc.h +++ b/porechop/include/seqan/arg_parse/tool_doc.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -444,6 +444,13 @@ class TextToolDocPrinter_ : std::fill_n(out, _layout.leftPadding, ' '); stream << _toText(listItem._term); unsigned pos = _layout.leftPadding + length(listItem._term); + + if (empty(listItem._description)) + { + stream << '\n'; + return; + } + if (pos + _layout.centerPadding > _layout.rightColumnTab) { stream << '\n'; diff --git a/porechop/include/seqan/arg_parse/xml_support.h b/porechop/include/seqan/arg_parse/xml_support.h index 6e14d40..cc46ab3 100644 --- a/porechop/include/seqan/arg_parse/xml_support.h +++ b/porechop/include/seqan/arg_parse/xml_support.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/bam_io.h b/porechop/include/seqan/bam_io.h index f9f9842..7b7154f 100644 --- a/porechop/include/seqan/bam_io.h +++ b/porechop/include/seqan/bam_io.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ // Prerequisites. // =========================================================================== +#include #include #include #include diff --git a/porechop/include/seqan/bam_io/bam_alignment_record.h b/porechop/include/seqan/bam_io/bam_alignment_record.h index 4e694d5..e731861 100644 --- a/porechop/include/seqan/bam_io/bam_alignment_record.h +++ b/porechop/include/seqan/bam_io/bam_alignment_record.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -117,12 +117,12 @@ struct BamTypeChar { VALUE = (IsSameType::VALUE)? 'A': - (IsSameType::VALUE)? 'c': - (IsSameType::VALUE)? 'C': - (IsSameType::VALUE)? 's': - (IsSameType::VALUE)? 'S': - (IsSameType::VALUE)? 'i': - (IsSameType::VALUE)? 'I': + (IsSameType::VALUE)? 'c': + (IsSameType::VALUE)? 'C': + (IsSameType::VALUE)? 's': + (IsSameType::VALUE)? 'S': + (IsSameType::VALUE)? 'i': + (IsSameType::VALUE)? 'I': (IsSameType::VALUE)? 'f': // (IsSameType::VALUE)? 'd': (IsSequence::VALUE)? 'Z': @@ -131,14 +131,14 @@ struct BamTypeChar }; // List of primitive BAM types (ordered by expected usage frequency) -typedef TagList > > > > > > > BamTagTypes; @@ -254,7 +254,7 @@ class BamAlignmentRecord : public BamAlignmentRecordCore static int32_t const INVALID_LEN = 0; static uint32_t const INVALID_QID = 4294967295u; // TODO(holtgrew): Undocumented as of yet. - BamAlignmentRecord() : _qID(MaxValue::VALUE) { clear(*this); } + BamAlignmentRecord() : _qID(std::numeric_limits::max()) { clear(*this); } }; // ============================================================================ @@ -281,7 +281,7 @@ clear(BamAlignmentRecord & record) { clear(record.qName); record.flag = 0; - record._qID = MaxValue::VALUE; + record._qID = std::numeric_limits::max(); record.rID = BamAlignmentRecord::INVALID_REFID; record.beginPos = BamAlignmentRecord::INVALID_POS; record.mapQ = 255; @@ -607,6 +607,37 @@ getAlignmentLengthInRef(BamAlignmentRecord const & record) return l; } +// ---------------------------------------------------------------------------- +// Function appendRawPod() +// ---------------------------------------------------------------------------- + +#if SEQAN_BIG_ENDIAN +inline void +enforceLittleEndian(BamAlignmentRecordCore & r) +{ + enforceLittleEndian(r.rID); + enforceLittleEndian(r.beginPos); + // _l_qname unchanged because 8bit + // mapQ unchanged because 8bit + r.bin = htole16(r.bin); + r._n_cigar = htole16(r._n_cigar); + r.flag = htole16(r.flag); + enforceLittleEndian(r._l_qseq); + enforceLittleEndian(r.rNextId); + enforceLittleEndian(r.pNext); + enforceLittleEndian(r.tLen); +} + +// This function is guarded so that we save the copy on little endian systems +template +inline void +appendRawPod(TTarget & target, BamAlignmentRecordCore r) +{ + enforceLittleEndian(r); + appendRawPodImpl(target, r); +} +#endif + } // namespace seqan #endif // #ifndef INCLUDE_SEQAN_BAM_IO_BAM_RECORD_H_ diff --git a/porechop/include/seqan/bam_io/bam_alignment_record_util.h b/porechop/include/seqan/bam_io/bam_alignment_record_util.h index 1a7a02f..777edd6 100644 --- a/porechop/include/seqan/bam_io/bam_alignment_record_util.h +++ b/porechop/include/seqan/bam_io/bam_alignment_record_util.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -237,7 +237,7 @@ bamRecordToAlignment(Align & result, TReference & reference, Bam // TODO(holtgrew): Clipping better than copying infix? But is it generic? resize(rows(result), 2); - unsigned len = record.beginPos + getAlignmentLengthInRef(record) - countPaddings(record.cigar); + unsigned len = getAlignmentLengthInRef(record) - countPaddings(record.cigar); setSource(row(result, 0), reference); setClippedEndPosition(row(result, 0), record.beginPos + len); diff --git a/porechop/include/seqan/bam_io/bam_file.h b/porechop/include/seqan/bam_io/bam_file.h index bf1c681..5190796 100644 --- a/porechop/include/seqan/bam_io/bam_file.h +++ b/porechop/include/seqan/bam_io/bam_file.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -243,7 +243,7 @@ readRecord(BamAlignmentRecord & record, FormattedFile & file) template inline SEQAN_FUNC_ENABLE_IF(And::Type, BamAlignmentRecord>, - IsInteger >, TSize) + Is > >, TSize) readRecords(TRecords & records, FormattedFile & file, TSize maxRecords) { String & buffers = context(file).buffers; diff --git a/porechop/include/seqan/bam_io/bam_header_record.h b/porechop/include/seqan/bam_io/bam_header_record.h index 0854d33..45e3f16 100644 --- a/porechop/include/seqan/bam_io/bam_header_record.h +++ b/porechop/include/seqan/bam_io/bam_header_record.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -272,7 +272,7 @@ findTagKey(unsigned & idx, TKeyName const & key, BamHeaderRecord const & record) template SEQAN_FUNC_ENABLE_IF( - IsInteger, + Is >, bool) inline getTagValue(CharString & value, TId idx, BamHeaderRecord const & record) { @@ -310,7 +310,7 @@ inline getTagValue(CharString & value, TKeyName const & key, BamHeaderRecord con template SEQAN_FUNC_ENABLE_IF( - IsInteger, + Is >, void) inline setTagValue(TId idx, CharString const & value, BamHeaderRecord & record) { diff --git a/porechop/include/seqan/bam_io/bam_index_bai.h b/porechop/include/seqan/bam_io/bam_index_bai.h index db5ed68..fbb9f8f 100644 --- a/porechop/include/seqan/bam_io/bam_index_bai.h +++ b/porechop/include/seqan/bam_io/bam_index_bai.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ /* The MIT License - Copyright (c) 2008-2009 Genome Research Ltd. + Copyright (c) 2008-2018 Genome Research Ltd. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -146,7 +146,7 @@ class BamIndex String _binIndices; String _linearIndices; - BamIndex() : _unalignedCount(maxValue()) + BamIndex() : _unalignedCount(std::numeric_limits::max()) {} }; @@ -162,24 +162,29 @@ class BamIndex * @fn BamFileIn#jumpToRegion * @brief Seek in BamFileIn using an index. * - * You provide a region [pos, posEnd) on the reference refID that you want to jump to and the function - * jumps to the first alignment in this region, if any. + * You provide a region [regionStart, regionEnd] on the reference refID + * that you want to jump to and the function jumps to the first alignment (bam record) + * whose start position lies inside this region, if any. + * Note: The current inmplementation only consideres the read start positions. + * Therefore, we do guarantee that reads overlapping the region are included. + * To account for this limitation you may want to choose the start of your + * your region with an appropiate offset (e.g. start - length_of_read). * - * @signature bool jumpToRegion(bamFileIn, hasAlignments, refID, pos, posEnd, index); + * @signature bool jumpToRegion(bamFileIn, hasAlignments, refID, regionStart, regionEnd, index); * * @param[in,out] bamFileIn The @link BamFileIn @endlink to jump with. - * @param[out] hasAlignments A bool that is set true if the region [pos, posEnd) has any - * alignments. + * @param[out] hasAlignments A bool that is set true if the region [regionStart, regionEnd] has any + * at least one overlapping alignment (bam record). * @param[in] refID The reference id to jump to (int32_t). - * @param[in] pos The begin of the region to jump to (int32_t). - * @param[in] posEnd The end of the region to jump to (int32_t). + * @param[in] regionStart The begin of the region to jump to (int32_t). + * @param[in] regionEnd The end of the region to jump to (int32_t). * @param[in] index The @link BamIndex @endlink to use for the jumping. * * @return bool true if seeking was successful, false if not. * * @section Remarks * - * This function fails if refID/pos are invalid. + * This function fails if refID/regionStart are invalid. */ static inline void @@ -202,8 +207,8 @@ inline bool jumpToRegion(FormattedFile & bamFile, bool & hasAlignments, int32_t refId, - int32_t pos, - int32_t posEnd, + int32_t regionStart, + int32_t regionEnd, BamIndex const & index) { if (!isEqual(format(bamFile), Bam())) @@ -218,14 +223,14 @@ jumpToRegion(FormattedFile & bamFile, // ------------------------------------------------------------------------ // Compute offset in BGZF file. // ------------------------------------------------------------------------ - uint64_t offset = MaxValue::VALUE; + uint64_t offset = std::numeric_limits::max(); - // Retrieve the candidate bin identifiers for [pos, posEnd). + // Retrieve the candidate bin identifiers for [regionStart, regionEnd). String candidateBins; - _baiReg2bins(candidateBins, pos, posEnd); + _baiReg2bins(candidateBins, regionStart, regionEnd); // Retrieve the smallest required offset from the linear index. - unsigned windowIdx = pos >> 14; // Linear index consists of 16kb windows. + unsigned windowIdx = regionStart >> 14; // Linear index consists of 16kb windows. uint64_t linearMinOffset = 0; if (windowIdx >= length(index._linearIndices[refId])) { @@ -298,24 +303,43 @@ jumpToRegion(FormattedFile & bamFile, readRecord(record, bamFile); // std::cerr << "record.beginPos == " << record.beginPos << "\n"; - // int32_t endPos = record.beginPos + getAlignmentLengthInRef(record); if (record.rID != refId) continue; // Wrong contig. - if (!hasAlignments || record.beginPos <= pos) + + if (record.beginPos <= regionStart) { - // Found a valid alignment. - hasAlignments = true; offset = *candIt; } - if (record.beginPos >= posEnd) + if (record.beginPos >= regionEnd) break; // Cannot find overlapping any more. } - if (offset != MaxValue::VALUE) - setPosition(bamFile, offset); + if (offset == std::numeric_limits::max()) + return true; // Finding no overlapping alignment is not an error, hasAlignments is false. + + // Now only the right most offset was found but it is not ensured that the + // alignment at the start of the offset lies inside the region. + // Therefore we must advance further or until the region ends. + setPosition(bamFile, offset); + + while (!atEnd(bamFile)) + { + auto seek_pos = position(bamFile); // store current pos to reset bamFile if necessary + + readRecord(record, bamFile); + + if (record.beginPos >= regionEnd) + break; + + if (record.beginPos >= regionStart) + { + hasAlignments = true; + setPosition(bamFile, seek_pos); + break; + } + } - // Finding no overlapping alignment is not an error, hasAlignments is false. return true; } @@ -345,19 +369,19 @@ bool jumpToOrphans(FormattedFile & bamFile, hasAlignments = false; // Search linear indices for the largest entry of all references. - uint64_t aliOffset = MaxValue::VALUE; + uint64_t aliOffset = std::numeric_limits::max(); for (int i = length(index._linearIndices) - 1; i >= 0; --i) if (!empty(index._linearIndices[i])) { aliOffset = back(index._linearIndices[i]); break; } - if (aliOffset == MaxValue::VALUE) + if (aliOffset == std::numeric_limits::max()) return false; // No offset found. // Get index of the first orphan alignment by seeking from linear index bucket. BamAlignmentRecord record; - uint64_t offset = MaxValue::VALUE; + uint64_t offset = std::numeric_limits::max(); uint64_t result = 0; if (!setPosition(bamFile, aliOffset)) return false; // Error while seeking. @@ -375,7 +399,7 @@ bool jumpToOrphans(FormattedFile & bamFile, } // Jump back to the first alignment. - if (offset != MaxValue::VALUE) + if (offset != std::numeric_limits::max()) { if (!setPosition(bamFile, offset)) return false; // Error while seeking. @@ -440,6 +464,7 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&nRef), 4); if (!fin.good()) return false; + enforceLittleEndian(nRef); resize(index._linearIndices, nRef); resize(index._binIndices, nRef); @@ -451,6 +476,7 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&nBin), 4); if (!fin.good()) return false; + enforceLittleEndian(nBin); index._binIndices[i].clear(); BaiBamIndexBinData_ data; for (int j = 0; j < nBin; ++j) // For each bin. @@ -461,11 +487,13 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&bin), 4); if (!fin.good()) return false; + enforceLittleEndian(bin); int32_t nChunk = 0; fin.read(reinterpret_cast(&nChunk), 4); if (!fin.good()) return false; + enforceLittleEndian(nChunk); reserve(data.chunkBegEnds, nChunk); for (int k = 0; k < nChunk; ++k) // For each chunk; { @@ -475,6 +503,8 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&chunkEnd), 8); if (!fin.good()) return false; + enforceLittleEndian(chunkBeg); + enforceLittleEndian(chunkEnd); appendValue(data.chunkBegEnds, Pair(chunkBeg, chunkEnd)); } @@ -487,6 +517,7 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&nIntv), 4); if (!fin.good()) return false; + enforceLittleEndian(nIntv); clear(index._linearIndices[i]); reserve(index._linearIndices[i], nIntv); for (int j = 0; j < nIntv; ++j) @@ -495,6 +526,7 @@ open(BamIndex & index, char const * filename) fin.read(reinterpret_cast(&ioffset), 8); if (!fin.good()) return false; + enforceLittleEndian(ioffset); appendValue(index._linearIndices[i], ioffset); } } @@ -510,6 +542,7 @@ open(BamIndex & index, char const * filename) fin.clear(); nNoCoord = 0; } + enforceLittleEndian(nNoCoord); index._unalignedCount = nNoCoord; return true; @@ -549,6 +582,7 @@ inline bool save(BamIndex const & index, char const * baiFilename) // Write header. out.write("BAI\1", 4); int32_t numRefSeqs = length(index._binIndices); + enforceLittleEndian(numRefSeqs); out.write(reinterpret_cast(&numRefSeqs), 4); // Write out indices. @@ -556,42 +590,59 @@ inline bool save(BamIndex const & index, char const * baiFilename) typedef TBamIndex::TBinIndex_ const TBinIndex; typedef TBinIndex::const_iterator TBinIndexIter; typedef TBamIndex::TLinearIndex_ TLinearIndex; - for (int i = 0; i < numRefSeqs; ++i) + for (unsigned i = 0; i < length(index._binIndices); ++i) { TBinIndex const & binIndex = index._binIndices[i]; TLinearIndex const & linearIndex = index._linearIndices[i]; // Write out binning index. int32_t numBins = binIndex.size(); + enforceLittleEndian(numBins); out.write(reinterpret_cast(&numBins), 4); for (TBinIndexIter itB = binIndex.begin(), itBEnd = binIndex.end(); itB != itBEnd; ++itB) { // Write out bin id. - out.write(reinterpret_cast(&itB->first), 4); + uint32_t tmp = itB->first; + enforceLittleEndian(tmp); + out.write(reinterpret_cast(&tmp), 4); // Write out number of chunks. uint32_t numChunks = length(itB->second.chunkBegEnds); + enforceLittleEndian(numChunks); out.write(reinterpret_cast(&numChunks), 4); // Write out all chunks. typedef Iterator > const, Rooted>::Type TChunkIter; for (TChunkIter itC = begin(itB->second.chunkBegEnds); !atEnd(itC); goNext(itC)) { - out.write(reinterpret_cast(&itC->i1), 8); - out.write(reinterpret_cast(&itC->i2), 8); + uint64_t tmp1 = itC->i1; + enforceLittleEndian(tmp1); + uint64_t tmp2 = itC->i2; + enforceLittleEndian(tmp2); + out.write(reinterpret_cast(&tmp1), 8); + out.write(reinterpret_cast(&tmp2), 8); } } // Write out linear index. int32_t numIntervals = length(linearIndex); + enforceLittleEndian(numIntervals); out.write(reinterpret_cast(&numIntervals), 4); typedef Iterator const, Rooted>::Type TLinearIndexIter; for (TLinearIndexIter it = begin(linearIndex, Rooted()); !atEnd(it); goNext(it)) - out.write(reinterpret_cast(&*it), 8); + { + uint64_t tmp = *it; + enforceLittleEndian(tmp); + out.write(reinterpret_cast(&tmp), 8); + } } // Write the number of unaligned reads if set. //std::cerr << "UNALIGNED\t" << index._unalignedCount << std::endl; - if (index._unalignedCount != maxValue()) - out.write(reinterpret_cast(&index._unalignedCount), 8); + if (index._unalignedCount != std::numeric_limits::max()) + { + uint64_t tmp = index._unalignedCount; + enforceLittleEndian(tmp); + out.write(reinterpret_cast(&tmp), 8); + } return out.good(); // false on error, true on success. } @@ -656,13 +707,13 @@ inline bool build(BamIndex & index, char const * bamFilename) // Scan over BAM file and create index. BamAlignmentRecord record; - uint32_t currBin = maxValue(); - uint32_t prevBin = maxValue(); + uint32_t currBin = std::numeric_limits::max(); + uint32_t prevBin = std::numeric_limits::max(); int32_t currRefId = BamAlignmentRecord::INVALID_REFID; int32_t prevRefId = BamAlignmentRecord::INVALID_REFID; uint64_t currOffset = position(bamFile); uint64_t prevOffset = currOffset; - int32_t prevPos = minValue(); + int32_t prevPos = std::numeric_limits::min(); while (!atEnd(bamFile)) { @@ -710,7 +761,7 @@ inline bool build(BamIndex & index, char const * bamFilename) // Update reference book keeping. prevRefId = record.rID; - prevBin = minValue(); + prevBin = std::numeric_limits::min(); } // If the alignment's reference id is valid and its bin is not a leaf. @@ -736,7 +787,7 @@ inline bool build(BamIndex & index, char const * bamFilename) if (record.bin != prevBin) { // If not first bin of reference, save previous bin data. - if (currBin != maxValue()) + if (currBin != std::numeric_limits::max()) _baiAddAlignmentChunkToBin(index, currBin, currOffset, prevOffset); // Update markers. diff --git a/porechop/include/seqan/bam_io/bam_io_context.h b/porechop/include/seqan/bam_io/bam_io_context.h index 3bdf2e3..a4808ab 100644 --- a/porechop/include/seqan/bam_io/bam_io_context.h +++ b/porechop/include/seqan/bam_io/bam_io_context.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/bam_io/bam_sam_conversion.h b/porechop/include/seqan/bam_io/bam_sam_conversion.h index 4cec8de..90e090b 100644 --- a/porechop/include/seqan/bam_io/bam_sam_conversion.h +++ b/porechop/include/seqan/bam_io/bam_sam_conversion.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -128,7 +128,7 @@ void _appendTagsSamToBamOneTag(TTarget & target, TForwardIter & iter, CharString ++nEntries; // Write out array length. - appendRawPod(target, (uint32_t)nEntries); + appendRawPod(target, nEntries); // Write out array values. size_t startPos = 1; @@ -233,7 +233,9 @@ struct AssignTagsBamToSamOneTagHelper_ if (BamTypeChar::VALUE != typeC) return false; - appendNumber(target, reinterpret_cast(*it)); + Type tmp = *reinterpret_cast(&*it); + enforceLittleEndian(tmp); + appendNumber(target, tmp); it += sizeof(Type); return true; } @@ -299,14 +301,15 @@ void _appendTagsBamToSamOneTag(TTarget & target, TSourceIter & it) // Read array length. union { char raw[4]; - unsigned len; + uint32_t len; } tmp; - for (unsigned i = 0; i < 4; ++i) + for (uint32_t i = 0; i < 4; ++i) { SEQAN_ASSERT_NOT(atEnd(it)); tmp.raw[i] = *it++; } - for (unsigned i = 0; i < tmp.len; ++i) + enforceLittleEndian(tmp.len); + for (uint32_t i = 0; i < tmp.len; ++i) { writeValue(target, ','); if (!tagApply(func, BamTagTypes())) diff --git a/porechop/include/seqan/bam_io/bam_scanner_cache.h b/porechop/include/seqan/bam_io/bam_scanner_cache.h index bbc1f42..9fe8bc8 100644 --- a/porechop/include/seqan/bam_io/bam_scanner_cache.h +++ b/porechop/include/seqan/bam_io/bam_scanner_cache.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/bam_io/bam_tags_dict.h b/porechop/include/seqan/bam_io/bam_tags_dict.h index 05ddae5..cbb21e3 100644 --- a/porechop/include/seqan/bam_io/bam_tags_dict.h +++ b/porechop/include/seqan/bam_io/bam_tags_dict.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -302,6 +302,7 @@ buildIndex(BamTagsDict const & bamTags) uint32_t len; } tmp; arrayCopyForward(it, it + 4, tmp.raw); + enforceLittleEndian(tmp.len); it += 4 + tmp.len * getBamTypeSize(c); } else @@ -492,6 +493,7 @@ struct ExtractTagValueHelper_ } tmp; arrayCopyForward(rawIter, rawIter + sizeof(Type), tmp.raw); + enforceLittleEndian(tmp.i); result = static_cast(tmp.i); return true; } @@ -666,6 +668,7 @@ struct ToBamTagValueHelper_ } tmp; tmp.i = static_cast(val); + enforceLittleEndian(tmp.i); append(result, toRange(&tmp.raw[0], &tmp.raw[sizeof(Type)])); return true; } diff --git a/porechop/include/seqan/bam_io/cigar.h b/porechop/include/seqan/bam_io/cigar.h index 8a61fef..1d6df11 100644 --- a/porechop/include/seqan/bam_io/cigar.h +++ b/porechop/include/seqan/bam_io/cigar.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/bam_io/read_bam.h b/porechop/include/seqan/bam_io/read_bam.h index 71059c8..b655c9f 100644 --- a/porechop/include/seqan/bam_io/read_bam.h +++ b/porechop/include/seqan/bam_io/read_bam.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -207,6 +207,7 @@ readRecord(BamAlignmentRecord & record, // BamAlignmentRecordCore. arrayCopyForward(it, it + sizeof(BamAlignmentRecordCore), reinterpret_cast(&record)); + enforceLittleEndian(*reinterpret_cast(&record)); it += sizeof(BamAlignmentRecordCore); remainingBytes -= sizeof(BamAlignmentRecordCore) + record._l_qname + @@ -236,7 +237,7 @@ readRecord(BamAlignmentRecord & record, TCigarIter cigEnd = end(record.cigar, Standard()); for (TCigarIter cig = begin(record.cigar, Standard()); cig != cigEnd; ++cig) { - unsigned opAndCnt; + uint32_t opAndCnt; readRawPod(opAndCnt, it); SEQAN_ASSERT_LEQ(opAndCnt & 15, 8u); cig->operation = CIGAR_MAPPING[opAndCnt & 15]; @@ -251,9 +252,9 @@ readRecord(BamAlignmentRecord & record, { unsigned char ui = getValue(it); ++it; - assignValue(sit, Iupac(ui >> 4)); + *sit = Iupac(ui >> 4); ++sit; - assignValue(sit, Iupac(ui & 0x0f)); + *sit = Iupac(ui & 0x0f); ++sit; } if (record._l_qseq & 1) @@ -266,7 +267,7 @@ readRecord(BamAlignmentRecord & record, TQualIter qitEnd = end(record.qual, Standard()); for (TQualIter qit = begin(record.qual, Standard()); qit != qitEnd;) *qit++ = '!' + *it++; - if (!empty(record.qual) && record.qual[0] == '\xff') + if (!empty(record.qual) && static_cast(record.qual[0] - '!') == '\xff') clear(record.qual); // tags diff --git a/porechop/include/seqan/bam_io/read_sam.h b/porechop/include/seqan/bam_io/read_sam.h index ad30a46..6b21cf9 100644 --- a/porechop/include/seqan/bam_io/read_sam.h +++ b/porechop/include/seqan/bam_io/read_sam.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -353,7 +353,7 @@ readRecord(BamAlignmentRecord & record, // TLEN if (value(iter) == '*') { - record.tLen = MaxValue::VALUE; + record.tLen = std::numeric_limits::max(); skipOne(iter); } else diff --git a/porechop/include/seqan/bam_io/write_bam.h b/porechop/include/seqan/bam_io/write_bam.h index 6eb1e1c..1578dba 100644 --- a/porechop/include/seqan/bam_io/write_bam.h +++ b/porechop/include/seqan/bam_io/write_bam.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/bam_io/write_sam.h b/porechop/include/seqan/bam_io/write_sam.h index 3191e9a..a8b51ba 100644 --- a/porechop/include/seqan/bam_io/write_sam.h +++ b/porechop/include/seqan/bam_io/write_sam.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic.h b/porechop/include/seqan/basic.h index 0cf12db..cd83b1b 100644 --- a/porechop/include/seqan/basic.h +++ b/porechop/include/seqan/basic.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -106,7 +106,4 @@ // Basic device metafunctions. #include -// Basic SIMD vector implementation using intrinsics. -#include - #endif // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_H_ diff --git a/porechop/include/seqan/basic/aggregate_concept.h b/porechop/include/seqan/basic/aggregate_concept.h index f79a7d1..d23f2d0 100644 --- a/porechop/include/seqan/basic/aggregate_concept.h +++ b/porechop/include/seqan/basic/aggregate_concept.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/allocator_chunkpool.h b/porechop/include/seqan/basic/allocator_chunkpool.h index d41f433..f8cae4f 100644 --- a/porechop/include/seqan/basic/allocator_chunkpool.h +++ b/porechop/include/seqan/basic/allocator_chunkpool.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/allocator_interface.h b/porechop/include/seqan/basic/allocator_interface.h index 41d7169..a90b401 100644 --- a/porechop/include/seqan/basic/allocator_interface.h +++ b/porechop/include/seqan/basic/allocator_interface.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -200,34 +200,18 @@ allocate(T const &, #else data = (TValue *) malloc(count * sizeof(TValue)); #endif*/ - data = (TValue *) operator new(count * sizeof(TValue)); -#endif - -#ifdef SEQAN_PROFILE - if (data) - SEQAN_PROADD(SEQAN_PROMEMORY, count * sizeof(TValue)); -#endif -} - -template -inline void -allocate(T &, - TValue * & data, - TSize count, - Tag const &) -{ -// data = (TValue *) operator new(count * sizeof(TValue)); -#ifdef STDLIB_VS - data = (TValue *) _aligned_malloc(count * sizeof(TValue), __alignof(TValue)); -#else -/*#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 - const size_t align = (__alignof__(TValue) < sizeof(void*)) ? sizeof(void*) : __alignof__(TValue); - if (posix_memalign(&(void* &)data, align, count * sizeof(TValue))) - data = NULL; -#else - data = (TValue *) malloc(count * sizeof(TValue)); -#endif*/ - data = (TValue *) operator new(count * sizeof(TValue)); +// suppress -Walloc-size-larger-than= warning; a simple static_cast does not work +// a working solution would be to downcast std::size_t to unsigned, but this +// would loose information; thus disabling this for gcc 7 and upwards + SEQAN_ASSERT_LEQ(static_cast(count), std::numeric_limits::max() / sizeof(TValue)); +# if defined(COMPILER_GCC) && __GNUC__ >= 7 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Walloc-size-larger-than=" +# endif //COMPILER_GCC + data = (TValue *) operator new(count * sizeof(TValue)); +# if defined(COMPILER_GCC) && __GNUC__ >= 7 +# pragma GCC diagnostic pop +# endif //COMPILER_GCC #endif #ifdef SEQAN_PROFILE diff --git a/porechop/include/seqan/basic/allocator_multipool.h b/porechop/include/seqan/basic/allocator_multipool.h index a93cbd1..8b0932a 100644 --- a/porechop/include/seqan/basic/allocator_multipool.h +++ b/porechop/include/seqan/basic/allocator_multipool.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/allocator_simple.h b/porechop/include/seqan/basic/allocator_simple.h index 37d45ce..09ec3b1 100644 --- a/porechop/include/seqan/basic/allocator_simple.h +++ b/porechop/include/seqan/basic/allocator_simple.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/allocator_singlepool.h b/porechop/include/seqan/basic/allocator_singlepool.h index 314cdab..c037b99 100644 --- a/porechop/include/seqan/basic/allocator_singlepool.h +++ b/porechop/include/seqan/basic/allocator_singlepool.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/allocator_to_std.h b/porechop/include/seqan/basic/allocator_to_std.h index b7d07a5..981dbb3 100644 --- a/porechop/include/seqan/basic/allocator_to_std.h +++ b/porechop/include/seqan/basic/allocator_to_std.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/alphabet_adapt_builtins.h b/porechop/include/seqan/basic/alphabet_adapt_builtins.h index a5db639..7fdeff1 100644 --- a/porechop/include/seqan/basic/alphabet_adapt_builtins.h +++ b/porechop/include/seqan/basic/alphabet_adapt_builtins.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -171,13 +171,15 @@ unknownValueImpl(char const *) // ---------------------------------------------------------------------------- template +[[deprecated("Use std::numeric_limits::max() instead.")]] inline T const & supremumValueImpl(T *) { - static T const x = MaxValue::VALUE; + static T const x = std::numeric_limits::max(); return x; } +[[deprecated("Use std::numeric_limits::max() instead.")]] inline long double const & supremumValueImpl(long double *) { @@ -185,12 +187,15 @@ supremumValueImpl(long double *) return _value; } +[[deprecated("Use std::numeric_limits::max() instead.")]] inline double const & supremumValueImpl(double *) { static double const _value = std::numeric_limits::infinity( ); return _value; } + +[[deprecated("Use std::numeric_limits::max() instead.")]] inline float const & supremumValueImpl(float *) { @@ -203,13 +208,15 @@ supremumValueImpl(float *) // ---------------------------------------------------------------------------- template +[[deprecated("Use std::numeric_limits::min() instead.")]] inline T const & infimumValueImpl(T *) { - static T const x = MinValue::VALUE; + static T const x = std::numeric_limits::min(); return x; } +[[deprecated("Use std::numeric_limits::min() instead.")]] inline float const & infimumValueImpl(float *) { @@ -217,6 +224,7 @@ infimumValueImpl(float *) return _value; } +[[deprecated("Use std::numeric_limits::min() instead.")]] inline double const & infimumValueImpl(double *) { @@ -224,6 +232,7 @@ infimumValueImpl(double *) return _value; } +[[deprecated("Use std::numeric_limits::min() instead.")]] inline long double const & infimumValueImpl(long double *) { diff --git a/porechop/include/seqan/basic/alphabet_bio.h b/porechop/include/seqan/basic/alphabet_bio.h index 0339e34..701e82e 100644 --- a/porechop/include/seqan/basic/alphabet_bio.h +++ b/porechop/include/seqan/basic/alphabet_bio.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/alphabet_concept.h b/porechop/include/seqan/basic/alphabet_concept.h index 50e5164..c8a9206 100644 --- a/porechop/include/seqan/basic/alphabet_concept.h +++ b/porechop/include/seqan/basic/alphabet_concept.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -171,7 +171,7 @@ SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructibl * * @section Status * - * Deprecated, will be removed in favour of OrderedAlphabetConcept#MaxValue. + * @deprecated Will be removed in favour of MaxValue. * * @see OrderedAlphabetConcept#maxValue */ @@ -191,7 +191,7 @@ SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructibl * * @section Status * - * Deprecated, will be removed in favour of MaxValue. + * @deprecated Will be removed in favour of MaxValue. * * @see OrderedAlphabetConcept#supremumValueImpl * @see OrderedAlphabetConcept#minValue @@ -213,7 +213,7 @@ SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructibl * * @section Status * - * Deprecated, will be removed in favour of MinValue. + * @deprecated Will be removed in favour of MinValue. * * @see OrderedAlphabetConcept#minValue */ @@ -233,7 +233,7 @@ SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructibl * * @section Status * - * Deprecated, will be removed in favour of MinValue. + * @deprecated Will be removed in favour of MinValue. * * @see OrderedAlphabetConcept#infimumValueImpl * @see OrderedAlphabetConcept#maxValue @@ -243,10 +243,10 @@ SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructibl // Forwards for Metafunctions and Functions. template struct MinValue; template struct MaxValue; -template T const & minValue(); -template T const & minValue(T); -template T const & maxValue(); -template T const & maxValue(T); +template T minValue(); +template T minValue(T); +template T maxValue(); +template T maxValue(T); SEQAN_CONCEPT_REFINE(OrderedAlphabetConcept, (TValue), (AlphabetConcept)(Comparable)) { @@ -255,11 +255,11 @@ SEQAN_CONCEPT_REFINE(OrderedAlphabetConcept, (TValue), (AlphabetConcept)(Compara SEQAN_CONCEPT_USAGE(OrderedAlphabetConcept) { // type consistency checks - sameType(minValue(val), val); - sameType(minValue(), val); + // sameType(minValue(val), val); // minValue() is deprecated + // sameType(minValue(), val); // minValue() is deprecated sameType(MinValue::VALUE, val); - sameType(maxValue(val), val); - sameType(maxValue(), val); + // sameType(maxValue(val), val); // maxValue() is deprecated + // sameType(maxValue(), val); // maxValue() is deprecated sameType(MaxValue::VALUE, val); // TODO(holtgrew): This does not work in C++98, we need C++11 with constexpr. diff --git a/porechop/include/seqan/basic/alphabet_math.h b/porechop/include/seqan/basic/alphabet_math.h index c77afdb..7031bc4 100644 --- a/porechop/include/seqan/basic/alphabet_math.h +++ b/porechop/include/seqan/basic/alphabet_math.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -211,7 +211,7 @@ unsigned char toUpperValue(unsigned char c) // Function supremumValueImpl // ---------------------------------------------------------------------------- -template inline T const & supremumValueImpl(T *); +template [[deprecated("Use std::numeric_limits::max() instead.")]] inline T const & supremumValueImpl(T *); // ---------------------------------------------------------------------------- // Function maxValue @@ -220,26 +220,26 @@ template inline T const & supremumValueImpl(T *); // Forward to supremumValueImpl() only. template -inline T const & +[[deprecated("Use std::numeric_limits::max() instead.")]] +inline T maxValue() { - T * _tag = 0; - return supremumValueImpl(_tag); + return std::numeric_limits::max(); } template -inline T const & +[[deprecated("Use std::numeric_limits::max() instead.")]] +inline T maxValue(T /*tag*/) { - T * _tag = 0; - return supremumValueImpl(_tag); + return std::numeric_limits::max(); } // ---------------------------------------------------------------------------- // Function infimumValueImpl // ---------------------------------------------------------------------------- -template inline T const & infimumValueImpl(T *); +template [[deprecated("Use std::numeric_limits::min() instead.")]] inline T const & infimumValueImpl(T *); // ---------------------------------------------------------------------------- // Function minValue @@ -248,19 +248,19 @@ template inline T const & infimumValueImpl(T *); // Forward to infimumValueImpl() only. template -inline T const & +[[deprecated("Use std::numeric_limits::min() instead.")]] +inline T minValue() { - T * _tag = 0; - return infimumValueImpl(_tag); + return std::numeric_limits::min(); } template -inline T const & +[[deprecated("Use std::numeric_limits::min() instead.")]] +inline T minValue(T /*tag*/) { - T * _tag = 0; - return infimumValueImpl(_tag); + return std::numeric_limits::min(); } // ---------------------------------------------------------------------------- diff --git a/porechop/include/seqan/basic/alphabet_profile.h b/porechop/include/seqan/basic/alphabet_profile.h index ac81662..52d4d05 100644 --- a/porechop/include/seqan/basic/alphabet_profile.h +++ b/porechop/include/seqan/basic/alphabet_profile.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/alphabet_qualities.h b/porechop/include/seqan/basic/alphabet_qualities.h index b3b79de..d249279 100644 --- a/porechop/include/seqan/basic/alphabet_qualities.h +++ b/porechop/include/seqan/basic/alphabet_qualities.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/alphabet_residue.h b/porechop/include/seqan/basic/alphabet_residue.h index fae9710..7033a45 100644 --- a/porechop/include/seqan/basic/alphabet_residue.h +++ b/porechop/include/seqan/basic/alphabet_residue.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -767,6 +767,17 @@ inline void assign(Rna & target, char c_source) target.value = TranslateTableCharToDna_<>::VALUE[(unsigned char)c_source]; } +template <> +struct CompareTypeImpl +{ + typedef Rna5 Type; +}; + +inline void assign(Rna5 & target, Iupac const & source) +{ + target.value = TranslateTableIupacToDna5_<>::VALUE[source.value]; +} + template <> struct CompareTypeImpl { diff --git a/porechop/include/seqan/basic/alphabet_residue_tabs.h b/porechop/include/seqan/basic/alphabet_residue_tabs.h index ca2f439..ef3dd49 100644 --- a/porechop/include/seqan/basic/alphabet_residue_tabs.h +++ b/porechop/include/seqan/basic/alphabet_residue_tabs.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/alphabet_simple_type.h b/porechop/include/seqan/basic/alphabet_simple_type.h index f4955fc..8e4fb0e 100644 --- a/porechop/include/seqan/basic/alphabet_simple_type.h +++ b/porechop/include/seqan/basic/alphabet_simple_type.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -135,26 +135,20 @@ class SimpleType // Members; Have to be defined in class. // ------------------------------------------------------------------------ - TValue value; + TValue value{0}; // ------------------------------------------------------------------------ // Constructors; Have to be defined in class. // ------------------------------------------------------------------------ // TODO(holtgrew): Do we want default initialization? - - SimpleType() : value(0) - {} - - - SimpleType(SimpleType const & other) - { - assign(*this, other); - } + SimpleType() = default; + SimpleType(SimpleType const &) = default; + SimpleType(SimpleType &&) = default; + ~SimpleType() = default; // TODO(holtgrew): Do we want an explicit here? template - SimpleType(T const & other) { assign(*this, other); @@ -163,13 +157,8 @@ class SimpleType // ------------------------------------------------------------------------ // Assignment Operator; Have to be defined in class. // ------------------------------------------------------------------------ - - - SimpleType & operator=(SimpleType const & other) - { - assign(*this, other); - return *this; - } + SimpleType & operator=(SimpleType const &) = default; + SimpleType & operator=(SimpleType &&) = default; template inline SimpleType & @@ -264,6 +253,67 @@ class SimpleType }; #pragma pack(pop) +} // namespace seqan + +// ---------------------------------------------------------------------------- +// Class numeric_limits +// ---------------------------------------------------------------------------- +namespace std +{ + +template +class numeric_limits > +{ +public: + static constexpr bool is_specialized = true; + static constexpr bool is_signed = false; + static constexpr bool is_integer = false; + static constexpr bool is_exact = true; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr float_round_style round_style = round_toward_zero; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulu = false; + static constexpr int digits = seqan::BitsPerValue>::VALUE; + static constexpr int digits10 = digits - 1; + static constexpr int max_digits10 = 0; + static constexpr int radix = 2; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + + static constexpr seqan::SimpleType min() + { + return seqan::SimpleType(0); + } + + static constexpr seqan::SimpleType max() + { + return seqan::SimpleType(((TValue)seqan::ValueSize >::VALUE - 1)); + } + + static constexpr seqan::SimpleType lowest() + { + return seqan::SimpleType(0); + } + + static constexpr seqan::SimpleType infinity() + { + return seqan::SimpleType(((TValue)seqan::ValueSize >::VALUE - 1)); + } +}; + +} //namespace std + +namespace seqan +{ // ============================================================================ // Metafunctions // ============================================================================ @@ -319,7 +369,7 @@ struct MinValue > }; template -const SimpleType MinValue >::VALUE = SimpleType(0); +const SimpleType MinValue >::VALUE = std::numeric_limits>::min(); template inline SimpleType const & @@ -339,7 +389,7 @@ struct MaxValue > }; template -const SimpleType MaxValue >::VALUE = SimpleType(((TValue)ValueSize >::VALUE - 1)); +const SimpleType MaxValue >::VALUE = std::numeric_limits>::max(); template inline SimpleType const & diff --git a/porechop/include/seqan/basic/alphabet_storage.h b/porechop/include/seqan/basic/alphabet_storage.h index 53a5df3..da54a45 100644 --- a/porechop/include/seqan/basic/alphabet_storage.h +++ b/porechop/include/seqan/basic/alphabet_storage.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/array_construct_destruct.h b/porechop/include/seqan/basic/array_construct_destruct.h index cb83d7a..3cf5aab 100644 --- a/porechop/include/seqan/basic/array_construct_destruct.h +++ b/porechop/include/seqan/basic/array_construct_destruct.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -460,9 +460,7 @@ _arrayConstructCopyDefault(TSource1 source_begin, { while (source_begin != source_end) { - // NOTE(holtgrew): getValue() is used here since value() could return - // a proxy! - valueConstruct(target_begin, getValue(source_begin)); + valueConstruct(target_begin, *source_begin); ++source_begin; ++target_begin; } diff --git a/porechop/include/seqan/basic/basic_aggregate.h b/porechop/include/seqan/basic/basic_aggregate.h index e0998f7..aa23d45 100644 --- a/porechop/include/seqan/basic/basic_aggregate.h +++ b/porechop/include/seqan/basic/basic_aggregate.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_allocator.h b/porechop/include/seqan/basic/basic_allocator.h index 1a3f609..05c53d2 100644 --- a/porechop/include/seqan/basic/basic_allocator.h +++ b/porechop/include/seqan/basic/basic_allocator.h @@ -1,7 +1,7 @@ // ========================================================================== // basic_allocator.h // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_alphabet.h b/porechop/include/seqan/basic/basic_alphabet.h index 91da52a..b71360a 100644 --- a/porechop/include/seqan/basic/basic_alphabet.h +++ b/porechop/include/seqan/basic/basic_alphabet.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_concept.h b/porechop/include/seqan/basic/basic_concept.h index 5fb0376..e2871c2 100644 --- a/porechop/include/seqan/basic/basic_concept.h +++ b/porechop/include/seqan/basic/basic_concept.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_container.h b/porechop/include/seqan/basic/basic_container.h index d8f8bf0..ffea681 100644 --- a/porechop/include/seqan/basic/basic_container.h +++ b/porechop/include/seqan/basic/basic_container.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_debug.h b/porechop/include/seqan/basic/basic_debug.h index 3b0aefe..4263268 100644 --- a/porechop/include/seqan/basic/basic_debug.h +++ b/porechop/include/seqan/basic/basic_debug.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_exception.h b/porechop/include/seqan/basic/basic_exception.h index 8a5a95a..0166a0b 100644 --- a/porechop/include/seqan/basic/basic_exception.h +++ b/porechop/include/seqan/basic/basic_exception.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -369,7 +369,7 @@ inline static void globalExceptionHandler() } // Install global exception handler. -static const std::terminate_handler SEQAN_UNUSED _globalExceptionHandler = std::set_terminate(globalExceptionHandler); +static const std::terminate_handler _globalExceptionHandler SEQAN_UNUSED = std::set_terminate(globalExceptionHandler); #endif // #if defined(SEQAN_EXCEPTIONS) && defined(SEQAN_GLOBAL_EXCEPTION_HANDLER) diff --git a/porechop/include/seqan/basic/basic_functors.h b/porechop/include/seqan/basic/basic_functors.h index 6633709..b26d606 100644 --- a/porechop/include/seqan/basic/basic_functors.h +++ b/porechop/include/seqan/basic/basic_functors.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_fundamental.h b/porechop/include/seqan/basic/basic_fundamental.h index b60abdc..5fec637 100644 --- a/porechop/include/seqan/basic/basic_fundamental.h +++ b/porechop/include/seqan/basic/basic_fundamental.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_iterator.h b/porechop/include/seqan/basic/basic_iterator.h index 82a1ecc..5adadd6 100644 --- a/porechop/include/seqan/basic/basic_iterator.h +++ b/porechop/include/seqan/basic/basic_iterator.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_math.h b/porechop/include/seqan/basic/basic_math.h index a9473b6..9a7e124 100644 --- a/porechop/include/seqan/basic/basic_math.h +++ b/porechop/include/seqan/basic/basic_math.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_metaprogramming.h b/porechop/include/seqan/basic/basic_metaprogramming.h index d620dcf..13d04a8 100644 --- a/porechop/include/seqan/basic/basic_metaprogramming.h +++ b/porechop/include/seqan/basic/basic_metaprogramming.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_parallelism.h b/porechop/include/seqan/basic/basic_parallelism.h index b96c43a..22b0461 100644 --- a/porechop/include/seqan/basic/basic_parallelism.h +++ b/porechop/include/seqan/basic/basic_parallelism.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_proxy.h b/porechop/include/seqan/basic/basic_proxy.h index fe6b711..e5bfb1d 100644 --- a/porechop/include/seqan/basic/basic_proxy.h +++ b/porechop/include/seqan/basic/basic_proxy.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_smart_pointer.h b/porechop/include/seqan/basic/basic_smart_pointer.h index deca95f..d28544d 100644 --- a/porechop/include/seqan/basic/basic_smart_pointer.h +++ b/porechop/include/seqan/basic/basic_smart_pointer.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_stream.h b/porechop/include/seqan/basic/basic_stream.h index e03dca2..b570852 100644 --- a/porechop/include/seqan/basic/basic_stream.h +++ b/porechop/include/seqan/basic/basic_stream.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -813,8 +813,9 @@ writeValue(TTargetValue * & iter, TValue val) template inline void _write(TTarget &target, TFwdIterator &iter, TSize n, TIChunk, TOChunk) { + typedef typename GetValue::Type TValue; for (; n > (TSize)0; --n, ++iter) - writeValue(target, getValue(iter)); + writeValue(target, static_cast(*iter)); } // ---------------------------------------------------------------------------- @@ -1190,18 +1191,38 @@ formattedNumber(const char *format, TValue const & val) template inline void -appendRawPod(TTarget & target, TValue const & val) +appendRawPodImpl(TTarget & target, TValue const & val) { write(target, (unsigned char*)&val, sizeof(TValue)); } template inline void -appendRawPod(TTargetValue * &ptr, TValue const & val) +appendRawPodImpl(TTargetValue * &ptr, TValue const & val) { *reinterpret_cast(ptr)++ = val; } +template +inline std::enable_if_t::value> +appendRawPod(TTarget & target, TValue val) +{ + enforceLittleEndian(val); + appendRawPodImpl(target, val); +} + +template +inline std::enable_if_t::value> +appendRawPod(SEQAN_UNUSED TTarget & target, SEQAN_UNUSED TValue const & val) +{ +#if SEQAN_BIG_ENDIAN + static_assert(std::is_arithmetic::value /*false*/, + "You are serialising a data structure on big endian architecture that needs a custom writer. THIS IS A BUG!"); +#else + appendRawPodImpl(target, val); +#endif +} + // ---------------------------------------------------------------------------- // Function write(TNumber); write fundamental type // ---------------------------------------------------------------------------- @@ -1258,7 +1279,7 @@ read(TTarget &target, TFwdIterator &iter, TSize n) { TSize i; for (i = 0; !atEnd(iter) && i < n; ++i, ++iter) - writeValue(target, value(iter)); + writeValue(target, *iter); return i; } diff --git a/porechop/include/seqan/basic/basic_tangle.h b/porechop/include/seqan/basic/basic_tangle.h index 4190559..d3c06ac 100644 --- a/porechop/include/seqan/basic/basic_tangle.h +++ b/porechop/include/seqan/basic/basic_tangle.h @@ -1,7 +1,7 @@ // ========================================================================== // basic_tangle.h // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/basic_type.h b/porechop/include/seqan/basic/basic_type.h index 1039a24..61d6837 100644 --- a/porechop/include/seqan/basic/basic_type.h +++ b/porechop/include/seqan/basic/basic_type.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // Copyright (c) 2013 NVIDIA Corporation // All rights reserved. // diff --git a/porechop/include/seqan/basic/boost_preprocessor_subset.h b/porechop/include/seqan/basic/boost_preprocessor_subset.h index 634568a..e7c1988 100644 --- a/porechop/include/seqan/basic/boost_preprocessor_subset.h +++ b/porechop/include/seqan/basic/boost_preprocessor_subset.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -4821,12 +4821,12 @@ // ==> boost/config/suffix.hpp <== // -------------------------------------------------------------------------- -// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001-2018 John Maddock // Copyright (c) 2001 Darin Adler // Copyright (c) 2001 Peter Dimov // Copyright (c) 2002 Bill Kempf // Copyright (c) 2002 Jens Maurer -// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2002-2018 David Abrahams // Copyright (c) 2003 Gennaro Prota // Copyright (c) 2003 Eric Friedman // Copyright (c) 2010 Eric Jourdanneau, Joel Falcou diff --git a/porechop/include/seqan/basic/builtin_functions.h b/porechop/include/seqan/basic/builtin_functions.h index a16edfb..d9688ed 100644 --- a/porechop/include/seqan/basic/builtin_functions.h +++ b/porechop/include/seqan/basic/builtin_functions.h @@ -1,7 +1,7 @@ // ========================================================================== // builtin_functions.h // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/concept_checking.h b/porechop/include/seqan/basic/concept_checking.h index 96dcc8a..18a3bd6 100644 --- a/porechop/include/seqan/basic/concept_checking.h +++ b/porechop/include/seqan/basic/concept_checking.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/container_concept.h b/porechop/include/seqan/basic/container_concept.h index 0836eda..1213dd2 100644 --- a/porechop/include/seqan/basic/container_concept.h +++ b/porechop/include/seqan/basic/container_concept.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/debug_helper.h b/porechop/include/seqan/basic/debug_helper.h index c171d7f..97f7e73 100644 --- a/porechop/include/seqan/basic/debug_helper.h +++ b/porechop/include/seqan/basic/debug_helper.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/debug_test_system.h b/porechop/include/seqan/basic/debug_test_system.h index d98d4e2..e2a121b 100644 --- a/porechop/include/seqan/basic/debug_test_system.h +++ b/porechop/include/seqan/basic/debug_test_system.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // Copyright (c) 2013 NVIDIA Corporation // All rights reserved. // @@ -114,7 +114,11 @@ // Set default for SEQAN_ENABLE_DEBUG. #ifndef SEQAN_ENABLE_DEBUG +#ifdef NDEBUG #define SEQAN_ENABLE_DEBUG 0 +#else +#define SEQAN_ENABLE_DEBUG 1 +#endif #endif // #ifndef SEQAN_ENABLE_DEBUG #if !SEQAN_ENABLE_DEBUG @@ -1731,10 +1735,10 @@ inline void fail() // This macro returns from the current function and logs a "skipped" // event for the current test. -#define SEQAN_SKIP_TEST \ - do { \ - ::seqan::ClassTest::skipCurrentTest(); \ - return; \ +#define SEQAN_SKIP_TEST \ + do { \ + ::seqan::ClassTest::skipCurrentTest(); \ + throw ::seqan::ClassTest::AssertionFailedException(); \ } while (false) #endif // #if SEQAN_ENABLE_TESTING @@ -2316,7 +2320,6 @@ inline void fail() #define SEQAN_PATH_TO_ROOT() \ ::seqan::ClassTest::StaticData::pathToRoot() - // Returns the POSIX int file handle to an open file. // TODO(holtgrewe): Uncomment if openTempFile has been implemented. // #define SEQAN_OPEN_TEMP_FILE() (::seqan::ClassTest::openTempFile()) @@ -2384,7 +2387,7 @@ inline void fail() inline std::string getAbsolutePath(const char * path) { - return std::string(SEQAN_PATH_TO_ROOT()) + "/" + path; + return std::string(::seqan::ClassTest::StaticData::pathToRoot()) + "/" + path; } } // namespace seqan diff --git a/porechop/include/seqan/basic/fundamental_chunking.h b/porechop/include/seqan/basic/fundamental_chunking.h index 9a58559..428343c 100644 --- a/porechop/include/seqan/basic/fundamental_chunking.h +++ b/porechop/include/seqan/basic/fundamental_chunking.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/fundamental_comparison.h b/porechop/include/seqan/basic/fundamental_comparison.h index ca13458..3dff852 100644 --- a/porechop/include/seqan/basic/fundamental_comparison.h +++ b/porechop/include/seqan/basic/fundamental_comparison.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/fundamental_concepts.h b/porechop/include/seqan/basic/fundamental_concepts.h index 5cf7646..d820741 100644 --- a/porechop/include/seqan/basic/fundamental_concepts.h +++ b/porechop/include/seqan/basic/fundamental_concepts.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -277,6 +277,7 @@ struct Is > : * @endcode * * @see DefaultConstructibleConcept + * @see MoveConstructibleConcept */ SEQAN_CONCEPT(CopyConstructible,(T)) @@ -299,6 +300,33 @@ SEQAN_CONCEPT(CopyConstructible,(T)) T b; }; +/*! + * @concept MoveConstructibleConcept + * @brief A type with a move-constructor. + * + * @headerfile + * + * @signature MoveConstructible + * + * @section Valid Expressions + * + * @code{.cpp} + * T a(rv); // rv is an rvalue expression of type T + * @endcode + * + * @see DefaultConstructibleConcept + * @see CopyConstructibleConcept + */ + +SEQAN_CONCEPT(MoveConstructible,(T)) +{ + SEQAN_CONCEPT_USAGE(MoveConstructible) + { + T a{T{}}; // require move constructor + ignoreUnusedVariableWarning(a); + } +}; + // ============================================================================ // Relation Concepts @@ -680,10 +708,10 @@ struct IsSignedInteger : Is< SignedIntegerConcept > {}; template struct IsUnsignedInteger : Is< UnsignedIntegerConcept > {}; template -struct IsInteger : Is< IntegerConcept > {}; +struct [[deprecated("Please use Is >::Type.")]] IsInteger : Is< IntegerConcept > {}; template -struct IsIntegral : IsInteger {}; +struct [[deprecated("Please use Is >::Type.")]] IsIntegral : Is< IntegerConcept > {}; // ============================================================================ // Concepts for integers diff --git a/porechop/include/seqan/basic/fundamental_conversion.h b/porechop/include/seqan/basic/fundamental_conversion.h index 6508247..af0b730 100644 --- a/porechop/include/seqan/basic/fundamental_conversion.h +++ b/porechop/include/seqan/basic/fundamental_conversion.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without diff --git a/porechop/include/seqan/basic/fundamental_metafunctions.h b/porechop/include/seqan/basic/fundamental_metafunctions.h index 7f3a702..86c9a3f 100644 --- a/porechop/include/seqan/basic/fundamental_metafunctions.h +++ b/porechop/include/seqan/basic/fundamental_metafunctions.h @@ -1,7 +1,7 @@ // ========================================================================== // SeqAn - The Library for Sequence Analysis // ========================================================================== -// Copyright (c) 2006-2016, Knut Reinert, FU Berlin +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -202,12 +202,24 @@ struct Spec typedef void Type; }; -// Case for one template argument. +// Case for variable number of template arguments. +// Note, that a spec by default should be the last template argument in SeqAn. +// This helper recursively reduces the template argument list to the last template argument. +template +struct GetSpecHelper_ : GetSpecHelper_ +{}; + +// Recursion anchor. +template +struct GetSpecHelper_<1, T1> +{ + using Type = T1; +}; -template