Skip to content

Browse and import large HDF5 and NeXus experimental files - #13

Merged
PierreRaybaut merged 20 commits into
developfrom
feature/experimental-data-integration
Oct 23, 2026
Merged

PierreRaybaut merged 20 commits into
developfrom
feature/experimental-data-integration

Conversation

@PierreRaybaut

@PierreRaybaut PierreRaybaut commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #12.

Second of three companion PRs for experimental data integration:

  1. Record the origin of experimental data and import large integers exactly Sigima#78 — experimental-source API and exact integer conversion (Sigima 1.4.0); merge first
  2. This PR
  3. Integrate experimental data: NeXus files, robust HDF5 import and threaded plugin instruments DataLab#422 — NeXus files, robust HDF5 import, threaded instruments

This branch requires Sigima ≥ 1.4.0 (pyproject.toml, requirements.txt). The development CI clones Sigima's branch of the same name, so it runs against DataLab-Platform/Sigima#78.

Changes

  • Lazy HDF5 browsing (h5/common.py, h5/generic.py, h5/utils.py): datasets classified from shape and dtype without reading them; text previews read only the first elements; attributes above MAX_ATTRIBUTE_ITEMS skipped; broken soft/external links skipped with a warning.
  • Threaded, bounded previews (widgets/h5browser.py): previews read in a worker thread with stale results discarded, decimated above 2²⁴ elements (bisected step), cleared when an unsupported node is selected; closing waits for the running read.
  • NeXus NXdata import (h5/nexus.py): @signal/@axes/@<axis>_indices and legacy conventions, bin edges → centers, uniform-axis detection at the dtype precision, decreasing image axes reversed, invalid axes reported; origin recorded in experimental_source. Blank long_name/units attributes fall back to dataset names.
  • Declarative data mappings (h5/mapping.py) and N-D selections (h5/selection.py).
  • Exact import: uint32 images no longer clipped, complex64 signals keep their imaginary part, large-integer precision warnings.
  • Release notes, HDF5 guide and French catalogs.

Validation

  • sigimax/tests/hdf5: 308 passed.
  • Ruff check/format clean, Pylint 10/10 on changed modules.

Also stops clipping uint32 images and adds NodeFactory.unregister for plugin reloads.

Assisted-by: Claude Opus 5.5
Assisted-by: Claude Opus 5.5
Provide complete HDF5 mapping and selection examples, clarify preview limits, expand the API reference, update French translations and require Sigima 1.4.

Assisted-by: GPT-6.1 Sol
NeXus and mapped objects recorded a dimension without axis as None, which
HDF5 files restore as an empty string (and which Sigima now rejects). Use
".", as NeXus `axes` attributes do.

Assisted-by: Claude Opus 5.5
…ng at import

- An `@axes` attribute whose length differs from the signal rank, and
  `@<axis>_indices` attributes designating a missing dimension, several
  dimensions or a dimension already described, are reported as problems
  instead of being silently truncated, padded or overwritten.
- Axis datasets that do not hold real numbers are reported; such
  uncertainty datasets are ignored. Both previously made the node look
  importable and then failed when the object was created.

Assisted-by: Claude Opus 5.5
- Uniform axes are detected within the precision of the data type they
  were stored with: float32 axes and axes with a large origin were imported
  as non-uniform coordinates. The pixel size is computed from the axis ends.
- Decreasing image axes are reversed with the image, and the conversion is
  recorded in experimental_source: PlotPy failed to show such images
  ("x must be an increasing 1D array"). Image axes that are not strictly
  monotonic (e.g. constant) raise a ValueError instead of producing a
  degenerate image.

Assisted-by: Claude Opus 5.5
…port

BaseNode.set_signal_data cast every dataset that was not float64 or
complex128 to float64 before Sigima's converter: complex64 1D datasets lost
their imaginary part (ComplexWarning), and integers beyond 2**53 were
rounded without Sigima's precision warning. NXdata signals bypassed the
converter too.

- New common.to_signal_data helper, used by generic and NXdata signals:
  float64 for real data (as before), complex128 for complex data, through
  Sigima's converter.
- 2D tables with complex X values or uncertainties are reported as
  unsupported instead of being truncated.
- Release notes: NeXus axis handling (previous commits) and this fix.

Assisted-by: Claude Opus 5.5
- Previews of nodes selected while another one was read were all read in
  turn: they are now cancelled, and skipped by the worker if they already
  left the queue.
- Closing the browser dialog (OK, Cancel or window close) waits for the
  preview being read: SigimaX and DataLab read the selected nodes right
  after, which accessed the HDF5 file concurrently with the preview thread.
- PlotPreview.wait waits for every previous read (it only waited for the
  last request), and cleanup stops the worker thread, which is created
  again when needed.

Assisted-by: Claude Opus 5.5
NeXus NXdata groups and mapped objects were previewed with their complete
native object, whatever their size. Above PlotPreview.MAX_ITEMS elements,
their preview now reads one element out of a step along each dimension
(signal, uncertainties and axis values), with the same axis handling as
the import (bin centers, reversed decreasing image axes). Import still
reads every value.

Assisted-by: Claude Opus 5.5
Broken soft links and external links to missing files (e.g. synchrotron
master files without their detector files) are returned as None by h5py:
opening such a file failed with an AttributeError, so it could be neither
browsed nor imported. Broken links are now skipped, with a console warning
telling the link target.

Assisted-by: Claude Opus 5.5
The step was incremented one by one from a geometric estimate, which took
about 100 000 iterations for very elongated arrays (e.g. 3 x 1e8). The
smallest step is now found by bisection (the view size decreases with the
step), with the same results.

Assisted-by: Claude Opus 5.5
Selecting a node that cannot be previewed (a group, for example) while a
preview was read showed that preview for the newly selected node. The
pending preview is now discarded and the plot cleared.

The pending preview is also discarded, without waiting, before the node
description is read: the description no longer waits for the read of a
preview that is not needed anymore.

Assisted-by: Claude Opus 5.5
- Ignore NumPy's dynamically populated `finfo` class, as Sigima does.
- Split the compound branch of `GenericArrayNode.numeric_layout` and the
  signal/image construction of `NXdataNode._build_object`.
- Share `NXdataNode.make_source` with mapped nodes (`SOURCE_KIND`,
  `source_details`) instead of duplicating it.
- Tests: use `usefixtures` for the mapping registration fixture and
  `contextlib.closing` for the importer.

Assisted-by: Claude Opus 5.5
…alogs

- Release notes and HDF5 guide: broken links are skipped, and selecting a
  node that cannot be previewed clears the preview.
- French translations: new and updated entries, the Main window and Qt
  helpers entries of the 1.1 release notes, and the Sigima >= 1.4.0
  requirement of the installation guide.

Assisted-by: Claude Opus 5.5
A long_name attribute that is empty or made of spaces gave an empty label to the signal or axis, instead of the dataset name.

Assisted-by: Claude Opus 5.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant