packages feed

diversity 0.4.0.2 → 0.5.0.0

raw patch · 6 files changed

+201/−81 lines, 6 filesdep +MonadRandomdep +random-shufflePVP ok

version bump matches the API change (PVP)

Dependencies added: MonadRandom, random-shuffle

API changes (from Hackage documentation)

+ Math.Diversity.RandomSampling: subsample :: (Eq a, Ord a) => Int -> Int -> StdGen -> [a] -> [a]
+ Math.Diversity.RandomSampling: subsampleES :: (Eq a, Ord a) => Int -> Int -> Int -> [a] -> IO (Double, Double)
+ Math.Diversity.RandomSampling: subsampleSpecies :: (Eq a, Ord a) => Int -> Int -> StdGen -> [a] -> Int
+ Math.Diversity.Statistics: median :: [Double] -> Maybe Double
+ Math.Diversity.Statistics: medmad :: [Double] -> (Double, Double)
- Math.Diversity.Diversity: rarefactionCurve :: (Eq a, Ord a) => Bool -> Integer -> Integer -> [a] -> [(Int, Double)]
+ Math.Diversity.Diversity: rarefactionCurve :: (Eq a, Ord a) => Bool -> Int -> Integer -> Integer -> [a] -> IO [(Int, (Double, Double))]
- Math.Diversity.Diversity: rarefactionSampleCurve :: (Ord a, Ord b) => Bool -> Int -> Int -> [(a, b)] -> [(Int, Double)]
+ Math.Diversity.Diversity: rarefactionSampleCurve :: (Ord a, Ord b) => Bool -> Int -> Int -> [(a, b)] -> IO [(Int, (Double, Double))]
- Math.Diversity.Print: printRarefaction :: Bool -> Bool -> Int -> Int -> Label -> Window -> PositionMap -> String
+ Math.Diversity.Print: printRarefaction :: Bool -> Bool -> Int -> Int -> Int -> Label -> Window -> PositionMap -> IO String
- Math.Diversity.Print: printRarefactionCurve :: Bool -> Bool -> Bool -> Int -> Int -> Label -> Window -> PositionMap -> String
+ Math.Diversity.Print: printRarefactionCurve :: Bool -> Bool -> Bool -> Int -> Int -> Int -> Label -> Window -> PositionMap -> IO String

Files

