def test_bounds(self): """ Make sure error is thrown when trying to access out of bounds """ original = np.arange(5**4).reshape(tuple([5] * 4)) global_offset = (100, 200, 300, 400) offset_array = GlobalOffsetArray(original) with self.assertRaises(IndexError): offset_array[5:6, 4:5, 6:7, 7:8] with self.assertRaises(IndexError): offset_array[2, 2:5, 6:8, 0:2] with self.assertRaises(IndexError): offset_array[2, 9, 0:3, 0:2] offset_array = GlobalOffsetArray(original, global_offset=global_offset) with self.assertRaises(IndexError): offset_array[105:106, 204:205, 306:307, 407:408] with self.assertRaises(IndexError): offset_array[102, 202:205, 306:308, 400:402] with self.assertRaises(IndexError): offset_array[102, 209, 300:303, 400:402]
def test_subarray(self): """ Make sure subarrays of contain the correct adjusted global_offset and a copy is returned """ original = np.arange(5**4).reshape(tuple([5] * 4)) global_offset = (100, 200, 300, 400) offset_array = GlobalOffsetArray(original, global_offset=global_offset) # test slice with only slices offset_index = (slice(100, 102), slice(202, 205), slice(303, 305), slice(400, 403)) sub_array = offset_array[offset_index] self.assertTrue(np.array_equal(original[0:2, 2:5, 3:5, 0:3], sub_array)) self.assertEqual((100, 202, 303, 400), sub_array.global_offset) self.assertTrue( np.array_equal(offset_array[offset_index], sub_array[offset_index])) # ensure that returned sub_array is actually a view sub_array[sub_array.global_offset] = 1337 self.assertEqual(1337, offset_array[sub_array.global_offset]) # test slice with some slices some fixed offset_index = (slice(100, 102), 203, slice(303, 305), slice(400, 403)) sub_array = offset_array[offset_index] self.assertTrue(np.array_equal(original[0:2, 3, 3:5, 0:3], sub_array)) self.assertEqual((100, 303, 400), sub_array.global_offset) self.assertTrue( np.array_equal( offset_array[offset_index], sub_array[tuple(s for s in offset_index if isinstance(s, slice))]))
def test_get_with_offset(self): """ Make sure all global_offset_arrays are equivalent when given offset the proper offset indices. """ for test_array in TEST_ARRAYS: # set offset at each dimension to the dimension index + 1 offset = tuple( [index + 1 for index in range(0, len(test_array.shape))]) shape = test_array.shape offset_array = GlobalOffsetArray(test_array, global_offset=offset) self.assertEqual(offset, offset_array.global_offset) test_slices = tuple( slice(0, shape[dimension]) for dimension in range(0, test_array.ndim)) # same as test_slices but at offset offset_slices = tuple( slice(test_slice.start + offset[dimension], test_slice.stop + offset[dimension]) for dimension, test_slice in enumerate(test_slices)) sliced_offset_array = offset_array[offset_slices] self.assertTrue( np.array_equal(test_array[test_slices], sliced_offset_array)) self.recurse_compare(test_array[test_slices], sliced_offset_array, test_array.shape)
def test_get_no_offset(self): """ Make sure all arrays are properly equivalent when no offset is given """ for test_array in TEST_ARRAYS: offset_array = GlobalOffsetArray(test_array) self.assertEqual(tuple([0] * test_array.ndim), offset_array.global_offset) self.assertTrue(np.array_equal(test_array, offset_array))
def test_get_offset_origin(self): """ Make sure all arrays are properly equivalent when offset of the origin is given """ for test_array in TEST_ARRAYS: offset_array = GlobalOffsetArray( test_array, global_offset=tuple(0 for _ in range(0, test_array.ndim))) self.assertEqual(tuple([0] * test_array.ndim), offset_array.global_offset) self.assertTrue(np.array_equal(test_array, offset_array)) self.recurse_compare(test_array, offset_array, test_array.shape)
def generate_data(self, ndim, length): """ Generate test data """ original = np.arange(1, length**ndim + 1).reshape(tuple([length] * ndim)) copy = original.copy() global_offset = tuple(dimension * 100 for dimension in range(1, ndim + 1)) offset_array = GlobalOffsetArray(original, global_offset=global_offset) return (copy, offset_array)
def generate_replacement(self, ndim, length, global_offset): """ """ # Test with regulard ndarray are properly set into the offset_array replacement_length = floor(length / 2) replacement = np.arange(1, replacement_length**ndim + 1).reshape( tuple([replacement_length] * ndim)) # replace global offset array with new replaced value replacement_slice = () offset_replace_slice = () replacement_offset = () for offset in global_offset: replacement_slice += (slice(replacement_length, replacement_length * 2), ) offset_replace_slice += (slice(replacement_length + offset, replacement_length * 2 + offset), ) replacement_offset += (replacement_length + offset, ) replacement = GlobalOffsetArray(replacement, global_offset=replacement_offset) return (replacement_slice, offset_replace_slice, replacement)
def test_operator_diff_size_global_offset_array(self): """ Test to make sure operators return a copy of the original array """ ndim = 5 length = 4 for op in STANDARD_OPERATORS | IN_PLACE_OPERATORS: for forward in [True, False]: (original, offset_array) = self.generate_data(ndim, length) half_size = tuple( floor(size / 2) for size in offset_array.shape) offset = tuple(half_size[dimension] + offset for dimension, offset in enumerate(offset_array.global_offset)) half_slice = tuple(slice(s, s + s) for s in half_size) operate_param = GlobalOffsetArray( np.ones(half_size, dtype=offset_array.dtype) * 255, global_offset=offset) # itrue div requires floats when doing true division (can't do in place conversion to float) if op == operator.itruediv: original = original.astype(np.float64) offset_array = offset_array.astype(np.float64) operate_param = operate_param.astype(np.float64) if forward: left_expected = original[half_slice] right_expected = operate_param.view(np.ndarray) left_offset = offset_array right_offset = operate_param else: # test operation commutativity left_expected = operate_param.view(np.ndarray) right_expected = original[half_slice] left_offset = operate_param right_offset = offset_array # in place operators should only work if the left param is larger than the right if op in IN_PLACE_OPERATORS: with self.assertRaises(ValueError): op(left_offset, right_offset) continue actual_result = op(left_offset, right_offset) expected_sub_array = op(left_expected, right_expected) if op in STANDARD_OPERATORS: expected = original.astype(type( expected_sub_array.item(0))) actual = actual_result else: # in place operations modify originals expected = original actual = offset_array # Simulate expected expected[half_slice] = expected_sub_array # ensure global_offset is preserved self.assertEqual(offset_array.global_offset, actual.global_offset) self.assertTrue(np.array_equal(expected, actual)) # ensure the results that are returned are a copy of an array instead of a view just like ndarray expected[tuple([0] * ndim)] = 1337 actual[actual.global_offset] = 1337 # original arrays were not modified self.assertEqual(np.any(original == 1337), np.any(offset_array == 1337)) # Fail on partial overlap with self.assertRaises(ValueError): operate_param.global_offset = tuple( floor(size / 2) + floor(size / 4) for size in offset_array.shape) op(left_offset, right_offset)
def test_operator_same_size_global_offset_array(self): """ Test that when using operators on two GlobalOffsetArray it works only when they have the same global_offset """ ndim = 5 length = 4 for op in STANDARD_OPERATORS | IN_PLACE_OPERATORS: for forward in [True, False]: (original, offset_array) = self.generate_data(ndim, length) operate_param = GlobalOffsetArray( np.ones(offset_array.shape, dtype=offset_array.dtype) * 10, global_offset=offset_array.global_offset) # itrue div requires floats when doing true division (can't do in place conversion to float) if op == operator.itruediv: original = original.astype(np.float64) offset_array = offset_array.astype(np.float64) operate_param = operate_param.astype(np.float64) # Make sure to compare expected results as a ndarray because operate_param is a GlobalOffsetArray. if forward: left_expected = original.view(np.ndarray) right_expected = operate_param.view(np.ndarray) left_offset = offset_array right_offset = operate_param else: # test operation commutativity left_expected = operate_param.view(np.ndarray) right_expected = original.view(np.ndarray) left_offset = operate_param right_offset = offset_array expected_result = op(left_expected, right_expected) actual_result = op(left_offset, right_offset) if op in STANDARD_OPERATORS: expected = expected_result actual = actual_result else: expected = original actual = offset_array # ensure global_offset is preserved self.assertEqual(offset_array.global_offset, actual.global_offset) # ensure actual results match that of a regular ndarray self.assertTrue(np.array_equal(expected, actual)) # ensure the results that are returned are a copy of an array instead of a view just like ndarray expected[tuple([0] * ndim)] = 1337 actual[actual.global_offset] = 1337 # original arrays were not modified self.assertEqual(np.any(original == 1337), np.any(offset_array == 1337)) # Try testing with the operate param with a different global_offset operate_param.global_offset = tuple([1337] * ndim) with self.assertRaises(ValueError): op(left_offset, right_offset) # Try testing with the operate param with a partially overlapping data operate_param.global_offset = tuple( floor(size / 2) + offset for size, offset in zip( offset_array.shape, offset_array.global_offset)) with self.assertRaises(ValueError): op(left_offset, right_offset)