def test_bounds(self):
        """
        Tests to make sure get index is has compatible behavior as the regular numpy array

        """
        original = np.arange(5**4).reshape(tuple([5] * 4))
        global_offset = (100, 200, 300, 400)

        no_offset_array = GlobalOffsetArray(original)
        offset_array = GlobalOffsetArray(original, global_offset=global_offset)

        slices_tests = [
            # pre indexed sub slicing
            (slice(-5, 2), slice(0, 5), slice(0, 5), slice(0, 5)),
            # post indexed sub slicing
            (slice(3, 8), slice(0, 5), slice(0, 5), slice(0, 5)),
            # pre and post indexed mixed sub slicing
            (slice(-5, 2), slice(3, 8), slice(4, 7), slice(2, 8)),
            # pre to post sub slicing
            (slice(-2, 8), slice(0, 5), slice(0, 5), slice(0, 5)),
            # completely outside bounding box
            (slice(5, 6), slice(4, 5), slice(4, 7), slice(7, 8)),
            # single addressed index
            (2, slice(2, 5), slice(6, 8), slice(0, 2)),
            # single addressed index out of bounds
            (8, slice(2, 5), slice(6, 8), slice(0, 2)),
            # two addressed index but one is out of bounds
            (2, 9, slice(0, 3), slice(0, 2)),
        ]
        offset_slices_tests = [
            tuple(
                slice(s.start + o, s.stop + o) if isinstance(s, slice) else s +
                o for s, o in zip(slices, global_offset))
            for slices in slices_tests
        ]

        for slices, offset_slices in zip(slices_tests, offset_slices_tests):
            expected_exception = None
            expected_value = None
            try:
                expected_value = original[no_wrap_slices(slices)]
            except Exception as e:
                expected_exception = e

            if expected_exception is not None:
                with pytest.raises(type(expected_exception)):
                    no_offset_array[slices]
                with pytest.raises(type(expected_exception)):
                    offset_array[offset_slices]
            else:
                assert np.array_equal(expected_value, no_offset_array[slices])
                assert np.array_equal(expected_value,
                                      offset_array[offset_slices])
    def test_bad_offset(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)

        with pytest.raises(ValueError):
            GlobalOffsetArray(original, global_offset=global_offset + (32, ))

        with pytest.raises(ValueError):
            GlobalOffsetArray(original, global_offset=global_offset[1:])
    def test_pickle(self):
        dimensions = (4, 3, 2, 1)
        data = np.arange(0, np.product(dimensions)).reshape(dimensions)
        global_offset = (3, 2, 1, 0)
        global_offset_data = GlobalOffsetArray(data,
                                               global_offset=global_offset)
        bounds = global_offset_data.bounds()

        pickled = pickle.dumps(global_offset_data)
        unpickled = pickle.loads(pickled)

        assert global_offset_data.data is not unpickled
        assert global_offset == unpickled.global_offset
        assert np.array_equal(global_offset_data.data, unpickled.data)
        assert bounds == unpickled.bounds()
 def test_autofill_dimensions(self):
     dimensions = (4, 3, 2, 1)
     data = np.arange(0, np.product(dimensions)).reshape(dimensions)
     global_offset_data = GlobalOffsetArray(data,
                                            global_offset=(3, 2, 1, 0))
     assert np.array_equal(global_offset_data[5], data[2])
     assert np.array_equal(global_offset_data[5, 3], data[2, 1])
    def test_broadcast(self):
        larger = GlobalOffsetArray(
            np.array(tuple(np.ones((3, 3)) * i for i in range(1, 4))))
        smaller = np.ones((3, 3)) * 2

        result = larger * smaller

        assert np.all(result[0] == 2)
        assert np.all(result[1] == 4)
        assert np.all(result[2] == 6)

        result = smaller * larger

        assert np.all(result[0] == 2)
        assert np.all(result[1] == 4)
        assert np.all(result[2] == 6)

        larger *= smaller

        assert np.all(larger[0] == 2)
        assert np.all(larger[1] == 4)
        assert np.all(larger[2] == 6)

        with pytest.raises(ValueError):
            smaller *= larger
