-
Notifications
You must be signed in to change notification settings - Fork 16
1290 add ABM visualization from paper to memilio plot #1291
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
Open
xsaschako
wants to merge
11
commits into
main
Choose a base branch
from
1290-add-abm-visualization-from-paper-to-memilio-plot
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
840303d
Add scripts for analyzing infection states and ICU data from simulati…
xsaschako c7ffab3
Remove unused imports and enable plotting functions in infection stat…
xsaschako e986d96
Refactor infection states plotting script: enhance documentation, imp…
xsaschako 6e4c6fe
Refactor plotAbmInfectionStates.py: update authorship, enhance module…
xsaschako 663a189
Add unit tests for plotAbmInfectionStates: implement comprehensive te…
xsaschako 28c3187
Refactor setup.py: enhance PylintCommand documentation and update com…
xsaschako 2ba672e
Fix comment in setup.py: update example for Excel file types in insta…
xsaschako baa272b
Remove plotAbmICUAndDeadComp.py: delete unused script for ICU and dea…
xsaschako 20b651e
formatting
xsaschako 706aea0
Implement martins suggestions
xsaschako ab2e0e8
Refactor plotAbmInfectionStates.py: update paths to use command line …
xsaschako File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
266 changes: 266 additions & 0 deletions
266
pycode/memilio-plot/memilio/plot/plotAbmICUAndDeadComp.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,266 @@ | ||
# Python script to analyze bs runs | ||
# input is a bs run folder with the following structure: | ||
# bs_run_folder has a txt file for each bs run | ||
# each txt file has a line for each time step | ||
# each line has a column for each compartment as well as the timestep | ||
# each column has the number of individuals in that compartment | ||
# the first line of each txt file is the header | ||
|
||
import sys | ||
import argparse | ||
import os | ||
import pandas as pd | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
import matplotlib | ||
import matplotlib.colors as colors | ||
import matplotlib.cm as cmx | ||
import matplotlib.patches as mpatches | ||
import matplotlib.lines as mlines | ||
import h5py | ||
from datetime import datetime | ||
from matplotlib.dates import DateFormatter | ||
|
||
fontsize = 20 | ||
|
||
|
||
def plot_dead(path): | ||
# we will have a seperate plot the cumulative infected individuals, cumulative symptomatic individuals and cumulative dead individual | ||
# we need to load the data | ||
f_p50 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p50/Results.h5", 'r') | ||
p50_bs = f_p50['0'] | ||
|
||
# do the same for 25 and 75 percentile | ||
f_p25 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p25/Results.h5", 'r') | ||
p25_bs = f_p25['0'] | ||
|
||
f_p75 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p75/Results.h5", 'r') | ||
p75_bs = f_p75['0'] | ||
|
||
# do the same for 05 and 95 percentile | ||
f_p05 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p05/Results.h5", 'r') | ||
p05_bs = f_p05['0'] | ||
|
||
f_p95 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p95/Results.h5", 'r') | ||
p95_bs = f_p95['0'] | ||
|
||
age_group_access = ['Group1', 'Group2', 'Group3', | ||
'Group4', 'Group5', 'Group6', 'Total'] | ||
|
||
# we need the real data json file cases_all_county_age | ||
df_abb = pd.read_json( | ||
path+"/../../../pydata/Germany/cases_all_county_age_ma1.json") | ||
|
||
# we just need the columns cases and date | ||
# we need to offset the dates by 19 day | ||
df_abb['Date'] = df_abb['Date'] + pd.DateOffset(days=18) | ||
# we need just the dates bewteen 2021-03-01 and 2021-06-01 | ||
df_abb = df_abb[(df_abb['Date'] >= '2021-03-01') & | ||
(df_abb['Date'] <= '2021-06-01')] | ||
# we just need the cases with id 3101 | ||
df_abb = df_abb[df_abb['ID_County'] == 3101] | ||
# df_abb['Deaths'] = np.round(df_abb[['Deaths']].to_numpy()) | ||
|
||
# we need the amount of dead persons for each age group: These are A00-A04, A05-A14, A15-A34, A35-A59, A60-A79, A80+ | ||
age_groups = ['A00-A04', 'A05-A14', 'A15-A34', 'A35-A59', 'A60-A79', 'A80+'] | ||
age_grous_string = ['Age 0-4', 'Age 5-14', 'Age 15-34', 'Age 35-59', 'Age 60-79', 'Age 80+'] | ||
# we need to sum up the amount of dead persons for each age group | ||
|
||
# we want the deaths for the age groups | ||
df_abb = df_abb[['Date', 'Deaths', 'Age_RKI']] | ||
# we want a plot with 2 rows. Second row has a plot with each age group and the simulated and real dead persons | ||
# First row has the cumulative dead persons | ||
fig = plt.figure('Deaths') | ||
fig.set_figwidth(20) | ||
fig.set_figheight(9) | ||
gs = fig.add_gridspec(2,6) | ||
|
||
# we need the cumulative dead persons | ||
ax = fig.add_subplot(gs[0, :]) | ||
df_total_dead = df_abb.groupby('Date').sum()[0:90] | ||
y_real = df_total_dead['Deaths'].to_numpy() | ||
# we need to substract the first value from the rest | ||
y_real = y_real - y_real[0] | ||
|
||
y_sim = p50_bs['Total'][()][:, 7][::24][0:90] | ||
y_sim = y_sim - y_sim[0] | ||
|
||
y_sim25 = p25_bs['Total'][()][:, 7][::24][0:90] | ||
y_sim25 = y_sim25 - y_sim25[0] | ||
|
||
y_sim75 = p75_bs['Total'][()][:, 7][::24][0:90] | ||
y_sim75 = y_sim75 - y_sim75[0] | ||
|
||
y_sim05 = p05_bs['Total'][()][:, 7][::24][0:90] | ||
y_sim05 = y_sim05 - y_sim05[0] | ||
|
||
y_sim95 = p95_bs['Total'][()][:, 7][::24][0:90] | ||
y_sim95 = y_sim95 - y_sim95[0] | ||
|
||
|
||
|
||
# we calculate the RMSE | ||
rmse_dead = np.sqrt(((y_real- y_sim)**2).mean()) | ||
# we need to plot the cumulative dead persons from the real world and from the simulation | ||
|
||
ax.plot(df_total_dead.index, y_sim, color='tab:blue',label='Simulated deaths') | ||
ax.plot(df_total_dead.index, y_real, 'v',color='tab:red', linewidth=4, label='Extrapolated deaths from reported infection case data') | ||
ax.fill_between(df_total_dead.index, y_sim75, y_sim25, | ||
alpha=0.5, color='tab:blue', label='50% Confidence interval') | ||
ax.fill_between(df_total_dead.index,y_sim95, y_sim05, | ||
alpha=0.25, color='tab:blue', label='90% Confidence interval') | ||
# ax.text(0.25, 0.8, 'RMSE: '+str(float("{:.2f}".format(rmse_dead))), horizontalalignment='center', | ||
# verticalalignment='center', transform=plt.gca().transAxes, color='pink', fontsize=15) | ||
ax.set_label('Number of individuals') | ||
ax.set_title('Cumulative Deaths', fontsize=fontsize) | ||
ax.set_ylabel('Number of individuals', fontsize=fontsize-8) | ||
ax.legend(fontsize=fontsize-8) | ||
|
||
# now for each age group | ||
for i, age_group in zip(range(6), age_group_access): | ||
ax = fig.add_subplot(gs[1, i]) | ||
# we need the amount of dead persons for each age group | ||
df_abb_age_group = df_abb[df_abb['Age_RKI'] == age_groups[i]][0:90] | ||
y_real = np.round(df_abb_age_group['Deaths'].to_numpy()) | ||
# we need to plot the dead persons from the real world and from the simulation | ||
ax.plot(df_abb_age_group['Date'], y_real-y_real[0], color='tab:red') | ||
ax.plot(df_abb_age_group['Date'], p50_bs[age_group_access[i]][()][:, 7][::24][0:90]-p50_bs[age_group_access[i]][()][:, 7][::24][0], color='tab:blue') | ||
ax.fill_between(df_abb_age_group['Date'], p75_bs[age_group_access[i]][()][:, 7][::24][0:90]-p75_bs[age_group_access[i]][()][:, 7][::24][0], p25_bs[age_group_access[i]][()][:, 7][::24][0:90]-p25_bs[age_group_access[i]][()][:, 7][::24][0], | ||
alpha=0.5, color='tab:blue') | ||
ax.set_title('Deaths, '+age_grous_string[i]) | ||
ax.set_ybound(lower=0) | ||
ax.set_xticks(df_abb_age_group['Date'][::50]) | ||
ax.tick_params(axis='both', which='major', labelsize=fontsize-10) | ||
ax.tick_params(axis='both', which='minor', labelsize=fontsize-10) | ||
if i == 0: | ||
ax.set_ylabel('Number of individuals',fontsize=fontsize-8) | ||
ax.set_ybound(upper=1) | ||
|
||
plt.show() | ||
|
||
def plot_icu(path): | ||
|
||
df_abb = pd.read_json(path+"/../../../pydata/Germany/county_divi.json") | ||
|
||
perc_of_critical_in_icu_age = [0.55,0.55,0.55,0.56,0.54,0.46] | ||
perc_of_critical_in_icu=0.55 | ||
|
||
age_group_access = ['Group1', 'Group2', 'Group3', | ||
'Group4', 'Group5', 'Group6', 'Total'] | ||
|
||
|
||
# we just need the columns ICU_low and ICU_hig | ||
df_abb = df_abb[['ID_County', 'ICU', 'Date']] | ||
|
||
df_abb = df_abb[df_abb['ID_County'] == 3101] | ||
# we need just the dates bewteen 2021-03-01 and 2021-06-01 | ||
df_abb = df_abb[(df_abb['Date'] >= '2021-03-01') & | ||
(df_abb['Date'] <= '2021-06-01')] | ||
|
||
# we plot this against this the Amount of persons in the ICU from our model | ||
f_p50 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p50/Results.h5", 'r') | ||
total_50 = f_p50['0']['Total'][()][::24][0:90] | ||
|
||
total_50_age = f_p50['0'][age_group_access[0]][()] | ||
for i in range(6): | ||
total_50_age += f_p50['0'][age_group_access[i]][()]*perc_of_critical_in_icu_age[i] | ||
total_50_age = total_50_age[::24][0:90] | ||
|
||
|
||
# we plot this against this the Amount of persons in the ICU from our model | ||
f_p75 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p75/Results.h5", 'r') | ||
# total_75 = f_p75['0']['Total'][()][::24][0:90] | ||
total_75_age = f_p75['0'][age_group_access[0]][()] | ||
for i in range(6): | ||
total_75_age += f_p75['0'][age_group_access[i]][()]*perc_of_critical_in_icu_age[i] | ||
total_75_age = total_75_age[::24][0:90] | ||
|
||
# same with 25 percentile | ||
f_p25 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p25/Results.h5", 'r') | ||
# total_25 = f_p25['0']['Total'][()][::24][0:90] | ||
total_25_age = f_p25['0'][age_group_access[0]][()] | ||
for i in range(6): | ||
total_25_age += f_p25['0'][age_group_access[i]][()]*perc_of_critical_in_icu_age[i] | ||
total_25_age = total_25_age[::24][0:90] | ||
|
||
# same with 05 and 95 percentile | ||
f_p05 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p05/Results.h5", 'r') | ||
# total_05 = f_p05['0']['Total'][()][::24][0:90] | ||
total_05_age = f_p05['0'][age_group_access[0]][()] | ||
for i in range(6): | ||
total_05_age += f_p05['0'][age_group_access[i]][()]*perc_of_critical_in_icu_age[i] | ||
total_05_age = total_05_age[::24][0:90] | ||
|
||
f_p95 = h5py.File( | ||
path+"/infection_state_per_age_group/0/p95/Results.h5", 'r') | ||
# total_95 = f_p95['0']['Total'][()][::24][0:90] | ||
total_95_age = f_p95['0'][age_group_access[0]][()] | ||
for i in range(6): | ||
total_95_age += f_p95['0'][age_group_access[i]][()]*perc_of_critical_in_icu_age[i] | ||
total_95_age = total_95_age[::24][0:90] | ||
|
||
|
||
ICU_Simulation_one_percentile = np.floor(total_50[:, 5]*perc_of_critical_in_icu) | ||
ICU_Simulation = np.round(total_50_age[:, 5]) | ||
ICU_Simulation75 = np.round(total_75_age[:, 5]) | ||
ICU_Simulation25 = np.round(total_25_age[:, 5]) | ||
ICU_Simulation05 = np.round(total_05_age[:, 5]) | ||
ICU_Simulation95 = np.round(total_95_age[:, 5]) | ||
ICU_Real = df_abb['ICU'][0:90] | ||
|
||
#smooth the data | ||
# ICU_Real = gaussian_filter1d(ICU_Real, sigma=1, mode='nearest') | ||
# ICU_Simulation = gaussian_filter1d(ICU_Simulation, sigma=1, mode='nearest') | ||
|
||
|
||
|
||
# we calculate the RMSE | ||
rmse_ICU = np.sqrt(((ICU_Real - ICU_Simulation_one_percentile)**2).mean()) | ||
|
||
# plot the ICU beds and the ICU beds taken | ||
fig, ax = plt.subplots(1, 1, constrained_layout=True) | ||
fig.set_figwidth(12) | ||
fig.set_figheight(9) | ||
# we plot the ICU_low and the ICU_high | ||
ax.plot(df_abb['Date'][0:90], ICU_Real,'x', color='tab:red', linewidth=10, label='Data') | ||
ax.plot(df_abb['Date'][0:90], ICU_Simulation, color='tab:blue', label='Simulation') | ||
# ax.plot(df_abb['Date'][0:90], ICU_Simulation_one_percentile, color='tab:green', label='Simulated ICU beds') | ||
ax.fill_between(df_abb['Date'][0:90],ICU_Simulation75, ICU_Simulation25, | ||
alpha=0.5, color='tab:blue', label='50% Confidence interval') | ||
ax.fill_between(df_abb['Date'][0:90],ICU_Simulation05, ICU_Simulation95, | ||
alpha=0.25, color='tab:blue', label='90% Confidence interval') | ||
|
||
|
||
# we also write the rmse | ||
# ax.text(0.25, 0.8, 'RMSE: '+str(float("{:.2f}".format(rmse_ICU))), horizontalalignment='center', | ||
# verticalalignment='center', transform=plt.gca().transAxes, color='pink', fontsize=15) | ||
ax.tick_params(axis='both', which='major', labelsize=fontsize-4) | ||
ax.tick_params(axis='both', which='minor', labelsize=fontsize-4) | ||
ax.set_ylabel('Occupied ICU beds', fontsize=fontsize) | ||
ax.set_title('ICU beds', fontsize=fontsize+4) | ||
ax.legend(fontsize=fontsize-4) | ||
plt.show() | ||
|
||
|
||
|
||
|
||
if __name__ == "__main__": | ||
path = "" | ||
|
||
if (len(sys.argv) > 1): | ||
n_runs = sys.argv[1] | ||
else: | ||
n_runs = len([entry for entry in os.listdir(path) | ||
if os.path.isfile(os.path.join(path, entry))]) | ||
|
||
# plot_icu(path) | ||
# plot_dead(path) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.