def test_add_complex_noise_filter_wrong_input_type_error(): """Check a FilterInputValidationError is raised when the inputs to the add commplex noise filter are incorrect or missing""" noise_filter = AddComplexNoiseFilter() noise_filter.add_input("snr", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # image not defined noise_filter.add_input("image", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # image wrong type noise_filter = AddComplexNoiseFilter() noise_filter.add_input( "image", NumpyImageContainer(image=np.zeros(TEST_VOLUME_DIMENSIONS)) ) with pytest.raises(FilterInputValidationError): noise_filter.run() # snr not defined noise_filter.add_input("snr", "str") with pytest.raises(FilterInputValidationError): noise_filter.run() # snr wrong type noise_filter = AddComplexNoiseFilter() noise_filter.add_input( "image", NumpyImageContainer(image=np.zeros(TEST_VOLUME_DIMENSIONS)) ) noise_filter.add_input("snr", 1) noise_filter.add_input("reference_image", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # reference_image wrong type
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 casl_input_fixture() -> dict: """Creates test data for testing the CASL/pCASL model""" np.random.seed(0) return { "perfusion_rate": NumpyImageContainer( image=np.random.normal(60, 10, TEST_VOLUME_DIMENSIONS)), "transit_time": TEST_IMAGE_ONES, "t1_tissue": NumpyImageContainer(image=1.4 * np.ones(TEST_VOLUME_DIMENSIONS)), "m0": TEST_IMAGE_ONES, "label_type": CASL, "label_duration": 1.8, "signal_time": 3.6, "label_efficiency": 0.85, "lambda_blood_brain": 0.9, "t1_arterial_blood": 1.6, }
def mock_data_fixture() -> dict: """ creates valid mock test data """ np.random.seed(0) return { "t1": NumpyImageContainer( image=np.random.normal(1.4, 0.1, TEST_VOLUME_DIMENSIONS)), "t2": NumpyImageContainer( image=np.random.normal(0.1, 0.01, TEST_VOLUME_DIMENSIONS)), "t2_star": NumpyImageContainer( image=np.random.normal(0.7, 0.01, TEST_VOLUME_DIMENSIONS)), "m0": NumpyImageContainer( image=np.random.normal(100, 1, TEST_VOLUME_DIMENSIONS)), "mag_enc": NumpyImageContainer( image=np.random.normal(1, 0.1, TEST_VOLUME_DIMENSIONS)), "acq_contrast": "ge", "echo_time": 0.01, "repetition_time": 1.0, "excitation_flip_angle": 90.0, }
def test_add_complex_noise_filter_with_mock_data(): """ Test the add complex noise filter with some data """ signal_level = 100.0 snr = 100.0 seed = 1234 np.random.seed(seed) image = np.random.normal(signal_level, 10, TEST_VOLUME_DIMENSIONS) reference_image = image np.random.seed(seed) image_with_noise = add_complex_noise_function(image, reference_image, snr) image_container = NumpyImageContainer(image=image) reference_container = NumpyImageContainer(image=reference_image) noise_filter_1 = AddComplexNoiseFilter() noise_filter_1.add_input("image", image_container) noise_filter_1.add_input("snr", snr) # noise filter 2, copy of noise_filter_1 noise_filter_2 = deepcopy(noise_filter_1) # noise filter 3 with reference noise_filter_3 = deepcopy(noise_filter_2) noise_filter_3.add_input("reference_image", reference_container) noise_filter_1.run() # reset RNG np.random.seed(seed) noise_filter_2.run() # reset RNG np.random.seed(seed) noise_filter_3.run() # Compare output of noise_filter_1 with image_with_noise # seed is different so they should not be equal with numpy.testing.assert_raises(AssertionError): numpy.testing.assert_array_equal( noise_filter_1.outputs["image"].image, image_with_noise ) # Compare output of noise_filter_2 with image_with_noise # seed is the same so they should be equal numpy.testing.assert_array_equal( noise_filter_2.outputs["image"].image, image_with_noise ) # Compare output of noise_filter_3 with image_with_noise # seed is the same so they should be equal numpy.testing.assert_array_equal( noise_filter_3.outputs["image"].image, image_with_noise ) # Calculate the SNR of the images using the subtraction method calculated_snr = simulate_dual_image_snr_measurement_function(image_container, snr) print(f"calculated snr = {calculated_snr}, desired snr = {snr}") # This should be almost equal to the desired snr numpy.testing.assert_array_almost_equal(calculated_snr, snr, 0)
def test_numpy_image_container_time_step_seconds_setter( numpy_image_container: NumpyImageContainer, ): """ Test that the correct time step is get on a NumpyImageContainer """ numpy_image_container.time_step_seconds = 10.0 numpy_image_container.time_units = UNITS_MILLISECONDS np.testing.assert_almost_equal(numpy_image_container.time_step_seconds, 10000.0)
def test_image_container_metadata_get_set(): """ Test the Image Container metadata getting and setting """ numpy = NumpyImageContainer(image=np.ones((1, 1, 1)), affine=np.eye(4)) assert numpy.metadata == {} numpy.metadata = {"one": 1, "two": 2} assert numpy.metadata == {"one": 1, "two": 2} numpy.metadata["three"] = 3 assert numpy.metadata == {"one": 1, "two": 2, "three": 3} with pytest.raises(TypeError): numpy.metadata = "not a dict"
def test_numpy_image_container_time_step_seconds_getter( numpy_image_container: NumpyImageContainer, ): """ Test that the correct time step is returned from a NumpyImageContainer """ # NIFTI header has seconds in xytz_units assert numpy_image_container.time_step_seconds == 2000.0 numpy_image_container.time_units = UNITS_MILLISECONDS assert numpy_image_container.time_step_seconds == 2e6 numpy_image_container.time_units = UNITS_MICROSECONDS assert numpy_image_container.time_step_seconds == 2e9
def test_numpy_image_container_voxel_size_mm_setter( numpy_image_container: NumpyImageContainer, ): """ Test that the correct voxel size is set on a NumpyImageContainer """ # voxel size is 2x2x2mm numpy_image_container.voxel_size_mm = [3.0, 2.0, 1.0] numpy_image_container.space_units = UNITS_METERS # Just test that we have 3x2x1m reported in mm np.testing.assert_array_almost_equal(numpy_image_container.voxel_size_mm, np.array([3000.0, 2000.0, 1000.0]))
def test_image_container_spatial_domain_initialisation(): """Check that passing a string not in SPATIAL_DOMAIN or INVERSE_DOMAIN to data_domain raises an exception ( and vice versa )""" with pytest.raises(ValueError): NumpyImageContainer(image=np.zeros((3, 3, 3)), data_domain="foobar") image_container = NumpyImageContainer(image=np.zeros((3, 3, 3)), data_domain=SPATIAL_DOMAIN) # OK assert image_container.data_domain == SPATIAL_DOMAIN image_container = NumpyImageContainer(image=np.zeros((3, 3, 3)), data_domain=INVERSE_DOMAIN) # OK assert image_container.data_domain == INVERSE_DOMAIN
def test_numpy_image_container_voxel_size_mm_getter( numpy_image_container: NumpyImageContainer, ): """ Test that the correct voxel size is returned from a NumpyImageContainer """ # NIFTI header has mm in xyzt_units np.testing.assert_array_almost_equal(numpy_image_container.voxel_size_mm, np.array([2.0, 2.0, 2.2])) numpy_image_container.space_units = UNITS_METERS np.testing.assert_array_almost_equal(numpy_image_container.voxel_size_mm, np.array([2000.0, 2000.0, 2200.0])) numpy_image_container.space_units = UNITS_MICRONS np.testing.assert_array_almost_equal(numpy_image_container.voxel_size_mm, np.array([2.0e-3, 2.0e-3, 2.2e-3]))
def test_range_exclusive_validator_image_container(): """ Test the exclusive validator with an image container """ validator = range_exclusive_validator(-1, 1) assert str(validator) == "Value(s) must be between -1 and 1 (exclusive)" image_container = NumpyImageContainer( image=np.array([[-0.5, 0.2], [0.1, -0.9]])) assert validator(image_container) image_container = NumpyImageContainer( image=np.array([[-1.0, 0.2], [0.1, -0.9]])) assert not validator(image_container) image_container = NumpyImageContainer( image=np.array([[-0.5, 0.2], [1, -0.9]])) assert not validator(image_container)
def test_greater_than_equal_to_validator_image_container(): """ Test the greater than equal to validator with an image container """ validator = greater_than_equal_to_validator(1.5) assert str(validator) == "Value(s) must be greater than or equal to 1.5" image_container = NumpyImageContainer( image=np.array([[-0.5, 0.2], [0.1, -0.9]])) assert not validator(image_container) image_container = NumpyImageContainer( image=np.array([[1.5, 2.2], [1.7, 90]])) assert validator(image_container) image_container = NumpyImageContainer( image=np.array([[1.51, 2.2], [1.7, 90]])) assert validator(image_container)
def test_numpy_image_container_clone(): """ Check that the numpy image container is cloned correctly """ # Use none of the default parameters image_container = NumpyImageContainer( image=np.ones(shape=(3, 4, 5)), affine=np.eye(4) * 2, space_units=UNITS_METERS, time_units=UNITS_MICROSECONDS, voxel_size=np.array([1, 2, 3]), time_step=0.5, data_domain=INVERSE_DOMAIN, ) cloned_image_container = image_container.clone() general_image_container_clone_tests(image_container, cloned_image_container)
def test_isinstance_validator(): """ Test the isinstance_validator """ validator = isinstance_validator(str) assert str(validator) == "Value must be of type str" assert validator("foo") assert not validator([]) assert not validator({}) assert not validator(1) assert not validator(2.0) validator = isinstance_validator(int) assert str(validator) == "Value must be of type int" assert validator(1) assert not validator("foo") assert not validator(1.0) assert not validator([]) assert not validator({}) validator = isinstance_validator(BaseImageContainer) assert str(validator) == "Value must be of type BaseImageContainer" image_container = NumpyImageContainer( image=np.array([[-0.5, 0.2], [0.1, -0.9]])) assert validator(image_container) assert not validator("foo") assert not validator(1) assert not validator([]) validator = isinstance_validator((float, int)) assert str(validator) == "Value must be of type float or int" assert validator(1.0) assert validator(2) assert not validator([1]) assert not validator([1, 2]) assert not validator("foo") assert not validator(["foo", "bar"])
def test_numpy_image_container_image_properties( numpy_image_container: NumpyImageContainer, ): """ Test the numpy image container image setter/getter """ new_image = np.ones(shape=(4, 4, 4)) * 10 numpy_image_container.image = new_image numpy.testing.assert_array_equal(numpy_image_container.image, new_image) assert numpy_image_container.image.shape == (4, 4, 4)
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 complex_image_container_function() -> NumpyImageContainer: """ Creates a NumpyImageContainer with mock real data """ signal_level = 100.0 np.random.seed(0) image = np.random.normal( signal_level / np.sqrt(2), 10, (32, 32, 32)) + 1j * np.random.normal(signal_level / np.sqrt(2), 10, (32, 32, 32)) return NumpyImageContainer(image=image)
def test_mri_signal_timecourse( t1: float, t2: float, m0: float, t2_star: float, acq_contrast: str, echo_time: float, repetition_time: float, expected: float, ): """Tests the MriSignalFilter with timecourse data that is generated at multiple echo times Args: t1 (float): longitudinal relaxation time, s t2 (float): transverse relaxation time, s m0 (float): equilibrium magnetisation t2_star (float): transverse relaxation time inc. time invariant fields, s acq_contrast (str): signal model to use: 'ge' or 'se' echo_time (float): array of echo times, s repetition_time (float): repeat time, s expected (float): Array of expected values that the MriSignalFilter should generate Should be the same size and shape as 'echo_time' """ mri_signal_timecourse = np.ndarray(echo_time.shape) for idx, te in np.ndenumerate(echo_time): params = { "t1": NumpyImageContainer(image=np.full((1, 1, 1), t1)), "t2": NumpyImageContainer(image=np.full((1, 1, 1), t2)), "t2_star": NumpyImageContainer(image=np.full((1, 1, 1), t2_star)), "m0": NumpyImageContainer(image=np.full((1, 1, 1), m0)), "mag_enc": NumpyImageContainer(image=np.zeros((1, 1, 1))), "acq_contrast": acq_contrast, "echo_time": te, "repetition_time": repetition_time, "excitation_flip_angle": 90.0, } mri_signal_filter = MriSignalFilter() mri_signal_filter = add_multiple_inputs_to_filter( mri_signal_filter, params) mri_signal_filter.run() mri_signal_timecourse[idx] = mri_signal_filter.outputs["image"].image # arrays should be equal to 9 decimal places numpy.testing.assert_array_almost_equal(mri_signal_timecourse, expected, 9)
def test_gkm_timecourse( f: float, delta_t: float, timepoints: np.array, label_type: str, tau: float, alpha: str, expected: np.ndarray, ): # pylint: disable=too-many-arguments """Tests the GkmFilter with timecourse data that is generated at multiple 'signal_time's. Arguments: f (float): Perfusion Rate, ml/100g/min delta_t (float): Bolus arrival time/transit time, seconds timepoints (np.array): Array of time points that the signal is generated at, seconds label_type (str): GKM model to use: 'PASL' or 'CASL'/'pCASL' tau (float): Label duration, seconds alpha (str): Label efficiency, 0 to 1 expected (np.ndarray): Array of expected values that the GkmFilter should generate. Should be the same size and shape as `timepoints`. """ delta_m_timecourse = np.ndarray(timepoints.shape) for idx, t in np.ndenumerate(timepoints): params = { "perfusion_rate": NumpyImageContainer(image=f * np.ones((1, 1, 1))), "transit_time": NumpyImageContainer(image=delta_t * np.ones((1, 1, 1))), "t1_tissue": NumpyImageContainer(image=1.4 * np.ones((1, 1, 1))), "m0": 1.0, "label_type": label_type, "label_duration": tau, "signal_time": t, "label_efficiency": alpha, "lambda_blood_brain": 0.9, "t1_arterial_blood": 1.6, } gkm_filter = GkmFilter() gkm_filter = add_multiple_inputs_to_filter(gkm_filter, params) gkm_filter.run() delta_m_timecourse[idx] = gkm_filter.outputs["delta_m"].image # arrays should be equal to 9 decimal places numpy.testing.assert_array_almost_equal(delta_m_timecourse, expected, 10)
def test_gkm_filter_pasl(pasl_input): """Test the GkmFilter for Pulsed ASL""" gkm_filter = GkmFilter() gkm_filter = add_multiple_inputs_to_filter(gkm_filter, pasl_input) gkm_filter.run() delta_m = gkm_pasl_function(pasl_input) numpy.testing.assert_array_equal(delta_m, gkm_filter.outputs["delta_m"].image) # Set 'signal_time' to be less than the transit time so that the bolus # has not arrived yet pasl_input["signal_time"] = 0.5 assert (pasl_input["signal_time"] < pasl_input["transit_time"].image).all() gkm_filter = GkmFilter() gkm_filter = add_multiple_inputs_to_filter(gkm_filter, pasl_input) gkm_filter.run() # check the m0 is added to the metadata, as all values of m0 for the image are the same gkm_filter.outputs["delta_m"].metadata["m0"] = 1.0 # 'delta_m' should be all zero numpy.testing.assert_array_equal( gkm_filter.outputs["delta_m"].image, np.zeros(gkm_filter.outputs["delta_m"].shape), ) # create input images with some zeros in to test that divide-by-zero is not encountered at # runtime image_with_some_zeros = numpy.concatenate((np.ones( (32, 32, 16)), np.zeros((32, 32, 16))), axis=2) pasl_input["perfusion_rate"] = NumpyImageContainer(image=60 * image_with_some_zeros) pasl_input["transit_time"] = NumpyImageContainer( image=image_with_some_zeros) pasl_input["m0"] = NumpyImageContainer(image=image_with_some_zeros) pasl_input["t1_tissue"] = NumpyImageContainer(image=1.4 * image_with_some_zeros) pasl_input["lambda_blood_brain"] = 0.0 pasl_input["t1_arterial_blood"] = 0.0 gkm_filter = GkmFilter() gkm_filter = add_multiple_inputs_to_filter(gkm_filter, pasl_input) gkm_filter.run()
def test_numpy_to_nifti(numpy_image_container: NumpyImageContainer): """ Check the as_nifti functionality works correctly on a nifti container """ for new_image_container in [ numpy_image_container.as_numpy(), numpy_image_container.as_nifti(), ]: np.testing.assert_array_equal(new_image_container.image, numpy_image_container.image) np.testing.assert_array_equal(new_image_container.affine, numpy_image_container.affine) assert new_image_container.data_domain == numpy_image_container.data_domain assert new_image_container.image_type == numpy_image_container.image_type assert new_image_container.metadata == numpy_image_container.metadata assert new_image_container.space_units == numpy_image_container.space_units assert new_image_container.time_units == numpy_image_container.time_units np.testing.assert_array_equal(new_image_container.voxel_size_mm, numpy_image_container.voxel_size_mm) assert (new_image_container.time_step_seconds == numpy_image_container.time_step_seconds)
def test_fourier_filters_fft_validation(): """Check that running an fft on an INVERSE_DOMAIN image raises a FilterInputValidationError""" image_data = np.random.normal(0, 1, TEST_VOLUME_DIMENSIONS) image_container = NumpyImageContainer(image=image_data, data_domain=INVERSE_DOMAIN) fft_filter = FftFilter() fft_filter.add_input("image", image_container) with pytest.raises(FilterInputValidationError): fft_filter.run()
def test_invert_image_filter_with_numpy(): """ Test the invert image filter works correctly with NumpyImageContainer""" invert_image_filter = InvertImageFilter() array = np.ones(shape=(3, 3, 3, 1), dtype=np.float32) nifti_image_container = NumpyImageContainer(image=array) invert_image_filter.add_input("image", nifti_image_container) invert_image_filter.run() assert_array_equal(invert_image_filter.outputs["image"].image, -array)
def test_add_noise_filter_validate_inputs(): """Check a FilterInputValidationError is raised when the inputs to the add commplex noise filter are incorrect or missing""" noise_filter = AddNoiseFilter() noise_filter.add_input("snr", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # image not defined noise_filter.add_input("image", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # image wrong type noise_filter = AddNoiseFilter() noise_filter.add_input("image", NumpyImageContainer(image=np.zeros((32, 32, 32)))) with pytest.raises(FilterInputValidationError): noise_filter.run() # snr not defined noise_filter.add_input("snr", "str") with pytest.raises(FilterInputValidationError): noise_filter.run() # snr wrong type noise_filter = AddNoiseFilter() noise_filter.add_input("image", NumpyImageContainer(image=np.zeros((32, 32, 32)))) noise_filter.add_input("snr", 1) noise_filter.add_input("reference_image", 1) with pytest.raises(FilterInputValidationError): noise_filter.run() # reference_image wrong type noise_filter = AddNoiseFilter() noise_filter.add_input("image", NumpyImageContainer(image=np.zeros((32, 32, 32)))) noise_filter.add_input("snr", 1) noise_filter.add_input("reference_image", NumpyImageContainer(image=np.zeros((32, 32, 31)))) with pytest.raises(FilterInputValidationError): noise_filter.run() # reference_image wrong shape
def numpy_image_container() -> NumpyImageContainer: """ Creates and returns a NumpyImageContainer for testing """ return NumpyImageContainer( image=np.ones((2, 3, 4, 5, 6)), affine=np.array([ [-2.0, 0.0, 0.0, 117.86], [-0.0, 1.97, -0.36, -35.72], [0.0, 0.32, 2.17, -7.25], [0.0, 0.0, 0.0, 1.0], ]), space_units=UNITS_MILLIMETERS, time_units=UNITS_SECONDS, voxel_size=[2.0, 2.0, 2.2], time_step=2000.0, )
def test_add_complex_noise_filter_snr_zero(): """ Checks that the output image is equal to the input image when snr=0 """ signal_level = 100.0 np.random.seed(0) image = np.random.normal(signal_level, 10, (32, 32, 32)) image_container = NumpyImageContainer(image=image) # calculate using the filter add_complex_noise_filter = AddComplexNoiseFilter() add_complex_noise_filter.add_input("image", image_container) add_complex_noise_filter.add_input("snr", 0.0) add_complex_noise_filter.run() # image_with_noise and image_with_noise_container.image should be equal numpy.testing.assert_array_equal( image_container.image, add_complex_noise_filter.outputs["image"].image )
def test_fourier_filters_with_mock_data(): """Test the fft filter with some data + its discrete fourier transform""" # Create a 3D numpy image of normally distributed noise # fft to obtain k-space data, then ifft that to go back # to the image image_data = np.random.normal(0, 1, TEST_VOLUME_DIMENSIONS) kspace_data = np.fft.fftn(image_data) inverse_transformed_image_data = np.fft.ifftn(kspace_data) image_container = NumpyImageContainer(image=image_data) fft_filter = FftFilter() fft_filter.add_input("image", image_container) ifft_filter = IfftFilter() ifft_filter.add_parent_filter(parent=fft_filter) # Should run without error ifft_filter.run() # Check that the output of the fft_filter is in the INVERSE_DOMAIN assert fft_filter.outputs["image"].data_domain == INVERSE_DOMAIN # Check the output image is labelled as COMPLEX assert fft_filter.outputs["image"].image_type == COMPLEX_IMAGE_TYPE # Compare the fft_filter output image with kspace_data numpy.testing.assert_array_equal(fft_filter.outputs["image"].image, kspace_data) # Check that the output of the ifft_filter is in the SPATIAL_DOMAIN assert ifft_filter.outputs["image"].data_domain == SPATIAL_DOMAIN # Check the output image is labelled as COMPLEX assert ifft_filter.outputs["image"].image_type == COMPLEX_IMAGE_TYPE # Compare the ifft_filter_output image with inverse_transformed_image_data numpy.testing.assert_array_equal(ifft_filter.outputs["image"].image, inverse_transformed_image_data)
def test_mri_signal_timecourse_inversion_recovery( t1: float, t2: float, m0: float, t2_star: float, echo_time: float, repetition_time: float, flip_angle: float, inversion_angle: float, inversion_time: float, expected: float, ): """Tests the MriSignalFilter inversion recovery signal over a range of TI's. :param t1: longitudinal relaxation time, s :type t1: float :param t2: transverse relaxation time, s :type t2: float :param m0: equilibrium magnetisation :type m0: float :param t2_star: transverse relaxation time inc. time invariant fields, s :type t2_star: float :param echo_time: the echo time, s :type echo_time: float :param repetition_time: the repetition time, s :type repetition_time: float :param flip_angle: the excitation pulse flip angle, degrees :type flip_angle: float :param inversion_angle: the inversion pulse flip angle, degrees :type inversion_angle: float :param inversion_time: array of durations between the inversion pulse and excitation pulse, s :type inversion_time: float :param expected: array of expected valuesm, same length as `inversion_time` :type expected: float """ mri_signal_timecourse = np.ndarray(inversion_time.shape) for idx, ti in np.ndenumerate(inversion_time): params = { "t1": NumpyImageContainer(image=np.full((1, 1, 1), t1)), "t2": NumpyImageContainer(image=np.full((1, 1, 1), t2)), "t2_star": NumpyImageContainer(image=np.full((1, 1, 1), t2_star)), "m0": NumpyImageContainer(image=np.full((1, 1, 1), m0)), "acq_contrast": "ir", "echo_time": echo_time, "repetition_time": repetition_time, "excitation_flip_angle": flip_angle, "inversion_flip_angle": inversion_angle, "inversion_time": ti, } mri_signal_filter = MriSignalFilter() mri_signal_filter = add_multiple_inputs_to_filter( mri_signal_filter, params) mri_signal_filter.run() mri_signal_timecourse[idx] = mri_signal_filter.outputs["image"].image # arrays should be equal to 9 decimal places numpy.testing.assert_array_almost_equal(mri_signal_timecourse, expected, 9)
"""GkmFilter tests""" # pylint: disable=duplicate-code from copy import deepcopy import pytest import numpy as np import numpy.testing from asldro.containers.image import BaseImageContainer, NumpyImageContainer from asldro.filters.basefilter import BaseFilter, FilterInputValidationError from asldro.filters.gkm_filter import GkmFilter TEST_VOLUME_DIMENSIONS = (32, 32, 32) TEST_IMAGE_ONES = NumpyImageContainer(image=np.ones(TEST_VOLUME_DIMENSIONS)) TEST_IMAGE_101 = NumpyImageContainer(image=101 * np.ones(TEST_VOLUME_DIMENSIONS)) TEST_IMAGE_NEG = NumpyImageContainer(image=-1.0 * np.ones(TEST_VOLUME_DIMENSIONS)) TEST_IMAGE_SMALL = NumpyImageContainer(image=np.ones((8, 8, 8))) CASL = "CASL" PCASL = "pCASL" PASL = "PASL" # test data dictionary, [0] in each tuple passes, after that should fail validation TEST_DATA_DICT_PASL_M0_IM = { "perfusion_rate": (TEST_IMAGE_ONES, TEST_IMAGE_NEG, TEST_IMAGE_SMALL), "transit_time": (TEST_IMAGE_ONES, TEST_IMAGE_NEG, TEST_IMAGE_SMALL), "m0": (TEST_IMAGE_ONES, TEST_IMAGE_NEG, TEST_IMAGE_SMALL), "t1_tissue": (TEST_IMAGE_ONES, TEST_IMAGE_NEG, TEST_IMAGE_SMALL, TEST_IMAGE_101), "label_type": ("pasl", "PSL", "str"),