diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 05ce33b18..34dc020d4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,12 +4,16 @@ on: push: branches: - main # push commit to the main branch - tags: - - 'v2*' # push tag starting with "v2" to the main branch pull_request: branches: - main # pull request to the main branch workflow_dispatch: # allow manual triggering + inputs: + deploy: + description: 'Deploy documentation' + type: boolean + required: true + default: false defaults: run: @@ -33,7 +37,7 @@ jobs: fetch-depth: 0 - name: Deploy Information - if: ${{ startsWith(github.ref, 'refs/tags') && env.python_version == '3.7' }} + if: ${{ github.event.inputs.deploy && env.python_version == '3.7' }} run: | echo "The HTML NeXus User Manual will be pushed to" echo " https://github.com/nexusformat/definitions/tree/gh-pages" @@ -81,14 +85,14 @@ jobs: ls -lAFgh build/manual/build/latex/nexus.pdf - name: Build and Commit the User Manual - if: ${{ startsWith(github.ref, 'refs/tags') && env.python_version == '3.7' }} + if: ${{ github.event.inputs.deploy && env.python_version == '3.7' }} uses: sphinx-notes/pages@master with: # path to the conf.py directory documentation_path: build/manual/source - name: Deploy the User Manual - if: ${{ startsWith(github.ref, 'refs/tags') && env.python_version == '3.7' }} + if: ${{ github.event.inputs.deploy && env.python_version == '3.7' }} uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGES.rst b/CHANGES.rst index e54d7fb45..de734d097 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,6 +22,51 @@ Highlights of each release are described below. For more details, see our wiki which provides links to the Release Notes (itemized list of changes) for any release. +v2023.06 +++++++++ + +expected *2023-06* + +New Features +------------ + +Add ``h5wasm`` and ``H5Web`` to HDF tools list. + +Allow ``recommended`` attribute as alias for ``optional``, but with the +recommendation that this attribute be specified. + +NXxas: Added `NXdata/mode` to report detection method. + +Fixes +----------- + +Added missing close parenthesis in rendering of suggested target. + +Maintenance +----------- + +NXdata: clarify how errors are described in documentation. + +NXmx: clarify pixel size. + +NXsas: Various fields and groups changed to optional. Only those deemed +necessary for data reduction are required. + +NXtransformations: Add ``equipment_component`` attribute + +NXxas: `data` fields` changed from `NX_INT` to `NX_NUMBER`. + +NXxpcs: clarify use of ``entry_identifier``, ``entry_identifier_uuid``, and ``scan_number``. + +Deprecations +------------ + +NXdata: deprecate `errors` field in favor of `VARIABLE_errors` for the signal field. + +.. + Contributors + ------------ + v2022.07 ++++++++ diff --git a/applications/NXmx.nxdl.xml b/applications/NXmx.nxdl.xml index 8557ddbd5..0c71dab11 100644 --- a/applications/NXmx.nxdl.xml +++ b/applications/NXmx.nxdl.xml @@ -457,7 +457,7 @@ Boolean to indicate if the distance is a derived, rather than a primary observation. If distance_derived true or is not specified, - the distance is assumed to be derived from delector axis + the distance is assumed to be derived from detector axis specifications. @@ -628,10 +628,25 @@ - True when a count-rate correction has already been applied in - the data recorded here, false otherwise. + Counting detectors usually are not able to measure all incoming particles, + especially at higher count-rates. Count-rate correction is applied to + account for these errors. + + True when count-rate correction has been applied, false otherwise. + + + The countrate_correction_lookup_table defines the LUT used for count-rate + correction. It maps a measured count :math:`c` to its corrected value + :math:`countrate\_correction\_lookup\_table[c]`. + + :math:`m` denotes the length of the table. + + + + + @@ -691,7 +706,7 @@ - + The value at which the detector goes into saturation. Data above this value is known to be invalid. @@ -702,7 +717,7 @@ - + The lowest value at which pixels for this detector would be reasonably be measured. diff --git a/applications/NXsas.nxdl.xml b/applications/NXsas.nxdl.xml index aa9ceab24..a9ffae265 100644 --- a/applications/NXsas.nxdl.xml +++ b/applications/NXsas.nxdl.xml @@ -2,9 +2,9 @@ @@ -373,7 +375,6 @@ as the ``data``. At least one ``dim`` must have length "n". - diff --git a/base_classes/NXmonitor.nxdl.xml b/base_classes/NXmonitor.nxdl.xml index 7723f8a50..fce17418f 100644 --- a/base_classes/NXmonitor.nxdl.xml +++ b/base_classes/NXmonitor.nxdl.xml @@ -96,7 +96,6 @@ ``1 <= dataRank <= NX_MAXRANK=32``. At least one ``dim`` must have length ``n``. - diff --git a/contributed_definitions/NXxpcs.nxdl.xml b/contributed_definitions/NXxpcs.nxdl.xml index 4693b7485..9839fbb2a 100644 --- a/contributed_definitions/NXxpcs.nxdl.xml +++ b/contributed_definitions/NXxpcs.nxdl.xml @@ -177,7 +177,7 @@ - + unnormalized intensity auto-correlation function. @@ -192,7 +192,7 @@ - + delay_difference (also known as delay or lag step) diff --git a/dev_tools/docs/nxdl.py b/dev_tools/docs/nxdl.py index 14b3579a9..8da3ebbc0 100644 --- a/dev_tools/docs/nxdl.py +++ b/dev_tools/docs/nxdl.py @@ -357,12 +357,6 @@ def _analyze_dimensions(self, ns, parent) -> str: - The legacy way of doing this (still supported) - - - - - 4. Rank and dimensions equal to that of another field called `field_name` @@ -383,10 +377,11 @@ def _analyze_dimensions(self, ns, parent) -> str: if not index.isdigit(): raise RuntimeError("A dimension must have an index") index = int(index) - if index == 0: - # No longer needed: legacy way to specify that the - # rank is variable - continue + if index <= 0: + # No longer permitted + raise RuntimeError( + "A dimension's index must be a positive integer (>=1)" + ) # Expand dimensions when needed index -= 1 diff --git a/impatient-guide/index.rst b/impatient-guide/index.rst index bfa47b9b4..b78cebcd9 100644 --- a/impatient-guide/index.rst +++ b/impatient-guide/index.rst @@ -497,15 +497,16 @@ Application definitions Reading NeXus Files =================== -The simplest way to read and plot a NeXus file is through the Python *PyTree* API: +The simplest way to read and plot a NeXus file is through the +nexusformat [#nexusformat]_ Python package : .. code-block:: python :linenos: - import nxs - nxs.load('powder.h5').plot() + from nexusformat.nexus import nxopen + nxopen('powder.h5').plot() -In order for this to be possible, *PyTree* uses the NeXus conventions to locate +In order for this to be possible, *nexusformat* uses the NeXus conventions to locate the plottable data and the axes to use. In particular, this plots the first ``NXdata`` group in the first ``NXentry`` in the ``powder.h5`` file. The NeXus python package provides additional support for working with NeXus groups. @@ -722,6 +723,8 @@ find on the NeXus WWW site. .. [#HDF5] HDF-5: http://www.hdfgroup.org/HDF5/ +.. [#nexusformat] *nexusformat*: https://nexpy.github.io/nexpy/ + .. [#h5py] *h5py*: https://www.h5py.org/ .. [#lrcs3701] ``lrcs3701.nx5`` (NeXus HDF-5 data file): diff --git a/manual/source/conf.py b/manual/source/conf.py index 92007c726..51b35e4bb 100644 --- a/manual/source/conf.py +++ b/manual/source/conf.py @@ -46,7 +46,8 @@ 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinx.ext.githubpages', - 'sphinx.ext.todo' + 'sphinx.ext.todo', + 'sphinx_tabs.tabs' ] # Show `.. todo` directives in the output diff --git a/manual/source/design.rst b/manual/source/design.rst index 6ae741f94..956b102f1 100644 --- a/manual/source/design.rst +++ b/manual/source/design.rst @@ -31,20 +31,20 @@ used by NeXus. These are: Levels in the NeXus hierarchy. May contain fields and other groups. :ref:`Design-Fields` - Multidimensional arrays and scalars representing the actual data to be stored + Multidimensional arrays and scalars representing the actual data to be stored. :ref:`Design-Attributes` Attributes containing additional metadata can be assigned to groups, fields, or :ref:`files `. :ref:`Design-Links` - Elements which point to data stored in another place in the file hierarchy + Elements which point to data stored in another place in the file hierarchy. :ref:`Design-NeXusClasses` - Dictionaries of names possible in the various types of NeXus groups + Dictionaries of names possible in the various types of NeXus groups. :ref:`Design-NeXusApplications` - Describe the minimum content of a NeXus file for a particular usage case + Describe the minimum content of a NeXus file for a particular usage case. In the following sections these elements of NeXus files will be defined in more detail. @@ -58,9 +58,9 @@ In the following sections these elements of NeXus files will be defined in more The tree syntax is a very condensed version (with high information density) meant to convey the structure of the HDF file. - * Groups have a ``/`` appended to their name (with NeXus class name shown) + * Groups have a ``/`` appended to their name (with NeXus class name shown). * Indentation shows membership in the lesser indented parent above. - * Fields have a data type and value appended (for arrays, this may be an abbreviated view) + * Fields have a data type and value appended (for arrays, this may be an abbreviated view). * Attributes (of groups or fields) are prefixed with ``@``. * NeXus-style links are described with some sort of arrow notation such as ``-->``. @@ -106,12 +106,12 @@ Fields (also called data fields, data items or data sets) contain the essential information stored in a NeXus file. They can be scalar values or multidimensional arrays of a variety of sizes (1-byte, 2-byte, 4-byte, 8-byte) and types (integers, floats, characters). The fields may -store both experimental results (counts, detector angles, etc), and other +store both experimental results (counts, detector angles, etc.), and other information associated with the experiment (start and end times, user names, -etc). Fields are identified by their names, which must be unique within the +etc.). Fields are identified by their names, which must be unique within the group in which they are stored. Some fields have engineering units to be specified. In some cases, such as :ref:`/NXdata/DATA `, a field is -expected to have be an array of several dimensions. +expected to be an array of several dimensions. .. compound:: @@ -126,7 +126,7 @@ expected to have be an array of several dimensions. Errors (uncertainties) associated with axis ``variable``. ``wavelength`` (*NX_FLOAT*) - wavelength of radiation, ``units="NX_FLOAT"`` + wavelength of radiation, ``units="NX_FLOAT"``. ``chemical_formula`` (*NX_CHAR*) The chemical formula specified using CIF conventions. @@ -135,7 +135,7 @@ expected to have be an array of several dimensions. Name of user responsible for this entry. ``data`` (*NX_NUMBER*) - Data values from the detector, ``units="NX_ANY"`` + Data values from the detector, ``units="NX_ANY"``. See the sections :ref:`nxdl-types` and :ref:`nxdl-units` for complete lists of the data types and engineering units types, respectively. @@ -236,7 +236,7 @@ Links .. sidebar:: Python h5py code to make NeXus links - The section titled :ref:`Example-H5py` provides example + The section titled :ref:`Example-Python` provides example python code to create links (both internal and external) in NeXus data files. See the routines: @@ -441,8 +441,8 @@ Data groups often describe objects in the experiment (monitors, detectors, monochromators, etc.), so that the contents (both fields and/or other groups) comprise the properties of that object. NeXus has defined a set of standard objects, or :ref:`base classes `, -out of which a NeXus file can be constructed. This is each data group -is identified by a name and a class. The group class, defines the type of object +out of which a NeXus file can be constructed. Each data group +is identified by a name and a class. The group class defines the type of object and the properties that it can contain, whereas the group name defines a unique instance of that class. These classes are defined in XML using the NeXus Definition Language @@ -483,8 +483,8 @@ But there are some base classes which have special uses which need to be mention :ref:`NXdata` ``NXdata`` is used to identify the default :index:`plottable data `. - The notion of a default plot of data is a basic motivation of NeXus. - (see :ref:`SimplePlotting`) + The notion of a default plot of data is a basic motivation of NeXus + (see :ref:`SimplePlotting`). :ref:`NXlog` ``NXlog`` is used to store time stamped data like the log of a temperature controller. @@ -926,8 +926,8 @@ edges must be present but does not need to be correct :linenos: :language: text -Following the initial line are the xyz coordinates of each vertex. Proceeding -which is the list of faces. Each line defining a face starts with the number of +Following the initial line are the xyz coordinates of each vertex, followed +by the list of faces. Each line defining a face starts with the number of vertices in that face followed by the sequence number of the composing vertices, indexed from zero. The vertex indices form a winding order by defining the face normal by the right-hand rule. The number of vertices in each face need not be diff --git a/manual/source/examples/epics/index.rst b/manual/source/examples/epics/index.rst index c6824d115..e5d453c29 100644 --- a/manual/source/examples/epics/index.rst +++ b/manual/source/examples/epics/index.rst @@ -1,6 +1,6 @@ .. index:: !EPICS; instrument examples -..Example-EPICS: +.. _Example-EPICS: EPICS Area Detector Examples ############################ diff --git a/manual/source/examples/index.rst b/manual/source/examples/index.rst index 27acd3bd1..dbea811c4 100644 --- a/manual/source/examples/index.rst +++ b/manual/source/examples/index.rst @@ -26,8 +26,7 @@ Please be aware that not all examples are up to date with the latest format reco :maxdepth: 1 code_native - h5py/index - nexusformat/index + python/index matlab/index napi/c napi/fortran @@ -42,10 +41,10 @@ Tools to visualize NeXus HDF5 files graphically or in text form. .. toctree:: - view/h5dump - view/punx view/nexpy view/silx + view/punx + view/h5dump .. _Examples.instruments: diff --git a/manual/source/examples/matlab/index.rst b/manual/source/examples/matlab/index.rst index 1438adef4..9e40494be 100644 --- a/manual/source/examples/matlab/index.rst +++ b/manual/source/examples/matlab/index.rst @@ -19,7 +19,7 @@ HDF5 in MATLAB ``input.dat`` +++++++++++++ -This is the same data used with :ref:`Example-H5py`. +This is the same data used with :ref:`Example-Python`. .. literalinclude:: input.dat :tab-width: 4 diff --git a/manual/source/examples/nexusformat/index.rst b/manual/source/examples/nexusformat/index.rst deleted file mode 100644 index 3d2b496cf..000000000 --- a/manual/source/examples/nexusformat/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. index:: !nexusformat; code examples - -.. _Example-nexusformat: - -=================================== -HDF5 in Python with ``nexusformat`` -=================================== - -``nexusformat`` provides a higher level API on top of h5py (see chapter :ref:`Example-H5py`). -While h5py provides a basic API to read and write HDF5 files, ``nexusformat`` enriches this -API with NeXus specific utilities. - -Please refer to the ``NeXpy`` documentation: https://nexpy.github.io/nexpy/. - -Code examples -============= - -* `Write examples for different NeXus classes `_ \ No newline at end of file diff --git a/manual/source/examples/h5py/create_data.sh b/manual/source/examples/python/create_data.sh similarity index 100% rename from manual/source/examples/h5py/create_data.sh rename to manual/source/examples/python/create_data.sh diff --git a/manual/source/examples/h5py/external_example_write/external_angles.hdf5 b/manual/source/examples/python/external_example_write/external_angles.hdf5 similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_angles.hdf5 rename to manual/source/examples/python/external_example_write/external_angles.hdf5 diff --git a/manual/source/examples/h5py/external_example_write/external_angles_h5dump.txt b/manual/source/examples/python/external_example_write/external_angles_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_angles_h5dump.txt rename to manual/source/examples/python/external_example_write/external_angles_h5dump.txt diff --git a/manual/source/examples/h5py/external_example_write/external_angles_structure.txt b/manual/source/examples/python/external_example_write/external_angles_structure.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_angles_structure.txt rename to manual/source/examples/python/external_example_write/external_angles_structure.txt diff --git a/manual/source/examples/h5py/external_example_write/external_counts.hdf5 b/manual/source/examples/python/external_example_write/external_counts.hdf5 similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_counts.hdf5 rename to manual/source/examples/python/external_example_write/external_counts.hdf5 diff --git a/manual/source/examples/h5py/external_example_write/external_counts_h5dump.txt b/manual/source/examples/python/external_example_write/external_counts_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_counts_h5dump.txt rename to manual/source/examples/python/external_example_write/external_counts_h5dump.txt diff --git a/manual/source/examples/h5py/external_example_write/external_counts_structure.txt b/manual/source/examples/python/external_example_write/external_counts_structure.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_counts_structure.txt rename to manual/source/examples/python/external_example_write/external_counts_structure.txt diff --git a/manual/source/examples/h5py/external_example_write/external_example_write.py b/manual/source/examples/python/external_example_write/external_example_write.py similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_example_write.py rename to manual/source/examples/python/external_example_write/external_example_write.py diff --git a/manual/source/examples/h5py/external_example_write/external_master.hdf5 b/manual/source/examples/python/external_example_write/external_master.hdf5 similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_master.hdf5 rename to manual/source/examples/python/external_example_write/external_master.hdf5 diff --git a/manual/source/examples/h5py/external_example_write/external_master_h5dump.txt b/manual/source/examples/python/external_example_write/external_master_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_master_h5dump.txt rename to manual/source/examples/python/external_example_write/external_master_h5dump.txt diff --git a/manual/source/examples/h5py/external_example_write/external_master_structure.txt b/manual/source/examples/python/external_example_write/external_master_structure.txt similarity index 100% rename from manual/source/examples/h5py/external_example_write/external_master_structure.txt rename to manual/source/examples/python/external_example_write/external_master_structure.txt diff --git a/manual/source/examples/h5py/external_example_write/index.rst b/manual/source/examples/python/external_example_write/index.rst similarity index 66% rename from manual/source/examples/h5py/external_example_write/index.rst rename to manual/source/examples/python/external_example_write/index.rst index 4afbf78ac..d14b59287 100644 --- a/manual/source/examples/h5py/external_example_write/index.rst +++ b/manual/source/examples/python/external_example_write/index.rst @@ -103,29 +103,41 @@ to write a NeXus-compliant HDF5 file with links to data in other HDF5 files. .. rubric:: *external_example_write.py*: Write using HDF5 external links - .. _Example-H5py-external_example_write: + .. _Example-Python-external_example_write: - .. literalinclude:: external_example_write.py - :tab-width: 4 - :linenos: - :language: python + .. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/external_example_write.py + :tab-width: 4 + :linenos: + :language: python + + .. tab:: h5py + + .. literalinclude:: external_example_write.py + :tab-width: 4 + :linenos: + :language: python downloads ========= The Python code and files related to this section may be downloaded from the following table. -=========================================== ============================================= -file description -=========================================== ============================================= -:download:`external_angles_h5dump.txt` *h5dump* analysis of *external_angles.hdf5* -:download:`external_angles.hdf5` HDF5 file written by *external_example_write* -:download:`external_angles_structure.txt` *punx tree* analysis of *external_angles.hdf5* -:download:`external_counts_h5dump.txt` *h5dump* analysis of *external_counts.hdf5* -:download:`external_counts.hdf5` HDF5 file written by *external_example_write* -:download:`external_counts_structure.txt` *punx tree* analysis of *external_counts.hdf5* -:download:`external_example_write.py` python code to write external linking examples -:download:`external_master_h5dump.txt` *h5dump* analysis of *external_master.hdf5* -:download:`external_master.hdf5` NeXus file written by *external_example_write* -:download:`external_master_structure.txt` *punx tree* analysis of *external_master.hdf5* -=========================================== ============================================= \ No newline at end of file +================================================= =================================================== +file description +================================================= =================================================== +:download:`external_angles_h5dump.txt` *h5dump* analysis of *external_angles.hdf5* +:download:`external_angles.hdf5` HDF5 file written by *external_example_write* +:download:`external_angles_structure.txt` *punx tree* analysis of *external_angles.hdf5* +:download:`external_counts_h5dump.txt` *h5dump* analysis of *external_counts.hdf5* +:download:`external_counts.hdf5` HDF5 file written by *external_example_write* +:download:`external_counts_structure.txt` *punx tree* analysis of *external_counts.hdf5* +:download:`external_example_write.py` h5py code to write external linking examples +:download:`nexusformat/external_example_write.py` nexusformat code to write external linking examples +:download:`external_master_h5dump.txt` *h5dump* analysis of *external_master.hdf5* +:download:`external_master.hdf5` NeXus file written by *external_example_write* +:download:`external_master_structure.txt` *punx tree* analysis of *external_master.hdf5* +================================================= =================================================== \ No newline at end of file diff --git a/manual/source/examples/python/external_example_write/nexusformat/external_example_write.py b/manual/source/examples/python/external_example_write/nexusformat/external_example_write.py new file mode 100755 index 000000000..6885bf9d2 --- /dev/null +++ b/manual/source/examples/python/external_example_write/nexusformat/external_example_write.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +""" +Writes a NeXus HDF5 file using h5py with links to data in other HDF5 files. + +This example is based on ``writer_2_1``. +""" + +from pathlib import Path + +import h5py +import numpy + +from nexusformat.nexus import (NXdata, NXdetector, NXentry, NXfield, + NXinstrument, NXlink, nxopen) + +FILE_HDF5_MASTER = "external_master.hdf5" +FILE_HDF5_ANGLES = "external_angles.hdf5" +FILE_HDF5_COUNTS = "external_counts.hdf5" + +# --------------------------- + +# get some data +filename = str(Path(__file__).absolute().parent.parent / "simple_example.dat") +buffer = numpy.loadtxt(filename).T +tthData = buffer[0] # float[] +countsData = numpy.asarray(buffer[1], "int32") # int[] + +# put the angle data in an external (non-NeXus) HDF5 data file +with h5py.File(FILE_HDF5_ANGLES, "w") as f: + ds = f.create_dataset("angles", data=tthData) + ds.attrs["units"] = "degrees" + +# put the detector counts in an external HDF5 data file +# with *incomplete* NeXus structure (no NXdata group) +with nxopen(FILE_HDF5_COUNTS, "w") as f: + f["entry"] = NXentry() + f["entry/instrument"] = NXinstrument() + f["entry/instrument/detector"] = NXdetector() + f["entry/instrument/detector/counts"] = NXfield(countsData, units="counts") + f["entry/instrument/detector/two_theta"] = NXlink("/angles", + FILE_HDF5_ANGLES) + +# create a master NeXus HDF5 file +with nxopen(FILE_HDF5_MASTER, "w") as f: + f["entry"] = NXentry() + counts = NXlink("/entry/instrument/detector/counts", FILE_HDF5_COUNTS, + name="counts") + two_theta = NXlink("/angles", FILE_HDF5_ANGLES, name="two_theta") + f["entry/data"] = NXdata(counts, two_theta) + f["entry/data"].set_default() + f["entry/instrument"] = NXlink("/entry/instrument", FILE_HDF5_COUNTS) diff --git a/manual/source/examples/h5py/index.rst b/manual/source/examples/python/index.rst similarity index 57% rename from manual/source/examples/h5py/index.rst rename to manual/source/examples/python/index.rst index 6270d7d71..40e952773 100644 --- a/manual/source/examples/h5py/index.rst +++ b/manual/source/examples/python/index.rst @@ -1,22 +1,27 @@ .. index:: !h5py; code examples -.. _Example-H5py: +.. _Example-python: -============================ -HDF5 in Python with ``h5py`` -============================ +============== +HDF5 in Python +============== One way to gain a quick familiarity with NeXus is to start working with some data. For at least the first few examples in this section, we have a simple two-column set of 1-D data, collected as part of a -series of alignment scans by the APS USAXS instrument during the time it was stationed at -beam line 32ID. We will show how to write this -data using the Python language and the ``h5py`` package [#]_ -(:index:`using ` ``h5py`` calls directly rather than using the NeXus NAPI). The -actual data to be written was extracted (elsewhere) from a ``spec`` [#]_ data file +series of alignment scans by the Advanced Photon Source USAXS instrument during the time it was stationed at +beam line 32ID. We will show how to read and write this data in Python using both the +``nexusformat`` [#]_ and ``h5py`` [#]_ packages. The ``nexusformat`` package provides a simplified syntax for +reading and writing NeXus-compliant files by automatically handling some of the features required by the +NeXus standard, such as the attributes that define group classes and plottable data. However, it also uses +the ``h5py`` package to read/write the HDF5 files on disk. We provide tabbed examples showing +how to produce equivalent files either using ``nexusformat`` or directly in ``h5py``. + +The actual data to be written was extracted (elsewhere) from a ``spec`` [#]_ data file and read as a text block from a file by the Python source code. Our examples will start with the simplest case and add only mild complexity with each new case since these examples are meant for those who are unfamiliar with NeXus. +.. [#] *nexusformat*: https://nexpy.github.io/nexpy/ .. [#] *h5py*: https://www.h5py.org/ .. [#] *SPEC*: http://certif.com/spec.html @@ -32,7 +37,8 @@ Code examples external_example_write/index plotting/index -* `Write examples for different NeXus classes `_ +* `Write examples with nexusformat for different NeXus classes `_ +* `Write examples with h5py for different NeXus classes `_ Example data used ================= diff --git a/manual/source/examples/h5py/plotting/index.rst b/manual/source/examples/python/plotting/index.rst similarity index 50% rename from manual/source/examples/h5py/plotting/index.rst rename to manual/source/examples/python/plotting/index.rst index 7e57b8c13..5ffee40e2 100644 --- a/manual/source/examples/h5py/plotting/index.rst +++ b/manual/source/examples/python/plotting/index.rst @@ -16,14 +16,25 @@ subsection :ref:`Find-Plottable-Data-v3`, for the details.) .. compound:: - .. rubric:: *reader_attributes_trail.py*: Read a NeXus HDF5 file using Python with h5py + .. rubric:: *reader_attributes_trail.py*: Read a NeXus HDF5 file using Python - .. _Example-H5py-Reader_attributes_trail: + .. _Example-Python-Reader_attributes_trail: - .. literalinclude:: reader_attributes_trail.py - :tab-width: 4 - :linenos: - :language: python +.. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/reader_attributes_trail.py + :tab-width: 4 + :linenos: + :language: python + + .. tab:: h5py + + .. literalinclude:: reader_attributes_trail.py + :tab-width: 4 + :linenos: + :language: python Output from ``reader_attributes_trail.py`` is shown next. @@ -41,8 +52,9 @@ downloads The Python code and files related to this section may be downloaded from the following table. -=========================================== ============================================= -file description -=========================================== ============================================= -:download:`reader_attributes_trail.py` Read NeXus HDF5 file and find plotaable data -=========================================== ============================================= \ No newline at end of file +================================================== ================================================================= +file description +================================================== ================================================================= +:download:`reader_attributes_trail.py` h5py code to read NeXus HDF5 file and find plottable data +:download:`nexusformat/reader_attributes_trail.py` nexusformat code to read NeXus HDF5 file and find plottable data +================================================== ================================================================= \ No newline at end of file diff --git a/manual/source/examples/python/plotting/nexusformat/reader_attributes_trail.py b/manual/source/examples/python/plotting/nexusformat/reader_attributes_trail.py new file mode 100644 index 000000000..0ea950706 --- /dev/null +++ b/manual/source/examples/python/plotting/nexusformat/reader_attributes_trail.py @@ -0,0 +1,22 @@ +from pathlib import Path +from nexusformat.nexus import nxopen + +filename = str( + Path(__file__).absolute().parent.parent + / "simple_example_basic" + / "simple_example_basic.nexus.hdf5" +) +with nxopen(filename) as f: + # find the default NXdata group + nx_data = f.get_default() + signal = nx_data.nxsignal + axes = nx_data.nxaxes[0] + +nx_data.plot() # plot the data using Matplotlib + +print(f"file: {f.nxfilename}") +print(f"signal: {signal.nxname}") +print(f"axes: {axes.nxname}") +print(f"{axes.nxname} {signal.nxname}") +for x, y in zip(axes, signal): + print(x, y) diff --git a/manual/source/examples/h5py/plotting/reader_attributes_trail.py b/manual/source/examples/python/plotting/reader_attributes_trail.py similarity index 100% rename from manual/source/examples/h5py/plotting/reader_attributes_trail.py rename to manual/source/examples/python/plotting/reader_attributes_trail.py diff --git a/manual/source/examples/h5py/plotting/reader_attributes_trail.txt b/manual/source/examples/python/plotting/reader_attributes_trail.txt similarity index 100% rename from manual/source/examples/h5py/plotting/reader_attributes_trail.txt rename to manual/source/examples/python/plotting/reader_attributes_trail.txt diff --git a/manual/source/examples/h5py/simple_example.dat b/manual/source/examples/python/simple_example.dat similarity index 100% rename from manual/source/examples/h5py/simple_example.dat rename to manual/source/examples/python/simple_example.dat diff --git a/manual/source/examples/h5py/simple_example.png b/manual/source/examples/python/simple_example.png similarity index 100% rename from manual/source/examples/h5py/simple_example.png rename to manual/source/examples/python/simple_example.png diff --git a/manual/source/examples/h5py/simple_example.txt b/manual/source/examples/python/simple_example.txt similarity index 100% rename from manual/source/examples/h5py/simple_example.txt rename to manual/source/examples/python/simple_example.txt diff --git a/manual/source/examples/h5py/simple_example_basic/index.rst b/manual/source/examples/python/simple_example_basic/index.rst similarity index 69% rename from manual/source/examples/h5py/simple_example_basic/index.rst rename to manual/source/examples/python/simple_example_basic/index.rst index d4ce54b70..bc6237798 100644 --- a/manual/source/examples/h5py/simple_example_basic/index.rst +++ b/manual/source/examples/python/simple_example_basic/index.rst @@ -1,14 +1,14 @@ -.. _Example-H5py-complete: +.. _Example-Python-complete: Getting started ############### -.. _Example-H5py-Writing: +.. _Example-Python-Writing: Write a NeXus HDF5 File ======================= -In the main code section of :ref:`simple_example_basic_write.py `, +In the main code section of :ref:`simple_example_basic_write.py `, the data (``mr`` is similar to "two_theta" and ``I00`` is similar to "counts") is collated into two Python lists. We use the **numpy** package to read the file and parse the two-column format. @@ -53,21 +53,31 @@ corrupt the file when the program quits. .. rubric:: *simple_example_basic_write.py*: Write a NeXus HDF5 file using Python with h5py - .. _Example-H5py-BasicWriter: + .. _Example-Python-BasicWriter: - .. literalinclude:: simple_example_basic_write.py - :tab-width: 4 - :linenos: - :language: python + .. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/simple_example_basic_write.py + :tab-width: 4 + :linenos: + :language: python -.. _Example-H5py-Reading: + .. tab:: h5py + + .. literalinclude:: simple_example_basic_write.py + :tab-width: 4 + :linenos: + :language: python + +.. _Example-Python-Reading: Read a NeXus HDF5 File ====================== -The file reader, :ref:`simple_example_basic_read.py `, -is very simple since the bulk of the work is done by ``h5py``. -Our code opens the HDF5 we wrote above, +The file reader, :ref:`simple_example_basic_read.py `, +opens the HDF5 we wrote above, prints the HDF5 attributes from the file, reads the two datasets, and then prints them out as columns. As simple as that. Of course, real code might add some error-handling and @@ -80,14 +90,25 @@ extracting other useful stuff from the file. .. compound:: - .. rubric:: *simple_example_basic_read.py*: Read a NeXus HDF5 file using Python with h5py - - .. _Example-H5py-Reader: + .. rubric:: *simple_example_basic_read.py*: Read a NeXus HDF5 file using Python - .. literalinclude:: simple_example_basic_read.py - :tab-width: 4 - :linenos: - :language: python + .. _Example-Python-Reader: + + .. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/simple_example_basic_read.py + :tab-width: 4 + :linenos: + :language: python + + .. tab:: h5py + + .. literalinclude:: simple_example_basic_read.py + :tab-width: 4 + :linenos: + :language: python Output from ``simple_example_basic_read.py`` is shown next. @@ -105,13 +126,15 @@ downloads The Python code and files related to this section may be downloaded from the following table. -===================================================== ============================================= +===================================================== =================================================================== file description -===================================================== ============================================= +===================================================== =================================================================== :download:`../simple_example.dat` 2-column ASCII data used in this section -:download:`simple_example_basic_read.py` python code to read example *simple_example_basic.nexus.hdf5* -:download:`simple_example_basic_write.py` python code to write example *simple_example_basic.nexus.hdf5* +:download:`simple_example_basic_read.py` h5py code to read example *simple_example_basic.nexus.hdf5* +:download:`nexusformat/simple_example_basic_read.py` nexusformat code to read example *simple_example_basic.nexus.hdf5* +:download:`simple_example_basic_write.py` h5py code to write example *simple_example_basic.nexus.hdf5* +:download:`nexusformat/simple_example_basic_write.py` nexusformat code to write example *simple_example_basic.nexus.hdf5* :download:`simple_example_basic.nexus_h5dump.txt` *h5dump* analysis of the NeXus file :download:`simple_example_basic.nexus.hdf5` NeXus file written by *BasicWriter* :download:`simple_example_basic.nexus_structure.txt` *punx tree* analysis of the NeXus file -===================================================== ============================================= +===================================================== =================================================================== diff --git a/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_read.py b/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_read.py new file mode 100755 index 000000000..c86db3068 --- /dev/null +++ b/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_read.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +"""Reads NeXus HDF5 files using nexusformat and prints the contents""" + +from nexusformat.nexus import nxopen + +fileName = "simple_example_basic.nexus.hdf5" +with nxopen(fileName) as f: + print(f.tree) diff --git a/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_write.py b/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_write.py new file mode 100755 index 000000000..bdbccff97 --- /dev/null +++ b/manual/source/examples/python/simple_example_basic/nexusformat/simple_example_basic_write.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +"""Writes a NeXus HDF5 file using h5py and numpy""" + +from pathlib import Path +from re import X +import numpy + +from nexusformat.nexus import NXdata, NXentry, NXfield, nxopen + +print("Write a NeXus HDF5 file") +fileName = "simple_example_basic.nexus.hdf5" + +# load data from two column format +data_filename = str(Path(__file__).absolute().parent.parent / "simple_example.dat") +data = numpy.loadtxt(data_filename).T +mr_arr = data[0] +i00_arr = numpy.asarray(data[1], "int32") + +# create the HDF5 NeXus file +with nxopen(fileName, "w") as f: + + # create the NXentry group + f["entry"] = NXentry() + f["entry/title"] = "1-D scan of I00 v. mr" + + # create the NXdata group + x = NXfield(mr_arr, name="mr", units="degrees", long_name="USAXS mr (degrees)") + y = NXfield(i00_arr, name="I00", units="counts", + long_name="USAXS I00 (counts)") + f["entry/mr_scan"] = NXdata(y, x) + +print("wrote file:", fileName) diff --git a/manual/source/examples/h5py/simple_example_basic/output.txt b/manual/source/examples/python/simple_example_basic/output.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/output.txt rename to manual/source/examples/python/simple_example_basic/output.txt diff --git a/manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus.hdf5 b/manual/source/examples/python/simple_example_basic/simple_example_basic.nexus.hdf5 similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus.hdf5 rename to manual/source/examples/python/simple_example_basic/simple_example_basic.nexus.hdf5 diff --git a/manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus_h5dump.txt b/manual/source/examples/python/simple_example_basic/simple_example_basic.nexus_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus_h5dump.txt rename to manual/source/examples/python/simple_example_basic/simple_example_basic.nexus_h5dump.txt diff --git a/manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus_structure.txt b/manual/source/examples/python/simple_example_basic/simple_example_basic.nexus_structure.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/simple_example_basic.nexus_structure.txt rename to manual/source/examples/python/simple_example_basic/simple_example_basic.nexus_structure.txt diff --git a/manual/source/examples/h5py/simple_example_basic/simple_example_basic_read.py b/manual/source/examples/python/simple_example_basic/simple_example_basic_read.py similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/simple_example_basic_read.py rename to manual/source/examples/python/simple_example_basic/simple_example_basic_read.py diff --git a/manual/source/examples/h5py/simple_example_basic/simple_example_basic_write.py b/manual/source/examples/python/simple_example_basic/simple_example_basic_write.py similarity index 100% rename from manual/source/examples/h5py/simple_example_basic/simple_example_basic_write.py rename to manual/source/examples/python/simple_example_basic/simple_example_basic_write.py diff --git a/manual/source/examples/h5py/simple_example_test/simple_example_test_read.py b/manual/source/examples/python/simple_example_test/simple_example_test_read.py similarity index 100% rename from manual/source/examples/h5py/simple_example_test/simple_example_test_read.py rename to manual/source/examples/python/simple_example_test/simple_example_test_read.py diff --git a/manual/source/examples/h5py/simple_example_test/simple_example_test_write.py b/manual/source/examples/python/simple_example_test/simple_example_test_write.py similarity index 100% rename from manual/source/examples/h5py/simple_example_test/simple_example_test_write.py rename to manual/source/examples/python/simple_example_test/simple_example_test_write.py diff --git a/manual/source/examples/h5py/simple_example_write1/index.rst b/manual/source/examples/python/simple_example_write1/index.rst similarity index 83% rename from manual/source/examples/h5py/simple_example_write1/index.rst rename to manual/source/examples/python/simple_example_write1/index.rst index 9ac96f937..b05158fd4 100644 --- a/manual/source/examples/h5py/simple_example_write1/index.rst +++ b/manual/source/examples/python/simple_example_write1/index.rst @@ -15,15 +15,15 @@ as shown in the next figure. .. compound:: - .. _fig.simple-example-h5py: + .. _fig.simple-example-python: .. figure:: ../../../img/simple_example_write1.png - :alt: fig.simple-example-h5py + :alt: fig.simple-example-python :width: 50% Simple Example -In the :ref:`above figure `, +In the :ref:`above figure `, the data file (``simple_example_write1_h5py.hdf5``) contains a hierarchy of items, starting with an ``NXentry`` named ``entry``. (The full HDF5 path reference, ``/entry`` in this case, is shown to the right of each @@ -41,10 +41,21 @@ When the next Python program (``simple_example_write1_h5py.py``) is run from the command line (and there are no problems), the ``simple_example_write1_h5py.hdf5`` file is generated. -.. literalinclude:: simple_example_write1.py - :tab-width: 4 - :linenos: - :language: python +.. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/simple_example_write1.py + :tab-width: 4 + :linenos: + :language: python + + .. tab:: h5py + + .. literalinclude:: simple_example_write1.py + :tab-width: 4 + :linenos: + :language: python One of the tools provided with the HDF5 support libraries is the ``h5dump`` command, a command-line tool to print out the @@ -86,12 +97,13 @@ downloads The Python code and files related to this section may be downloaded from the following table. -================================================ ============================================= +================================================ ========================================================= file description -================================================ ============================================= +================================================ ========================================================= :download:`../simple_example.dat` 2-column ASCII data used in this section -:download:`simple_example_write1.py` python code to write example *simple_example_write1* +:download:`simple_example_write1.py` h5py code to write example *simple_example_write1* +:download:`nexusformat/simple_example_write1.py` nexusformat code to write example *simple_example_write1* :download:`simple_example_write1.hdf5` NeXus file written by this code :download:`simple_example_write1_h5dump.txt` *h5dump* analysis of the NeXus file :download:`simple_example_write1_structure.txt` *punx tree* analysis of the NeXus file -================================================ ============================================= +================================================ ========================================================= diff --git a/manual/source/examples/python/simple_example_write1/nexusformat/simple_example_write1.py b/manual/source/examples/python/simple_example_write1/nexusformat/simple_example_write1.py new file mode 100755 index 000000000..7e56d100c --- /dev/null +++ b/manual/source/examples/python/simple_example_write1/nexusformat/simple_example_write1.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +""" +Writes the simplest NeXus HDF5 file using h5py + +Uses method accepted at 2014NIAC +according to the example from Figure 1.3 +in the Introduction chapter +""" + +from pathlib import Path + +import numpy + +from nexusformat.nexus import NXdata, NXentry, NXfield, nxopen + +filename = str(Path(__file__).absolute().parent.parent / "simple_example.dat") +buffer = numpy.loadtxt(filename).T +tthData = buffer[0] +countsData = numpy.asarray(buffer[1], "int32") + +with nxopen("simple_example_write1.hdf5", "w") as f: # create the NeXus file + f["Scan"] = NXentry() + tth = NXfield(tthData, name="two_theta", units="degrees") + counts = NXfield(countsData, name="counts", units="counts") + f["Scan/data"] = NXdata(counts, tth) diff --git a/manual/source/examples/h5py/simple_example_write1/simple_example_write1.hdf5 b/manual/source/examples/python/simple_example_write1/simple_example_write1.hdf5 similarity index 100% rename from manual/source/examples/h5py/simple_example_write1/simple_example_write1.hdf5 rename to manual/source/examples/python/simple_example_write1/simple_example_write1.hdf5 diff --git a/manual/source/examples/h5py/simple_example_write1/simple_example_write1.py b/manual/source/examples/python/simple_example_write1/simple_example_write1.py similarity index 100% rename from manual/source/examples/h5py/simple_example_write1/simple_example_write1.py rename to manual/source/examples/python/simple_example_write1/simple_example_write1.py diff --git a/manual/source/examples/h5py/simple_example_write1/simple_example_write1_h5dump.txt b/manual/source/examples/python/simple_example_write1/simple_example_write1_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_write1/simple_example_write1_h5dump.txt rename to manual/source/examples/python/simple_example_write1/simple_example_write1_h5dump.txt diff --git a/manual/source/examples/h5py/simple_example_write1/simple_example_write1_structure.txt b/manual/source/examples/python/simple_example_write1/simple_example_write1_structure.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_write1/simple_example_write1_structure.txt rename to manual/source/examples/python/simple_example_write1/simple_example_write1_structure.txt diff --git a/manual/source/examples/h5py/simple_example_write2/index.rst b/manual/source/examples/python/simple_example_write2/index.rst similarity index 84% rename from manual/source/examples/h5py/simple_example_write2/index.rst rename to manual/source/examples/python/simple_example_write2/index.rst index 2eed5a5c9..cbf15b6a9 100644 --- a/manual/source/examples/h5py/simple_example_write2/index.rst +++ b/manual/source/examples/python/simple_example_write2/index.rst @@ -35,10 +35,21 @@ Links are made from that data to the ``/entry/data`` group. The Python code to build an HDF5 data file with that structure (using numerical data from the previous example) is shown below. -.. literalinclude:: simple_example_write2.py - :tab-width: 4 - :linenos: - :language: python + .. tabs:: + + .. tab:: nexusformat + + .. literalinclude:: nexusformat/simple_example_write2.py + :tab-width: 4 + :linenos: + :language: python + + .. tab:: h5py + + .. literalinclude:: simple_example_write2.py + :tab-width: 4 + :linenos: + :language: python It is interesting to compare the output of the ``h5dump`` of the data file ``simple_example_write2.hdf5`` with our Python instructions. @@ -86,13 +97,14 @@ downloads The Python code and files related to this section may be downloaded from the following table. -================================================ ============================================= +================================================ ========================================================= file description -================================================ ============================================= +================================================ ========================================================= :download:`../simple_example.dat` 2-column ASCII data used in this section -:download:`simple_example_write2.py` python code to write example *simple_example_write2* +:download:`simple_example_write2.py` h5py code to write example *simple_example_write2* +:download:`nexusformat/simple_example_write2.py` nexusformat code to write example *simple_example_write2* :download:`simple_example_write2.hdf5` NeXus file written by this code :download:`simple_example_write2_h5dump.txt` *h5dump* analysis of the NeXus file :download:`simple_example_write2_structure.txt` *punx tree* analysis of the NeXus file -================================================ ============================================= +================================================ ========================================================= \ No newline at end of file diff --git a/manual/source/examples/python/simple_example_write2/nexusformat/simple_example_write2.py b/manual/source/examples/python/simple_example_write2/nexusformat/simple_example_write2.py new file mode 100755 index 000000000..035fd13dd --- /dev/null +++ b/manual/source/examples/python/simple_example_write2/nexusformat/simple_example_write2.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +""" +Writes a simple NeXus HDF5 file using h5py with links +according to the example from Figure 2.1 in the Design chapter +""" + +from pathlib import Path + +import numpy + +from nexusformat.nexus import (NXdata, NXdetector, NXentry, NXfield, + NXinstrument, NXlink, nxopen) + +filename = str(Path(__file__).absolute().parent.parent / "simple_example.dat") +buffer = numpy.loadtxt(filename).T +tthData = buffer[0] # float[] +countsData = numpy.asarray(buffer[1], "int32") # int[] + +with nxopen("simple_example_write2.hdf5", "w") as f: # create the HDF5 NeXus file + f["entry"] = NXentry() + f["entry/instrument"] = NXinstrument() + f["entry/instrument/detector"] = NXdetector() + + # store the data in the NXdetector group + f["entry/instrument/detector/two_theta"] = NXfield(tthData, units="degrees") + f["entry/instrument/detector/counts"] = NXfield(countsData, units="counts") + + f["entry/data"] = NXdata(NXlink("/entry/instrument/detector/counts"), + NXlink("/entry/instrument/detector/two_theta")) + f["entry/data"].set_default() diff --git a/manual/source/examples/h5py/simple_example_write2/simple_example_write2.hdf5 b/manual/source/examples/python/simple_example_write2/simple_example_write2.hdf5 similarity index 100% rename from manual/source/examples/h5py/simple_example_write2/simple_example_write2.hdf5 rename to manual/source/examples/python/simple_example_write2/simple_example_write2.hdf5 diff --git a/manual/source/examples/h5py/simple_example_write2/simple_example_write2.py b/manual/source/examples/python/simple_example_write2/simple_example_write2.py similarity index 100% rename from manual/source/examples/h5py/simple_example_write2/simple_example_write2.py rename to manual/source/examples/python/simple_example_write2/simple_example_write2.py diff --git a/manual/source/examples/h5py/simple_example_write2/simple_example_write2_h5dump.txt b/manual/source/examples/python/simple_example_write2/simple_example_write2_h5dump.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_write2/simple_example_write2_h5dump.txt rename to manual/source/examples/python/simple_example_write2/simple_example_write2_h5dump.txt diff --git a/manual/source/examples/h5py/simple_example_write2/simple_example_write2_structure.txt b/manual/source/examples/python/simple_example_write2/simple_example_write2_structure.txt similarity index 100% rename from manual/source/examples/h5py/simple_example_write2/simple_example_write2_structure.txt rename to manual/source/examples/python/simple_example_write2/simple_example_write2_structure.txt diff --git a/manual/source/fileformat.rst b/manual/source/fileformat.rst index 404b85f36..31340fc49 100644 --- a/manual/source/fileformat.rst +++ b/manual/source/fileformat.rst @@ -78,8 +78,8 @@ A NeXus ``link`` directly maps to the HDF hard link mechanisms. - :ref:`example.napi.python` - :ref:`code_native.writing` - :ref:`code_native.reading` - - :ref:`Example-H5py-Writing` - - :ref:`Example-H5py-Reading` + - :ref:`Example-Python-Writing` + - :ref:`Example-Python-Reading` Perhaps the easiest way to view the implementation of NeXus in HDF5 is to look at the data structure. For this, we use the ``h5dump`` command-line diff --git a/manual/source/utilities.rst b/manual/source/utilities.rst index 25e9db830..9dcf2033b 100644 --- a/manual/source/utilities.rst +++ b/manual/source/utilities.rst @@ -379,16 +379,18 @@ languages that will allow low level programmatic access to the data structures. extension for `Microsoft Visual Studio Code Editor `__ * On-line visualization with NeXus file (using ``h5wasm``): - `simple_example_basic.nexus.hdf5 `__ + `simple_example_basic.nexus.hdf5 `__ * `H5Web demonstration site `__ .. index:: HDF; tools -**HDF Group command line tools** (http://www.hdfgroup.org/products/hdf5_tools/#h5dist/) - There are various command line tools that are available from the HDF - Group, these are usually shipped with the HDF5 kits but are also available for +**HDF Group tools** (https://portal.hdfgroup.org/display/support/Downloads) + Various tools are available from the HDF + Group. These are usually shipped with the HDF5 kits but are also available for download separately. + The HDF5 source code (https://github.com/HDFGroup/hdf5) + is available on GitHub. .. index:: HDFexplorer; tools diff --git a/nxdl.xsd b/nxdl.xsd index 2d0b9fa92..a2ef83e80 100755 --- a/nxdl.xsd +++ b/nxdl.xsd @@ -989,6 +989,14 @@ + + + + A synonym for optional, but with the recommendation that this + attribute be specified. + + + @@ -1282,7 +1290,7 @@ - + Number or symbol indicating which axis (subscript) is @@ -1292,9 +1300,6 @@ ``A[i,j,k]``, ``index="1"`` would refer to the ``i`` axis (subscript). - (``NXdata`` uses ``index="0"`` - to indicate a situation when the specific index is not - known *a priori*.) diff --git a/requirements.txt b/requirements.txt index 815406521..6d024bda3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ pyyaml # Documentation building sphinx>=5 +sphinx-tabs # Testing pytest @@ -11,4 +12,4 @@ pytest # Code style and auto-formatting black>=22.3 flake8>=4 -isort>=5.10 \ No newline at end of file +isort>=5.10