tlynx 0.4.1 → 0.5.0
raw patch · 11 files changed
+82/−73 lines, 11 files
Files
- ChangeLog.md +10/−0
- README.md +27/−27
- src/TLynx/Compare/Compare.hs +8/−9
- src/TLynx/Connect/Connect.hs +5/−6
- src/TLynx/Distance/Distance.hs +9/−7
- src/TLynx/Distance/Options.hs +4/−3
- src/TLynx/Examine/Examine.hs +7/−8
- src/TLynx/Parsers.hs +2/−3
- src/TLynx/Shuffle/Shuffle.hs +6/−6
- src/TLynx/Simulate/Simulate.hs +3/−3
- tlynx.cabal +1/−1
ChangeLog.md view
@@ -5,6 +5,16 @@ ## Unreleased changes +## Version 0.5.0++- `modLen`, `modSup`.+- Newtype wrappers for branch length, branch support, and node name. Those data+ types and some functions were also renamed.+- Add `Path`, and `getSubTreeUnsafe` to tree zipper.+- Rename `unsafe` functions so that `unsafe` is at the end.+- Many small changes.++ ## Version 0.4.1 - Improve `TimeSpec` (Point process).
README.md view
@@ -2,7 +2,7 @@ # The ELynx Suite -Version: 0.4.1.+Version: 0.5.0. 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.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] [--no-elynx-file] COMMAND@@ -137,9 +137,9 @@ slynx concatenate --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE Concatenate sequences found in input files.@@ -158,9 +158,9 @@ slynx examine --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site] Examine sequences. If data is a multi sequence alignment, additionally analyze columns.@@ -180,9 +180,9 @@ slynx filter-rows --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH] [--shorter-than LENGTH] [--standard-characters]@@ -203,9 +203,9 @@ slynx filter-columns --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE [--standard-chars DOUBLE]@@ -227,9 +227,9 @@ slynx simulate --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -306,9 +306,9 @@ slynx sub-sample --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE (-n|--number-of-sites INT)@@ -336,9 +336,9 @@ slynx translate --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT) (-u|--universal-code CODE)@@ -361,9 +361,9 @@ tlynx --help | head -n -16 - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] [--no-elynx-file] COMMAND@@ -401,9 +401,9 @@ tlynx compare --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect] [-f|--newick-format FORMAT] NAMES@@ -430,9 +430,9 @@ tlynx examine --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT] Compute summary statistics of phylogenetic trees.@@ -454,9 +454,9 @@ tlynx simulate --help - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: tlynx simulate (-t|--nTrees INT) (-n|--nLeaves INT) PROCESS [-u|--sub-sample DOUBLE] [-s|--summary-statistics] @@ -491,9 +491,9 @@ elynx --help | head -n -16 - ELynx Suite version 0.4.1.+ ELynx Suite version 0.5.0. Developed by Dominik Schrempf.- Compiled on October 16, 2020, at 12:46 pm, UTC.+ Compiled on November 10, 2020, at 14:29 pm, UTC. Usage: elynx COMMAND Validate and redo past ELynx analyses
src/TLynx/Compare/Compare.hs view
@@ -21,7 +21,6 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-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@@ -46,7 +45,7 @@ FilePath -> ELynx CompareArguments- (Tree Phylo BS.ByteString, Tree Phylo BS.ByteString)+ (Tree Phylo Name, Tree Phylo Name) treesOneFile tf = do nwF <- argsNewickFormat . local <$> ask $(logInfo) $ T.pack $ "Parse file '" ++ tf ++ "'."@@ -63,7 +62,7 @@ FilePath -> ELynx CompareArguments- (Tree Phylo BS.ByteString, Tree Phylo BS.ByteString)+ (Tree Phylo Name, Tree Phylo Name) treesTwoFiles tf1 tf2 = do nwF <- argsNewickFormat . local <$> ask $(logInfo) $ T.pack $ "Parse first tree file '" ++ tf1 ++ "'."@@ -112,8 +111,8 @@ analyzeDistance :: Handle ->- Tree Phylo BS.ByteString ->- Tree Phylo BS.ByteString ->+ Tree Phylo Name ->+ Tree Phylo Name -> ELynx CompareArguments () analyzeDistance outH t1 t2 = do let formatD str val = T.justifyLeft 25 ' ' str <> " " <> val@@ -178,8 +177,8 @@ analyzeBipartitions :: Handle ->- Tree Phylo BS.ByteString ->- Tree Phylo BS.ByteString ->+ Tree Phylo Name ->+ Tree Phylo Name -> ELynx CompareArguments () analyzeBipartitions outH t1 t2 = case (phyloToLengthTree t1, phyloToLengthTree t2) of@@ -215,8 +214,8 @@ liftIO $ hPutStrLn outH "There are no common bipartitions." liftIO $ hPutStrLn outH "No plots have been generated." else do- let bpToBrLen1 = M.map getLen $ either error id $ bipartitionToBranch t1l- bpToBrLen2 = M.map getLen $ either error id $ bipartitionToBranch t2l+ let bpToBrLen1 = M.map (fromLength . getLen) $ either error id $ bipartitionToBranch t1l+ bpToBrLen2 = M.map (fromLength . getLen) $ either error id $ bipartitionToBranch t2l liftIO $ hPutStrLn outH
src/TLynx/Connect/Connect.hs view
@@ -20,7 +20,6 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.Set as S import ELynx.Tools@@ -68,9 +67,9 @@ liftIO $ hClose outH connectTrees ::- Tree Length BS.ByteString ->- Tree Length BS.ByteString ->- Forest Length BS.ByteString+ Tree Length Name ->+ Tree Length Name ->+ Forest Length Name connectTrees t = either error id . connect 0 "root" t type Constraint a = S.Set a@@ -103,7 +102,7 @@ FilePath -> ELynx ConnectArguments- (Tree Length BS.ByteString, Tree Length BS.ByteString)+ (Tree Length Name, Tree Length Name) parseTreeTuple l r = do nwF <- nwFormat . local <$> ask tl <- liftIO $ parseTree nwF l@@ -130,7 +129,7 @@ $(logInfo) $ fromBs $ BL.intercalate "\n" $ map toNewick cts (tl, tr) <- parseTreeTuple l r let ts = connectTrees tl tr- cs = map S.fromList $ concatMap multifurcatingGroups cts :: [Constraint BS.ByteString]+ cs = map S.fromList $ concatMap multifurcatingGroups cts :: [Constraint Name] -- Only collect trees that are compatible with the constraints. ts' = filter (compatibleWith getName cs) ts $(logInfo) $ "Connected trees: " <> tShow (length ts)
src/TLynx/Distance/Distance.hs view
@@ -31,7 +31,6 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.Reader hiding (local) import Data.Bifunctor-import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BL import Data.List hiding (intersect) import Data.Maybe@@ -136,17 +135,20 @@ ++ "." BranchScore -> $(logInfo) "Use branch score distance." let distanceMeasure' ::- Tree Phylo BS.ByteString ->- Tree Phylo BS.ByteString ->+ Tree Phylo Name ->+ Tree Phylo Name -> Double distanceMeasure' t1 t2 = either error id $ case dist of Symmetric -> second fromIntegral $ symmetric t1 t2- IncompatibleSplit val -> second fromIntegral $ incompatibleSplits- (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t1)- (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t2)+ IncompatibleSplit val ->+ second fromIntegral $+ incompatibleSplits+ (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t1)+ (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t2) BranchScore -> branchScore (normalizeF $ either error id $ phyloToLengthTree t1) (normalizeF $ either error id $ phyloToLengthTree t2)- where normalizeF = if argsNormalize l then normalizeBranchLengths else id+ where+ normalizeF = if argsNormalize l then normalizeBranchLengths else id -- Possibly intersect trees before distance calculation. when (argsIntersect l) $ $(logInfo) "Intersect trees before calculation of distances."
src/TLynx/Distance/Options.hs view
@@ -23,6 +23,7 @@ import qualified Data.Attoparsec.ByteString.Char8 as AC import qualified Data.ByteString.Char8 as BS import ELynx.Tools+import ELynx.Tree (Support (..), toSupportUnsafe) import Options.Applicative import TLynx.Parsers import Text.Printf@@ -33,7 +34,7 @@ Symmetric | -- | Incompatible split distance; collapse nodes -- with branch support below given value.- IncompatibleSplit Double+ IncompatibleSplit Support | -- | Branch score distance. BranchScore deriving (Eq, Generic)@@ -44,7 +45,7 @@ instance Show DistanceMeasure where show Symmetric = "Symmetric"- show (IncompatibleSplit c) = "Incompatible Split (" ++ printf "%.2f" c ++ ")"+ show (IncompatibleSplit c) = "Incompatible Split (" ++ printf "%.2f" (fromSupport c) ++ ")" show BranchScore = "Branch Score" -- | Arguments needed to compute distance measures.@@ -117,7 +118,7 @@ _ <- AC.char ']' _ <- AC.endOfInput if (0 <= f) && (f <= 1)- then pure $ IncompatibleSplit f+ then pure $ IncompatibleSplit $ toSupportUnsafe f else error "Branch support has to be in [0, 1]." branchScore :: AC.Parser DistanceMeasure
src/TLynx/Examine/Examine.hs view
@@ -20,7 +20,6 @@ import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Reader (ask)-import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BL import Data.Containers.ListUtils (nubOrd) import Data.List ((\\))@@ -35,8 +34,8 @@ import TLynx.Parsers import Text.Printf -pretty :: BranchLength -> String-pretty = printf "%.5f"+pretty :: Length -> String+pretty = printf "%.5f" . fromLength prettyRow :: String -> String -> BL.ByteString prettyRow name val = alignLeft 33 n <> alignRight 8 v@@ -45,8 +44,8 @@ v = BL.pack val -- | Examine branches of a tree.-summarizeBranchLengths :: Measurable e => Tree e a -> BL.ByteString-summarizeBranchLengths t =+summarizeLengths :: Measurable e => Tree e a -> BL.ByteString+summarizeLengths t = BL.intercalate "\n" [ prettyRow "Origin height: " $ pretty h,@@ -59,7 +58,7 @@ h' = sum (distancesOriginLeaves t) / fromIntegral n b = totalBranchLength t -readTrees :: FilePath -> ELynx ExamineArguments (Forest Phylo BS.ByteString)+readTrees :: FilePath -> ELynx ExamineArguments (Forest Phylo Name) readTrees fp = do $(logInfo) $ T.pack $ "Read tree(s) from file " <> fp <> "." nf <- argsNewickFormat . local <$> ask@@ -71,7 +70,7 @@ let l = phyloToLengthTree t case l of Left _ -> hPutStrLn h "Branch lengths not available."- Right t' -> BL.hPutStrLn h $ summarizeBranchLengths t'+ Right t' -> BL.hPutStrLn h $ summarizeLengths t' unless (null dups) $ hPutStrLn h "" >> hPutStrLn@@ -79,7 +78,7 @@ ("Duplicate leaves: " ++ show dups) BL.hPutStrLn h $ "Leave names: " <> BL.intercalate " " lvs where- lvs = map getName $ leaves t+ lvs = map (fromName . getName) $ leaves t dups = lvs \\ nubOrd lvs -- | Examine phylogenetic trees.
src/TLynx/Parsers.hs view
@@ -19,7 +19,6 @@ ) where -import qualified Data.ByteString.Char8 as BS import Data.List import ELynx.Tools import ELynx.Tree@@ -35,7 +34,7 @@ -- -- Error if no or more than one trees are found. -- Error if both file formats fail to parse.-parseTree :: NewickFormat -> FilePath -> IO (Tree Phylo BS.ByteString)+parseTree :: NewickFormat -> FilePath -> IO (Tree Phylo Name) parseTree fmt fn = do parseResultNewick <- runParserOnFile (oneNewick fmt) fn case parseResultNewick of@@ -51,7 +50,7 @@ -- | Parse a Newick tree file or a Nexus file with Newick trees. -- -- Error if both file formats fail to parse.-parseTrees :: NewickFormat -> FilePath -> IO (Forest Phylo BS.ByteString)+parseTrees :: NewickFormat -> FilePath -> IO (Forest Phylo Name) parseTrees fmt fn = do parseResultNewick <- runParserOnFile (someNewick fmt) fn case parseResultNewick of
src/TLynx/Shuffle/Shuffle.hs view
@@ -54,10 +54,10 @@ let dh = sum $ map (height t -) (distancesOriginLeaves t) $(logDebug) $ "Distance in branch length to being ultrametric: " <> tShow dh when (dh > 2e-4) (error "Tree is not ultrametric.")- when (dh > eps && dh < 2e-4) $+ when (dh > toLengthUnsafe eps && dh < 2e-4) $ $(logInfo) "Tree is nearly ultrametric, ignore branch length differences smaller than 2e-4."- when (dh < eps) $ $(logInfo) "Tree is ultrametric."+ when (dh < toLengthUnsafe eps) $ $(logInfo) "Tree is ultrametric." let cs = filter (> 0) $ labels $ C.extend rootHeight t ls = map getName $ leaves t $(logDebug) $ "Number of coalescent times: " <> tShow (length cs)@@ -73,11 +73,11 @@ shuffleT :: Int -> -- How many?- Double -> -- Stem length.- [Double] -> -- Coalescent times.- [BL.ByteString] -> -- Leave names.+ Length -> -- Stem length.+ [Length] -> -- Coalescent times.+ [Name] -> -- Leave names. GenIO ->- IO (Forest Length BL.ByteString)+ IO (Forest Length Name) 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
@@ -209,10 +209,10 @@ return [dropLeavesWith (`Set.notMember` ls) tree | ls <- lsSets] -- Pair of branch length with number of extant children.-type BrLnNChildren = (BranchLength, Int)+type BrLnNChildren = (Length, Int) -- Possible summary statistic of phylogenetic trees. A list of tuples--- (BranchLength, NumberOfExtantChildrenBelowThisBranch).+-- (Length, NumberOfExtantChildrenBelowThisBranch). type NChildSumStat = [BrLnNChildren] -- Format the summary statistics in the following form:@@ -228,7 +228,7 @@ formatNChildSumStatLine :: BrLnNChildren -> BB.Builder formatNChildSumStatLine (l, n) =- BB.intDec n <> BB.char8 ' ' <> BB.doubleDec l <> BB.char8 '\n'+ BB.intDec n <> BB.char8 ' ' <> BB.doubleDec (fromLength l) <> BB.char8 '\n' -- Compute NChilSumStat for a phylogenetic tree. toNChildSumStat :: Measurable e => Tree e a -> NChildSumStat
tlynx.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: tlynx-version: 0.4.1+version: 0.5.0 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