Пример #1
0
    def test_slicing_and_indexing(self):
        # Dummy data
        data_a = numpy.array([
            [[0, 1], [2, 3], [-1, 0]],
            [[1, 0], [3, 2], [+3, 2]],
            [[1, 1], [2, 2], [-3, 0]],
        ],
                             dtype=float)

        x = Axis('x', 0., 1.)
        y = Axis('y', 1., 2.)
        z = Axis('z', 2., 3.)

        cube_a = HyperspectralCube(data=data_a, x=x, y=y, z=z)

        # SLICING USING [:,:,:]
        cube_t = cube_a[0:1, :, :-1]
        data_t = numpy.array([[[0.], [2.], [-1.]]], dtype=float)
        self.assertIsInstance(cube_t, HyperspectralCube,
                              "Truncation result is a HyperspectralCube")
        self.assertArrayEqual(data_t, cube_t.data,
                              "Supports extraction of sub-cube using [:,:,:]")
        # SLICING UPDATES METADATA
        self.assertEqual(cube_t.z.start, z.start, "Z axis start is unchanged")
        self.assertEqual(cube_t.y.start, y.start, "Y axis start is unchanged")
        self.assertEqual(cube_t.x.start, x.start, "X axis start is unchanged")

        # SLICING [min:max] <=> [min:max,:,:]
        cube_t = cube_a[1:2]
        data_t = numpy.array([[[1, 0], [3, 2], [+3, 2]]], dtype=float)
        self.assertArrayEqual(
            data_t, cube_t.data,
            "Unspecified axes are defaulted to `:` in slicing")
        # SLICING UPDATES METADATA
        self.assertEqual(cube_t.z.start, z.start + z.step,
                         "Z axis start has shifted")

        # MUTATING ONE VALUE USING [λ,y,x] INDICES
        data_t = numpy.array([
            [[0, 1], [2, 3], [-1, 0]],
            [[1, 0], [3, 9], [+3, 2]],
            [[1, 1], [2, 2], [-3, 0]],
        ],
                             dtype=float)
        cube_t = cube_a.copy()
        cube_t[1, 1, 1] = 9
        self.assertArrayEqual(data_t, cube_t.data,
                              "Supports mutation cube[λ,y,x] = n")

        # MUTATING MULTIPLE VALUES USING [:,y,x] INDICES
        data_t = numpy.array([
            [[0, 1], [2, 9], [-1, 0]],
            [[1, 0], [3, 9], [+3, 2]],
            [[1, 1], [2, 9], [-3, 0]],
        ],
                             dtype=float)
        cube_t = cube_a.copy()
        cube_t[:, 1, 1] = 9
        self.assertArrayEqual(data_t, cube_t.data,
                              "Supports mutation cube[:,y,x] = n")
Пример #2
0
    def test_shape_property(self):
        data_a = numpy.array([
            [[0, 1], [2, 3], [-1, +0]],
            [[1, 0], [3, 2], [+3, +2]],
            [[1, 1], [2, 2], [-3, +0]],
        ],
                             dtype=float)
        cube_a = HyperspectralCube(data=data_a)

        self.assertArrayEqual((3, 3, 2), cube_a.shape,
                              "cube.shape should return the shape")
Пример #3
0
 def test_init_empty_cube(self):
     cube = HyperspectralCube()
     self.assertTrue(cube.is_empty())
