VV: Segment Features (C-Axis Misalignment) fully V&V'ed - #1685
VV: Segment Features (C-Axis Misalignment) fully V&V'ed#1685imikejackson wants to merge 12 commits into
Conversation
217c54c to
47c921d
Compare
Second-Engineer V&V ReviewFull independent review of the V&V package: every claim in Verified — no action needed
Action itemsCorrectness / coverage (should address before merge):
Hardening (recommended, small):
Performance:
Docs (trivial):
Follow-up issues (out of scope for this PR):
Adversarial checks that came back cleanEmpty-geometry/0-tuple path, |
Summary: - Found and fixed 3 bugs (D1 unvalidated first seed in shared SegmentFeatures driver, D4 spurious -8363 rejection of unindexed/ masked cells + missing CrystalStructures bounds check, D5 stale ImageGeom cast crashing RectGrid input); - documented 5 deviations from DREAM3D 6.5.171 (D1 phantom first feature, D2 legacy always clock-randomizes FeatureIds, D3 NX-only hexagonal validation, D4 unindexed-cell rejection, D5 RectGrid); - retired 4 tests (circular-oracle segment_features_test_data exemplar consumers; archive remains for EBSDSegmentFeatures); - unit tests replaced with 13 inlined *Class 1 (Analytical) + Class 4 (Invariant)* test fixtures; - added 3 V&V source-tree deliverables (report, deviations, provenance) plus the 6.5.171 A/B comparison pipelines/results; - documented hexagonal-only requirement, mask/phase-0 semantics, RectGrid support, and deterministic FeatureId randomization in the user docs. Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* Add 3x2x2 axis-asymmetric Class 1 fixture pinning the x-fastest voxel linearization and the y/z stride neighbor branches (prior fixtures were invariant under dims permutation) * Assert the randomized FeatureIds differ from the canonical labeling so a dead randomizer fails the Class 4 test; add a masked variant pinning the FeatureId 0 -> 0 mapping through the shuffle * Preflight now rejects cell arrays whose tuple count differs from the geometry cell count (-652) instead of walking out of bounds at execute * Create FeatureIds with the cell AttributeMatrix tuple shape rather than the Quats array shape * Return cleanly from a canceled run instead of misreporting -87000 * Update V&V report (18 tests, new paths/pins) Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* Add -653 preflight guard: the geometry cell AttributeMatrix hosting the created FeatureIds must match the geometry cell count (closes the residual hole behind the -652 check) * Add Class 1 fixture with Quats in a sibling AttributeMatrix, pinning the preflight/execute FeatureIds path agreement * Refresh V&V report bookkeeping (20 tests, 10 oracle fixtures, dual-build 20/20 rerun), name the path-derivation half of the executeImpl fix * Fix deviation-ID typo in comparison.md; make make_input.py's writer-module path overridable via LEGACY_DREAM3D_SKILL_DIR Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* Remove dead pCrystalStructuresArrayPathValue in preflightImpl (the
selection parameter already validates existence)
* Rename determineGrouping parameters to camelBack per convention;
rename getSeed's misnamed randPoint (linear scan) to candidatePoint
* Fix comment typos ("in and EBSD file", "visual clarify") and note the
hex-validation comment's actual guard wording
* Normalize trailing period on the -87000 message
* Refresh algorithm line count in the V&V report
Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
…tests * Add masked-voxel-0 regression tests to EBSDSegmentFeaturesFilter and ScalarSegmentFeatures suites, mirroring the CAxis pin: the first seed must come from getSeed(), or a masked index 0 yields a phantom empty feature and shifted FeatureIds * The driver fix lives in src/simplnx/Utilities/SegmentFeatures.cpp; each consumer now carries its own pin so a test refactor in one plugin cannot silently unpin the core-library behavior Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* vv_policy.md restricted "algorithmic choice" to Rewrite relationships, but Port/Minor-changes reports across the fleet already use it for deliberate guards and behavior differences (added validation, changed defaults, exposed randomization) * Reword the taxonomy entry to allow any Algorithm Relationship, keeping the Rewrite UUID-defense requirement Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* Correct the -8363 message to say "every phase that participates in the segmentation" now that phase-0/masked cells are exempt; quote the path and punctuate the -8362 message; -87000 names the actual tolerance parameter; un-shout "zero" in -655 * Add direct <algorithm> include for std::clamp; Ref-suffix the DataStore references in getSeed and unify their spelled type; drop redundant this-> prefixes; unify cellFeatureAM naming * Alphabetize NumberParameter.hpp into the Parameters include block; rename preflight locals (cellFeatureAMPath, useMask) to match the values they hold; normalize parameter-description punctuation * Tag oracle tests [Class1]/[Class4] per sibling convention; Title Case the two new preflight test names (report references updated); collapse the three hand-built preflight arg blocks into BuildManualPreflightArgs; comment the RectGrid fixture's deliberate geometry-name reuse * Docs: c-axis is the [0001] direction; point "migration deviation notes" at the vv/deviations file; algorithm header docstring describes the algorithm rather than the filter * Provenance "Used by tests" no longer overclaims the preflight tests; annotate make_input.py enum constants; drop narration comment and unify int64 spelling in SegmentFeatures.cpp Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* CAxisSegmentFeatures::getSeed now only stamps the seed's FeatureId, mirroring the sibling EBSD/Scalar segmentation algorithms; the feature AttributeMatrix is resized exactly once after segmentation completes. The per-seed resizeAttributeArrays() was a vestige of the legacy 6.5 port (needed there to refresh raw Active pointers) and cost O(F^2) copy traffic in the number of features. * Drop the redundant pre-execute Active fill; the authoritative fill happens after the post-run resize. * Mirror the CAxis cancel guard and execute() result propagation into EBSDSegmentFeatures and ScalarSegmentFeatures so a canceled run is not misreported as -87000 "no Features were detected". * Update V&V report code-path 13 to match the lean getSeed. Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
…tion * SegmentFeatures::execute() returns before the first getSeed() when the run is already canceled on entry, so a pre-canceled run mutates nothing (getSeed stamps the seed cell's FeatureId as a side effect). * Cache validated phases in the CAxis crystal-structure loop so the mask is consulted only for the first cell of each phase instead of every cell; per-element mask access is expensive on out-of-core stores. * Reword the -87000 error in all three segmentation filters: the only reachable cause is that no cell was eligible to seed (masked out or unindexed), not a tolerance/threshold setting. Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* With the validated first seed, a dataset where no voxel can seed now fails with -87000 instead of "succeeding" with one phantom, zero-cell feature; pin that behavior per sibling so the shared-driver change is covered beyond the partially-masked case. Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
* TC5_3D (3x2x2, bool mask excluding voxels 0 and 5) exercises the y/z stride branches of the 3-D flood fill against 6.5.171; the original four fixtures are all 1-D lines. One feature spans x/y/z hops plus a pi-fold link; masked voxel 0 pins the validated-first-seed path in 3-D. * Full five-fixture suite rerun through both runners 2026-07-24: all partitions match with identical feature counts; NX equals the oracle. * Refresh V&V report: five-fixture comparison, current sibling suite counts (EBSD 7/7, Scalar 4/4). * nx.d3dpipeline writer args updated to parameters_version 2 (use_compression/compression_level) to silence the -5432 load warning. Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
… refills * The IsPeriodic option (added in BlueQuartzSoftware#1291) has been silently ignored since the BlueQuartzSoftware#1373 neighbor refactor dropped the wrap logic from the shared SegmentFeatures driver. getFaceNeighbors/getAllNeighbors now take isPeriodic and emit the wrap-around neighbor for boundary cells (each axis wraps independently; axes of extent 1 never wrap), and the driver reports when a Feature crosses a periodic boundary, matching the documented behavior. Pinned by periodic-wrap tests for EBSD (face) and Scalar (face and 26-neighbor schemes). * The burst worklist was shrunk to size 1 after every feature, so the first accepted neighbor of each subsequent feature re-grew it by 100k elements and re-wrote 100k -1 sentinels that nothing ever reads. The list now keeps its high-water size across features and is never sentinel-filled; only indices below the live count are read. Fixes BlueQuartzSoftware#1690 Fixes BlueQuartzSoftware#1691 Signed-off-by: Michael Jackson <mike.jackson@bluequartz.net>
88b4898 to
20bcb38
Compare
Summary
Full V&V cycle for
CAxisSegmentFeaturesFilterper the v2 MTR V&V policy, verified against an independent Class 1 (Analytical) + Class 4 (Invariant) oracle before any legacy comparison.SegmentFeaturesdriver burst from an unvalidated rawseed = 0(introduced in BUG: Fixes issue when segmenting features with a +1 feature count #1466): phantom empty feature / ids shifted by one / growth from a masked voxel whenever index 0 could not legitimately seed. RestoredgetSeed()for the first seed; fix also coversEBSDSegmentFeaturesandScalarSegmentFeatures, and each consumer suite now carries its own masked-voxel-0 regression pin.CrystalStructureswithout a bounds check (new-8364).getDataAs<ImageGeom>cast crashed on RectGrid input (parameter allows RectGrid; siblings already usedIGridGeometry).-652/-653preflight guards (cell arrays / cell AttributeMatrix vs geometry cell count), preflight-consistent FeatureIds path derivation and tuple shape, clean cancel return.segment_features_test_dataCAxis_FeatureIds_*arrays were generated from SIMPLNX output); the archive remains for the EBSD tests. Replaced with 20 tests built on inline pure-Phi Bunge fixtures with the closed-form derivation embedded in the test source.vv/CAxisSegmentFeaturesFilter.md(READY FOR REVIEW),vv/deviations/,vv/provenance/,vv/comparisons/pipelines + results; user docs updated (hexagonal requirement, mask/phase-0 semantics, RectGrid, deterministic randomization).vv_policy.md: "algorithmic choice" root-cause wording aligned with fleet practice (usable outside Rewrite relationships).Review follow-ups folded in: the shared driver's
IsPeriodicoption (a silent no-op since the #1373 neighbor refactor dropped #1291's wrap logic) is restored with per-sibling regression pins, and the per-feature 100k-sentinel worklist refill is removed.Fixes #1690
Fixes #1691
No parameter changes —
parametersVersion()stays at 2.Approving this PR constitutes the second-engineer sign-off for the report; the Oracle section and provenance sidecar flag the two items to double-check (pure-Phi derivation, folded-distance metric).
Test Plan
OrientationAnalysis::CAxisSegmentFeaturesFilter20/20 on in-core buildOrientationAnalysis::CAxisSegmentFeaturesFilter20/20 on out-of-core buildEBSDSegmentFeatures8/8 andScalarSegmentFeatures5/5 in both builds (shared-driver regression check, incl. all-cells-masked -87000 and periodic-wrap pins)OrientationAnalysis::+SimplnxCore::suites 1205/1205 on in-core build after the shared-driver changesvv/comparisons/CAxisSegmentFeaturesFilter/results/comparison.md)