diff --git a/src/IO.cpp b/src/IO.cpp index 596f2053..2c04e0ca 100644 --- a/src/IO.cpp +++ b/src/IO.cpp @@ -152,7 +152,7 @@ InferenceConfig ReadInferenceConfig(const std::string& configDir, Utilities::log inferenceConfig.toleranceLimit[ii] = ReadNumberFromFile(KeyName.str(), "Tolerance settings", ParamsPath); } - inferenceConfig.observations = ReadInferenceObservations(configDir, log); + inferenceConfig.observations = ReadInferenceObservations(configDir, log, inferenceConfig.herd_id); return inferenceConfig; } @@ -195,10 +195,8 @@ PredictionConfig ReadPredictionConfig(const std::string& configDir, int index, U return predictionConfig; } -ObservationsForInference ReadInferenceObservations(const std::string& configDir, Utilities::logging_stream::Sptr log) -{ - ObservationsForInference observations; - +HealthBoardData ReadInferenceObservations(const std::string& configDir, Utilities::logging_stream::Sptr log, int herd_id) +{ (*log) << "Observations For Inference Config:" << std::endl; const std::string scot_data_file = configDir + "/scot_data.csv"; @@ -209,39 +207,41 @@ ObservationsForInference ReadInferenceObservations(const std::string& configDir, //rows from 1 are indivudual health board //last row is for all of scotland (*log) << "\t- " << scot_data_file << std::endl; - observations.cases = Utilities::read_csv(scot_data_file, ','); + std::vector> cases_in = Utilities::read_csv(scot_data_file, ','); //Uploading observed death data //Note: first vector is the vector of time. value of -1 indicate number of pigs in the herd //rows from 1 are indivudual health board //last row is for all of scotland (*log) << "\t- " << scot_deaths_file << std::endl; - observations.deaths = Utilities::read_csv(scot_deaths_file, ','); - + std::vector> deaths_in = Utilities::read_csv(scot_deaths_file, ','); + const std::string settings_file = configDir + "/parameters.ini"; ValidationParameters validationParams = ImportValidationParameters(configDir); int nHealthBoards = validationParams.nHealthBoards; int nCasesDays = validationParams.nCasesDays; - unsigned int cases_rows = observations.cases.size(); - unsigned int cases_cols = observations.cases[0].size(); + unsigned int cases_rows = cases_in.size(); + unsigned int cases_cols = cases_in[0].size(); ImportConsistencyCheck(scot_data_file, cases_rows, (nHealthBoards + 1), "rows"); ImportConsistencyCheck(scot_data_file, cases_cols, nCasesDays, "columns"); - unsigned int deaths_rows = observations.deaths.size(); - unsigned int deaths_cols = observations.deaths[0].size(); + unsigned int deaths_rows = deaths_in.size(); + unsigned int deaths_cols = deaths_in[0].size(); ImportConsistencyCheck(scot_deaths_file, deaths_rows, (nHealthBoards + 1), "rows"); ImportConsistencyCheck(scot_deaths_file, deaths_cols, nCasesDays, "columns"); + HealthBoardData observations(herd_id, cases_in, deaths_in); + return observations; } -ObservationsForModels ReadModelObservations(const std::string& configDir, Utilities::logging_stream::Sptr log) +HealthBoardData ReadModelObservations(const std::string& configDir, Utilities::logging_stream::Sptr log, int herd_id) { - ObservationsForModels observations; + // ObservationsForModels observations; (*log) << "Observations For Models:" << std::endl; @@ -265,27 +265,44 @@ ObservationsForModels ReadModelObservations(const std::string& configDir, Utilit //rows from 1 are indivudual health board //last row is for all of scotland (*log) << "\t- " << scot_data_file << std::endl; - observations.cases = Utilities::read_csv(scot_data_file, ','); + // observations.cases = Utilities::read_csv(scot_data_file, ','); + std::vector> cases_in = Utilities::read_csv(scot_data_file, ','); - unsigned int cases_rows = observations.cases.size(); - unsigned int cases_cols = observations.cases[0].size(); + unsigned int cases_rows = cases_in.size(); + unsigned int cases_cols = cases_in[0].size(); ImportConsistencyCheck(scot_data_file, cases_rows, (nHealthBoards + 1), "rows"); ImportConsistencyCheck(scot_data_file, cases_cols, nCasesDays, "columns"); //Uploading population per age group - //columns are for each individual Health Borad - //last column is for Scotland - //rows are for each age group: [0] Under20,[1] 20-29,[2] 30-39,[3] 40-49,[4] 50-59,[5] 60-69,[6] Over70,[7] HCW + //rows are for each individual Health Board + //last row is for Scotland + //columns are for each age group: [0] Under20,[1] 20-29,[2] 30-39,[3] 40-49,[4] 50-59,[5] 60-69,[6] Over70,[7] HCW (*log) << "\t- " << scot_ages_file << std::endl; - observations.age_pop = Utilities::read_csv(scot_ages_file, ','); + // observations.age_pop = Utilities::read_csv(scot_ages_file, ','); + std::vector> age_pop_in = Utilities::read_csv(scot_ages_file, ','); - unsigned int age_pop_rows = observations.age_pop.size(); - unsigned int age_pop_cols = observations.age_pop[0].size(); + unsigned int age_pop_rows = age_pop_in.size(); + unsigned int age_pop_cols = age_pop_in[0].size(); ImportConsistencyCheck(scot_ages_file, age_pop_rows, nHealthBoards, "rows"); ImportConsistencyCheck(scot_ages_file, age_pop_cols, (nAgeGroups - 1), "columns"); + //Upload frailty probability p_f by age group + //columns are for each age group: [0] Under20,[1] 20-29,[2] 30-39,[3] 40-49,[4] 50-59,[5] 60-69,[6] Over70,[7] HCW + //rows are for each individual Health Board + //last row is for Scotland + (*log) << "\t- " << scot_frail_file << std::endl; + // observations.pf_pop = Utilities::read_csv(scot_frail_file, ','); + std::vector> pf_pop_in = Utilities::read_csv(scot_frail_file, ','); + + unsigned int pf_pop_rows = pf_pop_in.size(); + unsigned int pf_pop_cols = pf_pop_in[0].size(); + + ImportConsistencyCheck(scot_frail_file, pf_pop_rows, nHealthBoards, "rows"); + ImportConsistencyCheck(scot_frail_file, pf_pop_cols, nAgeGroups, "columns"); + + HealthBoardData observations(herd_id, cases_in, age_pop_in, pf_pop_in); //mean number of daily contacts per age group (overall) (*log) << "\t- " << waifw_norm_file << std::endl; @@ -331,19 +348,6 @@ ObservationsForModels ReadModelObservations(const std::string& configDir, Utilit ImportConsistencyCheck(cfr_byage_file, cfr_rows, nAgeGroups, "rows"); ImportConsistencyCheck(cfr_byage_file, cfr_cols, nCfrCategories, "columns"); - //Upload frailty probability p_f by age group - //columns are for each age group: [0] Under20,[1] 20-29,[2] 30-39,[3] 40-49,[4] 50-59,[5] 60-69,[6] Over70,[7] HCW - //rows are for each individual Health Borad - //last row is for Scotland - (*log) << "\t- " << scot_frail_file << std::endl; - observations.pf_pop = Utilities::read_csv(scot_frail_file, ','); - - unsigned int pf_pop_rows = observations.pf_pop.size(); - unsigned int pf_pop_cols = observations.pf_pop[0].size(); - - ImportConsistencyCheck(scot_frail_file, pf_pop_rows, nHealthBoards, "rows"); - ImportConsistencyCheck(scot_frail_file, pf_pop_cols, nAgeGroups, "columns"); - return observations; } diff --git a/src/IO.h b/src/IO.h index 4c492a16..60617a1f 100644 --- a/src/IO.h +++ b/src/IO.h @@ -121,7 +121,7 @@ std::vector ReadPredictionParametersFromFile(const std::string& filePath * * @return Observations needed for Inference framework */ -ObservationsForInference ReadInferenceObservations(const std::string& configDir, Utilities::logging_stream::Sptr log); +HealthBoardData ReadInferenceObservations(const std::string& configDir, Utilities::logging_stream::Sptr log, int herd_id); /** * @brief Read observations needed for all models @@ -131,7 +131,7 @@ ObservationsForInference ReadInferenceObservations(const std::string& configDir, * * @return Observations needed for all models */ -ObservationsForModels ReadModelObservations(const std::string& configDir, Utilities::logging_stream::Sptr log); +HealthBoardData ReadModelObservations(const std::string& configDir, Utilities::logging_stream::Sptr log, int herd_id); /** * @brief Read seed settings from the parameters file diff --git a/src/InferenceFramework.cpp b/src/InferenceFramework.cpp index 1f366b1b..16a60dcc 100644 --- a/src/InferenceFramework.cpp +++ b/src/InferenceFramework.cpp @@ -70,9 +70,9 @@ void InferenceFramework::Run() SimpleTimer runTimer; const int time_back = GetTimeOffSet(inferenceConfig_); - const std::vector& regionalCases = inferenceConfig_.observations.cases[inferenceConfig_.herd_id]; - const std::vector& regionalDeaths = inferenceConfig_.observations.deaths[inferenceConfig_.herd_id]; - const std::vector& timeStamps = inferenceConfig_.observations.cases[0]; + const std::vector& regionalCases = inferenceConfig_.observations.cases; + const std::vector& regionalDeaths = inferenceConfig_.observations.deaths; + const std::vector& timeStamps = inferenceConfig_.observations.timeStamps; const Observations::ObsSelect obs_selections = Observations::SelectObservations( inferenceConfig_.day_shut, timeStamps, regionalCases, diff --git a/src/IrishModel.cpp b/src/IrishModel.cpp index 06d31f25..eee539b2 100644 --- a/src/IrishModel.cpp +++ b/src/IrishModel.cpp @@ -4,7 +4,7 @@ namespace EERAModel { namespace Model { IrishModel::IrishModel(const CommonModelInputParameters& commonParameters, - const ObservationsForModels& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) + const HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) : rng_(rng) { fixedParameters_ = BuildFixedParameters( @@ -16,11 +16,11 @@ IrishModel::IrishModel(const CommonModelInputParameters& commonParameters, observations.waifw_home, observations.waifw_sdist, observations.cfr_byage, - observations.pf_pop[commonParameters.herd_id - 1] + observations.pf_byage }; int regionalPopulation = GetPopulationOfRegion( - observations, commonParameters.herd_id + observations ); int healthCareWorkers = ComputeNumberOfHCWInRegion( @@ -28,7 +28,7 @@ IrishModel::IrishModel(const CommonModelInputParameters& commonParameters, ); ageNums_ = ComputeAgeNums( - commonParameters.herd_id, regionalPopulation, healthCareWorkers, observations + regionalPopulation, healthCareWorkers, observations ); (*log) << "[Model settings]" << std::endl; diff --git a/src/IrishModel.h b/src/IrishModel.h index 7b8116de..5177b49f 100644 --- a/src/IrishModel.h +++ b/src/IrishModel.h @@ -21,7 +21,7 @@ class IrishModel : public ModelInterface * @param rng Random number generator to be used by the model * @param log Logger */ - IrishModel(const CommonModelInputParameters& commonParameters, const ObservationsForModels& observations, + IrishModel(const CommonModelInputParameters& commonParameters, const HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log); /** diff --git a/src/ModelCommon.cpp b/src/ModelCommon.cpp index 6bd2eac1..3362f87b 100644 --- a/src/ModelCommon.cpp +++ b/src/ModelCommon.cpp @@ -16,12 +16,12 @@ std::vector BuildFixedParameters(unsigned int size, params parameters) return std::vector(size, parameters); } -std::vector ComputeAgeNums(int shb_id, int Npop, int N_hcw, const ObservationsForModels& obs) { +std::vector ComputeAgeNums(int Npop, int N_hcw, const HealthBoardData& obs) { std::vector agenums; // define age structure of the shb of interest. the -1 is to account for difference in number of // rows between two datasets (age_pop does not have a row with column name) - const auto& agedist = obs.age_pop[shb_id - 1]; + const auto& agedist = obs.age_structure; for (const auto& var : agedist) { // modulate the population of non-hcw now to proportion in each age group recorded in 2011 @@ -33,17 +33,17 @@ std::vector ComputeAgeNums(int shb_id, int Npop, int N_hcw, const Observati return agenums; } -int GetPopulationOfRegion(const ObservationsForModels& obs, int region_id) +int GetPopulationOfRegion(const HealthBoardData& obs) { - return obs.cases[region_id][0]; + return obs.cases[0]; } -int ComputeNumberOfHCWInRegion(int regionalPopulation, int totalHCW, const ObservationsForModels& obs) +int ComputeNumberOfHCWInRegion(int regionalPopulation, int totalHCW, const HealthBoardData& obs) { - int scotlandPopulation = 0; - for (unsigned int region = 0; region < obs.cases.size() - 1; ++region) { - scotlandPopulation += obs.cases[region][0]; - } + int scotlandPopulation = obs.totScotPopulation; + // for (unsigned int region = 0; region < obs.cases.size() - 1; ++region) { + // scotlandPopulation += obs.cases[region][0]; + // } double regionalProportion = static_cast(regionalPopulation) / scotlandPopulation; return static_cast(round(totalHCW * regionalProportion)); diff --git a/src/ModelCommon.h b/src/ModelCommon.h index c3315817..40245523 100644 --- a/src/ModelCommon.h +++ b/src/ModelCommon.h @@ -129,7 +129,7 @@ int accumulate_compartments(const Compartments& comp); * * @return The population of the region */ -int GetPopulationOfRegion(const ObservationsForModels& obs, int region_id); +int GetPopulationOfRegion(const HealthBoardData& obs); /** * @brief Compute number of health care workers (HCW) in the region @@ -141,7 +141,7 @@ int GetPopulationOfRegion(const ObservationsForModels& obs, int region_id); * @param totalHCW Total number of HCWs in the country * @param obs Input observations */ -int ComputeNumberOfHCWInRegion(int regionalPopulation, int totalHCW, const ObservationsForModels& obs); +int ComputeNumberOfHCWInRegion(int regionalPopulation, int totalHCW, const HealthBoardData& obs); /** * @brief Compute the agenums @@ -152,7 +152,7 @@ int ComputeNumberOfHCWInRegion(int regionalPopulation, int totalHCW, const Obser * * @return agenums */ -std::vector ComputeAgeNums(int shb_id, int Npop, int N_hcw, const ObservationsForModels& obs); +std::vector ComputeAgeNums(int Npop, int N_hcw, const HealthBoardData& obs); /** * @brief Build the fixed parameters data structure diff --git a/src/ModelTypes.h b/src/ModelTypes.h index f8424f9f..9a482a9c 100644 --- a/src/ModelTypes.h +++ b/src/ModelTypes.h @@ -2,6 +2,8 @@ #include #include +#include +#include namespace EERAModel { @@ -155,6 +157,79 @@ struct Status pop_array; /*!< Population per epidemiological state and per age group on every day. */ }; +/** + * @brief Enumerated type to access data with axis/axes corresponding to Age Groups. + */ +enum AgeGroup { + Age_Pre_20 = 0, + Age_20_29 = 1, + Age_30_39 = 2, + Age_40_49 = 3, + Age_50_59 = 4, + Age_60_69 = 5, + Age_Post_70 = 6, + HealthCareWorkers = 7 +}; + +/** + * @brief Enumerated type to access data with axis/axes corresponding to + * case fatality ratio identifiers + */ +enum CFRCategories { + ProbabilityOfHospitalisation = 0, + CaseFatalityRatio = 1, + ProbabilityOfDeath = 2 +}; + +/** + * @brief Class that holds health board data. + * The overloaded constructors allow name consistency between, + * Health Board data needed for the Model and Inference framework. + */ +class HealthBoardData +{ + public: + int HealthBoardID; + int totScotPopulation; + std::string HealthBoardLabel; + std::vector cases; + std::vector deaths; + std::vector age_structure; + std::vector pf_byage; + std::vector timeStamps; + std::vector> waifw_norm; + std::vector> waifw_home; + std::vector> waifw_sdist; + std::vector> cfr_byage; + + HealthBoardData() {} + + HealthBoardData( + const int& HealthBoardID_in, + const std::vector>& cases_in, + const std::vector>& deaths_in + ) { + HealthBoardID = HealthBoardID_in; + HealthBoardLabel = "Health Board " + std::to_string(HealthBoardID); + cases = cases_in[HealthBoardID]; + deaths = deaths_in[HealthBoardID]; + timeStamps = cases_in[0]; + } + HealthBoardData( + const int& HealthBoardID_in, + const std::vector>& cases_in, + const std::vector>& age_structure_in, + const std::vector>& pf_byage_in + ) { + HealthBoardID = HealthBoardID_in; + HealthBoardLabel = "Health Board " + std::to_string(HealthBoardID); + cases = cases_in[HealthBoardID]; + age_structure = age_structure_in[HealthBoardID - 1]; + pf_byage = pf_byage_in[HealthBoardID - 1]; + totScotPopulation = cases_in[cases_in.size() - 1][0]; + } +}; + /** * @brief Structure containing population counters after infection * @@ -230,7 +305,7 @@ struct InferenceConfig int nSim; int nParticleLimit; std::vector toleranceLimit; - ObservationsForInference observations; + HealthBoardData observations; }; /** diff --git a/src/OriginalModel.cpp b/src/OriginalModel.cpp index 3481989d..1c666515 100644 --- a/src/OriginalModel.cpp +++ b/src/OriginalModel.cpp @@ -4,7 +4,7 @@ namespace EERAModel { namespace Model { OriginalModel::OriginalModel(const CommonModelInputParameters& commonParameters, - ObservationsForModels& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) + HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) : rng_(rng) { fixedParameters_ = BuildFixedParameters( @@ -16,11 +16,11 @@ OriginalModel::OriginalModel(const CommonModelInputParameters& commonParameters, observations.waifw_home, observations.waifw_sdist, observations.cfr_byage, - observations.pf_pop[commonParameters.herd_id - 1] + observations.pf_byage }; int regionalPopulation = GetPopulationOfRegion( - observations, commonParameters.herd_id + observations ); int healthCareWorkers = ComputeNumberOfHCWInRegion( @@ -28,7 +28,7 @@ OriginalModel::OriginalModel(const CommonModelInputParameters& commonParameters, ); ageNums_ = ComputeAgeNums( - commonParameters.herd_id, regionalPopulation, healthCareWorkers, observations + regionalPopulation, healthCareWorkers, observations ); (*log) << "[Model settings]" << std::endl; @@ -147,7 +147,6 @@ Status OriginalModel::Run(std::vector parameter_set, const seed& seedlis GenerateInfectionSpread(poparray[age], infection_state.hospitalised, fixedParameters_[age],parameter_fit[age], ageGroupData_.cfr_byage[age], lambda[age]); - infection_state.deaths += new_spread.deaths; infection_state.hospital_deaths += new_spread.hospital_deaths; infection_state.detected += new_spread.detected; diff --git a/src/OriginalModel.h b/src/OriginalModel.h index b63acb4e..66b2987c 100644 --- a/src/OriginalModel.h +++ b/src/OriginalModel.h @@ -21,7 +21,7 @@ class OriginalModel : public ModelInterface * @param rng Random number generator to be used by the model * @param log Logger */ - OriginalModel(const CommonModelInputParameters& commonParameters, ObservationsForModels& observations, + OriginalModel(const CommonModelInputParameters& commonParameters, HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log); /** diff --git a/src/TempModel.cpp b/src/TempModel.cpp index ffc9f424..e5c94d2e 100644 --- a/src/TempModel.cpp +++ b/src/TempModel.cpp @@ -4,7 +4,7 @@ namespace EERAModel { namespace Model { TempModel::TempModel(const CommonModelInputParameters& commonParameters, - const ObservationsForModels& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) + const HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log) : rng_(rng) { fixedParameters_ = BuildFixedParameters( @@ -16,11 +16,11 @@ TempModel::TempModel(const CommonModelInputParameters& commonParameters, observations.waifw_home, observations.waifw_sdist, observations.cfr_byage, - observations.pf_pop[commonParameters.herd_id - 1] + observations.pf_byage }; int regionalPopulation = GetPopulationOfRegion( - observations, commonParameters.herd_id + observations ); int healthCareWorkers = ComputeNumberOfHCWInRegion( @@ -28,7 +28,7 @@ TempModel::TempModel(const CommonModelInputParameters& commonParameters, ); ageNums_ = ComputeAgeNums( - commonParameters.herd_id, regionalPopulation, healthCareWorkers, observations + regionalPopulation, healthCareWorkers, observations ); (*log) << "[Model settings]" << std::endl; diff --git a/src/TempModel.h b/src/TempModel.h index 93386f72..201c598d 100644 --- a/src/TempModel.h +++ b/src/TempModel.h @@ -21,7 +21,7 @@ class TempModel : public ModelInterface * @param rng Random number generator to be used by the model * @param log Logger */ - TempModel(const CommonModelInputParameters& commonParameters, const ObservationsForModels& observations, + TempModel(const CommonModelInputParameters& commonParameters, const HealthBoardData& observations, Random::RNGInterface::Sptr rng, Utilities::logging_stream::Sptr log); /** diff --git a/src/main.cpp b/src/main.cpp index dee09c3e..cf314a9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,7 +46,7 @@ int main(int argc, char** argv) // Import model observational data std::string modelConfigDir(std::string(ROOT_DIR) + "/data"); - ObservationsForModels modelObservations = IO::ReadModelObservations(modelConfigDir, logger); + HealthBoardData modelObservations = IO::ReadModelObservations(modelConfigDir, logger, commonParameters.herd_id); // Log the disease seed settings IO::LogSeedSettings(supplementaryParameters.seedlist, logger);