Health zones
The health-zone stage melded onto the joint fit: the model, the fixed inputs it reads from a parent chain, and the post-processing that turns its draws into shares, reproduction numbers, forecasts and scores. The model and its inputs are in models/zone.jl and the post-processing of a zone chain is in zone.jl.
Index
BVDOutbreakSize.ZONE_FORECAST_METHODBVDOutbreakSize.bvd_zoneBVDOutbreakSize.fit_zoneBVDOutbreakSize.plot_zone_composition_ppcBVDOutbreakSize.reconstruct_zone_rtBVDOutbreakSize.reconstruct_zone_sharesBVDOutbreakSize.zone_composition_calibrationBVDOutbreakSize.zone_composition_drawsBVDOutbreakSize.zone_composition_ppcBVDOutbreakSize.zone_correlation_factorsBVDOutbreakSize.zone_deformationBVDOutbreakSize.zone_diagnostics_tableBVDOutbreakSize.zone_draw_mixingBVDOutbreakSize.zone_fit_inputsBVDOutbreakSize.zone_forecastBVDOutbreakSize.zone_forecast_archiveBVDOutbreakSize.zone_forecast_blockBVDOutbreakSize.zone_forecast_drawsBVDOutbreakSize.zone_forecast_probabilitiesBVDOutbreakSize.zone_forecast_scoresBVDOutbreakSize.zone_forecast_tableBVDOutbreakSize.zone_forecast_truthBVDOutbreakSize.zone_forecast_vs_truthBVDOutbreakSize.zone_infectionsBVDOutbreakSize.zone_last_case_datesBVDOutbreakSize.zone_meld_blockBVDOutbreakSize.zone_meld_checkBVDOutbreakSize.zone_overview_tableBVDOutbreakSize.zone_parent_epsilonBVDOutbreakSize.zone_parent_extractBVDOutbreakSize.zone_parent_inputsBVDOutbreakSize.zone_parent_scaleBVDOutbreakSize.zone_patch_infectionsBVDOutbreakSize.zone_recent_casesBVDOutbreakSize.zone_sampler_diagnosticsBVDOutbreakSize.zone_score_keyBVDOutbreakSize.zone_score_rowsBVDOutbreakSize.zone_share_renewalBVDOutbreakSize.zone_subsetBVDOutbreakSize.zone_week_midpoints
Reference
BVDOutbreakSize.bvd_zone Method
bvd_zone(
zd;
region_sd_prior,
region_halflife_prior,
severity_sd_prior,
mixing_within_prior,
mixing_departure_prior,
offset_prior,
forecast
) -> AnyHealth-zone composition model, stage two of the melding. zd is the model_data of zone_fit_inputs: the fixed stage-1 inputs (patch infections Ī_p, the generation-interval and infection-to-report PMFs), the zone count matrix and the scored cells, the knot days and the walking mask, all plain arrays, plus the softmax scale share_scale, the knot spacing week and the reporting floor rt_floor. Nothing in it is sampled here.
Parameters
s is zd.share_scale and w is zd.week, the days between knots. The mixing block (ε_w, τ, z^m) is sampled only where zd.mixing carries the kernel, the correlation ρ_corr only where zd.zone_distances does, and the shared draw η only where zd.meld_d is positive. The deviation knots δ_z(k) are deviation_knots, the province model's construction, applied with one group per patch and the zones of a patch as its units: the level and the innovations are correlated within a patch by zone_correlation_factors and centred within it, so every patch sums to zero at every knot.
The innovations exist for the walking zones W_p only (cumulative confirmed cases at the cut-off at or above the threshold, and at least two such zones in the patch). A level-only zone decays along the AR mean path. Each block is one ~ over a product_distribution, and the innovation block is absent when no zone walks. κ floors both ρ and 1 − ρ at machine epsilon (safe_rate), so a proposal at either end of the prior's support keeps the composition mass finite.
Every scale the two levels share takes its prior from the province posterior fitted to its draws (zd.parent_priors): the drift scale, the two composition overdispersions, the relative ascertainment and fatality scales, and the deviation correlation. A zone therefore starts at its province's estimate and departs only as far as its own counts require.
The shared quantity
η ~ N(0, I_d) is the whitened draw of the province model's weekly infections in each patch and, when the zones mix, of its log importation intensity per origin patch, the quantities the two stages share (zone_meld_block). Its Cholesky factor carries the province model's joint posterior over all patches, weeks and origins together, so a draw moves whole patch trajectories, and moves the patches together where the province model says they move together. The daily patch trajectory the draw implies is the province model's mean curve times exp(a_p(t)) with a = L η (zone_parent_scale), its origin intensities the mean times e = exp(c) (zone_parent_epsilon), and the zone model is conditional on both.
This is the model's only parent term. The zone infections sum to the sampled patch total by construction. Scoring those sums against the province model's posterior again would count that posterior twice. With no kept cell (zd.meld_d == 0) the stage reads the province model's mean curve.
Likelihood
The share renewal zone_share_renewal gives each zone's infections as its share of the sampled patch infections, the delay operator (zone_delay_operator) and binning (zone_report_increments) give the expected confirmed reports per vintage window, and the observed zone increments of each patch and vintage follow a Dirichlet-multinomial on the allocated total with concentration κ π (zone_composition_logpdf), as one @addlogprob! over every cell.
The allocated zone deaths of every vintage follow a second Dirichlet-multinomial, on the infection-to-confirmed-death PMF rather than the case delay, with its own concentration from ρ_death. A case table and a death table do not disperse alike. The two do not share one.
Cases observe incidence times case-finding and deaths incidence times lethality, so each composition carries its own multiplier over the zones of a patch, relative_multiplier: relative ascertainment on the cases and relative fatality on the deaths. Both are the province model's own per-province construction, log contrasts summing to zero within the group, partially pooled at a scale whose prior is the province posterior for the same scale between provinces. A composition identifies only the product of a multiplier and the incidence split, so the pooling is what separates them: as the scale shrinks the shares weight zones by incidence alone.
Both are relative to the zone's own province. A factor common to a patch cancels in a within-patch composition, so the province level of each multiplier is the one the province model estimates from the per-province compositions, and the zone level is estimated here. The two are multiplied into zone_ascertainment_national and zone_severity_national for reporting on one scale.
Two compositions carry three unknowns per zone, so one has to be pinned. severity_sd_prior is tight where the ascertainment scale is the province posterior's, which asserts that deaths per infection vary little between the zones of a patch. The death composition then pins the incidence split and the case composition identifies ascertainment as the residual, as the province model's own asymmetry does between provinces. Read zone_severity_sd against its prior: a posterior that has not moved says the assumption is carrying the identification.
Infections cross zone boundaries through the two blocks of zone_importation_blocks as zone_share_renewal applies them. Between patches the flows are the province model's own at the shared draw (zone_draw_mixing): its per-origin intensity weights the origin zones and its arrivals into a patch set how many infections land there, so the zone stage only distributes them over the destination patch's zones and the same movement is not counted at both levels. Within a patch the spill is the zone stage's own mechanism and carries its own intensity, ε_w ~ Beta(1, 20) with a pooled per-origin deviation τ (z − z̄) on the logit scale. Mixing is off when the health-zone metadata does not cover every zone or the parent chain carries no between-patch movement (zd.mixing === nothing).
Deterministics
Flattened column-major where a matrix: delta_knots_zone (n_zones × n_knots), share_knots_zone (n_zones × n_knots), delta_T_zone, share_T_zone, share_start_zone (the initial shares w_z(t_0)), R_T_zone (the implied I_z / Λ_z at the cut-off, NaN below zd.rt_floor cumulative zone infections), region_sd_zone (σ_L), region_drift_sd_zone (σ_δ, one per patch), region_halflife_zone (h), composition_rho_zone (ρ), composition_rho_death_zone, zone_ascertainment_national and zone_severity_national (the same multipliers against the national average, the province model's contrast times the zone's own), correlation_reference_zone (ρ_corr) and correlation_length_zone (ℓ), parent_eta_zone (the whitened shared draw η), parent_patch_T_zone (the sampled patch infections on the last grid day) and, with mixing, mixing_epsilon_zone. Daily trajectories are rebuilt from these by zone_forward.
Forecast
With forecast a ForecastHorizon (see with_horizon) the model runs past the cut-off on the inputs of zone_forecast_block, which zd.forecast must carry for the same horizon. The future weeks of the shared quantity are η_future ∼ N(0, I) through the extended factor, the future knots take fresh innovations z_drift_future through the same AR(1), and the renewal and delays run on over the horizon. Each zone's expected confirmed reports over the horizon, times its relative ascertainment, set its share forecast_zone_share of the patch. forecast_pair picks a parent forecast draw, whose confirmed cases per patch (forecast_patch_confirmed) are split over the zones by the fitted case composition into forecast_zone_confirmed. Every fitted quantity is computed on the fitted days as without a forecast.
BVDOutbreakSize.fit_zone Method
fit_zone(
parent_chain,
obs;
samples,
chains,
n_adapts,
target_accept,
max_depth,
seed,
callback,
top_zones,
walk_threshold,
lead_days,
week,
share_scale,
rt_floor,
zones,
patch_names,
patch_labels,
model_kwargs,
kwargs...
) -> Anyfit_zone(
parent_chain,
obs;
samples,
chains,
n_adapts,
target_accept,
max_depth,
seed,
callback,
top_zones,
walk_threshold,
lead_days,
week,
share_scale,
rt_floor,
zones,
patch_names,
patch_labels,
model_kwargs,
kwargs...
) -> AnyFit the health-zone model bvd_zone melded from parent_chain, a bvd_joint chain with the patch structure on, to the zone tables in obs. Builds the fixed inputs with zone_fit_inputs and runs nuts_sample at the settings the caller gives, which the fit registry sets to the ones every other fit in the report uses. Logs the adapted step size, the divergences and the fraction of iterations at the tree-depth cap per chain. The zones mix wherever the health-zone metadata and the parent chain allow it, and the log says when they do not. top_zones fits the zone_subset of the observations, for fast iteration. walk_threshold, lead_days, week, share_scale, rt_floor, zones, patch_names and patch_labels pass through to zone_fit_inputs, model_kwargs to bvd_zone and any other keyword to nuts_sample. Priors belong in model_kwargs; passed loose they reach the sampler, which drops what it does not know. Returns the chain.
BVDOutbreakSize.zone_correlation_factors Method
zone_correlation_factors(
distances::AbstractVector,
ℓ::Real;
ridge
) -> Anyzone_correlation_factors(
distances::AbstractVector,
ℓ::Real;
ridge
) -> AnyLower-triangular correlation factors of the zone deviations, one per patch, for deviation_knots. The correlation between two zones decays with the distance between their centroids on one shared length scale,
so ρ_ref is the correlation of two zones a reference distance d̄ apart. A ridge on the diagonal conditions each factorisation. distances holds one matrix per patch, over its zones for the level and over its walking zones for the innovations. The meld carries correlation between patches, through the parent draw every zone of a patch shares. This carries it within a patch, where the zones multiply one trajectory and only their deviations separate them, so a cluster of neighbours can share a local excursion.
BVDOutbreakSize.zone_deformation Function
zone_deformation(zd, scale) -> NamedTuple
zone_deformation(zd, scale, e) -> NamedTuplezone_deformation(zd, scale) -> NamedTuple
zone_deformation(zd, scale, e) -> NamedTupleThe patch quantities the zone renewal reads, deformed by the sampled parent draw. scale is the multiplier of zone_parent_scale and e that of zone_parent_epsilon, or nothing for the cut, which reads the province model's posterior mean and carries none of its uncertainty. Because the deformation is constant over the days before the grid start, every pre-t0 term of zone_fixed_terms is the fixed one times one factor per patch. mixing is the draw's between-patch movement (zone_draw_mixing), nothing when the zones do not mix.
BVDOutbreakSize.zone_draw_mixing Method
zone_draw_mixing(
mix,
scale,
e
) -> NamedTuple{(:within, :between, :origin_weight, :import_fraction, :patch_of_zone), <:Tuple{Any, Any, Any, Matrix, Any}}zone_draw_mixing(
mix,
scale,
e
) -> NamedTuple{(:within, :between, :origin_weight, :import_fraction, :patch_of_zone), <:Tuple{Any, Any, Any, Matrix, Any}}The between-patch movement of one parent draw, in the form zone_share_renewal reads, from the mean movement mix of zone_fit_inputs, the draw's trajectory multiplier scale (zone_parent_scale) and origin intensity multiplier e (zone_parent_epsilon), either nothing at the parent's centre.
The origin weights are the mean weights times e of the origin's patch. The import fraction is the province model's arrivals formula on the deformed curves, on the log-odds scale so it stays below one:
where ō is the mean log odds that an infection in p was imported and s_{pq} the share of p's mean arrivals sent by q. A patch with no arrival share keeps its mean odds.
BVDOutbreakSize.zone_fit_inputs Method
zone_fit_inputs(
parent_chain,
obs;
walk_threshold,
lead_days,
week,
share_scale,
rt_floor,
meld_min_infections,
zones,
patch_names,
patch_labels,
parent_forecast,
horizon
) -> NamedTuple{(:model_data, :zone_keys, :zone_labels, :zone_province, :zone_names, :patch_of_zone, :patch_ranges, :patch_names, :patch_labels, :days, :dates, :counts, :cumulative, :excluded, :walking, :walk_threshold, :knots, :t0, :n, :week, :share_scale, :rt_floor, :seeding, :cutoff, :I_bar, :g, :f, :death_pmf, :meld), <:Tuple{NamedTuple{(:counts, :cell_patch, :cell_vintage, :cell_total, :cell_const, :days, :I_bar, :g, :f, :patch_ranges, :patch_of_zone, :knots, :t0, :n, :week, :share_scale, :rt_floor, :walking, :walk_index, :n_walking, :force_pre, :report_pre_cum, :infections_pre, :mixing, :interp, :report_matrix, :report_pre_rows, :death_counts, :death_cell_patch, :death_cell_vintage, :death_cell_total, :death_cell_const, :death_days, :death_pre_cum, :death_matrix, :death_pre_rows, :meld_weights, :meld_L, :meld_d, :meld_epsilon_rows, :zone_distances, :zone_walk_distances, :correlation_distance, :parent_priors, :province_ascertainment, :province_severity, :forecast), <:Tuple{Matrix{Int64}, Vector{Int64}, Vector{Int64}, Vector{Int64}, Vector{Float64}, Vector{Int64}, Any, Any, Any, Vector{UnitRange{Int64}}, Vector{Int64}, Any, Any, Any, Int64, Float64, Float64, Vector{Bool}, Vector{Int64}, Int64, Any, Any, Any, Union{Nothing, NamedTuple{(:within, :between, :origin_weight, :patch_of_zone, :import_log_odds, :arrival_shares), <:Tuple{Matrix{Float64}, Matrix{Float64}, Any, Vector{Int64}, Any, Any}}}, Any, Matrix{Float64}, Any, Matrix{Int64}, Vector{Int64}, Vector{Int64}, Vector{Int64}, Vector{Float64}, Vector{Int64}, Any, Matrix{Float64}, Any, Any, Matrix{Float64}, Any, Any, Vector{Matrix{Float64}}, Vector{Matrix{Float64}}, Float64, NamedTuple{(:ascertainment_sd, :drift_sd, :rho, :rho_death, :correlation), <:NTuple{5, Tuple{Any, Any}}}, Vector{Float64}, Vector{Float64}, Nothing}}, Vector{String}, Vector{String}, Vector{String}, Vector{String}, Vector{Int64}, Vector{UnitRange{Int64}}, Vector{String}, Vector{String}, Vector{Int64}, Vector, Matrix{Int64}, Vector, Vector, Vector{Bool}, Int64, Any, Any, Any, Int64, Float64, Float64, Any, Any, Any, Any, Any, Any, Union{NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Int64, Any, Vector{Float64}, Any}}, NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Any, Any, Vector{Float64}, Matrix{Float64}}}}}}zone_fit_inputs(
parent_chain,
obs;
walk_threshold,
lead_days,
week,
share_scale,
rt_floor,
meld_min_infections,
zones,
patch_names,
patch_labels,
parent_forecast,
horizon
) -> NamedTuple{(:model_data, :zone_keys, :zone_labels, :zone_province, :zone_names, :patch_of_zone, :patch_ranges, :patch_names, :patch_labels, :days, :dates, :counts, :cumulative, :excluded, :walking, :walk_threshold, :knots, :t0, :n, :week, :share_scale, :rt_floor, :seeding, :cutoff, :I_bar, :g, :f, :death_pmf, :meld), <:Tuple{NamedTuple{(:counts, :cell_patch, :cell_vintage, :cell_total, :cell_const, :days, :I_bar, :g, :f, :patch_ranges, :patch_of_zone, :knots, :t0, :n, :week, :share_scale, :rt_floor, :walking, :walk_index, :n_walking, :force_pre, :report_pre_cum, :infections_pre, :mixing, :interp, :report_matrix, :report_pre_rows, :death_counts, :death_cell_patch, :death_cell_vintage, :death_cell_total, :death_cell_const, :death_days, :death_pre_cum, :death_matrix, :death_pre_rows, :meld_weights, :meld_L, :meld_d, :meld_epsilon_rows, :zone_distances, :zone_walk_distances, :correlation_distance, :parent_priors, :province_ascertainment, :province_severity, :forecast), <:Tuple{Matrix{Int64}, Vector{Int64}, Vector{Int64}, Vector{Int64}, Vector{Float64}, Vector{Int64}, Any, Any, Any, Vector{UnitRange{Int64}}, Vector{Int64}, Any, Any, Any, Int64, Float64, Float64, Vector{Bool}, Vector{Int64}, Int64, Any, Any, Any, Union{Nothing, NamedTuple{(:within, :between, :origin_weight, :patch_of_zone, :import_log_odds, :arrival_shares), <:Tuple{Matrix{Float64}, Matrix{Float64}, Any, Vector{Int64}, Any, Any}}}, Any, Matrix{Float64}, Any, Matrix{Int64}, Vector{Int64}, Vector{Int64}, Vector{Int64}, Vector{Float64}, Vector{Int64}, Any, Matrix{Float64}, Any, Any, Matrix{Float64}, Any, Any, Vector{Matrix{Float64}}, Vector{Matrix{Float64}}, Float64, NamedTuple{(:ascertainment_sd, :drift_sd, :rho, :rho_death, :correlation), <:NTuple{5, Tuple{Any, Any}}}, Vector{Float64}, Vector{Float64}, Nothing}}, Vector{String}, Vector{String}, Vector{String}, Vector{String}, Vector{Int64}, Vector{UnitRange{Int64}}, Vector{String}, Vector{String}, Vector{Int64}, Vector, Matrix{Int64}, Vector, Vector, Vector{Bool}, Int64, Any, Any, Any, Int64, Float64, Float64, Any, Any, Any, Any, Any, Any, Union{NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Int64, Any, Vector{Float64}, Any}}, NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Any, Any, Vector{Float64}, Matrix{Float64}}}}}}Everything the zone model and its render need, built once from the parent chain and the observations: the fixed stage-1 inputs (zone_parent_inputs), the zone units and their data, the grid and the sampler's starting point.
Zones are the health-zone rows of obs.zone_confirmed_history (zone_increment_matrix), nested in the stage-1 patches of PROVINCE_NAMES and ordered patch by patch; unallocated pseudo-rows are never units. Per vintage the zone increments are the consecutive-vintage differences clamped at zero, the first vintage's increment its cumulative, and the allocated patch total their sum. A vintage on which a patch's unallocated count falls in either zone block is a reattribution into the zones and is zeroed for that patch (zone_increment_matrix); excluded lists those (patch, date) pairs. Cells with a zero allocated total are dropped here, so the model scores only positive totals. The walking set is the zones whose cumulative confirmed count at the cut-off is at least walk_threshold, in patches with at least two such zones. The grid starts lead_days before the first vintage and carries knots every week days (knot_days) to the cut-off. share_scale is the softmax scale of the initial shares and rt_floor the cumulative zone infections below which R_T_zone is undefined; both are stored in model_data for the model and in the returned inputs for the render, so the two read one value.
The shared quantity's multivariate normal is fitted here too (zone_meld_block), over the weekly windows of the same knot grid and every patch together, and meld_min_infections is the parent mean below which a window is dropped as not yet seeded.
parent_forecast, the parent's posterior-predictive draws (forecast_draws), adds the inputs the forecast reads (zone_forecast_block) over horizon days as model_data.forecast. The fitted model does not read them, so a chain fitted without them serves the forecast model.
zones is the metadata table of load_health_zones, read from the package data by default, for labels and, with mixing, populations and centroids. Returns a named tuple whose model_data field is the plain-array input of bvd_zone, alongside the zone keys and labels, the patch index and labels, the vintage days and dates, the cumulative counts, the walking mask, the knots, the grid start, the initial-share start values and the shared quantity's block.
BVDOutbreakSize.zone_forecast_block Method
zone_forecast_block(
forecast,
meld,
I_bar::AbstractMatrix,
g::AbstractVector,
f::AbstractVector,
death_pmf::AbstractVector,
t0::Integer,
knots::AbstractVector{<:Integer},
patch_of_zone,
mixing;
horizon,
week,
min_infections,
ridge
) -> NamedTuple{(:horizon, :knots, :n_future_knots, :meld_weights, :meld_L, :meld_d_future, :I_bar, :force_pre, :report_pre_cum, :infections_pre, :report_pre_rows, :death_pre_cum, :death_pre_rows, :interp, :report_matrix, :death_matrix, :mixing, :totals), <:Tuple{Int64, Any, Any, Any, Any, Int64, Any, Any, Any, Any, Any, Any, Any, Any, Matrix{Float64}, Matrix{Float64}, Any, Any}}zone_forecast_block(
forecast,
meld,
I_bar::AbstractMatrix,
g::AbstractVector,
f::AbstractVector,
death_pmf::AbstractVector,
t0::Integer,
knots::AbstractVector{<:Integer},
patch_of_zone,
mixing;
horizon,
week,
min_infections,
ridge
) -> NamedTuple{(:horizon, :knots, :n_future_knots, :meld_weights, :meld_L, :meld_d_future, :I_bar, :force_pre, :report_pre_cum, :infections_pre, :report_pre_rows, :death_pre_cum, :death_pre_rows, :interp, :report_matrix, :death_matrix, :mixing, :totals), <:Tuple{Int64, Any, Any, Any, Any, Int64, Any, Any, Any, Any, Any, Any, Any, Any, Matrix{Float64}, Matrix{Float64}, Any, Any}}The fixed inputs bvd_zone reads past the cut-off n when run with a ForecastHorizon of horizon days, built from the fitted shared quantity meld (zone_meld_block) and the parent's posterior-predictive draws forecast (forecast_draws on the parent), which carry one draw per parent draw in the same order.
The shared quantity is extended over the forecast weeks. Each parent draw's log weekly patch infections over the fitted cells of meld and over the future windows (n, n + 7], … (kept where the parent's mean reaches min_infections) are stacked, and their covariance factorised with the fitted block held at meld.L:
A fresh η_f ∼ N(0, I) then draws the future weeks from the parent's posterior conditional on the fitted draw η, and the fitted model is unchanged. The daily deformation keeps the fitted rows up to n and interpolates from day n to the future midpoints after it. The mean curve past n is the parent's mean log predicted infections, and every delay operator and pre-t0 term is rebuilt on the longer grid. The mean import odds and arrival shares of the mixing hold their value at n, and the draw's deformation moves them past it as before it.
totals holds each parent draw's predicted confirmed cases per patch over (n, n + horizon] (forecast_province_confirmed), the counts the zone forecast splits. horizon must be one of the parent's weekly forecast vintages.
BVDOutbreakSize.zone_meld_block Method
zone_meld_block(
infections::AbstractVector,
np::Integer,
n::Integer,
knots::AbstractVector{<:Integer},
I_bar::AbstractMatrix,
t0::Integer;
extra,
min_infections,
ridge
) -> Union{NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Int64, Any, Vector{Float64}, Any}}, NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Any, Any, Vector{Float64}, Matrix{Float64}}}}zone_meld_block(
infections::AbstractVector,
np::Integer,
n::Integer,
knots::AbstractVector{<:Integer},
I_bar::AbstractMatrix,
t0::Integer;
extra,
min_infections,
ridge
) -> Union{NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Int64, Any, Vector{Float64}, Any}}, NamedTuple{(:weights, :L, :cells_patch, :cells_week, :midpoints, :d, :extra_cells, :mean_log, :log_sums), <:Tuple{Any, Matrix{Float64}, Vector{Int64}, Vector{Int64}, Any, Any, Any, Vector{Float64}, Matrix{Float64}}}}The quantity the two stages share: the province model's weekly infections in each patch, as one multivariate normal on the log scale fitted to its draws.
infections holds one flattened (n_patches × n) infection matrix per parent draw, knots the weekly grid and I_bar the parent's mean patch infections. Window k of patch p spans (knots[k], knots[k + 1]], and the pair is kept when the parent's mean infections over that window reach min_infections. That drops the windows in which a patch is not yet seeded, whose log sums are not normal. Over the kept pairs the log sums have mean m and sample covariance Σ. The Cholesky factor L is taken after adding ridge of each cell's own variance to the diagonal, so that log S = m + L η with η ∼ N(0, I_d) reproduces the parent's joint posterior on the shared quantity to first order. Σ is rank deficient whenever the parent carries fewer draws than there are cells. The factorisation then blends toward diag(Σ) at the smallest weight that succeeds (_zone_meld_factor). Shrinking toward the diagonal of Σ rather than toward the identity keeps every week's own variance and gives up only the correlations, which is the direction the parent's posterior supports least.
Only the deviation a = L η is used, never m, because the zone stage multiplies the parent's own mean curve by exp(a). weights is the linear map from a to that daily log deviation on every patch and day, an (n_patches · n) × d matrix whose rows are flattened patch-major as the parent stores infections_patch. It interpolates each patch's kept midpoints (zone_week_midpoints) and holds flat outside them. Every patch's first kept midpoint falls on or after the grid start t0, so the deviation is constant over the days before t0, which is what lets the pre-t0 terms of zone_fixed_terms be rescaled by one factor per patch rather than rebuilt on every forward pass. A patch whose first kept midpoint fell before t0 would break that, and is an error.
extra holds further shared quantities, one row per parent draw and one column each, on the scale they are melded on. They are appended after the patch-week cells as extra_cells, so the infection block of L is the leading block, and their rows of weights are zero: they reach the zone model through L η alone. The zone stage passes the per-origin log importation intensity here when the zones mix.
Returns (; weights, L, cells_patch, cells_week, midpoints, d, extra_cells, mean_log, log_sums), log_sums holding the per-draw log sums and the extra columns (n_draws × d).
BVDOutbreakSize.zone_parent_epsilon Method
zone_parent_epsilon(
rows::AbstractMatrix,
η::AbstractVector
) -> Anyzone_parent_epsilon(
rows::AbstractMatrix,
η::AbstractVector
) -> AnyThe multiplier the sampled parent draw applies to the province model's mean importation intensity of each origin patch, exp(c) with c the draw's rows of L η for the origin cells of zone_meld_block. rows are those rows of L, empty when the zones do not mix.
BVDOutbreakSize.zone_parent_extract Method
zone_parent_extract(
chn;
source,
n_patches
) -> NamedTuple{(:draws, :n, :keys, :source, :created), <:Tuple{Dict{Symbol, Any}, Any, Vector{Symbol}, String, String}}zone_parent_extract(
chn;
source,
n_patches
) -> NamedTuple{(:draws, :n, :keys, :source, :created), <:Tuple{Dict{Symbol, Any}, Any, Vector{Symbol}, String, String}}The draws the zone stage reads from a parent bvd_joint chain, as plain arrays: one iterations-by-chains matrix per key of _ZONE_EXTRACT_KEYS the chain carries (a vector-valued quantity holds one vector per cell), under draws, with the number of grid days n the patch infections span (their length over n_patches), the keys present and the source label. The extract is a few megabytes where the chain is tens, serialises without a chains library, and is accepted wherever the zone stage takes a parent chain (zone_fit_inputs, zone_forecast_draws). The fit script writes one next to a cached fit (docs/fits/summary.jl).
BVDOutbreakSize.zone_parent_inputs Method
zone_parent_inputs(
chn
) -> NamedTuple{(:log_infections, :g, :f, :death_pmf, :origin_epsilon, :import_log_odds, :priors, :province_ascertainment, :province_severity), <:Tuple{Any, Any, Any, Any, Any, Any, NamedTuple{(:ascertainment_sd, :drift_sd, :rho, :rho_death, :correlation), <:NTuple{5, Tuple{Any, Any}}}, Any, Any}}zone_parent_inputs(
chn
) -> NamedTuple{(:log_infections, :g, :f, :death_pmf, :origin_epsilon, :import_log_odds, :priors, :province_ascertainment, :province_severity), <:Tuple{Any, Any, Any, Any, Any, Any, NamedTuple{(:ascertainment_sd, :drift_sd, :rho, :rho_death, :correlation), <:NTuple{5, Tuple{Any, Any}}}, Any, Any}}The stage-1 quantities the zone model conditions on, read from a bvd_joint parent chain: the patch infections Ī_p(t) (n_patches × n), the generation-interval PMF g (lag 1), the infection-to-confirmed-report PMF f = incubation ⊛ receipt (lag 0, the delay the parent's per-province composition applies to infections) and the infection-to-confirmed-death PMF death_pmf = incubation ⊛ onset-to-death ⊛ receipt, with the between-patch movement: the per-origin importation intensity origin_epsilon and the log odds import_log_odds that an infection in a patch was imported, flattened as infections_patch.
Each is a posterior mean: log_infections is the mean over draws of the log infections per day, so Ī_p is its exponential reshaped to (n_patches × n), the movement is centred on the log scale in the same way, and the PMFs are the mean of the per-draw PMFs. The parent's uncertainty about the patch trajectory and the intensity does not enter here: it enters the fit through the shared quantity of zone_meld_block, which deforms these centres. Returns (; log_infections, g, f, death_pmf, origin_epsilon, import_log_odds, priors, province_ascertainment, province_severity).
BVDOutbreakSize.zone_parent_scale Method
zone_parent_scale(
weights::AbstractMatrix,
L::AbstractMatrix,
η::AbstractVector,
np::Integer,
n::Integer
) -> Anyzone_parent_scale(
weights::AbstractMatrix,
L::AbstractMatrix,
η::AbstractVector,
np::Integer,
n::Integer
) -> AnyThe multiplier the sampled parent draw applies to the province model's mean patch infections, exp(a_p(t)) as an (n_patches × n) matrix, from the whitened draw η. weights and L are the corresponding fields of zone_meld_block. One triangular matrix-vector product and one interpolation product per forward pass.
BVDOutbreakSize.zone_share_renewal Method
zone_share_renewal(
I_bar::AbstractMatrix,
g::AbstractVector,
δ_daily::AbstractMatrix,
w0::AbstractVector,
patch_ranges::AbstractVector{<:UnitRange},
t0::Integer,
force_pre::AbstractMatrix;
mix,
ε
) -> NamedTuple{(:shares, :forces, :infections, :imports), <:NTuple{4, Any}}zone_share_renewal(
I_bar::AbstractMatrix,
g::AbstractVector,
δ_daily::AbstractMatrix,
w0::AbstractVector,
patch_ranges::AbstractVector{<:UnitRange},
t0::Integer,
force_pre::AbstractMatrix;
mix,
ε
) -> NamedTuple{(:shares, :forces, :infections, :imports), <:NTuple{4, Any}}The share renewal over the days t0 … n. Each zone's force of infection is its own past infections through the generation interval g (lag 1), with the days before t0 entering as the initial share times the patch's pre-t0 force (force_pre, from zone_fixed_terms):
δ_daily is (n_days × n_zones), the interpolation weights (zone_interpolation_weights) times the knots, w0 the initial shares and I_bar the patch infections the draw's shared quantity implies.
Without mixing a zone takes the share of its patch its own force earns, w_z = u_z / \sum_{z' ∈ p} u_{z'} and I_z = Ī_p w_z.
With mix, the blocks of zone_importation_blocks and the province model's own per-origin intensity and import fraction at one shared draw (zone_draw_mixing), each day splits the patch total into what the patch grew and what it received:
The within-patch spill is a transfer, so it conserves \sum_{z ∈ p} v_z, and the imports are allocated to exactly the parent's own arrivals, so \sum_{z ∈ p} I_z(t) = Ī_p(t) exactly and no second parent term is added. Before any other patch has infections the import pattern is empty and the arrivals fall to the zones in proportion to their own force. ε is the sampled per-origin within-patch intensity. Pass mix = nothing or ε = nothing to leave the zones unmixed.
Returns (; shares, forces, infections, imports), each (n_days × n_zones).
BVDOutbreakSize.zone_subset Method
zone_subset(obs; top_zones, zones, pool_name)zone_subset(obs; top_zones, zones, pool_name)The observations and health-zone metadata reduced to the top_zones zones of each province with most confirmed cases at the cut-off, the rest of the province's zones pooled into one pool_name zone so every patch total is still allocated. The pooled zone's cumulative case and death series are the sums of the pooled zones', its population their sum and its centroid their population-weighted mean, so mixing and the distance correlation stay on. A province with top_zones zones or fewer is unchanged, and the unallocated rows pass through. For fast iteration on real data rather than for reporting: fit_zone takes top_zones and applies this. Returns (; obs, zones, kept), with kept the retained zone keys per province.
BVDOutbreakSize.zone_week_midpoints Method
zone_week_midpoints(knots::AbstractVector{<:Integer}) -> Anyzone_week_midpoints(knots::AbstractVector{<:Integer}) -> AnyMidpoint day of each weekly window of knots. Window k spans (knots[k], knots[k + 1]], so its midpoint is the mean of the two, and there are length(knots) - 1 of them. A window's infections are attributed to its midpoint when the parent's weekly deformation is interpolated to a daily curve.
BVDOutbreakSize.ZONE_FORECAST_METHOD Constant
ZONE_FORECAST_METHODThe method zone_forecast_archive records on each row, and the only one the release scoring scores for the health zones. It names the method of zone_forecast.
BVDOutbreakSize.plot_zone_composition_ppc Method
plot_zone_composition_ppc(
chn,
inputs;
prior_chain,
top,
ncols,
label,
stream
) -> Vector{Makie.Figure}plot_zone_composition_ppc(
chn,
inputs;
prior_chain,
top,
ncols,
label,
stream
) -> Vector{Makie.Figure}One figure per patch of the composition check: for the top zones with most of the stream's counts, the share band of chn (5–95% and 25–75%, named label in the title), the prior predictive band from prior_chain when given, and the observed share per vintage as points. stream picks the composition, :cases or :deaths. Returns a vector of figures in patch order, one per patch with zones.
BVDOutbreakSize.reconstruct_zone_rt Method
reconstruct_zone_rt(chn, inputs; rt_floor) -> Anyreconstruct_zone_rt(chn, inputs; rt_floor) -> AnyEach zone's implied daily reproduction number I_z(t) / Λ_z(t), rebuilt per draw from the shares and that draw's own patch trajectory, so the interval carries the province model's uncertainty as the fit saw it. A zone is reported from the day its cumulative infections reach rt_floor (the fit's inputs.rt_floor by default) in the median draw, and holds NaN in every draw before that day, so the reported draws are never a selected subset. Returns one (ndraws × n) matrix per zone.
BVDOutbreakSize.reconstruct_zone_shares Method
reconstruct_zone_shares(chn, inputs) -> Anyreconstruct_zone_shares(chn, inputs) -> AnyEach zone's daily share of its patch's infections, rebuilt for every draw by re-running the share renewal (zone_forward) from the knots and the fixed inputs. Returns one (ndraws × n) matrix per zone, in the order of inputs.zone_keys; the days before the grid start hold the draw's initial share, as the model does.
BVDOutbreakSize.zone_composition_calibration Method
zone_composition_calibration(
chn,
inputs;
stream,
rng
) -> DataFrames.DataFramezone_composition_calibration(
chn,
inputs;
stream,
rng
) -> DataFrames.DataFrameCalibration of the composition per patch, in the columns of stream_calibration: over every zone and vintage with a positive allocated patch total, the mean bias_sample of the observed count against the predictive counts of zone_composition_draws and the fraction of cells inside the central 50% and 90% predictive intervals. One row per patch and an All zones row. stream picks the composition, :cases or :deaths.
BVDOutbreakSize.zone_composition_draws Method
zone_composition_draws(
chn,
inputs;
stream,
cumulative,
rng
) -> NamedTuple{(:expected, :predictive, :predictive_share, :observed), <:NTuple{4, Any}}zone_composition_draws(
chn,
inputs;
stream,
cumulative,
rng
) -> NamedTuple{(:expected, :predictive, :predictive_share, :observed), <:NTuple{4, Any}}Per-draw composition draws for the posterior predictive check, one (ndraws × n_vintages) matrix per zone in chain order: expected, the modelled share of the patch's allocated total; predictive, counts drawn per draw and vintage from the Dirichlet-multinomial on the observed allocated total at that draw's ρ; and predictive_share, those counts over the total. observed is the (n_zones × n_vintages) observed share. With cumulative = true counts accumulate over the vintages and the shares are of the patch's cumulative allocated total. Shares are NaN where the total is zero.
stream picks the composition: :cases for the per-zone confirmed cases and :deaths for the per-zone confirmed deaths, each with its own concentration and its own observed counts. Both are scored on one vintage grid.
BVDOutbreakSize.zone_composition_ppc Method
zone_composition_ppc(
chn,
inputs;
top,
prior_chain,
stream
) -> DataFrames.DataFramezone_composition_ppc(
chn,
inputs;
top,
prior_chain,
stream
) -> DataFrames.DataFrameComposition posterior predictive check: the observed and modelled share of each patch's allocated counts per vintage, for the top zones with most of them in each patch. The modelled share is the median and 90% interval over draws of the expected increments normalised within the patch. With prior_chain (draws from the model prior, sample(model, Prior(), n)) the same summaries of the prior predictive are added as prior_lower_90, prior_median and prior_upper_90. stream picks the composition, :cases or :deaths. Returns a long DataFrame with columns patch, zone, date, day, observed, observed_share, total, lower_90, median and upper_90; vintages whose allocated patch total is zero are omitted.
BVDOutbreakSize.zone_diagnostics_table Function
zone_diagnostics_table(chn) -> DataFrames.DataFrame
zone_diagnostics_table(chn, inputs) -> DataFrames.DataFramezone_diagnostics_table(chn) -> DataFrames.DataFrame
zone_diagnostics_table(chn, inputs) -> DataFrames.DataFrameSplit R-hat and bulk and tail effective sample sizes of the cut-off quantities of every zone: the reproduction number R_T_zone, the share share_T_zone and the deviation delta_T_zone. One row per zone, in chain order, with the zone's label when inputs is given. A quantity that is constant, or undefined in any draw (a zone below the reporting floor), shows NaN. A level-only zone's R_T_zone varies across draws only at round-off, so its R-hat is meaningless; read the R_T columns for the walking zones (the walking column when inputs is given).
BVDOutbreakSize.zone_forecast Method
zone_forecast(
chn,
inputs;
seed
) -> Union{AbstractMCMC.SamplingOutput{_A, I, Missing, Missing} where {_A, I<:(AbstractRange{<:Integer})}, FlexiChains.FlexiChain{AbstractPPL.VarName, FlexiChains.FlexiChainMetadata{var"#s185", var"#s1851", Vector{Missing}, Vector{Missing}}} where {var"#s185"<:DimensionalData.Dimensions.Lookups.Lookup{Int64, 1}, var"#s1851"<:DimensionalData.Dimensions.Lookups.Lookup{Int64, 1}}}zone_forecast(
chn,
inputs;
seed
) -> Union{AbstractMCMC.SamplingOutput{_A, I, Missing, Missing} where {_A, I<:(AbstractRange{<:Integer})}, FlexiChains.FlexiChain{AbstractPPL.VarName, FlexiChains.FlexiChainMetadata{var"#s185", var"#s1851", Vector{Missing}, Vector{Missing}}} where {var"#s185"<:DimensionalData.Dimensions.Lookups.Lookup{Int64, 1}, var"#s1851"<:DimensionalData.Dimensions.Lookups.Lookup{Int64, 1}}}Posterior-predictive draws of the zone forecast: predict on bvd_zone run past the cut-off (forecast_draws) over the zone chain chn. inputs must carry the parent's forecast (zone_fit_inputs with parent_forecast), whose horizon the forecast runs to. Each draw keeps its fitted parameters, draws the future shared quantity from the parent's posterior conditional on the fitted one, fresh deviation innovations for the future knots and a parent draw of the patch totals, and splits each total over the zones by the fitted composition.
BVDOutbreakSize.zone_forecast_archive Method
zone_forecast_archive(fc, inputs; made_date, thin)zone_forecast_archive(fc, inputs; made_date, thin)Long-format archive of the zone forecast draws fc (zone_forecast) made from the cut-off made_date, in the province_forecast_archive schema plus a zone column. province is the patch key and zone the manifest's dotted province.zone key, whose first part is the source province of the zone histories. Each value is one draw of the zone's new confirmed cases over the forecast horizon, the one horizon the zone forecast runs to, under the confirmed cases stream label. method is ZONE_FORECAST_METHOD. thin keeps every thin-th draw.
BVDOutbreakSize.zone_forecast_draws Method
zone_forecast_draws(
fc,
inputs
) -> NamedTuple{(:zones, :patches, :shares, :kappa), <:NTuple{4, Any}}zone_forecast_draws(
fc,
inputs
) -> NamedTuple{(:zones, :patches, :shares, :kappa), <:NTuple{4, Any}}The zone forecast draws fc (zone_forecast) per zone and patch: the new confirmed cases over the horizon, one draw vector per zone in the order of inputs.zone_keys, the paired parent patch totals, one draw vector per patch, each draw's zone shares (ndraws × n_zones) and each draw's composition concentration. Returns (; zones, patches, shares, kappa).
BVDOutbreakSize.zone_forecast_probabilities Method
zone_forecast_probabilities(
fc,
inputs;
thresholds,
draws
) -> Anyzone_forecast_probabilities(
fc,
inputs;
thresholds,
draws
) -> AnyProbability that each zone reports at least K new confirmed cases over the horizon, for every K in thresholds. Under the fitted composition a zone's count given its patch total N is Beta-binomial, the marginal of the Dirichlet-multinomial with concentration κ π, so over the forecast draws i (zone_forecast_draws), each with its patch total N_i, zone share π_i and concentration κ_i:
Returns an (n_zones × length(thresholds)) matrix.
BVDOutbreakSize.zone_forecast_scores Method
zone_forecast_scores(
fc,
inputs;
truth,
window,
k_baseline,
rng
)zone_forecast_scores(
fc,
inputs;
truth,
window,
k_baseline,
rng
)Scores of the zone forecast draws fc (zone_forecast) against the observed split truth (zone_forecast_truth). Per patch, the multinomial log score of the observed zone split of the patch's weekly total under the zone model (the log of the draw-averaged multinomial mass at the projected shares), against two nulls: share persistence, the observed cumulative zone shares at the cut-off, and naive persistence, the zone split of the last window days before the cut-off. Both nulls carry a pseudo-count of 0.5 per zone. Patches whose observed total is zero or whose truth is incomplete are skipped. The patch total is scored alongside the split by score_draws, the zone model's total against a naive persistence total of the last window days with negative-binomial noise at dispersion k_baseline. Returns a DataFrame with patch, method, observed and log_score, then the score_draws columns crps, log_crps, dispersion, overprediction, underprediction, coverage_50, coverage_90, bias and n. Share persistence forecasts no total, so its score columns are missing.
BVDOutbreakSize.zone_forecast_table Method
zone_forecast_table(
fc,
inputs;
digits,
thresholds
) -> DataFrames.DataFramezone_forecast_table(
fc,
inputs;
digits,
thresholds
) -> DataFrames.DataFramePer-zone new confirmed cases over the forecast horizon from the zone forecast draws fc (zone_forecast), as the median and the 90/60/30% intervals the other forecast tables report, then the probability of at least K cases for each K in thresholds (zone_forecast_probabilities) as p_ge_K, one row per zone with a patch-total row per patch (its threshold columns missing).
BVDOutbreakSize.zone_forecast_truth Method
zone_forecast_truth(obs, inputs; made_date, horizon)zone_forecast_truth(obs, inputs; made_date, horizon)The observed new confirmed cases per zone over (made_date, made_date + horizon], from the zone histories in obs (a later vintage than the fit's), in the order of inputs.zone_keys: the cumulative at the vintage on the target date minus the cumulative at the last vintage on or before made_date, clamped at zero. A zone whose history has no vintage on the target date itself is missing, since the nearest vintage either side would count a different window; zone_forecast_vs_truth shows such a zone unscored and zone_forecast_scores skips its patch.
BVDOutbreakSize.zone_forecast_vs_truth Method
zone_forecast_vs_truth(fc, inputs; truth, digits)zone_forecast_vs_truth(fc, inputs; truth, digits)Per-zone forecast against what was observed: the median, 50% and 90% intervals of the zone forecast draws fc (zone_forecast), the observed count from truth (zone_forecast_truth) and whether it fell inside the interval, one row per zone plus a patch-total row.
BVDOutbreakSize.zone_infections Method
zone_infections(chn, inputs) -> Anyzone_infections(chn, inputs) -> AnyDaily zone infections with the patch uncertainty carried: each draw's share of its own draw of the patch trajectory, I_z = I_p^{(j)}(t) w_z^{(j)}(t), so the two stages are one object rather than paired after the fact. Returns one (ndraws × n) matrix per zone.
BVDOutbreakSize.zone_last_case_dates Method
zone_last_case_dates(inputs) -> Anyzone_last_case_dates(inputs) -> AnyDate of the last vintage on which each zone's allocated confirmed count rose, or missing for a zone with no allocated case, in the order of inputs.zone_keys.
BVDOutbreakSize.zone_meld_check Method
zone_meld_check(
chn,
inputs
) -> NamedTuple{(:table, :mean_norm_sq, :dimension), <:Tuple{DataFrames.DataFrame, Any, Any}}zone_meld_check(
chn,
inputs
) -> NamedTuple{(:table, :mean_norm_sq, :dimension), <:Tuple{DataFrames.DataFrame, Any, Any}}How the fitted draw of the shared quantity compares with the province model's own posterior on it. The zone stage places no prior of its own on that quantity beyond the province model's, so if the zone data say nothing about it the whitened draw should read back as its prior, a standard normal in every component. A component whose posterior mean is far from zero or whose spread is well under one says the zone structure is pulling the province model's trajectory in that week.
Returns (; table, mean_norm_sq, dimension). The table has one row per kept patch-week cell: the patch, the window's midpoint day and date, the posterior mean and standard deviation of that component of the whitened draw, and the province model's own posterior standard deviation of the log weekly infections there. The origin intensity cells have no row. mean_norm_sq is the mean of ‖η‖² over every component, which is dimension when the fit reproduces the prior.
BVDOutbreakSize.zone_overview_table Method
zone_overview_table(
chn,
inputs;
digits
) -> DataFrames.DataFramezone_overview_table(
chn,
inputs;
digits
) -> DataFrames.DataFrameOne row per health zone: its patch, the confirmed cases to date, the share of its patch's infections at the cut-off with a 90% interval, the implied reproduction number at the cut-off with its 90% interval and the posterior probability that it exceeds one, the log-transmission deviation at the cut-off with a 90% interval and whether the zone carries a time-varying deviation. The reproduction number is also given numerically as rt_median, rt_lo90 and rt_hi90 (NaN below the reporting floor), the probability unrounded as p_rt_above_one, and the patch as its index patch_index. It is rebuilt by reconstruct_zone_rt. Walking zones sort first, in decreasing order of the probability that the reproduction number exceeds one with those below the reporting floor last among them, then the level-only zones in the same order.
BVDOutbreakSize.zone_patch_infections Method
zone_patch_infections(chn, inputs) -> Anyzone_patch_infections(chn, inputs) -> AnyDaily patch infections as the zone stage draws them: each draw's own patch trajectory, the province model's mean curve deformed by that draw's shared quantity. The zone infections of zone_infections sum to it within each patch. Returns one (ndraws × n) matrix per patch.
BVDOutbreakSize.zone_recent_cases Method
zone_recent_cases(inputs; window) -> Anyzone_recent_cases(inputs; window) -> AnyConfirmed cases allocated to each zone over the window days ending at the fit's cut-off, from the fitted count matrix and vintage days, in the order of inputs.zone_keys.
BVDOutbreakSize.zone_sampler_diagnostics Function
zone_sampler_diagnostics(chn; ...) -> NamedTuple
zone_sampler_diagnostics(
chn,
inputs;
max_depth
) -> NamedTuplezone_sampler_diagnostics(chn; ...) -> NamedTuple
zone_sampler_diagnostics(
chn,
inputs;
max_depth
) -> NamedTupleSampler-level diagnostics of a zone chain: the number of divergent transitions, the fraction of iterations that hit the tree-depth cap max_depth, the energy Bayesian fraction of missing information (E-BFMI) per chain and the adapted step size per chain, plus the worst R-hat and smallest effective sample sizes over the stored quantities as fit_diagnostics computes them, with R_T_zone left out of that pool (see zone_diagnostics_table). With inputs the walking zones' R_T_zone R-hat is reported separately as max_rhat_R_T_walking.
BVDOutbreakSize.zone_score_key Method
zone_score_key(stream::AbstractString) -> Anyzone_score_key(stream::AbstractString) -> AnyThe zone key of a per-zone scored stream label, "<stream> {<zone key>}" as scripts/score_releases.jl writes it, or nothing for any other label.
BVDOutbreakSize.zone_score_rows Method
zone_score_rows(
tbl::DataFrames.DataFrame,
zone_keys::AbstractVector,
zone_labels::AbstractVector
) -> Anyzone_score_rows(
tbl::DataFrames.DataFrame,
zone_keys::AbstractVector,
zone_labels::AbstractVector
) -> AnyThe rows of a per-zone score or overlay table tbl (data/zone/, written by scripts/score_releases.jl) for the zones zone_keys, in that order, with each stream replaced by the zone's entry in zone_labels. Rows of any other zone are dropped.