---
title: "Advanced topics"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Advanced topics}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(MicroMoB)
```

## Writing new packages

Often the base way to extend **Micro-MoB** will be to write a new package that depends on it
and which implements specific new models as needed, and depends on the bits of core computation
provided by **Micro-MoB**.

The steps for writing a new package that depends on **Micro-MoB** are:

  1. Add `MicroMoB` to the `Imports:` list of your package's DESCRIPTION
  2. If you want to depend on the latest version of **Micro-MoB**, rather than CRAN,
  add `dd-harp/MicroMoB` to the `Remotes:` list of DESCRIPTION
  3. To use methods from **Micro-MoB** we recommend importing using roxygen2
  tags, for example `@importFrom MicroMoB compute_q` to import the generic 
  method `compute_q`, rather than using the `::` operator in every instance. Please
  note you only need to import the generic, and not the class-specific methods, as
  R's namespace lookup will find the right function for you.
  
To see an example of an extension package, please take a look at [MicroWNV](https://github.com/dd-harp/MicroWNV),
which adds a new host component, birds, for modeling of West Nile virus.

## Writing new models

To write a model for a component means that one must write methods that fulfill
each component's interface, and ensure that those methods return the correct
data structure. Information on the methods can be found in the function reference
under each component. In addition, a new model must have a setup function,
which takes in parameters, does argument checking, and attaches a new object with
the correct name and class attached to the model object returned from `make_MicroMoB()`.

For example, to make a new mosquito model, with class `MyModel`, one would need
to do the following:
  
  1. Write a function `setup_mosquito_MyModel` which attaches an object (usually a list)
  to the model environment with the `class` attribute assigned to `"MyModel"`.
  2. Write methods for the interface `compute_f.MyModel`, `compute_q.MyModel`,
  `compute_Z.MyModel`, and `compute_oviposit.MyModel`. Information on what each
  method is expected to compute and return can be found [here](https://dd-harp.github.io/MicroMoB/reference/index.html#adult-mosquito-component).
  3. Write a step (updating) function, `step_mosquitoes.MyModel`. One can optionally
  allow the `class` attribute of the model list to have 2 elements to allow for dispatching
  on stochastic or deterministic step updates, in which case one would additionally write
  `step_mosquitoes.MyModel_stochastic` and `step_mosquitoes.MyModel_deterministic`.
  Please look at the [source code](https://github.com/dd-harp/MicroMoB/blob/HEAD/R/mosquito_RM.R)
  of the Ross-Macdonald mosquito model to see how to do this.
  4. Write basic tests for your model, which go in `tests/testthat`. At a minimum,
  your tests should confirm that the model can be set up properly and produces
  correct results when updated over a time step.
  
## Plumber web API

**Micro-MoB** includes some limited support for configuring and running models
via web API, using the [Plumber package](https://www.rplumber.io/).

All APIs are stored in `inst/plumber/APINAME/plumber.R`, where `APINAME` is the name of the specific API.

A simple API can be started up from within R by running the following code:
```
library(MicroMoB)
plumb_api(package = "MicroMoB", name = "mosquito") %>% pr_run()
```

The web APIs use JSON files to configure the model, please see the `get_config_COMPONENT_MODEL`
function documentation for how those files should be specified. The web API functionality
is highly unstable so please be aware there may be large changes from version to version.

.
