// ========================================================================== // 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: Ren� Rahn <rene.rahn@fu-berlin.de> // ========================================================================== // Here are defined the strategies for the different alignment algorithms. // All classes are only used to determine the correct computational state // of a particular alignment algorithm depending on its profile at a // particular time. // All classes are only used on a meta-level. // ========================================================================== // TODO(holtgrew): Documentation in this header necessary or internal only? #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_META_INFO_H_ #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_META_INFO_H_ namespace seqan { // ============================================================================ // Forwards // ============================================================================ // ============================================================================ // Tags, Classes, Enums // ============================================================================ // ---------------------------------------------------------------------------- // Tag DPInitialColumn // ---------------------------------------------------------------------------- // Specifies the first column of the dp matrix. struct DPInitialColumn_; typedef Tag<DPInitialColumn_> DPInitialColumn; // ---------------------------------------------------------------------------- // Tag DPInnerColumn // ---------------------------------------------------------------------------- // Specifies any inner column of the dp matrix between the first and the last // column. struct DPInnerColumn_; typedef Tag<DPInnerColumn_> DPInnerColumn; // ---------------------------------------------------------------------------- // Tag DPFinalColumn // ---------------------------------------------------------------------------- // Specifies the last column of a dp matrix. struct DPFinalColumn_; typedef Tag<DPFinalColumn_> DPFinalColumn; // The TColumnProperty determines the property of the column (if it is initial, inner, or last column) // The TLocation determines how the column is organized in the matrix. // It can have the values: FullColumn, PartialColumnTop, PartialColumnMiddle, PartialColumnBottom. template <typename TColumnProperty_, typename TLocation_> struct MetaColumnDescriptor { typedef TColumnProperty_ TColumnProperty; typedef TLocation_ TLocation; }; // ---------------------------------------------------------------------------- // Tag FullColumn // ---------------------------------------------------------------------------- // Columns that span over the complete dp-matrix. (Unbanded alignemnts) struct FullColumn_; typedef Tag<FullColumn_> FullColumn; // ---------------------------------------------------------------------------- // Tag PartialColumnTop // ---------------------------------------------------------------------------- // Columns that begin in the first row, but does not at the last row of the dp-matrix struct PartialColumnTop_; typedef Tag<PartialColumnTop_> PartialColumnTop; // ---------------------------------------------------------------------------- // Tag PartialColumnMiddle // ---------------------------------------------------------------------------- // Columns that are not attached to the begin or end of the dp-matrix. struct PartialColumnMiddle_; typedef Tag<PartialColumnMiddle_> PartialColumnMiddle; // ---------------------------------------------------------------------------- // Tag PartialColumnBottom // ---------------------------------------------------------------------------- // Columns that end in the last row of the dp-matrix but do not start in the first row. struct PartialColumnBottom_; typedef Tag<PartialColumnBottom_> PartialColumnBottom; // The cell specifiers are used to determine the cell of a column. // There are three different cell specifiers used for the first cell, the // inner cell and the last cell of a column. // ---------------------------------------------------------------------------- // Tag FirstCell // ---------------------------------------------------------------------------- struct FirstCell_; typedef Tag<FirstCell_> FirstCell; // ---------------------------------------------------------------------------- // Tag InnerCell // ---------------------------------------------------------------------------- struct InnerCell_; typedef Tag<InnerCell_> InnerCell; // ---------------------------------------------------------------------------- // Tag LastCell // ---------------------------------------------------------------------------- struct LastCell_; typedef Tag<LastCell_> LastCell; // ---------------------------------------------------------------------------- // Class DPMetaCell_ // ---------------------------------------------------------------------------- // Keeps meta-information of a cell in the dp-matrix. It stores the recursion direction // for a particular cell type and whether it can be tracked or not. template <typename TDPRecursionDirection, typename TTrackFlag> struct DPMetaCell_ {}; // ---------------------------------------------------------------------------- // Class DPMetaColumn_ // ---------------------------------------------------------------------------- // Keeps meta-information of an entire column in the dp-matrix. Depending on the chosen // DPProfile and the current column descriptor it selects for the different column locations and // cell specifiers the correct meta-information about how is which cell computed and which cell is // tracked. template <typename TDPProfile, typename TColumnDescriptor> struct DPMetaColumn_ {}; // ---------------------------------------------------------------------------- // Class DPMetaColumn_ [FullColumn] // ---------------------------------------------------------------------------- template <typename TDPProfile, typename TColumnType> struct DPMetaColumn_<TDPProfile, MetaColumnDescriptor<TColumnType, FullColumn> > { typedef typename IsLocalAlignment_<TDPProfile>::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 // If InnerColumn -> Horizontal | Zero, All, All // If FinalColumn -> Horizontal | Zero, All, All typedef typename If<Or<IsSameType<TColumnType, DPInitialColumn>, IsFreeEndGap_<TDPProfile, DPFirstRow> >, RecursionDirectionZero, RecursionDirectionHorizontal>::Type TRecursionTypeFirstCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeInnerCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeLastCell_; // If Local // If InitialColumn -> True, True, True // If InnerColumn -> True, True, True // If FinalColumn -> True, True, True // If Global // If InitialColumn -> False, False, False | True (if DPLastRow) // If InnerColumn -> False, False, False | True (if DPLastRow) // If FinalColumn -> False | True, False | True (if DPLastColumn), True typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > // check this if he is really entitled to find the maximum here. >, True, False>::Type TrackFlagFirstCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagInnerCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, Or<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastRow> > >, True, False>::Type TrackFlagLastCell_; typedef DPMetaCell_<TRecursionTypeFirstCell_, TrackFlagFirstCell_> TFirstCell_; typedef DPMetaCell_<TRecursionTypeInnerCell_, TrackFlagInnerCell_> TInnerCell_; typedef DPMetaCell_<TRecursionTypeLastCell_, TrackFlagLastCell_> TLastCell_; }; // ---------------------------------------------------------------------------- // Class DPMetaColumn_ [PartialColumnTop] // ---------------------------------------------------------------------------- template <typename TDPProfile, typename TColumnType> struct DPMetaColumn_<TDPProfile, MetaColumnDescriptor<TColumnType, PartialColumnTop> > { typedef typename IsLocalAlignment_<TDPProfile>::Type TIsLocal; // How does the recursion directions look like? // 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 // If InnerColumn -> Horizontal | Zero, All, LowerBand // If FinalColumn -> Horizontal | Zero, All, LowerBand typedef typename If<Or<IsSameType<TColumnType, DPInitialColumn>, IsFreeEndGap_<TDPProfile, DPFirstRow> >, RecursionDirectionZero, RecursionDirectionHorizontal>::Type TRecursionTypeFirstCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeInnerCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionLowerDiagonal>::Type TRecursionTypeLastCell_; // If Local // If InitialColumn -> True, True, True // If InnerColumn -> True, True, True // If FinalColumn -> True, True, True // If Global // If InitialColumn -> False, False, False // If InnerColumn -> False, False, False // If FinalColumn -> False | True, False | True, False | True (if DPLastColumn True) typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagFirstCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagInnerCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagLastCell_; typedef DPMetaCell_<TRecursionTypeFirstCell_, TrackFlagFirstCell_> TFirstCell_; typedef DPMetaCell_<TRecursionTypeInnerCell_, TrackFlagInnerCell_> TInnerCell_; typedef DPMetaCell_<TRecursionTypeLastCell_, TrackFlagLastCell_> TLastCell_; }; // ---------------------------------------------------------------------------- // Class DPMetaColumn_ [PartialColumnMiddle] // ---------------------------------------------------------------------------- template <typename TDPProfile, typename TColumnType> struct DPMetaColumn_<TDPProfile, MetaColumnDescriptor<TColumnType, PartialColumnMiddle> > { typedef typename IsLocalAlignment_<TDPProfile>::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 // If InnerColumn -> UpperDiagonal, All, LowerDiagonal // If FinalColumn -> UpperDiagonal, All, LowerDiagonal typedef typename If<IsSameType<TColumnType, DPInitialColumn>, RecursionDirectionZero, RecursionDirectionUpperDiagonal>::Type TRecursionTypeFirstCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeInnerCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionLowerDiagonal>::Type TRecursionTypeLastCell_; // If Local // If InitialColumn -> True, True, True // If InnerColumn -> True, True, True // If FinalColumn -> True, True, True // If Global // If InitialColumn -> False, False, False // If InnerColumn -> False, False, False // If FinalColumn -> False | True, False | True, False | True (if DPLastColumn True) typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagFirstCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagInnerCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagLastCell_; typedef DPMetaCell_<TRecursionTypeFirstCell_, TrackFlagFirstCell_> TFirstCell_; typedef DPMetaCell_<TRecursionTypeInnerCell_, TrackFlagInnerCell_> TInnerCell_; typedef DPMetaCell_<TRecursionTypeLastCell_, TrackFlagLastCell_> TLastCell_; }; // ---------------------------------------------------------------------------- // Class DPMetaColumn_ [PartialColumnBottom] // ---------------------------------------------------------------------------- template <typename TDPProfile, typename TColumnType> struct DPMetaColumn_<TDPProfile, MetaColumnDescriptor<TColumnType, PartialColumnBottom> > { typedef typename IsLocalAlignment_<TDPProfile>::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 // If InnerColumn -> UpperDiagonal, All, All // If FinalColumn -> UpperDiagonal, All, All typedef typename If<IsSameType<TColumnType, DPInitialColumn>, RecursionDirectionZero, RecursionDirectionUpperDiagonal>::Type TRecursionTypeFirstCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeInnerCell_; typedef typename If<IsSameType<TColumnType, DPInitialColumn>, typename If<IsFreeEndGap_<TDPProfile, DPFirstColumn>, RecursionDirectionZero, RecursionDirectionVertical>::Type, RecursionDirectionAll>::Type TRecursionTypeLastCell_; // If Local // If InitialColumn -> True, True, True // If InnerColumn -> True, True, True // If FinalColumn -> True, True, True // If Global // If InitialColumn -> False, False, False | True (if DPLastRow) // If InnerColumn -> False, False, False | True (if DPLastRow) // If FinalColumn -> False | True, False | True (if DPLastColumn), True (last is always true) typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagFirstCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, And<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastColumn> > >, True, False>::Type TrackFlagInnerCell_; typedef typename If<Or<IsLocalAlignment_<TDPProfile>, Or<IsSameType<TColumnType, DPFinalColumn>, IsFreeEndGap_<TDPProfile, DPLastRow> > >, True, False>::Type TrackFlagLastCell_; typedef DPMetaCell_<TRecursionTypeFirstCell_, TrackFlagFirstCell_> TFirstCell_; typedef DPMetaCell_<TRecursionTypeInnerCell_, TrackFlagInnerCell_> TInnerCell_; typedef DPMetaCell_<TRecursionTypeLastCell_, TrackFlagLastCell_> TLastCell_; }; // ---------------------------------------------------------------------------- // Metafunction GetRecursionDirection_ // ---------------------------------------------------------------------------- // Returns the type of recursion for a given DPMetaCell object. template <typename TMetaCell> struct GetRecursionDirection_ { typedef Nothing Type; }; template <typename TRecursionDirection, typename TTraceFlag> struct GetRecursionDirection_<DPMetaCell_<TRecursionDirection, TTraceFlag> > { typedef TRecursionDirection Type; }; // ---------------------------------------------------------------------------- // Metafunction RecursionDirection_ // ---------------------------------------------------------------------------- // Returns the type of recursion for a given DPMetaColumn object and a given cell specifier. template <typename TDPMetaColumn, typename TCellDescriptor> struct RecursionDirection_ {}; template <typename TDPMetaColumn> struct RecursionDirection_<TDPMetaColumn, FirstCell> { typedef typename GetRecursionDirection_<typename TDPMetaColumn::TFirstCell_>::Type Type; }; template <typename TDPMetaColumn> struct RecursionDirection_<TDPMetaColumn, InnerCell> { typedef typename GetRecursionDirection_<typename TDPMetaColumn::TInnerCell_>::Type Type; }; template <typename TDPMetaColumn> struct RecursionDirection_<TDPMetaColumn, LastCell> { typedef typename GetRecursionDirection_<typename TDPMetaColumn::TLastCell_>::Type Type; }; // ---------------------------------------------------------------------------- // Metafunction IsTrackingEnabled_ // ---------------------------------------------------------------------------- // Returns an object that evaluates to true if for a given cell description the // tracking was enabled. Otherwise the object evaluates to false. template <typename TMetaCell> struct IsTrackingEnabled_ : False {}; template <typename TRecursionDirection> struct IsTrackingEnabled_<DPMetaCell_<TRecursionDirection, True> >: True {}; template <typename TDPMetaColumn, typename TCellDescriptor> struct TrackingEnabled_ : False {}; template <typename TDPMetaColumn> struct TrackingEnabled_<TDPMetaColumn, FirstCell>: IsTrackingEnabled_<typename TDPMetaColumn::TFirstCell_>{}; template <typename TDPMetaColumn> struct TrackingEnabled_<TDPMetaColumn, InnerCell>: IsTrackingEnabled_<typename TDPMetaColumn::TInnerCell_>{}; template <typename TDPMetaColumn> struct TrackingEnabled_<TDPMetaColumn, LastCell>: IsTrackingEnabled_<typename TDPMetaColumn::TLastCell_>{}; // ---------------------------------------------------------------------------- // Metafunction LastColumnEnabled_ // ---------------------------------------------------------------------------- template <typename TAlgo, typename TColumnDescriptor> struct LastColumnEnabled_ { typedef typename IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::Type Type; }; template <typename TAlgo, typename TGapSpec, typename TTraceSpec, typename TColumnDescriptor> struct LastColumnEnabled_<DPProfile_<TAlgo, TGapSpec, TTraceSpec>, TColumnDescriptor> : LastColumnEnabled_<TAlgo, TColumnDescriptor> {}; // ---------------------------------------------------------------------------- // Metafunction LastRowEnabled_ // ---------------------------------------------------------------------------- template <typename TAlgo, typename TCellDescriptor, typename TColumnDescriptor> struct LastRowEnabled_ { typedef typename And<IsSameType<TCellDescriptor, LastCell>, Or<IsSameType<typename TColumnDescriptor::TLocation, PartialColumnBottom>, IsSameType<typename TColumnDescriptor::TLocation, FullColumn> > >::Type Type; }; template <typename TAlgo, typename TGapSpec, typename TTraceSpec, typename TCellDescriptor, typename TColumnDescriptor> struct LastRowEnabled_<DPProfile_<TAlgo, TGapSpec, TTraceSpec>, TCellDescriptor, TColumnDescriptor> : LastRowEnabled_<TAlgo, TCellDescriptor, TColumnDescriptor> {}; // ============================================================================ // Functions // ============================================================================ } // namespace seqan #endif // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_META_INFO_H_