Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
xin-huang committed Apr 23, 2024
1 parent 57b9ab2 commit 3521287
Show file tree
Hide file tree
Showing 3 changed files with 375 additions and 9 deletions.
22 changes: 21 additions & 1 deletion dadi_cli/__main__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import argparse
from dadi_cli.parsers.generate_fs_parsers import add_generate_fs_parsers
from dadi_cli.parsers.generate_cache_parsers import add_generate_cache_parsers
from dadi_cli.parsers.simulate_dm_parsers import add_simulate_dm_parsers
from dadi_cli.parsers.simulate_dfe_parsers import add_simulate_dfe_parsers
from dadi_cli.parsers.simulate_demes_parsers import add_simulate_demes_parsers
from dadi_cli.parsers.infer_dm_parsers import add_infer_dm_parsers
from dadi_cli.parsers.infer_dfe_parsers import add_infer_dfe_parsers
from dadi_cli.parsers.plot_parsers import add_plot_parsers
from dadi_cli.parsers.stat_dm_parsers import add_stat_dm_parsers
from dadi_cli.parsers.stat_dfe_parsers import add_stat_dfe_parsers
from dadi_cli.parsers.bestfit_parsers import add_bestfit_parsers
from dadi_cli.parsers.model_parsers import add_model_parsers
from dadi_cli.parsers.pdf_parsers import add_pdf_parsers


