From b1ad2e68c4afc82d941e0c8761bbb3e9af0eb9a5 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Sun, 30 Jun 2024 14:50:28 +0200 Subject: [PATCH 01/20] sometimes referred to as -> also referred to as --- base_classes/NXdata.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 67b54a7b0e..efc7390b26 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -50,8 +50,8 @@ The :ref:`NXdata` class is designed to encapsulate all the information required for a set of data to be plotted. - NXdata groups contain plottable data (sometimes referred to as *signals* or *dependent variables*) and their - associated axis coordinates (sometimes referred to as *axes* or *independent variables*). + NXdata groups contain plottable data (also referred to as *signals* or *dependent variables*) and their + associated axis coordinates (also referred to as *axes* or *independent variables*). The actual names of the :ref:`DATA </NXdata/DATA-field>` and :ref:`AXISNAME </NXdata/AXISNAME-field>` fields can be chosen :ref:`freely <validItemName>`, as indicated by the upper case (this is a common convention in all NeXus classes). From 26315aa3088c1db7cd59cb211c9b8702f6275f10 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Sun, 30 Jun 2024 14:52:40 +0200 Subject: [PATCH 02/20] NXdata@axes rectification: contains the default axes, not all axes --- base_classes/NXdata.nxdl.xml | 198 +++++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 76 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index efc7390b26..78135e7235 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -85,124 +85,170 @@ .. index:: axes (attribute) .. index:: coordinates - The :ref:`AXISNAME </NXdata/AXISNAME-field>` fields contain the axis coordinates associated with the data values. - The names of all :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are listed in the - :ref:`axes </NXdata@axes-attribute>` attribute. + The :ref:`AXISNAME </NXdata/AXISNAME-field>` fields contain the axis coordinates associated with the signal values. - `Rank` + `Default axes` - :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays, which annotate one of the dimensions. + The :ref:`axes </NXdata@axes-attribute>` attribute provides the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` + fields to be used as the default axis for each dimension of the :ref:`data </NXdata/DATA-field>` fields. + As a result the length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`data </NXdata/DATA-field>` + fields. When a particular dimension has no default axis, the string “.” is used in that position. - An example of this would be + `Spanned dimensions` + + The :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes describe the + :ref:`data </NXdata/DATA-field>` dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. + + When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, + the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field name in the :ref:`axes </NXdata@axes-attribute>` attribute + is(are) used. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape of the + :ref:`data </NXdata/DATA-field>` dimensions it spans. + + Note that an :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span + more than one :ref:`data </NXdata/DATA-field>` dimension. Conversely, one :ref:`data </NXdata/DATA-field>` dimension + can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. As stated before, the default + axis name (if any) can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. + + `Available axes` + + With the current definition of the :ref:`axes </NXdata@axes-attribute>` and :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes + it is not straightforward to discover all available axes. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute + (excluding the “.” string) are axis field names. In addition the prefix of an attribute ending with the string "_indices" is also + an axis field name. + + This indirect way of discovering axes exists so that data which does not have the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes + does not become invalid. Such data requires the length of the :ref:`axes </NXdata@axes-attribute>` attribute to be equal to the rank of the + :ref:`data </NXdata/DATA-field>` fields. + + **Axes examples:** + + `1. Single-dimensional axes` + + :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays that span a single :ref:`data </NXdata/DATA-field>` dimension. + + An example of this would be 2D data on a regular coordinate grid .. code-block:: data:NXdata @signal = "data" - @axes = ["x", "y"] --> the order matters + @axes = ["x", "y"] data: float[10,20] x: float[10] --> coordinates along the first dimension y: float[20] --> coordinates along the second dimension In this example each data point ``data[i,j]`` has axis coordinates ``[x[i], y[j]]``. - However, the fields can also have a rank greater than 1, in which case the rank of each - :ref:`AXISNAME </NXdata/AXISNAME-field>` must be equal to the number of data dimensions it spans. + Note that `@x_indices` and `@y_indices` attributes can be omitted in this case. However it is strongly encouraged to provide them. + + `2. Multi-dimensional axes` + + When coordinates do not form a regular grid, multi-dimensional :ref:`AXISNAME </NXdata/AXISNAME-field>` fields + can be used. Just remember that the shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape + of the :ref:`data </NXdata/DATA-field>` dimensions it spans. - An example of this would be + An example of this would be 2D scatter data where each data point has unique coordinates .. code-block:: data:NXdata @signal = "data" - @axes = ["x", "y"] --> the order does NOT matter + @axes = ["x", "y"] @x_indices = [0, 1] @y_indices = [0, 1] data: float[10,20] x: float[10,20] --> coordinates along both dimensions y: float[10,20] --> coordinates along both dimensions - In this example each data point ``data[i,j]`` has axis coordinates ``[x[i,j], y[i,j]]``. - - `Dimensions` - - The data dimensions annotated by an :ref:`AXISNAME </NXdata/AXISNAME-field>` field are defined by the - :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attribute. When this attribute is missing, - the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` string in the - :ref:`axes </NXdata@axes-attribute>` attribute are used. + In this example each data point ``data[i,j]`` has axis coordinates ``[x[i,j], y[i,j]]`` and when + plotting, `x` is used along the first data dimension by default and `y` along the second data dimension. + Since `x` and `y` span both dimensions, a reader could choose to use `y` for the first dimension + and `x` for the second as an alternative to the default. A writer could also choose to not specify + any default by specifying `@axes = [".", "."]` and leave the decision up the the reader. - When all :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are one-dimensional, and none of the data dimensions - have more than one axis, the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - are often omitted. If one of the data dimensions has no :ref:`AXISNAME </NXdata/AXISNAME-field>` field, - the string “.” can be used in the corresponding index of the axes list. + Note that omitting `@x_indices` would result in `@x_indices = [0]` as derived from the position of `"x"` in `@axes`. + This would be invalid since the shape `[10,20]` of `x` is not equal to the shape `[10]` of the spanned data dimensions. - An example of this would be + Omitting indices for multi-dimensional axes can only be done by repeating the :ref:`AXISNAME </NXdata/AXISNAME-field>` + name in all positions of the :ref:`axes </NXdata@axes-attribute>` attribute which they span. .. code-block:: data:NXdata @signal = "data" - @axes = ["x", ".", "z"] --> the order matters - data: float[10,20,30] - x: float[10] --> coordinates along the first dimension - z: float[30] --> coordinates along the third dimension + @axes = ["x", "x"] + data: float[10,20] + x: float[10,20] --> coordinates along both dimensions + + Note that since ``NXdata`` does not describe how the data is to be plotted or even the dimensionality of the plot, + a reader would probably treat this particular example as a 1D signal and plot it as such. + + `3. Dimensions spanned by more than one axis` - When using :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` this becomes + In the case of multi-dimensional axes, single-dimensional axes are often introduced as default axes + to support readers that does not use the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes + or cannot handle multi-dimensional axes. + + The 2D scatter example can be enriched as follows .. code-block:: data:NXdata @signal = "data" - @axes = ["x", "z"] --> the order does NOT matter - data: float[10,20,30] - @x_indices = 0 - @z_indices = 2 - x: float[10] --> coordinates along the first dimension - z: float[30] --> coordinates along the third dimension - - When providing :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes it is recommended - to do it for all axes. - - `Non-trivial axes` + @axes = ["x_set", "y_set"] + @x_indices = [0, 1] + @y_indices = [0, 1] + @x_set_indices = 0 --> or [0] + @y_set_indices = 1 --> or [1] + data: float[10,20] + x: float[10,20] --> coordinates along both dimensions + y: float[10,20] --> coordinates along both dimensions + x_set: float[10] --> coordinates along the first dimension + y_set: float[20] --> coordinates along the second dimension - What follows are two examples where :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - cannot be omitted. + Technically `@x_set_indices` and `@y_set_indices` can be omitted. However it is strongly encouraged to provide them. - The first is an example where data dimensions have alternative axis coordinates. The NXdata group represents - a stack of images collected at different energies. The ``wavelength`` is an alternative axis of ``energy`` - for the last dimension (or vice versa). + Another common case is the need to specify alternative axes for the same dimension .. code-block:: data:NXdata @signal = "data" - @axes = ["x", "y", "energy", "wavelength"] --> the order does NOT matter - @x_indices = 0 - @y_indices = 1 - @energy_indices = 2 - @wavelength_indices = 2 - data: float[10,20,30] - x: float[10] --> coordinates along the first dimension - y: float[20] --> coordinates along the second dimension - energy: float[30] --> coordinates along the third dimension - wavelength: float[30] --> coordinates along the third dimension - - The second is an example with coordinates that span more than one dimension. The NXdata group represents data - from 2D mesh scans performed at multiple energies. Each data point ``data[i,j,k]`` has axis coordinates - ``[x[i,j,k], y[i,j,k], energy[k]]``. + @axes = ["eta", "q"] + data: float[10,20] + @eta_indices = [0] + @tth_indices = [1] + @q_indices = [1] + eta: float[10] --> coordinates along the first dimension + tth: float[20] --> coordinates along the second dimension (alternative) + q: float[20] --> coordinates along the second dimension (default) + + Note that to recognize `tth` as an axis, `@tth_indices` must be present. Readers that do + not use :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will + have no way to understand that `tth` is an axis and simple ignore it. + + `4. Axes without defaults` + + Expanding on the 2D scatter example, a stack of 2D scatter data where the stack dimension + does not have an axis can be described as follows .. code-block:: data:NXdata @signal = "data" - @axes = ["x", "y", "energy"] --> the order does NOT matter - @x_indices = [0, 1, 2] - @y_indices = [0, 1, 2] - @energy_indices = 2 - data: float[10,20,30] - x: float[10,20,30] --> coordinates along all dimensions - y: float[10,20,30] --> coordinates along all dimensions - energy: float[30] --> coordinates along the third dimension + @axes = [".", "x_set", "y_set"] + @x_indices = [1, 2] + @y_indices = [1, 2] + @x_set_indices = 1 + @y_set_indices = 2 + data: float[5,10,20] + x: float[10,20] --> coordinates along the last two dimensions + y: float[10,20] --> coordinates along the last two dimensions + x_set: float[10] --> coordinates along the second dimension + y_set: float[20] --> coordinates along the third dimension + + Note that the first dimension does not have a default axis but this doesn't necessarily mean + the first dimension is not spanned by any axis, although in this example that is the case. **Uncertainties:** @@ -319,8 +365,8 @@ The ``AXISNAME_indices`` attribute is a single integer or an array of integers that defines which :ref:`data </NXdata/DATA-field>` dimension(s) are spanned by the corresponding axis. The first dimension index is ``0`` (zero). - When the ``AXISNAME_indices`` attribute is missing for an :ref:`AXISNAME </NXdata/AXISNAME-field>` field, its value becomes the index - (or indices) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` name in the :ref:`axes </NXdata@axes-attribute>` attribute. + When the ``AXISNAME_indices`` attribute is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, its value becomes + the index (or indices) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` name in the :ref:`axes </NXdata@axes-attribute>` attribute. .. note:: When ``AXISNAME_indices`` contains multiple integers, it must be saved as an actual array of integers and not a comma separated string. @@ -331,7 +377,9 @@ .. index:: plotting The ``axes`` attribute is a list of strings which are the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` fields - that contain the values of the coordinates along the :ref:`data </NXdata/DATA-field>` dimensions. + to be used as the default axis along all :ref:`data </NXdata/DATA-field>` dimensions. As a result the length must + be equal to the rank of the :ref:`data </NXdata/DATA-field>` fields. The string "." can be used for + dimensions without default axes. .. note:: When ``axes`` contains multiple strings, it must be saved as an actual array of strings and not a single comma separated string. @@ -341,14 +389,12 @@ - Coordinate values along one or more :ref:`data </NXdata/DATA-field>` dimensions. The rank must be equal - to the number of dimensions it spans. - + Coordinate values along one or more :ref:`data </NXdata/DATA-field>` dimensions. The shape of an ``AXISNAME`` field + must be equal to the shape of the :ref:`data </NXdata/DATA-field>` dimensions it spans. + As the upper case ``AXISNAME`` indicates, the names of the ``AXISNAME`` fields can be chosen :ref:`freely <validItemName>`. - The :ref:`axes </NXdata@axes-attribute>` attribute can be used to find all datasets in the - ``NXdata`` that contain coordinate values. - Most AXISNAME fields will be sequences of numbers but if an axis is better represented using names, such as channel names, + Most ``AXISNAME`` fields will be sequences of numbers but if an axis is better represented using names, such as channel names, an array of NX_CHAR can be provided. Axis label From d19ff479ef0a4bac0b4705ca1ee51b2238f3a3cf Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 20:48:25 +0200 Subject: [PATCH 03/20] clarify what "equal shape" means --- base_classes/NXdata.nxdl.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 78135e7235..9af7db6f1b 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -102,7 +102,8 @@ When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field name in the :ref:`axes </NXdata@axes-attribute>` attribute is(are) used. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape of the - :ref:`data </NXdata/DATA-field>` dimensions it spans. + :ref:`data </NXdata/DATA-field>` dimensions it spans. This means that `AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]` + for each `i` in `[0, AXISNAME.ndim)`. Note that an :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span more than one :ref:`data </NXdata/DATA-field>` dimension. Conversely, one :ref:`data </NXdata/DATA-field>` dimension From 7844bda53f67f068200a71e4a7f92404e644c1f0 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 20:53:56 +0200 Subject: [PATCH 04/20] rephrase the fact that a list of axis names is not provided by NXdata directly --- base_classes/NXdata.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 9af7db6f1b..2ab47c6c52 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -112,8 +112,8 @@ `Available axes` - With the current definition of the :ref:`axes </NXdata@axes-attribute>` and :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - it is not straightforward to discover all available axes. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute + With this definition of the :ref:`axes </NXdata@axes-attribute>` and :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes + a list of all available axes is not provided directly. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute (excluding the “.” string) are axis field names. In addition the prefix of an attribute ending with the string "_indices" is also an axis field name. From d85f56c8dd788b9642cd87c118a21d810699143f Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 21:00:34 +0200 Subject: [PATCH 05/20] clarify that one dimension is covered by more than on axis --- base_classes/NXdata.nxdl.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 2ab47c6c52..b492dac9a9 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -207,6 +207,9 @@ x_set: float[10] --> coordinates along the first dimension y_set: float[20] --> coordinates along the second dimension + The first dimension is covered by three axes: `x`, `y` and `x_set`. The second dimension is also + covered by three axes: `x`, `y` and `y_set`. + Technically `@x_set_indices` and `@y_set_indices` can be omitted. However it is strongly encouraged to provide them. Another common case is the need to specify alternative axes for the same dimension From 61343dd3b645a15f2d5dda9a80d83046f5a992fe Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 21:04:35 +0200 Subject: [PATCH 06/20] capitals DATA in analogy to AXISNAME --- base_classes/NXdata.nxdl.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index b492dac9a9..2537c1d3e2 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -90,23 +90,23 @@ `Default axes` The :ref:`axes </NXdata@axes-attribute>` attribute provides the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` - fields to be used as the default axis for each dimension of the :ref:`data </NXdata/DATA-field>` fields. - As a result the length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`data </NXdata/DATA-field>` + fields to be used as the default axis for each dimension of the :ref:`DATA </NXdata/DATA-field>` fields. + As a result the length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` fields. When a particular dimension has no default axis, the string “.” is used in that position. `Spanned dimensions` The :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes describe the - :ref:`data </NXdata/DATA-field>` dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. + :ref:`DATA </NXdata/DATA-field>` dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field name in the :ref:`axes </NXdata@axes-attribute>` attribute is(are) used. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape of the - :ref:`data </NXdata/DATA-field>` dimensions it spans. This means that `AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]` + :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that `AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]` for each `i` in `[0, AXISNAME.ndim)`. Note that an :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span - more than one :ref:`data </NXdata/DATA-field>` dimension. Conversely, one :ref:`data </NXdata/DATA-field>` dimension + more than one :ref:`DATA </NXdata/DATA-field>` dimension. Conversely, one :ref:`DATA </NXdata/DATA-field>` dimension can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. As stated before, the default axis name (if any) can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. @@ -119,13 +119,13 @@ This indirect way of discovering axes exists so that data which does not have the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes does not become invalid. Such data requires the length of the :ref:`axes </NXdata@axes-attribute>` attribute to be equal to the rank of the - :ref:`data </NXdata/DATA-field>` fields. + :ref:`DATA </NXdata/DATA-field>` fields. **Axes examples:** `1. Single-dimensional axes` - :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays that span a single :ref:`data </NXdata/DATA-field>` dimension. + :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays that span a single :ref:`DATA </NXdata/DATA-field>` dimension. An example of this would be 2D data on a regular coordinate grid @@ -146,7 +146,7 @@ When coordinates do not form a regular grid, multi-dimensional :ref:`AXISNAME </NXdata/AXISNAME-field>` fields can be used. Just remember that the shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape - of the :ref:`data </NXdata/DATA-field>` dimensions it spans. + of the :ref:`DATA </NXdata/DATA-field>` dimensions it spans. An example of this would be 2D scatter data where each data point has unique coordinates @@ -366,7 +366,7 @@ --> - The ``AXISNAME_indices`` attribute is a single integer or an array of integers that defines which :ref:`data </NXdata/DATA-field>` + The ``AXISNAME_indices`` attribute is a single integer or an array of integers that defines which :ref:`DATA </NXdata/DATA-field>` dimension(s) are spanned by the corresponding axis. The first dimension index is ``0`` (zero). When the ``AXISNAME_indices`` attribute is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, its value becomes @@ -381,8 +381,8 @@ .. index:: plotting The ``axes`` attribute is a list of strings which are the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` fields - to be used as the default axis along all :ref:`data </NXdata/DATA-field>` dimensions. As a result the length must - be equal to the rank of the :ref:`data </NXdata/DATA-field>` fields. The string "." can be used for + to be used as the default axis along all :ref:`DATA </NXdata/DATA-field>` dimensions. As a result the length must + be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` fields. The string "." can be used for dimensions without default axes. .. note:: When ``axes`` contains multiple strings, it must be saved as an actual array @@ -393,8 +393,8 @@ - Coordinate values along one or more :ref:`data </NXdata/DATA-field>` dimensions. The shape of an ``AXISNAME`` field - must be equal to the shape of the :ref:`data </NXdata/DATA-field>` dimensions it spans. + Coordinate values along one or more :ref:`DATA </NXdata/DATA-field>` dimensions. The shape of an ``AXISNAME`` field + must be equal to the shape of the :ref:`DATA </NXdata/DATA-field>` dimensions it spans. As the upper case ``AXISNAME`` indicates, the names of the ``AXISNAME`` fields can be chosen :ref:`freely <validItemName>`. From 939fb7e4403a41c3fcff9918cd6a9fcba2e03c9d Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 21:23:57 +0200 Subject: [PATCH 07/20] switch order of examples for clarity --- base_classes/NXdata.nxdl.xml | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 2537c1d3e2..773937978f 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -142,7 +142,28 @@ Note that `@x_indices` and `@y_indices` attributes can be omitted in this case. However it is strongly encouraged to provide them. - `2. Multi-dimensional axes` + `2. Data dimensions spanned by more than one axis` + + A common case is the need to specify alternative axes for the same dimension + + .. code-block:: + + data:NXdata + @signal = "data" + @axes = ["eta", "q"] + data: float[10,20] + @eta_indices = [0] + @tth_indices = [1] + @q_indices = [1] + eta: float[10] --> coordinates along the first dimension + tth: float[20] --> coordinates along the second dimension (alternative) + q: float[20] --> coordinates along the second dimension (default) + + Note that to recognize `tth` as an axis, `@tth_indices` must be present. Readers that do + not use :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will + have no way to understand that `tth` is an axis and simple ignore it. + + `3. Multi-dimensional axes` When coordinates do not form a regular grid, multi-dimensional :ref:`AXISNAME </NXdata/AXISNAME-field>` fields can be used. Just remember that the shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape @@ -171,7 +192,7 @@ This would be invalid since the shape `[10,20]` of `x` is not equal to the shape `[10]` of the spanned data dimensions. Omitting indices for multi-dimensional axes can only be done by repeating the :ref:`AXISNAME </NXdata/AXISNAME-field>` - name in all positions of the :ref:`axes </NXdata@axes-attribute>` attribute which they span. + name in all positions of the :ref:`axes </NXdata@axes-attribute>` attribute which they span. For example .. code-block:: @@ -184,8 +205,6 @@ Note that since ``NXdata`` does not describe how the data is to be plotted or even the dimensionality of the plot, a reader would probably treat this particular example as a 1D signal and plot it as such. - `3. Dimensions spanned by more than one axis` - In the case of multi-dimensional axes, single-dimensional axes are often introduced as default axes to support readers that does not use the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes or cannot handle multi-dimensional axes. @@ -212,25 +231,6 @@ Technically `@x_set_indices` and `@y_set_indices` can be omitted. However it is strongly encouraged to provide them. - Another common case is the need to specify alternative axes for the same dimension - - .. code-block:: - - data:NXdata - @signal = "data" - @axes = ["eta", "q"] - data: float[10,20] - @eta_indices = [0] - @tth_indices = [1] - @q_indices = [1] - eta: float[10] --> coordinates along the first dimension - tth: float[20] --> coordinates along the second dimension (alternative) - q: float[20] --> coordinates along the second dimension (default) - - Note that to recognize `tth` as an axis, `@tth_indices` must be present. Readers that do - not use :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will - have no way to understand that `tth` is an axis and simple ignore it. - `4. Axes without defaults` Expanding on the 2D scatter example, a stack of 2D scatter data where the stack dimension From ecd53dc91e259f09e69c3bb7cf05aa801c6b3dff Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 1 Jul 2024 21:45:00 +0200 Subject: [PATCH 08/20] use "spanned" instead of "covered" --- base_classes/NXdata.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 773937978f..216079340a 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -226,8 +226,8 @@ x_set: float[10] --> coordinates along the first dimension y_set: float[20] --> coordinates along the second dimension - The first dimension is covered by three axes: `x`, `y` and `x_set`. The second dimension is also - covered by three axes: `x`, `y` and `y_set`. + The first dimension is spanned by three axes: `x`, `y` and `x_set`. The second dimension is also + spanned by three axes: `x`, `y` and `y_set`. Technically `@x_set_indices` and `@y_set_indices` can be omitted. However it is strongly encouraged to provide them. From 69e53c959cc92638169047780bccb354147579ad Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 07:44:12 +0200 Subject: [PATCH 09/20] each dimension can only have one default axis --- base_classes/NXdata.nxdl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 216079340a..aec826389c 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -383,7 +383,7 @@ The ``axes`` attribute is a list of strings which are the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` fields to be used as the default axis along all :ref:`DATA </NXdata/DATA-field>` dimensions. As a result the length must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` fields. The string "." can be used for - dimensions without default axes. + dimensions without a default axis. .. note:: When ``axes`` contains multiple strings, it must be saved as an actual array of strings and not a single comma separated string. From 9a78a11c2b1b9a75dbd4a699f62fcc67740df63a Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 07:57:28 +0200 Subject: [PATCH 10/20] remove justification for the complex axes definition --- base_classes/NXdata.nxdl.xml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index aec826389c..e56a558aec 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -102,13 +102,13 @@ When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field name in the :ref:`axes </NXdata@axes-attribute>` attribute is(are) used. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape of the - :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that `AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]` - for each `i` in `[0, AXISNAME.ndim)`. + :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that ``AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]`` + for each ``i`` in ``[0, AXISNAME.ndim)``. Note that an :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span more than one :ref:`DATA </NXdata/DATA-field>` dimension. Conversely, one :ref:`DATA </NXdata/DATA-field>` dimension can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. As stated before, the default - axis name (if any) can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. + axis name (if any) of each dimension can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. `Available axes` @@ -117,10 +117,6 @@ (excluding the “.” string) are axis field names. In addition the prefix of an attribute ending with the string "_indices" is also an axis field name. - This indirect way of discovering axes exists so that data which does not have the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - does not become invalid. Such data requires the length of the :ref:`axes </NXdata@axes-attribute>` attribute to be equal to the rank of the - :ref:`DATA </NXdata/DATA-field>` fields. - **Axes examples:** `1. Single-dimensional axes` From 1c61a09dd247998656164af076f81ae1f76a93ca Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 08:02:30 +0200 Subject: [PATCH 11/20] reword --- base_classes/NXdata.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index e56a558aec..f613cfbba9 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -156,8 +156,8 @@ q: float[20] --> coordinates along the second dimension (default) Note that to recognize `tth` as an axis, `@tth_indices` must be present. Readers that do - not use :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will - have no way to understand that `tth` is an axis and simple ignore it. + not make used of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will + not understand that `tth` is an axis and cannot take this field into account. `3. Multi-dimensional axes` From 6a014b57520f4abaf6c160ea34ad441bd261c88d Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 08:04:25 +0200 Subject: [PATCH 12/20] reword --- base_classes/NXdata.nxdl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index f613cfbba9..1e2bb7d17c 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -182,7 +182,7 @@ plotting, `x` is used along the first data dimension by default and `y` along the second data dimension. Since `x` and `y` span both dimensions, a reader could choose to use `y` for the first dimension and `x` for the second as an alternative to the default. A writer could also choose to not specify - any default by specifying `@axes = [".", "."]` and leave the decision up the the reader. + any default by defining `@axes = [".", "."]` and leave the decision up the the reader. Note that omitting `@x_indices` would result in `@x_indices = [0]` as derived from the position of `"x"` in `@axes`. This would be invalid since the shape `[10,20]` of `x` is not equal to the shape `[10]` of the spanned data dimensions. From 115e631c53f934844f79301bc6bd4473f0192730 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 08:22:48 +0200 Subject: [PATCH 13/20] change quotes --- base_classes/NXdata.nxdl.xml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 1e2bb7d17c..c7f2c58535 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -119,7 +119,7 @@ **Axes examples:** - `1. Single-dimensional axes` + ``1. Single-dimensional axes`` :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays that span a single :ref:`DATA </NXdata/DATA-field>` dimension. @@ -136,9 +136,9 @@ In this example each data point ``data[i,j]`` has axis coordinates ``[x[i], y[j]]``. - Note that `@x_indices` and `@y_indices` attributes can be omitted in this case. However it is strongly encouraged to provide them. + Note that ``@x_indices`` and ``@y_indices`` attributes can be omitted in this case. However it is strongly encouraged to provide them. - `2. Data dimensions spanned by more than one axis` + ``2. Data dimensions spanned by more than one axis`` A common case is the need to specify alternative axes for the same dimension @@ -155,11 +155,11 @@ tth: float[20] --> coordinates along the second dimension (alternative) q: float[20] --> coordinates along the second dimension (default) - Note that to recognize `tth` as an axis, `@tth_indices` must be present. Readers that do - not make used of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will - not understand that `tth` is an axis and cannot take this field into account. + Note that to recognize ``tth`` as an axis, ``@tth_indices`` must be present. Readers that do + not make use of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will + not understand that ``tth`` is an axis and cannot take this field into account. - `3. Multi-dimensional axes` + ``3. Multi-dimensional axes`` When coordinates do not form a regular grid, multi-dimensional :ref:`AXISNAME </NXdata/AXISNAME-field>` fields can be used. Just remember that the shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape @@ -179,13 +179,13 @@ y: float[10,20] --> coordinates along both dimensions In this example each data point ``data[i,j]`` has axis coordinates ``[x[i,j], y[i,j]]`` and when - plotting, `x` is used along the first data dimension by default and `y` along the second data dimension. - Since `x` and `y` span both dimensions, a reader could choose to use `y` for the first dimension - and `x` for the second as an alternative to the default. A writer could also choose to not specify - any default by defining `@axes = [".", "."]` and leave the decision up the the reader. + plotting, ``x`` is used along the first data dimension by default and `y` along the second data dimension. + Since ``x`` and ``y`` span both dimensions, a reader could choose to use ``y`` for the first dimension + and ``x`` for the second as an alternative to the default. A writer could also choose to not specify + any default by defining ``@axes = [".", "."]`` and leave the decision up the the reader. - Note that omitting `@x_indices` would result in `@x_indices = [0]` as derived from the position of `"x"` in `@axes`. - This would be invalid since the shape `[10,20]` of `x` is not equal to the shape `[10]` of the spanned data dimensions. + Note that omitting ``@x_indices`` would result in ``@x_indices = [0]`` as derived from the position of the string ``"x"`` in ``@axes``. + This would be invalid since the shape ``[10,20]`` of ``x`` is not equal to the shape ``[10]`` of the spanned data dimensions. Omitting indices for multi-dimensional axes can only be done by repeating the :ref:`AXISNAME </NXdata/AXISNAME-field>` name in all positions of the :ref:`axes </NXdata@axes-attribute>` attribute which they span. For example @@ -202,7 +202,7 @@ a reader would probably treat this particular example as a 1D signal and plot it as such. In the case of multi-dimensional axes, single-dimensional axes are often introduced as default axes - to support readers that does not use the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes + to support readers that do not make use of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes or cannot handle multi-dimensional axes. The 2D scatter example can be enriched as follows @@ -222,12 +222,12 @@ x_set: float[10] --> coordinates along the first dimension y_set: float[20] --> coordinates along the second dimension - The first dimension is spanned by three axes: `x`, `y` and `x_set`. The second dimension is also - spanned by three axes: `x`, `y` and `y_set`. + The first dimension is spanned by three axes: ``x``, ``y`` and ``x_set``. The second dimension is also + spanned by three axes: ``x``, ``y`` and ``y_set``. - Technically `@x_set_indices` and `@y_set_indices` can be omitted. However it is strongly encouraged to provide them. + Technically ``@x_set_indices`` and ``@y_set_indices`` can be omitted. However it is strongly encouraged to provide them. - `4. Axes without defaults` + ``4. Axes without defaults`` Expanding on the 2D scatter example, a stack of 2D scatter data where the stack dimension does not have an axis can be described as follows From c8e5d6c712caed6af4f152c5dd1f3c8bf18049cd Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 08:28:33 +0200 Subject: [PATCH 14/20] change quotes --- base_classes/NXdata.nxdl.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index c7f2c58535..d291f5a123 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -87,14 +87,14 @@ The :ref:`AXISNAME </NXdata/AXISNAME-field>` fields contain the axis coordinates associated with the signal values. - `Default axes` + ``Default axes`` The :ref:`axes </NXdata@axes-attribute>` attribute provides the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` fields to be used as the default axis for each dimension of the :ref:`DATA </NXdata/DATA-field>` fields. As a result the length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` fields. When a particular dimension has no default axis, the string “.” is used in that position. - `Spanned dimensions` + ``Spanned dimensions`` The :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes describe the :ref:`DATA </NXdata/DATA-field>` dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. @@ -110,7 +110,7 @@ can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. As stated before, the default axis name (if any) of each dimension can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. - `Available axes` + ``Available axes`` With this definition of the :ref:`axes </NXdata@axes-attribute>` and :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes a list of all available axes is not provided directly. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute From 27cfde301a1f09ebe5facb05357e6675d728100a Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Wed, 17 Jul 2024 08:50:45 +0200 Subject: [PATCH 15/20] reword --- base_classes/NXdata.nxdl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index d291f5a123..3bf71b03dd 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -229,7 +229,7 @@ ``4. Axes without defaults`` - Expanding on the 2D scatter example, a stack of 2D scatter data where the stack dimension + Expanding on the previous example, a stack of 2D scatter data where the stack dimension does not have an axis can be described as follows .. code-block:: From 37306ef5549ba9f10d5458d8b26fb19405de01a4 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Thu, 15 Aug 2024 08:23:07 +0200 Subject: [PATCH 16/20] express length(axes) == rank(data) in NXDL --- base_classes/NXdata.nxdl.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 3bf71b03dd..147d88812e 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -375,15 +375,18 @@ .. index:: plotting - + The ``axes`` attribute is a list of strings which are the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` fields - to be used as the default axis along all :ref:`DATA </NXdata/DATA-field>` dimensions. As a result the length must + to be used as the default axis along every :ref:`DATA </NXdata/DATA-field>` dimension. As a result the length must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` fields. The string "." can be used for dimensions without a default axis. .. note:: When ``axes`` contains multiple strings, it must be saved as an actual array of strings and not a single comma separated string. + + + From e37a676c8de7755625d8305dcbdb446f17945d2a Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Thu, 15 Aug 2024 11:45:43 +0200 Subject: [PATCH 17/20] NIAC suggestions: start with simple example at the top, histogram axis +1, indices can be omitted, indices cannot contradict @axes --- base_classes/NXdata.nxdl.xml | 313 ++- base_classes/data/example2D_hist.excalidraw | 2086 +++++++++++++++++++ base_classes/data/example2D_hist.png | Bin 0 -> 114752 bytes 3 files changed, 2226 insertions(+), 173 deletions(-) create mode 100644 base_classes/data/example2D_hist.excalidraw create mode 100644 base_classes/data/example2D_hist.png diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 147d88812e..a0a9e945af 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -60,222 +60,181 @@ does not describe how the data is to be plotted or even the dimensionality of the plot. https://www.nexusformat.org/NIAC2018Minutes.html#nxdata-plottype--attribute - **Signals:** - - .. index:: plotting - - The :ref:`DATA </NXdata/DATA-field>` fields contain the signal values to be plotted. The name of the field - to be used as the *default plot signal* is provided by the :ref:`signal </NXdata@signal-attribute>` attribute. - The names of the fields to be used as *secondary plot signals* are provided by the - :ref:`auxiliary_signals</NXdata@auxiliary_signals-attribute>` attribute. - - An example with three signals, one of which being the default - - .. code-block:: - - data:NXdata - @signal = "data1" - @auxiliary_signals = ["data2", "data3"] - data1: float[10,20,30] --> the default signal - data2: float[10,20,30] - data3: float[10,20,30] - - **Axes:** - - .. index:: axes (attribute) - .. index:: coordinates + **Usage:** - The :ref:`AXISNAME </NXdata/AXISNAME-field>` fields contain the axis coordinates associated with the signal values. + .. admonition:: Plot data versus x axis - ``Default axes`` + .. code-block:: - The :ref:`axes </NXdata@axes-attribute>` attribute provides the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` - fields to be used as the default axis for each dimension of the :ref:`DATA </NXdata/DATA-field>` fields. - As a result the length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` - fields. When a particular dimension has no default axis, the string “.” is used in that position. + data:NXdata + @signal = "data" + @axes = ["x"] + data: float[100] + x: float[100] - ``Spanned dimensions`` + More complex cases are supported - The :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes describe the - :ref:`DATA </NXdata/DATA-field>` dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. + * histogram data: ``x`` has one more value than ``data``. + * alternative axes: instead of a single ``x`` axis you can have several axes, one of which being the default. + * signals with more than one dimension: ``data`` could be 2D with axes ``x`` and ``y`` along each dimension. + * axes with more than one dimension: ``data`` could be 2D with axes ``x`` and ``y`` also being 2D, providing a + unique ``[x, y]`` coordinate for each ``data`` point. - When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, - the position(s) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field name in the :ref:`axes </NXdata@axes-attribute>` attribute - is(are) used. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape of the - :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that ``AXISNAME.shape[i] == DATA.shape[AXISNAME_indices[i]]`` - for each ``i`` in ``[0, AXISNAME.ndim)``. + **Signals:** - Note that an :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span - more than one :ref:`DATA </NXdata/DATA-field>` dimension. Conversely, one :ref:`DATA </NXdata/DATA-field>` dimension - can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. As stated before, the default - axis name (if any) of each dimension can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. + .. index:: plotting - ``Available axes`` + .. admonition:: Defined by - With this definition of the :ref:`axes </NXdata@axes-attribute>` and :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - a list of all available axes is not provided directly. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute - (excluding the “.” string) are axis field names. In addition the prefix of an attribute ending with the string "_indices" is also - an axis field name. + * :ref:`DATA </NXdata/DATA-field>` fields + * the :ref:`signal </NXdata@signal-attribute>` attribute + * the :ref:`auxiliary_signals</NXdata@auxiliary_signals-attribute>` attribute - **Axes examples:** + The :ref:`DATA </NXdata/DATA-field>` fields contain the signal values to be plotted. The name of the field + to be used as the *default plot signal* is provided by the :ref:`signal </NXdata@signal-attribute>` attribute. + The names of the fields to be used as *secondary plot signals* are provided by the + :ref:`auxiliary_signals</NXdata@auxiliary_signals-attribute>` attribute. - ``1. Single-dimensional axes`` + .. admonition:: An example with three signals, one of which being the default - :ref:`AXISNAME </NXdata/AXISNAME-field>` fields are typically one-dimensional arrays that span a single :ref:`DATA </NXdata/DATA-field>` dimension. + .. code-block:: - An example of this would be 2D data on a regular coordinate grid + data:NXdata + @signal = "data1" + @auxiliary_signals = ["data2", "data3"] + data1: float[10,20,30] --> the default signal + data2: float[10,20,30] + data3: float[10,20,30] - .. code-block:: + **Axes:** - data:NXdata - @signal = "data" - @axes = ["x", "y"] - data: float[10,20] - x: float[10] --> coordinates along the first dimension - y: float[20] --> coordinates along the second dimension + .. index:: axes (attribute) + .. index:: coordinates - In this example each data point ``data[i,j]`` has axis coordinates ``[x[i], y[j]]``. + .. admonition:: Defined by - Note that ``@x_indices`` and ``@y_indices`` attributes can be omitted in this case. However it is strongly encouraged to provide them. + * :ref:`AXISNAME </NXdata/AXISNAME-field>` fields + * the :ref:`axes </NXdata@axes-attribute>` attribute + * :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - ``2. Data dimensions spanned by more than one axis`` + The fields and attributes are defined as follows - A common case is the need to specify alternative axes for the same dimension + 1. The :ref:`AXISNAME </NXdata/AXISNAME-field>` fields contain the axis coordinates associated with the signal values. - .. code-block:: + 2. The :ref:`axes </NXdata@axes-attribute>` attribute provides the names of the :ref:`AXISNAME </NXdata/AXISNAME-field>` + fields to be used as the `default axis` for each dimension of the :ref:`DATA </NXdata/DATA-field>` fields. - data:NXdata - @signal = "data" - @axes = ["eta", "q"] - data: float[10,20] - @eta_indices = [0] - @tth_indices = [1] - @q_indices = [1] - eta: float[10] --> coordinates along the first dimension - tth: float[20] --> coordinates along the second dimension (alternative) - q: float[20] --> coordinates along the second dimension (default) + 3. The :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes describe the :ref:`DATA </NXdata/DATA-field>` + dimensions spanned by the corresponding :ref:`AXISNAME </NXdata/AXISNAME-field>` fields. - Note that to recognize ``tth`` as an axis, ``@tth_indices`` must be present. Readers that do - not make use of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes will - not understand that ``tth`` is an axis and cannot take this field into account. + Additional requirements for a complete definition - ``3. Multi-dimensional axes`` + 1. The length of the :ref:`axes </NXdata@axes-attribute>` attribute must be equal to the rank of the :ref:`DATA </NXdata/DATA-field>` + fields. When a particular dimension has no default axis, the string “.” is used in that position. - When coordinates do not form a regular grid, multi-dimensional :ref:`AXISNAME </NXdata/AXISNAME-field>` fields - can be used. Just remember that the shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must be equal to the shape - of the :ref:`DATA </NXdata/DATA-field>` dimensions it spans. + 2. The number of values in :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` must be equal to the rank of the corresponding + :ref:`AXISNAME </NXdata/AXISNAME-field>` field. - An example of this would be 2D scatter data where each data point has unique coordinates + 3. When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is missing for a given + :ref:`AXISNAME </NXdata/AXISNAME-field>` field, the positions of the :ref:`AXISNAME </NXdata/AXISNAME-field>` + field name in the :ref:`axes </NXdata@axes-attribute>` attribute are used. - .. code-block:: + 4. When :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` is the same as the indices of "AXISNAME" in the + :ref:`axes </NXdata@axes-attribute>` attribute, there is no need to provide + :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>`. - data:NXdata - @signal = "data" - @axes = ["x", "y"] - @x_indices = [0, 1] - @y_indices = [0, 1] - data: float[10,20] - x: float[10,20] --> coordinates along both dimensions - y: float[10,20] --> coordinates along both dimensions + 5. The indices of "AXISNAME" in the :ref:`axes </NXdata@axes-attribute>` attribute must be a subset of + :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>`. - In this example each data point ``data[i,j]`` has axis coordinates ``[x[i,j], y[i,j]]`` and when - plotting, ``x`` is used along the first data dimension by default and `y` along the second data dimension. - Since ``x`` and ``y`` span both dimensions, a reader could choose to use ``y`` for the first dimension - and ``x`` for the second as an alternative to the default. A writer could also choose to not specify - any default by defining ``@axes = [".", "."]`` and leave the decision up the the reader. + 6. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must correspond to the shape of the + :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that for each dimension ``i`` in ``[0, AXISNAME.ndim)`` + spanned by an :ref:`AXISNAME </NXdata/AXISNAME-field>` field the number of data points along this dimension + ``DATA.shape[AXISNAME_indices[i]]`` must be equal to the number of axis values along this dimension ``AXISNAME.shape[i]`` + or the number of bin edges ``AXISNAME.shape[i]+1`` in case of histogram data. - Note that omitting ``@x_indices`` would result in ``@x_indices = [0]`` as derived from the position of the string ``"x"`` in ``@axes``. - This would be invalid since the shape ``[10,20]`` of ``x`` is not equal to the shape ``[10]`` of the spanned data dimensions. + Highlight concequences that follow the definition - Omitting indices for multi-dimensional axes can only be done by repeating the :ref:`AXISNAME </NXdata/AXISNAME-field>` - name in all positions of the :ref:`axes </NXdata@axes-attribute>` attribute which they span. For example + 1. An :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span + more than one :ref:`DATA </NXdata/DATA-field>` dimension. Conversely, one :ref:`DATA </NXdata/DATA-field>` dimension + can be spanned by more than one :ref:`AXISNAME </NXdata/AXISNAME-field>` field. The default axis name (if any) + of each dimension can be found in the :ref:`axes </NXdata@axes-attribute>` attribute. - .. code-block:: + 2. A list of all available axes is not provided directly. All strings in the :ref:`axes </NXdata@axes-attribute>` attribute + (excluding the “.” string) are axis field names. In addition the prefix of an attribute ending with the string "_indices" is also + an axis field name. - data:NXdata - @signal = "data" - @axes = ["x", "x"] - data: float[10,20] - x: float[10,20] --> coordinates along both dimensions + .. admonition:: The following example covers all axes features supported - Note that since ``NXdata`` does not describe how the data is to be plotted or even the dimensionality of the plot, - a reader would probably treat this particular example as a 1D signal and plot it as such. + .. code-block:: - In the case of multi-dimensional axes, single-dimensional axes are often introduced as default axes - to support readers that do not make use of the :ref:`AXISNAME_indices </NXdata@AXISNAME_indices-attribute>` attributes - or cannot handle multi-dimensional axes. + data:NXdata + @signal = "data" + @axes = ["x_set", "y_set", "."] --> default axes for all three dimensions + @x_encoder_indices = [0, 1] + @y_encoder_indices = 1 --> or [1] + data: float[10,7,1024] + x_encoder: float[11,7] --> coordinates along the first and second dimensions + y_encoder: float[7] --> coordinates along the second dimension + x_set: float[10] --> coordinates along the first dimension + y_set: float[7] --> coordinates along the second dimension - The 2D scatter example can be enriched as follows + One scientific application that provided such data is 2D scanning X-Ray Fluorescence (XRF) + where the sample is scanned through a focussed X-ray beam in two dimensions and an XRF spectrum + with 1024 channels is recorded at each position. In addition the x motor is scanned + continuously and both motors have an encoder which records the actual motor position as + opposed to the requested or `set` position. - .. code-block:: + .. image:: data/example2D_hist.png + :width: 100% - data:NXdata - @signal = "data" - @axes = ["x_set", "y_set"] - @x_indices = [0, 1] - @y_indices = [0, 1] - @x_set_indices = 0 --> or [0] - @y_set_indices = 1 --> or [1] - data: float[10,20] - x: float[10,20] --> coordinates along both dimensions - y: float[10,20] --> coordinates along both dimensions - x_set: float[10] --> coordinates along the first dimension - y_set: float[20] --> coordinates along the second dimension + 1. ``@axes`` has three values which corresponds to the ``data`` rank of three - The first dimension is spanned by three axes: ``x``, ``y`` and ``x_set``. The second dimension is also - spanned by three axes: ``x``, ``y`` and ``y_set``. + 2. ``x_set`` and ``y_set`` are the default axes for the first two dimensions while the third + dimension does not have a default axis or any axis for that matter. - Technically ``@x_set_indices`` and ``@y_set_indices`` can be omitted. However it is strongly encouraged to provide them. + 3. ``x_set_indices`` and ``y_set_indices`` are omitted because they would be equal to + the position of ``"x_set"`` and ``"y_set"`` in ``@axes``. - ``4. Axes without defaults`` + 4. The first dimension is spanned by two axes ``x_set`` and ``x_encoder``. Since + the x motor is scanned continuously, the encoder records the edge of every bin + on which an XRF spectrum is recorded yielding 11 values instead of 10 along the + first dimension. The ``x_encoder`` spans two dimensions because the actual x edges + are slightly different for every x motion at each y position. - Expanding on the previous example, a stack of 2D scatter data where the stack dimension - does not have an axis can be described as follows + 5. The second dimension is spanned by two axes ``y_set`` and ``y_encoder``. The axes + have as many values are there are data points along the second dimension. This is + because the y motor moves one step after each scan of the x motor. Since the y + motor does not move while scanning x, there is no need for ``y_encoder`` to span + the first dimension because the value along this dimension remains constant. - .. code-block:: + **Uncertainties:** - data:NXdata - @signal = "data" - @axes = [".", "x_set", "y_set"] - @x_indices = [1, 2] - @y_indices = [1, 2] - @x_set_indices = 1 - @y_set_indices = 2 - data: float[5,10,20] - x: float[10,20] --> coordinates along the last two dimensions - y: float[10,20] --> coordinates along the last two dimensions - x_set: float[10] --> coordinates along the second dimension - y_set: float[20] --> coordinates along the third dimension - - Note that the first dimension does not have a default axis but this doesn't necessarily mean - the first dimension is not spanned by any axis, although in this example that is the case. + .. admonition:: Defined by - **Uncertainties:** + * :ref:`FIELDNAME_errors </NXdata/FIELDNAME_errors-field>` fields Standard deviations on data values as well as coordinates can be provided by :ref:`FIELDNAME_errors </NXdata/FIELDNAME_errors-field>` fields where ``FIELDNAME`` is the name of a :ref:`DATA </NXdata/DATA-field>` field or an :ref:`AXISNAME </NXdata/AXISNAME-field>` field. - An example of uncertainties on the signal, auxiliary signals and axis coordinates - - .. code-block:: - - data:NXdata - @signal = "data1" - @auxiliary_signals = ["data2", "data3"] - @axes = ["x", "z"] - @x_indices = 0 - @z_indices = 2 - data1: float[10,20,30] - data2: float[10,20,30] - data3: float[10,20,30] - x: float[10] - z: float[30] - data1_errors: float[10,20,30] - data2_errors: float[10,20,30] - data3_errors: float[10,20,30] - x_errors: float[10] - z_errors: float[30] + .. admonition:: An example of uncertainties on the signal, auxiliary signals and axis coordinates + + .. code-block:: + + data:NXdata + @signal = "data1" + @auxiliary_signals = ["data2", "data3"] + @axes = ["x", ".", "z"] + data1: float[10,20,30] + data2: float[10,20,30] + data3: float[10,20,30] + x: float[10] + z: float[30] + data1_errors: float[10,20,30] + data2_errors: float[10,20,30] + data3_errors: float[10,20,30] + x_errors: float[10] + z_errors: float[30] @@ -363,7 +322,9 @@ The ``AXISNAME_indices`` attribute is a single integer or an array of integers that defines which :ref:`DATA </NXdata/DATA-field>` - dimension(s) are spanned by the corresponding axis. The first dimension index is ``0`` (zero). + dimensions are spanned by the corresponding axis. The first dimension index is ``0`` (zero). + + The number of indices must be equal to the rank of the :ref:`AXISNAME </NXdata/AXISNAME-field>` field. When the ``AXISNAME_indices`` attribute is missing for a given :ref:`AXISNAME </NXdata/AXISNAME-field>` field, its value becomes the index (or indices) of the :ref:`AXISNAME </NXdata/AXISNAME-field>` name in the :ref:`axes </NXdata@axes-attribute>` attribute. @@ -392,8 +353,12 @@ - Coordinate values along one or more :ref:`DATA </NXdata/DATA-field>` dimensions. The shape of an ``AXISNAME`` field - must be equal to the shape of the :ref:`DATA </NXdata/DATA-field>` dimensions it spans. + Coordinate values along one or more :ref:`DATA </NXdata/DATA-field>` dimensions. + + The shape of an ``AXISNAME`` field must correspond to the shape of the :ref:`DATA </NXdata/DATA-field>` + dimensions it spans. This means that for each ``i`` in ``[0, AXISNAME.ndim)`` the number of data points + ``DATA.shape[AXISNAME_indices[i]]`` must be equal to the number of coordinates ``AXISNAME.shape[i]`` or the + number of bin edges ``AXISNAME.shape[i]+1`` in case of histogram data. As the upper case ``AXISNAME`` indicates, the names of the ``AXISNAME`` fields can be chosen :ref:`freely <validItemName>`. @@ -429,7 +394,7 @@ .. index:: plotting - + Data values to be used as the NeXus *plottable data*. As the upper case ``DATA`` indicates, the names of the ``DATA`` fields can be chosen :ref:`freely <validItemName>`. The :ref:`signal attribute </NXdata@signal-attribute>` and :ref:`auxiliary_signals attribute</NXdata@auxiliary_signals-attribute>` can be used to find all datasets in the ``NXdata`` @@ -473,10 +438,12 @@ "Errors" (meaning *uncertainties* or *standard deviations*) associated with any field named ``FIELDNAME`` in this ``NXdata`` - group (e.g. an axis, signal or auxiliary signal). + group. This can be a :ref:`DATA </NXdata/DATA-field>` field + (signal or auxiliary signal) or a :ref:`AXISNAME </NXdata/AXISNAME-field>` + field (axis). The dimensions of the ``FIELDNAME_errors`` field must match - the dimensions of the ``FIELDNAME`` field. + the dimensions of the corresponding ``FIELDNAME`` field. diff --git a/base_classes/data/example2D_hist.excalidraw b/base_classes/data/example2D_hist.excalidraw new file mode 100644 index 0000000000..a2ab01a928 --- /dev/null +++ b/base_classes/data/example2D_hist.excalidraw @@ -0,0 +1,2086 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "text", + "version": 92, + "versionNonce": 2086153431, + "index": "av", + "isDeleted": false, + "id": "O4IOlsidXZtjGGLx7bkV5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 942, + "y": 121, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 144.98333740234375, + "height": 35, + "seed": 740456628, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1723712683105, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 5, + "text": "x_set (10)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "x_set (10)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "line", + "version": 191, + "versionNonce": 829234295, + "index": "b028", + "isDeleted": false, + "id": "0Peull3zXZeLrxe84K3Ra", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 671, + "y": 237.84596154393358, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 1758717068, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 232, + "versionNonce": 1020938873, + "index": "b02G", + "isDeleted": false, + "id": "lpIHrlma980BuMZ22Hxys", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 738.6964704909454, + "y": 238.27014754734356, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 1597659660, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 250, + "versionNonce": 1285584279, + "index": "b02V", + "isDeleted": false, + "id": "PUFCzOPsFTUt6_P7bE4-o", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 805.2806311922333, + "y": 237.66218893044274, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 1892698892, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 241, + "versionNonce": 603755353, + "index": "b02d", + "isDeleted": false, + "id": "EfAasH1uSrQhLqYCV_dJ1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 870.8811690564545, + "y": 237.91153860797692, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 444649740, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 284, + "versionNonce": 374057655, + "index": "b02l", + "isDeleted": false, + "id": "2Jg7xQEPafAB7j3CZ1DG0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 937.3420218591018, + "y": 238.09135773008992, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 877710644, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 302, + "versionNonce": 94552121, + "index": "b03", + "isDeleted": false, + "id": "S3x-U6c9M12L9hdo75RnK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1003.9839447540695, + "y": 237.7882788050355, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 547948212, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 293, + "versionNonce": 722680791, + "index": "b03G", + "isDeleted": false, + "id": "JdOPLCUGd6YqHw25CxxV9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1070.6258676490374, + "y": 236.5201690030599, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 415109172, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 301, + "versionNonce": 800084249, + "index": "b03V", + "isDeleted": false, + "id": "9sRft8pqldmfDKi6uLgoo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1137.9559844374378, + "y": 238.17061949598, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 525258164, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 319, + "versionNonce": 520857847, + "index": "b04", + "isDeleted": false, + "id": "hTMDH7z4306-HND5Uy428", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1204.5979073324056, + "y": 237.69558633969984, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 1829959476, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 347, + "versionNonce": 1738065401, + "index": "b04V", + "isDeleted": false, + "id": "Cnvi7-v-Og7O7mzfGRjk0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1269.477944775103, + "y": 237.11038040417975, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 2020545716, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 364, + "versionNonce": 263811607, + "index": "b05", + "isDeleted": false, + "id": "R2dfs7C7B9g8X_NkD2ROD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1336.1198676700708, + "y": 237.90971411641078, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 5, + "height": 360.6954803590299, + "seed": 1754422836, + "groupIds": [ + "P-S6GWdd2jcWPuY9sOgk8" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709852930, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 5, + 360.6954803590299 + ] + ] + }, + { + "type": "line", + "version": 815, + "versionNonce": 198155577, + "index": "b0F8", + "isDeleted": false, + "id": "qlf6NDVKWc-PfUXMB2bnY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 679.2532792040847, + "y": 231.58333333333337, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 226363788, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 859, + "versionNonce": 1983483417, + "index": "b0FG", + "isDeleted": false, + "id": "6sCsQLqs_tdU11glCJDsV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 679.8150779037358, + "y": 281.6874653857596, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 1661870604, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 877, + "versionNonce": 1676829433, + "index": "b0FV", + "isDeleted": false, + "id": "BdwAiwjE12b4f4qTwDSwe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 678.9503475441884, + "y": 333.48449152659305, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 133305228, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 920, + "versionNonce": 1367186393, + "index": "b0Fl", + "isDeleted": false, + "id": "D4FVyNFGYsUAIo9Uaw_-t", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 679.4407215494107, + "y": 386.5352084867595, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 2046804492, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 845, + "versionNonce": 1592703161, + "index": "b0G", + "isDeleted": false, + "id": "KMLRntLpvwGKTkDPtGJhe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 679.6740320062427, + "y": 439.93111694854036, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 1203294644, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 888, + "versionNonce": 1575565721, + "index": "b0GV", + "isDeleted": false, + "id": "COWd6ZBGiICka8aWYvGpJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 681.0868703301162, + "y": 493.0385660527098, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 27032372, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 855, + "versionNonce": 530620025, + "index": "b0H", + "isDeleted": false, + "id": "iihkKJF5A0Mq32M51LKkU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 680.6645339611346, + "y": 546.1613624409579, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 1650608308, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "line", + "version": 898, + "versionNonce": 47736665, + "index": "b0I", + "isDeleted": false, + "id": "3-R7bwGv6ecggMjz00nf0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 679.6981549367256, + "y": 598.7928285018907, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 652.5419601267315, + "height": 0, + "seed": 369037876, + "groupIds": [ + "HySgwqNRDOZS_38GUeoPR" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723709875833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 652.5419601267315, + 0 + ] + ] + }, + { + "type": "text", + "version": 185, + "versionNonce": 394926233, + "index": "b0d", + "isDeleted": false, + "id": "3nLFPdUk_WeZLC6vIVWF9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 453.6666666666665, + "y": 393.16666666666674, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 129.73333740234375, + "height": 35, + "seed": 700169612, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1723710311231, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 5, + "text": "y_set (7)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "y_set (7)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "line", + "version": 248, + "versionNonce": 602645849, + "index": "b0n8", + "isDeleted": false, + "id": "JnzsYu_ZslnjyScLARyqu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.023274319471, + "y": 266, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1483048244, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 238, + "versionNonce": 504281271, + "index": "b0nG", + "isDeleted": false, + "id": "wE-Z234j1AJh4cvGBPnuU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.3070583081071, + "y": 318.1035680246503, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 273333004, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 258, + "versionNonce": 434082361, + "index": "b0nV", + "isDeleted": false, + "id": "FdydPRu81qu86qN2zKoDG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.6202041172993, + "y": 369.41308094485197, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1681795764, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 260, + "versionNonce": 591694295, + "index": "b0nl", + "isDeleted": false, + "id": "1yZbdnRYZrurejiYu5b4T", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.247322592697, + "y": 421.3699934295827, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1706510516, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 219, + "versionNonce": 142795545, + "index": "b0o", + "isDeleted": false, + "id": "NqCk5MDaAmJEgYLWP9r3M", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.0881400594476, + "y": 473.46049268803154, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1915764236, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 242, + "versionNonce": 1608726263, + "index": "b0oG", + "isDeleted": false, + "id": "AsCE-HwSCbqnSMAmpaxkZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 616.186931647939, + "y": 524.9721183654877, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1350796, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 261, + "versionNonce": 1816729593, + "index": "b0oV", + "isDeleted": false, + "id": "_-ECJC0D8tmzti-pi3-Ee", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 615.9144580101793, + "y": 577.1707388064154, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 12.5, + "height": 0, + "seed": 1055468300, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 12.5, + 0 + ] + ] + }, + { + "type": "line", + "version": 231, + "versionNonce": 711933975, + "index": "b0ol", + "isDeleted": false, + "id": "NObpCvXI5ttnpfAvHDJ4I", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 631.25, + "y": 266.5, + "strokeColor": "#1971c2", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 312.5, + "seed": 399783692, + "groupIds": [ + "jWlJ_Q_kUH1mkn9At1ziz" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723712743933, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 312.5 + ] + ] + }, + { + "type": "arrow", + "version": 427, + "versionNonce": 1594264343, + "index": "b0q", + "isDeleted": false, + "id": "iLkOUg7TmkslaYgU9SdaW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 680.25, + "y": 365.4292272146313, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "width": 656.25, + "height": 0, + "seed": 1372353972, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723710349411, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 656.25, + 0 + ] + ], + "elbowed": false + }, + { + "type": "arrow", + "version": 578, + "versionNonce": 1850937399, + "index": "b0r", + "isDeleted": false, + "id": "fsE3yUyb3qu39XzmZCM6W", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 680.1636851166654, + "y": 312.7047592879178, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "width": 656.25, + "height": 0, + "seed": 1513965239, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723710349411, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 656.25, + 0 + ] + ], + "elbowed": false + }, + { + "type": "arrow", + "version": 549, + "versionNonce": 672264535, + "index": "b0s", + "isDeleted": false, + "id": "grxeuUUFSREmLSwqtGjYB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 680.3337634762097, + "y": 261.54311806311057, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "width": 656.25, + "height": 0, + "seed": 1107660567, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723710349411, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 656.25, + 0 + ] + ], + "elbowed": false + }, + { + "type": "text", + "version": 88, + "versionNonce": 1101544537, + "index": "b13", + "isDeleted": false, + "id": "enGL1MyA4g-tAkCJvk2CO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1368.75, + "y": 289, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "width": 245.81666564941406, + "height": 70, + "seed": 1578367961, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1723711239934, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 5, + "text": "continuous motion\nof x for each y", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "continuous motion\nof x for each y", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 302, + "versionNonce": 503827127, + "index": "b14", + "isDeleted": false, + "id": "OXiZBby7KE7-cWu_3uP2P", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 745.5, + "y": 631.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "width": 535, + "height": 35, + "seed": 536866169, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1723712090669, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 5, + "text": "XRF spectra recorded at (10, 7) points", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "XRF spectra recorded at (10, 7) points", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "line", + "version": 226, + "versionNonce": 584020119, + "index": "b15", + "isDeleted": false, + "id": "Jvvzf5AW1-AXaLkRpLU0r", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 707.75, + "y": 204, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 599.75, + "height": 0, + "seed": 328296076, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 599.75, + 0 + ] + ] + }, + { + "type": "line", + "version": 190, + "versionNonce": 1217316953, + "index": "b16", + "isDeleted": false, + "id": "1oquHYfUWM7jFEPRmPJCd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 707.4846985493728, + "y": 188.7146671758289, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 335175092, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 102, + "versionNonce": 1659061687, + "index": "b17", + "isDeleted": false, + "id": "Q3qiL31W6HDgEKYSUG44h", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 773.998812262217, + "y": 188.64039871145502, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 1348995380, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 158, + "versionNonce": 606491961, + "index": "b18", + "isDeleted": false, + "id": "fLh6-WEtUmLDbT4M3fmKK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 840.5761866634622, + "y": 188.76089835307093, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 896199820, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 137, + "versionNonce": 1476359895, + "index": "b19", + "isDeleted": false, + "id": "d2dHO2MXV3EZOASR9evEu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 907.3511757106554, + "y": 188.7219522011722, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 351632140, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 181, + "versionNonce": 1123632665, + "index": "b1A", + "isDeleted": false, + "id": "1nDRWGr4xXByQvmj4T75k", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 973.2610885627203, + "y": 188.61094508609264, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 202421132, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 160, + "versionNonce": 2025358327, + "index": "b1B", + "isDeleted": false, + "id": "uQCHrBIsIyOaHGD4_oPNZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1039.7842991070493, + "y": 188.73879469756733, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 1095393804, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 167, + "versionNonce": 1878727417, + "index": "b1C", + "isDeleted": false, + "id": "OAscfoYCZDCZw-bIYAeo8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1106.30466623029, + "y": 188.67396988396297, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 119825548, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 146, + "versionNonce": 1964174615, + "index": "b1D", + "isDeleted": false, + "id": "7IG0ZYhtA4tBldWiNqe1S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1172.4958883062177, + "y": 188.58912470689506, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 1623192332, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 225, + "versionNonce": 1269781465, + "index": "b1E", + "isDeleted": false, + "id": "Q_IPp2bqbuRgV_0b9k7cZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1305.247926274241, + "y": 188.81302467665165, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 1556442508, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + }, + { + "type": "line", + "version": 155, + "versionNonce": 142815799, + "index": "b1F", + "isDeleted": false, + "id": "tAImMCvx-5ghWxDuw2u48", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1238.6946591843853, + "y": 188.65582932287592, + "strokeColor": "#e03131", + "backgroundColor": "#b2f2bb", + "width": 0, + "height": 12, + "seed": 430513529, + "groupIds": [ + "0eZqsfw3BdSiWeVivw9dn" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1723716614076, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 12 + ] + ] + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/base_classes/data/example2D_hist.png b/base_classes/data/example2D_hist.png new file mode 100644 index 0000000000000000000000000000000000000000..8b35aeafb97b7941e22b2e0cefc536ab798d162e GIT binary patch literal 114752 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

  • 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 Date: Tue, 20 Aug 2024 13:48:24 +0200 Subject: [PATCH 18/20] review --- base_classes/NXdata.nxdl.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index a0a9e945af..f8fe253c3a 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -78,7 +78,7 @@ * alternative axes: instead of a single ``x`` axis you can have several axes, one of which being the default. * signals with more than one dimension: ``data`` could be 2D with axes ``x`` and ``y`` along each dimension. * axes with more than one dimension: ``data`` could be 2D with axes ``x`` and ``y`` also being 2D, providing a - unique ``[x, y]`` coordinate for each ``data`` point. + unique ``(x, y)`` coordinate for each ``data`` point. **Signals:** @@ -152,7 +152,7 @@ ``DATA.shape[AXISNAME_indices[i]]`` must be equal to the number of axis values along this dimension ``AXISNAME.shape[i]`` or the number of bin edges ``AXISNAME.shape[i]+1`` in case of histogram data. - Highlight concequences that follow the definition + Highlight consequences that follow the definition 1. An :ref:`AXISNAME </NXdata/AXISNAME-field>` field can have more than one dimension and can therefore span more than one :ref:`DATA </NXdata/DATA-field>` dimension. Conversely, one :ref:`DATA </NXdata/DATA-field>` dimension From 6b23f02516c48b614b484886219971fee3e3e92b Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Tue, 20 Aug 2024 13:49:24 +0200 Subject: [PATCH 19/20] #edges = #data_points + 1 --- base_classes/NXdata.nxdl.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index f8fe253c3a..3611a5e75a 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -148,9 +148,10 @@ 6. The shape of an :ref:`AXISNAME </NXdata/AXISNAME-field>` field must correspond to the shape of the :ref:`DATA </NXdata/DATA-field>` dimensions it spans. This means that for each dimension ``i`` in ``[0, AXISNAME.ndim)`` - spanned by an :ref:`AXISNAME </NXdata/AXISNAME-field>` field the number of data points along this dimension - ``DATA.shape[AXISNAME_indices[i]]`` must be equal to the number of axis values along this dimension ``AXISNAME.shape[i]`` - or the number of bin edges ``AXISNAME.shape[i]+1`` in case of histogram data. + spanned by axis field :ref:`AXISNAME </NXdata/AXISNAME-field>`, the number of axis values ``AXISNAME.shape[i]`` + along dimension ``i`` must be equal to the number of data points ``DATA.shape[AXISNAME_indices[i]]`` along dimension ``i`` + or one more than the number of data points ``DATA.shape[AXISNAME_indices[i]]+1`` in case the + :ref:`AXISNAME </NXdata/AXISNAME-field>` field contains histogram bin edges along dimension ``i``. Highlight consequences that follow the definition From c27e2d38b0662cc50fcacf25baab7f4dfb3b8400 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Sun, 29 Sep 2024 17:16:07 +0200 Subject: [PATCH 20/20] WIP --- base_classes/NXdata.nxdl.xml | 2 + dev_tools/apps/manual_app.py | 18 ++++++-- dev_tools/utils/copy.py | 12 +++++ galleries/nxdata/GALLERY_HEADER.rst | 1 + galleries/nxdata/plot_curve1.py | 38 +++++++++++++++ galleries/nxdata/plot_curve2.py | 66 +++++++++++++++++++++++++++ galleries/nxdata/plot_histogram_1d.py | 25 ++++++++++ galleries/nxdata/plot_image.py | 23 ++++++++++ manual/source/conf.py | 9 +++- requirements.txt | 3 ++ 10 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 galleries/nxdata/GALLERY_HEADER.rst create mode 100644 galleries/nxdata/plot_curve1.py create mode 100644 galleries/nxdata/plot_curve2.py create mode 100644 galleries/nxdata/plot_histogram_1d.py create mode 100644 galleries/nxdata/plot_image.py diff --git a/base_classes/NXdata.nxdl.xml b/base_classes/NXdata.nxdl.xml index 3611a5e75a..10faae6e44 100644 --- a/base_classes/NXdata.nxdl.xml +++ b/base_classes/NXdata.nxdl.xml @@ -60,6 +60,8 @@ does not describe how the data is to be plotted or even the dimensionality of the plot. https://www.nexusformat.org/NIAC2018Minutes.html#nxdata-plottype--attribute + .. include:: data/index.rst + **Usage:** .. admonition:: Plot data versus x axis diff --git a/dev_tools/apps/manual_app.py b/dev_tools/apps/manual_app.py index dfb2c1b824..f07adfde0f 100644 --- a/dev_tools/apps/manual_app.py +++ b/dev_tools/apps/manual_app.py @@ -6,6 +6,7 @@ from ..globals import directories from ..nxdl import iter_definitions from ..nxdl import validate_definition +from ..utils.copy import copy_directories from ..utils.copy import copy_files from ..utils.copy import copydir from ..utils.diff import diff_ascii @@ -22,7 +23,7 @@ def manual_args(parser): parser.add_argument( "--prepare", action="store_true", - help="Create the build files for the NeXus Impatient Guide", + help="Create the build files for the NeXus documentation", ) parser.add_argument( "--diff", @@ -107,14 +108,25 @@ def manual_exec(args): with open(index_file, "w") as fh: fh.writelines(rst_lines) - # Generate the anchor list in several format if args.prepare: + directories.manual_build_root() print("generate anchor list files in", output_path) anchor_registry.write() + + print("copy extra files", output_path) copy_files(EXTRA_FILES) + print("copy extra directories", output_path) + copy_directories(EXTRA_DIRECTORIES) + # Path relative to source directory, # Path relative to build directory, # Overwrite (boolean) -EXTRA_FILES = [["NXDL_VERSION", "NXDL_VERSION", True], ["LGPL.txt", "LGPL.txt", True]] +EXTRA_FILES = [ + ["NXDL_VERSION", "NXDL_VERSION", True], + ["LGPL.txt", "LGPL.txt", True], +] +EXTRA_DIRECTORIES = [ + ["galleries", "galleries", True], +] diff --git a/dev_tools/utils/copy.py b/dev_tools/utils/copy.py index 099dd8d759..9a29413c37 100644 --- a/dev_tools/utils/copy.py +++ b/dev_tools/utils/copy.py @@ -28,3 +28,15 @@ def copy_files(files: List[Tuple[str, str, bool]]) -> None: copyfile(from_path, to_path) else: print("already exists", to_path) + + +def copy_directories(dirs: List[Tuple[str, str, bool]]) -> None: + source_root = directories.get_source_root() + build_root = directories.get_build_root() + for from_subname, to_subname, overwrite in dirs: + to_path = build_root / to_subname + if overwrite or not to_path.exists(): + from_path = source_root / from_subname + copydir(from_path, to_path) + else: + print("already exists", to_path) diff --git a/galleries/nxdata/GALLERY_HEADER.rst b/galleries/nxdata/GALLERY_HEADER.rst new file mode 100644 index 0000000000..65bbd4031b --- /dev/null +++ b/galleries/nxdata/GALLERY_HEADER.rst @@ -0,0 +1 @@ +**Usage** \ No newline at end of file diff --git a/galleries/nxdata/plot_curve1.py b/galleries/nxdata/plot_curve1.py new file mode 100644 index 0000000000..b071c4646c --- /dev/null +++ b/galleries/nxdata/plot_curve1.py @@ -0,0 +1,38 @@ +""" +=============== +Curve (1D Grid) +=============== + +Curve (not necessarily evenly spaced) + +.. code:: + + @NX_class = "NXroot" + @default = "scan1" + scan1:NXentry + @NX_class = "NXentry" + @default = "data" + data:NXdata + @NX_class = "NXdata" + @auxiliary_signals = ["y2"] + @axes = ["x"] + @signal = "y1" + x:NX_INT64[10] + y1:NX_FLOAT64[10] + y2:NX_FLOAT64[10] +""" + +import numpy as np +import matplotlib.pyplot as plt + +plt.style.use("_mpl-gallery") + +fig, ax = plt.subplots() + +x = np.arange(10) ** 2 +y1 = 4 + np.sin(2 * x) +y2 = 2 + np.sin(3 * x) +ax.plot(x, y1, "o-", label="y1") +ax.plot(x, y2, "go-", label="y2") + +plt.show() diff --git a/galleries/nxdata/plot_curve2.py b/galleries/nxdata/plot_curve2.py new file mode 100644 index 0000000000..cb0afffda5 --- /dev/null +++ b/galleries/nxdata/plot_curve2.py @@ -0,0 +1,66 @@ +""" +=============== +Curve (1D Grid) +=============== + +Curve (not necessarily evenly spaced) + +.. code:: + + @NX_class = "NXroot" + @default = "scan1" + scan1:NXentry + @NX_class = "NXentry" + @default = "data" + data:NXdata + @NX_class = "NXdata" + @auxiliary_signals = ["y2"] + @axes = ["x"] + @signal = "y1" + x:NX_INT64[10] + y1:NX_FLOAT64[10] + y2:NX_FLOAT64[10] +""" + +# %% +# HDF5 example in Python. +import h5py +import numpy as np + +with h5py.File("curve.h5", "w") as root: + root.attrs["NX_class"] = "NXroot" + scan1 = root.create_group("scan1") + scan1.attrs["NX_class"] = "NXentry" + data = scan1.create_group("data") + data.attrs["NX_class"] = "NXdata" + + data.attrs["axes"] = ["x"] + data.attrs["signal"] = "y1" + data.attrs["auxiliary_signals"] = ["y2"] + x = np.arange(10) ** 2 + data["x"] = x + data["y1"] = 4 + np.sin(2 * x) + data["y2"] = 2 + np.sin(3 * x) + +# %% +# Plot example in Python. +import matplotlib.pyplot as plt + +plt.style.use("_mpl-gallery") + +fig, ax = plt.subplots() + +with h5py.File("curve.h5", "r") as root: + data = root["/scan1/data"] + + xname = data.attrs["axes"][0] + yname1 = data.attrs["signal"] + yname2 = data.attrs["auxiliary_signals"][0] + + x = data[xname][()] + y1 = data[yname1][()] + y2 = data[yname2][()] + ax.plot(x, y1, "o-", label=yname1) + ax.plot(x, y2, "go-", label=yname2) + +plt.show() diff --git a/galleries/nxdata/plot_histogram_1d.py b/galleries/nxdata/plot_histogram_1d.py new file mode 100644 index 0000000000..b555a5c945 --- /dev/null +++ b/galleries/nxdata/plot_histogram_1d.py @@ -0,0 +1,25 @@ +""" +============ +1D Histogram +============ + +1D Histogram (not necessarily evenly spaced) +""" + +import matplotlib.pyplot as plt +import numpy as np + +plt.style.use("_mpl-gallery") + +# make data: +x = 0.5 + np.arange(8) +y = [4.8, 5.5, 3.5, 4.6, 6.5, 6.6, 2.6, 3.0] + +# plot +fig, ax = plt.subplots() + +ax.bar(x, y, width=1, edgecolor="white", linewidth=0.7) + +ax.set(xlim=(0, 8), xticks=np.arange(1, 8), ylim=(0, 8), yticks=np.arange(1, 8)) + +plt.show() diff --git a/galleries/nxdata/plot_image.py b/galleries/nxdata/plot_image.py new file mode 100644 index 0000000000..df7dda3531 --- /dev/null +++ b/galleries/nxdata/plot_image.py @@ -0,0 +1,23 @@ +""" +=============== +Image (2D Grid) +=============== + +Image (not necessarily evenly spaced) +""" + +import matplotlib.pyplot as plt +import numpy as np + +plt.style.use("_mpl-gallery-nogrid") + +# make data +X, Y = np.meshgrid(np.linspace(-3, 3, 16), np.linspace(-3, 3, 16)) +Z = (1 - X / 2 + X**5 + Y**3) * np.exp(-(X**2) - Y**2) + +# plot +fig, ax = plt.subplots() + +ax.imshow(Z, origin="lower") + +plt.show() diff --git a/manual/source/conf.py b/manual/source/conf.py index 9b90263f10..8e871a2459 100644 --- a/manual/source/conf.py +++ b/manual/source/conf.py @@ -48,7 +48,8 @@ 'sphinx.ext.githubpages', 'sphinx.ext.todo', 'sphinx_tabs.tabs', - 'contrib_ext' + 'contrib_ext', + 'sphinx_gallery.gen_gallery' ] # Show `.. todo` directives in the output @@ -109,3 +110,9 @@ def setup(app): \DeclareUnicodeCharacter{2906}{<=} \listfiles''' } + +# -- Options the gallery ------------------------------------------------- +sphinx_gallery_conf = { + 'examples_dirs': '../../galleries/nxdata', # path with .py files + 'gallery_dirs': 'classes/base_classes/data', # path where to save gallery generated output +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index ba1f751d3f..9adedc9a84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,9 @@ nyaml sphinx>=5 sphinx-tabs sphinx-toolbox +sphinx-gallery +matplotlib +h5py # Testing pytest