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

1081 rework ABM state transitions #1107

Open
wants to merge 42 commits into
base: main
Choose a base branch
from

Conversation

jubicker
Copy link
Member

@jubicker jubicker commented Aug 13, 2024

Changes and Information

Please briefly list the changes (main added features, changed items, or corrected bugs) made:

  • add classes for Exponential, LogNormal and Constant ParameterDistributions
  • add rng as input argument for get_random_sample method of ParameterDistribution
  • add ParameterDistributionWrapper class that is used as parameter type for the transition times in the ABM
  • make the transition times in the ABM ParameterDistributionWrappers such that you can plug in any ParameterDistribution

Merge Request - Guideline Checklist

Please check our git workflow. Use the draft feature if the Pull Request is not yet ready to review.

Checks by code author

  • Every addressed issue is linked (use the "Closes #ISSUE" keyword below)
  • New code adheres to coding guidelines
  • No large data files have been added (files should in sum not exceed 100 KB, avoid PDFs, Word docs, etc.)
  • Tests are added for new functionality and a local test run was successful (with and without OpenMP)
  • Appropriate documentation for new functionality has been added (Doxygen in the code and Markdown files if necessary)
  • Proper attention to licenses, especially no new third-party software with conflicting license has been added
  • (For ABM development) Checked benchmark results and ran and posted a local test above from before and after development to ensure performance is monitored.

Checks by code reviewer(s)

  • Corresponding issue(s) is/are linked and addressed
  • Code is clean of development artifacts (no deactivated or commented code lines, no debugging printouts, etc.)
  • Appropriate unit tests have been added, CI passes, code coverage and performance is acceptable (did not decrease)
  • No large data files added in the whole history of commits(files should in sum not exceed 100 KB, avoid PDFs, Word docs, etc.)
  • On merge, add 2-5 lines with the changes (main added features, changed items, or corrected bugs) to the merge-commit-message. This can be taken from the briefly-list-the-changes above (best case) or the separate commit messages (worst case).

coses #1081

@jubicker jubicker marked this pull request as ready for review August 22, 2024 06:55
Copy link

codecov bot commented Aug 22, 2024

Codecov Report

Attention: Patch coverage is 83.19739% with 103 lines in your changes missing coverage. Please review.

Project coverage is 96.30%. Comparing base (f192ec6) to head (be07ec6).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cpp/memilio/utils/parameter_distributions.h 66.49% 65 Missing ⚠️
cpp/memilio/utils/parameter_distribution_wrapper.h 69.49% 18 Missing ⚠️
cpp/models/abm/model_functions.cpp 40.00% 9 Missing ⚠️
cpp/models/abm/parameters.h 92.92% 8 Missing ⚠️
cpp/models/abm/infection.cpp 97.08% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1107      +/-   ##
==========================================
- Coverage   96.97%   96.30%   -0.67%     
==========================================
  Files         148      149       +1     
  Lines       13718    14061     +343     
==========================================
+ Hits        13303    13542     +239     
- Misses        415      519     +104     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mknaranja mknaranja changed the title 1081 rework abm state transitions 1081 rework ABM state transitions Oct 16, 2024
Copy link
Member

@DavidKerkmann DavidKerkmann left a comment

Choose a reason for hiding this comment

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

Thank you for the implementation!
Apart from some smaller things, we could talk again about the detailed implementation of the distributions, I think @reneSchm will have some more comments and ideas once he has taken a deeper look. Many lines from the param distribtuions are listed as not tested, this could be fixed afterwards.
Related issues that will be closed should be linked correctly. We can have a look together, so that we also know what has to be done next.

Comment on lines +53 to +55
// Distribution that can be used for the time spend in InfectionStates
using InfectionStateTimesDistributionsParameters = LogNormalDistribution<double>::ParamType;

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Distribution that can be used for the time spend in InfectionStates
using InfectionStateTimesDistributionsParameters = LogNormalDistribution<double>::ParamType;

