Skip to content
Merged

Dev #195

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ea3e4ab
feat(impact): hide python/r buttons (#192)
amyheather Mar 2, 2026
334282b
feat(index/impact): add renal capacity model and quote from lucy
amyheather Mar 5, 2026
c244b02
chore(vv): spelling mistake
amyheather Mar 11, 2026
de36ab5
feat(vv): mentiont TRACE
amyheather Mar 11, 2026
ae2d824
feat(version): add mcq (#145)
amyheather Mar 12, 2026
c58fa7e
feat(environment): add mcq (#145)
amyheather Mar 12, 2026
bd36bb3
feat(package): add mcq (#145)
amyheather Mar 12, 2026
d99e2ed
feat(code_structure): add mcq (#145)
amyheather Mar 12, 2026
84e0324
feat(input_modelling): add mcq (#145)
amyheather Mar 12, 2026
6d2668f
feat(parameters_file): add mcq (#145)
amyheather Mar 12, 2026
9c2cad7
chore(parameters_script): add activity heading
amyheather Mar 12, 2026
313f981
feat(param_validation): add mcq (#145)
amyheather Mar 12, 2026
be65ec3
feat(patients): add mcq (#145)
amyheather Mar 12, 2026
1530d13
chore(distributions): add quiz/activity headings
amyheather Mar 12, 2026
37bd031
feat(process): add mcq (#145)
amyheather Mar 12, 2026
0a1d22f
feat(full_run): add mcq (#145)
amyheather Mar 12, 2026
764e405
feat(scenarios): add mcq (#145)
amyheather Mar 12, 2026
229f38e
feat(tables_figures): add mcq (#145)
amyheather Mar 12, 2026
0bfe519
feat(logs): add mcq (#145)
amyheather Mar 12, 2026
90567e6
feat(length_warmup): add mcq (#145)
amyheather Mar 12, 2026
3672f3b
feat(n_reps): add mcq (#145)
amyheather Mar 12, 2026
9958bfe
feat(outputs): add mcq (#145)
amyheather Mar 13, 2026
343eeb1
feat(parallel): add mcq (#145)
amyheather Mar 13, 2026
4d6bfbe
feat(replications): add mcq (#145)
amyheather Mar 13, 2026
73509cf
feat(warmup): add mcq (#145)
amyheather Mar 13, 2026
d943254
chore(archive+citation): add quiz + activity titles
amyheather Mar 13, 2026
4c6da01
feat(changelog/docstrings/documentation): add mcq (#145)
amyheather Mar 13, 2026
a3fa5fc
feat(githubactions/linting): add mcq (#145)
amyheather Mar 13, 2026
a4e0880
feat(qa): add mcq (#145) and activity
amyheather Mar 13, 2026
cb76d99
feat(vv/math/test): add mcq (#145)
amyheather Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ format:
}
</style>

This open book is a self-paced training resource that teaches you how to design, implement, and share discrete-event simulation (DES) models in Python and R as part of a reproducible analytical pipeline. It combines a step-by-step guide with complete example repositories that you can adapt for your own projects.
This open book is a self-paced training resource that teaches you how to design, implement, and share discrete-event simulation (DES) models in Python and R as part of a reproducible analytical pipeline. It combines a **step-by-step guide** with **complete example repositories** that you can adapt for your own projects.

The material is designed for researchers, research software engineers, analysts, and postgraduate students in health and operations research who want to build transparent, trustworthy simulation models. Educators and trainers can adopt the book as a complete syllabus for a short course or reuse individual chapters as standalone teaching units (for example, sessions on RAP, testing, packaging, or sharing models), and should cite the resource when they do so in line with the provided citation below. The accompanying code is released under an MIT licence, and the text is available under a CC BY-SA 4.0 licence, allowing reuse and adaptation with appropriate attribution.
The material is designed for analysts, researchers, and students in health and operations research who want to build transparent, trustworthy simulation models. To get the most from this resource, you should be comfortable with basic programming in either Python or R and have some familiarity with probability and basic statistics. **No prior DES experience is required**: short introductions to DES, reproducible analytical pipelines, and free and open source software are provided in the "Intros" section and linked below.

> If you use the DES RAP book in your teaching, research, or training, we'd love to hear about it. Please [get in touch](/pages/guide/further_info/feedback.qmd) to share how you've used the material, suggest improvements, or point us to example models or case studies that others might find helpful.
::: {.pale-blue}

"The DES RAP Book was a valuable resource in our transition to open-source DES modelling. It provided us with a step-by-step structure to follow and guidance on best practice for writing code, tests and documentation for our package. Our model is being using in the Midlands, and beyond, for understanding future demand and capacity within Kidney Replacement Therapy." - **Lucy Morgan, Analytics Manager at The Strategy Unit**.

To get the most from this resource, you should be comfortable with basic programming in either Python or R and have some familiarity with probability and basic statistics. No prior DES experience is required: short introductions to DES, reproducible analytical pipelines, and free and open source software are provided in the "Intros" section and linked below.
:::

An engaged learner can complete the core step-by-step guide in around 10-15 hours, including time to run the code examples and attempt the exercises. You can work through the material in order as a structured course, or dip into specific sections (such as input modelling, verification and validation, or sharing and archiving) as needed.

Expand All @@ -48,6 +50,10 @@ After working through this resource, you will be able to:
* Improve **style, documentation, and automation** with linting, docstrings, and GitHub Actions.
* **Collaborate and share** your work effectively, including code review, licensing, citation, changelogs, and archiving.

> If you use the DES RAP book in your teaching, research, or training, we'd love to hear about it. Please [get in touch](/pages/guide/further_info/feedback.qmd) to share how you've used the material, suggest improvements, or point us to example models or case studies that others might find helpful.
>
> Educators and trainers can adopt the book as a complete syllabus for a short course or reuse individual chapters as standalone teaching units (for example, sessions on RAP, testing, packaging, or sharing models), and should cite the resource when they do so in line with the provided citation below. The accompanying code is released under an MIT licence, and the text is available under a CC BY-SA 4.0 licence, allowing reuse and adaptation with appropriate attribution.

<br>

```{=html}
Expand Down
70 changes: 70 additions & 0 deletions pages/guide/experiments/full_run.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,76 @@ Both have a file `run_rmarkdown.sh` (like the example above) which is used to ru

## Test yourself

<div class="h3-tight"></div>

### Quiz

```{r}
#| echo: false
library(webexercises) # nolint: library_call_linter
```

::: {.callout-note}

## Why is being able to run the entire analysis from a single command considered important in a RAP workflow?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"Because it reduces manual steps, avoids inconsistencies between runs, ",
"and makes the full workflow repeatable by you and others."
),
"Because it guarantees that the model will always run faster.",
"Because it allows you to skip documenting intermediate steps."
)))
```

:::

:::: {.python-content}

::: {.callout-note}

## What is the main role of `run_notebooks.sh`?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"To run all Jupyter notebooks in a random order.",
"To run all Jupyter notebooks in parallel.",
answer = "To run all Jupyter notebooks in sequence."
)))
```

:::

::::

:::: {.r-content}

::: {.callout-note}

## What is the main role of `run_rmarkdown.sh`?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"To run all `.Rmd` files in a random order.",
"To run all `.Rmd` files in parallel.",
answer = "To run all `.Rmd` files in sequence."
)))
```

:::

::::

### Activity

Try writing a bash scripts that runs some of your analysis files.

You can print a message before running each one to check whether each command succeeded.
Expand Down
50 changes: 50 additions & 0 deletions pages/guide/experiments/scenarios.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,56 @@ However, there are two key things to keep in mind:

## Test yourself

<div class="h3-tight"></div>

### Quiz

```{r}
#| echo: false
library(webexercises) # nolint: library_call_linter
```

::: {.callout-note}

## Why should code be shared for every scenario, not just the base case?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"Because published descriptions are often ambiguous, and without code ",
"for each scenario it can be hard or impossible to reproduce the results."
),
"Because reviewers only care about the scenario code and not the base case.",
"Because scenario code runs faster than base‑case code."
)))
```

:::

::: {.callout-note}

## Conceptually, how does scenario analysis differ from sensitivity analysis?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"Scenario analysis studies predefined, plausible configurations (often ",
"changing several parameters), while sensitivity analysis varies one or ",
"a small set of parameters to see how input uncertainty affects outputs."
),
"Scenario analysis only changes one parameter; sensitivity changes many.",
"Scenario analysis is exploratory; sensitivity is only about performance."
)))
```

:::

### Activity

Try running your own scenario and sensitivity analyses.

You could build your own simple loop to test different values - just make sure you use a fresh set of parameters for each run.
Expand Down
33 changes: 33 additions & 0 deletions pages/guide/experiments/tables_figures.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,39 @@ In this figure, the blue line shows the result (e.g., mean wait time) as we incr

## Test yourself

<div class="h3-tight"></div>

### Quiz

```{r}
#| echo: false
library(webexercises) # nolint: library_call_linter
```

::: {.callout-note}

## What is the key message of this page regarding tables and figures in DES studies?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"That visual outputs are optional and not part of reproducibility.",
answer = paste0(
"That tables and figures should be generated by code, and that code must ",
"be shared so others can recreate the reported results."
),
paste0(
"That only raw simulation logs need to be archived; plots can be ",
"drawn by hand."
)
)))
```

:::

### Activity

Create at least one table and figure from your simulation results.

If you don't have any to hand, feel free to download ours:
Expand Down
90 changes: 90 additions & 0 deletions pages/guide/inputs/input_modelling.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,96 @@ A common challenge in healthcare modelling is having insufficient data or no sui

## Test yourself

<div class="h3-tight"></div>

### Quiz

```{r}
#| echo: false
library(webexercises) # nolint: library_call_linter
```

::: {.callout-note}

## How is randomness typically introduced into a DES model?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"By choosing a single fixed time for each event and reusing it.",
answer = paste0(
"By randomly sampling event times (e.g. arrivals, service durations) ",
"from probability distributions."
),
"By manually typing in new event times before each simulation run."
)))
```

:::

::: {.callout-note}

## In the arrivals example, what is the usual relationship between the Poisson and exponential distributions?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
paste0(
"They are unrelated; Poisson is only used for costs and exponential only ",
"for ages."
),
answer = paste0(
"If arrivals follow a Poisson process with a constant rate, the ",
"inter‑arrival times follow an exponential distribution with the same rate."
),
"They both always produce symmetric bell‑shaped distributions."
)))
```

:::

::: {.callout-note}

## What is the main purpose of plotting a histogram of inter‑arrival or service times in this workflow?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"To check whether the data file was saved in CSV or Excel format.",
answer = paste0(
"To inspect the shape and support of the data (e.g. right‑skewed, ",
"non‑negative) and identify plausible candidate distributions."
),
"To verify that the mean is exactly equal to the median."
)))
```

:::

::: {.callout-note}

## When data are insufficient (e.g. sparse histograms or only summary statistics), which strategy is recommended in the chapter?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"Use simpler standard distributions (e.g. exponential or triangular), ",
"draw on expert judgement, and explore sensitivity to plausible ranges."
),
"Always switch to the most complex multi‑parameter distribution available.",
"Abandon modelling and instead assume all times are fixed at the mean."
)))
```

:::

### Activity

If you haven't already followed along, **now's the time to put everything from this page into practice!**

**Task:**
Expand Down
72 changes: 72 additions & 0 deletions pages/guide/inputs/parameters_file.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,78 @@ The nurse visit model doesn't import parameters from a file. It instead stores t

## Test yourself

<div class="h3-tight"></div>

### Quiz

```{r}
#| echo: false
library(webexercises) # nolint: library_call_linter
```

::: {.callout-note}

## Why might you choose to store simulation parameters in an external file rather than directly in your script?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"Because it avoids hard‑coded values, makes it easier to share different ",
"parameter sets (e.g. real vs synthetic), and lets non‑programmers edit ",
"parameters without touching the code."
),
paste0(
"Because parameters in a script cannot be version controlled, whereas ",
"files like CSV or JSON can."
)
)))
```

:::

::: {.callout-note}

## When is CSV usually preferred over JSON for parameter files?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
answer = paste0(
"When parameters fit naturally into a flat table of rows and columns ",
"following tidy data principles."
),
paste0(
"When parameters contain deeply nested structures and many attributes ",
"per item that must mirror nested code objects."
)
)))
```

:::

::: {.callout-note}

## What is the main purpose of a data dictionary for parameter files in this workflow?

```{r}
#| output: asis
#| echo: false
cat(longmcq(c(
"To store raw simulation outputs alongside parameters.",
answer = paste0(
"To document each parameter’s meaning, units, and any codes or ",
"abbreviations so others can correctly interpret and modify them."
)
)))
```

:::

### Activity

If you haven't already, now's the time to practice working with **external parameter files**.

**Task:**
Expand Down
Loading
Loading