Example #1
0
def test_GIVEN_nexus_file_with_linked_transformation_but_without_dependee_of_attr_WHEN_opening_nexus_file_THEN_components_linked_contain_dependee_of_attribute(
):
    nexus_wrapper = NexusWrapper(str(uuid1()))
    transform_name = "transform_1"
    transform = create_transform(nexus_wrapper, transform_name)

    component1_name = "test_component1"
    component2_name = "test_component2"

    component1 = add_component_to_file(nexus_wrapper,
                                       component_name=component1_name)
    component2 = add_component_to_file(nexus_wrapper,
                                       component_name=component2_name)
    component1.depends_on = transform
    component2.depends_on = transform

    del transform._dataset.attrs[CommonAttrs.DEPENDEE_OF]

    nexus_wrapper.load_nexus_file(nexus_wrapper.nexus_file)
    new_transform_group = nexus_wrapper.nexus_file[transform_name]

    assert CommonAttrs.DEPENDEE_OF in new_transform_group.attrs
    assert len(new_transform_group.attrs[CommonAttrs.DEPENDEE_OF]) == 2
    assert (new_transform_group.attrs[CommonAttrs.DEPENDEE_OF][0] == "/" +
            component1_name)
    assert (new_transform_group.attrs[CommonAttrs.DEPENDEE_OF][1] == "/" +
            component2_name)
Example #2
0
def test_transform_dependents_depends_on_are_updated_when_transformation_name_is_changed(
):
    nexus_wrapper = NexusWrapper(str(uuid1()))

    test_name = "slartibartfast"
    test_value = 42
    test_vector = QVector3D(1.0, 0.0, 0.0)
    test_type = "Translation"

    transform_dataset = _add_transform_to_file(nexus_wrapper, test_name,
                                               test_value, test_vector,
                                               test_type)

    component = nexus_wrapper.create_nx_group("test", "NXaperture",
                                              nexus_wrapper.nexus_file)

    component.create_dataset("depends_on", data=transform_dataset.name)

    transform = Transformation(nexus_wrapper, transform_dataset)
    transform.register_dependent(Component(nexus_wrapper, component))

    new_name = test_name + "1"

    transform.name = new_name

    assert transform.name == new_name
    assert str(component["depends_on"][()],
               encoding="UTF-8") == transform.dataset.name
Example #3
0
def test_dependee_of_contains_both_components_when_generating_dependee_of_chain_with_mixture_of_absolute_and_relative_paths(
        file,  # noqa: F811
):
    entry_group = file.create_group("entry")
    entry_group.attrs["NX_class"] = "NXentry"
    instrument_group = entry_group.create_group("instrument")
    instrument_group.attrs["NX_class"] = "NXinstrument"

    component_a = instrument_group.create_group("a")
    component_a.attrs["NX_class"] = "NXaperture"
    transforms_group = component_a.create_group("Transforms1")
    transform_1 = transforms_group.create_dataset("transform1", data=1.0)
    # Relative path to transform
    component_a.create_dataset("depends_on", data="Transforms1/transform1")

    component_b = instrument_group.create_group("b")
    component_b.attrs["NX_class"] = "NXaperture"
    # Absolute path to transform
    component_b.create_dataset(
        "depends_on", data="/entry/instrument/a/Transforms1/transform1")

    nexus_wrapper = NexusWrapper("test_dependent_transforms_1")
    nexus_wrapper.load_file(entry_group, file)
    Instrument(nexus_wrapper, NX_CLASS_DEFINITIONS)
    transform_1_loaded = Transformation(nexus_wrapper, transform_1)

    # Check both relative and absolute are in dependee_of list
    assert component_a.name in transform_1_loaded.dataset.attrs[
        "NCdependee_of"]
    assert component_b.name in transform_1_loaded.dataset.attrs[
        "NCdependee_of"]
