예제 #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")
    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")
예제 #3
0
    def test_wavelength_conversion_roundtrip(self, filepath):
        cube = HyperspectralCube.from_fits(filepath)

        # For each spectral pixel index
        for pixel in range(0, cube.shape[0]):
            self.assertEqual(
                round(cube.pixel_of(cube.wavelength_of(pixel))), pixel,
                "Wavelength conversion from pixel index #%d to λ "
                "and back from λ to pixel index #%d." % (pixel, pixel))
예제 #4
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")
    def test_wavelength_conversion_roundtrip(self, filepath):
        cube = HyperspectralCube.from_fits(filepath)

        # For each spectral pixel index
        for pixel in range(0, cube.shape[0]):
            self.assertEqual(
                round(cube.pixel_of(cube.wavelength_of(pixel))),
                pixel,
                "Wavelength conversion from pixel index #%d to λ "
                "and back from λ to pixel index #%d." % (pixel, pixel)
            )
예제 #6
0
    def test_wavelength_of(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # With a singe pixel position
        self.assertEqual(u.Quantity(6734.7802734375, 'Angstrom'),
                         cube.wavelength_of(3))

        # With a list of pixel positions
        self.assertArrayEqual([6734.7802734375, 6737.2802734375],
                              cube.wavelength_of([3, 5]).value)
        self.assertEqual(u.Unit('Angstrom'), cube.wavelength_of([3, 5]).unit)
    def test_wavelength_of(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # With a singe pixel position
        self.assertEqual(u.Quantity(6734.7802734375, 'Angstrom'),
                         cube.wavelength_of(3))

        # With a list of pixel positions
        self.assertArrayEqual([6734.7802734375, 6737.2802734375],
                              cube.wavelength_of([3, 5]).value)
        self.assertEqual(u.Unit('Angstrom'), cube.wavelength_of([3, 5]).unit)
예제 #8
0
    def test_pixel_of(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # With a single wavelength expressed as a simple float
        self.assertEqual(3, cube.pixel_of(6734.7802734375))

        # With a list of wavelengths
        self.assertArrayEqual([3, 5],
                              cube.pixel_of([6734.7802734375,
                                             6737.2802734375]),
                              "pixel_of() supports a list as input")

        # With a ndarray of wavelengths
        self.assertArrayEqual(
            numpy.array([3, 5]),
            cube.pixel_of(numpy.array([6734.7802734375, 6737.2802734375])),
            "pixel_of() supports a numpy array as input")
    def test_pixel_of(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # With a single wavelength expressed as a simple float
        self.assertEqual(3, cube.pixel_of(6734.7802734375))

        # With a list of wavelengths
        self.assertArrayEqual(
            [3, 5],
            cube.pixel_of([6734.7802734375, 6737.2802734375]),
            "pixel_of() supports a list as input"
        )

        # With a ndarray of wavelengths
        self.assertArrayEqual(
            numpy.array([3, 5]),
            cube.pixel_of(numpy.array([6734.7802734375, 6737.2802734375])),
            "pixel_of() supports a numpy array as input"
        )
    def test_write_to_fits_file(self):
        cube = HyperspectralCube.from_fits(self.muse_01_filename)
        fits_out_filename = os.path.join(self.fits_folder, 'tmp_output.fits')

        self.assertFalse(os.path.isfile(fits_out_filename),
                         "Sanity check : Output FITS file should not exist ; "
                         "Please remove it by hand and then "
                         "re-run this test : %s" % fits_out_filename)
        cube.to_fits(fits_out_filename)
        self.assertTrue(os.path.isfile(fits_out_filename),
                        "Output FITS file should be created")

        # `clobber` option should be false by default
        with self.assertRaises(IOError):
            cube.to_fits(fits_out_filename)

        # clobber without raising
        cube.to_fits(fits_out_filename, clobber=True)

        os.remove(fits_out_filename)  # cleanup
예제 #11
0
    def test_getting_steps(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # Collect the data
        steps = cube.get_steps()
        # print "STEPS: %s" % steps
        # <Quantity 1.25 Angstrom>
        # <Quantity 5.55555555556e-05 deg>
        # <Quantity -5.55555555556e-05 deg>

        # Test the success/failure of the API
        self.assertEqual(steps[0], cube.get_step(0))
        self.assertEqual(steps[1], cube.get_step(1))
        self.assertEqual(steps[2], cube.get_step(2))

        # Test unit conversion -- this test is hardwired to muse_01.fits
        self.assertEqual(cube.get_step(0).value, 1.25)
        self.assertAlmostEqual(
            cube.get_step(0).to(u.Unit('micron')).value, 1.25e-4)
예제 #12
0
    def test_write_to_fits_file(self):
        cube = HyperspectralCube.from_fits(self.muse_01_filename)
        fits_out_filename = os.path.join(self.fits_folder, 'tmp_output.fits')

        self.assertFalse(
            os.path.isfile(fits_out_filename),
            "Sanity check : Output FITS file should not exist ; "
            "Please remove it by hand and then "
            "re-run this test : %s" % fits_out_filename)
        cube.to_fits(fits_out_filename)
        self.assertTrue(os.path.isfile(fits_out_filename),
                        "Output FITS file should be created")

        # `clobber` option should be false by default
        with self.assertRaises(IOError):
            cube.to_fits(fits_out_filename)

        # clobber without raising
        cube.to_fits(fits_out_filename, clobber=True)

        os.remove(fits_out_filename)  # cleanup
    def test_getting_steps(self):
        # This test is hardwired to muse_01.fits
        cube = HyperspectralCube.from_fits(self.muse_01_filename)

        # Collect the data
        steps = cube.get_steps()
        # print "STEPS: %s" % steps
        # <Quantity 1.25 Angstrom>
        # <Quantity 5.55555555556e-05 deg>
        # <Quantity -5.55555555556e-05 deg>

        # Test the success/failure of the API
        self.assertEqual(steps[0], cube.get_step(0))
        self.assertEqual(steps[1], cube.get_step(1))
        self.assertEqual(steps[2], cube.get_step(2))

        # Test unit conversion -- this test is hardwired to muse_01.fits
        self.assertEqual(cube.get_step(0).value, 1.25)
        self.assertAlmostEqual(
            cube.get_step(0).to(u.Unit('micron')).value,
            1.25e-4
        )
예제 #14
0
 def test_init_with_unfit_filename(self):
     with self.assertRaises(IOError):
         cube = HyperspectralCube.from_fits('this_is_not_a_fits_file')
예제 #15
0
 def test_init_empty_cube(self):
     cube = HyperspectralCube()
     self.assertTrue(cube.is_empty())
예제 #16
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 **")
예제 #17
0
 def test_from_fits(self, filepath):
     cube = HyperspectralCube.from_fits(filepath)  # should not raise
     print cube
 def test_from_fits(self, filepath):
     cube = HyperspectralCube.from_fits(filepath)  # should not raise
     print cube
 def test_init_with_unfit_filename(self):
     with self.assertRaises(IOError):
         cube = HyperspectralCube.from_fits('this_is_not_a_fits_file')
 def test_init_empty_cube(self):
     cube = HyperspectralCube()
     self.assertTrue(cube.is_empty())