From b24e4d46e4463c496334819c640b07315bb4178a Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 2 Jun 2026 14:03:34 +0000 Subject: [PATCH] refactor(baseline): clearer divergence-threshold constant names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR feedback: the threshold constants were obscure. Rename to state intent — _SAP10_2_FLOOR -> _MIN_TRUSTED_SAP_VERSION, _SAP_ABS_TOL -> _MAX_SAP_SCORE_DIVERGENCE, _REL_TOL -> _MAX_RELATIVE_DIVERGENCE — matching the existing _log_divergence vocabulary, and fold the rationale into the comments: the calculator emits a continuous SAP score vs the lodged rounded integer, so a gap up to 0.5 is rounding, beyond it a genuine disagreement worth recording; CO2/PEUI are not rounded so they get a 1% relative band. Behaviour unchanged. Co-Authored-By: Claude Opus 4.8 --- .../calculator_rebaseliner.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/domain/property_baseline/calculator_rebaseliner.py b/domain/property_baseline/calculator_rebaseliner.py index 184f56b0..9c412c4e 100644 --- a/domain/property_baseline/calculator_rebaseliner.py +++ b/domain/property_baseline/calculator_rebaseliner.py @@ -12,12 +12,19 @@ if TYPE_CHECKING: logger = logging.getLogger(__name__) -# The calculator targets SAP 10.2 (14-03-2025). A cert lodged below this carries -# a superseded methodology and is rebaselined to the calculator's output; at or -# above it, the API's lodged figures are kept and the calculator only validates. -_SAP10_2_FLOOR = 10.2 -_SAP_ABS_TOL = 0.5 -_REL_TOL = 0.01 +# Lodged figures are trusted from SAP 10.2 (14-03-2025) onward — the version the +# calculator targets. A cert lodged below this carries a superseded methodology, +# so the calculator's output replaces it; at or above it the lodged figures are +# kept and the calculator only validates against them. +_MIN_TRUSTED_SAP_VERSION = 10.2 + +# Divergence thresholds for that validation log. The calculator emits a +# *continuous* SAP score whereas the lodged score is rounded to an integer, so a +# gap up to half a point is just rounding — beyond it the calculator and the +# register genuinely disagree and we record it. CO2 and Primary Energy Intensity +# are not rounded that way, so they get a 1% relative band instead. +_MAX_SAP_SCORE_DIVERGENCE = 0.5 +_MAX_RELATIVE_DIVERGENCE = 0.01 _KG_PER_TONNE = 1000.0 @@ -49,7 +56,7 @@ class CalculatorRebaseliner(Rebaseliner): # load-bearing, so the batch aborts and the cert is fixed at once. result: SapResult = self._calculator.calculate(effective_epc) sap_version: Optional[float] = effective_epc.sap_version - if sap_version is not None and sap_version < _SAP10_2_FLOOR: + if sap_version is not None and sap_version < _MIN_TRUSTED_SAP_VERSION: return Performance.from_sap_result(result), "pre_sap10" self._log_divergence( property_id=property_id, sap_version=sap_version, result=result, lodged=lodged @@ -64,15 +71,15 @@ class CalculatorRebaseliner(Rebaseliner): result: "SapResult", lodged: Performance, ) -> None: - if abs(result.sap_score_continuous - lodged.sap_score) > _SAP_ABS_TOL: + if abs(result.sap_score_continuous - lodged.sap_score) > _MAX_SAP_SCORE_DIVERGENCE: self._warn(property_id, sap_version, "sap_score", lodged.sap_score, result.sap_score_continuous) - if _relative_diff(result.primary_energy_kwh_per_m2, lodged.primary_energy_intensity) > _REL_TOL: + if _relative_diff(result.primary_energy_kwh_per_m2, lodged.primary_energy_intensity) > _MAX_RELATIVE_DIVERGENCE: self._warn( property_id, sap_version, "primary_energy_intensity", lodged.primary_energy_intensity, result.primary_energy_kwh_per_m2, ) calculated_co2_t = result.co2_kg_per_yr / _KG_PER_TONNE - if _relative_diff(calculated_co2_t, lodged.co2_emissions) > _REL_TOL: + if _relative_diff(calculated_co2_t, lodged.co2_emissions) > _MAX_RELATIVE_DIVERGENCE: self._warn(property_id, sap_version, "co2_emissions", lodged.co2_emissions, calculated_co2_t) def _warn(