tlynx 0.3.0 → 0.3.1
raw patch · 11 files changed
+157/−131 lines, 11 filesdep +attoparsecdep −arraydep −megaparsecdep −primitive
Dependencies added: attoparsec
Dependencies removed: array, megaparsec, primitive, scientific
Files
- ChangeLog.md +8/−1
- README.md +27/−27
- src/TLynx/Coalesce/Coalesce.hs +7/−7
- src/TLynx/Compare/Compare.hs +15/−15
- src/TLynx/Connect/Connect.hs +10/−10
- src/TLynx/Distance/Distance.hs +22/−20
- src/TLynx/Distance/Options.hs +24/−30
- src/TLynx/Examine/Examine.hs +30/−3
- src/TLynx/Shuffle/Shuffle.hs +4/−4
- src/TLynx/Simulate/Simulate.hs +7/−7
- tlynx.cabal +3/−7
ChangeLog.md view
@@ -2,7 +2,14 @@ # Changelog for ELynx -## Version 0.3.1; in development+## Version 0.3.2; in development+++## Version 0.3.1++- Use Attoparsec.+- Use ByteString consistently.+- Remove elynx-tools dependency from libaries. ## Version 0.3.0
README.md view
@@ -2,7 +2,7 @@ # The ELynx Suite -Version: 0.3.0.+Version: 0.3.1. Reproducible evolution made easy. <p align="center"><img src="https://travis-ci.org/dschrempf/elynx.svg?branch=master"/></p>@@ -90,9 +90,9 @@ slynx --help | head -n -16 - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] COMMAND@@ -136,9 +136,9 @@ slynx concatenate --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE Concatenate sequences found in input files.@@ -157,9 +157,9 @@ slynx examine --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site] Examine sequences. If data is a multi sequence alignment, additionally analyze columns.@@ -179,9 +179,9 @@ slynx filter-rows --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH] [--shorter-than LENGTH] [--standard-characters]@@ -202,9 +202,9 @@ slynx filter-columns --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE [--standard-chars DOUBLE]@@ -226,9 +226,9 @@ slynx simulate --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -305,9 +305,9 @@ slynx sub-sample --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE (-n|--number-of-sites INT)@@ -335,9 +335,9 @@ slynx translate --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT) (-u|--universal-code CODE)@@ -360,9 +360,9 @@ tlynx --help | head -n -16 - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] COMMAND@@ -399,9 +399,9 @@ tlynx compare --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect] [-f|--newick-format FORMAT] NAMES@@ -428,9 +428,9 @@ tlynx examine --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT] Compute summary statistics of phylogenetic trees.@@ -452,9 +452,9 @@ tlynx simulate --help - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE] [-M|--condition-on-mrca] [-l|--lambda DOUBLE] @@ -491,9 +491,9 @@ elynx --help | head -n -16 - ELynx Suite version 0.3.0.+ ELynx Suite version 0.3.1. Developed by Dominik Schrempf.- Compiled on July 30, 2020, at 12:40 pm, UTC.+ Compiled on August 3, 2020, at 12:12 pm, UTC. Usage: elynx COMMAND Validate and redo past ELynx analyses
src/TLynx/Coalesce/Coalesce.hs view
@@ -28,8 +28,8 @@ import Control.Monad.Logger import Control.Monad.Trans.Reader (ask) import Control.Parallel.Strategies-import qualified Data.ByteString.Builder as L-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Builder as BB+import qualified Data.ByteString.Lazy.Char8 as BL import Data.Maybe import qualified Data.Sequence as Seq import qualified Data.Text as T@@ -60,7 +60,7 @@ if s then parMap rpar (formatNChildSumStat . toNChildSumStat) trs else parMap rpar toNewick (map lengthToPhyloTree trs)- let res = L.unlines ls+ let res = BL.unlines ls out "simulated trees" res ".tree" simulateNTreesConcurrently :: ELynx CoalesceArguments (Forest Length Int)@@ -126,13 +126,13 @@ -- nLeaves1 branchLength1 -- nLeaves2 branchLength2 -- ....-formatNChildSumStat :: NChildSumStat -> L.ByteString+formatNChildSumStat :: NChildSumStat -> BL.ByteString formatNChildSumStat s =- L.toLazyByteString . mconcat $ map formatNChildSumStatLine s+ BB.toLazyByteString . mconcat $ map formatNChildSumStatLine s -formatNChildSumStatLine :: BrLnNChildren -> L.Builder+formatNChildSumStatLine :: BrLnNChildren -> BB.Builder formatNChildSumStatLine (l, n) =- L.intDec n <> L.char8 ' ' <> L.doubleDec l <> L.char8 '\n'+ BB.intDec n <> BB.char8 ' ' <> BB.doubleDec l <> BB.char8 '\n' -- | Compute NChilSumStat for a phylogenetic tree. toNChildSumStat :: Measurable e => Tree e a -> NChildSumStat
src/TLynx/Compare/Compare.hs view
@@ -21,8 +21,8 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import Data.List (intercalate) import qualified Data.Map as M import qualified Data.Set as S@@ -48,7 +48,7 @@ FilePath -> ELynx CompareArguments- (Tree PhyloStrict ByteString, Tree PhyloStrict ByteString)+ (Tree PhyloStrict BS.ByteString, Tree PhyloStrict BS.ByteString) treesOneFile tf = do nwF <- argsNewickFormat . local <$> ask $(logInfo) $ T.pack $ "Parse file '" ++ tf ++ "'."@@ -68,7 +68,7 @@ FilePath -> ELynx CompareArguments- (Tree PhyloStrict ByteString, Tree PhyloStrict ByteString)+ (Tree PhyloStrict BS.ByteString, Tree PhyloStrict BS.ByteString) treesTwoFiles tf1 tf2 = do nwF <- argsNewickFormat . local <$> ask $(logInfo) $ T.pack $ "Parse first tree file '" ++ tf1 ++ "'."@@ -93,9 +93,9 @@ error "Need two input files with one tree each or one input file with two trees." liftIO $ hPutStrLn outH "Tree 1:"- liftIO $ L.hPutStrLn outH $ toNewick $ fromStrictTree tr1+ liftIO $ BL.hPutStrLn outH $ toNewick $ fromStrictTree tr1 liftIO $ hPutStrLn outH "Tree 2:"- liftIO $ L.hPutStrLn outH $ toNewick $ fromStrictTree tr2+ liftIO $ BL.hPutStrLn outH $ toNewick $ fromStrictTree tr2 liftIO $ hPutStrLn outH "" -- Intersect trees. (t1, t2) <-@@ -103,8 +103,8 @@ then do let [x, y] = either error id $ intersect [tr1, tr2] liftIO $ hPutStrLn outH "Intersected trees are:"- liftIO $ L.hPutStrLn outH $ toNewick $ fromStrictTree x- liftIO $ L.hPutStrLn outH $ toNewick $ fromStrictTree y+ liftIO $ BL.hPutStrLn outH $ toNewick $ fromStrictTree x+ liftIO $ BL.hPutStrLn outH $ toNewick $ fromStrictTree y return (x, y) else return (tr1, tr2) -- Check input (moved to library functions).@@ -135,8 +135,8 @@ let t1' = normalizeBranchSupport t1 t2' = normalizeBranchSupport t2 $(logDebug) "Trees with normalized branch support values:"- $(logDebug) $ E.decodeUtf8 $ L.toStrict $ toNewick $ fromStrictTree t1'- $(logDebug) $ E.decodeUtf8 $ L.toStrict $ toNewick $ fromStrictTree t2'+ $(logDebug) $ E.decodeUtf8 $ BL.toStrict $ toNewick $ fromStrictTree t1'+ $(logDebug) $ E.decodeUtf8 $ BL.toStrict $ toNewick $ fromStrictTree t2' liftIO $ T.hPutStrLn outH $ formatD@@ -168,14 +168,14 @@ (T.pack $ show $ incompatibleSplits (collapse 0.9 t1') (collapse 0.9 t2')) -- liftIO $ T.hPutStrLn outH $ formatD "Incompatible split (1.01)" -- (T.pack $ show $ incompatibleSplits (collapse 1.01 t1') (collapse 1.01 t2'))- -- liftIO $ L.hPutStrLn outH $ toNewick (collapse 1.01 t1')+ -- liftIO $ BL.hPutStrLn outH $ toNewick (collapse 1.01 t1') -- Bipartitions. when (argsBipartitions l) ( do- let bp1 = either error id $ bipartitions (fmap getName t1)- bp2 = either error id $ bipartitions (fmap getName t2)+ let bp1 = either error id $ bipartitions t1+ bp2 = either error id $ bipartitions t2 bp1Only = bp1 S.\\ bp2 bp2Only = bp2 S.\\ bp1 unless@@ -184,10 +184,10 @@ liftIO $ hPutStrLn outH "" liftIO $ hPutStrLn outH "Bipartitions in Tree 1 that are not in Tree 2."- -- let bp1Strs = map (bphuman L.unpack . bpmap getName) (S.toList bp1Only)+ -- let bp1Strs = map (bphuman BL.unpack . bpmap getName) (S.toList bp1Only) forM_ bp1Only (liftIO . hPutStrLn outH . bpHuman) )- -- let bp1Strs = map (bphuman L.unpack) (S.toList bp1Only)+ -- let bp1Strs = map (bphuman BL.unpack) (S.toList bp1Only) -- liftIO $ hPutStrLn outH $ intercalate "\n" bp1Strs) unless (S.null bp2Only)
src/TLynx/Connect/Connect.hs view
@@ -20,8 +20,8 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.Set as S import ELynx.Data.Tree import ELynx.Export.Tree.Newick (toNewick)@@ -73,9 +73,9 @@ liftIO $ hClose outH connectTrees ::- Tree Length ByteString ->- Tree Length ByteString ->- Forest Length ByteString+ Tree Length BS.ByteString ->+ Tree Length BS.ByteString ->+ Forest Length BS.ByteString connectTrees t = either error id . connect 0 "root" t type Constraint a = S.Set a@@ -106,7 +106,7 @@ FilePath -> ELynx ConnectArguments- (Tree Length ByteString, Tree Length ByteString)+ (Tree Length BS.ByteString, Tree Length BS.ByteString) parseTrees l r = do nwF <- nwFormat . local <$> ask tl <- liftIO $ parseFileWith (oneNewick nwF) l@@ -122,7 +122,7 @@ (tl, tr) <- parseTrees l r let ts = connectTrees tl tr $(logInfo) $ "Connected trees: " <> tShow (length ts)- liftIO $ L.hPutStr h $ L.unlines $ map (toNewick . lengthToPhyloTree) ts+ liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts connectAndFilter :: Handle -> FilePath -> FilePath -> FilePath -> ELynx ConnectArguments ()@@ -130,12 +130,12 @@ nwF <- nwFormat . local <$> ask cts <- liftIO $ parseFileWith (someNewick nwF) c $(logInfo) "Constraints:"- $(logInfo) $ fromBs $ L.intercalate "\n" $ map toNewick cts+ $(logInfo) $ fromBs $ BL.intercalate "\n" $ map toNewick cts (tl, tr) <- parseTrees l r let ts = connectTrees tl tr- cs = map S.fromList $ concatMap multifurcatingGroups cts :: [Constraint ByteString]+ cs = map S.fromList $ concatMap multifurcatingGroups cts :: [Constraint BS.ByteString] -- Only collect trees that are compatible with the constraints. ts' = filter (compatibleWith getName cs) ts $(logInfo) $ "Connected trees: " <> tShow (length ts) $(logInfo) $ "Compatible trees: " <> tShow (length ts')- liftIO $ L.hPutStr h $ L.unlines $ map (toNewick . lengthToPhyloTree) ts'+ liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts'
src/TLynx/Distance/Distance.hs view
@@ -31,9 +31,11 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.Reader hiding (local) import Data.Bifunctor-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import Data.List hiding (intersect) import Data.Maybe+-- TODO: Remove text dependency. import qualified Data.Text as T import qualified Data.Text.IO as T import qualified Data.Text.Lazy as LT@@ -54,20 +56,20 @@ pf :: String pf = "%.3f" -header :: Int -> Int -> DistanceMeasure -> L.ByteString+header :: Int -> Int -> DistanceMeasure -> BL.ByteString header n m d = alignLeft (n + 2) "Tree 1" <> alignLeft (n + 2) "Tree 2" <> alignRight (m + 2)- (L.pack $ show d)+ (BL.pack $ show d) showTriplet ::- (PrintfArg a) => Int -> Int -> [String] -> (Int, Int, a) -> L.ByteString+ (PrintfArg a) => Int -> Int -> [String] -> (Int, Int, a) -> BL.ByteString showTriplet n m args (i, j, d) = i' <> j' <> d' where- i' = alignLeft (n + 2) $ L.pack (args !! i)- j' = alignLeft (n + 2) $ L.pack (args !! j)- d' = alignRight (m + 2) $ L.pack (printf pf d)+ i' = alignLeft (n + 2) $ BL.pack (args !! i)+ j' = alignLeft (n + 2) $ BL.pack (args !! j)+ d' = alignRight (m + 2) $ BL.pack (printf pf d) -- Compute pairwise distances of a list of input trees. Use given distance -- measure. Returns a triple, the first two elements are the indices of the@@ -132,7 +134,7 @@ -- when (isNothing mtree) $ $(logInfo) -- "Compute pairwise distances between trees from different files." $(logDebug) "The trees are:"- $(logDebug) $ LT.toStrict $ LT.decodeUtf8 $ L.unlines $ map toNewick trees+ $(logDebug) $ LT.toStrict $ LT.decodeUtf8 $ BL.unlines $ map toNewick trees -- Set the distance measure. let dist = argsDistance l case argsDistance l of@@ -147,8 +149,8 @@ BranchScore -> $(logInfo) "Use branch score distance." let distanceMeasure' :: (Measurable e1, Measurable e2) =>- Tree e1 L.ByteString ->- Tree e2 L.ByteString ->+ Tree e1 BS.ByteString ->+ Tree e2 BS.ByteString -> Double distanceMeasure' t1 t2 = either error id $ case dist of Symmetric -> second fromIntegral $ symmetric t1 t2@@ -177,10 +179,10 @@ IncompatibleSplit val -> collapse val . normalizeBranchSupport _ -> id -- The trees can be prepared now.- let trees' :: Forest PhyloStrict L.ByteString+ let trees' :: Forest PhyloStrict BS.ByteString trees' = map (collapseF . normalizeF . either error id . toStrictTree) trees $(logDebug) "The prepared trees are:"- $(logDebug) $ LT.toStrict $ LT.decodeUtf8 $ L.unlines $ map (toNewick . fromStrictTree) trees'+ $(logDebug) $ LT.toStrict $ LT.decodeUtf8 $ BL.unlines $ map (toNewick . fromStrictTree) trees' let dsTriplets = case mtree of Nothing -> pairwise distanceMeasure trees' Just pt ->@@ -208,9 +210,9 @@ T.justifyLeft 10 ' ' "Variance: " <> T.pack (printf pf (variance dsVec))- -- L.putStrLn $ L.unlines $ map toNewick ts- -- L.putStrLn $ L.unlines $ map toNewick tsN- -- L.putStrLn $ L.unlines $ map toNewick tsC+ -- BS.putStrLn $ BS.unlines $ map toNewick ts+ -- BS.putStrLn $ BS.unlines $ map toNewick tsN+ -- BS.putStrLn $ BS.unlines $ map toNewick tsC lift $ unless@@ -219,17 +221,17 @@ let n = maximum $ 6 : map length names m = length $ show dist lift $ hPutStrLn outH ""- lift $ L.hPutStrLn outH $ header n m dist+ lift $ BL.hPutStrLn outH $ header n m dist case mname of Nothing -> lift $- L.hPutStr outH $- L.unlines+ BL.hPutStr outH $+ BL.unlines (map (showTriplet n m names) dsTriplets) Just mn -> lift $- L.hPutStr outH $- L.unlines+ BL.hPutStr outH $+ BL.unlines (map (showTriplet n m (mn : names)) dsTriplets) ) liftIO $ hClose outH
src/TLynx/Distance/Options.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-} -- | -- Module : TLynx.Distance.Options@@ -19,21 +20,11 @@ ) where -import Data.Scientific (toRealFloat)-import Data.Void+import qualified Data.Attoparsec.ByteString.Char8 as AC+import qualified Data.ByteString.Char8 as BS import ELynx.Tools import Options.Applicative import TLynx.Parsers-import Text.Megaparsec- ( Parsec,- eof,- try,- )-import Text.Megaparsec.Char- ( char,- string,- )-import Text.Megaparsec.Char.Lexer (scientific) import Text.Printf -- | Supported distance measures.@@ -112,38 +103,41 @@ <> help "Read tree(s) from INPUT-FILES; if more files are given, one tree is expected per file" -symmetric :: Parsec Void String DistanceMeasure+symmetric :: AC.Parser DistanceMeasure symmetric = do- _ <- string "symmetric"- _ <- eof+ _ <- AC.string "symmetric"+ _ <- AC.endOfInput pure Symmetric -incompatibleSplit :: Parsec Void String DistanceMeasure+incompatibleSplit :: AC.Parser DistanceMeasure incompatibleSplit = do- _ <- string "incompatible-split"- _ <- char '['- f <- toRealFloat <$> scientific- _ <- char ']'- _ <- eof+ _ <- AC.string "incompatible-split"+ _ <- AC.char '['+ f <- AC.double+ _ <- AC.char ']'+ _ <- AC.endOfInput if (0 <= f) && (f <= 1) then pure $ IncompatibleSplit f else error "Branch support has to be in [0, 1]." -branchScore :: Parsec Void String DistanceMeasure+branchScore :: AC.Parser DistanceMeasure branchScore = do- _ <- string "branch-score"- _ <- eof+ _ <- AC.string "branch-score"+ _ <- AC.endOfInput pure BranchScore -distanceParser :: Parsec Void String DistanceMeasure-distanceParser =- -- Try first the normalized one, since the normal branch score- -- parser also succeeds in this case.- try symmetric <|> try incompatibleSplit <|> branchScore+-- Try first the normalized one, since the normal branch score+-- parser also succeeds in this case.+distanceParser :: AC.Parser DistanceMeasure+distanceParser = symmetric <|> incompatibleSplit <|> branchScore +-- See 'eitherReader', but for an attoparsec parser.+eitherReadA :: AC.Parser a -> ReadM a+eitherReadA p = eitherReader $ \input -> AC.parseOnly p (BS.pack input)+ distanceOpt :: Parser DistanceMeasure distanceOpt =- option (megaReadM distanceParser) $+ option (eitherReadA distanceParser) $ long "distance" <> short 'd' <> metavar "MEASURE"
src/TLynx/Examine/Examine.hs view
@@ -20,7 +20,8 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import Data.Containers.ListUtils (nubOrd) import Data.List ((\\)) import qualified Data.Text as T@@ -32,8 +33,33 @@ hPutStrLn, ) import TLynx.Examine.Options+import Text.Printf -readTrees :: FilePath -> ELynx ExamineArguments (Forest Phylo L.ByteString)+pretty :: BranchLength -> String+pretty = printf "%.5f"++prettyRow :: String -> String -> BL.ByteString+prettyRow name val = alignLeft 33 n <> alignRight 8 v+ where+ n = BL.pack name+ v = BL.pack val++-- | Examine branches of a tree.+summarizeBranchLengths :: Measurable e => Tree e a -> BL.ByteString+summarizeBranchLengths t =+ BL.intercalate+ "\n"+ [ prettyRow "Origin height: " $ pretty h,+ prettyRow "Mean distance origin leaves: " $ pretty h',+ prettyRow "Total branch length: " $ pretty b+ ]+ where+ n = length $ leaves t+ h = height t+ h' = sum (distancesOriginLeaves t) / fromIntegral n+ b = totalBranchLength t++readTrees :: FilePath -> ELynx ExamineArguments (Forest Phylo BS.ByteString) readTrees fp = do $(logInfo) $ T.pack $ "Read tree(s) from file " <> fp <> "." nf <- argsNewickFormat . local <$> ask@@ -45,12 +71,13 @@ let l = phyloToLengthTree t case l of Left _ -> hPutStrLn h "Branch lengths not available."- Right t' -> L.hPutStrLn h $ summarizeBranchLengths t'+ Right t' -> BL.hPutStrLn h $ summarizeBranchLengths t' unless (null dups) $ hPutStrLn h "" >> hPutStrLn h ("Duplicate leaves: " ++ show dups)+ BL.hPutStrLn h $ "Leave names: " <> BL.intercalate " " lvs where lvs = map getName $ leaves t dups = lvs \\ nubOrd lvs
src/TLynx/Shuffle/Shuffle.hs view
@@ -25,7 +25,7 @@ import Control.Monad.IO.Class (liftIO) import Control.Monad.Logger (logDebug, logInfo) import Control.Monad.Trans.Reader (ask)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Lazy.Char8 as BL import ELynx.Data.Tree import ELynx.Export.Tree.Newick (toNewick) import ELynx.Import.Tree.Newick (oneNewick)@@ -69,16 +69,16 @@ Random -> error "Seed not available; please contact maintainer." Fixed s -> liftIO $ initialize s ts <- liftIO $ shuffleT (nReplicates l) (height t) cs ls gen- liftIO $ L.hPutStr h $ L.unlines $ map (toNewick . lengthToPhyloTree) ts+ liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts liftIO $ hClose h shuffleT :: Int -> -- How many? Double -> -- Stem length. [Double] -> -- Coalescent times.- [L.ByteString] -> -- Leave names.+ [BL.ByteString] -> -- Leave names. GenIO ->- IO (Forest Length L.ByteString)+ IO (Forest Length BL.ByteString) shuffleT n o cs ls gen = do css <- grabble cs n (length cs) gen lss <- grabble ls n (length ls) gen
src/TLynx/Simulate/Simulate.hs view
@@ -35,8 +35,8 @@ import Control.Monad.Logger import Control.Monad.Trans.Reader (ask) import Control.Parallel.Strategies-import qualified Data.ByteString.Builder as L-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Builder as BB+import qualified Data.ByteString.Lazy.Char8 as BL import Data.Foldable (toList) import Data.Maybe import qualified Data.Sequence as Seq@@ -91,7 +91,7 @@ if sumS then parMap rpar (formatNChildSumStat . toNChildSumStat) trs else parMap rpar toNewick $ map lengthToPhyloTree trs- let res = L.unlines ls+ let res = BL.unlines ls out "simulated trees" res ".tree" simulateNTreesConcurrently ::@@ -182,13 +182,13 @@ -- nLeaves1 branchLength1 -- nLeaves2 branchLength2 -- ....-formatNChildSumStat :: NChildSumStat -> L.ByteString+formatNChildSumStat :: NChildSumStat -> BL.ByteString formatNChildSumStat s =- L.toLazyByteString . mconcat $ map formatNChildSumStatLine s+ BB.toLazyByteString . mconcat $ map formatNChildSumStatLine s -formatNChildSumStatLine :: BrLnNChildren -> L.Builder+formatNChildSumStatLine :: BrLnNChildren -> BB.Builder formatNChildSumStatLine (l, n) =- L.intDec n <> L.char8 ' ' <> L.doubleDec l <> L.char8 '\n'+ BB.intDec n <> BB.char8 ' ' <> BB.doubleDec l <> BB.char8 '\n' -- | Compute NChilSumStat for a phylogenetic tree. toNChildSumStat :: Measurable e => Tree e a -> NChildSumStat
tlynx.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4c935a10e73a1a6ec515b771ad749be8dcdb27e3daea89833fa5218ceafe0b47+-- hash: f43d3e414f073da7967cef379f86a9accddecf157c0eb4dcfded3e6282fc8d8f name: tlynx-version: 0.3.0+version: 0.3.1 synopsis: Handle phylogenetic trees description: Examine, compare, and simulate phylogenetic trees in a reproducible way. Please see the README on GitHub at <https://github.com/dschrempf/elynx>. category: Bioinformatics@@ -55,7 +55,7 @@ ghc-options: -Wall -fllvm build-depends: aeson- , array+ , attoparsec , base >=4.7 && <5 , bytestring , comonad@@ -64,13 +64,10 @@ , elynx-tree , gnuplot , lifted-async- , megaparsec , monad-logger , mwc-random , optparse-applicative , parallel- , primitive- , scientific , statistics , text , transformers@@ -86,6 +83,5 @@ ghc-options: -Wall -fllvm -threaded -rtsopts -with-rtsopts=-N build-depends: base >=4.7 && <5- , elynx-tools , tlynx default-language: Haskell2010