{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# OPTIONS_GHC -Wno-orphans #-}

-- |
-- Module      :  TLynx.Simulate.Options
-- Description :  Argument parser for seq-ana
-- Copyright   :  (c) Dominik Schrempf 2021
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  dominik.schrempf@gmail.com
-- Stability   :  unstable
-- Portability :  portable
--
-- Creation date: Fri May  3 11:51:07 2019.
module TLynx.Simulate.Options
  ( Process (..),
    SimulateArguments (..),
    simulateArguments,
    reportSimulateArguments,
  )
where

import Data.List
import Data.Maybe
import ELynx.Tools
import ELynx.Tree.Simulate.PointProcess (TimeSpec (..))
import Options.Applicative

deriving instance Eq TimeSpec

deriving instance Generic TimeSpec

instance Show TimeSpec where
  show :: TimeSpec -> String
show TimeSpec
Random = String
"Random"
  show (Origin Time
o) = String
"Condition on height of origin: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Time -> String
forall a. Show a => a -> String
show Time
o
  show (Mrca Time
m) = String
"Condition on height of MRCA: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Time -> String
forall a. Show a => a -> String
show Time
m

instance FromJSON TimeSpec

instance ToJSON TimeSpec

-- | Process to be used for simulation.
data Process
  = BirthDeath
      { -- | Birth rate.
        Process -> Time
bdLambda :: Double,
        -- | Death rate.
        Process -> Time
bdMu :: Double,
        -- | Sampling rate.
        Process -> Maybe Time
bdRho :: Maybe Double,
        -- | Condition on height?
        Process -> TimeSpec
bdHeight :: TimeSpec
      }
  | Coalescent
  deriving (Process -> Process -> Bool
(Process -> Process -> Bool)
-> (Process -> Process -> Bool) -> Eq Process
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Process -> Process -> Bool
$c/= :: Process -> Process -> Bool
== :: Process -> Process -> Bool
$c== :: Process -> Process -> Bool
Eq, Int -> Process -> ShowS
[Process] -> ShowS
Process -> String
(Int -> Process -> ShowS)
-> (Process -> String) -> ([Process] -> ShowS) -> Show Process
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Process] -> ShowS
$cshowList :: [Process] -> ShowS
show :: Process -> String
$cshow :: Process -> String
showsPrec :: Int -> Process -> ShowS
$cshowsPrec :: Int -> Process -> ShowS
Show, (forall x. Process -> Rep Process x)
-> (forall x. Rep Process x -> Process) -> Generic Process
forall x. Rep Process x -> Process
forall x. Process -> Rep Process x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Process x -> Process
$cfrom :: forall x. Process -> Rep Process x
Generic)

instance FromJSON Process

instance ToJSON Process

reportProcess :: Process -> String
reportProcess :: Process -> String
reportProcess (BirthDeath Time
l Time
m Maybe Time
mr TimeSpec
ts) =
  String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
    String
"\n"
    [ String
"Model: Birth and death process",
      String
"  Birth rate: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Time -> String
forall a. Show a => a -> String
show Time
l,
      String
"  Death rate: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Time -> String
forall a. Show a => a -> String
show Time
m,
      String
"  Sampling probability: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> (Time -> String) -> Maybe Time -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"1.0" Time -> String
forall a. Show a => a -> String
show Maybe Time
mr,
      String
"  Height specification: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TimeSpec -> String
forall a. Show a => a -> String
show TimeSpec
ts
    ]
reportProcess Process
Coalescent = String
"Model: Coalescent process"

