refactor: lift-and-shift packages/domain/src/domain/ml → domain/sap10_ml

Sibling migration to the sap10_calculator move — `domain.ml` now lives
at the root-level layout (`domain/sap10_ml/`) matching the pattern
already used by `domain.addresses`, `domain.tasks`, `domain.postcode`,
and `domain.sap10_calculator`.

Changes:

- `git mv packages/domain/src/domain/ml → domain/sap10_ml` (19 files;
  history preserved).
- Subpackage rename: `domain.ml` → `domain.sap10_ml`. 32 references
  rewritten across .py and .md files: 11 internal + 21 external
  (datatypes/epc/domain/mapper.py, 14 files in domain/sap10_calculator,
  2 backend tests, 2 ADRs, 1 README, 1 design doc).
- Path-string updates: `pytest.ini` testpath
  `packages/domain/src/domain/ml/tests` → `domain/sap10_ml/tests` so
  ML tests stay in the default auto-discovered sweep. `CONTEXT.md`
  also updated.

`packages/domain/src/domain/` is now empty — the workspace `domain/`
tree has been fully migrated. Together with the `domain/__init__.py`
deletions from the sap10_calculator commit (29ac35cc), `domain` is
now a single root-level namespace package with subpackages
{addresses, sap10_calculator, sap10_ml, tasks} + the standalone
`postcode.py` module.

Verified:

- Focused sweep (backend mapper-chain + sap10_calculator worksheet
  e2e + golden fixtures): 99 passed / 19 failed — identical baseline.
- Wider sweep (all sap10_calculator + sap10_ml): 1654 passed / 20
  failed (same pre-existing failures).
- domain/sap10_ml/tests: 210/210 PASSED at new path.
- Pyright net-zero: heat_transmission.py 13, cert_to_inputs.py 35,
  mapper.py 33, rdsap_uvalues.py 1 (all unchanged from baseline).

Note: `packages/domain/pyproject.toml` still declares
`packages = ["src/domain"]` for the hatchling wheel — that target
directory is now empty and the wheel build is effectively a no-op.
Retiring the workspace package or repointing the wheel is a follow-up.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-26 13:01:35 +00:00
parent 29ac35ccbe
commit 68401c517a
42 changed files with 55 additions and 55 deletions

View file

@ -132,7 +132,7 @@ _Avoid_: outlier, mismatch, divergence flag
### ML training
**EPC ML Transform**:
The versioned class at `packages/domain/src/domain/ml/transform.py` that maps an EpcPropertyData to a fixed-width row of features + targets. The single ML-data contract between this repo and the AutoGluon training repo. Owns the windows compression, building-parts compression, Top-N Code Taxonomy, and UCL folding decisions. Each version is tagged on the deployed scoring lambda; a mismatch is a deploy-time fail.
The versioned class at `domain/sap10_ml/transform.py` that maps an EpcPropertyData to a fixed-width row of features + targets. The single ML-data contract between this repo and the AutoGluon training repo. Owns the windows compression, building-parts compression, Top-N Code Taxonomy, and UCL folding decisions. Each version is tagged on the deployed scoring lambda; a mismatch is a deploy-time fail.
_Avoid_: feature builder, ML mapper, EPC vectoriser
**Feature Schema Version**:

View file

@ -412,7 +412,7 @@ For tests, each repo has a `FakeXRepo` companion backed by a dict. Service unit
| Concern | Owner |
|---|---|
| Defining the EPC → features transform | **This repo** (`ara.domain.ml.EpcMlTransform`) |
| Defining the EPC → features transform | **This repo** (`ara.domain.sap10_ml.EpcMlTransform`) |
| Loading data, applying transform, writing training parquet to S3 | **This repo** (sub-PRD (ii) batch job) |
| Training, hyperparameter search, deployment | **Autogluon repo** |
| Scoring at modelling time | **This repo** (`FeatureBuilder` calls `EpcMlTransform`, sends DataFrame to deployed lambda) |

View file

