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

Inside demonstrator munich #1169

Open
wants to merge 119 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
59d7ab5
first draft
xsaschako Mar 17, 2023
72f9c60
add another logger
xsaschako Mar 27, 2023
6e97737
change some things
xsaschako Mar 27, 2023
b49606f
example for testing purposes
xsaschako Mar 27, 2023
bf50995
barebone implementation
xsaschako Mar 30, 2023
7879f10
add simulation for abm demonstrator
jubicker Mar 30, 2023
cf260b7
add to cmakelist
xsaschako Mar 30, 2023
929753a
further enhance object file
xsaschako Apr 3, 2023
8cf13dd
some more
xsaschako Apr 3, 2023
2d7892e
comments
jubicker Apr 4, 2023
22c7e3e
convert size to int
jubicker Apr 4, 2023
93819a0
add another logger
xsaschako Apr 4, 2023
f9037d8
python abm demonstrator
jubicker Apr 5, 2023
ee57e2d
[CI SKIP] inside demonstrator
jubicker Apr 6, 2023
a3d3423
python demonstrator
jubicker Apr 12, 2023
8217776
[ci skip] add location capacities
jubicker Apr 14, 2023
ad215b7
[ci skip] comments
jubicker Apr 14, 2023
84d1135
add hiistory buffer
xsaschako Apr 14, 2023
80f4bf3
some additions
xsaschako Apr 18, 2023
1d80694
new additions
xsaschako Apr 20, 2023
284ed76
added julias output
xsaschako Apr 20, 2023
26d555d
[ci skip] simulation python binding
jubicker Apr 24, 2023
d25eec6
[ci skip] correct abm simulation bindings
jubicker Apr 24, 2023
cd4e51c
implement basic output for julia
xsaschako Apr 25, 2023
1ab0476
test output txt using output object
jubicker May 3, 2023
d9b8f37
log first time point
jubicker May 3, 2023
6703fa7
set initial time_since_transmission
jubicker May 3, 2023
6ef8eec
Merge branch '424-output-object-for-the-abm' into 604-enhancement-abm…
jubicker May 3, 2023
1b3eae2
output object for cpp demonstrator
jubicker May 3, 2023
e935bbe
Merge branch 'main' into 604-enhancement-abm-inside-demonstrator
jubicker May 3, 2023
153c3c3
write location mapping to file
jubicker May 5, 2023
3dce4d7
[ci skip] run simulation on linux
jubicker May 5, 2023
4711b9a
[ci skip] python demonstrator
jubicker May 5, 2023
ca11403
[ci skip] bug in python demonstrator
jubicker May 9, 2023
5c80091
[ci skip] set time until carrier
jubicker May 9, 2023
b46146a
paths and comments
jubicker May 9, 2023
3b2274e
comments and household distributions
jubicker May 10, 2023
e394edc
pre commit and fix CI
jubicker May 10, 2023
9534c3b
[ci skip] set seeds
jubicker May 15, 2023
688f592
merge main
jubicker Jun 26, 2023
8abd5c2
fix cpp demonstrator
jubicker Jun 27, 2023
62324fc
format
jubicker Jun 27, 2023
b3671d2
fix bindings
jubicker Jun 27, 2023
46f4360
assign_infection_state
jubicker Jun 27, 2023
fd1078f
add cemetery
jubicker Jun 27, 2023
5ae1e31
rename infection states
jubicker Jun 28, 2023
73f65db
delete old files
jubicker Jun 28, 2023
26c2692
fix merge with main
jubicker Jun 28, 2023
4fa83e1
add history object to test_abm
jubicker Jun 28, 2023
909dbc3
set time since transmission to -1 for recovered
jubicker Jun 30, 2023
02e7d91
Change recovered compartment in print
jubicker Jun 30, 2023
0620444
bug fix: dead people are not infectious
jubicker Jul 2, 2023
e08189d
read me
jubicker Jul 6, 2023
9c0b649
correct readMe and print console output to csv
jubicker Jul 10, 2023
fc4e054
set correct time since transmission at beginning
jubicker Jul 11, 2023
4bdafc3
Merge branch 'main' into inside-demonstrator-merge
jubicker Jul 12, 2023
183546d
Merge branch 'main' into inside-demonstrator-merge
jubicker Jul 12, 2023
fdc6687
remove wrong parameters
jubicker Jul 13, 2023
9c3da56
set seeds for location distribution
jubicker Jul 14, 2023
eaaf781
autopep
jubicker Jul 14, 2023
46eb63f
scale infectivity function
jubicker Jul 17, 2023
0823538
bindings and new default values
jubicker Jul 17, 2023
5179fb6
new probabilities for infection course
jubicker Jul 17, 2023
00cf250
write infection paths to file
jubicker Jul 18, 2023
af8ce7a
pre-commit
jubicker Jul 18, 2023
48033fc
scale infectiousness
jubicker Jul 26, 2023
07d340a
Merge branch 'inside-demonstrator-merge' of https://github.com/DLR-SC…
jubicker Jul 26, 2023
9d4cac2
scaling infectivity curve
jubicker Jul 27, 2023
dccb141
new output & bugfix
jubicker Aug 2, 2023
17c0fbd
add abm checks to anaylsis section
schminin Oct 6, 2023
e825967
move analysis to extra repo
schminin Oct 6, 2023
3e8ee9f
delete ipynb checkpoints
schminin Oct 8, 2023
246587a
delete png files
schminin Oct 8, 2023
1f10b33
load parameter values from file
schminin Oct 9, 2023
488cc7a
add at least one adult to other households
jubicker Oct 9, 2023
2291160
merge
jubicker Oct 9, 2023
f43fba9
platform independent file access
schminin Oct 10, 2023
53d31cb
change Location Id
jubicker Nov 7, 2023
0759722
merge main
jubicker Mar 21, 2024
1c07656
fix cpp demonstrator
jubicker Mar 21, 2024
71e1303
fix bindings
jubicker Mar 22, 2024
5f37103
introduce parameter distributions
jubicker Mar 27, 2024
8317074
minor changes
jubicker Mar 28, 2024
b745387
new parameters
jubicker Apr 2, 2024
b8c4a4f
bug fix
jubicker Apr 2, 2024
2a9e569
bug fix
jubicker Apr 2, 2024
c5ccc67
set aerosol transmission to 0
jubicker Apr 17, 2024
06d942a
bug fix and rework output
jubicker Aug 28, 2024
c21be46
new infectivity curve
jubicker Sep 2, 2024
f4e70d2
change t_peak and t_shift
jubicker Sep 6, 2024
26f708f
add individual return from work/school times
jubicker Sep 9, 2024
1ecf01e
seed and comp output
jubicker Sep 12, 2024
6842175
bug fix
jubicker Sep 12, 2024
95c537b
add comp output
jubicker Sep 12, 2024
6608a98
test
jubicker Sep 12, 2024
a4684d7
test
jubicker Sep 12, 2024
18e6337
test
jubicker Sep 12, 2024
a197f20
test
jubicker Sep 12, 2024
d73cf6e
test
jubicker Sep 12, 2024
e4fad2f
test
jubicker Sep 12, 2024
9c8ea31
test
jubicker Sep 12, 2024
dabbd19
new intialization
jubicker Sep 17, 2024
547c214
input files
jubicker Sep 23, 2024
7c40a57
new output format
jubicker Dec 17, 2024
cc1bee3
merge main
jubicker Dec 17, 2024
fc70de8
fix merge conflicts
jubicker Dec 17, 2024
21a5370
fix tests
jubicker Dec 18, 2024
fb5cef0
mock lognormal dist
jubicker Jan 2, 2025
e5e08c3
fix msvc tests
jubicker Jan 2, 2025
34db01a
abm bindings
jubicker Jan 3, 2025
c8eb6f5
fix demonstrator
jubicker Jan 3, 2025
952ebd6
set age groups for school and work
jubicker Jan 3, 2025
1db9ebd
Merge branch 'main' into inside-demonstrator-munich
jubicker Jan 7, 2025
afc0f4b
fix python unittest
jubicker Jan 7, 2025
352a8f9
demonstrator file
jubicker Jan 16, 2025
526946e
demonstrator_munich
jubicker Jan 18, 2025
f4b53c8
initialize model function
jubicker Jan 20, 2025
92cd78d
demonstrator munich
jubicker Jan 21, 2025
af7bcbd
fix time since transmission bug
jubicker Jan 21, 2025
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
Prev Previous commit
Next Next commit
bug fix and rework output
  • Loading branch information
jubicker committed Aug 28, 2024
commit 06d942af1383f2e22013e31da6c28ff0a32aba17
27 changes: 21 additions & 6 deletions cpp/models/abm/infection.cpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
*/

#include "abm/infection.h"
#include <algorithm>
#include <math.h>

namespace mio
@@ -85,12 +86,13 @@ ScalarType Infection::get_infectivity(TimePoint t) const
auto scaled_time = TimePoint(0) + seconds(int(scaling_factor * (t.seconds() - time_shift.seconds()) -
(scaling_factor - 1) * m_viral_load.start_date.seconds()));
ScalarType infectivity = 1 / (1 + exp(-(m_log_norm_alpha + m_log_norm_beta * get_viral_load(scaled_time))));
if (m_infection_course.size() > 3 && m_infection_course[3].second == InfectionState::InfectedSevere) {
return infectivity;
}
else {
return 0.75 * infectivity;
}
return 0.75 * infectivity;
// if (m_infection_course.size() > 3 && m_infection_course[3].second == InfectionState::InfectedSevere) {
// return infectivity;
// }
// else {
// return 0.75 * infectivity;
// }
}

VirusVariant Infection::get_virus_variant() const
@@ -134,6 +136,19 @@ TimePoint Infection::get_start_date() const
return m_viral_load.start_date;
}

