Skip to content

Simplify filters, SampleSmall, FE Aperture. Rework filters.yml into beamline constants.yml - #125

Merged
Anthony Sligar (sligara7) merged 10 commits into
NSLS2:mainfrom
jwlodek:remove-display-name-logic
Oct 29, 2026
Merged

Anthony Sligar (sligara7) merged 10 commits into
NSLS2:mainfrom
jwlodek:remove-display-name-logic

Conversation

@jwlodek

Copy link
Copy Markdown
Contributor
  • Fix the germ acquire logic test
  • Fix tests

@sligara7

Anthony Sligar (sligara7) commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Crystal-1 OUT changes from -36.0 to +48.3 mm during the constants migration. Both white-beam movement and beam-mode readback use it. Wanted to confirm the values.

@sligara7

Anthony Sligar (sligara7) commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Should we retain the 0.05 mm tolerance and "between apertures" readback? The nearest-position calculation reports "Fully closed" at Y=4 mm, "Fully open" at -30.67 mm, and "Pinhole" at 100 mm.

@jwlodek

Copy link
Copy Markdown
Contributor Author

Should we retain the 0.05 mm tolerance and "between apertures" readback? The nearest-position calculation reports "Fully closed" at Y=4 mm, "Fully open" at -30.67 mm, and "Pinhole" at 100 mm.

I added an in position signal instead. That way the aperture signal has tighter typing than str.

The constant change was a typo, fixed that.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The changes remove Bluesky magic registration from fresh sessions and introduce filter regressions that reject selected-device-only requests and the previously supported "pass through" input.

2 open issues
What changed in this PR

This PR centralizes HEX beamline constants and simplifies filter and front-end aperture configuration. It also removes custom SampleSmall labels and IPython magics, switches type checking to Pyright, and updates related tests and documentation.

Changes:

  • Move filter positions, monochromator constants, and aperture settings into shared YAML configuration.
  • Update device construction, filter choices, shutter handling, and GUI integration.
  • Adjust tests, typing, and documentation for the revised interfaces.
File Description
tests/​tomography/​test_flyscans.py Update shutter exception expectations.
tests/​tomography/​test_alignment.py Initialize shutter state and update error assertions.
tests/​test_profile_namespace.py Expect the renamed aperture plan.
tests/​test_movable_wrappers_stop.py Adapt filter construction.
tests/​test_magics.py Remove custom magic regression tests.
tests/​test_log.py Add a hook typing suppression.
tests/​test_edxd.py Centralize typed GeRM data access.
tests/​photon_delivery_system/​test_shutter.py Expand shutter-state coverage and update timeouts.
tests/​photon_delivery_system/​test_filters.py Test constants-backed filters and mock interlocks.
tests/​photon_delivery_system/​test_fe_slit.py Update aperture names, imports, and readback expectations.
tests/​photon_delivery_system/​test_dclm.py Read constants from device instances.
tests/​gui/​test_window_close.py Make application setup and layout checks explicit.
tests/​gui/​test_sample_small_labels.py Remove custom label tests.
tests/​gui/​test_run_viewer.py Adjust application setup and contrast-level checks.
tests/​gui/​test_plan_widget_filters.py Validate enum-based filter choices.
tests/​gui/​test_plan_widget_fe_slit.py Test the renamed aperture plan and labels.
tests/​gui/​test_plan_history.py Make application initialization explicit.
tests/​detectors/​test_phantom.py Update acquisition and download mock state.
src/​hextools/​xrd/​calibration.py Convert the initial motor readback to float.
src/​hextools/​utils/​magics.py Remove waiting-hook-preserving magics.
src/​hextools/​settings/​plans.py Add typing for generated settings enums.
src/​hextools/​profiles/​collection.py Construct filters explicitly and remove magic registration.
src/​hextools/​photon_delivery_system/​slits.py Incorporate constants-backed front-end aperture control.
src/​hextools/​photon_delivery_system/​shutter.py Standardize timeouts, errors, and settling-time parameters.
src/​hextools/​photon_delivery_system/​filters.yml Remove the former filter configuration.
src/​hextools/​photon_delivery_system/​filters.py Load shared constants and add enums and mock interlocks.
src/​hextools/​photon_delivery_system/​fe_slit.py Remove the module consolidated into slits.py.
src/​hextools/​photon_delivery_system/​dclm.py Load shared constants and remove tuning-result plots.
src/​hextools/​photon_delivery_system/​__init__.py Update public device and plan exports.
src/​hextools/​gui/​shutter_status.py Disable settling delay for GUI shutter toggles.
src/​hextools/​gui/​run_viewer.py Clarify profile-line value typing.
src/​hextools/​gui/​plan_widget.py Display device namespace paths directly.
src/​hextools/​gui/​plan_status.py Adjust the toolbar import.
src/​hextools/​gui/​misc/​weather.py Use the local worker implementation.
src/​hextools/​gui/​misc/​tabbed_detectors_widget.py Handle an absent current tab explicitly.
src/​hextools/​gui/​live_re_md_viewer.py Use the local worker implementation.
src/​hextools/​gui/​device_sources.py Remove custom SampleSmall display names.
src/​hextools/​gui/​device_selector_widget.py Show device identifiers without label overrides.
src/​hextools/​gui/​device_progress_viewer.py Check progress inputs explicitly for None.
src/​hextools/​gui/​available_devices.py Display namespace names directly.
src/​hextools/​gui/​_threading.py Raise AttributeError for unknown worker attributes.
src/​hextools/​gui/​__main__.py Use the renamed aperture plan.
src/​hextools/​exporters/​tomography.py Validate detector metadata entries as strings.
src/​hextools/​detectors/​phantom.py Declare the optional processing plugin.
src/​hextools/​bl_constants.yml Centralize beamline positions and geometry constants.
src/​hextools/​bl_constants.py Add constants loading and position-enum helpers.
README.md Remove the custom SampleSmall label description.
pyproject.toml Configure Pyright environments and remove ty rules.
pixi.toml Replace ty with Pyright.
docs/​profile.md Document revised filter construction and aperture naming.
docs/​developer.md Update type-checking guidance to Pyright.
docs/​cli.md Update aperture command examples.

