예제 #1
0
    def test_load_projection_angles(self, getOpenFileName: mock.Mock,
                                    StackSelectorDialog: mock.Mock,
                                    ProjectionAngleFileParser: Mock,
                                    QMessageBox: Mock):
        StackSelectorDialog.return_value.exec.return_value = QDialog.Accepted
        selected_stack = "selected_stack"
        StackSelectorDialog.return_value.selected_stack = selected_stack

        selected_file = "~/home/test/directory/selected_file.txt"
        getOpenFileName.return_value = (selected_file, None)

        proj_angles = ProjectionAngles(np.arange(0, 10))
        ProjectionAngleFileParser.return_value.get_projection_angles.return_value = proj_angles

        self.view.load_projection_angles()

        StackSelectorDialog.assert_called_once_with(
            main_window=self.view,
            title='Stack Selector',
            message=self.view.LOAD_PROJECTION_ANGLES_DIALOG_MESSAGE)
        getOpenFileName.assert_called_once_with(
            caption=self.view.LOAD_PROJECTION_ANGLES_FILE_DIALOG_CAPTION,
            filter="All (*.*)")

        self.presenter.add_projection_angles_to_sample.assert_called_once_with(
            selected_stack, proj_angles)
        QMessageBox.information.assert_called_once()
    def test_set_projection_angles(self):
        images = generate_images()
        pangles = ProjectionAngles(list(range(0, 10)))
        images.set_projection_angles(pangles)

        actual = images.projection_angles()
        self.assertEqual(10, len(actual.value))
        self.assertAlmostEqual(images.projection_angles().value, pangles.value, places=4)
예제 #3
0
    def projection_angles(self) -> ProjectionAngles:
        angles = numpy.zeros(
            len(self._data[IMATLogColumn.IMAGE_TYPE_IMAGE_COUNTER]))
        for i, angle_str in enumerate(
                self._data[IMATLogColumn.IMAGE_TYPE_IMAGE_COUNTER]):
            assert "angle:" in angle_str
            angles[i] = float(angle_str[angle_str.rfind(": ") + 1:])

        return ProjectionAngles(numpy.deg2rad(angles))
예제 #4
0
    def test_add_projection_angles_to_sample_no_stack(self):
        proj_angles = ProjectionAngles(np.arange(0, 10))
        stack_name = "stack name"
        stack_mock = mock.MagicMock()
        self.model.get_stack_by_name = stack_mock
        stack_mock.return_value = None
        self.assertRaises(RuntimeError, self.model.add_projection_angles_to_sample, stack_name, proj_angles)

        stack_mock.assert_called_with(stack_name)
예제 #5
0
def generate(max_angle, number_radiograms) -> ProjectionAngles:
    """
    Generate equidistance projection angles.

    :param max_angle: The maximum angle of the tomography
    :param number_radiograms: The number of radiograms in the tomography
    :returns: list of projection angles
    """
    return ProjectionAngles(
        np.linspace(0, (math.tau / 360) * max_angle, number_radiograms))
예제 #6
0
    def test_add_projection_angles_to_stack_success(self):
        mock_stack = mock.Mock()
        mock_stack.windowTitle.return_value = window_title = "window title"
        stack_id = "stack-id"
        self.presenter.stacks[stack_id] = mock_stack
        projection_angles = ProjectionAngles(np.ndarray([1]))

        self.presenter.add_projection_angles_to_sample(window_title,
                                                       projection_angles)
        self.model.add_projection_angles_to_sample(stack_id, projection_angles)
예제 #7
0
    def test_add_projection_angles_to_sample(self):
        proj_angles = ProjectionAngles(np.arange(0, 10))
        stack_name = "stack name"
        stack_mock = mock.MagicMock()
        self.model.get_stack_by_name = stack_mock

        self.model.add_projection_angles_to_sample(stack_name, proj_angles)

        stack_mock.assert_called_with(stack_name)
        stack_mock.return_value.widget.return_value.presenter.images.set_projection_angles.assert_called_once_with(
            proj_angles)
예제 #8
0
    def test_add_projection_angles_to_sample(self):
        proj_angles = ProjectionAngles(np.arange(0, 10))
        images_id = "id"
        get_images_mock = mock.MagicMock()
        self.model.get_images_by_uuid = get_images_mock

        self.model.add_projection_angles_to_sample(images_id, proj_angles)

        get_images_mock.assert_called_with(images_id)
        get_images_mock.return_value.set_projection_angles.assert_called_once_with(
            proj_angles)
