#!/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_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_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_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)