packages feed

tlynx 0.5.1.1 → 0.6.0.0

raw patch · 12 files changed

+267/−668 lines, 12 filesdep +asyncdep +data-default-classdep −lifted-asyncdep −monad-loggerdep ~aesondep ~attoparsecdep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: async, data-default-class

Dependencies removed: lifted-async, monad-logger

Dependency ranges changed: aeson, attoparsec, bytestring, comonad, containers, elynx-tools, elynx-tree, gnuplot, mwc-random, optparse-applicative, parallel, statistics, text, transformers, vector

API changes (from Hackage documentation)

- TLynx.Shuffle.Options: ShuffleArguments :: NewickFormat -> Int -> FilePath -> Seed -> ShuffleArguments
+ TLynx.Shuffle.Options: ShuffleArguments :: NewickFormat -> Int -> FilePath -> SeedOpt -> ShuffleArguments
- TLynx.Shuffle.Options: [argsSeed] :: ShuffleArguments -> Seed
+ TLynx.Shuffle.Options: [argsSeed] :: ShuffleArguments -> SeedOpt
- TLynx.Simulate.Options: SimulateArguments :: Int -> Int -> Process -> Maybe Double -> Bool -> Seed -> SimulateArguments
+ TLynx.Simulate.Options: SimulateArguments :: Int -> Int -> Process -> Maybe Double -> Bool -> SeedOpt -> SimulateArguments
- TLynx.Simulate.Options: [argsSeed] :: SimulateArguments -> Seed
+ TLynx.Simulate.Options: [argsSeed] :: SimulateArguments -> SeedOpt

Files