TimeSpan Infection::get_time_in_state(InfectionState state)
{
auto pos = std::find_if(m_infection_course.begin(), m_infection_course.end(),
[state](const std::pair<TimePoint, InfectionState>& inf) {
return (inf.second == state);
});
// infection state is not part of infection course
if (pos == m_infection_course.end()) {
return TimeSpan(0);
}
return ((pos + 1)->first - pos->first);
}

TimePoint Infection::draw_infection_course(Person::RandomNumberGenerator& rng, AgeGroup age, const Parameters& params,
TimePoint init_date, InfectionState init_state,
std::pair<ExposureType, TimePoint> latest_protection)
13 changes: 8 additions & 5 deletions cpp/models/abm/infection.h
Original file line number Diff line number Diff line change
@@ -120,6 +120,14 @@ class Infection
*/
TimePoint get_start_date() const;

/**
* @brief Get the the time in #InfectionState.
* If the infection state is not part of the infection course, the time is zero.
* @param[in] state InfectionState of the query.
* @return TimeSpan spent in state.
*/
TimeSpan get_time_in_state(InfectionState state);

private:
/**
* @brief Determine ViralLoad course and Infection course based on init_state.
@@ -160,11 +168,6 @@ class Infection
TimePoint draw_infection_course_backward(Person::RandomNumberGenerator& rng, AgeGroup age, const Parameters& params,
TimePoint init_date, InfectionState init_state);

/**
* @return the time a person is infected.
*/
void get_time_infected();

