Model/datatypes
Khalim Conn-Kowlessar 8e752e5720 Slice 92: API mapper floor dimensions (SAP +0.25m + exposed-floor + NI→None)
Three coupled API-mapper fixes that close the cert 001479 floor-W/K
gap from +4.39 to EXACT 0.

(1) Upper-floor room_height_m += 0.25 m

SAP 10.2 convention: every storey above the lowest adds 0.25 m to the
lodged room_height for the joist/floor-void contribution (cohort
Elmhurst mapper already applies this via `_UPPER_FLOOR_HEIGHT_ADD_M`
at line 2338). The API schema lodges the raw internal height; the
cascade volume computation needs the +0.25 m before computing party-
wall area and ventilation ACH. For cert 001479 Main floor=1, raw
lodge 2.28 m vs worksheet 2.53 m — without the fix, party W/K was
short by 0.87 (party_wall_length × delta_height × U).

(2) `is_exposed_floor=True` when `bp.floor_heat_loss == 1`

API integer code 1 on `floor_heat_loss` signals an exposed floor (a
bp's lowest storey hanging over an unheated space or external air).
Mirrors the cohort Elmhurst mapper's `_is_floor_exposed_to_unheated_
space` for the API path. Applied only to the lowest storey (floor==0)
per the cohort 000490/000487 fixture convention. For cert 001479
Ext2 (cantilevered upper-storey extension over external air), this
routes the cascade through Table 20's `u_exposed_floor` (U=1.20)
rather than the BS EN ISO 13370 ground-floor formula.

(3) `floor_insulation_thickness="NI" → None` for cascade default

API certs commonly lodge "NI" (no measured thickness) on floors that
aren't actually uninsulated — for newer age bands (I-M with non-zero
Table 19 defaults: 25/75/100/100/140 mm) the cascade should use the
age-band default insulation rather than treating "NI" as explicit
zero. Translate "NI" → None at the mapper boundary so `u_floor`
reaches the Table 19 fallback. For cert 001479 Ext1 (age M, suspended
timber, NI lodged) the cascade now returns U=0.20 via the age-M
140 mm default — previously gave U=1.05 from treating thickness as 0.

**Floor W/K is now EXACT for cert 001479** (23.1705 ✓).

Impact on cert 001479 API path:
  Before Slice 87: +3.0752 SAP delta
  After  Slice 90: +1.5298
  After  Slice 91: +1.0970
  After  Slice 92: +1.0022 (floor W/K exact; remaining gap is in
                            windows / gains — Slice 93)

Golden cert residual updates: 7 of 10 expectations shifted from the
floor cascade improvements (NI→None changed many certs with age I-M
extensions). Spec-compliance shifts; new residuals committed.

Pyright: mapper.py 33 → 33.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 08:09:28 +00:00
..
epc Slice 92: API mapper floor dimensions (SAP +0.25m + exposed-floor + NI→None) 2026-05-26 08:09:28 +00:00
magicplan typing and renaming 🟪 2026-05-07 13:26:49 +00:00
__init__.py further breaking up code 2023-07-20 12:24:34 +01:00
datatypes.py further breaking up code 2023-07-20 12:24:34 +01:00
enums.py completed build of new demo portfolio - some fixed required still 2023-11-20 14:42:16 +00:00