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 +10/−0
- README.md +27/−412
- src/TLynx/Compare/Compare.hs +26/−33
- src/TLynx/Connect/Connect.hs +23/−23
- src/TLynx/Distance/Distance.hs +45/−50
- src/TLynx/Examine/Examine.hs +4/−6
- src/TLynx/Shuffle/Options.hs +2/−2
- src/TLynx/Shuffle/Shuffle.hs +18/−17
- src/TLynx/Simulate/Options.hs +4/−4
- src/TLynx/Simulate/Simulate.hs +31/−39
- src/TLynx/TLynx.hs +8/−14
- tlynx.cabal +69/−68
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