From 203b7a3d5bc891cdd934cfcc5c266558d4588686 Mon Sep 17 00:00:00 2001
From: pjentsch <pjentsch@uwaterloo.ca>
Date: Thu, 25 Mar 2021 21:07:18 -0400
Subject: [PATCH] fixed a breakage moving mixing distributions to
 IntervalsModel from CovidAlterVaccinationModel

---
 CovidAlertVaccinationModel/src/data.jl        | 65 -------------------
 .../src/mixing_distributions.jl               | 43 ------------
 IntervalsModel/src/IntervalsModel.jl          |  5 +-
 IntervalsModel/src/rest_durations_model.jl    | 10 ++-
 IntervalsModel/src/ws_durations_model.jl      | 29 ++++++++-
 5 files changed, 38 insertions(+), 114 deletions(-)

diff --git a/CovidAlertVaccinationModel/src/data.jl b/CovidAlertVaccinationModel/src/data.jl
index f472779..abebc66 100644
--- a/CovidAlertVaccinationModel/src/data.jl
+++ b/CovidAlertVaccinationModel/src/data.jl
@@ -10,15 +10,6 @@ function get_canada_demographic_distribution()::Vector{Float64}
     source_bins = map(parse_string_as_float_pair, df[:,:demographic_data_bins])
     return [sum(binned_data[1:5]),sum(binned_data[6:13]),sum(binned_data[14:end])]
 end
-function get_distancing_data_sets()::NTuple{3,Vector{Float64}}
-    f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/distancing_data.csv"), ',')
-    df = filter(row -> row[:country_region_code] == "CA" && row[:sub_region_1] == "Ontario", DataFrame([f[1,i] => f[2:end, i] for i = 1:length(f[1,:])]))
-    distancing_data = df[:,:retail_and_recreation_percent_change_from_baseline] ./ 100
-    workplace_data = df[:,:workplaces_percent_change_from_baseline] ./ 100
-    residental_data = df[:,:residential_percent_change_from_baseline] ./ 100
-    
-    return (workplace_data, distancing_data,residental_data)
-end
 
 function get_canada_case_fatality()::Tuple{Vector{Tuple{Float64,Float64}},Vector{Float64}}
     f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/case_fatality_data.csv"), ',')
@@ -62,62 +53,6 @@ function get_household_data_proportions()
 end
 
 
-function parse_string_as_float_pair(s)::Tuple{Float64,Float64}
-    parsed = strip(s, ['(',')']) |> s -> split(s, ",")
-    if length(parsed) > 2
-        error("input tuple too long")
-    end
-    return (parse(Float64, parsed[begin]), parse(Float64, parsed[end]))
-end
-
-bin_str_to_int(bin_str) = occursin('<',bin_str) ? 1 : parse(Int, strip(bin_str, 's')) #this function parses the bin formatting in the input csv
-
-bin_to_index(bin) = findfirst(((lower,upper),) -> lower <= bin < upper, age_bins)
-
-
-
-function parse_cases_data()::Tuple{Vector{Date},Matrix{Float64}} #this type declaration probably not needed
-    f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/COVID_ontario_data.csv"), ',')
-    df = DataFrame([f[1,i] => f[2:end, i] for i = 1:length(f[1,:])])
-
-    dropmissing!(df,:Accurate_Episode_Date)
-    map!(x -> Date(x),df[!,:Accurate_Episode_Date],df[!,:Accurate_Episode_Date])
-    sort!(df,:Accurate_Episode_Date) 
-
-    #there are some cases before jan 1 2020 but they are neglible so we assume that cases start here
-    begin_date = Date(2020,1,1) 
-    cases_by_date = groupby(df,:Accurate_Episode_Date)
-
-    #Ontario health says that case data with 2 weeks of current date are subject to change
-
-    end_date = Date(maximum(df[!,:Accurate_Episode_Date])) - Day(14) 
-    dates = collect(begin_date:Day(1):end_date)
-    infection_data = zeros(Float64,length(dates), length(age_bins))
-
-
-    for (i,day) in enumerate(dates)
-        cases_on_date = get(cases_by_date, (Accurate_Episode_Date = day,),nothing)
-
-        if !isnothing(cases_on_date)
-            cases_by_age_group = groupby(cases_on_date,:Age_Group)
-
-            for age_group_key in keys(cases_by_age_group)
-                cases = cases_by_age_group[age_group_key]
-                bin_str = age_group_key[:Age_Group]
-                num_cases = nrow(cases)
-                if length(bin_str)>0 && !occursin("UNKNOWN",bin_str)
-                    bin = bin_str_to_int(bin_str)
-                    bin_index = bin_to_index(bin)
-                    infection_data[i,bin_index] = num_cases
-                else
-                    #account for missing age data?
-                end
-            end
-        end
-    end
-
-    return dates, infection_data
-end
 using CSV
 
 function load_mixing_matrices()
