|
5 | 5 | "id": "0be7dabf-cb34-4faf-abb1-e2c8e735beda",
|
6 | 6 | "metadata": {},
|
7 | 7 | "source": [
|
8 |
| - "# Implementing a warm-up period\n", |
| 8 | + "# Coding a warm-up period in SimPy\n", |
9 | 9 | "\n",
|
10 |
| - "We will implement warm-up as a single event that resets all of our results collection variables. \n", |
| 10 | + "## Why do you need a warm-up period?\n", |
11 | 11 | "\n",
|
12 |
| - "This is a simpler approach than including lots of if statements in `simpy` processes." |
| 12 | + "Typically when you are modelling a non-terminating system, you will need to deal with **initialisation bias**. That is the real system always has work-in-progress (e.g. patients in queues and in service), but the model starts from empty. One way to do this is to split the model's run length into warm-up and data collection periods. We discard all results in the warm-up period.\n", |
| 13 | + "\n", |
| 14 | + "> In this tutorial we will focus on coding a warm-up period rather than analysis to determine its length\n", |
| 15 | + "\n", |
| 16 | + "## But how do you code it?\n", |
| 17 | + "\n", |
| 18 | + "💪 We will implement warm-up as a **single event** that resets all of our results collection variables. \n", |
| 19 | + "\n", |
| 20 | + "> This is a simpler approach than including lots of if statements in `simpy` processes.\n", |
| 21 | + "\n", |
| 22 | + "## Illustrative example model\n", |
| 23 | + "\n", |
| 24 | + "We will use a very simple model for this example. This is a acute stroke pathway with a single arrival processes, a single type of resource, and a single treatment process. This is a non-terminating system. There are always patients in the system - it does not start up from empty\n", |
| 25 | + "\n", |
| 26 | + "\n", |
| 27 | + "" |
13 | 28 | ]
|
14 | 29 | },
|
15 | 30 | {
|
|
34 | 49 | },
|
35 | 50 | {
|
36 | 51 | "cell_type": "code",
|
37 |
| - "execution_count": 25, |
| 52 | + "execution_count": 2, |
38 | 53 | "id": "ea3d507f-9e6d-4ff0-8b90-f9c63c8a8bdf",
|
39 | 54 | "metadata": {},
|
40 | 55 | "outputs": [],
|
|
212 | 227 | "id": "7ff9beae-89cc-419c-b584-c05b81086865",
|
213 | 228 | "metadata": {},
|
214 | 229 | "source": [
|
215 |
| - "## 🥵 Warm-up period" |
| 230 | + "## 🥵 Warm-up period\n", |
| 231 | + "\n", |
| 232 | + "The acute stroke pathway model starts from empty. As it is a non-terminating system our estimate of waiting time is biased due to the empty period at the start of the simulation. We can remove this initialisation bias using a warm-up period. \n", |
| 233 | + "\n", |
| 234 | + "We will implement a warm-up through an **event** that happens once in a single run of the model. The model will be run for the **warm-up period + results collection period**. At the end of the warm-up period an event will happen where all variables in the current experiment are reset (e.g. empty lists and set quantitative values to 0)." |
216 | 235 | ]
|
217 | 236 | },
|
218 | 237 | {
|
|
248 | 267 | "id": "94f0f9c5-22cb-493a-9f1f-4e2a8325beaa",
|
249 | 268 | "metadata": {},
|
250 | 269 | "source": [
|
251 |
| - "## 4. Pathway process logic\n", |
| 270 | + "## 4. Stroke pathway process logic\n", |
252 | 271 | "\n",
|
253 | 272 | "The key things to recognise are \n",
|
254 | 273 | "\n",
|
|
309 | 328 | },
|
310 | 329 | {
|
311 | 330 | "cell_type": "code",
|
312 |
| - "execution_count": 33, |
| 331 | + "execution_count": 8, |
313 | 332 | "id": "b3e686ce-5371-4471-a052-b9d43309bc85",
|
314 | 333 | "metadata": {},
|
315 | 334 | "outputs": [],
|
|
352 | 371 | },
|
353 | 372 | {
|
354 | 373 | "cell_type": "code",
|
355 |
| - "execution_count": 34, |
| 374 | + "execution_count": 9, |
356 | 375 | "id": "0d0ea6cf-7d95-4d2c-9690-fcdbdae35d84",
|
357 | 376 | "metadata": {},
|
358 | 377 | "outputs": [],
|
|
424 | 443 | },
|
425 | 444 | {
|
426 | 445 | "cell_type": "code",
|
427 |
| - "execution_count": 35, |
| 446 | + "execution_count": 22, |
428 | 447 | "id": "caf52390-5455-4fa1-bb22-60b5b91ad8d0",
|
429 | 448 | "metadata": {},
|
430 | 449 | "outputs": [
|
|
436 | 455 | "3.29: Stroke arrival.\n",
|
437 | 456 | "3.29: Patient 1 admitted to acute ward.(waited 0.00 days)\n",
|
438 | 457 | "4.06: Stroke arrival.\n",
|
439 |
| - "4.06: Patient 2 admitted to acute ward.(waited 0.00 days)\n" |
| 458 | + "4.06: Patient 2 admitted to acute ward.(waited 0.00 days)\n", |
| 459 | + "5.31: Stroke arrival.\n", |
| 460 | + "5.31: Patient 3 admitted to acute ward.(waited 0.00 days)\n", |
| 461 | + "5.53: Stroke arrival.\n", |
| 462 | + "5.53: Patient 4 admitted to acute ward.(waited 0.00 days)\n", |
| 463 | + "5.76: Stroke arrival.\n", |
| 464 | + "5.76: Patient 5 admitted to acute ward.(waited 0.00 days)\n" |
440 | 465 | ]
|
441 | 466 | },
|
442 | 467 | {
|
|
445 | 470 | "{'mean_acute_wait': 0.0}"
|
446 | 471 | ]
|
447 | 472 | },
|
448 |
| - "execution_count": 35, |
| 473 | + "execution_count": 22, |
449 | 474 | "metadata": {},
|
450 | 475 | "output_type": "execute_result"
|
451 | 476 | }
|
452 | 477 | ],
|
453 | 478 | "source": [
|
454 | 479 | "TRACE = True\n",
|
455 | 480 | "experiment = Experiment()\n",
|
456 |
| - "results = single_run(experiment, rep=0, wu_period=0.0, rc_period=5.0)\n", |
| 481 | + "results = single_run(experiment, rep=0, wu_period=0.0, rc_period=6.0)\n", |
457 | 482 | "results"
|
458 | 483 | ]
|
459 | 484 | },
|
460 | 485 | {
|
461 | 486 | "cell_type": "code",
|
462 |
| - "execution_count": 36, |
| 487 | + "execution_count": 23, |
463 | 488 | "id": "ddedb4f1-207d-4295-9ae4-c49b2c7cdcaf",
|
464 | 489 | "metadata": {},
|
465 | 490 | "outputs": [
|
466 | 491 | {
|
467 | 492 | "data": {
|
468 | 493 | "text/plain": [
|
469 |
| - "{'n_arrivals': 2, 'waiting_acute': [0.0, 0.0]}" |
| 494 | + "{'n_arrivals': 5, 'waiting_acute': [0.0, 0.0, 0.0, 0.0, 0.0]}" |
470 | 495 | ]
|
471 | 496 | },
|
472 |
| - "execution_count": 36, |
| 497 | + "execution_count": 23, |
473 | 498 | "metadata": {},
|
474 | 499 | "output_type": "execute_result"
|
475 | 500 | }
|
|
484 | 509 | "id": "660ea2e1-d9c2-4355-876c-43dfd9dab0fe",
|
485 | 510 | "metadata": {},
|
486 | 511 | "source": [
|
487 |
| - "## Quick check 1: Include a warm-up" |
| 512 | + "## Quick check 2: Include a warm-up" |
488 | 513 | ]
|
489 | 514 | },
|
490 | 515 | {
|
491 | 516 | "cell_type": "code",
|
492 |
| - "execution_count": 37, |
| 517 | + "execution_count": 24, |
493 | 518 | "id": "72b5284a-1fcb-4126-b663-c0ef0002e4bf",
|
494 | 519 | "metadata": {},
|
495 | 520 | "outputs": [
|
|
516 | 541 | "{'mean_acute_wait': 0.0}"
|
517 | 542 | ]
|
518 | 543 | },
|
519 |
| - "execution_count": 37, |
| 544 | + "execution_count": 24, |
520 | 545 | "metadata": {},
|
521 | 546 | "output_type": "execute_result"
|
522 | 547 | }
|
|
530 | 555 | },
|
531 | 556 | {
|
532 | 557 | "cell_type": "code",
|
533 |
| - "execution_count": 38, |
| 558 | + "execution_count": 25, |
534 | 559 | "id": "7f5e282b-0f41-41df-bdca-f128e7d418c1",
|
535 | 560 | "metadata": {},
|
536 | 561 | "outputs": [
|
|
540 | 565 | "{'n_arrivals': 3, 'waiting_acute': [0.0, 0.0, 0.0]}"
|
541 | 566 | ]
|
542 | 567 | },
|
543 |
| - "execution_count": 38, |
| 568 | + "execution_count": 25, |
544 | 569 | "metadata": {},
|
545 | 570 | "output_type": "execute_result"
|
546 | 571 | }
|
|
0 commit comments