blob: d017487a7c710f3233769859410debcb07661d03 [file] [log] [blame]
package org.eclipse.stem.diseasemodels.standard.impl;
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import java.util.Iterator;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.Edge;
import org.eclipse.stem.core.graph.IntegrationLabel;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.graph.SimpleDataExchangeLabelValue;
import org.eclipse.stem.core.model.STEMTime;
import org.eclipse.stem.definitions.edges.MigrationEdgeLabel;
import org.eclipse.stem.definitions.edges.impl.MigrationEdgeLabelImpl;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabel;
import org.eclipse.stem.diseasemodels.standard.DiseaseModelLabelValue;
//import org.eclipse.stem.diseasemodels.standard.SEIRLabelValue;
//import org.eclipse.stem.diseasemodels.standard.SILabelValue;
import org.eclipse.stem.diseasemodels.standard.SEIRLabel;
import org.eclipse.stem.diseasemodels.standard.SEIRLabelValue;
import org.eclipse.stem.diseasemodels.standard.SILabelValue;
import org.eclipse.stem.diseasemodels.standard.SIR;
import org.eclipse.stem.diseasemodels.standard.SIRLabel;
import org.eclipse.stem.diseasemodels.standard.SIRLabelValue;
import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabel;
import org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabelValue;
import org.eclipse.stem.diseasemodels.standard.StandardFactory;
import org.eclipse.stem.diseasemodels.standard.StandardPackage;
/**
* <!-- begin-user-doc --> An implementation of the model object '<em><b>SIR</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link org.eclipse.stem.diseasemodels.standard.impl.SIRImpl#getImmunityLossRate <em>Immunity Loss Rate</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public abstract class SIRImpl extends SIImpl implements SIR {
/**
* The default value of the '{@link #getImmunityLossRate() <em>Immunity Loss Rate</em>}' attribute.
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @see #getImmunityLossRate()
* @generated
* @ordered
*/
protected static final double IMMUNITY_LOSS_RATE_EDEFAULT = 0.0;
/**
* The cached value of the '{@link #getImmunityLossRate() <em>Immunity Loss Rate</em>}' attribute.
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @see #getImmunityLossRate()
* @generated
* @ordered
*/
protected double immunityLossRate = IMMUNITY_LOSS_RATE_EDEFAULT;
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @generated
*/
protected SIRImpl() {
super();
}
/**
* @param sirDiseaseModel
* the SIR disease model to be initialized
* @param diseaseModelName
* @param backgroundMortalityRate
* @param infectiousMortality
* @param infectiousMortalityRate
* the rate at which fatally infectious population members die
* @param transmissionRate
* @param recoveryRate
* @param immunityLossRate
* @param incubationRate
* @param nonLinearityCoefficient
* @param timePeriod
* @param populationIdentifier
*/
protected static SIR initializeSIRDiseaseModel(final SIR sirDiseaseModel,
final String diseaseModelName,
final double backgroundMortalityRate,
final double infectiousMortalityRate,
final double transmissionRate, final double recoveryRate,
final double immunityLossRate,
final double nonLinearityCoefficient, final long timePeriod,
final String populationIdentifier) {
SIImpl.initializeSIDiseaseModel(sirDiseaseModel, diseaseModelName,
backgroundMortalityRate,
infectiousMortalityRate, transmissionRate, recoveryRate,
nonLinearityCoefficient, timePeriod, populationIdentifier);
sirDiseaseModel.setImmunityLossRate(immunityLossRate);
return sirDiseaseModel;
} // initializeSIRDiseaseModel
/**
* @see org.eclipse.stem.diseasemodels.standard.impl.DiseaseModelImpl#createDiseaseModelLabel()
*/
@Override
public DiseaseModelLabel createDiseaseModelLabel() {
return StandardFactory.eINSTANCE.createSIRLabel();
} // createDiseaseModelLabel
@Override
public DiseaseModelLabelValue createDiseaseModelLabelValue() {
return StandardFactory.eINSTANCE.createSIRLabelValue();
} // createDiseaseModelLabelValue
/**
* @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#computeDeaths(org.eclipse.stem.diseasemodels.standard.StandardDiseaseModelLabelValue,
* long)
*/
@Override
public StandardDiseaseModelLabelValue computeDiseaseDeathsDeltas(
final STEMTime time, final StandardDiseaseModelLabel diseaseLabel, final StandardDiseaseModelLabelValue currentLabelValue, final long timeDelta, DiseaseModelLabelValue returnValue) {
final SIRLabelValue currentSIR = (SIRLabelValue) currentLabelValue;
final double adjustedInfectiousMortalityRate = getAdjustedInfectiousMortalityRate(timeDelta);
final double diseaseDeaths = adjustedInfectiousMortalityRate
* currentSIR.getI();
SIRLabelValueImpl ret = (SIRLabelValueImpl)returnValue;
ret.setS(0.0);
ret.setI(-diseaseDeaths);
ret.setIncidence(0.0);
ret.setR(0.0);
ret.setDiseaseDeaths(diseaseDeaths);
return ret;
} // computeDeaths
/**
* @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#computeTransitions(StandardDiseaseModelLabelValue,
* StandardDiseaseModelLabel, long)
*/
@Override
public StandardDiseaseModelLabelValue computeDiseaseDeltas(
final STEMTime time,
final StandardDiseaseModelLabelValue currentState,
final StandardDiseaseModelLabel diseaseLabel, final long timeDelta, DiseaseModelLabelValue returnValue) {
final SIRLabelValue currentSIR = (SIRLabelValue) currentState;
// This is beta*
double transmissionRate = getAdjustedTransmissionRate(timeDelta);
if(!this.isFrequencyDependent()) transmissionRate *= getTransmissionRateScaleFactor(diseaseLabel);
// The effective Infectious population is a dimensionles number normalize by total
// population used in teh computation of bets*S*i where i = Ieffective/Pop.
// This includes a correction to the current
// infectious population (Ieffective) based on the conserved exchange of people (circulation)
// between regions. Note that this is no the "arrivals" and "departures" which are
// a different process.
final double effectiveInfectious = getNormalizedEffectiveInfectious(diseaseLabel.getNode(), diseaseLabel, currentSIR.getI());
/*
* Compute state transitions
*
* Regarding computing the number of transitions from Susceptible to Exposed:
* In a linear model the "effective" number of infectious people is just
* the number of infectious people In a nonlinear model we have a
* nonLinearity exponent that is > 1 this models the effect of immune
* system saturation when Susceptible people are exposed to large
* numbers of infectious people. then the "effective" number of
* infectious people is I^nonLinearity exponent to allow for either
* linear or nonlinear models we always calculate I^nonLinearity
* exponent and allow nonLinearity exponent >= 1.0
*/
double numberOfInfectedToRecovered = getAdjustedRecoveryRate(timeDelta)
* currentSIR.getI();
double numberOfRecoveredToSusceptible = getAdjustedImmunityLossRate(timeDelta)
* currentSIR.getR();
// Need to checked what do do here. If non linear coefficient is not 1 and
// the effective infectious is negative (which is possible), what do do?
// Let's fall back on the linear method for now.
double numberOfSusceptibleToInfected = 0.0;
if(getNonLinearityCoefficient() != 1.0 && effectiveInfectious >= 0.0)
numberOfSusceptibleToInfected = transmissionRate
* currentSIR.getS()* Math.pow(effectiveInfectious, getNonLinearityCoefficient());
else
numberOfSusceptibleToInfected = transmissionRate
* currentSIR.getS()* effectiveInfectious;
// Determine delta S
final double deltaS = numberOfRecoveredToSusceptible - numberOfSusceptibleToInfected;
// Determine delta I
final double deltaI = numberOfSusceptibleToInfected- numberOfInfectedToRecovered;
// Determine delta R
final double deltaR = numberOfInfectedToRecovered - numberOfRecoveredToSusceptible;
SIRLabelValueImpl ret = (SIRLabelValueImpl)returnValue;
ret.setS(deltaS);
ret.setI(deltaI);
ret.setIncidence(numberOfInfectedToRecovered);
ret.setR(deltaR);
ret.setDiseaseDeaths(0);
return ret;
} // computeTransitions
/**
* @param fractionToDepart
* @param nextState
* @return
*/
@Override
protected StandardDiseaseModelLabelValue computeDepartures(
final double fractionToDepart,final StandardDiseaseModelLabelValue nextState) {
final SIRLabelValue departees = StandardFactory.eINSTANCE
.createSIRLabelValue();
final SIRLabelValue siState = (SIRLabelValue) nextState;
departees.setS(fractionToDepart * siState.getS());
departees.setI(fractionToDepart * siState.getI());
departees.setR(fractionToDepart * siState.getR());
return departees;
} // computeDepartures
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return StandardPackage.Literals.SIR;
}
/**
* <!-- begin-user-doc -->
*
* @return
*
* <!-- end-user-doc -->
* @generated
*/
public double getImmunityLossRate() {
return immunityLossRate;
}
/**
* <!-- begin-user-doc -->
*
* @param newImmunityLossRate
*
* <!-- end-user-doc -->
* @generated
*/
public void setImmunityLossRate(double newImmunityLossRate) {
double oldImmunityLossRate = immunityLossRate;
immunityLossRate = newImmunityLossRate;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.SIR__IMMUNITY_LOSS_RATE, oldImmunityLossRate, immunityLossRate));
}
/**
* <!-- begin-user-doc -->
*
* @param timeDelta
* @return
*
* <!-- end-user-doc -->
* @generated NOT
*/
public double getAdjustedImmunityLossRate(long timeDelta) {
return getImmunityLossRate()
* ((double) timeDelta / (double) getTimePeriod());
} // getAdjustedImmunityRate
/**
* <!-- begin-user-doc -->
*
* @param featureID
* @param resolve
* @param coreType
* @return
*
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
return getImmunityLossRate();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
*
* @param featureID
* @param newValue
*
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
setImmunityLossRate((Double)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
*
* @param featureID
*
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
setImmunityLossRate(IMMUNITY_LOSS_RATE_EDEFAULT);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
*
* @param featureID
* @return
*
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case StandardPackage.SIR__IMMUNITY_LOSS_RATE:
return immunityLossRate != IMMUNITY_LOSS_RATE_EDEFAULT;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
*
* @return
*
* <!-- end-user-doc -->
* @generated
*/
@Override
public String toString() {
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer(super.toString());
result.append(" (immunityLossRate: "); //$NON-NLS-1$
result.append(immunityLossRate);
result.append(')');
return result.toString();
}
/**
* @see org.eclipse.stem.diseasemodels.standard.impl.SIImpl#sane()
*/
@Override
public boolean sane() {
boolean retValue = super.sane();
retValue = retValue && immunityLossRate >= IMMUNITY_LOSS_RATE_EDEFAULT;
assert retValue;
retValue = retValue && !Double.isInfinite(immunityLossRate);
assert retValue;
retValue = retValue && !Double.isNaN(immunityLossRate);
assert retValue;
return retValue;
} // sane
} // SIRImpl