Skip to content

Aging alignment with EMOD-Generic - #228

Merged
kfrey-idm merged 4 commits into
mainfrom
more_aging
Aug 9, 2026
Merged

Aging alignment with EMOD-Generic#228
kfrey-idm merged 4 commits into
mainfrom
more_aging

Conversation

@kfrey-idm

Copy link
Copy Markdown
Member

Notes from Claude:

What it does: refactors Susceptibility (and its HIV/Malaria/STI/Vector subclasses) to stop tracking its own private age copy and instead read age live from parent->GetAge() (the IndividualHuman). Mostly mechanical signature cleanup (CreateSusceptibility/Initialize drop the now-redundant age parameter everywhere), plus some cosmetic reformatting. The regression baselines were regenerated wholesale (huge CSV/JSON diffs), which is the tell that this is not behavior-neutral.

Real behavioral differences found

  • Age-desync when Enable_Immunity=false and infections are active, across all disease types. In main, IndividualHuman::Update() only calls susceptibility->Update(dt) (which advanced the local age) inside if(ImmunityEnabled()) during the infection sub-stepping loop, but calls it unconditionally in the no-infection branch. So whenever immunity was disabled and an individual had an active infection, Susceptibility's private age silently stopped advancing while IndividualHuman::m_age kept going — a permanent, uncorrected lag. In more_aging there's no private copy to desync; it always reads the live age. This changes age-dependent susceptibility math (maternal protection modifier, malaria BitingRiskAgeFactor, recalculateBloodCapacity, pyrogenic threshold vs. age) specifically for sims run with Enable_Immunity: 0 plus active infections.
  • Age-freeze coupling changes when Enable_Aging=false. In main, Susceptibility::age incremented unconditionally on every Update() call regardless of the Enable_Aging config flag — so immune aging (maternal protection decay, malaria RBC-capacity growth, pyrogenic threshold drift, age-dependent biting risk) kept progressing even when chronological aging was turned off for the individual. In more_aging, since it now reads parent->GetAge() (which is only advanced inside if(IndividualHumanConfig::aging)), all of that immune/physiological aging now freezes along with chronological age. Any Malaria/Vector regression or user config that sets Enable_Aging: 0 will see a real behavior change here.

Other notable changes

  • Susceptibility::IsImmune() and InitNewInfection() changed from LOG_WARN + safe no-op/false to release_assert(false). No current caller of these base-class virtuals in-tree.
  • Node::LoadOtherDiseaseSpecificDistributions() call moved from before to after ExtractDataFromDemographics() in Node::SetParameters. No current override of this virtual exists anywhere in the tree, so it's a no-op today — but it's an ordering change a disease module overrides it and depends on ExtractDataFromDemographicshaving/not having run yet.
  • Interface type narrowing: IIndividualHuman::GetAge()/GetMonteCarloWeight() changed double to float, and ISusceptibilityContext::getAge() was removed. The backing storage (m_age, m_mc_weight) was already float, so this isn't an actual precision loss, just the interface catching up to reality. Not a concern.
  • Serialization: Susceptibility::age is still archived (ar.labelElement("age") & susceptibility.age, marked // REMOVE NEXT VERSION) but is now permanently 0.0f and unused — dead field kept only for checkpoint schema stability. Harmless, but means old checkpoints' age data is silently discarded on load, which is fine since nothing reads it anymore.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aligns EMOD’s susceptibility “aging” behavior with EMOD-Generic by removing Susceptibility’s private age tracking and instead reading age directly from the owning IIndividualHumanContext (parent->GetAge()). It also propagates signature updates (dropping redundant age parameters) across disease-specific susceptibility subclasses and updates several interfaces to use float for age/MC weight.

Changes:

  • Refactor Susceptibility (+ HIV/Malaria/STI/Vector subclasses) to stop maintaining an internal age copy; age-dependent calculations now use parent->GetAge().
  • Update factory/initialize APIs to remove the age parameter and narrow age/MC weight interface return types from double to float.
  • Adjust Node demographics distribution hooks to accept NodeDemographics* and move the “other disease distributions” hook to run after demographics extraction; regenerate regression baselines.

Reviewed changes

Copilot reviewed 31 out of 45 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Regression/STI/86_STI_ReportRelationshipCensus/output/ReportRelationshipCensus.csv Updated STI regression output baseline reflecting new age-alignment behavior.
Eradication/VectorToHumanAdapter.h Interface return types updated (GetAge, GetMonteCarloWeight) to float.
Eradication/VectorToHumanAdapter.cpp Implementation updated to match new float return types.
Eradication/SusceptibilityVector.h Remove age parameter from factory/init; rename some age parameters for clarity.
Eradication/SusceptibilityVector.cpp Use live parent age for biting-risk calculations; remove unused config accessor.
Eradication/SusceptibilitySTI.h Remove age parameter from factory/init.
Eradication/SusceptibilitySTI.cpp Wire factory/init to new signature (no explicit age).
Eradication/SusceptibilityMalaria.h Remove age parameter from factory/init; make age-dependent helpers read from parent age.
Eradication/SusceptibilityMalaria.cpp Convert malaria age-dependent logic to use parent->GetAge(); refactor innate variation selection.
Eradication/SusceptibilityHIV.h Remove age parameter from factory/init.
Eradication/SusceptibilityHIV.cpp Remove immune-age increment; rely on parent age and updated init signature.
Eradication/Susceptibility.h Add IIndividualHumanContext include; remove getAge() from ISusceptibilityContext exposure; refactor initialization API.
Eradication/Susceptibility.cpp Remove local age increment and getAge(); switch maternal/immune logic to parent age; tighten base virtuals with asserts.
Eradication/NodeEventContextHost.h Minor formatting/cleanup.
Eradication/NodeEventContext.h Forward declaration cleanup and formatting changes.
Eradication/NodeEventContext.cpp Formatting cleanup; return explicit broadcaster interface pointer.
Eradication/Node.h Change demographics distribution hooks to accept NodeDemographics*.
Eradication/Node.cpp Call updated demographics distribution hooks with NodeDemographics* and adjust ordering.
Eradication/ISusceptibilityContext.h Remove getAge() from susceptibility context interface.
Eradication/IndividualVector.cpp Update susceptibility creation call to new signature (no explicit age).
Eradication/IndividualSTI.h Friend/refcounting layout cleanup.
Eradication/IndividualSTI.cpp Update STI susceptibility creation call; formatting cleanup.
Eradication/IndividualMalaria.cpp Update malaria susceptibility creation call to new signature (no explicit age).
Eradication/IndividualHIV.cpp Update HIV susceptibility creation call; formatting cleanup.
Eradication/IndividualEventContext.h Update GetAge/GetMonteCarloWeight return types to float; formatting cleanup.
Eradication/Individual.h Update individual event context accessors to float age/MC weight; minor API ordering/formatting.
Eradication/Individual.cpp Rename parameters for clarity; some minor logic/formatting changes in migration duration helper.
Eradication/IIndividualHumanContext.h Add GetAge() to context interface (as float).
Eradication/IIndividualHuman.h Narrow interface return types for age/MC weight to float and reorder some accessors.
componentTests/IndividualHumanContextFake.h Update fake to match interface type changes (float age/MC weight) and formatting.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Eradication/Susceptibility.h
Comment thread Eradication/Individual.cpp
@kfrey-idm
kfrey-idm merged commit e1c2e02 into main Aug 9, 2026
34 of 38 checks passed
@kfrey-idm
kfrey-idm deleted the more_aging branch August 9, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants