---
title: "Project Owners"
author: "Matthew Cornell"
date: "2022-04-04"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Project Owners}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  message=FALSE, 
  warning=FALSE,
  eval = nzchar(Sys.getenv("IS_DEVELOPMENT_MACHINE"))
)
```


# zoltr for Project Owners

Welcome to the zoltr vignette for project owners and forecasters. You should read this if you are interested in creating and managing your own [zoltardata.com](https://www.zoltardata.com/) projects using this package to access them via the Zoltar API. Building on the _Getting Started_ vignette, this one covers creating projects and models, and uploading forecasts.

Before starting, you should have an account on [zoltardata.com](https://www.zoltardata.com/), and an [`.Renviron`](https://stat.ethz.ch/R-manual/R-devel/library/base/html/Startup.html) file set up as described in _Getting Started_.


## Connect to the host and authenticate

<!-- run but don't show. NB: will run only if above eval=TRUE -->
```{r setup, include=FALSE}
library(httr)  # o/w devtools::check() gets `could not find function "POST"` error
```

<!-- run but don't show. NB: will run only if above eval=TRUE -->
```{r, include=FALSE}
library(zoltr)
zoltar_connection <- new_connection(host = Sys.getenv("Z_HOST"))
zoltar_authenticate(zoltar_connection, Sys.getenv("Z_USERNAME"), Sys.getenv("Z_PASSWORD"))
```

<!-- show but don't run-->
```{r, eval=FALSE, include=TRUE}
library(zoltr)
zoltar_connection <- new_connection()
zoltar_authenticate(zoltar_connection, Sys.getenv("Z_USERNAME"), Sys.getenv("Z_PASSWORD"))
```


## Create a sandbox project to play with

Let's use the `create_project()` function to make a temporary project to work with. (Note that if you're repeating this step and need to delete a previously-created project, you can either use the web UI's delete button on the project detail page or call the zoltr `delete_project()` function to do it programmatically.) `create_project()` takes a `project_config` parameter that is a `list` specifying everything Zoltar needs to create a project, including meta information like name, whether it's public, etc. In addition, it lists the units, targets, and timezeros to create. The new project's URL is returned, which you can pass to other functions. Here we use `docs-project.json`, which is the one that creates the example documentation project.

```{r}
project_config <- jsonlite::read_json("docs-project.json")  # "name": "My project"
project_url <- create_project(zoltar_connection, project_config)
the_project_info <- project_info(zoltar_connection, project_url)
```


## Add a model to the project and then upload a forecast into it

We can use the `create_model()` function to create a model in a particular project. Like `create_project()`, it takes a `list` that is the configuration to use when creating the model. There is an example at `example-model-config.json`, but here we will construct the `list` ourselves.

```{r}
model_config <- list("name" = "a model_name",
                     "abbreviation" = "an abbreviation",
                     "team_name" = "a team_name",
                     "description" = "a description",
                     "contributors" = "the contributors",
                     "license" = "other",
                     "notes" = "some notes",
                     "citation" = "a citation",
                     "methods" = "the methods",
                     "home_url" = "http://example.com/",
                     "aux_data_url" = "http://example.com/")
model_url <- create_model(zoltar_connection, project_url, model_config)
```

Now let's upload a forecast to the model using `upload_forecast()` and then see how to list all of a model's forecasts (in this case just the one).

> As we noted in _Getting Started with zoltr_, long operations like querying or uploading forecasts are queued, and require polling to determine when they are done.

`upload_forecast()` takes the `model_url` to upload to, the `timezero_date` in the project to associate the forecast with, and the `forecast_data` itself. The latter is a nested `list` of _predictions_ as documented in [docs.zoltardata.com](https://docs.zoltardata.com/), but you can learn about it by looking at the example `docs-predictions.json`. Briefly, you can see that there is a `predictions` list of `prediction elements` (the `meta` section is ignored), each of which encodes data for a particular unit and target combination. Each `prediction element` has a class that's one of four possibilities: `bin`, `named`, `point`, and `sample`. The structure of the `prediction element's` contents (the `prediction` section) is determined by the particular class. For example, a `point` just has a `value`, but a `bin` has a table of `cat` and `prob` values.

Here we will upload the `docs-predictions.json` file. Note that the passed `timezero_date` matches one of the timezeros in `docs-project.json`, the file that was used to create the project. It is an error otherwise.

```{r}
forecast_data <- jsonlite::read_json("docs-predictions.json")
job_url <- upload_forecast(zoltar_connection, model_url, "2011-10-02", forecast_data, TRUE)
busy_poll_job(zoltar_connection, job_url)
```

Hopefully you'll see some number of "QUEUED" entries followed by a "SUCCESS" one. (How long it takes will depend on how much other work Zoltar is handling.)

Get the new forecast's URL from the `Job` object and then call the `forecasts()` function to get a `data.frame` of that model's forecasts (just the one in our case).

```{r}
the_job_info <- job_info(zoltar_connection, job_url)
forecast_url <- job_info_forecast_url(zoltar_connection, the_job_info)
the_forecast_info <- forecast_info(zoltar_connection, forecast_url)
the_forecasts <- forecasts(zoltar_connection, the_forecast_info$forecast_model_url)
str(the_forecasts)
```


## Clean up by deleting the sandbox project

**NB: This will delete all the data associated with the project without warning, including models and forecasts.** 

```{r}
delete_project(zoltar_connection, project_url)
```
