mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
The cert's `floor_insulation_thickness` field carries "NI" (Not
Indicated) on 58% of corpus certs — by far the most common value. For
~2 413 of those (12% of corpus) the description also says "Solid,
insulated (assumed)" or "Suspended, insulated (assumed)" — the
assessor saw insulation but didn't measure the thickness. Our
`_parse_thickness_mm("NI")` returns 0, which feeds `u_floor` as an
explicit "0 mm" → r_f=0 → uninsulated-floor U-value. Wrong.
RdSAP 10 §5.12 Table 19 footnote (2) (page 46): "For floors which
have retrofitted insulation, use the greater of 50 mm and the
thickness according to the age band". `u_floor` now accepts a
`description` kwarg; when `_described_as_insulated(description)` is
true and the lodged thickness is missing/zero, ins_mm =
max(50, age-band default).
Geometry sanity-check, 100 m² × 40 m perimeter, w=0.3 (B=5):
- Uninsulated solid floor: d_t = 0.615, U = 0.60 W/m²K
- 50 mm assumption: d_t = 2.758, U = 0.31 W/m²K
Parity probe at 300 certs, seed=7:
PE MAE 45.37 → 44.19 (-1.18)
PE bias 39.75 → 38.56 (-1.19)
Band J bias +41.2 → +29.7 (-11.5)
Band K bias +34.1 → +22.4 (-11.7)
Band L bias +19.6 → +11.3 (-8.3)
Band M bias +86.3 → +55.1 (-31.2)
Bands A-H mostly unchanged (max(50, 0) = 50 either way; description
overrides on older stock are rarer in this sample)
The K-L-M dwellings improved most because for them the age-band
default insulation (100-140 mm) is now applied instead of 0 mm.
Cumulative across S-B23 → S-B27:
PE MAE 57.28 → 44.19 (-13.09)
PE bias 51.56 → 38.56 (-13.00)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| domain | ||
| fetchers | ||
| repos | ||
| utils | ||
| README.md | ||
Shared packages
Workspace packages consumed by services/*. Each package is its own Python distribution with its own pyproject.toml; services import via the workspace dependency mechanism ({ workspace = true }).
| Package | Purpose |
|---|---|
domain/ |
Shared domain types — Property, BaselinePerformance, Plan, Scenario, EpcPropertyData, etc. No persistence, no IO, no business logic. |
repos/ |
Persistence layer — one repo per aggregate. Owns the SQL. Depends on domain. |
fetchers/ |
External API clients (gov EPC, Ofgem, Google Solar, etc.). Depend on domain for response shapes. |
utils/ |
Cross-cutting infra — logging, S3, CloudWatch URL builders, SQS task helpers. |
Adding a new shared package
Only when a real second consumer materialises. Don't pre-shatter (repos-epc, repos-property, ...) — split when a deployment needs to drop a dep, not before.
See ../ara_backend_design.md §11 for the broader monorepo layout and ../CONTEXT.md for the domain glossary that names the types living in domain/.