Example #4
0
def test_GIVEN_stream_group_that_has_ev42_advanced_option_WHEN_filling_in_existing_field_widget_THEN_ev42_group_box_is_shown(
        file, qtbot):
    group = file.create_group("stream2")
    group.attrs["NX_class"] = "NCstream"

    vlen_str = h5py.special_dtype(vlen=str)
    group.create_dataset("writer_module", dtype=vlen_str, data="ev42")
    group.create_dataset("topic", dtype=vlen_str, data="topic1")
    group.create_dataset("source", dtype=vlen_str, data="source1")
    group.create_dataset(ADC_PULSE_DEBUG, dtype=bool, data=True)

    wrapper = NexusWrapper()
    wrapper.load_file(file, file)

    instrument = Instrument(wrapper, {})

    widget = FieldWidget(instrument=instrument)
    qtbot.addWidget(widget)

    update_existing_stream_field(group, widget)

    # this would usually be done outside of the update_existing_stream_field
    widget.name = get_name_of_node(group)

    assert widget.streams_widget.ev42_advanced_group_box.isEnabled()

    generated_group = widget.streams_widget.get_stream_group()
    assert generated_group["writer_module"][()] == group["writer_module"][()]
    assert generated_group["topic"][()] == group["topic"][()]
    assert generated_group["source"][()] == group["source"][()]
    assert generated_group[ADC_PULSE_DEBUG][()] == group[ADC_PULSE_DEBUG][()]
Example #5
0
def test_GIVEN_no_entry_or_instrument_in_file_WHEN_finding_entry_THEN_default_entry_and_instrument_are_created(
    file, ):
    wrapper = NexusWrapper(filename="test_nw5")
    wrapper.find_entries_in_file(file)

    assert isinstance(wrapper.entry, h5py.Group)
    assert isinstance(wrapper.instrument, h5py.Group)
Example #6
0
def test_GIVEN_multiple_entry_groups_in_file_WHEN_finding_entry_THEN_signal_is_emitted_with_entry_options(
):
    with InMemoryFile("test_file") as file:
        entry = file.create_group("entry")
        # Test with byte string as well as python string.
        entry.attrs["NX_class"] = b"NXentry"

        inst_group = entry.create_group("instrument")
        inst_group.attrs["NX_class"] = "NXinstrument"

        entry2 = file.create_group("entry2")
        entry2.attrs["NX_class"] = "NXentry"

        inst_group2 = entry2.create_group("instrument2")
        inst_group2.attrs["NX_class"] = "NXinstrument"

        wrapper = NexusWrapper(filename="test_nw7")
        wrapper.show_entries_dialog = Mock()
        wrapper.show_entries_dialog.emit = Mock()

        wrapper.find_entries_in_file(file)

        expected_entry_dict = {entry.name: entry, entry2.name: entry2}

        assert wrapper.show_entries_dialog.emit.called_once_with(
            expected_entry_dict, file)
Example #7
0
def test_validate_group_reports_problem_when_group_does_not_have_expected_nx_class(
):
    nexus_wrapper = NexusWrapper()
    group = nexus_wrapper.create_nx_group("test_group", "NXsomething",
                                          nexus_wrapper.nexus_file)

    problems = validate_group(group, "NXtest", ())
    assert (
        len(problems) > 0
    ), "Expected there to be a reported problem because group does not have expected NX_class"
Example #8
0
def test_validate_group_does_not_report_problem_when_group_has_expected_nx_class(
):
    nexus_wrapper = NexusWrapper()
    nexus_class = "NXtest"
    group = nexus_wrapper.create_nx_group("test_group", nexus_class,
                                          nexus_wrapper.nexus_file)

    problems = validate_group(group, nexus_class, ())
    assert (
        len(problems) == 0
    ), "Expected there to be no reported problem because group has expected NX_class"
Example #9
0
def create_component(nexus_wrapper: NexusWrapper,
                     component_group: h5py.Group) -> Component:
    if (nexus_wrapper.get_attribute_value(
            component_group, CommonAttrs.NX_CLASS) == CHOPPER_CLASS_NAME):
        return Component(nexus_wrapper, component_group,
                         ChopperShape(nexus_wrapper, component_group))
    if (nexus_wrapper.get_attribute_value(
            component_group, CommonAttrs.NX_CLASS) in PIXEL_COMPONENT_TYPES
            and "pixel_shape" in component_group):
        return Component(nexus_wrapper, component_group,
                         PixelShape(nexus_wrapper, component_group))
    return Component(nexus_wrapper, component_group)
Example #10
0
def test_GIVEN_group_with_bytes_attribute_WHEN_getting_attribute_value_THEN_returns_value_as_str(
):
    wrapper = NexusWrapper(filename="test_attr_as_str")
    test_group = wrapper.nexus_file.create_group("test_group")
    attr_value = b"test_attr_value"
    attr_name = "test_attr"
    test_group.attrs[attr_name] = attr_value

    attr_value_as_str = attr_value.decode("utf-8")

    assert wrapper.get_attribute_value(test_group,
                                       attr_name) == attr_value_as_str
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")
Example #12
0
def test_validate_dataset_reports_problem_when_expected_dataset_is_not_present(
):
    nexus_wrapper = NexusWrapper()
    nexus_wrapper.set_field_value(nexus_wrapper.nexus_file, "a_dataset", 0)

    dataset_name = "test_dataset"
    validator = ValidateDataset(dataset_name)
    problems = []
    validator.check(nexus_wrapper.nexus_file, problems)
    assert (
        len(problems) > 0
    ), "Expected there to be a reported problem because dataset is not present"
Example #13
0
def test_validate_dataset_reports_problem_when_expected_attribute_is_not_present(
):
    nexus_wrapper = NexusWrapper()
    dataset_name = "test_dataset"
    nexus_wrapper.set_field_value(nexus_wrapper.nexus_file, dataset_name, 0)

    validator = ValidateDataset(dataset_name,
                                attributes={"test_attribute": None})
    problems = []
    validator.check(nexus_wrapper.nexus_file, problems)
    assert (
        len(problems) > 0
    ), "Expected there to be a reported problem because attribute is not present"
Example #14
0
def test_GIVEN_variable_length_string_type_dataset_WHEN_getting_value_THEN_returned_as_str(
):
    wrapper = NexusWrapper(filename="test_read_vlen_str_dataset")
    dataset_name = "vlen_str_dataset"
    string_data = b"This is a string"
    wrapper.nexus_file.create_dataset(dataset_name,
                                      dtype=h5py.special_dtype(vlen=str),
                                      data=string_data)

    assert wrapper.get_field_value(wrapper.nexus_file,
                                   dataset_name) == string_data.decode("utf8")
    assert isinstance(
        wrapper.get_field_value(wrapper.nexus_file, dataset_name), str)
def record_faces_in_file(nexus_wrapper: nx.NexusWrapper, group: h5py.Group,
                         new_faces: List[List[int]]):
    """
    Record face data in file
    :param nexus_wrapper: Wrapper for the file the data will be stored in
    :param group: The shape group node
    :param new_faces: The new face data, list of list for each face with indices of vertices in face
    """
    winding_order = [index for new_face in new_faces for index in new_face]
    nexus_wrapper.set_field_value(group, "winding_order", winding_order)
    faces_length = [0]
    faces_length.extend([len(new_face) for new_face in new_faces[:-1]])
    faces_start_indices = np.cumsum(faces_length)
    nexus_wrapper.set_field_value(group, "faces", faces_start_indices)
Example #16
0
def test_GIVEN_entry_group_with_one_instrument_group_WHEN_getting_instrument_group_from_entry_THEN_group_is_returned(
    file, ):
    entry = file.create_group("entry")
    entry.attrs["NX_class"] = "NXentry"

    inst_group = entry.create_group("instrument")
    inst_group.attrs["NX_class"] = "NXinstrument"

    wrapper = NexusWrapper(filename="test_nw")
    wrapper.load_file(entry, file)

    assert wrapper.instrument == inst_group
    assert wrapper.entry == entry
    assert wrapper.nexus_file == file
