diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 786a6ab3..10d6f52c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,4 +19,3 @@ repos:
     - id: ruff
       args: [--fix, --exit-non-zero-on-fix]
     - id: ruff-format
-
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d7338ad7..6fbbf1ba 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -4,4 +4,4 @@
     ],
     "python.testing.unittestEnabled": false,
     "python.testing.pytestEnabled": true,
-}
\ No newline at end of file
+}
diff --git a/docs/conf.py b/docs/conf.py
index 203bf5e3..3a8d8b81 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -4,6 +4,7 @@
 # https://www.sphinx-doc.org/en/master/usage/configuration.html
 import os
 import sys
+
 import versioningit
 
 sys.path.insert(0, os.path.abspath("../src"))
@@ -59,7 +60,9 @@
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 #
-html_theme = "alabaster"  # "sphinx_rtd_theme", please add corresponding package to environment.yml if you want to use it
+html_theme = (
+    "alabaster"  # "sphinx_rtd_theme", please add corresponding package to environment.yml if you want to use it
+)
 autosummary_generate = True
 
 # Napoleon settings
diff --git a/docs/ex_h5py_NXtas.py b/docs/ex_h5py_NXtas.py
index ba0d469f..a73d1a2e 100644
--- a/docs/ex_h5py_NXtas.py
+++ b/docs/ex_h5py_NXtas.py
@@ -1,241 +1,242 @@
- 
-import numpy as np
 import datetime
-import h5py
 import os
