---
title: "Hospital Capacity Planning Using Discrete Event Simulation: Introduction" 
author:
  - name: Thomas Bartz-Beielstein
    affiliation: IDEA, TH Köln
    address:
    - Steinmülleralle 1
    - 51643 Gummersbach, Germany
    email:  thomas.bartz-beielstein@th-koeln.de
  - name: Frederik Rehbach
    affiliation: IDEA, TH Köln
    address:
    - Steinmülleralle 1
    - 51643 Gummersbach, Germany
    email:  frederik.rehbach@th-koeln.de
  - name: Olaf Mersmann
    affiliation: IDEA, TH Köln
    address:
    - Steinmülleralle 1
    - 51643 Gummersbach, Germany
    email:  olaf.mersmann@th-koeln.de
  - name: Eva Bartz
    affiliation: Bartz und Bartz GmbH
    address:
    - Goebenstr. 10
    - 51643 Gummersbach, Germany
    email:  eva.bartz@bartzundbartz.de
abstract: >
 Resource planning for hospitals under special consideration of the COVID-19 pandemic.
preamble: |
  % Any extra LaTeX you need in the preamble
  % header-includes:
always_allow_html: true  
date: "`r Sys.Date()`"
output:
    rmarkdown::html_vignette:
    fig_caption: yes 
    includes:
          in_header: babsim.hospital.sty
    pdf_document:
vignette: >
  %\VignetteIndexEntry{Hospital Capacity Planning Using Discrete Event Simulation: Introduction}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---   


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

## Introduction

* Resource and capacity planning for hospitals.
* Ideas used in this packages are based on the paper: 
A novel modeling technique to predict resource-requirements 
in critical care:  a case study (Lawton, McCooe) see (Lawt19a).
* `babsim.hospital` implements a discrete-event simulation, which 
uses the `simmer` package. 

## Data and Copyright Notes

The simulator requires two types of data:

1. **simulation data** that describes the spread of the pandemic over time and
1. **field data** that contains daily resource usage data.

