Skip to content

Commit 00ec21b

Browse files
Merge pull request #76 from hubverse-org/mc/model-info/56
implements [add info about models on viz page #56] by outputting a model_urls options object field that, when present, makes model names links
2 parents 19ccf2e + d42484d commit 00ec21b

File tree

11 files changed

+188
-4
lines changed

11 files changed

+188
-4
lines changed

demo/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</div>
3030

3131
<script type="module">
32-
import App from 'https://cdn.jsdelivr.net/gh/reichlab/predtimechart@3.1.2/dist/predtimechart.bundle.js';
32+
import App from 'https://cdn.jsdelivr.net/gh/reichlab/predtimechart@3.1.3/dist/predtimechart.bundle.js';
3333
document.predtimechart = App; // for debugging
3434

3535
function replace_chars(the_string) {

src/hub_predtimechart/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.2.1"
1+
__version__ = "2.2.4"

src/hub_predtimechart/generate_options.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ def get_max_ref_date_or_first_config_ref_date(reference_dates):
7373
options['models'].sort()
7474
options['initial_checked_models'] = hub_config.initial_checked_models
7575

76+
# set `model_urls`
77+
options['model_urls'] = {}
78+
for model_id, metadata in hub_config.model_id_to_metadata.items():
79+
if model_id not in options['models']: # o/w causes a predtimechart validation error
80+
continue
81+
82+
host, owner, name = _host_owner_name(hub_config)
83+
repo_url = f"https://{host}.com/{owner}/{name}"
84+
85+
# recall that 'file_name' is a custom hub-dashboard-predtimechart field:
86+
options['model_urls'][model_id] = f"{repo_url}/blob/main/model-metadata/{metadata['file_name']}"
87+
7688
# add `disclaimer` if present
7789
if hub_config.disclaimer is not None:
7890
options['disclaimer'] = hub_config.disclaimer
@@ -81,3 +93,40 @@ def get_max_ref_date_or_first_config_ref_date(reference_dates):
8193
options['initial_xaxis_range'] = hub_config.initial_xaxis_range if hub_config.initial_xaxis_range else None
8294

8395
return options
96+
97+
98+
def _host_owner_name(hub_config):
99+
"""
100+
`ptc_options_for_hub()` helper that returns a 3-tuple for `hub_config`'s `repository` section, handling the various
101+
schemas found in the test hubs
102+
103+
cases:
104+
- 'host', 'owner', 'name' (current schema) # flu-metrocast
105+
- 'host', 'owner', 'repository' # example-complex-forecast-hub, FluSight-forecast-hub
106+
- 'host', 'url', 'name' # covid19-forecast-hub
107+
108+
:param hub_config: a HubConfigPtc
109+
:return: a 3-tuple: (host, owner, name)
110+
"""
111+
# validate schema
112+
admin_repo = hub_config.admin['repository']
113+
valid_keys = [{'host', 'owner', 'name'},
114+
{'host', 'owner', 'repository'},
115+
{'host', 'url', 'name'}]
116+
admin_repo_keys = set(admin_repo.keys())
117+
if admin_repo_keys not in valid_keys:
118+
raise RuntimeError(f"invalid admin repository keys. {admin_repo_keys=}, {valid_keys=}")
119+
120+
host, owner, name = admin_repo['host'], None, None
121+
if admin_repo_keys == {'host', 'owner', 'name'}:
122+
owner = admin_repo['owner']
123+
name = admin_repo['name']
124+
elif admin_repo_keys == {'host', 'owner', 'repository'}:
125+
owner = admin_repo['owner']
126+
name = admin_repo['repository']
127+
elif admin_repo_keys == {'host', 'url', 'name'}:
128+
owner = admin_repo['url'].split('/')[3] # ex: "https://github.com/CDCgov/covid19-forecast-hub"
129+
name = admin_repo['name']
130+
else:
131+
raise RuntimeError(f"invalid admin repository keys. {admin_repo_keys=}")
132+
return host, owner, name

src/hub_predtimechart/hub_config_ptc.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ def __init__(self, hub_path: Path, ptc_config_file: Path):
8282
list((self.hub_path / 'model-metadata').glob('*.yaml'))):
8383
with open(model_metadata_file) as fp:
8484
model_metadata = yaml.safe_load(fp)
85+
86+
# add a custom hub-dashboard-predtimechart field to the loaded metadata for functions that need the
87+
# original file name (which could be .yml OR .yaml)
88+
model_metadata['file_name'] = model_metadata_file.name
89+
8590
model_id = f"{model_metadata['team_abbr']}-{model_metadata['model_abbr']}"
8691
self.model_id_to_metadata[model_id] = model_metadata
8792

tests/expected/FluSight-forecast-hub/predtimechart-options.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,41 @@
7676
"models": [
7777
"CADPH-FluCAT_Ensemble", "CEPH-Rtrend_fluH", "CMU-TimeSeries", "CU-ensemble", "FluSight-baseline", "FluSight-ensemble", "GT-FluFNP", "ISU_NiemiLab-NLH", "JHU_CSSE-CSSE_Ensemble", "LUcompUncertLab-chimera", "LosAlamos_NAU-CModel_Flu", "MIGHTE-Nsemble", "MOBS-GLEAM_FLUH", "NIH-Flu_ARIMA", "NU_UCSD-GLEAM_AI_FLUH", "PSI-PROF", "SGroup-RandomForest", "SigSci-CREG", "SigSci-TSENS", "Stevens-GBR", "UGA_flucast-Copycat", "UGA_flucast-INFLAenza", "UGuelph-CompositeCurve", "UGuelphensemble-GRYPHON", "UM-DeepOutbreak", "UMass-flusion", "UMass-trends_ensemble", "UNC_IDD-InfluPaint", "UVAFluX-Ensemble", "VTSanghani-Ensemble", "cfa-flumech", "cfarenewal-cfaepimlight", "fjordhest-ensemble"
7878
],
79+
"model_urls": {
80+
"CADPH-FluCAT_Ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/CADPH-FluCAT_Ensemble.yml",
81+
"CEPH-Rtrend_fluH": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/CEPH-Rtrend_fluH.yaml",
82+
"CMU-TimeSeries": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/CMU-TimeSeries.yml",
83+
"CU-ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/CU-ensemble.yml",
84+
"FluSight-baseline": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/FluSight-baseline.yml",
85+
"FluSight-ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/FluSight-ensemble.yml",
86+
"GT-FluFNP": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/GT-FluFNP.yml",
87+
"ISU_NiemiLab-NLH": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/ISU_NiemiLab-NLH.yml",
88+
"JHU_CSSE-CSSE_Ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/JHU_CSSE-CSSE_Ensemble.yml",
89+
"LUcompUncertLab-chimera": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/LUcompUncertLab-chimera.yml",
90+
"LosAlamos_NAU-CModel_Flu": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/LosAlamos_NAU-CModel_Flu.yml",
91+
"MIGHTE-Nsemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/MIGHTE-Nsemble.yml",
92+
"MOBS-GLEAM_FLUH": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/MOBS-GLEAM_FLUH.yml",
93+
"NIH-Flu_ARIMA": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/NIH-Flu_ARIMA.yaml",
94+
"NU_UCSD-GLEAM_AI_FLUH": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/NU_UCSD-GLEAM_AI_FLUH.yml",
95+
"PSI-PROF": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/PSI-PROF.yml",
96+
"SGroup-RandomForest": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/SGroup-RandomForest.yml",
97+
"SigSci-CREG": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/SigSci-CREG.yml",
98+
"SigSci-TSENS": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/SigSci-TSENS.yml",
99+
"Stevens-GBR": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/Stevens-GBR.yml",
100+
"UGA_flucast-Copycat": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UGA_flucast-Copycat.yml",
101+
"UGA_flucast-INFLAenza": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UGA_flucast-INFLAenza.yml",
102+
"UGuelph-CompositeCurve": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UGuelph-CompositeCurve.yml",
103+
"UGuelphensemble-GRYPHON": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UGuelphensemble-GRYPHON.yml",
104+
"UM-DeepOutbreak": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UM-DeepOutbreak.yml",
105+
"UMass-flusion": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UMass-flusion.yml",
106+
"UMass-trends_ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UMass-trends_ensemble.yml",
107+
"UNC_IDD-InfluPaint": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UNC_IDD-InfluPaint.yml",
108+
"UVAFluX-Ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/UVAFluX-Ensemble.yml",
109+
"VTSanghani-Ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/VTSanghani-Ensemble.yml",
110+
"cfa-flumech": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/cfa-flumech.yml",
111+
"cfarenewal-cfaepimlight": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/cfarenewal-cfaepimlight.yml",
112+
"fjordhest-ensemble": "https://github.com/cdcepi/FluSight-forecast-hub/blob/main/model-metadata/fjordhest-ensemble.yml"
113+
},
79114
"initial_checked_models": ["FluSight-baseline", "FluSight-ensemble"],
80115
"disclaimer": "Most forecasts have failed to reliably predict rapid changes in the trends of reported cases and hospitalizations. Due to this limitation, they should not be relied upon for decisions about the possibility or timing of rapid changes in trends.",
81116
"initial_xaxis_range": null

tests/expected/covid19-forecast-hub/predtimechart-options.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@
7676
},
7777
"initial_as_of": "2024-11-09",
7878
"current_date": "2024-11-09",
79-
"models": [],
79+
"model_urls": {
80+
"UMass-ar6_pooled": "https://github.com/CDCgov/covid19-forecast-hub/blob/main/model-metadata/UMass-ar6_pooled.yml"
81+
},
82+
"models": ["UMass-ar6_pooled"],
8083
"initial_checked_models": [],
8184
"initial_xaxis_range": null
8285
}

