slynx 0.0.1 → 0.1.0
raw patch · 16 files changed
+343/−246 lines, 16 filesdep −lensdep ~elynx-seqdep ~elynx-toolsdep ~elynx-tree
Dependencies removed: lens
Dependency ranges changed: elynx-seq, elynx-tools, elynx-tree, math-functions
Files
- ChangeLog.md +2/−2
- README.md +88/−78
- app/Main.hs +7/−7
- app/Options.hs +33/−36
- slynx.cabal +11/−12
- src/Concatenate/Concatenate.hs +3/−3
- src/Concatenate/Options.hs +5/−0
- src/Examine/Examine.hs +36/−24
- src/Examine/Options.hs +10/−1
- src/Filter/Filter.hs +25/−21
- src/Filter/Options.hs +15/−8
- src/Simulate/Options.hs +20/−0
- src/Simulate/Simulate.hs +75/−41
- src/SubSample/SubSample.hs +10/−10
- src/Tools.hs +2/−2
- src/Translate/Translate.hs +1/−1
ChangeLog.md view
@@ -1,10 +1,10 @@ # Table of Contents -1. [Changelog for ELynx](#org9916021)+1. [Changelog for ELynx](#org263dcac) -<a id="org9916021"></a>+<a id="org263dcac"></a> # Changelog for ELynx
README.md view
@@ -2,33 +2,33 @@ # The ELynx Suite -Version: 0.0.1.+Version: 0.1.0. Reproducible evolution made easy. The ELynx Suite is a Haskell library and a tool set for computational biology. The goal of the ELynx Suite is reproducible research. Evolutionary sequences and phylogenetic trees can be read, viewed, modified and simulated. Exact specification of all options is necessary, and nothing is assumed about the data-(e.g., the type of code). The command line with all arguments is consistently,-and automatically logged. The work overhead in the beginning usually pays off in-the end.+(e.g., the type of the genetic code). The command line with all arguments is+consistently, and automatically logged. The work overhead in the beginning+usually pays off in the end. The Elynx Suite consists of three library packages and two executables providing a range of sub commands. The library packages are: -- **elynx-seq:** Handle evolutionary sequences and multi sequence alignments;-- **elynx-tree:** Handle phylogenetic trees;-- **elynx-tools:** Tools for the provided executables;+- **elynx-seq:** Handle evolutionary sequences and multi sequence alignments.+- **elynx-tree:** Handle phylogenetic trees.+- **elynx-tools:** Tools for the provided executables. The executables are: -- **SLynx:** Analyze, modify, and simulate evolutionary sequences (FASTA format);-- **TLynx:** Analyze, modify, and simulate phylogenetic trees (Newick format).+- **slynx:** Analyze, modify, and simulate evolutionary sequences (FASTA format).+- **tlynx:** Analyze, modify, and simulate phylogenetic trees (Newick format). -**ELynx is still under development. We happily receive comments, ideas, feature-requests, or pull requests!**+**ELynx is actively developed. We happily receive comments, ideas, feature+requests, and pull requests!** # Installation@@ -57,8 +57,8 @@ stack install - The binaries are installed into `~/.local/bin/` which has to be added [PATH](https://en.wikipedia.org/wiki/PATH_(variable)).- Then, they can be used directly.+ The binaries are installed into `~/.local/bin/` which has to be added to the+ [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable. Then, they can be used directly. # SLynx@@ -67,8 +67,8 @@ slynx --help - ELynx Suite version 0.5.1. Developed by Dominik Schrempf. Compiled on September- 9, 2019, at 10:48 am, UTC.+ ELynx Suite version 0.1.0. Developed by Dominik Schrempf. Compiled on January+ 30, 2020, at 09:18 am, UTC. Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] COMMAND Analyze, and simulate multi sequence alignments.@@ -82,17 +82,14 @@ Specify base name of output file Available commands:- concatenate - examine If data is a multi sequence alignment, additionally- analyze columns.- filter-rows - filter-columns - simulate - sub-sample Create a given number of multi sequence alignments,- each of which containing a given number of random- sites drawn from the original multi sequence- alignment.- translate + concatenate Concatenate sequences found in input files.+ examine Examine sequences. If data is a multi sequence+ alignment, additionally analyze columns.+ filter-rows Filter rows (or sequences) found in input files.+ filter-columns Filter columns of multi-sequence alignments.+ simulate Simulate multi sequence alignments.+ sub-sample Sub-sample columns from multi sequence alignments.+ translate Translate from DNA to Protein or DNAX to ProteinX. File formats: - FASTA@@ -106,15 +103,20 @@ - ProteinS (amino acids; including gaps, and translation stops) - ProteinI (amino acids; including gaps, translation stops, and IUPAC codes) - The ELynx Suite.+ The ELynx Suite+ --------------- A Haskell library and a tool set for computational biology. The goal of the ELynx Suite is reproducible research. Evolutionary sequences and phylogenetic trees can be read, viewed, modified and simulated. Exact specification of all options is necessary, and nothing is assumed about the data (e.g., the type of code). The command line with all arguments is consistently, and automatically- logged. The work overhead in the beginning usually pays off in the end.+ logged.+ slynx Analyze, modify, and simulate evolutionary sequences. tlynx Analyze, modify, and simulate phylogenetic trees.+ + Get help for specific commands:+ slynx examine --help ## Concatenate@@ -123,9 +125,8 @@ slynx concatenate --help - Concatenate sequences found in input files.- Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE+ Concatenate sequences found in input files. Available options: -a,--alphabet NAME Specify alphabet type NAME@@ -139,10 +140,9 @@ slynx examine --help - Examine sequences.- Usage: slynx examine (-a|--alphabet NAME) [INPUT-FILE] [--per-site]- If data is a multi sequence alignment, additionally analyze columns.+ Examine sequences. If data is a multi sequence alignment, additionally analyze+ columns. Available options: -a,--alphabet NAME Specify alphabet type NAME@@ -157,26 +157,27 @@ slynx filter-rows --help - Filter rows (or sequences) found in input files.- 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: -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`. slynx filter-columns --help - Filter columns of multi-sequence alignments.- Usage: slynx filter-columns (-a|--alphabet NAME) [INPUT-FILE] [--standard-chars DOUBLE]+ Filter columns of multi-sequence alignments. Available options: -a,--alphabet NAME Specify alphabet type NAME@@ -192,13 +193,13 @@ slynx simulate --help - Simulate multi sequence alignments.- Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] [-m|--mixture-model MODEL] [-e|--edm-file NAME]+ [-p|--siteprofile-files NAMES] [-w|--mixture-model-weights "[DOUBLE,DOUBLE,...]"] [-g|--gamma-rate-heterogeneity "(NCAT,SHAPE)"] (-l|--length NUMBER) [-S|--seed [INT]]+ Simulate multi sequence alignments. Available options: -t,--tree-file Name Read trees from file NAME@@ -210,6 +211,8 @@ are shown below (mutually exclusive with -s option) -e,--edm-file NAME Empirical distribution model file NAME in Phylobayes format+ -p,--siteprofile-files NAMES+ File names of site profiles in Phylobayes format -w,--mixture-model-weights "[DOUBLE,DOUBLE,...]" Weights of mixture model components -g,--gamma-rate-heterogeneity "(NCAT,SHAPE)"@@ -257,8 +260,7 @@ Usage: slynx sub-sample (-a|--alphabet NAME) [INPUT-FILE] (-n|--number-of-sites INT) (-m|--number-of-alignments INT) [-S|--seed [INT]]- Create a given number of multi sequence alignments, each of which containing a- given number of random sites drawn from the original multi sequence alignment.+ Sub-sample columns from multi sequence alignments. Available options: -a,--alphabet NAME Specify alphabet type NAME@@ -269,6 +271,9 @@ -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@@ -277,10 +282,9 @@ slynx translate --help - Translate from DNA to Protein or DNAX to ProteinX.- 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: -a,--alphabet NAME Specify alphabet type NAME@@ -297,8 +301,8 @@ tlynx --help - ELynx Suite version 0.5.1. Developed by Dominik Schrempf. Compiled on September- 9, 2019, at 10:48 am, UTC.+ ELynx Suite version 0.1.0. Developed by Dominik Schrempf. Compiled on January+ 30, 2020, at 09:18 am, UTC. Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] COMMAND Compare, examine, and simulate phylogenetic trees.@@ -312,26 +316,34 @@ Specify base name of output file Available commands:- compare - examine - simulate Simulate reconstructed trees using the point process.- See Gernhard, T. (2008). The conditioned- reconstructed process. Journal of Theoretical- Biology, 253(4), 769–778.- http://doi.org/10.1016/j.jtbi.2008.04.005+ distance Compute distances between many phylogenetic trees.+ examine Compute summary statistics of phylogenetic trees.+ simulate Simulate phylogenetic trees using birth and death+ processes.+ compare Compare two phylogenetic trees (compute distances and+ branch-wise differences).+ connect Connect two phylogenetic trees in all ways (possibly+ honoring constraints).+ shuffle Shuffle a phylogenetic tree (keep coalescent times,+ but shuffle topology and leaves). File formats: - Newick - The ELynx Suite.+ The ELynx Suite+ --------------- A Haskell library and a tool set for computational biology. The goal of the ELynx Suite is reproducible research. Evolutionary sequences and phylogenetic trees can be read, viewed, modified and simulated. Exact specification of all options is necessary, and nothing is assumed about the data (e.g., the type of code). The command line with all arguments is consistently, and automatically- logged. The work overhead in the beginning usually pays off in the end.+ logged.+ slynx Analyze, modify, and simulate evolutionary sequences. tlynx Analyze, modify, and simulate phylogenetic trees.+ + Get help for specific commands:+ slynx examine --help ## Compare@@ -340,24 +352,18 @@ tlynx compare --help - Compute distances between phylogenetic trees.- - Usage: tlynx compare (-d|--distance MEASURE) [-s|--summary-statistics]- [INPUT-FILES]+ Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-i|--newick-iqtree]+ NAME+ Compare two phylogenetic trees (compute distances and branch-wise+ differences). Available options:- -d,--distance MEASURE Type of distance to calculate (available distance- measures are listed below)- -s,--summary-statistics Report summary statistics only- INPUT-FILES Read tree(s) from INPUT-FILES; if more files are- given, one tree is expected per file+ -n,--normalize Normalize trees before comparison+ -b,--bipartitions Print common and missing bipartitions+ -i,--newick-iqtree Use IQ-TREE Newick format (internal node labels are+ branch support values)+ NAME Tree file -h,--help Show this help text- - Available distance measures:- Symmetric distance: -d symmetric- Incompatible split distance: -d incompatible-split[VAL]- Collapse branches with support less than VAL before distance calculation;- in this way, only well supported difference contribute to the distance measure. ## Examine@@ -366,12 +372,13 @@ tlynx examine --help - Compute summary statistics of phylogenetic trees.- - Usage: tlynx examine [INPUT-FILE]+ Usage: tlynx examine [INPUT-FILE] [-i|--newick-iqtree]+ Compute summary statistics of phylogenetic trees. Available options: INPUT-FILE Read trees from INPUT-FILE+ -i,--newick-iqtree Use IQ-TREE Newick format (internal node labels are+ branch support values) -h,--help Show this help text @@ -381,15 +388,11 @@ tlynx simulate --help - Simulate phylogenetic trees using birth and death processes.- Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE] [-M|--condition-on-mrca] [-l|--lambda DOUBLE] [-m|--mu DOUBLE] [-r|--rho DOUBLE] [-u|--sub-sample] [-s|--summary-statistics] [-S|--seed [INT]]- Simulate reconstructed trees using the point process. See Gernhard, T. (2008).- The conditioned reconstructed process. Journal of Theoretical Biology, 253(4),- 769–778. http://doi.org/10.1016/j.jtbi.2008.04.005+ Simulate phylogenetic trees using birth and death processes. Available options: -t,--nTrees INT Number of trees (default: 10)@@ -409,9 +412,16 @@ Height of Trees: if no tree height is given, the heights will be randomly drawn from the expected distribution given the number of leaves, the birth and the death rate. Summary statistics only: only print (NumberOfExtantChildren BranchLength) pairs for each branch of each tree. The trees are separated by a newline character. Sub-sampling: simulate one big tree with n'=round(n/rho), n'>=n, leaves, and randomly sample sub-trees with n leaves. Hence, with rho=1.0, the same tree is reported over and over again.+ Gernhard, T. (2008). The conditioned reconstructed process. Journal of Theoretical Biology, 253(4), 769–778. http://doi.org/10.1016/j.jtbi.2008.04.005 # ELynx -Documentation of the library can be found on Hackage.+Documentation of the library can be found on [Hackage](https://hackage.haskell.org/):++- [elynx-seq](https://hackage.haskell.org/package/elynx-seq)+- [elynx-tree](https://hackage.haskell.org/package/elynx-tree)+- [elynx-tools](https://hackage.haskell.org/package/elynx-tools)+- [slynx](https://hackage.haskell.org/package/slynx)+- [tlynx](https://hackage.haskell.org/package/tlynx)
app/Main.hs view
@@ -35,10 +35,10 @@ lvl = verbosity g lf = (++ ".log") <$> fn case c of- Concatenate a -> runReaderT (eLynxWrapper lvl lf concatenateHeader $ concatenateCmd fn) a- Examine a -> runReaderT (eLynxWrapper lvl lf examineHeader $ examineCmd fn) a- FilterRows a -> runReaderT (eLynxWrapper lvl lf filterRowsHeader $ filterRowsCmd fn) a- FilterColumns a -> runReaderT (eLynxWrapper lvl lf filterColumnsHeader $ filterColumnsCmd fn) a- Simulate a -> runReaderT (eLynxWrapper lvl lf simulateHeader $ simulateCmd fn) a- SubSample a -> runReaderT (eLynxWrapper lvl lf subSampleHeader $ subSampleCmd fn) a- Translate a -> runReaderT (eLynxWrapper lvl lf translateHeader $ translateCmd fn) a+ Concatenate a -> runReaderT (eLynxWrapper lvl lf concatenateDescription $ concatenateCmd fn) a+ Examine a -> runReaderT (eLynxWrapper lvl lf examineDescription $ examineCmd fn) a+ FilterRows a -> runReaderT (eLynxWrapper lvl lf filterRowsDescription $ filterRowsCmd fn) a+ FilterCols a -> runReaderT (eLynxWrapper lvl lf filterColumnsDescription $ filterColsCmd fn) a+ Simulate a -> runReaderT (eLynxWrapper lvl lf simulateDescription $ simulateCmd fn) a+ SubSample a -> runReaderT (eLynxWrapper lvl lf subSampleDescription $ subSampleCmd fn) a+ Translate a -> runReaderT (eLynxWrapper lvl lf translateDescription $ translateCmd fn) a
app/Options.hs view
@@ -16,13 +16,13 @@ ( Arguments (..) , CommandArguments (..) , parseArguments- , concatenateHeader- , examineHeader- , filterRowsHeader- , filterColumnsHeader- , simulateHeader- , subSampleHeader- , translateHeader+ , concatenateDescription+ , examineDescription+ , filterRowsDescription+ , filterColumnsDescription+ , simulateDescription+ , subSampleDescription+ , translateDescription ) where import Options.Applicative@@ -37,65 +37,69 @@ import ELynx.Data.Alphabet.Alphabet import ELynx.Tools.Options+-- TODO: Removed reproducibility stuff for now, have to work on that.+-- import ELynx.Tools.Reproduction data CommandArguments = Concatenate ConcatenateArguments | Examine ExamineArguments | FilterRows FilterRowsArguments- | FilterColumns FilterColumnsArguments+ | FilterCols FilterColsArguments | Simulate SimulateArguments | SubSample SubSampleArguments | Translate TranslateArguments -concatenateHeader, examineHeader, filterRowsHeader, filterColumnsHeader, simulateHeader, subSampleHeader, translateHeader :: String-concatenateHeader = "Concatenate sequences found in input files."-examineHeader = "Examine sequences."-filterRowsHeader = "Filter rows (or sequences) found in input files."-filterColumnsHeader = "Filter columns of multi-sequence alignments."-simulateHeader = "Simulate multi sequence alignments."-subSampleHeader = "Sub-sample columns from multi sequence alignments."-translateHeader = "Translate from DNA to Protein or DNAX to ProteinX."+-- instance Reproducible CommandArguments where+-- inFiles (Concatenate a) = inFiles a +concatenateDescription, examineDescription, filterRowsDescription, filterColumnsDescription, simulateDescription, subSampleDescription, translateDescription :: String+concatenateDescription = "Concatenate sequences found in input files."+examineDescription = "Examine sequences. If data is a multi sequence alignment, additionally analyze columns."+filterRowsDescription = "Filter rows (or sequences) found in input files."+filterColumnsDescription = "Filter columns of multi-sequence alignments."+simulateDescription = "Simulate multi sequence alignments."+subSampleDescription = "Sub-sample columns from multi sequence alignments."+translateDescription = "Translate from DNA to Protein or DNAX to ProteinX."+ concatenateCommand :: Mod CommandFields CommandArguments concatenateCommand = command "concatenate" $ info (Concatenate <$> concatenateArguments)- $ header concatenateHeader+ $ progDesc concatenateDescription examineCommand :: Mod CommandFields CommandArguments examineCommand = command "examine" $ info (Examine <$> examineArguments) ( fullDesc- <> header examineHeader- <> progDesc "If data is a multi sequence alignment, additionally analyze columns." )+ <> progDesc examineDescription ) filterRowsCommand :: Mod CommandFields CommandArguments filterRowsCommand = command "filter-rows" $ info (FilterRows <$> filterRowsArguments)- $ header filterRowsHeader+ $ progDesc filterRowsDescription filterColumnsCommand :: Mod CommandFields CommandArguments filterColumnsCommand = command "filter-columns" $- info (FilterColumns <$> filterColumnsArguments)- $ header filterColumnsHeader+ info (FilterCols <$> filterColsArguments)+ $ progDesc filterColumnsDescription simulateCommand :: Mod CommandFields CommandArguments simulateCommand = command "simulate" $ info (Simulate <$> simulateArguments) (fullDesc- <> header simulateHeader+ <> progDesc simulateDescription <> footerDoc (Just $ pretty simulateFooter) ) subSampleCommand :: Mod CommandFields CommandArguments subSampleCommand = command "sub-sample" $ info (SubSample <$> subSampleArguments) ( fullDesc- <> header subSampleHeader- <> progDesc "Create a given number of multi sequence alignments, each of which containing a given number of random sites drawn from the original multi sequence alignment." )+ <> progDesc subSampleDescription+ <> footer "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." ) translateCommand :: Mod CommandFields CommandArguments translateCommand = command "translate" $ info (Translate <$> translateArguments)- $ header translateHeader+ $ progDesc translateDescription commandArguments :: Parser CommandArguments commandArguments = hsubparser $@@ -107,15 +111,8 @@ <> subSampleCommand <> translateCommand -data Arguments = Arguments- { globalArgs :: GlobalArguments- , cmdArgs :: CommandArguments }--parseArguments :: IO Arguments-parseArguments = parseArgumentsWith desc ftr $- Arguments- <$> globalArguments- <*> commandArguments+parseArguments :: IO (Arguments CommandArguments)+parseArguments = parseArgumentsWith desc ftr commandArguments desc :: [String] desc = [ "Analyze, and simulate multi sequence alignments." ]@@ -126,4 +123,4 @@ where toListItem = (" - " ++) fs = map toListItem ["FASTA"]- as = map (toListItem . alphabetNameVerbose) [(minBound :: Alphabet) ..]+ as = map (toListItem . description) [(minBound :: Alphabet) ..]
slynx.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: slynx-version: 0.0.1+version: 0.1.0 license: GPL-3 license-file: LICENSE copyright: Dominik Schrempf (2019)@@ -41,20 +41,19 @@ other-modules: Paths_slynx default-language: Haskell2010- ghc-options: -Wall+ ghc-options: -Wall -O2 build-depends: async >=2.2.2 && <2.3, base >=4.12.0.0 && <4.13, bytestring >=0.10.8.2 && <0.11, containers >=0.6.0.1 && <0.7, data-memocombinators >=0.5.1 && <0.6,- elynx-seq >=0.0.1 && <0.1,- elynx-tools >=0.0.1 && <0.1,- elynx-tree >=0.0.1 && <0.1,+ elynx-seq >=0.1.0 && <0.2,+ elynx-tools >=0.1.0 && <0.2,+ elynx-tree >=0.1.0 && <0.2, hmatrix >=0.20.0.0 && <0.21, integration >=0.2.1 && <0.3,- lens >=4.17.1 && <4.18,- math-functions >=0.3.1.0 && <0.4,+ math-functions >=0.3.2.1 && <0.4, matrices >=0.5.0 && <0.6, megaparsec >=7.0.5 && <7.1, monad-logger >=0.3.30 && <0.4,@@ -76,19 +75,19 @@ Options Paths_slynx default-language: Haskell2010- ghc-options: -Wall -eventlog -threaded -rtsopts -with-rtsopts=-N+ ghc-options: -Wall -O2 -eventlog -threaded -rtsopts+ -with-rtsopts=-N build-depends: async >=2.2.2 && <2.3, base >=4.12.0.0 && <4.13, bytestring >=0.10.8.2 && <0.11, containers >=0.6.0.1 && <0.7, data-memocombinators >=0.5.1 && <0.6,- elynx-seq >=0.0.1 && <0.1,- elynx-tools >=0.0.1 && <0.1,+ elynx-seq >=0.1.0 && <0.2,+ elynx-tools >=0.1.0 && <0.2, hmatrix >=0.20.0.0 && <0.21, integration >=0.2.1 && <0.3,- lens >=4.17.1 && <4.18,- math-functions >=0.3.1.0 && <0.4,+ math-functions >=0.3.2.1 && <0.4, matrices >=0.5.0 && <0.6, megaparsec >=7.0.5 && <7.1, monad-logger >=0.3.30 && <0.4,
src/Concatenate/Concatenate.hs view
@@ -27,7 +27,7 @@ import Concatenate.Options import Tools -import ELynx.Data.Sequence.Sequence+import qualified ELynx.Data.Sequence.Sequence as S import ELynx.Export.Sequence.Fasta import ELynx.Tools.InputOutput @@ -37,7 +37,7 @@ $(logInfo) "Command: Concatenate sequences." ConcatenateArguments al fps <- lift ask sss <- mapM (readSeqs al . Just) fps- let result = sequencesToFasta $ concatenateSeqs sss+ let result = sequencesToFasta $ S.concatSequences sss let outFilePath = (++ ".fasta") <$> outFileBaseName- io "concatenated multi sequence alignment " result outFilePath+ out "concatenated multi sequence alignment " result outFilePath
src/Concatenate/Options.hs view
@@ -26,11 +26,16 @@ import Tools import ELynx.Data.Alphabet.Alphabet+import ELynx.Tools.Reproduction -- | Arguments needed to concatenate multi sequence alignments. data ConcatenateArguments = ConcatenateArguments { ccAlphabet :: Alphabet , ccInFiles :: [FilePath] }++instance Reproducible ConcatenateArguments where+ inFiles = ccInFiles+ parser _ = concatenateArguments -- | Logger and Reader type. type Concatenate = LoggingT (ReaderT ConcatenateArguments IO)
src/Examine/Examine.hs view
@@ -24,24 +24,28 @@ import Control.Monad.Logger import Control.Monad.Trans.Class import Control.Monad.Trans.Reader-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.Set as S import Text.Printf import Examine.Options import Tools -import ELynx.Data.Sequence.MultiSequenceAlignment-import ELynx.Data.Sequence.Sequence+import qualified ELynx.Data.Alphabet.Alphabet as A+import qualified ELynx.Data.Alphabet.Character as C+import qualified ELynx.Data.Sequence.Alignment as M+import qualified ELynx.Data.Sequence.Sequence as Seq import ELynx.Tools.InputOutput -examineMSA :: Bool -> MultiSequenceAlignment -> L.ByteString-examineMSA perSiteFlag msa =- L.unlines [ L.pack $ "Total number of columns in alignment: "- ++ show (msaLength msa)+examineAlignment :: Bool -> M.Alignment -> L.ByteString+examineAlignment perSiteFlag a =+ L.unlines [ L.pack "Sequences have equal length (multi sequence alignment, or single sequence)."+ , L.pack $ "Total number of columns in alignment: "+ ++ show (M.length a) , L.pack $ "Number of columns without gaps: "- ++ show (msaLength msaNoGaps)+ ++ show (M.length aNoGaps) , L.pack $ "Number of columns with standard characters only: "- ++ show (msaLength msaOnlyStd)+ ++ show (M.length aOnlyStd) , L.empty , L.pack $ "Total number of characters: " ++ show nTot , L.pack $ "Standard (i.e., not extended IUPAC) characters: "@@ -58,6 +62,12 @@ , L.pack $ "Percentage of unknowns: " ++ printf "%.3f" percentageUnknowns , L.empty+ , L.pack "Distribution of characters:"+ -- Holy crap.+ , L.pack $ concatMap ((: " ") . C.toChar) $ S.toList $+ A.std $ A.alphabetSpec $ M.alphabet a+ , L.pack $ unwords $ map (printf "%.3f") charFreqs+ , L.empty , L.pack "Mean effective number of states (measured using entropy):" , L.pack "Across whole alignment: " <> L.pack (printf "%.3f" kEffMean)@@ -68,18 +78,20 @@ ] <> perSiteBS where- nTot = msaLength msa * msaNSequences msa- nIUPAC = countIUPACChars msa- nGaps = countGaps msa- nUnknowns = countUnknowns msa+ nTot = M.length a * M.nSequences a+ nIUPAC = M.countIUPACChars a+ nGaps = M.countGaps a+ nUnknowns = M.countUnknowns a percentageIUPAC = fromIntegral nIUPAC / fromIntegral nTot :: Double percentageGaps = fromIntegral nGaps / fromIntegral nTot :: Double percentageUnknowns = fromIntegral nUnknowns / fromIntegral nTot :: Double- msaNoGaps = filterColumnsNoGaps msa- msaOnlyStd = filterColumnsOnlyStd msaNoGaps- kEffs = kEffEntropy . toFrequencyData $ msa- kEffsNoGaps = kEffEntropy . toFrequencyData $ msaNoGaps- kEffsOnlyStd = kEffEntropy . toFrequencyData $ msaOnlyStd+ aNoGaps = M.filterColsNoGaps a+ aOnlyStd = M.filterColsOnlyStd aNoGaps+ charFreqsPerSite = M.toFrequencyData a+ charFreqs = M.distribution charFreqsPerSite+ kEffs = M.kEffEntropy charFreqsPerSite+ kEffsNoGaps = M.kEffEntropy . M.toFrequencyData $ aNoGaps+ kEffsOnlyStd = M.kEffEntropy . M.toFrequencyData $ aOnlyStd kEffMean = sum kEffs / fromIntegral (length kEffs) kEffMeanNoGaps = sum kEffsNoGaps / fromIntegral (length kEffsNoGaps) kEffMeanOnlyStd = sum kEffsOnlyStd / fromIntegral (length kEffsOnlyStd)@@ -89,11 +101,11 @@ ] else L.empty -examine :: Bool -> [Sequence] -> L.ByteString-examine perSiteFlag ss = summarizeSequenceList ss <>- case fromSequenceList ss of- Left _ -> L.empty- Right msa -> L.pack "\n" <> examineMSA perSiteFlag msa+examine :: Bool -> [Seq.Sequence] -> L.ByteString+examine perSiteFlag ss = Seq.summarizeSequences ss <>+ case M.fromSequences ss of+ Left _ -> L.empty+ Right a -> L.pack "\n" <> examineAlignment perSiteFlag a -- | Examine sequences. examineCmd :: Maybe FilePath -> Examine ()@@ -103,4 +115,4 @@ ss <- readSeqs al inFile let result = examine perSiteFlag ss let outFilePath = (++ ".out") <$> outFileBaseName- io "result of examination" result outFilePath+ out "result of examination" result outFilePath
src/Examine/Options.hs view
@@ -18,20 +18,29 @@ , examineArguments ) where -import Control.Applicative+import Control.Applicative (optional) import Control.Monad.Logger import Control.Monad.Trans.Reader+import Data.Maybe (fromJust) import Options.Applicative import Tools import ELynx.Data.Alphabet.Alphabet+import ELynx.Tools.Reproduction -- | Arguments needed to examine sequences. data ExamineArguments = ExamineArguments { exAlphabet :: Alphabet , exInFile :: Maybe FilePath , exPerSite :: Bool }++instance Reproducible ExamineArguments where+ -- TODO: How do I combine optional input files with reproducibility? The+ -- answer is: use checksums! Also other input files have to be checked with+ -- check sums. StdIO can also be checked in the same way.+ inFiles = pure . fromJust . exInFile+ parser _ = examineArguments -- | Logger and Reader type. type Examine = LoggingT (ReaderT ExamineArguments IO)
src/Filter/Filter.hs view
@@ -17,60 +17,64 @@ module Filter.Filter ( filterRowsCmd- , filterColumnsCmd+ , filterColsCmd ) where +import Control.Monad (when) import Control.Monad.Logger import Control.Monad.Trans.Class import Control.Monad.Trans.Reader-import qualified Data.ByteString.Lazy.Char8 as L-import Data.Maybe (fromMaybe)-import qualified Data.Text as T+import qualified Data.ByteString.Lazy.Char8 as L+import Data.Maybe (fromMaybe)+import qualified Data.Text as T import Filter.Options import Tools -import ELynx.Data.Sequence.MultiSequenceAlignment-import ELynx.Data.Sequence.Sequence+import qualified ELynx.Data.Sequence.Alignment as M+import qualified ELynx.Data.Sequence.Sequence as S import ELynx.Export.Sequence.Fasta import ELynx.Tools.InputOutput import ELynx.Tools.Misc -filterRows :: Maybe Int -> Maybe Int -> [Sequence] -> L.ByteString-filterRows ml ms ss = sequencesToFasta $ compose filters ss- where filters = map (fromMaybe id) [filterLongerThan <$> ml, filterShorterThan <$> ms]+filterRows :: Maybe Int -> Maybe Int -> Bool -> [S.Sequence] -> L.ByteString+filterRows ml ms std ss = sequencesToFasta $ compose filters ss+ where filters' = map (fromMaybe id) [S.filterLongerThan <$> ml, S.filterShorterThan <$> ms]+ filters = if std then S.filterStandard : filters' else filters' -- | Filter sequences. filterRowsCmd :: Maybe FilePath -> FilterRows () filterRowsCmd outFileBaseName = do $(logInfo) "Command: Filter sequences of a list of sequences."- FilterRowsArguments al inFile long short <- lift ask+ FilterRowsArguments al inFile long short std <- lift ask maybe (return ()) (\val -> $(logInfo) $ T.pack $ " Keep sequences longer than " <> show val <> ".") long maybe (return ()) (\val -> $(logInfo) $ T.pack $ " Keep sequences shorter than " <> show val <> ".") short+ when std $+ $(logInfo) " Keep sequences containing at least one standard (i.e., non-IUPAC) character." ss <- readSeqs al inFile- let result = filterRows long short ss+ let result = filterRows long short std ss let outFilePath = (++ ".fasta") <$> outFileBaseName- io "filtered sequences" result outFilePath+ out "filtered sequences" result outFilePath -filterColumns :: Maybe Double -> [Sequence] -> L.ByteString-filterColumns ms ss = sequencesToFasta . toSequenceList $ compose filters msa- where msa = either error id (fromSequenceList ss)- filters = map (fromMaybe id) [ filterColumnsStd <$> ms ]+filterCols :: Maybe Double -> [S.Sequence] -> L.ByteString+filterCols ms ss = sequencesToFasta . M.toSequences $ compose filters a+ where a = either error id (M.fromSequences ss)+ filters = map (fromMaybe id) [ M.filterColsStd <$> ms ] -- | Filter columns.-filterColumnsCmd :: Maybe FilePath -> FilterColumns ()-filterColumnsCmd outFileBaseName = do+filterColsCmd :: Maybe FilePath -> FilterCols ()+filterColsCmd outFileBaseName = do $(logInfo) "Command: Filter columns of a multi sequence alignment."- FilterColumnsArguments al inFile standard <- lift ask+ FilterColsArguments al inFile standard <- lift ask case standard of Nothing -> return () Just p -> $(logInfo) $ T.pack $ " Keep columns with a proportion of standard (non-IUPAC) characters larger than " ++ show p ++ "." ss <- readSeqs al inFile- let result = filterColumns standard ss+ let result = filterCols standard ss let outFilePath = (++ ".fasta") <$> outFileBaseName- io "filtered sequences" result outFilePath+ out "filtered sequences" result outFilePath
src/Filter/Options.hs view
@@ -14,11 +14,11 @@ module Filter.Options ( FilterRowsArguments (..)- , FilterColumnsArguments (..)+ , FilterColsArguments (..) , FilterRows- , FilterColumns+ , FilterCols , filterRowsArguments- , filterColumnsArguments+ , filterColsArguments ) where import Control.Applicative@@ -35,10 +35,11 @@ { frAlphabet :: Alphabet , frInFile :: Maybe FilePath , frLonger :: Maybe Int- , frShorter :: Maybe Int }+ , frShorter :: Maybe Int+ , frStandard :: Bool } -- | Arguments needed for filtering columns of a multi sequence alignment.-data FilterColumnsArguments = FilterColumnsArguments+data FilterColsArguments = FilterColsArguments { fcAlphabet :: Alphabet , fcInFile :: Maybe FilePath , fcStandard :: Maybe Double }@@ -47,7 +48,7 @@ type FilterRows = LoggingT (ReaderT FilterRowsArguments IO) -- | Logger and Reader for column filtering.-type FilterColumns = LoggingT (ReaderT FilterColumnsArguments IO)+type FilterCols = LoggingT (ReaderT FilterColsArguments IO) -- | Command line parser. filterRowsArguments :: Parser FilterRowsArguments@@ -56,6 +57,7 @@ <*> optional inFileArg <*> filterLongerThanOpt <*> filterShorterThanOpt+ <*> filterStandardChars filterLongerThanOpt :: Parser (Maybe Int) filterLongerThanOpt = optional $ option auto $@@ -69,9 +71,14 @@ metavar "LENGTH" <> help "Only keep sequences shorter than LENGTH" +filterStandardChars :: Parser Bool+filterStandardChars = switch $+ long "standard-characters" <>+ help "Only keep sequences containing at least one standard (i.e., non-IUPAC) character"+ -- | Command line parser.-filterColumnsArguments :: Parser FilterColumnsArguments-filterColumnsArguments = FilterColumnsArguments+filterColsArguments :: Parser FilterColsArguments+filterColsArguments = FilterColsArguments <$> alphabetOpt <*> optional inFileArg <*> filterStandardOpt
src/Simulate/Options.hs view
@@ -46,8 +46,12 @@ import Control.Monad.Logger import Control.Monad.Trans.Reader import Data.List+import Data.String (words)+-- import Data.Void import Data.Word import Options.Applicative+-- import Text.Megaparsec (Parsec, takeWhile1P)+-- import Text.Megaparsec.Char (space) import ELynx.Tools.Options @@ -60,6 +64,7 @@ , argsSubstitutionModelString :: Maybe String , argsMixtureModelString :: Maybe String , argsEDMFile :: Maybe FilePath+ , argsSiteprofilesFiles :: Maybe [FilePath] , argsMixtureWeights :: Maybe [Double] , argsGammaParams :: Maybe GammaRateHeterogeneityParams , argsLength :: Int@@ -76,6 +81,7 @@ <*> phyloSubstitutionModelOpt <*> phyloMixtureModelOpt <*> maybeEDMFileOpt+ <*> maybeSiteprofilesFilesOpt <*> maybeMixtureWeights <*> maybeGammaParams <*> lengthOpt@@ -108,6 +114,20 @@ <> short 'e' <> metavar "NAME" <> help "Empirical distribution model file NAME in Phylobayes format" )++-- fn :: Parsec Void String FilePath+-- fn = space *> takeWhile1P () <* space++-- fns :: Parsec Void String [FilePath]+-- fns = do+-- many string++maybeSiteprofilesFilesOpt :: Parser (Maybe [FilePath])+maybeSiteprofilesFilesOpt = optional $ words <$> strOption+ ( long "siteprofile-files"+ <> short 'p'+ <> metavar "NAMES"+ <> help "File names of site profiles in Phylobayes format" ) maybeMixtureWeights :: Parser (Maybe [Double]) maybeMixtureWeights = optional $ option auto
src/Simulate/Simulate.hs view
@@ -19,40 +19,47 @@ ( simulateCmd ) where +import Control.Applicative ((<|>)) import Control.Concurrent import Control.Concurrent.Async-import Control.Lens+import Control.Monad (unless,+ when) import Control.Monad.IO.Class import Control.Monad.Logger import Control.Monad.Trans.Class import Control.Monad.Trans.Reader-import qualified Data.ByteString.Lazy as L-import qualified Data.ByteString.Lazy.Char8 as LC-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 qualified Data.ByteString.Lazy as L+import qualified Data.ByteString.Lazy.Char8 as LC+import Data.Maybe+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 Data.Tree-import qualified Data.Vector.Unboxed as V-import Numeric.LinearAlgebra hiding ((<>))+import qualified Data.Vector.Unboxed as V+import Numeric.LinearAlgebra hiding ((<>)) import System.Random.MWC import Simulate.Options import Simulate.PhyloModel -import ELynx.Data.Alphabet.Alphabet as A+import ELynx.Data.Alphabet.Alphabet as A import ELynx.Data.MarkovProcess.GammaRateHeterogeneity-import qualified ELynx.Data.MarkovProcess.MixtureModel as M-import qualified ELynx.Data.MarkovProcess.PhyloModel as P-import qualified ELynx.Data.MarkovProcess.SubstitutionModel as S-import ELynx.Data.Sequence.MultiSequenceAlignment-import ELynx.Data.Sequence.Sequence hiding (name)+import qualified ELynx.Data.MarkovProcess.MixtureModel as M+import qualified ELynx.Data.MarkovProcess.PhyloModel as P+import qualified ELynx.Data.MarkovProcess.SubstitutionModel as SM+import qualified ELynx.Data.Sequence.Alignment as A+import qualified ELynx.Data.Sequence.Sequence as Seq hiding+ (name) import ELynx.Data.Tree.MeasurableTree import ELynx.Data.Tree.NamedTree import ELynx.Data.Tree.Tree import ELynx.Export.Sequence.Fasta-import ELynx.Import.MarkovProcess.EDMModelPhylobayes hiding (Parser)-import ELynx.Import.Tree.Newick hiding (name)+import ELynx.Import.MarkovProcess.EDMModelPhylobayes hiding+ (Parser)+import ELynx.Import.MarkovProcess.SiteprofilesPhylobayes hiding+ (Parser)+import ELynx.Import.Tree.Newick hiding (name) import ELynx.Simulate.MarkovProcessAlongTree import ELynx.Tools.ByteString@@ -60,36 +67,40 @@ import ELynx.Tools.InputOutput import ELynx.Tools.Misc --- Simulate a 'MultiSequenceAlignment' for a given phylogenetic model,+-- Simulate a 'Alignment' for a given phylogenetic model, -- phylogenetic tree, and alignment length.-simulateMSA :: (Measurable a, Named a)+simulateAlignment :: (Measurable a, Named a) => P.PhyloModel -> Tree a -> Int -> GenIO- -> IO MultiSequenceAlignment-simulateMSA pm t n g = do+ -> IO A.Alignment+simulateAlignment pm t n g = do c <- getNumCapabilities gs <- splitGen c g let chunks = getChunks c n leafStatesS <- case pm of+ -- TODO: This parallelization is not very intelligent, because the matrices+ -- exponentiation is done in all threads. So ten threads will exponentiate+ -- the same matrix ten times. P.SubstitutionModel sm -> mapConcurrently- (\(num, gen) -> simulateAndFlattenNSitesAlongTree num d e t gen) (zip chunks gs)- where d = sm ^. S.stationaryDistribution- e = sm ^. S.exchangeabilityMatrix- P.MixtureModel mm -> mapConcurrently- (\(num, gen) -> simulateAndFlattenNSitesAlongTreeMixtureModel num ws ds es t gen) (zip chunks gs)+ (\(num, gen) -> simulateAndFlatten num d e t gen) (zip chunks gs)+ where d = SM.stationaryDistribution sm+ e = SM.exchangeabilityMatrix sm+ -- P.MixtureModel mm -> mapConcurrently+ -- (\(num, gen) -> simulateAndFlattenNSitesAlongTreeMixtureModel num ws ds es t gen) (zip chunks gs)+ P.MixtureModel mm -> simulateAndFlattenMixtureModelPar n ws ds es t g where ws = vector $ M.getWeights mm- ds = map (view S.stationaryDistribution) $ M.getSubstitutionModels mm- es = map (view S.exchangeabilityMatrix) $ M.getSubstitutionModels mm+ ds = map SM.stationaryDistribution $ M.getSubstitutionModels mm+ es = map SM.exchangeabilityMatrix $ M.getSubstitutionModels mm -- XXX: The horizontal concatenation might be slow. If so, 'concatenateSeqs'- -- or 'concatenateMSAs' can be used, which directly appends vectors.+ -- or 'concatenateAlignments' can be used, which directly appends vectors. let leafStates = horizontalConcat leafStatesS leafNames = map getName $ leaves t code = P.getAlphabet pm -- XXX: Probably use type safe stuff here? alph = A.all $ alphabetSpec code- sequences = [ Sequence sName code (V.fromList $ map (`Set.elemAt` alph) ss) |+ sequences = [ Seq.Sequence sName code (V.fromList $ map (`Set.elemAt` alph) ss) | (sName, ss) <- zip leafNames leafStates ]- return $ either error id $ fromSequenceList sequences+ return $ either error id $ A.fromSequences sequences -- Summarize EDM components; line to be printed to screen or log. summarizeEDMComponents :: [EDMComponent] -> L.ByteString@@ -101,32 +112,48 @@ -- necessary. A human readable summary is reported anyways, and for Protein -- models the exchangeabilities are too many. reportModel :: Maybe FilePath -> P.PhyloModel -> Simulate ()-reportModel outFn m = do- let modelFn = (<> ".model") <$> outFn- io "model definition (machine readable)" (bsShow m <> "\n") modelFn+reportModel Nothing _ = $(logInfo) "No output file provided; omit detailed report of phylogenetic model."+reportModel (Just outFn) m = do+ let modelFn = outFn <> ".model"+ out "model definition (machine readable)" (bShow m <> "\n") (Just modelFn) -- | Simulate sequences. simulateCmd :: Maybe FilePath -> Simulate () simulateCmd outFn = do a <- lift ask- $(logInfo) "Read tree." let treeFile = argsTreeFile a++ $(logInfo) ""+ $(logInfo) $ T.pack $ "Read tree from file '" ++ treeFile ++ "'." tree <- liftIO $ parseFileWith newick treeFile $(logInfo) $ LT.toStrict $ LT.decodeUtf8 $ summarize tree let edmFile = argsEDMFile a+ let sProfileFiles = argsSiteprofilesFiles a+ $(logInfo) ""+ $(logDebug) "Read EDM file or siteprofile files."+ when (isJust edmFile && isJust sProfileFiles) $ error "Got both: --edm-file and --siteprofile-files." edmCs <- case edmFile of Nothing -> return Nothing Just edmF -> do $(logInfo) "Read EDM file." liftIO $ Just <$> parseFileWith phylobayes edmF maybe (return ()) ($(logInfo) . LT.toStrict . LT.decodeUtf8 . summarizeEDMComponents) edmCs+ sProfiles <- case sProfileFiles of+ Nothing -> return Nothing+ Just fns -> do+ $(logInfo) $ T.pack $ "Read siteprofiles from " ++ show (length fns) ++ " file(s)."+ $(logDebug) $ T.pack $ "The file names are:" ++ show fns+ xs <- liftIO $ mapM (parseFileWith siteprofiles) fns+ return $ Just $ concat xs+ maybe (return ()) ($(logInfo) . LT.toStrict . LT.decodeUtf8 . summarizeEDMComponents) sProfiles+ let edmCsOrSiteprofiles = edmCs <|> sProfiles $(logInfo) "Read model string." let ms = argsSubstitutionModelString a mm = argsMixtureModelString a mws = argsMixtureWeights a- eitherPhyloModel' = getPhyloModel ms mm mws edmCs+ eitherPhyloModel' = getPhyloModel ms mm mws edmCsOrSiteprofiles phyloModel' <- case eitherPhyloModel' of Left err -> lift $ error err Right pm -> return pm@@ -139,10 +166,16 @@ return phyloModel' Just (n, alpha) -> do $(logInfo) $ LT.toStrict $ LT.decodeUtf8- $ LC.unlines $ P.summarize phyloModel' ++ summarizeGammaRateHeterogeneity n alpha+ $ LC.intercalate "\n" $ P.summarize phyloModel' ++ summarizeGammaRateHeterogeneity n alpha return $ expand n alpha phyloModel'- reportModel outFn phyloModel + -- -- XXX: Do not report possibly huge empirical distribution mixture models+ -- -- for now, because it takes too long and uses too much disk space :).+ unless (isJust sProfiles) (+ do reportModel outFn phyloModel+ $(logInfo) ""+ )+ $(logInfo) "Simulate alignment." let alignmentLength = argsLength a $(logInfo) $ T.pack $ "Length: " <> show alignmentLength <> "."@@ -152,7 +185,8 @@ >> liftIO createSystemRandom Just s -> $(logInfo) (T.pack ("Seed: " <> show s <> ".")) >> liftIO (initialize (V.fromList s))- msa <- liftIO $ simulateMSA phyloModel tree alignmentLength gen- let output = (sequencesToFasta . toSequenceList) msa+ alignment <- liftIO $ simulateAlignment phyloModel tree alignmentLength gen+ let output = (sequencesToFasta . A.toSequences) alignment outFile = (<> ".fasta") <$> outFn- io "simulated multi sequence alignment" output outFile+ $(logInfo) ""+ out "simulated multi sequence alignment" output outFile
src/SubSample/SubSample.hs view
@@ -25,17 +25,17 @@ import Control.Monad.Logger import Control.Monad.Trans.Class import Control.Monad.Trans.Reader-import qualified Data.Text as T-import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Builder as LT-import qualified Data.Text.Lazy.Builder.Int as LT-import qualified Data.Vector as V+import qualified Data.Text as T+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Builder as LT+import qualified Data.Text.Lazy.Builder.Int as LT+import qualified Data.Vector as V import System.Random.MWC import SubSample.Options import Tools -import ELynx.Data.Sequence.MultiSequenceAlignment+import qualified ELynx.Data.Sequence.Alignment as M import ELynx.Export.Sequence.Fasta import ELynx.Tools.InputOutput @@ -60,11 +60,11 @@ $(logInfo) $ T.pack $ " Sample " <> show nAlignments <> " multi sequence alignments." ss <- readSeqs al inFile gen <- liftIO $ maybe createSystemRandom (initialize . V.fromList) seed- let msa = either error id (fromSequenceList ss)- samples <- lift $ replicateM nAlignments $ randomSubSample nSites msa gen- let results = map (sequencesToFasta . toSequenceList) samples+ let a = either error id (M.fromSequences ss)+ samples <- lift $ replicateM nAlignments $ M.randomSubSample nSites a gen+ let results = map (sequencesToFasta . M.toSequences) samples outFilePaths <- case outFileBaseName of Nothing -> return $ repeat Nothing Just fn -> return $ Just <$> getOutFilePaths fn nAlignments "fasta"- zipWithM_ (io "sub sampled multi sequence alignments") results outFilePaths+ zipWithM_ (out "sub sampled multi sequence alignments") results outFilePaths
src/Tools.hs view
@@ -29,7 +29,7 @@ import ELynx.Data.Alphabet.Alphabet import ELynx.Data.Sequence.Sequence-import ELynx.Import.Sequence.Fasta+import ELynx.Import.Sequence.Fasta hiding (Parser) import ELynx.Tools.InputOutput -- | Read sequences of given alphabet from file or standard input.@@ -41,7 +41,7 @@ <> show a <> "." Just fp -> $(logInfo) $ T.pack $ "Read sequences from file "- <> fp <> "; alphabet" <> show a <> "."+ <> fp <> "; alphabet " <> show a <> "." liftIO $ parseFileOrIOWith (fasta a) mfp -- | Command line option to specify the alphabet. Used by various commands.
src/Translate/Translate.hs view
@@ -48,4 +48,4 @@ ss <- readSeqs al inFile let result = sequencesToFasta $ translateSeqs rf uc ss let outFilePath = (++ ".fasta") <$> outFileBaseName- io "translated sequences" result outFilePath+ out "translated sequences" result outFilePath