|
7 | 7 | from collections.abc import Iterable
|
8 | 8 | from itertools import repeat
|
9 | 9 | from pathlib import Path
|
10 |
| -from typing import Dict, List, NamedTuple, Optional, Tuple |
| 10 | +from typing import Dict, List, NamedTuple, Optional, Tuple, Union |
11 | 11 |
|
12 | 12 | import numpy as np
|
13 | 13 | import pandas as pd
|
@@ -928,7 +928,7 @@ def _rescale_capabilities_to_capture_effective_capability(self):
|
928 | 928 | # Only rescale if rescaling factor is greater than 1 (i.e. don't reduce
|
929 | 929 | # available capabilities if these were under-used the previous year).
|
930 | 930 | rescaling_factor = self._summary_counter.frac_time_used_by_officer_type_and_level(
|
931 |
| - officer_type, level |
| 931 | + officer_type=officer_type, level=level |
932 | 932 | )
|
933 | 933 | if rescaling_factor > 1 and rescaling_factor != float("inf"):
|
934 | 934 | self._daily_capabilities[officer] *= rescaling_factor
|
@@ -1678,7 +1678,7 @@ def write_to_never_ran_hsi_log(
|
1678 | 1678 | def log_current_capabilities_and_usage(self):
|
1679 | 1679 | """
|
1680 | 1680 | This will log the percentage of the current capabilities that is used at each Facility Type, according the
|
1681 |
| - `runnning_total_footprint`. |
| 1681 | + `runnning_total_footprint`. This runs every day. |
1682 | 1682 | """
|
1683 | 1683 | current_capabilities = self.capabilities_today
|
1684 | 1684 | total_footprint = self.running_total_footprint
|
@@ -2506,7 +2506,6 @@ def _reset_internal_stores(self) -> None:
|
2506 | 2506 |
|
2507 | 2507 | self._frac_time_used_overall = [] # Running record of the usage of the healthcare system
|
2508 | 2508 | self._sum_of_daily_frac_time_used_by_officer_type_and_level = Counter()
|
2509 |
| - |
2510 | 2509 | self._squeeze_factor_by_hsi_event_name = defaultdict(list) # Running record the squeeze-factor applying to each
|
2511 | 2510 | # treatment_id. Key is of the form:
|
2512 | 2511 | # "<TREATMENT_ID>:<HSI_EVENT_NAME>"
|
@@ -2561,7 +2560,7 @@ def record_hs_status(
|
2561 | 2560 | self._sum_of_daily_frac_time_used_by_officer_type_and_level[officer_type_facility_level] += fraction_time
|
2562 | 2561 |
|
2563 | 2562 | def write_to_log_and_reset_counters(self):
|
2564 |
| - """Log summary statistics reset the data structures.""" |
| 2563 | + """Log summary statistics reset the data structures. This usually occurs at the end of the year.""" |
2565 | 2564 |
|
2566 | 2565 | logger_summary.info(
|
2567 | 2566 | key="HSI_Event",
|
@@ -2600,16 +2599,47 @@ def write_to_log_and_reset_counters(self):
|
2600 | 2599 | },
|
2601 | 2600 | )
|
2602 | 2601 |
|
2603 |
| - self._reset_internal_stores() |
2604 |
| - |
2605 |
| - def frac_time_used_by_officer_type_and_level(self, officer_type, level): |
2606 |
| - """Average fraction of time used by officer type and level since last reset.""" |
2607 |
| - # Use len(self._frac_time_used_overall) as proxy for number of days in past year. |
2608 |
| - return ( |
2609 |
| - self._sum_of_daily_frac_time_used_by_officer_type_and_level[officer_type, level] |
2610 |
| - / len(self._frac_time_used_overall) |
| 2602 | + # Log mean of 'fraction time used by officer type and facility level' from daily entries from the previous |
| 2603 | + # year. |
| 2604 | + logger_summary.info( |
| 2605 | + key="Capacity_By_OfficerType_And_FacilityLevel", |
| 2606 | + description="The fraction of healthcare worker time that is used each day, averaged over this " |
| 2607 | + "calendar year, for each officer type at each facility level.", |
| 2608 | + data=flatten_multi_index_series_into_dict_for_logging( |
| 2609 | + self.frac_time_used_by_officer_type_and_level()), |
2611 | 2610 | )
|
2612 | 2611 |
|
| 2612 | + self._reset_internal_stores() |
| 2613 | + |
| 2614 | + def frac_time_used_by_officer_type_and_level( |
| 2615 | + self, |
| 2616 | + officer_type: Optional[str]=None, |
| 2617 | + level: Optional[str]=None, |
| 2618 | + ) -> Union[float, pd.Series]: |
| 2619 | + """Average fraction of time used by officer type and level since last reset. |
| 2620 | + If `officer_type` and/or `level` is not provided (left to default to `None`) then a pd.Series with a multi-index |
| 2621 | + is returned giving the result for all officer_types/levels.""" |
| 2622 | + |
| 2623 | + if (officer_type is not None) and (level is not None): |
| 2624 | + return ( |
| 2625 | + self._sum_of_daily_frac_time_used_by_officer_type_and_level[officer_type, level] |
| 2626 | + / len(self._frac_time_used_overall) |
| 2627 | + # Use len(self._frac_time_used_overall) as proxy for number of days in past year. |
| 2628 | + ) |
| 2629 | + else: |
| 2630 | + # Return multiple in the form of a pd.Series with multiindex |
| 2631 | + mean_frac_time_used = { |
| 2632 | + (_officer_type, _level): v / len(self._frac_time_used_overall) |
| 2633 | + for (_officer_type, _level), v in self._sum_of_daily_frac_time_used_by_officer_type_and_level.items() |
| 2634 | + if (_officer_type == officer_type or officer_type is None) and (_level == level or level is None) |
| 2635 | + } |
| 2636 | + return pd.Series( |
| 2637 | + index=pd.MultiIndex.from_tuples( |
| 2638 | + mean_frac_time_used.keys(), |
| 2639 | + names=['OfficerType', 'FacilityLevel'] |
| 2640 | + ), |
| 2641 | + data=mean_frac_time_used.values() |
| 2642 | + ).sort_index() |
2613 | 2643 |
|
2614 | 2644 | class HealthSystemChangeParameters(Event, PopulationScopeEventMixin):
|
2615 | 2645 | """Event that causes certain internal parameters of the HealthSystem to be changed; specifically:
|
|
0 commit comments