def test_image_container_metadata_init(): """ Test the metadata initialisation on the Image Container classes """ numpy = NumpyImageContainer(image=np.ones((1, 1, 1)), affine=np.eye(4)) assert numpy.metadata == {} nifti = NiftiImageContainer( nifti_img=nib.Nifti1Image(np.ones((1, 1, 1)), affine=np.eye(4))) assert nifti.metadata == {} numpy = NumpyImageContainer(image=np.ones((1, 1, 1)), affine=np.eye(4), metadata={"foo": "bar"}) assert numpy.metadata == {"foo": "bar"} nifti = NiftiImageContainer( nifti_img=nib.Nifti1Image(np.ones((1, 1, 1)), affine=np.eye(4)), metadata={"bar": "foo"}, ) assert nifti.metadata == {"bar": "foo"} with pytest.raises(TypeError): NumpyImageContainer(image=np.ones((1, 1, 1)), affine=np.eye(4), metadata=1) # non-dict with pytest.raises(TypeError): NiftiImageContainer( nifti_img=nib.Nifti1Image(np.ones((1, 1, 1)), affine=np.eye(4)), metadata="foobar", # non-dict )
def check_resampling(): """Function to visualise the resampling of a test image using pylot requires matplotlib.pyplot""" rotation = (0.0, 0.0, -45.0) translation = (10.0, -10.0, 0.0) target_shape = (128, 128, 1) (nifti_image, rotation_origin) = create_test_image() # use transform_resample_affine to obtain the affine target_affine_1, _ = rs.transform_resample_affine(nifti_image, translation, rotation, rotation_origin, target_shape) # resample using nilearn function resampled_nifti = nil.image.resample_img(nifti_image, target_affine=target_affine_1, target_shape=target_shape) nifti_image_container = NiftiImageContainer(nifti_image) resampled_nifti_image_container = NiftiImageContainer(resampled_nifti) # visually check plt.figure() plt.imshow(np.fliplr(np.rot90(nifti_image_container.image, axes=(1, 0)))) plt.title("original image") plt.axis("image") plt.figure() plt.imshow( np.fliplr(np.rot90(resampled_nifti_image_container.image, axes=(1, 0)))) plt.title("transformed and resampled with filter") plt.axis("image") plt.text( 0, resampled_nifti_image_container.shape[1], f"rotation={rotation}" "\n" f"rotation origin-{rotation_origin}" "\n" f"translation={translation}" "\n" f"shape = {resampled_nifti_image_container.shape}" "\n", {"color": "white"}, ) plt.show()
def fixture_test_image(): """Create a random test NiftiImageContainer. The data are in COMPLEX space, created from images that have - Magnitude values drawn from a standard Normal distribution (mean=0, stdev=1) - Phase values drawn from a uniform distribution (low=-pi, high=pi) - Shape: 3,4,5,6 :return: a tuple of: - the magnitude data (np.ndarray, type: float64) - the phase data (np.ndarray, type: float64) - the complex data (np.ndarray, type: complex128) in an Image Container """ random_number_generator = default_rng() magnitude_data = random_number_generator.uniform(low=0, high=1e4, size=(3, 4, 5, 6)) phase_data = random_number_generator.uniform( low=-np.pi, high=np.pi, size=(3, 4, 5, 6) ) complex_data = magnitude_data * np.exp(1j * phase_data) return ( magnitude_data, phase_data, NiftiImageContainer( nifti_img=nib.Nifti1Image(dataobj=complex_data, affine=np.eye(4),), image_type=COMPLEX_IMAGE_TYPE, data_domain=SPATIAL_DOMAIN, ), )
def _run(self): """ Load the input `filename` using nibabel and create a Image container from it. Put this in the output named `image`. """ self.outputs["image"] = NiftiImageContainer( nifti_img=nib.load(self.inputs["filename"]))
def test_image_container_unexpected_arguments(): """ Check that passing unexpected arguments raises an error """ with pytest.raises(TypeError): NumpyImageContainer(image=np.zeros((3, 3, 3)), unexpected="test") with pytest.raises(TypeError): NiftiImageContainer(nib.Nifti1Pair(np.zeros((3, 3, 3)), affine=np.eye(4)), unexpected="test")
def fixture_test_image(): """Create a test image of shape 3x3x3. Where each element (voxel) increases in value across each voxel as 0,1,2,3,...,26. The last axis changes the fastest (C-like index order)""" return NiftiImageContainer( nifti_img=nib.Nifti1Image( dataobj=np.reshape(np.array(range(3 ** 3)), (3, 3, 3)), affine=np.eye(4) ) )
def _run(self): indexed_containers = self._get_input_images() containers = [c[0] for c in indexed_containers] dataobj = np.stack([container.image for container in containers], axis=3) output_container = NiftiImageContainer(nifti_img=nib.Nifti1Image( dataobj=dataobj, affine=containers[0].affine)) output_container.data_domain = containers[0].data_domain # TODO: We could set output_container.time_step_seconds here # Create the metadata output_container.metadata = {} # Find all of the keys in all of the metadata all_keys = { key for container in containers for key in container.metadata.keys() } for key in all_keys: present = [key in container.metadata for container in containers] if sum(present) == 1: # The key appears in one container only, so copy it to the output output_container.metadata[key] = containers[present.index( True)].metadata[key] else: # The key appears in more than one containers all_values = [ container.metadata[key] if key in container.metadata else None for container in containers ] # find values that are not None values_not_none = [ val for val in all_values if val is not None ] if all_values.count(all_values[0]) == len(all_values): # All values are the same - output that value for the given key output_container.metadata[key] = containers[0].metadata[ key] elif all_values.count( values_not_none[0]) == len(values_not_none): # All values that are not None are the same, output just that value for # given key output_container.metadata[key] = values_not_none[0] else: # The values are not the same - concatenate them into a list output_container.metadata[key] = all_values self.outputs[self.KEY_IMAGE] = output_container
def test_invert_image_filter_with_nifti(): """ Test the invert image filter works correctly with NiftiImageContainer""" invert_image_filter = InvertImageFilter() array = np.ones(shape=(3, 3, 3, 1), dtype=np.float32) img = nib.Nifti2Image(dataobj=array, affine=np.eye(4)) nifti_image_container = NiftiImageContainer(nifti_img=img) invert_image_filter.add_input("image", nifti_image_container) invert_image_filter.run() assert_array_equal(invert_image_filter.outputs["image"].image, -array)
def nifti_image_containers_a() -> List[NiftiImageContainer]: """Returns a list of NiftiImageContainers. The first items uses a Nifti1Image. The second item uses a Nifti2Image""" containers = [] for image_type in [nib.Nifti1Image, nib.Nifti2Image]: temp_img = image_type(np.zeros((1, 1, 1)), affine=np.eye(4)) header = temp_img.header for key, value in NIFTI_HEADER.items(): # Skip adding headers that don't exist in a NIFTI2 header if image_type == nib.Nifti2Image and key in NIFTI2_HEADER_EXCLUDES: continue header[key] = value image_container = NiftiImageContainer(nifti_img=image_type( np.zeros(NIFTI_HEADER["dim"][1:1 + NIFTI_HEADER["dim"][0]]), affine=NIFTI_AFFINE, header=header, )) containers.append(image_container) return containers
def mock_data_fixture() -> dict: """Mock data inputs for GroundTruthLoaderFilter""" images = [ np.ones(shape=(3, 3, 3, 1), dtype=np.float32) * i for i in range(7) ] stacked_image = np.stack(arrays=images, axis=4) # Create a 5D numpy image (float32) where the value of voxel corresponds # with the distance across 5th dimension (from 0 to 6 inclusive) img = nib.Nifti2Image(dataobj=stacked_image, affine=np.eye(4)) nifti_image_container = NiftiImageContainer(nifti_img=img) return { "image": nifti_image_container, "quantities": [ "perfusion_rate", "transit_time", "t1", "t2", "t2_star", "m0", "seg_label", ], "segmentation": { "csf": 3, "grey_matter": 1, "white_matter": 2 }, "parameters": { "lambda_blood_brain": 0.9, "t1_arterial_blood": 1.65, "magnetic_field_strength": 3.0, }, "units": ["ml/100g/min", "s", "s", "s", "s", "", ""], }
from asldro.filters.append_metadata_filter import AppendMetadataFilter from asldro.filters.basefilter import FilterInputValidationError from asldro.containers.image import NiftiImageContainer TEST_VOLUME_DIMENSIONS = (32, 32, 32) TEST_NIFTI_ONES = nib.Nifti2Image( np.ones(TEST_VOLUME_DIMENSIONS), affine=np.array(( (1, 0, 0, -16), (0, 1, 0, -16), (0, 0, 1, -16), (0, 0, 0, 1), )), ) TEST_NIFTI_CON_ONES = NiftiImageContainer(nifti_img=TEST_NIFTI_ONES) TEST_METADATA = { "key1": 1.0, "key2": 2.0, "keystr": "str", "apple": "apple", "pi": np.pi, } # test data dictionary, # each entry, [0] = optional (True/False), [1] = pass, [2:] = fail INPUT_VALIDATION_DICT = { "image": (False, TEST_NIFTI_CON_ONES, TEST_NIFTI_ONES, 1, "str"), "metadata": (False, TEST_METADATA, 1, "str"), }
import numpy as np import numpy.testing import nibabel as nib from asldro.filters.acquire_mri_image_filter import AcquireMriImageFilter from asldro.filters.basefilter import FilterInputValidationError from asldro.containers.image import NiftiImageContainer logger = logging.getLogger(__name__) TEST_VOLUME_DIMENSIONS = (32, 32, 32) TEST_NIFTI_ONES = NiftiImageContainer(nifti_img=nib.Nifti2Image( np.ones(TEST_VOLUME_DIMENSIONS), affine=np.array(( (1, 0, 0, -16), (0, 1, 0, -16), (0, 0, 1, -16), (0, 0, 0, 1), )), )) # each entry, [0] = optional (True/False), [1] = pass, [2:] = fail INPUT_DICT = { "t1": (False, TEST_NIFTI_ONES, "str", np.ones(TEST_VOLUME_DIMENSIONS)), "t2": (False, TEST_NIFTI_ONES, "str", np.ones(TEST_VOLUME_DIMENSIONS)), "t2_star": (False, TEST_NIFTI_ONES, "str", np.ones(TEST_VOLUME_DIMENSIONS)), "m0": (False, TEST_NIFTI_ONES, "str", np.ones(TEST_VOLUME_DIMENSIONS)), "acq_contrast": (False, "ge", 1, TEST_NIFTI_ONES), "echo_time": (False, 0.1, "str", TEST_NIFTI_ONES), "repetition_time": (False, 0.1, "str", TEST_NIFTI_ONES),
def input_validation_dict_fixture(): """Returns an object of tuples containing test data for input validation of the GroundTruthLoaderFilter""" test_volume_dimensions = (3, 3, 3, 1, 7) test_nifti_ones = nib.Nifti2Image( np.ones(test_volume_dimensions), affine=np.eye(4), ) test_nifti_con_ones = NiftiImageContainer(nifti_img=test_nifti_ones) par_dict = { "lambda_blood_brain": 0.9, "t1_arterial_blood": 1.65, "magnetic_field_strength": 3.0, } seg_dict = {"csf": 3, "grey_matter": 1, "white_matter": 2} quantities = [ "perfusion_rate", "transit_time", "t1", "t2", "t2_star", "m0", "seg_label", ] units = ["ml/100g/min", "s", "s", "s", "s", "", ""] # tuples where # 0: is_optional # 1: correct values # 2:end values that should fail return { "image": (False, test_nifti_con_ones, test_nifti_ones, 1, "str"), "quantities": (False, quantities, "str", 1, par_dict), "units": (False, units, units[:6], "str", 1, par_dict), "parameters": (False, par_dict, "str", test_nifti_con_ones, 1), "segmentation": (False, seg_dict, "str", test_nifti_con_ones, 1), "image_override": ( True, # is optional { "m0": 10, "t2": 1.1 }, # good data { "bad_key": 10, "t2": 1.1 }, # no bad_key quantity { "m0": "a_str" }, # values must be int/float "a_str", # must be dictionary input ), "parameter_override": ( True, # is optional { "lambda_blood_brain": 10, "t1_arterial_blood": 1.1 }, # good data { "lambda_blood_brain": "a_str" }, # values must be int/float "a_str", # must be dictionary input ), }
def test_bids_output_filter_complex_image_component(): """tests that the field ComplexImageComponent is correctly set""" with TemporaryDirectory() as temp_dir: image = deepcopy(TEST_NIFTI_CON_ONES) image.image_type = "MAGNITUDE_IMAGE_TYPE" bids_output_filter = BidsOutputFilter() bids_output_filter.add_input("image", image) bids_output_filter.add_input("output_directory", temp_dir) bids_output_filter.run() assert ( bids_output_filter.outputs["sidecar"]["ComplexImageComponent"] == "MAGNITUDE" ) with TemporaryDirectory() as temp_dir: image = deepcopy(TEST_NIFTI_CON_ONES) image.image_type = "REAL_IMAGE_TYPE" bids_output_filter = BidsOutputFilter() bids_output_filter.add_input("image", image) bids_output_filter.add_input("output_directory", temp_dir) bids_output_filter.run() assert bids_output_filter.outputs["sidecar"]["ComplexImageComponent"] == "REAL" with TemporaryDirectory() as temp_dir: image = deepcopy(TEST_NIFTI_CON_ONES) image.image_type = "IMAGINARY_IMAGE_TYPE" bids_output_filter = BidsOutputFilter() bids_output_filter.add_input("image", image) bids_output_filter.add_input("output_directory", temp_dir) bids_output_filter.run() assert ( bids_output_filter.outputs["sidecar"]["ComplexImageComponent"] == "IMAGINARY" ) with TemporaryDirectory() as temp_dir: image = deepcopy(TEST_NIFTI_CON_ONES) image.image_type = "PHASE_IMAGE_TYPE" bids_output_filter = BidsOutputFilter() bids_output_filter.add_input("image", image) bids_output_filter.add_input("output_directory", temp_dir) bids_output_filter.run() assert bids_output_filter.outputs["sidecar"]["ComplexImageComponent"] == "PHASE" with TemporaryDirectory() as temp_dir: image = NiftiImageContainer( nifti_img=nib.Nifti2Image( np.random.normal(100, 10, TEST_VOLUME_DIMENSIONS), affine=np.array( ((1, 0, 0, -16), (0, 1, 0, -16), (0, 0, 1, -16), (0, 0, 0, 1),) ), ), metadata={ "series_number": 1, "series_type": "structural", "modality": "T1w", }, ) image.image_type = "COMPLEX_IMAGE_TYPE" bids_output_filter = BidsOutputFilter() bids_output_filter.add_input("image", image) bids_output_filter.add_input("output_directory", temp_dir) bids_output_filter.run() assert ( bids_output_filter.outputs["sidecar"]["ComplexImageComponent"] == "COMPLEX" )
import numpy.testing import nibabel as nib from asldro.filters.bids_output_filter import BidsOutputFilter from asldro.filters.basefilter import FilterInputValidationError from asldro.containers.image import NiftiImageContainer from asldro import __version__ as asldro_version TEST_VOLUME_DIMENSIONS = (32, 32, 32) TEST_NIFTI_ONES = nib.Nifti2Image( np.ones(TEST_VOLUME_DIMENSIONS), affine=np.array(((1, 0, 0, -16), (0, 1, 0, -16), (0, 0, 1, -16), (0, 0, 0, 1),)), ) TEST_NIFTI_CON_ONES = NiftiImageContainer( nifti_img=TEST_NIFTI_ONES, metadata={"series_number": 1, "series_type": "structural", "modality": "T1w",}, ) INPUT_VALIDATION_DICT = { "image": [False, TEST_NIFTI_CON_ONES, TEST_NIFTI_ONES, 1, "str"], "output_directory": [False, "tempdir_placeholder", 1, "str"], "filename_prefix": [True, "prefix", 1, TEST_NIFTI_CON_ONES], } METDATA_VALIDATION_DICT_STRUCT = { "series_number": [False, 1, "001", 1.0], "series_type": [False, "structural", "struct", 1], "modality": [False, "T1w", "t1w", 1], } METDATA_VALIDATION_DICT_ASL = {
def test_transform_resample_image_filter_mock_data(): """ Test the transform_resampe_image_filter with some mock data """ # Create some synthetic data grid = np.mgrid[0:128, 0:128] circle = ( np.sum((grid - np.array([32, 32])[:, np.newaxis, np.newaxis]) ** 2, axis=0) < 256 ) diamond = ( np.sum(np.abs(grid - np.array([75, 32])[:, np.newaxis, np.newaxis]), axis=0) < 16 ) rectangle = ( np.max(np.abs(grid - np.array([64, 64])[:, np.newaxis, np.newaxis]), axis=0) < 16 ) image = np.zeros_like(circle) image = image + circle + 2.0 * rectangle + 3.0 * diamond + np.eye(128) image = numpy.expand_dims(image, axis=2) # define world coordinate origin (x,y,z) = (0,0,0) at (i,j,k) = (64,64,1) # and 1 voxel == 1mm isotropically # therefore according to RAS+: source_affine = np.array( ((1, 0, 0, -64), (0, 1, 0, -64), (0, 0, 1, -0.5), (0, 0, 0, 1)) ) nifti_image = nib.Nifti2Image(image, affine=source_affine) rotation = (0.0, 0.0, 45.0) rotation_origin = tuple( np.array(nil.image.coord_transform(75, 32, 0, source_affine)).astype(float) ) # rotation_origin = (0.0, 0.0, 0.0) translation = (0.0, 10.0, 0.0) target_shape = (64, 64, 1) image[ tuple( np.rint( nil.image.coord_transform( rotation_origin[0], rotation_origin[1], rotation_origin[2], np.linalg.inv(source_affine), ) ).astype(np.int32) ) ] = 5.0 # create NiftiImageContainer of this image nifti_image_container = NiftiImageContainer(nifti_image) xr_obj_filter = TransformResampleImageFilter() xr_obj_filter.add_input( TransformResampleImageFilter.KEY_IMAGE, nifti_image_container ) xr_obj_filter.add_input(TransformResampleImageFilter.KEY_ROTATION, rotation) xr_obj_filter.add_input( TransformResampleImageFilter.KEY_ROTATION_ORIGIN, rotation_origin ) xr_obj_filter.add_input(TransformResampleImageFilter.KEY_TRANSLATION, translation) xr_obj_filter.add_input(TransformResampleImageFilter.KEY_TARGET_SHAPE, target_shape) xr_obj_filter.run() new_nifti_container: NiftiImageContainer = xr_obj_filter.outputs[ TransformResampleImageFilter.KEY_IMAGE ] ### function called here str_nifti, _ = transform_resample_image( nifti_image, translation, rotation, rotation_origin, target_shape ) # data should match numpy.testing.assert_array_equal(str_nifti.dataobj, new_nifti_container.image) # Affines should match numpy.testing.assert_array_equal(str_nifti.affine, new_nifti_container.affine) # confirm the voxel_size is calculated correctly. numpy.testing.assert_array_equal( new_nifti_container.metadata["voxel_size"], nib.affines.voxel_sizes(new_nifti_container.affine), )
import numpy as np import numpy.testing import nibabel as nib import nilearn as nil from asldro.filters.basefilter import BaseFilter, FilterInputValidationError from asldro.containers.image import NiftiImageContainer from asldro.filters.transform_resample_image_filter import TransformResampleImageFilter from asldro.utils.resampling import transform_resample_image logger = logging.getLogger(__name__) TEST_VOLUME_DIMENSIONS = (32, 32, 32) TEST_NIFTI_ONES = NiftiImageContainer( nifti_img=nib.Nifti2Image(np.zeros(TEST_VOLUME_DIMENSIONS), affine=np.eye(4)) ) INPUT_VALIDATION_DICTIONARY = { "image": (TEST_NIFTI_ONES, np.ones(TEST_VOLUME_DIMENSIONS), "str", 1.0), "target_shape": ( TEST_VOLUME_DIMENSIONS, (16.0, 16.0, 16.0), (1, 2, 3, 4), "str", 1, [32, 32, 32], ), "rotation": ( (0.0, 0.0, 0.0), 1.0,
def test_resample_filter_single_point_transformations( rotation: float, rotation_origin: float, translation: float, scale: float, target_shape: tuple, expected_signal: list, ): # pylint: disable=too-many-locals, too-many-arguments """Tests the ResampleFilter by resampling an image comprising of points based on affines that are generated with rotation, translation, and scale parameters. After resampling, `expected_signal` is a list of tuples defining voxel coordinates where signal should be, and `expected_background` is a list of tuples defining voxel coordinates where signal shouldn't be. :param rotation: Tuple of floats describing rotation angles about x, y, z :type rotation: float :param rotation_offset: Tuple of floats describing the coordinates of the rotation origin :type rotation_offset: float :param translation: Tuple of floats describing a translation vector :type translation: float :param scale: Tuple of floats describing scaling along x, y, z :type scale: Tuple[float, float, float] :param target_shape: Target shape after resampling :type target_shape: Tuple[float, float, float] :param expected_signal: List of [x,y,z] coordinates where signal should be expected :type expected_signal: list :param expected_background: List of [x,y,z] coordinates where background should be expected :type expected_background: list """ # create blank image n_i = 100 n_j = 100 n_k = 100 image = np.zeros((n_i, n_j, n_k)) # define world coordinate origin (x,y,z) = (0,0,0) at (i,j,k) = (50,50,50) # and 1 voxel == 1mm isotropically # therefore according to RAS+: affine = np.array(((1, 0, 0, -50), (0, 1, 0, -50), (0, 0, 1, -50), (0, 0, 0, 1),)) # define a vector in this space: world coords (10, 10, 10) vector_image_coords = np.rint( nil.image.coord_transform(10, 10, 10, np.linalg.inv(affine)) ).astype(np.int32) # assign this point as signal (== 1) image[vector_image_coords[0], vector_image_coords[1], vector_image_coords[2]] = 1 nii = nib.Nifti2Image(image, affine=affine) original_image_container = NiftiImageContainer(nifti_img=nii) # Create transformation affine. affine_filter = AffineMatrixFilter() affine_filter.add_input("affine", affine) affine_filter.add_input("rotation", rotation) affine_filter.add_input("rotation_origin", rotation_origin) affine_filter.add_input("translation", translation) affine_filter.add_input("scale", scale) # ResampleFilter resample_filter = ResampleFilter() resample_filter.add_input("image", original_image_container) resample_filter.add_input("shape", target_shape) resample_filter.add_parent_filter(affine_filter) resample_filter.run() transformed_image = resample_filter.outputs["image"] # Compare voxels where signal is above a threshold - the resampling will not preserve # exact values signal_threshold = 0.1 signal_detected = transformed_image.image > signal_threshold signal_should_be_present = np.zeros_like(signal_detected, dtype=bool) signal_should_be_present[expected_signal] = True numpy.testing.assert_array_equal(signal_detected, signal_should_be_present)
def _run(self): """Load the inputs using a NiftiLoaderFilter and JsonLoaderFilter. Create the image outputs and the segmentation key outputs""" image_container: NiftiImageContainer = self.inputs[self.KEY_IMAGE] for i, quantity in enumerate(self.inputs[self.KEY_QUANTITIES]): # Create a new NiftiContainer - easier as we can just augment # the header to remove the 5th dimension header = copy.deepcopy(image_container.header) header["dim"][0] = 4 # Remove the 5th dimension if header["dim"][4] == 1: # If we only have 1 time-step, reduce to 3D header["dim"][0] = 3 header["dim"][5] = 1 # tidy the 5th dimensions size # Grab the relevant image data image_data: np.ndarray = image_container.image[:, :, :, :, i] if header["dim"][0] == 3: # squeeze the 4th dimension if there is only one time-step image_data = np.squeeze(image_data, axis=3) # If we have a corresponding 'image_override' value, update the # 'image_data' with that value if ( self.KEY_IMAGE_OVERRIDE in self.inputs and quantity in self.inputs[self.KEY_IMAGE_OVERRIDE] ): image_data.fill(self.inputs[self.KEY_IMAGE_OVERRIDE][quantity]) # If we have a segmentation label, round and squash the # data to uint16 and update the NIFTI header metadata = {} if quantity == "seg_label": header["datatype"] = 512 image_data = np.around(image_data).astype(dtype=np.uint16) metadata[self.KEY_SEGMENTATION] = self.inputs[self.KEY_SEGMENTATION] nifti_image_type = image_container.nifti_type metadata[self.KEY_MAG_STRENGTH] = self.inputs[self.KEY_PARAMETERS][ self.KEY_MAG_STRENGTH ] metadata[self.KEY_QUANTITY] = quantity metadata[self.KEY_UNITS] = self.inputs[self.KEY_UNITS][i] # If we have a ground_truth_modulate input, and this quantity is to be modulated if ( "ground_truth_modulate" in self.inputs and quantity in self.inputs["ground_truth_modulate"] ): scale_offset = self.inputs["ground_truth_modulate"][quantity] if "scale" in scale_offset: # Allow unsafe casting (allow data-type conversion) image_data = np.multiply( image_data, scale_offset["scale"], casting="unsafe" ) if "offset" in scale_offset: # Allow unsafe casting (allow data-type conversion) image_data = np.add( image_data, scale_offset["offset"], casting="unsafe" ) new_image_container = NiftiImageContainer( nifti_img=nifti_image_type( dataobj=image_data, affine=image_container.affine, header=header ), metadata=metadata, ) self.outputs[quantity] = new_image_container # Get the parameter_override dictionary (empty dict if it doesn't exist) overrides = ( self.inputs[self.KEY_PARAMETER_OVERRIDE] if self.KEY_PARAMETER_OVERRIDE in self.inputs else {} ) # Pipe through all parameters self.outputs = {**self.outputs, **self.inputs[self.KEY_PARAMETERS], **overrides}
def test_resample_filter_mock_data(): """ Test the resample_filter with some mock data """ # Create some synthetic data grid = np.mgrid[0:128, 0:128] circle = ( np.sum((grid - np.array([32, 32])[:, np.newaxis, np.newaxis]) ** 2, axis=0) < 256 ) diamond = ( np.sum(np.abs(grid - np.array([75, 32])[:, np.newaxis, np.newaxis]), axis=0) < 16 ) rectangle = ( np.max(np.abs(grid - np.array([64, 96])[:, np.newaxis, np.newaxis]), axis=0) < 16 ) image = np.zeros_like(circle) image = image + circle + 2.0 * rectangle + 3.0 * diamond image = numpy.expand_dims(image, axis=2) source_affine = np.eye(4) nifti_image = nib.Nifti2Image(image, affine=source_affine) # create NumpyImageContainer and NiftiImageContainer of this image numpy_image_container = NumpyImageContainer(image=image, affine=source_affine) nifti_image_container = NiftiImageContainer(nifti_image) # Create affine matrix for a translation of +10 along the x-axis affine_translate = AffineMatrixFilter() affine_translate.add_input(AffineMatrixFilter.KEY_TRANSLATION, (10.0, 0.0, 0.0)) affine_translate.run() target_affine = affine_translate.outputs["affine"] target_shape = (128, 128, 1) # resample image without using the filter resampled_image = nil.image.resample_img( nifti_image, target_affine=target_affine, target_shape=target_shape ) # run for the NumpyImageContainer resample_translate_filter = ResampleFilter() resample_translate_filter.add_input("affine", target_affine) resample_translate_filter.add_input("image", numpy_image_container) resample_translate_filter.add_input("shape", target_shape) resample_translate_filter.run() resampled_numpy_container = resample_translate_filter.outputs["image"].clone() # run for the NiftiImageContainer resample_translate_filter = ResampleFilter() resample_translate_filter.add_input("affine", target_affine) resample_translate_filter.add_input("image", nifti_image_container) resample_translate_filter.add_input("shape", target_shape) resample_translate_filter.run() resampled_nifti_container = resample_translate_filter.outputs["image"].clone() # compare outputs: image data numpy.testing.assert_array_equal( np.asanyarray(resampled_image.dataobj), resampled_numpy_container.image, ) numpy.testing.assert_array_equal( np.asanyarray(resampled_image.dataobj), resampled_nifti_container.image, ) # compare outputs: affine numpy.testing.assert_array_equal( resampled_image.affine, resampled_numpy_container.affine, ) numpy.testing.assert_array_equal( resampled_image.affine, resampled_nifti_container.affine, )
def icbm_v1_nifti(): """ Returns the ICBM v1 test nifti data """ return NiftiImageContainer(nifti_img=nib.load( os.path.join(definitions.ROOT_DIR, "data", "hrgt_ICBM_2009a_NLS_v1.nii.gz")))