LegacySplitImmunityModel.java
package org.matsim.episim.model;
import com.google.inject.Inject;
import org.matsim.episim.EpisimPerson.DiseaseStatus;
import org.matsim.episim.Immunizable;
/**
* The immunity split that the simulation had before {@link ImmunityModel} existed: protection against infection
* from the effectiveness curves, protection against a severe course from antibody levels.
*
* <p>This is not a model anybody chose. It is what fell out of two independent Guice bindings, since the source
* of immunity used to be decided by which class was bound in each channel:</p>
* <ul>
* <li>{@code InfectionModel} was bound to {@code AgeAndProgressionDependentInfectionModelWithSeasonality},
* which reads {@code getVaccinationEffectiveness} / {@code getImmunityEffectiveness} and
* {@code DefaultInfectionModel.getInfectivity} — all three are curves;</li>
* <li>{@code DiseaseStatusTransitionModel} was bound to {@code AgeDependentDiseaseStatusTransitionModel},
* which inherits the antibody overrides of {@code AntibodyDependentTransitionModel}.</li>
* </ul>
*
* <p>Both scenarios in this repository bind exactly that pair, so this class reproduces their results while the
* source of immunity becomes a single binding. It exists to make that refactoring provably behaviour-preserving
* and is meant to be deleted: a run should be able to say which immunity model it uses, not inherit an answer
* that differs between "will I be infected" and "how badly will it go".</p>
*
* <p>The routing is fixed on purpose. Making it configurable would turn a historical accident into an option.</p>
*/
public class LegacySplitImmunityModel implements ImmunityModel {
private final LegacyCurveImmunityModel curves;
private final LegacyAntibodyImmunityModel antibodies;
@Inject
public LegacySplitImmunityModel(LegacyCurveImmunityModel curves, LegacyAntibodyImmunityModel antibodies) {
this.curves = curves;
this.antibodies = antibodies;
}
@Override
public double getFactor(Immunizable person, VirusStrain strain, DiseaseStatus target, int day) {
return delegateFor(target).getFactor(person, strain, target, day);
}
@Override
public double getInfectivityFactor(Immunizable infector, VirusStrain strain, int day) {
// the infection model read the curve-based infectivity, so this follows the infection side
return curves.getInfectivityFactor(infector, strain, day);
}
private ImmunityModel delegateFor(DiseaseStatus target) {
switch (target) {
case infectedButNotContagious:
return curves;
case showingSymptoms:
case seriouslySick:
case critical:
return antibodies;
default:
throw new IllegalArgumentException("No protection is configured against disease status '" + target
+ "'. Supported are infectedButNotContagious, showingSymptoms, seriouslySick and critical.");
}
}
}