Esempio n. 1
0
def test_multiple_relative_transform_paths_are_converted_to_absolute_path_in_dependee_of_field(
        file, nexus_wrapper):
    component_name = "component_1"

    component1 = add_component_to_file(nexus_wrapper,
                                       component_name=component_name)
    # make depends_on point to relative transformations group
    component1.group["depends_on"] = "transformations/transform1"

    transformations_group = component1.group.create_group("transformations")

    transform1_name = "transform1"
    transform1_dataset = transformations_group.create_dataset(transform1_name,
                                                              data=1)
    transform1_dataset.attrs[CommonAttrs.VECTOR] = qvector3d_to_numpy_array(
        QVector3D(1, 0, 0))
    transform1_dataset.attrs[
        CommonAttrs.TRANSFORMATION_TYPE] = TransformationType.TRANSLATION

    transform2_name = "transform2"

    # make transform1 depends_on point to relative transform in same directory
    transform1_dataset.attrs["depends_on"] = transform2_name

    transform2_dataset = transformations_group.create_dataset(transform2_name,
                                                              data=2)
    transform2_dataset.attrs[CommonAttrs.VECTOR] = qvector3d_to_numpy_array(
        QVector3D(1, 1, 0))
    transform2_dataset.attrs[
        CommonAttrs.TRANSFORMATION_TYPE] = TransformationType.TRANSLATION

    # make sure the depends_on points to the absolute path of the transform it depends on in the file
    assert (Transformation(
        nexus_wrapper,
        transform1_dataset).depends_on.dataset.name == transform2_dataset.name)
Esempio n. 2
0
 def add_rotation(
     self,
     axis: QVector3D,
     angle: float,
     name: str = None,
     depends_on: Transformation = None,
 ) -> Transformation:
     """
     Note, currently assumes angle is in degrees
     :param axis: axis
     :param angle:
     :param name: Name of the rotation group (Optional)
     :param depends_on: existing transformation which the new one depends on (otherwise relative to origin)
     """
     transforms_group = self.file.create_transformations_group_if_does_not_exist(
         self.group)
     if name is None:
         name = _generate_incremental_name(TransformationType.ROTATION,
                                           transforms_group)
     field = self.file.set_field_value(transforms_group, name, angle, float)
     self.file.set_attribute_value(field, CommonAttrs.UNITS, "degrees")
     self.file.set_attribute_value(field, CommonAttrs.VECTOR,
                                   qvector3d_to_numpy_array(axis))
     self.file.set_attribute_value(field, CommonAttrs.TRANSFORMATION_TYPE,
                                   TransformationType.ROTATION)
     rotation_transform = Transformation(self.file, field)
     rotation_transform.depends_on = depends_on
     rotation_transform.ui_value = angle
     return rotation_transform
Esempio n. 3
0
    def _create_transform(
        self,
        name: str,
        transformation_type: TransformationType,
        angle_or_magnitude: float,
        units: str,
        vector: QVector3D,
        depends_on: Transformation,
    ):
        transforms_group = self.file.create_transformations_group_if_does_not_exist(
            self.group
        )
        if name is None:
            name = _generate_incremental_name(transformation_type, transforms_group)

        field = self.file.set_field_value(
            transforms_group, name, angle_or_magnitude, float
        )
        self.file.set_attribute_value(field, CommonAttrs.UNITS, units)
        self.file.set_attribute_value(
            field, CommonAttrs.VECTOR, qvector3d_to_numpy_array(vector)
        )
        self.file.set_attribute_value(
            field, CommonAttrs.TRANSFORMATION_TYPE, transformation_type
        )
        transform = create_transformation(self.file, field)
        transform.ui_value = angle_or_magnitude
        transform.depends_on = depends_on
        return transform
Esempio n. 4
0
    def add_translation(self,
                        vector: QVector3D,
                        name: str = None,
                        depends_on: Transformation = None) -> Transformation:
        """
        Note, currently assumes translation is in metres
        :param vector: direction and magnitude of translation as a 3D vector
        :param name: name of the translation group (Optional)
        :param depends_on: existing transformation which the new one depends on (otherwise relative to origin)
        """
        transforms_group = self.file.create_transformations_group_if_does_not_exist(
            self.group)
        if name is None:
            name = _generate_incremental_name(TransformationType.TRANSLATION,
                                              transforms_group)
        unit_vector, magnitude = _normalise(vector)
        field = self.file.set_field_value(transforms_group, name, magnitude,
                                          float)
        self.file.set_attribute_value(field, CommonAttrs.UNITS, "m")
        self.file.set_attribute_value(field, CommonAttrs.VECTOR,
                                      qvector3d_to_numpy_array(unit_vector))
        self.file.set_attribute_value(field, CommonAttrs.TRANSFORMATION_TYPE,
                                      TransformationType.TRANSLATION)

        translation_transform = Transformation(self.file, field)
        translation_transform.ui_value = magnitude
        translation_transform.depends_on = depends_on
        return translation_transform
Esempio n. 5
0
def test_GIVEN_a_PixelShape_WHEN_calling_get_shape_THEN_shape_and_transformations_are_returned(
    nexus_wrapper, ):
    detector_group = nexus_wrapper.create_nx_group("detector", "NXdetector",
                                                   nexus_wrapper.instrument)
    shape_group = nexus_wrapper.create_nx_group("pixel_shape",
                                                "NXoff_geometry",
                                                detector_group)

    # Populate shape group
    vertices = [
        [-0.05, -0.05, 0.0],
        [0.05, -0.05, 0.0],
        [0.05, 0.05, 0.0],
        [-0.05, 0.05, 0.0],
    ]
    faces = [0]
    winding_order = [0, 1, 2, 3]

    vertices_field = nexus_wrapper.set_field_value(shape_group, "vertices",
                                                   vertices)
    nexus_wrapper.set_attribute_value(vertices_field, "units", "m")
    nexus_wrapper.set_field_value(shape_group, "winding_order", winding_order)
    nexus_wrapper.set_field_value(shape_group, "faces", faces)

    # Add pixel offsets to detector group
    x_offsets = np.array([[-0.05, 0.05], [-0.05, 0.05]])
    y_offsets = np.array([[-0.05, -0.05], [0.05, 0.05]])

    nexus_wrapper.set_field_value(detector_group, "x_pixel_offset", x_offsets)
    nexus_wrapper.set_field_value(detector_group, "y_pixel_offset", y_offsets)

    pixel_shape = PixelShape(nexus_wrapper, detector_group)
    assert isinstance(pixel_shape, PixelShape)
    shape, transformations = pixel_shape.get_shape()

    for vertex_index, vertex in enumerate(shape.vertices):
        assert np.allclose(qvector3d_to_numpy_array(vertex),
                           vertices[vertex_index])
    assert np.allclose(shape.faces, [winding_order])

    assert (len(transformations) == x_offsets.size
            ), "Expected one transformation per pixel offset"
    assert np.allclose(qvector3d_to_numpy_array(transformations[0]),
                       np.array([-0.05, -0.05, 0.0]))
    assert np.allclose(qvector3d_to_numpy_array(transformations[3]),
                       np.array([0.05, 0.05, 0.0]))
Esempio n. 6
0
 def record_vertices(self, new_vertices: List[QVector3D]):
     """
     Record vertex data in file
     :param new_vertices: The new vertices data, list of cartesian coords for each vertex
     """
     vertices = np.array(
         [qvector3d_to_numpy_array(vertex) for vertex in new_vertices])
     self.set_field_value(CommonAttrs.VERTICES, vertices, ValueTypes.FLOAT)
     self[CommonAttrs.VERTICES].attributes.set_attribute_value(
         CommonAttrs.UNITS, "m")
def record_vertices_in_file(nexus_wrapper: nx.NexusWrapper, group: h5py.Group,
                            new_vertices: List[QVector3D]):
    """
    Record vertex data in file
    :param nexus_wrapper: Wrapper for the file the data will be stored in
    :param group: The shape group node
    :param new_vertices: The new vertices data, list of cartesian coords for each vertex
    """
    vertices = [qvector3d_to_numpy_array(vertex) for vertex in new_vertices]
    vertices_node = nexus_wrapper.set_field_value(group, CommonAttrs.VERTICES,
                                                  vertices)
    nexus_wrapper.set_attribute_value(vertices_node, CommonAttrs.UNITS, "m")
Esempio n. 8
0
 def calculate_vertices(axis_direction: QVector3D, height: float,
                        radius: float) -> np.ndarray:
     """
     Given cylinder axis, height and radius, calculate the base centre, base edge and top centre vertices
     :param axis_direction: axis of the cylinder (not required to be unit vector)
     :param height: height of the cylinder
     :param radius: radius of the cylinder
     :return: base centre, base edge and top centre vertices as a numpy array
     """
     axis_direction = axis_direction.normalized()
     top_centre = axis_direction * height / 2.0
     base_centre = axis_direction * height / -2.0
     radial_direction = get_an_orthogonal_unit_vector(
         axis_direction).normalized()
     base_edge = base_centre + (radius * radial_direction)
     vertices = np.vstack((
         qvector3d_to_numpy_array(base_centre),
         qvector3d_to_numpy_array(base_edge),
         qvector3d_to_numpy_array(top_centre),
     ))
     return vertices
Esempio n. 9
0
def _add_transform_to_file(
    nexus_wrapper: NexusWrapper,
    name: str,
    value: Any,
    vector: QVector3D,
    transform_type: str,
):
    transform_dataset = nexus_wrapper.nexus_file.create_dataset(name,
                                                                data=value)
    transform_dataset.attrs[CommonAttrs.VECTOR] = qvector3d_to_numpy_array(
        vector)
    transform_dataset.attrs[CommonAttrs.TRANSFORMATION_TYPE] = transform_type
    return transform_dataset
Esempio n. 10
0
def test_transforms_with_no_dependees_return_None_for_depends_on(
        file, nexus_wrapper):
    component_name = "component_1"

    component1 = add_component_to_file(nexus_wrapper,
                                       component_name=component_name)
    # make depends_on point to relative transformations group
    component1.group["depends_on"] = "transformations/transform1"

    transformations_group = component1.group.create_group("transformations")

    transform1_name = "transform1"
    transform1_dataset = transformations_group.create_dataset(transform1_name,
                                                              data=1)
    transform1_dataset.attrs[CommonAttrs.VECTOR] = qvector3d_to_numpy_array(
        QVector3D(1, 0, 0))
    transform1_dataset.attrs[
        CommonAttrs.TRANSFORMATION_TYPE] = TransformationType.TRANSLATION

    transform1_dataset.attrs["depends_on"] = "."
    transformation = Transformation(nexus_wrapper, transform1_dataset)

    assert not transformation.depends_on