@@ -2276,4 +2276,75 @@ def get_capabilities_today(const_HR_scaling_mode: str) -> pd.Series:
22762276 )
22772277
22782278
2279+ def test_dynamic_HR_scaling (seed , tmpdir ):
2280+ """Check that we can scale the minutes of time available for healthcare workers on a yearly basis based on either
2281+ a fixed scaling factor or population grown, or both."""
22792282
2283+ def get_initial_capabilities () -> pd .Series :
2284+ sim = Simulation (start_date = start_date , seed = seed )
2285+ sim .register (
2286+ demography .Demography (resourcefilepath = resourcefilepath ),
2287+ healthsystem .HealthSystem (resourcefilepath = resourcefilepath )
2288+ )
2289+ sim .make_initial_population (n = 100 )
2290+ sim .simulate (end_date = start_date + pd .DateOffset (days = 0 ))
2291+
2292+ return sim .modules ['HealthSystem' ].capabilities_today
2293+
2294+ def get_capabilities_after_two_years (dynamic_HR_scaling_factor : float , scale_HR_by_pop_size : bool ) -> tuple :
2295+ sim = Simulation (start_date = start_date , seed = seed )
2296+ sim .register (
2297+ demography .Demography (resourcefilepath = resourcefilepath ),
2298+ healthsystem .HealthSystem (resourcefilepath = resourcefilepath ),
2299+ simplified_births .SimplifiedBirths (resourcefilepath = resourcefilepath ),
2300+
2301+ )
2302+ sim .modules ['HealthSystem' ].parameters ['dynamic_HR_scaling_factor' ] = dynamic_HR_scaling_factor
2303+ sim .modules ['HealthSystem' ].parameters ['scale_HR_by_popsize' ] = scale_HR_by_pop_size
2304+ sim .make_initial_population (n = 100 )
2305+
2306+ # Ensure simulation lasts long enough so that current capabilities reflect that used in the third year of
2307+ # simulation (i.e. after two annual updates)
2308+ sim .simulate (end_date = start_date + pd .DateOffset (years = 2 , days = 1 ))
2309+
2310+ popsize = sim .modules ['Demography' ].popsize_by_year
2311+
2312+ final_popsize_increase = popsize [2012 ]/ popsize [2010 ]
2313+
2314+ return sim .modules ['HealthSystem' ].capabilities_today , final_popsize_increase
2315+
2316+ dynamic_HR_scaling_factor = 1.05
2317+
2318+ # Get initial capabilities and remove all officers with no minutes available
2319+ initial_caps = get_initial_capabilities ()
2320+ initial_caps = initial_caps [initial_caps != 0 ]
2321+
2322+ # Check that dynamic expansion over two years leads to expansion = dynamic_HR_scaling_factor^2
2323+ caps , final_popsize_increase = get_capabilities_after_two_years (
2324+ dynamic_HR_scaling_factor = dynamic_HR_scaling_factor ,
2325+ scale_HR_by_pop_size = False
2326+ )
2327+ caps = caps [caps != 0 ]
2328+ ratio_in_sim = caps / initial_caps
2329+ expected_value = dynamic_HR_scaling_factor * dynamic_HR_scaling_factor
2330+ assert np .allclose (ratio_in_sim , expected_value )
2331+
2332+ # Check that expansion over two years with scaling prop to pop expansion works as expected
2333+ caps , final_popsize_increase = get_capabilities_after_two_years (
2334+ dynamic_HR_scaling_factor = 1.0 ,
2335+ scale_HR_by_pop_size = True
2336+ )
2337+ caps = caps [caps != 0 ]
2338+ ratio_in_sim = caps / initial_caps
2339+ expected_value = final_popsize_increase
2340+ assert np .allclose (ratio_in_sim , expected_value )
2341+
2342+ # Check that expansion over two years with both fixed scaling and pop expansion scaling works as expected
2343+ caps , final_popsize_increase = get_capabilities_after_two_years (
2344+ dynamic_HR_scaling_factor = dynamic_HR_scaling_factor ,
2345+ scale_HR_by_pop_size = True
2346+ )
2347+ caps = caps [caps != 0 ]
2348+ ratio_in_sim = caps / initial_caps
2349+ expected_value = final_popsize_increase * dynamic_HR_scaling_factor * dynamic_HR_scaling_factor
2350+ assert np .allclose (ratio_in_sim , expected_value )
0 commit comments