-- | Arguments need to simulate phylogenetic trees using birth and death processes.
data SimulateArguments = SimulateArguments
  { -- | Simulated trees.
    SimulateArguments -> Int
argsNTrees :: Int,
    -- | Number of leaves.
    SimulateArguments -> Int
argsNLeaves :: Int,
    -- | Process.
    SimulateArguments -> Process
argsProcess :: Process,
    -- | Perform sub-sampling with given probability.
    SimulateArguments -> Maybe Time
argsSubSample :: Maybe Double,
    -- | Only print summary statistics?
    SimulateArguments -> Bool
argsSumStat :: Bool,
    -- | Seed of NRG, random if 'Nothing'.
    SimulateArguments -> SeedOpt
argsSeed :: SeedOpt
  }
  deriving (SimulateArguments -> SimulateArguments -> Bool
(SimulateArguments -> SimulateArguments -> Bool)
-> (SimulateArguments -> SimulateArguments -> Bool)
-> Eq SimulateArguments
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimulateArguments -> SimulateArguments -> Bool
$c/= :: SimulateArguments -> SimulateArguments -> Bool
== :: SimulateArguments -> SimulateArguments -> Bool
$c== :: SimulateArguments -> SimulateArguments -> Bool
Eq, Int -> SimulateArguments -> ShowS
[SimulateArguments] -> ShowS
SimulateArguments -> String
(Int -> SimulateArguments -> ShowS)
-> (SimulateArguments -> String)
-> ([SimulateArguments] -> ShowS)
-> Show SimulateArguments
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimulateArguments] -> ShowS
$cshowList :: [SimulateArguments] -> ShowS
show :: SimulateArguments -> String
$cshow :: SimulateArguments -> String
showsPrec :: Int -> SimulateArguments -> ShowS
$cshowsPrec :: Int -> SimulateArguments -> ShowS
Show, (forall x. SimulateArguments -> Rep SimulateArguments x)
-> (forall x. Rep SimulateArguments x -> SimulateArguments)
-> Generic SimulateArguments
forall x. Rep SimulateArguments x -> SimulateArguments
forall x. SimulateArguments -> Rep SimulateArguments x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SimulateArguments x -> SimulateArguments
$cfrom :: forall x. SimulateArguments -> Rep SimulateArguments x
Generic)

instance Reproducible SimulateArguments where
  inFiles :: SimulateArguments -> [String]
inFiles SimulateArguments
_ = []
  outSuffixes :: SimulateArguments -> [String]
outSuffixes SimulateArguments
_ = [String
".tree"]
  getSeed :: SimulateArguments -> Maybe SeedOpt
getSeed = SeedOpt -> Maybe SeedOpt
forall a. a -> Maybe a
Just (SeedOpt -> Maybe SeedOpt)
-> (SimulateArguments -> SeedOpt)
-> SimulateArguments
-> Maybe SeedOpt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimulateArguments -> SeedOpt
argsSeed
  setSeed :: SimulateArguments -> SeedOpt -> SimulateArguments
setSeed SimulateArguments
a SeedOpt
s = SimulateArguments
a {argsSeed :: SeedOpt
argsSeed = SeedOpt
s}
  parser :: Parser SimulateArguments
parser = Parser SimulateArguments
simulateArguments
  cmdName :: String
cmdName = String
"simulate"
  cmdDsc :: [String]
cmdDsc = [String
"Simulate phylogenetic trees using a birth and death or coalescent process."]
  cmdFtr :: [String]
cmdFtr = [String]
simulateFooter

instance FromJSON SimulateArguments

instance ToJSON SimulateArguments

-- | Print useful information about the provided arguments.
reportSimulateArguments :: SimulateArguments -> String
reportSimulateArguments :: SimulateArguments -> String
reportSimulateArguments SimulateArguments
a =
  String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate
    String
"\n"
    [ String
"Number of simulated trees: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (SimulateArguments -> Int
argsNTrees SimulateArguments
a),
      String
"Number of leaves per tree: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (SimulateArguments -> Int
argsNLeaves SimulateArguments
a),
      Process -> String
reportProcess (SimulateArguments -> Process
argsProcess SimulateArguments
a),
      String
"Perform sub-sampling: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
ssStr,
      String
"Summary statistics only: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show (SimulateArguments -> Bool
argsSumStat SimulateArguments
a)
    ]
  where
    ssStr :: String
ssStr = case SimulateArguments -> Maybe Time
argsSubSample SimulateArguments
a of
      Maybe Time
Nothing -> String
"No"
      Just Time
p -> String
"Yes, with probability " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Time -> String
forall a. Show a => a -> String
show Time
p

-- | Command line parser.
simulateArguments :: Parser SimulateArguments
simulateArguments :: Parser SimulateArguments
simulateArguments =
  Int
-> Int
-> Process
-> Maybe Time
-> Bool
-> SeedOpt
-> SimulateArguments
SimulateArguments
    (Int
 -> Int
 -> Process
 -> Maybe Time
 -> Bool
 -> SeedOpt
 -> SimulateArguments)
-> Parser Int
-> Parser
     (Int
      -> Process -> Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Int
nTreeOpt
    Parser
  (Int
   -> Process -> Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
-> Parser Int
-> Parser
     (Process -> Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int
nLeavesOpt
    Parser
  (Process -> Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
-> Parser Process
-> Parser (Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Process
process
    Parser (Maybe Time -> Bool -> SeedOpt -> SimulateArguments)
-> Parser (Maybe Time)
-> Parser (Bool -> SeedOpt -> SimulateArguments)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe Time)
subSampleOpt
    Parser (Bool -> SeedOpt -> SimulateArguments)
-> Parser Bool -> Parser (SeedOpt -> SimulateArguments)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Bool
sumStatOpt
    Parser (SeedOpt -> SimulateArguments)
-> Parser SeedOpt -> Parser SimulateArguments
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser SeedOpt
seedOpt

nTreeOpt :: Parser Int
nTreeOpt :: Parser Int
nTreeOpt =
  ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Int
forall a. Read a => ReadM a
auto (Mod OptionFields Int -> Parser Int)
-> Mod OptionFields Int -> Parser Int
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"nTrees"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
't'
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"INT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
help String
"Number of trees"

nLeavesOpt :: Parser Int
nLeavesOpt :: Parser Int
nLeavesOpt =
  ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Int
forall a. Read a => ReadM a
auto (Mod OptionFields Int -> Parser Int)
-> Mod OptionFields Int -> Parser Int
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"nLeaves"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'n'
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"INT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
help String
"Number of leaves per tree"

lambdaOpt :: Parser Double
lambdaOpt :: Parser Time
lambdaOpt =
  ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Time
forall a. Read a => ReadM a
auto (Mod OptionFields Time -> Parser Time)
-> Mod OptionFields Time -> Parser Time
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"lambda"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'l'
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Birth rate lambda"

muOpt :: Parser Double
muOpt :: Parser Time
muOpt =
  ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Time
forall a. Read a => ReadM a
auto (Mod OptionFields Time -> Parser Time)
-> Mod OptionFields Time -> Parser Time
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"mu"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'm'
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Death rate mu"

rhoOpt :: Parser Double
rhoOpt :: Parser Time
rhoOpt =
  ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Time
forall a. Read a => ReadM a
auto (Mod OptionFields Time -> Parser Time)
-> Mod OptionFields Time -> Parser Time
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"rho"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'r'
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
      Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Sampling probability rho"

mrca :: Parser TimeSpec
mrca :: Parser TimeSpec
mrca =
  Time -> TimeSpec
Mrca
    (Time -> TimeSpec) -> Parser Time -> Parser TimeSpec
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM Time
forall a. Read a => ReadM a
auto
      ( String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"mrca"
          Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
          Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Condition on height of most recent common ancestor"
      )

origin :: Parser TimeSpec
origin :: Parser TimeSpec
origin =
  Time -> TimeSpec
Origin
    (Time -> TimeSpec) -> Parser Time -> Parser TimeSpec
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM Time
forall a. Read a => ReadM a
auto
      ( String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"origin"
          Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
          Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Condition on height of origin"
      )

timeSpec :: Parser TimeSpec
timeSpec :: Parser TimeSpec
timeSpec = TimeSpec -> Maybe TimeSpec -> TimeSpec
forall a. a -> Maybe a -> a
fromMaybe TimeSpec
Random (Maybe TimeSpec -> TimeSpec)
-> Parser (Maybe TimeSpec) -> Parser TimeSpec
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TimeSpec -> Parser (Maybe TimeSpec)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser TimeSpec
mrca Parser TimeSpec -> Parser TimeSpec -> Parser TimeSpec
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser TimeSpec
origin)

birthDeath :: Parser Process
birthDeath :: Parser Process
birthDeath = Time -> Time -> Maybe Time -> TimeSpec -> Process
BirthDeath (Time -> Time -> Maybe Time -> TimeSpec -> Process)
-> Parser Time
-> Parser (Time -> Maybe Time -> TimeSpec -> Process)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Time
lambdaOpt Parser (Time -> Maybe Time -> TimeSpec -> Process)
-> Parser Time -> Parser (Maybe Time -> TimeSpec -> Process)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Time
muOpt Parser (Maybe Time -> TimeSpec -> Process)
-> Parser (Maybe Time) -> Parser (TimeSpec -> Process)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Time -> Parser (Maybe Time)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser Time
rhoOpt Parser (TimeSpec -> Process) -> Parser TimeSpec -> Parser Process
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TimeSpec
timeSpec

coalescent :: Parser Process
coalescent :: Parser Process
coalescent = Process -> Parser Process
forall (f :: * -> *) a. Applicative f => a -> f a
pure Process
Coalescent

process :: Parser Process
process :: Parser Process
process =
  Mod CommandFields Process -> Parser Process
forall a. Mod CommandFields a -> Parser a
hsubparser (Mod CommandFields Process -> Parser Process)
-> Mod CommandFields Process -> Parser Process
forall a b. (a -> b) -> a -> b
$
    ( String -> ParserInfo Process -> Mod CommandFields Process
forall a. String -> ParserInfo a -> Mod CommandFields a
command
        String
"birthdeath"
        ( Parser Process -> InfoMod Process -> ParserInfo Process
forall a. Parser a -> InfoMod a -> ParserInfo a
info
            Parser Process
birthDeath
            ( String -> InfoMod Process
forall a. String -> InfoMod a
progDesc String
"Birth and death process"
                InfoMod Process -> InfoMod Process -> InfoMod Process
forall a. Semigroup a => a -> a -> a
<> String -> InfoMod Process
forall a. String -> InfoMod a
footer String
"Height: If no tree height is given, the heights will be randomly drawn from the expected distribution given the number of leaves, the birth and the death rate assuming a uniform prior."
            )
        )
        Mod CommandFields Process
-> Mod CommandFields Process -> Mod CommandFields Process
forall a. Semigroup a => a -> a -> a
<> String -> ParserInfo Process -> Mod CommandFields Process
forall a. String -> ParserInfo a -> Mod CommandFields a
command
          String
"coalescent"
          (Parser Process -> InfoMod Process -> ParserInfo Process
forall a. Parser a -> InfoMod a -> ParserInfo a
info Parser Process
coalescent (String -> InfoMod Process
forall a. String -> InfoMod a
progDesc String
"Coalescent process"))
    )
      Mod CommandFields Process
-> Mod CommandFields Process -> Mod CommandFields Process
forall a. Semigroup a => a -> a -> a
<> String -> Mod CommandFields Process
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PROCESS"
      Mod CommandFields Process
-> Mod CommandFields Process -> Mod CommandFields Process
forall a. Semigroup a => a -> a -> a
<> String -> Mod CommandFields Process
forall a. String -> Mod CommandFields a
commandGroup String
"Available processes:"

subSampleOpt :: Parser (Maybe Double)
subSampleOpt :: Parser (Maybe Time)
subSampleOpt =
  Parser Time -> Parser (Maybe Time)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Time -> Parser (Maybe Time))
-> Parser Time -> Parser (Maybe Time)
forall a b. (a -> b) -> a -> b
$
    ReadM Time -> Mod OptionFields Time -> Parser Time
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Time
forall a. Read a => ReadM a
auto (Mod OptionFields Time -> Parser Time)
-> Mod OptionFields Time -> Parser Time
forall a b. (a -> b) -> a -> b
$
      String -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => String -> Mod f a
long
        String
"sub-sample"
        Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Time
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'u'
        Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"DOUBLE"
        Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields Time
forall a (f :: * -> *). Show a => Mod f a
showDefault
        Mod OptionFields Time
-> Mod OptionFields Time -> Mod OptionFields Time
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Time
forall (f :: * -> *) a. String -> Mod f a
help String
"Perform sub-sampling; see below."

sumStatOpt :: Parser Bool
sumStatOpt :: Parser Bool
sumStatOpt =
  Mod FlagFields Bool -> Parser Bool
switch (Mod FlagFields Bool -> Parser Bool)
-> Mod FlagFields Bool -> Parser Bool
forall a b. (a -> b) -> a -> b
$
    String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"summary-statistics" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> Char -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
's' Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> Mod FlagFields Bool
forall a (f :: * -> *). Show a => Mod f a
showDefault
      Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields Bool
forall (f :: * -> *) a. String -> Mod f a
help
        String
"For each branch, print length and number of children"

-- citation :: String
-- citation =
--   "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"

-- | And a footer.
simulateFooter :: [String]
simulateFooter :: [String]
simulateFooter =
  [ String
"See, for example, 'tlynx simulate birthdeath --help'.",
    String
"Sub-sample with probability p:\n  1. Simulate one big tree with n'=round(n/p), n'>=n, leaves;\n  2. Randomly sample sub trees with n leaves.\n  (With p=1.0, the same tree is reported over and over again.)"
  ]