Skip to content

Commit d0f6bd4

Browse files
authored
Merge pull request #50 from pythonhealthdatascience/dev
Dev
2 parents 2db7cc8 + ee470ea commit d0f6bd4

33 files changed

+2412
-2291
lines changed

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ The simulation code is in the `simulation/` folder as a local package. Example a
5555
%autoreload 1
5656
%aimport simulation
5757
58-
from simulation.model import Param, Runner, run_scenarios
59-
from simulation.helper import summary_stats
58+
from simulation import Param, Runner, run_scenarios, summary_stats
6059
# etc.
6160
```
6261

@@ -247,9 +246,9 @@ This repository was developed with thanks to several others sources. These are a
247246
| - | - |
248247
| Amy Heather, Thomas Monks, Alison Harper, Navonil Mustafee, Andrew Mayne (2025) On the reproducibility of discrete-event simulation studies in health research: an empirical study using open models (https://doi.org/10.48550/arXiv.2501.13137). | `docs/heather_2025.md` |
249248
| NHS Digital (2024) RAP repository template (https://github.com/NHSDigital/rap-package-template) (MIT Licence) | `simulation/logging.py`<br>`docs/nhs_rap.md` |
250-
| 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>`notebooks/choosing_cores.ipynb` |
251-
| 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/model.py`<br>`simulation/replications.py`<br>`notebooks/choosing_replications.ipynb` |
252-
| 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/model.py` |
249+
| 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` |
250+
| 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` |
251+
| 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` |
253252
| 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` |
254253
| 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` |
255254

notebooks/analysis.ipynb

Lines changed: 111 additions & 112 deletions
Large diffs are not rendered by default.

notebooks/choosing_cores.ipynb

Lines changed: 15 additions & 15 deletions
Large diffs are not rendered by default.

notebooks/choosing_replications.ipynb

Lines changed: 37 additions & 37 deletions
Large diffs are not rendered by default.

notebooks/choosing_warmup.ipynb

Lines changed: 38 additions & 38 deletions
Large diffs are not rendered by default.

notebooks/generate_exp_results.ipynb

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
"import time\n",
5757
"from IPython.display import display\n",
5858
"\n",
59-
"from simulation.model import Param, Runner, run_scenarios\n",
60-
"from simulation.replications import confidence_interval_method"
59+
"from simulation import confidence_interval_method, Param, Runner, run_scenarios"
6160
]
6261
},
6362
{
@@ -91,7 +90,7 @@
9190
"outputs": [],
9291
"source": [
9392
"# Define path to folder for expected results for tests\n",
94-
"TESTS = '../tests/exp_results/'"
93+
"TESTS = \"../tests/exp_results/\""
9594
]
9695
},
9796
{
@@ -302,7 +301,7 @@
302301
"# Patient-level results\n",
303302
"display(experiment.patient_results_df)\n",
304303
"experiment.patient_results_df.to_csv(\n",
305-
" os.path.join(TESTS, 'patient.csv'), index=False)"
304+
" os.path.join(TESTS, \"patient.csv\"), index=False)"
306305
]
307306
},
308307
{
@@ -444,7 +443,7 @@
444443
"# Run results\n",
445444
"display(experiment.run_results_df)\n",
446445
"experiment.run_results_df.to_csv(\n",
447-
" os.path.join(TESTS, 'run.csv'), index=False)"
446+
" os.path.join(TESTS, \"run.csv\"), index=False)"
448447
]
449448
},
450449
{
@@ -624,7 +623,7 @@
624623
"# Interval audit results\n",
625624
"display(experiment.interval_audit_df)\n",
626625
"experiment.interval_audit_df.to_csv(\n",
627-
" os.path.join(TESTS, 'interval.csv'), index=False)"
626+
" os.path.join(TESTS, \"interval.csv\"), index=False)"
628627
]
629628
},
630629
{
@@ -740,7 +739,7 @@
740739
"# Overall results\n",
741740
"display(experiment.overall_results_df)\n",
742741
"experiment.overall_results_df.to_csv(\n",
743-
" os.path.join(TESTS, 'overall.csv'), index=True)"
742+
" os.path.join(TESTS, \"overall.csv\"), index=True)"
744743
]
745744
},
746745
{
@@ -934,16 +933,16 @@
934933
" cores=1\n",
935934
")\n",
936935
"scenario_results = run_scenarios(\n",
937-
" scenarios={'patient_inter': [3, 4],\n",
938-
" 'number_of_nurses': [6, 7]},\n",
936+
" scenarios={\"patient_inter\": [3, 4],\n",
937+
" \"number_of_nurses\": [6, 7]},\n",
939938
" param=param\n",
940939
")\n",
941940
"\n",
942941
"# Preview\n",
943942
"display(scenario_results.head())\n",
944943
"\n",
945944
"# Save to csv\n",
946-
"scenario_results.to_csv(os.path.join(TESTS, 'scenario.csv'), index=True)"
945+
"scenario_results.to_csv(os.path.join(TESTS, \"scenario.csv\"), index=True)"
947946
]
948947
},
949948
{
@@ -1192,15 +1191,15 @@
11921191
"\n",
11931192
"_, man_df = confidence_interval_method(\n",
11941193
" replications=40,\n",
1195-
" metrics=['mean_time_with_nurse',\n",
1196-
" 'mean_q_time_nurse',\n",
1197-
" 'mean_nurse_utilisation'],\n",
1194+
" metrics=[\"mean_time_with_nurse\",\n",
1195+
" \"mean_q_time_nurse\",\n",
1196+
" \"mean_nurse_utilisation\"],\n",
11981197
" param=param)\n",
11991198
"\n",
12001199
"display(man_df)\n",
12011200
"\n",
12021201
"man_df.to_csv(\n",
1203-
" os.path.join(TESTS, 'replications.csv'), index=False)"
1202+
" os.path.join(TESTS, \"replications.csv\"), index=False)"
12041203
]
12051204
},
12061205
{
@@ -1229,7 +1228,7 @@
12291228
"runtime = round(end_time - start_time)\n",
12301229
"\n",
12311230
"# Display converted to minutes and seconds\n",
1232-
"print(f'Notebook run time: {runtime // 60}m {runtime % 60}s')"
1231+
"print(f\"Notebook run time: {runtime // 60}m {runtime % 60}s\")"
12331232
]
12341233
}
12351234
],