Example #17
0
def test_GIVEN_single_entry_group_with_instrument_group_WHEN_finding_entry_THEN_file_is_loaded_correctly(
    file, ):
    entry = file.create_group("entry")
    entry.attrs["NX_class"] = "NXentry"

    inst_group = entry.create_group("instrument")
    inst_group.attrs["NX_class"] = "NXinstrument"

    wrapper = NexusWrapper(filename="test_nw5")

    wrapper.find_entries_in_file(file)

    assert wrapper.nexus_file == file
    assert wrapper.entry == entry
    assert wrapper.instrument == inst_group
Example #18
0
def test_can_set_transform_properties():
    nexus_wrapper = NexusWrapper(str(uuid1()))

    initial_name = "slartibartfast"

    transform = create_transform(nexus_wrapper, initial_name)

    test_name = "beeblebrox"
    test_value = 34.0
    test_vector = QVector3D(0.0, 0.0, 1.0)
    test_type = "Rotation"

    transform.name = test_name
    transform.value = test_value
    transform.vector = test_vector
    transform.type = test_type

    assert (
        transform.name == test_name
    ), "Expected the transform name to match what was in the NeXus file"
    assert (
        transform.value == test_value
    ), "Expected the transform value to match what was in the NeXus file"
    assert (
        transform.vector == test_vector
    ), "Expected the transform vector to match what was in the NeXus file"
    assert (
        transform.type == test_type
    ), "Expected the transform type to match what was in the NeXus file"
Example #19
0
def test_validate_dataset_does_not_report_problem_when_dataset_has_expected_shape(
):
    nexus_wrapper = NexusWrapper()
    dataset_name = "test_dataset"
    dataset_value = np.array(list(range(12)))
    dataset_shape = (3, 4)
    dataset_value = np.reshape(dataset_value, dataset_shape)
    nexus_wrapper.set_field_value(nexus_wrapper.nexus_file, dataset_name,
                                  dataset_value)

    validator = ValidateDataset(dataset_name, shape=dataset_shape)
    problems = []
    validator.check(nexus_wrapper.nexus_file, problems)
    assert (
        len(problems) == 0
    ), "Expected there to be no reported problem because dataset has expected shape"
Example #20
0
def test_can_get_transform_properties():
    nexus_wrapper = NexusWrapper(str(uuid1()))

    test_name = "slartibartfast"
    test_value = 42
    test_vector = QVector3D(1.0, 0.0, 0.0)
    test_type = "Translation"

    transform_dataset = _add_transform_to_file(nexus_wrapper, test_name,
                                               test_value, test_vector,
                                               test_type)

    transform = Transformation(nexus_wrapper, transform_dataset)

    assert (
        transform.name == test_name
    ), "Expected the transform name to match what was in the NeXus file"
    assert (
        transform.ui_value == test_value
    ), "Expected the transform value to match what was in the NeXus file"
    assert (
        transform.vector == test_vector
    ), "Expected the transform vector to match what was in the NeXus file"
    assert (
        transform.type == test_type
    ), "Expected the transform type to match what was in the NeXus file"
def test_UI_GIVEN_scalar_angle_WHEN_creating_rotation_view_THEN_ui_is_filled_correctly(
    qtbot,
):
    wrapper = NexusWrapper()
    instrument = Instrument(wrapper, {})

    component = instrument.create_component("test", "NXaperture", "")

    x = 1
    y = 2
    z = 3
    angle = 90

    transform = component.add_rotation(angle=angle, axis=QVector3D(x, y, z))

    view = EditRotation(parent=None, transformation=transform, instrument=instrument)
    qtbot.addWidget(view)

    assert view.transformation_frame.x_spinbox.value() == x
    assert view.transformation_frame.y_spinbox.value() == y
    assert view.transformation_frame.z_spinbox.value() == z
    assert view.transformation_frame.value_spinbox.value() == angle
    assert view.transformation_frame.magnitude_widget.value[()] == angle
    assert (
        view.transformation_frame.magnitude_widget.field_type
        == FieldType.scalar_dataset
    )
def test_UI_GIVEN_new_values_are_provided_WHEN_save_changes_is_called_THEN_transformation_changed_signal_is_called_to_update_3d_view(
    qtbot,
):
    wrapper = NexusWrapper()
    instrument = Instrument(wrapper, {})

    component = instrument.create_component("test", "NXaperture", "")

    x = 1
    y = 2
    z = 3
    angle = 90

    transform = component.add_rotation(angle=angle, axis=QVector3D(x, y, z))

    view = EditRotation(parent=None, transformation=transform, instrument=instrument)
    instrument.nexus.transformation_changed = Mock()
    qtbot.addWidget(view)

    new_x = 4

    view.transformation_frame.x_spinbox.setValue(new_x)
    view.saveChanges()
    instrument.nexus.transformation_changed.emit.assert_called_once()
    assert transform.vector == QVector3D(new_x, y, z)
def test_UI_GIVEN_vector_updated_WHEN_saving_view_changes_THEN_model_is_updated(qtbot):
    wrapper = NexusWrapper()
    instrument = Instrument(wrapper, {})

    component = instrument.create_component("test", "NXaperture", "")

    x = 1
    y = 2
    z = 3
    angle = 90

    transform = component.add_rotation(angle=angle, axis=QVector3D(x, y, z))

    view = EditRotation(parent=None, transformation=transform, instrument=instrument)
    qtbot.addWidget(view)

    new_x = 4
    new_y = 5
    new_z = 6

    view.transformation_frame.x_spinbox.setValue(new_x)
    view.transformation_frame.y_spinbox.setValue(new_y)
    view.transformation_frame.z_spinbox.setValue(new_z)

    view.saveChanges()

    assert transform.vector == QVector3D(new_x, new_y, new_z)
def create_transformation(trans_type: TransformationType):
    file = NexusWrapper(str(uuid.uuid4()))
    ds = file.nexus_file.create_dataset("transform", data=8)
    t = Transformation(file, ds)
    t.type = trans_type
    t.vector = QVector3D(1, 0, 0)
    return t
Example #25
0
def test_GIVEN_instrument_with_component_WHEN_component_is_removed_THEN_components_list_does_not_contain_component(
):
    wrapper = NexusWrapper("test_components_list")
    instrument = Instrument(wrapper, NX_CLASS_DEFINITIONS)

    component_type = "NXcrystal"
    name = "test_crystal"
    description = "shiny"
    test_component = instrument.create_component(name, component_type,
                                                 description)

    # Test component should be in list
    check_if_component_is_in_component_list(component_type,
                                            description,
                                            instrument,
                                            name,
                                            expect_component_present=True)

    instrument.remove_component(test_component)

    # Test component should no longer be in list
    check_if_component_is_in_component_list(component_type,
                                            description,
                                            instrument,
                                            name,
                                            expect_component_present=False)
def test_UI_GIVEN_array_dataset_as_magnitude_WHEN_creating_translation_THEN_ui_is_filled_correctly(
    qtbot, file  # noqa:F811
):
    wrapper = NexusWrapper()
    instrument = Instrument(wrapper, {})

    component = instrument.create_component("test", "NXaperture", "")

    array = np.array([1, 2, 3, 4])

    x = 1
    y = 0
    z = 0
    transform = component.add_translation(QVector3D(x, y, z), name="test")

    transform.dataset = file.create_dataset("test", data=array)

    view = EditTranslation(parent=None, transformation=transform, instrument=instrument)
    qtbot.addWidget(view)

    assert view.transformation_frame.x_spinbox.value() == x
    assert view.transformation_frame.y_spinbox.value() == y
    assert view.transformation_frame.z_spinbox.value() == z
    assert np.allclose(view.transformation.dataset[...], array)
    assert (
        view.transformation_frame.magnitude_widget.field_type == FieldType.array_dataset
    )
Example #27
0
def test_GIVEN_instrument_containing_component_WHEN_generating_json_THEN_file_is_written_containing_components(
):
    file = io.StringIO(newline=None)
    wrapper = NexusWrapper("test.nxs")
    data = Instrument(wrapper, NX_CLASS_DEFINITIONS)

    component_name = "pinhole"
    component_nx_class = "NXpinhole"

    dataset_name = "depends_on"
    dataset_value = "something_else"

    component = data.create_component(component_name, component_nx_class, "")
    component.set_field(dataset_name, value=dataset_value, dtype=str)

    write_nexus_structure_to_json(data, file)

    output_file_dict = json.loads(file.getvalue())

    component = output_file_dict["children"][0]["children"][0]["children"][0]

    assert component["name"].lstrip("/entry/instrument/") == component_name
    assert (component["children"][0]["name"].lstrip(
        f"/entry/instrument/{component_name}/") == dataset_name)
    assert component["children"][0]["type"] == "dataset"
    assert component["children"][0]["values"] == dataset_value
    assert component["children"][0]["dataset"]["type"] == "string"
Example #28
0
def test_can_get_rotation_as_4_by_4_matrix():
    nexus_wrapper = NexusWrapper(str(uuid1()))

    test_value = 45.0  # degrees
    test_vector = QVector3D(0.0, 1.0, 0.0)  # around y-axis
    test_type = "Rotation"
    dataset = _add_transform_to_file(nexus_wrapper, "test_transform",
                                     test_value, test_vector, test_type)
    transformation = Transformation(nexus_wrapper, dataset)

    test_matrix = transformation.qmatrix
    # for a rotation around the y-axis:
    test_value_radians = np.deg2rad(test_value)
    expected_matrix = np.array((
        np.cos(-test_value_radians),
        0,
        np.sin(-test_value_radians),
        0,
        0,
        1,
        0,
        0,
        -np.sin(-test_value_radians),
        0,
        np.cos(-test_value_radians),
        0,
        0,
        0,
        0,
        1,
    ))
    assert np.allclose(expected_matrix,
                       np.array(test_matrix.data()),
                       atol=1.0e-7)
def test_UI_GIVEN_link_as_rotation_magnitude_WHEN_creating_rotation_view_THEN_ui_is_filled_correctly(
    qtbot,
):
    wrapper = NexusWrapper(filename="asdfgsdfh")
    instrument = Instrument(wrapper, {})

    component = instrument.create_component("test", "NXaperture", "")

    x = 0
    y = 0
    z = 0
    path = "/entry"

    transform = component.add_rotation(QVector3D(x, y, z), 0, name="test")
    link = wrapper.instrument["asdfgh"] = h5py.SoftLink(path)

    transform.dataset = link

    view = EditRotation(parent=None, transformation=transform, instrument=instrument)
    qtbot.addWidget(view)

    assert view.transformation_frame.x_spinbox.value() == x
    assert view.transformation_frame.y_spinbox.value() == y
    assert view.transformation_frame.z_spinbox.value() == z
    assert view.transformation_frame.value_spinbox.value() == 0.0
    assert view.transformation_frame.magnitude_widget.field_type == FieldType.link
    assert view.transformation_frame.magnitude_widget.value.path == path
Example #30
0
def test_GIVEN_component_with_cylindrical_shape_information_WHEN_duplicating_component_THEN_shape_information_is_stored_in_nexus_file(
):
    wrapper = NexusWrapper("test_duplicate_cyl_shape")
    instrument = Instrument(wrapper, NX_CLASS_DEFINITIONS)

    first_component_name = "component1"
    first_component_nx_class = "NXdetector"
    description = "desc"
    first_component = instrument.create_component(first_component_name,
                                                  first_component_nx_class,
                                                  description)

    axis_direction = QVector3D(1, 0, 0)
    height = 2
    radius = 3
    units = "cm"
    first_component.set_cylinder_shape(axis_direction=axis_direction,
                                       height=height,
                                       radius=radius,
                                       units=units)
    tree_model = ComponentTreeModel(instrument)

    first_component_index = tree_model.index(0, 0, QModelIndex())
    tree_model.duplicate_node(first_component_index)

    assert tree_model.rowCount(QModelIndex()) == 3
    second_component_index = tree_model.index(2, 0, QModelIndex())
    second_component = second_component_index.internalPointer()
    second_shape, _ = second_component.shape
    assert second_shape.axis_direction == axis_direction
    assert second_shape.height == height
    assert second_shape.units == units