Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

ECDC-3526-NXtransformations_offsets #1042

Merged
merged 43 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
847b38a
updated text fields
ggoneiESS Oct 9, 2023
c6c4645
updated text
ggoneiESS Oct 9, 2023
d07ed1f
vector for offset
ggoneiESS Oct 9, 2023
778ca02
working vector for offset
ggoneiESS Oct 9, 2023
3bd3b61
magic missing widgets
ggoneiESS Oct 9, 2023
54a6636
fixed typo
ggoneiESS Oct 9, 2023
d8f5f3f
no crashes stash
ggoneiESS Oct 10, 2023
528b920
Merge branch 'main' into ECDC-3526-NXtransformations_offsets
ggoneiESS Oct 10, 2023
95bfcb5
latest changes stash
ggoneiESS Oct 12, 2023
56691af
fixed translation issue
ggoneiESS Oct 12, 2023
de34010
Update NeXus HTML documentation
cow-bot Oct 12, 2023
01690fc
Merge branch 'ECDC-3621-move-object' into ECDC-3526-NXtransformations…
ggoneiESS Oct 12, 2023
cb9fb09
offset vector
ggoneiESS Oct 12, 2023
f2bf8ff
offset working in appearance but not adjjustment
ggoneiESS Oct 12, 2023
090f3aa
triggers all working
ggoneiESS Oct 13, 2023
a9ba6df
test fixing
ggoneiESS Oct 13, 2023
3fe8960
tests fixed
ggoneiESS Oct 13, 2023
0e0b063
Merge commit 'fd997d62aab03717d872720095a28ce2b4a71291' into HEAD
yashikno Oct 13, 2023
1c50f1b
GO FORMAT YOURSELF (black)
cow-bot Oct 13, 2023
09c2d07
Update NeXus HTML documentation
cow-bot Oct 13, 2023
7751656
small refactor
ggoneiESS Oct 13, 2023
7f9ceee
review additions
ggoneiESS Oct 13, 2023
39b9863
missed qvector 3D
ggoneiESS Oct 16, 2023
e2d8d0f
GO FORMAT YOURSELF (black)
cow-bot Oct 16, 2023
da60c44
Update NeXus HTML documentation
cow-bot Oct 16, 2023
f5c7407
the WORKING units commit
ggoneiESS Oct 17, 2023
674e553
Working units with validator
ggoneiESS Oct 18, 2023
43bedad
json complete but units written twice
ggoneiESS Oct 18, 2023
6db3e97
Update NeXus HTML documentation
cow-bot Oct 18, 2023
2c9eb8a
offset_units read correctly
ggoneiESS Oct 24, 2023
5cce655
removed passing of current_vector
ggoneiESS Oct 24, 2023
30a1d08
fixed one test but why not the other
ggoneiESS Oct 24, 2023
f10cddc
GO FORMAT YOURSELF (black)
cow-bot Oct 24, 2023
76fd2a1
Update NeXus HTML documentation
cow-bot Oct 24, 2023
1402616
working tests
ggoneiESS Oct 24, 2023
8f4b165
fix for exporting offset only if present
ggoneiESS Oct 24, 2023
6c21773
small test change since zero offset not saved
ggoneiESS Oct 24, 2023
62c683a
Merge remote-tracking branch 'refs/remotes/origin/ECDC-3526-NXtransfo…
ggoneiESS Oct 24, 2023
97cc1f2
flake fix
ggoneiESS Oct 25, 2023
a39b9cf
GO FORMAT YOURSELF (black)
cow-bot Oct 25, 2023
e568035
Update NeXus HTML documentation
cow-bot Oct 25, 2023
a5e93cc
post-review commit
ggoneiESS Oct 25, 2023
499df19
initialise _ui_offset_scale_factor
ggoneiESS Oct 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nexus_constructor/common_attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class CommonAttrs:
NX_CLASS = "NX_class"
DEPENDS_ON = "depends_on"
TRANSFORMATION_TYPE = "transformation_type"
OFFSET_UNITS = "offset_units"
VECTOR = "vector"
UNITS = "units"
VERTICES = "vertices"
Expand Down
33 changes: 19 additions & 14 deletions nexus_constructor/field_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ def __init__(
):
super(FieldWidget, self).__init__(parent)

fix_horizontal_size = QSizePolicy()
fix_horizontal_size.setHorizontalPolicy(QSizePolicy.Fixed)

possible_field_names = []
self.default_field_types_dict = {}
self.streams_widget: StreamFieldsWidget = None
Expand Down Expand Up @@ -123,12 +126,10 @@ def __init__(
self.unit_validator = UnitValidator()
self.units_line_edit.setValidator(self.unit_validator)
self.units_line_edit.setMinimumWidth(20)
self.units_line_edit.setMaximumWidth(50)
unit_size_policy = QSizePolicy()
unit_size_policy.setHorizontalPolicy(QSizePolicy.Preferred)
unit_size_policy.setHorizontalStretch(1)
self.units_line_edit.setSizePolicy(unit_size_policy)

self.unit_validator.is_valid.connect(
partial(validate_line_edit, self.units_line_edit)
)
Expand All @@ -140,9 +141,6 @@ def __init__(
self.field_type_combo.currentTextChanged.connect(
self._open_edit_dialog_if_stream
)

fix_horizontal_size = QSizePolicy()
fix_horizontal_size.setHorizontalPolicy(QSizePolicy.Fixed)
self.field_type_combo.setSizePolicy(fix_horizontal_size)

self.value_type_combo: QComboBox = QComboBox()
Expand Down Expand Up @@ -179,14 +177,17 @@ def __init__(
self.attrs_button.clicked.connect(self.show_attrs_dialog)

self.layout = QHBoxLayout()
self.layout.addWidget(self.field_name_edit)
self.layout.addWidget(self.field_type_combo)
self.layout.addWidget(self.value_line_edit)
self.layout.addWidget(self.nx_class_combo)
self.layout.addWidget(self.edit_button)
self.layout.addWidget(self.value_type_combo)
self.layout.addWidget(self.units_line_edit)
self.layout.addWidget(self.attrs_button)
for widget in [
self.field_name_edit,
self.field_type_combo,
self.value_line_edit,
self.nx_class_combo,
self.edit_button,
self.value_type_combo,
self.units_line_edit,
self.attrs_button,
]:
self.layout.addWidget(widget)

self.layout.setAlignment(Qt.AlignLeft)
self.setLayout(self.layout)
Expand Down Expand Up @@ -437,7 +438,11 @@ def field_type_changed(self):
self.edit_dialog = QDialog(parent=self)
self.edit_dialog.setModal(True)
self._set_up_value_validator(False)
if self.streams_widget and self.streams_widget._old_schema:
if (
self._node_parent
and self.streams_widget
and self.streams_widget._old_schema
):
self._node_parent.add_stream_module(self.streams_widget._old_schema)
if self.field_type == FieldType.scalar_dataset:
self.set_visibility(True, False, False, True)
Expand Down
24 changes: 17 additions & 7 deletions nexus_constructor/json/transformation_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
create_fw_module_object,
)
from nexus_constructor.model.transformation import Transformation
from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP, ValueTypes
from nexus_constructor.model.value_type import VALUE_TYPE_TO_NP
from nexus_constructor.transformations_list import TransformationsList

TRANSFORMATION_MAP = {
Expand Down Expand Up @@ -176,7 +176,7 @@ def _find_attribute_in_list(
:return: The value of the attribute if is is found in the list, otherwise the failure value is returned.
"""
attribute = _find_attribute_from_list_or_dict(attribute_name, attributes_list)
if not attribute and attribute_name not in [CommonAttrs.OFFSET]:
if not attribute:
ggoneiESS marked this conversation as resolved.
Show resolved Hide resolved
self.warnings.append(
TransformDependencyMissing(
f"Unable to find {attribute_name} attribute in transformation"
Expand Down Expand Up @@ -301,6 +301,19 @@ def _create_transformations(self, json_transformations: list):
vector = self._find_attribute_in_list(
CommonAttrs.VECTOR, name, attributes, [0.0, 0.0, 0.0]
)
offset_vector = self._find_attribute_in_list(
CommonAttrs.OFFSET, name, attributes, [0.0, 0.0, 0.0]
)

offset_units = self._find_attribute_in_list(
CommonAttrs.OFFSET_UNITS, name, attributes
)
if not offset_units:
if offset_vector is [0.0, 0.0, 0.0]:
continue
else:
offset_units = ""

danesss marked this conversation as resolved.
Show resolved Hide resolved
# This attribute is allowed to be missing, missing is equivalent to the value "." which means
# depends on origin (end of dependency chain)
depends_on = _find_attribute_from_list_or_dict(
Expand Down Expand Up @@ -337,12 +350,9 @@ def _create_transformations(self, json_transformations: list):
vector=QVector3D(*vector),
depends_on=None,
values=values,
offset_vector=QVector3D(*offset_vector),
offset_units=offset_units,
)
offset = self._find_attribute_in_list(CommonAttrs.OFFSET, name, attributes)
if offset:
transform.attributes.set_attribute_value(
CommonAttrs.OFFSET, offset, ValueTypes.FLOAT
)
if depends_on not in DEPENDS_ON_IGNORE:
depends_on_id = TransformId(
*get_component_and_transform_name(depends_on)
Expand Down
9 changes: 9 additions & 0 deletions nexus_constructor/model/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ def add_rotation(
type=ValueTypes.DOUBLE,
),
target_pos: int = -1,
offset_vector: Optional[QVector3D] = None,
offset_units: str = ""
) -> Transformation:
"""
Note, currently assumes angle is in degrees
Expand All @@ -263,6 +265,8 @@ def add_rotation(
depends_on,
values,
target_pos,
offset_vector if offset_vector is not None else QVector3D(0.0, 0.0, 0.0),
offset_units
)

def _create_and_add_transform(
Expand All @@ -275,6 +279,8 @@ def _create_and_add_transform(
depends_on: Transformation,
values: Union[Dataset, Group, StreamModule],
target_pos: int = -1,
offset_vector: Optional[QVector3D] = None,
offset_units: str = "",
) -> Transformation:
if name is None:
name = _generate_incremental_name(transformation_type, self.transforms)
Expand All @@ -296,7 +302,10 @@ def _create_and_add_transform(
transform.transform_type = transformation_type
transform.ui_value = angle_or_magnitude
transform.units = units
if offset_units != "":
transform.offset_units = offset_units
transform.vector = vector
transform.offset_vector = offset_vector
transform.depends_on = depends_on
transform.parent_component = self
if target_pos:
Expand Down
44 changes: 37 additions & 7 deletions nexus_constructor/model/transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numpy as np
from PySide6.Qt3DCore import Qt3DCore
from PySide6.QtGui import QMatrix4x4, QVector3D
from typing import Optional

from nexus_constructor.common_attrs import (
CommonAttrs,
Expand Down Expand Up @@ -38,6 +39,7 @@ class Transformation(Dataset):
_dependents = attr.ib(type=list, init=False)
_ui_value = attr.ib(type=float, default=None)
_ui_scale_factor = attr.ib(type=float, default=1.0, init=False)
_ui_offset_scale_factor = attr.ib(type=float, default=1.0, init=False)

@property
def absolute_path(self):
Expand Down Expand Up @@ -67,6 +69,23 @@ def vector(self, new_vector: QVector3D):
vector_as_np_array = np.array([new_vector.x(), new_vector.y(), new_vector.z()])
self.attributes.set_attribute_value(CommonAttrs.VECTOR, vector_as_np_array)

@property
def offset_vector(self) -> QVector3D:
ggoneiESS marked this conversation as resolved.
Show resolved Hide resolved
vector = self.attributes.get_attribute_value(CommonAttrs.OFFSET)
return (
QVector3D(vector[0], vector[1], vector[2])
if vector is not None
else QVector3D(0.0, 0.0, 0.0)
)

@offset_vector.setter
def offset_vector(self, new_vector: Optional[QVector3D]):
if new_vector:
vector_as_np_array = np.array(
[new_vector.x(), new_vector.y(), new_vector.z()]
)
self.attributes.set_attribute_value(CommonAttrs.OFFSET, vector_as_np_array)

@property
def ui_value(self) -> float:
try:
Expand Down Expand Up @@ -103,19 +122,18 @@ def qmatrix(self) -> QMatrix4x4:
"""
transform = Qt3DCore.QTransform()
transform.matrix()
offset = self.attributes.get_attribute_value(CommonAttrs.OFFSET)
if not offset:
offset = 0.0
if self.transform_type == TransformationType.ROTATION:
# apply offset first to translate it, and then apply rotation
transform.setTranslation(self.offset_vector * self._ui_offset_scale_factor)
quaternion = transform.fromAxisAndAngle(
self.vector, (self.ui_value + offset) * self._ui_scale_factor
self.vector, self.ui_value * self._ui_scale_factor
)

transform.setRotation(quaternion)
elif self.transform_type == TransformationType.TRANSLATION:
transform.setTranslation(
ggoneiESS marked this conversation as resolved.
Show resolved Hide resolved
self.vector.normalized()
* (self.ui_value + offset)
* self._ui_scale_factor
self.vector.normalized() * self.ui_value * self._ui_scale_factor
+ self.offset_vector * self._ui_offset_scale_factor
)
else:
raise (
Expand All @@ -132,6 +150,15 @@ def units(self, new_units):
self._evaluate_ui_scale_factor(new_units)
self.attributes.set_attribute_value(CommonAttrs.UNITS, new_units)

@property
def offset_units(self):
return self.attributes.get_attribute_value(CommonAttrs.OFFSET_UNITS)

@offset_units.setter
def offset_units(self, new_units):
self._evaluate_ui_offset_scale_factor(new_units)
self.attributes.set_attribute_value(CommonAttrs.OFFSET_UNITS, new_units)

def _evaluate_ui_scale_factor(self, units):
try:
if self.transform_type == TransformationType.TRANSLATION:
Expand All @@ -141,6 +168,9 @@ def _evaluate_ui_scale_factor(self, units):
except Exception:
pass

def _evaluate_ui_offset_scale_factor(self, units):
self._ui_offset_scale_factor = calculate_unit_conversion_factor(units, METRES)

@property
def depends_on(self) -> "Transformation":
return self.attributes.get_attribute_value(CommonAttrs.DEPENDS_ON)
Expand Down
56 changes: 34 additions & 22 deletions nexus_constructor/transformation_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ def __init__(self, parent: QWidget, transformation: Transformation, model: Model
self.transformation_frame = UiTransformation(self)
self.transformation = transformation
self.transformation_parent = transformation.parent_component
current_vector = self.transformation.vector
self._fill_in_existing_fields(current_vector)
self._fill_in_existing_fields()
self.transformation_frame.depends_on_text_box.setEnabled(False)
self.disable()
self._init_connections()
Expand All @@ -37,32 +36,44 @@ def _init_connections(self):
self.save_transformation_name
)

for box in self.transformation_frame.spinboxes[:-1]:
for box in self.transformation_frame.spinboxes:
box.textChanged.connect(self.save_transformation_vector)

for box in self.transformation_frame.offset_spinboxes:
box.textChanged.connect(self.save_offset)

self.transformation_frame.magnitude_widget.value_line_edit.textChanged.connect(
self.save_magnitude
)
self.transformation_frame.magnitude_widget.units_line_edit.textChanged.connect(
self.save_magnitude
)
self.transformation_frame.offset_units_line_edit.textChanged.connect(
self.save_offset
)
if self.model:
self.model.signals.transformation_changed.connect(self.update_depends_on_ui)

def _fill_in_existing_fields(self, current_vector):
def _fill_in_existing_fields(self):
self.transformation_frame.name_line_edit.setText(self.transformation.name)
self.transformation_frame.x_spinbox.setValue(current_vector.x())
self.transformation_frame.y_spinbox.setValue(current_vector.y())
self.transformation_frame.z_spinbox.setValue(current_vector.z())
self.transformation_frame.x_spinbox.setValue(self.transformation.vector.x())
self.transformation_frame.y_spinbox.setValue(self.transformation.vector.y())
self.transformation_frame.z_spinbox.setValue(self.transformation.vector.z())
update_function = find_field_type(self.transformation.values)
if update_function is not None:
update_function(
self.transformation.values, self.transformation_frame.magnitude_widget
)
self.transformation_frame.magnitude_widget.units = self.transformation.units
offset = self.transformation.attributes.get_attribute_value(CommonAttrs.OFFSET)
if offset:
self.transformation_frame.offset_box.setValue(offset)
if offset is not None:
self.transformation_frame.x_spinbox_offset.setValue(offset[0])
self.transformation_frame.y_spinbox_offset.setValue(offset[1])
self.transformation_frame.z_spinbox_offset.setValue(offset[2])
if self.transformation.offset_units:
self.transformation_frame.offset_units_line_edit.setText(
self.transformation.offset_units
)
self.update_depends_on_ui()

def disable(self):
Expand Down Expand Up @@ -110,29 +121,33 @@ def save_transformation_name(self):
self.model.signals.transformation_changed.emit()

def save_offset(self):
offset_value = self.transformation_frame.offset_box.value()
if offset_value is not None:
self.transformation.attributes.set_attribute_value(
CommonAttrs.OFFSET, offset_value
)
self.transformation.offset_vector = QVector3D(
*[spinbox.value() for spinbox in self.transformation_frame.offset_spinboxes]
)
if self.transformation_frame.offset_units:
self.transformation.offset_units = self.transformation_frame.offset_units
self.model.signals.transformation_changed.emit()

def save_all_changes(self):
self.save_transformation_name()
self.save_transformation_vector()
self.save_offset()
self.save_magnitude()

def transformation_text(self, transformation_type):
self.transformation_frame.vector_label.setText("Vector")
self.transformation_frame.value_label.setText("Magnitude")
self.transformation_frame.offset_label.setText("Offset")
self.setTitle(transformation_type)


class EditTranslation(EditTransformation):
def __init__(self, parent: QWidget, transformation: Transformation, model: Model):
super().__init__(parent, transformation, model)
self.transformation_frame.magnitude_widget.unit_validator.expected_dimensionality = (
METRES
)
self.transformation_frame.vector_label.setText("Direction")
self.transformation_frame.value_label.setText("Distance (m)")
self.transformation_frame.offset_label.setText("Offset (m)")
self.setTitle(TransformationType.TRANSLATION)
self.transformation_text(TransformationType.TRANSLATION)


class EditRotation(EditTransformation):
Expand All @@ -141,10 +156,7 @@ def __init__(self, parent: QWidget, transformation: Transformation, model: Model
self.transformation_frame.magnitude_widget.unit_validator.expected_dimensionality = (
RADIANS
)
self.transformation_frame.vector_label.setText("Rotation Axis")
self.transformation_frame.value_label.setText("Angle (°)")
self.transformation_frame.offset_label.setText("Offset (°)")
self.setTitle(TransformationType.ROTATION)
self.transformation_text(TransformationType.ROTATION)


def links_back_to_component(reference: Component, comparison: Component):
Expand Down
2 changes: 1 addition & 1 deletion nx-class-documentation/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ <h1>User Manual and Reference Documentation<a class="headerlink" href="#user-man
</div>
<hr class="docutils" />
<p class="rubric">Publishing Information</p>
<p>This manual built Oct 12, 2023.</p>
<p>This manual built Oct 25, 2023.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p>This document is available in these formats online:</p>
Expand Down
2 changes: 1 addition & 1 deletion nx-class-documentation/html/searchindex.js

Large diffs are not rendered by default.

Loading