Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,121 @@ A ***critical bug*** was fixed that affects bulk CTR calculations:
released versions, up to and including v1.5.0. See the CTR structure-factor
documentation for details.

GUI changes:

- The position readout of the image plot now shows ``HKL`` as a single
bracketed triplet instead of three separate ``H``, ``K`` and ``L`` fields,
and reports the momentum transfer of the selected reciprocal-space frame as
``Q[alpha]``, ``Q[lab]``, ``Q[omega]``, ``Q[chi]``, ``Q[phi]`` or
``Q[cryst]``. The field is relabelled when the frame selection changes.
Both triplets are shown with five decimals, and the two fields are sized so
that the full triplet is visible instead of being elided. Pixel coordinates
are shown with two decimals, which is the space this needs.

GUI fixes:

- The Q-plot now restores the plot orientation when it is switched off. The
x-axis origin was flipped on entering but never recorded or restored, and
the y-axis restore was tied to the maximum/sum image, so it was skipped
whenever no additional image was displayed. The conversion itself is now
guarded as well: a failure reports an error and leaves the displayed image
and both axes untouched, instead of leaving the plot half-converted with the
scan image hidden.
- The Q-plot ordinate now follows the geometry instead of always pointing
upwards. In an inverted, downward-scattering setup such as the one at ID31 —
recognised from the azimuthal reference, not hardcoded — the out-of-plane
coordinate grows towards the bottom of the detector image, and drawing it
upwards showed the reciprocal-space image mirrored with respect to the
detector image.
- The position readout is now correct while the Q-plot is switched on. The
plot axes hold momentum transfer there and not detector pixels, so the
``X``/``Y`` labels were wrong and ``HKL``, ``del``, ``gam`` and ``Q`` were
computed as if the cursor were on a pixel. The two axis fields are now
labelled ``q_par[<frame>]`` and ``q_perp[<frame>]`` and shown with five
decimals, and the remaining fields are obtained by inverting the conversion,
so hovering a point of the Q-plot reports the same ``HKL`` and the same
detector angles as hovering the pixel it came from. The reported ``Q`` is
the reconstructed vector, so its components are exactly the coordinates
under the cursor; it is unrefracted in the Q-plot because the axes are
unrefracted as well, while ``HKL`` stays refraction corrected in both modes.
Positions that no pixel maps to — the corners of the rebinned grid, or
anything outside the Ewald sphere — are shown as ``------``.
- Cancelling or resetting the machine parameter or the crystal parameter
dialog now restores the configuration that was active when the dialog was
opened. Both dialogs apply every edit immediately, so restoring the widgets
alone left the edited values active, and the discarded configuration stayed
in use until it was overwritten or a config file was loaded.

ESRF ID31 beamline support and reciprocal-space display:

- Detector images can now be displayed in reciprocal space. The new ``Q-plot``
toolbar action rebins the currently shown image (single image, maximum, or
sum) onto a regular grid of in-plane and out-of-plane momentum transfer
using pyFAI's ``FiberIntegrator``, which requires pyFAI >= 2025.1. With an
older pyFAI the action reports an error and stays disabled. A drop-down next
to the action selects the reciprocal-space frame: ``Q_alpha`` (the surface
frame returned by ``QAlpha``, the default), ``Q_lab``, ``Q_omega``,
``Q_chi``, ``Q_phi`` and ``Q_cryst``. The frames that undo the ``omega``
rotation are only defined for a single image and are refused for maximum and
sum images. **This feature is experimental and its conventions may still
change.**
- The reciprocal-space conversion lives in the new module
``orgui.app.qconversion`` and is exact for arbitrary azimuthal references.
It is deliberately part of the application layer rather than of
``orgui.datautils.xrayutils``, so that it is not mistaken for production
reciprocal-space code. pyFAI's ``sample_orientation`` flag can only express
quarter turns and its rotations are composed about fixed axes, neither of
which matches orGUI's continuous azimuth convention, so orGUI supplies
``FiberIntegrator`` with its own unit definitions. The result agrees with the
per-pixel ``QAlpha`` calculation to numerical precision; see the geometry
documentation for when to use which.
- Added the compiled extension ``_qconversion_cpp``, which converts a full
detector image in a single pass. A 6.2 megapixel Pilatus 6M image is
converted in roughly 50 ms; a numpy implementation is used when the extension
has not been built. The pyFAI integrator is reused while the conversion is
unchanged, so stepping through images no longer resets it for every image.
- HDF5 files that are still being written can now be refreshed from the GUI.
The tree view is rebuilt and the current scan reloaded without restarting
the application.
- Added a ``BlissScan_EBS_p4`` backend for the ID31 Pilatus4 detector, an
example backend under ``examples/backend/ID31_EBS_p4_backend.py``, and the
``ch8153`` beamtime.
- The default backend is now ``id31_default_p4`` and the fallback geometry
describes a Pilatus4 4M CdTe detector.
- Maximum and sum images are now untoggled when the image number changes, and
the maximum/sum toolbar icons no longer get out of sync with the displayed
image.
- The Q-plot now stays switched on and follows the display instead of being
turned off. It is rebuilt when the image number changes, when the maximum or
sum image is toggled, when the frame is changed, and when the machine angles,
the azimuthal reference, the energy or the orientation matrix are edited.
- The ``Q-plot`` toolbar action now has an icon, a capital Q, instead of being
the only text button in that toolbar. The text is kept as the action name
and the tooltip is unchanged.
- **BREAKING CHANGE:** HDF5 file locking is now disabled by default
(``HDF5_USE_FILE_LOCKING=False``), so that files still open for writing by
the acquisition system can be read. A manually set environment variable
still wins, and ``--hdflocking`` / ``-l`` restores the previous behavior.
- **BREAKING CHANGE:** the segmented ("interlaced") scan loader no longer
guesses a file's layout from a hardcoded list of beamtime ids. Backends can
now answer directly with the new optional ``Scan.listScans`` classmethod,
which returns the scan identifiers -- numbers such as ``[1, 2, 10]``, names
such as ``["ascan_12", "dscan_3"]``, or ``(identifier, label)`` pairs to
label the rows of the selection dialog. Backends that do not implement it
are handled by applying their own ``parse_h5_node`` to every entry of the
file root, which requires no backend change but relies on ``parse_h5_node``
raising for entries that are not scans. Either way the loader can no longer
disagree with how the same backend opens a single scan. This fixes the
``id31_default_p4`` backend, which the old list did not cover, and makes
custom backends work regardless of what their class is called -- the example
backend under ``examples/backend/ID31_EBS_p4_backend.py`` was itself
affected. Backends addressed by a name rather than by a number are now
supported here as well, which makes segmented scans work for the legacy
``ch5523`` beamtime for the first time: it was listed as ID31-style, so the
loader looked for a ``"<scan>.<subscan>"`` name its files never had and
raised before showing the dialog. Subscans such as ``1.10`` are no longer
mistaken for the ``1.1`` fast-counter subscan.


## [1.5.0] (2026-06-07)

Expand Down
61 changes: 60 additions & 1 deletion doc/source/beamline_backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ Required Scan Methods

``parse_h5_node(cls, node)``
Return a dictionary with at least ``scanno`` and ``name`` for a scan node
double clicked in the Nexus tree.
double clicked in the Nexus tree. It is expected to **raise** for a node
that is not a scan: the segmented scan loader uses that to tell scans apart
from the other entries of a file, see below.

``__len__()``
Return the number of images or points in the scan.
Expand All @@ -123,6 +125,63 @@ Required Scan Methods
Optional but convenient. The examples implement this by returning
``get_raw_img(i)``.

How a Scan Is Identified
------------------------

orGUI carries two fields for a scan, and a backend may need both when they
differ:

``scanno``
The scan number shown in the GUI. It is an integer, because the scan number
selector is a spin box.

``name``
A free-form identifier. Most backends do not need it, but a backend whose
constructor takes a *name* rather than a number is opened with this one --
``BlissScan`` (beamtime ``ch5523``) reads its scans as ``ascan_12``,
``dscan_3`` and so on, and uses the name as an HDF5 group key.

Which of the two is passed to the constructor is decided per beamtime in
``orgui.backend.backends.openScan``.

Listing Scans for the Segmented Scan Loader
-------------------------------------------

The segmented ("interlaced") scan loader has to know every scan in a file
*before* any scan object exists, so it cannot use ``parse_h5_node`` on a single
selected node the way normal scan loading does. Backends can answer directly
with the optional ``listScans`` classmethod:

.. code-block:: python

from orgui.backend.scans import Scan

class MyBackend(Scan):

@classmethod
def listScans(cls, h5file):
return [1, 2, 10] # scan numbers
# or
return ["ascan_12", "dscan_3"] # scan names
# or, with a label for the selection dialog
return [(1, "ascan th 0 90 90 1"), (2, "dscan mu 0 1 20 1")]

Return whatever your ``__init__`` accepts as its scan identifier. It is passed
back untouched when the scan is opened, and only converted to ``str`` for
display, so a backend addressed by name works exactly like one addressed by
number. Do not use ``float`` for BLISS style ``"<scan>.<subscan>"`` names --
``1.1`` and ``1.10`` are the same float.

**Implementing this is optional.** A backend that does not implement it gets
the fallback: orGUI applies the backend's own ``parse_h5_node`` to every entry
of the file root, keeps the entries that yield a ``scanno``, and collapses
repeated scan numbers so the subscans of one measurement appear once. That
needs no extra code in the backend and cannot disagree with normal scan
loading, but it has to walk the tree, and it depends on ``parse_h5_node``
raising for entries that are not scans.

Nothing here depends on the name of the backend class or on the beamtime id.

Image Objects
-------------

Expand Down
Loading