Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sector and income #230

Merged
merged 29 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
de623fd
Add SectorPrevalence to KevinHall.json config.
jamesturner246 Oct 20, 2023
d638cef
Load Rural Prevalence into model parser from JSON.
jamesturner246 Oct 20, 2023
585e936
Load Rural Prevalence into KH model.
jamesturner246 Oct 20, 2023
1922906
We want all our RF models' generate_ methods to run.
jamesturner246 Oct 20, 2023
3a6534e
Add stub initialise_sector method to KH model class.
jamesturner246 Oct 20, 2023
e5a312c
Add enum type for sector (region).
jamesturner246 Oct 20, 2023
87c4eac
Add 'unknown' sector enum type, and inititalise people to unknown sec…
jamesturner246 Oct 20, 2023
5f9a7fe
Finish initialise_sector code in KevinHall.
jamesturner246 Oct 20, 2023
eb35572
Clarify that we are using rural prevalence here.
jamesturner246 Oct 20, 2023
c404c0a
Don't std move trivial type
jamesturner246 Oct 20, 2023
f4d6638
model parser clang-tidy.
jamesturner246 Oct 23, 2023
b4d72ab
Add Income model parameters to KevinHall config JSON.
jamesturner246 Oct 23, 2023
d7f5b61
Load income models from JSON in mdoel parser.
jamesturner246 Oct 23, 2023
7c0846f
Load income models from mdoel parser into kevin hall model.
jamesturner246 Oct 23, 2023
1aea169
Add missing category_1 income model.
jamesturner246 Oct 24, 2023
3c6ad90
LinearModelParams should be a vector.
jamesturner246 Oct 24, 2023
c72c2bc
Add initialise_income to kevin hall model.
jamesturner246 Oct 24, 2023
61ab5b7
Fix read after std::move.
jamesturner246 Oct 25, 2023
06e553e
Call initialise_income in KH model.
jamesturner246 Oct 25, 2023
e373e53
Add sector update code to kevinhall.
jamesturner246 Oct 25, 2023
f5a22d2
Code to convert sector to a real, for use as a coefficient. Add error…
jamesturner246 Oct 25, 2023
2326ca9
Age group name consistency.
jamesturner246 Oct 25, 2023
3985efa
Add person method to check over 18.
jamesturner246 Oct 25, 2023
905223a
Add kevinhall code to update income.
jamesturner246 Oct 25, 2023
71926bd
Change weird if
jamesturner246 Oct 26, 2023
d32fd44
nutrient_ranges is now a Double interval, interval now has its own cl…
jamesturner246 Oct 26, 2023
a44f19c
KH: rural_prevalence should be an unordered_map.
jamesturner246 Oct 26, 2023
0ab8ef6
KH: use vector reserve, rather than letting it zero init.
jamesturner246 Oct 26, 2023
1ebaa1a
KH: push_back, don't assign, into reserved vector.
jamesturner246 Oct 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions example_new/KevinHall.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@
"Description": "string"
}
},
"RuralPrevalence": [
{
"AgeRange": [0, 17],
"Female": 0.65,
"Male": 0.65
},
{
"AgeRange": [18, 100],
"Female": 0.6,
"Male": 0.6
}
],
"AgeMeanHeight": {
"Male": [
0.498, 0.757, 0.868, 0.952, 1.023, 1.092, 1.155, 1.219, 1.28, 1.333,
Expand Down
24 changes: 17 additions & 7 deletions src/HealthGPS.Console/model_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,10 @@ load_ebhlm_risk_model_definition(const poco::json &opt) {
std::unique_ptr<hgps::KevinHallModelDefinition>
load_kevinhall_risk_model_definition(const poco::json &opt, const host::Configuration &config) {
MEASURE_FUNCTION();
std::unordered_map<hgps::core::Identifier, double> energy_equation;
std::unordered_map<hgps::core::Identifier, std::pair<double, double>> nutrient_ranges;
std::unordered_map<hgps::core::Identifier, std::map<hgps::core::Identifier, double>>
nutrient_equations;
std::unordered_map<hgps::core::Identifier, std::optional<double>> food_prices;
std::unordered_map<hgps::core::Gender, std::vector<double>> age_mean_height;

// Nutrient groups.
std::unordered_map<hgps::core::Identifier, double> energy_equation;
std::unordered_map<hgps::core::Identifier, std::pair<double, double>> nutrient_ranges;
jamesturner246 marked this conversation as resolved.
Show resolved Hide resolved
for (const auto &nutrient : opt["Nutrients"]) {
auto nutrient_key = nutrient["Name"].get<hgps::core::Identifier>();
nutrient_ranges[nutrient_key] = nutrient["Range"].get<std::pair<double, double>>();
Expand All @@ -272,6 +268,9 @@ load_kevinhall_risk_model_definition(const poco::json &opt, const host::Configur
}

// Food groups.
std::unordered_map<hgps::core::Identifier, std::map<hgps::core::Identifier, double>>
nutrient_equations;
std::unordered_map<hgps::core::Identifier, std::optional<double>> food_prices;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using floating-point numbers for currency is a common gotcha, because of rounding errors. Do you think it would work to use an integer type instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I didn't do that as I didn't think much arithmetic would happen with them. They aren't used yet, and will presumably be just logged for financial impact of interventions. They can be changed to unsigned integral types for pence/cents/... I'll leave that for another time, if and as needed.

for (const auto &food : opt["Foods"]) {
auto food_key = food["Name"].get<hgps::core::Identifier>();
food_prices[food_key] = food["Price"].get<std::optional<double>>();
Expand All @@ -291,7 +290,18 @@ load_kevinhall_risk_model_definition(const poco::json &opt, const host::Configur
const auto food_data_file_info = host::get_file_info(opt["FoodsDataFile"], config.root_path);
const auto food_data_table = load_datatable_from_csv(food_data_file_info);

// Rural sector prevalence for age groups and sex.
std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
rural_prevalence;
for (const auto &age_group : opt["RuralPrevalence"]) {
auto age_group_range = age_group["AgeRange"].get<hgps::core::IntegerInterval>();
rural_prevalence[std::move(age_group_range)] = {
jamesturner246 marked this conversation as resolved.
Show resolved Hide resolved
{hgps::core::Gender::female, age_group["Female"]},
{hgps::core::Gender::male, age_group["Male"]}};
}

// Load M/F average heights for age.
std::unordered_map<hgps::core::Gender, std::vector<double>> age_mean_height;
const auto max_age = static_cast<size_t>(config.settings.age_range.upper());
auto male_height = opt["AgeMeanHeight"]["Male"].get<std::vector<double>>();
auto female_height = opt["AgeMeanHeight"]["Female"].get<std::vector<double>>();
Expand All @@ -306,7 +316,7 @@ load_kevinhall_risk_model_definition(const poco::json &opt, const host::Configur

return std::make_unique<hgps::KevinHallModelDefinition>(
std::move(energy_equation), std::move(nutrient_ranges), std::move(nutrient_equations),
std::move(food_prices), std::move(age_mean_height));
std::move(food_prices), std::move(rural_prevalence), std::move(age_mean_height));
}

std::pair<hgps::RiskFactorModelType, std::unique_ptr<hgps::RiskFactorModelDefinition>>
Expand Down
13 changes: 10 additions & 3 deletions src/HealthGPS/kevin_hall_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ KevinHallModel::KevinHallModel(
const std::unordered_map<core::Identifier, std::map<core::Identifier, double>>
&nutrient_equations,
const std::unordered_map<core::Identifier, std::optional<double>> &food_prices,
const std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
&rural_prevalence,
jamesturner246 marked this conversation as resolved.
Show resolved Hide resolved
const std::unordered_map<core::Gender, std::vector<double>> &age_mean_height)
: energy_equation_{energy_equation}, nutrient_ranges_{nutrient_ranges},
nutrient_equations_{nutrient_equations}, food_prices_{food_prices},
age_mean_height_{age_mean_height} {
rural_prevalence_{rural_prevalence}, age_mean_height_{age_mean_height} {

if (energy_equation_.empty()) {
throw core::HgpsException("Energy equation mapping is empty");
Expand Down Expand Up @@ -280,10 +282,12 @@ KevinHallModelDefinition::KevinHallModelDefinition(
std::unordered_map<core::Identifier, std::pair<double, double>> nutrient_ranges,
std::unordered_map<core::Identifier, std::map<core::Identifier, double>> nutrient_equations,
std::unordered_map<core::Identifier, std::optional<double>> food_prices,
std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
rural_prevalence,
std::unordered_map<core::Gender, std::vector<double>> age_mean_height)
: energy_equation_{std::move(energy_equation)}, nutrient_ranges_{std::move(nutrient_ranges)},
nutrient_equations_{std::move(nutrient_equations)}, food_prices_{std::move(food_prices)},
age_mean_height_{std::move(age_mean_height)} {
rural_prevalence_{std::move(rural_prevalence)}, age_mean_height_{std::move(age_mean_height)} {

if (energy_equation_.empty()) {
throw core::HgpsException("Energy equation mapping is empty");
Expand All @@ -297,14 +301,17 @@ KevinHallModelDefinition::KevinHallModelDefinition(
if (food_prices_.empty()) {
throw core::HgpsException("Food prices mapping is empty");
}
if (rural_prevalence_.empty()) {
throw core::HgpsException("Rural prevalence mapping is empty");
}
if (age_mean_height_.empty()) {
throw core::HgpsException("Age mean height mapping is empty");
}
}

std::unique_ptr<RiskFactorModel> KevinHallModelDefinition::create_model() const {
return std::make_unique<KevinHallModel>(energy_equation_, nutrient_ranges_, nutrient_equations_,
food_prices_, age_mean_height_);
food_prices_, rural_prevalence_, age_mean_height_);
}

} // namespace hgps
Expand Down
10 changes: 10 additions & 0 deletions src/HealthGPS/kevin_hall_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,16 @@ class KevinHallModel final : public RiskFactorModel {
/// @param nutrient_ranges The minimum and maximum nutrient values
/// @param nutrient_equations The nutrient coefficients for each food group
/// @param food_prices The unit price for each food group
/// @param rural_prevalence Rural sector prevalence for age groups and sex
/// @param age_mean_height The mean height at all ages (male and female)
KevinHallModel(
const std::unordered_map<core::Identifier, double> &energy_equation,
const std::unordered_map<core::Identifier, std::pair<double, double>> &nutrient_ranges,
const std::unordered_map<core::Identifier, std::map<core::Identifier, double>>
&nutrient_equations,
const std::unordered_map<core::Identifier, std::optional<double>> &food_prices,
const std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
&rural_prevalence,
const std::unordered_map<core::Gender, std::vector<double>> &age_mean_height);

RiskFactorModelType type() const noexcept override;
Expand All @@ -77,6 +80,8 @@ class KevinHallModel final : public RiskFactorModel {
const std::unordered_map<core::Identifier, std::map<core::Identifier, double>>
&nutrient_equations_;
const std::unordered_map<core::Identifier, std::optional<double>> &food_prices_;
const std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
&rural_prevalence_;
const std::unordered_map<core::Gender, std::vector<double>> &age_mean_height_;

// Model parameters.
Expand Down Expand Up @@ -164,13 +169,16 @@ class KevinHallModelDefinition final : public RiskFactorModelDefinition {
/// @param nutrient_ranges The minimum and maximum nutrient values
/// @param nutrient_equations The nutrient coefficients for each food group
/// @param food_prices The unit price for each food group
/// @param rural_prevalence Rural sector prevalence for age groups and sex
/// @param age_mean_height The mean height at all ages (male and female)
/// @throws std::invalid_argument for empty arguments
KevinHallModelDefinition(
std::unordered_map<core::Identifier, double> energy_equation,
std::unordered_map<core::Identifier, std::pair<double, double>> nutrient_ranges,
std::unordered_map<core::Identifier, std::map<core::Identifier, double>> nutrient_equations,
std::unordered_map<core::Identifier, std::optional<double>> food_prices,
std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
rural_prevalence,
std::unordered_map<core::Gender, std::vector<double>> age_mean_height);

/// @brief Construct a new KevinHallModel from this definition
Expand All @@ -182,6 +190,8 @@ class KevinHallModelDefinition final : public RiskFactorModelDefinition {
std::unordered_map<core::Identifier, std::pair<double, double>> nutrient_ranges_;
std::unordered_map<core::Identifier, std::map<core::Identifier, double>> nutrient_equations_;
std::unordered_map<core::Identifier, std::optional<double>> food_prices_;
std::map<hgps::core::IntegerInterval, std::unordered_map<hgps::core::Gender, double>>
rural_prevalence_;
std::unordered_map<core::Gender, std::vector<double>> age_mean_height_;
};

Expand Down
Loading