US-RSE Conference 2025
7 October 2025
Infectious disease modeling has scaled rapidly…
“Comparing the accuracy of forecasting applications is difficult because forecasting methods, forecast outcomes, and reported validation metrics varied widely.”
Modeling hubs coordinate collaborative forecasting:
Provide centralised location for effort coordination
Define data standards and modeling targets
Improve transparency and comparability
Aggregate forecasts enabling ensembles
Facilitate timely public health decision-making
“Collaborative Hubs: Making the Most of Predictive Epidemic Modeling”, American Journal of Public Health Reich, et al. 2022
➡️ Need for generalisation, modularity, and configurability
An open-source software ecosystem to power modeling hubs:
Modeling hubs are built around a shared data standard:
mean
, quantiles
)✅ Enables comparability, validation, and streamlined data access
Hub administrators configure hubs using structured JSON config files:
admin.json
: hub-level metadata.task.json
: modeling task specification:
mean
, median
, quantiles
, cdf
, pmf
, samples
.The hubverse package ecosystem is organized by role. Each tool is designed to support a particular group of users in the hub workflow.
Hub roles
Tools & packages
hubAdmin
: config creation + validation 🛠️
hubValidations
: submission checks (structure, schema, content) 🔬 🛠️
hubData
(R) / hubdata
(Python) : access multi-file model output via Arrow 🛠️ 🔬 📊 🏛️
hubEvals
: compute evaluation metrics 🛠️ 📊 🏛️
hubEnsembles
: build weighted/unweighted ensembles 🛠 📊 🏛️
hubVis
: visualise model outputs 🛠️ 📊 🏛️
hub-dashboard-template
Dashboards are crucial for communicating model outputs to a broader audience, including policy makers, public health officials, and even the general public so we put effort into developing a plug and play dashboard template.
Our template is built in Quarto, so it’s easy to customise and extend.
What makes it powerful is that it’s fully static, no backend needed.
JSON data are generated from hub data by GitHub workflows, and the JavaScript frontend fetches this data to create a dynamic, interactive experience for the user.
This design makes it fast, easy to host (e.g. on GitHub Pages), and simple to replicate.
Hub admins can launch new dashboards quickly by copying and configuring the hub-dashboard-template
.
hubData
and Python 📦 hubdata
.As a bonus, we’ve developed infrastructure to mirror validated hub data to AWS S3 buckets, making it publicly accessible as Arrow datasets.
This enables downstream users, especially analysts, to query the data without needing to clone the full repository.
They can access it via the R or python equivalent package hubdata
.
This cloud mirroring service is something the hubverse currently provides.
To enable it for a new hub:
The hub administration needs to contact us so we can provision a bucket.
They need to add a bit of lightweight configuration to their admin.json
file to activate it and install the relevant action workflow.
We automate everything we can:
All hubverse actions stored in the hubverse-actions
repo and can be installed with hubCI::use_hub_github_action()
Automation is a cornerstone of the hubverse.
We use GitHub Actions to handle hub operations.
This includes:
Validating model output submissions and target data at the pull request level,
Validating hub configuration files,
Synchronising validated model output to cloud storage,
Generating dashboard data + computing model evaluation metrics.
All our workflows are stored in the hubverse-actions
repo.
They’re easy to adopt, hub administrators can install them using the hubCI::use_hub_github_action()
helper.
This approach ensures consistency, and relatively low overhead for administrators.
https://hubverse.io/community/hubs.html
Now that we’ve seen the infrastructure, let’s look at adoption.
This page on our site showcases hubs using the hubverse stack, from long-standing hubs like the Flusight Forecast Hub to newer efforts like the COVID-19 Variant Nowcast or West Nile Virus hubs.
Each hub entry includes structured metadata: like a hub description, whether data are publicly available, and links to the relevant GitHub repos, dashboards and cloud storage.
This kind of shared metadata and visibility wouldn’t be possible without the consistency enforced by the hubverse framework.
It also serves as a community resource, a growing catalog of open modeling hubs that are easy to discover and learn from.
Now let’s take a look at some this infrastrcuture in action by focusing on the CDC Flusight Hub
https://github.com/cdcepi/FluSight-forecast-hub
The CDC FluSight Hub is a flagship example of the hubverse stack in action.
It’s used by the US CDC to monitor influenza severity through weekly model outputs, submitted by over 40 teams, spanning 70 different models.
The hub is fully managed using the hubverse software, workflows and S3 cloud mirroring since the 2023/24 season.
If we peek into the repository structure, you’ll see the key directories that define a hub:
hub-config
: holds the JSON config files.model-output
: where teams submit their model output filestarget-data
: stores the observed data used to evaluate forecasts, such as reported influenza-like illness rates.Model outputs committed by teams to versioned directories > one directory per model > one file per modeling round.
This slide breaks down a single model output file and it’s location in the CDC FluSight hub.
On the top, we see the file lives under the model-output/<model_id>
directory.
Files are named using a round ID and model ID, e.g., 2023-10-14-CADPH-FluCAT_Ensemble.csv
. Each file contains all predictions for that round by that model.
Inside the file:
- The Task ID columns, like target
, horizon
, and location
store information about individual predictions.
- The Output Type columns describe the prediction format (e.g., quantiles).
- And the value
column holds the actual predicted values.
This file structure (task ids, output type, values) is fully standardised across all hubs.
hubValidations
Model outputs submitted through PRs and validated through GitHub Actions
Every model output is submitted via GitHub pull requests, and each submission is validated using the hubValidations
package.
On the left, we see the latest submissions from different teams for a specific forecast round.
On the right is an example validation log from GitHub Actions. Here, hubValidations
checks that the submission:
Passes file level checks e.g.:
Follows the required file structure,
Is named and placed correctly,
And passes content-level checks:
valid task ID and output type value combinations,
required tasks submitted,
valid output types - output type specific checks (e.g quantile crossing)
Custom checks also supported
These automated checks catch errors early and keep hub data clean and trustworthy.
hubData
Connect to Arrow dataset of forecast submissions
hub_connection
9 columns
reference_date: date32[day]
target: string
horizon: int32
target_end_date: date32[day]
location: string
output_type: string
output_type_id: string
value: double
model_id: string
Query and collect data
# Filter for one model and forecast date using dplyr
library(dplyr)
hub_con |>
filter(
model_id == "CADPH-FluCAT_Ensemble",
target_end_date == "2023-10-28"
) |>
collect_hub()
# A tibble: 92 × 9
model_id reference_date target horizon target_end_date location output_type
* <chr> <date> <chr> <int> <date> <chr> <chr>
1 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
2 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
3 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
4 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
5 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
6 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
7 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
8 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
9 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
10 CADPH-Flu… 2023-10-14 wk in… 2 2023-10-28 06 quantile
# ℹ 82 more rows
# ℹ 2 more variables: output_type_id <chr>, value <dbl>
See more in Accessing data vignette.
Python analogue hub-data
also available.
We’ve designed the hubverse format so that, while teams look after their own submission files, model outputs can be accessed as a whole as a queryable Arrow dataset.
Here we show how to connect to the FluSight hub’s S3 mirror using hubData
.
We can then filter and collect data using standard dplyr
verbs.
This makes it easy for analysts, modelers, or public health teams to extract relevant subsets of data they need.
The same functionality is available in Python via the hub-data
package.
hubEnsembles
Combine models using simple or weighted rules
forecast_df <- hub_con |>
filter(
model_id %in%
c(
"CADPH-FluCAT_Ensemble",
"CEPH-Rtrend_fluH",
"CFA_Pyrenew-Pyrenew_HE_Flu"
),
output_type == "quantile"
) |>
collect_hub()
hubEnsembles::simple_ensemble(
forecast_df,
agg_fun = median,
model_id = "simple-ensemble-median"
)
# A tibble: 282,716 × 9
model_id reference_date target horizon target_end_date location output_type
* <chr> <date> <chr> <int> <date> <chr> <chr>
1 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
2 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
3 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
4 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
5 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
6 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
7 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
8 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
9 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
10 simple-en… 2023-10-14 wk in… -1 2023-10-07 01 quantile
# ℹ 282,706 more rows
# ℹ 2 more variables: output_type_id <chr>, value <dbl>
Ensembling is central to the hub idea as it helps improve prediction robustness by combining multiple model predictions into a single output.
hubEnsembles
provides a simple interface to build various types of ensembles from hubverse formatted data.
This example shows how to pull data from a few different models and apply a simple ensemble method.
This is the FluSight dashboard and specifically the forecast page.
It enables users to explore predictions interactively: you can choose outcomes, forecast dates and compare multiple models visually.
Crucially, the dashboard also shows the target (observed) data alongside forecasts, which helps contextualise model behaviour and monitor real-world performance.
Clicking on any model name in the left-hand panel opens that model’s metadata page , which includes details about the model, contributors, assumptions etc.
Evaluates forecasts against target (observed) data.
This is the evaluation tab of the FluSight dashboard, which helps users compare model performance using standard metrics.
It’s powered by the hubEvals
package, which computes evaluation scores by comparing model outputs to the target data, also stored in the hub.
The evaluation supports scoring rules such as:
WIS (Weighted Interval Score)
MAE (Mean Absolute Error)
Coverage of 50% and 95% prediction intervals
Evaluations are performed during the dashboard build and are summarised into an interactive table, allowing for quick comparison across models.
To wrap up:
We hope this inspires other communities to adopt or adapt similar workflows.
Tip
Interested in getting involved in the community? Check out our Getting Involved page!
Thanks so much! I’ll leave you with some useful links, including information on how to get involved in the community like out newsletter, monthly community meetings or bi-weekly dev meetings.
I’m happy to chat about anything hubverse!