ChangeLog.md view
@@ -5,6 +5,16 @@ ## Unreleased changes  +## Version 0.6.0.0++-   **elynx-tree:** remove parallel folds with layers (`parBranchFoldMapWithLayer`+    too special and slow).+-   **elynx-tree:** fix various tree instances; add zip trees with appropriate+    instances.+-   Remove `monad-logger` dependency and implement lighter alternative.+-   Significant changes to the tool chain.++ ## Version 0.5.1.0  -   **elynx-tree:** new functions `isValidPath`, `isLeaf`, `depth`; add conversion
README.md view
@@ -2,7 +2,7 @@  # The ELynx Suite -Version: 0.5.1.0.+Version: 0.6.0.0. Reproducible evolution made easy.  <p align="center"><img src="https://travis-ci.org/dschrempf/elynx.svg?branch=master"/></p>@@ -39,7 +39,7 @@  # Installation -ELynx is written in [Haskell](https://www.haskell.org/) and can be installed with [Stack](https://docs.haskellstack.org/en/stable/README/).+ELynx is written in [Haskell](https://www.haskell.org/) and can be installed with [cabal-install](https://cabal.readthedocs.io/en/3.4/cabal-commands.html) or [Stack](https://docs.haskellstack.org/en/stable/README/).  1.  Install Stack with your package manager, or directly from the web     page.@@ -67,15 +67,15 @@     [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable. Then, they can be used directly.  -# SLynx+# Get help -Handle evolutionary sequences.+For example: -    stack exec slynx -- --help | head -n -16+    slynx --help -    ELynx Suite version 0.5.1.0.+    ELynx Suite version 0.6.0.0.     Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.+    Compiled on September 3, 2021, at 20:56 pm, UTC.          Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME]                   [-f|--force] [--no-elynx-file] COMMAND@@ -84,7 +84,7 @@     Available options:       -h,--help                Show this help text       -V,--version             Show version-      -v,--verbosity VALUE     Be verbose; one of: Quiet Warning Info Debug+      -v,--verbosity VALUE     Be verbose; one of: Quiet Warn Info Debug                                (default: Info)       -o,--output-file-basename NAME                                Specify base name of output file@@ -112,107 +112,33 @@       - Protein (amino acids)       - ProteinX (amino acids; including gaps)       - ProteinS (amino acids; including gaps, and translation stops)---## Concatenate--Concatenate multi sequence alignments.--    stack exec slynx -- concatenate --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE-      Concatenate sequences found in input files.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      -h,--help                Show this help text---## Examine--Examine sequence with `slynx examine`.--    stack exec slynx -- examine --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site]-      Examine sequences. If data is a multi sequence alignment, additionally analyze columns.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      --per-site               Report per site summary statistics-      -h,--help                Show this help text---## Filter--Filter sequences with `filer-rows`.--    stack exec slynx -- filter-rows --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH] -                             [--shorter-than LENGTH] [--standard-characters]-      Filter rows (or sequences) found in input files.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      --longer-than LENGTH     Only keep sequences longer than LENGTH-      --shorter-than LENGTH    Only keep sequences shorter than LENGTH-      --standard-characters    Only keep sequences containing at least one standard-                               (i.e., non-IUPAC) character-      -h,--help                Show this help text--Filter columns of multi sequence alignments with `filter-columns`.--    stack exec slynx -- filter-columns --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.+      - ProteinI (amino acids; including gaps, translation stops, and IUPAC codes)+    ELynx+    -----+    A Haskell library and tool set for computational biology. The goal of ELynx is+    reproducible research. Evolutionary sequences and phylogenetic trees can be+    read, viewed, modified and simulated. The command line with all arguments is+    logged consistently, and automatically. Data integrity is verified using SHA256+    sums so that validation of past analyses is possible without the need to+    recompute the result.     -    Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE -                                [--standard-chars DOUBLE]-      Filter columns of multi sequence alignments.+    slynx     Analyze, modify, and simulate evolutionary sequences.+    tlynx     Analyze, modify, and simulate phylogenetic trees.+    elynx     Validate and redo past analyses.     -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      --standard-chars DOUBLE  Keep columns with a proportion standard (non-IUPAC)-                               characters larger than DOUBLE in [0,1]-      -h,--help                Show this help text+    Get help for sub commands:+      slynx examine --help  -## Simulate+## Sub command -Simulate sequences with `slynx simulate`.+The documentation of sub commands can be accessed separately: -    stack exec slynx -- simulate --help+    slynx simulate --help -    ELynx Suite version 0.5.1.0.+    ELynx Suite version 0.6.0.0.     Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.+    Compiled on September 3, 2021, at 20:56 pm, UTC.          Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL]                            [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -281,315 +207,4 @@          LG exchangeabilities with site profiles (Phylobayes) given in FILES.          -m "EDM(LG-Custom)" -p FILES     For special mixture models, mixture weights are optional.---## Sub-sample--Sub-sample columns from multi sequence alignments.--    stack exec slynx -- sub-sample --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE-                            (-n|--number-of-sites INT)-                            (-m|--number-of-alignments INT) [-S|--seed [INT]]-      Sub-sample columns from multi sequence alignments.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      -n,--number-of-sites INT Number of sites randomly drawn with replacement-      -m,--number-of-alignments INT-                               Number of multi sequence alignments to be created-      -S,--seed [INT]          Seed for random number generator; list of 32 bit-                               integers with up to 256 elements (default: random)-      -h,--help                Show this help text-    -    Create a given number of multi sequence alignments, each of which contains a given number of random sites drawn from the original multi sequence alignment.---## Translate--Translate sequences.--    stack exec slynx -- translate --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT)-                           (-u|--universal-code CODE)-      Translate from DNA to Protein or DNAX to ProteinX.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -a,--alphabet NAME       Specify alphabet type NAME-      INPUT-FILE               Read sequences from INPUT-FILE-      -r,--reading-frame INT   Reading frame [0|1|2].-      -u,--universal-code CODE universal code; one of: Standard,-                               VertebrateMitochondrial.-      -h,--help                Show this help text---# TLynx--Handle phylogenetic trees in Newick format.--    stack exec tlynx -- --help | head -n -16--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] -                 [-f|--force] [--no-elynx-file] COMMAND-      Compare, examine, and simulate phylogenetic trees.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -v,--verbosity VALUE     Be verbose; one of: Quiet Warning Info Debug-                               (default: Info)-      -o,--output-file-basename NAME-                               Specify base name of output file-      -f,--force               Ignore previous analysis and overwrite existing-                               output files.-      --no-elynx-file          Do not write data required to reproduce an analysis.-    -    Available commands:-      compare                  Compare two phylogenetic trees (compute distances and branch-wise differences).-      connect                  Connect two phylogenetic trees in all ways (possibly honoring constraints).-      distance                 Compute distances between many phylogenetic trees.-      examine                  Compute summary statistics of phylogenetic trees.-      shuffle                  Shuffle a phylogenetic tree (keep coalescent times, but shuffle topology and leaves).-      simulate                 Simulate phylogenetic trees using a birth and death or coalescent process.-    -    -    Available tree file formats:-      - Newick Standard: Branch support values are stored in square brackets after branch lengths.-      - Newick IqTree:   Branch support values are stored as node names after the closing bracket of forests.-      - Newick RevBayes: Key-value pairs is provided in square brackets after node names as well as branch lengths. XXX: Key value pairs are ignored at the moment.---## Compare--Compute distances between phylogenetic trees.--    stack exec tlynx -- compare --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect] -                         [-f|--newick-format FORMAT] NAMES-      Compare two phylogenetic trees (compute distances and branch-wise differences).-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -n,--normalize           Normalize trees before comparison-      -b,--bipartitions        Print and plot common and missing bipartitions-      -t,--intersect           Compare intersections; i.e., before comparison, drop-                               leaves that are not present in the other tree-      -f,--newick-format FORMAT-                               Newick tree format: Standard, IqTree, or RevBayes;-                               default: Standard; for detailed help, see 'tlynx-                               --help'-      NAMES                    Tree files-      -h,--help                Show this help text---## Connect--Connect two phylogenetic tree in all ways (possibly honoring constraints).--    stack exec tlynx -- connect --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx connect [-f|--newick-format FORMAT] [-c|--contraints CONSTRAINTS]-                         TREE-FILE-A TREE-FILE-B-      Connect two phylogenetic trees in all ways (possibly honoring constraints).-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -f,--newick-format FORMAT-                               Newick tree format: Standard, IqTree, or RevBayes;-                               default: Standard; for detailed help, see 'tlynx-                               --help'-      -c,--contraints CONSTRAINTS-                               File containing one or more Newick trees to be used-                               as constraints-      TREE-FILE-A              File containing the first Newick tree-      TREE-FILE-B              File containing the second Newick tree-      -h,--help                Show this help text---## Distancce--Compute distances between many phylogenetic trees.--    stack exec tlynx -- distance --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx distance (-d|--distance MEASURE) [-n|--normalize] [-t|--intersect] -                          [-s|--summary-statistics] -                          [-m|--master-tree-file MASTER-TREE-File] -                          [-f|--newick-format FORMAT] [INPUT-FILES]-      Compute distances between many phylogenetic trees.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -d,--distance MEASURE    Type of distance to calculate (available distance-                               measures are listed below)-      -n,--normalize           Normalize trees before distance calculation; only-                               affect distances depending on branch lengths-      -t,--intersect           Compare intersections; i.e., before comparison, drop-                               leaves that are not present in the other tree-      -s,--summary-statistics  Report summary statistics only-      -m,--master-tree-file MASTER-TREE-File-                               Compare all trees to the tree in the master tree-                               file.-      -f,--newick-format FORMAT-                               Newick tree format: Standard, IqTree, or RevBayes;-                               default: Standard; for detailed help, see 'tlynx-                               --help'-      INPUT-FILES              Read tree(s) from INPUT-FILES; if more files are-                               given, one tree is expected per file-      -h,--help                Show this help text-    -    Distance measures:-      symmetric                Symmetric distance (Robinson-Foulds distance).-      incompatible-split[VAL]  Incompatible split distance. Collapse branches with (normalized)-                               support less than 0.0<=VAL<=1.0 before distance calculation;-                               if, let's say, VAL>0.7, only well supported differences contribute-                               to the total distance.-      branch-score             Branch score distance.---## Examine--Compute summary statistics of phylogenetic trees.--    stack exec tlynx -- examine --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT]-      Compute summary statistics of phylogenetic trees.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      INPUT-FILE               Read trees from INPUT-FILE-      -f,--newick-format FORMAT-                               Newick tree format: Standard, IqTree, or RevBayes;-                               default: Standard; for detailed help, see 'tlynx-                               --help'-      -h,--help                Show this help text---## Shuffle--Shuffle a phylogenetic tree (keep coalescent times, but shuffle topology and-leaves).--    stack exec tlynx -- shuffle --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx shuffle [-f|--newick-format FORMAT] [-n|--replicates N] TREE-FILE -                         [-S|--seed [INT]]-      Shuffle a phylogenetic tree (keep coalescent times, but shuffle topology and leaves).-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -f,--newick-format FORMAT-                               Newick tree format: Standard, IqTree, or RevBayes;-                               default: Standard; for detailed help, see 'tlynx-                               --help'-      -n,--replicates N        Number of trees to generate-      TREE-FILE                File containing a Newick tree-      -S,--seed [INT]          Seed for random number generator; list of 32 bit-                               integers with up to 256 elements (default: random)-      -h,--help                Show this help text---## Simulate--Simulate phylogenetic trees using birth and death processes.--    stack exec tlynx -- simulate --help--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: tlynx simulate (-t|--nTrees INT) (-n|--nLeaves INT) PROCESS -                          [-u|--sub-sample DOUBLE] [-s|--summary-statistics] -                          [-S|--seed [INT]]-      Simulate phylogenetic trees using a birth and death or coalescent process.-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-      -t,--nTrees INT          Number of trees-      -n,--nLeaves INT         Number of leaves per tree-      -u,--sub-sample DOUBLE   Perform sub-sampling; see below.-      -s,--summary-statistics  For each branch, print length and number of children-      -S,--seed [INT]          Seed for random number generator; list of 32 bit-                               integers with up to 256 elements (default: random)-      -h,--help                Show this help text-    -    Available processes:-      birthdeath               Birth and death process-      coalescent               Coalescent process-    -    See, for example, 'tlynx simulate birthdeath --help'.-    Sub-sample with probability p:-      1. Simulate one big tree with n'=round(n/p), n'>=n, leaves;-      2. Randomly sample sub-trees with n leaves.-      (With p=1.0, the same tree is reported over and over again.)---# ELynx--Validate and (optionally) redo past ELynx analyses.--    stack exec elynx -- --help | head -n -16--    ELynx Suite version 0.5.1.0.-    Developed by Dominik Schrempf.-    Compiled on June 12, 2021, at 14:54 pm, UTC.-    -    Usage: elynx COMMAND-      Validate and redo past ELynx analyses-    -    Available options:-      -h,--help                Show this help text-      -V,--version             Show version-    -    Available commands:-      validate                 Validate an ELynx analysis-      redo                     Redo an ELynx analysis 
src/TLynx/Compare/Compare.hs view
@@ -19,21 +19,14 @@  import Control.Monad import Control.Monad.IO.Class-import Control.Monad.Logger import Control.Monad.Trans.Reader (ask) import qualified Data.ByteString.Lazy.Char8 as BL import Data.List (intercalate) import qualified Data.Map as M import qualified Data.Set as S import qualified Data.Text as T-import qualified Data.Text.Encoding as E import qualified Data.Text.IO as T import ELynx.Tools-  ( Arguments (..),-    ELynx,-    GlobalArguments (..),-    outHandle,-  ) import ELynx.Tree import Graphics.Gnuplot.Simple import System.IO@@ -47,8 +40,8 @@     CompareArguments     (Tree Phylo Name, Tree Phylo Name) treesOneFile tf = do-  nwF <- argsNewickFormat . local <$> ask-  $(logInfo) $ T.pack $ "Parse file '" ++ tf ++ "'."+  nwF <- argsNewickFormat . localArguments <$> ask+  logInfoS $ "Parse file '" ++ tf ++ "'."   ts <- liftIO $ parseTrees nwF tf   let n = length ts   case compare n 2 of@@ -64,25 +57,25 @@     CompareArguments     (Tree Phylo Name, Tree Phylo Name) treesTwoFiles tf1 tf2 = do-  nwF <- argsNewickFormat . local <$> ask-  $(logInfo) $ T.pack $ "Parse first tree file '" ++ tf1 ++ "'."+  nwF <- argsNewickFormat . localArguments <$> ask+  logInfoS $ "Parse first tree file '" ++ tf1 ++ "'."   t1 <- liftIO $ parseTree nwF tf1-  $(logInfo) $ T.pack $ "Parse second tree file '" ++ tf2 ++ "'."+  logInfoS $ "Parse second tree file '" ++ tf2 ++ "'."   t2 <- liftIO $ parseTree nwF tf2   return (t1, t2)  -- | More detailed comparison of two trees. compareCmd :: ELynx CompareArguments () compareCmd = do-  l <- local <$> ask+  l <- localArguments <$> ask   -- Determine output handle (stdout or file).   outH <- outHandle "results" ".out"   -- Read input.-  let inFiles = argsInFiles l-      nFiles = length inFiles-  (tr1, tr2) <- case nFiles of-    1 -> treesOneFile (head inFiles)-    2 -> treesTwoFiles (head inFiles) (head . tail $ inFiles)+  let inFs = argsInFiles l+      nFs = length inFs+  (tr1, tr2) <- case nFs of+    1 -> treesOneFile (head inFs)+    2 -> treesTwoFiles (head inFs) (head . tail $ inFs)     _ ->       error         "Need two input files with one tree each or one input file with two trees."@@ -122,7 +115,7 @@       formatD         "Symmetric"         (T.pack $ show $ symmetric t1 t2)-  case (phyloToLengthTree t1, phyloToLengthTree t2) of+  case (toLengthTree t1, toLengthTree t2) of     (Right t1', Right t2') -> do       liftIO $         T.hPutStrLn outH $@@ -130,15 +123,15 @@             "Branch score"             (T.pack $ show $ branchScore t1' t2')     _ -> do-      $(logInfo) "Some branches do not have length values."-      $(logInfo) "Distances involving length cannot be calculated."+      logInfoS "Some branches do not have length values."+      logInfoS "Distances involving length cannot be calculated."   case (toExplicitTree t1, toExplicitTree t2) of     (Right t1', Right t2') -> do       let t1n = normalizeBranchSupport t1'           t2n = normalizeBranchSupport t2'-      $(logDebug) "Trees with normalized branch support values:"-      $(logDebug) $ E.decodeUtf8 $ BL.toStrict $ toNewick $ toPhyloTree t1n-      $(logDebug) $ E.decodeUtf8 $ BL.toStrict $ toNewick $ toPhyloTree t2n+      logDebugS "Trees with normalized branch support values:"+      logDebugB $ toNewick $ toPhyloTree t1n+      logDebugB $ toNewick $ toPhyloTree t2n       liftIO $         T.hPutStrLn outH $           formatD@@ -172,8 +165,8 @@     --   (T.pack $ show $ incompatibleSplits (collapse 1.01 t1n) (collapse 1.01 t2n))     -- liftIO $ BL.hPutStrLn outH $ toNewick (collapse 1.01 t1n)     _ -> do-      $(logInfo) "Some branches do not have support values."-      $(logInfo) "Distances involving branch support cannot be calculated."+      logInfoS "Some branches do not have support values."+      logInfoS "Distances involving branch support cannot be calculated."  analyzeBipartitions ::   Handle ->@@ -181,7 +174,7 @@   Tree Phylo Name ->   ELynx CompareArguments () analyzeBipartitions outH t1 t2 =-  case (phyloToLengthTree t1, phyloToLengthTree t2) of+  case (toLengthTree t1, toLengthTree t2) of     (Right t1l, Right t2l) -> do       let bp1 = either error id $ bipartitions t1l           bp2 = either error id $ bipartitions t2l@@ -214,8 +207,8 @@           liftIO $ hPutStrLn outH "There are no common bipartitions."           liftIO $ hPutStrLn outH "No plots have been generated."         else do-          let bpToBrLen1 = M.map (fromLength . getLen) $ either error id $ bipartitionToBranch t1l-              bpToBrLen2 = M.map (fromLength . getLen) $ either error id $ bipartitionToBranch t2l+          let bpToBrLen1 = M.map (fromLength . getLength) $ either error id $ bipartitionToBranch t1l+              bpToBrLen2 = M.map (fromLength . getLength) $ either error id $ bipartitionToBranch t2l           liftIO $             hPutStrLn               outH@@ -230,19 +223,19 @@             )           -- XXX: This circumvents the extension checking, and hash creation for           -- elynx files.-          bn <- outFileBaseName . global <$> ask+          bn <- outFileBaseName . globalArguments <$> ask           case bn of             Nothing ->-              $(logInfo) "No output file name provided. Do not generate plots."+              logInfoS "No output file name provided. Do not generate plots."             Just fn -> do               let compareCommonBps =                     [ (bpToBrLen1 M.! b, bpToBrLen2 M.! b)                       | b <- S.toList bpCommon                     ]               liftIO $ epspdfPlot fn (plotBps compareCommonBps)-              $(logInfo)+              logInfoS                 "Comparison of branch lengths plot generated (EPS and PDF)"-    _ -> $(logWarn) "Not all branches have a length! Can not analyze bipartitions."+    _ -> logWarnS "Not all branches have a length! Can not analyze bipartitions."  header :: String header = intercalate "  " $ cols ++ ["Bipartition"]
src/TLynx/Connect/Connect.hs view
@@ -18,17 +18,11 @@ where  import Control.Monad.IO.Class-import Control.Monad.Logger import Control.Monad.Trans.Reader (ask) import qualified Data.ByteString.Lazy.Char8 as BL+import Data.Default.Class import qualified Data.Set as S import ELynx.Tools-  ( Arguments (..),-    ELynx,-    fromBs,-    outHandle,-    tShow,-  ) import ELynx.Tree import System.IO import TLynx.Connect.Options@@ -43,7 +37,13 @@ -- introduced. -- -- Return 'Left' if one tree has a non-bifurcating root node.-connect :: (Semigroup e, Splittable e) => e -> a -> Tree e a -> Tree e a -> Either String (Forest e a)+connect ::+  (Semigroup e, Splittable e, Default a) =>+  e ->+  a ->+  Tree e a ->+  Tree e a ->+  Either String (Forest e a) connect br lb l r = do   ls <- roots l   rs <- roots r@@ -55,7 +55,7 @@ -- nodes, respectively, there are (n-2)*(m-2) ways to connect them. connectCmd :: ELynx ConnectArguments () connectCmd = do-  lArgs <- local <$> ask+  lArgs <- localArguments <$> ask   outH <- outHandle "results" ".out"   -- Do we have constraints or not?   let cs = constraints lArgs@@ -104,34 +104,34 @@     ConnectArguments     (Tree Length Name, Tree Length Name) parseTreeTuple l r = do-  nwF <- nwFormat . local <$> ask+  nwF <- nwFormat . localArguments <$> ask   tl <- liftIO $ parseTree nwF l   tr <- liftIO $ parseTree nwF r-  $(logInfo) "Tree 1:"-  $(logInfo) $ fromBs $ toNewick tl-  $(logInfo) "Tree 2:"-  $(logInfo) $ fromBs $ toNewick tr-  return (either error id $ phyloToLengthTree tl, either error id $ phyloToLengthTree tr)+  logInfoS "Tree 1:"+  logInfoB $ toNewick tl+  logInfoS "Tree 2:"+  logInfoB $ toNewick tr+  return (either error id $ toLengthTree tl, either error id $ toLengthTree tr)  connectOnly :: Handle -> FilePath -> FilePath -> ELynx ConnectArguments () connectOnly h l r = do   (tl, tr) <- parseTreeTuple l r   let ts = connectTrees tl tr-  $(logInfo) $ "Connected trees: " <> tShow (length ts)-  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . measurableToPhyloTree) ts+  logInfoS $ "Connected trees: " <> show (length ts)+  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts  connectAndFilter ::   Handle -> FilePath -> FilePath -> FilePath -> ELynx ConnectArguments () connectAndFilter h c l r = do-  nwF <- nwFormat . local <$> ask+  nwF <- nwFormat . localArguments <$> ask   cts <- liftIO $ parseTrees nwF c-  $(logInfo) "Constraints:"-  $(logInfo) $ fromBs $ BL.intercalate "\n" $ map toNewick cts+  logInfoS "Constraints:"+  logInfoB $ BL.intercalate "\n" $ map toNewick cts   (tl, tr) <- parseTreeTuple l r   let ts = connectTrees tl tr       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)-  $(logInfo) $ "Compatible trees: " <> tShow (length ts')-  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . measurableToPhyloTree) ts'+  logInfoS $ "Connected  trees: " <> show (length ts)+  logInfoS $ "Compatible trees: " <> show (length ts')+  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts'
src/TLynx/Distance/Distance.hs view
@@ -24,10 +24,6 @@     when,   ) import Control.Monad.IO.Class-import Control.Monad.Logger-  ( logDebug,-    logInfo,-  ) import Control.Monad.Trans.Class import Control.Monad.Trans.Reader hiding (local) import Data.Bifunctor@@ -36,8 +32,6 @@ import Data.Maybe import qualified Data.Text as T import qualified Data.Text.IO as T-import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Encoding as LT import qualified Data.Vector.Unboxed as V import ELynx.Tools import ELynx.Tree@@ -87,7 +81,7 @@ -- | Compute distance functions between phylogenetic trees. distance :: ELynx DistanceArguments () distance = do-  l <- local <$> ask+  l <- localArguments <$> ask   let nwFormat = argsNewickFormat l   -- Determine output handle (stdout or file).   outH <- outHandle "results" ".out"@@ -96,44 +90,43 @@   mtree <- case mname of     Nothing -> return Nothing     Just f -> do-      $(logInfo) $ T.pack $ "Read master tree from file: " <> f <> "."+      logInfoS $ "Read master tree from file: " <> f <> "."       t <- liftIO $ parseTree nwFormat f-      $(logInfo) "Compute distances between all trees and master tree."+      logInfoS "Compute distances between all trees and master tree."       return $ Just t   let tfps = argsInFiles l   (trees, names) <- case tfps of     [] -> error "No tree input files given."     [tf] -> do-      $(logInfo) "Read trees from single file."+      logInfoS "Read trees from single file."       ts <- liftIO $ parseTrees nwFormat tf-      $(logInfo) $ tShow (length ts) <> " trees found in file."-      $(logInfo) "Trees are indexed with integers."+      logInfoS $ show (length ts) <> " trees found in file."+      logInfoS "Trees are indexed with integers."       return (ts, map show [0 .. length ts - 1])     _ -> do-      $(logInfo) "Read trees from files."+      logInfoS "Read trees from files."       ts <- liftIO $ mapM (parseTree nwFormat) tfps-      $(logInfo) "Trees are named according to their file names."+      logInfoS "Trees are named according to their file names."       return (ts, tfps)   when (null trees) (error "Not enough trees found in files.")   when     (isNothing mtree && length trees == 1)     (error "Not enough trees found in files.")-  -- when (isNothing mtree) $ $(logInfo)+  -- when (isNothing mtree) $ logInfoS   --   "Compute pairwise distances between trees from different files."-  $(logDebug) "The trees are:"-  $(logDebug) $ LT.toStrict $ LT.decodeUtf8 $ BL.unlines $ map toNewick trees+  logDebugS "The trees are:"+  logDebugB $ BL.unlines $ map toNewick trees   -- Set the distance measure.   let dist = argsDistance l   case argsDistance l of-    Symmetric -> $(logInfo) "Use symmetric (Robinson-Foulds) distance."+    Symmetric -> logInfoS "Use symmetric (Robinson-Foulds) distance."     IncompatibleSplit val -> do-      $(logInfo) "Use incompatible split distance."-      $(logInfo) $-        T.pack $-          "Collapse nodes with support less than "-            ++ show val-            ++ "."-    BranchScore -> $(logInfo) "Use branch score distance."+      logInfoS "Use incompatible split distance."+      logInfoS $+        "Collapse nodes with support less than "+          ++ show val+          ++ "."+    BranchScore -> logInfoS "Use branch score distance."   let distanceMeasure' ::         Tree Phylo Name ->         Tree Phylo Name ->@@ -143,15 +136,17 @@         IncompatibleSplit val ->           second fromIntegral $             incompatibleSplits-              (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t1)-              (collapse val $ normalizeBranchSupport $ either error id $ phyloToSupportTree t2)+              (collapse val $ normalizeBranchSupport $ either error id $ toSupportTree t1)+              (collapse val $ normalizeBranchSupport $ either error id $ toSupportTree t2)         BranchScore ->-          branchScore (normalizeF $ either error id $ phyloToLengthTree t1) (normalizeF $ either error id $ phyloToLengthTree t2)+          branchScore+            (normalizeF $ either error id $ toLengthTree t1)+            (normalizeF $ either error id $ toLengthTree t2)         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."+    logInfoS "Intersect trees before calculation of distances."   let distanceMeasure =         if argsIntersect l           then@@ -162,12 +157,13 @@           else distanceMeasure'   -- Possibly normalize trees.   when (argsNormalize l) $-    $(logInfo) "Normalize trees before calculation of distances."+    logInfoS "Normalize trees before calculation of distances."   let dsTriplets = case mtree of         Nothing -> pairwise distanceMeasure trees         Just masterTree -> [(0, i, distanceMeasure masterTree t') | (i, t') <- zip [1 ..] trees]       ds = map (\(_, _, x) -> x) dsTriplets       dsVec = V.fromList ds+  -- TODO: This should never happen (hPutStrLn??).   liftIO $     hPutStrLn outH $       "Summary statistics of "@@ -192,24 +188,23 @@   -- BS.putStrLn $ BS.unlines $ map toNewick tsN   -- BS.putStrLn $ BS.unlines $ map toNewick tsC -  lift $-    unless-      (argsSummaryStatistics l)-      ( do-          let n = maximum $ 6 : map length names-              m = length $ show dist-          lift $ hPutStrLn outH ""-          lift $ BL.hPutStrLn outH $ header n m dist-          case mname of-            Nothing ->-              lift $-                BL.hPutStr outH $-                  BL.unlines-                    (map (showTriplet n m names) dsTriplets)-            Just mn ->-              lift $-                BL.hPutStr outH $-                  BL.unlines-                    (map (showTriplet n m (mn : names)) dsTriplets)-      )+  unless+    (argsSummaryStatistics l)+    ( do+        let n = maximum $ 6 : map length names+            m = length $ show dist+        lift $ hPutStrLn outH ""+        lift $ BL.hPutStrLn outH $ header n m dist+        case mname of+          Nothing ->+            lift $+              BL.hPutStr outH $+                BL.unlines+                  (map (showTriplet n m names) dsTriplets)+          Just mn ->+            lift $+              BL.hPutStr outH $+                BL.unlines+                  (map (showTriplet n m (mn : names)) dsTriplets)+    )   liftIO $ hClose outH
src/TLynx/Examine/Examine.hs view
@@ -18,12 +18,10 @@  import Control.Monad (unless) import Control.Monad.IO.Class-import Control.Monad.Logger import Control.Monad.Trans.Reader (ask) import qualified Data.ByteString.Lazy.Char8 as BL import Data.Containers.ListUtils (nubOrd) import Data.List ((\\))-import qualified Data.Text as T import ELynx.Tools import ELynx.Tree import System.IO@@ -60,14 +58,14 @@  readTrees :: FilePath -> ELynx ExamineArguments (Forest Phylo Name) readTrees fp = do-  $(logInfo) $ T.pack $ "Read tree(s) from file " <> fp <> "."-  nf <- argsNewickFormat . local <$> ask+  logInfoS $ "Read tree(s) from file " <> fp <> "."+  nf <- argsNewickFormat . localArguments <$> ask   liftIO $ parseTrees nf fp  examineTree :: HasName a => Handle -> Tree Phylo a -> IO () examineTree h t = do   hPutStrLn h $ "Number of leaves: " ++ show (length lvs)-  let l = phyloToLengthTree t+  let l = toLengthTree t   case l of     Left _ -> hPutStrLn h "Branch lengths not available."     Right t' -> BL.hPutStrLn h $ summarizeLengths t'@@ -82,7 +80,7 @@ -- | Examine phylogenetic trees. examine :: ELynx ExamineArguments () examine = do-  l <- local <$> ask+  l <- localArguments <$> ask   let inFn = argsInFile l   trs <- readTrees inFn   outH <- outHandle "results" ".out"
src/TLynx/Shuffle/Options.hs view
@@ -26,7 +26,7 @@   { nwFormat :: NewickFormat,     nReplicates :: Int,     inFile :: FilePath,-    argsSeed :: Seed+    argsSeed :: SeedOpt   }   deriving (Eq, Show, Generic) @@ -34,7 +34,7 @@   inFiles = pure . inFile   outSuffixes _ = [".tree"]   getSeed = Just . argsSeed-  setSeed a s = a {argsSeed = Fixed s}+  setSeed a s = a {argsSeed = s}   parser = shuffleArguments   cmdName = "shuffle"   cmdDsc =
src/TLynx/Shuffle/Shuffle.hs view
@@ -23,7 +23,6 @@ import qualified Control.Comonad as C import Control.Monad (when) 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 BL import ELynx.Tools@@ -34,8 +33,8 @@   ) import System.IO (hClose) import System.Random.MWC (GenIO, initialize)-import TLynx.Shuffle.Options import TLynx.Parsers+import TLynx.Shuffle.Options  -- | Shuffle a tree. Get all coalescent times, shuffle them. Get all leaves, -- shuffle them. Connect the shuffled leaves with the shuffled coalescent times.@@ -43,32 +42,34 @@ -- times and leaves. shuffleCmd :: ELynx ShuffleArguments () shuffleCmd = do-  l <- local <$> ask+  l <- localArguments <$> ask   h <- outHandle "results" ".tree"   let nwF = nwFormat l   tPhylo <- liftIO $ parseTree nwF (inFile l)-  $(logInfo) "Input tree:"-  $(logInfo) $ fromBs $ toNewick tPhylo-  let t = either error id $ phyloToLengthTree tPhylo+  logInfoS "Input tree:"+  logInfoB $ toNewick tPhylo+  let t = either error id $ toLengthTree tPhylo   -- Check if tree is ultrametric enough.   let dh = sum $ map (height t -) (distancesOriginLeaves t)-  $(logDebug) $ "Distance in branch length to being ultrametric: " <> tShow dh+  logDebugS $ "Distance in branch length to being ultrametric: " <> show dh   when (dh > 2e-4) (error "Tree is not ultrametric.")   when (dh > toLengthUnsafe eps && dh < 2e-4) $-    $(logInfo)+    logInfoS       "Tree is nearly ultrametric, ignore branch length differences smaller than 2e-4."-  when (dh < toLengthUnsafe eps) $ $(logInfo) "Tree is ultrametric."+  when (dh < toLengthUnsafe eps) $ logInfoS "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)-  $(logDebug) $ "Number of leaves: " <> tShow (length ls)-  $(logDebug) "The coalescent times are: "-  $(logDebug) $ tShow cs-  gen <- case argsSeed l of-    Random -> error "Seed not available; please contact maintainer."-    Fixed s -> liftIO $ initialize s+  logDebugS $ "Number of coalescent times: " <> show (length cs)+  logDebugS $ "Number of leaves: " <> show (length ls)+  logDebugS "The coalescent times are: "+  logDebugS $ show cs+  gen <- liftIO $+    initialize $ case argsSeed l of+      RandomUnset -> error "Seed not available; please contact maintainer."+      RandomSet s -> s+      Fixed s -> s   ts <- liftIO $ shuffleT (nReplicates l) (height t) cs ls gen-  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . measurableToPhyloTree) ts+  liftIO $ BL.hPutStr h $ BL.unlines $ map (toNewick . lengthToPhyloTree) ts   liftIO $ hClose h  shuffleT ::
src/TLynx/Simulate/Options.hs view
@@ -24,7 +24,7 @@  import Data.List import Data.Maybe-import ELynx.Tools hiding (Random)+import ELynx.Tools import ELynx.Tree.Simulate.PointProcess (TimeSpec (..)) import Options.Applicative @@ -85,7 +85,7 @@     -- | Only print summary statistics?     argsSumStat :: Bool,     -- | Seed of NRG, random if 'Nothing'.-    argsSeed :: Seed+    argsSeed :: SeedOpt   }   deriving (Eq, Show, Generic) @@ -93,7 +93,7 @@   inFiles _ = []   outSuffixes _ = [".tree"]   getSeed = Just . argsSeed-  setSeed a s = a {argsSeed = Fixed s}+  setSeed a s = a {argsSeed = s}   parser = simulateArguments   cmdName = "simulate"   cmdDsc = ["Simulate phylogenetic trees using a birth and death or coalescent process."]@@ -243,5 +243,5 @@ simulateFooter :: [String] simulateFooter =   [ "See, for example, 'tlynx simulate birthdeath --help'.",-    "Sub-sample with probability p:\n  1. Simulate one big tree with n'=round(n/p), n'>=n, leaves;\n  2. Randomly sample sub-trees with n leaves.\n  (With p=1.0, the same tree is reported over and over again.)"+    "Sub-sample with probability p:\n  1. Simulate one big tree with n'=round(n/p), n'>=n, leaves;\n  2. Randomly sample sub trees with n leaves.\n  (With p=1.0, the same tree is reported over and over again.)"   ]
src/TLynx/Simulate/Simulate.hs view
@@ -26,12 +26,11 @@ where  import Control.Concurrent (getNumCapabilities)-import Control.Concurrent.Async.Lifted.Safe+import Control.Concurrent.Async   ( mapConcurrently,   ) import Control.Monad import Control.Monad.IO.Class-import Control.Monad.Logger import Control.Monad.Trans.Reader hiding (local) import Control.Parallel.Strategies import qualified Data.ByteString.Builder as BB@@ -40,9 +39,6 @@ import Data.Maybe import qualified Data.Sequence as Seq import qualified Data.Set as Set-import qualified Data.Text as T-import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Encoding as LT import ELynx.Tools import ELynx.Tree import qualified ELynx.Tree.Simulate.Coalescent as CS@@ -53,12 +49,12 @@ -- | Simulate phylogenetic trees using birth and death process. simulate :: ELynx SimulateArguments () simulate = do-  l@(SimulateArguments nTrees nLeaves pr subS sumS (Fixed s)) <- local <$> ask+  l@(SimulateArguments nTrees nLeaves pr subS sumS (Fixed s)) <- localArguments <$> ask   c <- liftIO getNumCapabilities-  logNewSection "Arguments"-  $(logInfo) $ T.pack $ reportSimulateArguments l-  logNewSection "Simulation"-  $(logInfo) $ T.pack $ "Number of used cores: " <> show c+  logInfoNewSection "Arguments"+  logInfoS $ reportSimulateArguments l+  logInfoNewSection "Simulation"+  logInfoS $ "Number of used cores: " <> show c   gs <- liftIO $ initialize s >>= \gen -> splitGen c gen   let chunks = getChunks c nTrees   trs <- case pr of@@ -82,7 +78,7 @@   let ls =         if sumS           then parMap rpar (formatNChildSumStat . toNChildSumStat) trs-          else parMap rpar toNewick $ map measurableToPhyloTree trs+          else parMap rpar toNewick $ map lengthToPhyloTree trs   let res = BL.unlines ls   out "simulated trees" res ".tree" @@ -130,21 +126,19 @@   let nLeavesBigTree = (round $ fromIntegral nLeaves / p) :: Int       l' = l * r       m' = m - l * (1.0 - r)-  logNewSection $-    T.pack $-      "Simulate one big tree with "-        <> show nLeavesBigTree-        <> " leaves."+  logInfoNewSection $+    "Simulate one big tree with "+      <> show nLeavesBigTree+      <> " leaves."   tr <- liftIO $ PP.simulateReconstructedTree nLeavesBigTree timeSpec l' m' (head gs)   -- Log the base tree.-  $(logInfo) $ LT.toStrict $ LT.decodeUtf8 $ toNewick $ measurableToPhyloTree tr-  logNewSection $-    T.pack $-      "Sub sample "-        <> show (sum chunks)-        <> " trees with "-        <> show nLeaves-        <> " leaves."+  logInfoB $ toNewick $ lengthToPhyloTree tr+  logInfoNewSection $+    "Sub sample "+      <> show (sum chunks)+      <> " trees with "+      <> show nLeaves+      <> " leaves."   let lvs = Seq.fromList $ leaves tr   trss <-     liftIO $@@ -162,21 +156,19 @@   ELynx SimulateArguments (Forest Length Int) coalSimulateAndSubSampleNTreesConcurrently nL p chunks gs = do   let nLeavesBigTree = (round $ fromIntegral nL / p) :: Int-  logNewSection $-    T.pack $-      "Simulate one big tree with "-        <> show nLeavesBigTree-        <> " leaves."+  logInfoNewSection $+    "Simulate one big tree with "+      <> show nLeavesBigTree+      <> " leaves."   tr <- liftIO $ CS.simulate nLeavesBigTree (head gs)   -- Log the base tree.-  $(logInfo) $ LT.toStrict $ LT.decodeUtf8 $ toNewick $ measurableToPhyloTree tr-  logNewSection $-    T.pack $-      "Sub sample "-        <> show (sum chunks)-        <> " trees with "-        <> show nL-        <> " leaves."+  logInfoB $ toNewick $ lengthToPhyloTree tr+  logInfoNewSection $+    "Sub sample "+      <> show (sum chunks)+      <> " trees with "+      <> show nL+      <> " leaves."   let lvs = Seq.fromList $ leaves tr   trss <-     liftIO $@@ -232,8 +224,8 @@  -- Compute NChilSumStat for a phylogenetic tree. toNChildSumStat :: HasLength e => Tree e a -> NChildSumStat-toNChildSumStat (Node br _ []) = [(getLen br, 1)]-toNChildSumStat (Node br _ ts) = (getLen br, sumCh) : concat nChSS+toNChildSumStat (Node br _ []) = [(getLength br, 1)]+toNChildSumStat (Node br _ ts) = (getLength br, sumCh) : concat nChSS   where     nChSS = map toNChildSumStat ts     sumCh = sum $ map (snd . head) nChSS
src/TLynx/TLynx.hs view
@@ -24,23 +24,17 @@ import TLynx.Shuffle.Shuffle import TLynx.Simulate.Simulate --- TODO: Use a class here (e.g., elynx-wrappable) which defines the extractor function.- -- | Run TLynx with given arguments. tlynx :: Arguments CommandArguments -> IO () tlynx c = case local c of-  Compare _ ->-    eLynxWrapper c (\(Arguments g (Compare l)) -> Arguments g l) compareCmd-  Connect _ ->-    eLynxWrapper c (\(Arguments g (Connect l)) -> Arguments g l) connectCmd-  Distance _ ->-    eLynxWrapper c (\(Arguments g (Distance l)) -> Arguments g l) distance-  Examine _ ->-    eLynxWrapper c (\(Arguments g (Examine l)) -> Arguments g l) examine-  Shuffle _ ->-    eLynxWrapper c (\(Arguments g (Shuffle l)) -> Arguments g l) shuffleCmd-  Simulate _ ->-    eLynxWrapper c (\(Arguments g (Simulate l)) -> Arguments g l) simulate+  Compare l -> eLynxWrapper g l Compare compareCmd+  Connect l -> eLynxWrapper g l Connect connectCmd+  Distance l -> eLynxWrapper g l Distance distance+  Examine l -> eLynxWrapper g l Examine examine+  Shuffle l -> eLynxWrapper g l Shuffle shuffleCmd+  Simulate l -> eLynxWrapper g l Simulate simulate+  where+    g = global c  -- | Run TLynx, parse arguments from command line. rTLynx :: IO ()
tlynx.cabal view
@@ -1,78 +1,79 @@-cabal-version:      2.2-name:               tlynx-version:            0.5.1.1-license:            GPL-3.0-or-later-license-file:       LICENSE-copyright:          Dominik Schrempf (2021)-maintainer:         dominik.schrempf@gmail.com-author:             Dominik Schrempf-homepage:           https://github.com/dschrempf/elynx#readme-bug-reports:        https://github.com/dschrempf/elynx/issues-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>.+cabal-version:  2.2+name:           tlynx+version:        0.6.0.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+homepage:       https://github.com/dschrempf/elynx#readme+bug-reports:    https://github.com/dschrempf/elynx/issues+author:         Dominik Schrempf+maintainer:     dominik.schrempf@gmail.com+copyright:      Dominik Schrempf (2021)+license:        GPL-3.0-or-later+license-file:   LICENSE+build-type:     Simple -category:           Bioinformatics-build-type:         Simple extra-source-files:     README.md     ChangeLog.md  source-repository head-    type:     git-    location: https://github.com/dschrempf/elynx+  type: git+  location: https://github.com/dschrempf/elynx  library-    exposed-modules:-        TLynx.Compare.Compare-        TLynx.Compare.Options-        TLynx.Connect.Connect-        TLynx.Connect.Options-        TLynx.Distance.Distance-        TLynx.Distance.Options-        TLynx.Examine.Examine-        TLynx.Examine.Options-        TLynx.Options-        TLynx.Parsers-        TLynx.Shuffle.Options-        TLynx.Shuffle.Shuffle-        TLynx.Simulate.Options-        TLynx.Simulate.Simulate-        TLynx.TLynx--    hs-source-dirs:   src-    other-modules:    Paths_tlynx-    autogen-modules:  Paths_tlynx-    default-language: Haskell2010-    ghc-options:      -Wall -Wunused-packages-    build-depends:-        aeson >=1.5.6.0,-        attoparsec >=0.13.2.5,-        base >=4.7 && <5,-        bytestring >=0.10.12.0,-        comonad >=5.0.8,-        containers >=0.6.2.1,-        elynx-tools >=0.5.1.1,-        elynx-tree >=0.5.1.1,-        gnuplot >=0.5.6.1,-        lifted-async >=0.10.2,-        monad-logger >=0.3.36,-        mwc-random >=0.15.0.1,-        optparse-applicative >=0.16.1.0,-        parallel >=3.2.2.0,-        statistics >=0.15.2.0,-        text >=1.2.4.1,-        transformers >=0.5.6.2,-        vector >=0.12.3.0+  exposed-modules:+      TLynx.Compare.Compare+      TLynx.Compare.Options+      TLynx.Connect.Connect+      TLynx.Connect.Options+      TLynx.Distance.Distance+      TLynx.Distance.Options+      TLynx.Examine.Examine+      TLynx.Examine.Options+      TLynx.Options+      TLynx.Parsers+      TLynx.Shuffle.Options+      TLynx.Shuffle.Shuffle+      TLynx.Simulate.Options+      TLynx.Simulate.Simulate+      TLynx.TLynx+  other-modules:+      Paths_tlynx+  autogen-modules:+      Paths_tlynx+  hs-source-dirs: src+  ghc-options: -Wall -Wunused-packages+  build-depends:+      aeson+    , async+    , attoparsec+    , base >=4.7 && <5+    , bytestring+    , comonad+    , containers+    , data-default-class+    , elynx-tools+    , elynx-tree+    , gnuplot+    , mwc-random+    , optparse-applicative+    , parallel+    , statistics+    , text+    , transformers+    , vector+  default-language: Haskell2010  executable tlynx-    main-is:          Main.hs-    hs-source-dirs:   app-    other-modules:    Paths_tlynx-    default-language: Haskell2010-    ghc-options:-        -Wall -Wunused-packages -threaded -rtsopts -with-rtsopts=-N--    build-depends:-        base >=4.7 && <5,-        tlynx -any+  main-is: Main.hs+  other-modules:+      Paths_tlynx+  autogen-modules:+      Paths_tlynx+  hs-source-dirs: app+  ghc-options: -Wall -Wunused-packages -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.7 && <5+    , tlynx+  default-language: Haskell2010