cross_genotype
Cross-genotype coordination for multi-genotype HPV.
Two modules that operate across HPV genotypes:
CrossImmunity(ss.Connector): per-step, reads each registered HPV’snab_imm/cell_immand writes per-targetrel_sus/sev_immvia a cross-protection matrix. Runs betweenDisease.step_stateandDisease.step_infect. Convention: row = target genotype, col = source genotype. Effective immunity to targetgissum_k cross[g, k] * source[uid, k]. Diagonals must lie in [0, 1].HPVTotal(ss.Analyzer): post-hoc, pools per-genotype results into Sim-level totals. Auto-added byhpv.Simwhenever HPV modules are present; accessible atsim.results.all_hpv(the analyzer’snamedefaults to'all_hpv').
Classes
| Name | Description |
|---|---|
| CrossImmunity | Cross-immunity + shared HPV-agent state for multi-genotype HPV. |
| HPVTotal | Analyzer that pools per-genotype HPV results into Sim-level totals. |
CrossImmunity
cross_genotype.CrossImmunity(
cross_imm_sus=None,
cross_imm_sev=None,
pars=None,
**kwargs,
)Cross-immunity + shared HPV-agent state for multi-genotype HPV.
Per-step, reads each registered HPV instance’s clearance-conferred nab_imm / cell_imm and writes per-target sev_imm and a nab-based susceptibility reduction via cross-protection matrices. Vaccine-conferred vax_imm is combined with the nab contribution as an independent-protection path — it is not matrix-multiplied, so the CSV per-genotype rel_imm values are the complete vaccine cross-protection profile. Therapeutic-conferred txvx_sev_imm is likewise pre-scaled per target genotype, and adds to the severity term rather than passing through the matrix.
Combining formulas
sus_imm_nab[target] = sum_k cross_imm_sus[target, k] * nab_imm[uid, k] rel_sus[target] = (1 - sus_imm_nab[target]) * (1 - vax_imm[target]) sev_imm[target] = sum_k cross_imm_sev[target, k] * cell_imm[uid, k] + txvx_sev_imm[target]
Also owns per-agent rel_sev — an intrinsic biological severity scaler sampled once per agent and shared across every genotype’s progression, so each agent has a single intrinsic progression speed. It lives on the connector rather than per HPV module so that all genotypes read the same per-agent draw from set_prognoses.
Methods
| Name | Description |
|---|---|
| ensure_rel_sev | Sample rel_sev for any of uids that don’t have a sample yet. |
| make_cross_immunity | Return (m_sus, m_sev) matrices built from self.pars scalars |
ensure_rel_sev
cross_genotype.CrossImmunity.ensure_rel_sev(uids)Sample rel_sev for any of uids that don’t have a sample yet.
Called from each HPV module’s set_prognoses so that each agent is sampled exactly once, at first need, regardless of module init order. Subsequent calls for the same uids are no-ops.
make_cross_immunity
cross_genotype.CrossImmunity.make_cross_immunity(keys=None)Return (m_sus, m_sev) matrices built from self.pars scalars (cross_imm_sus_med/high, cross_imm_sev_med/high, own_imm_hr). keys defaults to GENOTYPE_KEYS.
HPVTotal
cross_genotype.HPVTotal(*args, **kwargs)Analyzer that pools per-genotype HPV results into Sim-level totals.
Schema is mirrored from the per-genotype HPV modules at init time, so HPVTotal automatically gains a matching all_hpv.<metric> entry for each per-genotype result. Three aggregation strategies are applied:
- People-level union for per-agent state counts listed in
_UNION_STATES: boolean OR across each module’s BoolState array, then counted (an agent infected with any genotype counts once). - Custom derivation for results that need it:
n_susceptible(= n_alive - n_infected),prevalence(= n_infected / n_alive), and the extracum_infections_unique(people-level cumulative unique-agent count, complementing the sum-of-flowscum_infections). - Element-wise sum across module result arrays for everything else, computed in
finalize_results. Cancer flows/cumulatives are exact under this (cancer is attributed to one genotype per agent); infection flows overcount co-infections by design.
Auto-added by hpv.Sim whenever HPV modules are present.
Methods
| Name | Description |
|---|---|
| accumulate_asr_histograms | Compute per-ti annualized cancer rates (crude, ASR, HIV-strat). |
| compute_asr | Age-standardized cancer incidence per 100k person-years (WHO 2000). |
| finalize_results | Sum across modules for all results not handled by step(). |
| init_pre | Discover HPV modules once at init; mirrors CrossImmunity’s pattern. |
| init_results | Mirror schema from per-genotype HPV results + add derived/extras. |
| step | Capture per-step union-based state counts and derived results. |
| update_hiv_cancer_results | Per-ti HIV-stratified cancer counts and annualized rates. |
| who2000_weights_for_edges | Aggregate WHO 2000 5-year weights to arbitrary bin edges. |
accumulate_asr_histograms
cross_genotype.HPVTotal.accumulate_asr_histograms(ti, people, hpvs)Compute per-ti annualized cancer rates (crude, ASR, HIV-strat).
Each rate is stored as events_this_ti / dt / headcount * 1e5 – i.e. the annualized rate at this instant. The Results carry summarize_by='mean', so a downstream annualize() averages the sub-annual quarters back to the annual rate (exact at constant population, ~0.03% error at realistic Rwanda-scale growth).
compute_asr
cross_genotype.HPVTotal.compute_asr(cancers_by_age, n_female_by_age, edges)Age-standardized cancer incidence per 100k person-years (WHO 2000).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| cancers_by_age | per-bin annual cancer counts. | required | |
| n_female_by_age | per-bin female population at risk. | required | |
| edges | bin edges (len = counts + 1); weights aggregate to these bins from WHO2000_5YR_WEIGHTS. |
required |
finalize_results
cross_genotype.HPVTotal.finalize_results()Sum across modules for all results not handled by step().
init_pre
cross_genotype.HPVTotal.init_pre(sim)Discover HPV modules once at init; mirrors CrossImmunity’s pattern.
Set hpv_modules/hiv_module before the super().init_pre call, since starsim’s Module.init_pre invokes self.init_results which reads them.
init_results
cross_genotype.HPVTotal.init_results()Mirror schema from per-genotype HPV results + add derived/extras.
Diseases initialize before analyzers in Starsim’s setup, so the per-genotype HPV result definitions (dtype + label) are available as a template when this runs.
The union-based stocks (n_infected, n_precin, n_cin, n_cancerous) are declared as dtype=float so that step() can write scale-weighted values (fine agents carry scale=1/ratio and must count as 1/ratio).
step
cross_genotype.HPVTotal.step()Capture per-step union-based state counts and derived results.
Element-wise sums for the remaining results are computed in finalize_results once each module’s full per-step array exists.
Union stocks (n_infected, n_precin, n_cin, n_cancerous) are written as scale-weighted floats: people.scale_flows(uids_in_state) so that fine agents (scale=1/ratio) count as 1/ratio, not 1. Derived results (n_susceptible, prevalence) are computed from scale-weighted totals.
update_hiv_cancer_results
cross_genotype.HPVTotal.update_hiv_cancer_results(ti, people, new_cancer, dt)Per-ti HIV-stratified cancer counts and annualized rates.
who2000_weights_for_edges
cross_genotype.HPVTotal.who2000_weights_for_edges(edges)Aggregate WHO 2000 5-year weights to arbitrary bin edges. Each output bin [edges[i], edges[i+1]) sums the 5-year weights whose age midpoint falls within it.