@ -140,12 +140,12 @@ class TestBuildingPart:
def test_wall_construction(self, result: EpcPropertyData) -> None:
# SAP10 wall_construction integer: 4 = Cavity (per
# domain.ml.rdsap_uvalues.WALL_CAVITY).
# domain.sap10_ml.rdsap_uvalues.WALL_CAVITY).
assert result.sap_building_parts[0].wall_construction == 4
def test_wall_insulation_type(self, result: EpcPropertyData) -> None:
# SAP10 wall_insulation_type integer: 2 = Filled cavity (per
# domain.ml.rdsap_uvalues.WALL_INSULATION_FILLED_CAVITY).
# domain.sap10_ml.rdsap_uvalues.WALL_INSULATION_FILLED_CAVITY).
assert result.sap_building_parts[0].wall_insulation_type == 2
def test_wall_thickness_measured(self, result: EpcPropertyData) -> None:

View file

@ -1974,7 +1974,7 @@ def _leading_code(value: str) -> str:
# Elmhurst wall-type codes mapped to SAP10 wall_construction integers
# (matches the constants defined in domain.ml.rdsap_uvalues).
# (matches the constants defined in domain.sap10_ml.rdsap_uvalues).
_ELMHURST_WALL_CODE_TO_SAP10: Dict[str, int] = {
"ST": 1, # Stone (granite/sandstone) — placeholder; sandstone vs granite
# ambiguity resolved downstream via walls[].description.
@ -1990,7 +1990,7 @@ _ELMHURST_WALL_CODE_TO_SAP10: Dict[str, int] = {
# Elmhurst wall-insulation-type codes mapped to the SAP10 integer enum
# documented at domain.ml.rdsap_uvalues.WALL_INSULATION_FILLED_CAVITY.
# documented at domain.sap10_ml.rdsap_uvalues.WALL_INSULATION_FILLED_CAVITY.
_ELMHURST_INSULATION_CODE_TO_SAP10: Dict[str, int] = {
"E": 1, # External wall insulation
"F": 2, # Filled cavity

View file

@ -79,7 +79,7 @@ domain/sap10_calculator/
cascade_defaults.py # the RdSAP10 "assume-typical" rules (currently in rdsap_uvalues.py)
```
The existing `domain.ml.*` modules stay where they are during Session A; they continue serving the live ML pipeline. Session B promotes them into `domain.sap10_calculator.*` once parity is reached.
The existing `domain.sap10_ml.*` modules stay where they are during Session A; they continue serving the live ML pipeline. Session B promotes them into `domain.sap10_calculator.*` once parity is reached.
## Sap10Calculator interface
@ -147,7 +147,7 @@ Re-derivation work is bounded — a few hundred numbers across tables — and th
## Consequences
- A new top-level domain area `domain.sap10_calculator.*` is introduced; over Sessions B/C it absorbs `domain.ml.{envelope,demand,ecf,rdsap_uvalues,sap_efficiencies,ventilation}.py`. The ML transform stops shipping those as standalone features once the residual head takes over.
- A new top-level domain area `domain.sap10_calculator.*` is introduced; over Sessions B/C it absorbs `domain.sap10_ml.{envelope,demand,ecf,rdsap_uvalues,sap_efficiencies,ventilation}.py`. The ML transform stops shipping those as standalone features once the residual head takes over.
- The codebase carries two SAP outputs: cert-reported `sap_score` (ground truth at training time) and calculator-emitted `sap_score` (ground truth at inference time for any RdSAP cert input). The product layer chooses; for "score this hypothetical post-retrofit state", calculator wins.
- The deterministic calculator is **version-bound to SAP 10.3.** A future SAP 10.4 is a calculator MAJOR bump and an ADR. The ML residual head is SAP-version-agnostic only insofar as the residual distribution it learns stays stationary; in practice a spec bump retrains the residual head.
- Spec PDFs live in `docs/sap-spec/` (this repo). The repo now carries the canonical reference for what the calculator computes. License: SAP 10.3 © Crown copyright 2026; RdSAP 10 © BRE — both are public-interest references for SAP-compliant software, included for traceability.

View file

@ -120,12 +120,12 @@ Two engine bugs surfaced during the wire-up:
- **000490 SAP integer + fuel cost tests xfail** (strict). Appendix L closure is spec-faithful (lighting kWh 614 → 171 matches U985 (232)=171.4217 to abs=1e-4), but the cost residual widens from -4.7% to -12.9% and SAP delta widens 3 → 6. The remaining residual is from other broken components on this fixture — primary suspects: fuel pricing for the pre-2025-07-01 cohort (Table 32 lodge-date snapshot semantics), main heating fuel +2.5% overshoot, Table D1/D2/D3 Ecodesign corrections, Appendix N heat-pump cascade. Per `feedback-e2e-validation-philosophy` memory: don't widen, hunt. Tests re-enable when each next component closes.
- **Golden fixture `_PE_TOLERANCE_KWH_PER_M2` widened 30 → 35** to absorb the elec-PEF × lighting-Δ contribution (~4 kWh/m²) on the non-Elmhurst cohort. Pre-Appendix-L baseline residuals already sat near -28 kWh/m² from unrelated components on those certs. Tightens back when the dominant remaining components close.
- **Per-component worksheet-level pins land**: `result.lighting_kwh_per_yr == U985 (232)` at abs=1e-4 for the 2 e2e fixtures, and `InternalGainsResult.lighting_kwh_per_yr == U985 (232)` at abs=1e-4 for all 6 §5 fixtures. New per-fixture constant `LINE_232_LIGHTING_KWH_PER_YR` pins each lodged value.
- **`predicted_lighting_kwh` kept** in `domain/ml/demand.py` with a deprecation note. Still used by `domain.ml.ecf.energy_cost_factor` and `domain.ml.transform.transform_to_predictions` — both legacy ML pre-SAP-rewrite call sites; rip when those migrate.
- **`predicted_lighting_kwh` kept** in `domain/ml/demand.py` with a deprecation note. Still used by `domain.sap10_ml.ecf.energy_cost_factor` and `domain.sap10_ml.transform.transform_to_predictions` — both legacy ML pre-SAP-rewrite call sites; rip when those migrate.
### Deferred work (named in Appendix L slice 3)
- **000490 / cohort SAP-integer closure (residual hunt).** Next ticket. Suspects above. Driven by user's next batch of test fixtures (battle-testing the engine) → emergent residual identification.
- **`predicted_lighting_kwh` deletion.** Future cleanup ticket once `domain.ml.ecf` + `domain.ml.transform` are off the legacy heuristic.
- **`predicted_lighting_kwh` deletion.** Future cleanup ticket once `domain.sap10_ml.ecf` + `domain.sap10_ml.transform` are off the legacy heuristic.
- **RdSAP10 → API integration test.** End-state e2e harness: RdSAP API response → `cert_to_inputs``calculate_sap_from_inputs` → SAP integer = lodged integer. Once enough cohort fixtures pass delta=0 on isolated components.
## Amendment — Cohort residual hunt + SAP 10.2 rating constants (2026-05-22)

View file

@ -110,7 +110,7 @@ So a 2.91 m upper-storey internal height appears on the worksheet as 3.16 m. Mir
- Simplified Type 1 (RR lodged with only `floor_area`) still works via the spec's `A_RR = 12.5 × √(A_RR_floor/1.5)` formula at `u_rr_default_all_elements` (Table 18 col 4). Detailed lodgement supersedes when present.
### Party wall U mapping
`party_wall_construction` integer codes resolve via `domain.ml.rdsap_uvalues.u_party_wall`:
`party_wall_construction` integer codes resolve via `domain.sap10_ml.rdsap_uvalues.u_party_wall`:
- `0` (Unknown / "Unable to determine") → 0.25 W/m²K
- `1` (Stone granite) / `3` (Solid brick) / `5` (Timber frame) / `6` (System built) → 0.0
- `4` (Cavity, unfilled) → 0.5

View file

@ -61,9 +61,9 @@ from datatypes.epc.domain.epc_property_data import (
SapWindow,
)
from domain.ml.demand import predicted_hot_water_kwh
from domain.ml.rdsap_uvalues import Country, u_floor
from domain.ml.sap_efficiencies import (
from domain.sap10_ml.demand import predicted_hot_water_kwh
from domain.sap10_ml.rdsap_uvalues import Country, u_floor
from domain.sap10_ml.sap_efficiencies import (
seasonal_efficiency,
water_heating_efficiency as _legacy_water_heating_efficiency,
)
@ -805,7 +805,7 @@ def _other_fuel_cost_gbp_per_kwh(
# Water-heating codes that say "inherit from the main system" — the
# `seasonal_efficiency` cascade returns 0 as a sentinel for these in the
# legacy `domain.ml.sap_efficiencies` module. We need to inherit through
# legacy `domain.sap10_ml.sap_efficiencies` module. We need to inherit through
# the SAME cascade the main heating uses, including the main_heating_
# category fallback (e.g. heat pumps return 2.30 via category 4).
_WATER_INHERIT_FROM_MAIN_CODES: Final[frozenset[int]] = frozenset({901, 902, 914})

View file

@ -20,7 +20,7 @@ import pytest
from datatypes.epc.domain.epc_property_data import MainHeatingDetail, PhotovoltaicArray
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_building_part,
make_floor_dimension,
make_minimal_sap10_epc,

View file

@ -202,7 +202,7 @@ _DEFAULT_CO2_KG_PER_KWH: Final[float] = 0.210 # mains gas baseline
# Gov EPC API main_fuel_type → SAP 10.3 Table 12 fuel code. Lifted from
# the SAP 10.2 mapper (`domain.ml.sap_efficiencies._API_TO_TABLE32`) —
# the SAP 10.2 mapper (`domain.sap10_ml.sap_efficiencies._API_TO_TABLE32`) —
# the API enum and Table 32/12 codes are unchanged across spec versions.
API_FUEL_TO_TABLE_12: Final[dict[int, int]] = {
0: 30, 1: 1, 2: 2, 3: 3, 4: 4, 5: 15, 6: 20, 7: 23, 8: 21, 9: 10,

View file

@ -23,13 +23,13 @@ Worksheet line mapping (SAP 10.2 §3, canonical xlsx rows 121-207):
(36) thermal bridging = y × Σ exposed area (RdSAP Table 21)
(37) total fabric heat loss = (33) + (36)
This is the calculator-vocabulary sibling of `domain.ml.envelope`. During
This is the calculator-vocabulary sibling of `domain.sap10_ml.envelope`. During
Session A both modules coexist the legacy envelope.py continues to feed
the ML transform's `envelope_heat_loss_w_per_k` physics-feature. Session B
will retire envelope.py in favour of this module (ADR-0009 §"Module
layout").
U-value lookups cascade through `domain.ml.rdsap_uvalues` migrating to
U-value lookups cascade through `domain.sap10_ml.rdsap_uvalues` migrating to
`domain.sap10_calculator.rdsap.cascade_defaults` in Session B.
Reference: SAP 10.2 specification §3 (pages 17-22); RdSAP 10 §5 (Tables
@ -49,7 +49,7 @@ from datatypes.epc.domain.epc_property_data import (
SapRoofWindow,
)
from domain.ml.rdsap_uvalues import (
from domain.sap10_ml.rdsap_uvalues import (
Country,
WALL_UNKNOWN,
_described_as_insulated,

View file

@ -31,7 +31,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -29,7 +29,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -30,7 +30,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -28,7 +28,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -33,7 +33,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -36,7 +36,7 @@ from datatypes.epc.domain.epc_property_data import (
ShowerOutlet,
ShowerOutlets,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -70,7 +70,7 @@ from datatypes.epc.domain.epc_property_data import (
SapVentilation,
SapWindow,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_main_heating_detail,
make_minimal_sap10_epc,
make_sap_heating,

View file

@ -21,7 +21,7 @@ from datatypes.epc.domain.epc_property_data import (
SapRoomInRoof,
)
from datatypes.epc.domain.mapper import EpcPropertyDataMapper
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_building_part,
make_floor_dimension,
make_minimal_sap10_epc,

View file

@ -7,7 +7,7 @@ a typed `HeatTransmission` breakdown so callers can audit each
worksheet contribution.
U-values cascade through the RdSAP 10 §5 defaults (currently implemented
in `domain.ml.rdsap_uvalues` migrates to `domain.sap10_calculator.rdsap.cascade_defaults`
in `domain.sap10_ml.rdsap_uvalues` migrates to `domain.sap10_calculator.rdsap.cascade_defaults`
in Session B).
Reference: SAP 10.3 specification §3 (pages 17-22);
@ -25,7 +25,7 @@ from datatypes.epc.domain.epc_property_data import (
SapRoomInRoofSurface,
)
from domain.ml.tests._fixtures import (
from domain.sap10_ml.tests._fixtures import (
make_building_part,
make_floor_dimension,
make_minimal_sap10_epc,

View file

@ -43,7 +43,7 @@ from datatypes.epc.domain.epc_property_data import (
SapHeating,
SapWindow,
)
from domain.ml.tests._fixtures import make_minimal_sap10_epc
from domain.sap10_ml.tests._fixtures import make_minimal_sap10_epc
from domain.sap10_calculator.worksheet.tests._elmhurst_fixtures import ALL_FIXTURES, fixture_id

View file

@ -18,7 +18,7 @@ from datatypes.epc.domain.epc_property_data import (
SapWindow,
WindowTransmissionDetails,
)
from domain.ml.tests._fixtures import make_minimal_sap10_epc, make_window
from domain.sap10_ml.tests._fixtures import make_minimal_sap10_epc, make_window
from domain.sap10_calculator.worksheet.internal_gains import OvershadingCategory
from domain.sap10_calculator.worksheet.solar_gains import (
Orientation,

View file

@ -235,8 +235,8 @@ def predicted_lighting_kwh(
cascade is in `domain.sap10_calculator.worksheet.internal_gains.annual_lighting_kwh`
and is what `cert_to_inputs` now plumbs into `inputs.lighting_kwh_per_yr`.
This heuristic over-counts ~3× on the Elmhurst cohort (528 vs 140 kWh
on 000474). Kept only for `domain.ml.ecf.energy_cost_factor` and
`domain.ml.transform.transform_to_predictions` legacy ML predictor
on 000474). Kept only for `domain.sap10_ml.ecf.energy_cost_factor` and
`domain.sap10_ml.transform.transform_to_predictions` legacy ML predictor
callsites that pre-date the SAP rewrite. Rip when those migrate.
See ADR-0010 amendment "Appendix L lighting (2026-05-22)".
"""

View file

@ -15,7 +15,7 @@ from __future__ import annotations
from math import log10
from typing import Final, Optional
from domain.ml.sap_efficiencies import fuel_unit_price_p_per_kwh
from domain.sap10_ml.sap_efficiencies import fuel_unit_price_p_per_kwh
# SAP10 deflator applied to total cost before the rating equation (Table 32).

View file

@ -15,7 +15,7 @@ from typing import Any, Optional
from datatypes.epc.domain.epc_property_data import SapBuildingPart
from domain.ml.rdsap_uvalues import (
from domain.sap10_ml.rdsap_uvalues import (
Country,
WALL_CAVITY,
WALL_UNKNOWN,

View file

@ -2,7 +2,7 @@
import pytest
from domain.ml.demand import (
from domain.sap10_ml.demand import (
predicted_hot_water_kwh,
predicted_lighting_kwh,
predicted_space_heating_kwh,

View file

@ -5,7 +5,7 @@ from math import log10
import pytest
from domain.ml.ecf import (
from domain.sap10_ml.ecf import (
predicted_ecf,
predicted_log10_ecf,
predicted_pv_generation_kwh,

View file

@ -6,8 +6,8 @@ test cases stay close to the shape transform.py sees on a real cert.
import pytest
from domain.ml.envelope import envelope_heat_loss_w_per_k
from domain.ml.tests._fixtures import make_building_part, make_floor_dimension
from domain.sap10_ml.envelope import envelope_heat_loss_w_per_k
from domain.sap10_ml.tests._fixtures import make_building_part, make_floor_dimension
def test_envelope_single_storey_no_windows_no_doors_age_g_cavity_returns_expected_w_per_k() -> None:

View file

@ -20,7 +20,7 @@ from typing import Optional
import pytest
from domain.ml.rdsap_uvalues import (
from domain.sap10_ml.rdsap_uvalues import (
Country,
WALL_CAVITY,
WALL_INSULATION_FILLED_CAVITY,

View file

@ -11,7 +11,7 @@ Helpers never raise on missing codes; they fall back to typical-fuel values.
import pytest
from domain.ml.sap_efficiencies import (
from domain.sap10_ml.sap_efficiencies import (
fuel_unit_price_p_per_kwh,
seasonal_efficiency,
water_heating_efficiency,

View file

@ -8,8 +8,8 @@ from datatypes.epc.domain.epc_property_data import (
SapRoomInRoof,
WindowTransmissionDetails,
)
from domain.ml.schema import ColumnSpec, TransformSchema
from domain.ml.tests._fixtures import (
from domain.sap10_ml.schema import ColumnSpec, TransformSchema
from domain.sap10_ml.tests._fixtures import (
make_building_part,
make_floor_dimension,
make_main_heating_detail,
@ -18,7 +18,7 @@ from domain.ml.tests._fixtures import (
make_sap_heating,
make_window,
)
from domain.ml.transform import EpcMlTransform
from domain.sap10_ml.transform import EpcMlTransform
_EXPECTED_TARGET_DTYPES: dict[str, type] = {
@ -1269,7 +1269,7 @@ def test_schema_advertises_envelope_heat_loss_feature() -> None:
def test_to_row_emits_positive_envelope_heat_loss_for_sap10_epc() -> None:
# Arrange
from domain.ml.tests._fixtures import make_building_part, make_floor_dimension
from domain.sap10_ml.tests._fixtures import make_building_part, make_floor_dimension
main = make_building_part(
identifier=BuildingPartIdentifier.MAIN,

View file

@ -9,7 +9,7 @@ fixed m³/h additions; draught-proofed windows reduce the structural baseline.
import pytest
from domain.ml.ventilation import ventilation_heat_loss_w_per_k
from domain.sap10_ml.ventilation import ventilation_heat_loss_w_per_k
def test_ventilation_bare_masonry_no_openings_returns_structural_baseline_only() -> None:

View file

@ -24,22 +24,22 @@ from datatypes.epc.domain.epc_property_data import (
SapHeating,
SapWindow,
)
from domain.ml.demand import (
from domain.sap10_ml.demand import (
predicted_hot_water_kwh,
predicted_lighting_kwh,
predicted_space_heating_kwh,
)
from domain.ml.ecf import (
from domain.sap10_ml.ecf import (
predicted_ecf,
predicted_log10_ecf,
predicted_pv_generation_kwh,
predicted_total_fuel_cost_gbp,
)
from domain.ml.envelope import envelope_heat_loss_w_per_k
from domain.ml.ventilation import ventilation_heat_loss_w_per_k
from domain.ml.sap_efficiencies import seasonal_efficiency, water_heating_efficiency
from domain.ml.schema import ColumnSpec, TransformSchema
from domain.ml.ucl import apply_ucl_correction
from domain.sap10_ml.envelope import envelope_heat_loss_w_per_k
from domain.sap10_ml.ventilation import ventilation_heat_loss_w_per_k
from domain.sap10_ml.sap_efficiencies import seasonal_efficiency, water_heating_efficiency
from domain.sap10_ml.schema import ColumnSpec, TransformSchema
from domain.sap10_ml.ucl import apply_ucl_correction
# SAP10 orientation codes: 1=N, 2=NE, 3=E, 4=SE, 5=S, 6=SW, 7=W, 8=NW.

View file

@ -25,6 +25,6 @@ testpaths =
etl/epc_clean/tests
etl/hubspot/tests
etl/spatial/tests
packages/domain/src/domain/ml/tests
domain/sap10_ml/tests
markers =
integration: mark a test as an integration test