tests/expected/example-complex-forecast-hub/predtimechart-options.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
"initial_as_of": "2022-12-17",
7676
"current_date": "2022-12-17",
7777
"models": ["Flusight-baseline", "MOBS-GLEAM_FLUH", "PSI-DICE"],
78+
"model_urls": {
79+
"Flusight-baseline": "https://github.com/Infectious-Disease-Modeling-Hubs/example-complex-forecast-hub/blob/main/model-metadata/Flusight-baseline.yml",
80+
"MOBS-GLEAM_FLUH": "https://github.com/Infectious-Disease-Modeling-Hubs/example-complex-forecast-hub/blob/main/model-metadata/MOBS-GLEAM_FLUH.yml",
81+
"PSI-DICE": "https://github.com/Infectious-Disease-Modeling-Hubs/example-complex-forecast-hub/blob/main/model-metadata/PSI-DICE.yml"
82+
},
7883
"initial_checked_models": ["Flusight-baseline"],
7984
"disclaimer": "Most forecasts have failed to reliably predict rapid changes in the trends of reported cases and hospitalizations. Due to this limitation, they should not be relied upon for decisions about the possibility or timing of rapid changes in trends.",
8085
"initial_xaxis_range": null

tests/expected/flu-metrocast/predtimechart-options.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
"initial_xaxis_range": null,
1515
"intervals": ["0%", "50%", "95%"],
1616
"models": ["epiENGAGE-Copycat", "epiENGAGE-GBQR", "epiENGAGE-INFLAenza", "epiforecasts-dyngam"],
17+
"model_urls": {
18+
"epiENGAGE-Copycat": "https://github.com/reichlab/flu-metrocast/blob/main/model-metadata/epiENGAGE-Copycat.yml",
19+
"epiENGAGE-INFLAenza": "https://github.com/reichlab/flu-metrocast/blob/main/model-metadata/epiENGAGE-INFLAenza.yml",
20+
"epiENGAGE-GBQR": "https://github.com/reichlab/flu-metrocast/blob/main/model-metadata/epiENGAGE-GBQR.yml",
21+
"epiforecasts-dyngam": "https://github.com/reichlab/flu-metrocast/blob/main/model-metadata/epiforecasts-dyngam.yml"
22+
},
1723
"target_variables": [
1824
{
1925
"plot_text": "ED visits due to ILI",

tests/hub_predtimechart/test_generate_options.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
22
from pathlib import Path
33

4-
from hub_predtimechart.generate_options import ptc_options_for_hub
4+
import pytest
5+
6+
from hub_predtimechart.generate_options import ptc_options_for_hub, _host_owner_name
57
from hub_predtimechart.hub_config_ptc import HubConfigPtc
68

79

@@ -64,3 +66,30 @@ def test_generate_options_initial_xaxis_range_covid19_forecast_hub():
6466
exp_options['initial_xaxis_range'] = hub_config.initial_xaxis_range
6567
act_options = ptc_options_for_hub(hub_config)
6668
assert act_options == exp_options
69+
70+
71+
#
72+
# model_urls tests
73+
#
74+
75+
@pytest.mark.parametrize("hub_dir,exp_host_owner_name", [
76+
('tests/hubs/covid19-forecast-hub',
77+
('github', 'CDCgov', 'covid19-forecast-hub')),
78+
('tests/hubs/example-complex-forecast-hub',
79+
('github', 'Infectious-Disease-Modeling-Hubs', 'example-complex-forecast-hub')),
80+
('tests/hubs/flu-metrocast',
81+
('github', 'reichlab', 'flu-metrocast')),
82+
('tests/hubs/FluSight-forecast-hub',
83+
('github', 'cdcepi', 'FluSight-forecast-hub'))])
84+
def test__host_owner_name(hub_dir, exp_host_owner_name):
85+
hub_dir = Path(hub_dir)
86+
hub_config = HubConfigPtc(hub_dir, hub_dir / 'hub-config/predtimechart-config.yml')
87+
assert _host_owner_name(hub_config) == exp_host_owner_name
88+
89+
90+
def test__host_owner_name_invalid_keys():
91+
hub_dir = Path('tests/hubs/flu-metrocast')
92+
hub_config = HubConfigPtc(hub_dir, hub_dir / 'hub-config/predtimechart-config.yml')
93+
hub_config.admin['repository'] = {'bad-repo': 0}
94+
with pytest.raises(RuntimeError, match="invalid admin repository keys"):
95+
_host_owner_name(hub_config)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
team_name: "CovidHub-hub-models"
2+
team_abbr: "CovidHub"
3+
model_name: "CovidHub baseline model"
4+
model_abbr: "baseline"
5+
model_version: "1.0"
6+
model_contributors:
7+
[
8+
{
9+
"name": "Covid Hub",
10+
"affiliation": "Centers for Disease Control and Prevention (CDC)",
11+
"email": "covidhub@cdc.gov"
12+
}
13+
]
14+
website_url: "https://github.com/CDCgov/covid19-forecast-hub"
15+
license: "CC-BY-4.0"
16+
designated_model: false
17+
methods: "Flat baseline model. The most observed value from the target dataset is the median forward projection. Prospective uncertainty is based on the preceding timeseries."
18+
data_inputs: "Epiweekly incident COVID-19 hospital admissions from the NHSN Weekly Hospital Respiratory Data dataset,
19+
https://data.cdc.gov/Public-Health-Surveillance/Weekly-Hospital-Respiratory-Data-HRD-Metrics-by-Ju/mpgq-jmmr/about_data
20+
"
21+
methods_long: "Flat baseline model. The most observed value from the target dataset is the median forward projection. Prospective uncertainty is based on the preceding timeseries. This is the standard baseline model used by the COVID-19 Forecast Hub and the FluSight Forecast Hub. It is implemented using the `cdc_baseline_forecaster()` function from the `epipredict` R package. https://cmu-delphi.github.io/epipredict/reference/cdc_baseline_forecaster.html"
22+
ensemble_of_models: false
23+
ensemble_of_hub_models: false

0 commit comments

Comments
 (0)