|
2 | 2 | import copy
|
3 | 3 | import os
|
4 | 4 | from pathlib import Path
|
| 5 | +from typing import Dict |
5 | 6 |
|
6 | 7 | import pandas as pd
|
7 | 8 | import pytest
|
@@ -83,6 +84,88 @@ def test_beddays_in_isolation(tmpdir, seed):
|
83 | 84 | assert ([cap_bedtype1] * days_sim == tracker.values).all()
|
84 | 85 |
|
85 | 86 |
|
| 87 | +def test_beddays_allocation_resolution(tmpdir, seed): |
| 88 | + sim = Simulation(start_date=start_date, seed=seed) |
| 89 | + sim.register( |
| 90 | + demography.Demography(resourcefilepath=resourcefilepath), |
| 91 | + healthsystem.HealthSystem(resourcefilepath=resourcefilepath), |
| 92 | + ) |
| 93 | + |
| 94 | + # Update BedCapacity data with a simple table: |
| 95 | + level2_facility_ids = [128, 129, 130] # <-- the level 2 facilities for each region |
| 96 | + # This ensures over-allocations have to be properly resolved |
| 97 | + cap_bedtype1 = 10 |
| 98 | + cap_bedtype2 = 10 |
| 99 | + cap_bedtype3 = 10 |
| 100 | + |
| 101 | + # create a simple bed capacity dataframe |
| 102 | + hs = sim.modules["HealthSystem"] |
| 103 | + hs.parameters["BedCapacity"] = pd.DataFrame( |
| 104 | + data={ |
| 105 | + "Facility_ID": level2_facility_ids, |
| 106 | + "bedtype1": cap_bedtype1, |
| 107 | + "bedtype2": cap_bedtype2, |
| 108 | + "bedtype3": cap_bedtype3, |
| 109 | + } |
| 110 | + ) |
| 111 | + |
| 112 | + sim.make_initial_population(n=100) |
| 113 | + sim.simulate(end_date=start_date) |
| 114 | + |
| 115 | + # reset bed days tracker to the start_date of the simulation |
| 116 | + hs.bed_days.initialise_beddays_tracker() |
| 117 | + |
| 118 | + def assert_footprint_matches_expected( |
| 119 | + footprint: Dict[str, int], expected_footprint: Dict[str, int] |
| 120 | + ): |
| 121 | + """ |
| 122 | + Asserts that two footprints are identical. |
| 123 | + The footprint provided as the 2nd argument is assumed to be the footprint |
| 124 | + that we want to match, and the 1st as the result of the program attempting |
| 125 | + to resolve over-allocations. |
| 126 | + """ |
| 127 | + assert len(footprint) == len( |
| 128 | + expected_footprint |
| 129 | + ), "Bed type footprints did not return same allocations." |
| 130 | + for bed_type, expected_days in expected_footprint.items(): |
| 131 | + allocated_days = footprint[bed_type] |
| 132 | + assert expected_days == allocated_days, ( |
| 133 | + f"Bed type {bed_type} was allocated {allocated_days} upon combining, " |
| 134 | + f"but expected it to get {expected_days}." |
| 135 | + ) |
| 136 | + |
| 137 | + # Check that combining footprints for a person returns the expected output |
| 138 | + |
| 139 | + # SIMPLE 2-bed days case |
| 140 | + # Test uses example fail case given in https://github.com/UCL/TLOmodel/issues/1399 |
| 141 | + # Person p has: bedtyp1 for 2 days, bedtype2 for 0 days. |
| 142 | + # Person p then assigned: bedtype1 for 1 days, bedtype2 for 6 days. |
| 143 | + # EXPECT: p's footprints are combined into bedtype1 for 2 days, bedtype2 for 5 days. |
| 144 | + existing_footprint = {"bedtype1": 2, "bedtype2": 0, "bedtype3": 0} |
| 145 | + incoming_footprint = {"bedtype1": 1, "bedtype2": 6, "bedtype3": 0} |
| 146 | + expected_resolution = {"bedtype1": 2, "bedtype2": 5, "bedtype3": 0} |
| 147 | + allocated_footprint = hs.bed_days.combine_footprints_for_same_patient( |
| 148 | + existing_footprint, incoming_footprint |
| 149 | + ) |
| 150 | + assert_footprint_matches_expected(allocated_footprint, expected_resolution) |
| 151 | + |
| 152 | + # TEST case involve 3 different bed-types. |
| 153 | + # Person p has: bedtype1 for 2 days, then bedtype3 for 4 days. |
| 154 | + # p is assigned: bedtype1 for 1 day, bedtype2 for 3 days, and bedtype3 for 1 day. |
| 155 | + # EXPECT: p spends 2 days in each bedtype; |
| 156 | + # - Day 1 needs bedtype1 for both footprints |
| 157 | + # - Day 2 existing footprint at bedtype1 overwrites incoming at bedtype2 |
| 158 | + # - Day 3 & 4 incoming footprint at bedtype2 overwrites existing allocation to bedtype3 |
| 159 | + # - Day 5 both footprints want bedtype3 |
| 160 | + # - Day 6 existing footprint needs bedtype3, whilst incoming footprint is over.s |
| 161 | + existing_footprint = {"bedtype1": 2, "bedtype2": 0, "bedtype3": 4} |
| 162 | + incoming_footprint = {"bedtype1": 1, "bedtype2": 3, "bedtype3": 1} |
| 163 | + expected_resolution = {"bedtype1": 2, "bedtype2": 2, "bedtype3": 2} |
| 164 | + allocated_footprint = hs.bed_days.combine_footprints_for_same_patient( |
| 165 | + existing_footprint, incoming_footprint |
| 166 | + ) |
| 167 | + assert_footprint_matches_expected(allocated_footprint, expected_resolution) |
| 168 | + |
86 | 169 | def check_dtypes(simulation):
|
87 | 170 | # check types of columns
|
88 | 171 | df = simulation.population.props
|
|
0 commit comments