- 
-# Note this example script was generated by nxdl_to_hdf5.py using the current 
-# installed version of the NEXUS definitions ver[v2020.10] 
- 
-root = h5py.File('NXtas.h5', 'w')
-
-# Create the GROUPS 
- 
-root.create_group('entry')
-root['/entry'].attrs['NX_class'] = 'NXentry'
-root['/entry'].attrs['EX_required'] = 'true'
- 
-root['/entry/'].create_group('instrument')
-root['/entry/instrument'].attrs['NX_class'] = 'NXinstrument'
-root['/entry/instrument'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/'].create_group('source')
-root['/entry/instrument/source'].attrs['NX_class'] = 'NXsource'
-root['/entry/instrument/source'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/'].create_group('monochromator')
-root['/entry/instrument/monochromator'].attrs['NX_class'] = 'NXcrystal'
-root['/entry/instrument/monochromator'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/'].create_group('analyser')
-root['/entry/instrument/analyser'].attrs['NX_class'] = 'NXcrystal'
-root['/entry/instrument/analyser'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/'].create_group('detector')
-root['/entry/instrument/detector'].attrs['NX_class'] = 'NXdetector'
-root['/entry/instrument/detector'].attrs['EX_required'] = 'true'
- 
-root['/entry/'].create_group('sample')
-root['/entry/sample'].attrs['NX_class'] = 'NXsample'
-root['/entry/sample'].attrs['EX_required'] = 'true'
- 
-root['/entry/'].create_group('monitor')
-root['/entry/monitor'].attrs['NX_class'] = 'NXmonitor'
-root['/entry/monitor'].attrs['EX_required'] = 'true'
- 
-root['/entry/'].create_group('data')
-root['/entry/data'].attrs['NX_class'] = 'NXdata'
-root['/entry/data'].attrs['EX_required'] = 'true'
-
-# Create the FIELDS 
- 
-root['/entry'].create_dataset(name='title', data='SAMPLE-CHAR-DATA', maxshape=None)
-root['/entry/title'].attrs['type'] = 'NX_CHAR'
-root['/entry/title'].attrs['EX_required'] = 'true'
- 
-root['/entry'].create_dataset(name='start_time', data='2021-03-29T15:51:43.263179', maxshape=None)
-root['/entry/start_time'].attrs['type'] = 'NX_DATE_TIME'
-root['/entry/start_time'].attrs['EX_required'] = 'true'
- 
-# Valid enumeration values for root['/entry']['definition'] are: 
-#	 NXtas
- 
-root['/entry'].create_dataset(name='definition', data='NXtas', maxshape=None)
-root['/entry/definition'].attrs['type'] = 'NX_CHAR'
-root['/entry/definition'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/source'].create_dataset(name='name', data='SAMPLE-CHAR-DATA', maxshape=None)
-root['/entry/instrument/source/name'].attrs['type'] = 'NX_CHAR'
-root['/entry/instrument/source/name'].attrs['EX_required'] = 'true'
- 
-# Valid enumeration values for root['/entry/instrument/source']['probe'] are: 
-#	 neutron
-#	 x-ray
- 
-root['/entry/instrument/source'].create_dataset(name='probe', data='neutron', maxshape=None)
-root['/entry/instrument/source/probe'].attrs['type'] = 'NX_CHAR'
-root['/entry/instrument/source/probe'].attrs['EX_required'] = 'true'
- 
-root['/entry/instrument/monochromator'].create_dataset(name='ei', data=1.0, maxshape=None)
-root['/entry/instrument/monochromator/ei'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/monochromator/ei'].attrs['EX_required'] = 'true'
-root['/entry/instrument/monochromator/ei'].attrs['axis'] = '1'
-root['/entry/instrument/monochromator/ei'].attrs['units'] = 'NX_ENERGY'
- 
-root['/entry/instrument/monochromator'].create_dataset(name='rotation_angle', data=1.0, maxshape=None)
-root['/entry/instrument/monochromator/rotation_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/monochromator/rotation_angle'].attrs['EX_required'] = 'true'
-root['/entry/instrument/monochromator/rotation_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/instrument/analyser'].create_dataset(name='ef', data=1.0, maxshape=None)
-root['/entry/instrument/analyser/ef'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/analyser/ef'].attrs['EX_required'] = 'true'
-root['/entry/instrument/analyser/ef'].attrs['axis'] = '1'
-root['/entry/instrument/analyser/ef'].attrs['units'] = 'NX_ENERGY'
- 
-root['/entry/instrument/analyser'].create_dataset(name='rotation_angle', data=1.0, maxshape=None)
-root['/entry/instrument/analyser/rotation_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/analyser/rotation_angle'].attrs['EX_required'] = 'true'
-root['/entry/instrument/analyser/rotation_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/instrument/analyser'].create_dataset(name='polar_angle', data=1.0, maxshape=None)
-root['/entry/instrument/analyser/polar_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/analyser/polar_angle'].attrs['EX_required'] = 'true'
-root['/entry/instrument/analyser/polar_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/instrument/detector'].create_dataset(name='data', data=1, maxshape=None)
-root['/entry/instrument/detector/data'].attrs['type'] = 'NX_INT'
-root['/entry/instrument/detector/data'].attrs['EX_required'] = 'true'
-root['/entry/instrument/detector/data'].attrs['signal'] = '1'
- 
-root['/entry/instrument/detector'].create_dataset(name='polar_angle', data=1.0, maxshape=None)
-root['/entry/instrument/detector/polar_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/instrument/detector/polar_angle'].attrs['EX_required'] = 'true'
-root['/entry/instrument/detector/polar_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/sample'].create_dataset(name='name', data='SAMPLE-CHAR-DATA', maxshape=None)
-root['/entry/sample/name'].attrs['type'] = 'NX_CHAR'
-root['/entry/sample/name'].attrs['EX_required'] = 'true'
- 
-root['/entry/sample'].create_dataset(name='qh', data=1.0, maxshape=None)
-root['/entry/sample/qh'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/qh'].attrs['EX_required'] = 'true'
-root['/entry/sample/qh'].attrs['axis'] = '1'
-root['/entry/sample/qh'].attrs['units'] = 'NX_DIMENSIONLESS'
- 
-root['/entry/sample'].create_dataset(name='qk', data=1.0, maxshape=None)
-root['/entry/sample/qk'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/qk'].attrs['EX_required'] = 'true'
-root['/entry/sample/qk'].attrs['axis'] = '1'
-root['/entry/sample/qk'].attrs['units'] = 'NX_DIMENSIONLESS'
- 
-root['/entry/sample'].create_dataset(name='ql', data=1.0, maxshape=None)
-root['/entry/sample/ql'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/ql'].attrs['EX_required'] = 'true'
-root['/entry/sample/ql'].attrs['axis'] = '1'
-root['/entry/sample/ql'].attrs['units'] = 'NX_DIMENSIONLESS'
- 
-root['/entry/sample'].create_dataset(name='en', data=1.0, maxshape=None)
-root['/entry/sample/en'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/en'].attrs['EX_required'] = 'true'
-root['/entry/sample/en'].attrs['axis'] = '1'
-root['/entry/sample/en'].attrs['units'] = 'NX_ENERGY'
- 
-root['/entry/sample'].create_dataset(name='rotation_angle', data=1.0, maxshape=None)
-root['/entry/sample/rotation_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/rotation_angle'].attrs['EX_required'] = 'true'
-root['/entry/sample/rotation_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/sample'].create_dataset(name='polar_angle', data=1.0, maxshape=None)
-root['/entry/sample/polar_angle'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/polar_angle'].attrs['EX_required'] = 'true'
-root['/entry/sample/polar_angle'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/sample'].create_dataset(name='sgu', data=1.0, maxshape=None)
-root['/entry/sample/sgu'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/sgu'].attrs['EX_required'] = 'true'
-root['/entry/sample/sgu'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/sample'].create_dataset(name='sgl', data=1.0, maxshape=None)
-root['/entry/sample/sgl'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/sgl'].attrs['EX_required'] = 'true'
-root['/entry/sample/sgl'].attrs['units'] = 'NX_ANGLE'
- 
-root['/entry/sample'].create_dataset(name='unit_cell', data=1.0, maxshape=None)
-root['/entry/sample/unit_cell'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/unit_cell'].attrs['EX_required'] = 'true'
-root['/entry/sample/unit_cell'].attrs['units'] = 'NX_LENGTH'
- 
-root['/entry/sample'].create_dataset(name='orientation_matrix', data=1.0, maxshape=None)
-root['/entry/sample/orientation_matrix'].attrs['type'] = 'NX_FLOAT'
-root['/entry/sample/orientation_matrix'].attrs['EX_required'] = 'true'
-root['/entry/sample/orientation_matrix'].attrs['units'] = 'NX_DIMENSIONLESS'
- 
-# Valid enumeration values for root['/entry/monitor']['mode'] are: 
-#	 monitor
-#	 timer
- 
-root['/entry/monitor'].create_dataset(name='mode', data='monitor', maxshape=None)
-root['/entry/monitor/mode'].attrs['type'] = 'NX_CHAR'
-root['/entry/monitor/mode'].attrs['EX_required'] = 'true'
- 
-root['/entry/monitor'].create_dataset(name='preset', data=1.0, maxshape=None)
-root['/entry/monitor/preset'].attrs['type'] = 'NX_FLOAT'
-root['/entry/monitor/preset'].attrs['EX_required'] = 'true'
- 
-root['/entry/monitor'].create_dataset(name='data', data=1.0, maxshape=None)
-root['/entry/monitor/data'].attrs['type'] = 'NX_FLOAT'
-root['/entry/monitor/data'].attrs['EX_required'] = 'true'
-root['/entry/monitor/data'].attrs['units'] = 'NX_ANY'
-
-# Create the LINKS 
-root['/entry/data/ei'] = h5py.SoftLink('/entry/instrument/monochromator/ei')
-root['/entry/data/ei/'].attrs['target'] = '/entry/instrument/monochromator/ei'
-
-# Create the LINKS 
-root['/entry/data/ef'] = h5py.SoftLink('/entry/title')
-root['/entry/data/ef/'].attrs['target'] = '/entry/instrument/analyzer/ef'
-
-# Create the LINKS 
-root['/entry/data/en'] = h5py.SoftLink('/entry/sample/en')
-root['/entry/data/en/'].attrs['target'] = '/entry/sample/en'
-
-# Create the LINKS 
-root['/entry/data/qh'] = h5py.SoftLink('/entry/sample/qh')
-root['/entry/data/qh/'].attrs['target'] = '/entry/sample/qh'
-
-# Create the LINKS 
-root['/entry/data/qk'] = h5py.SoftLink('/entry/sample/qk')
-root['/entry/data/qk/'].attrs['target'] = '/entry/sample/qk'
-
-# Create the LINKS 
-root['/entry/data/ql'] = h5py.SoftLink('/entry/sample/ql')
-root['/entry/data/ql/'].attrs['target'] = '/entry/sample/ql'
-
-# Create the LINKS 
-root['/entry/data/data'] = h5py.SoftLink('/entry/instrument/detector/data')
-root['/entry/data/data/'].attrs['target'] = '/entry/instrument/detector/data'
-
-# Create the DOC strings 
-root['/entry/definition'].attrs['EX_doc'] = 'Official NeXus NXDL schema to which this file conforms '
-root['/entry/sample/name'].attrs['EX_doc'] = 'Descriptive name of sample '
-root['/entry/monitor/mode'].attrs['EX_doc'] = 'Count to a preset value based on either clock time (timer) or received monitor counts (monitor). '
-root['/entry/monitor/preset'].attrs['EX_doc'] = 'preset value for time or monitor '
-root['/entry/monitor/data'].attrs['EX_doc'] = 'Total integral monitor counts '
-root['/entry/data'].attrs['EX_doc'] = 'One of the ei,ef,qh,qk,ql,en should get a primary=1 attribute to denote the main scan axis '
- 
-
-# Create the ATTRIBUTES 
-root['/'].attrs['default'] = 'entry'
-root['/entry'].attrs['default'] = 'data'
-root['/entry/data'].attrs['signal'] = 'data'
-root['/entry/data/data'].attrs['signal'] = '1'
-root.attrs['file_name'] = os.path.abspath('NXtas')
-root.attrs['file_time'] = datetime.datetime.now().isoformat()
-root.attrs['h5py_version'] = h5py.version.version
-root.attrs['HDF5_Version'] = h5py.version.hdf5_version
 
-# Close the file
-root.close()
+import h5py
+
+# Note this example script was generated by nxdl_to_hdf5.py using the current
+# installed version of the NEXUS definitions ver[v2020.10]
+
+root = h5py.File("NXtas.h5", "w")
+
+# Create the GROUPS
+
+root.create_group("entry")
+root["/entry"].attrs["NX_class"] = "NXentry"
+root["/entry"].attrs["EX_required"] = "true"
+
+root["/entry/"].create_group("instrument")
+root["/entry/instrument"].attrs["NX_class"] = "NXinstrument"
+root["/entry/instrument"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/"].create_group("source")
+root["/entry/instrument/source"].attrs["NX_class"] = "NXsource"
+root["/entry/instrument/source"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/"].create_group("monochromator")
+root["/entry/instrument/monochromator"].attrs["NX_class"] = "NXcrystal"
+root["/entry/instrument/monochromator"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/"].create_group("analyser")
+root["/entry/instrument/analyser"].attrs["NX_class"] = "NXcrystal"
+root["/entry/instrument/analyser"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/"].create_group("detector")
+root["/entry/instrument/detector"].attrs["NX_class"] = "NXdetector"
+root["/entry/instrument/detector"].attrs["EX_required"] = "true"
+
+root["/entry/"].create_group("sample")
+root["/entry/sample"].attrs["NX_class"] = "NXsample"
+root["/entry/sample"].attrs["EX_required"] = "true"
+
+root["/entry/"].create_group("monitor")
+root["/entry/monitor"].attrs["NX_class"] = "NXmonitor"
+root["/entry/monitor"].attrs["EX_required"] = "true"
+
+root["/entry/"].create_group("data")
+root["/entry/data"].attrs["NX_class"] = "NXdata"
+root["/entry/data"].attrs["EX_required"] = "true"
+
+# Create the FIELDS
+
+root["/entry"].create_dataset(name="title", data="SAMPLE-CHAR-DATA", maxshape=None)
+root["/entry/title"].attrs["type"] = "NX_CHAR"
+root["/entry/title"].attrs["EX_required"] = "true"
+
+root["/entry"].create_dataset(name="start_time", data="2021-03-29T15:51:43.263179", maxshape=None)
+root["/entry/start_time"].attrs["type"] = "NX_DATE_TIME"
+root["/entry/start_time"].attrs["EX_required"] = "true"
+
+# Valid enumeration values for root['/entry']['definition'] are:
+# NXtas
+
+root["/entry"].create_dataset(name="definition", data="NXtas", maxshape=None)
+root["/entry/definition"].attrs["type"] = "NX_CHAR"
+root["/entry/definition"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/source"].create_dataset(name="name", data="SAMPLE-CHAR-DATA", maxshape=None)
+root["/entry/instrument/source/name"].attrs["type"] = "NX_CHAR"
+root["/entry/instrument/source/name"].attrs["EX_required"] = "true"
+
+# Valid enumeration values for root['/entry/instrument/source']['probe'] are:
+# neutron
+# x-ray
+
+root["/entry/instrument/source"].create_dataset(name="probe", data="neutron", maxshape=None)
+root["/entry/instrument/source/probe"].attrs["type"] = "NX_CHAR"
+root["/entry/instrument/source/probe"].attrs["EX_required"] = "true"
+
+root["/entry/instrument/monochromator"].create_dataset(name="ei", data=1.0, maxshape=None)
+root["/entry/instrument/monochromator/ei"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/monochromator/ei"].attrs["EX_required"] = "true"
+root["/entry/instrument/monochromator/ei"].attrs["axis"] = "1"
+root["/entry/instrument/monochromator/ei"].attrs["units"] = "NX_ENERGY"
+
+root["/entry/instrument/monochromator"].create_dataset(name="rotation_angle", data=1.0, maxshape=None)
+root["/entry/instrument/monochromator/rotation_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/monochromator/rotation_angle"].attrs["EX_required"] = "true"
+root["/entry/instrument/monochromator/rotation_angle"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/instrument/analyser"].create_dataset(name="ef", data=1.0, maxshape=None)
+root["/entry/instrument/analyser/ef"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/analyser/ef"].attrs["EX_required"] = "true"
+root["/entry/instrument/analyser/ef"].attrs["axis"] = "1"
+root["/entry/instrument/analyser/ef"].attrs["units"] = "NX_ENERGY"
+
+root["/entry/instrument/analyser"].create_dataset(name="rotation_angle", data=1.0, maxshape=None)
+root["/entry/instrument/analyser/rotation_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/analyser/rotation_angle"].attrs["EX_required"] = "true"
+root["/entry/instrument/analyser/rotation_angle"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/instrument/analyser"].create_dataset(name="polar_angle", data=1.0, maxshape=None)
+root["/entry/instrument/analyser/polar_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/analyser/polar_angle"].attrs["EX_required"] = "true"
+root["/entry/instrument/analyser/polar_angle"].attrs["units"] = "NX_ANGLE"
 
+root["/entry/instrument/detector"].create_dataset(name="data", data=1, maxshape=None)
+root["/entry/instrument/detector/data"].attrs["type"] = "NX_INT"
+root["/entry/instrument/detector/data"].attrs["EX_required"] = "true"
+root["/entry/instrument/detector/data"].attrs["signal"] = "1"
 
+root["/entry/instrument/detector"].create_dataset(name="polar_angle", data=1.0, maxshape=None)
+root["/entry/instrument/detector/polar_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/instrument/detector/polar_angle"].attrs["EX_required"] = "true"
+root["/entry/instrument/detector/polar_angle"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/sample"].create_dataset(name="name", data="SAMPLE-CHAR-DATA", maxshape=None)
+root["/entry/sample/name"].attrs["type"] = "NX_CHAR"
+root["/entry/sample/name"].attrs["EX_required"] = "true"
+
+root["/entry/sample"].create_dataset(name="qh", data=1.0, maxshape=None)
+root["/entry/sample/qh"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/qh"].attrs["EX_required"] = "true"
+root["/entry/sample/qh"].attrs["axis"] = "1"
+root["/entry/sample/qh"].attrs["units"] = "NX_DIMENSIONLESS"
+
+root["/entry/sample"].create_dataset(name="qk", data=1.0, maxshape=None)
+root["/entry/sample/qk"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/qk"].attrs["EX_required"] = "true"
+root["/entry/sample/qk"].attrs["axis"] = "1"
+root["/entry/sample/qk"].attrs["units"] = "NX_DIMENSIONLESS"
+
+root["/entry/sample"].create_dataset(name="ql", data=1.0, maxshape=None)
+root["/entry/sample/ql"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/ql"].attrs["EX_required"] = "true"
+root["/entry/sample/ql"].attrs["axis"] = "1"
+root["/entry/sample/ql"].attrs["units"] = "NX_DIMENSIONLESS"
+
+root["/entry/sample"].create_dataset(name="en", data=1.0, maxshape=None)
+root["/entry/sample/en"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/en"].attrs["EX_required"] = "true"
+root["/entry/sample/en"].attrs["axis"] = "1"
+root["/entry/sample/en"].attrs["units"] = "NX_ENERGY"
+
+root["/entry/sample"].create_dataset(name="rotation_angle", data=1.0, maxshape=None)
+root["/entry/sample/rotation_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/rotation_angle"].attrs["EX_required"] = "true"
+root["/entry/sample/rotation_angle"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/sample"].create_dataset(name="polar_angle", data=1.0, maxshape=None)
+root["/entry/sample/polar_angle"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/polar_angle"].attrs["EX_required"] = "true"
+root["/entry/sample/polar_angle"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/sample"].create_dataset(name="sgu", data=1.0, maxshape=None)
+root["/entry/sample/sgu"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/sgu"].attrs["EX_required"] = "true"
+root["/entry/sample/sgu"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/sample"].create_dataset(name="sgl", data=1.0, maxshape=None)
+root["/entry/sample/sgl"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/sgl"].attrs["EX_required"] = "true"
+root["/entry/sample/sgl"].attrs["units"] = "NX_ANGLE"
+
+root["/entry/sample"].create_dataset(name="unit_cell", data=1.0, maxshape=None)
+root["/entry/sample/unit_cell"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/unit_cell"].attrs["EX_required"] = "true"
+root["/entry/sample/unit_cell"].attrs["units"] = "NX_LENGTH"
+
+root["/entry/sample"].create_dataset(name="orientation_matrix", data=1.0, maxshape=None)
+root["/entry/sample/orientation_matrix"].attrs["type"] = "NX_FLOAT"
+root["/entry/sample/orientation_matrix"].attrs["EX_required"] = "true"
+root["/entry/sample/orientation_matrix"].attrs["units"] = "NX_DIMENSIONLESS"
+
+# Valid enumeration values for root['/entry/monitor']['mode'] are:
+# monitor
+# timer
+
+root["/entry/monitor"].create_dataset(name="mode", data="monitor", maxshape=None)
+root["/entry/monitor/mode"].attrs["type"] = "NX_CHAR"
+root["/entry/monitor/mode"].attrs["EX_required"] = "true"
+
+root["/entry/monitor"].create_dataset(name="preset", data=1.0, maxshape=None)
+root["/entry/monitor/preset"].attrs["type"] = "NX_FLOAT"
+root["/entry/monitor/preset"].attrs["EX_required"] = "true"
+
+root["/entry/monitor"].create_dataset(name="data", data=1.0, maxshape=None)
+root["/entry/monitor/data"].attrs["type"] = "NX_FLOAT"
+root["/entry/monitor/data"].attrs["EX_required"] = "true"
+root["/entry/monitor/data"].attrs["units"] = "NX_ANY"
+
+# Create the LINKS
+root["/entry/data/ei"] = h5py.SoftLink("/entry/instrument/monochromator/ei")
+root["/entry/data/ei/"].attrs["target"] = "/entry/instrument/monochromator/ei"
+
+# Create the LINKS
+root["/entry/data/ef"] = h5py.SoftLink("/entry/title")
+root["/entry/data/ef/"].attrs["target"] = "/entry/instrument/analyzer/ef"
+
+# Create the LINKS
+root["/entry/data/en"] = h5py.SoftLink("/entry/sample/en")
+root["/entry/data/en/"].attrs["target"] = "/entry/sample/en"
+
+# Create the LINKS
+root["/entry/data/qh"] = h5py.SoftLink("/entry/sample/qh")
+root["/entry/data/qh/"].attrs["target"] = "/entry/sample/qh"
+
+# Create the LINKS
+root["/entry/data/qk"] = h5py.SoftLink("/entry/sample/qk")
+root["/entry/data/qk/"].attrs["target"] = "/entry/sample/qk"
+
+# Create the LINKS
+root["/entry/data/ql"] = h5py.SoftLink("/entry/sample/ql")
+root["/entry/data/ql/"].attrs["target"] = "/entry/sample/ql"
+
+# Create the LINKS
+root["/entry/data/data"] = h5py.SoftLink("/entry/instrument/detector/data")
+root["/entry/data/data/"].attrs["target"] = "/entry/instrument/detector/data"
+
+# Create the DOC strings
+root["/entry/definition"].attrs["EX_doc"] = "Official NeXus NXDL schema to which this file conforms "
+root["/entry/sample/name"].attrs["EX_doc"] = "Descriptive name of sample "
+root["/entry/monitor/mode"].attrs["EX_doc"] = (
+    "Count to a preset value based on either clock time (timer) or received monitor counts (monitor). "
+)
+root["/entry/monitor/preset"].attrs["EX_doc"] = "preset value for time or monitor "
+root["/entry/monitor/data"].attrs["EX_doc"] = "Total integral monitor counts "
+root["/entry/data"].attrs["EX_doc"] = (
+    "One of the ei,ef,qh,qk,ql,en should get a primary=1 attribute to denote the main scan axis "
+)
+
+
+# Create the ATTRIBUTES
+root["/"].attrs["default"] = "entry"
+root["/entry"].attrs["default"] = "data"
+root["/entry/data"].attrs["signal"] = "data"
+root["/entry/data/data"].attrs["signal"] = "1"
+root.attrs["file_name"] = os.path.abspath("NXtas")
+root.attrs["file_time"] = datetime.datetime.now().isoformat()
+root.attrs["h5py_version"] = h5py.version.version
+root.attrs["HDF5_Version"] = h5py.version.hdf5_version
+
+# Close the file
+root.close()
diff --git a/src/tavi/configuration.py b/src/tavi/configuration.py
index 828cb5bb..e0de8627 100644
--- a/src/tavi/configuration.py
+++ b/src/tavi/configuration.py
@@ -4,9 +4,9 @@
 
 import os
 import shutil
-
 from configparser import ConfigParser
 from pathlib import Path
+
 from mantid.kernel import Logger
 
 logger = Logger("PACKAGENAME")
diff --git a/src/tavi/data/plotter.py b/src/tavi/data/plotter.py
index d19bcb2f..c7738d7a 100644
--- a/src/tavi/data/plotter.py
+++ b/src/tavi/data/plotter.py
@@ -5,7 +5,6 @@
 
 
 class Plot1D(object):
-
     def __init__(
         self,
         x: np.ndarray,
diff --git a/src/tavi/data/spice_reader.py b/src/tavi/data/spice_reader.py
index 5d079699..0f56bbe2 100644
--- a/src/tavi/data/spice_reader.py
+++ b/src/tavi/data/spice_reader.py
@@ -71,7 +71,7 @@ def read_spice_ubconf(ub_file_name: str) -> dict:
     Returns:
     """
     ubconf: dict[str, Any] = {}
-    with open(ub_file_name, 'r', encoding="utf-8") as f:
+    with open(ub_file_name, "r", encoding="utf-8") as f:
         all_content = f.readlines()
 
     for idx, line in enumerate(all_content):
@@ -129,8 +129,8 @@ def _create_spicelogs(path_to_scan_file: str) -> dict:
 
     scan_path = os.path.abspath(path_to_scan_file)
     (*folder_path, _, _) = scan_path.split("/")
-    ub_file_path = os.path.join('/',*folder_path,"UBConf", metadata["ubconf"])
-    ub_temp_file_path = os.path.join('/',*folder_path,"UBConf", "temp", metadata["ubconf"])
+    ub_file_path = os.path.join("/", *folder_path, "UBConf", metadata["ubconf"])
+    ub_temp_file_path = os.path.join("/", *folder_path, "UBConf", "temp", metadata["ubconf"])
 
     if os.path.isfile(ub_file_path):
         ub_conf_dict = {"file_path": ub_file_path}
diff --git a/src/tavi/data/ubconf.py b/src/tavi/data/ubconf.py
index b08d2cfc..945980c9 100644
--- a/src/tavi/data/ubconf.py
+++ b/src/tavi/data/ubconf.py
@@ -25,9 +25,7 @@ def convert_spice_ub_to_nexus(
     """Convert all UBConf files into one NeXus entry named UBConf.h5"""
 
     if verbose:
-        disp_str = (
-            f"Converting SPICE UBConf files at {path_to_spice_folder} to an NeXus entry at {path_to_hdf5_folder}"
-        )
+        disp_str = f"Converting SPICE UBConf files at {path_to_spice_folder} to an NeXus entry at {path_to_hdf5_folder}"
         print(disp_str)
 
     p = Path(path_to_spice_folder)
@@ -37,7 +35,6 @@ def convert_spice_ub_to_nexus(
     ub_conf_dicts = {ub_file.parts[-1].split(".")[0]: _read_spice_ub(ub_file) for ub_file in ub_files_all}
 
     with h5py.File(path_to_hdf5_folder + "UBConf.h5", "w") as root:
-
         for ub_name, ub_data in ub_conf_dicts.items():
             ub_entry = root.create_group(ub_name)
             ub_entry.attrs["NX_class"] = "NXcollection"
diff --git a/src/tavi/instrument/instrument_params/cg4c.json b/src/tavi/instrument/instrument_params/cg4c.json
index 644b5677..31119a53 100644
--- a/src/tavi/instrument/instrument_params/cg4c.json
+++ b/src/tavi/instrument/instrument_params/cg4c.json
@@ -70,4 +70,4 @@
         "v_post_sample": 600,
         "v_post_ana": 600
     }
-}
\ No newline at end of file
+}
diff --git a/src/tavi/instrument/instrument_params/hb1a.json b/src/tavi/instrument/instrument_params/hb1a.json
index eed0e724..06c7befa 100644
--- a/src/tavi/instrument/instrument_params/hb1a.json
+++ b/src/tavi/instrument/instrument_params/hb1a.json
@@ -69,4 +69,4 @@
         "v_post_sample": 600,
         "v_post_ana": 600
     }
-}
\ No newline at end of file
+}
diff --git a/src/tavi/instrument/instrument_params/hb3.json b/src/tavi/instrument/instrument_params/hb3.json
index 618c3e33..3943644c 100644
--- a/src/tavi/instrument/instrument_params/hb3.json
+++ b/src/tavi/instrument/instrument_params/hb3.json
@@ -73,4 +73,4 @@
         "v_post_sample": 300,
         "v_post_ana": 600
     }
-}
\ No newline at end of file
+}
diff --git a/src/tavi/instrument/instrument_params/hb3_mnte.json b/src/tavi/instrument/instrument_params/hb3_mnte.json
index f91f9639..cd42346d 100644
--- a/src/tavi/instrument/instrument_params/hb3_mnte.json
+++ b/src/tavi/instrument/instrument_params/hb3_mnte.json
@@ -73,4 +73,4 @@
         "v_post_sample": 120,
         "v_post_ana": 120
     }
-}
\ No newline at end of file
+}
diff --git a/src/tavi/instrument/instrument_params/takin_test.json b/src/tavi/instrument/instrument_params/takin_test.json
index ec33e9d9..f1f0995c 100644
--- a/src/tavi/instrument/instrument_params/takin_test.json
+++ b/src/tavi/instrument/instrument_params/takin_test.json
@@ -72,4 +72,4 @@
         "v_post_sample": 30,
         "v_post_ana": 30
     }
-}
\ No newline at end of file
+}
diff --git a/src/tavi/instrument/resolution/ellipse_curve.py b/src/tavi/instrument/resolution/ellipse_curve.py
index 77f538c0..6abd8657 100644
--- a/src/tavi/instrument/resolution/ellipse_curve.py
+++ b/src/tavi/instrument/resolution/ellipse_curve.py
@@ -143,7 +143,6 @@ def generate_plot(self, ax, c="black", linestyle="solid"):
         pts = self.generate_ellipse()
 
         if self.grid_helper is None:
-
             s = ax.plot(
                 pts[0],
                 pts[1],
diff --git a/src/tavi/instrument/resolution/ellipsoid.py b/src/tavi/instrument/resolution/ellipsoid.py
index 4cc78be8..d61fcf09 100755
--- a/src/tavi/instrument/resolution/ellipsoid.py
+++ b/src/tavi/instrument/resolution/ellipsoid.py
@@ -43,7 +43,6 @@ def __init__(
         sample: Xtal,
         projection: Optional[tuple] = ((1, 0, 0), (0, 1, 0), (0, 0, 1)),
     ) -> None:
-
         self.STATUS: Optional[bool] = None
         self.q: Optional[tuple[float, float, float]] = None
         self.hkl: tuple[float, float, float] = hkl
diff --git a/src/tavi/instrument/tas.py b/src/tavi/instrument/tas.py
index 62b506b1..44d08c6c 100644
--- a/src/tavi/instrument/tas.py
+++ b/src/tavi/instrument/tas.py
@@ -100,7 +100,7 @@ def calculate_ub_matrix(self, peaks: tuple[Peak, ...]):
         if not isinstance(self.sample, Xtal):
             raise ValueError("sample needs to be Xtal class for UB calculation.")
 
-        match (num_of_peaks := len(peaks)):
+        match num_of_peaks := len(peaks):
             case 2:
                 ubconf = self._find_u_from_two_peaks(peaks)
                 self.sample.set_orientation(ubconf)
diff --git a/tests/test_fit.py b/tests/test_fit.py
index 9feafe75..6d54fc62 100644
--- a/tests/test_fit.py
+++ b/tests/test_fit.py
@@ -7,7 +7,6 @@
 
 
 def test_fit_single_peak():
-
     nexus_file_name = "./test_data/IPTS32124_CG4C_exp0424/scan0042.h5"
     _, s1 = Scan.from_nexus_file(nexus_file_name)
 
@@ -26,7 +25,6 @@ def test_fit_single_peak():
 
 
 def test_fit_two_peak():
-
     nexus_file_name = "./test_data/IPTS32124_CG4C_exp0424/scan0042.h5"
     _, s1 = Scan.from_nexus_file(nexus_file_name)
 
diff --git a/tests/test_nxentry.py b/tests/test_nxentry.py
index 869ef9c2..fc115a25 100644
--- a/tests/test_nxentry.py
+++ b/tests/test_nxentry.py
@@ -142,7 +142,6 @@ def test_get_from_daslogs():
 
 
 def test_spice_to_nexus_one():
-
     path_to_spice_folder = "./test_data/exp424"
     path_to_nexus = "./test_data/spice_to_nxdict_test_scan0034.h5"
     scan0034 = NexusEntry.from_spice(path_to_spice_folder, 34)
@@ -168,7 +167,6 @@ def test_spice_to_nexus_all():
 
 @pytest.fixture
 def nexus_entries():
-
     analyser = {
         "attrs": {"EX_required": "true", "NX_class": "NXcrystal", "type": "NX_CHAR"},
         "a1": {