def test_set_get(self): shp = (10, 10, 10) chunk_shape = 32 dims = np.multiply(shp, chunk_shape) s = Sparse(shape=dims, chunks=chunk_shape) test_data = np.zeros(shape=dims) test_data[:dims[0] // 3, :dims[1] // 4, 32] = 3.14 test_data[128:160, 128:161, 128:159] = np.random.rand(32, 33, 31) s.set((0, 0, 0), test_data) for i in range(shp[0]): for j in range(shp[1]): for k in range(shp[2]): np.testing.assert_array_equal( s.get_chunk((i, j, k)), test_data[i * chunk_shape:(i + 1) * chunk_shape, j * chunk_shape:(j + 1) * chunk_shape, k * chunk_shape:(k + 1) * chunk_shape, ], )
def test_getitem(self): shp = (234, 231, 128) mga = np.random.rand(shp[0], shp[1], shp[2]) s = Sparse(shp, dtype=np.float_, chunks=(16, 32, 8), fill_value=0) s.set((0, 0, 0), mga) w2 = s[-138:-10:2, -223:-39:5, 120:128:1] w3 = mga[-138:-10:2, -223:-39:5, 120:128:1] np.testing.assert_array_equal(w2, w3)
def test_getitem_simple_vs_slice(self): shp = (234, 231, 128) mga = np.random.rand(*shp) s = Sparse(shp, dtype=np.float_, chunks=(16, 32, 8), fill_value=0) s.set((0, 0, 0), mga) for _ in range(10): i, j, k = map(np.random.randint, shp) v_slice = s[i:i + 1, j:j + 1, k:k + 1] v_simple = s[i, j, k] self.assertEqual(v_simple, v_slice)
def test_step_broadcast(self): expected = np.zeros((3, 3, 3)) expected[:2] = [3, 4, 5] s = Sparse(shape=(3, 3, 3)) s[:2] = [3, 4, 5] np.testing.assert_array_equal(s[...], expected) expected = np.zeros((3, 3, 3)) expected[::2] = [3, 4, 5] s = Sparse(shape=(3, 3, 3)) s[::2] = [3, 4, 5] np.testing.assert_array_equal(s[...], expected)
def test_zero(self): shp = (10, 10, 10) chunk_shape = 32 s = Sparse(shape=np.multiply(shp, chunk_shape), chunks=chunk_shape) zeros = np.zeros(shape=(chunk_shape, chunk_shape, chunk_shape)) for i in range(shp[0]): for j in range(shp[1]): for k in range(shp[2]): np.testing.assert_array_equal(s.get_chunk((i, j, k)), zeros)
def test_non_contiguous_memory_blocks(self): s = Sparse(shape=(3, 3, 3), chunks=(2, 2, 2)) s[1, 1, 1] = 1.0 s[2, 2, 2] = 1.0 # Exception: Memory blocks have wrong len: 2, use make_dense_data() to fix. with self.assertRaises(Exception): point_probe(np.zeros((1, 3)), s)
def test_max(self): sp = Sparse(shape=(10, 10, 10)) sp[0, 2, 1] = 2 sp[4, 3, 5] = 4 self.assertEqual(sf.max(sp), 4) sp[4, 4, 3] = np.nan self.assertTrue(np.isnan(sf.max(sp))) self.assertEqual(sf.nanmax(sp), 4)
def test_label(self): s = Sparse((30, 30, 30), dtype=np.uint32) s[2:5, 2:5, 2:5] = 1 s[7:9, 7:9, 7:9] = 1 s[15:18, 15:18, 15:18] = 1 s[25:28, 25:28, 25:28] = 1 label(s) self.assertSetEqual(unique(s), set(range(5)))
def save_load(self, compression_level): shp = (67, 87, 33) mga = np.random.randint(0, 100, shp, dtype=np.uint8) s = Sparse(shp, dtype=np.uint8, chunks=(16, 32, 8), fill_value=0) s.set((0, 0, 0), mga) s.save("save.msgpack", compression_level) loaded_s = Sparse.load("save.msgpack") for (k1, v1), (k2, v2) in zip(vars(s).items(), vars(loaded_s).items()): self.assertEqual(k1, k2) if k1 not in ["_grid", "_memory_blocks"]: # fields like 'shape' etc. self.assertEqual(v1, v2) continue if k1 == "_grid": for (_, d1), (_, d2) in zip(v1.items(), v2.items()): np.testing.assert_array_equal(d1, d2) continue if k1 == "_memory_blocks": for d1, d2 in zip(v1, v2): np.testing.assert_array_equal(d1, d2) continue os.remove("save.msgpack")
def test_thinning(self): s = Sparse((5, 5, 5), dtype=np.uint16) s[...] = 1 s[2, 2] = 0 expected_slice = np.array([ [0, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0], ], dtype=np.uint8) ss = {1: s, 2: s.copy()} for mp in (1, 2): with self.subTest(multiprocesses=mp): ss = s.copy() thinning(ss, (0, 0, 0), multiprocesses=mp) np.testing.assert_array_equal(ss[..., 2], expected_slice)
class TestInterpolation(unittest.TestCase): def setUp(self): self.s = Sparse(shape=(3, 3, 3), chunks=(2, 2, 2)) self.s[1, 1, 1] = 1.0 self.s[2, 2, 2] = 2.0 self.s.make_dense_data() self.s.update_grid_mask() def test_grid_mask_exception(self): s = Sparse(shape=(2, 2, 2), chunks=(2, 2, 2)) s[1, 1, 1] = 1.0 # RuntimeError: Missing grid_mask in sparse array. Use update_grid_mask() before point_probe(). with self.assertRaises(RuntimeError): point_probe(np.zeros((1, 3)), s) def test_non_contiguous_memory_blocks(self): s = Sparse(shape=(3, 3, 3), chunks=(2, 2, 2)) s[1, 1, 1] = 1.0 s[2, 2, 2] = 1.0 # Exception: Memory blocks have wrong len: 2, use make_dense_data() to fix. with self.assertRaises(Exception): point_probe(np.zeros((1, 3)), s) def test_empty_zeros(self): self.assertEqual(point_probe(np.zeros((1, 3)), self.s), 0.0) def test_flat_xyz(self): self.assertEqual(point_probe(np.ones(3), self.s), 1.0) def test_middle_of_voxel(self): self.assertEqual(point_probe(np.ones((1, 3)) * 0.5, self.s), 0.125) def test_list_xyz(self): self.assertEqual(point_probe([0.5, 0.5, 0.5], self.s), 0.125) def test_unequal_spacing(self): s = Sparse(shape=(2, 2, 2), chunks=(2, 2, 2), spacing=(1, 2, 4)) s[:2, :2, :2] = np.arange(8).reshape((2, 2, 2)) s.update_grid_mask() self.assertEqual(point_probe([0.5, 0.5, 0.5], s), 1.5) def test_shape_corner_probe(self): self.assertEqual(point_probe(np.full(3, 2), self.s), 2.0)
def test_to_indices_value(self): sp = Sparse(shape=(100, 100, 100)) sp[1, 2, 3] = 4 sp[50, 60, 70] = 80 result = to_indices_value(sp) result.sort(axis=0) np.testing.assert_array_equal( result, [[1, 2, 3, 4], [50, 60, 70, 80]], verbose=True, )
def test_min(self): sp = Sparse(shape=(10, 10, 10)) sp[0, 2, 1] = 2 sp[4, 3, 5] = 4 self.assertEqual(sf.min(sp), 0) sp[0, 2, 2] = -2 sp[4, 3, 3] = -4 self.assertEqual(sf.min(sp), -4) sp[4, 4, 3] = np.nan self.assertTrue(np.isnan(sf.min(sp))) self.assertEqual(sf.nanmin(sp), -4)
def test_setitem_simple_vs_slice(self): shp = (23, 12, 128) s_point = Sparse(shp, dtype=np.float_, chunks=(16, 32, 8), fill_value=0) s_slice = Sparse(shp, dtype=np.float_, chunks=(16, 32, 8), fill_value=0) s_point[0, 1, 2] = 3 s_slice[0:1, 1:2, 2:3] = 3 s_point[22, 11, 127] = 4 s_slice[22:23, 11:12, 127:128] = 4 for _ in range(200): i, j, k = map(np.random.randint, shp) val = np.random.random() s_slice[i:i + 1, j:j + 1, k:k + 1] = val s_point[i, j, k] = val np.testing.assert_array_equal(s_slice[...], s_point[...])
def test_dilate(self): s = Sparse((15, 15, 15), dtype=np.uint8) s[3, 3, 3] = 1 dilate(s, [1]) # also: dilate(s, 1) and dilate(s, (1, 1, 1)) expected = np.array( [ # as you see, corners are still empty, because this is # itk::BinaryBallStructuringElement (a ball kernel) [[0, 1, 0], [1, 1, 1], [0, 1, 0]], [[1, 1, 1], [1, 1, 1], [1, 1, 1]], [[0, 1, 0], [1, 1, 1], [0, 1, 0]] ], dtype=np.uint8) np.testing.assert_array_equal(s[2:5, 2:5, 2:5], expected) self.assertEqual(sf.sum(s), 3**3 - 8)
def test_contour(self): shape = (100, 100, 100) sp = Sparse(shape=shape) step = 0 step += 1 sp[50, 50, 50] = 100 c = contour(sp, 100) self.assertEqual(c.GetNumberOfCells(), 0) self.assertEqual(c.GetNumberOfPoints(), 0) step += 1 sp[50, 50, 50] = 101 c = contour(sp, 100) self.assertEqual(c.GetNumberOfPoints(), 6) self.assertEqual(c.GetNumberOfCells(), 8)
def test_too_big(self): # base behavior n = np.zeros((4, 4, 4)) with self.assertRaises(ValueError) as cm: n[:3, :3, :3] = np.ones((4, 4, 4)) self.assertTrue(str(cm.exception).startswith("could not broadcast")) # chunky behavior s = Sparse(shape=(4, 4, 4)) with self.assertRaises(ValueError) as cm: s[:3, :3, :3] = np.ones((4, 4, 4)) # time will show if this message is constant self.assertTrue( str(cm.exception).startswith( "operands could not be broadcast together"))
def test_sum(self): sp = Sparse(shape=(10, 10, 10)) sp[0, 2, 1] = 2 sp[4, 3, 5] = 4 self.assertEqual(sf.sum(sp), 6)
def test_negative_shape(self): with self.assertRaises(ValueError) as cm: Sparse((10, -2, 10)) self.assertTrue( str(cm.exception).startswith( "all dimensions of shape must be positive"))
def test_unsigned_shape(self): s = Sparse(tuple(np.arange(2, 5, dtype=np.uint8))) print(s.shape) self.assertTrue( np.all(-np.array(s.shape) < 0)) # unsinged would be > 0
def test_unequal_spacing(self): s = Sparse(shape=(2, 2, 2), chunks=(2, 2, 2), spacing=(1, 2, 4)) s[:2, :2, :2] = np.arange(8).reshape((2, 2, 2)) s.update_grid_mask() self.assertEqual(point_probe([0.5, 0.5, 0.5], s), 1.5)
def test_grid_mask_exception(self): s = Sparse(shape=(2, 2, 2), chunks=(2, 2, 2)) s[1, 1, 1] = 1.0 # RuntimeError: Missing grid_mask in sparse array. Use update_grid_mask() before point_probe(). with self.assertRaises(RuntimeError): point_probe(np.zeros((1, 3)), s)
def setUp(self): self.s = Sparse(shape=(3, 3, 3), chunks=(2, 2, 2)) self.s[1, 1, 1] = 1.0 self.s[2, 2, 2] = 2.0 self.s.make_dense_data() self.s.update_grid_mask()
def test_unique(self): sp = Sparse(shape=(10, 10, 10)) sp[0, 2, 1] = 2 sp[4, 3, 5] = 4 self.assertSetEqual(unique(sp), {0, 2, 4})
def test_memory_usage(self): s = Sparse(shape=(64, 64, 64), chunks=(2, 2, 2)) empty_memory = s.__sizeof__() s[0, 0, 0] = 1 single_chunk = s.__sizeof__() s[1, 1, 1] = 1 single_chunk2 = s.__sizeof__() self.assertEqual(single_chunk, single_chunk2) s[2, 2, 2] = 1 self.assertEqual(len(s._memory_blocks), 2) two_chunks = s.__sizeof__() self.assertAlmostEqual(two_chunks - single_chunk, single_chunk - empty_memory, delta=32) s.make_dense_data() self.assertEqual(len(s._memory_blocks), 1) defragmented = s.__sizeof__() self.assertLess(defragmented, two_chunks) s.update_grid_mask() mask_size = np.zeros(s._block_shape, dtype=np.int32).__sizeof__() after_grid_mask = s.__sizeof__() self.assertEqual(after_grid_mask, defragmented + mask_size - None.__sizeof__())
def test_uniform_value(self): s = Sparse(shape=(4, 4, 4)) s[...] = 3 np.testing.assert_array_equal(s[...], np.full((4, 4, 4), 3)) s[...] = 9 np.testing.assert_array_equal(s[...], np.full((4, 4, 4), 9))