diff --git a/CovidAlertVaccinationModel/src/mixing_distributions.jl b/CovidAlertVaccinationModel/src/mixing_distributions.jl
index 3fc3aba..60ad4a0 100644
--- a/CovidAlertVaccinationModel/src/mixing_distributions.jl
+++ b/CovidAlertVaccinationModel/src/mixing_distributions.jl
@@ -13,24 +13,6 @@ function adjust_distributions_mean(distribution_matrix::AbstractArray{T},mean_sh
     end
 end
 
-
-function ZeroPoisson(α,λ)
-    return ZWDist(α,Poisson(λ))
-end
-function ZeroGeometric(α,p)
-    return ZWDist(α,Geometric(p))
-end
-
-function symmetrize_means(population_sizes,mixing_matrix::Matrix{<:ZWDist})
-    mixing_means = mean.(mixing_matrix)
-    symmetrized_means = zeros((length(population_sizes),length(population_sizes)))
-    for i in 1:length(population_sizes), j in 1:length(population_sizes)
-        symmetrized_means[i,j] = 0.5*(mixing_means[i,j] + population_sizes[j]/population_sizes[i] * mixing_means[j,i])
-    end
-    return map(((dst,sym_mean),)->from_mean(typeof(dst),dst.α,sym_mean), zip(mixing_matrix,symmetrized_means))
-end
-
-
 function symmetrize_means(population_sizes,mixing_matrix::Matrix{<:Distribution})
     mixing_means = mean.(mixing_matrix)
     symmetrized_means = zeros((length(population_sizes),length(population_sizes)))
@@ -72,31 +54,6 @@ const unemployment_matrix = alpha_matrix(
     )
 )
 
-function make_workschool_mixing_matrix()
-
-    #all geometric with means given
-    ws_mixing = map(t->from_mean(t...),[
-        (Geometric{Float64}, 4.104848) (Geometric{Float64},2.568782) (Geometric{Float64},0.017729)
-        (Geometric{Float64}, 0.975688) (Geometric{Float64},5.057572) (Geometric{Float64},0.021307)
-        (Geometric{Float64},0.001937)   (Geometric{Float64},0.00722)   (Geometric{Float64}, 0.022134) 
-    ])
-
-    #symmetrize WS mixing with respect to the population proportions in the data 
-    ws_mixing_w_unemployment_symmetrized = symmetrize_means(get_household_data_proportions(),ws_mixing)
-
-    #define a function that adjusts the means of W according to the unemployment_matrix
-    ws_adjust_mean(W) = (5/7) .* (1 .- unemployment_matrix) ./ ( mean.(W) + (5/7) .*  (1 .- unemployment_matrix))
-
-    #create a zero weighted distribution where the zero-weight is given by the unemployment_matrix, and the non-zero weight is given by ws_mixing, symmetrized, with means adjust upwards
-    ws_mixing_w_unemployment_symmetrized_weekday_adjusted = ZWDist.(unemployment_matrix,Geometric.(ws_adjust_mean(ws_mixing_w_unemployment_symmetrized)))
-    
-    return ws_mixing_w_unemployment_symmetrized_weekday_adjusted
-end
-
-@views function ws_sample(age)
-    return rand.(initial_workschool_mixing_matrix[age,:]) * (rand(RNG) < (5/7))
-end
-
 const workschool_mixing, rest_mixing = load_mixing_matrices()
 
 
diff --git a/IntervalsModel/src/IntervalsModel.jl b/IntervalsModel/src/IntervalsModel.jl
index d0811f8..936a9d8 100644
--- a/IntervalsModel/src/IntervalsModel.jl
+++ b/IntervalsModel/src/IntervalsModel.jl
@@ -10,7 +10,6 @@ using Random
 using KernelDensity
 using StatsBase
 using Distributions
-using CovidAlertVaccinationModel
 using ZeroWeightedDistributions
 const PACKAGE_FOLDER = dirname(dirname(pathof(IntervalsModel)))
 using DataStructures:OrderedDict
@@ -58,7 +57,7 @@ end
         priors_list::Vector{Distribution}, 
         dists::Vector{Distribution}, 
         particles::Integer;
-        alpha = 0.95
+        alpha = 0.98
     )
 
 # Arguments
@@ -85,7 +84,7 @@ Number of particles to obtain representing posterior distribution of the distrib
 
 # Optional Arguments
 
-- alpha = 0.95
+- alpha = 0.98
 
 Threshold adaptive rate, see `KissABC.smc` for more details.
 """
diff --git a/IntervalsModel/src/rest_durations_model.jl b/IntervalsModel/src/rest_durations_model.jl
index c0f3203..8b3c7c2 100644
--- a/IntervalsModel/src/rest_durations_model.jl
+++ b/IntervalsModel/src/rest_durations_model.jl
@@ -1,5 +1,3 @@
-
-const rest_distributions = CovidAlertVaccinationModel.initial_rest_mixing_matrix
 const rest_data = get_rest_data()
 const kerneldensity_data_rest = (
     Y = InterpKDE(kde(rest_data.Y.durs,weights = rest_data.Y.weights)),
@@ -11,6 +9,14 @@ const data_rest = hcat(
     map(i->pdf(kerneldensity_data_rest.M,i), 0:143),
     map(i->pdf(kerneldensity_data_rest.O,i), 0:143),
 )
+using CovidAlertVaccinationModel: symmetrize_means, get_household_data_proportions, from_mean
+const rest_distributions = symmetrize_means(get_household_data_proportions(),map(t->from_mean(t...),[
+    (Geometric{Float64},2.728177)  (Geometric{Float64},1.382557)        (Geometric{Float64},0.206362) 
+    (Geometric{Float64},1.139072)    (Geometric{Float64},3.245594)        (Geometric{Float64},0.785297)   
+    (Geometric{Float64},0.264822)    (Geometric{Float64},0.734856)          (Geometric{Float64},0.667099) 
+]))
+
+
 """
     err_rest(p::Vector{Number},dist::Distribution)
 
diff --git a/IntervalsModel/src/ws_durations_model.jl b/IntervalsModel/src/ws_durations_model.jl
index c9d8de2..404e127 100644
--- a/IntervalsModel/src/ws_durations_model.jl
+++ b/IntervalsModel/src/ws_durations_model.jl
@@ -33,7 +33,7 @@ function err_ws(p,dist)
     for _ in 1:sample_repeat
         for age_sample in YOUNG:OLD
             #Sample neighbourhood sizes. Note that this includes the weekend/weekday coinflip, implemented in CovidAlertVaccinationModel.  
-            neighourhoods = CovidAlertVaccinationModel.ws_sample(age_sample)
+            neighourhoods = ws_sample(age_sample)
 
             for age_j in YOUNG:OLD #for a given age_sample loop over possible contact ages        
                 if neighourhoods[age_j] > 0
@@ -57,3 +57,30 @@ function err_ws(p,dist)
     end
     return errsum./sample_repeat
 end
+
+
+
+function make_workschool_mixing_matrix()
+
+    #all geometric with means given
+    ws_mixing = map(t->from_mean(t...),[
+        (Geometric{Float64}, 4.104848) (Geometric{Float64},2.568782) (Geometric{Float64},0.017729)
+        (Geometric{Float64}, 0.975688) (Geometric{Float64},5.057572) (Geometric{Float64},0.021307)
+        (Geometric{Float64},0.001937)   (Geometric{Float64},0.00722)   (Geometric{Float64}, 0.022134) 
+    ])
+
+    #symmetrize WS mixing with respect to the population proportions in the data 
+    ws_mixing_w_unemployment_symmetrized = symmetrize_means(get_household_data_proportions(),ws_mixing)
+
+    #define a function that adjusts the means of W according to the unemployment_matrix
+    ws_adjust_mean(W) = (5/7) .* (1 .- unemployment_matrix) ./ ( mean.(W) + (5/7) .*  (1 .- unemployment_matrix))
+
+    #create a zero weighted distribution where the zero-weight is given by the unemployment_matrix, and the non-zero weight is given by ws_mixing, symmetrized, with means adjust upwards
+    ws_mixing_w_unemployment_symmetrized_weekday_adjusted = ZWDist.(unemployment_matrix,Geometric.(ws_adjust_mean(ws_mixing_w_unemployment_symmetrized)))
+    
+    return ws_mixing_w_unemployment_symmetrized_weekday_adjusted
+end
+
+@views function ws_sample(age)
+    return rand.(initial_workschool_mixing_matrix[age,:]) * (rand(RNG) < (5/7))
+end
-- 
GitLab