diff --git a/.gitmodules b/.gitmodules index 0d75e08..a3d11e6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "demon_model"] path = resources/demon_model url = https://github.com/robjohnnoble/demon_model +[submodule "demonanalysis"] + path = resources/demonanalysis + url = https://github.com/robjohnnoble/demonanalysis diff --git a/prepare-environments.sh b/prepare-environments.sh new file mode 100644 index 0000000..a54c051 --- /dev/null +++ b/prepare-environments.sh @@ -0,0 +1,36 @@ +############################################################################### +# +# Create internal conda envs with all dependencies +# +# AUTHOR: Maciej_Bak +# CONTACT: wsciekly.maciek@gmail.com +# +############################################################################### + +snakemake \ + --snakefile="workflow/Snakefile" \ + --configfile="tests/localtest/config-template.yml" \ + --config workflow_repo_path="$PWD" \ + --config workflow_analysis_outdir="$PWD/tests/localtest/output" \ + --use-conda \ + --conda-create-envs-only \ + --cores 1 \ + --nolock \ + all + +for file in .snakemake/conda/*.yaml; do + if [ -f "$file" ]; then + if grep -q "name: warlock-r" "$file"; then + ENVPATH="${file%.yaml}" + break + fi + fi +done + +eval "$(conda shell.bash hook)" +conda deactivate +conda activate $ENVPATH + +# strange error often appears, installation needs to be called twice +Rscript -e "devtools::install('resources/demonanalysis', upgrade=TRUE)" +Rscript -e "devtools::install('resources/demonanalysis', upgrade=TRUE)" diff --git a/tests/localtest/config-template.yml b/tests/localtest/config-template.yml index 9a985d8..79f4d42 100644 --- a/tests/localtest/config-template.yml +++ b/tests/localtest/config-template.yml @@ -25,7 +25,7 @@ workflow_analysis_outdir: "{{ WORKFLOW_REPO_PATH }}/tests/localtest/output" ### DEMON PARAMETERS ### # spatial_structure -demon_log2_deme_carrying_capacity: 8 +demon_log2_deme_carrying_capacity: [8, 9, 10] # dispersal demon_migration_type: 0 @@ -34,13 +34,13 @@ demon_migration_edge_only: 1 demon_migration_rate_scales_with_K: 1 # mutation_rates -demon_mu_driver_birth: "1e-05" -demon_mu_passenger: 0.001 -demon_mu_driver_migration: 0.01 +demon_mu_driver_birth: "5e-06" +demon_mu_passenger: 0.1 +demon_mu_driver_migration: 0 demon_passenger_pop_threshold: -1 # fitness_effects -demon_normal_birth_rate: [0.8, 0.9] +demon_normal_birth_rate: 0.8 demon_baseline_death_rate: 0 demon_s_driver_birth: 0.1 demon_s_passenger: 0 @@ -51,7 +51,7 @@ demon_max_relative_migration_rate: 10 # non_biological_parameters demon_init_pop: 1 demon_matrix_max: -1 -demon_max_pop: 1000000 +demon_max_pop: 100000 demon_max_time: 86400 demon_max_generations: 2000 demon_seed: 10 diff --git a/warlock.sh b/warlock.sh index f560703..7229959 100644 --- a/warlock.sh +++ b/warlock.sh @@ -114,12 +114,17 @@ if [ -z "$CORES" ]; then CORES=1 fi +# in order to use R from conda-forge I need to set these env variables: +LANG=en_US.UTF-8 +LC_ALL=en_US.UTF-8 + # select a proper smk profile based on the command line args case "$ENV" in local) snakemake \ --configfile="$CONFIGFILE" \ --profile="workflow/profiles/local" \ + --use-conda \ --cores="$CORES" \ --nolock \ all @@ -128,6 +133,7 @@ case "$ENV" in snakemake \ --configfile="$CONFIGFILE" \ --profile="workflow/profiles/slurm" \ + --use-conda \ --cores="$CORES" \ --nolock \ all diff --git a/workflow/Snakefile b/workflow/Snakefile index fdc1366..59ca1b9 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -166,7 +166,6 @@ rule run_demon: ) params: - STR_runID = "{runID}", LOG_cluster_log = os.path.join( "{outdir}", "logs", @@ -220,15 +219,90 @@ rule run_demon: """ +rule generate_summary_plots: + """ + Generate per-simulation summary plots with 'demonanalysis' pkg. + """ + input: + DIR_simulations_outdir = os.path.join( + "{outdir}", + "simulations", + "{runID}" + ), + SCRIPT_generate_summary_plots = os.path.join( + config["workflow_repo_path"], + "workflow", + "scripts", + "generate-summary-plots.R", + ) + + output: + DIR_analyses_outdir = directory( + os.path.join( + "{outdir}", + "analyses", + "{runID}" + ) + ) + + params: + LOG_cluster_log = os.path.join( + "{outdir}", + "logs", + "{runID}", + "generate_summary_plots.cluster.log" + ) + + threads: 1 + + log: + LOG_local_stdout = os.path.join( + "{outdir}", + "logs", + "{runID}", + "generate_summary_plots.stdout.log" + ), + LOG_local_stderr = os.path.join( + "{outdir}", + "logs", + "{runID}", + "generate_summary_plots.stderr.log" + ) + + benchmark: + os.path.join( + "{outdir}", + "logs", + "{runID}", + "generate_summary_plots.benchmark.log" + ) + + conda: + "envs/warlock-r.yml" + + shell: + """ + (mkdir -p {output.DIR_analyses_outdir} \ + && \ + sleep 5 \ + && \ + Rscript {input.SCRIPT_generate_summary_plots} \ + --input {input.DIR_simulations_outdir} \ + --output {output.DIR_analyses_outdir}) \ + 1> {log.LOG_local_stdout} \ + 2> {log.LOG_local_stderr} + """ + + rule all: """ Target rule gathering final output of the workflow. """ input: - DIR_simulations_outdir = expand( + DIR_analyses_outdir = expand( os.path.join( "{outdir}", - "simulations", + "analyses", "{runID}" ), outdir = config["workflow_analysis_outdir"], diff --git a/workflow/envs/warlock-r.yml b/workflow/envs/warlock-r.yml new file mode 100644 index 0000000..829e505 --- /dev/null +++ b/workflow/envs/warlock-r.yml @@ -0,0 +1,27 @@ +############################################################################### +# +# AUTHOR: Maciej_Bak +# CONTACT: wsciekly.maciek@gmail.com +# +############################################################################### +--- + + name: warlock-r + + channels: + - conda-forge + + dependencies: + - cmake=3.26.4 + - compilers=1.3.0 + - graphviz=2.50.0 + - r-base=3.6.3 + - r-devtools=2.4.1 + - r-dplyr=1.0.6 + - r-foreign=0.8_76 + - r-ggplot2=3.3.3 + - r-optparse=1.6.6 + - r-readr=1.4.0 + - r-rvaidememoire=0.9_79 + +... diff --git a/workflow/scripts/generate-summary-plots.R b/workflow/scripts/generate-summary-plots.R new file mode 100644 index 0000000..7e32c40 --- /dev/null +++ b/workflow/scripts/generate-summary-plots.R @@ -0,0 +1,74 @@ +############################################################################### +# +# Small wrapper to plot all Muller plots for warlock simulations. +# +# AUTHOR: Maciek Bak +# AFFILIATION: City, University of London +# CONTACT: wsciekly.maciek@gmail.com +# CREATED: 23.11.2022 +# LICENSE: Apache_2.0 +# +############################################################################### + +Sys.setenv("LANGUAGE"="EN") + +# by default: suppress warnings +options(warn = -1) + +# load libraries +suppressPackageStartupMessages(suppressWarnings(library(demonanalysis))) +suppressPackageStartupMessages(suppressWarnings(library(optparse))) + +# list the command-line arguments +option_list <- list( + make_option(c("--input"), + action = "store_true", + dest = "input_directory", + type = "character", + help = "Path to the warlock output directory." + ), + make_option(c("--output"), + action = "store_true", + dest = "output_directory", + type = "character", + help = "Path for the output directory with plots." + ), + make_option(c("--help"), + action = "store_true", + dest = "help", + type = "logical", + default = FALSE, + help = "Show this information and exit." + ), + make_option(c("--verbose"), + action = "store_true", + dest = "verbose", + type = "logical", + default = FALSE, + help = "Run in verbose mode." + ) +) + +# parse command-line arguments +opt_parser <- OptionParser( + usage = "Usage: %prog [OPTIONS] --message [STRING]", + option_list = option_list, + add_help_option = FALSE, + description = "" +) +opt <- parse_args(opt_parser) + +# if verbose flag was set: print warnings +if (opt$verbose) { + options(warn = 0) +} + +############################################################################### +# MAIN +############################################################################### + +plot_all_images( + path = opt$input_directory, + output_filename = "muller", + output_dir = opt$output_directory +)