Review effort: Balanced

@sligara7 Anthony Sligar (sligara7) left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #125 looks good overall. Moving the constants into bl_constants.yml, adding FilterMock with the interlock behaviour, and the ensure_shutter_state tests are all improvements. I wouldn't approve it yet, though. It deletes features that other merged PRs added, the docs are out of date, and some dead code is left over.

I only read the code and fetched the PR into a local branch, pr125-review. I didn't run the tests.

Features this PR deletes:

  • IPython magics are gone. HEXBlueskyMagics and tests/test_magics.py came from Jakub's #109, and no other code in src registers magics. Operators lose %mov, %movr and %wa. The bug that wrapper worked around is still in the bundled bluesky: magics.py lines 114 and 132 set RE.waiting_hook = None. If the magics come back without the wrapper, the GUI progress bars stop showing after the first %mov.
  • Sample Small display names are gone. device_display_name and test_sample_small_labels.py came from #122. The GUI will show sample_small.x instead of "Sample Small X".
  • Energy auto-tune plots are gone (_PeakStatsPlot removed). Leftovers in dclm.py:
  • _figure_factory() is now unused, though plan_status.py still sets _fig_factory for it.
  • The comment "ps must come first so its stats are computed before plotter sees 'stop'" refers to a plotter that no longer exists.

Out-of-date docs and files:

  • cli.md still says RE(set_filters(filter1_downstream_setting="pass through")). The value is now "Pass Through", so that example raises ValueError. The text above it still says "Every filter defined in the filter configuration file…".
  • filters.yml describes the deleted filters.yml format and nothing references it now. Delete it or replace it with a schema for bl_constants.yml.
  • Breaking renames that other repos (hex-profile-collection, queue server) may use: set_fe_slit1_aperture → set_fe_aperture, PPSShutter.interlock → interlock_ack, load_filters removed, and the aperture strings changed. Shutter errors are now ValueError instead of RuntimeError.

Design points:

  • DCLM constants: setattr over whatever keys the YAML holds, plus 10 boilerplate properties. A typo in the YAML is silently ignored, and the matching property then raises AttributeError later. A frozen dataclass built with MonoConstants(**fetch_beamline_constants("monochromator")) would check the keys and remove the properties.
  • Filter lookup by name: a Filter now finds its settings in the YAML by its device name, so renaming a device breaks it. The old check that every filter defines all 7 positions is also gone. A test covers the packaged YAML, but nothing checks at run time.
  • set_filters now requires all three filters and fe_shutter to exist even when only one filter is being set.
  • FrontEndSlit.aperture now always reports the nearest aperture; the old "between apertures" value is gone. A Y of 5.0 reads as "Fully closed", and anything that reads only aperture (for example, run metadata) can't tell. The in-position tolerance is fixed at 1e-2; it used to be a tolerance=0.05 argument.
  • GUI shutter button now passes sleep_time=0.0, which skips the 4 s settle wait that ensure_shutter_state keeps because "the shutter status in EPICS is not reliable enough".

Nits:

  • pyright = "*" is unpinned, while every other dev tool in pixi.toml is pinned.
  • noqa E501 in shutter_status.py is missing its colon; wrapping the line is simpler.
  • cast( # type: ignore in bl_constants.py has an ignore it doesn't need.
  • In exporters/tomography.py, [str(n) for n in det_names] repeats the all-str check just above it.
  • Not from this PR: DEFAULT_TIMEOUT = 60.0 in profiles/collection.py is only a local variable, so ophyd-async's timeout stays at 10 s. The shutter now uses that 10 s value, so the "adjust to 60s" comment there is misleading.

@sligara7
Anthony Sligar (sligara7) merged commit 1518646 into NSLS2:main Oct 29, 2026
6 checks passed
Anthony Sligar (sligara7) added a commit to sligara7/hextools that referenced this pull request Oct 29, 2026
Retain approved manual shutter mutual exclusion and zero manual delay.

Assisted-by: copilot:gpt-6.1-sol
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants