Skip to content

Commit ff82091

Browse files
authored
Merge pull request #95 from pythonhealthdatascience/dev
Dev
2 parents e610774 + 76d6474 commit ff82091

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+4228
-16993
lines changed

README.md

Lines changed: 44 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@
1010
[![Coverage](https://github.com/pythonhealthdatascience/pydesrap_mms/raw/main/images/coverage-badge.svg)](https://github.com/pythonhealthdatascience/pydesrap_mms/actions/workflows/tests.yaml)
1111
</div>
1212

13+
<br>
14+
15+
This repository is an example accompanying the [**DES RAP Book**](https://github.com/pythonhealthdatascience/des_rap_book) — an open educational resource on reproducible discrete-event simulation (DES) in Python and R. The book demonstrates best practices for building, validating, and sharing DES models within a reproducible analytical pipeline (RAP). The `pydesrap_mms` model illustrates how these principles can be applied to a simple queueing model.
16+
17+
<br>
18+
1319
## Repository overview
1420

1521
This repository provides a reproducible analytical pipeline (RAP) for a simple **M/M/s queuing model** implemented in Python using SimPy. The model simulates patients arriving, waiting to see a nurse, being served, and leaving. All code is structured as a local Python package.
1622

23+
![](images/nurse_des.drawio.png)
24+
1725
An M/M/s queueing model is a classic mathematical model for systems where:
1826

1927
* Arrivals happen at random, following a Poisson process - and the time between arrivals follows an exponential distribution (the first "M", which stands for "Markovian" as it is memoryless - arrivals are independent).
@@ -24,7 +32,9 @@ This type of model is widely used for studying waiting lines in healthcare, call
2432

2533
<br>
2634

27-
## Installation
35+
## Usage and reproduction instructions
36+
37+
<details><summary><b>Installation</b></summary>
2838

2939
Clone the repository:
3040

@@ -42,9 +52,11 @@ conda activate
4252

4353
There is also a `requirements.txt` file which can be used to set up the environment with `virtualenv`, but this won't fetch a specific version of Python - so please note the version listed in `environment.yaml`.
4454

55+
</details>
56+
4557
<br>
4658

47-
## How to run
59+
<details><summary><b>How to run</b></summary>
4860

4961
The simulation code is in the `simulation/` folder as a local package. Example analyses and model runs are in `notebooks/`.
5062

@@ -87,48 +99,12 @@ To run one notebook from the command line (with the same settings - clearing the
8799
bash run_notebooks.sh notebooks/notebook_name.ipynb
88100
```
89101

90-
<br>
91-
92-
## How does the model work?
93-
94-
This section describes the purposes of each class in the simulation.
95-
96-
**Model Run Process:**
97-
98-
1. **Set Parameters:** Create a `Param` instance with desired model parameters.
99-
2. **Initialise Model:** Instantiate `Model` using the parameters. During setup, `Model` creates `Exponential` instances for each distribution.
100-
3. **Run Simulation:** Call `model.run()` to execute the simulation within the SimPy environment, running two processes:
101-
102-
* `generate_patient_arrivals()` to handle patient creation, then sending them on to `attend_clinic()`.
103-
* `interval_audit()` to record utilisation and wait times at specified intervals during the simulation.
104102

105-
**Runner Class Usage:**
106-
107-
Having set up `experiment = Runner()`...
108-
109-
* **Single Run:** Use `experiment.run_single()` to execute a single model run.
110-
* **Multiple Runs:** Use `experiment.run_reps()` to perform multiple replications of the model.
103+
</details>
111104

112105
<br>
113106

114-
![Model structure diagram](images/model_structure.png)
115-
116-
*Illustration of model structure created using [draw.io](https://draw.io/).*
117-
118-
<br>
119-
120-
## Reproducing results
121-
122-
To generate the figures and tables from the paper (`mock_paper.md`), execute:
123-
124-
* **Figures 1-4**: `notebooks/analysis.ipynb`
125-
* **Figures A.1-A.2**: `notebooks/input_modelling.ipynb`
126-
* **Figure B.1**: `notebooks/choosing_warmup.ipynb`
127-
* **Figures C.1-C.3**: `notebooks/choosing_replications.ipynb`
128-
129-
<br>
130-
131-
## Input data
107+
<details><summary><b>Input data</b></summary>
132108

133109
**Patient-level data** for our system is provided in the file: `inputs/NHS_synthetic.csv`.
134110

@@ -145,74 +121,50 @@ This dataset is released under the MIT licence. If you use this data, please cit
145121

146122
The code for input modelling is in: `notebooks/input_modelling.ipynb`. Model parameters are determined in this file and then stored in: `simulation/model.py`. Description for each parameter can be found in the class docstring within this file.
147123

148-
<br>
124+
</details>
149125

150-
## GitHub actions
151-
152-
GitHub actions in `.github/workflows/` automate testing and code checks.
126+
<br>
153127

154-
* **tests.yaml** runs the tests on Ubuntu, Windows, and Mac after each push to main.
155-
* **lint.yaml** checks code style in python scripts and .ipynb files to maintain code quality.
128+
<details><summary><b>Reproducing results</b></summary>
156129

157-
<br>
130+
To generate the figures and tables from the paper (`mock_paper.md`), execute:
158131

159-
## Repository structure
132+
* **Figures 1-4**: `notebooks/analysis.ipynb`
133+
* **Figures A.1-A.2**: `notebooks/input_modelling.ipynb`
134+
* **Figure B.1**: `notebooks/choosing_warmup.ipynb`
135+
* **Figures C.1-C.3**: `notebooks/choosing_replications.ipynb`
160136

161-
```
162-
repo/
163-
├── .github/workflows/ # GitHub actions
164-
├── docs/ # Documentation
165-
├── images/ # Image files and GIFs
166-
├── inputs/ # Folder to store any input data
167-
├── notebooks/ # Run DES model and analyse results
168-
├── outputs/ # Folder to save any outputs from model
169-
├── simulation/ # Local package containing code for the DES model
170-
├── tests/ # Unit and back testing of the DES model
171-
├── .gitignore # Untracked files
172-
├── .pylintrc # Pylint settings
173-
├── CHANGELOG.md # Describes changes between releases
174-
├── CITATION.cff # How to cite the repository
175-
├── CONTRIBUTING.md # Contribution instructions
176-
├── environment.yaml # Conda environment (includes Python version)
177-
├── LICENSE # Licence file
178-
├── lint.sh # Bash script to lint all .py and .ipynb files at once
179-
├── pyproject.toml # Metadata for local `simulation/` package
180-
├── README.md # This file! Describes the repository
181-
├── requirements.txt # Virtual environment (used by GitHub actions)
182-
└── run_notebooks.sh # Bash script to run all .ipynb from the command line
183-
```
137+
</details>
184138

185139
<br>
186140

187-
## Run time and machine specification
141+
<details><summary><b>Run time and machine specification</b></summary>
188142

189143
Run times from our analyses (on Intel Core i7-12700H, 32GB RAM, Ubuntu 24.04.1):
190144

191-
* `analysis.ipynb` - 23s
192-
* `choosing_cores.ipynb` - 19s
193-
* `choosing_replications.ipynb` - 33s
194-
* `choosing_warmup.ipynb` - 4s
195-
* `generate_exp_results.ipynb` - 7s
145+
* `analysis.ipynb` - 35s
146+
* `choosing_cores.ipynb` - 34s
147+
* `choosing_replications.ipynb` - 46s
148+
* `choosing_warmup.ipynb` - 38s
149+
* `generate_exp_results.ipynb` - 1s
196150
* `logs.ipynb` - 0s
197-
* `time_weighted_averages.ipynb` - 1s
198-
199-
<br>
151+
* `time_weighted_averages.ipynb` - 2s
200152

201-
## Community
202-
203-
Curious about contributing? Check out the [contributing guidelines](CONTRIBUTING.md) to learn how you can help. Every bit of help counts, and your contribution - no matter how minor - is highly valued.
153+
</details>
204154

205155
<br>
206156

207-
## Citation
157+
## Project details and credits
158+
159+
### How to cite the repository
208160

209161
If you use this repository, please cite either the GitHub repository or Zenodo:
210162

211163
> Heather, A. Monks, T. (2025). Simple M/M/s queuing model: Python DES RAP. GitHub. https://github.com/pythonhealthdatascience/pydesrap_mms.
212164
>
213165
> Heather, A. Monks, T. (2025). Simple M/M/s queuing model: Python DES RAP. Zenodo. https://doi.org/10.5281/zenodo.14622466
214166
215-
**Contributors:**
167+
### Contributors
216168

217169
**Amy Heather** - developed the repository.
218170

@@ -224,15 +176,15 @@ If you use this repository, please cite either the GitHub repository or Zenodo:
224176
* [![ORCID](https://img.shields.io/badge/ORCID-0000--0003--2631--4481-A6CE39?style=for-the-badge&logo=orcid&logoColor=white)](https://orcid.org/0000-0003-2631-4481)
225177
* [![GitHub](https://img.shields.io/badge/GitHub-TomMonks-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/TomMonks)
226178

227-
<br>
228-
229-
## Licence
179+
### Licence
230180

231181
MIT Licence. See `LICENSE` for details.
232182

233-
<br>
183+
### Community
184+
185+
Curious about contributing? Check out the [contributing guidelines](CONTRIBUTING.md) to learn how you can help. Every bit of help counts, and your contribution - no matter how minor - is highly valued.
234186

235-
## Acknowledgements
187+
### Acknowledgements
236188

237189
This repository was developed with thanks to several others sources. These are acknowledged throughout in the relevant notebooks/modules/functions, and also summarised here:
238190

@@ -243,11 +195,9 @@ This repository was developed with thanks to several others sources. These are a
243195
| Sammi Rosser and Dan Chalk (2024) HSMA - the little book of DES (https://github.com/hsma-programme/hsma6_des_book) (MIT Licence) | `simulation/model.py`<br>`simulation/patient.py`<br>`simulation/runner.py`<br>`notebooks/choosing_cores.ipynb` |
244196
| Tom Monks (2025) sim-tools: tools to support the Discrete-Event Simulation process in python (https://github.com/TomMonks/sim-tools) (MIT Licence)<br>Who themselves cite Hoad, Robinson, & Davies (2010). Automated selection of the number of replications for a discrete-event simulation (https://www.jstor.org/stable/40926090), and Knuth. D "The Art of Computer Programming" Vol 2. 2nd ed. Page 216. | `simulation/confidence_interval_method.py`<br>`simulation/onlinestatistics.py`<br>`simulation/plotly_confidence_interval_method.py`<br>`simulation/replicationsalgorithm.py`<br>`simulation/replicationtabulizer.py`<br>`notebooks/choosing_replications.ipynb` |
245197
| Tom Monks, Alison Harper and Amy Heather (2025) An introduction to Discrete-Event Simulation (DES) using Free and Open Source Software (https://github.com/pythonhealthdatascience/intro-open-sim/tree/main). (MIT Licence) - who themselves also cite Law. Simulation Modeling and Analysis 4th Ed. Pages 14 - 17. | `simulation/monitoredresource.py` |
246-
| Tom Monks (2024) [HPDM097 - Making a difference with health data](https://github.com/health-data-science-OR/stochastic_systems) (MIT Licence). | `notebooks/analysis.ipynb`<br>`notebooks/choosing_replications.ipynb`<br>`notebooks/choosing_warmup.ipynb` |
198+
| Tom Monks (2024) [HPDM097 - Making a difference with health data](https://github.com/health-data-science-OR/stochastic_systems) (MIT Licence). | `simulation/warmupauditor.py`<br>`notebooks/analysis.ipynb`<br>`notebooks/choosing_replications.ipynb`<br>`notebooks/choosing_warmup.ipynb` |
247199
| Monks T and Harper A. Improving the usability of open health service delivery simulation models using Python and web apps (https://doi.org/10.3310/nihropenres.13467.2) [version 2; peer review: 3 approved]. NIHR Open Res 2023, 3:48.<br>Who themselves cite a [Stack Overflow](https://stackoverflow.com/questions/59406167/plotly-how-to-filter-a-pandas-dataframe-using-a-dropdown-menu) post. | `notebooks/analysis.ipynb` |
248200

249-
<br>
250-
251-
## Funding
201+
### Funding
252202

253203
This project was developed as part of the project STARS: Sharing Tools and Artefacts for Reproducible Simulations. It is supported by the Medical Research Council [grant number [MR/Z503915/1](https://gtr.ukri.org/projects?ref=MR%2FZ503915%2F1)].

docs/hsma_changes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ In the template, results are instead saved as a dictionary into a list as the ru
170170
* Avoids initialising an empty dataframe.
171171
* Is consistent with how the patient-level results were also generated in the template.
172172

173-
Also, some of the calculations have been performed directly during the `run_single()` method, instead of from a seperate method `calculate_run_results()`. This is to help simplify the code, as it makes clear how each metric was calculated in one place, rather than needing to refer elsewhere.
173+
Also, some of the calculations have been performed directly during the `run_single()` method, instead of from a separate method `calculate_run_results()`. This is to help simplify the code, as it makes clear how each metric was calculated in one place, rather than needing to refer elsewhere.
174174

175175
```
176176
run_results = {

docs/quality_assurance.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Quality Assurance (QA)
2+
3+
## Roles and responsibilities
4+
5+
**Analyst:** Amy Heather (developed the model and implemented the analysis).
6+
7+
**Assurer/Approver:** Tom Monks (provided independent review proportionate to a small teaching example).
8+
9+
## QA when scoping the project
10+
11+
Scoping was agreed verbally between analyst and assurer: construct an M/M/s queueing model in SimPy using synthetic data as a worked example, rather than a decision‑critical tool. No formal written scoping document was produced, which would be expected for larger or higher‑risk work, but was judged unnecessary here.
12+
13+
No explicit QA plan (who, what, how much) was written at the outset; this document provides a retrospective QA summary and lessons learned for future projects.
14+
15+
## QA when designing the analysis
16+
17+
The analytical approach was intentionally simple: an M/M/s model implemented in SimPy, using synthetic data consistent, with no external data sources. This constrained the design space, so there were few substantive design choices beyond implementation details.
18+
19+
Verification and validation strategy was not agreed in advance but was developed iteratively during the analysis as issues and checks were identified.
20+
21+
Design decisions were not recorded in a separate design document; for future, non‑toy models, capturing key decisions in a short design or analysis‑plan file would be preferable.
22+
23+
## QA when performing the analysis
24+
25+
Verification and validation activities were carried out during development, and checked in a [summary GitHub issue](https://github.com/pythonhealthdatascience/pydesrap_mms/issues/84) (serving as part of the QA log). Checks were proportionate to the simplicity and teaching purpose of the model.
26+
27+
Assurance of code and workflows was ensured by following the [STARS Reproducibility Recommendations](https://doi.org/10.1080/17477778.2025.2552177) and the [NHS Levels of RAP Framework](https://nhsdigital.github.io/rap-community-of-practice/introduction_to_RAP/levels_of_RAP/).
28+
29+
Code is documented with docstrings and comments to aid understanding and reuse. User and technical documentation are currently provided via the [DES RAP Book](https://github.com/pythonhealthdatascience/des_rap_book). To avoid duplication of this material, the repository does not have it's own standalone user instructions or detailed technical description of the model structure, which would be expected for a model in practice.
30+
31+
GitHub issues act as an informal QA plan and log; for future projects, a more explicit QA project board and short summary of decisions and changes would strengthen the audit trail.

docs/heather_2025.md renamed to docs/stars_reproducibility_recommendations.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
# Reproducibility recommendations from Heather et al. 2025
1+
# STARS Reproducibility Recommendations
22

3-
As part of the project STARS (Sharing Tools and Artefacts for Reproducible Simulations), a series of computational reproducibility assessments were conducted by [Heather et al. 2025](https://doi.org/10.48550/arXiv.2501.13137). From these, several recommendations were shared to support reproducibility of healthcare discrete-event simulation (DES) models. These are copied below. Those marked with a star (⭐) were identified as having the greatest impact in Heather et al. 2025.
3+
As part of the project STARS (Sharing Tools and Artefacts for Reproducible Simulations), a series of computational reproducibility assessments were conducted and described in:
4+
5+
> Heather, A., Monks, T., Harper, A., Mustafee, N., & Mayne, A. (2025). On the reproducibility of discrete-event simulation studies in health research: an empirical study using open models. Journal of Simulation. https://doi.org/10.1080/17477778.2025.2552177.
6+
7+
From these, several recommendations were shared to support reproducibility of healthcare discrete-event simulation (DES) models. These are copied below. Those marked with a star (⭐) were identified as having the greatest impact in the paper.
48

59
## Recommendations to support reproduction
610

0 commit comments

Comments
 (0)