std::vector<std::pair<TimePoint, InfectionState>> m_infection_course; ///< Start date of each #InfectionState.
VirusVariant m_virus_variant; ///< Variant of the Infection.
ViralLoad m_viral_load; ///< ViralLoad of the Infection.
6 changes: 3 additions & 3 deletions cpp/models/abm/parameters.h
Original file line number Diff line number Diff line change
@@ -338,7 +338,7 @@ struct InfectionRateFromViralShed {
using Type = CustomIndexArray<ScalarType, VirusVariant>;
static Type get_default(AgeGroup /*size*/)
{
return Type({VirusVariant::Count}, 2.0); //Julia
return Type({VirusVariant::Count}, 0.2); //Julia
}
static std::string name()
{
@@ -404,7 +404,7 @@ struct SeverityProtectionFactor {
*/
struct HighViralLoadProtectionFactor {
using Type = InputFunctionForProtectionLevel;
static auto get_default()
static auto get_default(AgeGroup /*size*/)
{
return Type([](ScalarType /*days*/) -> ScalarType {
return 0;
@@ -471,7 +471,7 @@ struct PCRTest : public GenericTest {
*/
struct LockdownDate {
using Type = TimePoint;
static auto get_default()
static auto get_default(AgeGroup /*size*/)
{
return TimePoint(std::numeric_limits<int>::max());
}
88 changes: 73 additions & 15 deletions pycode/examples/simulation/ABM Demonstrator/abm_demonstrator.py
Original file line number Diff line number Diff line change
@@ -49,6 +49,23 @@ def __init__(self):
age_group_80_plus = AgeGroup(5)


def age_group_to_string(age_group):
if (age_group == age_group_0_to_4):
return "0"
elif (age_group == age_group_5_to_14):
return "1"
elif (age_group == age_group_15_to_34):
return "2"
elif (age_group == age_group_35_to_59):
return "3"
elif (age_group == age_group_60_to_79):
return "4"
elif (age_group == age_group_80_plus):
return "5"
else:
return "AgeGroup not found"


def set_infection_parameters(parameters):

infection_params = abm.Parameters(num_age_groups)
@@ -663,20 +680,49 @@ def write_infection_paths_to_file_states(path, log):
f.close()


def write_infection_paths_to_file(path, log):
agent_ids = [log[2][0][i][1] for i in range(len(log[2][0]))]
def write_infection_paths_to_file(path, world, tmax):
with open(path, 'w') as f:
f.write("Agent_id S E I_ns I_sy I_sev I_cri R D\n")
for id in agent_ids:
for person in world.persons:
line = str(id) + " "
# times_per_state is number of time points per compartment: [S, E, I_ns, I_sy, I_sev, I_cri, R, D]
times_per_state = [0 for comp in range(8)]
for t in range(len(log[2])):
times_per_state[int(log[2][t][id][3])] += 1
for state in range(len(times_per_state)):
line += str(times_per_state[state]) + " "
f.write(line)
f.write('\n')
if person.infection_state(tmax) == abm.InfectionState.Susceptible:
line += str(tmax.hours) + " "
for i in range(int(abm.InfectionState.Count)-1):
line += "0 "
else:
time_S = max(
person.infection.get_infection_start() - abm.TimePoint(0), abm.TimeSpan(0))
time_E = person.infection.get_time_in_state(
abm.InfectionState.Exposed)
time_INS = person.infection.get_time_in_state(
abm.InfectionState.InfectedNoSymptoms)
time_ISy = person.infection.get_time_in_state(
abm.InfectionState.InfectedSymptoms)
time_ISev = person.infection.get_time_in_state(
abm.InfectionState.InfectedSevere)
time_ICri = person.infection.get_time_in_state(
abm.InfectionState.InfectedCritical)
time_R = 0
time_D = 0
if (person.infection_state(tmax) == abm.InfectionState.Recovered):
time_infected = time_E + time_INS + time_ISy + time_ISev + time_ICri
if (time_S.hours == 0):
time_R = tmax - \
(time_infected +
(person.infection.get_infection_start() - abm.TimePoint(0)))
else:
time_R = tmax - time_S - time_infected
if (person.infection_state(tmax) == abm.InfectionState.Dead):
time_infected = time_E + time_INS + time_ISy + time_ISev + time_ICri
if (time_S.hours == 0):
time_R = tmax - \
(time_infected +
(person.infection.get_infection_start() - abm.TimePoint(0)))
else:
time_R = tmax - time_S - time_infected
line += str(time_S.hours) + " " + str(time_E.hours) + " " + str(time_INS.hours) + " " + str(time_ISy) + " " \
+ str(time_ISev) + " " + str(time_ICri) + \
" " + str(time_R) + " " + str(time_D)
f.close()


@@ -697,10 +743,20 @@ def set_sim_result_at_start(sim):
result += location.population.get_last_value()


def write_age_and_hh(world, path):
with open(path, 'w') as f:
for person in world.persons:
line = str(person.id) + " " + age_group_to_string(person.age) + " " + \
str(person.assigned_location(abm.LocationType.Home))
f.write(line)
f.write('\n')
f.close()


def run_abm_simulation():
mio.set_log_level(mio.LogLevel.Warning)
input_path = 'C:/Users/bick_ju/Documents/INSIDe/Demonstrator/INSIDeDemonstrator/'
output_path = 'C:/Users/bick_ju/Documents/INSIDe/Demonstrator/INSIDeDemonstrator/'
output_path = 'H:/Documents/INSIDeDemonstrator/share_with_julia/memilio_output/20240828/'
# set seed for fixed model initialization (locations and initial infection states)
np.random.seed(0)
# starting time point
@@ -728,18 +784,20 @@ def run_abm_simulation():
assign_locations(sim.world)
# output object
history = History()
# just used for debugging
# write_age_and_hh(sim.world, os.path.join(output_path, 'age_hh.txt'))
# advance simulation until tmax
sim.advance(tmax, history)
# results collected during the simulation
log = history.log
# write infection paths per agent to file
write_infection_paths_to_file(os.path.join(
output_path, 'infection_paths.txt'), sim.world, tmax)
# write simulation results to txt file
write_results_to_file(os.path.join(output_path, 'output.txt'), log)
# write location mapping to txt file
write_location_mapping_to_file(
os.path.join(output_path, 'location_mapping.txt'), mapping)
# write infection paths per agent to file
write_infection_paths_to_file(os.path.join(
output_path, 'infection_paths.txt'), log)

print('done')

16 changes: 15 additions & 1 deletion pycode/memilio-simulation/memilio/simulation/abm.cpp
Original file line number Diff line number Diff line change
@@ -191,8 +191,18 @@ PYBIND11_MODULE(_simulation_abm, m)
[](mio::abm::Person& self, mio::abm::Infection& infection, mio::abm::TimePoint t) {
self.add_new_infection(std::move(infection), t);
})
.def("assigned_location",
[](mio::abm::Person& self, mio::abm::LocationType type) {
return self.get_assigned_location_index(type);
})
.def("infection_state",
[](mio::abm::Person& self, mio::abm::TimePoint t) {
return self.get_infection_state(t);
})
.def_property_readonly("infection", py::overload_cast<>(&mio::abm::Person::get_infection, py::const_))
.def_property_readonly("location", py::overload_cast<>(&mio::abm::Person::get_location, py::const_))
.def_property_readonly("age", &mio::abm::Person::get_age)
.def_property_readonly("id", &mio::abm::Person::get_person_id)
.def_property_readonly("is_in_quarantine", &mio::abm::Person::is_in_quarantine);

py::class_<mio::abm::HouseholdMember>(m, "HouseholdMember")
@@ -238,7 +248,11 @@ PYBIND11_MODULE(_simulation_abm, m)
auto rng = mio::abm::Person::RandomNumberGenerator(world.get_rng(), person);
return mio::abm::Infection(rng, variant, person.get_age(), world.parameters, start_date, start_state,
person.get_latest_protection(), detected);
}));
}))
.def("get_infection_start", &mio::abm::Infection::get_infection_start)
.def("get_time_in_state", [](mio::abm::Infection& self, mio::abm::InfectionState state) {
return self.get_time_in_state(state);
});

py::class_<mio::abm::Location>(m, "Location")
.def("set_capacity", &mio::abm::Location::set_capacity)
4 changes: 4 additions & 0 deletions pycode/memilio-simulation/memilio/simulation/simulation.cpp
Original file line number Diff line number Diff line change
@@ -38,6 +38,8 @@
#include "memilio/geography/regions.h"
#include "memilio/epidemiology/contact_matrix.h"

#include "models/abm/virus_variant.h"

namespace py = pybind11;

namespace pymio
@@ -54,6 +56,8 @@ std::string pretty_name<mio::AgeGroup>()
PYBIND11_MODULE(_simulation, m)
{
pymio::bind_CustomIndexArray<mio::UncertainValue, mio::AgeGroup>(m, "AgeGroupArray");
pymio::bind_CustomIndexArray<bool, mio::AgeGroup>(m, "b_AgeGroupArray");
pymio::bind_CustomIndexArray<double, mio::abm::VirusVariant>(m, "d_VirusVariantArray");
py::class_<mio::AgeGroup, mio::Index<mio::AgeGroup>>(m, "AgeGroup").def(py::init<size_t>());

pymio::bind_date(m, "Date");