fix(#293) add ConstraintSet.with_constraint_values and document fixed-axis overrides#296
Merged
Merged
Conversation
…-axis overrides Issue #293 asked how to provide a non-default value for a fixed-axis constraint, and whether it was even possible. The answer was yes — by rebuilding the whole ConstraintSet — but the recipe was hard to discover from the per-mode reference docs, and the rebuild was verbose for any mode pinning more than one value (the psic B3 mode pins three, the sixc zaxis modes pin three, etc.). Add ConstraintSet.with_constraint_values(**updates) — a functional update method that returns a new ConstraintSet with the named constraint values replaced. Constraint order, computed, extras (with sentinel identity), and cut_points are all preserved. Receiver is unchanged; the method always returns a fresh instance. * Sample, detector, and reference constraints are matched by their .name attribute. * BisectConstraint and VirtualBisectConstraint are relational (no scalar value) and are intentionally invisible to the helper; any kwarg targeting one raises KeyError. * Unknown keys raise KeyError with a single message listing every unrecognised key and the available names. * Duplicate names within the receiver (a malformed mode that the YAML loader does not produce) raise ValueError. Document the helper, the rebuild-whole-ConstraintSet alternative, and the rationale for the immutable-constraint design in docs/source/howto/constraints.md. Add a top-level 'Change a fixed-axis value' FAQ heading to docs/source/howto/modes.md. Add a uniform 'Override at run time with g.modes[...] .with_constraint_values(...)' cross-link sentence to every fixed_* mode entry in the per-geometry reference pages (psic, fourcv, fourch, fivec, sixc, kappa4cv, kappa4ch, kappa6c, zaxis, s2d2) so this answer is discoverable from where users land. Contributed by: OpenCode (argo/claudeopus47)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue #293 asked how to provide a non-default value for a fixed-axis
constraint, and whether it was even possible. The answer was yes — by
rebuilding the whole
ConstraintSet— but the recipe was hard todiscover from the per-mode reference docs, and the rebuild was verbose
for any mode pinning more than one value (the psic B3 mode pins three,
the sixc zaxis modes pin three, etc.).
This PR delivers three coordinated changes on the single issue, per the
operator's standing preference for batched fixes.
Code
Adds
ConstraintSet.with_constraint_values(**updates)— a functionalupdate method that returns a fresh
ConstraintSetwith the namedconstraint values replaced. Constraint order,
computed,extras(with sentinel identity preserved), and
cut_pointsall surviveunchanged. Receiver is not mutated.
.name.BisectConstraint/VirtualBisectConstraintare relational (noscalar value) and are intentionally invisible to the helper; any
kwarg targeting one raises
KeyError.KeyErrorwith a single message listing everyunrecognised key and the available names (batched typo reporting).
ConstraintSetthat the YAML loader does not produce) raise
ValueError.Tests
14 new tests in
tests/test_mode.py: parametrized replacements(sample / detector / reference, float and bool), multi-value, empty
kwargs (returns equal fresh instance),
KeyErrorsingle+batched,ValueErroron duplicate name,BisectConstraintignored bothsolo and alongside settable constraints, round-trip via
to_dict().Docs
docs/source/howto/constraints.md— new 'Why constraint valuesare immutable' section, new 'Use
with_constraint_valuesfor aone-call override' subsection, new 'Rebuild the whole
ConstraintSet' subsection with detector and reference workedexamples.
docs/source/howto/modes.md— updates 'Fixed-angle modes' tolead with the new helper; new top-level '
Change a fixed-axis value' FAQ heading.fixed_*mode entry in the per-geometry reference pages(psic, fourcv, fourch, fivec, sixc, kappa4cv, kappa4ch, kappa6c,
zaxis, s2d2) gains a uniform 'Override at run time with
g.modes[...].with_constraint_values(...)' cross-link sentence,making the answer discoverable from where users actually land.
CHANGES.md
Incidental
The
insert-licensehook restored the SPDX header ontests/test_regression_issue_292.py(it had landed in #292 withoutthe header).
ruff-formatalso applied two line-wrap nits to thesame file. Both are pre-existing, non-functional changes carried in
this PR because they were on the working tree when pre-commit ran.
Verification on
wow.xray.aps.anl.gov(Python 3.14.4, NumPy 2.4)pytest: 2606 passed, 2 skipped, 3 deselected — 100.00 % coveragepre-commit run --all-files: cleanmake -C docs clean html: clean build, no warningsContributed by: OpenCode (argo/claudeopus47)