Source code for tests.test_series

#!/usr/bin/env python3

import unittest
import os.path
import tempfile
import pickle
import numpy as np
from numpy.random import default_rng
import copy
import pydicom.datadict

# from .context import imagedata
from src.imagedata.series import Series
import src.imagedata.axis as axis
import src.imagedata.formats as formats
from src.imagedata.viewer import grid_from_roi
from .compare_headers import compare_axes


[docs] class TestSeries(unittest.TestCase):
[docs] def test_repr(self): si = Series( 'data/dicom/time/time00/Image_00020.dcm') r = si.__repr__()
[docs] def test_repr_vol(self): si = Series( 'data/dicom/time/time00') r = si.__repr__()
[docs] def test_str(self): si = Series( 'data/dicom/time/time00/Image_00020.dcm') r = '{}'.format(si)
[docs] def test_max(self): si = Series( 'data/dicom/time/time00/Image_00020.dcm') mi = si.max() self.assertEqual(type(mi), np.uint16)
[docs] def test_get_keyword(self): si1 = Series( 'data/dicom/time/time00/Image_00020.dcm') self.assertEqual('dicom', si1.input_format) pname = si1.getDicomAttribute('PatientName') self.assertEqual( si1.getDicomAttribute('PatientName'), 'PHANTOM^T1') self.assertEqual( si1.getDicomAttribute( pydicom.datadict.tag_for_keyword('PatientID')), '19.02.07-14:04:17-STD-1.3.12.2.1107.5.2.43.66035')
[docs] def test_create_series_1(self): si = Series(np.uint16(1)) self.assertEqual(np.uint16, si.dtype) self.assertEqual((1,), si.shape)
[docs] def test_create_series_tuple_1D(self): si = Series((1, 2, 3)) self.assertEqual(np.int64, si.dtype) self.assertEqual((3,), si.shape)
[docs] def test_create_series(self): a = np.eye(128) si = Series(a) self.assertEqual(si.dtype, np.float64) self.assertEqual(si.shape, (128, 128))
[docs] def test_print_header(self): a = np.eye(128) si = Series(a) si.spacing = (1, 1, 1) self.assertEqual(si.slices, 1) np.testing.assert_array_equal(si.spacing, np.array((1, 1, 1)))
[docs] def test_copy_series(self): a = np.eye(128) si1 = Series(a) si1.spacing = (1, 1, 1) si2 = si1 self.assertEqual(si2.slices, 1) np.testing.assert_array_equal(si2.spacing, np.array((1, 1, 1)))
[docs] def test_copy_series2(self): a = np.eye(128) si1 = Series(a) si1.spacing = (1, 1, 1) si2 = si1.copy() self.assertEqual(si2.slices, 1) np.testing.assert_array_equal(si2.spacing, np.array((1, 1, 1)))
[docs] def test_subtract_series(self): a = Series(np.eye(128)) b = Series(np.eye(128)) a.spacing = (1, 1, 1) b.spacing = a.spacing si = a - b self.assertEqual(si.slices, 1) np.testing.assert_array_equal(si.spacing, np.array((1, 1, 1)))
[docs] def test_increase_ndim(self): a = np.eye(128) s = Series(a) with self.assertRaises(IndexError): s.shape = (1,1,128,128)
[docs] def test_set_variable_slice_locations(self): s = Series(np.zeros((3,12,12))) new_loc = np.array([1, 3, 6]) s.sliceLocations = new_loc np.testing.assert_array_equal(new_loc, s.sliceLocations)
[docs] def test_set_incorrect_slice_locations(self): s = Series(np.zeros((3,12,12))) with self.assertRaises(ValueError): s.sliceLocations = [3, 6]
[docs] def test_slicing_dim(self): a1 = np.eye(128) a1.shape = (1,128,128) a = np.vstack([a1, a1, a1, a1, a1]) s = Series(a) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) s_slice = s[2] self.assertEqual(s_slice.ndim, 2) self.assertEqual(len(s_slice.axes), 2) self.assertEqual(s_slice.axes[0].name, 'row') self.assertEqual(s_slice.axes[1].name, 'column')
[docs] def test_slicing_y(self): a1 = np.eye(128) a1.shape = (1,128,128) a = np.vstack([a1, a1, a1]) s = Series(a) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) a_slice = a[:,:,3:5] s_slice = s[:,:,3:5] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, 3)
[docs] def test_slicing_y_neg(self): rng = default_rng() s = Series(rng.standard_normal(64).reshape((4,4,4))) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) np.testing.assert_array_equal(s[:,3,:], s[:,-1,:]) np.testing.assert_array_equal(s[:,2,:], s[:,-2,:]) np.testing.assert_array_equal(s[:,1,:], s[:,-3,:]) np.testing.assert_array_equal(s[:,0,:], s[:,-4,:]) np.testing.assert_array_equal(s[:,2:3,:], s[:,2:-1,:]) np.testing.assert_array_equal(s[:,1:2,:], s[:,1:-2,:]) np.testing.assert_array_equal(s[:,0:2,:], s[:,0:-2,:])
[docs] def test_slicing_x(self): a1 = np.eye(128) a1.shape = (1,128,128) a = np.vstack([a1, a1, a1]) s = Series(a) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) a_slice = a[:,3:5,...] s_slice = s[:,3:5,...] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, 3)
[docs] def test_slicing_x_neg(self): from numpy.random import default_rng rng = default_rng() s = Series(rng.standard_normal(64).reshape((4,4,4))) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) np.testing.assert_array_equal(s[:,:,3], s[:,:,-1]) np.testing.assert_array_equal(s[:,:,2], s[:,:,-2]) np.testing.assert_array_equal(s[:,:,1], s[:,:,-3]) np.testing.assert_array_equal(s[:,:,0], s[:,:,-4]) np.testing.assert_array_equal(s[:,:,2:3], s[:,:,2:-1]) np.testing.assert_array_equal(s[:,:,1:2], s[:,:,1:-2]) np.testing.assert_array_equal(s[:,:,0:2], s[:,:,0:-2])
[docs] def test_assign_slice_x(self): a1 = np.eye(128) a1.shape = (1,128,128) a = np.vstack([a1, a1, a1]) s = Series(a) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) n = np.ones_like(a) * 4 p = Series(n) p.spacing = (1,1,1) p.axes[0] = axis.UniformLengthAxis('slice', 0, p.shape[0]) a[:,3:5,...] = n[:,3:5,...] s[:,3:5,...] = p[:,3:5,...] np.testing.assert_array_equal(a, s) np.testing.assert_array_equal(s[:,3:5,...], p[:,3:5,...]) self.assertEqual(s.slices, 3)
[docs] def test_assign_slice(self): a = np.array(range(4*5*6), dtype=np.uint16) a.shape = (4,5,6) s = Series(a) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) n = np.zeros((2,2,2), dtype=np.uint16) p = Series(n) p.spacing = (1,1,1) p.axes[0] = axis.UniformLengthAxis('slice', 0, p.shape[0]) a[1:3,2:4,2:4] = n[:] s[1:3,2:4,2:4] = p[:] np.testing.assert_array_equal(a, s) self.assertEqual(s.slices, 4)
[docs] def test_assign_slice_input_order(self): si = Series('data/dicom/time', 'time') sic = Series(si) self.assertEqual(si.input_order, sic.input_order)
[docs] def test_zeros_like(self): si = Series('data/dicom/time', 'time') a = np.zeros_like(si) self.assertEqual(si.input_order, a.input_order) for i in range(si.ndim): self.assertEqual(si.axes[i].name, a.axes[i].name) if isinstance(si.axes[i], axis.VariableAxis): np.testing.assert_array_almost_equal(si.axes[i].values, a.axes[i].values, 4) else: self.assertEqual(si.axes[i].slice, a.axes[i].slice) np.testing.assert_array_equal(si.transformationMatrix, a.transformationMatrix) np.testing.assert_array_equal(si.spacing, a.spacing) a[:, :, 10:50, 10:50] = 1
[docs] def test_sum_with_series_mask(self): si = Series('data/dicom/time', 'time') mask = np.zeros(si.shape[1:], dtype=np.uint8) mask[:, 10:20, 10:20] = 1 mask = Series(mask, input_order=si.input_order, template=si, geometry=si) time_course = np.sum(np.array(si), axis=(1, 2, 3), where=mask == 1) / np.count_nonzero(mask)
[docs] def test_slicing_z(self): a1 = np.eye(128) a1.shape = (1,128,128) a = np.vstack([a1, a1, a1]) s = Series(a) s.spacing = (1, 1, 1) s.sliceLocations = [3, 6, 9] for slice in range(s.slices): s.imagePositions = { slice: np.array([slice, 0, 0]) } a_slice = a[0:2,...] s_slice = s[0:2,...] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, 2) np.testing.assert_array_equal(s_slice.sliceLocations, np.array([3, 6])) # Compare imagePositions ipp2 = {} for slice in range(2): ipp2[slice] = np.array([slice, 0, 0]) self.assertEqual(len(s_slice.imagePositions), len(ipp2)) for slice in range(2): np.testing.assert_array_equal( s_slice.imagePositions[slice], ipp2[slice])
[docs] def test_slicing_z_neg(self): from numpy.random import default_rng rng = default_rng() s = Series(rng.standard_normal(64).reshape((4,4,4))) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('slice', 0, s.shape[0]) np.testing.assert_array_equal(s[3,:,:], s[-1,:,:]) np.testing.assert_array_equal(s[2,:,:], s[-2,:,:]) np.testing.assert_array_equal(s[1,:,:], s[-3,:,:]) np.testing.assert_array_equal(s[0,:,:], s[-4,:,:]) np.testing.assert_array_equal(s[2:3], s[2:-1]) np.testing.assert_array_equal(s[2:3,:,:], s[2:-1,:,:]) np.testing.assert_array_equal(s[1:2,:,:], s[1:-2,:,:]) np.testing.assert_array_equal(s[0:2,:,:], s[0:-2,:,:])
[docs] def test_slicing_t(self): a1 = np.eye(128) a1.shape = (1,128,128) a2 = np.vstack([a1, a1, a1]) a2.shape = (1,3,128,128) a = np.vstack([a2,a2,a2,a2]) s = Series(a, input_order=formats.INPUT_ORDER_TIME) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) tags = {} k = 0 for i in range(s.slices): tags[i] = np.arange(k, k+s.shape[0]) k += s.shape[0] s.tags = tags a_slice = a[1:3,...] s_slice = s[1:3,...] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, 3) self.assertEqual(len(s_slice.tags[0]), 2) for s in range(s_slice.slices): np.testing.assert_array_equal(s_slice.tags[s], tags[s][1:3])
[docs] def test_slicing_t_neg(self): from numpy.random import default_rng rng = default_rng() s = Series(rng.standard_normal(192).reshape((3,4,4,4))) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) np.testing.assert_array_equal(s[2], s[-1]) np.testing.assert_array_equal(s[1], s[-2]) np.testing.assert_array_equal(s[0], s[-3]) np.testing.assert_array_equal(s[1:2], s[1:-1]) np.testing.assert_array_equal(s[1:2,:,:], s[1:-1,:,:]) np.testing.assert_array_equal(s[0:1,:,:], s[0:-2,:,:])
[docs] def test_slicing_t_drop(self): from numpy.random import default_rng rng = default_rng() s = Series(rng.standard_normal(192).reshape((3,4,4,4)), 'time') s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) s_axes = copy.copy(s.axes) self.assertEqual(len(s_axes), 4) sum = np.sum(s, axis=0) compare_axes(self, s.axes, s_axes) del sum.axes[0] # TODO self.assertEqual(len(s_axes), 4) compare_axes(self, s_axes[1:], sum.axes)
[docs] def test_multiple_ellipses(self): a1 = np.eye(128) a1.shape = (1,128,128) a2 = np.vstack([a1, a1, a1]) a2.shape = (1,3,128,128) a = np.vstack([a2,a2,a2,a2]) s = Series(a, input_order=formats.INPUT_ORDER_TIME) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) tags = {} k = 0 for i in range(s.slices): tags[i] = np.arange(k, k+s.shape[0]) k += s.shape[0] s.tags = tags with self.assertRaises(IndexError): s_slice = s[...,1:3,...]
[docs] def test_ellipsis_first(self): a1 = np.eye(128) a1.shape = (1,128,128) a2 = np.vstack([a1, a1, a1]) a2.shape = (1,3,128,128) a = np.empty([4, 3,128,128]) for i in range(4): a[i] = a2 # a = np.vstack([a2,a2,a2,a2]) s = Series(a, input_order=formats.INPUT_ORDER_TIME) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) tags = {} k = 0 for i in range(s.slices): tags[i] = np.arange(k, k+s.shape[0]) k += s.shape[0] s.tags = tags a_slice = a[..., 3:5] s_slice = s[..., 3:5] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, s.slices) self.assertEqual(len(s_slice.tags[0]), len(s.tags[0]))
[docs] def test_ellipsis_middle(self): a1 = np.eye(128) a1.shape = (1,128,128) a2 = np.vstack([a1, a1, a1]) a2.shape = (1,3,128,128) a = np.vstack([a2,a2,a2,a2]) s = Series(a, input_order=formats.INPUT_ORDER_TIME) s.spacing = (1, 1, 1) s.axes[0] = axis.UniformLengthAxis('time', 0, s.shape[0]) s.axes[1] = axis.UniformLengthAxis('slice', 0, s.shape[1]) tags = {} k = 0 for i in range(s.slices): tags[i] = np.arange(k, k+s.shape[0]) k += s.shape[0] s.tags = tags a_slice = a[1:3, ..., 3:5] s_slice = s[1:3, ..., 3:5] np.testing.assert_array_equal(a_slice, s_slice) self.assertEqual(s_slice.slices, s.slices) self.assertEqual(len(s_slice.tags[0]), 2)
[docs] def test_cross_talk(self): si = Series('data/dicom/time/time00') self.assertEqual('dicom', si.input_format) # print('si before', si.getDicomAttribute('SeriesInstanceUID'), si.seriesInstanceUID) si1 = si[0] si1.seriesNumber = si.seriesNumber + 10 self.assertNotEqual(si.seriesNumber, si1.seriesNumber) # print('si after', si.getDicomAttribute('SeriesInstanceUID'), si.seriesInstanceUID) # print('si1', si1.getDicomAttribute('SeriesInstanceUID'), si1.seriesInstanceUID) self.assertNotEqual(si.seriesInstanceUID, si1.seriesInstanceUID) si2 = Series('data/dicom/time/time00') self.assertEqual('dicom', si2.input_format) si2.seriesNumber += 10 self.assertNotEqual(si.seriesNumber, si2.seriesNumber)
[docs] def test_cross_talk_wl_ref(self): si = Series('data/dicom/time/time00') self.assertEqual('dicom', si.input_format) si1 = si[0] * 10 self.assertNotEqual(si.windowWidth, si1.windowWidth)
[docs] def test_cross_talk_wl(self): si = Series('data/dicom/time/time00') self.assertEqual('dicom', si.input_format) si1 = copy.deepcopy(si)[0] * 10 self.assertNotEqual(si.windowWidth, si1.windowWidth)
[docs] def test_cross_talk_series_ref(self): si = Series('data/dicom/time/time00') self.assertEqual('dicom', si.input_format) si1 = Series(si, input_order=si.input_order) si1.windowWidth = 1 with tempfile.TemporaryDirectory() as d: si1.write(d, formats=['dicom']) si2 = Series(d) np.testing.assert_array_almost_equal(si2.windowWidth, si1.windowWidth, 4)
[docs] def test_cross_talk_dicom_series_template(self): template = Series('data/dicom/time/time00') template_window = template.windowWidth si = Series('data/dicom/time/time01', template=template) si1_window = si.windowWidth self.assertEqual('dicom', si.input_format) si.windowWidth = 1 with tempfile.TemporaryDirectory() as d: si.write(d, formats=['dicom']) si2 = Series(d) self.assertNotEqual(si2.windowWidth, template.windowWidth)
[docs] def test_cross_talk_series_template(self): template = Series('data/dicom/time/time00') self.assertEqual('dicom', template.input_format) template_window = template.windowWidth si = Series(np.zeros_like(template), template=template) si_window = si.windowWidth si.windowWidth = 1 with tempfile.TemporaryDirectory() as d: si.write(d, formats=['dicom']) si2 = Series(d) self.assertNotEqual(si.windowWidth, template.windowWidth) self.assertEqual(si2.windowWidth, si.windowWidth)
[docs] def test_cross_talk_spacing(self): si = Series('data/dicom/time', 'time') self.assertEqual('dicom', si.input_format) si1 = si[0] si1.spacing = (1,1,1) self.assertNotEqual(si.spacing.tolist(), si1.spacing.tolist())
[docs] def test_cross_talk_2(self): si1 = Series('data/dicom/time/time00') self.assertEqual('dicom', si1.input_format) si2 = si1 si2.seriesNumber += 10 self.assertEqual(si1.seriesNumber, si2.seriesNumber)
[docs] def test_cross_talk_3(self): si1 = Series('data/dicom/time/time00') self.assertEqual('dicom', si1.input_format) si2 = copy.copy(si1) si2.seriesNumber += 10 self.assertNotEqual(si1.seriesNumber, si2.seriesNumber)
[docs] def test_set_axes(self): si1 = Series('data/dicom/time/time00') self.assertEqual('dicom', si1.input_format) shape = si1.shape + (3,) img = np.zeros(shape, dtype=np.uint8) img[...,0] = si1[:] img[...,1] = si1[:] img[...,2] = si1[:] rgb = Series(img, geometry=si1, axes=si1.axes + [axis.VariableAxis('rgb',['r', 'g', 'b'])] )
[docs] def test_header_axes(self): geometry = Series('data/dicom/time/time00') self.assertEqual('dicom', geometry.input_format) si = Series(np.eye(128), geometry=geometry) self.assertEqual(len(si.axes), 2) for i in range(len(si.axes)): self.assertEqual(len(si.axes[i]), si.shape[i])
[docs] def test_get_rgb_voxel(self): si1 = Series('data/dicom/time/time00') self.assertEqual('dicom', si1.input_format) rgb = si1.to_rgb() _slice = rgb[1] voxel = _slice[1, 1] self.assertEqual(3, len(voxel))
[docs] def test_get_rgb_voxel_np_rgb(self): si1 = Series(np.zeros((4,10,10,3), dtype=np.uint8)) _slice = si1[1] voxel = _slice[1, 1] self.assertEqual(3, len(voxel))
[docs] def test_get_rgb_voxel_np(self): si1 = Series(np.zeros((4,10,10), dtype=np.uint8)) rgb = si1.to_rgb() _slice = rgb[1] voxel = _slice[1, 1] self.assertEqual(3, len(voxel))
[docs] def test_fuse_mask_3d_bw_uint8(self): si1 = Series(np.zeros((4,10,10), dtype=float)) mask = np.zeros_like(si1, dtype=np.uint8) mask[2, 2:7, 2:7] = 1 fused = si1.fuse_mask(mask) self.assertEqual(3, fused.ndim) self.assertEqual((0, 0, 0), fused[1, 7, 7]) self.assertEqual((58, 0, 0), fused[2, 3, 4])
[docs] def test_fuse_mask_3d_bw_float(self): si1 = Series(np.zeros((4,10,10), dtype=float)) mask = np.zeros_like(si1, dtype=np.uint8) mask[2, 2:7, 2:7] = 1 fused = si1.fuse_mask(mask) self.assertEqual(3, fused.ndim) np.testing.assert_array_equal((0, 0, 0), fused[1, 7, 7]) np.testing.assert_array_equal((58, 0, 0), fused[2, 3, 4])
[docs] def test_fuse_mask_3d_rgb_uint8(self): si = Series(np.zeros((4,10,10), dtype=np.uint8)) si1 = si.to_rgb() mask = np.zeros(si1.shape, dtype=np.uint8) mask[2, 3, 4] = 1 fused = si1.fuse_mask(mask) self.assertEqual(3, fused.ndim) np.testing.assert_array_equal((0, 0, 0), fused[1, 7, 7]) np.testing.assert_array_equal((5, 0, 0), fused[2, 3, 4])
[docs] def test_fuse_mask_3d_rgb_float(self): si = Series(np.zeros((4,10,10), dtype=float)) si1 = si.to_rgb() mask = np.zeros(si1.shape, dtype=np.uint8) mask[2, 3, 4] = 1 fused = si1.fuse_mask(mask) self.assertEqual(3, fused.ndim) np.testing.assert_array_equal((0, 0, 0), fused[1, 7, 7]) np.testing.assert_array_equal((5, 0, 0), fused[2, 3, 4])
[docs] def test_fuse_mask_lena(self): # si1 = Series(Image.open(os.path.join('data', 'lena_color.jpg'))) si1 = Series(os.path.join('data', 'dicom', 'lena_color.dcm')) # mask = np.zeros(si1.shape[:-1], dtype=np.uint8) mask = np.zeros(si1.shape, dtype=np.uint8) mask[100:200, 100:200] = 1 fused = si1.fuse_mask(mask) self.assertEqual(2, fused.ndim) np.testing.assert_array_equal((255, 68, 80), fused[150, 150]) np.testing.assert_array_equal((231, 136, 108), fused[50, 50])
[docs] def test_fuse_mask_3d_variable(self): si1 = Series(np.zeros((4,100,100), dtype=float)) N = 100 x = np.linspace(-3.0, 3.0, N) y = np.linspace(-2.0, 2.0, N) X, Y = np.meshgrid(x, y) Z1 = np.exp(-X**2 - Y**2) Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2) z = Z1 + 50 * Z2 mask = np.zeros_like(si1, dtype=np.float64) mask[2, :100, :100] = z fused = si1.fuse_mask(mask) self.assertEqual(3, fused.ndim) np.testing.assert_array_equal((0, 0, 1), fused[1, 7, 7]) np.testing.assert_array_equal((3, 2, 9), fused[2, 45, 50]) np.testing.assert_array_equal((75, 76, 57), fused[2, 50, 50])
[docs] def test_fuse_mask_3d_variable_maskrange(self): si1 = Series(np.zeros((4,100,100), dtype=float)) N = 100 x = np.linspace(-3.0, 3.0, N) y = np.linspace(-2.0, 2.0, N) X, Y = np.meshgrid(x, y) Z1 = np.exp(-X**2 - Y**2) Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2) z = Z1 + 50 * Z2 mask = np.zeros_like(si1, dtype=np.float64) mask[2, :100, :100] = z fused = si1.fuse_mask(mask, maskrange=(20, 44)) self.assertEqual(3, fused.ndim) np.testing.assert_array_equal((0, 0, 1), fused[1, 7, 7]) np.testing.assert_array_equal((0, 0, 1), fused[2, 45, 50]) np.testing.assert_array_equal((75, 76, 57), fused[2, 50, 50])
[docs] def test_align_3d(self): reference = Series( os.path.join('data', 'dicom', 'time', 'time00') ) moving = Series( os.path.join('data', 'dicom', 'time', 'time01') ) moved = moving.align(reference) with tempfile.TemporaryDirectory() as d: moved.write(d, formats=['dicom'])
[docs] def test_align_3d_few_slices_on_many(self): rng = default_rng() reference = Series(rng.standard_normal(80).reshape((5,4,4))) reference.spacing = (1, 1, 1) reference.axes[0] = axis.UniformLengthAxis('slice', 0, reference.shape[0]) moving = Series( os.path.join('data', 'dicom', 'time', 'time01') ) moved = moving.align(reference, force=True) with tempfile.TemporaryDirectory() as d: moved.write(d, formats=['dicom'])
[docs] def test_align_2d(self): reference = Series( os.path.join('data', 'dicom', 'time', 'time00') ) moving = Series( os.path.join('data', 'dicom', 'TI', 'TI_1.MR.0021.0001.2021.06.08.10.04.29.806302.203193459.IMA'), input_order='ti', opts={'ti': 'InversionTime'} ) with self.assertRaises(ValueError): moved = moving.align(reference)
[docs] def test_align_3d_on_4d(self): reference = Series( os.path.join('data', 'dicom', 'time') ) moving = Series( os.path.join('data', 'dicom', 'time', 'time01') ) moved = moving.align(reference) with tempfile.TemporaryDirectory() as d: moved.write(d, formats=['dicom'])
[docs] def test_align_4d_on_3d(self): moving = Series( os.path.join('data', 'dicom', 'time') ) reference = Series( os.path.join('data', 'dicom', 'time', 'time01') ) moved = moving.align(reference) with tempfile.TemporaryDirectory() as d: moved.write(d, formats=['dicom'])
[docs] def test_numpy_mask(self): si = Series(os.path.join('data', 'dicom', 'time')) mask = si < 10 curve = np.sum(si, axis=(1, 2, 3), where=mask==True)
[docs] def test_vertices_from_3d_grid(self): si = Series(os.path.join('data', 'dicom', 'time', 'time01')) with open(os.path.join('data', 'vertices', 'vertices3d.pickle'), 'rb') as f: vertices = pickle.load(f) grid = grid_from_roi(si, vertices, single=False) new_vertices = grid.vertices_from_grid(grid, align=False) new_grid = grid_from_roi(si, new_vertices, single=False) # Accept 100 pixels mismatch diff = np.absolute(new_grid.astype(float) - grid.astype(float)) s = np.sum(diff) self.assertLess(s, 100, "Too many mismatch pixels")
if __name__ == '__main__': unittest.main() # import logging # logging.basicConfig(level=logging.DEBUG) # runner = unittest.TextTestRunner(verbosity=2) # unittest.main(testRunner=runner)