packages feed

align 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+180/−13 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Data.Align: allIndices :: MultiTrace i a s -> [i]
+ Data.Align: center :: MultiStep a -> Maybe a
+ Data.Align: centerIndex :: MultiTrace i a s -> i
+ Data.Align: centerStar :: (Vector v a, Num s, Ord s, Ord i) => AlignConfig a s -> [(i, v a)] -> MultiTrace i a s
+ Data.Align: data MultiStep a
+ Data.Align: data MultiTrace i a s
+ Data.Align: debugMultiAlign :: [MultiStep Char] -> String
+ Data.Align: multiTrace :: MultiTrace i a s -> [MultiStep a]
+ Data.Align: otherIndices :: MultiTrace i a s -> [i]
+ Data.Align: others :: MultiStep a -> [Maybe a]
+ Data.Align: stepOfAll :: MultiStep a -> [Maybe a]
+ Data.Align.Demo: alignNuc :: Eq a => [a] -> [a] -> Trace a Double
+ Data.Align.Demo: alignedGlobal :: Trace Char Double
+ Data.Align.Demo: alignedNucPairs :: [Trace Char Double]
+ Data.Align.Demo: alignedNucStar :: MultiTrace Integer Char Double
+ Data.Align.Demo: debug :: Trace Char s -> IO ()
+ Data.Align.Demo: nucs :: [[Char]]
+ Data.Align.Demo: printAlignedGlobal :: IO ()
+ Data.Align.Demo: printAlignedNucPairs :: IO ()
+ Data.Align.Demo: printAlignedNucStar :: IO ()
+ Data.Align.Demo: sampleGlobalConfig :: Eq a => AlignConfig a Double
+ Data.Align.Demo: testIn1 :: [Char]
+ Data.Align.Demo: testIn2 :: [Char]
- Data.Align: align :: (Vector v a, Num s, Eq s, Ord s) => AlignConfig a s -> v a -> v a -> Trace a s
+ Data.Align: align :: (Vector v a, Num s, Ord s) => AlignConfig a s -> v a -> v a -> Trace a s

Files

