// ========================================================================== // 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 <rene.rahn@fu-berlin.de> // ========================================================================== // The dp scout is a structure that stores the current maximal score and its // host position in the underlying dp-matrix. // This class can be overloaded to implement different behaviors of tracking // the maximal score, e.g., for the split breakpoint computation. // ========================================================================== // Author: Hannes Hauswedell <hauswedell@mi.fu-berlin.de> // ========================================================================== // The terminator specialization of dp scout offers the possibility to have // dp generation stop, if specified criteria are met. // To do this, define HasTerminationCriterium_<> for your algorithm and // implement a DPScoutState for your terminator specialization. In your // overloaded _scoutBestScore() or _computeCell() you can call // terminateScout() on your Scout to have DP-generation stop. // see dp_scout_xdrop.h for an example. // ========================================================================== #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_TEST_ALIGNMENT_DP_SCOUT_H_ #define SEQAN_INCLUDE_SEQAN_ALIGN_TEST_ALIGNMENT_DP_SCOUT_H_ namespace seqan { // ============================================================================ // Forwards // ============================================================================ // ============================================================================ // Tags, Classes, Enums // ============================================================================ // ---------------------------------------------------------------------------- // Class Terminator_ // ---------------------------------------------------------------------------- template <typename TSpec = void> struct Terminator_; // ---------------------------------------------------------------------------- // Class DPScoutState_ // ---------------------------------------------------------------------------- template <typename TSpec> class DPScoutState_; template <> class DPScoutState_<Default> : public Nothing // empty member optimization {}; // ---------------------------------------------------------------------------- // Class DPScout_ // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> class DPScout_; // The default implementation of the dp scout simply stores one maximum // and its corresponding position. // // The state must be a Nothing and is left untouched and unused. template <typename TDPCell, typename TSpec> class DPScout_ { public: using TBase = DPScout_; using TScoreValue = typename Value<TDPCell>::Type; TDPCell _maxScore = TDPCell(); size_t _maxHostPosition = 0; // The corresponding host position within the underlying dp-matrix. DPScout_() = default; DPScout_(DPScoutState_<Default> const & /*state*/) {} }; // Terminator_ Specialization template <typename TDPCell, typename TSpec> class DPScout_<TDPCell, Terminator_<TSpec> > : public DPScout_<TDPCell, Default> { public: using TBase = DPScout_<TDPCell, Default>; DPScoutState_<Terminator_<TSpec> > * state = nullptr; bool terminationCriteriumMet = false; DPScout_() = default; DPScout_(DPScoutState_<Terminator_<TSpec> > & pState) : TBase(), state(&pState) {} }; // ============================================================================ // Metafunctions // ============================================================================ // ---------------------------------------------------------------------------- // Metafunction ScoutSpecForAlignmentAlgorithm_ // ---------------------------------------------------------------------------- // Given an alignment algorithm tag such as GlobalAlignment_ or LocalAlignment_, returns the specialization tag for the // corresponding DPScout_ specialization. template <typename TAlignmentAlgorithm, typename TScoutState> struct ScoutSpecForAlignmentAlgorithm_ { typedef If<HasTerminationCriterium_<TAlignmentAlgorithm>, Terminator_<>, Default> Type; }; // ---------------------------------------------------------------------------- // Metafunction ScoutStateSpecForScout_ // ---------------------------------------------------------------------------- // Given an dp scout this meta-function returns the appropriate specialization for the scout state. template <typename TScout> struct ScoutStateSpecForScout_ { typedef Default Type; }; // ============================================================================ // Functions // ============================================================================ // ---------------------------------------------------------------------------- // Function _scoutBestScore() // ---------------------------------------------------------------------------- // Tracks the new score, if it is the new maximum. template <typename TDPCell, typename TSpec, typename TTraceMatrixNavigator, typename TIsLastColumn, typename TIsLastRow> inline void _scoutBestScore(DPScout_<TDPCell, TSpec> & dpScout, TDPCell const & activeCell, TTraceMatrixNavigator const & navigator, TIsLastColumn const & /**/, TIsLastRow const & /**/) { if (_scoreOfCell(activeCell) > _scoreOfCell(dpScout._maxScore)) { dpScout._maxScore = activeCell; dpScout._maxHostPosition = position(navigator); } } // TODO(rmaerker): Why is this needed? template <typename TDPCell, typename TSpec, typename TTraceMatrixNavigator, typename TIsLastColumn> inline void _scoutBestScore(DPScout_<TDPCell, TSpec> & dpScout, TDPCell const & activeCell, TTraceMatrixNavigator const & navigator, TIsLastColumn const & /**/) { _scoutBestScore(dpScout, activeCell, navigator, TIsLastColumn(), False()); } // TODO(rmaerker): Why is this needed? template <typename TDPCell, typename TSpec, typename TTraceMatrixNavigator> inline void _scoutBestScore(DPScout_<TDPCell, TSpec> & dpScout, TDPCell const & activeCell, TTraceMatrixNavigator const & navigator) { _scoutBestScore(dpScout, activeCell, navigator, False(), False()); } // ---------------------------------------------------------------------------- // Function maxScore() // ---------------------------------------------------------------------------- // Returns the current maximal score. template <typename TDPCell, typename TScoutSpec> inline typename Value<TDPCell>::Type const maxScore(DPScout_<TDPCell, TScoutSpec> const & dpScout) { return _scoreOfCell(dpScout._maxScore); } // ---------------------------------------------------------------------------- // Function maxHostPosition() // ---------------------------------------------------------------------------- // Returns the host position that holds the current maximum score. template <typename TDPCell, typename TScoutSpec> inline auto maxHostPosition(DPScout_<TDPCell, TScoutSpec> const & dpScout) { return dpScout._maxHostPosition; } // ---------------------------------------------------------------------------- // Function _terminationCriteriumIsMet() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline bool _terminationCriteriumIsMet(DPScout_<TDPCell, Terminator_<TSpec> > const & scout) { return scout.terminationCriteriumMet; } // ---------------------------------------------------------------------------- // Function terminateScout() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void terminateScout(DPScout_<TDPCell, Terminator_<TSpec> > & scout) { scout.terminationCriteriumMet = true; } // ---------------------------------------------------------------------------- // Function _preInitScoutHorizontal() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _preInitScoutHorizontal(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function _reachedHorizontalEndPoint() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec, typename TIter> constexpr inline bool _reachedHorizontalEndPoint(DPScout_<TDPCell, TSpec> const & /*scout*/, TIter const & /*hIt*/) { return false; } // ---------------------------------------------------------------------------- // Function _preInitScoutVertical() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _preInitScoutVertical(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function _reachedVerticalEndPoint() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec, typename TIter> constexpr inline bool _reachedVerticalEndPoint(DPScout_<TDPCell, TSpec> const & /*scout*/, TIter const & /*iter*/) { return false; } // ---------------------------------------------------------------------------- // Function _nextHorizontalEndPos() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _nextHorizontalEndPos(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function _nextVerticalEndPos() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _nextVerticalEndPos(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function _incHorizontalPos() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _incHorizontalPos(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function _incVerticalPos() // ---------------------------------------------------------------------------- template <typename TDPCell, typename TSpec> inline void _incVerticalPos(DPScout_<TDPCell, TSpec> const & /*scout*/) { // no-op. } // ---------------------------------------------------------------------------- // Function swapStateIf() // ---------------------------------------------------------------------------- template <typename TSingleMaxState, typename TPredicate> 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_