diff --git a/.github/workflows/test_pyqt5.yml b/.github/workflows/test_pyqt5.yml index be6ad700c..2e021c14a 100644 --- a/.github/workflows/test_pyqt5.yml +++ b/.github/workflows/test_pyqt5.yml @@ -77,8 +77,9 @@ jobs: pip install -e ../DataLab-Capsule # Install tomli for TOML parsing (safe if already present) pip install tomli - # Extract dependencies and save to file, then install - python -c "import tomli; f=open('pyproject.toml','rb'); data=tomli.load(f); deps=[d for d in data['project']['dependencies'] if not any(p in d for p in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" + # Extract dependencies of DataLab and SigimaX (installed with --no-deps + # above), save them to file, then install + python -c "import tomli; deps=[d for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomli.load(open(p,'rb'))['project']['dependencies'] if not any(n in d for n in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" pip install -r deps.txt # Install DataLab without dependencies pip install --no-deps . @@ -105,8 +106,9 @@ jobs: pip install -e ../DataLab-Capsule # Install tomli for TOML parsing (safe if already present) pip install tomli - # Extract dependencies and save to file, then install - python -c "import tomli; f=open('pyproject.toml','rb'); data=tomli.load(f); deps=[d for d in data['project']['dependencies'] if not any(p in d for p in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" + # Extract dependencies of DataLab and SigimaX (installed with --no-deps + # above), save them to file, then install + python -c "import tomli; deps=[d for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomli.load(open(p,'rb'))['project']['dependencies'] if not any(n in d for n in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" pip install -r deps.txt # Install DataLab without dependencies pip install --no-deps . @@ -186,9 +188,10 @@ jobs: python -m pip install -e ../SigimaX --no-deps python -m pip install -e ../DataLab-Capsule - # Extract dependency names from pyproject.toml (excluding Sigima and - # SigimaX, installed from local clones above) and install latest versions - python -m pip install -U --upgrade-strategy eager $(python -c "import tomllib, re; print(' '.join(re.sub(r'[\[\]<>=!~,.\s].*$', '', d).strip() for d in tomllib.loads(open('pyproject.toml', 'rb').read().decode())['project']['dependencies'] if not any(p in d for p in ['Sigima', 'SigimaX', 'datalab-capsule'])))") + # Extract dependency names from the pyproject.toml of DataLab and SigimaX + # (excluding Sigima and SigimaX, installed from local clones above) and + # install latest versions + python -m pip install -U --upgrade-strategy eager $(python -c "import tomllib, re; print(' '.join(sorted({re.sub(r'[\[\]<>=!~,.\s].*$', '', d).strip() for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomllib.loads(open(p, 'rb').read().decode())['project']['dependencies'] if not any(n in d for n in ['Sigima', 'SigimaX', 'datalab-capsule'])})))") - name: Lint with Ruff (latest) run: ruff check --output-format=github datalab diff --git a/.github/workflows/test_pyqt6.yml b/.github/workflows/test_pyqt6.yml index 1f046907c..0c2312d44 100644 --- a/.github/workflows/test_pyqt6.yml +++ b/.github/workflows/test_pyqt6.yml @@ -77,8 +77,9 @@ jobs: pip install -e ../DataLab-Capsule # Install tomli for TOML parsing (safe if already present) pip install tomli - # Extract dependencies and save to file, then install - python -c "import tomli; f=open('pyproject.toml','rb'); data=tomli.load(f); deps=[d for d in data['project']['dependencies'] if not any(p in d for p in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" + # Extract dependencies of DataLab and SigimaX (installed with --no-deps + # above), save them to file, then install + python -c "import tomli; deps=[d for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomli.load(open(p,'rb'))['project']['dependencies'] if not any(n in d for n in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" pip install -r deps.txt # Install DataLab without dependencies pip install --no-deps . @@ -105,8 +106,9 @@ jobs: pip install -e ../DataLab-Capsule # Install tomli for TOML parsing (safe if already present) pip install tomli - # Extract dependencies and save to file, then install - python -c "import tomli; f=open('pyproject.toml','rb'); data=tomli.load(f); deps=[d for d in data['project']['dependencies'] if not any(p in d for p in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" + # Extract dependencies of DataLab and SigimaX (installed with --no-deps + # above), save them to file, then install + python -c "import tomli; deps=[d for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomli.load(open(p,'rb'))['project']['dependencies'] if not any(n in d for n in ['guidata','PlotPy','Sigima', 'SigimaX', 'datalab-capsule'])]; open('deps.txt','w').write('\n'.join(deps))" pip install -r deps.txt # Install DataLab without dependencies pip install --no-deps . @@ -166,9 +168,10 @@ jobs: python -m pip install -e ../SigimaX --no-deps python -m pip install -e ../DataLab-Capsule - # Extract dependency names from pyproject.toml (excluding Sigima and - # SigimaX, installed from local clones above) and install latest versions - python -m pip install -U --upgrade-strategy eager $(python -c "import tomllib, re; print(' '.join(re.sub(r'[\[\]<>=!~,.\s].*$', '', d).strip() for d in tomllib.loads(open('pyproject.toml', 'rb').read().decode())['project']['dependencies'] if not any(p in d for p in ['Sigima', 'SigimaX', 'datalab-capsule'])))") + # Extract dependency names from the pyproject.toml of DataLab and SigimaX + # (excluding Sigima and SigimaX, installed from local clones above) and + # install latest versions + python -m pip install -U --upgrade-strategy eager $(python -c "import tomllib, re; print(' '.join(sorted({re.sub(r'[\[\]<>=!~,.\s].*$', '', d).strip() for p in ('pyproject.toml', '../SigimaX/pyproject.toml') for d in tomllib.loads(open(p, 'rb').read().decode())['project']['dependencies'] if not any(n in d for n in ['Sigima', 'SigimaX', 'datalab-capsule'])})))") - name: Lint with Ruff (latest) run: ruff check --output-format=github datalab diff --git a/datalab/tests/features/hdf5/nexus_views_app_test.py b/datalab/tests/features/hdf5/nexus_views_app_test.py new file mode 100644 index 000000000..f0058dc45 --- /dev/null +++ b/datalab/tests/features/hdf5/nexus_views_app_test.py @@ -0,0 +1,105 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +NeXus scans and multidimensional views test +-------------------------------------------- + +A scan written with the legacy NeXus conventions (as recent SOLEIL scans) is +imported with its axes: its counter versus the scanned motor and its detector +spectra as an image with the motor along Y. The frames of an image stack whose +view is enabled in the HDF5 browser are imported as images titled and located +by the motor position, and their origin survives a workspace round trip. +""" + +# guitest: show + +from __future__ import annotations + +import json +import os.path as osp + +import h5py +import numpy as np +import pytest +from sigima.objects import get_experimental_source +from sigimax.h5.selection import NDView +from sigimax.widgets.h5browser import H5BrowserDialog + +from datalab.tests import datalab_test_app_context, helpers + + +def _write_scan(fname: str) -> None: + """Write a step scan: legacy axis attributes, a counter, a detector writing a + spectrum per point and a detector writing an image per point""" + with h5py.File(fname, "w") as h5file: + entry = h5file.create_group("scan_0494") + entry.attrs["NX_class"] = "NXentry" + entry["title"] = "LaB6 calibration" + scan = entry.create_group("scan_data") + scan.attrs["NX_class"] = "NXdata" + scan["actuator_1_1"] = np.array([-8.0, -7.5, -7.0]) + scan["actuator_1_1"].attrs.update(axis=np.int32(1), primary=np.int32(1)) + scan["actuator_1_1"].attrs["units"] = "deg" + scan["counter"] = np.array([5.0, 9.0, 4.0]) + scan["spectra"] = np.arange(3 * 16, dtype=np.int32).reshape(3, 16) + scan["frames"] = np.arange(3 * 4 * 5, dtype=np.uint16).reshape(3, 4, 5) + for name in ("counter", "spectra", "frames"): + scan[name].attrs["signal"] = np.int32(1) + + +def _nexus_objects(panel, signal: str) -> list: + """Return the objects of a panel imported from a signal of an NXdata group""" + return [ + obj + for obj in panel.objmodel.get_all_objects() + if (get_experimental_source(obj) or {}).get("selection", {}).get("signal") + == signal + ] + + +def test_scan_frames_and_workspace(monkeypatch: pytest.MonkeyPatch) -> None: + """Legacy scan counters and detectors, then frames of a stack enabled in the + browser, and workspace round trip""" + original_open = H5BrowserDialog.open_file + + def open_and_enable_frames(dialog: H5BrowserDialog, fname: str) -> None: + """Open the file, and enable the import of the first two frames""" + original_open(dialog, fname) + tree = dialog.browser.tree + item = tree.find_node_item(tree.topLevelItem(0), "/scan_0494/scan_data::frames") + tree.get_node(item).set_view(NDView((1, 2), (0,), 0, 1)) + tree.set_item_importable(item, True) + + monkeypatch.setattr(H5BrowserDialog, "open_file", open_and_enable_frames) + with helpers.WorkdirRestoringTempDir() as tmpdir: + nxsname = osp.join(tmpdir, "scan.nxs") + _write_scan(nxsname) + wsname = osp.join(tmpdir, "workspace.h5") + with datalab_test_app_context(console=False, exec_loop=False) as win: + win.h5inputoutput.import_files([nxsname], True, False) + (counter,) = _nexus_objects(win.signalpanel, "counter") + np.testing.assert_array_equal(counter.x, [-8.0, -7.5, -7.0]) + assert counter.xunit == "deg" + source = get_experimental_source(counter) + assert source["details"] == {"entry_title": "LaB6 calibration"} + (spectra,) = _nexus_objects(win.imagepanel, "spectra") + assert spectra.data.shape == (3, 16) + assert (spectra.y0, spectra.dy) == (-8.0, 0.5) + frames = _nexus_objects(win.imagepanel, "frames") + assert len(frames) == 2 + assert frames[1].title.startswith("frames[1, :, :] (actuator_1_1=-7.5)") + np.testing.assert_array_equal( + frames[1].data, np.arange(20, 40).reshape(4, 5) + ) + win.save_h5_workspace(wsname) + + win.load_h5_workspace([wsname], reset_all=True) + frame = _nexus_objects(win.imagepanel, "frames")[1] + source = get_experimental_source(frame) + assert source["selection"]["view"] == {"displayed": [1, 2], "indices": [1]} + assert source["selection"]["positions"] == {"actuator_1_1": -7.5} + json.dumps(frame.metadata["experimental_source"]) + + +if __name__ == "__main__": + pytest.main([__file__]) diff --git a/doc/features/common/h5browser.rst b/doc/features/common/h5browser.rst index 8f614f4c3..0fdc3d405 100644 --- a/doc/features/common/h5browser.rst +++ b/doc/features/common/h5browser.rst @@ -51,9 +51,26 @@ neighbouring datasets. Images need increasing coordinates: a decreasing image axis is reversed together with the image, and this conversion is recorded, while an image axis that is not strictly monotonic prevents the import. +Files written with the legacy NeXus conventions, such as the scans of +synchrotron SOLEIL, are imported with their axes too: an axis dataset may give +the dimension it describes with its ``axis`` attribute, the one with the lowest +``primary`` attribute being preferred. The other measured datasets of a group, +such as all the counters and detectors of a scan, appear as additional items +below the group, each with the axes that fit its dimensions: a counter is a +signal versus the scanned motor, a detector writing a spectrum at each point an +image with the motor along Y, and a detector writing an image at each point a +stack of images (see below). + +When a NeXus file designates a default measurement (``default`` attributes), the +browser selects and previews it when the file is opened. Compressed detector +data, such as the bitshuffle/LZ4 data of Eiger detectors, is read; a dataset +compressed with an unavailable filter is reported in the tree instead of failing. + Files with several counters or incomplete NeXus descriptions can be interpreted by a plugin-provided data mapping. Each mapped object appears as an additional -item with its own axes, labels and units. Mappings must be registered before +item with its own axes, labels and units; the axes of a mapped object may +describe its first dimensions only, so that one mapping applies to the counters +and detectors of a scan. Mappings must be registered before opening the file; DataLab does not automatically discover JSON files beside it. Plugin authors can follow the `SigimaX HDF5 import guide `_. @@ -77,10 +94,30 @@ limit: compound datasets and signals stored as 2D tables still use complete objects for their graphical previews. Closing a file or the browser waits for its preview read to end. +Multidimensional datasets +------------------------- + Datasets with three or more dimensions, such as image stacks and spectral -cubes, are listed but cannot be imported as complete objects. There is no -graphical slice selector yet. Developers can read 1D or 2D views without loading -the whole cube using the selection API described in the SigimaX guide. +cubes, are imported as one image or signal per frame. Selecting such an item +shows a view selector below the preview: + + * **View**: images of two axes, or signals along one axis + * **Frames along**: the axis along which frames are taken, with the **First** + and **Last** frame and a **Step** + * **Fixed indices**: the index of the other axes, if any + * **Import these frames**: makes the item checkable and checked; unchecking + the item cancels the import + +The first frame of the view is previewed, and the number of frames is shown. +Images of the last two axes, with every frame along the preceding axis, are +proposed by default, unless the NeXus ``interpretation`` attribute of the +dataset designates spectra (signals along the last axis) or RGB images (one +image per channel). DataLab asks for confirmation before importing more than +100 frames. The frames of NeXus datasets keep the axes of their displayed +dimensions; their title gives the frame indices and, if the other axes have +coordinates, the position of the frame (e.g. ``frames[3, :, :] (theta=0.3)``). +Developers can also read views without creating objects, using the selection +API described in the SigimaX guide. Numerical values and experimental origin --------------------------------------- @@ -94,8 +131,9 @@ signals keep their imaginary part, including single-precision ones. NeXus and mapped objects carry an ``experimental_source`` metadata entry describing the source file, group, measured dataset, axes (``"."`` for a -dimension without axis) and recorded conversions. Mapped objects also identify -their mapping. This entry describes +dimension without axis) and recorded conversions, with the title, start and end +times of the NeXus entry, and, for frames, the frame indices and position. +Mapped objects also identify their mapping. This entry describes where the measurement came from; it is not the processing provenance shown in the Properties panel and does not make the experiment reproducible. diff --git a/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po b/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po index 1dc912e6d..4ccce1899 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po @@ -54,8 +54,14 @@ msgstr "L'import conserve les valeurs, libellés et unités des axes, y compris msgid "An axis with an invalid shape or length, an ``axes`` attribute that does not give one axis per dimension, or an axis that does not hold numbers is reported in the group description and prevents importing the group. An undeclared axis uses point or pixel indices; the importer does not infer a physical axis from neighbouring datasets. Images need increasing coordinates: a decreasing image axis is reversed together with the image, and this conversion is recorded, while an image axis that is not strictly monotonic prevents the import." msgstr "Un axe dont la forme ou la longueur est invalide, un attribut ``axes`` qui ne donne pas un axe par dimension ou un axe qui ne contient pas de nombres est signalé dans la description du groupe et empêche son import. Un axe non déclaré utilise les indices des points ou pixels ; l'importeur ne déduit pas d'axe physique à partir des jeux de données voisins. Les images nécessitent des coordonnées croissantes : un axe d'image décroissant est inversé avec l'image, et cette conversion est enregistrée, tandis qu'un axe d'image qui n'est pas strictement monotone empêche l'import." -msgid "Files with several counters or incomplete NeXus descriptions can be interpreted by a plugin-provided data mapping. Each mapped object appears as an additional item with its own axes, labels and units. Mappings must be registered before opening the file; DataLab does not automatically discover JSON files beside it. Plugin authors can follow the `SigimaX HDF5 import guide `_." -msgstr "Les fichiers contenant plusieurs compteurs ou des descriptions NeXus incomplètes peuvent être interprétés par un profil de correspondance fourni par un plugin. Chaque objet décrit apparaît comme un élément supplémentaire avec ses propres axes, libellés et unités. Les profils doivent être enregistrés avant l'ouverture du fichier ; DataLab ne découvre pas automatiquement les fichiers JSON placés à côté. Les auteurs de plugins peuvent suivre le `guide d'import HDF5 de SigimaX `_." +msgid "Files written with the legacy NeXus conventions, such as the scans of synchrotron SOLEIL, are imported with their axes too: an axis dataset may give the dimension it describes with its ``axis`` attribute, the one with the lowest ``primary`` attribute being preferred. The other measured datasets of a group, such as all the counters and detectors of a scan, appear as additional items below the group, each with the axes that fit its dimensions: a counter is a signal versus the scanned motor, a detector writing a spectrum at each point an image with the motor along Y, and a detector writing an image at each point a stack of images (see below)." +msgstr "Les fichiers écrits selon les conventions NeXus anciennes, comme les scans du synchrotron SOLEIL, sont aussi importés avec leurs axes : un jeu de données d'axe peut donner la dimension qu'il décrit avec son attribut ``axis``, celui dont l'attribut ``primary`` est le plus petit étant préféré. Les autres jeux de données mesurés d'un groupe, comme tous les compteurs et détecteurs d'un scan, apparaissent comme des éléments supplémentaires sous le groupe, chacun avec les axes qui correspondent à ses dimensions : un compteur est un signal en fonction du moteur scanné, un détecteur écrivant un spectre à chaque point une image avec le moteur selon Y, et un détecteur écrivant une image à chaque point une pile d'images (voir ci-dessous)." + +msgid "When a NeXus file designates a default measurement (``default`` attributes), the browser selects and previews it when the file is opened. Compressed detector data, such as the bitshuffle/LZ4 data of Eiger detectors, is read; a dataset compressed with an unavailable filter is reported in the tree instead of failing." +msgstr "Lorsqu'un fichier NeXus désigne une mesure par défaut (attributs ``default``), le navigateur la sélectionne et l'affiche à l'ouverture du fichier. Les données de détecteur compressées, comme les données bitshuffle/LZ4 des détecteurs Eiger, sont lues ; un jeu de données compressé avec un filtre indisponible est signalé dans l'arborescence au lieu de provoquer une erreur." + +msgid "Files with several counters or incomplete NeXus descriptions can be interpreted by a plugin-provided data mapping. Each mapped object appears as an additional item with its own axes, labels and units; the axes of a mapped object may describe its first dimensions only, so that one mapping applies to the counters and detectors of a scan. Mappings must be registered before opening the file; DataLab does not automatically discover JSON files beside it. Plugin authors can follow the `SigimaX HDF5 import guide `_." +msgstr "Les fichiers comportant plusieurs compteurs ou des descriptions NeXus incomplètes peuvent être interprétés par un profil de correspondance fourni par un plugin. Chaque objet décrit apparaît comme un élément supplémentaire avec ses propres axes, libellés et unités ; les axes d'un objet décrit peuvent ne décrire que ses premières dimensions, de sorte qu'un même profil s'applique aux compteurs et aux détecteurs d'un scan. Les profils doivent être enregistrés avant l'ouverture du fichier ; DataLab ne découvre pas automatiquement les fichiers JSON situés à côté. Les auteurs de plugins peuvent suivre le `guide d'import HDF5 de SigimaX `_." msgid "Large datasets and previews" msgstr "Grands jeux de données et aperçus" @@ -66,8 +72,26 @@ msgstr "La liste des jeux de données numériques utilise leur forme et leur typ msgid "Large ordinary 1D arrays and 2D images, NeXus and mapped objects are previewed with a sampling step above ``2**24`` elements (about 16.8 million). Import still reads every value, not the sampled preview. This is not a universal memory limit: compound datasets and signals stored as 2D tables still use complete objects for their graphical previews. Closing a file or the browser waits for its preview read to end." msgstr "Les grands tableaux 1D ordinaires et les images 2D, les objets NeXus et décrits par un profil sont prévisualisés avec un pas d'échantillonnage au-delà de ``2**24`` éléments (environ 16,8 millions). L'import lit toujours toutes les valeurs, pas l'aperçu échantillonné. Ce n'est pas une limite mémoire universelle : les jeux de données composites et les signaux stockés dans des tableaux 2D utilisent encore des objets complets pour leurs aperçus graphiques. La fermeture d'un fichier ou de l'explorateur attend la fin de la lecture de son aperçu." -msgid "Datasets with three or more dimensions, such as image stacks and spectral cubes, are listed but cannot be imported as complete objects. There is no graphical slice selector yet. Developers can read 1D or 2D views without loading the whole cube using the selection API described in the SigimaX guide." -msgstr "Les jeux de données à trois dimensions ou plus, comme les piles d'images et les cubes spectraux, sont listés mais ne peuvent pas être importés comme objets complets. Il n'existe pas encore de sélecteur graphique de coupes. Les développeurs peuvent lire des vues 1D ou 2D sans charger tout le cube avec l'API de sélection décrite dans le guide de SigimaX." +msgid "Multidimensional datasets" +msgstr "Jeux de données multidimensionnels" + +msgid "Datasets with three or more dimensions, such as image stacks and spectral cubes, are imported as one image or signal per frame. Selecting such an item shows a view selector below the preview:" +msgstr "Les jeux de données à trois dimensions ou plus, comme les piles d'images et les cubes spectraux, sont importés sous la forme d'une image ou d'un signal par trame. La sélection d'un tel élément affiche un sélecteur de vue sous l'aperçu :" + +msgid "**View**: images of two axes, or signals along one axis" +msgstr "**Vue** : images de deux axes, ou signaux selon un axe" + +msgid "**Frames along**: the axis along which frames are taken, with the **First** and **Last** frame and a **Step**" +msgstr "**Trames selon** : l'axe selon lequel les trames sont prises, avec la **Première** et la **Dernière** trame et un **Pas**" + +msgid "**Fixed indices**: the index of the other axes, if any" +msgstr "**Indices fixés** : l'indice des autres axes, le cas échéant" + +msgid "**Import these frames**: makes the item checkable and checked; unchecking the item cancels the import" +msgstr "**Importer ces trames** : rend l'élément cochable et le coche ; décocher l'élément annule l'import" + +msgid "The first frame of the view is previewed, and the number of frames is shown. Images of the last two axes, with every frame along the preceding axis, are proposed by default, unless the NeXus ``interpretation`` attribute of the dataset designates spectra (signals along the last axis) or RGB images (one image per channel). DataLab asks for confirmation before importing more than 100 frames. The frames of NeXus datasets keep the axes of their displayed dimensions; their title gives the frame indices and, if the other axes have coordinates, the position of the frame (e.g. ``frames[3, :, :] (theta=0.3)``). Developers can also read views without creating objects, using the selection API described in the SigimaX guide." +msgstr "La première trame de la vue est affichée en aperçu, avec le nombre de trames. Par défaut, ce sont des images des deux derniers axes qui sont proposées, avec toutes les trames selon l'axe précédent, sauf si l'attribut NeXus ``interpretation`` du jeu de données désigne des spectres (signaux selon le dernier axe) ou des images RVB (une image par canal). DataLab demande une confirmation avant d'importer plus de 100 trames. Les trames des jeux de données NeXus conservent les axes de leurs dimensions affichées ; leur titre donne les indices de la trame et, si les autres axes ont des coordonnées, la position de la trame (par exemple ``frames[3, :, :] (theta=0.3)``). Les développeurs peuvent aussi lire des vues sans créer d'objets, avec l'API de sélection décrite dans le guide de SigimaX." msgid "Numerical values and experimental origin" msgstr "Valeurs numériques et origine expérimentale" @@ -75,9 +99,12 @@ msgstr "Valeurs numériques et origine expérimentale" msgid "Unsigned 32-bit detector counts above 2 147 483 647 are imported as ``float64`` images without clipping or rounding. Other integer arrays are also converted to an exact supported type when possible. If conversion to floating point cannot preserve every integer (in particular beyond ``+/-2**53`` for ``float64``), Sigima emits a warning instead of silently promising exact values. Complex signals keep their imaginary part, including single-precision ones." msgstr "Les comptages de détecteur entiers non signés sur 32 bits au-delà de 2 147 483 647 sont importés comme images ``float64`` sans écrêtage ni arrondi. Les autres tableaux entiers sont aussi convertis vers un type pris en charge exact lorsque c'est possible. Si la conversion en flottant ne peut pas préserver chaque entier (notamment au-delà de ``+/-2**53`` pour ``float64``), Sigima émet un avertissement au lieu de promettre silencieusement des valeurs exactes. Les signaux complexes conservent leur partie imaginaire, y compris en simple précision." -msgid "NeXus and mapped objects carry an ``experimental_source`` metadata entry describing the source file, group, measured dataset, axes (``\".\"`` for a dimension without axis) and recorded conversions. Mapped objects also identify their mapping. This entry describes where the measurement came from; it is not the processing provenance shown in the Properties panel and does not make the experiment reproducible." -msgstr "Les objets NeXus et décrits par un profil portent une entrée de métadonnées ``experimental_source`` décrivant le fichier source, le groupe, le jeu de données mesurées, les axes (``\".\"`` pour une dimension sans axe) et les conversions enregistrées. Les objets décrits par un profil identifient aussi celui-ci. Cette entrée décrit l'origine de la mesure ; ce n'est pas la provenance des traitements affichée dans le panneau Propriétés et elle ne rend pas l'expérience reproductible." +msgid "NeXus and mapped objects carry an ``experimental_source`` metadata entry describing the source file, group, measured dataset, axes (``\".\"`` for a dimension without axis) and recorded conversions, with the title, start and end times of the NeXus entry, and, for frames, the frame indices and position. Mapped objects also identify their mapping. This entry describes where the measurement came from; it is not the processing provenance shown in the Properties panel and does not make the experiment reproducible." +msgstr "Les objets NeXus et décrits par un profil portent une entrée de métadonnées ``experimental_source`` décrivant le fichier source, le groupe, le jeu de données mesuré, les axes (``\".\"`` pour une dimension sans axe) et les conversions enregistrées, avec le titre et les dates de début et de fin de l'entrée NeXus et, pour les trames, les indices et la position de la trame. Les objets décrits par un profil identifient également leur profil. Cette entrée décrit l'origine de la mesure ; ce n'est pas la provenance des traitements affichée dans le panneau Propriétés, et elle ne rend pas l'expérience reproductible." msgid "Save the imported objects in a DataLab workspace to keep both their data and this metadata. Reopening that workspace does not require the original NeXus file or the mapping plugin. Generic raw dataset imports do not automatically receive this structured experimental source." msgstr "Enregistrez les objets importés dans un espace de travail DataLab pour conserver leurs données et ces métadonnées. La réouverture de cet espace de travail ne nécessite ni le fichier NeXus original ni le plugin du profil. Les imports génériques de jeux de données bruts ne reçoivent pas automatiquement cette description structurée de leur origine expérimentale." +#~ msgid "Datasets with three or more dimensions, such as image stacks and spectral cubes, are listed but cannot be imported as complete objects. There is no graphical slice selector yet. Developers can read 1D or 2D views without loading the whole cube using the selection API described in the SigimaX guide." +#~ msgstr "Les jeux de données à trois dimensions ou plus, comme les piles d'images et les cubes spectraux, sont listés mais ne peuvent pas être importés comme objets complets. Il n'existe pas encore de sélecteur graphique de coupes. Les développeurs peuvent lire des vues 1D ou 2D sans charger tout le cube avec l'API de sélection décrite dans le guide de SigimaX." + diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.04.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.04.po index b62c6f3ac..3eb18488e 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.04.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.04.po @@ -11,6 +11,12 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +msgid "Version 1.4" +msgstr "Version 1.4" + +msgid "DataLab Version 1.4.0" +msgstr "DataLab Version 1.4.0" + msgid "Requirements" msgstr "Prérequis" @@ -20,12 +26,6 @@ msgstr "Le package Python et les nouveaux projets de plugins générés exigent msgid "The Windows test runner excludes Python 3.9 from current matrices, while retaining explicit tests of pinned historical releases." msgstr "Le lanceur de tests Windows exclut Python 3.9 des matrices courantes, tout en conservant les tests explicites de versions historiques précisément sélectionnées." -msgid "Version 1.4" -msgstr "Version 1.4" - -msgid "DataLab Version 1.4.0" -msgstr "DataLab Version 1.4.0" - msgid "✨ New Features" msgstr "✨ Nouvelles fonctionnalités" @@ -305,14 +305,23 @@ msgstr "**Fichiers NeXus :**" msgid "NeXus `NXdata` groups are shown as single items in the HDF5 browser and imported as signals or images with their axes, units, labels and, for signals, uncertainties. Bin edges are converted to bin centers, non-uniform image axes are kept, and decreasing image axes are reversed with the image. Invalid axes are reported in the browser instead of being guessed" msgstr "Les groupes NeXus `NXdata` sont présentés comme des éléments uniques dans l'explorateur HDF5 et importés comme signaux ou images avec leurs axes, unités, libellés et, pour les signaux, incertitudes. Les bords de classes sont convertis en centres de classes, les axes d'image non uniformes sont conservés, et les axes d'image décroissants sont inversés avec l'image. Les axes invalides sont signalés dans l'explorateur au lieu d'être devinés" -msgid "Imported signals and images record where they come from (file, group, signal and axes, applied conversions) in their `experimental_source` metadata, which is saved with the workspace: a saved workspace reopens without the NeXus file" -msgstr "Les signaux et images importés enregistrent leur origine (fichier, groupe, signal et axes, conversions appliquées) dans leur métadonnée `experimental_source`, enregistrée avec l'espace de travail : un espace de travail enregistré se rouvre sans le fichier NeXus" +msgid "Files written with the legacy NeXus conventions, such as the scans of synchrotron SOLEIL, are imported with their axes (`axis` and `primary` attributes of the axis datasets), and every counter and detector of a scan is shown as an item of its own: counters as signals versus the scanned motor, detectors as images (a spectrum per point) or image stacks (an image per point) with the motor along their first axis" +msgstr "Les fichiers écrits selon les conventions NeXus anciennes, comme les scans du synchrotron SOLEIL, sont importés avec leurs axes (attributs `axis` et `primary` des jeux de données d'axe), et chaque compteur et détecteur d'un scan apparaît comme un élément à part entière : les compteurs comme des signaux en fonction du moteur scanné, les détecteurs comme des images (un spectre par point) ou des piles d'images (une image par point) avec le moteur selon leur premier axe" + +msgid "The HDF5 browser selects and previews the default measurement of a NeXus file (`default` attributes) when it is opened" +msgstr "Le navigateur HDF5 sélectionne et affiche la mesure par défaut d'un fichier NeXus (attributs `default`) à son ouverture" + +msgid "Compressed detector data, such as the bitshuffle/LZ4 data of Eiger detectors, is now read (with hdf5plugin, also in the standalone application); a dataset compressed with an unavailable filter is reported in the browser instead of failing" +msgstr "Les données de détecteur compressées, comme les données bitshuffle/LZ4 des détecteurs Eiger, sont désormais lues (avec hdf5plugin, y compris dans l'application autonome) ; un jeu de données compressé avec un filtre indisponible est signalé dans le navigateur au lieu de provoquer une erreur" + +msgid "Imported signals and images record where they come from (file, group, signal and axes, applied conversions, title and times of the NeXus entry) in their `experimental_source` metadata, which is saved with the workspace: a saved workspace reopens without the NeXus file" +msgstr "Les signaux et images importés enregistrent leur origine (fichier, groupe, signal et axes, conversions appliquées, titre et dates de l'entrée NeXus) dans leurs métadonnées `experimental_source`, enregistrées avec l'espace de travail : un espace de travail enregistré se rouvre sans le fichier NeXus" msgid "`.nxs` and `.nx5` files are proposed when opening HDF5 files" msgstr "Les fichiers `.nxs` et `.nx5` sont proposés à l'ouverture de fichiers HDF5" -msgid "Plugins can describe the signals and images of files that NeXus `NXdata` groups designate incompletely (no axes, several counters...) with declarative data mappings (JSON) registered with `sigimax.h5.mapping.register_mapping`: the HDF5 browser then shows each described object as an extra item, imported with its axes, labels and units" -msgstr "Les plugins peuvent décrire les signaux et images des fichiers que les groupes NeXus `NXdata` désignent de manière incomplète (sans axes, plusieurs compteurs...) avec des profils de correspondance déclaratifs (JSON) enregistrés avec `sigimax.h5.mapping.register_mapping` : l'explorateur HDF5 présente alors chaque objet décrit comme un élément supplémentaire, importé avec ses axes, libellés et unités" +msgid "Plugins can describe the signals and images of files that NeXus `NXdata` groups designate incompletely (no axes, several counters...) with declarative data mappings (JSON) registered with `sigimax.h5.mapping.register_mapping`: the HDF5 browser then shows each described object as an extra item, imported with its axes, labels and units; the axes of a mapped object may describe its first dimensions only, so that one mapping applies to the counters and detectors of a scan" +msgstr "Les plugins peuvent décrire les signaux et images des fichiers dont les groupes NeXus `NXdata` sont incomplets (pas d'axes, plusieurs compteurs...) avec des profils de correspondance déclaratifs (JSON) enregistrés par `sigimax.h5.mapping.register_mapping` : le navigateur HDF5 affiche alors chaque objet décrit comme un élément supplémentaire, importé avec ses axes, libellés et unités ; les axes d'un objet décrit peuvent ne décrire que ses premières dimensions, de sorte qu'un même profil s'applique aux compteurs et aux détecteurs d'un scan" msgid "🔄 Changes" msgstr "🔄 Changements" @@ -356,6 +365,39 @@ msgstr "Les identifiants d'annotation, l'état de verrouillage, les métadonnée msgid "DataLab now requires Sigima ≥ 1.4.0, SigimaX ≥ 1.1.0 and DataLab-Capsule 0.1.x; HDF5 imports use Sigima's experimental-source API" msgstr "DataLab nécessite désormais Sigima ≥ 1.4.0, SigimaX ≥ 1.1.0 et DataLab-Capsule 0.1.x ; les imports HDF5 utilisent l'API d'origine expérimentale de Sigima" +msgid "**Regions of interest:**" +msgstr "**Régions d'intérêt :**" + +msgid "A rectangular region of interest now selects the pixels whose centers lie inside the rectangle, bounds included, like circular and polygonal ROIs and like the display: its bounds were rounded to the nearest pixel, which could shift the selection by up to half a pixel. A rectangle whose bounds lie exactly on pixel centers now includes the pixels on both bounds, i.e. one more row and one more column than before. This applies to processing and analysis in ROIs, to ROI extraction and to the background area of the offset correction" +msgstr "Une région d'intérêt rectangulaire sélectionne désormais les pixels dont le centre est situé dans le rectangle, bornes comprises, comme les ROI circulaires et polygonales et comme l'affichage : ses bornes étaient arrondies au pixel le plus proche, ce qui pouvait décaler la sélection jusqu'à un demi-pixel. Un rectangle dont les bornes sont situées exactement sur des centres de pixels inclut désormais les pixels des deux bornes, soit une ligne et une colonne de plus qu'auparavant. Cela s'applique aux traitements et analyses dans les ROI, à l'extraction de ROI et à la zone de fond de la soustraction d'offset" + +msgid "Circular and polygonal regions of interest now also select the pixels whose centers lie inside their shape, boundary included: polygon vertices were rounded to the nearest pixel, so that the selected pixels could differ from the polygon drawn on the image, and circles were drawn in pixel units on images with non-uniform coordinates" +msgstr "Les régions d'intérêt circulaires et polygonales sélectionnent elles aussi désormais les pixels dont le centre est situé dans leur forme, bord compris : les sommets des polygones étaient arrondis au pixel le plus proche, de sorte que les pixels sélectionnés pouvaient différer du polygone tracé sur l'image, et les cercles étaient tracés en unités de pixels sur les images à coordonnées non uniformes" + +msgid "A rectangular ROI defined in pixel indices now covers its pixels up to their outer edges, so that it keeps the same pixels when converted to physical coordinates and back" +msgstr "Une ROI rectangulaire définie en indices de pixels couvre désormais ses pixels jusqu'à leurs bords extérieurs, de sorte qu'elle conserve les mêmes pixels lorsqu'elle est convertie en coordonnées physiques et inversement" + +msgid "The cells of ROI grids (**ROI > Create ROI grid...**) are now made of whole pixels, so that adjacent cells never share a pixel and a full-size grid covers every pixel exactly once, whatever the image size; on images with non-uniform coordinates, the grid now spans the whole image, whose last rows and columns were left out" +msgstr "Les cellules des grilles de ROI (**ROI > Créer une grille de ROI...**) sont désormais formées de pixels entiers, de sorte que des cellules adjacentes n'ont jamais de pixel en commun et qu'une grille pleine couvre chaque pixel exactement une fois, quelle que soit la taille de l'image ; sur les images à coordonnées non uniformes, la grille couvre désormais toute l'image, dont les dernières lignes et colonnes étaient omises" + +msgid "Regions of interest saved with earlier versions are not converted: they select pixels according to these rules when they are used again, so that processing and analysis in these regions may give slightly different results when recomputed" +msgstr "Les régions d'intérêt enregistrées avec des versions antérieures ne sont pas converties : elles sélectionnent les pixels selon ces règles lorsqu'elles sont réutilisées, de sorte que les traitements et analyses dans ces régions peuvent donner des résultats légèrement différents lorsqu'ils sont recalculés" + +msgid "**Image profiles in physical coordinates:**" +msgstr "**Profils d'image en coordonnées physiques :**" + +msgid "Line, segment, average and radial profiles (**Analysis > Intensity profiles**) are now defined in the physical coordinates of the image, like regions of interest and analysis results, instead of pixel indices: the profile parameters show coordinates in the units of the image axes, and the X axis of the resulting signals holds physical coordinates or distances with the matching unit. On images without calibration (origin 0, pixel size 1), results are unchanged" +msgstr "Les profils rectilignes, de segment, moyens et radiaux (**Analyse > Profils d'intensité**) sont désormais définis dans les coordonnées physiques de l'image, comme les régions d'intérêt et les résultats d'analyse, au lieu d'indices de pixels : les paramètres des profils indiquent des coordonnées dans les unités des axes de l'image, et l'axe X des signaux obtenus contient des coordonnées ou des distances physiques avec l'unité correspondante. Sur les images sans calibration (origine 0, taille de pixel 1), les résultats sont inchangés" + +msgid "The radial profile is now circular on images with rectangular pixels or non-uniform coordinates, and its center is correct on calibrated images, where the image center was misplaced" +msgstr "Le profil radial est désormais circulaire sur les images à pixels rectangulaires ou à coordonnées non uniformes, et son centre est correct sur les images calibrées, où le centre de l'image était mal placé" + +msgid "Segment and radial profiles are refused on images whose X and Y units differ, since distances are then undefined; coordinates outside the image are refused instead of being silently moved to its edge. Lines and segments drawn beyond the image in the profile dialog are brought back to its outermost pixels" +msgstr "Les profils de segment et radiaux sont refusés sur les images dont les unités X et Y diffèrent, les distances n'étant alors pas définies ; les coordonnées hors de l'image sont refusées au lieu d'être ramenées silencieusement au bord. Les lignes et segments tracés au-delà de l'image dans la boîte de dialogue de profil sont ramenés à ses pixels extrêmes" + +msgid "Scripts, macros and plugins must use the new parameter names (`y`/`x` for line profiles, `x1`, `y1`, `x2`, `y2` for segment and average profiles, `xc`/`yc` for radial profiles) and physical coordinates. Profile computations recorded in the provenance of workspaces saved with earlier versions are reported as not verifiable, instead of being replayed with a different meaning" +msgstr "Les scripts, macros et plugins doivent utiliser les nouveaux noms de paramètres (`y`/`x` pour les profils rectilignes, `x1`, `y1`, `x2`, `y2` pour les profils de segment et moyens, `xc`/`yc` pour les profils radiaux) et des coordonnées physiques. Les calculs de profils enregistrés dans la provenance d'espaces de travail sauvegardés avec des versions antérieures sont signalés comme non vérifiables, au lieu d'être rejoués avec une signification différente" + msgid "**HDF5 browser:**" msgstr "**Explorateur HDF5 :**" @@ -365,8 +407,8 @@ msgstr "Parcourir un fichier HDF5 ne lit plus ses jeux de données en entier : i msgid "The HDF5 browser stays responsive while a preview is read, and items selected meanwhile are not read; selecting an item that cannot be previewed (a group, for example) clears the preview. Ordinary 1D arrays and 2D images, NeXus and mapped objects above 2²⁴ values (about 16.8 million) are previewed with a step along each axis (the axes of NeXus images are still read entirely, to check them as on import); compound datasets and signals stored in 2D tables still use complete objects for graphical previews" msgstr "L'explorateur HDF5 reste réactif pendant la lecture d'un aperçu, et les éléments sélectionnés entre-temps ne sont pas lus ; la sélection d'un élément qui ne peut pas être prévisualisé (un groupe, par exemple) efface l'aperçu. Les tableaux 1D ordinaires et les images 2D, les objets NeXus et décrits par un profil au-delà de 2²⁴ valeurs (environ 16,8 millions) sont prévisualisés avec un pas le long de chaque axe (les axes des images NeXus sont encore lus entièrement, pour les vérifier comme à l'import) ; les jeux de données composites et les signaux stockés dans des tableaux 2D utilisent encore des objets complets pour leurs aperçus graphiques" -msgid "Datasets with three dimensions or more (image stacks, spectral cubes...) are now listed in the HDF5 browser, but are not directly importable and have no graphical slice selector" -msgstr "Les jeux de données à trois dimensions ou plus (piles d'images, cubes spectraux...) sont désormais listés dans l'explorateur HDF5, mais ne sont pas directement importables et n'ont pas de sélecteur graphique de coupes" +msgid "Datasets with three dimensions or more (image stacks, spectral cubes...) are now listed in the HDF5 browser and imported as one image or signal per frame: a view selector chooses the displayed axes, the frames (first, last and step along another axis) and the index of the other axes, previews the first frame, and imports the frames once **Import these frames** is checked (with a confirmation beyond 100 frames). Frames of NeXus datasets keep their axes, and their title gives their position (e.g. the motor position of each detector image of a scan)" +msgstr "Les jeux de données à trois dimensions ou plus (piles d'images, cubes spectraux...) sont désormais listés dans le navigateur HDF5 et importés sous la forme d'une image ou d'un signal par trame : un sélecteur de vue choisit les axes affichés, les trames (première, dernière et pas selon un autre axe) et l'indice des autres axes, affiche la première trame en aperçu, et importe les trames une fois **Importer ces trames** coché (avec une confirmation au-delà de 100 trames). Les trames des jeux de données NeXus conservent leurs axes, et leur titre donne leur position (par exemple la position du moteur pour chaque image de détecteur d'un scan)" msgid "Dataset attributes with more than 10 000 values are no longer copied to the metadata of imported objects" msgstr "Les attributs de jeux de données de plus de 10 000 valeurs ne sont plus copiés dans les métadonnées des objets importés" @@ -410,6 +452,15 @@ msgstr "Correction de l'import de plusieurs jeux de données depuis des fichiers msgid "Fixed HDF5 files containing broken links failing to open in the HDF5 browser, for example synchrotron master files whose detector files are not available (external links to a missing file): the broken links are now skipped and the rest of the file can be browsed and imported" msgstr "Correction de l'échec d'ouverture dans l'explorateur HDF5 des fichiers HDF5 contenant des liens rompus, par exemple les fichiers maîtres de synchrotron dont les fichiers de détecteur ne sont pas disponibles (liens externes vers un fichier absent) : les liens rompus sont désormais ignorés et le reste du fichier peut être exploré et importé" +msgid "Fixed HDF5 files containing a group linked into itself or into one of its subgroups failing to open in the HDF5 browser (the file was browsed endlessly until an error): such links back to a parent group are now skipped, while other aliases of a group or dataset are still shown at each of their paths" +msgstr "Correction des fichiers HDF5 contenant un groupe lié dans lui-même ou dans l'un de ses sous-groupes, qui ne pouvaient pas être ouverts dans l'explorateur HDF5 (le fichier était parcouru sans fin jusqu'à une erreur) : ces liens vers un groupe parent sont désormais ignorés, tandis que les autres alias d'un groupe ou d'un jeu de données restent affichés à chacun de leurs chemins" + +msgid "**Workspace saving:**" +msgstr "**Enregistrement de l'espace de travail :**" + +msgid "Fixed a failed save destroying the previous version of the workspace file: the file was emptied before the data was written, so that an error during the save, a full disk or an interruption left neither the previous nor the new workspace on disk. Workspaces, capsules and History files (`.dlhist`) are now written to a temporary file, which replaces the previous file only once completely written; if the save fails, the previous file is left untouched" +msgstr "Correction d'un enregistrement en échec qui détruisait la version précédente du fichier d'espace de travail : le fichier était vidé avant l'écriture des données, si bien qu'une erreur pendant l'enregistrement, un disque plein ou une interruption ne laissaient sur le disque ni l'ancien ni le nouvel espace de travail. Les espaces de travail, les capsules et les fichiers d'historique (`.dlhist`) sont désormais écrits dans un fichier temporaire, qui ne remplace le fichier précédent qu'une fois entièrement écrit ; en cas d'échec de l'enregistrement, le fichier précédent reste intact" + msgid "**Metadata:**" msgstr "**Métadonnées :**" @@ -428,6 +479,42 @@ msgstr "Les résultats de l'extraction de plusieurs régions d'intérêt dans un msgid "**Edit > Recompute** now also recomputes results of operations combining several objects (e.g., difference of two signals, average of several images), which were skipped" msgstr "**Édition > Retraiter** recalcule désormais aussi les résultats des opérations combinant plusieurs objets (par exemple la différence de deux signaux ou la moyenne de plusieurs images), qui étaient ignorés" +msgid "Fixed **Processing > Resampling** of images shifting every value by half a pixel: resampling an image with the default parameters, i.e. onto its own grid, filled its last row and column with NaN. The X/Y min/max parameters are now the coordinates of the centers of the first and last output pixels (by default, those of the image), and the 'Pixel size' mode keeps the requested pixel size exactly" +msgstr "Correction du **Traitement > Rééchantillonnage** des images, qui décalait toutes les valeurs d'un demi-pixel : rééchantillonner une image avec les paramètres par défaut, c'est-à-dire sur sa propre grille, remplissait sa dernière ligne et sa dernière colonne de NaN. Les paramètres X/Y min/max sont désormais les coordonnées des centres du premier et du dernier pixel de sortie (par défaut, ceux de l'image), et le mode 'Taille de pixel' conserve exactement la taille de pixel demandée" + +msgid "Fixed the sum, average, product and standard deviation of several signals, and their combination into an image, depending on the order of the signals: when a real signal came first, the imaginary parts of the complex signals were discarded" +msgstr "Correction de la somme, de la moyenne, du produit et de l'écart-type de plusieurs signaux, ainsi que de leur combinaison en image, qui dépendaient de l'ordre des signaux : lorsqu'un signal réel venait en premier, les parties imaginaires des signaux complexes étaient perdues" + +msgid "The sum, average and product of several images now accept complex images, which raised an error" +msgstr "La somme, la moyenne et le produit de plusieurs images acceptent désormais les images complexes, qui provoquaient une erreur" + +msgid "Fixed **Processing > Resampling** of complex images with the default parameters, and the Z-axis **Polynomial calibration** of complex images, discarding the imaginary parts: complex images now stay complex" +msgstr "Correction du **Traitement > Rééchantillonnage** des images complexes avec les paramètres par défaut, et de l'**Étalonnage polynomial** de l'axe Z des images complexes, qui supprimaient les parties imaginaires : les images complexes restent désormais complexes" + +msgid "Fixed modifying the result of a diagonal, horizontal or vertical flip or a 90° rotation of an image in place (e.g. from a macro or a plugin) also modifying its source image" +msgstr "Correction de la modification en place du résultat d'un retournement diagonal, horizontal ou vertical ou d'une rotation de 90° d'une image (par exemple depuis une macro ou un plugin), qui modifiait aussi l'image source" + +msgid "Fixed the extraction of several regions of interest into a single image giving wrong coordinates to images with non-uniform coordinates (the X coordinates were taken from the extracted rows and the Y coordinates from the extracted columns)" +msgstr "Correction de l'extraction de plusieurs régions d'intérêt dans une seule image, qui donnait des coordonnées erronées aux images à coordonnées non uniformes (les coordonnées X étaient prises sur les lignes extraites et les coordonnées Y sur les colonnes extraites)" + +msgid "The arbitrary rotation of images (**Processing > Geometry > Rotate by...**) now refuses images with non-uniform coordinates, like resizing and resampling, instead of producing an image whose coordinates did not match its pixels" +msgstr "La rotation arbitraire des images (**Traitement > Géométrie > Rotation de...**) refuse désormais les images à coordonnées non uniformes, comme le redimensionnement et le rééchantillonnage, au lieu de produire une image dont les coordonnées ne correspondaient pas à ses pixels" + +msgid "Fixed the uncertainty of the product of signals being lost where one of the signals is zero: it is now propagated there too" +msgstr "Correction de l'incertitude du produit de signaux, qui était perdue là où l'un des signaux est nul : elle y est désormais également propagée" + +msgid "Fixed ROIs, annotations and analysis results (centroids, detected peaks, contours...) being shifted by one pixel after a flip or a 90° rotation of an image; after a 90° rotation of a non-square image, or of an image whose coordinates do not start at zero, analysis results even ended up far from the features they describe. They now move exactly with the pixels; for images with non-uniform coordinates, circles, ellipses and polygons are moved approximately when the pixels are reversed along a non-uniform axis (a circle does not stay a circle). ROIs defined in pixel indices are also moved correctly, and inverse ROIs (which mask the inside of their shape) no longer become normal ROIs after these operations, a translation or a distribution of images on a grid" +msgstr "Correction du décalage d'un pixel des ROI, des annotations et des résultats d'analyse (centroïdes, pics détectés, contours...) après une symétrie ou une rotation de 90° d'une image ; après une rotation de 90° d'une image non carrée, ou d'une image dont les coordonnées ne commencent pas à zéro, les résultats d'analyse se retrouvaient même loin des éléments qu'ils décrivent. Ils se déplacent désormais exactement avec les pixels ; pour les images à coordonnées non uniformes, les cercles, ellipses et polygones sont déplacés de façon approchée lorsque les pixels sont inversés le long d'un axe non uniforme (un cercle ne reste pas un cercle). Les ROI définies en indices de pixels sont aussi correctement déplacées, et les ROI inverses (qui masquent l'intérieur de leur forme) ne deviennent plus des ROI normales après ces opérations, une translation ou une distribution d'images sur une grille" + +msgid "Fixed **ROI > Extract...** giving the extracted image a wrong origin when the coordinates of the source image do not start at zero, and coordinates not matching the extracted pixels for images with non-uniform coordinates" +msgstr "Correction de **ROI > Extraire...**, qui donnait à l'image extraite une origine erronée lorsque les coordonnées de l'image source ne commencent pas à zéro, et des coordonnées ne correspondant pas aux pixels extraits pour les images à coordonnées non uniformes" + +msgid "Fixed the coordinates of analysis results computed in a ROI being off by up to half a pixel" +msgstr "Correction des coordonnées des résultats d'analyse calculés dans une ROI, qui pouvaient être fausses jusqu'à un demi-pixel" + +msgid "Fixed **Processing > Level adjustment > Offset correction** using a background area truncated to integer coordinates: the area was wrong for images whose coordinates are not in pixels (e.g. in millimeters), and empty when smaller than one unit" +msgstr "Correction de **Traitement > Ajustement de niveau > Soustraction d'offset**, qui utilisait une zone de fond tronquée à des coordonnées entières : la zone était erronée pour les images dont les coordonnées ne sont pas en pixels (par exemple en millimètres), et vide lorsqu'elle mesurait moins d'une unité" + msgid "**Plugins:**" msgstr "**Plugins :**" @@ -482,89 +569,16 @@ msgstr "Correction des commandes à distance qui renvoyaient parfois le résulta msgid "Fixed DataLab freezing when closed while a remote command was still running (e.g. when closing the main window with `call_method(\"close\")`)" msgstr "Correction du blocage de DataLab lorsqu'il était fermé alors qu'une commande à distance était encore en cours d'exécution (par exemple en fermant la fenêtre principale avec `call_method(\"close\")`)" +#, python-brace-format +msgid "Fixed images with non-uniform coordinates losing them when transferred through the Web API (`GET` and `PUT /objects/{name}/data`): they were rebuilt with default uniform coordinates. The NPZ data format now includes these coordinates; archives written by earlier versions remain readable. Clients with their own NPZ reader, such as DataLab-Kernel, must support the new entries to take advantage of this" +msgstr "Correction des images à coordonnées non uniformes qui perdaient celles-ci lors d'un transfert par l'API Web (`GET` et `PUT /objects/{name}/data`) : elles étaient reconstruites avec des coordonnées uniformes par défaut. Le format de données NPZ inclut désormais ces coordonnées ; les archives écrites par les versions antérieures restent lisibles. Les clients disposant de leur propre lecteur NPZ, comme DataLab-Kernel, doivent prendre en charge les nouvelles entrées pour en bénéficier" + msgid "**Security:**" msgstr "**Sécurité :**" msgid "Opening a workspace received from someone else can no longer make DataLab load or run other code installed on the computer. The parameters stored with objects, analysis results and History actions name their class, and DataLab imported whatever module they named and called the object named there, which a modified file could use, for example, to make DataLab quit. Only parameter classes of DataLab, Sigima, guidata and installed plugins are now used; other stored parameters are reported as unreadable (fixes [Issue #407](https://github.com/DataLab-Platform/DataLab/issues/407))" msgstr "Ouvrir un espace de travail reçu d'une autre personne ne permet plus de faire charger ou exécuter par DataLab un autre code installé sur l'ordinateur. Les paramètres enregistrés avec les objets, les résultats d'analyse et les actions de l'historique nomment leur classe, et DataLab importait le module ainsi nommé puis appelait l'objet désigné, ce qu'un fichier modifié pouvait exploiter, par exemple pour faire quitter DataLab. Seules les classes de paramètres de DataLab, Sigima, guidata et des plugins installés sont désormais utilisées ; les autres paramètres enregistrés sont signalés comme illisibles (corrige [l'issue #407](https://github.com/DataLab-Platform/DataLab/issues/407))" -msgid "Fixed HDF5 files containing a group linked into itself or into one of its subgroups failing to open in the HDF5 browser (the file was browsed endlessly until an error): such links back to a parent group are now skipped, while other aliases of a group or dataset are still shown at each of their paths" -msgstr "Correction des fichiers HDF5 contenant un groupe lié dans lui-même ou dans l'un de ses sous-groupes, qui ne pouvaient pas être ouverts dans l'explorateur HDF5 (le fichier était parcouru sans fin jusqu'à une erreur) : ces liens vers un groupe parent sont désormais ignorés, tandis que les autres alias d'un groupe ou d'un jeu de données restent affichés à chacun de leurs chemins" - -msgid "**Workspace saving:**" -msgstr "**Enregistrement de l'espace de travail :**" - -msgid "Fixed a failed save destroying the previous version of the workspace file: the file was emptied before the data was written, so that an error during the save, a full disk or an interruption left neither the previous nor the new workspace on disk. Workspaces, capsules and History files (`.dlhist`) are now written to a temporary file, which replaces the previous file only once completely written; if the save fails, the previous file is left untouched" -msgstr "Correction d'un enregistrement en échec qui détruisait la version précédente du fichier d'espace de travail : le fichier était vidé avant l'écriture des données, si bien qu'une erreur pendant l'enregistrement, un disque plein ou une interruption ne laissaient sur le disque ni l'ancien ni le nouvel espace de travail. Les espaces de travail, les capsules et les fichiers d'historique (`.dlhist`) sont désormais écrits dans un fichier temporaire, qui ne remplace le fichier précédent qu'une fois entièrement écrit ; en cas d'échec de l'enregistrement, le fichier précédent reste intact" - -msgid "Fixed **Processing > Resampling** of images shifting every value by half a pixel: resampling an image with the default parameters, i.e. onto its own grid, filled its last row and column with NaN. The X/Y min/max parameters are now the coordinates of the centers of the first and last output pixels (by default, those of the image), and the 'Pixel size' mode keeps the requested pixel size exactly" -msgstr "Correction du **Traitement > Rééchantillonnage** des images, qui décalait toutes les valeurs d'un demi-pixel : rééchantillonner une image avec les paramètres par défaut, c'est-à-dire sur sa propre grille, remplissait sa dernière ligne et sa dernière colonne de NaN. Les paramètres X/Y min/max sont désormais les coordonnées des centres du premier et du dernier pixel de sortie (par défaut, ceux de l'image), et le mode 'Taille de pixel' conserve exactement la taille de pixel demandée" - -msgid "Fixed the sum, average, product and standard deviation of several signals, and their combination into an image, depending on the order of the signals: when a real signal came first, the imaginary parts of the complex signals were discarded" -msgstr "Correction de la somme, de la moyenne, du produit et de l'écart-type de plusieurs signaux, ainsi que de leur combinaison en image, qui dépendaient de l'ordre des signaux : lorsqu'un signal réel venait en premier, les parties imaginaires des signaux complexes étaient perdues" - -msgid "The sum, average and product of several images now accept complex images, which raised an error" -msgstr "La somme, la moyenne et le produit de plusieurs images acceptent désormais les images complexes, qui provoquaient une erreur" - -msgid "Fixed **Processing > Resampling** of complex images with the default parameters, and the Z-axis **Polynomial calibration** of complex images, discarding the imaginary parts: complex images now stay complex" -msgstr "Correction du **Traitement > Rééchantillonnage** des images complexes avec les paramètres par défaut, et de l'**Étalonnage polynomial** de l'axe Z des images complexes, qui supprimaient les parties imaginaires : les images complexes restent désormais complexes" - -msgid "Fixed modifying the result of a diagonal, horizontal or vertical flip or a 90° rotation of an image in place (e.g. from a macro or a plugin) also modifying its source image" -msgstr "Correction de la modification en place du résultat d'un retournement diagonal, horizontal ou vertical ou d'une rotation de 90° d'une image (par exemple depuis une macro ou un plugin), qui modifiait aussi l'image source" - -msgid "Fixed the extraction of several regions of interest into a single image giving wrong coordinates to images with non-uniform coordinates (the X coordinates were taken from the extracted rows and the Y coordinates from the extracted columns)" -msgstr "Correction de l'extraction de plusieurs régions d'intérêt dans une seule image, qui donnait des coordonnées erronées aux images à coordonnées non uniformes (les coordonnées X étaient prises sur les lignes extraites et les coordonnées Y sur les colonnes extraites)" - -msgid "The arbitrary rotation of images (**Processing > Geometry > Rotate by...**) now refuses images with non-uniform coordinates, like resizing and resampling, instead of producing an image whose coordinates did not match its pixels" -msgstr "La rotation arbitraire des images (**Traitement > Géométrie > Rotation de...**) refuse désormais les images à coordonnées non uniformes, comme le redimensionnement et le rééchantillonnage, au lieu de produire une image dont les coordonnées ne correspondaient pas à ses pixels" +#~ msgid "Datasets with three dimensions or more (image stacks, spectral cubes...) are now listed in the HDF5 browser, but are not directly importable and have no graphical slice selector" +#~ msgstr "Les jeux de données à trois dimensions ou plus (piles d'images, cubes spectraux...) sont désormais listés dans l'explorateur HDF5, mais ne sont pas directement importables et n'ont pas de sélecteur graphique de coupes" -msgid "Fixed the uncertainty of the product of signals being lost where one of the signals is zero: it is now propagated there too" -msgstr "Correction de l'incertitude du produit de signaux, qui était perdue là où l'un des signaux est nul : elle y est désormais également propagée" - -msgid "Fixed images with non-uniform coordinates losing them when transferred through the Web API (`GET` and `PUT /objects/{name}/data`): they were rebuilt with default uniform coordinates. The NPZ data format now includes these coordinates; archives written by earlier versions remain readable. Clients with their own NPZ reader, such as DataLab-Kernel, must support the new entries to take advantage of this" -msgstr "Correction des images à coordonnées non uniformes qui perdaient celles-ci lors d'un transfert par l'API Web (`GET` et `PUT /objects/{name}/data`) : elles étaient reconstruites avec des coordonnées uniformes par défaut. Le format de données NPZ inclut désormais ces coordonnées ; les archives écrites par les versions antérieures restent lisibles. Les clients disposant de leur propre lecteur NPZ, comme DataLab-Kernel, doivent prendre en charge les nouvelles entrées pour en bénéficier" - -msgid "**Regions of interest:**" -msgstr "**Régions d'intérêt :**" - -msgid "A rectangular region of interest now selects the pixels whose centers lie inside the rectangle, bounds included, like circular and polygonal ROIs and like the display: its bounds were rounded to the nearest pixel, which could shift the selection by up to half a pixel. A rectangle whose bounds lie exactly on pixel centers now includes the pixels on both bounds, i.e. one more row and one more column than before. This applies to processing and analysis in ROIs, to ROI extraction and to the background area of the offset correction" -msgstr "Une région d'intérêt rectangulaire sélectionne désormais les pixels dont le centre est situé dans le rectangle, bornes comprises, comme les ROI circulaires et polygonales et comme l'affichage : ses bornes étaient arrondies au pixel le plus proche, ce qui pouvait décaler la sélection jusqu'à un demi-pixel. Un rectangle dont les bornes sont situées exactement sur des centres de pixels inclut désormais les pixels des deux bornes, soit une ligne et une colonne de plus qu'auparavant. Cela s'applique aux traitements et analyses dans les ROI, à l'extraction de ROI et à la zone de fond de la soustraction d'offset" - -msgid "Circular and polygonal regions of interest now also select the pixels whose centers lie inside their shape, boundary included: polygon vertices were rounded to the nearest pixel, so that the selected pixels could differ from the polygon drawn on the image, and circles were drawn in pixel units on images with non-uniform coordinates" -msgstr "Les régions d'intérêt circulaires et polygonales sélectionnent elles aussi désormais les pixels dont le centre est situé dans leur forme, bord compris : les sommets des polygones étaient arrondis au pixel le plus proche, de sorte que les pixels sélectionnés pouvaient différer du polygone tracé sur l'image, et les cercles étaient tracés en unités de pixels sur les images à coordonnées non uniformes" - -msgid "A rectangular ROI defined in pixel indices now covers its pixels up to their outer edges, so that it keeps the same pixels when converted to physical coordinates and back" -msgstr "Une ROI rectangulaire définie en indices de pixels couvre désormais ses pixels jusqu'à leurs bords extérieurs, de sorte qu'elle conserve les mêmes pixels lorsqu'elle est convertie en coordonnées physiques et inversement" - -msgid "The cells of ROI grids (**ROI > Create ROI grid...**) are now made of whole pixels, so that adjacent cells never share a pixel and a full-size grid covers every pixel exactly once, whatever the image size; on images with non-uniform coordinates, the grid now spans the whole image, whose last rows and columns were left out" -msgstr "Les cellules des grilles de ROI (**ROI > Créer une grille de ROI...**) sont désormais formées de pixels entiers, de sorte que des cellules adjacentes n'ont jamais de pixel en commun et qu'une grille pleine couvre chaque pixel exactement une fois, quelle que soit la taille de l'image ; sur les images à coordonnées non uniformes, la grille couvre désormais toute l'image, dont les dernières lignes et colonnes étaient omises" - -msgid "Regions of interest saved with earlier versions are not converted: they select pixels according to these rules when they are used again, so that processing and analysis in these regions may give slightly different results when recomputed" -msgstr "Les régions d'intérêt enregistrées avec des versions antérieures ne sont pas converties : elles sélectionnent les pixels selon ces règles lorsqu'elles sont réutilisées, de sorte que les traitements et analyses dans ces régions peuvent donner des résultats légèrement différents lorsqu'ils sont recalculés" - -msgid "**Image profiles in physical coordinates:**" -msgstr "**Profils d'image en coordonnées physiques :**" - -msgid "Line, segment, average and radial profiles (**Analysis > Intensity profiles**) are now defined in the physical coordinates of the image, like regions of interest and analysis results, instead of pixel indices: the profile parameters show coordinates in the units of the image axes, and the X axis of the resulting signals holds physical coordinates or distances with the matching unit. On images without calibration (origin 0, pixel size 1), results are unchanged" -msgstr "Les profils rectilignes, de segment, moyens et radiaux (**Analyse > Profils d'intensité**) sont désormais définis dans les coordonnées physiques de l'image, comme les régions d'intérêt et les résultats d'analyse, au lieu d'indices de pixels : les paramètres des profils indiquent des coordonnées dans les unités des axes de l'image, et l'axe X des signaux obtenus contient des coordonnées ou des distances physiques avec l'unité correspondante. Sur les images sans calibration (origine 0, taille de pixel 1), les résultats sont inchangés" - -msgid "The radial profile is now circular on images with rectangular pixels or non-uniform coordinates, and its center is correct on calibrated images, where the image center was misplaced" -msgstr "Le profil radial est désormais circulaire sur les images à pixels rectangulaires ou à coordonnées non uniformes, et son centre est correct sur les images calibrées, où le centre de l'image était mal placé" - -msgid "Segment and radial profiles are refused on images whose X and Y units differ, since distances are then undefined; coordinates outside the image are refused instead of being silently moved to its edge. Lines and segments drawn beyond the image in the profile dialog are brought back to its outermost pixels" -msgstr "Les profils de segment et radiaux sont refusés sur les images dont les unités X et Y diffèrent, les distances n'étant alors pas définies ; les coordonnées hors de l'image sont refusées au lieu d'être ramenées silencieusement au bord. Les lignes et segments tracés au-delà de l'image dans la boîte de dialogue de profil sont ramenés à ses pixels extrêmes" - -msgid "Scripts, macros and plugins must use the new parameter names (`y`/`x` for line profiles, `x1`, `y1`, `x2`, `y2` for segment and average profiles, `xc`/`yc` for radial profiles) and physical coordinates. Profile computations recorded in the provenance of workspaces saved with earlier versions are reported as not verifiable, instead of being replayed with a different meaning" -msgstr "Les scripts, macros et plugins doivent utiliser les nouveaux noms de paramètres (`y`/`x` pour les profils rectilignes, `x1`, `y1`, `x2`, `y2` pour les profils de segment et moyens, `xc`/`yc` pour les profils radiaux) et des coordonnées physiques. Les calculs de profils enregistrés dans la provenance d'espaces de travail sauvegardés avec des versions antérieures sont signalés comme non vérifiables, au lieu d'être rejoués avec une signification différente" - -msgid "Fixed ROIs, annotations and analysis results (centroids, detected peaks, contours...) being shifted by one pixel after a flip or a 90° rotation of an image; after a 90° rotation of a non-square image, or of an image whose coordinates do not start at zero, analysis results even ended up far from the features they describe. They now move exactly with the pixels; for images with non-uniform coordinates, circles, ellipses and polygons are moved approximately when the pixels are reversed along a non-uniform axis (a circle does not stay a circle). ROIs defined in pixel indices are also moved correctly, and inverse ROIs (which mask the inside of their shape) no longer become normal ROIs after these operations, a translation or a distribution of images on a grid" -msgstr "Correction du décalage d'un pixel des ROI, des annotations et des résultats d'analyse (centroïdes, pics détectés, contours...) après une symétrie ou une rotation de 90° d'une image ; après une rotation de 90° d'une image non carrée, ou d'une image dont les coordonnées ne commencent pas à zéro, les résultats d'analyse se retrouvaient même loin des éléments qu'ils décrivent. Ils se déplacent désormais exactement avec les pixels ; pour les images à coordonnées non uniformes, les cercles, ellipses et polygones sont déplacés de façon approchée lorsque les pixels sont inversés le long d'un axe non uniforme (un cercle ne reste pas un cercle). Les ROI définies en indices de pixels sont aussi correctement déplacées, et les ROI inverses (qui masquent l'intérieur de leur forme) ne deviennent plus des ROI normales après ces opérations, une translation ou une distribution d'images sur une grille" - -msgid "Fixed **ROI > Extract...** giving the extracted image a wrong origin when the coordinates of the source image do not start at zero, and coordinates not matching the extracted pixels for images with non-uniform coordinates" -msgstr "Correction de **ROI > Extraire...**, qui donnait à l'image extraite une origine erronée lorsque les coordonnées de l'image source ne commencent pas à zéro, et des coordonnées ne correspondant pas aux pixels extraits pour les images à coordonnées non uniformes" - -msgid "Fixed the coordinates of analysis results computed in a ROI being off by up to half a pixel" -msgstr "Correction des coordonnées des résultats d'analyse calculés dans une ROI, qui pouvaient être fausses jusqu'à un demi-pixel" - -msgid "Fixed **Processing > Level adjustment > Offset correction** using a background area truncated to integer coordinates: the area was wrong for images whose coordinates are not in pixels (e.g. in millimeters), and empty when smaller than one unit" -msgstr "Correction de **Traitement > Ajustement de niveau > Soustraction d'offset**, qui utilisait une zone de fond tronquée à des coordonnées entières : la zone était erronée pour les images dont les coordonnées ne sont pas en pixels (par exemple en millimètres), et vide lorsqu'elle mesurait moins d'une unité" diff --git a/doc/release_notes/release_1.04.md b/doc/release_notes/release_1.04.md index 53a4b87d4..7afa2fe32 100644 --- a/doc/release_notes/release_1.04.md +++ b/doc/release_notes/release_1.04.md @@ -125,9 +125,12 @@ DataLab now uses stable UUID-based object references across object trees, result **NeXus files:** * NeXus `NXdata` groups are shown as single items in the HDF5 browser and imported as signals or images with their axes, units, labels and, for signals, uncertainties. Bin edges are converted to bin centers, non-uniform image axes are kept, and decreasing image axes are reversed with the image. Invalid axes are reported in the browser instead of being guessed -* Imported signals and images record where they come from (file, group, signal and axes, applied conversions) in their `experimental_source` metadata, which is saved with the workspace: a saved workspace reopens without the NeXus file +* Files written with the legacy NeXus conventions, such as the scans of synchrotron SOLEIL, are imported with their axes (`axis` and `primary` attributes of the axis datasets), and every counter and detector of a scan is shown as an item of its own: counters as signals versus the scanned motor, detectors as images (a spectrum per point) or image stacks (an image per point) with the motor along their first axis +* The HDF5 browser selects and previews the default measurement of a NeXus file (`default` attributes) when it is opened +* Compressed detector data, such as the bitshuffle/LZ4 data of Eiger detectors, is now read (with hdf5plugin, also in the standalone application); a dataset compressed with an unavailable filter is reported in the browser instead of failing +* Imported signals and images record where they come from (file, group, signal and axes, applied conversions, title and times of the NeXus entry) in their `experimental_source` metadata, which is saved with the workspace: a saved workspace reopens without the NeXus file * `.nxs` and `.nx5` files are proposed when opening HDF5 files -* Plugins can describe the signals and images of files that NeXus `NXdata` groups designate incompletely (no axes, several counters...) with declarative data mappings (JSON) registered with `sigimax.h5.mapping.register_mapping`: the HDF5 browser then shows each described object as an extra item, imported with its axes, labels and units +* Plugins can describe the signals and images of files that NeXus `NXdata` groups designate incompletely (no axes, several counters...) with declarative data mappings (JSON) registered with `sigimax.h5.mapping.register_mapping`: the HDF5 browser then shows each described object as an extra item, imported with its axes, labels and units; the axes of a mapped object may describe its first dimensions only, so that one mapping applies to the counters and detectors of a scan ### 🔄 Changes ### @@ -171,7 +174,7 @@ DataLab now uses stable UUID-based object references across object trees, result * Browsing an HDF5 file no longer reads its datasets entirely: they are listed and described from their shape and data type, and the value previews read only their first elements. Large files open faster and use less memory; data is read when a signal or an image is previewed or imported * The HDF5 browser stays responsive while a preview is read, and items selected meanwhile are not read; selecting an item that cannot be previewed (a group, for example) clears the preview. Ordinary 1D arrays and 2D images, NeXus and mapped objects above 2²⁴ values (about 16.8 million) are previewed with a step along each axis (the axes of NeXus images are still read entirely, to check them as on import); compound datasets and signals stored in 2D tables still use complete objects for graphical previews -* Datasets with three dimensions or more (image stacks, spectral cubes...) are now listed in the HDF5 browser, but are not directly importable and have no graphical slice selector +* Datasets with three dimensions or more (image stacks, spectral cubes...) are now listed in the HDF5 browser and imported as one image or signal per frame: a view selector chooses the displayed axes, the frames (first, last and step along another axis) and the index of the other axes, previews the first frame, and imports the frames once **Import these frames** is checked (with a confirmation beyond 100 frames). Frames of NeXus datasets keep their axes, and their title gives their position (e.g. the motor position of each detector image of a scan) * Dataset attributes with more than 10 000 values are no longer copied to the metadata of imported objects See the [HDF5 browser guide](../features/common/h5browser.rst) for scientific object import, experimental origin and preview limits.