From 24c6e812aef420b425636e897d7103d0c930ea73 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Sun, 15 Mar 2026 23:26:56 +0100 Subject: [PATCH 01/32] Update NXxas and add child classes --- applications/NXxas.nxdl.xml | 133 ++--- applications/NXxas_herfd.nxdl.xml | 549 ++++++++++++++++++ applications/NXxas_pey.nxdl.xml | 109 ++++ applications/NXxas_pfy.nxdl.xml | 126 ++++ applications/NXxas_tey.nxdl.xml | 102 ++++ applications/NXxas_tfy.nxdl.xml | 100 ++++ ...Xxas_new.nxdl.xml => NXxas_trans.nxdl.xml} | 141 ++--- base_classes/NXemission_line.nxdl.xml | 2 +- base_classes/NXxas_mode.nxdl.xml | 145 ----- 9 files changed, 1099 insertions(+), 308 deletions(-) create mode 100644 applications/NXxas_herfd.nxdl.xml create mode 100644 applications/NXxas_pey.nxdl.xml create mode 100644 applications/NXxas_pfy.nxdl.xml create mode 100644 applications/NXxas_tey.nxdl.xml create mode 100644 applications/NXxas_tfy.nxdl.xml rename applications/{NXxas_new.nxdl.xml => NXxas_trans.nxdl.xml} (52%) delete mode 100644 base_classes/NXxas_mode.nxdl.xml diff --git a/applications/NXxas.nxdl.xml b/applications/NXxas.nxdl.xml index f076e9bb42..89058b8209 100644 --- a/applications/NXxas.nxdl.xml +++ b/applications/NXxas.nxdl.xml @@ -3,7 +3,7 @@ - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://definition.nexusformat.org/nxdl/3.1 ../nxdl.xsd "> The symbol(s) listed here will be used below to coordinate datasets with the same shape. - - Number of points + + Number of energy data points - + + Number of electronic transitions + + - This is an application definition for raw data from an X-ray absorption spectroscopy experiment. - - This is essentially a scan on energy versus incoming/ - absorbed beam. + This is a generic application definition for X-ray absorption spectroscopy. Specialized definitions are available for different acquisition modes. - - - Official NeXus NXDL schema to which this file conforms + Official NeXus NXDL schema to which this file conforms. - - - - - - - - - - - - - - - - - - - - - - - - - - - This data corresponds to the sample signal. - - - - - + + Excited element + + + Absorption edge + + Specify if the data commes from a calculation + + + + The energy axis of the spectrum. + + + + + + + + The intensity of the spectrum. The precise definition of what is + meant by intensity depends on the acquisition mode, and will be + specified by each subclass application definition. + + + + + + + + The errors associated with the intensity of the spectrum. + + + + + - Descriptive name of sample - - - - - - Count to a preset value based on either clock time (timer) - or received monitor counts (monitor). - - - - - - - - preset value for time or monitor - - - This field could be a link to ``/NXentry/NXinstrument/incoming_beam:NXdetector/data`` - - - + Descriptive name of the sample - - - - - Detection method used for observing the sample absorption (pick one from the enumerated list and spell exactly) - - - - - - - - + + Plot of the X-ray absorption intensity versus energy + + diff --git a/applications/NXxas_herfd.nxdl.xml b/applications/NXxas_herfd.nxdl.xml new file mode 100644 index 0000000000..ac21c9a2bd --- /dev/null +++ b/applications/NXxas_herfd.nxdl.xml @@ -0,0 +1,549 @@ + + + + + + High-energy resolution fluorescence detection (HERFD) is a particular + case of partial fluorescence yield measured with a crystal analyzer + spectrometer with an energy bandwidth of approximately 1-2 eV. + + The HERFD spectrum corresponds to a constant-emission-energy cut + through the Resonant Inelastic X-ray Scattering (RIXS) plane. + The spectral shape depends on the emission energy, making the + emission line and emission energy mandatory metadata. + + .. math:: \mu(E) \propto I_f/I_0 + + The spectrometer uses Rowland circle geometry (Johann or Johansson + type). Multiple crystal analyzers may be arranged at different + horizontal angles around the sample to increase solid angle coverage. + + + + Official NeXus NXDL schema to which this file conforms. + + + + + + + The absorption coefficient :math:`\mu(E) \propto I_f/I_0`, + measured at a specific emission energy with high energy + resolution. + + + + + + + + The emission line at which the HERFD spectrum is measured. + + + + + The emission energy at which the spectrometer is set. + + + + + Beamline coordinate system with the sample at the origin: + x along the beam, y horizontal, z opposite to gravity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Should point to + ``transformations/beam``. + + + + + Two rotations relating the beamline frame to + the NeXus/McStas laboratory frame, plus direction + vectors labeling beam and gravity. + + + + Direction of the incident beam in the beamline + coordinate system. + + + + + + + + + + + + + + + Direction of gravity in the beamline coordinate + system. + + + + + + + + + + + + + + + Active rotation moving gravity from the + beamline direction (-z) to the McStas direction (-y). + + + + + + + + + + + + + + + + + + + + Active rotation moving the beam from the + beamline direction (+x) to the McStas direction (+z). + + + + + + + + + + + + + + Should point to ``.`` (the McStas laboratory + frame). + + + + + + + + + The sample is at the origin of the beamline + coordinate system. Should point to + ``/entry/beamline_coordinate_system``. + + + + + + The incident X-ray beam. + + + Energy of the incident beam at the sample position. + + + + + Should point to + ``beam/transformations/beam_direction``. + + + + + + Beam direction in the beamline coordinate + system. The beam travels along +x. + + + + + + + + + Should point to + ``/entry/beamline_coordinate_system`` + or to ``/entry/sample``. + + + + + + + + + + + + + + + + + Detector measuring the incident beam intensity + :math:`I_0`, positioned upstream of the sample along + the beam direction. + + + + + + + + + Should point to + ``i0/transformations/i0_distance``. + + + + + + Distance from the sample to the I0 detector, + measured upstream along the beam (negative x + direction in the beamline frame). + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + + + + + Crystal analyzer on the Rowland circle. For + multi-crystal spectrometers, use one group per + crystal (e.g. ``analyzer1``, ``analyzer2``). + + + + Type or material of the analyzer crystal + (Si, Ge, etc.). + + + + + Miller indices (hkl) values of the nominal + reflection. + + + + + + + + The spacing between crystal planes of the + reflection. + + + + + Bragg angle :math:`\theta_B` of the nominal + reflection. + + + + + Bending radius of the spherically bent crystal + analyzer. In Johann geometry this is :math:`2R_R` + (twice the Rowland radius). + + + + + Radius of the Rowland circle :math:`R_R`. The + sample, crystal center, and detector focus all + lie on this circle. + + + + + The energy bandwidth or resolution of the crystal + analyzer. + + + + + The type of crystal analyzer geometry. + + + + + + + + + Diameter of the crystal analyzer wafer. + + + + + Should point to the last transformation in the + chain, i.e. + ``transformations/analyzer_distance``. + + + + + Transformation chain placing the analyzer relative + to the sample: azimuthal angle, polar angle, + then distance. + + + + Sample-to-analyzer distance. + + + + + + + + + + + + + + + + + + + + Polar angle of the analyzer in the vertical + Rowland plane. Elevation from the horizontal + beam plane to the sample-analyzer direction. + + + + + + + + + + + + + + + + + + + + Azimuthal (horizontal) angle of the + spectrometer arm from the incident beam + direction. Rotation around the vertical + z-axis. Typically around 90 degrees to + minimize elastic scattering. + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + + + + + Detector measuring the fluorescence intensity + :math:`I_f` diffracted by the crystal analyzer(s). + + + + + + + + + Should point to the last transformation in the + chain, i.e. + ``transformations/detector_distance``. + + + + + Transformation chain placing the detector relative + to the sample: azimuthal angle, polar angle, + then distance. + + + + Distance from the sample to the detector. + + + + + + + + + + + + + + + + + + + + Polar angle of the detector in the vertical + Rowland plane. + + + + + + + + + + + + + + + + + + + + Azimuthal (horizontal) angle of the detector + from the incident beam direction. Should + match the analyzer azimuthal angle for + on-Rowland focusing. + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + + + + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, if). + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + + + diff --git a/applications/NXxas_pey.nxdl.xml b/applications/NXxas_pey.nxdl.xml new file mode 100644 index 0000000000..54db31dfdc --- /dev/null +++ b/applications/NXxas_pey.nxdl.xml @@ -0,0 +1,109 @@ + + + + + + In partial electron yield (PEY), the XAS spectrum is measured by + collecting electrons above a certain kinetic energy threshold. A + retarding voltage (bias) is applied to discriminate against + low-energy secondary electrons, selecting only higher-energy Auger + or photoelectrons: + + .. math:: \mu(E) \propto I_{ey}/I_0 + + By selecting a specific energy range, PEY can enhance the surface + sensitivity and selectivity compared to total electron yield. + + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field contains the processed absorption coefficient. When the raw + detector data and processing steps are available, they can be stored + in the optional ``NXinstrument`` and ``NXprocess`` groups, + enabling full reproducibility of the data reduction. + + + + Official NeXus NXDL schema to which this file conforms. + + + + + + + The absorption coefficient :math:`\mu(E) \propto I_{ey}/I_0`, + where :math:`I_{ey}` is the partial electron yield signal + above the retarding voltage threshold. + + + + + + + + + Detector measuring the incident beam intensity + :math:`I_0`. + + + + + + + + + + Detector measuring the partial electron yield + :math:`I_{ey}`. + + + + + + + + + The retarding voltage (bias) applied to select + electrons above a kinetic energy threshold. + + + + + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, iey). + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + + + diff --git a/applications/NXxas_pfy.nxdl.xml b/applications/NXxas_pfy.nxdl.xml new file mode 100644 index 0000000000..b3597b8380 --- /dev/null +++ b/applications/NXxas_pfy.nxdl.xml @@ -0,0 +1,126 @@ + + + + + + In partial fluorescence yield (PFY), an energy-dispersive detector + (such as a silicon-drift diode or high-purity Ge detector) is used to + select a portion of the fluorescence signal. Typically, only energies + around a selected fluorescence line of the absorbing element are + selected (e.g. :math:`K\alpha`), rejecting all other energies via a + region of interest (ROI) of the multichannel analyzer (MCA) spectrum. + + The absorption coefficient is proportional to: + + .. math:: \mu(E) \propto I_f/I_0 + + where :math:`I_f` is the fluorescence intensity summed over the ROI + channels (corrected for dead-time), and :math:`I_0` is the incident + beam intensity. PFY may be affected by self-absorption effects. + + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field contains the processed absorption coefficient. When the raw + detector data and processing steps are available, they can be stored + in the optional ``NXinstrument`` and ``NXprocess`` groups, + enabling full reproducibility of the data reduction. + + + + Official NeXus NXDL schema to which this file conforms. + + + + + + + The absorption coefficient :math:`\mu(E) \propto I_f/I_0`, + where :math:`I_f` is the dead-time corrected fluorescence + intensity integrated over the selected ROI. + + + + + + + + The emission line(s) selected in the ROI for the partial + fluorescence yield measurement. + + + + + + Detector measuring the incident beam intensity + :math:`I_0`. + + + + + + + + + + Energy-dispersive fluorescence detector. The ``data`` + field holds the fluorescence intensity integrated + over the ROI, corrected for dead-time. + + + + + + + + Dead-time correction constant. + + + + Detector live time per energy point. + + + + + + + + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, if), including dead-time + correction and any self-absorption correction applied. + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + + + diff --git a/applications/NXxas_tey.nxdl.xml b/applications/NXxas_tey.nxdl.xml new file mode 100644 index 0000000000..d23a31ab5c --- /dev/null +++ b/applications/NXxas_tey.nxdl.xml @@ -0,0 +1,102 @@ + + + + + + In total electron yield (TEY), the XAS spectrum is measured by + collecting all secondary electrons emitted from the sample surface. + The drain current or total electron current :math:`I_{ey}` is + proportional to the absorption coefficient: + + .. math:: \mu(E) \propto I_{ey}/I_0 + + TEY is inherently surface-sensitive because electrons are readily + absorbed by most materials, limiting the probing depth to a few + nanometers. + + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field contains the processed absorption coefficient. When the raw + detector data and processing steps are available, they can be stored + in the optional ``NXinstrument`` and ``NXprocess`` groups, + enabling full reproducibility of the data reduction. + + + + Official NeXus NXDL schema to which this file conforms. + + + + + + + The absorption coefficient :math:`\mu(E) \propto I_{ey}/I_0`, + where :math:`I_{ey}` is the total electron yield signal. + + + + + + + + + Detector measuring the incident beam intensity + :math:`I_0`. + + + + + + + + + + Detector measuring the total electron yield + :math:`I_{ey}` (drain current). + + + + + + + + + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, iey). + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + + + diff --git a/applications/NXxas_tfy.nxdl.xml b/applications/NXxas_tfy.nxdl.xml new file mode 100644 index 0000000000..732b4ac64e --- /dev/null +++ b/applications/NXxas_tfy.nxdl.xml @@ -0,0 +1,100 @@ + + + + + + In total fluorescence yield (TFY), the absorption coefficient + :math:`\mu(E)` is proportional to the ratio of the total fluorescence + intensity :math:`I_f` and the incident beam intensity :math:`I_0`: + + .. math:: \mu(E) \propto I_f/I_0 + + The total fluorescence signal is measured with a detector such as a + photodiode that collects all emitted fluorescence without energy + discrimination. + + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field contains the processed absorption coefficient. When the raw + detector data and processing steps are available, they can be stored + in the optional ``NXinstrument`` and ``NXprocess`` groups, + enabling full reproducibility of the data reduction. + + + + Official NeXus NXDL schema to which this file conforms. + + + + + + + The absorption coefficient :math:`\mu(E) \propto I_f/I_0`. + + + + + + + + + Detector measuring the incident beam intensity + :math:`I_0`. + + + + + + + + + + Detector measuring the total fluorescence emission + :math:`I_f`. + + + + + + + + + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, if). + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + + + diff --git a/applications/NXxas_new.nxdl.xml b/applications/NXxas_trans.nxdl.xml similarity index 52% rename from applications/NXxas_new.nxdl.xml rename to applications/NXxas_trans.nxdl.xml index 1c2df512ee..3383428935 100644 --- a/applications/NXxas_new.nxdl.xml +++ b/applications/NXxas_trans.nxdl.xml @@ -2,9 +2,9 @@ - - - - The symbol(s) listed here will be used below to coordinate datasets with the same shape. - - - Number of energy data points - - - Number of electronic transitions - - - This is an application definition for X-ray absorption spectroscopy. + In transmission, the linear attenuation coefficient or absorption + coefficient :math:`\mu(E)` is given by the Beer-Lambert law: + + .. math:: \mu(E)t = -\ln(I/I_0) + + where :math:`I` is the intensity of the transmitted beam, :math:`I_0` is + the intensity of the incident beam, and :math:`t` is the thickness of the + sample. + + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field contains the processed absorption coefficient. When the raw + detector data and processing steps are available, they can be stored + in the optional ``NXinstrument`` and ``NXprocess`` groups, + enabling full reproducibility of the data reduction. - Official NeXus NXDL schema to which this file conforms. TODO: replace NXxas + Official NeXus NXDL schema to which this file conforms. - + - - - - - Excited element - - - Absorption edge - - - Specify if the data commes from a calculation - - - TODO - - - - - TODO - - - - - - TODO + + The absorption coefficient :math:`\mu(E)t = -\ln(I/I_0)`. + - - - Descriptive name of the sample - - - - - Description on how :ref:`energy </NXxas_new/ENTRY/energy-field>` - and :ref:`intensity </NXxas_new/ENTRY/intensity-field>` were obtained - from the raw data. - - @@ -103,12 +71,15 @@ - + - spacing between crystal planes of the reflection + The spacing between crystal planes of the reflection - Type or material of monochromating substance (Si, Ge, Multilayer). + + Type or material of monochromating substance + (Si, Ge, Multilayer). + Miller indices (hkl) values of nominal reflection @@ -118,45 +89,57 @@ - + + + Detector measuring the incident beam intensity + :math:`I_0`. + - + + + Detector measuring the transmitted beam intensity + :math:`I`. + - - - XAS intensity versus energy plot - - - - - - Table like data structure common in the XAS domain. + + + Detector measuring the reference intensity + :math:`I_{ref}`, placed after a reference sample + (typically a metal foil). + - - - - - - - - - - + + + Description of how :ref:`intensity + </NXxas/ENTRY/intensity-field>` was obtained from + the raw detector data (i0, itrans). When present, it allows + a third party to fully reproduce the data reduction. + + + Name of the program used for processing. + + + Version of the program used for processing. + + + Date and time of processing. + + diff --git a/base_classes/NXemission_line.nxdl.xml b/base_classes/NXemission_line.nxdl.xml index 12c11aa89f..f2e47d5ffb 100644 --- a/base_classes/NXemission_line.nxdl.xml +++ b/base_classes/NXemission_line.nxdl.xml @@ -3,7 +3,7 @@ - - XAS measurement mode - - - X-ray absorption spectroscopy (XAS) is a technique that measures the absorption coefficient :math:`\mu(E)` of a material as a function of energy. - - The name of the XAS mode indicates the type of process being monitored to obtain the spectrum. Below is a description of the available modes, with emphasis on the expected values for the `intensity` and `monitor` fields. - - 1. Transmission - - The absorption coefficient is obtained by measuring the intensity of the incident :math:`I_0` and transmitted beam :math:`I`. - - .. math:: - \mu(E) = -\ln(I/I_0) - - 2. Total fluorescence yield (TFY) - - The absorption coefficient is obtained by measuring the intensity of the emitted fluorescence :math:`I_f` and the incident beam :math:`I_0`. - - .. math:: - \mu(E) \propto I_f/I_0 - - 3. Partial fluorescence yield (PFY) - - 4. Inverse partial fluorescence yield (IPFY) - - 5. High-energy resolution fluorescence detection (HERFD) - - 6. Total electron yield (TEY) - - 7. Partial electron yield (PEY) - - 8. Electron energy loss (EELS) - - 9. X-ray Raman Scattering (XRS) - - 10. Diffraction Anomalous Fine Structure (DAFS) - - 11. X-ray Excited Optical Luminescence (XEOL) - - 12. Grazing Angle Reflection Extended X-ray Absorption Fine Structure (ReflEXAFS) - - 13. Other - - - - - Transmission - - - - - Total Fluorescence Yield - - - - - Partial Fluorescence Yield - - - - - Inverse Partial Fluorescence Yield - - - - - High Energy Resolution Fluorescence Detected - - - - - Total Electron Yield - - - - - Partial Electron Yield - - - - - Electron Energy Loss - - - - - X-ray Raman Scattering - - - - - Diffraction Anomalous Fine Structure - - - - - X-ray Excited Optical Luminescence - - - - - Grazing Angle Reflection Extended X-ray Absorption Fine Structure - - - - - Other - - - - - - - Collection of emission lines detected or used in this measurement. - - - - - From f5739b6435e19997d389b62ae3efadde8b5e705f Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 17 Mar 2026 13:10:19 +0100 Subject: [PATCH 02/32] Build docs --- .github/workflows/deploy-branch-docs.yaml | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/deploy-branch-docs.yaml diff --git a/.github/workflows/deploy-branch-docs.yaml b/.github/workflows/deploy-branch-docs.yaml new file mode 100644 index 0000000000..5df819efbb --- /dev/null +++ b/.github/workflows/deploy-branch-docs.yaml @@ -0,0 +1,51 @@ +name: Deploy branch documentation + +on: + push: + branches: + - xas-modes-choice + - xas-using-inheritance + workflow_dispatch: + +defaults: + run: + shell: bash + +jobs: + build-and-deploy: + name: Build and deploy docs + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.12" + + - name: Install Requirements + run: | + python3 -m pip install --upgrade pip setuptools + make install + + - name: Build Documentation + run: | + make local + + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + folder: build/manual/build/html + target-folder: ${{ github.ref_name }} + clean: true + clean-exclude: | + xas-modes-choice + xas-using-inheritance From 849c728bf167b9e678430b59dcd5d1925742969a Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 17 Mar 2026 13:49:16 +0100 Subject: [PATCH 03/32] Add .readthedocs.yaml --- .github/workflows/deploy-branch-docs.yaml | 51 ----------------------- .gitignore | 1 + .readthedocs.yaml | 12 ++++++ 3 files changed, 13 insertions(+), 51 deletions(-) delete mode 100644 .github/workflows/deploy-branch-docs.yaml create mode 100644 .readthedocs.yaml diff --git a/.github/workflows/deploy-branch-docs.yaml b/.github/workflows/deploy-branch-docs.yaml deleted file mode 100644 index 5df819efbb..0000000000 --- a/.github/workflows/deploy-branch-docs.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: Deploy branch documentation - -on: - push: - branches: - - xas-modes-choice - - xas-using-inheritance - workflow_dispatch: - -defaults: - run: - shell: bash - -jobs: - build-and-deploy: - name: Build and deploy docs - runs-on: ubuntu-latest - - permissions: - contents: write - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.12" - - - name: Install Requirements - run: | - python3 -m pip install --upgrade pip setuptools - make install - - - name: Build Documentation - run: | - make local - - - name: Deploy to GitHub Pages - uses: JamesIves/github-pages-deploy-action@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - folder: build/manual/build/html - target-folder: ${{ github.ref_name }} - clean: true - clean-exclude: | - xas-modes-choice - xas-using-inheritance diff --git a/.gitignore b/.gitignore index 1e25594542..fbf3fd897e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Hidden files .* !.github +!.readthedocs.yaml # Python byte / compiled / optimized *.py[cod] diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000..fe110f1895 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,12 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.12" + commands: + - pip install -r requirements.txt + - make prepare + - make html + - mkdir -p $READTHEDOCS_OUTPUT/html + - cp -r build/manual/build/html/* $READTHEDOCS_OUTPUT/html/ From d27514ee1b41c8178847cc8676bdaaf92763fd05 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 17 Mar 2026 15:49:28 +0100 Subject: [PATCH 04/32] Remove optional iref from NXxas_trans --- applications/NXxas_trans.nxdl.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/applications/NXxas_trans.nxdl.xml b/applications/NXxas_trans.nxdl.xml index 3383428935..4126d27e74 100644 --- a/applications/NXxas_trans.nxdl.xml +++ b/applications/NXxas_trans.nxdl.xml @@ -111,18 +111,6 @@ - - - Detector measuring the reference intensity - :math:`I_{ref}`, placed after a reference sample - (typically a metal foil). - - - - - - - From 35f2bd4196fbf5f76182cecd403b1704f2cd5d3f Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 17 Mar 2026 22:40:09 +0100 Subject: [PATCH 05/32] Add a NXcollection for generic raw data --- applications/NXxas.nxdl.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/applications/NXxas.nxdl.xml b/applications/NXxas.nxdl.xml index 89058b8209..047c65d0e8 100644 --- a/applications/NXxas.nxdl.xml +++ b/applications/NXxas.nxdl.xml @@ -34,6 +34,9 @@ Number of electronic transitions + + Number of raw data channels + This is a generic application definition for X-ray absorption spectroscopy. Specialized definitions are available for different acquisition modes. @@ -90,5 +93,25 @@ + + + Table like data structure common in the XAS domain. + + + + + + + + + + + + + + + + + From 8e3f58fe85deffd63ca58519bea1919cd6e9bd79 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Sun, 29 Mar 2026 21:29:15 +0200 Subject: [PATCH 06/32] Move NXxas and related subclasses to contributed_definitions --- {base_classes => contributed_definitions}/NXedge.nxdl.xml | 0 {base_classes => contributed_definitions}/NXelement.nxdl.xml | 0 .../NXemission_line.nxdl.xml | 0 {applications => contributed_definitions}/NXxas.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_herfd.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_pey.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_pfy.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_tey.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_tfy.nxdl.xml | 0 {applications => contributed_definitions}/NXxas_trans.nxdl.xml | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename {base_classes => contributed_definitions}/NXedge.nxdl.xml (100%) rename {base_classes => contributed_definitions}/NXelement.nxdl.xml (100%) rename {base_classes => contributed_definitions}/NXemission_line.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_herfd.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_pey.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_pfy.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_tey.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_tfy.nxdl.xml (100%) rename {applications => contributed_definitions}/NXxas_trans.nxdl.xml (100%) diff --git a/base_classes/NXedge.nxdl.xml b/contributed_definitions/NXedge.nxdl.xml similarity index 100% rename from base_classes/NXedge.nxdl.xml rename to contributed_definitions/NXedge.nxdl.xml diff --git a/base_classes/NXelement.nxdl.xml b/contributed_definitions/NXelement.nxdl.xml similarity index 100% rename from base_classes/NXelement.nxdl.xml rename to contributed_definitions/NXelement.nxdl.xml diff --git a/base_classes/NXemission_line.nxdl.xml b/contributed_definitions/NXemission_line.nxdl.xml similarity index 100% rename from base_classes/NXemission_line.nxdl.xml rename to contributed_definitions/NXemission_line.nxdl.xml diff --git a/applications/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml similarity index 100% rename from applications/NXxas.nxdl.xml rename to contributed_definitions/NXxas.nxdl.xml diff --git a/applications/NXxas_herfd.nxdl.xml b/contributed_definitions/NXxas_herfd.nxdl.xml similarity index 100% rename from applications/NXxas_herfd.nxdl.xml rename to contributed_definitions/NXxas_herfd.nxdl.xml diff --git a/applications/NXxas_pey.nxdl.xml b/contributed_definitions/NXxas_pey.nxdl.xml similarity index 100% rename from applications/NXxas_pey.nxdl.xml rename to contributed_definitions/NXxas_pey.nxdl.xml diff --git a/applications/NXxas_pfy.nxdl.xml b/contributed_definitions/NXxas_pfy.nxdl.xml similarity index 100% rename from applications/NXxas_pfy.nxdl.xml rename to contributed_definitions/NXxas_pfy.nxdl.xml diff --git a/applications/NXxas_tey.nxdl.xml b/contributed_definitions/NXxas_tey.nxdl.xml similarity index 100% rename from applications/NXxas_tey.nxdl.xml rename to contributed_definitions/NXxas_tey.nxdl.xml diff --git a/applications/NXxas_tfy.nxdl.xml b/contributed_definitions/NXxas_tfy.nxdl.xml similarity index 100% rename from applications/NXxas_tfy.nxdl.xml rename to contributed_definitions/NXxas_tfy.nxdl.xml diff --git a/applications/NXxas_trans.nxdl.xml b/contributed_definitions/NXxas_trans.nxdl.xml similarity index 100% rename from applications/NXxas_trans.nxdl.xml rename to contributed_definitions/NXxas_trans.nxdl.xml From ef01dd91bebfbd8c3687604f6f1e68a38b73cd9f Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Mon, 30 Mar 2026 16:44:31 +0200 Subject: [PATCH 07/32] Substitute NXelement with the existing NXatom --- contributed_definitions/NXelement.nxdl.xml | 171 --------------------- contributed_definitions/NXxas.nxdl.xml | 3 +- 2 files changed, 2 insertions(+), 172 deletions(-) delete mode 100644 contributed_definitions/NXelement.nxdl.xml diff --git a/contributed_definitions/NXelement.nxdl.xml b/contributed_definitions/NXelement.nxdl.xml deleted file mode 100644 index 19237a8d29..0000000000 --- a/contributed_definitions/NXelement.nxdl.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - Definition of a chemical element. - - - For each symbol, the atomic number, common English name, and standard atomic weight are also given. - - - Z=1, name="hydrogen", standard_atomic_weight=1.0078 - Z=2, name="helium", standard_atomic_weight=4.0026 - Z=3, name="lithium", standard_atomic_weight=6.94 - Z=4, name="beryllium", standard_atomic_weight=9.0122 - Z=5, name="boron", standard_atomic_weight=10.81 - Z=6, name="carbon", standard_atomic_weight=12.011 - Z=7, name="nitrogen", standard_atomic_weight=14.007 - Z=8, name="oxygen", standard_atomic_weight=15.999 - Z=9, name="fluorine", standard_atomic_weight=18.9984 - Z=10, name="neon", standard_atomic_weight=20.1797 - Z=11, name="sodium", standard_atomic_weight=22.9898 - Z=12, name="magnesium", standard_atomic_weight=24.305 - Z=13, name="aluminum", standard_atomic_weight=26.9815 - Z=14, name="silicon", standard_atomic_weight=28.085 - Z=15, name="phosphorus", standard_atomic_weight=30.9738 - Z=16, name="sulfur", standard_atomic_weight=32.06 - Z=17, name="chlorine", standard_atomic_weight=35.453 - Z=18, name="argon", standard_atomic_weight=39.948 - Z=19, name="potassium", standard_atomic_weight=39.0983 - Z=20, name="calcium", standard_atomic_weight=40.078 - Z=21, name="scandium", standard_atomic_weight=44.9559 - Z=22, name="titanium", standard_atomic_weight=47.867 - Z=23, name="vanadium", standard_atomic_weight=50.9415 - Z=24, name="chromium", standard_atomic_weight=51.996 - Z=25, name="manganese", standard_atomic_weight=54.938 - Z=26, name="iron", standard_atomic_weight=55.845 - Z=27, name="cobalt", standard_atomic_weight=58.9332 - Z=28, name="nickel", standard_atomic_weight=58.6934 - Z=29, name="copper", standard_atomic_weight=63.546 - Z=30, name="zinc", standard_atomic_weight=65.38 - Z=31, name="gallium", standard_atomic_weight=69.72 - Z=32, name="germanium", standard_atomic_weight=72.63 - Z=33, name="arsenic", standard_atomic_weight=74.9216 - Z=34, name="selenium", standard_atomic_weight=78.971 - Z=35, name="bromine", standard_atomic_weight=79.904 - Z=36, name="krypton", standard_atomic_weight=83.798 - Z=37, name="rubidium", standard_atomic_weight=85.4678 - Z=38, name="strontium", standard_atomic_weight=87.62 - Z=39, name="yttrium", standard_atomic_weight=88.9058 - Z=40, name="zirconium", standard_atomic_weight=91.224 - Z=41, name="niobium", standard_atomic_weight=92.9064 - Z=42, name="molybdenum", standard_atomic_weight=95.95 - Z=43, name="technetium", standard_atomic_weight=97.907 - Z=44, name="ruthenium", standard_atomic_weight=101.07 - Z=45, name="rhodium", standard_atomic_weight=102.906 - Z=46, name="palladium", standard_atomic_weight=106.42 - Z=47, name="silver", standard_atomic_weight=107.868 - Z=48, name="cadmium", standard_atomic_weight=112.414 - Z=49, name="indium", standard_atomic_weight=114.818 - Z=50, name="tin", standard_atomic_weight=118.71 - Z=51, name="antimony", standard_atomic_weight=121.76 - Z=52, name="tellurium", standard_atomic_weight=127.6 - Z=53, name="iodine", standard_atomic_weight=126.905 - Z=54, name="xenon", standard_atomic_weight=131.293 - Z=55, name="cesium", standard_atomic_weight=132.905 - Z=56, name="barium", standard_atomic_weight=137.327 - Z=57, name="lanthanum", standard_atomic_weight=138.905 - Z=58, name="cerium", standard_atomic_weight=140.116 - Z=59, name="praseodymium", standard_atomic_weight=140.908 - Z=60, name="neodymium", standard_atomic_weight=144.242 - Z=61, name="promethium", standard_atomic_weight=145.0 - Z=62, name="samarium", standard_atomic_weight=150.36 - Z=63, name="europium", standard_atomic_weight=151.96 - Z=64, name="gadolinium", standard_atomic_weight=157.25 - Z=65, name="terbium", standard_atomic_weight=158.925 - Z=66, name="dysprosium", standard_atomic_weight=162.5 - Z=67, name="holmium", standard_atomic_weight=164.93 - Z=68, name="erbium", standard_atomic_weight=167.259 - Z=69, name="thulium", standard_atomic_weight=168.934 - Z=70, name="ytterbium", standard_atomic_weight=173.045 - Z=71, name="lutetium", standard_atomic_weight=174.967 - Z=72, name="hafnium", standard_atomic_weight=178.49 - Z=73, name="tantalum", standard_atomic_weight=180.948 - Z=74, name="tungsten", standard_atomic_weight=183.84 - Z=75, name="rhenium", standard_atomic_weight=186.207 - Z=76, name="osmium", standard_atomic_weight=190.23 - Z=77, name="iridium", standard_atomic_weight=192.217 - Z=78, name="platinum", standard_atomic_weight=195.084 - Z=79, name="gold", standard_atomic_weight=196.967 - Z=80, name="mercury", standard_atomic_weight=200.592 - Z=81, name="thallium", standard_atomic_weight=204.383 - Z=82, name="lead", standard_atomic_weight=207.2 - Z=83, name="bismuth", standard_atomic_weight=208.98 - Z=84, name="polonium", standard_atomic_weight=209.0 - Z=85, name="astatine", standard_atomic_weight=210.0 - Z=86, name="radon", standard_atomic_weight=222.0 - Z=87, name="francium", standard_atomic_weight=223.0 - Z=88, name="radium", standard_atomic_weight=226.0 - Z=89, name="actinium", standard_atomic_weight=227.0 - Z=90, name="thorium", standard_atomic_weight=232.038 - Z=91, name="protactinium", standard_atomic_weight=231.036 - Z=92, name="uranium", standard_atomic_weight=238.029 - Z=93, name="neptunium", standard_atomic_weight=237.048 - Z=94, name="plutonium", standard_atomic_weight=239.052 - Z=95, name="americium", standard_atomic_weight=243.0 - Z=96, name="curium", standard_atomic_weight=247.0 - Z=97, name="berkelium", standard_atomic_weight=247.0 - Z=98, name="californium", standard_atomic_weight=251.0 - Z=99, name="einsteinium", standard_atomic_weight=252 - Z=100, name="fermium", standard_atomic_weight=257 - Z=101, name="mendelevium", standard_atomic_weight=258 - Z=102, name="nobelium", standard_atomic_weight=259 - Z=103, name="lawrencium", standard_atomic_weight=266 - Z=104, name="rutherfordium", standard_atomic_weight=267 - Z=105, name="dubnium", standard_atomic_weight=268 - Z=106, name="seaborgium", standard_atomic_weight=269 - Z=107, name="bohrium", standard_atomic_weight=270 - Z=108, name="hassium", standard_atomic_weight=269 - Z=109, name="meitnerium", standard_atomic_weight=278 - Z=110, name="darmstadtium", standard_atomic_weight=281 - Z=111, name="roentgenium", standard_atomic_weight=282 - Z=112, name="copernicium", standard_atomic_weight=285 - Z=113, name="nihonium", standard_atomic_weight=286 - Z=114, name="flerovium", standard_atomic_weight=289 - Z=115, name="moscovium", standard_atomic_weight=290 - Z=116, name="livermorium", standard_atomic_weight=293 - Z=117, name="tennessine", standard_atomic_weight=294 - Z=118, name="oganesson", standard_atomic_weight=294 - - - - The charge number *Z* of the atomic nucleus. - - - - *Relative atomic mass* of the element in *amu*. It can be but is not restricted to the - *standard atomic weight* (using the natural abundance of isotopes). - - - - The charge of the atom after ionic approximation of its heteronuclear bonds. - - diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 047c65d0e8..0db4efbd18 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -48,8 +48,9 @@ - + Excited element + Absorption edge From e8733adda0e1ef4e41ea2023639b224a334c3906 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Mon, 30 Mar 2026 17:00:25 +0200 Subject: [PATCH 08/32] Rename element to absorber --- contributed_definitions/NXxas.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 0db4efbd18..ce4de40ca3 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -48,8 +48,8 @@ - - Excited element + + Absorbing atom From 50c10ee4dd00d2ffc34e9d6a853941dc72016eb9 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 31 Mar 2026 09:16:28 +0200 Subject: [PATCH 09/32] Re-add reference detector for transmission --- contributed_definitions/NXxas_trans.nxdl.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/contributed_definitions/NXxas_trans.nxdl.xml b/contributed_definitions/NXxas_trans.nxdl.xml index 4126d27e74..3383428935 100644 --- a/contributed_definitions/NXxas_trans.nxdl.xml +++ b/contributed_definitions/NXxas_trans.nxdl.xml @@ -111,6 +111,18 @@ + + + Detector measuring the reference intensity + :math:`I_{ref}`, placed after a reference sample + (typically a metal foil). + + + + + + + From 1105792ecff32a18e42bed738c7939c6b963825e Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 31 Mar 2026 09:17:45 +0200 Subject: [PATCH 10/32] Remove optional NXcollection group from NXxas definition --- contributed_definitions/NXxas.nxdl.xml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index ce4de40ca3..513d172c6e 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -94,25 +94,5 @@ - - - Table like data structure common in the XAS domain. - - - - - - - - - - - - - - - - - From ea40940a99af37c878f0741bd7e86878abadaab4 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 09:38:50 +0200 Subject: [PATCH 11/32] Update Read the Docs configuration to use Ubuntu 24.04 and Python 3.14 --- .readthedocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index fe110f1895..b9ed680f19 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,9 +1,9 @@ version: 2 build: - os: ubuntu-22.04 + os: ubuntu-24.04 tools: - python: "3.12" + python: "3.14" commands: - pip install -r requirements.txt - make prepare From f03e55102b07e22ecf2f08a0dc2a5f5d800dfa4b Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 09:49:21 +0200 Subject: [PATCH 12/32] Restrict sphinx version to smaller than 8.2.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2f45a3c7b4..b636761e0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pyyaml nyaml>=0.2.2 # Documentation building -sphinx>=5 +sphinx>=5,<8.2.0 sphinx-tabs sphinx-toolbox chios From 389d401d2215563ee367ed08b45808272b49d84c Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 09:59:16 +0200 Subject: [PATCH 13/32] Add NXatom group to absorption edge and emission line --- ...Xedge.nxdl.xml => NXabsorption_edge.nxdl.xml} | 16 +++++++++++++--- contributed_definitions/NXemission_line.nxdl.xml | 10 ++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) rename contributed_definitions/{NXedge.nxdl.xml => NXabsorption_edge.nxdl.xml} (91%) diff --git a/contributed_definitions/NXedge.nxdl.xml b/contributed_definitions/NXabsorption_edge.nxdl.xml similarity index 91% rename from contributed_definitions/NXedge.nxdl.xml rename to contributed_definitions/NXabsorption_edge.nxdl.xml index ef8a3e61ae..dfa55ed8ae 100644 --- a/contributed_definitions/NXedge.nxdl.xml +++ b/contributed_definitions/NXabsorption_edge.nxdl.xml @@ -21,20 +21,20 @@ # # For further information, see http://www.nexusformat.org --> - An absorption edge is a sharp discontinuity in the X-ray absorption spectrum of an element that occurs when the incident photon energy equals the binding - energy of a core electron, enabling photoionization of that shell. + energy of a core electron, enabling photoionization of that shell. Name of the absorption edge specified using `IUPAC notation`_ (e.g., ``K``, ``L2``, ``M5``), which identifies the shell and sub-shell from which the electron is ejected. - + Correspondence between IUPAC and electronic level notations: .. list-table:: @@ -137,4 +137,14 @@ Energy of the absorption edge. + + + The atom whose core electron is excited at this absorption edge. + + + + Chemical symbol of the element (e.g. ``Fe``, ``Cu``). + + + diff --git a/contributed_definitions/NXemission_line.nxdl.xml b/contributed_definitions/NXemission_line.nxdl.xml index f2e47d5ffb..cf237295d4 100644 --- a/contributed_definitions/NXemission_line.nxdl.xml +++ b/contributed_definitions/NXemission_line.nxdl.xml @@ -623,4 +623,14 @@ Energy of the emission line. + + + The atom from which this emission line originates. + + + + Chemical symbol of the element (e.g. ``Fe``, ``Cu``). + + + From 16b9f4a6f040aa361ab7c51d4ac82c0a3886be83 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 10:04:39 +0200 Subject: [PATCH 14/32] Replace the `calculated` boolean with `spectrum_type` --- contributed_definitions/NXxas.nxdl.xml | 37 ++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 513d172c6e..9699469b9b 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -26,7 +26,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://definition.nexusformat.org/nxdl/3.1 ../nxdl.xsd "> - The symbol(s) listed here will be used below to coordinate datasets with the same shape. + The symbol(s) listed here will be used below to coordinate datasets + with the same shape. Number of energy data points @@ -39,7 +40,9 @@ - This is a generic application definition for X-ray absorption spectroscopy. Specialized definitions are available for different acquisition modes. + This is a generic application definition for X-ray absorption + spectroscopy. Technique-specific application definitions extend this base + definition. @@ -49,14 +52,32 @@ - Absorbing atom - + + The atom whose core electron is excited by the incident X-rays. + + - - Absorption edge + + + The edge being probed, defined by the principal quantum number + and orbital symmetry of the photoionized electron (e.g. K, L1, + L2, L3). Together with the absorber uniquely identifies probed + electronic transition. + - - Specify if the data commes from a calculation + + + The origin of the data. Use ``experimental`` for data acquired + at a beamline or laboratory instrument, ``theoretical`` for + spectra calculated/simulated using a computational tool, and + ``reconstructed`` for spectra derived from a linear combination + of reference components (e.g. PCA, MCR-ALS). + + + + + + From 9f0b7919a132a3d905ba5b6456f7baf5c8407a4b Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 10:11:10 +0200 Subject: [PATCH 15/32] Update NXxas_trans definition to include 'iref' in intensity field description --- contributed_definitions/NXxas_trans.nxdl.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contributed_definitions/NXxas_trans.nxdl.xml b/contributed_definitions/NXxas_trans.nxdl.xml index 3383428935..3908195251 100644 --- a/contributed_definitions/NXxas_trans.nxdl.xml +++ b/contributed_definitions/NXxas_trans.nxdl.xml @@ -127,9 +127,9 @@ Description of how :ref:`intensity - </NXxas/ENTRY/intensity-field>` was obtained from - the raw detector data (i0, itrans). When present, it allows - a third party to fully reproduce the data reduction. + </NXxas/ENTRY/intensity-field>` was obtained from the raw + detector data (i0, itrans, and iref). When present, it allows a + third party to fully reproduce the data reduction. Name of the program used for processing. From 1cd13117625da6e802c7beaf9a998ce95fe892a3 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 10:53:30 +0200 Subject: [PATCH 16/32] Add NXemission_lines --- .../NXemission_lines.nxdl.xml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 contributed_definitions/NXemission_lines.nxdl.xml diff --git a/contributed_definitions/NXemission_lines.nxdl.xml b/contributed_definitions/NXemission_lines.nxdl.xml new file mode 100644 index 0000000000..e47554bc07 --- /dev/null +++ b/contributed_definitions/NXemission_lines.nxdl.xml @@ -0,0 +1,37 @@ + + + + + + A container for grouping multiple emission lines. + + Each child :ref:`NXemission_line` group describes a single emission line. + + + + An emission line described by this collection. + + + From 2e1dbdcea52a8a73b02b0cd7f6010ce54ed0632c Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 11:16:35 +0200 Subject: [PATCH 17/32] Remove unused symbols `nTransitions` and `nChan` from NXxas definition --- contributed_definitions/NXxas.nxdl.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 9699469b9b..239717f971 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -32,12 +32,6 @@ Number of energy data points - - Number of electronic transitions - - - Number of raw data channels - This is a generic application definition for X-ray absorption From e4fb42cce71e53ee5feaf5205eb5560fd06336b8 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 15:28:37 +0200 Subject: [PATCH 18/32] Add grating-type spectrometer to NXxas_pfy --- contributed_definitions/NXxas_pfy.nxdl.xml | 128 +++++++++++++++++---- 1 file changed, 103 insertions(+), 25 deletions(-) diff --git a/contributed_definitions/NXxas_pfy.nxdl.xml b/contributed_definitions/NXxas_pfy.nxdl.xml index b3597b8380..a8f6232c4a 100644 --- a/contributed_definitions/NXxas_pfy.nxdl.xml +++ b/contributed_definitions/NXxas_pfy.nxdl.xml @@ -24,27 +24,57 @@ + + + The symbol(s) listed here will be used below to coordinate datasets + with the same shape. + + + Number of energy data points + + + Number of detector channels + + + + Number of pixel rows in the region of interest (ROI) + on the grating-based spectrometer + + + + + Number of pixel columns in the region of interest (ROI) + on the grating-based spectrometer + + + - In partial fluorescence yield (PFY), an energy-dispersive detector - (such as a silicon-drift diode or high-purity Ge detector) is used to - select a portion of the fluorescence signal. Typically, only energies - around a selected fluorescence line of the absorbing element are - selected (e.g. :math:`K\alpha`), rejecting all other energies via a - region of interest (ROI) of the multichannel analyzer (MCA) spectrum. + In partial fluorescence yield (PFY), only a selected portion of the + fluorescence emission is detected, typically around a specific + fluorescence line of the absorbing element (e.g. :math:`K\alpha`). + Experimentally, this energy selectivity can be achieved in several ways: + + * **Energy-dispersive detector** (e.g. silicon-drift diode, + high-purity Ge detector, superconducting tunnel junction, etc.): + the detector bins photons by emission energy into channels; the + fluorescence line is isolated by selecting a channel range. + * **Grating spectrometer**: a diffraction grating disperses the + emitted photons by energy onto a 2D detector, providing + higher energy resolution. The absorption coefficient is proportional to: .. math:: \mu(E) \propto I_f/I_0 - where :math:`I_f` is the fluorescence intensity summed over the ROI - channels (corrected for dead-time), and :math:`I_0` is the incident - beam intensity. PFY may be affected by self-absorption effects. + where :math:`I_f` is the selected fluorescence intensity and + :math:`I_0` is the incident beam intensity. PFY may be affected by + detector dead-time and self-absorption effects. The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` field contains the processed absorption coefficient. When the raw detector data and processing steps are available, they can be stored - in the optional ``NXinstrument`` and ``NXprocess`` groups, - enabling full reproducibility of the data reduction. + in the optional ``NXinstrument``, ``NXcollection``, and ``NXprocess`` + groups, enabling full reproducibility of the data reduction. @@ -56,24 +86,25 @@ The absorption coefficient :math:`\mu(E) \propto I_f/I_0`, - where :math:`I_f` is the dead-time corrected fluorescence - intensity integrated over the selected ROI. + where :math:`I_f` is the selected fluorescence intensity + (dead-time corrected when using an energy-dispersive detector, + or spectrometer-integrated when using a grating spectrometer). - + - The emission line(s) selected in the ROI for the partial - fluorescence yield measurement. + The emission line(s) selected for the partial fluorescence + yield measurement, whether via a channel range or a + grating spectrometer. - Detector measuring the incident beam intensity - :math:`I_0`. + Detector measuring the incident beam intensity :math:`I_0`. @@ -81,11 +112,22 @@ + + + Diffraction grating used to select the emission energy + in a grating spectrometer. Present only when a grating + spectrometer is used instead of an energy-dispersive + detector. + + - Energy-dispersive fluorescence detector. The ``data`` - field holds the fluorescence intensity integrated - over the ROI, corrected for dead-time. + Fluorescence detector measuring :math:`I_f`. When using an + energy-dispersive detector, ``data`` holds the intensity + integrated over the selected detector channels. When using a + grating spectrometer, ``data`` holds the ROI integrated on the + spectrometer detector. In both cases the data may be corrected + for dead-time and self-absorption. @@ -93,9 +135,12 @@ - Dead-time correction constant. + Detector dead time per energy point. + + + - + Detector live time per energy point. @@ -105,12 +150,45 @@ + + + Raw data as written by the acquisition software, + preserved without modification to allow independent + reprocessing. Either ``detector_channels`` or ``detector_roi`` + will be present depending on the detector type used; + not both simultaneously. + + + + Raw channel counts per incident energy point for an + energy-dispersive detector. Axis 0 is the energy scan + axis; axis 1 enumerates the detector channels. Each + value is the count in that channel for one energy point. + + + + + + + + + Raw detector image within the ROI per incident energy point. + Axis 0 is the energy scan axis; axes 1 and 2 span the 2D + pixel grid of the downstream detector (nY rows, nX columns). + + + + + + + + Description of how :ref:`intensity </NXxas/ENTRY/intensity-field>` was obtained from - the raw detector data (i0, if), including dead-time - correction and any self-absorption correction applied. + the raw detector data (i0, if), including any applied correction, + e.g., dead-time or self-absorption. Name of the program used for processing. From cdb5c40120e76e946a766852af49b0556633f7a1 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 16:48:37 +0200 Subject: [PATCH 19/32] Clarify description of absorption edge in NXxas definition --- contributed_definitions/NXxas.nxdl.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 239717f971..3a4c942d77 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -53,10 +53,10 @@ - The edge being probed, defined by the principal quantum number - and orbital symmetry of the photoionized electron (e.g. K, L1, - L2, L3). Together with the absorber uniquely identifies probed - electronic transition. + The absorption edge being probed, defined by the principal + quantum number and orbital symmetry of the photoionized electron + (e.g. K, L1, L2, L3). Together with the absorber uniquely + identifies probed electronic transition. From b6fd81f9868a9dc82099b1c75d93e2c0a2ae7932 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Thu, 2 Apr 2026 21:58:07 +0200 Subject: [PATCH 20/32] Make 'energy' field optional and rename 'group' to 'atom' in NXabsorption_edge and NXemission_line --- contributed_definitions/NXabsorption_edge.nxdl.xml | 4 ++-- contributed_definitions/NXemission_line.nxdl.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contributed_definitions/NXabsorption_edge.nxdl.xml b/contributed_definitions/NXabsorption_edge.nxdl.xml index dfa55ed8ae..22b7f343ea 100644 --- a/contributed_definitions/NXabsorption_edge.nxdl.xml +++ b/contributed_definitions/NXabsorption_edge.nxdl.xml @@ -132,12 +132,12 @@ - + Energy of the absorption edge. - + The atom whose core electron is excited at this absorption edge. diff --git a/contributed_definitions/NXemission_line.nxdl.xml b/contributed_definitions/NXemission_line.nxdl.xml index cf237295d4..eae46ab01f 100644 --- a/contributed_definitions/NXemission_line.nxdl.xml +++ b/contributed_definitions/NXemission_line.nxdl.xml @@ -618,12 +618,12 @@ - + Energy of the emission line. - + The atom from which this emission line originates. From 454ecce45aa0653b866596982d4c27fb483cb72e Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Fri, 3 Apr 2026 09:57:37 +0200 Subject: [PATCH 21/32] Refactor 'spectrum_type' field to 'experimental' boolean --- contributed_definitions/NXxas.nxdl.xml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 3a4c942d77..d5916ce068 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -59,19 +59,14 @@ identifies probed electronic transition. - + - The origin of the data. Use ``experimental`` for data acquired - at a beamline or laboratory instrument, ``theoretical`` for - spectra calculated/simulated using a computational tool, and - ``reconstructed`` for spectra derived from a linear combination - of reference components (e.g. PCA, MCR-ALS). + Specify if the data comes from an experiment. Use ``true`` for + data acquired at a beamline or laboratory instrument, and + ``false`` for spectra calculated/simulated using a + computational tool, reconstructed from a linear combination + of reference components, etc. - - - - - From 82d682d61312546e13ec1a9b81b887ce76837c86 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 09:07:53 +0200 Subject: [PATCH 22/32] Allow for the two absorption edge notation --- contributed_definitions/NXxas.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index d5916ce068..68c739a287 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -55,8 +55,8 @@ The absorption edge being probed, defined by the principal quantum number and orbital symmetry of the photoionized electron - (e.g. K, L1, L2, L3). Together with the absorber uniquely - identifies probed electronic transition. + (e.g. K, L1, L2, L3, L2,3). Together with the absorber uniquely + identifies probed electronic transition. From 4e49c775b8cfebe91b77673095676c3869fe3341 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 09:08:21 +0200 Subject: [PATCH 23/32] Update NXabsorption_edge documentation --- .../NXabsorption_edge.nxdl.xml | 87 +++++++++++-------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/contributed_definitions/NXabsorption_edge.nxdl.xml b/contributed_definitions/NXabsorption_edge.nxdl.xml index 22b7f343ea..389483d147 100644 --- a/contributed_definitions/NXabsorption_edge.nxdl.xml +++ b/contributed_definitions/NXabsorption_edge.nxdl.xml @@ -26,78 +26,84 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://definition.nexusformat.org/nxdl/3.1 ../nxdl.xsd"> An absorption edge is a sharp discontinuity in the X-ray absorption spectrum - of an element that occurs when the incident photon energy equals the binding - energy of a core electron, enabling photoionization of that shell. + of an atom that occurs when the incident photon energy reaches the threshold + energy for exciting the atom from its neutral ground state to a core-vacancy + state. - Name of the absorption edge specified using - `IUPAC notation`_ (e.g., ``K``, ``L2``, ``M5``), which identifies the - shell and sub-shell from which the electron is ejected. + Name of the absorption edge using `IUPAC notation`_ (e.g., ``K``, + ``L2``, ``M5``), which identifies the core-vacancy state of the + atom. - Correspondence between IUPAC and electronic level notations: + Correspondence between IUPAC notation and electron configuration, + expressed as vacancy notation (superscript :math:`-1`): .. list-table:: :header-rows: 1 * - IUPAC - - Electronic level + - Electron configuration * - K - - 1s + - :math:`1s^{-1}` * - L1 - - 2s + - :math:`2s^{-1}` * - L2 - - :math:`2p_{1/2}` + - :math:`2p_{1/2}^{-1}` * - L3 - - :math:`2p_{3/2}` + - :math:`2p_{3/2}^{-1}` * - M1 - - 3s + - :math:`3s^{-1}` * - M2 - - :math:`3p_{1/2}` + - :math:`3p_{1/2}^{-1}` * - M3 - - :math:`3p_{3/2}` + - :math:`3p_{3/2}^{-1}` * - M4 - - :math:`3d_{3/2}` + - :math:`3d_{3/2}^{-1}` * - M5 - - :math:`3d_{5/2}` + - :math:`3d_{5/2}^{-1}` * - N1 - - 4s + - :math:`4s^{-1}` * - N2 - - :math:`4p_{1/2}` + - :math:`4p_{1/2}^{-1}` * - N3 - - :math:`4p_{3/2}` + - :math:`4p_{3/2}^{-1}` * - N4 - - :math:`4d_{3/2}` + - :math:`4d_{3/2}^{-1}` * - N5 - - :math:`4d_{5/2}` + - :math:`4d_{5/2}^{-1}` * - N6 - - :math:`4f_{5/2}` + - :math:`4f_{5/2}^{-1}` * - N7 - - :math:`4f_{7/2}` + - :math:`4f_{7/2}^{-1}` * - O1 - - 5s + - :math:`5s^{-1}` * - O2 - - :math:`5p_{1/2}` + - :math:`5p_{1/2}^{-1}` * - O3 - - :math:`5p_{3/2}` + - :math:`5p_{3/2}^{-1}` * - O4 - - :math:`5d_{3/2}` + - :math:`5d_{3/2}^{-1}` * - O5 - - :math:`5d_{5/2}` + - :math:`5d_{5/2}^{-1}` * - O6 - - :math:`5f_{5/2}` + - :math:`5f_{5/2}^{-1}` * - O7 - - :math:`5f_{7/2}` + - :math:`5f_{7/2}^{-1}` * - P1 - - 6s + - :math:`6s^{-1}` * - P2 - - :math:`6p_{1/2}` + - :math:`6p_{1/2}^{-1}` * - P3 - - :math:`6p_{3/2}` + - :math:`6p_{3/2}^{-1}` * - P4 - - :math:`6d_{3/2}` + - :math:`6d_{3/2}^{-1}` * - P5 - - :math:`6d_{5/2}` + - :math:`6d_{5/2}^{-1}` + + Per IUPAC, subscripts may be dropped when unknown or irrelevant. + When two spin-orbit split levels are not distinguished, they may be + written together (e.g. ``L2,3``). .. _IUPAC notation: https://doi.org/10.1002/xrs.1300200308 @@ -106,30 +112,41 @@ + + + + + + + + + + + From 0ce950658566e07f538779f312a73baf2f6a1620 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 09:19:57 +0200 Subject: [PATCH 24/32] Add emission_energy_window to NXxas_pfy and improve doc --- contributed_definitions/NXxas_pfy.nxdl.xml | 71 ++++++++++++++-------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/contributed_definitions/NXxas_pfy.nxdl.xml b/contributed_definitions/NXxas_pfy.nxdl.xml index a8f6232c4a..3d10d96808 100644 --- a/contributed_definitions/NXxas_pfy.nxdl.xml +++ b/contributed_definitions/NXxas_pfy.nxdl.xml @@ -33,7 +33,10 @@ Number of energy data points - Number of detector channels + + Number of selected detector channels within the + emission energy window + @@ -62,19 +65,17 @@ emitted photons by energy onto a 2D detector, providing higher energy resolution. - The absorption coefficient is proportional to: + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field stores the ratio :math:`I_f/I_0`, where :math:`I_f` is the + selected fluorescence intensity and :math:`I_0` is the incident beam + intensity. This ratio is proportional to the absorption coefficient: .. math:: \mu(E) \propto I_f/I_0 - where :math:`I_f` is the selected fluorescence intensity and - :math:`I_0` is the incident beam intensity. PFY may be affected by - detector dead-time and self-absorption effects. - - The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` - field contains the processed absorption coefficient. When the raw - detector data and processing steps are available, they can be stored - in the optional ``NXinstrument``, ``NXcollection``, and ``NXprocess`` - groups, enabling full reproducibility of the data reduction. + PFY may be affected by detector dead-time and self-absorption effects. + When the raw detector data and processing steps are available, they can be + stored in the optional ``NXinstrument``, ``NXcollection``, and + ``NXprocess`` groups, enabling full reproducibility of the data reduction. @@ -85,22 +86,33 @@ - The absorption coefficient :math:`\mu(E) \propto I_f/I_0`, - where :math:`I_f` is the selected fluorescence intensity - (dead-time corrected when using an energy-dispersive detector, - or spectrometer-integrated when using a grating spectrometer). + The ratio :math:`I_f/I_0`, where :math:`I_f` is the selected + fluorescence intensity and :math:`I_0` is the incident beam + intensity. - + The emission line(s) selected for the partial fluorescence yield measurement, whether via a channel range or a - grating spectrometer. + grating-based spectrometer. + + + The lower and upper bounds :math:`[e_{min}, e_{max}]` of the + detected emission energy window. This is the energy range + over which fluorescence photons are accepted, whether + defined by a detector channel range or a spectrometer + region of interest. + + + + + @@ -115,19 +127,24 @@ Diffraction grating used to select the emission energy - in a grating spectrometer. Present only when a grating + in a grating-based spectrometer. Present only when a grating spectrometer is used instead of an energy-dispersive detector. + + The grating lies on the line connecting the sample and + the fluorescence detector (``if``): the azimuthal and + polar angles must therefore match those of + ``if/transformations``, and only the distance differs. - + Fluorescence detector measuring :math:`I_f`. When using an energy-dispersive detector, ``data`` holds the intensity integrated over the selected detector channels. When using a - grating spectrometer, ``data`` holds the ROI integrated on the - spectrometer detector. In both cases the data may be corrected - for dead-time and self-absorption. + grating-based spectrometer, ``data`` holds the ROI integrated + on the spectrometer detector. In both cases the data may be + corrected for dead-time and self-absorption. @@ -160,10 +177,12 @@ - Raw channel counts per incident energy point for an - energy-dispersive detector. Axis 0 is the energy scan - axis; axis 1 enumerates the detector channels. Each - value is the count in that channel for one energy point. + Raw channel counts per incident energy point for the + selected channels of an energy-dispersive detector. + Only the channels within the emission energy window + are stored. Axis 0 is the energy scan axis; axis 1 + enumerates the selected channels. Each value is the + count in that channel for one energy point. From 648652f053fdefdb35ca2a7b1f816a138a88253b Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 09:22:51 +0200 Subject: [PATCH 25/32] Rename the field to `is_experimental` --- contributed_definitions/NXxas.nxdl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributed_definitions/NXxas.nxdl.xml b/contributed_definitions/NXxas.nxdl.xml index 68c739a287..2e607da818 100644 --- a/contributed_definitions/NXxas.nxdl.xml +++ b/contributed_definitions/NXxas.nxdl.xml @@ -59,7 +59,7 @@ identifies probed electronic transition. - + Specify if the data comes from an experiment. Use ``true`` for data acquired at a beamline or laboratory instrument, and From 706184ff1e0519b72f333b9599592ecbd05c1d86 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 09:29:13 +0200 Subject: [PATCH 26/32] Add beamline coordinate system and transformations to NXxas_pfy --- contributed_definitions/NXxas_pfy.nxdl.xml | 362 ++++++++++++++++++++- 1 file changed, 361 insertions(+), 1 deletion(-) diff --git a/contributed_definitions/NXxas_pfy.nxdl.xml b/contributed_definitions/NXxas_pfy.nxdl.xml index 3d10d96808..c713545f24 100644 --- a/contributed_definitions/NXxas_pfy.nxdl.xml +++ b/contributed_definitions/NXxas_pfy.nxdl.xml @@ -113,8 +113,175 @@ + + + Beamline coordinate system with the sample at the origin: + x along the beam, y horizontal, z opposite to gravity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Should point to + ``transformations/beam``. + + + + + Two rotations relating the beamline frame to + the NeXus laboratory frame, plus direction + vectors labeling beam and gravity. + + + + Direction of the incident beam in the beamline + coordinate system. + + + + + + + + + + + + + + + Direction of gravity in the beamline coordinate + system. + + + + + + + + + + + + + + + Active rotation moving gravity from the + beamline direction (-z) to the NeXus direction (-y). + + + + + + + + + + + + + + + + + + + + Active rotation moving the beam from the + beamline direction (+x) to the NeXus direction (+z). + + + + + + + + + + + + + + Should point to ``.`` (the NeXus laboratory + frame). + + + + + + + + + The sample is at the origin of the beamline + coordinate system. Should point to + ``/entry/beamline_coordinate_system``. + + + - + + The incident X-ray beam. + + + Should point to + ``beam/transformations/beam_direction``. + + + + + + Beam direction in the beamline coordinate + system. The beam travels along +x. + + + + + + + + + Should point to + ``/entry/beamline_coordinate_system`` + or to ``/entry/sample``. + + + + + + Detector measuring the incident beam intensity :math:`I_0`. @@ -123,6 +290,36 @@ + + + Should point to + ``i0/transformations/i0_distance``. + + + + + + Distance from the sample to the I0 detector, + measured upstream along the beam (negative x + direction in the beamline frame). + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + @@ -136,6 +333,86 @@ polar angles must therefore match those of ``if/transformations``, and only the distance differs. + + + Should point to the last transformation in the + chain, i.e. + ``transformations/grating_distance``. + + + + + Transformation chain placing the grating relative + to the sample. The azimuthal and polar angles must + be equal to those of the fluorescence detector + (``if``) to ensure colinearity. + + + + Distance from the sample to the grating along + the sample-to-detector direction. + + + + + + + + + + + + + + + + + + + + Polar (elevation) angle of the grating above + the horizontal beam plane. Must equal + ``if/transformations/if_polar_angle``. + + + + + + + + + + + + + + + + + + + + Azimuthal (horizontal) angle of the grating + from the incident beam direction. Must equal + ``if/transformations/if_azimuthal_angle``. + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + @@ -165,6 +442,89 @@ + + + Should point to the last transformation in the + chain, i.e. + ``transformations/if_distance``. + + + + + Transformation chain placing the fluorescence + detector relative to the sample: azimuthal angle, + polar angle, then distance. These angles are + required to compute self-absorption corrections. + + + + Distance from the sample to the fluorescence + detector (or spectrometer entrance). + + + + + + + + + + + + + + + + + + + + Polar (elevation) angle of the detector above + the horizontal beam plane. A value of 0 means + the detector is in the horizontal plane; 90 + degrees means it is directly above the sample. + + + + + + + + + + + + + + + + + + + + Azimuthal (horizontal) angle of the detector + from the incident beam direction. Rotation + around the vertical z-axis. Typically around + 90 degrees to minimize elastic scattering + background. + + + + + + + + + + + + + + Should point to ``/entry/sample``. + + + + From 79147a663775f7a9cde0d3283dabe6fdb0636ad8 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 10:34:29 +0200 Subject: [PATCH 27/32] Clarify the I_f and I_0 definitions --- contributed_definitions/NXxas_herfd.nxdl.xml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/contributed_definitions/NXxas_herfd.nxdl.xml b/contributed_definitions/NXxas_herfd.nxdl.xml index ac21c9a2bd..75dc4782bf 100644 --- a/contributed_definitions/NXxas_herfd.nxdl.xml +++ b/contributed_definitions/NXxas_herfd.nxdl.xml @@ -34,6 +34,12 @@ The spectral shape depends on the emission energy, making the emission line and emission energy mandatory metadata. + The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` + field stores the ratio :math:`I_f/I_0`, where :math:`I_f` is the + fluorescence intensity diffracted by the crystal analyzer(s) and + :math:`I_0` is the incident beam intensity. This ratio is + proportional to the absorption coefficient: + .. math:: \mu(E) \propto I_f/I_0 The spectrometer uses Rowland circle geometry (Johann or Johansson @@ -49,15 +55,15 @@ - The absorption coefficient :math:`\mu(E) \propto I_f/I_0`, - measured at a specific emission energy with high energy - resolution. + The ratio :math:`I_f/I_0`, where :math:`I_f` is the + fluorescence intensity diffracted by the crystal analyzer(s) + and :math:`I_0` is the incident beam intensity. - + The emission line at which the HERFD spectrum is measured. @@ -249,7 +255,7 @@ - + Detector measuring the incident beam intensity :math:`I_0`, positioned upstream of the sample along @@ -439,7 +445,7 @@ - + Detector measuring the fluorescence intensity :math:`I_f` diffracted by the crystal analyzer(s). From 85a9b77ddf9c99306abd9598ee38ef1f258bd756 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Tue, 7 Apr 2026 10:34:58 +0200 Subject: [PATCH 28/32] Make the coordinate sytem optional --- contributed_definitions/NXxas_herfd.nxdl.xml | 55 +++++++++----------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/contributed_definitions/NXxas_herfd.nxdl.xml b/contributed_definitions/NXxas_herfd.nxdl.xml index 75dc4782bf..498da8e60b 100644 --- a/contributed_definitions/NXxas_herfd.nxdl.xml +++ b/contributed_definitions/NXxas_herfd.nxdl.xml @@ -73,7 +73,7 @@ The emission energy at which the spectrometer is set. - + Beamline coordinate system with the sample at the origin: x along the beam, y horizontal, z opposite to gravity. @@ -98,17 +98,17 @@ - + - + - + @@ -119,10 +119,10 @@ ``transformations/beam``. - + Two rotations relating the beamline frame to - the NeXus/McStas laboratory frame, plus direction + the NeXus laboratory frame, plus direction vectors labeling beam and gravity. @@ -160,7 +160,7 @@ Active rotation moving gravity from the - beamline direction (-z) to the McStas direction (-y). + beamline direction (-z) to the NeXus direction (-y). @@ -181,7 +181,7 @@ Active rotation moving the beam from the - beamline direction (+x) to the McStas direction (+z). + beamline direction (+x) to the NeXus direction (+z). @@ -195,7 +195,7 @@ - Should point to ``.`` (the McStas laboratory + Should point to ``.`` (the NeXus laboratory frame). @@ -203,7 +203,7 @@ - + The sample is at the origin of the beamline coordinate system. Should point to @@ -212,20 +212,15 @@ - + The incident X-ray beam. - - - Energy of the incident beam at the sample position. - - - + Should point to ``beam/transformations/beam_direction``. - + Beam direction in the beamline coordinate @@ -266,13 +261,13 @@ - + Should point to ``i0/transformations/i0_distance``. - + Distance from the sample to the I0 detector, @@ -364,14 +359,14 @@ Diameter of the crystal analyzer wafer. - + Should point to the last transformation in the chain, i.e. ``transformations/analyzer_distance``. - + Transformation chain placing the analyzer relative to the sample: azimuthal angle, polar angle, @@ -455,20 +450,20 @@ - + Should point to the last transformation in the chain, i.e. - ``transformations/detector_distance``. + ``transformations/if_distance``. - + Transformation chain placing the detector relative to the sample: azimuthal angle, polar angle, then distance. - + Distance from the sample to the detector. @@ -484,11 +479,11 @@ - + - + Polar angle of the detector in the vertical Rowland plane. @@ -505,11 +500,11 @@ - + - + Azimuthal (horizontal) angle of the detector from the incident beam direction. Should From 375fa487202a7202aaddd5eae4b65856d276f9de Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Mon, 4 May 2026 09:37:52 +0200 Subject: [PATCH 29/32] Update intensity field description --- contributed_definitions/NXxas_pey.nxdl.xml | 2 +- contributed_definitions/NXxas_tey.nxdl.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contributed_definitions/NXxas_pey.nxdl.xml b/contributed_definitions/NXxas_pey.nxdl.xml index 54db31dfdc..f9338e572d 100644 --- a/contributed_definitions/NXxas_pey.nxdl.xml +++ b/contributed_definitions/NXxas_pey.nxdl.xml @@ -37,7 +37,7 @@ sensitivity and selectivity compared to total electron yield. The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` - field contains the processed absorption coefficient. When the raw + field stores the ratio :math:`I_{ey}/I_0`. When the raw detector data and processing steps are available, they can be stored in the optional ``NXinstrument`` and ``NXprocess`` groups, enabling full reproducibility of the data reduction. diff --git a/contributed_definitions/NXxas_tey.nxdl.xml b/contributed_definitions/NXxas_tey.nxdl.xml index d23a31ab5c..3fea61a58e 100644 --- a/contributed_definitions/NXxas_tey.nxdl.xml +++ b/contributed_definitions/NXxas_tey.nxdl.xml @@ -37,7 +37,7 @@ nanometers. The top-level :ref:`intensity </NXxas/ENTRY/intensity-field>` - field contains the processed absorption coefficient. When the raw + field stores the ratio :math:`I_{ey}/I_0`. When the raw detector data and processing steps are available, they can be stored in the optional ``NXinstrument`` and ``NXprocess`` groups, enabling full reproducibility of the data reduction. From 591c0ba0c7818c119e10260bd4b112bee91ba6d7 Mon Sep 17 00:00:00 2001 From: Peter Chang Date: Wed, 1 Apr 2026 16:37:32 +0100 Subject: [PATCH 30/32] Fix CI caused by sphinx_toolbox (#1628) Restrict sphinx version to be less than 9 as noted in https://github.com/sphinx-toolbox/sphinx-toolbox/issues/201 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b636761e0b..5ba23fa230 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pyyaml nyaml>=0.2.2 # Documentation building -sphinx>=5,<8.2.0 +sphinx<9 sphinx-tabs sphinx-toolbox chios From 03852f02511987e3b6f86baf8e3166adf79d1aef Mon Sep 17 00:00:00 2001 From: Kyle Qianli Ma <41385391+KyleQianliMa@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:48:17 -0400 Subject: [PATCH 31/32] updated event_index and event_id description (#1404) * updated event_index and event_id description Co-authored-by: Kyle Ma --- base_classes/NXevent_data.nxdl.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/base_classes/NXevent_data.nxdl.xml b/base_classes/NXevent_data.nxdl.xml index 081fae2ea3..196945b3b3 100644 --- a/base_classes/NXevent_data.nxdl.xml +++ b/base_classes/NXevent_data.nxdl.xml @@ -60,7 +60,9 @@ There will be extra information in the NXdetector to convert - event_id to detector_number. + event_id to detector_number. But in short, + event_id contains information about detector_id which is + related to the specific pixels on the detector bank. @@ -77,6 +79,10 @@ The index into the event_time_offset, event_id pair for the pulse occurring at the matching entry in event_time_zero. + Each pulse creates an entry in the event_index, + the value of event_index points to the latest index of the event in event_id. + Sometimes, two adjcent event_index[i] and event_index[i+1] will have the same value, + this means there is no additonal neutron hit the detector bank in (i+1)th pulse. From 59e6c399e082f6222bbc3c2a1130733a9a2a4e02 Mon Sep 17 00:00:00 2001 From: Marius Retegan Date: Wed, 29 Apr 2026 18:01:24 +0200 Subject: [PATCH 32/32] Add choice element rendering in documentation (#1613) This PR adds support for rendering elements in the HTML documentation and ensures that all elements (fields, groups, choices, links) are rendered in their original XML document order. Closes #1439 --- dev_tools/docs/nxdl.py | 203 ++++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 75 deletions(-) diff --git a/dev_tools/docs/nxdl.py b/dev_tools/docs/nxdl.py index 5b3dc64622..bd8e98ccf2 100644 --- a/dev_tools/docs/nxdl.py +++ b/dev_tools/docs/nxdl.py @@ -364,7 +364,7 @@ def _get_required_or_optional_text(self, node): :returns: formatted text """ tag = node.tag.split("}")[-1] - if tag in ("field", "group"): + if tag in ("field", "group", "choice"): optional_default = not self._use_application_defaults optional = node.get("optional", optional_default) in (True, "true", "1", 1) recommended = node.get("recommended", None) in (True, "true", "1", 1) @@ -624,91 +624,144 @@ def _print_full_tree(self, ns, parent, name, indent, parent_path): :param indent: to keep track of indentation level :param parent_path: NX class path of parent nodes """ - for node in parent.xpath("nx:field", namespaces=ns): - name = node.get("name") - formatted_name = get_rst_formatted_name(node) - index_name = name - dims = self._analyze_dimensions(ns, node) - - optional_text = self._get_required_or_optional_text(node) - self._print(f"{indent}{self._hyperlink_target(parent_path, name, 'field')}") - self._print(f"{indent}.. index:: {index_name} (field)\n") - self._print( - f"{indent}{formatted_name}: " - f"{optional_text}" - f"{self._format_type(node)}" - f"{dims}" - f"{self._format_units(node)}" - f" {self.get_first_parent_ref(f'{parent_path}/{name}', 'field')}" - "\n" - ) + # Process children in document order to preserve XML ordering. + for node in parent.xpath("nx:field|nx:group|nx:choice|nx:link", namespaces=ns): + tag = node.tag.split("}")[-1] + + if tag == "field": + name = node.get("name") + formatted_name = get_rst_formatted_name(node) + index_name = name + dims = self._analyze_dimensions(ns, node) + + optional_text = self._get_required_or_optional_text(node) + self._print( + f"{indent}{self._hyperlink_target(parent_path, name, 'field')}" + ) + self._print(f"{indent}.. index:: {index_name} (field)\n") + self._print( + f"{indent}{formatted_name}: " + f"{optional_text}" + f"{self._format_type(node)}" + f"{dims}" + f"{self._format_units(node)}" + f" {self.get_first_parent_ref(f'{parent_path}/{name}', 'field')}" + "\n" + ) - self._print_if_deprecated(ns, node, indent + self._INDENTATION_UNIT) - self._print_doc_enum(indent, ns, node) + self._print_if_deprecated(ns, node, indent + self._INDENTATION_UNIT) + self._print_doc_enum(indent, ns, node) + + for subnode in node.xpath("nx:attribute", namespaces=ns): + optional = self._get_required_or_optional_text(subnode) + self._print_attribute( + ns, + "field", + subnode, + optional, + indent + self._INDENTATION_UNIT, + parent_path + "/" + name, + ) - for subnode in node.xpath("nx:attribute", namespaces=ns): - optional = self._get_required_or_optional_text(subnode) - self._print_attribute( - ns, - "field", - subnode, - optional, - indent + self._INDENTATION_UNIT, - parent_path + "/" + name, + elif tag == "group": + name = node.get("name", "") + formatted_name = get_rst_formatted_name(node) + typ = node.get("type", "untyped (this is an error; please report)") + + optional_text = self._get_required_or_optional_text(node) + if typ.startswith("NX"): + if name == "": + name = typ.lstrip("NX").upper() + typ = f":ref:`{typ}`" + hTarget = self._hyperlink_target(parent_path, name, "group") + # target = hTarget.replace(".. _", "").replace(":\n", "") + # TODO: https://github.com/nexusformat/definitions/issues/1057 + self._print(f"{indent}{hTarget}") + self._print( + f"{indent}{formatted_name}: {optional_text}{typ} " + f"{self.get_first_parent_ref(f'{parent_path}/{name}', 'group')}\n" ) - for node in parent.xpath("nx:group", namespaces=ns): - name = node.get("name", "") - formatted_name = get_rst_formatted_name(node) - typ = node.get("type", "untyped (this is an error; please report)") - - optional_text = self._get_required_or_optional_text(node) - if typ.startswith("NX"): - if name == "": - name = typ.lstrip("NX").upper() - typ = f":ref:`{typ}`" - hTarget = self._hyperlink_target(parent_path, name, "group") - # target = hTarget.replace(".. _", "").replace(":\n", "") - # TODO: https://github.com/nexusformat/definitions/issues/1057 - self._print(f"{indent}{hTarget}") - self._print( - f"{indent}{formatted_name}: {optional_text}{typ} {self.get_first_parent_ref(f'{parent_path}/{name}', 'group')}\n" - ) - - self._print_if_deprecated(ns, node, indent + self._INDENTATION_UNIT) - self._print_doc_enum(indent, ns, node) + self._print_if_deprecated(ns, node, indent + self._INDENTATION_UNIT) + self._print_doc_enum(indent, ns, node) + + for subnode in node.xpath("nx:attribute", namespaces=ns): + optional = self._get_required_or_optional_text(subnode) + self._print_attribute( + ns, + "group", + subnode, + optional, + indent + self._INDENTATION_UNIT, + parent_path + "/" + name, + ) - for subnode in node.xpath("nx:attribute", namespaces=ns): - optional = self._get_required_or_optional_text(subnode) - self._print_attribute( + nodename = "%s/%s" % (name, node.get("type")) + self._print_full_tree( ns, - "group", - subnode, - optional, + node, + nodename, indent + self._INDENTATION_UNIT, parent_path + "/" + name, ) - nodename = "%s/%s" % (name, node.get("type")) - self._print_full_tree( - ns, - node, - nodename, - indent + self._INDENTATION_UNIT, - parent_path + "/" + name, - ) + elif tag == "choice": + name = node.get("name", "") + hTarget = self._hyperlink_target(parent_path, name, "choice") + self._print(f"{indent}{hTarget}") + optional_text = self._get_required_or_optional_text(node).strip("() ") + self._print( + f"{indent}**{name}**: ({optional_text}) " + "Only one of the following groups may be present:\n" + ) + self._print_doc_enum(indent, ns, node) - for node in parent.xpath("nx:link", namespaces=ns): - name = node.get("name") - formatted_name = get_rst_formatted_name(node) - self._print(f"{indent}{self._hyperlink_target(parent_path, name, 'link')}") - self._print( - f"{indent}{formatted_name}: " - ":ref:`link` " - f"(suggested target: ``{node.get('target')}``)" - "\n" - ) - self._print_doc_enum(indent, ns, node) + # Print each group option within the choice. + for subnode in node.xpath("nx:group", namespaces=ns): + subname = subnode.get("name", "") + typ = subnode.get( + "type", "untyped (this is an error; please report)" + ) + if typ.startswith("NX"): + if subname == "": + subname = typ.lstrip("NX").upper() + typ_ref = f":ref:`{typ}`" + else: + typ_ref = typ + sub_indent = indent + self._INDENTATION_UNIT + subTarget = self._hyperlink_target( + parent_path + "/" + name, subname, "group" + ) + self._print(f"{sub_indent}{subTarget}") + self._print(f"{sub_indent}**{subname}**: {typ_ref}\n") + self._print_doc_enum(sub_indent, ns, subnode) + + # Recursively print any content within this group option. + nodename = "%s/%s" % (subname, subnode.get("type")) + self._print_full_tree( + ns, + subnode, + nodename, + sub_indent + self._INDENTATION_UNIT, + parent_path + "/" + name + "/" + subname, + ) + + elif tag == "link": + name = node.get("name") + formatted_name = get_rst_formatted_name(node) + self._print( + f"{indent}{self._hyperlink_target(parent_path, name, 'link')}" + ) + self._print( + f"{indent}{formatted_name}: " + ":ref:`link` " + f"(suggested target: ``{node.get('target')}``)" + "\n" + ) + self._print_doc_enum(indent, ns, node) + + else: + raise ValueError(f"Unknown node type: {tag}") def _print(self, *args, end="\n"): # TODO: change instances of \t to proper indentation