Skip to content

Commit

Permalink
Merge pull request #21 from NTD-Modelling-Consortium/passSurveyInform…
Browse files Browse the repository at this point in the history
…ationBetweenSims

pass survey info between sims
  • Loading branch information
mattg3004 authored Aug 27, 2024
2 parents 84a1d10 + 24600b5 commit 6e61342
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 77 deletions.
3 changes: 2 additions & 1 deletion src/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ Host::operator hostState() const {
// save this object to the host state structure
return {WM, WF, totalWorms, totalWormYears,
M, biteRisk, age, monthsSinceTreated,
hydroMult, lymphoMult, sex};
hydroMult, lymphoMult, sex, pTreat};
}

void Host::restore(const hostState &state) {
Expand All @@ -211,4 +211,5 @@ void Host::restore(const hostState &state) {
hydroMult = state.hydroMult;
lymphoMult = state.lymphoMult;
sex = state.sex;
pTreat = state.pTreat;
}
1 change: 0 additions & 1 deletion src/Host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ typedef struct {
double hydroMult;
double lymphoMult;
int sex;
int neverTreat;
double pTreat; // probability of treatment drawn from a beta distribution as
// defined in section 1.5.3 of supplement to
// https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5340860/
Expand Down
98 changes: 44 additions & 54 deletions src/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,11 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
std::string folderName = opDir;
std::string MDAType;
int t_import_reduction = -1;
int preTASSurveyTime = -1000;
int TASSurveyTime = -1000;
int paramIndex = 0;
int targetMonth = sc.getMonthToSave(y); // simulate to start of this month
double mfprev = 1; // variable to check prevalence of mf for survey
// double icprev = 1; //variable to check prevalence of ic for survey
int numMDADoSurvey = popln.firstTASNumMDA;
popln.totMDAs = 0;
popln.post2020MDAs = 0;
popln.numPreTASSurveys = 0;
popln.numTASSurveys = 0;
popln.t_TAS_Pass = -1;
int sampleSize = popln.getSampleSize();
// set the outputEndgameDate to be relative to year 2000.
// This should be updated when we automatically get the baseYear of the
Expand All @@ -218,11 +211,9 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
double mfprev_aimp_old =
popln.getMFPrev(sc, 0, 0, outputEndgameDate, rep, popSize, folderName);
double mfprev_aimp_new = 0;
bool preTAS_Pass = 0;
int changeSensSpec = 0;
int changeNeverTreat = 0;
// int maxAge = popln.getMaxAge();
int TAS_Pass = 0;
int neededTASPass =
3; // number of times TAS must be passed to reached WHO target
// (https://www.who.int/publications/i/item/9789241501484)
Expand All @@ -241,19 +232,18 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
}

int vec_control = 0;
double prevCov = -1;
double prevRho = -1;

int minAge;
int maxAge = popln.returnMaxAge();
int donePreTAS = 0;
int doneTAS = 0;
// indicator if we should do the MDA when the MDA is called.
// This will be switched to 0 if preTAS is passed, then the MDA function will
// be called, but will not be done We will still get the output of the MDA
// showing that no people were treated this year. This is to keep the output
// of MDA's constant so that we can combine different runs even if they have
// different numbers of MDA's performed.
int DoMDA = 1;
// This will be switched to false if preTAS is passed, then the MDA function
// will be called, but will not be done. We will still get the output of the
// MDA showing that no people were treated this year. This is to keep the
// output of MDA's constant so that we can combine different runs even if they
// have different numbers of MDA's performed.
popln.DoMDA = true;

for (int q = 0; q < popln.sensSpecChangeCount; q++) {
if (popln.sensSpecChangeName[q] == sc.getName()) {
Expand Down Expand Up @@ -286,14 +276,15 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
// year we want to do the endgame output for, then don't do this.
if ((t % 12 == 0) && (outputEndgame == 1) && (t >= outputEndgameDate)) {
sc.writePrevByAge(popln, t, rep, folderName);
sc.writeRoadmapTarget(popln, t, rep, DoMDA, TAS_Pass, neededTASPass,
folderName);
sc.writeRoadmapTarget(popln, t, rep, popln.DoMDA, popln.TAS_Pass,
neededTASPass, folderName);
sc.writeNumberByAge(popln, t, rep, folderName, "not survey");
sc.writeSequelaeByAge(popln, t, LymphodemaTotalWorms, LymphodemaShape,
HydroceleTotalWorms, HydroceleShape, rep,
folderName);
popln.getIncidence(sc, t, rep, folderName);
sc.writeSurveyByAge(popln, t, preTAS_Pass, TAS_Pass, rep, folderName);
sc.writeSurveyByAge(popln, t, popln.preTAS_Pass, popln.TAS_Pass, rep,
folderName);
}

// If we haven't done a survey this year we still want to output this fact
Expand Down Expand Up @@ -345,50 +336,50 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
outputPrev); // prev measured before mda done to kill mf in hosts

// snippet to perform a preTAS survey
if (t == preTASSurveyTime) {
if (t == popln.preTASSurveyTime) {

preTAS_Pass = popln.PreTASSurvey(sc, outputEndgame, t, outputEndgameDate,
rep, folderName);
popln.preTAS_Pass = popln.PreTASSurvey(
sc, outputEndgame, t, outputEndgameDate, rep, folderName);
if ((outputEndgame == 1) && (t >= outputEndgameDate)) {
sc.writeNumberByAge(popln, t, rep, folderName, "PreTAS survey");
}

donePreTAS = 1;
if (preTAS_Pass == 1) {
if (popln.preTAS_Pass == 1) {
// if we pass the preTAS survey then we set a time for the TASsurvey
// we also stop doing MDA
TASSurveyTime = t;
DoMDA = 0;
popln.TASSurveyTime = t;
popln.DoMDA = false;
} else {
preTASSurveyTime = t + popln.interSurveyPeriod;
DoMDA = 1;
popln.preTASSurveyTime = t + popln.interSurveyPeriod;
popln.DoMDA = true;
}
}
// snippet to perform a TAS survey

if (t == TASSurveyTime) {
if (t == popln.TASSurveyTime) {
int TAS_Pass_ind =
popln.TASSurvey(sc, t, outputEndgameDate, rep, folderName);
if ((outputEndgame == 1) && (t >= outputEndgameDate)) {
sc.writeNumberByAge(popln, t, rep, folderName, "TAS survey");
}
doneTAS = 1;
TAS_Pass += TAS_Pass_ind;
popln.TAS_Pass += TAS_Pass_ind;
if (TAS_Pass_ind == 0) {
// if failed, then reset TAS_PAss to 0 and set a time to do another
// preTAS survey also switch back on MDA's
TAS_Pass = 0;
preTASSurveyTime = t + popln.interSurveyPeriod;
TASSurveyTime = t + popln.interSurveyPeriod;
DoMDA = 1;
} else if (TAS_Pass == neededTASPass) {
popln.TAS_Pass = 0;
popln.preTASSurveyTime = t + popln.interSurveyPeriod;
popln.TASSurveyTime = t + popln.interSurveyPeriod;
popln.DoMDA = true;
} else if (popln.TAS_Pass == neededTASPass) {
// if we have passed a sufficient number of times, then make it so we
// won't do any more TAS surveys
TASSurveyTime = 99999999;
} else if (TAS_Pass < neededTASPass) {
popln.TASSurveyTime = 99999999;
} else if (popln.TAS_Pass < neededTASPass) {
// if we have passed the survey, but need to pass more, then set a time
// for the next TAS survey
TASSurveyTime = t + popln.interSurveyPeriod;
popln.TASSurveyTime = t + popln.interSurveyPeriod;
if (vec_control == 0) {
vec_control = 1;
}
Expand All @@ -403,19 +394,19 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
double rho = applyMDA->getCompliance();
// if we this is the first MDA, then we need to initialise the Probability
// of treatment for each person
if (prevCov == -1) {
if (popln.prevCov == -1) {
popln.initPTreat(cov, rho);
prevCov = cov;
prevRho = rho;
popln.prevCov = cov;
popln.prevRho = rho;
}
// if the MDA parameters have changed then we need to update the
// probability of treatment for each person
if ((prevCov != applyMDA->getCoverage()) ||
(prevRho != applyMDA->getCompliance())) {
popln.checkForZeroPTreat(prevCov, prevRho);
if ((popln.prevCov != applyMDA->getCoverage()) ||
(popln.prevRho != applyMDA->getCompliance())) {
popln.checkForZeroPTreat(popln.prevCov, popln.prevRho);
popln.editPTreat(cov, rho);
prevCov = cov;
prevRho = rho;
popln.prevCov = cov;
popln.prevRho = rho;
}
// check for anyone with 0 probability of treatment, as these will be
// people who have not had this value initialised
Expand All @@ -426,13 +417,12 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
// then we will not begin MDA. If the indicator is not 1 then we will do
// MDA even with low MF prevalence this uses the sampleSize input as this
// would be assessed via a survey

if (popln.totMDAs == 0) {
if (popln.getNoMDALowMF() == 1) {
mfprev = popln.getMFPrev(sc, 0, t, outputEndgameDate, rep, sampleSize,
folderName);
if (mfprev <= popln.MFThreshold) {
DoMDA = 0;
popln.DoMDA = false;
}
}
}
Expand All @@ -446,10 +436,11 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
mfprev_aimp_old = popln.getMFPrev(sc, 0, t, outputEndgameDate, rep,
popSize, folderName);

// apply the MDA. If DoMDA = 0, then we call this function, but don't do
// the MDA, we just write to a file showing that no people were treated.
// apply the MDA. If popln.DoMDA = false, then we call this function, but
// don't do the MDA, we just write to a file showing that no people were
// treated.
popln.ApplyTreatmentUpdated(applyMDA, worms, sc, t, outputEndgameDate,
rep, DoMDA, outputEndgame, folderName);
rep, popln.DoMDA, outputEndgame, folderName);
t_import_reduction = t + 6;

popln.totMDAs += 1;
Expand All @@ -467,8 +458,8 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
// from now. We will set the time for the TAS survey if the pre TAS
// survey is passed.
int minNumberMonthsBeforeSurvey = 6;
preTASSurveyTime = std::max(popln.getSurveyStartDate(),
t + minNumberMonthsBeforeSurvey);
popln.preTASSurveyTime = std::max(popln.getSurveyStartDate(),
t + minNumberMonthsBeforeSurvey);
}
}

Expand Down Expand Up @@ -527,7 +518,6 @@ void Model::evolveAndSave(int y, Population &popln, Vector &vectors,
popln.neverTreatToOriginal();
// done
currentMonth = targetMonth;

if (y < (sc.getNumMonthsToSave() - 1)) { // not finished this scenario
popln.saveCurrentState(
currentMonth, sc.getName()); // worms and importation rate. Scenario
Expand Down
46 changes: 38 additions & 8 deletions src/Population.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,18 @@ void Population::initHosts(std::string distType, double k_val,
bedNetCov = 0.0;
aImp_factor = 1.0;
mdaCoverage = 0.0;
numPreTASSurveys = 0;
numTASSurveys = 0;
// when initializing the hosts, also reset everything to do with surveys
totMDAs = 0;
post2020MDAs = 0;
time_TAS_Passes = -1;
preTASSurveyTime = -1000;
TASSurveyTime = -1000;
DoMDA = true;
preTAS_Pass = 0;
TAS_Pass = 0;
prevCov = -1;
}

void Population::updateKVal(double k_val) {
Expand Down Expand Up @@ -551,7 +563,7 @@ int Population::TASSurvey(Scenario &sc, int t, int outputEndgameDate, int rep,
if ((icprev <= ICThreshold)) { // if the ic prevalence is below the threshold
// and mf prev also below threshold
TAS_Pass = 1; // set TAS pass indicator to 1
t_TAS_Pass = t; // store the time of passing TAS
time_TAS_Passes = t; // store the time of passing TAS
}
return TAS_Pass;
}
Expand Down Expand Up @@ -929,9 +941,7 @@ void Population::saveCurrentState(int month, std::string sname) {
savedMonth currentState;

currentState.scenario = sname; // debugging only
currentState.data.resize(size, {0, 0, 0, 0.0, 0.0, 0.0, 0,
0}); // WM, WF,totalWorms, totalWormYears,
// M,biteRisk,age,monthSinceTreated
currentState.data.resize(size);

for (int i = 0; i < size; i++)
currentState.data[i] =
Expand All @@ -946,7 +956,17 @@ void Population::saveCurrentState(int month, std::string sname) {
currentState.u0bednets = u0CompBednets;
currentState.mdaCov = mdaCoverage;
currentState.bednetCov = bedNetCov;

// when saving data, also save everything to do with surveys
currentState.DoMDA = DoMDA;
currentState.totMDAs = totMDAs;
currentState.numPreTASSurveys = numPreTASSurveys;
currentState.numTASSurveys = numTASSurveys;
currentState.preTASSurveyTime = preTASSurveyTime;
currentState.TASSurveyTime = TASSurveyTime;
currentState.preTAS_Pass = preTAS_Pass;
currentState.TAS_Pass = TAS_Pass;
currentState.prevCov = prevCov;
currentState.prevRho = prevRho;
savedMonths.push_back(currentState);
}

Expand All @@ -971,7 +991,17 @@ void Population::resetToMonth(int month) {
u0CompBednets = lastMonth.u0bednets;
mdaCoverage = lastMonth.mdaCov;
bedNetCov = lastMonth.bednetCov;

// when resetting time, also reset everything to do with surveys
DoMDA = lastMonth.DoMDA;
totMDAs = lastMonth.totMDAs;
numPreTASSurveys = lastMonth.numPreTASSurveys;
numTASSurveys = lastMonth.numTASSurveys;
preTASSurveyTime = lastMonth.preTASSurveyTime;
TASSurveyTime = lastMonth.TASSurveyTime;
preTAS_Pass = lastMonth.preTAS_Pass;
TAS_Pass = lastMonth.TAS_Pass;
prevCov = lastMonth.prevCov;
prevRho = lastMonth.prevRho;
if (_DEBUG)
std::cout << "Reset to month " << month << ", that was saved by "
<< lastMonth.scenario << std::endl;
Expand Down Expand Up @@ -1213,7 +1243,7 @@ int Population::returnMaxAge() { return maxAge; }

void Population::ApplyTreatmentUpdated(MDAEvent *mda, Worm &worms, Scenario &sc,
int t, int outputEndgameDate, int rep,
int DoMDA, int outputEndgame,
bool DoMDA, int outputEndgame,
std::string folderName) {
int minAge = (mda->getMinAge() >= 0) ? mda->getMinAge() : minAgeMDA;
int minAgeMDAinMonths = minAge * 12;
Expand All @@ -1232,7 +1262,7 @@ void Population::ApplyTreatmentUpdated(MDAEvent *mda, Worm &worms, Scenario &sc,
float flooredAge = std::floor(host_pop[i].age / 12);
int flooredAgeInt = std::min(static_cast<int>(flooredAge), maxAge - 1);
numHostsByAge[flooredAgeInt] += 1;
if (DoMDA == 1) {
if (DoMDA) {
if (host_pop[i].age >= minAgeMDAinMonths) {
if (stats.uniform_dist() < host_pop[i].pTreat) {
if (host_pop[i].neverTreat == 0) {
Expand Down
36 changes: 30 additions & 6 deletions src/Population.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class Population {
void ApplyTreatment(MDAEvent *mda, Worm &worms, Scenario &sc, int t, int rep,
std::string folderName);
void ApplyTreatmentUpdated(MDAEvent *mda, Worm &worms, Scenario &sc, int t,
int outputEndgameDate, int rep, int DoMDA,
int outputEndgameDate, int rep, bool DoMDA,
int outputEndgame, std::string folderName);
void saveCurrentState(int month, std::string sname);
void resetToMonth(int month);
Expand All @@ -123,11 +123,25 @@ class Population {
double MFThreshold;
int interSurveyPeriod;
int firstTASNumMDA;
int numPreTASSurveys = 0;
int numTASSurveys = 0;
int totMDAs = 0;
int post2020MDAs = 0;
int t_TAS_Pass = -1;
// declare the information regarding surveys
int numPreTASSurveys;
int numTASSurveys;
int totMDAs;
int post2020MDAs;
int time_TAS_Passes;
int preTASSurveyTime;
int TASSurveyTime;
int preTAS_Pass;
int TAS_Pass;
double prevCov;
double prevRho;
// indicator if we should do the MDA when the MDA is called.
// This will be switched to 0 if preTAS is passed, then the MDA function will
// be called, but will not be done We will still get the output of the MDA
// showing that no people were treated this year. This is to keep the output
// of MDA's constant so that we can combine different runs even if they have
// different numbers of MDA's performed.
bool DoMDA;
double aImp;
int sensSpecChangeCount = 0;
int neverTreatChangeCount = 0;
Expand Down Expand Up @@ -230,6 +244,16 @@ class Population {
double u0MDA;
double bednetCov;
double mdaCov;
bool DoMDA;
int totMDAs;
int numPreTASSurveys;
int numTASSurveys;
int preTASSurveyTime;
int TASSurveyTime;
int preTAS_Pass;
int TAS_Pass;
double prevCov;
double prevRho;
std::string
scenario; // for debugging only. The scenario that saved this month

Expand Down
Loading

0 comments on commit 6e61342

Please sign in to comment.