KPI Class¶
CalculateKPIS¶
The entrypoint for everything relevant to KPIs should be the CalculateKPIS
class. Missing functionality should be added to this class.
This class is responsible for calculating all KPIs for a given subset of of patients, set through its self.patients attribute. There are various methods used to calculate KPIs for different abstractions, but each method is a wrapper that works to set the self.patients attribute, and then they all call the _calculate_kpis method.
Initialisation¶
To initialise an instance of the CalculateKPIS class, you can pass in optional parameters to define the audit period and whether to return patient querysets as part of the KPI calculations.
Parameters
-
calculation_date(date, optional): The date used to define the start and end dates of the audit period, used throughout calculations. If no date is provided, the current date is used as the default. -
return_pt_querysets(bool, optional): If set toTrue, the calculated KPIs will include patient querysets used during the KPI calculation. The default isFalse. -
is_jersey(bool, optional): If set toTrueassumes the unique identifier for all patient queries isunique_reference_numberrather thannhs_number. The default isFalse.
from datetime import date
from project.npda.kpi_class.kpis import CalculateKPIS
# Initialise with default parameters
kpi_calculator = CalculateKPIS()
# Example 2: Initialise with a specific audit date
calculation_date = date(2023, 1, 1)
kpi_calculator_SPECIFIC_DATE = CalculateKPIS(calculation_date=calculation_date)
Calculation methods¶
We can then use one of the calculate_kpis_for_ methods to calculate KPIs:
1) calculate_kpis_for_patients (QuerySet[Patient])
- Calculate KPIs for given patients.
2) calculate_kpis_for_pdus (list[str])
- Calculate KPIs for given PZ codes.
All calculate_ methods return a KPICalculationsObject. This is used to represent the results of calculations across the specified audit period. It contains information about the audit dates, the total number of patients involved, and the calculated KPI results. It looks like:
@dataclass
class KPICalculationsObject:
calculation_datetime: datetime
audit_start_date: date
audit_end_date: date
total_patients_count: int
calculated_kpi_values: Dict[
str,
KPIResult,
]
Actual calculation results can be retrieved using the calculated_kpi_values key.
This is a dictionary where the key is the KPI name and the value is a KPIResult object. This object contains the calculated KPI value and the patient querysets used during the calculation (if return_pt_querysets was set to True during CalculateKPIS initialisation).
The KPI name for keys comes from kpi_name_registry (described later). The values are KPIResult objects that look like:
@dataclass
class KPIResult:
"""
Example would be:
`return_patient_querysets` == False
{
'total_eligible': 100,
'total_ineligible': 50,
'total_passed': 75,
'total_failed': 25,
'patient_querysets': None
}
`return_patient_querysets` == True
{
'total_eligible': 100,
'total_ineligible': 50,
'total_passed': 75,
'total_failed': 25,
'patient_querysets': {
'eligible': <QuerySet[Patient]>,
'ineligible': <QuerySet[Patient]>,
'passed': <QuerySet[Patient]>,
'failed': <QuerySet[Patient]>,
}
}
"""
total_eligible: int
total_ineligible: int
total_passed: Union[int | None] # E.g. KPIs 1-12 would be None as counts
total_failed: Union[int | None] # E.g. KPIs 1-12 would be None as counts
kpi_label: str = "KPI Name not found"
patient_querysets: Union[Dict[str, QuerySet[Patient]], None] = None
Example usage¶
class PatientVisitsListView(
...
):
...
def get_context_data(self, **kwargs):
patient_id = self.kwargs.get("patient_id")
context = super(PatientVisitsListView, self).get_context_data(**kwargs)
patients = Patient.objects.filter(pk=patient_id)
...
calculate_kpis = CalculateKPIS(
calculation_date=datetime.date.today(), return_pt_querysets=False
)
# Calculate the KPIs for this patient, returning only subset relevant
# for a single patient's calculation
kpi_calculations_object = calculate_kpis.calculate_kpis_for_patients(patients)
context["kpi_results"] = kpi_calculations_object
return context
kpi_name_registry¶
The CalculateKPIS object has a .kpi_name_registry attribute that can be used to access both attribute names and rendered label names for each KPI.
The benefit of using this registry is that it allows for a single source of truth for KPI names, which can be used throughout the application. This is particularly useful when needing to access KPI names in multiple places, such as in the frontend and backend.
It exposes the following methods:
get_kpi(self, number: int) -> KPINameswhich returns aKPINamesobject for the given KPI number:
@dataclass
class KPINames:
attribute_name: str # e.g. kpi_32_1_health_check_completion_rate
rendered_label: str # e.g. Care Processes Completion Rate
-
get_attribute_name(self, number: int) -> strwhich returns the attribute name for the given KPI number -
get_rendered_label(self, number: int) -> strwhich returns the rendered label name for the given KPI number