From 4ce19b0b4e555620c12e50058c485699ab4127a5 Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Tue, 18 Jun 2024 11:21:05 +0100 Subject: [PATCH 1/5] unit tests for pipeline functions. --- pipeline/src/pipeline/do_inference.jl | 21 +++++++++++++ pipeline/src/pipeline/do_truthdata.jl | 19 ++++++++++++ .../test/pipeline/test_pipelinefunctions.jl | 31 +++++++++++++++++++ pipeline/test/runtests.jl | 1 + 4 files changed, 72 insertions(+) create mode 100644 pipeline/test/pipeline/test_pipelinefunctions.jl diff --git a/pipeline/src/pipeline/do_inference.jl b/pipeline/src/pipeline/do_inference.jl index 57f47254c..0e1e83a09 100644 --- a/pipeline/src/pipeline/do_inference.jl +++ b/pipeline/src/pipeline/do_inference.jl @@ -17,3 +17,24 @@ function do_inference(truthdata, pipeline::AbstractEpiAwarePipeline) truthdata, inference_configs, pipeline; tspan, inference_method) return inference_results end + +""" +Generate inference results using the specified truth data and pipeline. This is +example mode. + +# Arguments +- `truthdata`: The truth data used for generating inference results. +- `pipeline::EpiAwareExamplePipeline`: Sets the pipeline behavior. + +# Returns +An array of inference results. + +""" +function do_inference(truthdata, pipeline::EpiAwareExamplePipeline) + inference_configs = [rand(make_inference_configs(pipeline))] + tspan = make_tspan(pipeline) + inference_method = make_inference_method(pipeline) + inference_results = map_inference_results( + truthdata, inference_configs, pipeline; tspan, inference_method) + return inference_results +end diff --git a/pipeline/src/pipeline/do_truthdata.jl b/pipeline/src/pipeline/do_truthdata.jl index 3781bc3f5..21e4e530d 100644 --- a/pipeline/src/pipeline/do_truthdata.jl +++ b/pipeline/src/pipeline/do_truthdata.jl @@ -16,3 +16,22 @@ function do_truthdata(pipeline::AbstractEpiAwarePipeline) end return truthdata_from_configs end + +""" +Generate truth data for the EpiAwarePipeline. This is example mode. + +# Arguments +- `pipeline::EpiAwareExamplePipeline`: The EpiAwarePipeline object. + +# Returns +An array of truth data generated from the given pipeline. + +""" +function do_truthdata(pipeline::EpiAwareExamplePipeline) + truth_data_configs = [rand(make_truth_data_configs(pipeline))] + truthdata_from_configs = map(truth_data_configs) do truth_data_config + return Dagger.@spawn cache=true generate_truthdata( + truth_data_config, pipeline; plot = true) + end + return truthdata_from_configs +end diff --git a/pipeline/test/pipeline/test_pipelinefunctions.jl b/pipeline/test/pipeline/test_pipelinefunctions.jl new file mode 100644 index 000000000..43244242c --- /dev/null +++ b/pipeline/test/pipeline/test_pipelinefunctions.jl @@ -0,0 +1,31 @@ +@testset "do_truthdata tests" begin + using EpiAwarePipeline, Dagger + pipeline = EpiAwareExamplePipeline() + truthdata_dg_task = do_truthdata(pipeline) + truthdata = fetch.(truthdata_dg_task) + + @test length(truthdata) == 1 + @test all([data["y_t"] isa Vector{Union{Missing, Real}} for data in truthdata]) +end + +@testset "do_inference tests" begin + using EpiAwarePipeline + pipeline = EpiAwareExamplePipeline() + + function make_inference() + truthdata = do_truthdata(pipeline) + do_inference(truthdata[1:1], pipeline) + end + + inference_results_tsk = make_inference() + inference_results = fetch.(inference_results_tsk) + @test length(inference_results) == 1 + @test all([result["inference_results"] isa EpiAwareObservables for result in inference_results]) +end + +@testset "do_pipeline test: just run" begin + using EpiAwarePipeline + pipeline = EpiAwareExamplePipeline() + res = do_pipeline(pipeline) + @test isnothing(res) +end diff --git a/pipeline/test/runtests.jl b/pipeline/test/runtests.jl index e349f6441..ce97f3d9d 100644 --- a/pipeline/test/runtests.jl +++ b/pipeline/test/runtests.jl @@ -3,6 +3,7 @@ quickactivate(@__DIR__(), "EpiAwarePipeline") # Run tests include("pipeline/test_pipelinetypes.jl"); +include("pipeline/test_pipelinefunctions.jl"); include("constructors/test_constructors.jl"); include("simulate/test_TruthSimulationConfig.jl"); include("simulate/test_SimulationConfig.jl"); From 933814be91fa1739b8cf88663e194c05b9b25881 Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Tue, 18 Jun 2024 11:23:56 +0100 Subject: [PATCH 2/5] reformat --- pipeline/test/pipeline/test_pipelinefunctions.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipeline/test/pipeline/test_pipelinefunctions.jl b/pipeline/test/pipeline/test_pipelinefunctions.jl index 43244242c..45e8a6123 100644 --- a/pipeline/test/pipeline/test_pipelinefunctions.jl +++ b/pipeline/test/pipeline/test_pipelinefunctions.jl @@ -20,7 +20,8 @@ end inference_results_tsk = make_inference() inference_results = fetch.(inference_results_tsk) @test length(inference_results) == 1 - @test all([result["inference_results"] isa EpiAwareObservables for result in inference_results]) + @test all([result["inference_results"] isa EpiAwareObservables + for result in inference_results]) end @testset "do_pipeline test: just run" begin From 596610672adcbe0d21d7c3084b2176886ccf7f77 Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Tue, 18 Jun 2024 11:54:54 +0100 Subject: [PATCH 3/5] Move dispatch on example mode to the config list constructors with additional unit testing --- .../constructors/make_inference_configs.jl | 26 +++++++++++++++ .../constructors/make_truth_data_configs.jl | 13 +++++++- pipeline/src/pipeline/do_inference.jl | 21 ------------ pipeline/src/pipeline/do_truthdata.jl | 19 ----------- .../test/constructors/test_constructors.jl | 33 ++++++++++++++++--- 5 files changed, 67 insertions(+), 45 deletions(-) diff --git a/pipeline/src/constructors/make_inference_configs.jl b/pipeline/src/constructors/make_inference_configs.jl index 53f38be85..d43195d00 100644 --- a/pipeline/src/constructors/make_inference_configs.jl +++ b/pipeline/src/constructors/make_inference_configs.jl @@ -22,3 +22,29 @@ function make_inference_configs(pipeline::AbstractEpiAwarePipeline) return inference_configs end + +""" +Create inference configurations for the given pipeline. This is the example method, +which only returns a randomly selected inference configuration. + +# Arguments +- `pipeline`: An instance of `EpiAwareExamplePipeline`. + +# Returns +- An object representing the inference configurations. + +""" +function make_inference_configs(pipeline::EpiAwareExamplePipeline) + gi_param_dict = make_gi_params(pipeline) + namemodel_vect = make_epiaware_name_latentmodel_pairs(pipeline) + igps = make_inf_generating_processes(pipeline) + obs = make_observation_model(pipeline) + priors = make_model_priors(pipeline) + + inference_configs = Dict("igp" => igps, "latent_namemodels" => namemodel_vect, + "observation_model" => obs, "gi_mean" => gi_param_dict["gi_means"], + "gi_std" => gi_param_dict["gi_stds"], "log_I0_prior" => priors["log_I0_prior"]) |> + dict_list + + return [rand(inference_configs)] +end diff --git a/pipeline/src/constructors/make_truth_data_configs.jl b/pipeline/src/constructors/make_truth_data_configs.jl index f122c1179..9868a1cef 100644 --- a/pipeline/src/constructors/make_truth_data_configs.jl +++ b/pipeline/src/constructors/make_truth_data_configs.jl @@ -1,5 +1,5 @@ """ -Create a dictionary of truth data configurations for `pipeline <: AbstractEpiAwarePipeline`. +Create a vector of truth data configurations for `pipeline <: AbstractEpiAwarePipeline`. This is the default method. # Returns @@ -13,3 +13,14 @@ function make_truth_data_configs(pipeline::AbstractEpiAwarePipeline) "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> dict_list end + +""" +Create a vector of truth data configurations for `pipeline <: AbstractEpiAwarePipeline`. +This is the example method, which only returns a randomly selected truth data configuration. +""" +function make_truth_data_configs(pipeline::EpiAwareExamplePipeline) + gi_param_dict = make_gi_params(pipeline) + return Dict( + "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> + dict_list |> list -> [rand(list)] +end diff --git a/pipeline/src/pipeline/do_inference.jl b/pipeline/src/pipeline/do_inference.jl index 0e1e83a09..57f47254c 100644 --- a/pipeline/src/pipeline/do_inference.jl +++ b/pipeline/src/pipeline/do_inference.jl @@ -17,24 +17,3 @@ function do_inference(truthdata, pipeline::AbstractEpiAwarePipeline) truthdata, inference_configs, pipeline; tspan, inference_method) return inference_results end - -""" -Generate inference results using the specified truth data and pipeline. This is -example mode. - -# Arguments -- `truthdata`: The truth data used for generating inference results. -- `pipeline::EpiAwareExamplePipeline`: Sets the pipeline behavior. - -# Returns -An array of inference results. - -""" -function do_inference(truthdata, pipeline::EpiAwareExamplePipeline) - inference_configs = [rand(make_inference_configs(pipeline))] - tspan = make_tspan(pipeline) - inference_method = make_inference_method(pipeline) - inference_results = map_inference_results( - truthdata, inference_configs, pipeline; tspan, inference_method) - return inference_results -end diff --git a/pipeline/src/pipeline/do_truthdata.jl b/pipeline/src/pipeline/do_truthdata.jl index 21e4e530d..3781bc3f5 100644 --- a/pipeline/src/pipeline/do_truthdata.jl +++ b/pipeline/src/pipeline/do_truthdata.jl @@ -16,22 +16,3 @@ function do_truthdata(pipeline::AbstractEpiAwarePipeline) end return truthdata_from_configs end - -""" -Generate truth data for the EpiAwarePipeline. This is example mode. - -# Arguments -- `pipeline::EpiAwareExamplePipeline`: The EpiAwarePipeline object. - -# Returns -An array of truth data generated from the given pipeline. - -""" -function do_truthdata(pipeline::EpiAwareExamplePipeline) - truth_data_configs = [rand(make_truth_data_configs(pipeline))] - truthdata_from_configs = map(truth_data_configs) do truth_data_config - return Dagger.@spawn cache=true generate_truthdata( - truth_data_config, pipeline; plot = true) - end - return truthdata_from_configs -end diff --git a/pipeline/test/constructors/test_constructors.jl b/pipeline/test/constructors/test_constructors.jl index eaf7ab948..9d5ef5a79 100644 --- a/pipeline/test/constructors/test_constructors.jl +++ b/pipeline/test/constructors/test_constructors.jl @@ -85,7 +85,8 @@ end @testset "make_truth_data_configs" begin using EpiAwarePipeline - pipeline = EpiAwareExamplePipeline() + pipeline = RtwithoutRenewalPipeline() + example_pipeline = EpiAwareExamplePipeline() @testset "make_truth_data_configs should return a dictionary" begin config_dicts = make_truth_data_configs(pipeline) @test eltype(config_dicts) <: Dict @@ -96,14 +97,38 @@ end @test all(config_dicts .|> config -> haskey(config, "gi_mean")) @test all(config_dicts .|> config -> haskey(config, "gi_std")) end + + @testset "make_truth_data_configs should return a vector of length 1 for EpiAwareExamplePipeline" begin + config_dicts = make_truth_data_configs(example_pipeline) + @test length(config_dicts) == 1 + end end @testset "default inference configurations" begin using EpiAwarePipeline - pipeline = EpiAwareExamplePipeline() - inference_configs = make_inference_configs(pipeline) - @test eltype(inference_configs) <: Dict + pipeline = RtwithoutRenewalPipeline() + example_pipeline = EpiAwareExamplePipeline() + + @testset "make_inference_configs should return a vector of dictionaries" begin + inference_configs = make_inference_configs(pipeline) + @test eltype(inference_configs) <: Dict + end + + @testset "make_inference_configs should contain igp, latent_namemodels, observation_model, gi_mean, gi_std, and log_I0_prior keys" begin + inference_configs = make_inference_configs(pipeline) + @test inference_configs .|> (config -> haskey(config, "igp") )|> all + @test inference_configs .|> (config -> haskey(config, "latent_namemodels") )|> all + @test inference_configs .|> (config -> haskey(config, "observation_model") )|> all + @test inference_configs .|> (config -> haskey(config, "gi_mean") )|> all + @test inference_configs .|> (config -> haskey(config, "gi_std") )|> all + @test inference_configs .|> (config -> haskey(config, "log_I0_prior") )|> all + end + + @testset "make_inference_configs should return a vector of length 1 for EpiAwareExamplePipeline" begin + inference_configs = make_inference_configs(example_pipeline) + @test length(inference_configs) == 1 + end end @testset "make_default_params" begin From cbdb52bd64aa7da47b38a97f3f838bfef98aca4d Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Tue, 18 Jun 2024 11:58:33 +0100 Subject: [PATCH 4/5] reformat --- pipeline/src/constructors/make_truth_data_configs.jl | 2 +- pipeline/test/constructors/test_constructors.jl | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pipeline/src/constructors/make_truth_data_configs.jl b/pipeline/src/constructors/make_truth_data_configs.jl index 9868a1cef..abb02848b 100644 --- a/pipeline/src/constructors/make_truth_data_configs.jl +++ b/pipeline/src/constructors/make_truth_data_configs.jl @@ -21,6 +21,6 @@ This is the example method, which only returns a randomly selected truth data co function make_truth_data_configs(pipeline::EpiAwareExamplePipeline) gi_param_dict = make_gi_params(pipeline) return Dict( - "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> + "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> dict_list |> list -> [rand(list)] end diff --git a/pipeline/test/constructors/test_constructors.jl b/pipeline/test/constructors/test_constructors.jl index 9d5ef5a79..5f2e07aba 100644 --- a/pipeline/test/constructors/test_constructors.jl +++ b/pipeline/test/constructors/test_constructors.jl @@ -117,12 +117,12 @@ end @testset "make_inference_configs should contain igp, latent_namemodels, observation_model, gi_mean, gi_std, and log_I0_prior keys" begin inference_configs = make_inference_configs(pipeline) - @test inference_configs .|> (config -> haskey(config, "igp") )|> all - @test inference_configs .|> (config -> haskey(config, "latent_namemodels") )|> all - @test inference_configs .|> (config -> haskey(config, "observation_model") )|> all - @test inference_configs .|> (config -> haskey(config, "gi_mean") )|> all - @test inference_configs .|> (config -> haskey(config, "gi_std") )|> all - @test inference_configs .|> (config -> haskey(config, "log_I0_prior") )|> all + @test inference_configs .|> (config -> haskey(config, "igp")) |> all + @test inference_configs .|> (config -> haskey(config, "latent_namemodels")) |> all + @test inference_configs .|> (config -> haskey(config, "observation_model")) |> all + @test inference_configs .|> (config -> haskey(config, "gi_mean")) |> all + @test inference_configs .|> (config -> haskey(config, "gi_std")) |> all + @test inference_configs .|> (config -> haskey(config, "log_I0_prior")) |> all end @testset "make_inference_configs should return a vector of length 1 for EpiAwareExamplePipeline" begin From 102240f1579d2e74cec85bba62704fa4416b70fd Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Wed, 19 Jun 2024 10:57:32 +0100 Subject: [PATCH 5/5] Add _selector methods to dispatch different pipeline number of scenarios --- pipeline/src/constructors/constructors.jl | 1 + .../constructors/make_inference_configs.jl | 29 ++----------------- .../constructors/make_truth_data_configs.jl | 18 +++--------- pipeline/src/constructors/selector.jl | 15 ++++++++++ 4 files changed, 22 insertions(+), 41 deletions(-) create mode 100644 pipeline/src/constructors/selector.jl diff --git a/pipeline/src/constructors/constructors.jl b/pipeline/src/constructors/constructors.jl index 68e02819d..630502c4f 100644 --- a/pipeline/src/constructors/constructors.jl +++ b/pipeline/src/constructors/constructors.jl @@ -1,3 +1,4 @@ +include("selector.jl") include("make_gi_params.jl") include("make_inf_generating_processes.jl") include("make_model_priors.jl") diff --git a/pipeline/src/constructors/make_inference_configs.jl b/pipeline/src/constructors/make_inference_configs.jl index d43195d00..ab0d3815e 100644 --- a/pipeline/src/constructors/make_inference_configs.jl +++ b/pipeline/src/constructors/make_inference_configs.jl @@ -20,31 +20,6 @@ function make_inference_configs(pipeline::AbstractEpiAwarePipeline) "gi_std" => gi_param_dict["gi_stds"], "log_I0_prior" => priors["log_I0_prior"]) |> dict_list - return inference_configs -end - -""" -Create inference configurations for the given pipeline. This is the example method, -which only returns a randomly selected inference configuration. - -# Arguments -- `pipeline`: An instance of `EpiAwareExamplePipeline`. - -# Returns -- An object representing the inference configurations. - -""" -function make_inference_configs(pipeline::EpiAwareExamplePipeline) - gi_param_dict = make_gi_params(pipeline) - namemodel_vect = make_epiaware_name_latentmodel_pairs(pipeline) - igps = make_inf_generating_processes(pipeline) - obs = make_observation_model(pipeline) - priors = make_model_priors(pipeline) - - inference_configs = Dict("igp" => igps, "latent_namemodels" => namemodel_vect, - "observation_model" => obs, "gi_mean" => gi_param_dict["gi_means"], - "gi_std" => gi_param_dict["gi_stds"], "log_I0_prior" => priors["log_I0_prior"]) |> - dict_list - - return [rand(inference_configs)] + selected_inference_configs = _selector(inference_configs, pipeline) + return selected_inference_configs end diff --git a/pipeline/src/constructors/make_truth_data_configs.jl b/pipeline/src/constructors/make_truth_data_configs.jl index abb02848b..59db1f000 100644 --- a/pipeline/src/constructors/make_truth_data_configs.jl +++ b/pipeline/src/constructors/make_truth_data_configs.jl @@ -1,6 +1,5 @@ """ Create a vector of truth data configurations for `pipeline <: AbstractEpiAwarePipeline`. - This is the default method. # Returns A vector of dictionaries containing the mean and standard deviation values for @@ -9,18 +8,9 @@ A vector of dictionaries containing the mean and standard deviation values for """ function make_truth_data_configs(pipeline::AbstractEpiAwarePipeline) gi_param_dict = make_gi_params(pipeline) - return Dict( + gi_param_dict_list = Dict( "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> - dict_list -end - -""" -Create a vector of truth data configurations for `pipeline <: AbstractEpiAwarePipeline`. -This is the example method, which only returns a randomly selected truth data configuration. -""" -function make_truth_data_configs(pipeline::EpiAwareExamplePipeline) - gi_param_dict = make_gi_params(pipeline) - return Dict( - "gi_mean" => gi_param_dict["gi_means"], "gi_std" => gi_param_dict["gi_stds"]) |> - dict_list |> list -> [rand(list)] + dict_list + selected_truth_data_configs = _selector(gi_param_dict_list, pipeline) + return selected_truth_data_configs end diff --git a/pipeline/src/constructors/selector.jl b/pipeline/src/constructors/selector.jl new file mode 100644 index 000000000..65cf4d7b8 --- /dev/null +++ b/pipeline/src/constructors/selector.jl @@ -0,0 +1,15 @@ +""" +Internal method for selecting from a list of items based on the pipeline type. +Default is to return the list as is. +""" +function _selector(list, pipeline::AbstractEpiAwarePipeline) + return list +end + +""" +Internal method for selecting from a list of items based on the pipeline type. +Example/test mode is to return a randomly selected item from the list. +""" +function _selector(list, pipeline::EpiAwareExamplePipeline) + return [rand(list)] +end