Repository navigation
1210 abm paper logger #1507
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
base: main
Are you sure you want to change the base?
1210 abm paper logger #1507
Changes from all commits
840303d
c7ffab3
e986d96
6e4c6fe
663a189
28c3187
2ba672e
baa272b
20b651e
706aea0
ab2e0e8
e4df6cb
c5cf7dc
f5dffd6
f124f04
75e1105
ddb9cb4
c2433fc
606ba7f
e316b6a
a446792
8a002c7
392ec54
cb08197
7ccdb45
2132e8a
0c5c13a
0fdbb15
e22dd77
7d544bf
9724423
22044c6
6c6879f
49d0587
8fc375a
72fcfc5
d40ead4
19b306e
faf0f40
650985f
8e9d969
d8102a2
64998ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,17 +30,19 @@ | |
| #include "abm/mobility_data.h" | ||
| #include "memilio/utils/mioomp.h" | ||
|
|
||
| #include <vector> | ||
|
|
||
| namespace mio | ||
| { | ||
| namespace abm | ||
| { | ||
|
|
||
| /** | ||
| * @brief Struct to save specific mobility data of an agent. | ||
| * The data consists of: | ||
| * | ||
| * The data consists of the agent's id, the Location%s it moved between, the times it left and arrived, | ||
| * the TransportMode and ActivityType of the trip, and the agent's InfectionState. | ||
| */ | ||
| struct mobility_data { | ||
| struct MobilityData { | ||
| uint32_t agent_id; | ||
| uint32_t from_id; | ||
| uint32_t to_id; | ||
|
|
@@ -51,6 +53,11 @@ struct mobility_data { | |
| mio::abm::InfectionState infection_state; | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Deduce the ActivityType an agent is most likely pursuing from the LocationType it is at. | ||
| * @param[in] current_location The type of the Location the agent is currently at. | ||
| * @return The ActivityType associated with the given LocationType, or ActivityType::UnknownActivity if there is none. | ||
| */ | ||
| constexpr mio::abm::ActivityType guess_activity_type(mio::abm::LocationType current_location) | ||
| { | ||
| switch (current_location) { | ||
|
|
@@ -153,7 +160,7 @@ struct LogDataForMobility : mio::LogAlways { | |
| static Type log(const mio::abm::Simulation<>& sim) | ||
| { | ||
| Type mobility_data{}; | ||
| for (Person p : sim.get_model().get_persons()) { | ||
| for (const Person& p : sim.get_model().get_persons()) { | ||
| mobility_data.push_back( | ||
| std::make_tuple(p.get_id(), p.get_location(), sim.get_time(), p.get_last_transport_mode(), | ||
| guess_activity_type(p.get_location_type()), p.get_infection_state(sim.get_time()))); | ||
|
|
@@ -174,19 +181,95 @@ struct LogInfectionState : mio::LogAlways { | |
| */ | ||
| static Type log(const mio::abm::Simulation<>& sim) | ||
| { | ||
|
|
||
| Eigen::VectorX<ScalarType> sum = | ||
| Eigen::VectorX<ScalarType>::Zero(Eigen::Index(mio::abm::InfectionState::Count)); | ||
| auto curr_time = sim.get_time(); | ||
| PRAGMA_OMP(for) | ||
| for (auto& location : sim.get_model().get_locations()) { | ||
| for (uint32_t inf_state = 0; inf_state < (int)mio::abm::InfectionState::Count; inf_state++) { | ||
| sum[inf_state] += sim.get_model().get_subpopulation(location.get_id(), curr_time, | ||
| mio::abm::InfectionState(inf_state)); | ||
| const auto curr_time = sim.get_time(); | ||
| const auto& model = sim.get_model(); | ||
| for (const Person& p : model.get_persons()) { | ||
| if (p.get_location_model_id() == model.get_id()) { | ||
| sum[(Eigen::Index)p.get_infection_state(curr_time)] += 1; | ||
| } | ||
| } | ||
| return std::make_pair(curr_time, sum); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Logger to log the TimeSeries of the number of Person%s in an #InfectionState per AgeGroup. | ||
| * This is a finer grained variant of LogInfectionState. It is not used by ResultSimulation, but provided here so that | ||
| * a Simulation can be given an age resolved History where that resolution is needed. | ||
| */ | ||
| struct LogInfectionStatePerAgeGroup : mio::LogAlways { | ||
| using Type = std::pair<mio::abm::TimePoint, Eigen::VectorXd>; | ||
| /** | ||
| * @brief Log the TimeSeries of the number of Person%s in an #InfectionState per AgeGroup. | ||
| * @param[in] sim The simulation of the abm. | ||
| * @return A pair of the TimePoint and a vector counting the Person%s per AgeGroup and #InfectionState, | ||
| * indexed by `age_group * InfectionState::Count + infection_state`. | ||
| */ | ||
| static Type log(const mio::abm::Simulation<>& sim) | ||
| { | ||
| Eigen::VectorXd sum = Eigen::VectorXd::Zero( | ||
| Eigen::Index((size_t)mio::abm::InfectionState::Count * sim.get_model().parameters.get_num_groups())); | ||
| const auto curr_time = sim.get_time(); | ||
|
|
||
| for (const Person& p : sim.get_model().get_persons()) { | ||
| auto index = (((size_t)(mio::abm::InfectionState::Count)) * ((uint32_t)p.get_age().get())) + | ||
| ((uint32_t)p.get_infection_state(curr_time)); | ||
| sum[index] += 1; | ||
| } | ||
| return std::make_pair(curr_time, sum); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Logger to log the TimeSeries of new #Infection%s per LocationType and AgeGroup. | ||
| * Unlike the other loggers, this one keeps a state: the time and the LocationType of each Person at its previous log. | ||
| * Hence, it has to log after every time step, which is the case when used in a History passed to Simulation::advance. | ||
| */ | ||
| struct LogInfectionPerLocationTypePerAgeGroup : mio::LogAlways { | ||
| using Type = std::pair<mio::abm::TimePoint, Eigen::VectorXd>; | ||
|
xsaschako marked this conversation as resolved.
|
||
| /** | ||
| * @brief Log the TimeSeries of new #Infection%s per LocationType and AgeGroup. | ||
| * A Person is counted if it became #InfectionState::Exposed since the previous log. A Person is infected during the | ||
| * interaction at the beginning of a time step and may move to another Location afterwards. Hence, it is attributed | ||
| * to the LocationType it was at during the previous log, not to its current one. | ||
| * At the first log there is no previous log to compare against, so no Person is counted. This avoids miscounting | ||
| * the initially infected Person%s of the Model as new #Infection%s. | ||
|
Comment on lines
+237
to
+238
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has changed somehow as the quick return clause was removed. |
||
| * @param[in] sim The simulation of the abm. | ||
| * @return A pair of the TimePoint and a vector counting the newly exposed Person%s per AgeGroup and LocationType, | ||
| * indexed by `age_group * LocationType::Count + location_type`. | ||
| */ | ||
|
xsaschako marked this conversation as resolved.
|
||
| Type log(const mio::abm::Simulation<>& sim) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if this has any implications removing the static flag. |
||
| { | ||
| Eigen::VectorXd sum = Eigen::VectorXd::Zero( | ||
| Eigen::Index((size_t)mio::abm::LocationType::Count * sim.get_model().parameters.get_num_groups())); | ||
| const auto curr_time = sim.get_time(); | ||
| const auto persons = sim.get_model().get_persons(); | ||
| const size_t num_persons = persons.size(); | ||
| // Only Persons that were already present at the previous log can be compared against it. | ||
| const size_t num_previous = m_prev_location_types.size(); | ||
| m_prev_location_types.resize(num_persons); | ||
|
Comment on lines
+250
to
+252
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If persons get removed during a time step for some reason, woudn't this be an issue and shift every persons past information after the removed person by one? |
||
|
|
||
| size_t i = 0; | ||
| for (const Person& p : persons) { | ||
| if (i < num_previous && (p.get_infection_state(m_prev_time) != mio::abm::InfectionState::Exposed) && | ||
| (p.get_infection_state(curr_time) == mio::abm::InfectionState::Exposed)) { | ||
| auto index = (((size_t)(mio::abm::LocationType::Count)) * ((uint32_t)p.get_age().get())) + | ||
| ((uint32_t)m_prev_location_types[i]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is tracked here in the first step when |
||
| sum[index] += 1; | ||
| } | ||
| // Remember where the Person is now, which is where the interaction of the next time step happens. | ||
| m_prev_location_types[i] = p.get_location_type(); | ||
| ++i; | ||
| } | ||
| m_prev_time = curr_time; | ||
| return std::make_pair(curr_time, sum); | ||
| } | ||
|
|
||
| private: | ||
| mio::abm::TimePoint m_prev_time{0}; ///< Time of the previous log. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The simulation doesn't have to start at 0, this could lead to bugs. |
||
| std::vector<mio::abm::LocationType> m_prev_location_types; ///< LocationType of each Person at the previous log. | ||
| }; | ||
|
|
||
| /** | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.