From 4c627441412ff02e296ce13413bd7696d50704e1 Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 16 May 2023 14:59:29 +0200
Subject: [PATCH 01/13] "This is a short test to make sure I can actually push
to remote before starting anything; updates 3446"
From fbf0d3a595caa6c683a23654dc6c8d66c3d3a5fb Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 16 May 2023 15:00:56 +0200
Subject: [PATCH 02/13] "This is a short test to make sure I can actually push
to remote before starting anything; updates 3446"
From fd42568a93cc926380c14a5a5df56d9e015c0d5e Mon Sep 17 00:00:00 2001
From: ggoneiESS
Date: Tue, 16 May 2023 15:05:30 +0200
Subject: [PATCH 03/13] "This is a short test to make sure I can actually push
to remote before starting anything; updates 3446"
From c442a7ffba2b46d4ded71457646b9204fbda92ce Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Fri, 9 Jun 2023 17:46:27 +0200
Subject: [PATCH 04/13] add'n of (starting?) filewriter module attribute
---
nexus_constructor/add_component_window.py | 4 ++--
nexus_constructor/common_attrs.py | 1 +
nexus_constructor/field_utils.py | 18 +++++++++++++---
nexus_constructor/field_widget.py | 22 ++++++++++---------
nexus_constructor/json/load_from_json.py | 3 ++-
nexus_constructor/model/module.py | 26 +++++++++++++++++++++++
nexus_constructor/module_view.py | 6 +++---
nexus_constructor/ui_utils.py | 4 ++--
nexus_constructor/validators.py | 8 ++++---
requirements.txt | 4 +++-
ui/main_window.py | 1 +
11 files changed, 72 insertions(+), 25 deletions(-)
diff --git a/nexus_constructor/add_component_window.py b/nexus_constructor/add_component_window.py
index 0484571a5..1496d8b6c 100644
--- a/nexus_constructor/add_component_window.py
+++ b/nexus_constructor/add_component_window.py
@@ -33,7 +33,7 @@
OFFGeometryNoNexus,
)
from nexus_constructor.model.model import Model
-from nexus_constructor.model.module import Dataset, Link
+from nexus_constructor.model.module import Dataset, Link, FileWriter
from nexus_constructor.pixel_options import PixelOptions
from nexus_constructor.ui_utils import (
file_dialog,
@@ -763,7 +763,7 @@ def add_fields_to_component(
for i in range(fields_widget.count()):
widget = fields_widget.itemWidget(fields_widget.item(i))
try:
- if not isinstance(widget.value, (Link, Dataset)):
+ if not isinstance(widget.value, (Link, Dataset, FileWriter)):
stream_module = deepcopy(widget.value)
stream_module.parent_node = component
component.children.append(stream_module)
diff --git a/nexus_constructor/common_attrs.py b/nexus_constructor/common_attrs.py
index 3aa4d8d5e..cbedf1a70 100644
--- a/nexus_constructor/common_attrs.py
+++ b/nexus_constructor/common_attrs.py
@@ -41,6 +41,7 @@ class TransformationType:
SAMPLE_NAME = "sample"
ARRAY = "Array"
SCALAR = "Scalar"
+FILEWRITER = "Filewriter"
SHAPE_GROUP_NAME = "shape"
PIXEL_SHAPE_GROUP_NAME = "pixel_shape"
GEOMETRY_GROUP_NAME = "geometry"
diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py
index 36fd098a2..7f2ef8b47 100644
--- a/nexus_constructor/field_utils.py
+++ b/nexus_constructor/field_utils.py
@@ -7,7 +7,7 @@
from nexus_constructor.field_widget import FieldWidget
from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES
from nexus_constructor.model.group import Group
-from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule
+from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule, FileWriter
from nexus_constructor.model.value_type import ValueTypes
from nexus_constructor.utils.required_component_fields import required_component_fields
from nexus_constructor.validators import FieldType
@@ -47,7 +47,17 @@ def __update_existing_dataset_field(field: Dataset, new_ui_field: FieldWidget):
new_ui_field.value = field.values # type: ignore
new_ui_field.attrs = field
units = field.attributes.get_attribute_value(CommonAttrs.UNITS)
- new_ui_field.units = units
+ new_ui_field.units = units or ""
+
+
+def update_existing_filewriter_field(field: Dataset, new_ui_field: FieldWidget):
+ """
+ Fill in a UI filewriter field for an existing filewriter field in the component group
+ :param field: The dataset to copy into the ???value line edit
+ :param new_ui_field: The new UI field to fill in with existing data
+ """
+ new_ui_field.field_type = FieldType(FieldType.filewriter.value)
+ __update_existing_dataset_field(field, new_ui_field)
def update_existing_scalar_field(field: Dataset, new_ui_field: FieldWidget):
@@ -69,7 +79,7 @@ def update_existing_stream_field(
:param new_ui_field: The new UI field to fill in with existing data
"""
new_ui_field.field_type = FieldType.kafka_stream
- new_ui_field._old_schema = field.writer_module # type: ignore
+ new_ui_field._old_schema = field.writer_module
new_ui_field.streams_widget.update_existing_stream_info(field)
new_ui_field.attrs = field
units = field.attributes.get_attribute_value(CommonAttrs.UNITS)
@@ -115,6 +125,8 @@ def find_field_type(item: "ValueType", ignore_names=INVALID_FIELD_NAMES) -> Call
return update_existing_stream_field
elif isinstance(item, Link):
return update_existing_link_field
+ elif isinstance(item,FileWriter):
+ return update_existing_filewriter_field
else:
try:
logging.debug(
diff --git a/nexus_constructor/field_widget.py b/nexus_constructor/field_widget.py
index 681787b48..0c8161a69 100644
--- a/nexus_constructor/field_widget.py
+++ b/nexus_constructor/field_widget.py
@@ -25,7 +25,7 @@
from nexus_constructor.field_attrs import FieldAttrsDialog
from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES
from nexus_constructor.model.group import Group
-from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule
+from nexus_constructor.model.module import Dataset, FileWriter, FileWriterModule, Link, StreamModule
from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP, ValueTypes
from nexus_constructor.stream_fields_widget import StreamFieldsWidget
from nexus_constructor.ui_utils import validate_line_edit
@@ -367,6 +367,12 @@ def value(self) -> Union[FileWriterModule, None]:
name=self.name,
source=self.value_line_edit.text(),
)
+ elif self.field_type == FieldType.filewriter:
+ return_object = FileWriter(
+ parent_node=self._node_parent,
+ name=self.name,
+ type=dtype,
+ )
else:
logging.error(f"unknown field type: {self.name}")
return None
@@ -450,14 +456,10 @@ def field_type_changed(self):
self.streams_widget.ok_validator.validate_ok()
self.streams_widget.cancel_button.clicked.connect(self.reset_field_type)
elif self.field_type == FieldType.link:
- self.set_visibility(
- True,
- False,
- False,
- False,
- show_unit_line_edit=False,
- show_attrs_edit=False,
- )
+ self.set_visibility(True, False, False, False, show_unit_line_edit=False, show_attrs_edit=False)
+ self._set_up_value_validator(False)
+ elif self.field_type == FieldType.filewriter:
+ self.set_visibility(False, False, False, False, True, False, False)
self._set_up_value_validator(False)
def reset_field_type(self):
@@ -488,7 +490,7 @@ def _set_up_value_validator(self, is_link: bool):
FieldValueValidator(
self.field_type_combo,
self.value_type_combo,
- FieldType.scalar_dataset.value,
+ self.field_type.value
)
)
tooltip_on_accept = "Value is cast-able to numpy type."
diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py
index ec4f44401..57dc6f9d9 100644
--- a/nexus_constructor/json/load_from_json.py
+++ b/nexus_constructor/json/load_from_json.py
@@ -43,6 +43,7 @@
from nexus_constructor.model.model import Model
from nexus_constructor.model.module import (
Dataset,
+ FileWriter,
FileWriterModule,
Link,
StreamModule,
@@ -276,7 +277,7 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None):
elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object:
module_type = json_object[CommonKeys.MODULE]
if (
- module_type == WriterModules.DATASET.value
+ ( module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value )
and json_object[NodeType.CONFIG][CommonKeys.NAME]
== CommonAttrs.DEPENDS_ON
):
diff --git a/nexus_constructor/model/module.py b/nexus_constructor/model/module.py
index 27327389f..ac87761f9 100644
--- a/nexus_constructor/model/module.py
+++ b/nexus_constructor/model/module.py
@@ -39,6 +39,7 @@ class WriterModules(Enum):
LINK = "link"
DATASET = "dataset"
ADAR = "ADAr"
+ FILEWRITER = "filewriter"
class StreamModules(Enum):
@@ -167,6 +168,24 @@ class F144Stream(F142Stream):
writer_module = attr.ib(type=str, default=WriterModules.F144.value, init=False)
+@attr.s
+class FileWriter(FileWriterModule):
+ name = attr.ib(type=str)
+ type = attr.ib(type=str, default="string")
+ values = attr.ib(type=str, default=None)
+ writer_module = attr.ib(type=str, default=WriterModules.FILEWRITER.value, init=False)
+
+ def as_dict(self, error_collector: List[str]):
+ return {
+ CommonKeys.MODULE: self.writer_module,
+ NodeType.CONFIG: {CommonKeys.NAME: self.name},
+ }
+
+ def as_nexus(self, nexus_node, error_collector: List[str]):
+ nexus_dataset = nexus_node.create_dataset(self.name, data=self.name)
+ nexus_dataset.attrs[self.name] = self.name
+
+
@attr.s
class Link(FileWriterModule):
name = attr.ib(type=str)
@@ -305,6 +324,7 @@ class WriterModuleClasses(Enum):
LINK = Link
DATASET = Dataset
ADAR = ADARStream
+ FILEWRITER = FileWriter
module_class_dict = dict(
@@ -373,6 +393,12 @@ def create_fw_module_object(mod_type, configuration, parent_node):
source=configuration[SOURCE],
parent_node=parent_node,
)
+ elif mod_type == WriterModules.FILEWRITER.value:
+ fw_mod_obj = fw_mod_class(
+ name=configuration[CommonKeys.NAME],
+ parent_node=parent_node,
+ type="string"
+ )
elif mod_type == WriterModules.DATASET.value:
if CommonKeys.DATA_TYPE in configuration:
dtype = configuration[CommonKeys.DATA_TYPE]
diff --git a/nexus_constructor/module_view.py b/nexus_constructor/module_view.py
index 878b1375c..642b27f70 100644
--- a/nexus_constructor/module_view.py
+++ b/nexus_constructor/module_view.py
@@ -31,7 +31,7 @@ def _setup_frame(self, module):
source = module.source if module.source else "not specified"
self.layout.addWidget(self._get_label(f"link name: {name} | "))
self.layout.addWidget(self._get_label(f"source: {source}"))
- elif module.writer_module == WriterModules.DATASET.value:
+ elif module.writer_module == WriterModules.DATASET.value or module.writer_module == WriterModules.FILEWRITER.value:
name = module.name if module.name else "not specified"
dtype = module.type if module.type else "not specified"
self.layout.addWidget(self._get_label(f"dataset name: {name} | "))
@@ -74,8 +74,8 @@ def _set_existing_items(self):
if (
self.module.writer_module == WriterModules.DATASET.value
or self.module.writer_module == WriterModules.LINK.value
- or self.module.writer_module
- in [StreamMode.value for StreamMode in StreamModules]
+ or self.module.writer_module in [StreamMode.value for StreamMode in StreamModules]
+ or self.module.writer_module == WriterModules.FILEWRITER.value
):
update_function = find_field_type(module, [])
if update_function is not None:
diff --git a/nexus_constructor/ui_utils.py b/nexus_constructor/ui_utils.py
index 3fd8d10eb..8b9a3d08a 100644
--- a/nexus_constructor/ui_utils.py
+++ b/nexus_constructor/ui_utils.py
@@ -61,7 +61,7 @@ def validate_combobox_edit(
:param tooltip_on_reject: Tooltip to display combobox edit is invalid.
:return: None.
"""
- colour = "#FFFFFF" if is_valid else "#f6989d"
+ colour = "#333333" if is_valid else "#f6989d"
combobox_edit.setStyleSheet(f"QComboBox {{ background-color: {colour} }}")
if "Suggestion" in tooltip_on_reject and callable(suggestion_callable):
tooltip_on_reject += suggestion_callable()
@@ -86,7 +86,7 @@ def validate_line_edit(
:param tooltip_on_reject: Tooltip to display if line edit is invalid.
:return: None.
"""
- colour = "#FFFFFF" if is_valid else "#f6989d"
+ colour = "#333333" if is_valid else "#f6989d"
line_edit.setStyleSheet(f"QLineEdit {{ background-color: {colour} }}")
if "Suggestion" in tooltip_on_reject and callable(suggestion_callable):
tooltip_on_reject += suggestion_callable()
diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py
index 996369e1e..fba06dc15 100644
--- a/nexus_constructor/validators.py
+++ b/nexus_constructor/validators.py
@@ -10,7 +10,7 @@
from PySide6.QtWidgets import QComboBox, QListWidget, QRadioButton, QWidget
from stl import mesh
-from nexus_constructor.common_attrs import SCALAR
+from nexus_constructor.common_attrs import SCALAR, FILEWRITER
from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP
from nexus_constructor.unit_utils import (
units_are_expected_dimensionality,
@@ -392,6 +392,8 @@ class FieldType(Enum):
array_dataset = "Array dataset"
kafka_stream = "Kafka stream"
link = "Link"
+ filewriter = "Filewriter"
+
class FieldValueValidator(QValidator):
@@ -417,9 +419,9 @@ def validate(self, input: str, pos: int) -> QValidator.State:
:param pos: mouse position cursor(ignored, just here to satisfy overriding function)
:return: QValidator state (Acceptable, Intermediate, Invalid) - returning intermediate because invalid stops the user from typing.
"""
- if not input: # More criteria here
+ if not input and not self.scalar == FILEWRITER: # More criteria here
return self._emit_and_return(False)
- if self.field_type_combo.currentText() == self.scalar:
+ if self.field_type_combo.currentText() == SCALAR:
try:
VALUE_TYPE_TO_NP[self.dataset_type_combo.currentText()](input)
except ValueError:
diff --git a/requirements.txt b/requirements.txt
index a921a837e..8d10cbf48 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,10 +1,12 @@
nexusformat
numpy
numpy-stl
-open3d
+#lightgbm for macOS should instead be installed via (brew/port) install libomp (needed for open3d)
+open3d #installs a binary linked to homebrew; make a directory and symlink, e.g. ln -s /opt/local/lib/libomp/libomp.dylib /opt/homebrew/opt/libomp/lib/libomp.dylib
pint
PySide6<6.4.0
pytest-qt
xmltodict
h5py
ess-streaming-data-types >= 0.9.5
+attrs
\ No newline at end of file
diff --git a/ui/main_window.py b/ui/main_window.py
index c80d3f15d..d2ef33c31 100644
--- a/ui/main_window.py
+++ b/ui/main_window.py
@@ -20,6 +20,7 @@
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.resize(1280, 720)
+ MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}")
self.central_widget = QWidget(MainWindow)
self.splitter = QSplitter(self.central_widget)
From 5de59ffc0328ec55d6ebd21b525caa19cdbe662e Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Fri, 9 Jun 2023 19:34:23 +0200
Subject: [PATCH 05/13] correct colour in tests (for dark mode visibility)
---
tests/test_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index f939309bb..b523fbbea 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -24,7 +24,7 @@ def test_GIVEN_invalid_WHEN_validating_line_edit_THEN_line_edit_turns_red():
def test_GIVEN_valid_WHEN_validating_line_edit_THEN_line_edit_turns_white():
line_edit = DummyLineEdit()
validate_line_edit(line_edit, True)
- assert "background-color: #FFFFFF" in line_edit.stylesheet
+ assert "background-color: #333333" in line_edit.stylesheet
def test_GIVEN_valid_WHEN_validating_line_edit_with_tooltip_THEN_line_edit_tooltip_is_changed():
From f59eb33625ec6e3f25ecd450b771e94489e97a75 Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Mon, 12 Jun 2023 18:04:22 +0200
Subject: [PATCH 06/13] added test, altered pint version, all successful
---
nexus_constructor/validators.py | 2 +-
requirements.txt | 2 +-
tests/test_validators.py | 13 +++++++++++++
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py
index fba06dc15..f8996d972 100644
--- a/nexus_constructor/validators.py
+++ b/nexus_constructor/validators.py
@@ -421,7 +421,7 @@ def validate(self, input: str, pos: int) -> QValidator.State:
"""
if not input and not self.scalar == FILEWRITER: # More criteria here
return self._emit_and_return(False)
- if self.field_type_combo.currentText() == SCALAR:
+ if self.field_type_combo.currentText() == self.scalar:
try:
VALUE_TYPE_TO_NP[self.dataset_type_combo.currentText()](input)
except ValueError:
diff --git a/requirements.txt b/requirements.txt
index 8d10cbf48..3480f22d0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,7 +3,7 @@ numpy
numpy-stl
#lightgbm for macOS should instead be installed via (brew/port) install libomp (needed for open3d)
open3d #installs a binary linked to homebrew; make a directory and symlink, e.g. ln -s /opt/local/lib/libomp/libomp.dylib /opt/homebrew/opt/libomp/lib/libomp.dylib
-pint
+pint<=0.21
PySide6<6.4.0
pytest-qt
xmltodict
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 0b509002b..461bbee75 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -172,6 +172,19 @@ def test_GIVEN_valid_string_value_WHEN_validating_field_value_THEN_returns_accep
assert validator.validate(strvalue, 0) == QValidator.Acceptable
validator.is_valid.emit.assert_called_once_with(True)
+def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptable_and_emits_signal_with_true():
+ strvalue = "123a"
+
+ field_type_combo = DummyCombo(FieldType.filewriter.value)
+ dataset_type_combo = DummyCombo(ValueTypes.STRING)
+
+ validator = FieldValueValidator(
+ field_type_combo, dataset_type_combo, FieldType.filewriter.value
+ )
+ validator.is_valid = Mock()
+
+ assert validator.validate(strvalue, 0) == QValidator.Acceptable
+ validator.is_valid.emit.assert_called_once_with(True)
def test_GIVEN_invalid_float_value_WHEN_validating_field_value_THEN_returns_intermediate_and_emits_signal_with_false():
invalid_value = "sdfn"
From 7af08cf320540287cbef012aacd44832135c2638 Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Mon, 12 Jun 2023 18:22:24 +0200
Subject: [PATCH 07/13] Cleaned up code as per flake8
---
nexus_constructor/field_utils.py | 2 +-
nexus_constructor/json/load_from_json.py | 4 ++--
nexus_constructor/validators.py | 1 -
tests/test_validators.py | 2 ++
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py
index 7f2ef8b47..2117ce07f 100644
--- a/nexus_constructor/field_utils.py
+++ b/nexus_constructor/field_utils.py
@@ -125,7 +125,7 @@ def find_field_type(item: "ValueType", ignore_names=INVALID_FIELD_NAMES) -> Call
return update_existing_stream_field
elif isinstance(item, Link):
return update_existing_link_field
- elif isinstance(item,FileWriter):
+ elif isinstance(item, FileWriter):
return update_existing_filewriter_field
else:
try:
diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py
index 57dc6f9d9..24ad1a2ac 100644
--- a/nexus_constructor/json/load_from_json.py
+++ b/nexus_constructor/json/load_from_json.py
@@ -202,7 +202,7 @@ def _load_from_json_dict(self, json_dict: Dict) -> bool:
self.entry_node = self._read_json_object(json_dict[CommonKeys.CHILDREN][0])
self.model.entry.attributes = self.entry_node.attributes
for child in self.entry_node.children:
- if isinstance(child, (Dataset, Link, Group)):
+ if isinstance(child, (Dataset, Link, FileWriter, Group)):
self.model.entry[child.name] = child
else:
self.model.entry.children.append(child)
@@ -277,7 +277,7 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None):
elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object:
module_type = json_object[CommonKeys.MODULE]
if (
- ( module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value )
+ (module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value)
and json_object[NodeType.CONFIG][CommonKeys.NAME]
== CommonAttrs.DEPENDS_ON
):
diff --git a/nexus_constructor/validators.py b/nexus_constructor/validators.py
index f8996d972..f3692552b 100644
--- a/nexus_constructor/validators.py
+++ b/nexus_constructor/validators.py
@@ -395,7 +395,6 @@ class FieldType(Enum):
filewriter = "Filewriter"
-
class FieldValueValidator(QValidator):
"""
Validates the field value line edit to check that the entered string is castable to the selected numpy type.
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 461bbee75..b2a8cdb92 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -172,6 +172,7 @@ def test_GIVEN_valid_string_value_WHEN_validating_field_value_THEN_returns_accep
assert validator.validate(strvalue, 0) == QValidator.Acceptable
validator.is_valid.emit.assert_called_once_with(True)
+
def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptable_and_emits_signal_with_true():
strvalue = "123a"
@@ -186,6 +187,7 @@ def test_GIVEN_valid_name_value_WHEN_validating_filewriter_THEN_returns_acceptab
assert validator.validate(strvalue, 0) == QValidator.Acceptable
validator.is_valid.emit.assert_called_once_with(True)
+
def test_GIVEN_invalid_float_value_WHEN_validating_field_value_THEN_returns_intermediate_and_emits_signal_with_false():
invalid_value = "sdfn"
From c7f925953501409a8f6df10ece6acc9179ee82ac Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 13 Jun 2023 16:00:03 +0200
Subject: [PATCH 08/13] Changed styling
---
nexus-constructor.py | 1 +
ui/UI.md | 13 -------------
ui/main_window.py | 2 +-
3 files changed, 2 insertions(+), 14 deletions(-)
delete mode 100644 ui/UI.md
diff --git a/nexus-constructor.py b/nexus-constructor.py
index b0c8c41b8..bead28395 100644
--- a/nexus-constructor.py
+++ b/nexus-constructor.py
@@ -75,6 +75,7 @@ def closeEvent(self, event: QCloseEvent) -> None:
if "help" in parser.parse_args():
exit(0)
logging.basicConfig(level=logging.INFO)
+ QApplication.setStyle("Fusion")
QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
surfaceFormat = QSurfaceFormat()
surfaceFormat.setSwapInterval(1)
diff --git a/ui/UI.md b/ui/UI.md
deleted file mode 100644
index 500cc5e81..000000000
--- a/ui/UI.md
+++ /dev/null
@@ -1,13 +0,0 @@
-#ui/
-
-This directory contains auto-generated python files and UI files to be used with Qt Creator/Qt Designer.
-
-Use `pyside2-uic uifile.ui -o pythonfile.py` to convert the .ui files to python with the same name.
-
-
-## Known issues when using pyside2-uic
-Some of the UI components don't seem to generate the correct import statements when using `pyside2-uic`. They paste the incorrect import statement underneath the code for some reason.
-
-
-- [QWebEngine](https://bugreports.qt.io/browse/PYSIDE-1020)
- - workaround - paste in `from PySide2.QtWebEngineWidgets import QWebEngineView` and remove the incorrect import statement
diff --git a/ui/main_window.py b/ui/main_window.py
index d2ef33c31..08340f9de 100644
--- a/ui/main_window.py
+++ b/ui/main_window.py
@@ -20,7 +20,7 @@
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.resize(1280, 720)
- MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}")
+# MainWindow.setStyleSheet("* {color: #000000;background-color: #999999;}") # style set instead in nexus-constructor.py:78:QApplication.setStyle("Fusion")
self.central_widget = QWidget(MainWindow)
self.splitter = QSplitter(self.central_widget)
From 8f6137206c49b3ff41ae6fcf2b58ea723a88c467 Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 13 Jun 2023 16:08:17 +0200
Subject: [PATCH 09/13] corrected white_background to new off-white colour
---
ui_tests/ui_test_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui_tests/ui_test_utils.py b/ui_tests/ui_test_utils.py
index 0d1327410..6805d9348 100644
--- a/ui_tests/ui_test_utils.py
+++ b/ui_tests/ui_test_utils.py
@@ -7,7 +7,7 @@
RUNNING_ON_WINDOWS = sys.platform.startswith("win")
RED_BACKGROUND = "{ background-color: #f6989d }"
-WHITE_BACKGROUND = "{ background-color: #FFFFFF }"
+WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white
LINE_EDIT = "QLineEdit "
SPIN_BOX = "QSpinBox "
RED_LINE_EDIT_STYLE_SHEET = LINE_EDIT + RED_BACKGROUND
From ba5e2c1f5bba951b5e83e2725be11a73bf78ca91 Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 13 Jun 2023 16:23:59 +0200
Subject: [PATCH 10/13] flake8 format
---
ui_tests/ui_test_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui_tests/ui_test_utils.py b/ui_tests/ui_test_utils.py
index 6805d9348..522df0f51 100644
--- a/ui_tests/ui_test_utils.py
+++ b/ui_tests/ui_test_utils.py
@@ -7,7 +7,7 @@
RUNNING_ON_WINDOWS = sys.platform.startswith("win")
RED_BACKGROUND = "{ background-color: #f6989d }"
-WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white
+WHITE_BACKGROUND = "{ background-color: #333333 }" # no longer white
LINE_EDIT = "QLineEdit "
SPIN_BOX = "QSpinBox "
RED_LINE_EDIT_STYLE_SHEET = LINE_EDIT + RED_BACKGROUND
From e87393c2491abc2483622c1c0021a2fb5555462f Mon Sep 17 00:00:00 2001
From: George O'Neill
Date: Tue, 13 Jun 2023 17:09:05 +0200
Subject: [PATCH 11/13] fixed SSL error for HTML documentation build,
filewriter to JSON
---
definitions/requirements.txt | 1 +
tests/json/test_load_from_json.py | 18 ++++++++++++------
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/definitions/requirements.txt b/definitions/requirements.txt
index bded64d61..6492a2e43 100644
--- a/definitions/requirements.txt
+++ b/definitions/requirements.txt
@@ -1,3 +1,4 @@
lxml
pyRestTable==2020.0.3
+urllib3<2.0
Sphinx
diff --git a/tests/json/test_load_from_json.py b/tests/json/test_load_from_json.py
index 57e7a2c61..f116d111e 100644
--- a/tests/json/test_load_from_json.py
+++ b/tests/json/test_load_from_json.py
@@ -45,7 +45,7 @@ def nexus_json_dictionary() -> dict:
"values":"NXinstrument"
}],
"children":[
-
+
]
},
{
@@ -62,10 +62,16 @@ def nexus_json_dictionary() -> dict:
"type":"group",
"name":"transformations",
"children":[
-
+
]
}
]
+ },
+ {
+ "module": "filewriter",
+ "config": {
+ "name": "start_time"
+ }
}
]
}
@@ -117,7 +123,7 @@ def json_dict_with_component():
"type":"group",
"name":"transformations",
"children":[
-
+
]
}
]
@@ -139,7 +145,7 @@ def json_dict_with_component():
"type":"group",
"name":"transformations",
"children":[
-
+
]
}
]
@@ -289,7 +295,7 @@ def test_GIVEN_json_with_missing_value_WHEN_loading_from_json_THEN_json_loader_r
"values":"NXinstrument"
},
"children":[
-
+
]
},
{
@@ -306,7 +312,7 @@ def test_GIVEN_json_with_missing_value_WHEN_loading_from_json_THEN_json_loader_r
"type":"group",
"name":"transformations",
"children":[
-
+
]
}
]
From 751d57ee499d539382e66e3d0cd9fb0a64a1f3ab Mon Sep 17 00:00:00 2001
From: cow-bot
Date: Tue, 13 Jun 2023 15:13:09 +0000
Subject: [PATCH 12/13] GO FORMAT YOURSELF (black)
---
nexus_constructor/field_utils.py | 8 +++++++-
nexus_constructor/field_widget.py | 21 ++++++++++++++++-----
nexus_constructor/json/load_from_json.py | 9 +++++----
nexus_constructor/model/module.py | 8 ++++----
nexus_constructor/module_view.py | 8 ++++++--
5 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/nexus_constructor/field_utils.py b/nexus_constructor/field_utils.py
index 2117ce07f..da79e0c27 100644
--- a/nexus_constructor/field_utils.py
+++ b/nexus_constructor/field_utils.py
@@ -7,7 +7,13 @@
from nexus_constructor.field_widget import FieldWidget
from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES
from nexus_constructor.model.group import Group
-from nexus_constructor.model.module import Dataset, FileWriterModule, Link, StreamModule, FileWriter
+from nexus_constructor.model.module import (
+ Dataset,
+ FileWriterModule,
+ Link,
+ StreamModule,
+ FileWriter,
+)
from nexus_constructor.model.value_type import ValueTypes
from nexus_constructor.utils.required_component_fields import required_component_fields
from nexus_constructor.validators import FieldType
diff --git a/nexus_constructor/field_widget.py b/nexus_constructor/field_widget.py
index 0c8161a69..0eda46af7 100644
--- a/nexus_constructor/field_widget.py
+++ b/nexus_constructor/field_widget.py
@@ -25,7 +25,13 @@
from nexus_constructor.field_attrs import FieldAttrsDialog
from nexus_constructor.invalid_field_names import INVALID_FIELD_NAMES
from nexus_constructor.model.group import Group
-from nexus_constructor.model.module import Dataset, FileWriter, FileWriterModule, Link, StreamModule
+from nexus_constructor.model.module import (
+ Dataset,
+ FileWriter,
+ FileWriterModule,
+ Link,
+ StreamModule,
+)
from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP, ValueTypes
from nexus_constructor.stream_fields_widget import StreamFieldsWidget
from nexus_constructor.ui_utils import validate_line_edit
@@ -456,7 +462,14 @@ def field_type_changed(self):
self.streams_widget.ok_validator.validate_ok()
self.streams_widget.cancel_button.clicked.connect(self.reset_field_type)
elif self.field_type == FieldType.link:
- self.set_visibility(True, False, False, False, show_unit_line_edit=False, show_attrs_edit=False)
+ self.set_visibility(
+ True,
+ False,
+ False,
+ False,
+ show_unit_line_edit=False,
+ show_attrs_edit=False,
+ )
self._set_up_value_validator(False)
elif self.field_type == FieldType.filewriter:
self.set_visibility(False, False, False, False, True, False, False)
@@ -488,9 +501,7 @@ def _set_up_value_validator(self, is_link: bool):
else:
self.value_line_edit.setValidator(
FieldValueValidator(
- self.field_type_combo,
- self.value_type_combo,
- self.field_type.value
+ self.field_type_combo, self.value_type_combo, self.field_type.value
)
)
tooltip_on_accept = "Value is cast-able to numpy type."
diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py
index 24ad1a2ac..56051ef0c 100644
--- a/nexus_constructor/json/load_from_json.py
+++ b/nexus_constructor/json/load_from_json.py
@@ -277,10 +277,11 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None):
elif CommonKeys.MODULE in json_object and NodeType.CONFIG in json_object:
module_type = json_object[CommonKeys.MODULE]
if (
- (module_type == WriterModules.DATASET.value or module_type == WriterModules.FILEWRITER.value)
- and json_object[NodeType.CONFIG][CommonKeys.NAME]
- == CommonAttrs.DEPENDS_ON
- ):
+ module_type == WriterModules.DATASET.value
+ or module_type == WriterModules.FILEWRITER.value
+ ) and json_object[NodeType.CONFIG][
+ CommonKeys.NAME
+ ] == CommonAttrs.DEPENDS_ON:
nexus_object = None
elif module_type in [x.value for x in WriterModules]:
nexus_object = create_fw_module_object(
diff --git a/nexus_constructor/model/module.py b/nexus_constructor/model/module.py
index ac87761f9..1219310b2 100644
--- a/nexus_constructor/model/module.py
+++ b/nexus_constructor/model/module.py
@@ -173,7 +173,9 @@ class FileWriter(FileWriterModule):
name = attr.ib(type=str)
type = attr.ib(type=str, default="string")
values = attr.ib(type=str, default=None)
- writer_module = attr.ib(type=str, default=WriterModules.FILEWRITER.value, init=False)
+ writer_module = attr.ib(
+ type=str, default=WriterModules.FILEWRITER.value, init=False
+ )
def as_dict(self, error_collector: List[str]):
return {
@@ -395,9 +397,7 @@ def create_fw_module_object(mod_type, configuration, parent_node):
)
elif mod_type == WriterModules.FILEWRITER.value:
fw_mod_obj = fw_mod_class(
- name=configuration[CommonKeys.NAME],
- parent_node=parent_node,
- type="string"
+ name=configuration[CommonKeys.NAME], parent_node=parent_node, type="string"
)
elif mod_type == WriterModules.DATASET.value:
if CommonKeys.DATA_TYPE in configuration:
diff --git a/nexus_constructor/module_view.py b/nexus_constructor/module_view.py
index 642b27f70..bb792a583 100644
--- a/nexus_constructor/module_view.py
+++ b/nexus_constructor/module_view.py
@@ -31,7 +31,10 @@ def _setup_frame(self, module):
source = module.source if module.source else "not specified"
self.layout.addWidget(self._get_label(f"link name: {name} | "))
self.layout.addWidget(self._get_label(f"source: {source}"))
- elif module.writer_module == WriterModules.DATASET.value or module.writer_module == WriterModules.FILEWRITER.value:
+ elif (
+ module.writer_module == WriterModules.DATASET.value
+ or module.writer_module == WriterModules.FILEWRITER.value
+ ):
name = module.name if module.name else "not specified"
dtype = module.type if module.type else "not specified"
self.layout.addWidget(self._get_label(f"dataset name: {name} | "))
@@ -74,7 +77,8 @@ def _set_existing_items(self):
if (
self.module.writer_module == WriterModules.DATASET.value
or self.module.writer_module == WriterModules.LINK.value
- or self.module.writer_module in [StreamMode.value for StreamMode in StreamModules]
+ or self.module.writer_module
+ in [StreamMode.value for StreamMode in StreamModules]
or self.module.writer_module == WriterModules.FILEWRITER.value
):
update_function = find_field_type(module, [])
From b63623f02dd4dbcc60864fab5cb18b5980ad2c9c Mon Sep 17 00:00:00 2001
From: cow-bot
Date: Tue, 13 Jun 2023 15:14:22 +0000
Subject: [PATCH 13/13] Update NeXus HTML documentation
---
.../html/applying-nexus.html | 5 +-
nx-class-documentation/html/authorgroup.html | 5 +-
.../html/classes/applications/NXarchive.html | 5 +-
.../html/classes/applications/NXarpes.html | 5 +-
.../html/classes/applications/NXcanSAS.html | 9 ++-
.../classes/applications/NXdirecttof.html | 5 +-
.../html/classes/applications/NXfluo.html | 5 +-
.../classes/applications/NXindirecttof.html | 5 +-
.../html/classes/applications/NXiqproc.html | 5 +-
.../html/classes/applications/NXlauetof.html | 5 +-
.../html/classes/applications/NXmonopd.html | 5 +-
.../html/classes/applications/NXmx.html | 5 +-
.../html/classes/applications/NXrefscan.html | 5 +-
.../html/classes/applications/NXreftof.html | 5 +-
.../html/classes/applications/NXsas.html | 5 +-
.../html/classes/applications/NXsastof.html | 5 +-
.../html/classes/applications/NXscan.html | 5 +-
.../html/classes/applications/NXspe.html | 5 +-
.../html/classes/applications/NXsqom.html | 5 +-
.../html/classes/applications/NXstxm.html | 5 +-
.../html/classes/applications/NXtas.html | 5 +-
.../html/classes/applications/NXtofnpd.html | 5 +-
.../html/classes/applications/NXtofraw.html | 5 +-
.../classes/applications/NXtofsingle.html | 5 +-
.../html/classes/applications/NXtomo.html | 5 +-
.../classes/applications/NXtomophase.html | 5 +-
.../html/classes/applications/NXtomoproc.html | 5 +-
.../html/classes/applications/NXxas.html | 5 +-
.../html/classes/applications/NXxasproc.html | 5 +-
.../html/classes/applications/NXxbase.html | 5 +-
.../html/classes/applications/NXxeuler.html | 5 +-
.../html/classes/applications/NXxkappa.html | 5 +-
.../html/classes/applications/NXxlaue.html | 5 +-
.../classes/applications/NXxlaueplate.html | 5 +-
.../html/classes/applications/NXxnb.html | 5 +-
.../html/classes/applications/NXxrot.html | 5 +-
.../html/classes/applications/index.html | 5 +-
.../html/classes/base_classes/NXaperture.html | 5 +-
.../classes/base_classes/NXattenuator.html | 5 +-
.../html/classes/base_classes/NXbeam.html | 5 +-
.../classes/base_classes/NXbeam_stop.html | 5 +-
.../base_classes/NXbending_magnet.html | 5 +-
.../classes/base_classes/NXcapillary.html | 5 +-
.../html/classes/base_classes/NXcite.html | 5 +-
.../classes/base_classes/NXcollection.html | 5 +-
.../classes/base_classes/NXcollimator.html | 5 +-
.../html/classes/base_classes/NXcrystal.html | 5 +-
.../base_classes/NXcylindrical_geometry.html | 5 +-
.../html/classes/base_classes/NXdata.html | 5 +-
.../html/classes/base_classes/NXdetector.html | 5 +-
.../base_classes/NXdetector_group.html | 5 +-
.../base_classes/NXdetector_module.html | 5 +-
.../classes/base_classes/NXdisk_chopper.html | 5 +-
.../html/classes/base_classes/NXentry.html | 7 +--
.../classes/base_classes/NXenvironment.html | 5 +-
.../classes/base_classes/NXevent_data.html | 5 +-
.../classes/base_classes/NXfermi_chopper.html | 5 +-
.../html/classes/base_classes/NXfilter.html | 5 +-
.../html/classes/base_classes/NXflipper.html | 5 +-
.../base_classes/NXfresnel_zone_plate.html | 5 +-
.../html/classes/base_classes/NXgeometry.html | 5 +-
.../html/classes/base_classes/NXgrating.html | 5 +-
.../html/classes/base_classes/NXguide.html | 5 +-
.../base_classes/NXinsertion_device.html | 5 +-
.../classes/base_classes/NXinstrument.html | 5 +-
.../html/classes/base_classes/NXlog.html | 5 +-
.../html/classes/base_classes/NXmirror.html | 5 +-
.../classes/base_classes/NXmoderator.html | 5 +-
.../html/classes/base_classes/NXmonitor.html | 5 +-
.../classes/base_classes/NXmonochromator.html | 5 +-
.../html/classes/base_classes/NXnote.html | 5 +-
.../html/classes/base_classes/NXobject.html | 5 +-
.../classes/base_classes/NXoff_geometry.html | 5 +-
.../classes/base_classes/NXorientation.html | 5 +-
.../classes/base_classes/NXparameters.html | 5 +-
.../html/classes/base_classes/NXpdb.html | 5 +-
.../html/classes/base_classes/NXpinhole.html | 5 +-
.../classes/base_classes/NXpolarizer.html | 5 +-
.../classes/base_classes/NXpositioner.html | 5 +-
.../html/classes/base_classes/NXprocess.html | 5 +-
.../classes/base_classes/NXreflections.html | 5 +-
.../html/classes/base_classes/NXroot.html | 5 +-
.../html/classes/base_classes/NXsample.html | 5 +-
.../base_classes/NXsample_component.html | 5 +-
.../html/classes/base_classes/NXsensor.html | 5 +-
.../html/classes/base_classes/NXshape.html | 5 +-
.../html/classes/base_classes/NXslit.html | 5 +-
.../html/classes/base_classes/NXsource.html | 5 +-
.../html/classes/base_classes/NXsubentry.html | 5 +-
.../base_classes/NXtransformations.html | 5 +-
.../classes/base_classes/NXtranslation.html | 5 +-
.../html/classes/base_classes/NXuser.html | 5 +-
.../base_classes/NXvelocity_selector.html | 5 +-
.../html/classes/base_classes/NXxraylens.html | 5 +-
.../html/classes/base_classes/index.html | 5 +-
.../contributed_definitions/NXcontainer.html | 5 +-
.../contributed_definitions/NXcsg.html | 5 +-
.../contributed_definitions/NXcxi_ptycho.html | 5 +-
.../NXelectrostatic_kicker.html | 5 +-
.../NXmagnetic_kicker.html | 5 +-
.../contributed_definitions/NXquadric.html | 5 +-
.../NXquadrupole_magnet.html | 5 +-
.../contributed_definitions/NXseparator.html | 5 +-
.../contributed_definitions/NXsnsevent.html | 5 +-
.../contributed_definitions/NXsnshisto.html | 5 +-
.../NXsolenoid_magnet.html | 5 +-
.../NXsolid_geometry.html | 5 +-
.../contributed_definitions/NXspecdata.html | 7 +--
.../NXspin_rotator.html | 5 +-
.../contributed_definitions/index.html | 5 +-
.../html/classes/index.html | 7 +--
nx-class-documentation/html/colophon.html | 5 +-
nx-class-documentation/html/community.html | 5 +-
nx-class-documentation/html/copyright.html | 5 +-
nx-class-documentation/html/datarules.html | 23 ++++----
nx-class-documentation/html/defs_intro.html | 7 +--
nx-class-documentation/html/design.html | 20 +++----
nx-class-documentation/html/docs_about.html | 5 +-
.../html/examples/code_napi.html | 9 ++-
.../html/examples/code_native.html | 5 +-
.../html/examples/epics/index.html | 27 +++++----
.../html/examples/h5py/index.html | 13 ++---
.../html/examples/h5py/writer_1_3.html | 7 +--
.../html/examples/h5py/writer_2_1.html | 5 +-
.../html/examples/index.html | 5 +-
.../html/examples/lrmecs/index.html | 7 +--
.../html/examples/matlab/index.html | 5 +-
nx-class-documentation/html/faq.html | 8 +--
nx-class-documentation/html/fileformat.html | 5 +-
nx-class-documentation/html/genindex.html | 3 +-
nx-class-documentation/html/github.html | 5 +-
nx-class-documentation/html/history.html | 11 ++--
nx-class-documentation/html/index.html | 7 +--
nx-class-documentation/html/installation.html | 9 ++-
.../html/introduction-napi.html | 21 ++++---
nx-class-documentation/html/introduction.html | 7 +--
nx-class-documentation/html/issues.html | 5 +-
nx-class-documentation/html/mailinglist.html | 5 +-
nx-class-documentation/html/motivations.html | 5 +-
nx-class-documentation/html/napi-c.html | 5 +-
nx-class-documentation/html/napi-f77.html | 5 +-
nx-class-documentation/html/napi-f90.html | 5 +-
nx-class-documentation/html/napi-idl.html | 5 +-
nx-class-documentation/html/napi-java.html | 5 +-
nx-class-documentation/html/napi.html | 5 +-
nx-class-documentation/html/niac.html | 7 +--
nx-class-documentation/html/nxdl-types.html | 5 +-
nx-class-documentation/html/nxdl.html | 9 ++-
nx-class-documentation/html/nxdl_desc.html | 5 +-
nx-class-documentation/html/preface.html | 5 +-
nx-class-documentation/html/ref_doc.html | 5 +-
nx-class-documentation/html/revhistory.html | 5 +-
nx-class-documentation/html/rules.html | 5 +-
nx-class-documentation/html/search.html | 3 +-
nx-class-documentation/html/searchindex.js | 2 +-
nx-class-documentation/html/strategies.html | 5 +-
nx-class-documentation/html/user_manual.html | 5 +-
nx-class-documentation/html/utilities.html | 57 +++++++++----------
nx-class-documentation/html/validation.html | 5 +-
159 files changed, 403 insertions(+), 559 deletions(-)
diff --git a/nx-class-documentation/html/applying-nexus.html b/nx-class-documentation/html/applying-nexus.html
index 99ab54dc6..47ed1fa7c 100644
--- a/nx-class-documentation/html/applying-nexus.html
+++ b/nx-class-documentation/html/applying-nexus.html
@@ -1,13 +1,12 @@
-
-
+
1.3. Constructing NeXus Files and Application Definitions — nexus v2020.10 documentation
@@ -790,7 +789,7 @@ Navigation
\ No newline at end of file
diff --git a/nx-class-documentation/html/authorgroup.html b/nx-class-documentation/html/authorgroup.html
index 736586ba3..285aabff1 100644
--- a/nx-class-documentation/html/authorgroup.html
+++ b/nx-class-documentation/html/authorgroup.html
@@ -1,13 +1,12 @@
-
-
+
9.1. Authors — nexus v2020.10 documentation
@@ -152,7 +151,7 @@ Navigation
\ No newline at end of file
diff --git a/nx-class-documentation/html/classes/applications/NXarchive.html b/nx-class-documentation/html/classes/applications/NXarchive.html
index da46f168f..77f79b58b 100644
--- a/nx-class-documentation/html/classes/applications/NXarchive.html
+++ b/nx-class-documentation/html/classes/applications/NXarchive.html
@@ -1,13 +1,12 @@
-
-
+
3.3.2.1. NXarchive — nexus v2020.10 documentation
@@ -451,7 +450,7 @@ Navigation
\ No newline at end of file
diff --git a/nx-class-documentation/html/classes/applications/NXarpes.html b/nx-class-documentation/html/classes/applications/NXarpes.html
index 8f214dd91..8b6d450eb 100644
--- a/nx-class-documentation/html/classes/applications/NXarpes.html
+++ b/nx-class-documentation/html/classes/applications/NXarpes.html
@@ -1,13 +1,12 @@
-
-
+
3.3.2.2. NXarpes — nexus v2020.10 documentation
@@ -370,7 +369,7 @@ Navigation
\ No newline at end of file
diff --git a/nx-class-documentation/html/classes/applications/NXcanSAS.html b/nx-class-documentation/html/classes/applications/NXcanSAS.html
index b93292b91..fb1b7bfdb 100644
--- a/nx-class-documentation/html/classes/applications/NXcanSAS.html
+++ b/nx-class-documentation/html/classes/applications/NXcanSAS.html
@@ -1,13 +1,12 @@
-
-
+
3.3.2.3. NXcanSAS — nexus v2020.10 documentation
@@ -192,7 +191,7 @@ Navigation
Use the Unidata UDunits specification
as this is compatible with various community standards.