Skip to content

Commit 9ff79d8

Browse files
authored
Merge pull request #282 from cmu-delphi/ndefries/modernize-readme
Update README
2 parents f12ab6f + d3383a4 commit 9ff79d8

File tree

4 files changed

+124
-61
lines changed

4 files changed

+124
-61
lines changed

DESCRIPTION

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
Package: forecasteval
22
Title: Forecast Evaluation Dashboard
33
Version: 7.0.0
4-
Authors@R: c(person("Kate", "Harwood", email = "[email protected]", role = "cre"),
4+
Authors@R: c(person("Kate", "Harwood", role = "aut"),
55
person("Chris", "Scott", role = "ctb"),
6-
person("Jed", "Grabman", role = "ctb"))
7-
Description: This app collects and scores COVID-19 forecasts submitted to the CDC and displays the results in an RShiny dashboard.
6+
person("Jed", "Grabman", role = "ctb")),
7+
person("Nat", "DeFries", email= "[email protected]", role = c("aut", "cre")))
8+
Description: This app collects and scores COVID-19 forecasts submitted to the CDC, and displays the results in an RShiny dashboard.
89
License: MIT License, Copyright (c) 2021 Delphi contributors
910
URL: https://github.com/cmu-delphi/forecast-eval/
1011
BugReports: https://github.com/cmu-delphi/forecast-eval/issues

Makefile

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,31 @@ S3_BUCKET=s3://forecast-eval
77

88
build: build_dashboard
99

10+
# Build a docker image suitable for running the scoring pipeline
11+
#
12+
# `docker_build/Dockerfile` is based on `ghcr.io/cmu-delphi/covidcast:latest`.
13+
# Docker will try to fetch it from the image repository, which requires
14+
# authentication. As a workaround, locally build a docker image with the same
15+
# name and set `--pull=never`.
1016
r_build:
1117
docker build --no-cache --force-rm --pull -t forecast-eval-build docker_build
1218

19+
# Download the named file from the AWS S3 bucket
1320
%.rds: dist
1421
test -f dist/$@ || curl -o dist/$@ $(S3_URL)/$@
1522

23+
# Specify all the data files we want to download
1624
pull_data: score_cards_state_deaths.rds score_cards_state_cases.rds score_cards_nation_cases.rds score_cards_nation_deaths.rds score_cards_state_hospitalizations.rds score_cards_nation_hospitalizations.rds datetime_created_utc.rds predictions_cards.rds
1725

26+
# Create the dist directory
1827
dist:
1928
mkdir $@
2029

30+
# Remove the dist directory
2131
clean:
2232
rm -rf dist
2333

34+
# Run the scoring pipeline in a docker container
2435
score_forecast: r_build dist pull_data
2536
docker run --rm \
2637
-v ${PWD}/Report:/var/forecast-eval \
@@ -29,10 +40,16 @@ score_forecast: r_build dist pull_data
2940
forecast-eval-build \
3041
Rscript create_reports.R --dir /var/dist
3142

43+
# Post scoring pipeline output files to the AWS S3 bucket
3244
deploy: score_forecast
3345
aws s3 cp dist/ $(S3_BUCKET)/ --recursive --exclude "*" --include "*rds" --acl public-read
3446

35-
# Starts a docker image with a full preconfigured R environment
47+
# Run bash in a docker container with a full preconfigured R environment
48+
#
49+
# If `--pull=always`, docker will try to fetch the
50+
# `ghcr.io/cmu-delphi/forecast-eval:latest` image from the image repository,
51+
# which requires authentication. As a workaround, locally build a docker
52+
# image with the same name and set `--pull=never`.
3653
start_dev: r_build
3754
docker run --pull=always -ti --rm \
3855
-v ${PWD}/Report:/var/forecast-eval \
@@ -41,14 +58,18 @@ start_dev: r_build
4158
-w /var/forecast-eval \
4259
ghcr.io/cmu-delphi/forecast-eval:latest bash
4360

61+
# Build a docker image for local use
4462
build_dashboard_dev: pull_data
4563
docker build --no-cache --pull -t ghcr.io/cmu-delphi/forecast-eval:latest -f devops/Dockerfile .
4664

