packages feed

elynx-tree 0.3.0 → 0.3.1

raw patch · 19 files changed

+263/−300 lines, 19 filesdep +attoparsecdep +double-conversiondep −hspec-megaparsecdep −megaparsecdep −vector

Dependencies added: attoparsec, double-conversion

Dependencies removed: hspec-megaparsec, megaparsec, vector

Files

ChangeLog.md view
@@ -2,7 +2,14 @@ # Changelog for ELynx  -## Version 0.3.1; in development+## Version 0.3.2; in development+++## Version 0.3.1++-   Use Attoparsec.+-   Use ByteString consistently.+-   Remove elynx-tools dependency from libaries.   ## Version 0.3.0
README.md view
@@ -2,7 +2,7 @@  # The ELynx Suite -Version: 0.3.0.+Version: 0.3.1. Reproducible evolution made easy.  <p align="center"><img src="https://travis-ci.org/dschrempf/elynx.svg?branch=master"/></p>@@ -90,9 +90,9 @@      slynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME]                   [-f|--force] COMMAND@@ -136,9 +136,9 @@      slynx concatenate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx concatenate (-a|--alphabet NAME) INPUT-FILE       Concatenate sequences found in input files.@@ -157,9 +157,9 @@      slynx examine --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx examine (-a|--alphabet NAME) INPUT-FILE [--per-site]       Examine sequences. If data is a multi sequence alignment, additionally analyze columns.@@ -179,9 +179,9 @@      slynx filter-rows --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx filter-rows (-a|--alphabet NAME) INPUT-FILE [--longer-than LENGTH]                               [--shorter-than LENGTH] [--standard-characters]@@ -202,9 +202,9 @@      slynx filter-columns --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx filter-columns (-a|--alphabet NAME) INPUT-FILE                                  [--standard-chars DOUBLE]@@ -226,9 +226,9 @@      slynx simulate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL]                            [-m|--mixture-model MODEL] [-e|--edm-file NAME] @@ -305,9 +305,9 @@      slynx sub-sample --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx sub-sample (-a|--alphabet NAME) INPUT-FILE                             (-n|--number-of-sites INT)@@ -335,9 +335,9 @@      slynx translate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: slynx translate (-a|--alphabet NAME) INPUT-FILE (-r|--reading-frame INT)                            (-u|--universal-code CODE)@@ -360,9 +360,9 @@      tlynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME]                   [-f|--force] COMMAND@@ -399,9 +399,9 @@      tlynx compare --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx compare [-n|--normalize] [-b|--bipartitions] [-t|--intersect]                           [-f|--newick-format FORMAT] NAMES@@ -428,9 +428,9 @@      tlynx examine --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx examine INPUT-FILE [-f|--newick-format FORMAT]       Compute summary statistics of phylogenetic trees.@@ -452,9 +452,9 @@      tlynx simulate --help -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: tlynx simulate [-t|--nTrees INT] [-n|--nLeaves INT] [-H|--height DOUBLE]                            [-M|--condition-on-mrca] [-l|--lambda DOUBLE] @@ -491,9 +491,9 @@      elynx --help | head -n -16 -    ELynx Suite version 0.3.0.+    ELynx Suite version 0.3.1.     Developed by Dominik Schrempf.-    Compiled on July 30, 2020, at 12:40 pm, UTC.+    Compiled on August 3, 2020, at 12:12 pm, UTC.          Usage: elynx COMMAND       Validate and redo past ELynx analyses
bench/Bench.hs view
@@ -12,7 +12,7 @@ module Main where  import Criterion.Main-import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree import ELynx.Import.Tree.Newick import ELynx.Tools@@ -20,7 +20,7 @@ treeFileMany :: FilePath treeFileMany = "data/Many.trees" -getManyTrees :: IO (Forest Phylo ByteString)+getManyTrees :: IO (Forest Phylo BS.ByteString) getManyTrees = parseFileWith (someNewick Standard) treeFileMany  main :: IO ()
elynx-tree.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: df9f8f1cb0b1f1f6bac542cb0c44ceb8e3530eb04ea14e29c0b5bb4be0e831f3+-- hash: 5876c21cdef387a8327af59315c4809662b893bf5daeb4f5e60874063f34384f  name:           elynx-tree-version:        0.3.0+version:        0.3.1 synopsis:       Handle phylogenetic trees description:    Examine, compare, and simulate phylogenetic trees in a reproducible way. Please see the README on GitHub at <https://github.com/dschrempf/elynx>. category:       Bioinformatics@@ -65,19 +65,18 @@   ghc-options: -Wall -fllvm   build-depends:       aeson+    , attoparsec     , base >=4.7 && <5     , bytestring     , comonad     , containers     , deepseq+    , double-conversion     , elynx-nexus-    , elynx-tools     , math-functions-    , megaparsec     , mwc-random     , primitive     , statistics-    , vector   default-language: Haskell2010  test-suite tree-test@@ -101,14 +100,13 @@   ghc-options: -Wall -fllvm   build-depends:       QuickCheck+    , attoparsec     , base >=4.7 && <5     , bytestring     , containers     , elynx-tools     , elynx-tree     , hspec-    , hspec-megaparsec-    , megaparsec   default-language: Haskell2010  benchmark tree-bench@@ -122,7 +120,6 @@   build-depends:       base >=4.7 && <5     , bytestring-    , containers     , criterion     , elynx-tools     , elynx-tree
src/ELynx/Data/Tree/Measurable.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE OverloadedStrings #-}- -- | -- Module      :  ELynx.Data.Tree.Measurable -- Description :  Measurable branch labels@@ -21,7 +19,6 @@     rootHeight,     distancesOriginLeaves,     totalBranchLength,-    summarizeBranchLengths,     normalizeBranchLengths,     normalizeHeight,     ultrametric,@@ -31,18 +28,11 @@  import Data.Bifoldable import Data.Bifunctor-import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L import ELynx.Data.Tree.Rooted-import ELynx.Tools-import Text.Printf  -- | Branch length. type BranchLength = Double -pretty :: BranchLength -> String-pretty = printf "%.5f"- -- | A branch label with measurable and modifiable branch length. class Measurable e where   -- | Length of attached branch.@@ -101,27 +91,6 @@ totalBranchLength :: Measurable e => Tree e a -> BranchLength totalBranchLength = bifoldl' (+) const 0 . first getLen -prettyRow :: String -> String -> ByteString-prettyRow name val = alignLeft 33 n <> alignRight 8 v-  where-    n = L.pack name-    v = L.pack val---- | Examine branches of a tree.-summarizeBranchLengths :: Measurable e => Tree e a -> ByteString-summarizeBranchLengths t =-  L.intercalate-    "\n"-    [ prettyRow "Origin height: " $ pretty h,-      prettyRow "Average distance origin to leaves: " $ pretty h',-      prettyRow "Total branch length: " $ pretty b-    ]-  where-    n = length $ leaves t-    h = height t-    h' = sum (distancesOriginLeaves t) / fromIntegral n-    b = totalBranchLength t- -- | Normalize branch lengths so that the sum is 1.0. normalizeBranchLengths :: Measurable e => Tree e a -> Tree e a normalizeBranchLengths t = first (apply (/ s)) t@@ -133,6 +102,15 @@ normalizeHeight t = first (apply (/ h)) t   where     h = height t++eps :: Double+eps = 1e-12++allNearlyEqual :: [Double] -> Bool+allNearlyEqual [] = True+allNearlyEqual xs = all (\y -> eps > abs (x - y)) (tail xs)+  where+    x = head xs  -- | Check if a tree is ultrametric. ultrametric :: Measurable e => Tree e a -> Bool
src/ELynx/Data/Tree/Named.hs view
@@ -14,21 +14,30 @@   ) where -import Data.ByteString.Lazy.Builder (char8, doubleDec, intDec, toLazyByteString)-import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Builder as BB+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL+import Data.Double.Conversion.ByteString as BC  -- | Data types with names. class Named a where-  getName :: a -> ByteString+  -- Use lazy byte strings because Newick strings are built using chunks.+  getName :: a -> BL.ByteString +instance Named () where+  getName = const BL.empty+ instance Named Int where-  getName = toLazyByteString . intDec+  getName = BB.toLazyByteString . BB.intDec  instance Named Double where-  getName = toLazyByteString . doubleDec+  getName = BL.fromStrict . toShortest  instance Named Char where-  getName = toLazyByteString . char8+  getName = BB.toLazyByteString . BB.char8 -instance Named ByteString where+instance Named BL.ByteString where   getName = id++instance Named BS.ByteString where+  getName = BL.fromStrict
src/ELynx/Export/Tree/Newick.hs view
@@ -16,38 +16,38 @@ -- See nomenclature in 'ELynx.Data.Tree.Tree'. module ELynx.Export.Tree.Newick   ( toNewick,+    toNewickBuilder,   ) where -import Data.ByteString.Lazy.Builder (Builder)-import qualified Data.ByteString.Lazy.Builder as L-import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Builder as BB+import qualified Data.ByteString.Lazy.Char8 as BL import Data.List (intersperse) import ELynx.Data.Tree.Named import ELynx.Data.Tree.Phylogeny import ELynx.Data.Tree.Rooted-import ELynx.Tools -toNewickBuilder :: Named a => Tree Phylo a -> Builder-toNewickBuilder t = go t <> L.word8 (c2w ';')+-- | See 'toNewick'.+toNewickBuilder :: Named a => Tree Phylo a -> BB.Builder+toNewickBuilder t = go t <> BB.char8 ';'   where     go (Node b l []) = lbl b l     go (Node b l ts) =-      L.word8 (c2w '(')-        <> mconcat (intersperse (L.word8 $ c2w ',') $ map go ts)-        <> L.word8 (c2w ')')+      BB.char8 '('+        <> mconcat (intersperse (BB.char8 ',') $ map go ts)+        <> BB.char8 ')'         <> lbl b l-    mBrSupBuilder x = maybe mempty (\bs -> L.word8 (c2w '[') <> L.doubleDec bs <> L.word8 (c2w ']')) (brSup x)-    mBrLenBuilder x = maybe mempty (\bl -> L.word8 (c2w ':') <> L.doubleDec bl) (brLen x)+    mBrSupBuilder x = maybe mempty (\bs -> BB.char8 '[' <> BB.doubleDec bs <> BB.char8 ']') (brSup x)+    mBrLenBuilder x = maybe mempty (\bl -> BB.char8 ':' <> BB.doubleDec bl) (brLen x)     lbl x y =-      L.lazyByteString (getName y)+      BB.lazyByteString (getName y)         <> mBrLenBuilder x         -- After reading several discussion, I go for the "more semantical         -- form" with branch support values in square brackets.         <> mBrSupBuilder x --- | General conversion of a tree into a Newick 'L.Bytestring'. Use provided+-- | General conversion of a tree into a Newick 'BL.Bytestring'. Use provided -- functions to extract node labels and branch lengths builder objects. See also -- Biobase.Newick.Export.-toNewick :: Named a => Tree Phylo a -> ByteString-toNewick = L.toLazyByteString . toNewickBuilder+toNewick :: Named a => Tree Phylo a -> BL.ByteString+toNewick = BB.toLazyByteString . toNewickBuilder
src/ELynx/Export/Tree/Nexus.hs view
@@ -16,7 +16,7 @@   ) where -import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy.Char8 as BL import ELynx.Data.Tree.Named import ELynx.Data.Tree.Phylogeny import ELynx.Data.Tree.Rooted@@ -24,8 +24,8 @@ import ELynx.Export.Tree.Newick  -- | Export a list of (NAME, TREE) to a Nexus file.-toNexusTrees :: Named a => [(ByteString, Tree Phylo a)] -> ByteString+toNexusTrees :: Named a => [(BL.ByteString, Tree Phylo a)] -> BL.ByteString toNexusTrees ts = toNexus "TREES" (map tree ts) -tree :: Named a => (ByteString, Tree Phylo a) -> ByteString+tree :: Named a => (BL.ByteString, Tree Phylo a) -> BL.ByteString tree (n, t) = "  TREE " <> n <> " = " <> toNewick t
src/ELynx/Import/Tree/Newick.hs view
@@ -1,8 +1,5 @@ {-# LANGUAGE DeriveGeneric #-} --- TODO: Use 'between' for forests.---- | -- Module      :  ELynx.Import.Tree.Newick -- Description :  Import Newick trees -- Copyright   :  (c) Dominik Schrempf 2020@@ -22,12 +19,11 @@ -- In particular, no conversion from _ to (space) is done right now. -- -- For a description of rooted 'Tree's, please see the 'ELynx.Data.Tree.Rooted'++-- | -- module header. module ELynx.Import.Tree.Newick-  ( Parser,--    -- * Newick tree format-    NewickFormat (..),+  ( NewickFormat (..),     description,     newick,     oneNewick,@@ -35,24 +31,16 @@   ) where -import Data.ByteString.Lazy (ByteString)-import qualified Data.ByteString.Lazy as L-import Data.Void-import Data.Word+import Control.Applicative+import Data.Aeson (FromJSON, ToJSON)+import Data.Attoparsec.ByteString.Char8+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree.Measurable import ELynx.Data.Tree.Phylogeny-import ELynx.Data.Tree.Rooted hiding (label)+import ELynx.Data.Tree.Rooted hiding (forest, label) import ELynx.Data.Tree.Supported-import ELynx.Tools-import Text.Megaparsec-import Text.Megaparsec.Byte-import Text.Megaparsec.Byte.Lexer-  ( decimal,-    float,-  )---- | Shortcut.-type Parser = Parsec Void ByteString+import GHC.Generics+import Prelude hiding (takeWhile)  -- | Newick tree format. --@@ -77,133 +65,117 @@   "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."  -- | Parse a single Newick tree. Also succeeds when more trees follow.-newick :: NewickFormat -> Parser (Tree Phylo ByteString)+newick :: NewickFormat -> Parser (Tree Phylo BS.ByteString) newick Standard = newickStandard newick IqTree = newickIqTree newick RevBayes = newickRevBayes  -- | Parse a single Newick tree. Fails when end of file is not reached.-oneNewick :: NewickFormat -> Parser (Tree Phylo ByteString)+oneNewick :: NewickFormat -> Parser (Tree Phylo BS.ByteString) oneNewick Standard = oneNewickStandard oneNewick IqTree = oneNewickIqTree oneNewick RevBayes = oneNewickRevBayes  -- | Parse one or more Newick trees until end of file.-someNewick :: NewickFormat -> Parser (Forest Phylo ByteString)+someNewick :: NewickFormat -> Parser (Forest Phylo BS.ByteString) someNewick Standard = someNewickStandard someNewick IqTree = someNewickIqTree someNewick RevBayes = someNewickRevBayes -w :: Char -> Parser Word8-w = char . c2w- -- Parse a single Newick tree. Also succeeds when more trees follow.-newickStandard :: Parser (Tree Phylo ByteString)-newickStandard = space *> tree <* w ';' <* space <?> "newickStandard"+newickStandard :: Parser (Tree Phylo BS.ByteString)+newickStandard = skipWhile isSpace *> tree <* char ';' <* skipWhile isSpace <?> "newickStandard"  -- Parse a single Newick tree. Fails when end of file is not reached.-oneNewickStandard :: Parser (Tree Phylo ByteString)-oneNewickStandard = newickStandard <* eof <?> "oneNewickStandard"+oneNewickStandard :: Parser (Tree Phylo BS.ByteString)+oneNewickStandard = newickStandard <* endOfInput <?> "oneNewickStandard"  -- Parse one ore more Newick trees until end of file.-someNewickStandard :: Parser (Forest Phylo ByteString)-someNewickStandard = some newickStandard <* eof <?> "someNewickStandard"+someNewickStandard :: Parser (Forest Phylo BS.ByteString)+someNewickStandard = some newickStandard <* endOfInput <?> "someNewickStandard" -tree :: Parser (Tree Phylo ByteString)+tree :: Parser (Tree Phylo BS.ByteString) tree = branched <|> leaf <?> "tree" -branched :: Parser (Tree Phylo ByteString)-branched = label "branched" $ do-  f <- forestP+branched :: Parser (Tree Phylo BS.ByteString)+branched = (<?> "branched") $ do+  f <- forest   n <- name   p <- phylo   return $ Node p n f  -- A 'forest' is a set of trees separated by @,@ and enclosed by parentheses.-forestP :: Parser (Forest Phylo ByteString)-forestP = between (w '(') (w ')') (tree `sepBy1` w ',') <?> "forestP"--branchSupport :: Parser (Maybe BranchSupport)-branchSupport = label "branchSupport" $-  optional $-    try $-      do-        _ <- w '['-        s <- float <|> decimalAsDouble-        _ <- w ']'-        return s+forest :: Parser (Forest Phylo BS.ByteString)+forest = char '(' *> (tree `sepBy1` char ',') <* char ')' <?> "forest"  -- A 'leaf' has a 'name' and a 'phylo' branch.-leaf :: Parser (Tree Phylo ByteString)-leaf = label "leaf" $ do+leaf :: Parser (Tree Phylo BS.ByteString)+leaf = (<?> "leaf") $ do   n <- name   p <- phylo   return $ Node p n [] -checkNameCharacter :: Word8 -> Bool-checkNameCharacter c = c `notElem` map c2w " :;()[],"+nameChar :: Char -> Bool+nameChar c = c `notElem` " :;()[],"  -- A name can be any string of printable characters except blanks, colons, -- semicolons, parentheses, and square brackets (and commas).-name :: Parser ByteString-name = L.pack <$> many (satisfy checkNameCharacter) <?> "name"+name :: Parser BS.ByteString+name = takeWhile nameChar <?> "name"  phylo :: Parser Phylo-phylo = Phylo <$> branchLength <*> branchSupport <?> "phylo"+phylo = Phylo <$> optional branchLength <*> optional branchSupport <?> "phylo"  -- Branch length.-branchLength :: Parser (Maybe BranchLength)-branchLength = optional (w ':' *> branchLengthGiven) <?> "branchLength"--branchLengthGiven :: Parser Double-branchLengthGiven = try float <|> decimalAsDouble <?> "branchLengthGiven"+branchLength :: Parser BranchLength+branchLength = char ':' *> double <?> "branchLength" -decimalAsDouble :: Parser Double-decimalAsDouble = fromIntegral <$> (decimal :: Parser Int) <?> "decimalAsDouble"+branchSupport :: Parser BranchSupport+branchSupport = (<?> "branchSupport") $+  do+    _ <- char '['+    s <- double+    _ <- char ']'+    return s  -------------------------------------------------------------------------------- -- IQ-TREE.  -- IQ-TREE stores the branch support as node names after the closing bracket of -- a forest. Parse a single Newick tree. Also succeeds when more trees follow.-newickIqTree :: Parser (Tree Phylo ByteString)-newickIqTree = space *> treeIqTree <* w ';' <* space <?> "newickIqTree"+newickIqTree :: Parser (Tree Phylo BS.ByteString)+newickIqTree = skipWhile isSpace *> treeIqTree <* char ';' <* skipWhile isSpace <?> "newickIqTree"  -- See 'newickIqTree'. Parse a single Newick tree. Fails when end of file is not -- reached.-oneNewickIqTree :: Parser (Tree Phylo ByteString)-oneNewickIqTree = newickIqTree <* eof <?> "oneNewickIqTree"+oneNewickIqTree :: Parser (Tree Phylo BS.ByteString)+oneNewickIqTree = newickIqTree <* endOfInput <?> "oneNewickIqTree"  -- See 'newickIqTree'. Parse one ore more Newick trees until end of file.-someNewickIqTree :: Parser (Forest Phylo ByteString)-someNewickIqTree = some newickIqTree <* eof <?> "someNewickIqTree"+someNewickIqTree :: Parser (Forest Phylo BS.ByteString)+someNewickIqTree = some newickIqTree <* endOfInput <?> "someNewickIqTree"  -- IQ-TREE stores the branch support as node names after the closing bracket of a forest.-treeIqTree :: Parser (Tree Phylo ByteString)+treeIqTree :: Parser (Tree Phylo BS.ByteString) treeIqTree = branchedIqTree <|> leaf <?> "treeIqTree"  -- IQ-TREE stores the branch support as node names after the closing bracket of a forest.-branchedIqTree :: Parser (Tree Phylo ByteString)-branchedIqTree = label "branchedIqTree" $ do+branchedIqTree :: Parser (Tree Phylo BS.ByteString)+branchedIqTree = (<?> "branchedIqTree") $ do   f <- forestIqTree-  s <- branchSupportIqTree+  s <- optional double   n <- name-  b <- branchLength+  b <- optional branchLength   return $ Node (Phylo b s) n f  -- IQ-TREE stores the branch support as node names after the closing bracket of a forest.-forestIqTree :: Parser (Forest Phylo ByteString)-forestIqTree = label "forestIqTree" $ do-  _ <- w '('-  f <- treeIqTree `sepBy1` w ','-  _ <- w ')'+forestIqTree :: Parser (Forest Phylo BS.ByteString)+forestIqTree = (<?> "forestIqTree") $ do+  _ <- char '('+  f <- treeIqTree `sepBy1` char ','+  _ <- char ')'   return f --- TODO: Same here, why try?--- IQ-TREE stores the branch support as node names after the closing bracket of a forest.-branchSupportIqTree :: Parser (Maybe BranchSupport)-branchSupportIqTree = label "branchSupportIqTree" $ optional $ try float <|> try decimalAsDouble- -------------------------------------------------------------------------------- -- RevBayes. @@ -212,54 +184,52 @@ -- trees follow. -- -- XXX: Key value pairs are ignored at the moment.-newickRevBayes :: Parser (Tree Phylo ByteString)+newickRevBayes :: Parser (Tree Phylo BS.ByteString) newickRevBayes =-  space *> optional brackets *> treeRevBayes <* w ';' <* space <?> "newickRevBayes"+  skipWhile isSpace *> optional brackets *> treeRevBayes <* char ';' <* skipWhile isSpace <?> "newickRevBayes"  -- See 'newickRevBayes'. Parse a single Newick tree. Fails when end of file is -- not reached.-oneNewickRevBayes :: Parser (Tree Phylo ByteString)-oneNewickRevBayes = newickRevBayes <* eof <?> "oneNewickRevBayes"+oneNewickRevBayes :: Parser (Tree Phylo BS.ByteString)+oneNewickRevBayes = newickRevBayes <* endOfInput <?> "oneNewickRevBayes"  -- See 'newickRevBayes'. Parse one ore more Newick trees until end of file.-someNewickRevBayes :: Parser (Forest Phylo ByteString)-someNewickRevBayes = some newickRevBayes <* eof <?> "someNewickRevBayes"+someNewickRevBayes :: Parser (Forest Phylo BS.ByteString)+someNewickRevBayes = some newickRevBayes <* endOfInput <?> "someNewickRevBayes" -treeRevBayes :: Parser (Tree Phylo ByteString)+treeRevBayes :: Parser (Tree Phylo BS.ByteString) treeRevBayes = branchedRevBayes <|> leafRevBayes <?> "treeRevBayes" -branchedRevBayes :: Parser (Tree Phylo ByteString)-branchedRevBayes = label "branchedRevgBayes" $ do+branchedRevBayes :: Parser (Tree Phylo BS.ByteString)+branchedRevBayes = (<?> "branchedRevgBayes") $ do   f <- forestRevBayes   n <- nameRevBayes-  b <- branchLengthRevBayes+  b <- optional branchLengthRevBayes   return $ Node (Phylo b Nothing) n f -forestRevBayes :: Parser (Forest Phylo ByteString)-forestRevBayes = label "forestRevBayes" $ do-  _ <- w '('-  f <- treeRevBayes `sepBy1` w ','-  _ <- w ')'+forestRevBayes :: Parser (Forest Phylo BS.ByteString)+forestRevBayes = (<?> "forestRevBayes") $ do+  _ <- char '('+  f <- treeRevBayes `sepBy1` char ','+  _ <- char ')'   return f -nameRevBayes :: Parser ByteString+nameRevBayes :: Parser BS.ByteString nameRevBayes = name <* optional brackets <?> "nameRevBayes" -branchLengthRevBayes :: Parser (Maybe BranchLength)+branchLengthRevBayes :: Parser BranchLength branchLengthRevBayes = branchLength <* optional brackets <?> "branchLengthRevBayes" -leafRevBayes :: Parser (Tree Phylo ByteString)-leafRevBayes = label "leafRevBayes" $ do+leafRevBayes :: Parser (Tree Phylo BS.ByteString)+leafRevBayes = (<?> "leafRevBayes") $ do   n <- nameRevBayes-  b <- branchLengthRevBayes+  b <- optional branchLengthRevBayes   return $ Node (Phylo b Nothing) n []  -- Drop anything between brackets. brackets :: Parser ()-brackets = label "brackets" $ do-  _ <--    between-      (w '[')-      (w ']')-      (takeWhileP (Just "allCharsButBracketEnd") (/= c2w ']'))+brackets = (<?> "brackets") $ do+  _ <- char '['+  _ <- takeWhile (/= ']')+  _ <- char ']'   return ()
src/ELynx/Import/Tree/Nexus.hs view
@@ -16,30 +16,30 @@   ) where -import Data.ByteString.Internal (c2w)-import Data.ByteString.Lazy (ByteString, pack)+import Control.Applicative+import Data.Attoparsec.ByteString.Char8+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree.Phylogeny import ELynx.Data.Tree.Rooted-import ELynx.Import.Nexus hiding (Parser)+import ELynx.Import.Nexus import ELynx.Import.Tree.Newick-import Text.Megaparsec-import Text.Megaparsec.Byte+import Prelude hiding (takeWhile)  -- | Parse a Nexus files with a TREES block.-nexusTrees :: NewickFormat -> Parser [(ByteString, Tree Phylo ByteString)]+nexusTrees :: NewickFormat -> Parser [(BS.ByteString, Tree Phylo BS.ByteString)] nexusTrees = nexus . trees -trees :: NewickFormat -> Block [(ByteString, Tree Phylo ByteString)]+trees :: NewickFormat -> Block [(BS.ByteString, Tree Phylo BS.ByteString)] trees f = Block "TREES" (some $ namedNewick f) -namedNewick :: NewickFormat -> Parser (ByteString, Tree Phylo ByteString)+namedNewick :: NewickFormat -> Parser (BS.ByteString, Tree Phylo BS.ByteString) namedNewick f = do-  _ <- space+  _ <- skipWhile isSpace   _ <- string "TREE"-  _ <- space-  n <- some alphaNumChar-  _ <- space-  _ <- char $ c2w '='-  _ <- space+  _ <- skipWhile isSpace+  n <- takeWhile1 (\x -> isAlpha_ascii x || isDigit x)+  _ <- skipWhile isSpace+  _ <- char '='+  _ <- skipWhile isSpace   t <- newick f-  return (pack n, t)+  return (n, t)
src/ELynx/Simulate/PointProcess.hs view
@@ -29,7 +29,8 @@  import Control.Monad import Control.Monad.Primitive-import Data.List (mapAccumL)+import Data.Function+import Data.List import Data.Sequence (Seq) import qualified Data.Sequence as S import ELynx.Data.Tree.Measurable@@ -42,7 +43,6 @@ import ELynx.Distribution.TimeOfOrigin import ELynx.Distribution.TimeOfOriginNearCritical import ELynx.Distribution.Types-import ELynx.Tools import qualified Statistics.Distribution as D   ( genContVar,   )@@ -54,6 +54,23 @@ epsNearCriticalTimeOfOrigin :: Double epsNearCriticalTimeOfOrigin = 1e-8 +eps :: Double+eps = 1e-12++(=~=) :: Double -> Double -> Bool+x =~= y = eps > abs (x - y)++-- Sort a list and also return original indices.+sortListWithIndices :: Ord a => [a] -> [(a, Int)]+sortListWithIndices xs = sortBy (compare `on` fst) $ zip xs ([0 ..] :: [Int])++-- Insert element into random position of list.+randomInsertList :: PrimMonad m => a -> [a] -> Gen (PrimState m) -> m [a]+randomInsertList e v g = do+  let l = length v+  i <- uniformR (0, l) g+  return $ take i v ++ [e] ++ drop i v+ -- | A __point process__ for \(n\) points and of age \(t_{or}\) is defined as -- follows. Draw $n$ points on the horizontal axis at \(1,2,\ldots,n\). Pick -- \(n-1\) points at locations \((i+1/2, s_i)\), \(i=1,2,\ldots,n-1\);@@ -148,10 +165,10 @@     return $ PointProcess [0 .. (n - 1)] vs' t   | otherwise = error "simulate: Fell through guard, this should never happen." --- | Sort the values of a point process and their indices to be (the indices+-- Sort the values of a point process and their indices to be (the indices -- that they will have while creating the tree).-sort :: (Ord b) => PointProcess a b -> ([b], [Int])-sort (PointProcess _ vs _) = (vsSorted, isSorted)+sortPP :: (Ord b) => PointProcess a b -> ([b], [Int])+sortPP (PointProcess _ vs _) = (vsSorted, isSorted)   where     vsIsSorted = sortListWithIndices vs     vsSorted = map fst vsIsSorted@@ -229,7 +246,7 @@     otherwise =     treeOrigin   where-    (vsSorted, isSorted) = sort pp+    (vsSorted, isSorted) = sortPP pp     !lvs = S.fromList [Node (Length 0) p [] | p <- ps]     !heights = S.replicate (length ps) 0     !treeRoot = toReconstructedTree' isSorted vsSorted l lvs heights
test/ELynx/Data/Tree/BipartitionSpec.hs view
@@ -15,7 +15,7 @@   ) where -import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Char8 as BS import Data.Map (Map) import qualified Data.Map as M import Data.Set (Set)@@ -25,16 +25,16 @@ import ELynx.Tools import Test.Hspec -sfrom :: [ByteString] -> S.Set ByteString+sfrom :: [BS.ByteString] -> S.Set BS.ByteString sfrom = S.fromList  treeFileSimple :: FilePath treeFileSimple = "data/TreeDist.trees" -getSimpleTrees :: IO (Forest Phylo ByteString)+getSimpleTrees :: IO (Forest Phylo BS.ByteString) getSimpleTrees = parseFileWith (someNewick Standard) treeFileSimple -bipartitionToBranchAnswer :: Map (Bipartition ByteString) Length+bipartitionToBranchAnswer :: Map (Bipartition BS.ByteString) Length bipartitionToBranchAnswer =   M.fromList     [ (bpUnsafe (sfrom ["B"]) (sfrom ["A", "C", "D", "E"]), 0.3),@@ -46,7 +46,7 @@       (bpUnsafe (sfrom ["E"]) (sfrom ["A", "B", "C", "D"]), 0.8)     ] -bipartitionsFirstTree :: Set (Bipartition ByteString)+bipartitionsFirstTree :: Set (Bipartition BS.ByteString) bipartitionsFirstTree =   S.fromList     [ bpUnsafe (sfrom ["B"]) (sfrom ["A", "C", "D", "E"]),@@ -58,7 +58,7 @@       bpUnsafe (sfrom ["E"]) (sfrom ["A", "B", "C", "D"])     ] -bipartitionsSecondTree :: Set (Bipartition ByteString)+bipartitionsSecondTree :: Set (Bipartition BS.ByteString) bipartitionsSecondTree =   S.fromList     [ bpUnsafe (sfrom ["B"]) (sfrom ["A", "C", "D", "E"]),
test/ELynx/Data/Tree/DistanceSpec.hs view
@@ -16,13 +16,10 @@   ) where --- import Data.Bifunctor-import Data.ByteString.Lazy.Char8 (ByteString)+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree--- import qualified Data.Set as S import ELynx.Data.Tree.Arbitrary () import ELynx.Import.Tree.Newick--- import ELynx.Export.Tree.Newick import ELynx.Tools import Test.Hspec import Test.QuickCheck@@ -30,13 +27,13 @@ treeFileSimple :: FilePath treeFileSimple = "data/TreeDist.trees" -getSimpleTrees :: IO (Forest Phylo ByteString)+getSimpleTrees :: IO (Forest Phylo BS.ByteString) getSimpleTrees = parseFileWith (someNewick Standard) treeFileSimple  treeFileMany :: FilePath treeFileMany = "data/Many.trees" -getManyTrees :: IO (Forest Phylo ByteString)+getManyTrees :: IO (Forest Phylo BS.ByteString) getManyTrees = parseFileWith (someNewick Standard) treeFileMany  -- I used treedist from Phylip to get the correct results.@@ -184,20 +181,20 @@       Node () ' ' [Node () 'B' [], Node () ' ' [Node () 'D' [], Node () 'E' []]]     ] -incSplitTree1a :: Tree Phylo ByteString-incSplitTree1a = parseByteStringWith "" (oneNewick IqTree) "((a,b)0.7,(c,d));"+incSplitTree1a :: Tree Phylo BS.ByteString+incSplitTree1a = parseByteStringWith (oneNewick IqTree) "((a,b)0.7,(c,d));" -incSplitTree1b :: Tree Phylo ByteString-incSplitTree1b = parseByteStringWith "" (oneNewick IqTree) "((a,b)0.7,c,d);"+incSplitTree1b :: Tree Phylo BS.ByteString+incSplitTree1b = parseByteStringWith (oneNewick IqTree) "((a,b)0.7,c,d);" -incSplitTree2 :: Tree Phylo ByteString-incSplitTree2 = parseByteStringWith "" (oneNewick IqTree) "((a,c),(b,d));"+incSplitTree2 :: Tree Phylo BS.ByteString+incSplitTree2 = parseByteStringWith (oneNewick IqTree) "((a,c),(b,d));" -incSplitTree3 :: Tree Phylo ByteString-incSplitTree3 = parseByteStringWith "" (oneNewick IqTree) "(((a,b)0.7,c),(d,e));"+incSplitTree3 :: Tree Phylo BS.ByteString+incSplitTree3 = parseByteStringWith (oneNewick IqTree) "(((a,b)0.7,c),(d,e));" -incSplitTree4 :: Tree Phylo ByteString-incSplitTree4 = parseByteStringWith "" (oneNewick IqTree) "(((a,c),b),(d,e));"+incSplitTree4 :: Tree Phylo BS.ByteString+incSplitTree4 = parseByteStringWith (oneNewick IqTree) "(((a,c),b),(d,e));"  -- Compute distances between adjacent pairs of a list of input trees. Use given -- distance measure.
test/ELynx/Data/Tree/PhylogenySpec.hs view
@@ -17,14 +17,10 @@   ) where --- import Data.Bifunctor--- import Data.ByteString.Lazy.Char8 (ByteString) import Data.Either import qualified Data.Set as S import ELynx.Data.Tree import ELynx.Data.Tree.Arbitrary ()--- import ELynx.Import.Tree.Newick--- import ELynx.Tools import Test.Hspec import Test.Hspec.QuickCheck import Test.QuickCheck hiding (labels)
test/ELynx/Data/Tree/RootedSpec.hs view
@@ -16,8 +16,8 @@   ) where -import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import Data.Maybe import ELynx.Data.Tree import ELynx.Import.Tree.Newick@@ -36,16 +36,14 @@ smallSubTreePruned :: Tree () Int smallSubTreePruned = node 1 -sampleTreeBS :: ByteString-sampleTreeBS =-  L.pack-    "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);"+sampleTreeBS :: BL.ByteString+sampleTreeBS = "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);" -largeTree :: Tree Phylo ByteString-largeTree = parseByteStringWith "Sample newick byte string" (newick Standard) sampleTreeBS+largeTree :: Tree Phylo BS.ByteString+largeTree = parseByteStringWith (newick Standard) sampleTreeBS -subSampleLargeTree :: Tree Phylo ByteString-subSampleLargeTree = fromJust $ dropLeavesWith ((/= 'P') . L.head) largeTree+subSampleLargeTree :: Tree Phylo BS.ByteString+subSampleLargeTree = fromJust $ dropLeavesWith ((/= 'P') . BS.head) largeTree  spec :: Spec spec = do
test/ELynx/Export/Tree/NewickSpec.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module      :  ELynx.Export.Tree.NewickSpec -- Copyright   :  (c) Dominik Schrempf 2020@@ -14,8 +16,8 @@ where  import Data.Bifunctor-import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL import ELynx.Data.Tree import ELynx.Data.Tree.Arbitrary () import ELynx.Export.Tree.Newick@@ -24,29 +26,26 @@ import Test.Hspec import Test.QuickCheck hiding (label) -samplePhyloByteStringTree :: Tree Phylo ByteString-samplePhyloByteStringTree = parseByteStringWith "Sample newick byte string" (newick Standard) sampleNewickByteString1+samplePhyloByteStringTree :: Tree Phylo BS.ByteString+samplePhyloByteStringTree = parseByteStringWith (newick Standard) sampleNewickByteString1 -sampleNewickByteString1 :: ByteString-sampleNewickByteString1 =-  L.pack-    "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);"+sampleNewickByteString1 :: BL.ByteString+sampleNewickByteString1 = "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);"  prop_invariant :: Tree Phylo Int -> Bool prop_invariant t =-  parseByteStringWith "Sample newick byte string" (newick Standard) (toNewick t)+  parseByteStringWith (newick Standard) (toNewick t)     ==     -- We have to convert Int to ByteString, but we cannot use     -- arbitrary instances with ByteStrings because many     -- characters are disallowed and break the Newick string.-    second getName t+    second (BL.toStrict . getName) t  spec :: Spec spec = describe "parseByteStringWith newick $ toNewickPhyloByteString" $ do   it "should be an invariant for a sample tree" $ do     let bs = toNewick samplePhyloByteStringTree     parseByteStringWith-      "Newick string converted from tree object"       (newick Standard)       bs       `shouldBe` samplePhyloByteStringTree
test/ELynx/Export/Tree/NexusSpec.hs view
@@ -16,7 +16,7 @@   ) where -import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree import ELynx.Export.Tree.Nexus import ELynx.Import.Tree.Newick (NewickFormat (..))@@ -24,7 +24,7 @@ import ELynx.Tools import Test.Hspec -tree :: Tree Phylo ByteString+tree :: Tree Phylo BS.ByteString tree =   Node     (Phylo Nothing Nothing)@@ -42,5 +42,5 @@ spec = describe "toNexusTrees" $   it "exports a nexus file with a TREES block" $     do-      let ts = parseByteStringWith "NexusTrees" (nexusTrees Standard) (toNexusTrees [("tree1", tree)])+      let ts = parseByteStringWith (nexusTrees Standard) (toNexusTrees [("tree1", tree)])       head ts `shouldBe` ("tree1", tree)
test/ELynx/Import/Tree/NewickSpec.hs view
@@ -15,14 +15,13 @@   ) where -import Data.ByteString.Lazy.Char8 (ByteString)-import qualified Data.ByteString.Lazy.Char8 as L+import Data.Attoparsec.ByteString.Char8+import qualified Data.ByteString.Char8 as BS+import Data.Either import ELynx.Data.Tree import ELynx.Import.Tree.Newick import ELynx.Tools import Test.Hspec-import Test.Hspec.Megaparsec-import Text.Megaparsec  -- sampleLabelByteString :: ByteString -- sampleLabelByteString = "name:0.3"@@ -48,20 +47,17 @@ --       ] --   ] -sampleNewickByteString1 :: ByteString-sampleNewickByteString1 =-  L.pack-    "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);"+sampleNewickByteString1 :: BS.ByteString+sampleNewickByteString1 = "(Aeropyrum0:0.5478645225,(((((((((Arabidopsi:0.0701001024,Oryza_sati:0.0765988261):0.0309636193,Gymnosperm:0.0520325624):0.0338982245,Physcomitr:0.0768008916):0.0895714685,(Chlamydomo:0.1136227755,Dunaliella:0.1406347323):0.1117340620):0.0818876186,Rhodophyta:0.3405656487):0.0363527066,((((((Babesia_bo:0.1646969208,Theileria0:0.1519889486):0.1908081096,Plasmodium:0.3250696762):0.0637865908,(Toxoplasma:0.1153570425,Eimeria000:0.1671916078):0.0980136930):0.0518956330,Cryptospor:0.3175062809):0.1607708388,Ciliophora:0.5687502950):0.0624078848,(Phytophtho:0.2016424948,((Thalassios:0.1202730781,Phaeodacty:0.1290341329):0.1772775509,Phaeophyce:0.1989260715):0.0312359673):0.1154768302):0.0311952864):0.0149160316,(((((((((Candida_al:0.1027755272,Saccharomy:0.1190206560):0.1333487870,Neurospora:0.1977309079):0.0522926266,Schizosacc:0.2019603227):0.0567441011,(Cryptococc:0.1948614959,Ustilago_m:0.1564451295):0.0775729694):0.0323959951,Glomus_int:0.1573670796):0.0194701292,Chytridiom:0.2228415254):0.0384370601,Encephalit:1.4622174644):0.0416231688,(((Drosophila:0.2160627753,(Mammalians:0.1080484094,Tunicates0:0.1739253014):0.0289624371):0.0346633757,Hydrozoa00:0.2058137032):0.0480963050,Monosiga_b:0.3020637584):0.0654894239):0.0380915725,(Dictyostel:0.3453588998,Mastigamoe:0.3844779231):0.0478795653):0.0129578395):1.7592083381,((Archaeoglo:0.5402784445,Methanococ:0.4088567459):0.0993669265,Pyrococcus:0.4058713829):0.1734405968):0.2193511807,Pyrobaculu:0.7507718047):0.1646616482,Sulfolobus:0.5404967897);" -sampleNewickByteString2 :: ByteString+sampleNewickByteString2 :: BS.ByteString sampleNewickByteString2 =-  L.pack-    "(Caenorhabd:0.0176707431,C0briggsae:0.0142817073,(Ancylostom:0.0711440844,(Pristionch:0.1301309005,((Brugia_mal:0.0757534325,Ascaris0su:0.0482660407)1:0.0563924634,(((Meloidogyn:0.1239621893,Heteroderi:0.0987968800)1:0.1136879428,Strongyloi:0.2483437292)1:0.0252467381,(Trichoceph:0.2985037612,((((((Coleoptera:0.0907850846,(Apis0melli:0.0754058285,Hemiptera0:0.1675359618)0.93:0.0085703192)1:0.0146980945,(Siphonapte:0.0556805916,Bombyx0mor:0.0968983509)1:0.0127867903)1:0.0167360185,((Drosophila:0.0492149086,Glossina0m:0.0534390467)1:0.0583462602,Anopheles0:0.0968919941)1:0.0431343553)1:0.0535616453,Crustacea0:0.2247268999)1:0.0252755187,Chelicerat:0.1537491558)1:0.0212497286,((Echinoderm:0.1803896615,(Cephalocho:0.1492264574,(Urochordat:0.2194747834,(Mammalia00:0.0393008407,Actinopter:0.0491700096):0.0858550024)1:0.0157515969)1:0.0132516777)1:0.0203423736,((((((((Neurospora:0.0721607581,Magnaporth:0.0814182810)1:0.0198940548,Gibberella:0.0858192964)1:0.0533872590,Eurotiomyc:0.1058840539)1:0.1266302603,(Candida0al:0.1349957509,Saccharomy:0.1553464572)1:0.1791344287)1:0.0529664967,Schizosacc:0.2550087905)1:0.0723650615,(Ustilago0m:0.2031812772,(Homobasidi:0.1473391802,Cryptococc:0.2070743149)1:0.0347868586)1:0.0790327507)1:0.0727415175,Glomales00:0.1779430068)1:0.0169066667,Chytridiom:0.3028920870)1:0.3311420273)1:0.0278566156)1:0.1049569161)1:0.1366217350)1:0.0171168289)1:0.0345725378)1:0.0542036935)1:0.0879337167)1;"+  "(Caenorhabd:0.0176707431,C0briggsae:0.0142817073,(Ancylostom:0.0711440844,(Pristionch:0.1301309005,((Brugia_mal:0.0757534325,Ascaris0su:0.0482660407)1:0.0563924634,(((Meloidogyn:0.1239621893,Heteroderi:0.0987968800)1:0.1136879428,Strongyloi:0.2483437292)1:0.0252467381,(Trichoceph:0.2985037612,((((((Coleoptera:0.0907850846,(Apis0melli:0.0754058285,Hemiptera0:0.1675359618)0.93:0.0085703192)1:0.0146980945,(Siphonapte:0.0556805916,Bombyx0mor:0.0968983509)1:0.0127867903)1:0.0167360185,((Drosophila:0.0492149086,Glossina0m:0.0534390467)1:0.0583462602,Anopheles0:0.0968919941)1:0.0431343553)1:0.0535616453,Crustacea0:0.2247268999)1:0.0252755187,Chelicerat:0.1537491558)1:0.0212497286,((Echinoderm:0.1803896615,(Cephalocho:0.1492264574,(Urochordat:0.2194747834,(Mammalia00:0.0393008407,Actinopter:0.0491700096):0.0858550024)1:0.0157515969)1:0.0132516777)1:0.0203423736,((((((((Neurospora:0.0721607581,Magnaporth:0.0814182810)1:0.0198940548,Gibberella:0.0858192964)1:0.0533872590,Eurotiomyc:0.1058840539)1:0.1266302603,(Candida0al:0.1349957509,Saccharomy:0.1553464572)1:0.1791344287)1:0.0529664967,Schizosacc:0.2550087905)1:0.0723650615,(Ustilago0m:0.2031812772,(Homobasidi:0.1473391802,Cryptococc:0.2070743149)1:0.0347868586)1:0.0790327507)1:0.0727415175,Glomales00:0.1779430068)1:0.0169066667,Chytridiom:0.3028920870)1:0.3311420273)1:0.0278566156)1:0.1049569161)1:0.1366217350)1:0.0171168289)1:0.0345725378)1:0.0542036935)1:0.0879337167)1;" -sampleNewickEmptyByteString :: ByteString-sampleNewickEmptyByteString = L.pack "(,(,,),);"+sampleNewickEmptyByteString :: BS.ByteString+sampleNewickEmptyByteString = "(,(,,),);" -sampleNewickEmpty :: Tree Phylo ByteString+sampleNewickEmpty :: Tree Phylo BS.ByteString sampleNewickEmpty =   Node     noPL@@ -77,9 +73,8 @@       Node noPL "" []     ] -sampleTreeNewickRevbayes :: ByteString-sampleTreeNewickRevbayes =-  L.pack "[&R](l[IDL]:0.3[KEYVALPAIRS],r[IDR]:0.4[KEYVALPARIS])[ID]:0.3;"+sampleTreeNewickRevbayes :: BS.ByteString+sampleTreeNewickRevbayes = "[&R](l[IDL]:0.3[KEYVALPAIRS],r[IDR]:0.4[KEYVALPARIS])[ID]:0.3;"  sampleNewickRevBayesFile :: String sampleNewickRevBayesFile = "data/NewickRevBayes.tree"@@ -104,7 +99,7 @@   --     parse name "" "aName bla"   --       `shouldParse` "aName" -  --   it "allows empty names" $ parse name "" "" `shouldParse` L.pack ""+  --   it "allows empty names" $ parse name "" "" `shouldParse` BL.pack ""    -- describe "node" $ do   --   it "parses a tree node" $@@ -127,13 +122,13 @@    describe "newick" $ do     it "parses newick trees" $ do-      parse (newick Standard) "" `shouldSucceedOn` sampleNewickByteString1-      parse (newick Standard) "" `shouldSucceedOn` sampleNewickByteString2+      parseOnly (newick Standard) sampleNewickByteString1 `shouldSatisfy` isRight+      parseOnly (newick Standard) sampleNewickByteString2 `shouldSatisfy` isRight     it "parses a weird newick tree without node labels nor branch lengths" $-      parse (newick Standard) "" sampleNewickEmptyByteString `shouldParse` sampleNewickEmpty+      parseOnly (newick Standard) sampleNewickEmptyByteString `shouldBe` Right sampleNewickEmpty   describe "newickRevBayes" $     it "parses newick trees in RevBayes format" $       do-        parse (newick RevBayes) "" `shouldSucceedOn` sampleTreeNewickRevbayes+        parseOnly (newick RevBayes) sampleTreeNewickRevbayes `shouldSatisfy` isRight         t2 <- parseFileWith (newick RevBayes) sampleNewickRevBayesFile         length (leaves t2) `shouldBe` 102
test/ELynx/Import/Tree/NexusSpec.hs view
@@ -16,7 +16,7 @@   ) where -import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Char8 as BS import ELynx.Data.Tree import ELynx.Import.Tree.Newick (NewickFormat (..)) import ELynx.Import.Tree.Nexus@@ -29,7 +29,7 @@ noPL :: Phylo noPL = Phylo Nothing Nothing -res :: Tree Phylo ByteString+res :: Tree Phylo BS.ByteString res =   Node     noPL