* @brief Individual virus shed factor to account for variability in infectious viral load spread.
*/
struct VirusShedFactor {
using Type = CustomIndexArray<UniformDistribution<double>::ParamType, VirusVariant, AgeGroup>;
Copy link
Member

Choose a reason for hiding this comment

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

I'd make this and all other parameters where a fixed distribution is hardcoded also changable through the wrapper.

Comment on lines +65 to +66
std::min(std::max(min_val, (1 - dev_rel * 2.6) * v), 0.1 * std::numeric_limits<double>::max()),
std::min(std::max(min_val, (1 + dev_rel * 2.6) * v), 0.5 * std::numeric_limits<double>::max()),
Copy link
Member

Choose a reason for hiding this comment

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

One could use the definitions from lower_bound and upper_bound from above.

@@ -34,7 +35,7 @@ LocationType random_mobility(PersonalRandomNumberGenerator& rng, const Person& p
auto make_transition = [current_loc](auto l) {
return std::make_pair(l, l == current_loc ? 0. : 1.);
};
if (t < params.get<LockdownDate>()) {
if (t < params.get<mio::abm::LockdownDate>()) {
Copy link
Member

Choose a reason for hiding this comment

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

Is the mio::abm:: suddenly needed here (and below)?

/**
* @brief Time that a Person is infected but not yet infectious.
* @brief Time that a Person is infected but not yet infectious in day unit
*/
struct IncubationPeriod {
Copy link
Member

Choose a reason for hiding this comment

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

I thought a bit more about the naming and came to the conclusion that IncubationPeriod doesn't really fit, as it usually describes the time from Exposure to the first Symptoms. Therefore, we should rename it. Perhaps ExposedToInfectedNoSymptoms?

@@ -56,139 +57,184 @@ std::vector<Model> ensemble_params_percentile(const std::vector<std::vector<Mode
auto& new_params = get_param(percentile[n]);
new_params = single_element[static_cast<size_t>(num_runs * p)];
};
mio::unused(param_percentile);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
mio::unused(param_percentile);

return model.parameters.template get<IncubationPeriod>()[{virus_variant, age_group}];
},
[](auto& dist1, auto& dist2) {
return dist1.params()[0] < dist2.params()[0];
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure if always using the first param is a good idea for ordering in general, but it is a good default case. Perhaps we can create a function for each dist that explains how to order, and then always call this function here?

Comment on lines -59 to -63
EXPECT_THAT(self.get_lower_bound(),
FloatingPointEqual(p_other_uniform_distribution->get_lower_bound(), 1e-12, 1e-12));
EXPECT_THAT(self.get_upper_bound(),
FloatingPointEqual(p_other_uniform_distribution->get_upper_bound(), 1e-12, 1e-12));

Copy link
Member

Choose a reason for hiding this comment

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

Why are these checks gone? The lower and upper bounds still exist for these distributions.

Comment on lines +356 to +357
// Set trips to use weekday trips on weekends.
data.use_weekday_trips_on_weekend();
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Set trips to use weekday trips on weekends.
data.use_weekday_trips_on_weekend();

Duplication?

// Set trips to use weekday trips on weekends.
data.use_weekday_trips_on_weekend();

// Mock the distribution to prevent infections or state transitions in the test.
// Mock the distribution to prevent infectionsin the test.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Mock the distribution to prevent infectionsin the test.
// Mock the distribution to prevent infections in the test.

@DavidKerkmann
Copy link
Member

My suggestion is to close
#811 and #664
while
#1081 and #688
include the symptomatic state inclusion/seperation, which is not covered here.

Comment on lines +69 to +72
if (m_dist == nullptr) {
log_error("Distribution is not defined. Parameters cannot be deduced.");
}
return m_dist->params();
Copy link
Member

Choose a reason for hiding this comment

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

Logging is not enough here, as a nullptr dereference is undefined behaviour. If we are lucky, this return will immediately cause a segfault and crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants