From 96779b8090f22419d139c4f11d87bfbee42eaa57 Mon Sep 17 00:00:00 2001 From: AdrienLeGuillou Date: Tue, 7 Nov 2023 13:50:45 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20EpiModel?= =?UTF-8?q?/swfcalib@3b65c12a25aaae7c6a0c871ba03a1113a1e5fc5b=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- articles/swfcalib.html | 32 ++++++++++++++++---------------- pkgdown.yml | 2 +- search.json | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/articles/swfcalib.html b/articles/swfcalib.html index 0dd13a6..45841c1 100644 --- a/articles/swfcalib.html +++ b/articles/swfcalib.html @@ -89,9 +89,9 @@

The modelest <- readRDS("data/input/netest.rds") param <- param.net( - data.frame.params = read.csv("data/input/params.csv"), - netstats = netstats, - epistats = epistats + data.frame.params = read.csv("data/input/params.csv"), + netstats = netstats, + epistats = epistats ) init <- init_msm() @@ -360,9 +360,9 @@

Implementing the model fun est <- readRDS("data/input/netest.rds") param <- param.net( - data.frame.params = read.csv("data/input/params.csv"), - netstats = netstats, - epistats = epistats + data.frame.params = read.csv("data/input/params.csv"), + netstats = netstats, + epistats = epistats ) init <- init_msm() @@ -459,12 +459,12 @@

