def full(images: Images, cors: List[ScalarCoR], recon_params: ReconstructionParameters, progress: Optional[Progress] = None) -> Images: progress = Progress.ensure_instance(progress, num_steps=images.height) output_shape = (images.num_sinograms, images.width, images.width) output_images: Images = Images.create_empty_images( output_shape, images.dtype, images.metadata) output_images.record_operation('AstraRecon.full', 'Reconstruction', **recon_params.to_dict()) # FIXME multiple GPU support - just starting up a Pool doesn't seem to work # the GPUs can't initialise the memory properly. Not sure why # num_gpus = AstraRecon._count_gpus() # LOG.info(f"Running with {num_gpus} GPUs") # partial = ptsm.create_partial(AstraRecon.single, ptsm.fwd_gpu_recon, # num_gpus=num_gpus, cors=cors, # proj_angles=proj_angles, recon_params=recon_params) # ptsm.execute(images.sinograms, output_images.data, partial, num_gpus, progress=progress) proj_angles = images.projection_angles() for i in range(images.height): output_images.data[i] = AstraRecon.single_sino( images.sino(i), cors[i], proj_angles, recon_params) progress.update(1, "Reconstructed slice") return output_images
def test_adjust_cor(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), False) m.centre_value = 5 m.step = 1 m.adjust(ImageType.CURRENT) self.assertEqual(m.centre_value, 5) self.assertEqual(m.step, 0.5) m.adjust(ImageType.LESS) self.assertEqual(m.centre_value, 4.5) self.assertEqual(m.step, 0.5) m.adjust(ImageType.CURRENT) self.assertEqual(m.centre_value, 4.5) self.assertEqual(m.step, 0.25) m.adjust(ImageType.MORE) self.assertEqual(m.centre_value, 4.75) self.assertEqual(m.step, 0.25) m.adjust(ImageType.CURRENT) self.assertEqual(m.centre_value, 4.75) self.assertEqual(m.step, 0.125)
def test_construct(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), False) npt.assert_equal(m.sino, images.sino(5)) self.assertEqual(m.cor_extents, (0, 9)) self.assertEqual(m.proj_angles.value.shape, (10, ))
def test_current_cor(self): images = generate_images() m = CORInspectionDialogModel(images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak')) m.centre_cor = 5 m.cor_step = 1 self.assertEqual(m.cor(ImageType.LESS), 4) self.assertEqual(m.cor(ImageType.CURRENT), 5) self.assertEqual(m.cor(ImageType.MORE), 6)
def test_divide_iters_step(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), True) m.step = 11 m._divide_step() self.assertEqual(m.step, 5)
def recon_params(self) -> ReconstructionParameters: return ReconstructionParameters( algorithm=self.algorithm_name, filter_name=self.filter_name, num_iter=self.num_iter, cor=ScalarCoR(self.rotation_centre), tilt=Degrees(self.tilt), pixel_size=self.pixel_size, max_projection_angle=self.max_proj_angle)
def setUp(self, model) -> None: self.view = mock.MagicMock() self.model = model.return_value self.recon_params = ReconstructionParameters("", "", 0, ScalarCoR(2), Degrees(2), 2, 2) self.presenter = CORInspectionDialogPresenter(self.view, th.generate_images(), 5, ScalarCoR(2), self.recon_params, False)
def test_iters_mode_init(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), True) self.assertEqual(m.centre_value, INIT_ITERS_CENTRE_VALUE) self.assertEqual(m.step, INIT_ITERS_STEP) self.assertEqual(m._recon_preview, m._recon_iters_preview) self.assertEqual(m._divide_step, m._divide_iters_step)
def test_cor_mode_init(self): images = generate_images() initial_cor = ScalarCoR(20) m = CORInspectionDialogModel( images, 5, initial_cor, ReconstructionParameters('FBP_CUDA', 'ram-lak'), False) self.assertEqual(m.centre_value, initial_cor.value) self.assertEqual(m.step, images.width * 0.05) self.assertEqual(m._recon_preview, m._recon_cor_preview) self.assertEqual(m._divide_step, m._divide_cor_step)
def test_recon_iters_preview(self, replace_mock): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), True) m.reconstructor = Mock() m.recon_preview(ImageType.CURRENT) replace_mock.assert_called_once_with(m.recon_params, num_iter=100) m.reconstructor.single_sino.assert_called_once_with( m.sino, m.initial_cor, m.proj_angles, replace_mock.return_value)
def test_do_preview_reconstruct_slice(self, mock_start_async_task_view): recon_params = ReconstructionParameters("FBP", "ram-lak", 10) self.view.recon_params.return_value = recon_params self.presenter.model.preview_slice_idx = 0 self.presenter.model.last_cor = ScalarCoR(150) self.presenter.model.data_model._cached_gradient = None self.presenter.do_preview_reconstruct_slice() self.view.update_sinogram.assert_called_once() mock_start_async_task_view.assert_called_once() self.view.recon_params.assert_called_once()
def test_apply_pixel_size(self): images = generate_images() initial_value = images.data[0][0, 0] test_pixel_size = 100 recon_params = ReconstructionParameters("FBP", "ram-lak", test_pixel_size, pixel_size=test_pixel_size) images = self.model._apply_pixel_size(images, recon_params) # converts the number we put for pixel size to microns expected_value = initial_value / (test_pixel_size * 1e-4) self.assertAlmostEqual(expected_value, images.data[0][0, 0], places=4) self.assertEqual(test_pixel_size, images.metadata[const.PIXEL_SIZE]) self.assertEqual(1, len(images.metadata[const.OPERATION_HISTORY]))
def test_iterations(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), True) m.adjust(ImageType.LESS) self.assertEqual(m.centre_value, 50) self.assertEqual(m.step, 50) m.adjust(ImageType.CURRENT) self.assertEqual(m.centre_value, 50) self.assertEqual(m.step, 25) m.adjust(ImageType.MORE) self.assertEqual(m.centre_value, 75) self.assertEqual(m.step, 25)
def test_run_preview_recon(self, mock_get_reconstructor_for): mock_reconstructor = mock.Mock() mock_reconstructor.single_sino = mock.Mock() mock_get_reconstructor_for.return_value = mock_reconstructor expected_idx = 5 expected_sino = self.model.images.sino(expected_idx) expected_cor = ScalarCoR(15) expected_recon_params = ReconstructionParameters("FBP_CUDA", "ram-lak") self.model.run_preview_recon(expected_idx, expected_cor, expected_recon_params) mock_get_reconstructor_for.assert_called_once_with( expected_recon_params.algorithm) assert_called_once_with(mock_reconstructor.single_sino, expected_sino, expected_cor, self.model.images.projection_angles(), expected_recon_params)
def test_set_slice_preview_index(self, mock_get_reconstructor_for): mock_reconstructor = mock.Mock() mock_reconstructor.single_sino = mock.Mock() mock_reconstructor.single_sino.return_value = np.random.rand(128, 128) mock_get_reconstructor_for.return_value = mock_reconstructor recon_params = ReconstructionParameters("FBP", "ram-lak", 10) self.view.recon_params.return_value = recon_params self.presenter.set_preview_slice_idx(5) self.assertEqual(self.presenter.model.preview_slice_idx, 5) self.view.update_projection.assert_called_once() self.view.update_sinogram.assert_called_once() self.view.update_recon_preview.assert_called_once() self.view.recon_params.assert_called_once() mock_get_reconstructor_for.assert_called_once() mock_reconstructor.single_sino.assert_called_once()
def full(images: Images, cors: List[ScalarCoR], recon_params: ReconstructionParameters, progress: Optional[Progress] = None) -> Images: progress = Progress.ensure_instance(progress, num_steps=images.height) output_shape = (images.num_sinograms, images.width, images.width) output_images: Images = Images.create_empty_images( output_shape, images.dtype, images.metadata) output_images.record_operation('AstraRecon.full', 'Reconstruction', **recon_params.to_dict()) proj_angles = images.projection_angles( recon_params.max_projection_angle) for i in range(images.height): output_images.data[i] = AstraRecon.single_sino( images.sino(i), cors[i], proj_angles, recon_params) progress.update(1, "Reconstructed slice") return output_images
def test_do_reconstruct_slice(self, mock_get_reconstructor_for): mock_reconstructor = mock.Mock() mock_reconstructor.single_sino = mock.Mock() mock_reconstructor.single_sino.return_value = np.random.rand(128, 128) mock_get_reconstructor_for.return_value = mock_reconstructor recon_params = ReconstructionParameters("FBP", "ram-lak", 10) self.view.recon_params.return_value = recon_params self.presenter.model.preview_slice_idx = 0 self.presenter.model.last_cor = ScalarCoR(150) self.presenter.model.data_model._cached_gradient = None self.presenter.do_preview_reconstruct_slice() self.view.update_sinogram.assert_called_once() self.view.update_recon_preview.assert_called_once() self.view.recon_params.assert_called_once() mock_get_reconstructor_for.assert_called_once() mock_reconstructor.single_sino.assert_called_once()
def test_set_stack_uuid(self, mock_get_reconstructor_for): # reset the model data self.presenter.model.initial_select_data(None) mock_reconstructor = mock.Mock() mock_reconstructor.single_sino = mock.Mock() mock_reconstructor.single_sino.return_value = np.random.rand(128, 128) mock_get_reconstructor_for.return_value = mock_reconstructor recon_params = ReconstructionParameters("FBP", "ram-lak", 10) self.view.recon_params.return_value = recon_params # first-time selecting this data after reset self.presenter.set_stack_uuid(self.uuid) self.view.get_stack_visualiser.assert_called_once_with(self.uuid) self.view.update_projection.assert_called_once() self.view.clear_cor_table.assert_called_once() self.view.update_projection.assert_called_once() self.view.update_sinogram.assert_called_once() self.view.update_recon_preview.assert_called_once() mock_get_reconstructor_for.assert_called_once() mock_reconstructor.single_sino.assert_called_once() self.view.recon_params.assert_called_once() # calling again with the same stack shouldn't re-do everything self.presenter.set_stack_uuid(self.uuid) self.assertEqual(self.view.get_stack_visualiser.call_count, 2) self.view.get_stack_visualiser.assert_has_calls([mock.call(self.uuid), mock.call(self.uuid)]) self.view.update_projection.assert_called_once() self.view.clear_cor_table.assert_called_once() self.view.update_projection.assert_called_once() self.view.update_sinogram.assert_called_once() self.view.update_recon_preview.assert_called_once() mock_get_reconstructor_for.assert_called_once() mock_reconstructor.single_sino.assert_called_once()
def recon_params(self) -> ReconstructionParameters: return ReconstructionParameters(self.algorithm_name, self.filter_name, self.num_iter, ScalarCoR(self.rotation_centre), Degrees(self.tilt))
def test_start_cor_step(self): images = generate_images() m = CORInspectionDialogModel( images, 5, ScalarCoR(20), ReconstructionParameters('FBP_CUDA', 'ram-lak'), False) self.assertEqual(images.width * 0.05, m.step)