示例#6
0
    def test_overlap_slices_3d(self):
        bounds = (slice(0, 7), slice(0, 7), slice(0, 7))
        chunk_shape = (3, 3, 3)
        overlap = (1, 1, 1)

        block = Block(bounds=bounds, chunk_shape=chunk_shape, overlap=overlap)

        assert block.num_chunks == (3, 3, 3)

        fake_data = GlobalOffsetArray(np.zeros(block.shape),
                                      global_offset=(0, 0, 0))
        for chunk in block.chunk_iterator((1, 0, 1)):
            for edge_slice in block.overlap_slices(chunk):
                fake_data[edge_slice] += 1
            fake_data[block.core_slices(chunk)] += 1
        assert fake_data.sum() == np.product(fake_data.shape)
    def test_slice_fill_missing_dimensions(self):
        for test_array in TEST_ARRAYS[:]:
            sub_slices = tuple(
                slice(0, dim // 2) for dim in test_array.shape[1:])

            offset_array = 0 + GlobalOffsetArray(test_array)
            sub_offset_array = 0 + offset_array[sub_slices]
            assert sub_offset_array.global_offset == offset_array.global_offset
 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)
         assert offset_array.global_offset == tuple([0] * test_array.ndim)
         assert 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)))
         assert offset_array.global_offset == tuple([0] * test_array.ndim)
         assert np.array_equal(test_array, offset_array)
         self.recurse_compare(test_array, offset_array, test_array.shape)
    def test_slice_same_dimensions(self):
        for test_array in TEST_ARRAYS:
            sub_slices = tuple(slice(0, dim // 2) for dim in test_array.shape)

            offset_array = GlobalOffsetArray(test_array)

            sub_test_array = test_array[sub_slices]
            sub_offset_array = offset_array[sub_slices]

            assert sub_offset_array.shape == sub_test_array.shape
            assert len(sub_offset_array.global_offset) == len(
                sub_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 test_no_wrap(self):
        """
        Make sure index ranges before start does not perform wrap around
        """
        def test_recurse_slices(expected, actual, index, shape, slices):
            if index == len(shape):
                normalized_slices = no_wrap_slices(slices)
                assert np.array_equal(expected[normalized_slices], actual[slices]), \
                    'Incorrect value found requested slices: %s, normalized slices: %s, actual: %s, expected: %s' % (
                        slices, normalized_slices, actual[slices], expected[normalized_slices])

            else:
                dim = shape[index]
                for start in range(-dim, dim):
                    for stop in range(start, dim * 2):
                        test_recurse_slices(expected, actual, index + 1, shape,
                                            (slices + (slice(start, stop), )))

        for test_array in TEST_ARRAYS:
            offset_array = GlobalOffsetArray(test_array)
            test_recurse_slices(test_array, offset_array, 0,
                                offset_array.shape, ())
    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_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)
            assert offset_array.global_offset == 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]
            assert 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_subarray(self):
        """
        Make sure subarrays of contain the correct adjusted global_offset and a copy is returned

        """
        def to_offsets(slice_or_indices):
            return tuple(
                slice(s.start + o, s.stop + o) if isinstance(s, slice) else s +
                o for s, o in zip(original_index, global_offset))

        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
        original_index = (slice(0, 2), slice(2, 5), slice(3, 5), slice(0, 3))
        offset_index = to_offsets(original_index)
        sub_array = offset_array[offset_index]
        assert np.array_equal(sub_array, original[original_index])
        assert sub_array.global_offset == (100, 202, 303, 400)
        assert np.array_equal(sub_array[offset_index],
                              offset_array[offset_index])

        # ensure that returned sub_array is actually a view
        sub_array[sub_array.global_offset] = 1337
        assert offset_array[sub_array.global_offset] == 1337

        # test slice with some slices some fixed
        original_index = (slice(0, 2), 3, slice(3, 5), slice(0, 3))
        offset_index = to_offsets(original_index)
        sub_array = offset_array[offset_index]
        assert np.array_equal(original[original_index], sub_array)
        assert sub_array.global_offset == (100, 303, 400)
        assert np.array_equal(
            sub_array[tuple(s for s in offset_index if isinstance(s, slice))],
            offset_array[offset_index])
 def get(i):
     return GlobalOffsetArray(np.zeros((length, ) * dim),
                              global_offset=global_offsets[i])
    def test_standard_operators(self):
        """
        Tests that standard operators will only work when:
            * global offset and size are same for both operands
            * one operand is fully encapsulated by another (returns a copy of the larger with the smaller added)

        All other cases should throw errors
        """
        ndim = 5
        length = 4

        all_slices = (slice(None, None), ) * ndim
        # test all operators
        for op in STANDARD_OPERATORS:
            # test operation commutativity
            for forward in [True, False]:
                (original,
                 fixed_operand_template) = self.generate_data(ndim, length)
                # test different sizes
                for shape in [
                        fixed_operand_template.shape,
                        tuple(s * 2 for s in fixed_operand_template.shape),
                        tuple(s // 2 + 1 for s in fixed_operand_template.shape)
                ]:
                    # test different overlap offsets
                    for offset_of_offset in [-2, 0, 2, 100]:
                        fixed_operand = fixed_operand_template.copy()
                        # offset array used as other operand for operator
                        offsetted_operand = GlobalOffsetArray(
                            np.arange(np.prod(shape),
                                      dtype=fixed_operand.dtype).reshape(shape)
                            * 10 + 1,
                            global_offset=tuple(
                                offset_of_offset + offset
                                for offset in fixed_operand.global_offset))

                        expected_error = expected_result = None
                        actual_error = actual_result = None

                        fixed_in_offsetted = fixed_operand.is_contained_within(
                            offsetted_operand)
                        offsetted_in_fixed = offsetted_operand.is_contained_within(
                            fixed_operand)

                        # Determine the slices when one is fully encapsulated by the other
                        fixed_slices = tuple(
                            slice(offset_of_offset, offset_of_offset + s)
                            for s in offsetted_operand.shape)
                        offsetted_slices = tuple(
                            slice(-1 *
                                  offset_of_offset, -1 * offset_of_offset + s)
                            for s in fixed_operand.shape)

                        if fixed_in_offsetted and not offsetted_in_fixed:
                            sub_slices = offsetted_slices
                            expected_result = offsetted_operand.view(
                                np.ndarray).copy()
                        elif not fixed_in_offsetted and offsetted_in_fixed:
                            sub_slices = fixed_slices
                            expected_result = original.view(np.ndarray).copy()
                        else:
                            # either exactly the same or separate slices
                            fixed_slices = offsetted_slices = all_slices
                            sub_slices = all_slices

                        # swap operands around on forward flag
                        if forward:
                            left_expected = original.copy()
                            left_actual = fixed_operand
                            left_slices = fixed_slices

                            right_expected = offsetted_operand.view(np.ndarray)
                            right_actual = offsetted_operand
                            right_slices = offsetted_slices
                        else:
                            left_expected = offsetted_operand.view(
                                np.ndarray).copy()
                            left_actual = offsetted_operand
                            left_slices = offsetted_slices

                            right_expected = original.view(np.ndarray)
                            right_actual = fixed_operand
                            right_slices = fixed_slices

                        left_slices = no_wrap_slices(left_slices)
                        right_slices = no_wrap_slices(right_slices)
                        sub_slices = no_wrap_slices(sub_slices)

                        # Condition to autofail on partial overlaps
                        if not fixed_in_offsetted and not offsetted_in_fixed:
                            with pytest.raises(ValueError):
                                op(left_actual, right_actual)
                            continue

                        try:
                            interim_result = op(left_expected[left_slices],
                                                right_expected[right_slices])
                        except Exception as e:
                            expected_error = e

                        if expected_result is not None:
                            expected_result = expected_result.astype(
                                interim_result.dtype)
                            expected_result[sub_slices] = interim_result
                        else:
                            expected_result = interim_result

                        try:
                            actual_result = op(left_actual, right_actual)
                        except Exception as e:
                            actual_error = e

                        assert expected_error is None == actual_error is None, \
                            'Expected error: (%s) Actual error: (%s)' % (expected_error, actual_error) # noqa E711

                        # ensure global_offset is preserved
                        assert hasattr(actual_result, 'global_offset')
                        assert tuple(offset_of_offset + o
                                     for o in fixed_operand.global_offset
                                     ) == actual_result.global_offset

                        # ensure actual results match that of a regular ndarray
                        assert np.array_equal(expected_result, actual_result)

                        # ensure the results behave like ndarray to return a copy of the array instead of a view by
                        # testing that the original arrays were not modified
                        actual_result[actual_result.global_offset] = 1337
                        assert np.all(fixed_operand != 1337)
    def test_in_place_operators(self):
        """
        Tests that in-place operators will only work when:
            * global offset and size are same for both operands
            * one operand is fully encapsulated by another (returns a copy of the larger with the smaller added)

        All other cases should throw errors
        """
        ndim = 5
        length = 4

        # test all operators
        for op in IN_PLACE_OPERATORS:
            # test operation commutativity
            for forward in [True, False]:
                (original,
                 fixed_operand_template) = self.generate_data(ndim, length)

                # in place only works with floats because we can't mix int and float into the same ndarray
                if op == operator.itruediv:
                    original = original.astype(np.float64)
                    fixed_operand_template = fixed_operand_template.astype(
                        np.float64)

                # test different sizes
                for shape in [
                        fixed_operand_template.shape,
                        tuple(s * 2 for s in fixed_operand_template.shape),
                        tuple(s // 2 + 1 for s in fixed_operand_template.shape)
                ]:
                    # test different overlap offsets
                    for offset_of_offset in [-2, 0, 2, 100]:
                        fixed_operand = fixed_operand_template.copy()

                        # offset array used as other operand for operator
                        offsetted_operand = GlobalOffsetArray(
                            np.arange(np.prod(shape),
                                      dtype=fixed_operand.dtype).reshape(shape)
                            * 10 + 1,
                            global_offset=tuple(
                                offset_of_offset + offset
                                for offset in fixed_operand.global_offset))

                        expected_error = expected_result = None
                        actual_error = actual_result = None

                        fixed_in_offsetted = fixed_operand.is_contained_within(
                            offsetted_operand)
                        offsetted_in_fixed = offsetted_operand.is_contained_within(
                            fixed_operand)

                        fixed_slices = tuple(
                            slice(offset_of_offset, offset_of_offset + s)
                            for s in offsetted_operand.shape)
                        offsetted_slices = tuple(
                            slice(-1 *
                                  offset_of_offset, -1 * offset_of_offset + s)
                            for s in fixed_operand.shape)

                        # swap operands around on forward flag
                        if forward:
                            left_expected = original.copy()
                            left_actual = fixed_operand
                            left_slices = fixed_slices

                            right_expected = offsetted_operand.view(np.ndarray)
                            right_actual = offsetted_operand
                            right_slices = offsetted_slices

                            sub_slices = fixed_slices
                        else:
                            left_expected = offsetted_operand.view(
                                np.ndarray).copy()
                            left_actual = offsetted_operand
                            left_slices = offsetted_slices

                            right_expected = original.view(np.ndarray)
                            right_actual = fixed_operand
                            right_slices = fixed_slices

                            sub_slices = offsetted_slices

                        expected_result = left_expected

                        left_slices = no_wrap_slices(left_slices)
                        right_slices = no_wrap_slices(right_slices)
                        sub_slices = no_wrap_slices(sub_slices)

                        # Condition to autofail on disjoint
                        if not fixed_in_offsetted and not offsetted_in_fixed and shape[
                                0] > length * 2:
                            with pytest.raises(ValueError):
                                op(left_actual, right_actual)
                            continue

                        interim_result = op(left_expected[left_slices],
                                            right_expected[right_slices])
                        expected_result = expected_result.astype(
                            interim_result.dtype)
                        expected_result[sub_slices] = interim_result

                        try:
                            actual_result = op(left_actual, right_actual)
                        except Exception as e:
                            actual_error = e

                        assert expected_error is None == actual_error is None, \
                            'Expected error: (%s) Actual error: (%s)' % (expected_error, actual_error) # noqa E711

                        # ensure global_offset is preserved
                        assert hasattr(actual_result, 'global_offset')
                        assert left_actual.global_offset == actual_result.global_offset

                        # ensure actual results match that of a regular ndarray
                        assert np.array_equal(expected_result, actual_result)

                        # ensure that in place modifies the actual result
                        actual_result[actual_result.global_offset] = 1337
                        assert 1337 == left_actual[actual_result.global_offset]
 def test_aggregate_function(self):
     for test_array in TEST_ARRAYS:
         offset_array = GlobalOffsetArray(test_array)
         assert type(offset_array.sum()) == type(test_array.sum())  #noqa