From ba301fbde9a587e9213b4ff8c9f495529a419c77 Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Thu, 2 Oct 2025 09:28:28 +0000 Subject: [PATCH 1/9] fix image_geom_get_slice --- Wrappers/Python/cil/framework/image_data.py | 2 +- .../Python/cil/framework/image_geometry.py | 25 +++++---- Wrappers/Python/test/test_DataContainer.py | 13 ++++- Wrappers/Python/test/test_reconstructors.py | 4 -- Wrappers/Python/test/test_subset.py | 55 ++++++++++++++++++- Wrappers/Python/test/utils_projectors.py | 7 +++ 6 files changed, 87 insertions(+), 19 deletions(-) diff --git a/Wrappers/Python/cil/framework/image_data.py b/Wrappers/Python/cil/framework/image_data.py index 67cfbff5b7..53ab378f1d 100644 --- a/Wrappers/Python/cil/framework/image_data.py +++ b/Wrappers/Python/cil/framework/image_data.py @@ -127,7 +127,7 @@ def __eq__(self, other): def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None, force=False): ''' - Returns a new ImageData of a single slice of in the requested direction. + Returns a new ImageData of a single slice in the requested direction. ''' try: geometry_new = self.geometry.get_slice(channel=channel, vertical=vertical, horizontal_x=horizontal_x, horizontal_y=horizontal_y) diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index fc7f7771e7..b8aa141e9e 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -174,25 +174,30 @@ def __init__(self, def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None): ''' - Returns a new ImageGeometry of a single slice of in the requested direction. + Returns a new ImageGeometry of a single slice in the requested direction. ''' + geometry_new = self.copy() if channel is not None: - geometry_new.channels = 1 - - try: - geometry_new.channel_labels = [self.channel_labels[channel]] - except: - geometry_new.channel_labels = None + raise NotImplementedError("Slicing over channels not implemented for ImageGeometry") if vertical is not None: - geometry_new.voxel_num_z = 0 + geometry_new.voxel_num_z = 1 + if vertical != 'centre': + voxel_offset = (self.voxel_num_z)/2 - (vertical+0.5) + geometry_new.center_z -= voxel_offset * geometry_new.voxel_size_z if horizontal_y is not None: - geometry_new.voxel_num_y = 0 + geometry_new.voxel_num_y = 1 + if horizontal_y != 'centre': + voxel_offset = (self.voxel_num_y)/2 - (horizontal_y +0.5) + geometry_new.center_y -= voxel_offset * geometry_new.voxel_size_y if horizontal_x is not None: - geometry_new.voxel_num_x = 0 + geometry_new.voxel_num_x = 1 + if horizontal_x != 'centre': + voxel_offset = (self.voxel_num_x)/2 - (horizontal_x+0.5) + geometry_new.center_x -= voxel_offset * geometry_new.voxel_size_x return geometry_new diff --git a/Wrappers/Python/test/test_DataContainer.py b/Wrappers/Python/test/test_DataContainer.py index cb8bcf3d32..65cec9651e 100644 --- a/Wrappers/Python/test/test_DataContainer.py +++ b/Wrappers/Python/test/test_DataContainer.py @@ -860,13 +860,20 @@ def test_ImageDataSubset(self): ss1 = vol.get_slice(horizontal_x = 0) self.assertListEqual(['channel', 'horizontal_y'], list(ss1.geometry.dimension_labels)) + ss2 = vol.get_slice(channel=0) + self.assertListEqual([ImageDimension["HORIZONTAL_Y"], ImageDimension["HORIZONTAL_X"]], list(ss2.geometry.dimension_labels)) + vg = ImageGeometry(3,4,5,channels=2) self.assertListEqual([ImageDimension["CHANNEL"], ImageDimension["VERTICAL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["HORIZONTAL_X"]], list(vg.dimension_labels)) - ss2 = vg.allocate() - ss3 = vol.get_slice(channel=0) - self.assertListEqual([ImageDimension["HORIZONTAL_Y"], ImageDimension["HORIZONTAL_X"]], list(ss3.geometry.dimension_labels)) + vol2 = vg.allocate() + + ss3 = vol2.get_slice(vertical=0) + self.assertListEqual([ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["HORIZONTAL_X"]], + list(ss3.geometry.dimension_labels)) + + def test_DataContainerSubset(self): dc = DataContainer(np.ones((2,3,4,5))) diff --git a/Wrappers/Python/test/test_reconstructors.py b/Wrappers/Python/test/test_reconstructors.py index 572e4309cf..9f6d5bedfc 100644 --- a/Wrappers/Python/test/test_reconstructors.py +++ b/Wrappers/Python/test/test_reconstructors.py @@ -80,7 +80,6 @@ def setUp(self): .set_angles(angles)\ .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\ .set_labels(['angle','vertical','horizontal']) - self.ig3D = self.ag3D.get_ImageGeometry() self.ad3D = self.ag3D.allocate('random', seed=3) self.ig3D = self.ag3D.get_ImageGeometry() @@ -164,7 +163,6 @@ def setUp(self): .set_angles(angles)\ .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\ .set_labels(['angle','vertical','horizontal']) - self.ig3D = self.ag3D.get_ImageGeometry() self.ad3D = self.ag3D.allocate('random', seed=4) self.ig3D = self.ag3D.get_ImageGeometry() @@ -351,7 +349,6 @@ def setUp(self): .set_angles(angles)\ .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\ .set_labels(['angle','vertical','horizontal']) - self.ig3D = self.ag3D.get_ImageGeometry() self.ad3D = self.ag3D.allocate('random', seed=5) self.ig3D = self.ag3D.get_ImageGeometry() @@ -454,7 +451,6 @@ def setUp(self): .set_angles(angles)\ .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\ .set_labels(['angle','vertical','horizontal']) - self.ig3D = self.ag3D.get_ImageGeometry() self.ad3D = self.ag3D.allocate('random', seed=3) self.ig3D = self.ag3D.get_ImageGeometry() diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 638e882313..40fcfc7b45 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -161,13 +161,19 @@ def test_DataContainer(self): self.assertEqual(data_new.shape,(5,)) numpy.testing.assert_array_equal(data_new.array, arr[1,1,3,:]) - def test_ImageData(self): + def test_ImageData(self): ig = ImageGeometry(voxel_num_x=5, voxel_num_y=4, voxel_num_z=3, channels=2, dimension_labels=['channel','vertical','horizontal_y','horizontal_x']) data = ig.allocate(None) data_new = data.get_slice(vertical=1) self.assertEqual(data_new.shape,(2,4,5)) self.assertEqual(data_new.geometry.dimension_labels,('channel','horizontal_y','horizontal_x')) + def test_ImageGeometry(self): + ig = ImageGeometry(voxel_num_x=5, voxel_num_y=4, voxel_num_z=3, channels=2, dimension_labels=['channel','vertical','horizontal_y','horizontal_x']) + ig_new = ig.get_slice(vertical='centre') + self.assertEqual(ig_new.shape,(2,1,4,5)) + self.assertEqual(ig_new.dimension_labels,('channel','vertical','horizontal_y', 'horizontal_x')) + def test_AcquisitionData(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) data = ag.allocate(None) @@ -310,9 +316,56 @@ def test_ImageDataSubset1b(self): def test_ImageDataSubset1c(self): data = self.ig.allocate() + # TODO sort out changed behaviour here sub = data.get_slice(channel=0,horizontal_x=0,horizontal_y=0) self.assertTrue( sub.shape == (4,)) + def test_ImageGeometrySubset1a(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(vertical = 1) + self.assertTrue( sub.shape == (2,5,3,1)) + + self.assertEqual(sub.voxel_centre_x,0) + self.assertEqual(sub.voxel_centre_y,0) + self.assertEqual(sub.voxel_centre_z,-0.5) + + def test_ImageGeometrySubset2a(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_x = 1) + self.assertTrue( sub.shape == (1, 5,3,4)) + self.assertEqual(sub.voxel_centre_x,-0.5) + self.assertEqual(sub.voxel_centre_y,0) + self.assertEqual(sub.voxel_centre_z,0) + + def test_ImageGeometrySubset3a(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + with self.assertRaises(NotImplementedError): + self.ig.get_slice(channel = 1) + + def test_ImageGeometrySubset5a(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_y = 1) + self.assertTrue( sub.shape == (2,1)) + + def test_ImageGeometrySubset1b(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + new_dimension_labels = [ImageDimension["HORIZONTAL_Y"], ImageDimension["CHANNEL"], ImageDimension["VERTICAL"], ImageDimension["HORIZONTAL_X"]] + self.ig.set_labels(new_dimension_labels) + self.assertTrue( self.ig.shape == (3,5,4,2)) + + def test_ImageGeometrySubset1c(self): + sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) + self.assertTrue( sub.shape == (5,4,1,1)) + def test_AcquisitionDataAllocate1a(self): data = self.ag.allocate() diff --git a/Wrappers/Python/test/utils_projectors.py b/Wrappers/Python/test/utils_projectors.py index 9d767f51ea..91a5c1393a 100644 --- a/Wrappers/Python/test/utils_projectors.py +++ b/Wrappers/Python/test/utils_projectors.py @@ -656,10 +656,17 @@ def test_FBP_roi(self): np.testing.assert_allclose(reco.as_array(), self.gold_roi, atol=self.tolerance_fbp_roi) if AcquisitionType.DIM3 & self.ag.dimension: + # Manually generated single slice Image Geometry FBP = self.FBP(self.ig_single_slice, self.ag, **self.FBP_args) reco = FBP(self.acq_data) np.testing.assert_allclose(reco.as_array(), self.gold_roi_single_slice, atol=self.tolerance_fbp_roi) + # CIL generated single slice Image Geometry + central_slice_ig = self.ig.get_slice(vertical='centre') + FBP = self.FBP(central_slice_ig, self.ag, **self.FBP_args) + reco = FBP(self.acq_data) + np.testing.assert_allclose(reco.as_array(), self.img_data.get_slice(vertical='centre').as_array(),atol=self.tolerance_fbp) + def test_input_arguments(self): # default image_geometry, named parameter acquisition_geometry From 962d2af8b5431d810dd002c598564deb655e17c8 Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Tue, 28 Oct 2025 17:29:14 +0000 Subject: [PATCH 2/9] Fix get_slice tests --- .../Python/cil/framework/image_geometry.py | 33 +++++++++++++++++-- Wrappers/Python/test/test_subset.py | 18 +++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index b8aa141e9e..c359d4172b 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -99,7 +99,7 @@ def dimension_labels(self): labels = list(labels) for i, x in enumerate(shape_default): - if x == 0 or x==1: + if x == 0: try: labels.remove(labels_default[i]) except ValueError: @@ -166,7 +166,7 @@ def __init__(self, self.center_y = center_y self.center_z = center_z self.channels = channels - self.channel_labels = None + self.channel_labels = None# check if None, single channel geom self.channel_spacing = 1.0 self.dimension_labels = kwargs.get('dimension_labels', None) self.dtype = kwargs.get('dtype', numpy.float32) @@ -175,11 +175,38 @@ def __init__(self, def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None): ''' Returns a new ImageGeometry of a single slice in the requested direction. + + Parameters + ---------- + channel : int, optional + The channel index to slice. Default is None (no slicing). + vertical : int or 'centre', optional + The vertical index to slice. Default is None (no slicing). + horizontal_x : int or 'centre', optional + The horizontal x index to slice. Default is None (no slicing). + horizontal_y : int or 'centre', optional + The horizontal y index to slice. Default is None (no slicing). + Returns + ------- + geometry_new : ImageGeometry + A new ImageGeometry object representing the sliced geometry. + + Note + ---- + Slicing on vertical, horizontal_x or horizontal_y with 'centre' will return the + central slice in that dimension. + Slicing on channels returns a geometry with a single channel, however the channel label is not + typically stored in the geometry. ''' geometry_new = self.copy() if channel is not None: - raise NotImplementedError("Slicing over channels not implemented for ImageGeometry") + geometry_new.channels = 1 + try: + geometry_new.channel_labels = [self.channel_labels[channel]] + except: + geometry_new.channel_labels = None + if vertical is not None: geometry_new.voxel_num_z = 1 diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 40fcfc7b45..66e995a046 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -327,26 +327,26 @@ def test_ImageGeometrySubset1a(self): sub = self.ig.get_slice(vertical = 1) self.assertTrue( sub.shape == (2,5,3,1)) - self.assertEqual(sub.voxel_centre_x,0) - self.assertEqual(sub.voxel_centre_y,0) - self.assertEqual(sub.voxel_centre_z,-0.5) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,-0.5) def test_ImageGeometrySubset2a(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(horizontal_x = 1) - self.assertTrue( sub.shape == (1, 5,3,4)) - self.assertEqual(sub.voxel_centre_x,-0.5) - self.assertEqual(sub.voxel_centre_y,0) - self.assertEqual(sub.voxel_centre_z,0) + self.assertTrue(sub.shape == (1, 5,3,4)) + self.assertEqual(sub.center_x,0.5) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,0) def test_ImageGeometrySubset3a(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) - with self.assertRaises(NotImplementedError): - self.ig.get_slice(channel = 1) + sub = self.ig.get_slice(channel = 1) + self.assertTrue(sub.shape == (2,1,3,4)) def test_ImageGeometrySubset5a(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] From 4b64825cf1e6c6c9745085293bd3a3e7e3d04cbf Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Wed, 29 Oct 2025 16:58:26 +0000 Subject: [PATCH 3/9] Image geometry slice is now 2D --- Wrappers/Python/cil/framework/acquisition_data.py | 6 ++++++ Wrappers/Python/cil/framework/image_data.py | 7 +++++++ Wrappers/Python/cil/framework/image_geometry.py | 12 +++++++++++- Wrappers/Python/test/test_subset.py | 15 +++++++-------- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Wrappers/Python/cil/framework/acquisition_data.py b/Wrappers/Python/cil/framework/acquisition_data.py index 308f0d5462..4060543612 100644 --- a/Wrappers/Python/cil/framework/acquisition_data.py +++ b/Wrappers/Python/cil/framework/acquisition_data.py @@ -230,6 +230,12 @@ def get_slice(self, *args, **kwargs): kwargs['force'] = args[4] return self._get_slice(**kwargs) + + def get_centre_slice(self): + ''' + Returns a new AcquisitionData of the centre slice in the vertical direction. + ''' + return self.get_slice(vertical='centre') def reorder(self, order): ''' diff --git a/Wrappers/Python/cil/framework/image_data.py b/Wrappers/Python/cil/framework/image_data.py index 53ab378f1d..13878022f6 100644 --- a/Wrappers/Python/cil/framework/image_data.py +++ b/Wrappers/Python/cil/framework/image_data.py @@ -156,6 +156,13 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= return out else: return ImageData(out.array, deep_copy=False, geometry=geometry_new) + + def get_centre_slice(self): + ''' + Returns a new ImageData of the centre slice in the vertical direction. + ''' + return self.get_slice(vertical='centre') + def apply_circular_mask(self, radius=0.99, in_place=True): diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index c359d4172b..dd595a94ab 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -99,7 +99,7 @@ def dimension_labels(self): labels = list(labels) for i, x in enumerate(shape_default): - if x == 0: + if x == 0 or x==1: try: labels.remove(labels_default[i]) except ValueError: @@ -211,6 +211,10 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= if vertical is not None: geometry_new.voxel_num_z = 1 if vertical != 'centre': + if vertical == 0: + warnings.warn("Slicing vertical at index 0 results in a geometry \ + offset along the vertical axis. If you do not require an offset ImageGeometry, set vertical='centre", + UserWarning) voxel_offset = (self.voxel_num_z)/2 - (vertical+0.5) geometry_new.center_z -= voxel_offset * geometry_new.voxel_size_z @@ -227,6 +231,12 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= geometry_new.center_x -= voxel_offset * geometry_new.voxel_size_x return geometry_new + + def get_centre_slice(self): + ''' + Returns a new ImageGeometry of the centre slice in the vertical direction. + ''' + return self.get_slice(vertical='centre') def get_order_by_label(self, dimension_labels, default_dimension_labels): order = [] diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 66e995a046..89f287160f 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -171,8 +171,8 @@ def test_ImageData(self): def test_ImageGeometry(self): ig = ImageGeometry(voxel_num_x=5, voxel_num_y=4, voxel_num_z=3, channels=2, dimension_labels=['channel','vertical','horizontal_y','horizontal_x']) ig_new = ig.get_slice(vertical='centre') - self.assertEqual(ig_new.shape,(2,1,4,5)) - self.assertEqual(ig_new.dimension_labels,('channel','vertical','horizontal_y', 'horizontal_x')) + self.assertEqual(ig_new.shape,(2,4,5)) + self.assertEqual(ig_new.dimension_labels,('channel','horizontal_y', 'horizontal_x')) def test_AcquisitionData(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) @@ -325,8 +325,7 @@ def test_ImageGeometrySubset1a(self): ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(vertical = 1) - self.assertTrue( sub.shape == (2,5,3,1)) - + self.assertTrue( sub.shape == (2,5,3)) self.assertEqual(sub.center_x,0) self.assertEqual(sub.center_y,0) self.assertEqual(sub.center_z,-0.5) @@ -336,7 +335,7 @@ def test_ImageGeometrySubset2a(self): ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(horizontal_x = 1) - self.assertTrue(sub.shape == (1, 5,3,4)) + self.assertTrue(sub.shape == (5,3,4)) self.assertEqual(sub.center_x,0.5) self.assertEqual(sub.center_y,0) self.assertEqual(sub.center_z,0) @@ -346,13 +345,13 @@ def test_ImageGeometrySubset3a(self): ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(channel = 1) - self.assertTrue(sub.shape == (2,1,3,4)) + self.assertTrue(sub.shape == (2,3,4)) def test_ImageGeometrySubset5a(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(horizontal_y = 1) - self.assertTrue( sub.shape == (2,1)) + self.assertTrue( sub.shape == (2,)) def test_ImageGeometrySubset1b(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], @@ -364,7 +363,7 @@ def test_ImageGeometrySubset1b(self): def test_ImageGeometrySubset1c(self): sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) - self.assertTrue( sub.shape == (5,4,1,1)) + self.assertTrue( sub.shape == (5,4)) def test_AcquisitionDataAllocate1a(self): From be94d8e9d1baccc2ce92f9292783543aa2f240ce Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Wed, 29 Oct 2025 17:18:14 +0000 Subject: [PATCH 4/9] Add new unit tests --- Wrappers/Python/test/test_ImageGeometry.py | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Wrappers/Python/test/test_ImageGeometry.py diff --git a/Wrappers/Python/test/test_ImageGeometry.py b/Wrappers/Python/test/test_ImageGeometry.py new file mode 100644 index 0000000000..1ddc236684 --- /dev/null +++ b/Wrappers/Python/test/test_ImageGeometry.py @@ -0,0 +1,85 @@ +# Copyright 2025 United Kingdom Research and Innovation +# Copyright 2025 The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: +# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt + +import unittest +from utils import initialise_tests +from cil.framework import ImageGeometry +from cil.framework.labels import ImageDimension + +initialise_tests() + + +class TestImageGeometry(unittest.TestCase): + def setUp(self): + self.ig = ImageGeometry(2,3,4,channels=5) + + # get_slice tests --------------------------------------------------------------------------------------------------------------- + + def test_get_slice_vertical(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(vertical = 1) + self.assertTrue( sub.shape == (2,5,3)) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,-0.5) + + def test_get_slice_horizontal_x(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_x = 1) + self.assertTrue(sub.shape == (5,3,4)) + self.assertEqual(sub.center_x,0.5) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,0) + + def test_get_slice_channel(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(channel = 1) + self.assertTrue(sub.shape == (2,3,4)) + + def test_get_slice_horizontal_y(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_y = 0) + self.assertTrue( sub.shape == (2,)) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,-1) + self.assertEqual(sub.center_z,0) + + def test_get_slice_horizontal_x_and_horizontal_y(self): + sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) + self.assertTrue( sub.shape == (5,4)) + + # test get_centre_slice --------------------------------------------------------------------------------------------------------------- + + def test_get_centre_slice(self): + sub = self.ig.get_centre_slice() + sub2 = self.ig.get_slice(vertical='centre') + self.assertTrue( sub == sub2) + + # ------------------------------------------------------------------------------------------------------------------------------- + + def test_shape_change_with_new_labels(self): + new_dimension_labels = [ImageDimension["HORIZONTAL_Y"], ImageDimension["CHANNEL"], ImageDimension["VERTICAL"], ImageDimension["HORIZONTAL_X"]] + self.ig.set_labels(new_dimension_labels) + self.assertTrue( self.ig.shape == (3,5,4,2)) \ No newline at end of file From c1363c8e5b0158a4bee83060e053eb064858a587 Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Wed, 29 Oct 2025 17:22:31 +0000 Subject: [PATCH 5/9] Test voxel size z is maintained --- .../Python/cil/framework/image_geometry.py | 7 +-- Wrappers/Python/test/test_ImageGeometry.py | 10 +++- Wrappers/Python/test/test_subset.py | 59 ++++--------------- 3 files changed, 22 insertions(+), 54 deletions(-) diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index dd595a94ab..88010ef7c9 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -286,12 +286,11 @@ def __str__ (self): if self.voxel_num_z > 0: repres += "voxel_num : x{0},y{1},z{2}\n".format(self.voxel_num_x, self.voxel_num_y, self.voxel_num_z) - repres += "voxel_size : x{0},y{1},z{2}\n".format(self.voxel_size_x, self.voxel_size_y, self.voxel_size_z) - repres += "center : x{0},y{1},z{2}\n".format(self.center_x, self.center_y, self.center_z) else: repres += "voxel_num : x{0},y{1}\n".format(self.voxel_num_x, self.voxel_num_y) - repres += "voxel_size : x{0},y{1}\n".format(self.voxel_size_x, self.voxel_size_y) - repres += "center : x{0},y{1}\n".format(self.center_x, self.center_y) + + repres += "voxel_size : x{0},y{1},z{2}\n".format(self.voxel_size_x, self.voxel_size_y, self.voxel_size_z) + repres += "center : x{0},y{1},z{2}\n".format(self.center_x, self.center_y, self.center_z) return repres def allocate(self, value=0, **kwargs): diff --git a/Wrappers/Python/test/test_ImageGeometry.py b/Wrappers/Python/test/test_ImageGeometry.py index 1ddc236684..f378407063 100644 --- a/Wrappers/Python/test/test_ImageGeometry.py +++ b/Wrappers/Python/test/test_ImageGeometry.py @@ -33,12 +33,16 @@ def setUp(self): def test_get_slice_vertical(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(vertical = 1) + ig = self.ig.copy() + ig.set_labels(non_default_dimension_labels) + ig.voxel_size_z = 5.5 + sub = ig.get_slice(vertical = 1) self.assertTrue( sub.shape == (2,5,3)) + self.assertEqual(sub.voxel_size_z,5.5) self.assertEqual(sub.center_x,0) self.assertEqual(sub.center_y,0) - self.assertEqual(sub.center_z,-0.5) + self.assertEqual(sub.center_z,-0.5*sub.voxel_size_z) + def test_get_slice_horizontal_x(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 89f287160f..2fd1939321 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -305,6 +305,12 @@ def test_ImageDataSubset5a(self): sub = data.get_slice(horizontal_y = 1) self.assertTrue( sub.shape == (2,)) + def test_ImageDataCentreSubset(self): + data = self.ig.allocate() + sub = data.get_centre_slice() + sub2 = data.get_slice(vertical='centre') + self.assertTrue( sub == sub2) + def test_ImageDataSubset1b(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["VERTICAL"]] @@ -316,56 +322,9 @@ def test_ImageDataSubset1b(self): def test_ImageDataSubset1c(self): data = self.ig.allocate() - # TODO sort out changed behaviour here sub = data.get_slice(channel=0,horizontal_x=0,horizontal_y=0) self.assertTrue( sub.shape == (4,)) - def test_ImageGeometrySubset1a(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], - ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(vertical = 1) - self.assertTrue( sub.shape == (2,5,3)) - self.assertEqual(sub.center_x,0) - self.assertEqual(sub.center_y,0) - self.assertEqual(sub.center_z,-0.5) - - def test_ImageGeometrySubset2a(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], - ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(horizontal_x = 1) - self.assertTrue(sub.shape == (5,3,4)) - self.assertEqual(sub.center_x,0.5) - self.assertEqual(sub.center_y,0) - self.assertEqual(sub.center_z,0) - - def test_ImageGeometrySubset3a(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], - ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(channel = 1) - self.assertTrue(sub.shape == (2,3,4)) - - def test_ImageGeometrySubset5a(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(horizontal_y = 1) - self.assertTrue( sub.shape == (2,)) - - def test_ImageGeometrySubset1b(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], - ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - new_dimension_labels = [ImageDimension["HORIZONTAL_Y"], ImageDimension["CHANNEL"], ImageDimension["VERTICAL"], ImageDimension["HORIZONTAL_X"]] - self.ig.set_labels(new_dimension_labels) - self.assertTrue( self.ig.shape == (3,5,4,2)) - - def test_ImageGeometrySubset1c(self): - sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) - self.assertTrue( sub.shape == (5,4)) - - def test_AcquisitionDataAllocate1a(self): data = self.ag.allocate() default_dimension_labels = [AcquisitionDimension["CHANNEL"] , @@ -481,3 +440,9 @@ def test_AcquisitionDataSubset1l(self): sub = data.get_slice(projection = 0) sub = sub.get_slice(channel = 0) self.assertTrue(sub.shape == (2, 20)) + + def test_AcquisitionDataCentreSubset(self): + data = self.ig.allocate() + sub = data.get_centre_slice() + sub2 = data.get_slice(vertical='centre') + self.assertTrue( sub == sub2) From 5d861ba3a03e7eb1b3c75429122bb9f76e31510a Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Wed, 29 Oct 2025 17:44:39 +0000 Subject: [PATCH 6/9] Add tests for getting centre slices --- .../Python/cil/framework/image_geometry.py | 9 +++-- Wrappers/Python/test/test_ImageGeometry.py | 38 +++++++++++++++++++ Wrappers/Python/test/test_subset.py | 2 +- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index 88010ef7c9..755caa4428 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -166,7 +166,7 @@ def __init__(self, self.center_y = center_y self.center_z = center_z self.channels = channels - self.channel_labels = None# check if None, single channel geom + self.channel_labels = None self.channel_spacing = 1.0 self.dimension_labels = kwargs.get('dimension_labels', None) self.dtype = kwargs.get('dtype', numpy.float32) @@ -286,11 +286,12 @@ def __str__ (self): if self.voxel_num_z > 0: repres += "voxel_num : x{0},y{1},z{2}\n".format(self.voxel_num_x, self.voxel_num_y, self.voxel_num_z) + repres += "voxel_size : x{0},y{1},z{2}\n".format(self.voxel_size_x, self.voxel_size_y, self.voxel_size_z) + repres += "center : x{0},y{1},z{2}\n".format(self.center_x, self.center_y, self.center_z) else: repres += "voxel_num : x{0},y{1}\n".format(self.voxel_num_x, self.voxel_num_y) - - repres += "voxel_size : x{0},y{1},z{2}\n".format(self.voxel_size_x, self.voxel_size_y, self.voxel_size_z) - repres += "center : x{0},y{1},z{2}\n".format(self.center_x, self.center_y, self.center_z) + repres += "voxel_size : x{0},y{1}\n".format(self.voxel_size_x, self.voxel_size_y) + repres += "center : x{0},y{1}\n".format(self.center_x, self.center_y) return repres def allocate(self, value=0, **kwargs): diff --git a/Wrappers/Python/test/test_ImageGeometry.py b/Wrappers/Python/test/test_ImageGeometry.py index f378407063..ce2c1cc2ad 100644 --- a/Wrappers/Python/test/test_ImageGeometry.py +++ b/Wrappers/Python/test/test_ImageGeometry.py @@ -42,6 +42,16 @@ def test_get_slice_vertical(self): self.assertEqual(sub.center_x,0) self.assertEqual(sub.center_y,0) self.assertEqual(sub.center_z,-0.5*sub.voxel_size_z) + + def test_get_slice_vertical_centre(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(vertical = 'centre') + self.assertTrue( sub.shape == (2,5,3)) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,0) def test_get_slice_horizontal_x(self): @@ -54,12 +64,31 @@ def test_get_slice_horizontal_x(self): self.assertEqual(sub.center_y,0) self.assertEqual(sub.center_z,0) + def test_get_slice_horizontal_x_centre(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_x = 'centre') + self.assertTrue(sub.shape == (5,3,4)) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,0) + def test_get_slice_channel(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], ImageDimension["VERTICAL"]] self.ig.set_labels(non_default_dimension_labels) sub = self.ig.get_slice(channel = 1) self.assertTrue(sub.shape == (2,3,4)) + self.assertTrue(sub.channels == 1) + + def test_get_slice_channel_centre(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], + ImageDimension["VERTICAL"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(channel = 'centre') + self.assertTrue(sub.shape == (2,3,4)) + self.assertTrue(sub.channels == 1) def test_get_slice_horizontal_y(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] @@ -70,6 +99,15 @@ def test_get_slice_horizontal_y(self): self.assertEqual(sub.center_y,-1) self.assertEqual(sub.center_z,0) + def test_get_slice_horizontal_y_centre(self): + non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] + self.ig.set_labels(non_default_dimension_labels) + sub = self.ig.get_slice(horizontal_y = 'centre') + self.assertTrue( sub.shape == (2,)) + self.assertEqual(sub.center_x,0) + self.assertEqual(sub.center_y,0) + self.assertEqual(sub.center_z,0) + def test_get_slice_horizontal_x_and_horizontal_y(self): sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) self.assertTrue( sub.shape == (5,4)) diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 2fd1939321..447cd954f9 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -442,7 +442,7 @@ def test_AcquisitionDataSubset1l(self): self.assertTrue(sub.shape == (2, 20)) def test_AcquisitionDataCentreSubset(self): - data = self.ig.allocate() + data = self.ag_flex.allocate() sub = data.get_centre_slice() sub2 = data.get_slice(vertical='centre') self.assertTrue( sub == sub2) From 06d92df800fd643130901ddcc19ca5359601ae1a Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Thu, 30 Oct 2025 10:20:10 +0000 Subject: [PATCH 7/9] Fix unit test --- Wrappers/Python/test/test_subset.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index 447cd954f9..bfd73a2001 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -168,12 +168,6 @@ def test_ImageData(self): self.assertEqual(data_new.shape,(2,4,5)) self.assertEqual(data_new.geometry.dimension_labels,('channel','horizontal_y','horizontal_x')) - def test_ImageGeometry(self): - ig = ImageGeometry(voxel_num_x=5, voxel_num_y=4, voxel_num_z=3, channels=2, dimension_labels=['channel','vertical','horizontal_y','horizontal_x']) - ig_new = ig.get_slice(vertical='centre') - self.assertEqual(ig_new.shape,(2,4,5)) - self.assertEqual(ig_new.dimension_labels,('channel','horizontal_y', 'horizontal_x')) - def test_AcquisitionData(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) data = ag.allocate(None) @@ -442,7 +436,7 @@ def test_AcquisitionDataSubset1l(self): self.assertTrue(sub.shape == (2, 20)) def test_AcquisitionDataCentreSubset(self): - data = self.ag_flex.allocate() + data = self.ag.allocate() sub = data.get_centre_slice() sub2 = data.get_slice(vertical='centre') self.assertTrue( sub == sub2) From 5d393a46abc1f8690a59c92ab28b28f0fcd4e054 Mon Sep 17 00:00:00 2001 From: Laura Murgatroyd <60604372+lauramurgatroyd@users.noreply.github.com> Date: Thu, 30 Oct 2025 11:57:15 +0000 Subject: [PATCH 8/9] Update CHANGELOG with new features and bug fixes Added new features related to image geometry and slicing. Signed-off-by: Laura Murgatroyd <60604372+lauramurgatroyd@users.noreply.github.com> --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d49152780f..1992300dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ * XX.X.X + - New features: + - Added `get_centre_slice` method to `ImageData`, `ImageGeometry`, and `AcquisitionGeometry`. (#2235) + - Allows passing 'centre' to `ImageGeometry.get_slice` (#2235) - Bug fixes: - `CentreOfRotationCorrector.image_sharpness` data is now correctly smoothed to reduce aliasing artefacts and improve robustness. (#2202) + - Sets `center_x`, `center_y`, `center_z` appropriately for `ImageGeometry` returned by `get_slice` (#2235) * 25.0.0 - New features: From 991384c120b7852cf6a86a30e8f62868453c800e Mon Sep 17 00:00:00 2001 From: lauramurgatroyd Date: Wed, 5 Nov 2025 11:10:15 +0000 Subject: [PATCH 9/9] Remove centre option on horizontal axes --- CHANGELOG.md | 2 +- .../Python/cil/framework/image_geometry.py | 20 ++++++++----------- Wrappers/Python/test/test_ImageGeometry.py | 18 ----------------- 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1992300dfe..5e1c0b9a23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ * XX.X.X - New features: - Added `get_centre_slice` method to `ImageData`, `ImageGeometry`, and `AcquisitionGeometry`. (#2235) - - Allows passing 'centre' to `ImageGeometry.get_slice` (#2235) + - Allows passing vertical='centre' to `ImageGeometry.get_slice` (#2235) - Bug fixes: - `CentreOfRotationCorrector.image_sharpness` data is now correctly smoothed to reduce aliasing artefacts and improve robustness. (#2202) - Sets `center_x`, `center_y`, `center_z` appropriately for `ImageGeometry` returned by `get_slice` (#2235) diff --git a/Wrappers/Python/cil/framework/image_geometry.py b/Wrappers/Python/cil/framework/image_geometry.py index 755caa4428..3e38a23144 100644 --- a/Wrappers/Python/cil/framework/image_geometry.py +++ b/Wrappers/Python/cil/framework/image_geometry.py @@ -178,13 +178,13 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= Parameters ---------- - channel : int, optional + channel : int or 'centre', optional The channel index to slice. Default is None (no slicing). vertical : int or 'centre', optional The vertical index to slice. Default is None (no slicing). - horizontal_x : int or 'centre', optional + horizontal_x : int, optional The horizontal x index to slice. Default is None (no slicing). - horizontal_y : int or 'centre', optional + horizontal_y : int, optional The horizontal y index to slice. Default is None (no slicing). Returns ------- @@ -193,8 +193,7 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= Note ---- - Slicing on vertical, horizontal_x or horizontal_y with 'centre' will return the - central slice in that dimension. + Slicing on vertical with 'centre' will return the central slice in that dimension. Slicing on channels returns a geometry with a single channel, however the channel label is not typically stored in the geometry. ''' @@ -207,7 +206,6 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= except: geometry_new.channel_labels = None - if vertical is not None: geometry_new.voxel_num_z = 1 if vertical != 'centre': @@ -220,15 +218,13 @@ def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y= if horizontal_y is not None: geometry_new.voxel_num_y = 1 - if horizontal_y != 'centre': - voxel_offset = (self.voxel_num_y)/2 - (horizontal_y +0.5) - geometry_new.center_y -= voxel_offset * geometry_new.voxel_size_y + voxel_offset = (self.voxel_num_y)/2 - (horizontal_y +0.5) + geometry_new.center_y -= voxel_offset * geometry_new.voxel_size_y if horizontal_x is not None: geometry_new.voxel_num_x = 1 - if horizontal_x != 'centre': - voxel_offset = (self.voxel_num_x)/2 - (horizontal_x+0.5) - geometry_new.center_x -= voxel_offset * geometry_new.voxel_size_x + voxel_offset = (self.voxel_num_x)/2 - (horizontal_x+0.5) + geometry_new.center_x -= voxel_offset * geometry_new.voxel_size_x return geometry_new diff --git a/Wrappers/Python/test/test_ImageGeometry.py b/Wrappers/Python/test/test_ImageGeometry.py index ce2c1cc2ad..d310583796 100644 --- a/Wrappers/Python/test/test_ImageGeometry.py +++ b/Wrappers/Python/test/test_ImageGeometry.py @@ -64,15 +64,6 @@ def test_get_slice_horizontal_x(self): self.assertEqual(sub.center_y,0) self.assertEqual(sub.center_z,0) - def test_get_slice_horizontal_x_centre(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], - ImageDimension["VERTICAL"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(horizontal_x = 'centre') - self.assertTrue(sub.shape == (5,3,4)) - self.assertEqual(sub.center_x,0) - self.assertEqual(sub.center_y,0) - self.assertEqual(sub.center_z,0) def test_get_slice_channel(self): non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["CHANNEL"], ImageDimension["HORIZONTAL_Y"], @@ -99,15 +90,6 @@ def test_get_slice_horizontal_y(self): self.assertEqual(sub.center_y,-1) self.assertEqual(sub.center_z,0) - def test_get_slice_horizontal_y_centre(self): - non_default_dimension_labels = [ImageDimension["HORIZONTAL_X"], ImageDimension["HORIZONTAL_Y"]] - self.ig.set_labels(non_default_dimension_labels) - sub = self.ig.get_slice(horizontal_y = 'centre') - self.assertTrue( sub.shape == (2,)) - self.assertEqual(sub.center_x,0) - self.assertEqual(sub.center_y,0) - self.assertEqual(sub.center_z,0) - def test_get_slice_horizontal_x_and_horizontal_y(self): sub = self.ig.get_slice(horizontal_x=0,horizontal_y=0) self.assertTrue( sub.shape == (5,4))