elynx-seq 0.2.2 → 0.3.0
raw patch · 27 files changed
+1742/−1879 lines, 27 filesdep ~aesondep ~basedep ~bytestring
Dependency ranges changed: aeson, base, bytestring, containers, elynx-tools, hspec, hspec-megaparsec, matrices, megaparsec, mwc-random, parallel, primitive, vector, vector-th-unbox, word8
Files
- ChangeLog.md +11/−0
- README.md +68/−274
- elynx-seq.cabal +87/−85
- src/ELynx/Data/Alphabet/Alphabet.hs +102/−94
- src/ELynx/Data/Alphabet/Character.hs +32/−37
- src/ELynx/Data/Alphabet/DistributionDiversity.hs +52/−48
- src/ELynx/Data/Character/AminoAcid.hs +54/−58
- src/ELynx/Data/Character/AminoAcidI.hs +157/−127
- src/ELynx/Data/Character/AminoAcidS.hs +103/−87
- src/ELynx/Data/Character/AminoAcidX.hs +101/−85
- src/ELynx/Data/Character/Character.hs +35/−37
- src/ELynx/Data/Character/Codon.hs +172/−176
- src/ELynx/Data/Character/Nucleotide.hs +36/−40
- src/ELynx/Data/Character/NucleotideI.hs +118/−98
- src/ELynx/Data/Character/NucleotideX.hs +51/−52
- src/ELynx/Data/Sequence/Alignment.hs +161/−149
- src/ELynx/Data/Sequence/Defaults.hs +15/−19
- src/ELynx/Data/Sequence/Sequence.hs +129/−120
- src/ELynx/Data/Sequence/Translate.hs +32/−35
- src/ELynx/Export/Sequence/Fasta.hs +18/−23
- src/ELynx/Import/Sequence/Fasta.hs +36/−39
- test/ELynx/Data/Alphabet/DistributionDiversitySpec.hs +31/−38
- test/ELynx/Data/Sequence/AlignmentSpec.hs +33/−34
- test/ELynx/Data/Sequence/SequenceSpec.hs +33/−34
- test/ELynx/Data/Sequence/TranslateSpec.hs +22/−25
- test/ELynx/Export/Sequence/FastaSpec.hs +26/−29
- test/ELynx/Import/Sequence/FastaSpec.hs +27/−36
ChangeLog.md view
@@ -2,6 +2,17 @@ # Changelog for ELynx +## Version 0.3.1; in development+++## Version 0.3.0++- **`elynx-nexus`:** library to import and export Nexus files.+- **`elynx-tree`:** major refactor and big cleanup; use rose trees with branch+ labels.+- **`elynx-tree`:** provide zippers.++ ## Version 0.2.2 - Validation and repetition of previous analyses is finally possible with the
README.md view
@@ -2,9 +2,11 @@ # The ELynx Suite -Version: 0.2.2.+Version: 0.3.0. Reproducible evolution made easy. +<p align="center"><img src="https://travis-ci.org/dschrempf/elynx.svg?branch=master"/></p>+ 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@@ -12,11 +14,12 @@ sums so that validation of past analyses is possible without the need to recompute the result. -The Elynx Suite consists of four library packages and three executables providing-a range of sub commands.+The Elynx Suite consists of library packages and executables providing a range+of sub commands. The library packages are: +- **elynx-nexus:** Nexus file support. - **elynx-markov:** Simulate multi sequence alignments along phylogenetic trees. - **elynx-seq:** Handle evolutionary sequences and multi sequence alignments. - **elynx-tools:** Tools for the provided executables.@@ -43,7 +46,7 @@ 2. Clone the ELynx repository. - git clone clone https://github.com/dschrempf/elynx+ git clone https://github.com/dschrempf/elynx 3. Navigate to the newly created `elynx` folder and build the binaries. This will take a while.@@ -62,15 +65,34 @@ [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable. Then, they can be used directly. +# Documentation++Documentation is available on [Hackage](https://hackage.haskell.org/).++Libraries:++- [elynx-nexus](https://hackage.haskell.org/package/elynx-nexus)+- [elynx-markov](https://hackage.haskell.org/package/elynx-markov)+- [elynx-seq](https://hackage.haskell.org/package/elynx-seq)+- [elynx-tools](https://hackage.haskell.org/package/elynx-tools)+- [elynx-tree](https://hackage.haskell.org/package/elynx-tree)++Executables:++- [elynx](https://hackage.haskell.org/package/elynx)+- [slynx](https://hackage.haskell.org/package/slynx)+- [tlynx](https://hackage.haskell.org/package/tlynx)++ # SLynx Handle evolutionary sequences. - slynx --help+ slynx --help | head -n -16 - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] COMMAND@@ -95,6 +117,7 @@ sub-sample Sub-sample columns from multi sequence alignments. translate Translate from DNA to Protein or DNAX to ProteinX. + Available sequence file formats: - FASTA @@ -105,23 +128,6 @@ - Protein (amino acids) - ProteinX (amino acids; including gaps) - ProteinS (amino acids; including gaps, and translation stops)- - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Concatenate@@ -130,9 +136,9 @@ slynx concatenate --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE Concatenate sequences found in input files.@@ -143,23 +149,6 @@ -a,--alphabet NAME Specify alphabet type NAME INPUT-FILE Read sequences from INPUT-FILE -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Examine@@ -168,9 +157,9 @@ slynx examine --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site] Examine sequences. If data is a multi sequence alignment, additionally analyze columns.@@ -182,23 +171,6 @@ INPUT-FILE Read sequences from INPUT-FILE --per-site Report per site summary statistics -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Filter@@ -207,9 +179,9 @@ slynx filter-rows --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH] [--shorter-than LENGTH] [--standard-characters]@@ -225,31 +197,14 @@ --standard-characters Only keep sequences containing at least one standard (i.e., non-IUPAC) character -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help Filter columns of multi sequence alignments with `filter-columns`. slynx filter-columns --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE [--standard-chars DOUBLE]@@ -263,23 +218,6 @@ --standard-chars DOUBLE Keep columns with a proportion standard (non-IUPAC) characters larger than DOUBLE in [0,1] -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Simulate@@ -288,9 +226,9 @@ slynx simulate --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -352,27 +290,13 @@ where XX is 10, 20, 30, 40, 50, or 60; CXX models, Quang et al., 2008. -m "EDM(EXCHANGEABILITIES)" Arbitrary empirical distribution mixture (EDM) models.- Stationary distributions have to be provided with the -e option.+ Stationary distributions have to be provided with the -e or -p option. For example, LG exchangeabilities with stationary distributions given in FILE. -m "EDM(LG-Custom)" -e FILE+ LG exchangeabilities with site profiles (Phylobayes) given in FILES.+ -m "EDM(LG-Custom)" -p FILES For special mixture models, mixture weights are optional.- - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Sub-sample@@ -381,9 +305,9 @@ slynx sub-sample --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE (-n|--number-of-sites INT)@@ -403,22 +327,6 @@ -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.- - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Translate@@ -427,9 +335,9 @@ slynx translate --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT) (-u|--universal-code CODE)@@ -444,34 +352,17 @@ -u,--universal-code CODE universal code; one of: Standard, VertebrateMitochondrial. -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help # TLynx Handle phylogenetic trees in Newick format. - tlynx --help+ tlynx --help | head -n -16 - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] [-f|--force] COMMAND@@ -496,26 +387,10 @@ shuffle Shuffle a phylogenetic tree (keep coalescent times, but shuffle topology and leaves). simulate Simulate phylogenetic trees using birth and death processes (see also the 'coalesce' command for simulations using the 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.- - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Compare@@ -524,12 +399,12 @@ tlynx compare --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect] - [-f|--newick-format FORMAT] NAME+ [-f|--newick-format FORMAT] NAMES Compare two phylogenetic trees (compute distances and branch-wise differences). Available options:@@ -540,27 +415,11 @@ -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; see 'tlynx- --help' (default: Standard)- NAME Tree file+ Newick tree format: Standard, IqTree, or RevBayes;+ default: Standard; for detailed help, see 'tlynx+ --help'+ NAMES Tree files -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Examine@@ -569,9 +428,9 @@ tlynx examine --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT] Compute summary statistics of phylogenetic trees.@@ -581,26 +440,10 @@ -V,--version Show version INPUT-FILE Read trees from INPUT-FILE -f,--newick-format FORMAT- Newick tree format; see 'tlynx- --help' (default: Standard)+ Newick tree format: Standard, IqTree, or RevBayes;+ default: Standard; for detailed help, see 'tlynx+ --help' -h,--help Show this help text- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help ## Simulate@@ -609,9 +452,9 @@ tlynx simulate --help - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE] [-M|--condition-on-mrca] [-l|--lambda DOUBLE] @@ -640,33 +483,17 @@ 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- ------ 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help # ELynx Validate and (optionally) redo past ELynx analyses. - elynx --help+ elynx --help | head -n -16 - ELynx Suite version 0.2.1.+ ELynx Suite version 0.3.0. Developed by Dominik Schrempf.- Compiled on April 27, 2020, at 12:08 pm, UTC.+ Compiled on July 30, 2020, at 12:40 pm, UTC. Usage: elynx COMMAND Validate and redo past ELynx analyses@@ -678,37 +505,4 @@ Available commands: validate Validate an ELynx analysis redo Redo an ELynx analysis- - - 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.- - slynx Analyze, modify, and simulate evolutionary sequences.- tlynx Analyze, modify, and simulate phylogenetic trees.- elynx Validate and redo past analyses.- - Get help for sub commands:- slynx examine --help---# Library documentation--Documentation of the libraries can be found on [Hackage](https://hackage.haskell.org/):--- [elynx-markov](https://hackage.haskell.org/package/elynx-markov)-- [elynx-seq](https://hackage.haskell.org/package/elynx-seq)-- [elynx-tools](https://hackage.haskell.org/package/elynx-tools)-- [elynx-tree](https://hackage.haskell.org/package/elynx-tree)--Documentation of the executables is also available:--- [elynx](https://hackage.haskell.org/package/elynx)-- [slynx](https://hackage.haskell.org/package/slynx)-- [tlynx](https://hackage.haskell.org/package/tlynx)
elynx-seq.cabal view
@@ -1,94 +1,96 @@-cabal-version: 1.12-name: elynx-seq-version: 0.2.2-license: GPL-3-license-file: LICENSE-copyright: Dominik Schrempf (2020)-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 molecular sequences-description:- Examine, modify, and simulate molecular sequences in a reproducible way. Please see the README on GitHub at <https://github.com/dschrempf/elynx>.-category: Bioinformatics-build-type: Simple+cabal-version: 2.2++-- This file has been generated from package.yaml by hpack version 0.34.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: afdff7b344d4b63f734a6f18db88ef39b1f45ed84c64e63045b57edfb839684f++name: elynx-seq+version: 0.3.0+synopsis: Handle molecular sequences+description: Examine, modify, and simulate molecular sequences 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 (2020)+license: GPL-3.0-or-later+license-file: LICENSE+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:- ELynx.Data.Alphabet.Alphabet- ELynx.Data.Alphabet.Character- ELynx.Data.Alphabet.DistributionDiversity- ELynx.Data.Character.AminoAcid- ELynx.Data.Character.AminoAcidI- ELynx.Data.Character.AminoAcidS- ELynx.Data.Character.AminoAcidX- ELynx.Data.Character.Character- ELynx.Data.Character.Codon- ELynx.Data.Character.Nucleotide- ELynx.Data.Character.NucleotideI- ELynx.Data.Character.NucleotideX- ELynx.Data.Sequence.Alignment- ELynx.Data.Sequence.Defaults- ELynx.Data.Sequence.Sequence- ELynx.Data.Sequence.Translate- ELynx.Export.Sequence.Fasta- ELynx.Import.Sequence.Fasta- hs-source-dirs: src- other-modules:- Paths_elynx_seq- default-language: Haskell2010- ghc-options: -Wall -fllvm- build-depends:- aeson >=1.4.7.1 && <1.5,- base >=4.13.0.0 && <4.14,- bytestring >=0.10.10.0 && <0.11,- containers >=0.6.2.1 && <0.7,- elynx-tools >=0.2.2 && <0.3,- matrices >=0.5.0 && <0.6,- megaparsec >=8.0.0 && <8.1,- mwc-random >=0.14.0.0 && <0.15,- parallel >=3.2.2.0 && <3.3,- primitive >=0.7.0.1 && <0.8,- vector >=0.12.1.2 && <0.13,- vector-th-unbox >=0.2.1.7 && <0.3,- word8 >=0.1.3 && <0.2+ exposed-modules:+ ELynx.Data.Alphabet.Alphabet+ ELynx.Data.Alphabet.Character+ ELynx.Data.Alphabet.DistributionDiversity+ ELynx.Data.Character.AminoAcid+ ELynx.Data.Character.AminoAcidI+ ELynx.Data.Character.AminoAcidS+ ELynx.Data.Character.AminoAcidX+ ELynx.Data.Character.Character+ ELynx.Data.Character.Codon+ ELynx.Data.Character.Nucleotide+ ELynx.Data.Character.NucleotideI+ ELynx.Data.Character.NucleotideX+ ELynx.Data.Sequence.Alignment+ ELynx.Data.Sequence.Defaults+ ELynx.Data.Sequence.Sequence+ ELynx.Data.Sequence.Translate+ ELynx.Export.Sequence.Fasta+ ELynx.Import.Sequence.Fasta+ other-modules:+ Paths_elynx_seq+ autogen-modules:+ Paths_elynx_seq+ hs-source-dirs:+ src+ ghc-options: -Wall -fllvm+ build-depends:+ aeson+ , base >=4.7 && <5+ , bytestring+ , containers+ , elynx-tools+ , matrices+ , megaparsec+ , mwc-random+ , parallel+ , primitive+ , vector+ , vector-th-unbox+ , word8+ default-language: Haskell2010 test-suite seq-test- type: exitcode-stdio-1.0- main-is: Spec.hs- hs-source-dirs: test- other-modules:- ELynx.Data.Alphabet.DistributionDiversitySpec- ELynx.Data.Sequence.AlignmentSpec- ELynx.Data.Sequence.SequenceSpec- ELynx.Data.Sequence.TranslateSpec- ELynx.Export.Sequence.FastaSpec- ELynx.Import.Sequence.FastaSpec- Paths_elynx_seq- default-language: Haskell2010- ghc-options: -Wall -fllvm -threaded -rtsopts -with-rtsopts=-N- build-depends:- aeson >=1.4.7.1 && <1.5,- base >=4.13.0.0 && <4.14,- bytestring >=0.10.10.0 && <0.11,- containers >=0.6.2.1 && <0.7,- elynx-seq -any,- elynx-tools >=0.2.2 && <0.3,- hspec >=2.7.1 && <2.8,- hspec-megaparsec >=2.1.0 && <2.2,- matrices >=0.5.0 && <0.6,- megaparsec >=8.0.0 && <8.1,- mwc-random >=0.14.0.0 && <0.15,- parallel >=3.2.2.0 && <3.3,- primitive >=0.7.0.1 && <0.8,- vector >=0.12.1.2 && <0.13,- vector-th-unbox >=0.2.1.7 && <0.3,- word8 >=0.1.3 && <0.2+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ ELynx.Data.Alphabet.DistributionDiversitySpec+ ELynx.Data.Sequence.AlignmentSpec+ ELynx.Data.Sequence.SequenceSpec+ ELynx.Data.Sequence.TranslateSpec+ ELynx.Export.Sequence.FastaSpec+ ELynx.Import.Sequence.FastaSpec+ Paths_elynx_seq+ hs-source-dirs:+ test+ ghc-options: -Wall -fllvm+ build-depends:+ base >=4.7 && <5+ , bytestring+ , elynx-seq+ , elynx-tools+ , hspec+ , hspec-megaparsec+ , matrices+ , vector+ default-language: Haskell2010
src/ELynx/Data/Alphabet/Alphabet.hs view
@@ -1,62 +1,65 @@ {-# LANGUAGE DeriveGeneric #-} -{- |-Module : ELynx.Data.Alphabet.Alphabet-Description : Alphabets store hereditary information-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable--Portability : portable--Creation date: Fri May 10 11:10:32 2019.--Hierarchy:--1. 'Character' type.--2. Sets of 'Character's form 'Alphabet's; each 'Alphabet' has a specification-'AlphabetSpec'.--New alphabets have to be added manually in this module.--This way of handling characters and alphabets IS NOT TYPE SAFE, but much, much-faster. A second layer of modules such as 'ELynx.Data.Character.Nucleotide'-depend on a 'ELynx.Data.Character.Character.Character' type class. Hence, they-provide a type safe way of handling alphabets. Conversion is possible, for-instance, with 'ELynx.Data.Alphabet.Character.fromCVec', and-'ELynx.Data.Alphabet.Character.toCVec'.---}-+-- |+-- Module : ELynx.Data.Alphabet.Alphabet+-- Description : Alphabets store hereditary information+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+--+-- Portability : portable+--+-- Creation date: Fri May 10 11:10:32 2019.+--+-- Hierarchy:+--+-- 1. 'Character' type.+--+-- 2. Sets of 'Character's form 'Alphabet's; each 'Alphabet' has a specification+-- 'AlphabetSpec'.+--+-- New alphabets have to be added manually in this module.+--+-- This way of handling characters and alphabets IS NOT TYPE SAFE, but much, much+-- faster. A second layer of modules such as 'ELynx.Data.Character.Nucleotide'+-- depend on a 'ELynx.Data.Character.Character.Character' type class. Hence, they+-- provide a type safe way of handling alphabets. Conversion is possible, for+-- instance, with 'ELynx.Data.Alphabet.Character.fromCVec', and+-- 'ELynx.Data.Alphabet.Character.toCVec'. module ELynx.Data.Alphabet.Alphabet- ( Alphabet(..)- , AlphabetSpec(..)- , alphabetSpec- , alphabetDescription- , isStd- , isGap- , isUnknown- , isIUPAC- , isMember+ ( Alphabet (..),+ AlphabetSpec (..),+ alphabetSpec,+ alphabetDescription,+ isStd,+ isGap,+ isUnknown,+ isIUPAC,+ isMember, ) where -import qualified Data.Set as S-import Prelude hiding ( all )-import Data.Aeson ( FromJSON- , ToJSON- )-import GHC.Generics ( Generic )--import ELynx.Data.Alphabet.Character+import Data.Aeson+ ( FromJSON,+ ToJSON,+ )+import qualified Data.Set as S+import ELynx.Data.Alphabet.Character+import GHC.Generics (Generic)+import Prelude hiding (all) -- | Available alphabets; for details see 'alphabetSpec'.-data Alphabet = DNA | DNAX | DNAI- | Protein | ProteinX | ProteinS | ProteinI- deriving (Show, Read, Eq, Ord, Enum, Bounded, Generic)+data Alphabet+ = DNA+ | DNAX+ | DNAI+ | Protein+ | ProteinX+ | ProteinS+ | ProteinI+ deriving (Show, Read, Eq, Ord, Enum, Bounded, Generic) instance FromJSON Alphabet @@ -64,11 +67,11 @@ -- | Verbose alphabet name. alphabetDescription :: Alphabet -> String-alphabetDescription DNA = "DNA (nucleotides)"+alphabetDescription DNA = "DNA (nucleotides)" alphabetDescription DNAX = "DNAX (nucleotides; including gaps)" alphabetDescription DNAI = "DNAI (nucleotides; including gaps, and IUPAC codes)"-alphabetDescription Protein = "Protein (amino acids)"+alphabetDescription Protein = "Protein (amino acids)" alphabetDescription ProteinX = "ProteinX (amino acids; including gaps)" alphabetDescription ProteinS = "ProteinS (amino acids; including gaps, and translation stops)"@@ -76,27 +79,45 @@ "ProteinI (amino acids; including gaps, translation stops, and IUPAC codes)" -- | Alphabet specification. 'S.Set' is used because it provides fast lookups.-data AlphabetSpec = AlphabetSpec {- -- | Standard characters.- std :: !(S.Set Character)- -- | Gap characters.- , gap :: !(S.Set Character)- -- | Unknown characters.- , unknown :: !(S.Set Character)- -- | Other IUPAC codes.- , iupac :: !(S.Set Character)- -- | All characters in the alphabet.- , all :: !(S.Set Character)- -- | Convert from IUPAC to the corresponding standard characters.- , toStd :: Character -> [Character]+data AlphabetSpec = AlphabetSpec+ { -- | Standard characters.+ std :: !(S.Set Character),+ -- | Gap characters.+ gap :: !(S.Set Character),+ -- | Unknown characters.+ unknown :: !(S.Set Character),+ -- | Other IUPAC codes.+ iupac :: !(S.Set Character),+ -- | All characters in the alphabet.+ all :: !(S.Set Character),+ -- | Convert from IUPAC to the corresponding standard characters.+ toStd :: Character -> [Character] } +-- Create alphabet spec.+fromChars ::+ String -> String -> String -> String -> (Char -> String) -> AlphabetSpec+fromChars st ga un iu to =+ AlphabetSpec+ st'+ ga'+ un'+ iu'+ al+ (fromString . to . toChar)+ where+ st' = S.fromList $ fromString st+ ga' = S.fromList $ fromString ga+ un' = S.fromList $ fromString un+ iu' = S.fromList $ fromString iu+ al = S.unions [st', ga', un', iu']+ -- | Get the alphabet specification for a given alphabet. alphabetSpec :: Alphabet -> AlphabetSpec-alphabetSpec DNA = dna-alphabetSpec DNAX = dnaX-alphabetSpec DNAI = dnaI-alphabetSpec Protein = protein+alphabetSpec DNA = dna+alphabetSpec DNAX = dnaX+alphabetSpec DNAI = dnaI+alphabetSpec Protein = protein alphabetSpec ProteinX = proteinX alphabetSpec ProteinS = proteinS alphabetSpec ProteinI = proteinI@@ -124,21 +145,6 @@ isMember :: Alphabet -> Character -> Bool isMember = isWith all -fromChars- :: String -> String -> String -> String -> (Char -> String) -> AlphabetSpec-fromChars st ga un iu to = AlphabetSpec st'- ga'- un'- iu'- al- (fromString . to . toChar)- where- st' = S.fromList $ fromString st- ga' = S.fromList $ fromString ga- un' = S.fromList $ fromString un- iu' = S.fromList $ fromString iu- al = S.unions [st', ga', un', iu']- dna :: AlphabetSpec dna = fromChars "ACGT" [] [] [] toStdDNA @@ -147,7 +153,7 @@ toStdDNA 'C' = "C" toStdDNA 'G' = "G" toStdDNA 'T' = "T"-toStdDNA _ = error "tostdDNA: Cannot convert to standard nucleotide."+toStdDNA _ = error "tostdDNA: Cannot convert to standard nucleotide." dnaX :: AlphabetSpec dnaX = fromChars "ACGT" "-." [] [] toStdDNAX@@ -159,10 +165,10 @@ toStdDNAX 'T' = "T" toStdDNAX '-' = [] toStdDNAX '.' = []-toStdDNAX _ = error "toStdDNAX: Cannot convert to standard nucleotide."+toStdDNAX _ = error "toStdDNAX: Cannot convert to standard nucleotide." dnaI :: AlphabetSpec-dnaI = fromChars "ACGT" "-." "N" "UWSMKRYBDHV" toStdDNAI+dnaI = fromChars "ACGT" "-." "N?" "UWSMKRYBDHV" toStdDNAI toStdDNAI :: Char -> String toStdDNAI 'A' = "A"@@ -181,9 +187,10 @@ toStdDNAI 'H' = "ACT" toStdDNAI 'V' = "ACG" toStdDNAI 'N' = "ACGT"+toStdDNAI '?' = "ACGT" toStdDNAI '-' = [] toStdDNAI '.' = []-toStdDNAI _ = error "toStdDNAI: Cannot convert to standard nucleotide."+toStdDNAI _ = error "toStdDNAI: Cannot convert to standard nucleotide." protein :: AlphabetSpec protein = fromChars "ACDEFGHIKLMNPQRSTVWY" [] [] [] toStdP@@ -209,7 +216,7 @@ toStdP 'V' = "V" toStdP 'W' = "W" toStdP 'Y' = "Y"-toStdP _ = error "toStdP: Cannot convert to standard amino acid."+toStdP _ = error "toStdP: Cannot convert to standard amino acid." proteinX :: AlphabetSpec proteinX = fromChars "ACDEFGHIKLMNPQRSTVWY" "-." [] [] toStdPX@@ -237,7 +244,7 @@ toStdPX 'Y' = "Y" toStdPX '-' = "" toStdPX '.' = ""-toStdPX _ = error "toStdPX: Cannot convert to standard amino acid."+toStdPX _ = error "toStdPX: Cannot convert to standard amino acid." proteinS :: AlphabetSpec proteinS = fromChars "ACDEFGHIKLMNPQRSTVWY" "-." [] "*" toStdPS@@ -266,10 +273,10 @@ toStdPS '-' = "" toStdPS '.' = "" toStdPS '*' = ""-toStdPS _ = error "toStdPX: Cannot convert to standard amino acid."+toStdPS _ = error "toStdPX: Cannot convert to standard amino acid." proteinI :: AlphabetSpec-proteinI = fromChars "ACDEFGHIKLMNPQRSTVWY" "-." "X" "*JBZ" toStdPI+proteinI = fromChars "ACDEFGHIKLMNPQRSTVWY" "-." "X?" "*JBZ" toStdPI toStdPI :: Char -> String toStdPI 'A' = "A"@@ -299,4 +306,5 @@ toStdPI 'B' = "DN" toStdPI 'Z' = "EQ" toStdPI 'X' = "ACDEFGHIKLMNPQRSTVWY"-toStdPI _ = error "toStdPX: Cannot convert to standard amino acid."+toStdPI '?' = "ACDEFGHIKLMNPQRSTVWY"+toStdPI _ = error "toStdPX: Cannot convert to standard amino acid."
src/ELynx/Data/Alphabet/Character.hs view
@@ -1,41 +1,36 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.Alphabet.Character-Description : Alphabet characters-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Sun May 19 21:06:38 2019.---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.Alphabet.Character+-- Description : Alphabet characters+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Sun May 19 21:06:38 2019. module ELynx.Data.Alphabet.Character- ( Character- , toWord- , fromWord- , toChar- , fromChar- , toString- , fromString- , toCVec- , fromCVec+ ( Character,+ toWord,+ fromWord,+ toChar,+ fromChar,+ toString,+ fromString,+ toCVec,+ fromCVec, ) where -import qualified Data.Vector.Unboxed as V-import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import qualified Data.Vector.Unboxed as V+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Alphabet characters; abstracted so that representation can be changed at -- some point.@@ -74,8 +69,8 @@ fromCVec :: C.Character a => V.Vector a -> V.Vector Character fromCVec = V.map (fromWord . C.toWord) -derivingUnbox "Character"- [t| Character -> Word8 |]- [| \(Character w) -> w |]- [| Character |]-+derivingUnbox+ "Character"+ [t|Character -> Word8|]+ [|\(Character w) -> w|]+ [|Character|]
src/ELynx/Data/Alphabet/DistributionDiversity.hs view
@@ -1,48 +1,50 @@ {-# LANGUAGE FlexibleContexts #-} -{- |-Module : ELynx.Data.Alphabet.DistributionDiversity-Description : Summarize statistics for alphabets-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Mon Feb 25 13:32:56 2019.---}-+-- |+-- Module : ELynx.Data.Alphabet.DistributionDiversity+-- Description : Summarize statistics for alphabets+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Mon Feb 25 13:32:56 2019. module ELynx.Data.Alphabet.DistributionDiversity ( -- * Entropy- entropy- , kEffEntropy+ entropy,+ kEffEntropy,+ -- * Homoplasy- , homoplasy- , kEffHomoplasy+ homoplasy,+ kEffHomoplasy,+ -- * Count characters- , frequencyCharacters+ frequencyCharacters, ) where -import qualified Data.Set as S-import qualified Data.Vector.Generic as V-import Data.Vector.Generic ( Vector- , toList- )--import ELynx.Data.Alphabet.Alphabet-import ELynx.Data.Alphabet.Character-import ELynx.Tools+import qualified Data.Set as S+import Data.Vector.Generic+ ( Vector,+ toList,+ )+import qualified Data.Vector.Generic as V+import ELynx.Data.Alphabet.Alphabet+import ELynx.Data.Alphabet.Character+import ELynx.Tools -- | Entropy of vector. entropy :: (Vector v Double) => v Double -> Double-entropy v = if isNaN res- then error- ("entropy: Sesult of following vector is NaN: " ++ show (toList v) ++ ".")- else res- where res = negate $ sumVec $ V.map xLogX v+entropy v =+ if isNaN res+ then+ error+ ("entropy: Sesult of following vector is NaN: " ++ show (toList v) ++ ".")+ else res+ where+ res = negate $ sumVec $ V.map xLogX v -- | Effective number of used characters measured using 'entropy'. The result -- only makes sense when the sum of the array is 1.0.@@ -64,19 +66,21 @@ -- Increment element at index in vector by one. incrementElemIndexByOne :: Vector v Int => [Int] -> v Int -> v Int incrementElemIndexByOne is v = v V.// zip is es'- where es' = [ v V.! i + 1 | i <- is ]+ where+ es' = [v V.! i + 1 | i <- is] -- For a given code and counts vector, increment the count of the given character. acc :: Vector v Int => AlphabetSpec -> v Int -> Character -> v Int acc alph vec char = incrementElemIndexByOne is vec- where is = [ S.findIndex c (std alph) | c <- toStd alph char ]+ where+ is = [S.findIndex c (std alph) | c <- toStd alph char] -countCharacters- :: (Vector v Character, Vector v Int) => AlphabetSpec -> v Character -> v Int+countCharacters ::+ (Vector v Character, Vector v Int) => AlphabetSpec -> v Character -> v Int countCharacters alph = V.foldl' (acc alph) zeroCounts- where- nChars = length (std alph)- zeroCounts = V.replicate nChars (0 :: Int)+ where+ nChars = length (std alph)+ zeroCounts = V.replicate nChars (0 :: Int) saveDivision :: Int -> Int -> Double saveDivision value divisor =@@ -86,12 +90,12 @@ -- The input vector has arbitrary length (most often the number of sequences in -- an alignment), the length of the output vector is the number of characters in -- the alphabet.-frequencyCharacters- :: (Vector v Character, Vector v Int, Vector v Double)- => AlphabetSpec- -> v Character- -> v Double+frequencyCharacters ::+ (Vector v Character, Vector v Int, Vector v Double) =>+ AlphabetSpec ->+ v Character ->+ v Double frequencyCharacters alph d = V.map (`saveDivision` s) counts- where- counts = countCharacters alph d- s = sumVec counts+ where+ counts = countCharacters alph d+ s = sumVec counts
src/ELynx/Data/Character/AminoAcid.hs view
@@ -1,61 +1,56 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.AminoAcid-Description : Amino acid related types and functions-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.--Amino acids in alphabetical order.--@-Amino Acid Code: Three letter Code: Amino Acid:----------------- ------------------ ------------A Ala Alanine-C Cys Cysteine-D Asp Aspartic Acid-E Glu Glutamic Acid-F Phe Phenylalanine-G Gly Glycine-H His Histidine-I Ile Isoleucine-K Lys Lysine-L Leu Leucine-M Met Methionine-N Asn Asparagine-P Pro Proline-Q Gln Glutamine-R Arg Arginine-S Ser Serine-T Thr Threonine-V Val Valine-W Trp Tryptophan-Y Tyr Tyrosine-@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.AminoAcid+-- Description : Amino acid related types and functions+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- Amino acids in alphabetical order.+--+-- @+-- Amino Acid Code: Three letter Code: Amino Acid:+-- ---------------- ------------------ -----------+-- A Ala Alanine+-- C Cys Cysteine+-- D Asp Aspartic Acid+-- E Glu Glutamic Acid+-- F Phe Phenylalanine+-- G Gly Glycine+-- H His Histidine+-- I Ile Isoleucine+-- K Lys Lysine+-- L Leu Leucine+-- M Met Methionine+-- N Asn Asparagine+-- P Pro Proline+-- Q Gln Glutamine+-- R Arg Arginine+-- S Ser Serine+-- T Thr Threonine+-- V Val Valine+-- W Trp Tryptophan+-- Y Tyr Tyrosine+-- @ module ELynx.Data.Character.AminoAcid- ( AminoAcid(..)+ ( AminoAcid (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Amino acids. data AminoAcid = A | C | D | E | F | G | H | I | K | L | M | N | P | Q | R | S | T | V | W | Y@@ -105,13 +100,14 @@ 'V' -> V 'W' -> W 'Y' -> Y- _ -> error "fromWord: Cannot convert to AminoAcid."+ _ -> error "fromWord: Cannot convert to AminoAcid." -derivingUnbox "AminoAcid"- [t| AminoAcid -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "AminoAcid"+ [t|AminoAcid -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character AminoAcid where- toWord = toWord+ toWord = toWord fromWord = fromWord
src/ELynx/Data/Character/AminoAcidI.hs view
@@ -1,109 +1,135 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.AminoAcid-Description : Amino acid related types and functions-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.--Amino acid IUPAC code. See also https://www.bioinformatics.org/sms/iupac.html or-https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.--@-Amino Acid Code: Three letter Code: Amino Acid:----------------- ------------------ ------------A Ala Alanine-C Cys Cysteine-D Asp Aspartic Acid-E Glu Glutamic Acid-F Phe Phenylalanine-G Gly Glycine-H His Histidine-I Ile Isoleucine-K Lys Lysine-L Leu Leucine-M Met Methionine-N Asn Asparagine-P Pro Proline-Q Gln Glutamine-R Arg Arginine-S Ser Serine-T Thr Threonine-V Val Valine-W Trp Tryptophan-Y Tyr Tyrosine-------------------J Leucine or Isoleucine-B Asx Aspartic acid or Asparagine-Z Glx Glutamine or Glutamic acid-------------------X Xaa Any amino acid-------------------* Stp No amino acid-------------------- Gap No amino acid-. Gap No amino acid-@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.AminoAcid+-- Description : Amino acid related types and functions+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- Amino acid IUPAC code. See also https://www.bioinformatics.org/sms/iupac.html or+-- https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.+--+-- Remarks:+--+-- - Question marks (@?@) are interpreted as unknowns (same as @X@). However, when+-- a sequence is printed/exported, @X@s will be used.+--+-- - Full stops (@.@) are interpreted as gaps (same as @-@). However, when a+-- sequence is printed/exported, @-@s will be used+--+-- @+-- Amino Acid Code: Three letter Code: Amino Acid:+-- ---------------- ------------------ -----------+-- A Ala Alanine+-- C Cys Cysteine+-- D Asp Aspartic Acid+-- E Glu Glutamic Acid+-- F Phe Phenylalanine+-- G Gly Glycine+-- H His Histidine+-- I Ile Isoleucine+-- K Lys Lysine+-- L Leu Leucine+-- M Met Methionine+-- N Asn Asparagine+-- P Pro Proline+-- Q Gln Glutamine+-- R Arg Arginine+-- S Ser Serine+-- T Thr Threonine+-- V Val Valine+-- W Trp Tryptophan+-- Y Tyr Tyrosine+-- ---------------- ------------------ -----------+-- J Leucine or Isoleucine+-- B Asx Aspartic acid or Asparagine+-- Z Glx Glutamine or Glutamic acid+-- ---------------- ------------------ -----------+-- X Xaa Any amino acid (preferred; used for printing)+-- ? Xaa Any amino acid+-- ---------------- ------------------ -----------+-- * Stp No amino acid+-- ---------------- ------------------ -----------+-- - Gap No amino acid (preferred; used for printing)+-- . Gap No amino acid+-- @ module ELynx.Data.Character.AminoAcidI- ( AminoAcidI(..)+ ( AminoAcidI (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Amino acids.-data AminoAcidI = A | C | D | E | F | G | H | I | K | L | M | N | P | Q | R | S | T | V | W | Y- | J | B | Z- | X- | Stop- | Gap+data AminoAcidI+ = A+ | C+ | D+ | E+ | F+ | G+ | H+ | I+ | K+ | L+ | M+ | N+ | P+ | Q+ | R+ | S+ | T+ | V+ | W+ | Y+ | J+ | B+ | Z+ | X+ | Stop+ | Gap deriving (Show, Read, Eq, Ord, Enum, Bounded) toWord :: AminoAcidI -> Word8-toWord A = c2w 'A'-toWord C = c2w 'C'-toWord D = c2w 'D'-toWord E = c2w 'E'-toWord F = c2w 'F'-toWord G = c2w 'G'-toWord H = c2w 'H'-toWord I = c2w 'I'-toWord K = c2w 'K'-toWord L = c2w 'L'-toWord M = c2w 'M'-toWord N = c2w 'N'-toWord P = c2w 'P'-toWord Q = c2w 'Q'-toWord R = c2w 'R'-toWord S = c2w 'S'-toWord T = c2w 'T'-toWord V = c2w 'V'-toWord W = c2w 'W'-toWord Y = c2w 'Y'-toWord J = c2w 'J'-toWord B = c2w 'B'-toWord Z = c2w 'Z'-toWord X = c2w 'X'+toWord A = c2w 'A'+toWord C = c2w 'C'+toWord D = c2w 'D'+toWord E = c2w 'E'+toWord F = c2w 'F'+toWord G = c2w 'G'+toWord H = c2w 'H'+toWord I = c2w 'I'+toWord K = c2w 'K'+toWord L = c2w 'L'+toWord M = c2w 'M'+toWord N = c2w 'N'+toWord P = c2w 'P'+toWord Q = c2w 'Q'+toWord R = c2w 'R'+toWord S = c2w 'S'+toWord T = c2w 'T'+toWord V = c2w 'V'+toWord W = c2w 'W'+toWord Y = c2w 'Y'+toWord J = c2w 'J'+toWord B = c2w 'B'+toWord Z = c2w 'Z'+toWord X = c2w 'X' toWord Stop = c2w '*'-toWord Gap = c2w '-'+toWord Gap = c2w '-' fromWord :: Word8 -> AminoAcidI fromWord w = case w2c w of@@ -131,52 +157,56 @@ 'B' -> B 'Z' -> Z 'X' -> X+ -- Question marks code for @X@s.+ '?' -> X '*' -> Stop '-' -> Gap+ -- Full stops code for gaps (@-@s). '.' -> Gap- _ -> error "fromWord: Cannot convert Word8 to AminoAcidI"+ _ -> error "fromWord: Cannot convert Word8 to AminoAcidI" -derivingUnbox "AminoAcidI"- [t| AminoAcidI -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "AminoAcidI"+ [t|AminoAcidI -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character AminoAcidI where- toWord = toWord+ toWord = toWord fromWord = fromWord instance C.CharacterX AminoAcidI where gap = Gap toStandard :: AminoAcidI -> [AminoAcidI]-toStandard A = [A]-toStandard C = [C]-toStandard D = [D]-toStandard E = [E]-toStandard F = [F]-toStandard G = [G]-toStandard H = [H]-toStandard I = [I]-toStandard K = [K]-toStandard L = [L]-toStandard M = [M]-toStandard N = [N]-toStandard P = [P]-toStandard Q = [Q]-toStandard R = [R]-toStandard S = [S]-toStandard T = [T]-toStandard V = [V]-toStandard W = [W]-toStandard Y = [Y]-toStandard J = [L, I]-toStandard B = [D, N]-toStandard Z = [E, Q]-toStandard X = [A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y]+toStandard A = [A]+toStandard C = [C]+toStandard D = [D]+toStandard E = [E]+toStandard F = [F]+toStandard G = [G]+toStandard H = [H]+toStandard I = [I]+toStandard K = [K]+toStandard L = [L]+toStandard M = [M]+toStandard N = [N]+toStandard P = [P]+toStandard Q = [Q]+toStandard R = [R]+toStandard S = [S]+toStandard T = [T]+toStandard V = [V]+toStandard W = [W]+toStandard Y = [Y]+toStandard J = [L, I]+toStandard B = [D, N]+toStandard Z = [E, Q]+toStandard X = [A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y] toStandard Stop = []-toStandard Gap = []+toStandard Gap = [] instance C.CharacterI AminoAcidI where- unknown = X- iupac = [J, B, Z, X]+ unknown = X+ iupac = [J, B, Z, X] toStandard = toStandard
src/ELynx/Data/Character/AminoAcidS.hs view
@@ -1,96 +1,111 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.AminoAcid-Description : Amino acid related types and functions-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.--Amino acids with gaps and translation stops.--@-Amino Acid Code: Three letter Code: Amino Acid:----------------- ------------------ ------------A Ala Alanine-C Cys Cysteine-D Asp Aspartic Acid-E Glu Glutamic Acid-F Phe Phenylalanine-G Gly Glycine-H His Histidine-I Ile Isoleucine-K Lys Lysine-L Leu Leucine-M Met Methionine-N Asn Asparagine-P Pro Proline-Q Gln Glutamine-R Arg Arginine-S Ser Serine-T Thr Threonine-V Val Valine-W Trp Tryptophan-Y Tyr Tyrosine-------------------* Stp No amino acid-------------------- Gap No amino acid-. Gap No amino acid-@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.AminoAcid+-- Description : Amino acid related types and functions+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- Amino acids with gaps and translation stops.+--+-- @+-- Amino Acid Code: Three letter Code: Amino Acid:+-- ---------------- ------------------ -----------+-- A Ala Alanine+-- C Cys Cysteine+-- D Asp Aspartic Acid+-- E Glu Glutamic Acid+-- F Phe Phenylalanine+-- G Gly Glycine+-- H His Histidine+-- I Ile Isoleucine+-- K Lys Lysine+-- L Leu Leucine+-- M Met Methionine+-- N Asn Asparagine+-- P Pro Proline+-- Q Gln Glutamine+-- R Arg Arginine+-- S Ser Serine+-- T Thr Threonine+-- V Val Valine+-- W Trp Tryptophan+-- Y Tyr Tyrosine+-- ---------------- ------------------ -----------+-- * Stp No amino acid+-- ---------------- ------------------ -----------+-- - Gap No amino acid (preferred)+-- . Gap No amino acid+-- @ module ELynx.Data.Character.AminoAcidS- ( AminoAcidS(..)+ ( AminoAcidS (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Amino acids.-data AminoAcidS = A | C | D | E | F | G | H | I | K | L | M | N | P | Q | R | S | T | V | W | Y- | Stop- | Gap+data AminoAcidS+ = A+ | C+ | D+ | E+ | F+ | G+ | H+ | I+ | K+ | L+ | M+ | N+ | P+ | Q+ | R+ | S+ | T+ | V+ | W+ | Y+ | Stop+ | Gap deriving (Show, Read, Eq, Ord, Enum, Bounded) toWord :: AminoAcidS -> Word8-toWord A = c2w 'A'-toWord C = c2w 'C'-toWord D = c2w 'D'-toWord E = c2w 'E'-toWord F = c2w 'F'-toWord G = c2w 'G'-toWord H = c2w 'H'-toWord I = c2w 'I'-toWord K = c2w 'K'-toWord L = c2w 'L'-toWord M = c2w 'M'-toWord N = c2w 'N'-toWord P = c2w 'P'-toWord Q = c2w 'Q'-toWord R = c2w 'R'-toWord S = c2w 'S'-toWord T = c2w 'T'-toWord V = c2w 'V'-toWord W = c2w 'W'-toWord Y = c2w 'Y'+toWord A = c2w 'A'+toWord C = c2w 'C'+toWord D = c2w 'D'+toWord E = c2w 'E'+toWord F = c2w 'F'+toWord G = c2w 'G'+toWord H = c2w 'H'+toWord I = c2w 'I'+toWord K = c2w 'K'+toWord L = c2w 'L'+toWord M = c2w 'M'+toWord N = c2w 'N'+toWord P = c2w 'P'+toWord Q = c2w 'Q'+toWord R = c2w 'R'+toWord S = c2w 'S'+toWord T = c2w 'T'+toWord V = c2w 'V'+toWord W = c2w 'W'+toWord Y = c2w 'Y' toWord Stop = c2w '*'-toWord Gap = c2w '-'+toWord Gap = c2w '-' fromWord :: Word8 -> AminoAcidS fromWord w = case w2c w of@@ -117,15 +132,16 @@ '*' -> Stop '-' -> Gap '.' -> Gap- _ -> error "fromWord: Cannot convert to AminoAcidS."+ _ -> error "fromWord: Cannot convert to AminoAcidS." -derivingUnbox "AminoAcidS"- [t| AminoAcidS -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "AminoAcidS"+ [t|AminoAcidS -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character AminoAcidS where- toWord = toWord+ toWord = toWord fromWord = fromWord instance C.CharacterX AminoAcidS where
src/ELynx/Data/Character/AminoAcidX.hs view
@@ -1,93 +1,108 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.AminoAcid-Description : Amino acid related types and functions-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.--Extended amino acid with gaps. See also-https://www.bioinformatics.org/sms/iupac.html or-https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.--@-Amino Acid Code: Three letter Code: Amino Acid:----------------- ------------------ ------------A Ala Alanine-C Cys Cysteine-D Asp Aspartic Acid-E Glu Glutamic Acid-F Phe Phenylalanine-G Gly Glycine-H His Histidine-I Ile Isoleucine-K Lys Lysine-L Leu Leucine-M Met Methionine-N Asn Asparagine-P Pro Proline-Q Gln Glutamine-R Arg Arginine-S Ser Serine-T Thr Threonine-V Val Valine-W Trp Tryptophan-Y Tyr Tyrosine-------------------- Gap No amino acid-. Gap No amino acid-@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.AminoAcid+-- Description : Amino acid related types and functions+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- Extended amino acid with gaps. See also+-- https://www.bioinformatics.org/sms/iupac.html or+-- https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.+--+-- @+-- Amino Acid Code: Three letter Code: Amino Acid:+-- ---------------- ------------------ -----------+-- A Ala Alanine+-- C Cys Cysteine+-- D Asp Aspartic Acid+-- E Glu Glutamic Acid+-- F Phe Phenylalanine+-- G Gly Glycine+-- H His Histidine+-- I Ile Isoleucine+-- K Lys Lysine+-- L Leu Leucine+-- M Met Methionine+-- N Asn Asparagine+-- P Pro Proline+-- Q Gln Glutamine+-- R Arg Arginine+-- S Ser Serine+-- T Thr Threonine+-- V Val Valine+-- W Trp Tryptophan+-- Y Tyr Tyrosine+-- ---------------- ------------------ -----------+-- - Gap No amino acid+-- . Gap No amino acid+-- @ module ELynx.Data.Character.AminoAcidX- ( AminoAcidX(..)+ ( AminoAcidX (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Amino acids.-data AminoAcidX = A | C | D | E | F | G | H | I | K | L | M | N | P | Q | R | S | T | V | W | Y- | Gap+data AminoAcidX+ = A+ | C+ | D+ | E+ | F+ | G+ | H+ | I+ | K+ | L+ | M+ | N+ | P+ | Q+ | R+ | S+ | T+ | V+ | W+ | Y+ | Gap deriving (Show, Read, Eq, Ord, Enum, Bounded) toWord :: AminoAcidX -> Word8-toWord A = c2w 'A'-toWord C = c2w 'C'-toWord D = c2w 'D'-toWord E = c2w 'E'-toWord F = c2w 'F'-toWord G = c2w 'G'-toWord H = c2w 'H'-toWord I = c2w 'I'-toWord K = c2w 'K'-toWord L = c2w 'L'-toWord M = c2w 'M'-toWord N = c2w 'N'-toWord P = c2w 'P'-toWord Q = c2w 'Q'-toWord R = c2w 'R'-toWord S = c2w 'S'-toWord T = c2w 'T'-toWord V = c2w 'V'-toWord W = c2w 'W'-toWord Y = c2w 'Y'+toWord A = c2w 'A'+toWord C = c2w 'C'+toWord D = c2w 'D'+toWord E = c2w 'E'+toWord F = c2w 'F'+toWord G = c2w 'G'+toWord H = c2w 'H'+toWord I = c2w 'I'+toWord K = c2w 'K'+toWord L = c2w 'L'+toWord M = c2w 'M'+toWord N = c2w 'N'+toWord P = c2w 'P'+toWord Q = c2w 'Q'+toWord R = c2w 'R'+toWord S = c2w 'S'+toWord T = c2w 'T'+toWord V = c2w 'V'+toWord W = c2w 'W'+toWord Y = c2w 'Y' toWord Gap = c2w '-' fromWord :: Word8 -> AminoAcidX@@ -114,15 +129,16 @@ 'Y' -> Y '-' -> Gap '.' -> Gap- _ -> error "fromWord: Cannot convert to AminoAcidX."+ _ -> error "fromWord: Cannot convert to AminoAcidX." -derivingUnbox "AminoAcidX"- [t| AminoAcidX -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "AminoAcidX"+ [t|AminoAcidX -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character AminoAcidX where- toWord = toWord+ toWord = toWord fromWord = fromWord instance C.CharacterX AminoAcidX where
src/ELynx/Data/Character/Character.hs view
@@ -1,48 +1,46 @@-{- |-Module : Character-Description : Character interface-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Oct 12 16:24:02 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.---}-+-- |+-- Module : Character+-- Description : Character interface+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Oct 12 16:24:02 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'. module ELynx.Data.Character.Character- ( Character(..)- , fromChar- , toChar- , fromString- , toString- , CharacterX(..)- , isGap- , CharacterI(..)- , isUnknown- , isIUPAC- , isStandard- , convert+ ( Character (..),+ fromChar,+ toChar,+ fromString,+ toString,+ CharacterX (..),+ isGap,+ CharacterI (..),+ isUnknown,+ isIUPAC,+ isStandard,+ convert, ) where -import qualified Data.Set as S-import Data.Vector.Unboxed.Base ( Unbox )-import Data.Word8 ( Word8 )--import ELynx.Tools+import qualified Data.Set as S+import Data.Vector.Unboxed.Base (Unbox)+import Data.Word8 (Word8)+import ELynx.Tools -- XXX: Remove name clash with ELynx.Data.Alphabet.Alphabet.Character?+ -- | A set of characters forms an 'ELynx.Data.Alphabet.Alphabet'. At the -- moment, 'Word8' is used, since none of the alphabets has more than 255 -- characters. class (Show a, Read a, Eq a, Ord a, Enum a, Bounded a, Unbox a) => Character a where -- | Write characters.- toWord :: a -> Word8+ toWord :: a -> Word8+ -- | Read characters. fromWord :: Word8 -> a @@ -64,7 +62,7 @@ -- | An extended character type with gaps and unknowns. class Character a => CharacterX a where- gap :: a+ gap :: a -- | Is the character a gap or unknown? isGap :: CharacterX a => a -> Bool@@ -72,8 +70,8 @@ -- | IUPAC characters with a mapping to extended characters. class CharacterX a => CharacterI a where- unknown :: a- iupac :: [a]+ unknown :: a+ iupac :: [a] toStandard :: a -> [a] -- | Check if a IUPAC 'CharacterI' is unknown (e.g., N for nucleotides).
src/ELynx/Data/Character/Codon.hs view
@@ -1,53 +1,45 @@ {-# LANGUAGE DeriveGeneric #-} -{- |-Module : ELynx.Data.Character.Codon-Description : Codons are triplets of nucleotides-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu May 16 07:58:50 2019.--The different universal codes.-- https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c-- http://www.bioinformatics.org/sms2/genetic_code.html-- https://en.wikipedia.org/wiki/Genetic_code---}-+-- |+-- Module : ELynx.Data.Character.Codon+-- Description : Codons are triplets of nucleotides+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu May 16 07:58:50 2019.+--+-- The different universal codes.+-- - https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi?mode=c+-- - http://www.bioinformatics.org/sms2/genetic_code.html+-- - https://en.wikipedia.org/wiki/Genetic_code module ELynx.Data.Character.Codon- ( Codon(Codon)- , unsafeFromVec- , UniversalCode(..)- , translate- , translateX- , translateI+ ( Codon (Codon),+ unsafeFromVec,+ UniversalCode (..),+ translate,+ translateX,+ translateI, ) where -import Data.Aeson ( FromJSON- , ToJSON- )-import Data.List-import GHC.Generics ( Generic )-import qualified Data.Map as M-import qualified Data.Vector.Generic as V--import qualified ELynx.Data.Character.AminoAcidI- as AI-import ELynx.Data.Character.AminoAcidS-import qualified ELynx.Data.Character.Character- as C-import qualified ELynx.Data.Character.Nucleotide- as N-import qualified ELynx.Data.Character.NucleotideI- as NI-import qualified ELynx.Data.Character.NucleotideX- as NX+import Data.Aeson+ ( FromJSON,+ ToJSON,+ )+import Data.List+import qualified Data.Map as M+import qualified Data.Vector.Generic as V+import qualified ELynx.Data.Character.AminoAcidI as AI+import ELynx.Data.Character.AminoAcidS+import qualified ELynx.Data.Character.Character as C+import qualified ELynx.Data.Character.Nucleotide as N+import qualified ELynx.Data.Character.NucleotideI as NI+import qualified ELynx.Data.Character.NucleotideX as NX+import GHC.Generics (Generic) -- | Codons are triplets of characters. newtype Codon a = Codon (a, a, a)@@ -76,155 +68,158 @@ M.fromList $ zipWith4 (\f s t a -> (Codon (f, s, t), a)) xs ys zs as nucs :: Enum a => [a]-nucs = map toEnum [3, 1, 0, 2] -- Order T, C, A , G.+nucs = map toEnum [3, 1, 0, 2] -- Order T, C, A , G. -- Permutation of the triplets PLUS GAPS! I avoid 'Z' because I do not want to -- translate DNAI. base1, base2, base3 :: Enum a => [a]-base1 = [ n | n <- nucs, _ <- [0 .. 3 :: Int], _ <- [0 .. 3 :: Int] ]+base1 = [n | n <- nucs, _ <- [0 .. 3 :: Int], _ <- [0 .. 3 :: Int]] -- base1 = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG" ++ "-."-base2 = [ n | _ <- [0 .. 3 :: Int], n <- nucs, _ <- [0 .. 3 :: Int] ]+base2 = [n | _ <- [0 .. 3 :: Int], n <- nucs, _ <- [0 .. 3 :: Int]] -- base2 = "TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG" ++ "-."-base3 = [ n | _ <- [0 .. 3 :: Int], _ <- [0 .. 3 :: Int], n <- nucs ]+base3 = [n | _ <- [0 .. 3 :: Int], _ <- [0 .. 3 :: Int], n <- nucs]+ -- base3 = "TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG" ++ "-." -- The actual codes. standard :: [AminoAcidS] standard =- [ F- , F- , L- , L- , S- , S- , S- , S- , Y- , Y- , Stop- , Stop- , C- , C- , Stop- , W- , L- , L- , L- , L- , P- , P- , P- , P- , H- , H- , Q- , Q- , R- , R- , R- , R- , I- , I- , I- , M- , T- , T- , T- , T- , N- , N- , K- , K- , S- , S- , R- , R- , V- , V- , V- , V- , A- , A- , A- , A- , D- , D- , E- , E- , G- , G- , G- , G+ [ F,+ F,+ L,+ L,+ S,+ S,+ S,+ S,+ Y,+ Y,+ Stop,+ Stop,+ C,+ C,+ Stop,+ W,+ L,+ L,+ L,+ L,+ P,+ P,+ P,+ P,+ H,+ H,+ Q,+ Q,+ R,+ R,+ R,+ R,+ I,+ I,+ I,+ M,+ T,+ T,+ T,+ T,+ N,+ N,+ K,+ K,+ S,+ S,+ R,+ R,+ V,+ V,+ V,+ V,+ A,+ A,+ A,+ A,+ D,+ D,+ E,+ E,+ G,+ G,+ G,+ G ]+ -- "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG" ++ "--" vertebrateMitochondrial :: [AminoAcidS] vertebrateMitochondrial =- [ F- , F- , L- , L- , S- , S- , S- , S- , Y- , Y- , Stop- , Stop- , C- , C- , W- , W- , L- , L- , L- , L- , P- , P- , P- , P- , H- , H- , Q- , Q- , R- , R- , R- , R- , I- , I- , M- , M- , T- , T- , T- , T- , N- , N- , K- , K- , S- , S- , Stop- , Stop- , V- , V- , V- , V- , A- , A- , A- , A- , D- , D- , E- , E- , G- , G- , G- , G+ [ F,+ F,+ L,+ L,+ S,+ S,+ S,+ S,+ Y,+ Y,+ Stop,+ Stop,+ C,+ C,+ W,+ W,+ L,+ L,+ L,+ L,+ P,+ P,+ P,+ P,+ H,+ H,+ Q,+ Q,+ R,+ R,+ R,+ R,+ I,+ I,+ M,+ M,+ T,+ T,+ T,+ T,+ N,+ N,+ K,+ K,+ S,+ S,+ Stop,+ Stop,+ V,+ V,+ V,+ V,+ A,+ A,+ A,+ A,+ D,+ D,+ E,+ E,+ G,+ G,+ G,+ G ]+ -- "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG" ++ "--" -- | Translate a codon to amino acids including translation stops.@@ -249,6 +244,7 @@ translateI code codon@(Codon (x, y, z)) | C.isIUPAC x || C.isIUPAC y || C.isIUPAC z = AI.X | otherwise = C.convert . translateX code . convert $ codon+ -- translateI :: UniversalCode -> Codon NI.NucleotideI -> AI.AminoAcidI -- translateI _ (Codon (NI.N, _, _ )) = AI.X -- translateI _ (Codon (_ , NI.N, _ )) = AI.X
src/ELynx/Data/Character/Nucleotide.hs view
@@ -1,43 +1,38 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.Nucleotide-Description : Nucleotides-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.--See header of 'ELynx.Data.Alphabet.Alphabet'.--@-Symbol Description Bases represented Complement------- ----------- ----------------- -----------A Adenine A T-C Cytosine C G-G Guanine G C-T Thymine T A-@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.Nucleotide+-- Description : Nucleotides+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- @+-- Symbol Description Bases represented Complement+-- ------ ----------- ----------------- ----------+-- A Adenine A T+-- C Cytosine C G+-- G Guanine G C+-- T Thymine T A+-- @ module ELynx.Data.Character.Nucleotide- ( Nucleotide(..)+ ( Nucleotide (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Nucleotides. data Nucleotide = A | C | G | T@@ -59,13 +54,14 @@ 'C' -> C 'G' -> G 'T' -> T- c -> error $ "fromWord: Cannot convert " ++ show c ++ " to Nucleotide."+ c -> error $ "fromWord: Cannot convert " ++ show c ++ " to Nucleotide." -derivingUnbox "Nucleotide"- [t| Nucleotide -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "Nucleotide"+ [t|Nucleotide -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character Nucleotide where- toWord = toWord+ toWord = toWord fromWord = fromWord
src/ELynx/Data/Character/NucleotideI.hs view
@@ -1,69 +1,87 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.NucleotideI-Description : Nucleotides with IUPAC characters-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Thu Oct 4 18:26:35 2018.---See header of 'ELynx.Data.Alphabet.Alphabet'.--Nucleotide IUPAC code. See also https://www.bioinformatics.org/sms/iupac.html or-https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.--@-Symbol Description Bases represented Complement------- ----------- ----------------- -----------A Adenine A T-C Cytosine C G-G Guanine G C-T Thymine T A------- ----------- ----------------- -----------U Uracil U A-W Weak A T W-S Strong C G S-M aMino A C K-K Keto G T M-R puRine A G Y-Y pYrimidine C T R-B not A C G T V-D not C A G T H-H not G A C T D-V not T A C G B------- ----------- ----------------- -----------N any A C G T N------- ----------- ----------------- ------------ or . Gap (Zero) --@---}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.NucleotideI+-- Description : Nucleotides with IUPAC characters+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:26:35 2018.+--+-- See header of 'ELynx.Data.Alphabet.Alphabet'.+--+-- Nucleotide IUPAC code. See also https://www.bioinformatics.org/sms/iupac.html or+-- https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.+--+-- Remarks:+--+-- - Question marks (@?@) are interpreted as unknowns (same as @N@). However, when+-- a sequence is printed/exported, @N@s will be used.+--+-- - Full stops (@.@) are interpreted as gaps (same as @-@). However, when a+-- sequence is printed/exported, @-@s will be used+--+-- @+-- Symbol Description Bases represented Complement+-- ------ ----------- ----------------- ----------+-- A Adenine A T+-- C Cytosine C G+-- G Guanine G C+-- T Thymine T A+-- ------ ----------- ----------------- ----------+-- U Uracil U A+-- W Weak A T W+-- S Strong C G S+-- M aMino A C K+-- K Keto G T M+-- R puRine A G Y+-- Y pYrimidine C T R+-- B not A C G T V+-- D not C A G T H+-- H not G A C T D+-- V not T A C G B+-- ------ ----------- ----------------- ----------+-- N any A C G T N (preferred)+-- ? any A C G T N+-- ------ ----------- ----------------- ----------+-- - Gap (Zero) - (preferred)+-- . Gap (Zero) -+-- @ module ELynx.Data.Character.NucleotideI- ( NucleotideI(..)+ ( NucleotideI (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | NucleotideIs.-data NucleotideI = A | C | G | T- | U | W | S | M | K | R | Y | B | D | H | V- | N- | Gap+data NucleotideI+ = A+ | C+ | G+ | T+ | U+ | W+ | S+ | M+ | K+ | R+ | Y+ | B+ | D+ | H+ | V+ | N+ | Gap deriving (Show, Read, Eq, Ord, Enum, Bounded) -- See https://stackoverflow.com/a/31527024; apparently, pattern matching (and@@ -71,22 +89,22 @@ -- they are faster than guards (because equality has to be checked), and faster -- than lookups with sets. toWord :: NucleotideI -> Word8-toWord A = c2w 'A'-toWord C = c2w 'C'-toWord G = c2w 'G'-toWord T = c2w 'T'-toWord U = c2w 'U'-toWord W = c2w 'W'-toWord S = c2w 'S'-toWord M = c2w 'M'-toWord K = c2w 'K'-toWord R = c2w 'R'-toWord Y = c2w 'Y'-toWord B = c2w 'B'-toWord D = c2w 'D'-toWord H = c2w 'H'-toWord V = c2w 'V'-toWord N = c2w 'N'+toWord A = c2w 'A'+toWord C = c2w 'C'+toWord G = c2w 'G'+toWord T = c2w 'T'+toWord U = c2w 'U'+toWord W = c2w 'W'+toWord S = c2w 'S'+toWord M = c2w 'M'+toWord K = c2w 'K'+toWord R = c2w 'R'+toWord Y = c2w 'Y'+toWord B = c2w 'B'+toWord D = c2w 'D'+toWord H = c2w 'H'+toWord V = c2w 'V'+toWord N = c2w 'N' toWord Gap = c2w '-' fromWord :: Word8 -> NucleotideI@@ -107,42 +125,44 @@ 'H' -> H 'V' -> V 'N' -> N+ '?' -> N '-' -> Gap '.' -> Gap- _ -> error "fromWord: Cannot convert to NucleotideI."+ _ -> error "fromWord: Cannot convert to NucleotideI." -derivingUnbox "NucleotideI"- [t| NucleotideI -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "NucleotideI"+ [t|NucleotideI -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character NucleotideI where- toWord = toWord+ toWord = toWord fromWord = fromWord toStandard :: NucleotideI -> [NucleotideI]-toStandard A = [A]-toStandard C = [C]-toStandard G = [G]-toStandard T = [T]-toStandard U = [T]-toStandard W = [A, T]-toStandard S = [G, C]-toStandard M = [A, C]-toStandard K = [G, T]-toStandard R = [A, G]-toStandard Y = [C, T]-toStandard B = [C, G, T]-toStandard D = [A, G, T]-toStandard H = [A, C, T]-toStandard V = [A, C, G]-toStandard N = [A, C, G, T]+toStandard A = [A]+toStandard C = [C]+toStandard G = [G]+toStandard T = [T]+toStandard U = [T]+toStandard W = [A, T]+toStandard S = [G, C]+toStandard M = [A, C]+toStandard K = [G, T]+toStandard R = [A, G]+toStandard Y = [C, T]+toStandard B = [C, G, T]+toStandard D = [A, G, T]+toStandard H = [A, C, T]+toStandard V = [A, C, G]+toStandard N = [A, C, G, T] toStandard Gap = [] instance C.CharacterX NucleotideI where gap = Gap instance C.CharacterI NucleotideI where- unknown = N- iupac = [U, W, S, M, K, R, Y, B, D, H, V, N]+ unknown = N+ iupac = [U, W, S, M, K, R, Y, B, D, H, V, N] toStandard = toStandard
src/ELynx/Data/Character/NucleotideX.hs view
@@ -1,60 +1,58 @@ {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}--{- |-Module : ELynx.Data.NucleotideX-Description : Extended nucleotides including gaps and unknowns-Copyright : (c) Dominik Schrempf 2018--License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--See header of 'ELynx.Data.Alphabet'.--Extended nucleotides with gaps. See also-https://www.bioinformatics.org/sms/iupac.html or-https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.--@-Symbol Description Bases represented Complement------- ----------- ----------------- -----------A Adenine A T-C Cytosine C G-G Guanine G C-T Thymine T A------- ----------- ----------------- ------------ or . Gap (Zero) --@----}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} +-- |+-- Module : ELynx.Data.NucleotideX+-- Description : Extended nucleotides including gaps and unknowns+-- Copyright : (c) Dominik Schrempf 2018+--+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- See header of 'ELynx.Data.Alphabet'.+--+-- Extended nucleotides with gaps. See also+-- https://www.bioinformatics.org/sms/iupac.html or+-- https://en.wikipedia.org/wiki/International_Union_of_Pure_and_Applied_Chemistry.+--+-- @+-- Symbol Description Bases represented Complement+-- ------ ----------- ----------------- ----------+-- A Adenine A T+-- C Cytosine C G+-- G Guanine G C+-- T Thymine T A+-- ------ ----------- ----------------- ----------+-- - or . Gap (Zero) -+-- @ module ELynx.Data.Character.NucleotideX- ( NucleotideX(..)+ ( NucleotideX (..), ) where -import Data.Vector.Unboxed.Deriving-import Data.Word8--import qualified ELynx.Data.Character.Character- as C-import ELynx.Tools+import Data.Vector.Unboxed.Deriving+import Data.Word8+import qualified ELynx.Data.Character.Character as C+import ELynx.Tools -- | Extended nucleotides.-data NucleotideX = A | C | G | T- | Gap+data NucleotideX+ = A+ | C+ | G+ | T+ | Gap deriving (Show, Read, Eq, Ord, Enum, Bounded) toWord :: NucleotideX -> Word8-toWord A = c2w 'A'-toWord C = c2w 'C'-toWord G = c2w 'G'-toWord T = c2w 'T'+toWord A = c2w 'A'+toWord C = c2w 'C'+toWord G = c2w 'G'+toWord T = c2w 'T' toWord Gap = c2w '-' fromWord :: Word8 -> NucleotideX@@ -65,15 +63,16 @@ 'T' -> T '-' -> Gap '.' -> Gap- c -> error $ "fromWord: Cannot convert " ++ show c ++ " to NucleotideX."+ c -> error $ "fromWord: Cannot convert " ++ show c ++ " to NucleotideX." -derivingUnbox "NucleotideX"- [t| NucleotideX -> Word8 |]- [| toWord |]- [| fromWord |]+derivingUnbox+ "NucleotideX"+ [t|NucleotideX -> Word8|]+ [|toWord|]+ [|fromWord|] instance C.Character NucleotideX where- toWord = toWord+ toWord = toWord fromWord = fromWord instance C.CharacterX NucleotideX where
src/ELynx/Data/Sequence/Alignment.hs view
@@ -1,79 +1,75 @@-{- |-Module : ELynx.Data.Sequence.Alignment-Description : Multi sequence alignment related types and functions-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable--Portability : portable--Creation date: Thu Oct 4 18:40:18 2018.--This module is to be imported qualified.---}--+-- |+-- Module : ELynx.Data.Sequence.Alignment+-- Description : Multi sequence alignment related types and functions+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+--+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:40:18 2018.+--+-- This module is to be imported qualified. module ELynx.Data.Sequence.Alignment- ( Alignment(..)- , length- , nSequences- -- | * Input, output- , fromSequences- , toSequences- , summarize- -- | * Manipulation- , join- , concat- , concatAlignments- , filterColsOnlyStd- , filterColsStd- , filterColsNoGaps- -- | * Analysis- , FrequencyData- , distribution- , toFrequencyData- , kEffEntropy- , kEffHomoplasy- , countIUPACChars- , countGaps- , countUnknowns- -- | * Sub sample- , subSample- , randomSubSample+ ( Alignment (..),+ length,+ nSequences,+ -- | * Input, output+ fromSequences,+ toSequences,+ summarize,+ -- | * Manipulation+ join,+ concat,+ concatAlignments,+ filterColsOnlyStd,+ filterColsStd,+ filterColsNoGaps,+ -- | * Analysis+ FrequencyData,+ distribution,+ toFrequencyData,+ kEffEntropy,+ kEffHomoplasy,+ countIUPACChars,+ countGaps,+ countUnknowns,+ -- | * Sub sample+ subSample,+ randomSubSample, ) where -import Control.Monad hiding ( join )-import Control.Monad.Primitive-import qualified Data.ByteString.Lazy.Char8 as L-import Data.List hiding ( concat- , length- )-import qualified Data.Matrix.Unboxed as M-import qualified Data.Vector.Unboxed as V-import Prelude hiding ( concat- , length- )-import System.Random.MWC--import qualified ELynx.Data.Alphabet.Alphabet as A-import ELynx.Data.Alphabet.Character-import qualified ELynx.Data.Alphabet.DistributionDiversity- as D-import ELynx.Data.Sequence.Defaults-import qualified ELynx.Data.Sequence.Sequence as S-import ELynx.Tools+import Control.Monad hiding (join)+import Control.Monad.Primitive+import qualified Data.ByteString.Lazy.Char8 as L+import Data.List hiding+ ( concat,+ length,+ )+import qualified Data.Matrix.Unboxed as M+import qualified Data.Vector.Unboxed as V+import qualified ELynx.Data.Alphabet.Alphabet as A+import ELynx.Data.Alphabet.Character+import qualified ELynx.Data.Alphabet.DistributionDiversity as D+import ELynx.Data.Sequence.Defaults+import qualified ELynx.Data.Sequence.Sequence as S+import ELynx.Tools+import System.Random.MWC+import Prelude hiding+ ( concat,+ length,+ ) -- | A collection of sequences. data Alignment = Alignment- { names :: [S.Name]- , descriptions :: [S.Description]- , alphabet :: A.Alphabet- , matrix :: M.Matrix Character- }+ { names :: [S.Name],+ descriptions :: [S.Description],+ alphabet :: A.Alphabet,+ matrix :: M.Matrix Character+ } deriving (Show, Eq) -- | Number of sites.@@ -87,24 +83,28 @@ -- | Create 'Alignment' from a list of 'S.Sequence's. fromSequences :: [S.Sequence] -> Either String Alignment fromSequences ss- | S.equalLength ss && allEqual (map S.alphabet ss) = Right- $ Alignment ns ds a d+ | S.equalLength ss && allEqual (map S.alphabet ss) =+ Right $+ Alignment ns ds a d | S.equalLength ss = Left "Sequences do not have equal codes." | otherwise = Left "Sequences do not have equal lengths."- where- ns = map S.name ss- ds = map S.description ss- a = S.alphabet $ head ss- bss = map S.characters ss- d = M.fromRows bss+ where+ ns = map S.name ss+ ds = map S.description ss+ a = S.alphabet $ head ss+ bss = map S.characters ss+ d = M.fromRows bss -- | Conversion to list of 'S.Sequence's. toSequences :: Alignment -> [S.Sequence]-toSequences (Alignment ns ds a da) = zipWith3 (\n d r -> S.Sequence n d a r)- ns- ds- rows- where rows = M.toRows da+toSequences (Alignment ns ds a da) =+ zipWith3+ (\n d r -> S.Sequence n d a r)+ ns+ ds+ rows+ where+ rows = M.toRows da -- -- | Show a 'Alignment', untrimmed. -- summarizeSeq :: Alignment -> Int -> L.ByteString@@ -115,29 +115,29 @@ header :: Alignment -> L.ByteString header a =- L.unlines- $ [ L.pack "Multi sequence alignment."- , L.pack $ "Code: " ++ A.alphabetDescription (alphabet a) ++ "."- , L.pack $ "Length: " ++ show (length a) ++ "."- ]- ++ reportLengthSummary- ++ reportNumberSummary- where- reportLengthSummary =- [ L.pack- $ "For each sequence, the "- ++ show summaryLength- ++ " first bases are shown."- | length a > summaryLength- ]- reportNumberSummary =- [ L.pack- $ show summaryNSequences- ++ " out of "- ++ show (nSequences a)- ++ " sequences are shown."- | nSequences a > summaryNSequences+ L.unlines $+ [ L.pack "Multi sequence alignment.",+ L.pack $ "Code: " ++ A.alphabetDescription (alphabet a) ++ ".",+ L.pack $ "Length: " ++ show (length a) ++ "." ]+ ++ reportLengthSummary+ ++ reportNumberSummary+ where+ reportLengthSummary =+ [ L.pack $+ "For each sequence, the "+ ++ show summaryLength+ ++ " first bases are shown."+ | length a > summaryLength+ ]+ reportNumberSummary =+ [ L.pack $+ show summaryNSequences+ ++ " out of "+ ++ show (nSequences a)+ ++ " sequences are shown."+ | nSequences a > summaryNSequences+ ] -- | Similar to 'S.summarizeSequenceList' but with different Header. summarize :: Alignment -> L.ByteString@@ -148,49 +148,52 @@ join :: Alignment -> Alignment -> Alignment -- top bottom. join t b- | length t /= length b = error- "join: Multi sequence alignments do not have equal lengths."- | alphabet t /= alphabet b = error- "join: Multi sequence alignments do not have equal alphabets."+ | length t /= length b =+ error+ "join: Multi sequence alignments do not have equal lengths."+ | alphabet t /= alphabet b =+ error+ "join: Multi sequence alignments do not have equal alphabets." | otherwise = Alignment ns ds al (tD === bD)- where- ns = names t ++ names b- ds = descriptions t ++ descriptions b- tD = matrix t- bD = matrix b- al = alphabet t+ where+ ns = names t ++ names b+ ds = descriptions t ++ descriptions b+ tD = matrix t+ bD = matrix b+ al = alphabet t -- | Concatenate two 'Alignment's horizontally. That is, add more -- sites to an alignment. See also 'join'. concat :: Alignment -> Alignment -> Alignment -- left right. concat l r- | nSequences l /= nSequences r- = error- "concat: Multi sequence alignments do not have an equal number of sequences."- | alphabet l /= alphabet r- = error "concat: Multi sequence alignments do not have an equal alphabets."- | names l /= names r- = error "concat: Multi sequence alignments do not have an equal names."- | descriptions l /= descriptions r- = error "concat: Multi sequence alignments do not have an equal descriptions."- | otherwise- = Alignment (names l) (descriptions l) (alphabet l) (lD ||| rD)- where- lD = matrix l- rD = matrix r+ | nSequences l /= nSequences r =+ error+ "concat: Multi sequence alignments do not have an equal number of sequences."+ | alphabet l /= alphabet r =+ error "concat: Multi sequence alignments do not have an equal alphabets."+ | names l /= names r =+ error "concat: Multi sequence alignments do not have an equal names."+ | descriptions l /= descriptions r =+ error "concat: Multi sequence alignments do not have an equal descriptions."+ | otherwise =+ Alignment (names l) (descriptions l) (alphabet l) (lD ||| rD)+ where+ lD = matrix l+ rD = matrix r -- | Concatenate a list of 'Alignment's horizontally. See -- 'concat'. concatAlignments :: [Alignment] -> Alignment-concatAlignments [] = error "concatAlignments: Nothing to concatenate."+concatAlignments [] = error "concatAlignments: Nothing to concatenate." concatAlignments [a] = a-concatAlignments as = foldl' concat (head as) (tail as)+concatAlignments as = foldl' concat (head as) (tail as) -- Only keep columns from alignment that satisfy given predicate. filterColsWith :: (V.Vector Character -> Bool) -> Alignment -> Alignment-filterColsWith p a = a { matrix = m' }- where m' = M.fromColumns . filter p . M.toColumns $ matrix a+filterColsWith p a = a {matrix = m'}+ where+ m' = M.fromColumns . filter p . M.toColumns $ matrix a -- | Only keep columns with standard characters. Alignment columns with IUPAC -- characters are removed.@@ -199,12 +202,13 @@ -- | Filter columns with proportion of standard character larger than given number. filterColsStd :: Double -> Alignment -> Alignment-filterColsStd prop a = filterColsWith- (\col -> prop * n <= fromIntegral (V.length (V.filter (A.isStd al) col)))- a- where- al = alphabet a- n = fromIntegral $ nSequences a+filterColsStd prop a =+ filterColsWith+ (\col -> prop * n <= fromIntegral (V.length (V.filter (A.isStd al) col)))+ a+ where+ al = alphabet a+ n = fromIntegral $ nSequences a -- | Only keep columns without gaps or unknown characters. filterColsNoGaps :: Alignment -> Alignment@@ -218,14 +222,19 @@ -- | Calculcate frequency of characters at each site of a multi sequence alignment. toFrequencyData :: Alignment -> FrequencyData toFrequencyData a = fMapColParChunk 100 (D.frequencyCharacters spec) (matrix a)- where spec = A.alphabetSpec (alphabet a)+ where+ spec = A.alphabetSpec (alphabet a) -- | Calculate the distribution of characters. distribution :: FrequencyData -> [Double]-distribution fd = map (/ fromIntegral nSites) $ V.toList $ foldl1- (V.zipWith (+))- (M.toColumns fd)- where nSites = M.cols fd+distribution fd =+ map (/ fromIntegral nSites) $+ V.toList $+ foldl1+ (V.zipWith (+))+ (M.toColumns fd)+ where+ nSites = M.cols fd -- | Diversity analysis. See 'kEffEntropy'. kEffEntropy :: FrequencyData -> [Double]@@ -239,25 +248,28 @@ -- alignment. countIUPACChars :: Alignment -> Int countIUPACChars a = V.length . V.filter (A.isIUPAC (alphabet a)) $ allChars- where allChars = M.flatten $ matrix a+ where+ allChars = M.flatten $ matrix a -- | Count the number of gaps in the alignment. countGaps :: Alignment -> Int countGaps a = V.length . V.filter (A.isGap (alphabet a)) $ allChars- where allChars = M.flatten $ matrix a+ where+ allChars = M.flatten $ matrix a -- | Count the number of unknown characters in the alignment. countUnknowns :: Alignment -> Int countUnknowns a = V.length . V.filter (A.isUnknown (alphabet a)) $ allChars- where allChars = M.flatten $ matrix a+ where+ allChars = M.flatten $ matrix a -- | Sample the given sites from a multi sequence alignment. subSample :: [Int] -> Alignment -> Alignment-subSample is a = a { matrix = m' } where m' = subSampleMatrix is $ matrix a+subSample is a = a {matrix = m'} where m' = subSampleMatrix is $ matrix a -- | Randomly sample a given number of sites of the multi sequence alignment.-randomSubSample- :: PrimMonad m => Int -> Alignment -> Gen (PrimState m) -> m Alignment+randomSubSample ::+ PrimMonad m => Int -> Alignment -> Gen (PrimState m) -> m Alignment randomSubSample n a g = do let l = length a is <- replicateM n $ uniformR (0, l - 1) g
src/ELynx/Data/Sequence/Defaults.hs view
@@ -1,23 +1,19 @@-{- |-Module : ELynx.Defaults-Description : Various default values-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Oct 5 23:00:17 2018.---}--+-- |+-- Module : ELynx.Defaults+-- Description : Various default values+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Oct 5 23:00:17 2018. module ELynx.Data.Sequence.Defaults- ( nameWidth- , summaryLength- , summaryNSequences- , fieldWidth+ ( nameWidth,+ summaryLength,+ summaryNSequences,+ fieldWidth, ) where
src/ELynx/Data/Sequence/Sequence.hs view
@@ -1,66 +1,69 @@ {-# LANGUAGE OverloadedStrings #-} -{- |-Module : ELynx.Data.Sequence-Description : Hereditary sequences-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later+-- |+-- Module : ELynx.Data.Sequence+-- Description : Hereditary sequences+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Thu Oct 4 18:54:51 2018.+--+-- This module is to be imported qualified.+module ELynx.Data.Sequence.Sequence+ ( -- * Types+ Name,+ Description,+ Characters,+ Sequence (..), -Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable+ -- * Input+ fromByteString, -Creation date: Thu Oct 4 18:54:51 2018.+ -- * Output+ toByteString,+ header,+ summarize,+ summarizeSequences,+ body, -This module is to be imported qualified.+ -- * Analysis+ length,+ equalLength,+ longest, --}+ -- * Manipulation+ trim,+ concat,+ concatSequences, -module ELynx.Data.Sequence.Sequence- ( -- * Types- Name- , Description- , Characters- , Sequence(..)- -- * Input- , fromByteString- -- * Output- , toByteString- , header- , summarize- , summarizeSequences- , body- -- * Analysis- , length- , equalLength- , longest- -- * Manipulation- , trim- , concat- , concatSequences- -- * Filtering- , filterShorterThan- , filterLongerThan- , filterStandard+ -- * Filtering+ filterShorterThan,+ filterLongerThan,+ filterStandard, ) where -import Control.Parallel.Strategies-import qualified Data.ByteString.Lazy.Char8 as L-import Data.List ( maximumBy )-import Data.Ord ( comparing )-import qualified Data.Vector.Unboxed as V-import Prelude hiding ( concat- , length- )-import qualified Prelude as Pr- ( length )-import qualified Text.Printf as P--import qualified ELynx.Data.Alphabet.Alphabet as A-import ELynx.Data.Alphabet.Character-import ELynx.Data.Sequence.Defaults-import ELynx.Tools+import Control.Parallel.Strategies+import qualified Data.ByteString.Lazy.Char8 as L+import Data.List (maximumBy)+import Data.Ord (comparing)+import qualified Data.Vector.Unboxed as V+import qualified ELynx.Data.Alphabet.Alphabet as A+import ELynx.Data.Alphabet.Character+import ELynx.Data.Sequence.Defaults+import ELynx.Tools+import qualified Text.Printf as P+import Prelude hiding+ ( concat,+ length,+ )+import qualified Prelude as Pr+ ( length,+ ) -- | For now, 'Name's are just 'L.ByteString's. type Name = L.ByteString@@ -81,28 +84,32 @@ -- | Sequences have a name, a possibly empty description, a code and hopefully a -- lot of data.-data Sequence = Sequence { name :: Name- , description :: Description- , alphabet :: A.Alphabet- , characters :: Characters }+data Sequence = Sequence+ { name :: Name,+ description :: Description,+ alphabet :: A.Alphabet,+ characters :: Characters+ } deriving (Show, Eq) getInfo :: Sequence -> L.ByteString-getInfo s = L.unwords- [ alignLeft nameWidth (name s)- , alignRight fieldWidth (L.pack $ show $ alphabet s)- , alignRight fieldWidth (L.pack . show $ len)- , alignRight fieldWidth (L.pack $ P.printf "%2.2f" pGaps)- ]- where- len = length s- nGaps = countGaps s- pGaps = 100 * fromIntegral nGaps / fromIntegral len :: Double+getInfo s =+ L.unwords+ [ alignLeft nameWidth (name s),+ alignRight fieldWidth (L.pack $ show $ alphabet s),+ alignRight fieldWidth (L.pack . show $ len),+ alignRight fieldWidth (L.pack $ P.printf "%2.2f" pGaps)+ ]+ where+ len = length s+ nGaps = countGaps s+ pGaps = 100 * fromIntegral nGaps / fromIntegral len :: Double -- | Trim and show a 'Sequence'. summarize :: Sequence -> L.ByteString-summarize s = L.unwords- [getInfo s, summarizeByteString summaryLength $ toByteString (characters s)]+summarize s =+ L.unwords+ [getInfo s, summarizeByteString summaryLength $ toByteString (characters s)] -- | Trim and show a list of 'Sequence's. summarizeSequences :: [Sequence] -> L.ByteString@@ -110,36 +117,38 @@ -- | Header printed before 'Sequence' list. tableHeader :: L.ByteString-tableHeader = L.unwords- [ alignLeft nameWidth "Name"- , alignRight fieldWidth "Code"- , alignRight fieldWidth "Length"- , alignRight fieldWidth "Gaps [%]"- , "Sequence"- ]+tableHeader =+ L.unwords+ [ alignLeft nameWidth "Name",+ alignRight fieldWidth "Code",+ alignRight fieldWidth "Length",+ alignRight fieldWidth "Gaps [%]",+ "Sequence"+ ] -- | A short description of the sequence. header :: [Sequence] -> L.ByteString header ss =- L.unlines- $ reportIfSubsetIsShown- ++ [ L.pack- $ "For each sequence, the "- ++ show summaryLength- ++ " first bases are shown."- , L.pack $ "List contains " ++ show (Pr.length ss) ++ " sequences."- , ""- , tableHeader- ]- where- l = Pr.length ss- s =- show summaryNSequences- ++ " out of "- ++ show (Pr.length ss)- ++ " sequences are shown."- reportIfSubsetIsShown | l > summaryNSequences = [L.pack s]- | otherwise = []+ L.unlines $+ reportIfSubsetIsShown+ ++ [ L.pack $+ "For each sequence, the "+ ++ show summaryLength+ ++ " first bases are shown.",+ L.pack $ "List contains " ++ show (Pr.length ss) ++ " sequences.",+ "",+ tableHeader+ ]+ where+ l = Pr.length ss+ s =+ show summaryNSequences+ ++ " out of "+ ++ show (Pr.length ss)+ ++ " sequences are shown."+ reportIfSubsetIsShown+ | l > summaryNSequences = [L.pack s]+ | otherwise = [] -- | Trim and show a list of 'Sequence's. body :: [Sequence] -> L.ByteString@@ -168,35 +177,35 @@ -- | Concatenate two sequences. 'Name's have to match. concat :: Sequence -> Sequence -> Sequence concat (Sequence i d c cs) (Sequence j f k ks)- | i /= j- = error- $ "concatenate: Sequences do not have equal names: "- ++ L.unpack i- ++ ", "- ++ L.unpack j- ++ "."- | d /= f- = error- $ "concatenate: Sequences do not have equal descriptions: "- ++ L.unpack d- ++ ", "- ++ L.unpack f- ++ "."- | c /= k- = error- $ "concatenate: Sequences do not have equal alphabets: "- ++ show c- ++ ", "- ++ show k- ++ "."- | otherwise- = Sequence i d c (cs <> ks)+ | i /= j =+ error $+ "concatenate: Sequences do not have equal names: "+ ++ L.unpack i+ ++ ", "+ ++ L.unpack j+ ++ "."+ | d /= f =+ error $+ "concatenate: Sequences do not have equal descriptions: "+ ++ L.unpack d+ ++ ", "+ ++ L.unpack f+ ++ "."+ | c /= k =+ error $+ "concatenate: Sequences do not have equal alphabets: "+ ++ show c+ ++ ", "+ ++ show k+ ++ "."+ | otherwise =+ Sequence i d c (cs <> ks) -- | Concatenate a list of sequences, see 'concat'. concatSequences :: [[Sequence]] -> [Sequence]-concatSequences [] = error "concatenateSequences: Nothing to concatenate."+concatSequences [] = error "concatenateSequences: Nothing to concatenate." concatSequences [ss] = ss-concatSequences sss = foldl1 (zipWith concat) sss+concatSequences sss = foldl1 (zipWith concat) sss -- | Only take 'Sequence's that are shorter than a given number. filterShorterThan :: Int -> [Sequence] -> [Sequence]
src/ELynx/Data/Sequence/Translate.hs view
@@ -1,50 +1,47 @@-{- |-Module : ELynx.Data.Sequence.Translate-Description : Translate sequences-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri May 17 13:49:18 2019.---}-+-- |+-- Module : ELynx.Data.Sequence.Translate+-- Description : Translate sequences+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri May 17 13:49:18 2019. module ELynx.Data.Sequence.Translate- ( translateSeq+ ( translateSeq, ) where -import qualified Data.Vector.Unboxed as V--import ELynx.Data.Alphabet.Alphabet+import qualified Data.Vector.Unboxed as V+import ELynx.Data.Alphabet.Alphabet import qualified ELynx.Data.Alphabet.Character as C-import ELynx.Data.Character.Codon-import ELynx.Data.Sequence.Sequence-import ELynx.Tools+import ELynx.Data.Character.Codon+import ELynx.Data.Sequence.Sequence+import ELynx.Tools -- | Translate a sequence from 'DNA' or 'DNAX' to 'ProteinS'. translateSeq :: UniversalCode -> Int -> Sequence -> Sequence translateSeq uc rf (Sequence n d a cs) = case a of- DNA -> Sequence n d ProteinS (cs' $ translate uc)+ DNA -> Sequence n d ProteinS (cs' $ translate uc) DNAX -> Sequence n d ProteinS (cs' $ translateX uc) DNAI -> Sequence n d ProteinI (cs' $ translateI uc)- _ -> error "translate: can only translate DNA, DNAX, and DNAI."- where cs' f = C.fromCVec $ translateVecWith f rf (C.toCVec cs)+ _ -> error "translate: can only translate DNA, DNAX, and DNAI."+ where+ cs' f = C.fromCVec $ translateVecWith f rf (C.toCVec cs) -- Translate from DNA to Protein with given reading frame (0, 1, 2).-translateVecWith- :: (V.Unbox a, Ord a, V.Unbox b)- => (Codon a -> b)- -> Int- -> V.Vector a- -> V.Vector b+translateVecWith ::+ (V.Unbox a, Ord a, V.Unbox b) =>+ (Codon a -> b) ->+ Int ->+ V.Vector a ->+ V.Vector b translateVecWith f rf cs- | rf > 2 = error "translateVecWith: reading frame is larger than 2."- | rf < 0 = error "translateVecWith: reading frame is negative."+ | rf > 2 = error "translateVecWith: reading frame is larger than 2."+ | rf < 0 = error "translateVecWith: reading frame is negative." | otherwise = aas- where- codons = map unsafeFromVec $ chopVec 3 $ V.drop rf cs- aas = V.fromList $ map f codons+ where+ codons = map unsafeFromVec $ chopVec 3 $ V.drop rf cs+ aas = V.fromList $ map f codons
src/ELynx/Export/Sequence/Fasta.hs view
@@ -1,30 +1,25 @@-{- |-Module : ELynx.Export.Sequence.Fasta-Description : Export Fasta sequences-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later---Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Write FASTA files.--[NCBI file specifications](https://blast.ncbi.nlm.nih.gov/Blast.cgi?CMD=Web&PAGE_TYPE=BlastDocs&DOC_TYPE=BlastHelp).---}--+-- |+-- Module : ELynx.Export.Sequence.Fasta+-- Description : Export Fasta sequences+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Write FASTA files.+--+-- [NCBI file specifications](https://blast.ncbi.nlm.nih.gov/Blast.cgi?CMD=Web&PAGE_TYPE=BlastDocs&DOC_TYPE=BlastHelp). module ELynx.Export.Sequence.Fasta- ( sequenceToFasta- , sequencesToFasta+ ( sequenceToFasta,+ sequencesToFasta, ) where -import qualified Data.ByteString.Lazy.Char8 as L--import ELynx.Data.Sequence.Sequence+import qualified Data.ByteString.Lazy.Char8 as L+import ELynx.Data.Sequence.Sequence fastaHeader :: L.ByteString -> L.ByteString -> L.ByteString fastaHeader n d =
src/ELynx/Import/Sequence/Fasta.hs view
@@ -1,45 +1,42 @@ {-# LANGUAGE BangPatterns #-} -{- |-Module : ELynx.Import.Sequence.Fasta-Description : Import Fasta sequences-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later---Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Parse FASTA files.--[NCBI file specifications](https://blast.ncbi.nlm.nih.gov/Blast.cgi?CMD=Web&PAGE_TYPE=BlastDocs&DOC_TYPE=BlastHelp).--For more complicated parsers, try to use a [lexer](https://hackage.haskell.org/package/megaparsec-7.0.1/docs/Text-Megaparsec-Byte-Lexer.html).--}--+-- |+-- Module : ELynx.Import.Sequence.Fasta+-- Description : Import Fasta sequences+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Parse FASTA files.+--+-- [NCBI file specifications](https://blast.ncbi.nlm.nih.gov/Blast.cgi?CMD=Web&PAGE_TYPE=BlastDocs&DOC_TYPE=BlastHelp).+--+-- For more complicated parsers, try to use a [lexer](https://hackage.haskell.org/package/megaparsec-7.0.1/docs/Text-Megaparsec-Byte-Lexer.html). module ELynx.Import.Sequence.Fasta- ( Parser- , fastaSequence- , fasta+ ( Parser,+ fastaSequence,+ fasta, ) where -import Control.Monad-import qualified Data.ByteString.Lazy.Char8 as L-import qualified Data.Set as S-import Data.Void-import Data.Word8 ( Word8- , isAlphaNum- )-import Text.Megaparsec-import Text.Megaparsec.Byte--import ELynx.Data.Alphabet.Alphabet as A-import ELynx.Data.Alphabet.Character-import ELynx.Data.Sequence.Sequence-import ELynx.Tools+import Control.Monad+import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.Set as S+import Data.Void+import Data.Word8+ ( Word8,+ isAlphaNum,+ )+import ELynx.Data.Alphabet.Alphabet as A+import ELynx.Data.Alphabet.Character+import ELynx.Data.Sequence.Sequence+import ELynx.Tools+import Text.Megaparsec+import Text.Megaparsec.Byte -- | Shortcut. type Parser = Parsec Void L.ByteString@@ -66,9 +63,9 @@ -- this set only has to be calculcated once per sequence in 'fastaSequence'. sequenceLine :: S.Set Word8 -> Parser L.ByteString sequenceLine s = do- -- FIXME: Will fail for non-capital letters.+ -- XXX: Will fail for non-capital letters. !xs <- takeWhile1P (Just "Alphabet character") (`S.member` s)- _ <- void eol <|> eof+ _ <- void eol <|> eof return xs -- XXX: If sequences are parsed line by line, the lines have to be copied when@@ -80,7 +77,7 @@ (n, d) <- sequenceHeader let !alph = S.map toWord (A.all . alphabetSpec $ a) lns <- some (sequenceLine alph)- _ <- many eol+ _ <- many eol return $ Sequence n d a (fromByteString $ L.concat lns) -- | Parse a Fasta file with given 'Alphabet'.
test/ELynx/Data/Alphabet/DistributionDiversitySpec.hs view
@@ -1,26 +1,22 @@-{- |-Module : ELynx.Data.Alphabet.DistributionDiversitySpec-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Mon Feb 25 13:41:12 2019.---}-+-- |+-- Module : ELynx.Data.Alphabet.DistributionDiversitySpec+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Mon Feb 25 13:41:12 2019. module ELynx.Data.Alphabet.DistributionDiversitySpec- ( spec+ ( spec, ) where -import qualified Data.Vector.Unboxed as V-import Test.Hspec--import ELynx.Data.Alphabet.DistributionDiversity-import ELynx.Tools+import qualified Data.Vector.Unboxed as V+import ELynx.Data.Alphabet.DistributionDiversity+import ELynx.Tools+import Test.Hspec testArr1 :: V.Vector Double testArr1 = V.replicate 20 0.0@@ -34,28 +30,25 @@ spec :: Spec spec = do- describe "entropy" $ it "calculates entropy of vectors" $ do- entropy testArr1 `shouldBe` 0.0- entropy testArr2 `shouldBe` 0.0- entropy testArr3 `shouldSatisfy` nearlyEq 0.9773805948045555-- describe "kEffEntropy"- $ it "calculates the effective number of used states using entropy"- $ do+ describe "entropy" $+ it "calculates entropy of vectors" $ do+ entropy testArr1 `shouldBe` 0.0+ entropy testArr2 `shouldBe` 0.0+ entropy testArr3 `shouldSatisfy` nearlyEq 0.9773805948045555+ describe "kEffEntropy" $+ it "calculates the effective number of used states using entropy" $+ do kEffEntropy testArr1 `shouldBe` 1.0 kEffEntropy testArr2 `shouldBe` 1.0 kEffEntropy testArr3 `shouldSatisfy` nearlyEq 2.6574860842252765-- describe "homoplasy" $ it "calculates homoplasy of vectors" $ do- homoplasy testArr1 `shouldBe` 0.0- homoplasy testArr2 `shouldBe` 1.0- homoplasy testArr3 `shouldSatisfy` nearlyEq 0.74-- describe "kEffHomoplasy"- $ it "calculates the effective number of used states using homoplasy"- $ do+ describe "homoplasy" $+ it "calculates homoplasy of vectors" $ do+ homoplasy testArr1 `shouldBe` 0.0+ homoplasy testArr2 `shouldBe` 1.0+ homoplasy testArr3 `shouldSatisfy` nearlyEq 0.74+ describe "kEffHomoplasy" $+ it "calculates the effective number of used states using homoplasy" $+ do kEffHomoplasy testArr1 `shouldSatisfy` isInfinite kEffHomoplasy testArr2 `shouldBe` 1.0 kEffHomoplasy testArr3 `shouldSatisfy` nearlyEq 1.3513513513513513--
test/ELynx/Data/Sequence/AlignmentSpec.hs view
@@ -1,30 +1,26 @@-{- |-Module : ELynx.Data.Sequence.AlignmentSpec-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Oct 5 14:25:42 2018.---}-+-- |+-- Module : ELynx.Data.Sequence.AlignmentSpec+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Oct 5 14:25:42 2018. module ELynx.Data.Sequence.AlignmentSpec- ( spec+ ( spec, ) where -import qualified Data.ByteString.Lazy.Char8 as L-import qualified Data.Matrix.Unboxed as M-import Test.Hspec--import ELynx.Data.Alphabet.Alphabet-import ELynx.Data.Alphabet.Character-import ELynx.Data.Sequence.Alignment-import ELynx.Import.Sequence.Fasta-import ELynx.Tools+import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.Matrix.Unboxed as M+import ELynx.Data.Alphabet.Alphabet+import ELynx.Data.Alphabet.Character+import ELynx.Data.Sequence.Alignment+import ELynx.Import.Sequence.Fasta+import ELynx.Tools+import Test.Hspec fastaNucleotideIUPACFN :: FilePath fastaNucleotideIUPACFN = "data/NucleotideIUPAC.fasta"@@ -33,16 +29,19 @@ ssData = M.fromLists $ map (reverse . map fromChar) ["AAA", "GAA", "TAA"] ssA :: Alignment-ssA = Alignment (map L.pack ["SEQUENCE_1", "SEQUENCE_2", "SEQUENCE_3"])- (replicate 3 L.empty)- DNAI- ssData+ssA =+ Alignment+ (map L.pack ["SEQUENCE_1", "SEQUENCE_2", "SEQUENCE_3"])+ (replicate 3 L.empty)+ DNAI+ ssData spec :: Spec-spec = describe "subSample" $ it "correctly sub sample an Alignment" $ do- a <-- either error id- . fromSequences- <$> parseFileWith (fasta DNAI) fastaNucleotideIUPACFN- let ss = subSample [0, 3, 5] a- ss `shouldBe` ssA+spec = describe "subSample" $+ it "correctly sub sample an Alignment" $ do+ a <-+ either error id+ . fromSequences+ <$> parseFileWith (fasta DNAI) fastaNucleotideIUPACFN+ let ss = subSample [0, 3, 5] a+ ss `shouldBe` ssA
test/ELynx/Data/Sequence/SequenceSpec.hs view
@@ -1,28 +1,24 @@-{- |-Module : ELynx.Data.Sequence.SequenceSpec-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Oct 5 14:25:42 2018.---}-+-- |+-- Module : ELynx.Data.Sequence.SequenceSpec+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Oct 5 14:25:42 2018. module ELynx.Data.Sequence.SequenceSpec- ( spec+ ( spec, ) where -import qualified Data.ByteString.Lazy.Char8 as L-import Test.Hspec--import ELynx.Data.Alphabet.Alphabet-import ELynx.Data.Sequence.Sequence-import ELynx.Import.Sequence.Fasta-import ELynx.Tools+import qualified Data.ByteString.Lazy.Char8 as L+import ELynx.Data.Alphabet.Alphabet+import ELynx.Data.Sequence.Sequence+import ELynx.Import.Sequence.Fasta+import ELynx.Tools+import Test.Hspec fastaDifferentLengthFN :: FilePath fastaDifferentLengthFN = "data/NucleotideDifferentLength.fasta"@@ -31,23 +27,26 @@ fastaDifferentLengthTrimmedFN = "data/NucleotideDifferentLengthTrimmed.fasta" longestSequenceInFileBS :: L.ByteString-longestSequenceInFileBS = L.unlines- $ map L.pack [">SEQUENCE_3", "ATTTAAAAAAACCCAAAACCCGGGCCCCGGGTTTTTTTA"]+longestSequenceInFileBS =+ L.unlines $+ map L.pack [">SEQUENCE_3", "ATTTAAAAAAACCCAAAACCCGGGCCCCGGGTTTTTTTA"] longestSequenceInFile :: Sequence-longestSequenceInFile = parseByteStringWith "Fasta byte string"- (fastaSequence DNA)- longestSequenceInFileBS+longestSequenceInFile =+ parseByteStringWith+ "Fasta byte string"+ (fastaSequence DNA)+ longestSequenceInFileBS spec :: Spec spec = do- describe "longest" $ it "finds the longest sequence" $ do- ss <- parseFileWith (fasta DNA) fastaDifferentLengthFN- longest ss `shouldBe` longestSequenceInFile-- describe "filterLongerThan"- $ it "filters sequences that are longer than a specified length"- $ do- ss <- parseFileWith (fasta DNA) fastaDifferentLengthFN+ describe "longest" $+ it "finds the longest sequence" $ do+ ss <- parseFileWith (fasta DNA) fastaDifferentLengthFN+ longest ss `shouldBe` longestSequenceInFile+ describe "filterLongerThan" $+ it "filters sequences that are longer than a specified length" $+ do+ ss <- parseFileWith (fasta DNA) fastaDifferentLengthFN ss' <- parseFileWith (fasta DNA) fastaDifferentLengthTrimmedFN filterLongerThan 10 ss `shouldBe` ss'
test/ELynx/Data/Sequence/TranslateSpec.hs view
@@ -1,28 +1,24 @@-{- |-Module : ELynx.Data.Sequence.TranslateSpec-Copyright : (c) Dominik Schrempf 2018-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Oct 5 14:25:42 2018.---}-+-- |+-- Module : ELynx.Data.Sequence.TranslateSpec+-- Copyright : (c) Dominik Schrempf 2018+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Oct 5 14:25:42 2018. module ELynx.Data.Sequence.TranslateSpec- ( spec+ ( spec, ) where -import Test.Hspec--import ELynx.Data.Alphabet.Alphabet-import ELynx.Data.Character.Codon-import ELynx.Data.Sequence.Translate-import ELynx.Import.Sequence.Fasta-import ELynx.Tools+import ELynx.Data.Alphabet.Alphabet+import ELynx.Data.Character.Codon+import ELynx.Data.Sequence.Translate+import ELynx.Import.Sequence.Fasta+import ELynx.Tools+import Test.Hspec fastaTranslateDNAFN :: FilePath fastaTranslateDNAFN = "data/TranslateMitochondrialVertebrateDNA.fasta"@@ -32,7 +28,8 @@ spec :: Spec spec =- describe "translateDNAX" $ it "correctly translates a test sequence" $ do- ss <- parseFileWith (fasta DNAX) fastaTranslateDNAFN- ss' <- parseFileWith (fasta ProteinS) fastaTranslateProteinFN- map (translateSeq VertebrateMitochondrial 0) ss `shouldBe` ss'+ describe "translateDNAX" $+ it "correctly translates a test sequence" $ do+ ss <- parseFileWith (fasta DNAX) fastaTranslateDNAFN+ ss' <- parseFileWith (fasta ProteinS) fastaTranslateProteinFN+ map (translateSeq VertebrateMitochondrial 0) ss `shouldBe` ss'
test/ELynx/Export/Sequence/FastaSpec.hs view
@@ -1,41 +1,38 @@-{- |-Module : ELynx.Export.Sequence.FastaSpec-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Jan 18 09:59:57 2019.---}-+-- |+-- Module : ELynx.Export.Sequence.FastaSpec+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Jan 18 09:59:57 2019. module ELynx.Export.Sequence.FastaSpec- ( spec+ ( spec, ) where -import Test.Hspec--import ELynx.Data.Alphabet.Alphabet-import ELynx.Export.Sequence.Fasta-import ELynx.Import.Sequence.Fasta-import ELynx.Tools+import ELynx.Data.Alphabet.Alphabet+import ELynx.Export.Sequence.Fasta+import ELynx.Import.Sequence.Fasta+import ELynx.Tools+import Test.Hspec fastaNucleotideIUPACFN :: FilePath fastaNucleotideIUPACFN = "data/NucleotideIUPAC.fasta" spec :: Spec spec =- describe "sequencesToFasta"- $ it- "should create a fasta bytestring that, when parsed again, is the original sequence"- $ do+ describe "sequencesToFasta" $+ it+ "should create a fasta bytestring that, when parsed again, is the original sequence"+ $ do ss <- parseFileWith (fasta DNAI) fastaNucleotideIUPACFN- let f = sequencesToFasta ss- ss' = parseByteStringWith- "Fasta byte string created from sequence object"- (fasta DNAI)- f+ let f = sequencesToFasta ss+ ss' =+ parseByteStringWith+ "Fasta byte string created from sequence object"+ (fasta DNAI)+ f ss `shouldBe` ss'
test/ELynx/Import/Sequence/FastaSpec.hs view
@@ -1,28 +1,24 @@-{- |-Module : ELynx.Import.Sequence.FastaSpec-Copyright : (c) Dominik Schrempf 2020-License : GPL-3.0-or-later--Maintainer : dominik.schrempf@gmail.com-Stability : unstable-Portability : portable--Creation date: Fri Jan 18 09:54:38 2019.---}-+-- |+-- Module : ELynx.Import.Sequence.FastaSpec+-- Copyright : (c) Dominik Schrempf 2020+-- License : GPL-3.0-or-later+--+-- Maintainer : dominik.schrempf@gmail.com+-- Stability : unstable+-- Portability : portable+--+-- Creation date: Fri Jan 18 09:54:38 2019. module ELynx.Import.Sequence.FastaSpec- ( spec+ ( spec, ) where -import Data.Either-import Test.Hspec--import ELynx.Data.Alphabet.Alphabet+import Data.Either+import ELynx.Data.Alphabet.Alphabet import qualified ELynx.Data.Sequence.Alignment as M-import ELynx.Import.Sequence.Fasta-import ELynx.Tools+import ELynx.Import.Sequence.Fasta+import ELynx.Tools+import Test.Hspec fastaNucleotideFN :: FilePath fastaNucleotideFN = "data/Nucleotide.fasta"@@ -41,33 +37,28 @@ it "parses a fasta file with nucleotide sequences with equal length" $ do a <- either error id- . M.fromSequences- <$> parseFileWith (fasta DNA) fastaNucleotideFN+ . M.fromSequences+ <$> parseFileWith (fasta DNA) fastaNucleotideFN M.nSequences a `shouldBe` 3 M.length a `shouldBe` 40-- it "parses a fasta file with nucleotide IUPAC sequences with equal length"- $ do- a <-- either error id- . M.fromSequences+ it "parses a fasta file with nucleotide IUPAC sequences with equal length" $+ do+ a <-+ either error id+ . M.fromSequences <$> parseFileWith (fasta DNAI) fastaNucleotideIUPACFN- M.nSequences a `shouldBe` 3- M.length a `shouldBe` 40-+ M.nSequences a `shouldBe` 3+ M.length a `shouldBe` 40 it "should not parse erroneous files" $ do ea <- runParserOnFile (fasta DNAI) fastaErroneousFN ea `shouldSatisfy` isLeft- it "parses a fasta file with amino acid sequences with equal length" $ do a <- either error id- . M.fromSequences- <$> parseFileWith (fasta Protein) fastaAminoAcidFN+ . M.fromSequences+ <$> parseFileWith (fasta Protein) fastaAminoAcidFN M.nSequences a `shouldBe` 2 M.length a `shouldBe` 237- it "should not parse erroneous files" $ do a <- runParserOnFile (fasta ProteinI) fastaErroneousFN a `shouldSatisfy` isLeft-