diversity.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                diversity-version:             0.4.0.2+version:             0.5.0.0 synopsis:            Return the diversity at each position for all sequences in a fasta file description:         Find the diversity of a collection of entities, mainly for use with fasta sequences. Produces a binary which works on fasta files to find the diversity of any order and rarefaction curves for a sliding window across all positions in the sequences. To analyze just a collection of entities, just use the whole sequences and list flag. homepage:            https://github.com/GregorySchwartz/diversity@@ -18,9 +18,9 @@ library   ghc-options: -O2   hs-source-dirs:      src/src-lib-  exposed-modules:     Math.Diversity.Types, Math.Diversity.Diversity, Math.Diversity.GenerateDiversity, Math.Diversity.Print+  exposed-modules:     Math.Diversity.Types, Math.Diversity.Diversity, Math.Diversity.GenerateDiversity, Math.Diversity.Print, Math.Diversity.Statistics, Math.Diversity.RandomSampling   -- other-modules:-  build-depends:       base >=4.6 && <4.8, containers >=0.5 && <0.6, split >=0.2 && <0.3, parsec >=3.1 && <4.0, fasta >=0.5.1.3 && <0.6, math-functions >=0.1 && <0.2, scientific >= 0.3 && < 0.4+  build-depends:       base >=4.6 && <4.8, containers >=0.5 && <0.6, split >=0.2 && <0.3, parsec >=3.1 && <4.0, fasta >=0.5.1.3 && <0.6, math-functions >=0.1 && <0.2, scientific >= 0.3 && < 0.4, random-shuffle >=0.0 && < 0.1, MonadRandom >=0.3 && <0.4  executable diversity   ghc-options: -O2
src/src-exec/Main.hs view
@@ -24,6 +24,7 @@                        , inputSampleField       :: Int                        , inputSubsampling       :: String                        , fastBin                :: Bool+                       , runs                   :: Int                        , removeN                :: Bool                        , wholeSeq               :: Bool                        , list                   :: Bool@@ -87,6 +88,17 @@                  \ coefficient for the rarefaction analysis. This method\                  \ results in NaNs for larger numbers, so in that case you\                  \ you should use the slower, more accurate default method" )+      <*> option auto+          ( long "input-runs"+         <> short 'R'+         <> metavar "INT"+         <> value 0+         <> help "The number of runs for empirical resampling rarefaction.\+                 \ This method does not compute the theoretical, it reports the\+                 \ actual median and median absolute deviation (MAD) values of\+                 \ this many runs. If this value is not 0, empirical\+                 \ rarefaction is automatically enabled (individual based only,\+                 \ not for sample based)" )       <*> switch           ( long "remove-N"          <> short 'n'@@ -141,11 +153,11 @@  generateDiversity :: Options -> IO () generateDiversity opts = do-    contentsFile    <- if (null . inputFasta $ opts)+    contentsFile    <- if null . inputFasta $ opts                         then getContents                         else readFile . inputFasta $ opts     let lineIt       = unlines . (:) ">" . intersperse ">" . lines-        contents     = if (list opts) then lineIt contentsFile else contentsFile+        contents     = if list opts then lineIt contentsFile else contentsFile         label        = inputLabel opts         order        = inputOrder opts         window       = inputWindow opts@@ -172,27 +184,31 @@            $ positionMap     if (null . outputRarefaction $ opts)         then return ()-        else howToOutput (outputRarefaction opts)-           $ printRarefaction-             (sample opts)-             (fastBin opts)-             start-             interval-             label-             window-             positionMap+        else do+            s <- printRarefaction+                 (sample opts)+                 (fastBin opts)+                 (runs opts)+                 start+                 interval+                 label+                 window+                 positionMap+            howToOutput (outputRarefaction opts) s     if (null . outputRarefactionCurve $ opts)         then return ()-        else howToOutput (outputRarefactionCurve opts)-           $ printRarefactionCurve-             (rarefactionDF opts)-             (sample opts)-             (fastBin opts)-             start-             interval-             label-             window-             positionMap+        else do+            s <- printRarefactionCurve+                 (rarefactionDF opts)+                 (sample opts)+                 (fastBin opts)+                 (runs opts)+                 start+                 interval+                 label+                 window+                 positionMap+            howToOutput (outputRarefactionCurve opts) s  main :: IO () main = execParser opts >>= generateDiversity
src/src-lib/Math/Diversity/Diversity.hs view
@@ -14,11 +14,13 @@  -- Built-in import Data.List-import Data.Ratio import qualified Data.Set as Set import Numeric.SpecFunctions (choose) import Data.Function (on) +-- Local+import Math.Diversity.RandomSampling+ -- | Takes two strings, returns Hamming distance hamming :: String -> String -> Int hamming xs ys = length $ filter not $ zipWith (==) xs ys@@ -60,18 +62,23 @@ -- | Returns the rarefaction curve for each position in a list rarefactionCurve :: (Eq a, Ord a)                  => Bool+                 -> Int                  -> Integer                  -> Integer                  -> [a]-                 -> [(Int, Double)]-rarefactionCurve fastBin start interval xs =-    map rarefact $ [start,(start + interval)..(n_total - 1)] ++ [n_total]+                 -> IO [(Int, (Double, Double))]+rarefactionCurve !fastBin !runs !start !interval !xs =+        mapM rarefact $ [start,(start + interval)..(n_total - 1)] ++ [n_total]   where-    rarefact n-        | n == 0       = (fromIntegral n, 0)-        | n == 1       = (fromIntegral n, 1)-        | n == n_total = (fromIntegral n, k)-        | otherwise    = (fromIntegral n, k - inner n)+    rarefact !n+        | n == 0       = return (fromIntegral n, (0, 0))+        | n == 1       = return (fromIntegral n, (1, 0))+        | n == n_total = return (fromIntegral n, (k, 0))+        | runs == 0    = return (fromIntegral n, (k - inner n, 0))+        | otherwise    = do+            statTuple <-+                subsampleES runs (fromIntegral n_total) (fromIntegral n) xs+            return (fromIntegral n, statTuple)     inner n = ( \x -> if fastBin                         then x / choose (fromIntegral n_total) (fromIntegral n)                         else x )@@ -94,14 +101,14 @@                        -> Int                        -> Int                        -> [(a, b)]-                       -> [(Int, Double)]-rarefactionSampleCurve fastBin start interval ls =-    map rarefact $ [start,(start + interval)..(t_total - 1)] ++ [t_total]+                       -> IO [(Int, (Double, Double))]+rarefactionSampleCurve !fastBin !start !interval !ls =+    mapM rarefact $ [start,(start + interval)..(t_total - 1)] ++ [t_total]   where-    rarefact t-        | t == 0       = (t, 0)-        | t == t_total = (t, richness)-        | otherwise    = (t, richness - inner t)+    rarefact !t+        | t == 0       = return (t, (0, 0))+        | t == t_total = return (t, (richness, 0))+        | otherwise    = return (t, (richness - inner t, 0))     inner t     = ( \x -> if fastBin                             then x / choose t_total t                             else x )@@ -120,6 +127,6 @@  -- | Calculates the percent of the curve that is above 95% of height of the curve rarefactionViable :: [Double] -> Double-rarefactionViable xs = (genericLength valid / genericLength xs) * 100+rarefactionViable !xs = (genericLength valid / genericLength xs) * 100   where     valid = dropWhile (< (0.95 * last xs)) xs
src/src-lib/Math/Diversity/Print.hs view
@@ -44,28 +44,29 @@                  -> Bool                  -> Int                  -> Int+                 -> Int                  -> Label                  -> Window                  -> PositionMap-                 -> String-printRarefaction sample fastBin start interval label window positionMap =-    header ++ body+                 -> IO String+printRarefaction+    sample fastBin runs start interval label window positionMap = do+    body <- fmap unlines . mapM mapLine . M.toAscList $ positionMap+    return (header ++ body)   where     header           = "label,window,position,weight,percent_above\n"-    body             = unlines-                     . map mapLine-                     . M.toAscList-                     $ positionMap-    mapLine (p, xs) = intercalate "," . line p $ xs-    line p xs  = [ label-                 , show window-                 , show p-                 , show . length $ xs-                 , show-                 . rarefactionViable . map snd . getRarefactionCurve sample $ xs-                 ]+    mapLine (p, xs)  = fmap (intercalate ",") . line p $ xs+    line p xs        = do+        curve <- getRarefactionCurve sample xs+        return [ label+               , show window+               , show p+               , show . length $ xs+               , show . rarefactionViable . map (snd . snd) $ curve+               ]     getRarefactionCurve True = rarefactionSampleCurve fastBin start interval-    getRarefactionCurve False = rarefactionCurve fastBin (fromIntegral start) (fromIntegral interval)+    getRarefactionCurve False = rarefactionCurve+        fastBin runs (fromIntegral start) (fromIntegral interval)  -- Return the results of the rarefaction analysis of the entire curve in -- string form for saving to a file@@ -74,35 +75,50 @@                       -> Bool                       -> Int                       -> Int+                      -> Int                       -> Label                       -> Window                       -> PositionMap-                      -> String-printRarefactionCurve asDF sample fastBin start interval label window positionMap =-    header asDF ++ body+                      -> IO String+printRarefactionCurve+    asDF sample fastBin runs start interval label window positionMap = do+    body <- fmap unlines . mapM mapLine . M.toAscList $ positionMap++    return (header asDF ++ body)   where-    header False     = "label,window,position,weight,curve\n"-    header True      = "label,window,position,weight,subsample,vertical_curve\n"-    body             = unlines-                     . map mapLine-                     . M.toAscList-                     $ positionMap+    header False      = "label,window,position,weight,expected_richness,\+                        \mad\n"+    header True       = "label,window,position,weight,subsample,\+                        \expected_richness,mad\n"     mapLine (!p, !xs) = line asDF p xs-    line False p xs   = intercalate "," [ label+    line False p xs   = do+        curve <- getRarefactionCurve sample xs+        return . intercalate "," $ [ label+                                   , show window+                                   , show p+                                   , show . length $ xs+                                   , intercalate "/"+                                   . map (show . fst . snd)+                                   $ curve+                                   , intercalate "/"+                                   . map (show . snd . snd)+                                   $ curve+                                   ]+    line True p xs    = do+        curve <- getRarefactionCurve sample xs+        return . intercalate "\n"+               . map ( \(!x, (!y, !z))+                     -> intercalate "," [ label                                         , show window                                         , show p-                                        , show . length $ xs-                                        , intercalate "/" . map (show . snd) . getRarefactionCurve sample $ xs-                                        ]-    line True p xs    = intercalate "\n"-                      . map ( \(!x, !y) -> intercalate "," [ label-                                                           , show window-                                                           , show p-                                                           , show . length $ xs-                                                           , show x-                                                           , show y-                                                           ] )-                      . getRarefactionCurve sample $ xs+                                        , show+                                        . length+                                        $ xs+                                        , show x+                                        , show y+                                        , show z+                                        ] )+               $ curve     getRarefactionCurve True = rarefactionSampleCurve fastBin start interval-    getRarefactionCurve False =-        rarefactionCurve fastBin (fromIntegral start) (fromIntegral interval)+    getRarefactionCurve False = rarefactionCurve+        fastBin runs (fromIntegral start) (fromIntegral interval)
+ src/src-lib/Math/Diversity/RandomSampling.hs view
@@ -0,0 +1,47 @@+-- RandomSampling module.+-- By Gregory W. Schwartz+--+{- | Collection of functions pertaining to getting random samples from+- a population+-}++module Math.Diversity.RandomSampling ( subsample+                                     , subsampleSpecies+                                     , subsampleES ) where++-- Built-in+import qualified Data.Set as Set++-- Cabal+import Control.Monad.Random+import System.Random.Shuffle++-- Local+import Math.Diversity.Statistics++-- | Gets a random sampling by getting either the requested amount either+-- directly or through the inverse (for speed)+subsample :: (Eq a, Ord a) => Int -> Int -> StdGen -> [a] -> [a]+subsample size n gen xs+    | n > size `div` 2 = drop (size - n) shuffled+    | otherwise = take n shuffled+  where+    shuffled  = shuffle' xs size gen++-- | Get the number of types of entities in a subsample+subsampleSpecies :: (Eq a, Ord a) => Int -> Int -> StdGen -> [a] -> Int+subsampleSpecies size n gen = Set.size . Set.fromList . subsample size n gen++-- | Repeat the sampling to get a median and MAD value for the runs for the+-- expected species counts+subsampleES :: (Eq a, Ord a) => Int -> Int -> Int -> [a] -> IO (Double, Double)+subsampleES runs size n xs = do+    allRuns <- mapM (const run) [1..runs]++    let statTuple = medmad . map fromIntegral $ allRuns++    return statTuple+  where+    run = do+        gen <- newStdGen+        return $ subsampleSpecies size n gen xs
+ src/src-lib/Math/Diversity/Statistics.hs view
@@ -0,0 +1,34 @@+-- Statistics module.+-- By Gregory W. Schwartz+--+{- | Collection of functions pertaining statistics needed in the library+-}++module Math.Diversity.Statistics ( median, medmad ) where++-- Built-in+import Data.List+import Data.Maybe++-- | Get the median, adapted from+-- http://rosettacode.org/wiki/Averages/Median#Haskell, but FIXED due to+-- zero indexing+median :: [Double] -> Maybe Double+median xs | null xs  = Nothing+          | odd  len = Just $ xs !! mid+          | even len = Just meanMedian+  where+    len        = length xs+    mid        = len `div` 2+    meanMedian = (xs !! (mid - 1) + xs !! mid) / 2++-- | Get the median and median absolute deviation (MAD) of a list of numbers+medmad :: [Double] -> (Double, Double)+medmad xs = (sampleMedian, mad)+  where+    mad          = fromJust+                 . median+                 . sort+                 . map (\x -> abs (x - sampleMedian))+                 $ xs+    sampleMedian = fromJust . median . sort $ xs