Skip to content

test(geometry): add real corpus models as Geometry_IT fixtures - #2029

Merged
jcschaff merged 2 commits into
masterfrom
test/geometry-corpus-goldens
Aug 24, 2026
Merged

test(geometry): add real corpus models as Geometry_IT fixtures#2029
jcschaff merged 2 commits into
masterfrom
test/geometry-corpus-goldens

Conversation

@jcschaff

Copy link
Copy Markdown
Member

Extends the geometry golden suite (#2028) with real stored models, and wires the group into
regression CI.

Built the documented way: fixtures and goldens were generated on test/geometry-goldens-base
against the pre-change implementation (f35beaddcd), then cherry-picked here — so the goldens
provably predate the code they check.

Why real models, when synthetic fixtures already pass

The synthetic set is spheres, shells and stripes. Real segmentations are not shaped like that.

fixture pixels shape
corpus_209284198_600x300x22 3,960,000 3D, wide and thin
corpus_26454463_564x160x31 2,797,440 3D
corpus_95707047_208x153x83 2,641,392 3D, thick z
corpus_65311813_256x256x34 2,228,224 3D, cubic
corpus_12522025_2151x504_2d 1,084,104 2D, extreme aspect
corpus_201022999_211x201x11 466,521 3D, small

corpus_95707047 alone yields six regions from two pixel classes — five separate cytosol bodies.
Nothing in the synthetic set produces that, and multi-region-per-pixel-class is exactly the case that
region linking and merging has to get right.

The one design decision worth reviewing

These rebuild surfaces rather than pinning what the document already carries.

A stored model has a <SurfaceDescription>; XmlReader applies it, so precomputeAll skips
updateAll() on parse and the geometry arrives with regions restored from the file rather than
computed
(this is the correction recorded in #2025 §4.1). Pinning those would test the XML reader
instead of surface generation — the opposite of the point. fromCorpus() therefore calls
updateAll() to force a fresh RegionImage and SurfaceCollection.

Naming: they are not actually slow

You asked for these as slower fixtures, and I want to be straight that the label overstates it —
2.87 s for all six. They could sit in Fast and run on every push instead of only in the
regression lane, which would be strictly better protection. I kept them separate for headroom: they
depend on the corpus resources, and the obvious way to extend them is to add more models. Easy to
promote if you'd rather.

CI wiring — the part that would have silently done nothing

regression.yml drives its matrix from an explicit group table, so a tag that isn't listed is never
selected: the tests would have compiled and never run. Added Geometry_IT as a single shard.

Verified by executing the workflow's embedded matrix script directly rather than trusting the
edit — 16 entries across 7 groups with Geometry_IT present, and the YAML parses.

Verification

pre-merge base branch synthetic 7/7 (0.42 s), corpus 7/7 (2.87 s)
on master (post #2026/#2027) -Dgroups=Geometry_IT7/7 (3.87 s)
vcell-core Fast 594 run, 0 failures, 8 errors — the documented Poetry-environment ones

The middle row is the experiment repeated for real models: goldens generated by the old
implementation, matched exactly by current master.

Also in here

Golden regeneration is now split, so iterating on the synthetic fixtures doesn't silently leave the
corpus goldens stale or spend minutes rebuilding them — GeometrySurfaceGolden.main with no
argument does both, with fast does only the synthetic set. And the comparison logic is shared
between the two test classes rather than duplicated, including the everyFixtureHasAGolden guard,
since a @TestFactory whose resources went missing would otherwise just produce fewer tests and
stay green.

Refs #2021, #2025, #2028

🤖 Generated with Claude Code

https://claude.ai/code/session_018kr8SbzXtwW3gMVUgMfDDt

jcschaff and others added 2 commits August 24, 2026 00:42
Generated on the golden base branch, against the pre-change implementation
(f35bead), per the workflow this suite documents. Cherry-picked onto master
separately so the goldens provably predate the code they check.

Six stored models from the VCML test corpus, spanning 0.47-3.96 MP, 2D and 3D,
cubic through to a 2151x504 slab. They earn their place by being irregular in ways
the synthetic fixtures are not -- thin features, awkward aspect ratios, and
disconnected regions sharing a pixel value. corpus_95707047_208x153x83 alone yields
SIX regions from TWO pixel classes, five separate cytosol bodies, which nothing in
the synthetic set produces.

They deliberately REBUILD surfaces rather than pinning what the document already
carries. A stored model has a <SurfaceDescription>, XmlReader applies it, and
precomputeAll therefore skips updateAll() on parse -- so the geometry arrives with
regions restored from the file rather than computed. Pinning those would test the
XML reader instead of surface generation, which is the opposite of the point.
fromCorpus() calls updateAll() to force a fresh RegionImage and SurfaceCollection.

Kept in their own group and class so the fast lane stays fast. Worth being straight
about the naming though: at 2.87 s for all six they are not actually slow, and could
sit in Fast if running on every push is preferred over running only in the regression
lane. The separation is mainly headroom -- they depend on corpus resources and the
obvious way to extend them is to add more models.

Also splits golden regeneration so iterating on the synthetic fixtures does not
silently leave the corpus goldens stale or spend minutes rebuilding them:
GeometrySurfaceGolden.main with no argument does both, with 'fast' does only the
synthetic set.

The comparison logic is now shared rather than duplicated between the two test
classes, including the everyFixtureHasAGolden guard -- a @testfactory whose resources
went missing would otherwise just produce fewer tests and stay green.

Pre-merge verification: GeometrySurfaceRegressionTest 7/7 (0.42 s),
GeometrySurfaceCorpusRegressionTest 7/7 (2.87 s).

Refs #2021, #2025, #2028

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018kr8SbzXtwW3gMVUgMfDDt
Without this the corpus goldens compile and never execute in CI -- regression.yml
drives its matrix from an explicit group table, so a tag that is not listed there is
simply never selected. One shard; the whole group is ~3 s of tests on top of the
~4 min compile floor every shard already pays.

Verified by executing the workflow's embedded matrix script directly rather than
trusting the edit: 16 entries across 7 groups, with Geometry_IT present as a single
shard scoped to vcell-core. The YAML parses.

Refs #2021, #2028

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018kr8SbzXtwW3gMVUgMfDDt
@jcschaff
jcschaff merged commit f9cd0c3 into master Aug 24, 2026
9 checks passed
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