def _set_sigpipe_handler() -> None:
Expand All @@ -18,7 +28,7 @@ def _set_sigpipe_handler() -> None:
def _dadi_cli_parser() -> argparse.ArgumentParser:
"""
Initializes and configures the command-line interface parser
for gita.
for dadi-cli.
Returns
-------
Expand All @@ -31,7 +41,17 @@ def _dadi_cli_parser() -> argparse.ArgumentParser:
subparsers.required = True
add_generate_fs_parsers(subparsers)
add_generate_cache_parsers(subparsers)
add_simulate_dm_parsers(subparsers)
add_simulate_dfe_parsers(subparsers)
add_simulate_demes_parsers(subparsers)
add_infer_dm_parsers(subparsers)
add_infer_dfe_parsers(subparsers)
add_plot_parsers(subparsers)
add_stat_dm_parsers(subparsers)
add_stat_dfe_parsers(subparsers)
add_bestfit_parsers(subparsers)
add_model_parsers(subparsers)
add_pdf_parsers(subparsers)

return top_parser

Expand Down
305 changes: 305 additions & 0 deletions dadi_cli/parsers/common_arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
import argparse


def add_output_argument(parser):
parser.add_argument(
"--output", type=str, required=True, help="Name of the output file."
)


def add_bounds_argument(parser):
# Check that the model is not a standard neutral model
if 'snm_1d' not in sys.argv and 'snm_2d' not in sys.argv:
boundary_req = True
else:
if '--nomisid' in sys.argv:
boundary_req = False
else:
boundary_req = True
parser.add_argument(
"--lbounds",
type=float,
nargs="+",
required=boundary_req,
help="Lower bounds of the optimized parameters.",
)
parser.add_argument(
"--ubounds",
type=float,
nargs="+",
required=boundary_req,
help="Upper bounds of the optimized parameters.",
)


def add_demo_popt_argument(parser):
# Check that the model is not a standard neutral model
bestfit_req = False
if 'equil' not in sys.argv:
bestfit_req = True
parser.add_argument(
"--demo-popt",
type=str,
required=bestfit_req,
help="File containing the bestfit parameters for the demographic model.",
dest="demo_popt",
)


def add_grids_argument(parser):
parser.add_argument(
"--grids",
type=_check_positive_int,
nargs=3,
help="Sizes of grids. Default is based on sample size.",
)


def add_misid_argument(parser):
# Note that the code previously had a --misid function that did the opposite, but this ia more sensible default.
parser.add_argument(
"--nomisid",
default=False,
action="store_true",
help="Enable to *not* include a parameter modeling ancestral state misidentification when data are polarized.",
)


def add_model_argument(parser):
# Because most of the functions for Plot
# do not require a model, we make it
# conditionally required.
req_model_arg = True
if 'Plot' in sys.argv:
req_model_arg = False
parser.add_argument(
"--model",
type=str,
required=req_model_arg,
help="Name of the demographic model. To check available demographic models, please use `dadi-cli Model`.",
)
parser.add_argument(
"--model-file",
type=str,
required=False,
dest="model_file",
help="Name of python module file (not including .py) that contains custom models to use. Can be an HTML link. Default: None.",
)


def add_fs_argument(parser):
parser.add_argument(
"--fs",
type=str,
required=True,
help="Frequency spectrum of mutations used for inference. To generate the frequency spectrum, please use `dadi-cli GenerateFs`. Can be an HTML link.",
)


def add_seed_argument(parser):
parser.add_argument("--seed", type=_check_positive_int, help="Random seed.")


def add_constant_argument(parser):
parser.add_argument(
"--constants",
default=-1,
type=float,
nargs="+",
help="Fixed parameters during the inference or using Godambe analysis. Use -1 to indicate a parameter is NOT fixed. Default: None.",
)


def add_delta_ll_argument(parser):
parser.add_argument(
"--delta-ll",
type=_check_positive_num,
required=False,
dest="delta_ll",
default=0.0001,
help="When using --check-convergence argument in InferDM or InferDFE modules or the BestFits module, set the max percentage difference for log-likliehoods compared to the best optimization log-likliehood to be consider convergent (with 1 being 100%% difference to the best optimization's log-likelihood). Default: 0.0001.",
)


def add_sample_sizes_argument(parser):
parser.add_argument(
"--sample-sizes",
type=_check_positive_int,
nargs="+",
required=True,
help="Sample sizes of populations.",
dest="sample_sizes",
)


def add_eps_argument(parser):
parser.add_argument(
"--eps",
default=[0.1, 0.01, 0.001],
type=_check_nonnegative_float,
nargs="+",
required=False,
help="Step sizes to try for Godambe analysis. Default: [0.1, 0.01, 0.001]",
)


def add_popt_argument(parser):
parser.add_argument(
"--demo-popt",
type=str,
dest="demo_popt",
help="File containing the bestfit demographic parameters, generated by `dadi-cli BestFit`.",
)
parser.add_argument(
"--dfe-popt",
type=str,
dest="dfe_popt",
help="File containing the bestfit DFE parameters, generated by `dadi-cli BestFit`.",
)


def add_dfe_argument(parser):
parser.add_argument(
"--cache1d",
type=str,
help="File name of the 1D DFE cache. To generate the cache, please use `dadi-cli GenerateCache`.",
)
parser.add_argument(
"--cache2d",
type=str,
help="File name of the 2D DFE cache. To generate the cache, please use `dadi-cli GenerateCache`.",
)
parser.add_argument(
"--pdf1d",
type=str,
help="1D probability density function for the DFE inference. To check available probability density functions, please use `dadi-cli Pdf`.",
)
parser.add_argument(
"--pdf2d",
type=str,
help="2D probability density function for the joint DFE inference. To check available probability density functions, please use `dadi-cli Pdf`.",
)


# Currently this command is only needed for param_names.
def add_mix_pdf_argument(parser):
parser.add_argument(
"--mix-pdf",
dest="mix_pdf",
type=str,
default=None,
help="If you are using a model that is a mixture of probability density function for the joint DFE inference pass in the model name. To check available probability density functions, please use `dadi-cli Pdf`.",
)


def add_inference_argument(parser):
parser.add_argument(
"--p0",
default=-1,
type=float,
nargs="+",
required=False,
help="Initial parameter values for inference.",
)
parser.add_argument(
"--output-prefix",
type=str,
required=True,
dest="output_prefix",
help="Prefix for output files, which will be named <output_prefix>.InferDM.opts.<N>, where N is an increasing integer (to avoid overwriting existing files).",
)
parser.add_argument(
"--optimizations",
default=100,
type=_check_positive_int,
help="Total number of optimizations to run. Default: 100.",
)
parser.add_argument(
"--check-convergence",
default=0,
type=_check_positive_int,
dest="check_convergence",
help="Start checking for convergence after a chosen number of optimizations. Optimization runs will stop early if convergence criteria are reached. BestFit results file will be call <output_prefix>.InferDM.bestfits. Convergence not checked by default.",
)
parser.add_argument(
"--force-convergence",
default=0,
type=_check_positive_int,
dest="force_convergence",
help="Start checking for convergence after a chosen number of optimizations. Optimization runs will continue until convergence criteria is reached (--optimizations flag will be ignored). BestFit results file will be call <output_prefix>.InferDM.bestfits. Convergence not checked by default.",
)
parser.add_argument(
"--work-queue",
nargs=2,
default=[],
action="store",
dest="work_queue",
help="Enable Work Queue. Additional arguments are the WorkQueue project name, the name of the password file.",
)
parser.add_argument(
"--port",
default=9123,
type=_check_positive_int,
dest="port",
help="Choose a specific port for Work Queue communication. Default 9123.",
)
parser.add_argument(
"--debug-wq",
default=False,
action="store_true",
dest="debug_wq",
help='Store debug information from WorkQueue to a file called "debug.log". Default: False.',
)
parser.add_argument(
"--maxeval",
type=_check_positive_int,
default=False,
help="Max number of parameter set evaluations tried for optimizing demography. Default: Number of parameters multiplied by 100.",
)
parser.add_argument(
"--maxtime",
type=_check_positive_int,
default=np.inf,
help="Max amount of time for optimizing demography. Default: infinite.",
)
parser.add_argument(
"--cpus",
type=_check_nonnegative_int,
default=multiprocessing.cpu_count(),
help="Number of CPUs to use in multiprocessing. Default: All available CPUs.",
)
parser.add_argument(
"--gpus",
type=_check_nonnegative_int,
default=0,
help="Number of GPUs to use in multiprocessing. Default: 0.",
)
parser.add_argument(
"--bestfit-p0-file",
type=str,
dest="bestfit_p0",
help="Pass in a .bestfit or .opt.<N> file name to cycle --p0 between up to the top 10 best fits for each optimization."
)


def add_p0_argument(parser):
p0_req = False
if 'snm_1d' not in sys.argv and 'snm_2d' not in sys.argv:
p0_req = True
else:
if '--nomisid' not in sys.argv:
p0_req = True

parser.add_argument(
"--p0",
type=float,
nargs="+",
required=p0_req,
help="Parameters for simulated demography or dfe.",
)


def make_dir(path):
parent_dir = os.path.dirname(path)
if parent_dir != '':
os.makedirs(parent_dir, exist_ok=True)
Loading

0 comments on commit 3521287

Please sign in to comment.