cobot 0.1.1.0 → 0.1.1.1
raw patch · 7 files changed
+228/−149 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Bio.Chain.Alignment.Algorithms: horiz :: (Alignable m, Alignable m', IsGap g) => g -> Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool
- Bio.Chain.Alignment.Algorithms: vert :: (Alignable m, Alignable m', IsGap g) => g -> Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool
- Bio.Chain.Alignment.Type: [isDiag] :: Conditions m m' -> Condition m m'
- Bio.Chain.Alignment.Type: [isHoriz] :: Conditions m m' -> Condition m m'
- Bio.Chain.Alignment.Type: [isVert] :: Conditions m m' -> Condition m m'
- Bio.Chain.Alignment.Type: type Condition m m' = Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool
+ Bio.Chain.Alignment: difference' :: forall m m'. (Alignable m, Alignable m', IxValue m ~ IxValue m', Eq (IxValue m), Eq (IxValue m')) => AlignmentResult m m' -> R
+ Bio.Chain.Alignment: differenceGen' :: forall m m'. (Alignable m, Alignable m') => AlignmentResult m m' -> (IxValue m -> IxValue m' -> Bool) -> R
+ Bio.Chain.Alignment: similarity' :: forall m m'. (Alignable m, Alignable m', IxValue m ~ IxValue m', Eq (IxValue m), Eq (IxValue m')) => AlignmentResult m m' -> R
+ Bio.Chain.Alignment: similarityGen' :: forall m m'. (Alignable m, Alignable m') => AlignmentResult m m' -> (IxValue m -> IxValue m' -> Bool) -> R
+ Bio.Chain.Alignment.Algorithms: fillInnerMatrix :: (IsGap g, Ix ix, Ix ix', Enum ix, Enum ix') => g -> STUArray s (ix, ix', EditOp) Int -> Bool -> (ix -> ix' -> Int) -> ix -> ix' -> ST s ()
+ Bio.Chain.Alignment.Algorithms: move :: (Alignable m, Alignable m', IsGap g) => g -> Move m m'
+ Bio.Chain.Alignment.Algorithms: moveAffine :: (Alignable m, Alignable m', IsGap g) => g -> Move m m'
+ Bio.Chain.Alignment.Algorithms: moveSimple :: (Alignable m, Alignable m', IsGap g) => g -> Move m m'
+ Bio.Chain.Alignment.Type: [doMove] :: Conditions m m' -> Move m m'
+ Bio.Chain.Alignment.Type: type Move m m' = Matrix m m' -> m -> m' -> Index m -> Index m' -> EditOp " Current matrix, used in affine alignment" -> (EditOp, Index m, Index m', Operation (Index m) (Index m')) " Next matrix, next indices, new operation"
+ Bio.Chain.Alignment.Type: type Stop m m' = Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool
- Bio.Chain.Alignment.Type: Conditions :: Condition m m' -> Condition m m' -> Condition m m' -> Condition m m' -> Conditions m m'
+ Bio.Chain.Alignment.Type: Conditions :: Stop m m' -> Move m m' -> Conditions m m'
- Bio.Chain.Alignment.Type: [isStop] :: Conditions m m' -> Condition m m'
+ Bio.Chain.Alignment.Type: [isStop] :: Conditions m m' -> Stop m m'
- Bio.Protein.AminoAcid.Type: atom' :: forall r_atpb a_atpc. Lens' (Env r_atpb a_atpc) a_atpc
+ Bio.Protein.AminoAcid.Type: atom' :: forall r_atCq a_atCr. Lens' (Env r_atCq a_atCr) a_atCr
- Bio.Protein.AminoAcid.Type: c' :: forall nr_atpe car_atpf cr_atpg a_atph cr_awfE. Lens (AminoAcid nr_atpe car_atpf cr_atpg a_atph) (AminoAcid nr_atpe car_atpf cr_awfE a_atph) (cr_atpg a_atph) (cr_awfE a_atph)
+ Bio.Protein.AminoAcid.Type: c' :: forall nr_atCt car_atCu cr_atCv a_atCw cr_awt6. Lens (AminoAcid nr_atCt car_atCu cr_atCv a_atCw) (AminoAcid nr_atCt car_atCu cr_awt6 a_atCw) (cr_atCv a_atCw) (cr_awt6 a_atCw)
- Bio.Protein.AminoAcid.Type: ca' :: forall nr_atpe car_atpf cr_atpg a_atph car_awfF. Lens (AminoAcid nr_atpe car_atpf cr_atpg a_atph) (AminoAcid nr_atpe car_awfF cr_atpg a_atph) (car_atpf a_atph) (car_awfF a_atph)
+ Bio.Protein.AminoAcid.Type: ca' :: forall nr_atCt car_atCu cr_atCv a_atCw car_awt7. Lens (AminoAcid nr_atCt car_atCu cr_atCv a_atCw) (AminoAcid nr_atCt car_awt7 cr_atCv a_atCw) (car_atCu a_atCw) (car_awt7 a_atCw)
- Bio.Protein.AminoAcid.Type: cb :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cb :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cd :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cd :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cd1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cd1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cd2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cd2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ce :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ce :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ce1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ce1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ce2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ce2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ce3 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ce3 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cg :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cg :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cg' :: forall a_atp8 a_ay0c. Lens (CG a_atp8) (CG a_ay0c) a_atp8 a_ay0c
+ Bio.Protein.AminoAcid.Type: cg' :: forall a_atCn a_aydE. Lens (CG a_atCn) (CG a_aydE) a_atCn a_aydE
- Bio.Protein.AminoAcid.Type: cg1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cg1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cg2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cg2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ch2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ch2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cz :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cz :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cz2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cz2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: cz3 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: cz3 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: environment :: forall r_atpb a_atpc r_axXA. Lens (Env r_atpb a_atpc) (Env r_axXA a_atpc) (r_atpb a_atpc) (r_axXA a_atpc)
+ Bio.Protein.AminoAcid.Type: environment :: forall r_atCq a_atCr r_ayb2. Lens (Env r_atCq a_atCr) (Env r_ayb2 a_atCr) (r_atCq a_atCr) (r_ayb2 a_atCr)
- Bio.Protein.AminoAcid.Type: n' :: forall nr_atpe car_atpf cr_atpg a_atph nr_awfG. Lens (AminoAcid nr_atpe car_atpf cr_atpg a_atph) (AminoAcid nr_awfG car_atpf cr_atpg a_atph) (nr_atpe a_atph) (nr_awfG a_atph)
+ Bio.Protein.AminoAcid.Type: n' :: forall nr_atCt car_atCu cr_atCv a_atCw nr_awt8. Lens (AminoAcid nr_atCt car_atCu cr_atCv a_atCw) (AminoAcid nr_awt8 car_atCu cr_atCv a_atCw) (nr_atCt a_atCw) (nr_awt8 a_atCw)
- Bio.Protein.AminoAcid.Type: nd1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: nd1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: nd2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: nd2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ne :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ne :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ne1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ne1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: ne2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: ne2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: nh1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: nh1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: nh2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: nh2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: nz :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: nz :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: o' :: forall a_atp9. Lens' (OXT a_atp9) a_atp9
+ Bio.Protein.AminoAcid.Type: o' :: forall a_atCo. Lens' (OXT a_atCo) a_atCo
- Bio.Protein.AminoAcid.Type: od1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: od1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: od2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: od2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: oe1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: oe1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: oe2 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: oe2 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: og :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: og :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: og1 :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: og1 :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: oh :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: oh :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: oxt' :: forall a_atp9. Lens' (OXT a_atp9) a_atp9
+ Bio.Protein.AminoAcid.Type: oxt' :: forall a_atCo. Lens' (OXT a_atCo) a_atCo
- Bio.Protein.AminoAcid.Type: radical' :: forall a_atp8. Lens' (CG a_atp8) AA
+ Bio.Protein.AminoAcid.Type: radical' :: forall a_atCn. Lens' (CG a_atCn) AA
- Bio.Protein.AminoAcid.Type: sd :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: sd :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
- Bio.Protein.AminoAcid.Type: sg :: forall a_atpd. Traversal' (Radical a_atpd) a_atpd
+ Bio.Protein.AminoAcid.Type: sg :: forall a_atCs. Traversal' (Radical a_atCs) a_atCs
Files
- ChangeLog.md +9/−0
- cobot.cabal +2/−2
- src/Bio/Chain/Alignment.hs +100/−65
- src/Bio/Chain/Alignment/Algorithms.hs +87/−74
- src/Bio/Chain/Alignment/Type.hs +14/−6
- test/HandcraftedSpec.hs +14/−0
- test/JuliaSpec.hs +2/−2
ChangeLog.md view
@@ -2,6 +2,15 @@ ## Unreleased changes +## [0.1.1.1] - 2020-03-24+### Fixed+- Affine alignment matrix construction and traceback.+### Added+- `similarity'` family of functions to calculate similarity directly on `AlignnmentResult`.+### Changed+- Generalize affine gap matrix construction;+- Improve alignment documentation.+ ## [0.1.1.0] - 2019-06-17 ### Added - Typeclass `IsGap`.
cobot.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 5253d8bdc8faf78e15758bbf5ca466c06c743718a111840ff74966c4932315ad+-- hash: 19558d31d73118631f947a34b8de243404cf58e8942adbd414bf445b21381b86 name: cobot-version: 0.1.1.0+version: 0.1.1.1 synopsis: Computational biology toolkit to collaborate with researchers in constructive protein engineering description: Please see the README on GitHub at <https://github.com/less-wrong/cobot#readme> category: Bio
src/Bio/Chain/Alignment.hs view
@@ -1,14 +1,26 @@ module Bio.Chain.Alignment- ( AlignmentResult (..), SimpleGap, SimpleGap2, AffineGap (..), AffineGap2, Operation (..)+ (+ -- * Alignment function+ align+ -- ** Alignment algorithms , EditDistance (..) , GlobalAlignment (..), LocalAlignment (..), SemiglobalAlignment (..)+ , SimpleGap, SimpleGap2, AffineGap (..), AffineGap2 , IsGap (..)- , align+ -- ** Alignment result types+ , AlignmentResult (..), Operation (..)+ -- * Viewing alignment results , viewAlignment , prettyAlignmment+ -- * Similarity functions+ -- $similarity+ , similarityGen' , similarityGen+ , differenceGen' , differenceGen+ , similarity' , similarity+ , difference' , difference ) where @@ -82,69 +94,69 @@ -> Index m -> Index m' -> [Operation (Index m) (Index m')]-traceback algo mat s t i' j' = helper i' j' []+traceback algo mat s t i' j' = helper i' j' Match [] where- helper i j ar | isStop (cond algo) mat s t i j = ar- | isVert (cond algo) mat s t i j = helper (pred i) j (DELETE (pred i):ar)- | isHoriz (cond algo) mat s t i j = helper i (pred j) (INSERT (pred j):ar)- | isDiag (cond algo) mat s t i j = helper (pred i) (pred j) (MATCH (pred i) (pred j):ar)- | otherwise = error "Alignment traceback: you cannot be here"+ helper i j prevOp ar+ | isStop (cond algo) mat s t i j = ar+ | otherwise =+ let (nextOp, nextI, nextJ, op) = doMove (cond algo) mat s t i j prevOp+ in helper nextI nextJ nextOp $ op:ar ----------------------------------------------------------------------------------------------------------- --- -- Some TIPS for using the functions below- --- -- These are generic variants of similarity and difference functions alongside with their specialised variants.- -- Generic versions take the alignment algorithm used for sequence alignment,- -- an equality function on elements of both sequences to calculate hamming distance on aligned sequences,- -- and the sequences themselves.- --- -- Sample usage of generic functions:- --- -- > similarityGen (GlobalAlignment (\x y -> if x == ord y then 1 else 0) (AffineGap (-11) (-1))) (\x y -> x == ord y) [ord 'R'.. ord 'z'] ['a'..'z']- -- > 0.63414633- --- -- This one will calculate similarity between a list if `Int`s and a list of `Char`s.- -- Generic scoring function used in alignment is `\x y -> if x == ord y then 1 else 0`- -- Generic equality function used in hamming distance is `\x y -> x == ord y`- --- --- -- Specialised versions do not take the equality function as the sequences are already constrained to have `Eq` elements.- --- -- Sample usage of specialised function is the same as before:- --- -- > seq1 :: String- -- > seq1 = "EVQLLESGGGLVQPGGSLRLSCAASGFTFSSYAMSWVRQAPGKGLEWVSAISGSGGSTYYADSVKGRFTISRDNSKNTLYLQMNSLRAEDTAVYYCAKVQLERYFDYWGQGTLVTVSS"- -- >- -- > seq2 :: String- -- > seq2 = "EVQLLESGGGLVQPGGSLRLSAAASGFTFSTFSMNWVRQAPGKGLEWVSYISRTSKTIYYADSVKGRFTISRDNSKNTLYLQMNSLRAEDTAVYYVARGRFFDYWGQGTLVTVS"- -- >- -- > similarity (GlobalAlignment blosum62 (AffineGap (-11) (-1))) s1 s2- -- > 0.8130081- --- -- Sometimes for biological reasons gaps appearing in one of two sequences, that are being aligned,- -- are not physical. For that reason we might want to use different gap penalties when aligning these sequences.- --- -- Example of usage of different gaps when aligning two sequences is presented below:- --- -- > seq1 :: String- -- > seq1 = "AAAAAAGGGGGGGGGGGGTTTTTTTTT"- -- >- -- > seq2 :: String- -- > seq2 = "AAAAAATTTTTTTTT"- -- >- -- > gapForSeq1 :: AffineGap- -- > gapForSeq1 = AffineGap (-5) (-1)- -- >- -- > gapForSeq2 :: AffineGap- -- > gapForSeq2 = AffineGap (-1000) (-1000) -- basically, we forbid gaps on @seq2@- -- >- -- > local = LocalAlignment nuc44 (gapForSeq1, gapForSeq2)- -- >- -- > viewAlignment (align local seq1 seq2) == ("TTTTTTTTT", "TTTTTTTTT")- ------------------------------------------------------------------------------------------------------------+{- $similarity+These are generic variants of similarity and difference functions alongside with their specialised variants.+Generic versions take the alignment algorithm used for sequence alignment,+an equality function on elements of both sequences to calculate hamming distance on aligned sequences,+and the sequences themselves. +Sample usage of generic functions:++>>> similarityGen (GlobalAlignment (\x y -> if x == ord y then 1 else 0) (AffineGap (-11) (-1))) (\x y -> x == ord y) [ord 'R'.. ord 'z'] ['a'..'z']+0.63414633++This one will calculate similarity between a list of 'Int's and a list of 'Char's.+Generic scoring function used in alignment is @\\x y -> if x == ord y then 1 else 0@.+Generic equality function used in hamming distance is @\\x y -> x == ord y@.++Specialised versions do not take the equality function as the sequences are already constrained to have 'Eq' elements.++Sample usage of specialised function is the same as before:++>>> :{+seq1 :: String+seq1 = "EVQLLESGGGLVQPGGSLRLSCAASGFTFSSYAMSWVRQAPGKGLEWVSAISGSGGSTYYADSVKGRFTISRDNSKNTLYLQMNSLRAEDTAVYYCAKVQLERYFDYWGQGTLVTVSS"+<BLANKLINE>+seq2 :: String+seq2 = "EVQLLESGGGLVQPGGSLRLSAAASGFTFSTFSMNWVRQAPGKGLEWVSYISRTSKTIYYADSVKGRFTISRDNSKNTLYLQMNSLRAEDTAVYYVARGRFFDYWGQGTLVTVS"+<BLANKLINE>+similarity (GlobalAlignment blosum62 (AffineGap (-11) (-1))) s1 s2+:}+0.8130081++Sometimes for biological reasons gaps appearing in one of two sequences, that are being aligned,+are not physical. For that reason we might want to use different gap penalties when aligning these sequences.++Example of usage of different gaps when aligning two sequences is presented below:++>>> :{+seq1 :: String+seq1 = "AAAAAAGGGGGGGGGGGGTTTTTTTTT"+<BLANKLINE>+seq2 :: String+seq2 = "AAAAAATTTTTTTTT"+<BLANKLINE>+gapForSeq1 :: AffineGap+gapForSeq1 = AffineGap (-5) (-1)+<BLANKLINE>+gapForSeq2 :: AffineGap+gapForSeq2 = AffineGap (-1000) (-1000) -- basically, we forbid gaps on @seq2@+<BLANKLINE>+local = LocalAlignment nuc44 (gapForSeq1, gapForSeq2)+<BLANKLINE>+viewAlignment (align local seq1 seq2)+:}+("TTTTTTTTT", "TTTTTTTTT")+-}+ -- | Calculate similarity and difference between two sequences, aligning them first using given algorithm. -- similarityGen :: forall algo m m'.(SequenceAlignment algo, Alignable m, Alignable m')@@ -153,9 +165,18 @@ -> m -> m' -> R-similarityGen algo genericEq s t = fromIntegral hamming / fromIntegral len+similarityGen algo genericEq s t = similarityGen' (align algo s t) genericEq++-- | Calculate similarity by precomputed 'AlignmentResult'.+similarityGen' :: forall m m'. (Alignable m, Alignable m')+ => AlignmentResult m m'+ -> (IxValue m -> IxValue m' -> Bool)+ -> R+similarityGen' res genericEq = fromIntegral hamming / fromIntegral len where- operations = alignment (align algo s t)+ operations = alignment res+ s = sequence1 res+ t = sequence2 res len = length operations hamming = sum $ toScores <$> operations @@ -170,6 +191,10 @@ -> R similarity algo = similarityGen algo (==) +similarity' :: forall m m'.(Alignable m, Alignable m', IxValue m ~ IxValue m', Eq (IxValue m), Eq (IxValue m'))+ => AlignmentResult m m'+ -> R+similarity' res = similarityGen' res (==) differenceGen :: forall algo m m'.(SequenceAlignment algo, Alignable m, Alignable m') => algo (IxValue m) (IxValue m')@@ -179,6 +204,11 @@ -> R differenceGen algo genericEq s t = 1.0 - similarityGen algo genericEq s t +differenceGen' :: forall m m'.(Alignable m, Alignable m')+ => AlignmentResult m m'+ -> (IxValue m -> IxValue m' -> Bool)+ -> R+differenceGen' res genericEq = 1.0 - similarityGen' res genericEq difference :: forall algo m m'.(SequenceAlignment algo, Alignable m, Alignable m', IxValue m ~ IxValue m', Eq (IxValue m), Eq (IxValue m')) => algo (IxValue m) (IxValue m')@@ -187,7 +217,12 @@ -> R difference algo = differenceGen algo (==) --- | View alignment results as simple strings with gaps+difference' :: forall m m'.(Alignable m, Alignable m', IxValue m ~ IxValue m', Eq (IxValue m), Eq (IxValue m'))+ => AlignmentResult m m'+ -> R+difference' res = differenceGen' res (==)++-- | View alignment results as simple strings with gaps. -- viewAlignment :: forall m m'.(Alignable m, Alignable m', Symbol (IxValue m), Symbol (IxValue m')) => AlignmentResult m m' -> (String, String) viewAlignment ar = unzip (toChars <$> alignment ar)
src/Bio/Chain/Alignment/Algorithms.hs view
@@ -18,8 +18,8 @@ import Data.Array.Unboxed (Ix (..), UArray, (!)) --- | Alignnment methods---+-- Alignnment methods+ newtype EditDistance e1 e2 = EditDistance (e1 -> e2 -> Bool) data GlobalAlignment a e1 e2 = GlobalAlignment (Scoring e1 e2) a data LocalAlignment a e1 e2 = LocalAlignment (Scoring e1 e2) a@@ -57,23 +57,57 @@ (lowerT, _) = bounds t in i == lowerS || j == lowerT || m' ! (i, j, Match) == 0 -horiz :: (Alignable m, Alignable m', IsGap g) => g -> Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool-horiz g m s t i j = (j > lowerT) && ((i == lowerS) || (m ! (i, pred j, Match) + add == m ! (i, j, Match)))- where- add | isAffine g = m ! (i, pred j, Insert)- | otherwise = insertCostOpen g-- (lowerT, _) = bounds t- (lowerS, _) = bounds s+{-# INLINE move #-}+move+ :: (Alignable m, Alignable m', IsGap g)+ => g+ -> Move m m'+move g+ | isAffine g = moveAffine g+ | otherwise = moveSimple g -vert :: (Alignable m, Alignable m', IsGap g) => g -> Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool-vert g m s t i j = (i > lowerS) && ((lowerT == j) || (m ! (pred i, j, Match) + add == m ! (i, j, Match)))- where- add | isAffine g = m ! (pred i, j, Delete)- | otherwise = deleteCostOpen g+{-# INLINE moveSimple #-}+moveSimple+ :: (Alignable m, Alignable m', IsGap g)+ => g+ -> Move m m'+moveSimple g m s t i j _+ | i == lowerS = (Match, lowerS, pred j, INSERT $ pred j)+ | j == lowerT = (Match, pred i, lowerT, DELETE $ pred i)+ | m ! (pred i, j, Match) + deleteCostOpen g == m ! (i, j, Match) = (Match, pred i, j, DELETE $ pred i)+ | m ! (i, pred j, Match) + insertCostOpen g == m ! (i, j, Match) = (Match, i, pred j, INSERT $ pred j)+ | otherwise = (Match, pred i, pred j, MATCH (pred i) (pred j))+ where+ (lowerT, _) = bounds t+ (lowerS, _) = bounds s - (lowerT, _) = bounds t- (lowerS, _) = bounds s+{-# INLINE moveAffine #-}+-- | Move function for affine alignment traceback. Implements a "Manhattan grid".+--+-- See here: <http://www.csbio.unc.edu/mcmillan/Comp555S16/Lecture14.html>+-- or file @doc/Affine_Alignment.pdf@ in the repository.+moveAffine+ :: (Alignable m, Alignable m', IsGap g)+ => g+ -> Move m m'+moveAffine g m s t i j prevOp+ | i == lowerS = (Insert, lowerS, pred j, INSERT $ pred j)+ | j == lowerT = (Delete, pred i, lowerT, DELETE $ pred i)+ | otherwise =+ case prevOp of+ Delete+ | m ! (i, j, Delete) == m ! (pred i, j, Delete) + deleteCostExtend g -> (Delete, pred i, j, DELETE $ pred i)+ | otherwise -> (Match, pred i, j, DELETE $ pred i)+ Insert+ | m ! (i, j, Insert) == m ! (i, pred j, Insert) + insertCostExtend g -> (Insert, i, pred j, INSERT $ pred j)+ | otherwise -> (Match, i, pred j, INSERT $ pred j)+ Match+ | m ! (i, j, Match) == m ! (i, j, Delete) -> move g m s t i j Delete+ | m ! (i, j, Match) == m ! (i, j, Insert) -> move g m s t i j Insert+ | otherwise -> (Match, pred i, pred j, MATCH (pred i) (pred j))+ where+ (lowerT, _) = bounds t+ (lowerS, _) = bounds s -- | Default condition of moving diagonally in traceback. --@@ -141,7 +175,7 @@ -- Conditions of traceback are described below -- {-# INLINE cond #-}- cond (GlobalAlignment subC gap) = Conditions defStop (defDiag subC) (vert gap) (horiz gap)+ cond (GlobalAlignment _ gap) = Conditions defStop (move gap) -- Start from bottom right corner --@@ -199,22 +233,7 @@ writeArray matrix (ixS, ixT, Match) $ deleteCostOpen g + (deleteCostExtend g) * pred (index (lowerS, nilS) ixS) writeArray matrix (ixS, ixT, Delete) $ deleteCostExtend g writeArray matrix (ixS, ixT, Insert) $ insertCostOpen g- | otherwise -> do- predDiag <- matrix `readArray` (pred ixS, pred ixT, Match)- predS <- matrix `readArray` (pred ixS, ixT, Match)- predT <- matrix `readArray` ( ixS, pred ixT, Match)-- delCost <- matrix `readArray` (pred ixS, ixT, Delete)- insCost <- matrix `readArray` ( ixS, pred ixT, Insert)-- let maxScore = maximum [ predDiag + sub ixS ixT- , predS + delCost- , predT + insCost- ]-- writeArray matrix (ixS, ixT, Delete) $ if predS + delCost == maxScore then deleteCostExtend g else deleteCostOpen g- writeArray matrix (ixS, ixT, Insert) $ if predT + insCost == maxScore then insertCostExtend g else insertCostOpen g- writeArray matrix (ixS, ixT, Match) maxScore+ | otherwise -> fillInnerMatrix g matrix False sub ixS ixT pure matrix (lowerS, upperS) = bounds s@@ -230,7 +249,7 @@ -- Conditions of traceback are described below -- {-# INLINE cond #-}- cond (LocalAlignment subC gap) = Conditions localStop (defDiag subC) (vert gap) (horiz gap)+ cond (LocalAlignment _ gap) = Conditions localStop (move gap) -- Start from bottom right corner --@@ -280,23 +299,7 @@ writeArray matrix (ixS, ixT, Match) 0 writeArray matrix (ixS, ixT, Insert) $ insertCostOpen g writeArray matrix (ixS, ixT, Delete) $ deleteCostOpen g- | otherwise -> do- predDiag <- matrix `readArray` (pred ixS, pred ixT, Match)- predS <- matrix `readArray` (pred ixS, ixT, Match)- predT <- matrix `readArray` ( ixS, pred ixT, Match)-- delCost <- matrix `readArray` (pred ixS, ixT, Delete)- insCost <- matrix `readArray` ( ixS, pred ixT, Insert)-- let maxScore = maximum [ predDiag + sub ixS ixT- , predS + delCost- , predT + insCost- , 0- ]-- writeArray matrix (ixS, ixT, Delete) $ if predS + delCost == maxScore then deleteCostExtend g else deleteCostOpen g- writeArray matrix (ixS, ixT, Insert) $ if predT + insCost == maxScore then insertCostExtend g else insertCostOpen g- writeArray matrix (ixS, ixT, Match) maxScore+ | otherwise -> fillInnerMatrix g matrix True sub ixS ixT pure matrix (lowerS, upperS) = bounds s@@ -317,7 +320,7 @@ -- Conditions of traceback are described below -- {-# INLINE cond #-}- cond (SemiglobalAlignment subC gap) = Conditions defStop (defDiag subC) (vert gap) (horiz gap)+ cond (SemiglobalAlignment _ gap) = Conditions defStop (move gap) -- Start from bottom right corner --@@ -357,31 +360,11 @@ matrix <- newArray ((lowerS, lowerT, Insert), (nilS, nilT, Match)) 0 :: ST s (STUArray s (Index m, Index m', EditOp) Int) forM_ [lowerS .. nilS] $ \ixS -> forM_ [lowerT .. nilT] $ \ixT ->-- -- Next cell = max (d_i-1,j + gap, d_i,j-1 + gap, d_i-1,j-1 + s(i,j))- -- Matrices with gap costs are also filled as follows:- -- gepMatrix[i, j] <- gapExtend if one of strings has gap at this position else gapOpen- -- if | ixS == lowerS || ixT == lowerT -> do writeArray matrix (ixS, ixT, Match) 0 writeArray matrix (ixS, ixT, Insert) $ insertCostOpen g writeArray matrix (ixS, ixT, Delete) $ deleteCostOpen g- | otherwise -> do- predDiag <- matrix `readArray` (pred ixS, pred ixT, Match)- predS <- matrix `readArray` (pred ixS, ixT, Match)- predT <- matrix `readArray` ( ixS, pred ixT, Match)-- delCost <- matrix `readArray` (pred ixS, ixT, Delete)- insCost <- matrix `readArray` ( ixS, pred ixT, Insert)-- let maxScore = maximum [ predDiag + sub ixS ixT- , predS + delCost- , predT + insCost- ]-- writeArray matrix (ixS, ixT, Delete) $ if predS + delCost == maxScore then deleteCostExtend g else deleteCostOpen g- writeArray matrix (ixS, ixT, Insert) $ if predT + insCost == maxScore then insertCostExtend g else insertCostOpen g- writeArray matrix (ixS, ixT, Match) maxScore+ | otherwise -> fillInnerMatrix g matrix False sub ixS ixT pure matrix (lowerS, upperS) = bounds s@@ -391,3 +374,33 @@ sub :: Index m -> Index m' -> Int sub = substitute subC s t++{-# INLINE fillInnerMatrix #-}+fillInnerMatrix+ :: (IsGap g, Ix ix, Ix ix', Enum ix, Enum ix')+ => g+ -> STUArray s (ix, ix', EditOp) Int+ -> Bool -- ^ Is this local alignment?+ -> (ix -> ix' -> Int) -- ^ Substitution function+ -> ix+ -> ix'+ -> ST s ()+fillInnerMatrix g matrix isLocal sub ixS ixT = do+ predDiag <- matrix `readArray` (pred ixS, pred ixT, Match)+ predS <- matrix `readArray` (pred ixS, ixT, Match)+ predT <- matrix `readArray` ( ixS, pred ixT, Match)++ delCost <- matrix `readArray` (pred ixS, ixT, Delete)+ insCost <- matrix `readArray` ( ixS, pred ixT, Insert)++ let+ updInsCost = max (insCost + insertCostExtend g) (predT + insertCostOpen g)+ updDelCost = max (delCost + deleteCostExtend g) (predS + deleteCostOpen g)+ repCost = predDiag + sub ixS ixT+ maxCost = max repCost $ max updInsCost updDelCost++ finalCost = if isLocal then max 0 maxCost else maxCost++ writeArray matrix (ixS, ixT, Delete) updDelCost+ writeArray matrix (ixS, ixT, Insert) updInsCost+ writeArray matrix (ixS, ixT, Match) finalCost
src/Bio/Chain/Alignment/Type.hs view
@@ -111,16 +111,24 @@ -- type Matrix m m' = UArray (Index m, Index m', EditOp) Int --- | Traceback condition type+-- | Traceback stop condition type ---type Condition m m' = Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool+type Stop m m' = Matrix m m' -> m -> m' -> Index m -> Index m' -> Bool +-- | Traceback next move generator type+--+type Move m m'+ = Matrix m m'+ -> m -> m'+ -> Index m -> Index m'+ -> EditOp -- ^ Current matrix, used in affine alignment+ -> (EditOp, Index m, Index m', Operation (Index m) (Index m'))+ -- ^ Next matrix, next indices, new operation+ -- | A set of traceback conditions ---data Conditions m m' = Conditions { isStop :: Condition m m' -- ^ Should we stop?- , isDiag :: Condition m m' -- ^ Should we go daigonally?- , isVert :: Condition m m' -- ^ Should we go vertically?- , isHoriz :: Condition m m' -- ^ Should we go horizontally?+data Conditions m m' = Conditions { isStop :: Stop m m' -- ^ Should we stop?+ , doMove :: Move m m' -- ^ Where to go next? } -- | Sequence Alignment result
test/HandcraftedSpec.hs view
@@ -55,3 +55,17 @@ it "first sequence" $ a4' `shouldBe` a4Ans it "second sequence" $ b4' `shouldBe` b4Ans it "score" $ score4 `shouldBe` 42++ describe "SemiglobalAlignment. AffineGap. Validate traceback" $ do+ let testAlign = align (SemiglobalAlignment blosum62 (AffineGap (-11) (-1)))+ let s1 = "SSSLNRTTT"+ s2 = "SSSTTT"+ s1ans = "SSSLNRTTT"+ s2ans = "SSS---TTT"++ res = testAlign s1 s2+ (s1', s2') = viewAlignment res++ it "first sequence" $ s1' `shouldBe` s1ans+ it "second sequence" $ s2' `shouldBe` s2ans+ it "score" $ score res `shouldBe` 14
test/JuliaSpec.hs view
@@ -78,9 +78,9 @@ res2 = testAlign "AGGTACC" "CAATG" -- Честно посчитано руками в тетради- it "score" $ score res1 `shouldBe` (-4)+ it "score" $ score res1 `shouldBe` (-2) it "score" $ score res2 `shouldBe` (-8)- it "alignment" $ viewAlignment res1 `shouldBe` ("-AGGT", "CAA-T")+ it "alignment" $ viewAlignment res1 `shouldBe` ("--AGGT", "CAA--T") it "alignment" $ viewAlignment res2 `shouldBe` ("--AGGTACC","CAATG----") describe "GlobalAlignment. Sanity test" $ do