align.cabal view
@@ -1,5 +1,5 @@ name:                align-version:             0.1.0.0+version:             0.1.1.0 synopsis:            Sequence alignment algorithms. description:         Global or local sequence alignment, not exclusively for text. license:             BSD3@@ -11,11 +11,14 @@ cabal-version:       >=1.10 source-repository head   type: git-  location: http://bitbucket.org/robin_p/align.git+  location: https://github.com/robinp/align.git  library-  exposed-modules:     Data.Align-  build-depends:       base >=4.6 && <5, vector >=0.10, uglymemo >= 0.1+  exposed-modules:     Data.Align,+                       Data.Align.Demo+  build-depends:       base >=4.6 && <5,+                       uglymemo >= 0.1,+                       vector >=0.10   hs-source-dirs:      src   default-language:    Haskell98   ghc-options:         -Wall
src/Data/Align.hs view
@@ -1,21 +1,31 @@ {-# LANGUAGE RecordWildCards #-}+-- | Collection of functions for global, local and multi-sequence alignment. module Data.Align-  ( align+  (+  -- * Global and local alignment+    align   , AlignConfig   , alignConfig   , Step   , Trace, traceScore, trace+  -- * Align streams using sliding windows   , windowedAlign+  -- * Multi-sequence alignment+  , centerStar+  , MultiStep, center, others, stepOfAll+  , MultiTrace, centerIndex, otherIndices, allIndices, multiTrace+  -- * Debugging and demonstration   , debugAlign+  , debugMultiAlign   ) where -import Data.Function (fix)+import Data.Function (fix, on) import qualified Data.List as L+import Data.Maybe (fromMaybe) import Data.MemoUgly import Data.Ord import qualified Data.Vector as V import qualified Data.Vector.Generic as G-import qualified Debug.Trace as D  data AlignConfig a s = AlignConfig   { acPairScore :: a -> a -> s@@ -23,12 +33,22 @@   , ac_gap_penalty :: s   } +-- | Configures the scores used when aligning.+-- The gap scores should be negative in order to be penalties. alignConfig :: (a -> a -> s)  -- ^ Scoring function.-            -> s              -- ^ Initial gap penalty.-            -> s              -- ^ Gap penalty.+            -> s              -- ^ Initial gap score.+            -> s              -- ^ Gap score.             -> AlignConfig a s alignConfig = AlignConfig +-- | Configuration for local alignment.+localAlignConfig+  :: Num s+  => (a -> a -> s)  -- ^ Scoring function.+  -> s              -- ^ Gap score.+  -> AlignConfig a s+localAlignConfig f = alignConfig f 0+ -- | Either an unmatched item or a match. type Step a = Either (Either a a) (a, a) @@ -84,19 +104,19 @@ -- 1.25 -- doppl-e- -- -applied-align :: (G.Vector v a, Num s, Eq s, Ord s)+align :: (G.Vector v a, Num s, Ord s)   => AlignConfig a s   -> v a  -- ^ Left sequence.   -> v a  -- ^ Right sequence.   -> Trace a s-align (AlignConfig {..}) as bs =+align AlignConfig{..} as bs =   revTrace . fix (memo . go) $ (lastIndex as, lastIndex bs)   where   revTrace (Trace s t) = Trace s (reverse t)   lastIndex v = G.length v - 1   --   go k (i,j)-    | i == (-1) || j == (-1) = +    | i == (-1) || j == (-1) =       if i == j then Trace 0 []       else if i == (-1)            then skipInit j stepRight bs@@ -116,7 +136,7 @@  -- | Aligns long streams by performing alignment on windowed sections. windowedAlign :: (Num s, Eq s, Ord s)-  => AlignConfig a s +  => AlignConfig a s   -> Int  -- ^ Window size.   -> [a]  -- ^ Left stream.   -> [a]  -- ^ Right stream.@@ -149,3 +169,100 @@     reverse . dropWhile (not . isMatch) . reverse   --   countMatchOr f = length . filter (\s -> isMatch s || f s)++-- | A step in a multi-sequence alignment.+data MultiStep a = MultiStep+  { center :: Maybe a    -- ^ 'Nothing' means gap insertion.+  , others :: [Maybe a]  -- ^ Parallel to 'otherIndices'.+  }++-- | The result of a multi-sequence alignment.+data MultiTrace i a s = MultiTrace+  { centerIndex :: i+  , otherIndices :: [i]+  , multiTrace :: [MultiStep a]+  }++-- | The center step followed by other steps.+stepOfAll :: MultiStep a -> [Maybe a]+stepOfAll MultiStep{..} = center:others++-- | The center index followed by other indices.+allIndices :: MultiTrace i a s -> [i]+allIndices MultiTrace{..} = centerIndex:otherIndices++-- | Renders a char-based multi-alignment result to a string.+debugMultiAlign :: [MultiStep Char] -> String+debugMultiAlign =+  unlines . map (map charOrDash) . L.transpose . map stepOfAll+  where+  charOrDash = fromMaybe '-'++-- | Align multiple sequences using the Center Star heuristic method by+-- Chin, Ho, Lam, Wong and Chan (2003).+-- <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90.7448&rep=rep1&type=pdf>. +-- Assumes the list of sequences to be non-empty, and the indices to be unique.+centerStar :: (G.Vector v a, Num s, Ord s, Ord i)+  => AlignConfig a s+  -> [(i, v a)]  -- TODO use internal indices rather to make uniqueness sure+  -> MultiTrace i a s+centerStar conf vs =+  let (firstPair:rest) = centerPairs+      initialTrace = MultiTrace+        { centerIndex = fst . fst $ firstPair+        , otherIndices = [snd . fst $ firstPair]+        , multiTrace = initialSteps . trace . snd $ firstPair+        }+  in foldl mergePair initialTrace rest+  where+  initialSteps = go []+    where+    go acc [] = reverse acc+    go acc (s:xs) = go (conv s []:acc) xs+  --+  conv s rest = case s of +      Right (c, d) -> MultiStep (Just c) (Just d:rest)+      Left (Left c) -> MultiStep (Just c) (Nothing:rest)+      Left (Right d) -> MultiStep Nothing (Just d:rest)+  --+  mergePair MultiTrace{..} ((_,j), tr) = MultiTrace+    { centerIndex = centerIndex+    , otherIndices = j:otherIndices+    , multiTrace = mergeSteps multiTrace (trace tr)+    }+    where+    mergeSteps mss = go [] mss+      where+      noOthers = map (const Nothing) . others . head $ mss+      --+      go acc [] [] = reverse acc+      go acc (MultiStep{..}:mss) [] =+        go (MultiStep center (Nothing:others):acc) mss []+      go acc [] (s:ss) = go (conv s noOthers:acc) [] ss+      go acc (m@MultiStep{..}:mss) (s:ss) = case (center, s) of+        (Nothing, Left (Right d)) ->+          go (MultiStep center (Just d:others):acc) mss ss+        (Nothing, _) ->+          go (MultiStep center (Nothing:others):acc) mss (s:ss)+        (Just _, Right (_, d)) ->+          go (MultiStep center (Just d:others):acc) mss ss+        (Just _, Left (Left _)) ->+          go (MultiStep center (Nothing:others):acc) mss ss+        (Just _, Left (Right d)) ->+          go (MultiStep Nothing (Just d:noOthers):acc) (m:mss) ss+  --+  centerPairs+    = snd  -- drop cache+    . L.maximumBy (comparing fst)+    . map (\g -> (starSum g, g))  -- cache scores+    . L.groupBy ((==) `on` (fst . fst))+    . L.sortBy (comparing fst)+    $ pairAligns+    where+    pairAligns = do+      ((i,v):rest) <- L.tails vs+      (j,w) <- rest+      let tr = align conf v w+      [((i,j), tr), ((j,i), tr)]+    --+    starSum = sum . map (traceScore . snd)
+ src/Data/Align/Demo.hs view
@@ -0,0 +1,47 @@+-- | Browse the source of this module to see usage examples.+module Data.Align.Demo where++import Data.Align+import qualified Data.Vector as V++-- * Global alignment.++sampleGlobalConfig :: (Eq a) => AlignConfig a Double+sampleGlobalConfig = alignConfig+  (\a b -> if a == b then 1 else -0.25)+  (-0.5)+  (-1)++testIn1 = "dopple"+testIn2 = "applied"++alignedGlobal =+  align sampleGlobalConfig (V.fromList testIn1) (V.fromList testIn2)++debug = putStrLn . debugAlign . trace++printAlignedGlobal = debug alignedGlobal++-- * Multi-sequence fun.++-- | Example from https://www.biostat.wisc.edu/bmi576/lectures/multiple-alignment.pdf+nucs =+  [ "ATTGCCATT"+  , "ATGGCCATT"+  , "ATCCAATTTT"+  , "ATCTTCTT"+  , "ATTGCCGATT"+  ]++alignNuc a b = align sampleGlobalConfig (V.fromList a) (V.fromList b)++alignedNucPairs = do+  n <- tail nucs+  return $ alignNuc (head nucs) n++printAlignedNucPairs = mapM_ (\x -> debug x >> putStrLn "") alignedNucPairs++alignedNucStar =+  centerStar sampleGlobalConfig $ zip [1..] (map V.fromList nucs)++printAlignedNucStar = putStrLn . debugMultiAlign . multiTrace $ alignedNucStar