Skip to content

Commit 43065af

Browse files
authored
Merge branch 'develop' into issue_#214_cypress
2 parents 3f4ab03 + 7b8611b commit 43065af

File tree

8 files changed

+118
-72
lines changed

8 files changed

+118
-72
lines changed

.github/workflows/dockerpublish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ jobs:
9292
echo "::set-env name=VERSION::$VERSION"
9393
9494
# Update image version in application manifest
95-
sed -Ei "s,(- image: docker.pkg.github.com)(.*),\1/${{ github.repository }}/$IMAGE_NAME:$VERSION," k8s/app.yaml
95+
sed -Ei "s,(- image: docker.pkg.github.com)(.*),\1/${GITHUB_REPOSITORY,,}/$IMAGE_NAME:$VERSION," k8s/app.yaml
9696
9797
# Show updated manifest file
9898
cat k8s/app.yaml

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Setup file for chime
22
"""
3-
__version__ = "0.2.0"
3+
__version__ = "1.1.0"
44
__author__ = "Predictive Healthcare @ Penn Medicine"
55

66
from os import path

src/app.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
display_header(st, m, p)
3535

3636
if st.checkbox("Show more info about this tool"):
37-
notes = "The total size of the susceptible population will be the entire catchment area for Penn Medicine entities (HUP, PAH, PMC, CCH)"
37+
notes = "The total size of the susceptible population will be the entire catchment area for our hospitals."
3838
display_more_info(st=st, model=m, parameters=p, defaults=DEFAULTS, notes=notes)
3939

4040
st.subheader("New Admissions")
41-
st.markdown("Projected number of **daily** COVID-19 admissions at Penn hospitals")
41+
st.markdown("Projected number of **daily** COVID-19 admissions. \n\n _NOTE: Now including back-casting of prior admissions for comparison._")
4242
admits_chart = build_admits_chart(alt=alt, admits_df=m.admits_df, max_y_axis=p.max_y_axis)
4343
st.altair_chart(admits_chart, use_container_width=True)
44-
st.markdown(build_descriptions(chart=admits_chart, labels=p.labels))
44+
st.markdown(build_descriptions(chart=admits_chart, labels=p.labels, suffix=" Admissions"))
4545
display_download_link(
4646
st,
4747
filename=f"{p.current_date}_projected_admits.csv",
@@ -60,7 +60,7 @@
6060

6161

6262
st.subheader("Admitted Patients (Census)")
63-
st.markdown("Projected **census** of COVID-19 patients, accounting for arrivals and discharges at Penn hospitals")
63+
st.markdown("Projected **census** of COVID-19 patients, accounting for arrivals and discharges \n\n _NOTE: Now including back-casting of prior census for comparison._")
6464
census_chart = build_census_chart(alt=alt, census_df=m.census_df, max_y_axis=p.max_y_axis)
6565
st.altair_chart(census_chart, use_container_width=True)
6666
st.markdown(build_descriptions(chart=census_chart, labels=p.labels, suffix=" Census"))

src/penn_chime/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414

1515
EPSILON = 1.0e-7
1616

17-
FLOAT_INPUT_MIN = 0.001
18-
FLOAT_INPUT_STEP = FLOAT_INPUT_MIN
17+
FLOAT_INPUT_MIN = 0.0001
18+
FLOAT_INPUT_STEP = 0.1

src/penn_chime/models.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ def __init__(self, p: Parameters):
9191

9292
self.beta_t = get_beta(intrinsic_growth_rate, self.gamma, self.susceptible, p.relative_contact_rate)
9393
self.run_projection(p)
94-
self.infected = self.raw_df['infected'].values[i_day]
95-
self.susceptible = self.raw_df['susceptible'].values[i_day]
96-
self.recovered = self.raw_df['recovered'].values[i_day]
94+
9795
self.r_t = self.beta_t / gamma * susceptible
9896
self.r_naught = self.beta / gamma * susceptible
9997
logger.info('Set i_day = %s', i_day)
@@ -144,6 +142,10 @@ def __init__(self, p: Parameters):
144142
logger.info('len(np.arange(-i_day, n_days+1)): %s', len(np.arange(-self.i_day, p.n_days+1)))
145143
logger.info('len(raw_df): %s', len(self.raw_df))
146144

145+
self.infected = self.raw_df['infected'].values[self.i_day]
146+
self.susceptible = self.raw_df['susceptible'].values[self.i_day]
147+
self.recovered = self.raw_df['recovered'].values[self.i_day]
148+
147149
self.r_t = self.beta_t / gamma * susceptible
148150
self.r_naught = self.beta / gamma * susceptible
149151

src/penn_chime/parameters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __init__(
5959
infectious_days: int = 14,
6060
market_share: float = 1.0,
6161
max_y_axis: Optional[int] = None,
62-
n_days: int = 60,
62+
n_days: int = 100,
6363
population: Optional[int] = None,
6464
recovered: int = 0,
6565
region: Optional[Regions] = None,

src/penn_chime/presentation.py

Lines changed: 101 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,17 @@ def display_header(st, m, p):
5151
unsafe_allow_html=True,
5252
)
5353
st.markdown(
54-
"""[Documentation](https://code-for-philly.gitbook.io/chime/) | [Github](https://github.com/CodeForPhilly/chime/) | [Slack](https://codeforphilly.org/chat?channel=covid19-chime-penn)"""
54+
"""[Documentation]({docs_url}) | [Github](https://github.com/CodeForPhilly/chime/) |
55+
[Slack](https://codeforphilly.org/chat?channel=covid19-chime-penn)""".format(
56+
docs_url=DOCS_URL
57+
)
5558
)
5659
st.markdown(
5760
"""*This tool was developed by the [Predictive Healthcare team](http://predictivehealthcare.pennmedicine.org/) at
5861
Penn Medicine to assist hospitals and public health officials with hospital capacity planning,
5962
but can be used anywhere in the world.
6063
Customize it for your region by modifying data inputs in the left panel.*
61-
""".format(docs_url=DOCS_URL)
64+
"""
6265
)
6366

6467
st.markdown(
@@ -86,11 +89,14 @@ def display_header(st, m, p):
8689
relative_contact_rate=p.relative_contact_rate,
8790
r_t=m.r_t,
8891
doubling_time_t=abs(m.doubling_time_t),
89-
impact_statement=("halves the infections every" if m.r_t < 1 else "reduces the doubling time to"),
92+
impact_statement=(
93+
"halves the infections every"
94+
if m.r_t < 1
95+
else "reduces the doubling time to"
96+
),
9097
daily_growth=m.daily_growth_rate * 100.0,
9198
daily_growth_t=m.daily_growth_rate_t * 100.0,
92-
docs_url=DOCS_URL,
93-
infected_population_warning_str=infected_population_warning_str
99+
infected_population_warning_str=infected_population_warning_str,
94100
)
95101
)
96102

@@ -99,6 +105,7 @@ def display_header(st, m, p):
99105

100106
class Input:
101107
"""Helper to separate Streamlit input definition from creation/rendering"""
108+
102109
def __init__(self, st_obj, label, value, kwargs):
103110
self.st_obj = st_obj
104111
self.label = label
@@ -110,8 +117,20 @@ def __call__(self):
110117

111118

112119
class NumberInput(Input):
113-
def __init__(self, st_obj, label, min_value=None, max_value=None, value=None, step=None, format=None, key=None):
114-
kwargs = dict(min_value=min_value, max_value=max_value, step=step, format=format, key=key)
120+
def __init__(
121+
self,
122+
st_obj,
123+
label,
124+
min_value=None,
125+
max_value=None,
126+
value=None,
127+
step=None,
128+
format=None,
129+
key=None,
130+
):
131+
kwargs = dict(
132+
min_value=min_value, max_value=max_value, step=step, format=format, key=key
133+
)
115134
super().__init__(st_obj.number_input, label, value, kwargs)
116135

117136

@@ -122,8 +141,20 @@ def __init__(self, st_obj, label, value=None, key=None):
122141

123142

124143
class PercentInput(NumberInput):
125-
def __init__(self, st_obj, label, min_value=0.0, max_value=100.0, value=None, step=FLOAT_INPUT_STEP, format="%f", key=None):
126-
super().__init__(st_obj, label, min_value, max_value, value * 100.0, step, format, key)
144+
def __init__(
145+
self,
146+
st_obj,
147+
label,
148+
min_value=0.0,
149+
max_value=100.0,
150+
value=None,
151+
step=FLOAT_INPUT_STEP,
152+
format="%f",
153+
key=None,
154+
):
155+
super().__init__(
156+
st_obj, label, min_value, max_value, value * 100.0, step, format, key
157+
)
127158

128159
def __call__(self):
129160
return super().__call__() / 100.0
@@ -161,40 +192,37 @@ def display_sidebar(st, d: Parameters) -> Parameters:
161192
doubling_time_input = NumberInput(
162193
st_obj,
163194
"Doubling time before social distancing (days)",
164-
min_value=FLOAT_INPUT_MIN,
195+
min_value=0.5,
165196
value=d.doubling_time,
166-
step=FLOAT_INPUT_STEP,
197+
step=0.25,
167198
format="%f",
168199
)
169200
current_date_input = DateInput(
170-
st_obj,
171-
"Current date (Default is today)",
172-
value=d.current_date,
201+
st_obj, "Current date (Default is today)", value=d.current_date,
173202
)
174203
date_first_hospitalized_input = DateInput(
175-
st_obj,
176-
"Date of first hospitalized case",
204+
st_obj, "Date of first hospitalized case - Enter this date to have chime estimate the initial doubling time",
177205
value=d.date_first_hospitalized,
178206
)
179207
relative_contact_pct_input = PercentInput(
180208
st_obj,
181-
"Social distancing (% reduction in social contact)",
209+
"Social distancing (% reduction in social contact going forward)",
210+
min_value=0.0,
211+
max_value=100.0,
182212
value=d.relative_contact_rate,
213+
step=1.0,
183214
)
184215
hospitalized_pct_input = PercentInput(
185-
st_obj,
186-
"Hospitalization %(total infections)",
187-
value=d.hospitalized.rate,
216+
st_obj, "Hospitalization %(total infections)", value=d.hospitalized.rate,
188217
)
189-
icu_pct_input = PercentInput(
190-
st_obj,
218+
icu_pct_input = PercentInput(st_obj,
191219
"ICU %(total infections)",
220+
min_value=0.0,
192221
value=d.icu.rate,
222+
step=0.05
193223
)
194224
ventilated_pct_input = PercentInput(
195-
st_obj,
196-
"Ventilated %(total infections)",
197-
value=d.ventilated.rate,
225+
st_obj, "Ventilated %(total infections)", value=d.ventilated.rate,
198226
)
199227
hospitalized_days_input = NumberInput(
200228
st_obj,
@@ -223,14 +251,14 @@ def display_sidebar(st, d: Parameters) -> Parameters:
223251
market_share_pct_input = PercentInput(
224252
st_obj,
225253
"Hospital Market Share (%)",
226-
min_value=FLOAT_INPUT_MIN,
254+
min_value=0.5,
227255
value=d.market_share,
228256
)
229257
population_input = NumberInput(
230258
st_obj,
231259
"Regional Population",
232260
min_value=1,
233-
value=(d.region.population or d.population),
261+
value=(d.population),
234262
step=1,
235263
format="%i",
236264
)
@@ -242,22 +270,39 @@ def display_sidebar(st, d: Parameters) -> Parameters:
242270
step=1,
243271
format="%i",
244272
)
245-
max_y_axis_set_input = CheckboxInput(st_obj, "Set the Y-axis on graphs to a static value")
246-
max_y_axis_input = NumberInput(st_obj, "Y-axis static value", value=500, format="%i", step=25)
273+
max_y_axis_set_input = CheckboxInput(
274+
st_obj, "Set the Y-axis on graphs to a static value"
275+
)
276+
max_y_axis_input = NumberInput(
277+
st_obj, "Y-axis static value", value=500, format="%i", step=25
278+
)
247279

248280
# Build in desired order
281+
st.sidebar.markdown(
282+
"""**CHIME [v1.1.0](https://github.com/CodeForPhilly/chime/releases/tag/v1.1.0) (2020/03/30)**"""
283+
)
284+
249285
current_date = current_date_input()
250286

251-
st.sidebar.markdown("### Regional Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
287+
st.sidebar.markdown(
288+
"### Regional Parameters [ℹ]({docs_url}/what-is-chime/parameters#regional-parameters)".format(
289+
docs_url=DOCS_URL
290+
)
291+
)
252292
population = population_input()
253293
market_share = market_share_pct_input()
254-
#known_infected = known_infected_input()
294+
# known_infected = known_infected_input()
255295
current_hospitalized = current_hospitalized_input()
256296

257-
st.sidebar.markdown("### Spread and Contact Parameters [ℹ]({docs_url}/what-is-chime/parameters)"
258-
.format(docs_url=DOCS_URL))
297+
st.sidebar.markdown(
298+
"### Spread and Contact Parameters [ℹ]({docs_url}/what-is-chime/parameters#spread-and-contact-parameters)".format(
299+
docs_url=DOCS_URL
300+
)
301+
)
259302

260-
if st.sidebar.checkbox("I know the date of the first hospitalized case in the region."):
303+
if st.sidebar.checkbox(
304+
"I know the date of the first hospitalized case in the region."
305+
):
261306
date_first_hospitalized = date_first_hospitalized_input()
262307
doubling_time = None
263308
else:
@@ -266,7 +311,11 @@ def display_sidebar(st, d: Parameters) -> Parameters:
266311

267312
relative_contact_rate = relative_contact_pct_input()
268313

269-
st.sidebar.markdown("### Severity Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
314+
st.sidebar.markdown(
315+
"### Severity Parameters [ℹ]({docs_url}/what-is-chime/parameters#severity-parameters)".format(
316+
docs_url=DOCS_URL
317+
)
318+
)
270319
hospitalized_rate = hospitalized_pct_input()
271320
icu_rate = icu_pct_input()
272321
ventilated_rate = ventilated_pct_input()
@@ -275,7 +324,11 @@ def display_sidebar(st, d: Parameters) -> Parameters:
275324
icu_days = icu_days_input()
276325
ventilated_days = ventilated_days_input()
277326

278-
st.sidebar.markdown("### Display Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
327+
st.sidebar.markdown(
328+
"### Display Parameters [ℹ]({docs_url}/what-is-chime/parameters#display-parameters)".format(
329+
docs_url=DOCS_URL
330+
)
331+
)
279332
n_days = n_days_input()
280333
max_y_axis_set = max_y_axis_set_input()
281334

@@ -289,7 +342,6 @@ def display_sidebar(st, d: Parameters) -> Parameters:
289342
icu=Disposition(icu_rate, icu_days),
290343
relative_contact_rate=relative_contact_rate,
291344
ventilated=Disposition(ventilated_rate, ventilated_days),
292-
293345
current_date=current_date,
294346
date_first_hospitalized=date_first_hospitalized,
295347
doubling_time=doubling_time,
@@ -302,11 +354,7 @@ def display_sidebar(st, d: Parameters) -> Parameters:
302354

303355

304356
def display_more_info(
305-
st,
306-
model: Model,
307-
parameters: Parameters,
308-
defaults: Parameters,
309-
notes: str = "",
357+
st, model: Model, parameters: Parameters, defaults: Parameters, notes: str = "",
310358
):
311359
"""a lot of streamlit writing to screen."""
312360
st.subheader(
@@ -398,12 +446,6 @@ def display_more_info(
398446
""".format(
399447
notes=notes
400448
)
401-
+ "- "
402-
+ "| \n".join(
403-
f"{key} = {value} "
404-
for key, value in defaults.region.__dict__.items()
405-
if key != "_s"
406-
)
407449
)
408450
return None
409451

@@ -412,7 +454,9 @@ def write_definitions(st):
412454
st.subheader("Guidance on Selecting Inputs")
413455
st.markdown(
414456
"""**This information has been moved to the
415-
[User Documentation]({docs_url}/what-is-chime/parameters#guidance-on-selecting-inputs)**""".format(docs_url=DOCS_URL)
457+
[User Documentation]({docs_url}/what-is-chime/parameters)**""".format(
458+
docs_url=DOCS_URL
459+
)
416460
)
417461

418462

@@ -421,13 +465,19 @@ def write_footer(st):
421465
st.markdown(
422466
"""* AHA Webinar, Feb 26, James Lawler, MD, an associate professor University of Nebraska Medical Center, What Healthcare Leaders Need To Know: Preparing for the COVID-19
423467
* We would like to recognize the valuable assistance in consultation and review of model assumptions by Michael Z. Levy, PhD, Associate Professor of Epidemiology, Department of Biostatistics, Epidemiology and Informatics at the Perelman School of Medicine
468+
* Finally we'd like to thank [Code for Philly](https://codeforphilly.org/) and the many members of the open-source community that [contributed](https://github.com/CodeForPhilly/chime/graphs/contributors) to this project.
424469
"""
425470
)
426471
st.markdown("© 2020, The Trustees of the University of Pennsylvania")
427472

428473

429474
def display_download_link(st, filename: str, df: pd.DataFrame):
430475
csv = dataframe_to_base64(df)
431-
st.markdown("""
476+
st.markdown(
477+
"""
432478
<a download="{filename}" href="data:file/csv;base64,{csv}">Download {filename}</a>
433-
""".format(csv=csv,filename=filename), unsafe_allow_html=True)
479+
""".format(
480+
csv=csv, filename=filename
481+
),
482+
unsafe_allow_html=True,
483+
)

0 commit comments

Comments
 (0)