Configuration= n_sims, max_iteration = 100, default_proposal = dplyr::tibble( - hiv.test.rate_1 = 0.004123238, - hiv.test.rate_2 = 0.003771226, - hiv.test.rate_3 = 0.005956663, - tx.init.rate_1 = 0.2981623, - tx.init.rate_2 = 0.3680919, - tx.init.rate_3 = 0.358254, + hiv.test.rate_1 = 0.004123238, + hiv.test.rate_2 = 0.003771226, + hiv.test.rate_3 = 0.005956663, + tx.init.rate_1 = 0.2981623, + tx.init.rate_2 = 0.3680919, + tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 @@ -715,9 +715,9 @@

Running a calibration systemest <- readRDS("data/input/netest.rds") param <- param.net( - data.frame.params = read.csv("data/input/params.csv"), - netstats = netstats, - epistats = epistats + data.frame.params = read.csv("data/input/params.csv"), + netstats = netstats, + epistats = epistats ) init <- init_msm() @@ -842,7 +842,7 @@

Running a calibration systemhpc_configs <- EpiModelHPC::swf_configs_rsph( partition = "epimodel", r_version = "4.3", - mail_user = "user@emory.edu" + mail_user = "<your_user>@emory.edu" ) wf <- create_workflow( diff --git a/pkgdown.yml b/pkgdown.yml index 88cab65..db78058 100644 --- a/pkgdown.yml +++ b/pkgdown.yml @@ -3,7 +3,7 @@ pkgdown: 2.0.7 pkgdown_sha: ~ articles: swfcalib: swfcalib.html -last_built: 2023-11-07T13:19Z +last_built: 2023-11-07T13:50Z urls: reference: https://epimodel.github.io/swfcalib/reference article: https://epimodel.github.io/swfcalib/articles diff --git a/search.json b/search.json index 7bfddb1..a21e686 100644 --- a/search.json +++ b/search.json @@ -1 +1 @@ -[{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"the-model","dir":"Articles","previous_headings":"","what":"The model","title":"swfcalib","text":"single run model locally looks like : example, need load EpiModelHIV package, read 4 files located “data/input” folder pass 4 parameters netsim function. result, stored sim variable directly usable swfcalib.","code":"library(EpiModelHIV) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # The actual simulation happens here sim <- netsim(est, param, init, control)"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-parameters-and-outputs","dir":"Articles","previous_headings":"","what":"Calibration parameters and outputs","title":"swfcalib","text":"example, focus 9 parameters calibrate 9 outputs fit targets. many parameters model. get values literature, free parameters calibrated ignored sake simplicity example.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"outputs","dir":"Articles","previous_headings":"Calibration parameters and outputs","what":"Outputs","title":"swfcalib","text":"first outputs proportion HIV individuals diagnosed (.e. aware status). proportion HIV diagnosed started treatment less month diagnosis. Finally, prevalence diagnosed HIV population final output interest. population race stratified , black, hispanic white, get three time number outputs.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"parameters","dir":"Articles","previous_headings":"Calibration parameters and outputs","what":"Parameters","title":"swfcalib","text":"9 parameters calibrated fit model target values: weekly probability tested HIV. weekly probability starting treatment diagnosed HIV. transmission scaler parameter encompass mechanism affecting transmission explicitly defined model.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"relationship-between-parameters-and-outputs","dir":"Articles","previous_headings":"","what":"Relationship between parameters and outputs","title":"swfcalib","text":"Simply looking , can see parameters relate outputs way. hiv.test.rate parameters directly relate cc.dx outputs (proportion) diagnosed. Also, parameter list affect outcomes. Therefore, 3 one one relationship. race, test rate govern diagnosed proportion. similar situation can described linkage care (cc.linked1m) treatment start rate tx.init.rate. (denominator number diagnosed individuals, making independent cc.dx). prevalence (.prev.dx), hand, depends 9 parameters. proportion diagnosed influences number treated influences number individuals able transmit. scalers affect directly transmission one population. modify prevalence, also indirectly influence transmission sub populations. However, hiv.test.rate tx.init.rate calibrated values fixed, .prev.dx depends hiv.trans.scale parameters. Reducing 9 parameters 3 outputs problem simpler 3 parameters, 3 outputs one. following graph illustrate relationships. Parameters - Output relationship","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-structure","dir":"Articles","previous_headings":"","what":"Calibration structure","title":"swfcalib","text":"Knowing parameters - outputs relationship, can define calibration structure minimize number simulations required. first wave calibrate simultaneously 3 hiv.test.rate 3 tx.init.rate parameters. means run simulation test value 6 parameters. idea similar factorial experiment design possible independence parameters respective outcomes. 6 parameters calibrated (.e. given fixed final values), hiv.trans.scale parameters calibrated fit .prev.dx outcomes target values.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves-and-jobs","dir":"Articles","previous_headings":"","what":"Waves and jobs","title":"swfcalib","text":"express structure, need define calibration jobs going run parallel within several waves. example two waves, first one hiv.test.rate tx.init.rate parameters second hiv.trans.scale parameters.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"jobs","dir":"Articles","previous_headings":"Waves and jobs","what":"Jobs","title":"swfcalib","text":"Formally, swfcalib defines job set parameters calibrated trying make set outcomes reach set targets. job needs function make next set parameter proposals test well function checking proposals gave sufficiently good results. latter function charge stopping calibration process current job.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves","dir":"Articles","previous_headings":"Waves and jobs","what":"Waves","title":"swfcalib","text":"wave set multiple jobs can run parallel (.e. independent one another). practice, swfcalib takes proposals jobs wave, combine run one simulation per proposal. 3 job wave, making 10 proposal, 10 simulations run. evaluation step job assess quality ’s outcomes. jobs wave finished, system moves next one , using parameters calibrated previous ones.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"implementing-the-model-function","dir":"Articles","previous_headings":"","what":"Implementing the model function","title":"swfcalib","text":"Now good conceptual idea calibration go, need make code compatible swfcalib. model function pretty straightforward. need function signature: proposal one row tibble column parameter calibrate. case, proposal 1 row 9 columns tibble. results one row tibble column output calibration process. case, results must also 1 row 9 columns tibble. code example. Several things importance : call library within function. usual, must remember run sbatch job clean environment. Therefore, function must load required libraries files. must adapt proposal used simulation. case, helper function swfcalib_proposal_to_scenario . simply copying values proposal tibble works well. simulation, outputs must processed produce correctly formatted tibble. case, take mean last 52 weeks (1 year) desired outputs. users swfcalib, responsible correct output model. Also, model must function run single simulation produce single set results. function run parallel test several proposals .","code":"model <- function(proposal) { # simulation code return(results) } model <- function(proposal) { # Load all required elements library(EpiModelHIV) library(dplyr) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # Proposal to scenario ------------------------------------------------------- scenario <- EpiModelHPC::swfcalib_proposal_to_scenario(proposal) param_sc <- EpiModel::use_scenario(param, scenario) # Run the simulation --------------------------------------------------------- sim <- netsim(est, param_sc, init, control) # Process the results ------------------------------------------------------- results <- as_tibble(sim) |> mutate_calibration_targets() |> filter(time >= max(time) - 52) |> select( cc.dx.B, cc.dx.H, cc.dx.W, cc.linked1m.B, cc.linked1m.H, cc.linked1m.W, i.prev.dx.B, i.prev.dx.H, i.prev.dx.W, ) |> summarise(across( everything(), ~ mean(.x, na.rm = TRUE))) # Return the one row `tibble` return(results) }"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"configuring-an-swfcalib-system","dir":"Articles","previous_headings":"","what":"Configuring an swfcalib system","title":"swfcalib","text":"swfcalib maintain calib_object store state calibration well needs operate. object first defined locally updated HPC calibration progresses. object R list 3 elements: state, config waves. won’t cover state now created swfcalib edited .","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"configuration","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Configuration","title":"swfcalib","text":"config list following elements: simulator: function calibration model case root_directory: system store HPC n_sims: number simulations run parallel iteration max_iteration: maximum number iteration stopping calibration satisfactory state found. fail-safe mechanism avoid consuming HPC resources calibration work. default_proposal: default values calibrated parameters. fixes values parameters calibrated later waves. job finished, calibrated value stored used next runs","code":"config = list( simulator = model, root_directory = \"data/calib\", n_sims = n_sims, max_iteration = 100, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves-1","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Waves","title":"swfcalib","text":"waves list waves, wave list jobs","code":"waves = list( wave1 = list( job1 = list(), job2 = list(), job3 = list() ), wave2 = list( job1 = list(), job2 = list() ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-jobs","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Calibration jobs","title":"swfcalib","text":"calibration job list 6 elements: targets: name outputs fit (>= 1) targets_val: target values params: names parameters calibrate (>=1) initial_proposals: tibble values tested first run simulation. make_next_proposals: function define proposals make next get_result: function define calibration done job get details elements later . example job calibrating hiv.trans.scale parameters using .prev.dx outputs.","code":"job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"complete-configuration","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Complete configuration","title":"swfcalib","text":"complete calib_object defined locally. Note define n_sims variable beginning reuse configuration ensure correct number proposals step.","code":"n_sims <- 400 calib_object <- list( config = list( simulator = model, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ), root_directory = \"data/calib\", max_iteration = 100, n_sims = n_sims ), waves = list( wave1 = list( job1 = list( targets = \"cc.dx.B\", targets_val = 0.847, params = c(\"hiv.test.rate_1\"), # target: 0.00385 initial_proposals = dplyr::tibble( hiv.test.rate_1 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job2 = list( targets = \"cc.dx.H\", targets_val = 0.818, params = c(\"hiv.test.rate_2\"), # target: 0.0038 initial_proposals = dplyr::tibble( hiv.test.rate_2 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job3 = list( targets = \"cc.dx.W\", targets_val = 0.862, params = c(\"hiv.test.rate_3\"), # target: 0.0069 initial_proposals = dplyr::tibble( hiv.test.rate_3 = seq(0.004, 0.008, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job4 = list( targets = paste0(\"cc.linked1m.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.829, 0.898, 0.881), params = paste0(\"tx.init.rate_\", 1:3), initial_proposals = dplyr::tibble( tx.init.rate_1 = sample(seq(0.1, 0.5, length.out = n_sims)), tx.init.rate_2 = sample(tx.init.rate_1), tx.init.rate_3 = sample(tx.init.rate_1), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 3) ) ), wave2 = list( job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) ) ) ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"proposers-and-calibration-check","dir":"Articles","previous_headings":"","what":"Proposers and calibration check","title":"swfcalib","text":"mentioned earlier, calibration job needs function define proposal make next iteration (make_next_proposals) function assess calibration finished (get_result). won’t get details functions work focus instead practical use. can look respective documentation details.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"hiv-test-rate","dir":"Articles","previous_headings":"Proposers and calibration check","what":"HIV test rate","title":"swfcalib","text":"3 jobs related hiv.test.rate proportion diagnosed among infected (cc.dx) use approach: proposer function generated function factory: make_shrink_proposer(n_sims, shrink = 2). proposer shrink range proposals factor 2 around best guess far. calibration assessor made determ_poly_end(0.001, poly_n = 5). function uses linear model degree 5 polynomial predict best value parameter. calibration considered finished predicted value less threshold away target (0.001) prediction improving last iteration.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"linkage-to-care","dir":"Articles","previous_headings":"Proposers and calibration check","what":"Linkage to care","title":"swfcalib","text":"Linkage care uses functions 3 parameters targets fitted . implies single model fitted data. works well specific case relationship linkage care treatment uptake rate consistent three groups.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"hiv-prevalence","dir":"Articles","previous_headings":"Proposers and calibration check","what":"HIV prevalence","title":"swfcalib","text":"HIV prevalence transmission scale harder calibrate 3 parameters outputs linked together. iteration squared error 3 targets calculated proposal. ranges next round proposals ranges best 30% proposals previous rounds. function factory make_proposer_se_range. takes retain_prop argument governs proportion simulations used define new ranges. calibration considered done 100 simulations 3 outputs less thresholds away respective targets. determ_end_thresh function factory allow us define number good simulations required thresholds output.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"running-a-calibration-system","dir":"Articles","previous_headings":"","what":"Running a calibration system","title":"swfcalib","text":"Now pieces ready, can setup workflow using slurmworkflow package. allow HPC run calibration steps loop calibration finished. following script setup complete calibration workflow defined far. main thing may want change script batch_size variable governs many sims run parallel single cluster. RSPH HPC set 8. Therefore, 50 batches 8 submitted slurm make 400 simulations requested per iteration. mail sent job fails end 3rd calibration step. latter indicate calibration process done.","code":"library(\"slurmworkflow\") # Define the `model` function model <- function(proposal) { # Load all required elements library(EpiModelHIV) library(dplyr) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # Proposal to scenario ------------------------------------------------------- scenario <- EpiModelHPC::swfcalib_proposal_to_scenario(proposal) param_sc <- EpiModel::use_scenario(param, scenario) # Run the simulation --------------------------------------------------------- sim <- netsim(est, param_sc, init, control) # Process the results ------------------------------------------------------- results <- as_tibble(sim) |> mutate_calibration_targets() |> filter(time >= max(time) - 52) |> select( cc.dx.B, cc.dx.H, cc.dx.W, cc.linked1m.B, cc.linked1m.H, cc.linked1m.W, i.prev.dx.B, i.prev.dx.H, i.prev.dx.W, ) |> summarise(across( everything(), ~ mean(.x, na.rm = TRUE))) # Return the one row `tibble` return(results) } # Create the `calib_object` n_sims <- 400 calib_object <- list( config = list( simulator = model, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ), root_directory = \"data/calib\", max_iteration = 100, n_sims = n_sims ), waves = list( wave1 = list( job1 = list( targets = \"cc.dx.B\", targets_val = 0.847, params = c(\"hiv.test.rate_1\"), # target: 0.00385 initial_proposals = dplyr::tibble( hiv.test.rate_1 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job2 = list( targets = \"cc.dx.H\", targets_val = 0.818, params = c(\"hiv.test.rate_2\"), # target: 0.0038 initial_proposals = dplyr::tibble( hiv.test.rate_2 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job3 = list( targets = \"cc.dx.W\", targets_val = 0.862, params = c(\"hiv.test.rate_3\"), # target: 0.0069 initial_proposals = dplyr::tibble( hiv.test.rate_3 = seq(0.004, 0.008, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job4 = list( targets = paste0(\"cc.linked1m.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.829, 0.898, 0.881), params = paste0(\"tx.init.rate_\", 1:3), initial_proposals = dplyr::tibble( tx.init.rate_1 = sample(seq(0.1, 0.5, length.out = n_sims)), tx.init.rate_2 = sample(tx.init.rate_1), tx.init.rate_3 = sample(tx.init.rate_1), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 3) ) ), wave2 = list( job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) ) ) ) ) # Workflow --------------------------------------------------------------------- # Use preconfigured HPC settings hpc_configs <- EpiModelHPC::swf_configs_rsph( partition = \"epimodel\", r_version = \"4.3\", mail_user = \"user@emory.edu\" ) wf <- create_workflow( wf_name = \"Vignette_auto_calib\", default_sbatch_opts = hpc_configs$default_sbatch_opts ) # Calibration step 1 wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_do_call( what = swfcalib::calibration_step1, args = list( n_cores = 8, calib_object = calib_object ), setup_lines = hpc_configs$r_loader ), sbatch_opts = list( \"cpus-per-task\" = 8, \"time\" = \"00:20:00\", \"mem-per-cpu\" = \"4G\", \"mail-type\" = \"FAIL\" ) ) # Calibration step 2 batch_size <- 8 batch_numbers <- swfcalib:::get_batch_numbers(calib_object, batch_size) wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_map( FUN = swfcalib::calibration_step2, batch_num = batch_numbers, setup_lines = hpc_configs$r_loader, max_array_size = 500, MoreArgs = list( n_cores = batch_size, n_batches = max(batch_numbers), calib_object = calib_object ) ), sbatch_opts = list( \"cpus-per-task\" = batch_size, \"time\" = \"05:00:00\", \"mem-per-cpu\" = \"5G\", \"mail-type\" = \"FAIL\" ) ) # Calibration step 3 wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_do_call( what = swfcalib::calibration_step3, args = list( calib_object = calib_object ), setup_lines = hpc_configs$r_loader ), sbatch_opts = list( \"cpus-per-task\" = 1, \"time\" = \"00:20:00\", \"mem-per-cpu\" = \"8G\", \"mail-type\" = \"END\" ) )"},{"path":"https://epimodel.github.io/swfcalib/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Adrien Le Guillou. Author, maintainer.","code":""},{"path":"https://epimodel.github.io/swfcalib/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Le Guillou (2023). swfcalib: Package (One Line, Title Case). R package version 0.0.0.9000, https://epimodel.github.io/swfcalib/.","code":"@Manual{, title = {swfcalib: What the Package Does (One Line, Title Case)}, author = {Adrien {Le Guillou}}, year = {2023}, note = {R package version 0.0.0.9000}, url = {https://epimodel.github.io/swfcalib/}, }"},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"swfcalib","dir":"","previous_headings":"","what":"What the Package Does (One Line, Title Case)","title":"What the Package Does (One Line, Title Case)","text":"swfcalib designed automate calibration complex multi-parameters multi-outputs models ran Slurm equipped HPC.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"should-you-use-swfcalib","dir":"","previous_headings":"","what":"Should you use swfcalib","title":"What the Package Does (One Line, Title Case)","text":"swfcalib simplest calibration system set . designed solve specific set problems listed . already system works well probably consider swfcalib. However, following issues, swfcalib may : model many parameters calibrate produces many outputs. idea parameters influence outputs (see example ) outputs noisy don’t want Slurm job runs continuously whole duration calibration process (days several weeks) using slurmworkflow, swfcalib can implement loop like behavior Slurm without need pilot job staying alive whole duration calibration process (sometimes several weeks). swfcalib created calibrate epidemic models like one. models around 20 free parameters calibrate 20 outcomes matched observed targets. However, knowledge model allow us define many conditional one one relationship parameters outcomes. swfcalib can use knowledge split calibration multiple waves simpler parallel calibration jobs.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"design","dir":"","previous_headings":"","what":"Design","title":"What the Package Does (One Line, Title Case)","text":"calibration process follows proposal, validation loop. model run set parameters new proposals made according results. goes model fully calibrated. Terminology: model: function taking proposal returning outcomes. proposal: set parameters values passed model outcomes: output model run given proposal. job: set parameters calibrated using subset outcomes wave: set independent jobs can calibrated using run model. specificity swfcalib lies ability try many proposal HPC, set proposal validation loop without long running orchestrating job (pilot job). calibration split waves. wave can contains multiple jobs, focusing set parameters related outcomes. permits parallel calibration multiple independent parameters. iteration, model ran per proposal, job gather outcomes needs make next proposal. jobs wave done, .e. parameters govern calibrated, system moves next wave. allows sequential calibration parameters strong assumption independence can made. design crafted noisy models many replications needed parameters independent conditionally independent.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"versatility","dir":"","previous_headings":"","what":"Versatility","title":"What the Package Does (One Line, Title Case)","text":"swfcalib makes assumptions set parameters changed quality fit assessed. user provide mechanism : produce next proposals tested assess quality fit swfcalib provides pre-built functions . See getting started vignette.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"What the Package Does (One Line, Title Case)","text":"can install development version swfcalib like :","code":"remotes::install_github(\"EpiModel/swfcalib\")"},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"example","dir":"","previous_headings":"","what":"Example","title":"What the Package Does (One Line, Title Case)","text":"","code":"library(swfcalib)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":null,"dir":"Reference","previous_headings":"","what":"First calibration step — calibration_step1","title":"First calibration step — calibration_step1","text":"First calibration step","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"First calibration step — calibration_step1","text":"","code":"calibration_step1(calib_object, n_cores)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"First calibration step — calibration_step1","text":"calib_object formatted calibration object n_cores number cores run processing ","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":null,"dir":"Reference","previous_headings":"","what":"Second calibration step: run the model for each proposal — calibration_step2","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"Second calibration step: run model proposal","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"","code":"calibration_step2(calib_object, n_cores, batch_num, n_batches)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"calib_object formatted calibration object n_cores number cores run processing batch_num batch number current proposal n_batches total number batches step","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":null,"dir":"Reference","previous_headings":"","what":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"separate step allows mail send end calibration","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"","code":"calibration_step3(calib_object)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"calib_object formatted calibration object","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/load_sideload.html","id":null,"dir":"Reference","previous_headings":"","what":"Read some data saved to be reused by the calibration process — load_sideload","title":"Read some data saved to be reused by the calibration process — load_sideload","text":"Read data saved reused calibration process","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/load_sideload.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Read some data saved to be reused by the calibration process — load_sideload","text":"","code":"load_sideload(calib_object, job)"},{"path":"https://epimodel.github.io/swfcalib/reference/make_shrink_proposer.html","id":null,"dir":"Reference","previous_headings":"","what":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","title":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","text":"centers provided sideload, use ","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/make_shrink_proposer.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","text":"","code":"make_shrink_proposer(n_new, shrink = 2)"},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate an html report of the auto-calibration — render_assessment","title":"Generate an html report of the auto-calibration — render_assessment","text":"report contains descriptions parameters spaces residual errors duration calibration.","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate an html report of the auto-calibration — render_assessment","text":"","code":"render_assessment( path_to_assessments, output_filename = \"assessment.html\", output_dir = NULL )"},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate an html report of the auto-calibration — render_assessment","text":"path_to_assessments Path assessments.rds file generated swfcalib process. output_filename Name html report (default = \"assessment.html\") output_dir Directory store report (default = current working directory)","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/save_sideload.html","id":null,"dir":"Reference","previous_headings":"","what":"Save some data to be reused by the calibration process — save_sideload","title":"Save some data to be reused by the calibration process — save_sideload","text":"Save data reused calibration process","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/save_sideload.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Save some data to be reused by the calibration process — save_sideload","text":"","code":"save_sideload(calib_object, job, x)"}] +[{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"the-model","dir":"Articles","previous_headings":"","what":"The model","title":"swfcalib","text":"single run model locally looks like : example, need load EpiModelHIV package, read 4 files located “data/input” folder pass 4 parameters netsim function. result, stored sim variable directly usable swfcalib.","code":"library(EpiModelHIV) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # The actual simulation happens here sim <- netsim(est, param, init, control)"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-parameters-and-outputs","dir":"Articles","previous_headings":"","what":"Calibration parameters and outputs","title":"swfcalib","text":"example, focus 9 parameters calibrate 9 outputs fit targets. many parameters model. get values literature, free parameters calibrated ignored sake simplicity example.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"outputs","dir":"Articles","previous_headings":"Calibration parameters and outputs","what":"Outputs","title":"swfcalib","text":"first outputs proportion HIV individuals diagnosed (.e. aware status). proportion HIV diagnosed started treatment less month diagnosis. Finally, prevalence diagnosed HIV population final output interest. population race stratified , black, hispanic white, get three time number outputs.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"parameters","dir":"Articles","previous_headings":"Calibration parameters and outputs","what":"Parameters","title":"swfcalib","text":"9 parameters calibrated fit model target values: weekly probability tested HIV. weekly probability starting treatment diagnosed HIV. transmission scaler parameter encompass mechanism affecting transmission explicitly defined model.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"relationship-between-parameters-and-outputs","dir":"Articles","previous_headings":"","what":"Relationship between parameters and outputs","title":"swfcalib","text":"Simply looking , can see parameters relate outputs way. hiv.test.rate parameters directly relate cc.dx outputs (proportion) diagnosed. Also, parameter list affect outcomes. Therefore, 3 one one relationship. race, test rate govern diagnosed proportion. similar situation can described linkage care (cc.linked1m) treatment start rate tx.init.rate. (denominator number diagnosed individuals, making independent cc.dx). prevalence (.prev.dx), hand, depends 9 parameters. proportion diagnosed influences number treated influences number individuals able transmit. scalers affect directly transmission one population. modify prevalence, also indirectly influence transmission sub populations. However, hiv.test.rate tx.init.rate calibrated values fixed, .prev.dx depends hiv.trans.scale parameters. Reducing 9 parameters 3 outputs problem simpler 3 parameters, 3 outputs one. following graph illustrate relationships. Parameters - Output relationship","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-structure","dir":"Articles","previous_headings":"","what":"Calibration structure","title":"swfcalib","text":"Knowing parameters - outputs relationship, can define calibration structure minimize number simulations required. first wave calibrate simultaneously 3 hiv.test.rate 3 tx.init.rate parameters. means run simulation test value 6 parameters. idea similar factorial experiment design possible independence parameters respective outcomes. 6 parameters calibrated (.e. given fixed final values), hiv.trans.scale parameters calibrated fit .prev.dx outcomes target values.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves-and-jobs","dir":"Articles","previous_headings":"","what":"Waves and jobs","title":"swfcalib","text":"express structure, need define calibration jobs going run parallel within several waves. example two waves, first one hiv.test.rate tx.init.rate parameters second hiv.trans.scale parameters.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"jobs","dir":"Articles","previous_headings":"Waves and jobs","what":"Jobs","title":"swfcalib","text":"Formally, swfcalib defines job set parameters calibrated trying make set outcomes reach set targets. job needs function make next set parameter proposals test well function checking proposals gave sufficiently good results. latter function charge stopping calibration process current job.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves","dir":"Articles","previous_headings":"Waves and jobs","what":"Waves","title":"swfcalib","text":"wave set multiple jobs can run parallel (.e. independent one another). practice, swfcalib takes proposals jobs wave, combine run one simulation per proposal. 3 job wave, making 10 proposal, 10 simulations run. evaluation step job assess quality ’s outcomes. jobs wave finished, system moves next one , using parameters calibrated previous ones.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"implementing-the-model-function","dir":"Articles","previous_headings":"","what":"Implementing the model function","title":"swfcalib","text":"Now good conceptual idea calibration go, need make code compatible swfcalib. model function pretty straightforward. need function signature: proposal one row tibble column parameter calibrate. case, proposal 1 row 9 columns tibble. results one row tibble column output calibration process. case, results must also 1 row 9 columns tibble. code example. Several things importance : call library within function. usual, must remember run sbatch job clean environment. Therefore, function must load required libraries files. must adapt proposal used simulation. case, helper function swfcalib_proposal_to_scenario . simply copying values proposal tibble works well. simulation, outputs must processed produce correctly formatted tibble. case, take mean last 52 weeks (1 year) desired outputs. users swfcalib, responsible correct output model. Also, model must function run single simulation produce single set results. function run parallel test several proposals .","code":"model <- function(proposal) { # simulation code return(results) } model <- function(proposal) { # Load all required elements library(EpiModelHIV) library(dplyr) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # Proposal to scenario ------------------------------------------------------- scenario <- EpiModelHPC::swfcalib_proposal_to_scenario(proposal) param_sc <- EpiModel::use_scenario(param, scenario) # Run the simulation --------------------------------------------------------- sim <- netsim(est, param_sc, init, control) # Process the results ------------------------------------------------------- results <- as_tibble(sim) |> mutate_calibration_targets() |> filter(time >= max(time) - 52) |> select( cc.dx.B, cc.dx.H, cc.dx.W, cc.linked1m.B, cc.linked1m.H, cc.linked1m.W, i.prev.dx.B, i.prev.dx.H, i.prev.dx.W, ) |> summarise(across( everything(), ~ mean(.x, na.rm = TRUE))) # Return the one row `tibble` return(results) }"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"configuring-an-swfcalib-system","dir":"Articles","previous_headings":"","what":"Configuring an swfcalib system","title":"swfcalib","text":"swfcalib maintain calib_object store state calibration well needs operate. object first defined locally updated HPC calibration progresses. object R list 3 elements: state, config waves. won’t cover state now created swfcalib edited .","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"configuration","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Configuration","title":"swfcalib","text":"config list following elements: simulator: function calibration model case root_directory: system store HPC n_sims: number simulations run parallel iteration max_iteration: maximum number iteration stopping calibration satisfactory state found. fail-safe mechanism avoid consuming HPC resources calibration work. default_proposal: default values calibrated parameters. fixes values parameters calibrated later waves. job finished, calibrated value stored used next runs","code":"config = list( simulator = model, root_directory = \"data/calib\", n_sims = n_sims, max_iteration = 100, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"waves-1","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Waves","title":"swfcalib","text":"waves list waves, wave list jobs","code":"waves = list( wave1 = list( job1 = list(), job2 = list(), job3 = list() ), wave2 = list( job1 = list(), job2 = list() ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"calibration-jobs","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Calibration jobs","title":"swfcalib","text":"calibration job list 6 elements: targets: name outputs fit (>= 1) targets_val: target values params: names parameters calibrate (>=1) initial_proposals: tibble values tested first run simulation. make_next_proposals: function define proposals make next get_result: function define calibration done job get details elements later . example job calibrating hiv.trans.scale parameters using .prev.dx outputs.","code":"job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"complete-configuration","dir":"Articles","previous_headings":"Configuring an swfcalib system","what":"Complete configuration","title":"swfcalib","text":"complete calib_object defined locally. Note define n_sims variable beginning reuse configuration ensure correct number proposals step.","code":"n_sims <- 400 calib_object <- list( config = list( simulator = model, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ), root_directory = \"data/calib\", max_iteration = 100, n_sims = n_sims ), waves = list( wave1 = list( job1 = list( targets = \"cc.dx.B\", targets_val = 0.847, params = c(\"hiv.test.rate_1\"), # target: 0.00385 initial_proposals = dplyr::tibble( hiv.test.rate_1 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job2 = list( targets = \"cc.dx.H\", targets_val = 0.818, params = c(\"hiv.test.rate_2\"), # target: 0.0038 initial_proposals = dplyr::tibble( hiv.test.rate_2 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job3 = list( targets = \"cc.dx.W\", targets_val = 0.862, params = c(\"hiv.test.rate_3\"), # target: 0.0069 initial_proposals = dplyr::tibble( hiv.test.rate_3 = seq(0.004, 0.008, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job4 = list( targets = paste0(\"cc.linked1m.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.829, 0.898, 0.881), params = paste0(\"tx.init.rate_\", 1:3), initial_proposals = dplyr::tibble( tx.init.rate_1 = sample(seq(0.1, 0.5, length.out = n_sims)), tx.init.rate_2 = sample(tx.init.rate_1), tx.init.rate_3 = sample(tx.init.rate_1), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 3) ) ), wave2 = list( job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) ) ) ) )"},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"proposers-and-calibration-check","dir":"Articles","previous_headings":"","what":"Proposers and calibration check","title":"swfcalib","text":"mentioned earlier, calibration job needs function define proposal make next iteration (make_next_proposals) function assess calibration finished (get_result). won’t get details functions work focus instead practical use. can look respective documentation details.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"hiv-test-rate","dir":"Articles","previous_headings":"Proposers and calibration check","what":"HIV test rate","title":"swfcalib","text":"3 jobs related hiv.test.rate proportion diagnosed among infected (cc.dx) use approach: proposer function generated function factory: make_shrink_proposer(n_sims, shrink = 2). proposer shrink range proposals factor 2 around best guess far. calibration assessor made determ_poly_end(0.001, poly_n = 5). function uses linear model degree 5 polynomial predict best value parameter. calibration considered finished predicted value less threshold away target (0.001) prediction improving last iteration.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"linkage-to-care","dir":"Articles","previous_headings":"Proposers and calibration check","what":"Linkage to care","title":"swfcalib","text":"Linkage care uses functions 3 parameters targets fitted . implies single model fitted data. works well specific case relationship linkage care treatment uptake rate consistent three groups.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"hiv-prevalence","dir":"Articles","previous_headings":"Proposers and calibration check","what":"HIV prevalence","title":"swfcalib","text":"HIV prevalence transmission scale harder calibrate 3 parameters outputs linked together. iteration squared error 3 targets calculated proposal. ranges next round proposals ranges best 30% proposals previous rounds. function factory make_proposer_se_range. takes retain_prop argument governs proportion simulations used define new ranges. calibration considered done 100 simulations 3 outputs less thresholds away respective targets. determ_end_thresh function factory allow us define number good simulations required thresholds output.","code":""},{"path":"https://epimodel.github.io/swfcalib/articles/swfcalib.html","id":"running-a-calibration-system","dir":"Articles","previous_headings":"","what":"Running a calibration system","title":"swfcalib","text":"Now pieces ready, can setup workflow using slurmworkflow package. allow HPC run calibration steps loop calibration finished. following script setup complete calibration workflow defined far. main thing may want change script batch_size variable governs many sims run parallel single cluster. RSPH HPC set 8. Therefore, 50 batches 8 submitted slurm make 400 simulations requested per iteration. mail sent job fails end 3rd calibration step. latter indicate calibration process done.","code":"library(\"slurmworkflow\") # Define the `model` function model <- function(proposal) { # Load all required elements library(EpiModelHIV) library(dplyr) epistats <- readRDS(\"data/input/epistats.rds\") netstats <- readRDS(\"data/input/netstats.rds\") est <- readRDS(\"data/input/netest.rds\") param <- param.net( data.frame.params = read.csv(\"data/input/params.csv\"), netstats = netstats, epistats = epistats ) init <- init_msm() control <- control_msm( nsteps = 52 * 60, nsims = 1, ncores = 1 ) # Proposal to scenario ------------------------------------------------------- scenario <- EpiModelHPC::swfcalib_proposal_to_scenario(proposal) param_sc <- EpiModel::use_scenario(param, scenario) # Run the simulation --------------------------------------------------------- sim <- netsim(est, param_sc, init, control) # Process the results ------------------------------------------------------- results <- as_tibble(sim) |> mutate_calibration_targets() |> filter(time >= max(time) - 52) |> select( cc.dx.B, cc.dx.H, cc.dx.W, cc.linked1m.B, cc.linked1m.H, cc.linked1m.W, i.prev.dx.B, i.prev.dx.H, i.prev.dx.W, ) |> summarise(across( everything(), ~ mean(.x, na.rm = TRUE))) # Return the one row `tibble` return(results) } # Create the `calib_object` n_sims <- 400 calib_object <- list( config = list( simulator = model, default_proposal = dplyr::tibble( hiv.test.rate_1 = 0.004123238, hiv.test.rate_2 = 0.003771226, hiv.test.rate_3 = 0.005956663, tx.init.rate_1 = 0.2981623, tx.init.rate_2 = 0.3680919, tx.init.rate_3 = 0.358254, hiv.trans.scale_1 = 2.470962, hiv.trans.scale_2 = 0.4247816, hiv.trans.scale_3 = 0.3342994 ), root_directory = \"data/calib\", max_iteration = 100, n_sims = n_sims ), waves = list( wave1 = list( job1 = list( targets = \"cc.dx.B\", targets_val = 0.847, params = c(\"hiv.test.rate_1\"), # target: 0.00385 initial_proposals = dplyr::tibble( hiv.test.rate_1 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job2 = list( targets = \"cc.dx.H\", targets_val = 0.818, params = c(\"hiv.test.rate_2\"), # target: 0.0038 initial_proposals = dplyr::tibble( hiv.test.rate_2 = seq(0.002, 0.006, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job3 = list( targets = \"cc.dx.W\", targets_val = 0.862, params = c(\"hiv.test.rate_3\"), # target: 0.0069 initial_proposals = dplyr::tibble( hiv.test.rate_3 = seq(0.004, 0.008, length.out = n_sims), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 5) ), job4 = list( targets = paste0(\"cc.linked1m.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.829, 0.898, 0.881), params = paste0(\"tx.init.rate_\", 1:3), initial_proposals = dplyr::tibble( tx.init.rate_1 = sample(seq(0.1, 0.5, length.out = n_sims)), tx.init.rate_2 = sample(tx.init.rate_1), tx.init.rate_3 = sample(tx.init.rate_1), ), make_next_proposals = swfcalib::make_shrink_proposer(n_sims, shrink = 2), get_result = swfcalib::determ_poly_end(0.001, poly_n = 3) ) ), wave2 = list( job1 = list( targets = paste0(\"i.prev.dx.\", c(\"B\", \"H\", \"W\")), targets_val = c(0.33, 0.127, 0.09), params = paste0(\"hiv.trans.scale_\", 1:3), initial_proposals = dplyr::tibble( hiv.trans.scale_1 = sample(seq(1, 4, length.out = n_sims)), hiv.trans.scale_2 = sample(seq(0.2, 0.6, length.out = n_sims)), hiv.trans.scale_3 = sample(seq(0.2, 0.6, length.out = n_sims)) ), make_next_proposals = swfcalib::make_proposer_se_range(n_sims, retain_prop = 0.3), get_result = swfcalib::determ_end_thresh( thresholds = rep(0.02, 3), n_enough = 100 ) ) ) ) ) # Workflow --------------------------------------------------------------------- # Use preconfigured HPC settings hpc_configs <- EpiModelHPC::swf_configs_rsph( partition = \"epimodel\", r_version = \"4.3\", mail_user = \"@emory.edu\" ) wf <- create_workflow( wf_name = \"Vignette_auto_calib\", default_sbatch_opts = hpc_configs$default_sbatch_opts ) # Calibration step 1 wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_do_call( what = swfcalib::calibration_step1, args = list( n_cores = 8, calib_object = calib_object ), setup_lines = hpc_configs$r_loader ), sbatch_opts = list( \"cpus-per-task\" = 8, \"time\" = \"00:20:00\", \"mem-per-cpu\" = \"4G\", \"mail-type\" = \"FAIL\" ) ) # Calibration step 2 batch_size <- 8 batch_numbers <- swfcalib:::get_batch_numbers(calib_object, batch_size) wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_map( FUN = swfcalib::calibration_step2, batch_num = batch_numbers, setup_lines = hpc_configs$r_loader, max_array_size = 500, MoreArgs = list( n_cores = batch_size, n_batches = max(batch_numbers), calib_object = calib_object ) ), sbatch_opts = list( \"cpus-per-task\" = batch_size, \"time\" = \"05:00:00\", \"mem-per-cpu\" = \"5G\", \"mail-type\" = \"FAIL\" ) ) # Calibration step 3 wf <- add_workflow_step( wf_summary = wf, step_tmpl = step_tmpl_do_call( what = swfcalib::calibration_step3, args = list( calib_object = calib_object ), setup_lines = hpc_configs$r_loader ), sbatch_opts = list( \"cpus-per-task\" = 1, \"time\" = \"00:20:00\", \"mem-per-cpu\" = \"8G\", \"mail-type\" = \"END\" ) )"},{"path":"https://epimodel.github.io/swfcalib/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Adrien Le Guillou. Author, maintainer.","code":""},{"path":"https://epimodel.github.io/swfcalib/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Le Guillou (2023). swfcalib: Package (One Line, Title Case). R package version 0.0.0.9000, https://epimodel.github.io/swfcalib/.","code":"@Manual{, title = {swfcalib: What the Package Does (One Line, Title Case)}, author = {Adrien {Le Guillou}}, year = {2023}, note = {R package version 0.0.0.9000}, url = {https://epimodel.github.io/swfcalib/}, }"},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"swfcalib","dir":"","previous_headings":"","what":"What the Package Does (One Line, Title Case)","title":"What the Package Does (One Line, Title Case)","text":"swfcalib designed automate calibration complex multi-parameters multi-outputs models ran Slurm equipped HPC.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"should-you-use-swfcalib","dir":"","previous_headings":"","what":"Should you use swfcalib","title":"What the Package Does (One Line, Title Case)","text":"swfcalib simplest calibration system set . designed solve specific set problems listed . already system works well probably consider swfcalib. However, following issues, swfcalib may : model many parameters calibrate produces many outputs. idea parameters influence outputs (see example ) outputs noisy don’t want Slurm job runs continuously whole duration calibration process (days several weeks) using slurmworkflow, swfcalib can implement loop like behavior Slurm without need pilot job staying alive whole duration calibration process (sometimes several weeks). swfcalib created calibrate epidemic models like one. models around 20 free parameters calibrate 20 outcomes matched observed targets. However, knowledge model allow us define many conditional one one relationship parameters outcomes. swfcalib can use knowledge split calibration multiple waves simpler parallel calibration jobs.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"design","dir":"","previous_headings":"","what":"Design","title":"What the Package Does (One Line, Title Case)","text":"calibration process follows proposal, validation loop. model run set parameters new proposals made according results. goes model fully calibrated. Terminology: model: function taking proposal returning outcomes. proposal: set parameters values passed model outcomes: output model run given proposal. job: set parameters calibrated using subset outcomes wave: set independent jobs can calibrated using run model. specificity swfcalib lies ability try many proposal HPC, set proposal validation loop without long running orchestrating job (pilot job). calibration split waves. wave can contains multiple jobs, focusing set parameters related outcomes. permits parallel calibration multiple independent parameters. iteration, model ran per proposal, job gather outcomes needs make next proposal. jobs wave done, .e. parameters govern calibrated, system moves next wave. allows sequential calibration parameters strong assumption independence can made. design crafted noisy models many replications needed parameters independent conditionally independent.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"versatility","dir":"","previous_headings":"","what":"Versatility","title":"What the Package Does (One Line, Title Case)","text":"swfcalib makes assumptions set parameters changed quality fit assessed. user provide mechanism : produce next proposals tested assess quality fit swfcalib provides pre-built functions . See getting started vignette.","code":""},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"What the Package Does (One Line, Title Case)","text":"can install development version swfcalib like :","code":"remotes::install_github(\"EpiModel/swfcalib\")"},{"path":"https://epimodel.github.io/swfcalib/index.html","id":"example","dir":"","previous_headings":"","what":"Example","title":"What the Package Does (One Line, Title Case)","text":"","code":"library(swfcalib)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":null,"dir":"Reference","previous_headings":"","what":"First calibration step — calibration_step1","title":"First calibration step — calibration_step1","text":"First calibration step","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"First calibration step — calibration_step1","text":"","code":"calibration_step1(calib_object, n_cores)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step1.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"First calibration step — calibration_step1","text":"calib_object formatted calibration object n_cores number cores run processing ","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":null,"dir":"Reference","previous_headings":"","what":"Second calibration step: run the model for each proposal — calibration_step2","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"Second calibration step: run model proposal","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"","code":"calibration_step2(calib_object, n_cores, batch_num, n_batches)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step2.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Second calibration step: run the model for each proposal — calibration_step2","text":"calib_object formatted calibration object n_cores number cores run processing batch_num batch number current proposal n_batches total number batches step","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":null,"dir":"Reference","previous_headings":"","what":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"separate step allows mail send end calibration","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"","code":"calibration_step3(calib_object)"},{"path":"https://epimodel.github.io/swfcalib/reference/calibration_step3.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Third calibration step: Wrap up the calibration system and store the results — calibration_step3","text":"calib_object formatted calibration object","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/load_sideload.html","id":null,"dir":"Reference","previous_headings":"","what":"Read some data saved to be reused by the calibration process — load_sideload","title":"Read some data saved to be reused by the calibration process — load_sideload","text":"Read data saved reused calibration process","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/load_sideload.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Read some data saved to be reused by the calibration process — load_sideload","text":"","code":"load_sideload(calib_object, job)"},{"path":"https://epimodel.github.io/swfcalib/reference/make_shrink_proposer.html","id":null,"dir":"Reference","previous_headings":"","what":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","title":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","text":"centers provided sideload, use ","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/make_shrink_proposer.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Shrink the range by a shrink factor (default 2) — make_shrink_proposer","text":"","code":"make_shrink_proposer(n_new, shrink = 2)"},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate an html report of the auto-calibration — render_assessment","title":"Generate an html report of the auto-calibration — render_assessment","text":"report contains descriptions parameters spaces residual errors duration calibration.","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate an html report of the auto-calibration — render_assessment","text":"","code":"render_assessment( path_to_assessments, output_filename = \"assessment.html\", output_dir = NULL )"},{"path":"https://epimodel.github.io/swfcalib/reference/render_assessment.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate an html report of the auto-calibration — render_assessment","text":"path_to_assessments Path assessments.rds file generated swfcalib process. output_filename Name html report (default = \"assessment.html\") output_dir Directory store report (default = current working directory)","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/save_sideload.html","id":null,"dir":"Reference","previous_headings":"","what":"Save some data to be reused by the calibration process — save_sideload","title":"Save some data to be reused by the calibration process — save_sideload","text":"Save data reused calibration process","code":""},{"path":"https://epimodel.github.io/swfcalib/reference/save_sideload.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Save some data to be reused by the calibration process — save_sideload","text":"","code":"save_sideload(calib_object, job, x)"}]