예제 #9
0
    def test_add_projection_angles_to_sample_no_stack(self):
        proj_angles = ProjectionAngles(np.arange(0, 10))
        images_id = "id"
        get_images_mock = mock.MagicMock()
        self.model.get_images_by_uuid = get_images_mock
        get_images_mock.return_value = None
        self.assertRaises(RuntimeError,
                          self.model.add_projection_angles_to_sample,
                          images_id, proj_angles)

        get_images_mock.assert_called_with(images_id)
예제 #10
0
    def projection_angles(self) -> ProjectionAngles:
        angles = numpy.zeros(
            len(self._data[IMATLogColumn.IMAGE_TYPE_IMAGE_COUNTER]))
        for i, angle_str in enumerate(
                self._data[IMATLogColumn.IMAGE_TYPE_IMAGE_COUNTER]):
            if "angle:" not in angle_str:
                raise ValueError(
                    "Projection angles loaded from logfile do not have the correct formatting!"
                )
            angles[i] = float(angle_str[angle_str.rfind(": ") + 1:])

        return ProjectionAngles(numpy.deg2rad(angles))
예제 #11
0
    def projection_angles(self, max_angle: float = 360.0) -> ProjectionAngles:
        """
        Return projection angles, in priority order:
        - From a log
        - From the manually loaded file with a list of angles
        - Automatically generated with equidistant step

        :param max_angle: The maximum angle up to which the angles will be generated.
                          Only used when the angles are generated, if they are provided
                          via a log or a file the argument will be ignored.
        """
        if self._log_file is not None:
            return self._log_file.projection_angles()
        elif self._projection_angles is not None:
            return self._projection_angles
        else:
            return ProjectionAngles(np.linspace(0, np.deg2rad(max_angle), self.num_projections))
    def get_projection_angles(self) -> ProjectionAngles:
        if "," in self.contents[0]:
            if len(self.contents) > 2:
                # allows a file that has a single line of CSV angles,
                # and a new line after it
                raise RuntimeError(self.ERROR_MESSAGE)
            string_content = self.contents[0]
            # Handles the angles provided as comma separated values

            # angles are in CSV format 0,0.1,0.2...
            values = np.deg2rad(
                [float(angle.strip()) for angle in string_content.split(",")])
        else:
            # Handles the angles provided as a value per line
            values = np.deg2rad(
                [float(angle.strip()) for angle in self.contents])

        return ProjectionAngles(values)
예제 #13
0
    def test_create_new_stack_dataset_and_use_threshold_180(self):
        dock_mock = self.view.create_stack_window.return_value
        stack_visualiser_mock = mock.Mock()
        self.dataset.sample.set_projection_angles(
            ProjectionAngles(
                np.linspace(0, np.pi, self.dataset.sample.num_images)))

        dock_mock.widget.return_value = stack_visualiser_mock
        dock_mock.windowTitle.return_value = "somename"
        self.view.model_changed.emit = mock.Mock()

        self.dataset.flat_before.filenames = ["filename"] * 10
        self.dataset.dark_before.filenames = ["filename"] * 10
        self.dataset.flat_after.filenames = ["filename"] * 10
        self.dataset.dark_after.filenames = ["filename"] * 10

        self.view.ask_to_use_closest_to_180.return_value = False

        self.presenter.create_new_stack(self.dataset)

        self.assertEqual(6, len(self.presenter.stacks))
        self.view.model_changed.emit.assert_called_once()
예제 #14
0
    def _create_sample_images(self):
        """
        Creates the sample Images object.
        :return: An Images object containing projections. If given, projection angles, pixel size, and 180deg are also
            set.
        """
        assert self.sample_array is not None

        # Create sample array and Images object
        self.sample_array = self.sample_array[self.view.start_widget.value(
        ):self.view.stop_widget.value():self.view.step_widget.value()]
        sample_images = self._create_images(self.sample_array, "Projections")

        # Set attributes
        sample_images.pixel_size = int(self.view.pixelSizeSpinBox.value())
        if self.projection_angles is not None:
            sample_images.set_projection_angles(
                ProjectionAngles(
                    self.projection_angles[self.view.start_widget.
                                           value():self.view.stop_widget.value(
                                           ):self.view.step_widget.value()]))

        return sample_images
 def projection_angles(self) -> ProjectionAngles:
     angles = numpy.zeros(len(self._data[IMATLogColumn.PROJECTION_ANGLE]))
     angles[:] = self._data[IMATLogColumn.PROJECTION_ANGLE]
     return ProjectionAngles(numpy.deg2rad(angles))
예제 #16
0
 def test_add_projection_angles_to_stack_failure(self):
     with self.assertRaises(RuntimeError):
         self.presenter.add_projection_angles_to_sample(
             "doesn't-exist", ProjectionAngles(np.ndarray([1])))
     self.model.add_projection_angles_to_sample.assert_not_called()