Пример #4
0
    def test_arithmetic_core(self):
        inf = numpy.inf
        nan = numpy.nan

        # TEST DATA
        data_a = numpy.array([
            [[0, 1], [2, 3], [-1, +0]],
            [[1, 0], [3, 2], [+3, +2]],
            [[1, 1], [2, 2], [-3, +0]],
        ],
                             dtype=float)
        data_b = numpy.array([
            [[1, 1], [0, 0], [+1, -1]],
            [[0, 0], [3, 1], [+3, -2]],
            [[2, 2], [1, 2], [-1, +0]],
        ],
                             dtype=float)
        data_i = numpy.array([
            [[2, 0], [1, 1], [+1, -1]],
        ], dtype=float)

        # BRAIN COMPUTED EXPECTATIONS
        data_a_plus_1 = numpy.array([
            [[1, 2], [3, 4], [+0, +1]],
            [[2, 1], [4, 3], [+4, +3]],
            [[2, 2], [3, 3], [-2, +1]],
        ],
                                    dtype=float)
        data_a_plus_b = numpy.array([
            [[1, 2], [2, 3], [+0, -1]],
            [[1, 0], [6, 3], [+6, -0]],
            [[3, 3], [3, 4], [-4, +0]],
        ],
                                    dtype=float)
        data_a_plus_i = numpy.array([
            [[2, 1], [3, 4], [+0, -1]],
            [[3, 0], [4, 3], [+4, +1]],
            [[3, 1], [3, 3], [-2, -1]],
        ],
                                    dtype=float)
        data_a_minus_1 = numpy.array([
            [[-1, +0], [1, 2], [-2, -1]],
            [[+0, -1], [2, 1], [+2, +1]],
            [[+0, +0], [1, 1], [-4, -1]],
        ],
                                     dtype=float)
        data_1_minus_a = numpy.array([
            [[+1, +0], [-1, -2], [+2, +1]],
            [[+0, +1], [-2, -1], [-2, -1]],
            [[+0, +0], [-1, -1], [+4, +1]],
        ],
                                     dtype=float)
        data_a_times_2 = numpy.array([
            [[0, 2], [4, 6], [-2, +0]],
            [[2, 0], [6, 4], [+6, +4]],
            [[2, 2], [4, 4], [-6, +0]],
        ],
                                     dtype=float)
        data_a_times_b = numpy.array([
            [[0, 1], [0, 0], [-1, +0]],
            [[0, 0], [9, 2], [+9, -4]],
            [[2, 2], [2, 4], [+3, +0]],
        ],
                                     dtype=float)
        data_a_div_2 = numpy.array([
            [[.0, .5], [1.0, 3. / 2], [-.5, 0]],
            [[.5, .0], [3. / 2, 1.0], [3. / 2, 1]],
            [[.5, .5], [1.0, 1.0], [-3. / 2, 0]],
        ],
                                   dtype=float)
        data_a_div_b = numpy.array([
            [[0, 1], [inf, inf], [-1, -0.]],
            [[inf, nan], [1, 2], [+1, -1.]],
            [[.5, .5], [2, 1], [+3, nan]],
        ],
                                   dtype=float)
        data_a_pow_2 = numpy.array([
            [[0, 1], [4, 9], [+1, +0]],
            [[1, 0], [9, 4], [+9, +4]],
            [[1, 1], [4, 4], [+9, +0]],
        ],
                                   dtype=float)
        data_2_pow_a = numpy.array([
            [[1, 2], [4, 8], [0.5, 1]],
            [[2, 1], [8, 4], [8, 4]],
            [[2, 2], [4, 4], [1. / 8, 1]],
        ],
                                   dtype=float)
        data_b_pow_a = numpy.array([
            [[1, 1], [0, 0], [+1, +1]],
            [[0, 1], [27, 1], [27, +4]],
            [[2, 2], [1, 4], [-1, +1]],
        ],
                                   dtype=float)

        self.assertArrayEqual(data_a_div_b, data_a_div_b,
                              "Sanity check with inf and nan")

        cube_a = HyperspectralCube(data=data_a)
        cube_b = HyperspectralCube(data=data_b)
        cube_e = HyperspectralCube()  # empty

        # CUBE + NUMBER
        cube_a_plus_1 = cube_a + 1.
        self.assertIsInstance(cube_a_plus_1, HyperspectralCube,
                              "Addition result is a HyperspectralCube")
        self.assertArrayEqual(data_a_plus_1, cube_a_plus_1.data,
                              "Supports addition of cube and number using +")

        # # NUMBER + CUBE
        cube_a_plus_1 = 1. + cube_a
        self.assertIsInstance(cube_a_plus_1, HyperspectralCube,
                              "Addition result is a HyperspectralCube")
        self.assertArrayEqual(data_a_plus_1, cube_a_plus_1.data,
                              "Supports addition of number and cube using +")

        # CUBE A + CUBE B
        cube_a_plus_b = cube_a + cube_b
        self.assertIsInstance(cube_a_plus_b, HyperspectralCube,
                              "Addition result is a HyperspectralCube")
        self.assertArrayEqual(data_a_plus_b, cube_a_plus_b.data,
                              "Supports addition of two cubes using +")

        # CUBE A + NDARRAY
        cube_a_plus_b = cube_a + data_b
        self.assertIsInstance(cube_a_plus_b, HyperspectralCube,
                              "Addition result is a HyperspectralCube")
        self.assertArrayEqual(data_a_plus_b, cube_a_plus_b.data,
                              "Supports addition of cube and ndarray using +")

        # CUBE + IMAGE
        cube_a_plus_i = cube_a + data_i
        self.assertIsInstance(cube_a_plus_i, HyperspectralCube,
                              "Addition result is a HyperspectralCube")
        self.assertArrayEqual(data_a_plus_i, cube_a_plus_i.data,
                              "Supports addition of cube and image using +")

        # NDARRAY + CUBE
        # These are tricky : yields a numpy.ndarray because numpy is flexible
        # in what it accepts as the right hand operator, and it accepts our
        # HyperspectralCube because it provides the `__array__` method, so our
        # __radd__ method is never even called.
        cube_b_plus_a = data_b + cube_a
        self.assertIsInstance(cube_b_plus_a, numpy.ndarray,
                              "Addition result is a numpy.ndarray")
        self.assertArrayEqual(data_a_plus_b, cube_b_plus_a,
                              "Supports addition of image and cube using +")
        # IMAGE + CUBE
        cube_a_plus_i = data_i + cube_a
        self.assertIsInstance(cube_a_plus_i, numpy.ndarray,
                              "Addition result is a numpy.ndarray")
        self.assertArrayEqual(data_a_plus_i, cube_a_plus_i,
                              "Supports addition of image and cube using +")

        # ADDITION EXPECTED ERRORS
        with self.assertRaises(TypeError):
            cube_a + cube_e  # right-hand empty cube
        with self.assertRaises(TypeError):
            cube_e + cube_b  # left-hand empty cube
        with self.assertRaises(TypeError):
            cube_b + 'rock'  # left-hand "garbage"
        with self.assertRaises(TypeError):
            '666.' + cube_a  # right-hand "garbage"

        # CUBE - NUMBER
        cube_a_minus_1 = cube_a - 1
        self.assertIsInstance(cube_a_minus_1, HyperspectralCube,
                              "Subtraction result is a HyperspectralCube")
        self.assertArrayEqual(
            data_a_minus_1, cube_a_minus_1.data,
            "Supports subtraction of number from cube using -")

        # NUMBER - CUBE
        cube_1_minus_a = 1 - cube_a
        self.assertIsInstance(cube_1_minus_a, HyperspectralCube,
                              "Subtraction result is a HyperspectralCube")
        self.assertArrayEqual(
            data_1_minus_a, cube_1_minus_a.data,
            "Supports subtraction of cube from number using -")

        # CUBE * NUMBER
        cube_a_times_2 = cube_a * 2
        self.assertIsInstance(cube_a_times_2, HyperspectralCube,
                              "Multiplication result is a HyperspectralCube")
        self.assertArrayEqual(
            data_a_times_2, cube_a_times_2.data,
            "Supports multiplication of cube and number using *")

        # NUMBER * CUBE
        cube_a_times_2 = 2 * cube_a
        self.assertIsInstance(cube_a_times_2, HyperspectralCube,
                              "Multiplication result is a HyperspectralCube")
        self.assertArrayEqual(
            data_a_times_2, cube_a_times_2.data,
            "Supports multiplication of number and cube using *")

        # CUBE A * CUBE B
        cube_a_times_b = cube_a * cube_b
        self.assertIsInstance(cube_a_times_b, HyperspectralCube,
                              "Multiplication result is a HyperspectralCube")
        self.assertArrayEqual(data_a_times_b, cube_a_times_b.data,
                              "Supports multiplication of two cubes using *")

        # CUBE / NUMBER
        cube_a_div_2 = cube_a / 2
        self.assertIsInstance(cube_a_div_2, HyperspectralCube,
                              "Division result is a HyperspectralCube")
        self.assertArrayEqual(data_a_div_2, cube_a_div_2.data,
                              "Supports division of cube and number using /")

        # CUBE / CUBE
        cube_a_div_b = cube_a / cube_b
        self.assertIsInstance(cube_a_div_b, HyperspectralCube,
                              "Division result is a HyperspectralCube")
        self.assertArrayEqual(data_a_div_b, cube_a_div_b.data,
                              "Supports division of two cubes using /")

        # CUBE ** NUMBER
        cube_a_pow_2 = cube_a**2
        self.assertIsInstance(cube_a_pow_2, HyperspectralCube,
                              "Exponentiation result is a HyperspectralCube")
        self.assertArrayEqual(
            data_a_pow_2, cube_a_pow_2.data,
            "Supports exponentiation of cube by number using **")

        # NUMBER ** CUBE
        cube_2_pow_a = 2**cube_a
        self.assertIsInstance(cube_2_pow_a, HyperspectralCube,
                              "Exponentiation result is a HyperspectralCube")
        self.assertArrayEqual(
            data_2_pow_a, cube_2_pow_a.data,
            "Supports exponentiation of number by cube using **")