Skip to content

fix: store build parameters in model recipes, and refuse what they cannot rebuild - #375

Draft
lachlangrose wants to merge 3 commits into
masterfrom
fix/recipe-build-parameters
Draft

lachlangrose wants to merge 3 commits into
masterfrom
fix/recipe-build-parameters

Conversation

@lachlangrose

Copy link
Copy Markdown
Member

Draft, stacked on #374 (the xfail tests this fixes). Its diff against master includes #374's commit until that merges; the change here is the last commit. Stage 1 of the plan in #374's description.

Problem

A recipe rebuilt every feature with the default build parameters, and as a foliation. See the diagnosis in #374. In short: a model built with non-default nelements, interpolatortype or regularisation rebuilt to a different field (12 to 60 on a field of range about 560); a fault came back as a plain foliation; group_mapping was lost; a model with an unconformity could not be rebuilt at all.

Change

  • Record at creation. GeologicalModel.create_and_add_feature (the single entry point all create_and_add_* methods go through) stores the parameters it was requested with on the feature. The element count the interpolator realised (build_arguments["nelements"]) is deliberately not used: replaying it gave differences of 6 to 25, while replaying the requested count reproduced the field exactly.
  • Write them. Each foliation entry gets build: {feature_type, parameters}, and the stratigraphic column's group_mapping is stored. Additive: the schema version stays 1.
  • Replay them. from_recipe_* rebuilds each feature through create_and_add_feature(feature_type, name, **parameters).
  • Detect kinds correctly. feature_recipe_kind tests subclasses first, so a fault is fault (not structural_frame) and an unconformity is unconformity (not foliation).
  • Refuse what it cannot rebuild yet, instead of writing a recipe that rebuilds wrongly. to_recipe_* raises LoopValueError, naming the feature, for: a non-foliation feature (fault, unconformity, fold, ...), a feature built with its own data=, a parameter JSON cannot hold (e.g. a callable solver), or a feature with no creation record.
  • Older recipes still load (no build entry), with a warning that defaults are used. An older entry whose kind is not foliation is refused.

Behaviour change to be aware of

A model that contains a fault, an unconformity, a fold, or a feature built with data= can no longer be written to a recipe; it raises. Before, it wrote a recipe that rebuilt wrongly (or, for an unconformity, could not be loaded). COMPAT.md has a row. I have not checked whether the QGIS plugin or anything else relies on writing recipes for such models. If that is a concern, the alternative is to warn instead of raise; I chose to raise because a silent wrong rebuild is the worse failure.

Tests

  • test_recipe_reproduces_field.py: the three strict xfails from test: pin the recipe and inequality-constraint problems (strict xfail) #374 now pass and their markers are gone; I added a case with several parameters. The default case passes as before.
  • New test_recipe_limits.py (13 tests): requested (not realised) parameters are stored; data / faults / index are not; group_mapping round trip, and a column without it still loads; fault and unconformity are recognised; each refusal and its message; an older recipe loads with a warning; an older non-foliation entry is refused.
  • Run against the original serializer, 17 of these 18 tests fail (the one that passes is the defaults case, which was always correct).
  • tests: 748 passed, 6 skipped. ruff: no new findings.

Not done (stages 2 and 3)

  • Faults and unconformities (stage 2). The refusal messages say "foliations only".
  • Folds (stage 3): their fold functions are callables, which JSON cannot hold, so this may need a decision on how to describe them.
  • Not tested: intrusions, domain faults, fold frames. They are refused by the same rule (anything not a foliation).
  • custom data= could be supported by storing the data inline per feature; I did not.

🤖 Generated with Claude Code

lachlangrose and others added 2 commits October 29, 2026 14:50
Recipe: to_recipe_json / from_recipe_json do not store a feature's build parameters
(nelements, interpolatortype, regularisation), so a model built with anything but the defaults
rebuilds with the defaults and gives a different field (differences of 12 to 60 on a field of
range about 560). The default-parameter case passes; the three others are strict xfails.

Inequality: ADMM enforces the bounds with the arguments the existing builder test uses, but
with its default arguments returns essentially the unconstrained solution (4 of 24 bounds
violated, worst 0.056), and with solver cg the inequality data are dropped without a warning.
A control (the unconstrained solution does violate bounds) and the working ADMM configuration
pass; the default-ADMM case and the cg-warning expectation are strict xfails.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nnot rebuild

A recipe rebuilt every feature with the default build parameters and as a foliation, so a model
built with non-default nelements, interpolatortype or regularisation gave a different field (12
to 60 on a field of range ~560), a fault came back as a foliation, and a model with an
unconformity could not be rebuilt at all.

- create_and_add_feature records the parameters it was *requested* with on the feature (the
  element count realised by the interpolator would not reproduce the grid)
- the recipe stores them per foliation (build.feature_type, build.parameters) and the reader
  replays them through create_and_add_feature
- the stratigraphic column's group_mapping is stored
- feature_recipe_kind tests subclasses first, so faults and unconformities are no longer
  labelled structural_frame / foliation
- to_recipe_* raise LoopValueError for a feature it cannot rebuild yet (non-foliation, custom
  data=, a parameter JSON cannot hold, no creation record) instead of writing a wrong recipe
- recipes written before this (no build entry) still load, with a warning; an older non-foliation
  entry is refused

The three strict xfails from the recipe test now pass and their markers are removed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… parameters

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant