diff --git a/model/Clinical/Episode.cpp b/model/Clinical/Episode.cpp index 33958caf..b9c34d00 100644 --- a/model/Clinical/Episode.cpp +++ b/model/Clinical/Episode.cpp @@ -22,6 +22,7 @@ #include "Clinical/Episode.h" #include "Clinical/ClinicalModel.h" #include "Host/Human.h" +#include "Host/WithinHost/WHInterface.h" namespace OM { namespace Clinical { @@ -40,6 +41,8 @@ void Episode::flush() { void Episode::update (const Host::Human& human, Episode::State newState) { if( time + ClinicalModel::hsMemory() <= sim::ts0() ){ + infectionType = human.withinHostModel->getInfectionType(); + report (); time = sim::ts0(); @@ -66,6 +69,12 @@ void Episode::report () { } } else { // UC or UC2 mon::reportMSACI( mon::MHE_UNCOMPLICATED_EPISODES, surveyPeriod, ageGroup, cohortSet, 1 ); + if(infectionType == WithinHost::InfectionOrigin::Indigenous) + mon::reportMSACI( mon::MHE_UNCOMPLICATED_EPISODES_INDIGENOUS, surveyPeriod, ageGroup, cohortSet, 1 ); + else if(infectionType == WithinHost::InfectionOrigin::Introduced) + mon::reportMSACI( mon::MHE_UNCOMPLICATED_EPISODES_INTRODUCED, surveyPeriod, ageGroup, cohortSet, 1 ); + else + mon::reportMSACI( mon::MHE_UNCOMPLICATED_EPISODES_IMPORTED, surveyPeriod, ageGroup, cohortSet, 1 ); } // Report outcomes of malarial fevers diff --git a/model/Clinical/Episode.h b/model/Clinical/Episode.h index ab233ea7..f174c4ec 100644 --- a/model/Clinical/Episode.h +++ b/model/Clinical/Episode.h @@ -24,6 +24,7 @@ #include "Global.h" #include "Host/WithinHost/Pathogenesis/State.h" +#include "Host/WithinHost/Infection/Infection.h" #include "mon/AgeGroup.h" #include "mon/info.h" #include @@ -112,6 +113,8 @@ class Episode{ /// Descriptor of state, containing reporting info. Not all information will /// be reported (e.g. indirect deaths are reported independantly). Episode::State state; + + WithinHost::InfectionOrigin infectionType = WithinHost::InfectionOrigin::Indigenous; private: /** Report a clinical episode. diff --git a/model/Host/WithinHost/CommonWithinHost.cpp b/model/Host/WithinHost/CommonWithinHost.cpp index b32055a9..bd897275 100644 --- a/model/Host/WithinHost/CommonWithinHost.cpp +++ b/model/Host/WithinHost/CommonWithinHost.cpp @@ -260,14 +260,30 @@ void CommonWithinHost::update(Host::Human &human, LocalRng& rng, int &nNewInfs_i m_y_lag_l[y_lag_i * Genotypes::N() + g] = 0.0; } + int nImported = 0, nIntroduced = 0, nIndigenous = 0; for( auto inf = infections.begin(); inf != infections.end(); ++inf ) { if((*inf)->origin() == InfectionOrigin::Imported) m_y_lag_i[y_lag_i * Genotypes::N() + (*inf)->genotype()] += (*inf)->getDensity(); else m_y_lag_l[y_lag_i * Genotypes::N() + (*inf)->genotype()] += (*inf)->getDensity(); + + if((*inf)->origin() == InfectionOrigin::Indigenous) nIndigenous++; + else if((*inf)->origin() == InfectionOrigin::Introduced) nIntroduced++; + else nImported++; } + /* The rules are: + - Imported only if all infections are imported + - Introduced if at least one Introduced + - Indigenous otherwise (Imported + Indigenous or just Indigenous infections) */ + if(nIntroduced > 0) + infectionType = InfectionOrigin::Introduced; + else if(nIndigenous > 0) + infectionType = InfectionOrigin::Indigenous; + else + infectionType = InfectionOrigin::Imported; + // This is a bug, we keep it this way to be consistent with old simulations if(nNewInfsIgnored > 0) nNewInfs_l += nNewInfsIgnored; @@ -294,16 +310,7 @@ bool CommonWithinHost::summarize( Host::Human& human )const{ pkpdModel.summarize( human ); // If the number of infections is 0 and parasite density is positive we default to Indigenous - InfectionOrigin infectionType = InfectionOrigin::Indigenous; if( infections.size() > 0 ){ - int nImported = 0, nIntroduced = 0, nIndigenous = 0; - for(const auto infection : infections) - { - if(infection->origin() == InfectionOrigin::Indigenous) nIndigenous++; - else if(infection->origin() == InfectionOrigin::Introduced) nIntroduced++; - else nImported++; - } - mon::reportStatMHI( mon::MHR_INFECTED_HOSTS, human, 1 ); if(infectionType == InfectionOrigin::Indigenous) mon::reportStatMHI( mon::MHR_INFECTED_HOSTS_INDIGENOUS, human, 1 ); diff --git a/model/Host/WithinHost/DescriptiveWithinHost.cpp b/model/Host/WithinHost/DescriptiveWithinHost.cpp index a0868034..9a428189 100644 --- a/model/Host/WithinHost/DescriptiveWithinHost.cpp +++ b/model/Host/WithinHost/DescriptiveWithinHost.cpp @@ -151,7 +151,7 @@ void DescriptiveWithinHostModel::update(Host::Human &human, LocalRng& rng, int & bool treatmentLiver = treatExpiryLiver > sim::ts0(); bool treatmentBlood = treatExpiryBlood > sim::ts0(); - + for(auto inf = infections.begin(); inf != infections.end();) { //NOTE: it would be nice to combine this code with that in // CommonWithinHost.cpp, but a few changes would be needed: @@ -207,14 +207,30 @@ void DescriptiveWithinHostModel::update(Host::Human &human, LocalRng& rng, int & m_y_lag_l[y_lag_i * Genotypes::N() + g] = 0.0; } + int nImported = 0, nIntroduced = 0, nIndigenous = 0; for( auto inf = infections.begin(); inf != infections.end(); ++inf ) { if(inf->origin() == InfectionOrigin::Imported) m_y_lag_i[y_lag_i * Genotypes::N() + inf->genotype()] += inf->getDensity(); else m_y_lag_l[y_lag_i * Genotypes::N() + inf->genotype()] += inf->getDensity(); + + if(inf->origin() == InfectionOrigin::Indigenous) nIndigenous++; + else if(inf->origin() == InfectionOrigin::Introduced) nIntroduced++; + else nImported++; } + /* The rules are: + - Imported only if all infections are imported + - Introduced if at least one Introduced + - Indigenous otherwise (Imported + Indigenous or just Indigenous infections) */ + if(nIntroduced > 0) + infectionType = InfectionOrigin::Introduced; + else if(nIndigenous > 0) + infectionType = InfectionOrigin::Indigenous; + else + infectionType = InfectionOrigin::Imported; + // This is a bug, we keep it this way to be consistent with old simulations if(opt_vaccine_genotype == false) { @@ -230,27 +246,7 @@ bool DescriptiveWithinHostModel::summarize( Host::Human& human )const{ pathogenesisModel->summarize( human ); // If the number of infections is 0 and parasite density is positive we default to Indigenous - InfectionOrigin infectionType = InfectionOrigin::Indigenous; if( infections.size() > 0 ){ - int nImported = 0, nIntroduced = 0, nIndigenous = 0; - for(const auto& infection : infections) - { - if(infection.origin() == InfectionOrigin::Indigenous) nIndigenous++; - else if(infection.origin() == InfectionOrigin::Introduced) nIntroduced++; - else nImported++; - } - - /* The rules are: - - Imported only if all infections are imported - - Introduced if at least one Introduced - - Indigenous otherwise (Imported + Indigenous or just Indigenous infections) */ - if(nIntroduced > 0) - infectionType = InfectionOrigin::Introduced; - else if(nIndigenous > 0) - infectionType = InfectionOrigin::Indigenous; - else - infectionType = InfectionOrigin::Imported; - mon::reportStatMHI( mon::MHR_INFECTED_HOSTS, human, 1 ); if(infectionType == InfectionOrigin::Indigenous) mon::reportStatMHI( mon::MHR_INFECTED_HOSTS_INDIGENOUS, human, 1 ); @@ -259,6 +255,14 @@ bool DescriptiveWithinHostModel::summarize( Host::Human& human )const{ else reportStatMHI( mon::MHR_INFECTED_HOSTS_IMPORTED, human, 1 ); + int nImported = 0, nIntroduced = 0, nIndigenous = 0; + for( auto inf = infections.begin(); inf != infections.end(); ++inf ) + { + if(inf->origin() == InfectionOrigin::Indigenous) nIndigenous++; + else if(inf->origin() == InfectionOrigin::Introduced) nIntroduced++; + else nImported++; + } + // (patent) infections are reported by genotype, even though we don't have // genotype in this model mon::reportStatMHGI( mon::MHR_INFECTIONS, human, 0, infections.size() ); diff --git a/model/Host/WithinHost/WHFalciparum.h b/model/Host/WithinHost/WHFalciparum.h index 11834a51..032c72a7 100644 --- a/model/Host/WithinHost/WHFalciparum.h +++ b/model/Host/WithinHost/WHFalciparum.h @@ -70,6 +70,10 @@ class WHFalciparum : public WHInterface { virtual Pathogenesis::StatePair determineMorbidity( Host::Human& human, double ageYears, bool isDoomed ); + virtual InfectionOrigin getInfectionType() const { + return infectionType; + } + inline double getCumulative_h() const { return m_cumulative_h; } @@ -136,6 +140,8 @@ class WHFalciparum : public WHInterface { /// End of step on which treatment expires = start of first step after expiry SimTime treatExpiryLiver, treatExpiryBlood; + + InfectionOrigin infectionType = InfectionOrigin::Indigenous; virtual void checkpoint (istream& stream); virtual void checkpoint (ostream& stream); diff --git a/model/Host/WithinHost/WHInterface.h b/model/Host/WithinHost/WHInterface.h index 5ea43aea..ca8772e9 100644 --- a/model/Host/WithinHost/WHInterface.h +++ b/model/Host/WithinHost/WHInterface.h @@ -26,6 +26,8 @@ #include "util/random.h" #include "Host/WithinHost/Diagnostic.h" #include "Host/WithinHost/Pathogenesis/State.h" +#include "Host/WithinHost/Infection/Infection.h" + #include "Parameters.h" using namespace std; @@ -192,6 +194,8 @@ class WHInterface { virtual double getCumulative_h() const =0; virtual double getCumulative_Y() const =0; + virtual InfectionOrigin getInfectionType() const =0; + /** The maximum number of infections a human can have. The only real reason * for this limit is to prevent incase bad input from causing the number of * infections to baloon stupidly. diff --git a/model/Host/WithinHost/WHVivax.h b/model/Host/WithinHost/WHVivax.h index 62ff378c..93b502a4 100644 --- a/model/Host/WithinHost/WHVivax.h +++ b/model/Host/WithinHost/WHVivax.h @@ -164,6 +164,10 @@ class WHVivax : public WHInterface { virtual Pathogenesis::StatePair determineMorbidity( Host::Human& human, double ageYears, bool ); virtual void clearImmunity(); + + virtual InfectionOrigin getInfectionType() const { + return InfectionOrigin::Indigenous; + } protected: virtual void treatment( Host::Human& human, TreatmentId treatId ); diff --git a/model/mon/OutputMeasures.h b/model/mon/OutputMeasures.h index 35737b11..2adc061b 100644 --- a/model/mon/OutputMeasures.h +++ b/model/mon/OutputMeasures.h @@ -188,8 +188,10 @@ void defineOutMeasures(){ /// number of blood-stage treatments (inpatient) namedOutMeasures["nTreatments3"] = OutMeasure::humanAC( 13, MHT_TREATMENTS_3, false ); /// number of episodes (uncomplicated) - namedOutMeasures["nUncomp"] = - OutMeasure::humanAC( 14, MHE_UNCOMPLICATED_EPISODES, false ); + namedOutMeasures["nUncomp"] = OutMeasure::humanAC( 14, MHE_UNCOMPLICATED_EPISODES, false ); + namedOutMeasures["nUncomp_Imported"] = OutMeasure::humanAC( 1014, MHE_UNCOMPLICATED_EPISODES_IMPORTED, false ); + namedOutMeasures["nUncomp_Introduced"] = OutMeasure::humanAC( 2014, MHE_UNCOMPLICATED_EPISODES_INTRODUCED, false ); + namedOutMeasures["nUncomp_Indigenous"] = OutMeasure::humanAC( 3014, MHE_UNCOMPLICATED_EPISODES_INDIGENOUS, false ); /// Number of severe episodes (severe malaria or malaria + coinfection) namedOutMeasures["nSevere"] = OutMeasure::humanAC( 15, MHE_SEVERE_EPISODES, false ); diff --git a/model/mon/reporting.h b/model/mon/reporting.h index a11d34bc..aaaa9a7b 100644 --- a/model/mon/reporting.h +++ b/model/mon/reporting.h @@ -81,7 +81,7 @@ enum Measure{ // ——— MHE: measures for human episodes (integers) ——— // Number of uncomplicated fever episodes in humans. Units: cases - MHE_UNCOMPLICATED_EPISODES, + MHE_UNCOMPLICATED_EPISODES, MHE_UNCOMPLICATED_EPISODES_IMPORTED, MHE_UNCOMPLICATED_EPISODES_INTRODUCED, MHE_UNCOMPLICATED_EPISODES_INDIGENOUS, // Number of severe fever episodes in humans. Units: cases MHE_SEVERE_EPISODES, // Number of severe fever episodes without counting episodes due to comorbidities in humans. Units: cases diff --git a/unittest/WHMock.cpp b/unittest/WHMock.cpp index 8d6374dc..d2126c48 100644 --- a/unittest/WHMock.cpp +++ b/unittest/WHMock.cpp @@ -94,6 +94,10 @@ double WHMock::getCumulative_Y() const{ throw util::unimplemented_exception( "not needed in unit test" ); } +InfectionOrigin WHMock::getInfectionType() const{ + return InfectionOrigin::Indigenous; +} + void WHMock::checkpoint (istream& stream){ throw util::unimplemented_exception( "not needed in unit test" ); } diff --git a/unittest/WHMock.h b/unittest/WHMock.h index 88bd8dd5..531d45ed 100644 --- a/unittest/WHMock.h +++ b/unittest/WHMock.h @@ -59,6 +59,7 @@ class WHMock : public WHInterface { virtual void clearImmunity(); virtual double getCumulative_h() const; virtual double getCumulative_Y() const; + virtual InfectionOrigin getInfectionType() const; // This mock class does not have actual infections. Just set this as you please. double totalDensity;