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)