notebooks/input_modelling.ipynb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7563,49 +7563,49 @@
75637563
"name": "stderr",
75647564
"output_type": "stream",
75657565
"text": [
7566-
"[16-06-2025 14:16:54] [distfit.distfit] fit\n"
7566+
"[20-06-2025 09:52:08] [distfit.distfit] fit\n"
75677567
]
75687568
},
75697569
{
75707570
"name": "stderr",
75717571
"output_type": "stream",
75727572
"text": [
7573-
"[16-06-2025 14:16:54] [distfit.distfit] transform\n"
7573+
"[20-06-2025 09:52:08] [distfit.distfit] transform\n"
75747574
]
75757575
},
75767576
{
75777577
"name": "stderr",
75787578
"output_type": "stream",
75797579
"text": [
7580-
"[16-06-2025 14:16:54] [distfit.distfit] [expon] [0.00 sec] [RSS: 2.2484] [loc=0.000 scale=3.984]\n"
7580+
"[20-06-2025 09:52:08] [distfit.distfit] [expon] [0.00 sec] [RSS: 2.2484] [loc=0.000 scale=3.984]\n"
75817581
]
75827582
},
75837583
{
75847584
"name": "stderr",
75857585
"output_type": "stream",
75867586
"text": [
7587-
"[16-06-2025 14:16:54] [distfit.distfit] [expon] [0.00 sec] [RSS: 2.2484] [loc=0.000 scale=3.984]\n"
7587+
"[20-06-2025 09:52:08] [distfit.distfit] [expon] [0.00 sec] [RSS: 2.2484] [loc=0.000 scale=3.984]\n"
75887588
]
75897589
},
75907590
{
75917591
"name": "stderr",
75927592
"output_type": "stream",
75937593
"text": [
7594-
"[16-06-2025 14:16:54] [distfit.distfit] Compute confidence intervals [parametric]\n"
7594+
"[20-06-2025 09:52:08] [distfit.distfit] Compute confidence intervals [parametric]\n"
75957595
]
75967596
},
75977597
{
75987598
"name": "stderr",
75997599
"output_type": "stream",
76007600
"text": [
7601-
"[16-06-2025 14:16:54] [distfit.distfit] Create pdf plot for the parametric method.\n"
7601+
"[20-06-2025 09:52:08] [distfit.distfit] Create pdf plot for the parametric method.\n"
76027602
]
76037603
},
76047604
{
76057605
"name": "stderr",
76067606
"output_type": "stream",
76077607
"text": [
7608-
"[16-06-2025 14:16:54] [distfit.distfit] Estimated distribution: Expon(loc:0.000000, scale:3.984361)\n"
7608+
"[20-06-2025 09:52:08] [distfit.distfit] Estimated distribution: Expon(loc:0.000000, scale:3.984361)\n"
76097609
]
76107610
},
76117611
{

notebooks/logs.ipynb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
"import time\n",
3535
"from IPython.display import display\n",
3636
"\n",
37-
"from simulation.logging import SimLogger\n",
38-
"from simulation.model import Param, Model"
37+
"from simulation import Model, Param, SimLogger"
3938
]
4039
},
4140
{
@@ -80,12 +79,12 @@
8079
"text": [
8180
"\u001b[1m{\u001b[0m \u001b[32m'audit_list'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m, \n",
8281
" \u001b[32m'env'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m<\u001b[0m\u001b[32msimpy.core.Environment\u001b[0m\u001b[32m>'\u001b[0m\u001b[39m,\u001b[0m \n",
83-
"\u001b[39m \u001b[0m\u001b[32m'nurse'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<simulation.model.MonitoredResource>'\u001b[0m\u001b[39m,\u001b[0m \n",
82+
"\u001b[39m \u001b[0m\u001b[32m'nurse'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<simulation.monitoredresource.MonitoredResource>'\u001b[0m\u001b[39m,\u001b[0m \n",
8483
"\u001b[39m \u001b[0m\u001b[32m'nurse_consult_count'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m \n",
8584
"\u001b[39m \u001b[0m\u001b[32m'nurse_consult_time_dist'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<sim_tools.distributions.Exponential>'\u001b[0m\u001b[39m,\u001b[0m \n",
8685
"\u001b[39m \u001b[0m\u001b[32m'nurse_time_used'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m \n",
8786
"\u001b[39m \u001b[0m\u001b[32m'nurse_time_used_correction'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m \n",
88-
"\u001b[39m \u001b[0m\u001b[32m'param'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<simulation.model.Param>'\u001b[0m\u001b[39m,\u001b[0m \n",
87+
"\u001b[39m \u001b[0m\u001b[32m'param'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<simulation.param.Param>'\u001b[0m\u001b[39m,\u001b[0m \n",
8988
"\u001b[39m \u001b[0m\u001b[32m'patient_inter_arrival_dist'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'<sim_tools.distributions.Exponential\u001b[0m\u001b[32m>\u001b[0m\u001b[32m'\u001b[0m, \n",
9089
" \u001b[32m'patients'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m, \n",
9190
" \u001b[32m'results_list'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m, \n",
@@ -109,7 +108,7 @@
109108
" \u001b[32m'audit_interval'\u001b[0m: \u001b[1;36m120\u001b[0m, \n",
110109
" \u001b[32m'cores'\u001b[0m: \u001b[1;36m1\u001b[0m, \n",
111110
" \u001b[32m'data_collection_period'\u001b[0m: \u001b[1;36m50\u001b[0m, \n",
112-
" \u001b[32m'logger'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m<\u001b[0m\u001b[32msimulation.logging.SimLogger\u001b[0m\u001b[32m>\u001b[0m\u001b[32m'\u001b[0m, \n",
111+
" \u001b[32m'logger'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m<\u001b[0m\u001b[32msimulation.simlogger.SimLogger\u001b[0m\u001b[32m>\u001b[0m\u001b[32m'\u001b[0m, \n",
113112
" \u001b[32m'mean_n_consult_time'\u001b[0m: \u001b[1;36m10\u001b[0m, \n",
114113
" \u001b[32m'number_of_nurses'\u001b[0m: \u001b[1;36m1\u001b[0m, \n",
115114
" \u001b[32m'number_of_runs'\u001b[0m: \u001b[1;36m1\u001b[0m, \n",
@@ -186,7 +185,7 @@
186185
"output_type": "stream",
187186
"text": [
188187
"\u001b[1;36m28.667\u001b[0m: 🛠 Patient \u001b[1;36m4\u001b[0m starts consultation with \u001b[1;36m1.333\u001b[0m left of warm-up \u001b[1m(\u001b[0mwhich is \u001b[1;36m30.000\u001b[0m\u001b[1m)\u001b[0m. As their consultation is for \n",
189-
"\u001b[1;36m5.295\u001b[0m, they will exceed warmup by \u001b[1;36m3.962\u001b[0m, so we correct for this. \n"
188+
"\u001b[1;36m5.295\u001b[0m, they will exceed warmup by \u001b[1;36m3.962\u001b[0m,so we correct for this. \n"
190189
]
191190
},
192191
{
@@ -304,7 +303,7 @@
304303
" number_of_runs=1,\n",
305304
" cores=1,\n",
306305
" logger=SimLogger(log_to_console=True, log_to_file=True,\n",
307-
" file_path='../outputs/logs/log_example.log',\n",
306+
" file_path=\"../outputs/logs/log_example.log\",\n",
308307
" sanitise=True)\n",
309308
")\n",
310309
"\n",
@@ -404,7 +403,7 @@
404403
"runtime = round(end_time - start_time)\n",
405404
"\n",
406405
"# Display converted to minutes and seconds\n",
407-
"print(f'Notebook run time: {runtime // 60}m {runtime % 60}s')"
406+
"print(f\"Notebook run time: {runtime // 60}m {runtime % 60}s\")"
408407
]
409408
}
410409
],

0 commit comments

Comments
 (0)