Skip to content

Kinetix + PandA detector modules (promoted from hex-ob) - #77

Draft
Anthony Sligar (sligara7) wants to merge 11 commits into
mainfrom
kinetix-device
Draft

Kinetix + PandA detector modules (promoted from hex-ob)#77
Anthony Sligar (sligara7) wants to merge 11 commits into
mainfrom
kinetix-device

Conversation

@sligara7

@sligara7 Anthony Sligar (sligara7) commented Aug 13, 2026

Copy link
Copy Markdown

Stacked on #76 — branched from pyepics-migration so it builds against the pixi + ophyd-async 0.21 environment (the kinetix module uses the released 0.19/0.21 detector-assembly API, which the current main lock at 0.17a4 predates). The diff shows #76's commits until #76 merges, after which it collapses to this PR's own 3 files (+393 lines). No existing module is modified — germ and phantom are untouched.

Split from the original larger PR by request: this is the device layer only. The tomography plan family that drives these devices follows as its own stacked PR (#78), and the Phantom work comes later, after its device-surface reconciliation.

Promotes the proven kinetix-generation device work from NSLS2/hex-ob, where it was developed and tested against the mock and simulated beamline tiers:

  • detectors/kinetix.pyHEXKinetixDetector (+ make_kinetix factory for Det:1/Det:3) with the HEX workarounds baked in: SWMR off, no flush-now (locks the plugin at HEX), 60 s HDF close for network storage, live-view stop on stage / restart on unstage, and the NumCaptured-reset race fix at prepare. HEXProcPluginIO adds the recursive-filter (frame averaging) and flat-field fields to Proc1:. SettablePathProvider / set_output_dir let plans retarget the output directory per scan.
  • detectors/panda.pymake_panda (HDFPanda, settable path provider; the tomography PandA).
  • tests/detectors/test_kinetix.py — device tests under mock (construction, path-provider retargeting, count end-to-end, live-view restore).

Observed on the base branch (pre-existing, not from this PR): pytest at the repo root fails collection because testpaths includes src and detectors/germ.py imports DetectorArmLogic, which the 0.21 line doesn't ship. pytest tests/ is unaffected.

Jakub Wlodek (jwlodek) and others added 10 commits April 23, 2026 12:40
…async version. Add classes for Filters and Monochromater. Add plan for changing energies, with auto-tuning of the second crystal pitch
- detectors/kinetix.py: HEXKinetixDetector (+ make_kinetix for Det:1/Det:3)
  with the HEX workarounds baked in: SWMR off, no flush-now (locks the
  plugin at HEX), 60 s HDF close for network storage, live-view stop on
  stage / restart on unstage, NumCaptured-reset race fix at prepare.
  HEXProcPluginIO adds the recursive-filter (frame averaging) and
  flat-field fields to Proc1:. SettablePathProvider / set_output_dir let
  plans retarget the output directory per scan.
- detectors/panda.py: make_panda (HDFPanda, settable path provider).
- tests/detectors/test_kinetix.py: device tests under mock.

Existing modules (germ, phantom) untouched. The tomography plan family
that drives these devices follows as its own PR.
@sligara7 Anthony Sligar (sligara7) changed the title Kinetix detector module + tomography plan family (promoted from hex-ob) Kinetix + PandA detector modules (promoted from hex-ob) Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR promotes HEX beamline device-layer components (photon delivery system devices/plans plus Kinetix & PandA detector modules) and updates the project/CI packaging workflow to use pixi-based environments.

Changes:

  • Add new ophyd-async device implementations for the photon delivery system (shutter, filters, DCLM) and a change_energy plan.
  • Add new detector modules for Kinetix (HEX-specific workarounds + settable path provider) and PandA (HDFPanda + settable path provider), plus related/updated detector tests.
  • Switch CI/build/publish workflows and environment management to pixi (add pixi.toml, update GitHub Actions, adjust pytest ignores/warnings).

Reviewed changes

Copilot reviewed 19 out of 22 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/test_utils.py Adds unit coverage for is_running_in_ci().
tests/test_photon_delivery_system.py Adds end-to-end mock tests for shutter, filters, DCLM, and change_energy (incl. auto-tune).
tests/detectors/test_phantom.py Updates Phantom tests for the newer writer/acquire logic integration.
tests/detectors/test_kinetix.py Adds mock device tests for the new HEX Kinetix module and path retargeting.
tests/conftest.py Forces CI-mode env var in tests (autouse fixture).
src/hextools/utils.py Adds general utilities (CI detection, RE initialization, device auto-connect, prompt).
src/hextools/py.typed Marks package as typed.
src/hextools/profiles/collection.py Adds a beamline profile collection script wiring up devices for interactive use.
src/hextools/photon_delivery_system.py Introduces PDS device classes and change_energy plan.
src/hextools/motors.py Adds motor utilities and a velocity-respecting mock.
src/hextools/detectors/phantom.py Updates Phantom detector integration to newer ophyd-async writer/acquire APIs.
src/hextools/detectors/panda.py Adds make_panda() helper using a settable path provider.
src/hextools/detectors/kinetix.py Adds HEX Kinetix device/factory and HEX-specific HDF/data-logic workarounds.
src/hextools/_version.pyi Removes a version stub file.
pyproject.toml Updates runtime deps and pytest configuration (incl. ignoring profiles).
pixi.toml Adds pixi environment definition and tasks for dev/CI/profile usage.
.github/workflows/publish-pypi.yml Switches build/install/verify to pixi-based steps.
.github/workflows/pixi-update.yml Adds scheduled workflow to update pixi lockfile via PRs.
.github/workflows/ci.yml Updates lint/typecheck/tests to run via pixi environments per Python version.
.github/dependabot.yml Adjusts update cadence/groups; removes uv lockfile updates.
Suppressed comments (1)

src/hextools/profiles/collection.py:70

  • This uses Monochromator(...), but the corresponding device class in hextools.photon_delivery_system is DCLM. After fixing the import, update the constructor call accordingly.
    dclm = Monochromator("XF:27IDA-OP:1{Mono:DCLM-Ax:", name="dclm")

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/hextools/utils.py
Comment on lines +95 to +102
return RunEngine(
{
"data_session": "pass-123456",
"cycle": (
f"{datetime.today().year}-{int(datetime.today().month / 4) + 1}"
),
}
)

def change_energy(
dclm: DCLM,
energy: float = 0.0,
dclm.cooled_beam_stop, dclm.beam_stop_in,
dclm.flourescence_screen, fluo_y,
)
# fmt: on``
Comment on lines +114 to +121
def _get_description(self, in_pos: int, motor_pos: float) -> str:
"""Get the description of the current filter setting based on motor position.

Parameters
----------
in_pos : int
Indicates whether the filter is in position.
motor_pos : float
Comment thread src/hextools/detectors/kinetix.py
Comment on lines +21 to +27
from hextools.photon_delivery_system import (
Filter,
FilterPosition,
FilterSetting,
Monochromator,
Shutter,
)
Comment on lines +144 to +155
kinetix1 = KinetixDetector(
"XF:27ID1-ES{Kinetix:1}", ADWriterFactory.hdf(path_provider), name="kinetix1"
)
kinetix2 = KinetixDetector(
"XF:27ID1-ES{Kinetix:1}", ADWriterFactory.hdf(path_provider), name="kinetix2"
)
kinetix3 = KinetixDetector(
"XF:27ID1-ES{Kinetix:1}", ADWriterFactory.hdf(path_provider), name="kinetix3"
)
kinetix4 = KinetixDetector(
"XF:27ID1-ES{Kinetix:1}", ADWriterFactory.hdf(path_provider), name="kinetix4"
)
Comment thread pyproject.toml
"algotom",
"ipython",
"numpy",
"ophyd-async[ca, pva]",
@sligara7

Copy link
Copy Markdown
Author

On the other seven review comments (utils.py cycle-quarter math, photon_delivery_system.py energy default / stray backticks / in_pos typing, profiles/collection.py Monochromator import and kinetix prefixes, pyproject ophyd-async floor): those lines all come from the stacked #76 base — this PR adds only detectors/kinetix.py, detectors/panda.py, and the kinetix tests, and deliberately doesn't touch those files. They're worth addressing on #76's side; the diff here collapses to this PR's three files once #76 merges.

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