{-# LANGUAGE DeriveGeneric #-}

-- |
-- Module      :  SLynx.Simulate.Options
-- Description :  ELynxSim argument parsing
-- Copyright   :  2021 Dominik Schrempf
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  dominik.schrempf@gmail.com
-- Stability   :  unstable
-- Portability :  portable
--
-- Creation date: Sun Oct  7 17:29:45 2018.
--
-- Available options:
--   -h,--help                Show this help text
--   -v,--version             Show version
--   -t,--tree-file NAME      Specify tree file NAME
--   -s,--substitution-model MODEL
--                            Set the phylogenetic substitution model; available
--                            models are shown below
--   -m,--mixture-model MODEL Set the phylogenetic mixture model; available models
--                            are shown below
--   -l,--length NUMBER       Set alignment length to NUMBER
--   -e,--edm-file NAME       empirical distribution model file NAME in Phylobayes
--                            format
--   -w,--mixture-model-weights [DOUBLE,DOUBLE,...]
--                            weights of mixture model components
--   -g,--gamma-rate-heterogeneity (NCAT, SHAPE)
--                            number of gamma rate categories and shape parameter
--   -e,--seed [INT]            Set seed for the random number generator; list of 32
--                            bit integers with up to 256 elements (default: [0])
--   -q,--quiet               Be quiet
--   -o,--output-file NAME    Specify output file NAME
module SLynx.Simulate.Options
  ( GammaRateHeterogeneityParams,
    MixtureModelGlobalNormalization (..),
    SimulateArguments (..),
    simulateArguments,
    simulateFooter,
  )
where

import Data.Aeson
import Data.Maybe
  ( fromMaybe,
    maybeToList,
  )
import ELynx.Tools.Options
import ELynx.Tools.Reproduction
import GHC.Generics
import Options.Applicative

-- | Number of gamma rate categories and alpha parameter.
type GammaRateHeterogeneityParams = (Int, Double)

data MixtureModelGlobalNormalization = GlobalNormalization | LocalNormalization
  deriving (Int -> MixtureModelGlobalNormalization -> ShowS
[MixtureModelGlobalNormalization] -> ShowS
MixtureModelGlobalNormalization -> String
(Int -> MixtureModelGlobalNormalization -> ShowS)
-> (MixtureModelGlobalNormalization -> String)
-> ([MixtureModelGlobalNormalization] -> ShowS)
-> Show MixtureModelGlobalNormalization
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MixtureModelGlobalNormalization -> ShowS
showsPrec :: Int -> MixtureModelGlobalNormalization -> ShowS
$cshow :: MixtureModelGlobalNormalization -> String
show :: MixtureModelGlobalNormalization -> String
$cshowList :: [MixtureModelGlobalNormalization] -> ShowS
showList :: [MixtureModelGlobalNormalization] -> ShowS
Show, ReadPrec [MixtureModelGlobalNormalization]
ReadPrec MixtureModelGlobalNormalization
Int -> ReadS MixtureModelGlobalNormalization
ReadS [MixtureModelGlobalNormalization]
(Int -> ReadS MixtureModelGlobalNormalization)
-> ReadS [MixtureModelGlobalNormalization]
-> ReadPrec MixtureModelGlobalNormalization
-> ReadPrec [MixtureModelGlobalNormalization]
-> Read MixtureModelGlobalNormalization
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS MixtureModelGlobalNormalization
readsPrec :: Int -> ReadS MixtureModelGlobalNormalization
$creadList :: ReadS [MixtureModelGlobalNormalization]
readList :: ReadS [MixtureModelGlobalNormalization]
$creadPrec :: ReadPrec MixtureModelGlobalNormalization
readPrec :: ReadPrec MixtureModelGlobalNormalization
$creadListPrec :: ReadPrec [MixtureModelGlobalNormalization]
readListPrec :: ReadPrec [MixtureModelGlobalNormalization]
Read, MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization -> Bool
(MixtureModelGlobalNormalization
 -> MixtureModelGlobalNormalization -> Bool)
-> (MixtureModelGlobalNormalization
    -> MixtureModelGlobalNormalization -> Bool)
-> Eq MixtureModelGlobalNormalization
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization -> Bool
== :: MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization -> Bool
$c/= :: MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization -> Bool
/= :: MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization -> Bool
Eq, (forall x.
 MixtureModelGlobalNormalization
 -> Rep MixtureModelGlobalNormalization x)
-> (forall x.
    Rep MixtureModelGlobalNormalization x
    -> MixtureModelGlobalNormalization)
-> Generic MixtureModelGlobalNormalization
forall x.
Rep MixtureModelGlobalNormalization x
-> MixtureModelGlobalNormalization
forall x.
MixtureModelGlobalNormalization
-> Rep MixtureModelGlobalNormalization x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x.
MixtureModelGlobalNormalization
-> Rep MixtureModelGlobalNormalization x
from :: forall x.
MixtureModelGlobalNormalization
-> Rep MixtureModelGlobalNormalization x
$cto :: forall x.
Rep MixtureModelGlobalNormalization x
-> MixtureModelGlobalNormalization
to :: forall x.
Rep MixtureModelGlobalNormalization x
-> MixtureModelGlobalNormalization
Generic)

instance FromJSON MixtureModelGlobalNormalization

instance ToJSON MixtureModelGlobalNormalization

-- | Arguments needed to simulate sequences.
data SimulateArguments = SimulateArguments
  { SimulateArguments -> String
argsTreeFile :: FilePath,
    SimulateArguments -> Maybe String
argsSubstitutionModelString :: Maybe String,
    SimulateArguments -> Maybe String
argsMixtureModelString :: Maybe String,
    SimulateArguments -> MixtureModelGlobalNormalization
argsMixtureModelGlobalNormalization :: MixtureModelGlobalNormalization,
    SimulateArguments -> Maybe String
argsEDMFile :: Maybe FilePath,
    SimulateArguments -> Maybe [String]
argsSiteprofilesFiles :: Maybe [FilePath],
    SimulateArguments -> Maybe [Double]
argsMixtureWeights :: Maybe [Double],
    SimulateArguments -> Maybe GammaRateHeterogeneityParams
argsGammaParams :: Maybe GammaRateHeterogeneityParams,
    SimulateArguments -> Int
argsLength :: Int,
    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
$c== :: SimulateArguments -> SimulateArguments -> Bool
== :: SimulateArguments -> SimulateArguments -> Bool
$c/= :: SimulateArguments -> SimulateArguments -> Bool
/= :: 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
$cshowsPrec :: Int -> SimulateArguments -> ShowS
showsPrec :: Int -> SimulateArguments -> ShowS
$cshow :: SimulateArguments -> String
show :: SimulateArguments -> String
$cshowList :: [SimulateArguments] -> ShowS
showList :: [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
$cfrom :: forall x. SimulateArguments -> Rep SimulateArguments x
from :: forall x. SimulateArguments -> Rep SimulateArguments x
$cto :: forall x. Rep SimulateArguments x -> SimulateArguments
to :: forall x. Rep SimulateArguments x -> SimulateArguments
Generic)

instance Reproducible SimulateArguments where
  inFiles :: SimulateArguments -> [String]
inFiles SimulateArguments
a =
    SimulateArguments -> String
argsTreeFile SimulateArguments
a
      String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList (SimulateArguments -> Maybe String
argsEDMFile SimulateArguments
a) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] (SimulateArguments -> Maybe [String]
argsSiteprofilesFiles SimulateArguments
a))
  outSuffixes :: SimulateArguments -> [String]
outSuffixes SimulateArguments
_ = [String
".model.gz", String
".fasta"]
  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 = s}
  parser :: Parser SimulateArguments
parser = Parser SimulateArguments
simulateArguments
  cmdName :: String
cmdName = String
"simulate"
  cmdDsc :: [String]
cmdDsc = [String
"Simulate multi sequence alignments."]
  cmdFtr :: [String]
cmdFtr = [String]
simulateFooter

instance FromJSON SimulateArguments

instance ToJSON SimulateArguments

-- | Sub command parser.
simulateArguments :: Parser SimulateArguments
simulateArguments :: Parser SimulateArguments
simulateArguments =
  String
-> Maybe String
-> Maybe String
-> MixtureModelGlobalNormalization
-> Maybe String
-> Maybe [String]
-> Maybe [Double]
-> Maybe GammaRateHeterogeneityParams
-> Int
-> SeedOpt
-> SimulateArguments
SimulateArguments
    (String
 -> Maybe String
 -> Maybe String
 -> MixtureModelGlobalNormalization
 -> Maybe String
 -> Maybe [String]
 -> Maybe [Double]
 -> Maybe GammaRateHeterogeneityParams
 -> Int
 -> SeedOpt
 -> SimulateArguments)
-> Parser String
-> Parser
     (Maybe String
      -> Maybe String
      -> MixtureModelGlobalNormalization
      -> Maybe String
      -> Maybe [String]
      -> Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
treeFileOpt
    Parser
  (Maybe String
   -> Maybe String
   -> MixtureModelGlobalNormalization
   -> Maybe String
   -> Maybe [String]
   -> Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser (Maybe String)
-> Parser
     (Maybe String
      -> MixtureModelGlobalNormalization
      -> Maybe String
      -> Maybe [String]
      -> Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe String)
phyloSubstitutionModelOpt
    Parser
  (Maybe String
   -> MixtureModelGlobalNormalization
   -> Maybe String
   -> Maybe [String]
   -> Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser (Maybe String)
-> Parser
     (MixtureModelGlobalNormalization
      -> Maybe String
      -> Maybe [String]
      -> Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe String)
phyloMixtureModelOpt
    Parser
  (MixtureModelGlobalNormalization
   -> Maybe String
   -> Maybe [String]
   -> Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser MixtureModelGlobalNormalization
-> Parser
     (Maybe String
      -> Maybe [String]
      -> Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser MixtureModelGlobalNormalization
globalNormalizationFlag
    Parser
  (Maybe String
   -> Maybe [String]
   -> Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser (Maybe String)
-> Parser
     (Maybe [String]
      -> Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe String)
maybeEDMFileOpt
    Parser
  (Maybe [String]
   -> Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser (Maybe [String])
-> Parser
     (Maybe [Double]
      -> Maybe GammaRateHeterogeneityParams
      -> Int
      -> SeedOpt
      -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe [String])
maybeSiteprofilesFilesOpt
    Parser
  (Maybe [Double]
   -> Maybe GammaRateHeterogeneityParams
   -> Int
   -> SeedOpt
   -> SimulateArguments)
-> Parser (Maybe [Double])
-> Parser
     (Maybe GammaRateHeterogeneityParams
      -> Int -> SeedOpt -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe [Double])
maybeMixtureWeights
    Parser
  (Maybe GammaRateHeterogeneityParams
   -> Int -> SeedOpt -> SimulateArguments)
-> Parser (Maybe GammaRateHeterogeneityParams)
-> Parser (Int -> SeedOpt -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe GammaRateHeterogeneityParams)
maybeGammaParams
    Parser (Int -> SeedOpt -> SimulateArguments)
-> Parser Int -> Parser (SeedOpt -> SimulateArguments)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int
lengthOpt
    Parser (SeedOpt -> SimulateArguments)
-> Parser SeedOpt -> Parser SimulateArguments
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser SeedOpt
seedOpt

treeFileOpt :: Parser FilePath
treeFileOpt :: Parser String
treeFileOpt =
  Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$
    String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"tree-file"
      Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
't'
      Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"Name"
      Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help
        String
"Read tree from Newick file NAME"

phyloSubstitutionModelOpt :: Parser (Maybe String)
phyloSubstitutionModelOpt :: Parser (Maybe String)
phyloSubstitutionModelOpt =
  Parser String -> Parser (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser String -> Parser (Maybe String))
-> Parser String -> Parser (Maybe String)
forall a b. (a -> b) -> a -> b
$
    Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$
      String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"substitution-model"
        Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
's'
        Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"MODEL"
        Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help
          String
"Set the phylogenetic substitution model; available models are shown below (mutually exclusive with -m option)"

phyloMixtureModelOpt :: Parser (Maybe String)
phyloMixtureModelOpt :: Parser (Maybe String)
phyloMixtureModelOpt =
  Parser String -> Parser (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser String -> Parser (Maybe String))
-> Parser String -> Parser (Maybe String)
forall a b. (a -> b) -> a -> b
$
    Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
      ( String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"mixture-model"
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'm'
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"MODEL"
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help
            String
"Set the phylogenetic mixture model; available models are shown below (mutually exclusive with -s option)"
      )

globalNormalizationFlag :: Parser MixtureModelGlobalNormalization
globalNormalizationFlag :: Parser MixtureModelGlobalNormalization
globalNormalizationFlag =
  MixtureModelGlobalNormalization
-> MixtureModelGlobalNormalization
-> Mod FlagFields MixtureModelGlobalNormalization
-> Parser MixtureModelGlobalNormalization
forall a. a -> a -> Mod FlagFields a -> Parser a
flag
    MixtureModelGlobalNormalization
LocalNormalization
    MixtureModelGlobalNormalization
GlobalNormalization
    ( String -> Mod FlagFields MixtureModelGlobalNormalization
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"global-normalization"
        Mod FlagFields MixtureModelGlobalNormalization
-> Mod FlagFields MixtureModelGlobalNormalization
-> Mod FlagFields MixtureModelGlobalNormalization
forall a. Semigroup a => a -> a -> a
<> Char -> Mod FlagFields MixtureModelGlobalNormalization
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'n'
        Mod FlagFields MixtureModelGlobalNormalization
-> Mod FlagFields MixtureModelGlobalNormalization
-> Mod FlagFields MixtureModelGlobalNormalization
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields MixtureModelGlobalNormalization
forall (f :: * -> *) a. String -> Mod f a
help String
"Normalize mixture model globally (one normalization constant for all components)"
    )

maybeEDMFileOpt :: Parser (Maybe FilePath)
maybeEDMFileOpt :: Parser (Maybe String)
maybeEDMFileOpt =
  Parser String -> Parser (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser String -> Parser (Maybe String))
-> Parser String -> Parser (Maybe String)
forall a b. (a -> b) -> a -> b
$
    Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
      ( String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"edm-file"
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'e'
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"NAME"
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help
            String
"Empirical distribution model file NAME in Phylobayes format"
      )

maybeSiteprofilesFilesOpt :: Parser (Maybe [FilePath])
maybeSiteprofilesFilesOpt :: Parser (Maybe [String])
maybeSiteprofilesFilesOpt =
  Parser [String] -> Parser (Maybe [String])
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser [String] -> Parser (Maybe [String]))
-> Parser [String] -> Parser (Maybe [String])
forall a b. (a -> b) -> a -> b
$
    String -> [String]
words
      (String -> [String]) -> Parser String -> Parser [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
        ( String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"siteprofile-files"
            Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
            Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"NAMES"
            Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help
              String
"File names of site profiles in Phylobayes format"
        )

maybeMixtureWeights :: Parser (Maybe [Double])
maybeMixtureWeights :: Parser (Maybe [Double])
maybeMixtureWeights =
  Parser [Double] -> Parser (Maybe [Double])
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser [Double] -> Parser (Maybe [Double]))
-> Parser [Double] -> Parser (Maybe [Double])
forall a b. (a -> b) -> a -> b
$
    ReadM [Double] -> Mod OptionFields [Double] -> Parser [Double]
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM [Double]
forall a. Read a => ReadM a
auto
      ( String -> Mod OptionFields [Double]
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"mixture-model-weights"
          Mod OptionFields [Double]
-> Mod OptionFields [Double] -> Mod OptionFields [Double]
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields [Double]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'w'
          Mod OptionFields [Double]
-> Mod OptionFields [Double] -> Mod OptionFields [Double]
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields [Double]
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"\"[DOUBLE,DOUBLE,...]\""
          Mod OptionFields [Double]
-> Mod OptionFields [Double] -> Mod OptionFields [Double]
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields [Double]
forall (f :: * -> *) a. String -> Mod f a
help String
"Weights of mixture model components"
      )

maybeGammaParams :: Parser (Maybe GammaRateHeterogeneityParams)
maybeGammaParams :: Parser (Maybe GammaRateHeterogeneityParams)
maybeGammaParams =
  Parser GammaRateHeterogeneityParams
-> Parser (Maybe GammaRateHeterogeneityParams)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser GammaRateHeterogeneityParams
 -> Parser (Maybe GammaRateHeterogeneityParams))
-> Parser GammaRateHeterogeneityParams
-> Parser (Maybe GammaRateHeterogeneityParams)
forall a b. (a -> b) -> a -> b
$
    ReadM GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
-> Parser GammaRateHeterogeneityParams
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
      ReadM GammaRateHeterogeneityParams
forall a. Read a => ReadM a
auto
      ( String -> Mod OptionFields GammaRateHeterogeneityParams
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"gamma-rate-heterogeneity"
          Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields GammaRateHeterogeneityParams
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'g'
          Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields GammaRateHeterogeneityParams
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"\"(NCAT,SHAPE)\""
          Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
-> Mod OptionFields GammaRateHeterogeneityParams
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields GammaRateHeterogeneityParams
forall (f :: * -> *) a. String -> Mod f a
help String
"Number of gamma rate categories and shape parameter"
      )

lengthOpt :: Parser Int
lengthOpt :: Parser Int
lengthOpt =
  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
    ( String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"length"
        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
'l'
        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
"NUMBER"
        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
"Set alignment length to NUMBER"
    )

-- | The model specification is somewhat complicated, so we need to provide
-- additional help.
simulateFooter :: [String]
simulateFooter :: [String]
simulateFooter = [String]
sms [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
mms
  where
    sms :: [String]
sms =
      [ String
"Substitution models:",
        String
"-s \"MODEL[PARAMETER,PARAMETER,...]{STATIONARY_DISTRIBUTION}\"",
        String
"   Supported DNA models: JC, F81, HKY, GTR4.",
        String
"     For example,",
        String
"       -s HKY[KAPPA]{DOUBLE,DOUBLE,DOUBLE,DOUBLE}",
        String
"       -s GTR4[e_AC,e_AG,e_AT,e_CG,e_CT,e_GT]{DOUBLE,DOUBLE,DOUBLE,DOUBLE}",
        String
"          where the 'e_XY' are the exchangeabilities from nucleotide X to Y.",
        String
"   Supported Protein models: Poisson, Poisson-Custom, LG, LG-Custom, WAG, WAG-Custom, GTR20.",
        String
"     MODEL-Custom means that only the exchangeabilities of MODEL are used,",
        String
"     and a custom stationary distribution is provided.",
        String
"     For example,",
        String
"       -s LG",
        String
"       -s LG-Custom{...}",
        String
"       -s GTR20[e_AR,e_AN,...]{...}",
        String
"          the 'e_XY' are the exchangeabilities from amino acid X to Y (alphabetical order).",
        String
"   Notes: The F81 model for DNA is equivalent to the Poisson-Custom for proteins.",
        String
"          The GTR4 model for DNA is equivalent to the GTR20 for proteins."
      ]
    mms :: [String]
mms =
      [ String
"",
        String
"Mixture models:",
        String
"-m \"MIXTURE(SUBSTITUTION_MODEL_1,SUBSTITUTION_MODEL_2[PARAMETERS]{STATIONARY_DISTRIBUTION},...)\"",
        String
"   For example,",
        String
"     -m \"MIXTURE(JC,HKY[6.0]{0.3,0.2,0.2,0.3})\"",
        String
"Mixture weights have to be provided with the -w option.",
        String
"",
        String
"Special mixture models:",
        String
"-m CXX",
        String
"   where XX is 10, 20, 30, 40, 50, or 60; CXX models, Quang et al., 2008.",
        String
"-m \"EDM(EXCHANGEABILITIES)\"",
        String
"   Arbitrary empirical distribution mixture (EDM) models.",
        String
"   Stationary distributions have to be provided with the -e or -p option.",
        String
"   For example,",
        String
"     LG exchangeabilities with stationary distributions given in FILE.",
        String
"     -m \"EDM(LG-Custom)\" -e FILE",
        String
"     LG exchangeabilities with site profiles (Phylobayes) given in FILES.",
        String
"     -m \"EDM(LG-Custom)\" -p FILES",
        String
"For special mixture models, mixture weights are optional."
      ]