65+
# Run a local version of the dashboard in a docker container
66+
start_dashboard: build_dashboard_dev
67+
docker run --rm -p 3838:80 ghcr.io/cmu-delphi/forecast-eval:latest
68+
69+
# Build a docker image for production use
4770
build_dashboard: pull_data
4871
docker build --no-cache=true --pull -t ghcr.io/cmu-delphi/forecast-eval:$(imageTag) -f devops/Dockerfile .
4972

73+
# Push a production docker image to the image repository
5074
deploy_dashboard: build_dashboard
5175
docker push ghcr.io/cmu-delphi/forecast-eval:$(imageTag)
52-
53-
start_dashboard: build_dashboard_dev
54-
docker run --rm -p 3838:80 ghcr.io/cmu-delphi/forecast-eval:latest

README.md

Lines changed: 94 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,132 @@
11
# Forecast Eval
22

3-
Epiforecast scoring and interactive evaluation tools.
4-
https://delphi.cmu.edu/forecast-eval/
3+
The forecast evaluation dashboard provides a robust set of tools and methods for evaluating the performance of epidemic forecasts. The project's goal is to help epidemiological researchers gain insights into the performance of their forecasts and lead to more accurate epidemic forecasting.
54

6-
Code on the `dev` branch appears in staging: https://staging.delphi.cmu.edu/forecast-eval/
7-
Username and password are included in the [meeting notes doc](https://docs.google.com/document/d/1q8sKrbjzymEDsWQ9mUomOZ255-_5W6RPGgTdFlHmpmE/edit)
5+
## Background
86

9-
## Steps to contribute
10-
1. Create a new branch off of `dev`
11-
2. Create a pull request into `dev`
7+
This app collects and scores COVID-19 forecasts submitted to the CDC. The dashboard was developed by [CMU Delphi](https://delphi.cmu.edu) in collaboration with the [Reich Lab](https://reichlab.io) and US [COVID-19 Forecast Hub](https://covid19forecasthub.org/) from UMass-Amherst, as part of the Forecast Evaluation Research Collaborative.
128

13-
Branch `main` is the production branch. Branch `dev` will be merged into main when a release is ready. See below for instructions on how to create a release.
9+
The Reich Lab created and maintains the [COVID-19 Forecast Hub](https://covid19forecasthub.org/), a collaborative effort with over 80 groups submitting forecasts to be part of the official [CDC COVID-19 ensemble forecast](https://www.cdc.gov/coronavirus/2019-ncov/covid-data/mathematical-modeling.html). All Forecase Hub forecasters that are designated "primary" or "secondary" are scored and included in the dashboard.
1410

11+
The Delphi Group created and maintains COVIDcast, a platform for [epidemiological surveillance data](https://delphi.cmu.edu/covidcast/). COVIDcast provides the ground truth data used to score forecasts against.
1512

13+
The [public version of the dashboard](https://delphi.cmu.edu/forecast-eval/) runs off of the `main` branch.
1614

17-
**Note:** the easiest way to view and develop this project locally is to use RStudio and run the RShiny app from inside the IDE
15+
The version on the `dev` branch appears on the [staging website](https://staging.delphi.cmu.edu/forecast-eval/). The username and password are included in the [meeting notes doc](https://docs.google.com/document/d/1q8sKrbjzymEDsWQ9mUomOZ255-_5W6RPGgTdFlHmpmE/edit#bookmark=id.xqskfsdd2w4q) and [on Slack](https://delphi-org.slack.com/archives/C01H63T0QE7/p1682012756484679).
1816

19-
<img width="1111" alt="Screen Shot 2021-08-30 at 10 56 59 AM" src="https://user-images.githubusercontent.com/14190352/131359925-3b460d21-b9aa-4a40-a691-cd705ab98431.png">
17+
The dashboard is backed by the forecast evaluation pipeline. The pipeline runs three times a week, on Sunday, Monday, and Tuesday, using the code on the `dev` branch. It collects and scores forecasts from the Forecast Hub, and posts the resulting files to a publicly-accessible [AWS S3 bucket](https://forecast-eval.s3.us-east-2.amazonaws.com/).
2018

21-
Alternatively, ...
19+
See the ["About" writeup](https://github.com/cmu-delphi/forecast-eval/blob/dev/app/assets/about.md) for more information about the data and processing steps.
2220

21+
## Contributing
2322

24-
## Building
23+
`main` is the production branch and shouldn't be directly modified. Pull requests should be based on and merged into `dev`. When enough changes have accumulated on `dev`, a release will be made to sync `main` with it.
2524

26-
This project requires a recent version of gnu/make and docker.
25+
This project requires a recent version of GNU `make` and docker.
2726

28-
Builds use a containerized R environment. See the `docker_build` directory for more details.
27+
The easiest way to view and develop this project locally is to run the Shiny app from RStudio:
2928

30-
To build:
29+
<img width="1111" alt="RStudio Screen Shot with Run App button circled" src="https://user-images.githubusercontent.com/14190352/131359925-3b460d21-b9aa-4a40-a691-cd705ab98431.png">
3130

32-
```bash
33-
> make build
31+
This is the same as running
32+
33+
```R
34+
shiny::runApp("<directory>")
3435
```
3536

36-
To start `bash` shell in the docker container, which would let you start a R session:
37+
in R. However, dashboard behavior can differ running locally versus running in a container (due to package versioning, packages that haven't been properly added to the container environment, etc), so the dashboard should be also tested in a container.
38+
39+
The dashboard can be run in a Docker container using `make`. See notes in the Makefile for workarounds if you don't have image repository access.
40+
41+
The pipeline can be run locally with the `Report/create_reports.R` script or in a container. See notes in the Makefile for workarounds if you don't have image repository access.
42+
43+
### Running the scoring pipeline
44+
45+
The scoring pipline use a containerized R environment. See the `docker_build` directory for more details.
46+
47+
The pipeline can be run locally with the `Report/create_reports.R` script or in a container via
3748

3849
```bash
39-
> make start_repl
50+
> make score_forecast
4051
```
4152

42-
## Starting a local shiny server
53+
See notes in the Makefile for workarounds if you don't have image repository access.
54+
55+
### Running the Shiny app
4356

44-
To start a docker image of the shiny server locally:
57+
The dashboard can be run in a Docker container using
4558

4659
```bash
4760
> make start_dashboard
4861
```
4962

50-
# Releasing
51-
```
63+
See notes in the Makefile for workarounds if you don't have image repository access.
64+
65+
## Releasing
66+
67+
`main` is the production branch and contains the code that the public dashboard uses. Code changes will accumulate on the `dev` branch and when we want to make a release, `dev` will be merged into `main` via the ["Create Release" workflow](https://github.com/cmu-delphi/forecast-eval/blob/dev/.github/workflows/create_release.yml). Version bump type (major, minor, etc) is specified manually when running the action.
68+
69+
If there's some issue with the workflow-based release process, a release can be done manually with:
70+
```bash
5271
git checkout dev
5372
git pull origin dev
54-
git checkout -b release_v1.0 origin/dev
55-
```
56-
Update version number in DESCRIPTION FILE
73+
git checkout -b release_v<major>.<minor>.<patch> origin/dev
5774
```
75+
Update version number in the [DESCRIPTION file](https://github.com/cmu-delphi/forecast-eval/blob/dev/DESCRIPTION) and in the [dashboard](https://github.com/cmu-delphi/forecast-eval/blob/f12ab6f303ba81d6cbc32d61720061474496a00f/app/global.R#L13).
76+
```bash
5877
git add .
59-
git commit -m "Version 1.0 updates"
60-
git tag -a v1.0 -m "Version 1.0"
61-
git push origin release_v1.0
62-
git push origin v1.0
78+
git commit -m "Version <major>.<minor>.<patch> updates"
79+
git tag -a v<major>.<minor>.<patch> -m "Version <major>.<minor>.<patch>"
80+
git push origin release_v<major>.<minor>.<patch>
81+
git push origin v<major>.<minor>.<patch>
6382
```
64-
Create a PR into `main`.
65-
After code is merged to `main`, perform cleanup by merging `main` into `dev` so that `dev` stays up to date.
66-
67-
# Code Structure
68-
- `workflows` contains the weekly data pipeline workflow action (`s3_upload_ec2.yml`) and the `main.yml` that runs on branch merge
69-
- `Report` contains the scoring and data upload scripts that run weekly
70-
- `dashboard` contains all the code for the RShiny dashboard
71-
- `www` contains the styling and the assets
72-
- `app.R` is the main RShiny file with the UI and server functions
73-
- `common.R` is for code shared between the app and the download feature
74-
- `export_scores.R` contains the code for the download feature
75-
- `about.md` contains the code for the "About" tab in the dasboard (other .md files contain explanations of the scores and other text info that appears in the app)
76-
- `docker_buid` contains the `Dockerfile` specifying the version of the `covidcast` docker image to use
77-
- `docker_dashboard` contains the `Dockerfile` and `shiny_server.conf` for the RShiny app
78-
- ***Note: when adding a new package dependency to the app, it must be specified in this Dockerfile***
79-
- `DESCRIPTION` is where the version number is updated for each release
80-
- `Makefile` contains all commands to build and run the dashboard and score and upload the data
83+
Create a PR into `main`. After the branch is merged to `main`, perform cleanup by merging `main` into `dev` so that `dev` stays up to date.
84+
85+
### Dependencies
86+
87+
The scoring pipeline runs in a docker container built from [`docker_build/Dockerfile`](https://github.com/cmu-delphi/forecast-eval/blob/dev/docker_build/Dockerfile), which is a straight copy of the [`covidcast-docker` image](https://github.com/cmu-delphi/covidcast-docker/blob/dev/docker/Dockerfile). The dashboard runs in a docker container built from [`devops/Dockerfile`](https://github.com/cmu-delphi/forecast-eval/blob/dev/devops/Dockerfile).
8188

82-
## Note on Scoring Script
89+
When updates are made in the `evalcast` package the behavior of the scoring script can be affected and the `covidcast` docker image must be rebuilt. The [workflow in the `covidcast-docker` repository](https://github.com/cmu-delphi/covidcast-docker/blob/dev/.github/workflows/main.yml) that does this needs to be triggered manually. Before building the new image, ensure that the changes in `evalcast` will be compatible with the scoring pipeline.
8390

84-
When updates are made in the evalcast package that affect the scoring script, the covidcast docker image must be rebuilt by kicking off the workflow here: https://github.com/cmu-delphi/covidcast-docker/actions/workflows/main.yml. Ensure that the changes in evalcast will be compatible with the dashboard and will not cause errors - when the scoring script is run on these changes the results show up automatically in prod.
91+
Currently, the scoring pipeline uses the the [`evalcast` package](https://github.com/cmu-delphi/covidcast/tree/evalcast/R-packages/evalcast) from [the`evalcast` branch](https://github.com/cmu-delphi/covidcast-docker/blob/c5adf4bd088268398d574fc0658c8ac70953f91d/docker/dependencies.R#L18) of the `covidcast` repository. However, if we need to make forecast eval-specific changes to the `evalcast` package that would conflict with other use cases, we have in the past created a dedicated forecast-eval branch of `evalcast`.
8592

86-
## Perform Manual Rollback
93+
### Performing a manual rollback
94+
95+
#### For the dashboard
8796
This should only be performed if absolutely necessary.
8897

89-
1. Change [this forecasteval line](https://github.com/cmu-delphi/delphi-ansible-web/blob/main/vars.yml#L63) to point to the desired sha256 hash rather than `latest` tag. The hash tags can be found [here](https://github.com/orgs/cmu-delphi/packages/container/package/forecast-eval).
90-
2. Create PR into `main` (tag Brian as reviewer and let him know). Changes will automatically propagate to prod.
91-
3. When creating the next normal release, the hash tag will no longer automatically update to the `latest` tag. The change back to `latest` must be performed manually during the next release.
98+
1. Change [this `forecasteval` line](https://github.com/cmu-delphi/delphi-ansible-web/blob/05d42535187a736ea997f42cb4c23706a762d9bc/vars.yml#L77) to point to the desired (most recently working) sha256 hash rather than the `latest` tag. The hashes can be found in [the Delphi ghcr.io image repository](https://github.com/orgs/cmu-delphi/packages/container/package/forecast-eval) -- these require special permissions to view. Ask Brian for permissions, ask Nat for hash info.
99+
2. Create a PR into `main`. Tag Brian as reviewer and let him know over Slack. Changes will automatically propagate to production once merged.
100+
3. When creating the next normal release, code changes will no longer automatically propagate via the `latest` image to the public dashboard; the tag in the `ansible` settings file must be manually changed back to `latest`.
101+
102+
#### For the pipeline
103+
104+
1. Change the `FROM` line in the `docker_build` Dockerfile to point to the most recently working sha256 hash rather than the `latest` tag. The hashes can be found in [the Delphi ghcr.io image repository](https://github.com/orgs/cmu-delphi/packages/container/package/covidcast) -- these require special permissions to view. Ask Brian for permissions, ask Nat for hash info.
105+
2. Create a PR into `dev`. Tag Katie or Nat as reviewer and let them know over Slack. Changes will automatically propagate to production once merged.
106+
3. When building the next `covidcast` docker image, changes will no longer automatically propagate via the `latest` `covidcast` image to the local pipeline image; the tag in `docker_build/Dockerfile` must be manually changed back to `latest`.
107+
108+
## Code Structure
109+
- `.github`
110+
- `workflows` contains GitHub Actions workflow files
111+
- `ci.yml` runs linting on branch merge. Also builds new Docker images and pushes to the image repo for the `main` and `dev` branches
112+
- `create_release.yml` triggered manually to merge `dev` into `main`. Increments app version number, and creates PR into `main` and tags reviewer (currently Katie).
113+
- `release_main.yml` runs on merge of release branch. Creates tagged release using `release-drafter.yml` and merges updated `main` back into `dev` to keep them in sync.
114+
- `s3_upload_ec2.yml` runs the weekly self-hosted data pipeline workflow action (preceded by `s3_upload.yml` that ran the pipeline on a GitHub-provided VM)
115+
- `release-drafter.yml` creates a release
116+
- `Report` contains the code for fetching, scoring, and uploading forecasts. Runs 3 times a week
117+
- `app` contains all the code for the Shiny dashboard
118+
- `R` contains supporting R functions
119+
- `data.R` defines data-fetching functions
120+
- `data_manipulation.R` defines various filter functions
121+
- `delphiLayout.R` defines dashboard main and sub- UIs
122+
- `exportScores.R` contains tools to support the score CSV download tool included in the dashboard
123+
- `assets` contains supporting Markdown text. `about.md` contains the code for the "About" tab in the dasboard; other .md files contain explanations of the scores and other text info that appears in the app.
124+
- `www` contains CSS stylesheets and the logo images
125+
- `ui.R` sets up the UI for the dashboard, and defines starting values for selectors
126+
- `server.R` defines dashboard behavior. This is where the logic for the dashboard lives.
127+
- `global.R` defines constants and helper functions
128+
- `docker_buid` contains the Docker build configuration for the scoring pipeline
129+
- `devops` contains the Docker build configuration for the Shiny dashboard
130+
- ***Note: when adding a new package dependency to the app, it must be specified in this Dockerfile***
131+
- `DESCRIPTION` summarizes package information, such as contributors, version, and dependencies
132+
- `Makefile` contains commands to build and run the dashboard, and score and upload the data

app/assets/about.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The Forecaster Evaluation Dashboard is a collaborative project, which has been m
4646

4747
**Forecaster predictions** are drawn from the [COVID-19 Forecast Hub GitHub repository](https://github.com/reichlab/covid19-forecast-hub/)
4848

49-
Data for the dashboard is pulled from these sources on Mondays and Tuesdays.
49+
Data for the dashboard is pulled from these sources on Sunday, Monday, and Tuesday each week.
5050

5151
#### **Terms**
5252

0 commit comments

Comments
 (0)