|
1 | 1 | # Forecast Eval
|
2 | 2 |
|
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. |
5 | 4 |
|
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 |
8 | 6 |
|
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. |
12 | 8 |
|
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. |
14 | 10 |
|
| 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. |
15 | 12 |
|
| 13 | +The [public version of the dashboard](https://delphi.cmu.edu/forecast-eval/) runs off of the `main` branch. |
16 | 14 |
|
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). |
18 | 16 |
|
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/). |
20 | 18 |
|
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. |
22 | 20 |
|
| 21 | +## Contributing |
23 | 22 |
|
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. |
25 | 24 |
|
26 |
| -This project requires a recent version of gnu/make and docker. |
| 25 | +This project requires a recent version of GNU `make` and docker. |
27 | 26 |
|
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: |
29 | 28 |
|
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"> |
31 | 30 |
|
32 |
| -```bash |
33 |
| -> make build |
| 31 | +This is the same as running |
| 32 | + |
| 33 | +```R |
| 34 | +shiny::runApp("<directory>") |
34 | 35 | ```
|
35 | 36 |
|
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 |
37 | 48 |
|
38 | 49 | ```bash
|
39 |
| -> make start_repl |
| 50 | +> make score_forecast |
40 | 51 | ```
|
41 | 52 |
|
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 |
43 | 56 |
|
44 |
| -To start a docker image of the shiny server locally: |
| 57 | +The dashboard can be run in a Docker container using |
45 | 58 |
|
46 | 59 | ```bash
|
47 | 60 | > make start_dashboard
|
48 | 61 | ```
|
49 | 62 |
|
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 |
52 | 71 | git checkout dev
|
53 | 72 | 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 |
57 | 74 | ```
|
| 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 |
58 | 77 | 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> |
63 | 82 | ```
|
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). |
81 | 88 |
|
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. |
83 | 90 |
|
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`. |
85 | 92 |
|
86 |
| -## Perform Manual Rollback |
| 93 | +### Performing a manual rollback |
| 94 | + |
| 95 | +#### For the dashboard |
87 | 96 | This should only be performed if absolutely necessary.
|
88 | 97 |
|
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 |
0 commit comments