Model/packages/domain
Khalim Conn-Kowlessar afdf297f3b slice S-B31: Table 12c DLF on heat-network main and HW-from-main
Heat-network certs (cat=6) were under-predicted in cost — SAP bias
+6.31 across 13 sample certs, PE bias -15.6 (we under-predicted PE).
Root cause: missing distribution-loss-factor application.

SAP 10.2 spec references:
  - Table 12 note (k): "Cost is per unit of heat generated (i.e.
    before distribution losses); emission and primary factors are per
    unit of fuel used by the heat generator."
  - §C3.1: "Where a heat network is listed in the PCDB, the DLF is
    already factored into the cost, CO2 and PE factors recorded
    therein, so a DLF of 1 should be entered in worksheet (306) to
    avoid double counting." (Implication: non-PCDB networks MUST
    apply DLF.)
  - Table 12c (p. 193): DLF by age band, 1.20 (A pre-1900) →
    1.50 (K+ 2007+).
  - RdSAP 10 §10.11 Table 29 cross-references Table 12c.

Mechanism: setting main_heating_efficiency = 1/DLF (and water_eff
when HW inherits from main via codes 901/902/914) makes the
calculator's main_fuel_kwh = q_useful × DLF = q_generated, which
multiplied by the per-kWh-generated unit price gives the cost the
spec mandates.

Affects:
  - Heat-network main heating (sap_main_heating_code in 301-304 OR
    main_heating_category == 6)
  - HW from main on such certs (water_heating_code in 901/902/914)

Trade-off: CO2/PE for heat-network certs will under-predict ~20%
versus the spec's "fuel-burned × per-fuel-factor" formula, because
our architecture uses one main_fuel_kwh value for cost AND CO2/PE.
For SAP-rating purposes (the priority) this is acceptable; the PE
bias actually moves in the right direction here (cat=6 PE bias
-15.6 → -5.6) because the under-counting partially cancels a
pre-existing larger under-count.

Parity probe at 300 certs, seed=7:
  SAP MAE 4.69 → 4.61 (-0.08)
  SAP bias 0.98 → 0.87 (-0.11)
  PE  MAE 43.32 → 43.11 (-0.21)
  cat=6 PE bias -15.6 → -5.6  (+10.0, correct direction)
  cat=6 PE MAE  40.3 → 35.8   (-4.5)
  cat=6 our_pe  158.5 → 225.0 (cert 230.6 — converged)

Cumulative across S-B23 → S-B31:
  SAP MAE  5.34 → 4.61 (-0.73)
  PE  MAE 57.28 → 43.11 (-14.17)
  PE bias 51.56 → 38.64 (-12.92)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 22:59:36 +00:00
..
src/domain slice S-B31: Table 12c DLF on heat-network main and HW-from-main 2026-05-18 22:59:36 +00:00
pyproject.toml slice 13: to_rows(properties) returns pd.DataFrame 2026-05-16 16:43:28 +00:00
README.md added potential file scaffolding: 2026-05-15 10:56:53 +00:00

domna-domain

Shared domain types — Property, Properties, BaselinePerformance, Plan, PlanPhase, Scenario, ScenarioPhase, ScenarioSnapshot, Recommendation, OptimisedPackage, EpcPropertyData, etc.

Boundary: types only. No persistence, no IO, no business logic. Other packages and services depend on domna-domain; this package depends on nothing internal.

Domain definitions live in ../../CONTEXT.md. New types added here must match the glossary terms.

Layout

src/domain/
├── __init__.py
├── property.py             # Property, Properties, PropertyIdentity
├── site_notes.py
├── landlord_overrides.py
├── baseline_performance.py # lodged + effective pair (ADR-0004)
├── plan.py                 # Plan, PlanPhase, OptimisedPackage
├── scenario.py             # Scenario, ScenarioPhase, ScenarioSnapshot (ADR-0005)
├── recommendation.py
├── geospatial.py
├── solar.py
├── anomaly_flags.py
└── ml/
    ├── __init__.py
    ├── transform.py        # EpcMlTransform (versioned per §8.3)
    └── schema.py

When datatypes/epc/domain/ folds in, the EPC schema types move under src/domain/epc/.