§6 slice 6: cert_to_inputs swaps legacy _solar_gains_w → solar_gains_from_cert

CalculatorInputs.solar_gains_monthly_w now flows from the §6 orchestrator
instead of the legacy per-month leaf. Roof windows + rooflights pass empty
because cert summaries (incl. Elmhurst) don't lodge them distinctly; the
§6 conformance test in test_solar_gains.py exercises the roof glazing path
via SECTION_6_ROOF_WINDOWS fixture overrides.

Behavioural delta vs legacy path: orchestrator's Table 6b uses 0.76 for
glazing codes 2 + 3 (spec-correct: "Double glazed, air or argon filled")
where _window_inputs hardcodes 0.72. Golden cert fixtures remain within
their ±5-SAP tolerance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-20 20:53:51 +00:00
parent 376cdb6bc3
commit cd2bd9cedc

View file

@ -52,7 +52,7 @@ from domain.ml.sap_efficiencies import (
seasonal_efficiency,
water_heating_efficiency as _legacy_water_heating_efficiency,
)
from domain.sap.calculator import CalculatorInputs, WindowInput, _solar_gains_w
from domain.sap.calculator import CalculatorInputs, WindowInput
from domain.sap.tables.table_12 import (
co2_factor_kg_per_kwh,
primary_energy_factor,
@ -67,7 +67,7 @@ from domain.sap.worksheet.heat_transmission import (
DwellingExposure,
heat_transmission_from_cert,
)
from domain.sap.worksheet.solar_gains import Orientation
from domain.sap.worksheet.solar_gains import Orientation, solar_gains_from_cert
from domain.sap.worksheet.ventilation import (
MechanicalVentilationKind,
ventilation_from_inputs,
@ -998,18 +998,16 @@ def cert_to_inputs(
# SAP10.2 line (73)m — total internal gains W/month from §5
# orchestrator (composed above).
internal_gains_monthly_w=internal_gains_monthly_w,
# SAP10.2 line (83)m — total solar gains W/month. Computed here via
# the legacy `_solar_gains_w` per-month leaf to preserve identical
# behaviour during the §6 wiring migration; the next slice swaps
# this for the §6 orchestrator `solar_gains_from_cert`.
solar_gains_monthly_w=tuple(
_solar_gains_w(
windows=_window_inputs(epc.sap_windows),
region=_region_index(epc.region_code),
month=m,
)
for m in range(1, 13)
),
# SAP10.2 line (83)m — total solar gains W/month via §6 orchestrator.
# Cert summaries don't lodge roof windows or rooflights distinctly
# (Elmhurst data shows them all as `window_location = External wall`);
# both pass-throughs are empty. Per-fixture §6 conformance is
# exercised separately in `test_solar_gains.py`.
solar_gains_monthly_w=solar_gains_from_cert(
epc=epc,
region=_region_index(epc.region_code),
overshading=_INTERNAL_GAINS_DEFAULT_OVERSHADING,
).total_solar_gains_monthly_w,
region=_region_index(epc.region_code),
windows=_window_inputs(epc.sap_windows),
control_type=_control_type(main),