// ========================================================================== // 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> // ========================================================================== // This class stores the band information as well as the meta-inforation, // whether a band was selected or not. // ========================================================================== #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_BAND_H_ #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_BAND_H_ namespace seqan { // ============================================================================ // Forwards // ============================================================================ // ============================================================================ // Tags, Classes, Enums // ============================================================================ /*! * @defgroup DPBandSwitch * @brief Tags used to switch between banded and unbanded alignment. * * @tag DPBandSwitch#BandOn * @brief Switches banded alignment on. * @headerfile <seqan/align.h> * @signature struct BandOn_; * @signature typedef Tag<BandOn_> BandOn; * * @tag DPBandSwitch#BandOff * @brief Switches banded alignment off. * @headerfile <seqan/align.h> * @signature struct BandOff_; * @signature typedef Tag<BandOff_> BandOff; */ // ---------------------------------------------------------------------------- // Tag BandOff // ---------------------------------------------------------------------------- // Used when computing unbanded alignments. struct BandOff_; typedef Tag<BandOff_> BandOff; // ---------------------------------------------------------------------------- // Tag BandOn // ---------------------------------------------------------------------------- // Used when computing banded alignments. struct BandOn_; typedef Tag<BandOn_> BandOn; // ---------------------------------------------------------------------------- // Class DPBandConfig // ---------------------------------------------------------------------------- /*! * @class DPBandConfig * @headerfile <seqan/align.h> * @brief Simple class to configure banded alignments. * * @signature template <typename TSwitch> * class DPBandConfig<TSwitch>; * * @tparam TSwitch Tag to switch between banded and unbanded alignments. * One of @link DPBandSwitch @endlink. Defaults to @link DPBandSwitch#BandOff @endlink. * * To compute banded alignments use @link DPBand @endlink as a shortcut for the <tt>DPBandConfig</tt> with * band switched on. */ // Simple band class. template <typename TSpec = BandOff> struct DPBandConfig {}; // ---------------------------------------------------------------------------- // Class DPBandConfig [BandOff] // ---------------------------------------------------------------------------- // The specialization when using no band. // Per default the member variables _lowerDiagonal and _upperDiagonal are // always 0. template <> struct DPBandConfig<BandOff> { typedef int TPosition; }; // ---------------------------------------------------------------------------- // Class DPBandConfig [BandOn] // ---------------------------------------------------------------------------- // The specialization when using a band. // On construction the diagonals are set to 0. template <> struct DPBandConfig<BandOn> { typedef int TPosition; int _lowerDiagonal; int _upperDiagonal; /*! * @fn DPBandConfig::DPBandConfig * @brief Constructor. * * @signature DPBandConfig<TSwitch>(); * @signature DPBandConfig<BandOn>(lowerDiag, upperDiag); * * @tparam TSwitch Tag to switch between banded and unbanded alignments. One of @link DPBandSwitch @endlink. * The second constructor is only supported when @link DPBandConfig @endlink is specialized with * @link DPBandSwitch#BandOn @endlink. * * @param lowerDiag The value for the lower diagonal of the band. * @param upperDiag The value for the upper diagonal of the band. * * A negative value for the diagonals indicates an intersection of the diagonal with the vertical sequence (y-axis) * and a positive value indicates an intersection with the horizontal sequence (x-axis). * The value of the lower diagonal has to compare less or equal to the value of the upper diagonal. */ DPBandConfig() : _lowerDiagonal(0), _upperDiagonal(0) {} DPBandConfig(int lowerDiagonal, int upperDiagonal) : _lowerDiagonal(lowerDiagonal), _upperDiagonal(upperDiagonal) { SEQAN_ASSERT_LEQ(lowerDiagonal, upperDiagonal); } }; /*! * @typedef DPBand * @headerfile <seqan/align.h> * @brief Global typedef used for @link DPBandConfig @endlink specialized with @link DPBandSwitch#BandOn @endlink. * * @signature typedef DPBandConfig<BandOn> DPBand; */ // Typedef for Band. typedef DPBandConfig<BandOn> DPBand; // ============================================================================ // Metafunctions // ============================================================================ /*! * @mfn DPBandConfig#Position * @headerfile <seqan/align.h> * @brief Metafunction returning the position type. * * @signature typename Position<T>::Type; * * @tparam T The type @link DPBandConfig @endlink to query the position type for. * @return TPosition The position type. */ // ---------------------------------------------------------------------------- // Metafunction Position // ---------------------------------------------------------------------------- template <typename T> struct Position<DPBandConfig<T> > { typedef typename DPBandConfig<T>::TPosition Type; }; template <typename T> struct Position<DPBandConfig<T> const>: Position<DPBandConfig<T> >{}; // ---------------------------------------------------------------------------- // Metafunction Size // ---------------------------------------------------------------------------- /*! * @mfn DPBandConfig#Size * @headerfile <seqan/align.h> * @brief Metafunction returning the size type. * * @signature typename Size<T>::Type; * * @tparam T The type @link DPBandConfig @endlink to query the size type for. * @return TSize The size type. */ template <typename T> struct Size<DPBandConfig<T> > { typedef unsigned Type; }; template <typename T> struct Size<DPBandConfig<T> const>: Size<DPBandConfig<T> >{}; // ============================================================================ // Functions // ============================================================================ // ---------------------------------------------------------------------------- // Function setLowerDiagonal // ---------------------------------------------------------------------------- /*! * @fn DPBandConfig#setLowerDiagonal * @headerfile <seqan/align.h> * @brief Sets the value of the lower diagonal. * * @signature setLowerDiagonal(obj, val); * * @param obj The object of type @link DPBandConfig @endlink to set the lower diagonal for. * @param val The new value for the lower diagonal. * * @note If the band is switched off, this function defaults to no-op. */ inline void setLowerDiagonal(DPBandConfig<BandOff> & /*dpBand*/, int /*newLowerDiagonal*/) { //no-op } inline void setLowerDiagonal(DPBandConfig<BandOn> & dpBand, int newLowerDiagonal) { dpBand._lowerDiagonal = newLowerDiagonal; } // ---------------------------------------------------------------------------- // Function lowerDiagonal // ---------------------------------------------------------------------------- /*! * @fn DPBandConfig#lowerDiagonal * @headerfile <seqan/align.h> * @brief Returns the value of the lower diagonal. * * @signature TPosition lowerDiagonal(obj); * * @param obj The object of type @link DPBandConfig @endlink to query the lower diagonal for. * * @note If the band is switched off this function always returns 0. * @return TPosition The value of the lower diagonal. */ inline Position<DPBandConfig<BandOff> >::Type lowerDiagonal(DPBandConfig<BandOff> const & /*dpBand*/) { return 0; } template <typename TSwitch> inline typename Position<DPBandConfig<BandOff> >::Type lowerDiagonal(DPBandConfig<TSwitch> const & dpBand) { return dpBand._lowerDiagonal; } // ---------------------------------------------------------------------------- // Function setUpperDiagonal // ---------------------------------------------------------------------------- /*! * @fn DPBandConfig#setUpperDiagonal * @headerfile <seqan/align.h> * @brief Sets the value of the upper diagonal. * * @signature setUpperDiagonal(obj, val); * * @param obj The object of type @link DPBandConfig @endlink to set the upper diagonal for. * @param val The new value for the upper diagonal. * * @note If the band is switched off, this function defaults to no-op. */ inline void setUpperDiagonal(DPBandConfig<BandOff> & /*dpBand*/, int /*newUpperDiagonal*/) { //no-op } inline void setUpperDiagonal(DPBandConfig<BandOn> & dpBand, int newUpperDiagonal) { dpBand._upperDiagonal = newUpperDiagonal; } // ---------------------------------------------------------------------------- // Function upperDiagonal // ---------------------------------------------------------------------------- /*! * @fn DPBandConfig#upperDiagonal * @headerfile <seqan/align.h> * @brief Returns the value of the upper diagonal. * * @signature TPosition upperDiagonal(obj); * * @param obj The object of type @link DPBandConfig @endlink to query the upper diagonal for. * * @note If the band is switched off this function always returns 0. * @return TPosition The value of the upper diagonal. */ inline Position<DPBandConfig<BandOff> >::Type upperDiagonal(DPBandConfig<BandOff> const & /*dpBand*/) { return 0; } template <typename TSwitch> inline typename Position<DPBandConfig<BandOn> >::Type upperDiagonal(DPBandConfig<TSwitch> const & dpBand) { return dpBand._upperDiagonal; } // ---------------------------------------------------------------------------- // Function bandSize() // ---------------------------------------------------------------------------- /*! * @fn DPBandConfig#bandSize * @headerfile <seqan/align.h> * @brief Returns the size of the band. * * @signature TSize bandSize(obj); * * @param obj The object of type @link DPBandConfig @endlink to query the band size for. * * @note If the band is switched off this function always returns 0. * @return TSize The number of diagonals covered by the band. */ inline Size<DPBandConfig<BandOff> >::Type bandSize(DPBandConfig<BandOff> const &) { return 0; } template <typename TSwitch> inline typename Size<DPBandConfig<TSwitch> >::Type bandSize(DPBandConfig<TSwitch> const & band) { return upperDiagonal(band) - lowerDiagonal(band) + 1; } } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_BAND_H_