Included in the package are tools to generate synthetic data, e.g., you can generate simulation and field data to run the simulations.
This procedure is described in the paper ["Optimization of High-dimensional Simulation Models Using Synthetic Data"](https://arxiv.org/abs/2009.02781).
   
To demonstrate the usage of real-world data, we have included sample datasets from Germany.

### Simulation Data

We have included a data sample from the German [Robert Koch-Institute](https://www.rki.de) (RKI).
Please take the following copyright notice under advisement, if you plan to use the RKI data included in the package:

  > Die Daten sind die „Fallzahlen in Deutschland“ des Robert Koch-Institut (RKI) und stehen unter der Open Data Datenlizenz Deutschland Version 2.0 zur Verfügung.
  > Quellenvermerk: Robert Koch-Institut (RKI), dl-de/by-2-0   
  > Haftungsausschluss: „Die Inhalte, die über die Internetseiten des Robert Koch-Instituts zur Verfügung gestellt werden, dienen ausschließlich der allgemeinen Information der Öffentlichkeit, vorrangig der Fachöffentlichkeit“.
  
Taken from [here](https://npgeo-corona-npgeo-de.hub.arcgis.com/datasets/dd4580c810204019a7b8eb3e0b329dd6_0).

### Field Data

We have included a data sample from the German [DIVI Register](https://www.intensivregister.de/). 
Please take the following copyright notice under advisement.
The DIVI data are not open data. 
The following statement can be found on the DIVI web page: 
> Eine weitere wissenschaftliche Nutzung der Daten ist nur mit Zustimmung der DIVI gestattet.
Therefore, only an example data set, that reflects the structure of the original data from the DIVI register, is included in the `babsim.hospital` package as `icudata`.

## Packages

```{r, cleanStart}

suppressPackageStartupMessages({
library("SPOT")
library("babsim.hospital")
library("simmer")
library("simmer.plot")
})
```

We need at least version 2.1.8 of `SPOT`.

```{r loadSPOT, eval = TRUE}
packageVersion("SPOT")
```

# Data used by `babsim.hospital`

We combine data from two different sources:

1. `simData`: simulation data, i.e., input data for the simulation. 
   Here, we will use data from the Robert Koch-Institute in Germany.
2. `fieldData`: real data, i.e., data from the DIVI-Intensivregister.
   The field data is used to validate the output of the simulation.
 
The `babsim.hospital` simulator models resources usage in hospitals, e.g., number of ICU beds ($y$), as a function of the number of infected individuals ($x$).
In addition to the number of infections, information about age and gender will be used as simulation input.

We will take a closer look at the required input data in the following sections.

# Simulation Data: RKI Data

## Get Data From the RKI Server

`babsim.hospital` provides a function to update the (daily) RKI data.

```{r, eval = FALSE}
updateRkidataFile("https://www.arcgis.com/sharing/rest/content/items/f10774f1c63e40168479a1feb6c7ca74/data")
```

Users are expected to adapt this function to their local situation.

The downloaded data will be available as `rkidata`. 

Due to data size limits on CRAN, the full dataset is not included in the `babsim.hospital`package.
Instead, we provide a subset of the Robert Koch-Institut dataset with 10,000 observations in the package.

```{r, getAndShowRkiData}
str(babsim.hospital::rkidata)
```
Copyright notice for the data:

> Die Daten sind die „Fallzahlen in Deutschland“ des Robert Koch-Institut (RKI) und stehen unter der Open Data Datenlizenz Deutschland Version 2.0 zur Verfügung. 
> Quellenvermerk: Robert Koch-Institut (RKI), dl-de/by-2-0   
> Haftungsausschluss: „Die Inhalte, die über die Internetseiten des Robert Koch-Instituts zur Verfügung gestellt werden, dienen ausschließlich der allgemeinen Information der Öffentlichkeit, vorrangig der Fachöffentlichkeit“.

The `rkidata` can be visualized as follows (here `region = 0` is Germany, `region = 5` 
is North Rhine-Westphalia, `region = 5374` Oberbergischer Kreis, etc.):

```{r, visuRki, fig.width=8, out.width="100%"}
p <- ggVisualizeRki(data=babsim.hospital::rkidata, region = 5374)
print(p)
```

## Preprocessed RKI Data 

Not all the information from the original `rkidata` data set is required by the `babsim.hospital` simulator.
The function `getRkiData()` extracts the subset of the raw `rkidata` required by our simulation, optimization, and analysis:

```{r, preprocessRki}
rki <- getRkiData(rki = rkidata)
str(rki)
```

As illustrated by the output from above, we use the following data:
1. `Altersgruppe`: age group (intervals, categories), represented as character string
1. `Geschlecht`: gender 
1. `Day`: day of the infection
1. `IdBundesland`: federal state
1. `IdLandkreis`: county
1. `time`: number of days (`0` = start data). It will be used as `arrivalTimes` for the `simmer` simulations.
1. `Age`: integer representation of `Altersgruppe`


# Field Data (Real ICU Beds)

## Get Data From the DIVI Server

Similar to the `rkidata`, which is available online and can be downloaded from the RKI Server, the field data is also available online.
It can be downloaded from the DIVI Server as follows, where `YYYY-MM-DD` should be replaced by the current date, e.g, `2020-10-26`.

```{r, getDiviData, eval = FALSE}
updateIcudataFile("https://www.divi.de/joomlatools-files/docman-files/divi-intensivregister-tagesreports-csv/DIVI-Intensivregister_YYYY-MM-DD_12-15.csv") 
```

*Note*: The data structures on the DIVI server may change, so it might be necessary to modify the following procedure.
Please check the hints on the DIVI web page. Contrary to the `updateRkidataFile()` function, which downloads the complete historical dataset, the `updateIcudataFile()` function only downloads data for a single date.

The downloaded data will be available in `babsim.hospital` as `icudata`. 

**Important**: The DIVI dataset is *not* open data.
The following statement can be found on the DIVI web page: 

> Eine weitere wissenschaftliche Nutzung der Daten ist nur mit Zustimmung der DIVI gestattet.

Therefore, only an example data set, that reflects the structure of the original data from the DIVI register, is included in the `babsim.hospital` package as `icudata`:

```{r, getRkiData}
str(babsim.hospital::icudata)
```

The `ìcudata` can be visualized as follows (`region = 0` is Germany, `region = 5` is North Rhine-Westphalia, 
`region = 5374` is the Oberbergischer Kreis, etc.)

```{r, viszIcu}
p <- ggVisualizeIcu(region = 5374)
```

```{r, viszIcu1, fig.width=8, out.width="100%"}
print(p[[1]])
```

```{r, viszIcu2, fig.width=8, out.width="100%"}
print(p[[2]])
```

## Additional Data

### GV-ISys: Gemeindeverzeichnis-Informationssystem (GV-ISys) of the German Federal Statistics Office

* Gemeindeverzeichnis-Informationssystem (GV-ISys) of the German Federal Statistics Office, see [https://www.destatis.de/DE/Themen/Laender-Regionen/Regionales/Gemeindeverzeichnis/](https://www.destatis.de/DE/Themen/Laender-Regionen/Regionales/Gemeindeverzeichnis/)

## Preprocessing DIVI/ICU Data

*Note*: ICU beds without ventilation can be calculated as `faelle_covid_aktuell - faelle_covid_aktuell_beatmet`.

The function `getIcuBeds()` converts the 9 dimensional DIVI ICU dataset `icudata` (bundesland,gemeindeschluessel,..., daten_stand) into a data.frame with three columns:

1. `bed` 
1. `intensiveBedVentilation`
1. `Day` 

```{r}
fieldData <- getIcuBeds(babsim.hospital::icudata)
str(fieldData)
```
The field data based on `icudata` uses two bed categories:
1. `intensiveBed`: ICU bed without ventilation
2. `intensiveBedVentilation`: ICU bed with ventilation

# Performing Simulations

To run a simulation, the setting must be configured (seed, number of repeats, sequential or parallel evaluation, variable names, dates, etc.)

```{r, selectConfig}
region = 5374 # Germany, 5315 is Cologne, 5 is NRW
seed = 123
simrepeats = 2
parallel = FALSE
percCores = 0.8
resourceNames =  c("intensiveBed", "intensiveBedVentilation")
resourceEval = c("intensiveBed", "intensiveBedVentilation")
```


We can specify the field data based on `icudata`  (DIVI) for the simulation as follows:

```{r, selectIcuData}
FieldStartDate = "2020-09-01"
# Felddaten (Realdaten, ICU):
icudata <- getRegionIcu(data = icudata, region = region)
fieldData <- getIcuBeds(icudata)
fieldData <- fieldData[which(fieldData$Day >= as.Date(FieldStartDate)), ]
rownames(fieldData) <- NULL
icu = TRUE
icuWeights = c(1,1)
```

Next, simulation data (RKI data) can be selected.
The simulation data in our example, depend on the field data:

```{r, selectRkiData}
SimStartDate = "2020-08-01"
rkidata <- getRegionRki(data = rkidata, region = region)
simData <- getRkiData(rkidata)
simData <- simData[which(simData$Day >= as.Date(SimStartDate)), ]
## Auch mit fieldData cutten damit es immer das gleiche Datum ist
simData <- simData[as.Date(simData$Day) <= max(as.Date(fieldData$Day)),]
## time must start at 1
simData$time <- simData$time - min(simData$time)
rownames(simData) <- NULL
```

Finally, we combine all field and simulation data into a single `list()` called `data`:

```{r, combineSelectedData}
data <- list(simData = simData, fieldData = fieldData)
```

Configuration information is stored in the `conf` list, i.e., `conf` refers to the simulation configuration, e.g., sequential or parallel evaluation, number of cores, resource names, log level, etc.

```{r, getSimConf}
conf <- babsimToolsConf()
conf <- getConfFromData(conf = conf,
                        simData = data$simData,
                        fieldData = data$fieldData)
conf$parallel = parallel
conf$simRepeats = simrepeats
conf$ICU = icu
conf$ResourceNames = resourceNames
conf$ResourceEval = resourceEval
conf$percCores = percCores
conf$logLevel = 0
conf$w2 = icuWeights
set.seed(conf$seed)
```

## Simulation Model Parameters 

The core of the `babsim.hospital` simulations is based on the [`simmer`](https://r-simmer.org/) package. 

It uses simulation parameters, e.g., arrival times, durations, and transition probabilities. 
There are currently 29 parameters (shown below) that are stored in the list `para`.

```{r, getSimParameter}
para <- babsimHospitalPara()
str(para)
```

# Run simulation

* The `babsim.hospital` simulator requires the specification of
  1. `arrivalTimes`
  2. configuration list `conf`
  3. parameter list `para` 
for the simulation.

* Arrival times were not discussed yet.
* `babsim.hospital` provides the function `getRkiRisk()` that generates arrivals
with associated risks.
* `Risk` is based on age (`Altersgruppe`) and gender (`Geschlect`):

```{r, getRiskAndArrival}
rkiWithRisk <- getRkiRisk(data$simData, para)
head(rkiWithRisk)
```

* To perform simulations, only two parameters are required:
  1. `time`: arrival time 
  2. `Risk`: risk (based on age and gender)
* A data.frame with these two parameters is passed to the main simulation 
function `babsimHospital`.
* Output from the simulation is stored in the variable `envs`.

```{r, runSimmer, echo = FALSE}
arrivalTimes <- data.frame(time = rkiWithRisk$time,
                             risk = rkiWithRisk$Risk)
envs <- babsimHospital(arrivalTimes = arrivalTimes,
                         conf = conf,
                         para = para)
```
## Visualize Output

### Simmer Plots

* First, we illustrate how to generate plots using the `simmer.plot` package.

* In the following graph, the individual lines are all separate replications. 
The smoothing performed is a cumulative average. 

* Besides `intensiveBed` and  `intensiveBedVentilation`, `babsim.hospital` 
also provides information about the number of non-ICU beds. The non-ICU beds are
labeled as `bed`.

* Summarizing, `babsim.hospital` generates output for three bed categories:
 1. `bed`
 2. `intensiveBed`
 3. `intensiveBedVentilation`

* To plot resource usage for three resources side-by-side, we
can proceed as follows:

```{r, plotSimmerThreeResources, eval = FALSE}
resources <- get_mon_resources(envs)
resources$capacity <- resources$capacity/1e5
plot(resources, metric = "usage", c("bed", "intensiveBed", "intensiveBedVentilation"), items = "server")
```
* Each resource can be plotted separately.

1. The following command generates a plot of non icu beds:

```{r, plotBeds3, eval = FALSE}
plot(resources, metric = "usage", "bed", items = "server", steps = TRUE)
```

2. The following command generates a plot of icu beds without ventilation:

```{r, plotICU3, eval = FALSE}
plot(resources, metric = "usage", "intensiveBed", items = "server", steps = TRUE)
```

3. The following command generates a plot of icu beds with ventilation:

```{r, plotVent3, eval = FALSE}
plot(resources, metric = "usage", "intensiveBedVentilation", items = "server", steps = TRUE)
```

## Evaluate Simulation Results

* `babsim.hospital` provides functions for evaluating the quality of the
simulation results.
* Simulation results depend on the transition probabilities and durations, i.e.,
a vector of more than 30 variables.
* These vectors represent *parameter settings*.
* `babsim.hospital` provides a *default* parameter set, that is based on 
knowledge from domain experts (doctors, members of COVID-19 crises teams, 
mathematicians, and many more).
* We can calculate the error (RMSE) of the default parameter setting, which was used 
in this simulation, as follows:

```{r, getErrsResults}
fieldEvents <- getRealBeds(data = data$fieldData,
                        resource = conf$ResourceNames)
res <- getDailyMaxResults(envs = envs,  fieldEvents = fieldEvents, conf=conf)
resDefault <- getError(res, conf=conf)
```

The error is `r resDefault`.


* Here, we illustrate how `babsim` plots can be generated.
* Important note: 
Because we do not use the full data, simulation results are completely wrong!
* The following figures are included to demonstrate the working principles of the
visualization procedures.

```{r, plotSimAndResults, fig.caption="Output. Warning: incomplete data were used",  eval = FALSE}
p <- plotDailyMaxResults(res)
plot(p)
```

* Using `ggplot` and `plotly`can be used to generate interactive plots.

```{r, interactiveGGplotly, eval = FALSE}
plotly::ggplotly(p) 
```


## Optimization 

* As discussed above, `babsim.hospital` provides a default parameter set, which 
can be used for simulations.
* The function `babsimHospitalPara()` provides a convenient way to access the
default parameter set:
```{r,eval=FALSE}
para <- babsimHospitalPara()
```


* `babsim` provides an interface to optimize the parameter values of 
the simulation model. 
* The following code is just a quick demo.
* Warning: To run the following code, the complete `rkidata` and `icudata` data sets must be 
available. Please download the data from RKI and DIVI or provide your own
simulation and field data!
* Note: results are stored in the directory `results`. 

```{r, optimSpot, eval=FALSE}
library("babsim.hospital")
library("SPOT")
library("simmer")
dir.create("results")
res202010262 <- runoptDirect(
  expName = paste0("test_", format(Sys.time(), "%Y_%b.%d_%H.%M_V"), utils::packageVersion("babsim.hospital"),"R"),
  region = 5374,
  rkiwerte = babsim.hospital::rkidata,
  icuwerte = babsim.hospital::icudata,
  TrainSimStartDate = Sys.Date() - 10*7, 
  TrainFieldStartDate = Sys.Date() - 6*7, 
  TestSimStartDate = Sys.Date() - 8*7, 
  TestFieldStartDate = Sys.Date() - 4*7, 
  Overlap = 0,
  seed = 101170,
  direct = TRUE,
  repeats = 1,
  funEvals = 40,
  funEvalsFactor = 0,
  size = 35,
  simrepeats = 1,
  parallel = TRUE,
  percCores = 0.9,
  icu = TRUE,
  icuWeights = c(1,1),
  verbosity=11,
  testRepeats = 1,
  tryOnTestSet = TRUE
)
```

* Results from the `runopt()` runs are stored in the `paras.rda` file.
* `babsim.hospital` provides results from the following regions (towns and 
 counties in Germany):
   * `getParaSet(5374)`: Oberbergischer Kreis
   * `getParaSet(5315)`: City of Cologne
   * `getParaSet(5)`: North-Rhine Westphalia
   * `getParaSet(0)`: Germany


## Use Optimized Parameters

* Results (parameter settings) of the short `runopt()` optimization from above can be used 
as follows:

```{r, eval=FALSE}
para <- getBestParameter(getParaSet(5315))
res <- modelResultHospital(para=para, 
                           conf=conf,
                           data = data)
resOpt <- getError(res, conf=conf)
```

* Optimization improves the error
* This improvement can also be visualized.

```{r, eval = FALSE}
p <- plotDailyMaxResults(res)
print(p)
```

* `ggplot` and `plotly`can be used to generate interactive plots.

```{r, showGgplotly, eval = FALSE}
plotly::ggplotly(p)
```


## Smooth Parameters

* Smooth a parameter set using another parameter set
* Calculate the average of two parameter sets to smooth out any local anomalies.
*  Mostly useful to smooth out a local (say OBK) parameter set using a global one (say NRW).
* Technically this function calculates `(1-weight) * para + weight * other ` ensuring that the names etc. of  `para` are preserved.
* Parameters:
   * para Parameter set to smooth
   * other Other parameters to average in
   * weight Weight of other parameters
* return Weighted parameter set

```{r smooth, eval = FALSE}
para <- smoothParameter(getBestParameter(getParaSet(5374)), 
                getBestParameter(getParaSet(5)) )
```


## Visualize and Analyze Parameter Settings

* `babsim.hospital` includes tools to analyze parameter settings.
* You might recall that parameter settings consist of
   1. transition probabilities, e.g., the probability that an infected
   individual has to go to the hospital. 
   2. durations, e.g., the time span until an infected individual goes to the
   hospital (in days).
* The following plot illustrates the transition probabilities.
* States are as follows:
   1. `infec`: infected
   2. `out`: transfer out, no hospital required
   3. `hosp`: hospital
   4. `normal`: normal station, no ICU
   5. `intens`: ICU (without ventilation)
   6. `vent`: ICU ventilated
   7. `intafter`: intensive aftercare (from ICU with ventilation, on ICU)
   8. `aftercare`: aftercare (from ICU,  on normal station)
   9. `death`: patient dies
  10. `healthy`: recovered
 


* The transition matrix, that stores the probabilities, is shown below:

```{r, showMatrixP}
para <- babsimHospitalPara()
getMatrixP(para = para)
```


```{r, visParaP, eval = FALSE}
visualizeGraph(para=para, option = "P")
```



* Similar to the probabilities, durations can be visualized:

```{r, showDurationMatrix, eval = FALSE}
visualizeGraph(para = para, option = "D")
```

* The corresponding matrix is shown below:

```{r, showMatrixDurations}
getMatrixD(para = para)
```


# Extend RKI Data

* `babsim.hospital`can be used to simulate scenarios, i.e., possible 
developments of the pandemic.
* To simulate these scenarios, arrival events must be generated.
* The function `extendRki()` adds new arrival events. 
* To generate new arrivals, three parameters must be specified:
   1. `data`: an already existing data set, i.e., the history
   2. `EndDate`: last day of the simulated data (in the future)
   3. `R0`: base reproduction values (R0) at the first day of the scenario and at the 
   last day of the scenario. A linear interpolation between these two values will 
   be used, e.g., if `R0 = c(1,2)` and ten eleven days are specified, the 
   following R0 values will be used: (1.0, 1.1, 1.2, 1.3, ..., 1.9,2.0).


```{r, extendRkiDemo, eval = TRUE}
data <- getRkiData(babsim.hospital::rkidata)
n <-  as.integer( max(data$Day)-min(data$Day) )
StartDay <- min(data$Day) + round(n*0.9)  
data <- data[which(data$Day >=  StartDay), ]
EndDate <- max(data$Day) + 2
dataExt <- extendRki(data = data, 
                     EndDate = EndDate,
                     R0 = c(0.1, 0.2))
```

* To illustrate the `extendRki()` data extension procedure, a short 
example is shown below:

```{r, eval = FALSE}
visualizeRkiEvents(data = data, region=5374)
```


* The following plot shows the result of the data extension:
 

```{r, eval = FALSE}
visualizeRkiEvents(data = dataExt, region = 5374)
```

# Sensitivity Analysis

## Quick Analysis

* OBK Data

```{r, quickAnalysis1, eval = FALSE}
library("rpart")
library("rpart.plot")
library("babsim.hospital")
library("SPOT")
param <- getParaSet(5374)
n <- dim(param)[2] - 1
y <- param[,1]
x <- param[,2:dim(param)[2]]
fitTree <- buildTreeModel(x=x,
                 y=y,
                 control = list(xnames = paste0('x', 1:n)))
rpart.plot(fitTree$fit)
```
```{r, eval = FALSE}
getParameterNameList(c(24, 25, 3, 10))
```


```{r, quickAnalysisKoeln, eval = FALSE}
library("rpart")
library("rpart.plot")
param <- getParaSet(5315)
n <- dim(param)[2] - 1
y <- param[,1]
x <- param[,2:dim(param)[2]]
fitTree <- buildTreeModel(x=x,
                 y=y,
                 control = list(xnames = paste0('x', 1:n)))
rpart.plot(fitTree$fit)
```


## Sensitivity Analysis

* `babsim.hopital` uses the `R` package SPOT (sequential parameter optimization 
toolbox) to improve parameter settings.
* `SPOT` implements a set of tools for model-based optimization and tuning of 
algorithms (surrogate models, optimizers, DOE).
* `SPOT` can be used for sensitivity analysis, which is in important under 
many aspects, especially:
   * understanding the most important factors (parameters) that influence model
   behavior. For example, it is of great importance for simulation practitioners and
   doctors to discover relevant durations and probabilities. 
   * detecting interactions between parameters, e.g., do durations influence 
   each other?
* Before visualizations are presented, we show the underlying parameter setting.

```{r, eval = FALSE}
res <- res202010262[[2]][[1]]
xBest <- res$xbest
n <- length(xBest)
print(xBest)
```
* The corresponding parameter names are:

```{r, eval =FALSE}
n <- n-1
t(getParameterNameList(1:n))
```

* The fitness landscape can be visualized using the function `plotModel`.
* Note, `plotModel` requires two parameter values.
* In the following example, 
`GammaShapeParameter` (x16) and `AmntDaysNormalToHealthy` (x2) were chosen.
* The plot can be interpreted as follows:
   * The model error is reduced, if patients stay longer on the normal station 
   before they leave the hospital (healthy).
   * The effect of the parameter `GammaShapeParameter` is smaller than the effect of 
   the parameter `AmntDaysNormalToHealthy`.


```{r, eval = FALSE}
SPOT::plotModel(res$modelFit, which = c(16,2) ,xlab = c("Modellierungsparameter (Varianz), GammaShapeParameter", "x2: Normalstation zu Genesen (AmntDaysNormalToHealthy)"))
```

A regression-based parameter screening can be performed to discover relevant (and irrelevant) model parameters:

```{r, eval = FALSE}
fitLm <- SPOT::buildLM(x=res$x,
                 y=res$y,
                 control = list(useStep=TRUE))
summary(fitLm$fit)
```

* Parameter $x_7$  should be considered important.

```{r, eval = FALSE}
getParameterName(7)
```

* This finding is supported by a simple regression tree analysis:

```{r, eval = FALSE}
library("rpart")
library("rpart.plot")
fitTree <- buildTreeModel(x=res$x,
                 y=res$y,
                 control = list(xnames = paste0('x', 1:n)))
rpart.plot(fitTree$fit)
```


## Estimate Risks

An exponential model with two parameters was chosen to model `risk` as a function of `age` and `gender`: 
$r(x) = a\exp(b\,x)$.

```{r, estimateAB}
age <- c(2,10,25,47,70,90)
risk <- c(0.01,0.07,0.15,0.65,3,12.64)
fit <- nls(risk ~ a * exp( b * age), 
           start = list(a = 1, b = 0),
           control= nls.control(maxiter = 50, tol = 1e-05, minFactor = 1/1024,
                                printEval = FALSE, warnOnly = FALSE))
print(coef(fit))
```

```{r, plotEstimatedAB, eval = FALSE}
{plot(age,2*risk)
    # female:
    lines(age, 1* predict(fit, list(x = age)))
    # male:
    lines(age, 2* predict(fit, list(x = age) ), col ="red")}
```

# The RKI Data Classes

## Raw data:  rkidatafull

The full, unmodified RKI data set, can be  downloaded from the RKI web page.
Once downloaded, it is accessible as `rkidataFull`. 

**Note**: `rkidataFull` is a large data set, which is not included in the CRAN version.

```{r, dimRkidataFull, eval=FALSE}
dim(babsim.hospital::rkidataFull)
```

## Class rkidata

The `rkidata` data set is a subset of the `rkidataFull` data set.
* It contains data from `2020-09-01` until today.
* The `rkidata` subset is used, because the COVID-19 pandemic behavior changed 
over time. The period from September is sometimes referred to as the second wave.
* Note: the full `rkidata` set is not included in the CRAN version.
* The CRAN version includes a smaller data set:

```{r, dimRkidata, eval=TRUE}
str(babsim.hospital::rkidata)
```

## Class simData

To convert data from the `rkidata` format, the function `getRkiData()` can be used.
The function generates data that can be used as `simmer` arrival events, one arrival is listed in each row.
Each arrival includes the following information:

* age group (classification used by RKI)
* gender 
* day, the infection was registered (in German: `Meldedatum`)
* region information (id of the state)
* region information (id of the county)
* age as a numerical value (1:1 correspondence with age group)

**Note**: As mentioned earlier, the CRAN package does not include the full RKI dataset. 
Only a sample is included as `rkidata`
To perform real simulations, the user has to download the full RKI data set as described above.

```{r, getSimdataRki}
rkiSimData <- getRkiData(babsim.hospital::rkidata)
str(rkiSimData)
```

### Adding risk information to simData class data

The function `getRkiRisk(simData, para)` adds a numerical risk value, which is based on `Age` and `Geschlecht` to  `simData` data.
The parameters `RiskFactorA`, `RiskFactorB`, and `RiskMale` from `para` are used for the risk calculation.

```{r, addRisktoRki}
para <- babsimHospitalPara()
print(para$RiskFactorA)
print(para$RiskFactorB)
print(para$RiskMale)
rkiRiskSimData <- getRkiRisk(rkiSimData, para)
str(rkiRiskSimData)
```

## The Class arrivaldata 

* The `babsim.hospital` simulator function `babsimHospital()`, which 
implements a `simmer` class, processes arrival events.
* An element of the `arrivaldata` class can be generrated as follows:

```{r, generateArrivalEvent}
arrivalTimes <- data.frame(time = rkiRiskSimData$time, risk = rkiRiskSimData$Risk)
str(arrivalTimes)
```


# Optimization Details

## Bounds

```{r, eval = FALSE}
getParameterDataFrame()
```


```{r getBounds}
bounds <- getBounds()
print(bounds)
```


# References
\bibliography{../bab-bibfiles/bartzAll.bib}


# Appendix

## Run Scripts

The following R scripts demonstrate, how optimizations runs for the Oberbergische Kreis (OBK), Koeln, 
and NRW can be started.

**Note**: runs take several minutes/hours.

### Oberbergischer Kreis (OBK)

```{r, eval=FALSE}
library("babsim.hospital")
library("SPOT")
library("simmer")

runoptDirect(
  expName = paste0("obk_", format(Sys.time(), "%Y_%b.%d_%H.%M_V"), utils::packageVersion("babsim.hospital"),"R"),
  region = 5374,
  rkiwerte = babsim.hospital::rkidata,
  icuwerte = babsim.hospital::icudata,
  TrainSimStartDate = Sys.Date() - 10*7, # 11*7, #10*7, # "2020-09-03",
  TrainFieldStartDate = Sys.Date() - 6*7, # 8*7, # "2020-10-03",
  #TestSimStartDate = Sys.Date() - 8*7, # 6*7 , #"2020-09-23",
  #TestFieldStartDate = Sys.Date() - 4*7, #"2020-10-23",
  Overlap = 0,
  seed = 101170,
  direct = TRUE,
  repeats = 1000,
  funEvals = 1000,
  funEvalsFactor = 0,
  size = 250,
  simrepeats = 10,
  parallel = TRUE,
  percCores = 0.9,
  icu = TRUE,
  icuWeights = c(1,1),
  verbosity=11,
  testRepeats = 10,
  tryOnTestSet = FALSE
)
```

### Koeln (Cologne)

```{r, eval=FALSE}
library("babsim.hospital")
library("SPOT")
library("simmer")

runoptDirect(
  expName = paste0("koeln_", format(Sys.time(), "%Y_%b.%d_%H.%M_V"), utils::packageVersion("babsim.hospital"),"R"),
  region = 5315,
  rkiwerte = babsim.hospital::rkidata,
  icuwerte = babsim.hospital::icudata,
  TrainSimStartDate = Sys.Date() - 10*7, # 10*7, # "2020-09-03",
  TrainFieldStartDate = Sys.Date() - 6*7, # "2020-10-03",
  # TestSimStartDate = Sys.Date() - 8*7, # 6*7 , #"2020-09-23",
  # TestFieldStartDate = Sys.Date() - 4*7, #"2020-10-23",
  Overlap = 0,
  seed = 101170,
  direct = TRUE,
  repeats = 1000,
  funEvals = 1000,
  funEvalsFactor = 0,
  size = 250,
  simrepeats = 10,
  parallel = TRUE,
  percCores = 0.9,
  icu = TRUE,
  icuWeights = c(1,1),
  verbosity=11,
  testRepeats = 10,
  tryOnTestSet = FALSE
)
```

### NRW

```{r, eval = FALSE}
library("babsim.hospital")
library("SPOT")
library("simmer")

runoptDirect(
  expName = paste0("nrw_", format(Sys.time(), "%Y_%b.%d_%H.%M_V"), utils::packageVersion("babsim.hospital"),"R"),
  region = 5374,
  rkiwerte = babsim.hospital::rkidata,
  icuwerte = babsim.hospital::icudata,
  TrainSimStartDate = Sys.Date() - 10*7, #10*7, # "2020-09-03",
  TrainFieldStartDate = Sys.Date() - 6*7, # "2020-10-03",
  # TestSimStartDate = Sys.Date() - 8*7, #6*7 , #"2020-09-23",
  # TestFieldStartDate = Sys.Date() - 4*7, #"2020-10-23",
  Overlap = 0,
  seed = 101170,
  direct = TRUE,
  repeats = 1000,
  funEvals = 1000,
  funEvalsFactor = 0,
  size = 250,
  simrepeats = 10,
  parallel = TRUE,
  percCores = 0.9,
  icu = TRUE,
  icuWeights = c(1,1),
  verbosity=11,
  testRepeats = 10,
  tryOnTestSet = FALSE
)
```
