Exemple #1
0
    def test_make_cube_and_make_spectrum_return_the_same_fluxes(self):
        src_all = so._table_source() + \
                  so._image_source(dx=-4, dy=-4) + \
                  so._cube_source(weight=1e-8, dx=4)

        fov = _fov_190_210_um()
        fov.extract_from(src_all)

        # if photlam, units of ph / s / cm2 / AA, else units of ph / s / voxel
        cube = fov.make_cube_hdu()
        cube_waves = get_cube_waveset(cube.header)
        cube_spectrum = cube.data.sum(axis=2).sum(axis=1)

        # always units of ph / s / cm-2 / AA-1
        waves = fov.waveset
        spectrum = fov.make_spectrum()(waves).value

        bin_width = 0.02        # um
        photlam_to_si = 1e8     # cm-2 AA-1 --> m-2 um-1
        edge_compensation = 0.91

        spectrum *= bin_width * photlam_to_si * edge_compensation

        if PLOTS:
            plt.plot(waves, spectrum, "k")
            plt.plot(cube_waves, cube_spectrum, "r")
            plt.show()

        assert np.sum(cube.data) == approx(np.sum(spectrum), rel=0.001)
Exemple #2
0
    def test_makes_image_from_all_types_of_source_object(self):
        src_all = so._table_source() + \
                  so._image_source(dx=-4, dy=-4) + \
                  so._cube_source(weight=1e-8, dx=4)

        fov = _fov_190_210_um()
        fov.extract_from(src_all)

        image = fov.make_image_hdu()

        # sum up the expected flux in the output cube
        waveset = fov.spectra[0].waveset
        scale_factor = 0.02 * 0.91 * 1e8  # bin_width * half width edge bin * PHOTLAM -> SI

        table_sum = 0
        for x, y, ref, weight in src_all.fields[0]:
            flux = src_all.spectra[ref](waveset).value
            table_sum += np.sum(flux) * weight * scale_factor

        ref = src_all.fields[1].header["SPEC_REF"]
        spec = fov.spectra[ref](waveset).value
        image_sum = np.sum(src_all.fields[1].data) * np.sum(spec) * scale_factor

        cube_sum = np.sum(src_all.fields[2].data[70:81, :, :]) * 0.02 * 0.95

        in_sum = table_sum + image_sum + cube_sum
        out_sum = np.sum(image.data)

        assert out_sum == approx(in_sum, rel=0.01)

        if PLOTS:
            im = image.data
            plt.imshow(im, origin="lower", norm=LogNorm(), vmin=1e-8)
            plt.show()
Exemple #3
0
    def test_makes_spectrum_from_all_types_of_source_object(self):
        src_table = so._table_source()
        src_image = so._image_source(dx=-4, dy=-4)
        src_cube = so._cube_source(weight=1e-8, dx=4)
        src_all = src_table + src_image + src_cube

        fov = _fov_190_210_um()
        fov.extract_from(src_all)

        spec = fov.make_spectrum()

        table_sum = np.sum([n * spec(fov.waveset).value
                            for n, spec in zip([3, 1, 1], src_table.spectra)])  # sum of weights [3,1,1]
        image_sum = np.sum(src_image.fields[0].data) * \
                    np.sum(src_image.spectra[0](fov.waveset).value)
        cube_sum = np.sum(src_cube.fields[0].data[70:81, :, :]) * 1e-8

        in_sum = table_sum + image_sum + cube_sum
        out_sum = np.sum(spec(fov.waveset).value)

        assert in_sum == approx(out_sum)

        if PLOTS:
            waves = fov.waveset
            plt.plot(waves, spec(waves))
            for spectrum in src_all.spectra:
                plt.plot(waves, spectrum(waves))
            plt.show()
Exemple #4
0
    def test_extract_2d_image_from_hduimage(self):
        src = so._image_source(dx=10)       # 10x10" @ 0.2"/pix, offset by 10"
        fov = _fov_190_210_um()
        fov.extract_from(src)

        assert fov.fields[0].data.shape == (51, 26)
        assert len(fov.spectra[0].waveset) == 11
        assert fov.spectra[0].waveset[0].value == approx(19000)
def _basic_fov():
    src = _image_source()
    fov = FieldOfView(_basic_fov_header(),
                      waverange=[1, 2] * u.um,
                      area=1 * u.m**2)
    fov.extract_from(src)

    return fov
    def test_works_with_a_pointer_to_fits_imagehdu(self, cmds):
        # Basically just checking to make sure observe doesn't throw an error
        # when passed a Source object with a file pointer ImageHDU
        fits_src = src_objs._fits_image_source()
        array_src = src_objs._image_source()

        src = fits_src + array_src
        opt = OpticalTrain(cmds)
        opt.observe(src)

        assert np.sum(opt.image_planes[0].data) > 0
Exemple #7
0
    def test_make_spectrum_from_image(self):
        src_image = so._image_source()  # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_190_210_um()
        fov.extract_from(src_image)

        spec = fov.make_spectrum()

        in_sum = np.sum(src_image.fields[0].data) * \
                 np.sum(src_image.spectra[0](fov.waveset).value)
        out_sum = np.sum(spec(fov.waveset).value)

        assert in_sum == approx(out_sum)
Exemple #8
0
    def test_fits_image_and_array_image_are_added_correctly(self):
        img_src = so._image_source()
        fits_src = so._fits_image_source()

        img_fits_src = img_src + fits_src
        fits_img_src = fits_src + img_src

        assert len(img_src.fields) == 1
        assert len(fits_src.fields) == 1
        assert len(img_fits_src.fields) == 2
        assert len(fits_img_src.fields) == 2
        assert np.all(fits_img_src.fields[0].data == fits_src.fields[0].data)
        assert img_fits_src.fields[0] is not img_src.fields[0]
Exemple #9
0
    def test_makes_cube_from_imagehdu(self):
        src_image = so._image_source()            # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_190_210_um()
        fov.extract_from(src_image)

        cube = fov.make_cube_hdu()

        waveset = np.linspace(1.9, 2.1, np.shape(cube)[0]) * u.um
        spec = fov.spectra[0](waveset).to(u.ph/u.s/u.m**2/u.um).value
        in_sum = np.sum(src_image.fields[0].data) * np.sum(spec)
        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum, rel=0.01)

        if PLOTS:
            plt.imshow(cube.data[0, :, :], origin="lower")
            plt.show()
    def test_views_with_only_image(self, basic_fov_header):
        src = _image_source()
        flux = src.photons_in_range(1 * u.um, 2 * u.um).value
        orig_sum = np.sum(src.fields[0].data * flux)

        the_fov = FieldOfView(basic_fov_header, (1, 2) * u.um, area=1 * u.m**2)
        the_fov.extract_from(src)
        the_fov.view()

        assert np.isclose(np.sum(the_fov.hdu.data), orig_sum)

        if PLOTS:
            plt.imshow(src.fields[0].data, origin="lower", norm=LogNorm())
            plt.colorbar()
            plt.show()

            plt.imshow(the_fov.hdu.data, origin="lower", norm=LogNorm())
            plt.colorbar()
            plt.show()
Exemple #11
0
    def test_extract_one_of_each_type_from_source_object(self):
        src_table = so._table_source()              # 4 sources, put two outside of FOV
        src_table.fields[0]["x"] = [-15,-5,0,0] * u.arcsec
        src_table.fields[0]["y"] = [0,0,5,15] * u.arcsec
        src_image = so._image_source(dx=10)         # 10x10" @ 0.2"/pix
        src_cube = so._cube_source()                # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        src = src_cube + src_image + src_table

        fov = _fov_197_202_um()
        fov.extract_from(src)

        assert fov.fields[0].shape == (3, 51, 51)
        assert fov.fields[1].shape == (51, 26)
        assert len(fov.fields[2]) == 2

        assert len(fov.spectra) == 3
        assert fov.fields[1].header["SPEC_REF"] == 0
        for spec in fov.spectra.values():
            assert spec.waveset[0].value == approx(1.97e4)
            assert spec.waveset[-1].value == approx(2.02e4)     # Angstrom
Exemple #12
0
    def test_views_with_rotated_image(self, basic_fov_header):
        src = _image_source(angle=30)
        flux = src.photons_in_range(1 * u.um, 2 * u.um).value
        orig_sum = np.sum(src.fields[0].data) * flux

        the_fov = fov.FieldOfView(basic_fov_header, (1, 2) * u.um,
                                  area=1 * u.m**2)
        the_fov.extract_from(src)
        view = the_fov.view()

        assert np.isclose(np.sum(view), orig_sum, rtol=1e-3)

        if PLOTS:
            plt.imshow(src.fields[0].data, origin="lower", norm=LogNorm())
            plt.colorbar()
            plt.show()

            plt.imshow(view, origin="lower", norm=LogNorm())
            plt.colorbar()
            plt.show()
Exemple #13
0
    def test_all_spectra_are_referenced_correctly(self):
        src = so._image_source() + so._cube_source() + so._table_source()
        fov = _fov_190_210_um()
        fov.extract_from(src)
        # check the same spectrum object is referenced by both lists
        assert fov.fields[0].header["SPEC_REF"] == \
               src.fields[0].header["SPEC_REF"]
        assert np.all([fov.fields[2][i]["ref"] == \
                       src.fields[2][i]["ref"] for i in range(4)])

        def test_contains_all_fields_inside_fov(self, basic_fov_header,
                                                cube_source,
                                                image_source, table_source):
            src = image_source + cube_source + table_source
            the_fov = FieldOfView(basic_fov_header, (1, 2) * u.um,
                                  area=1 * u.m ** 2)
            the_fov.extract_from(src)
            assert len(the_fov.fields) == 3
            assert isinstance(the_fov.fields[0], fits.ImageHDU)
            assert isinstance(the_fov.fields[1], fits.ImageHDU)
            assert the_fov.fields[1].header["NAXIS"] == 3
            assert isinstance(the_fov.fields[2], Table)
Exemple #14
0
    def test_makes_image_from_image(self):
        src_image = so._image_source()  # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_190_210_um()
        fov.extract_from(src_image)

        img = fov.make_image_hdu()

        src_im_sum = np.sum(src_image.fields[0].data)
        src_spec = src_image.spectra[0](fov.waveset).to(u.ph/u.s/u.m**2/u.um)
        src_flux = 0.91 * np.sum(src_spec * 1 * u.m**2 * 0.02 * u.um).value
        in_sum = src_im_sum * src_flux
        out_sum = np.sum(img.data)

        # 2% discrepancy is because the edge bins in FOV (not of equal value)
        # are multiplied by 0.5 when summed. This test simply multiplies by 0.91
        # to account for the last (11th) bin edge in the range 1.9 : 2.1 : 0.01

        assert out_sum == approx(in_sum, rel=0.01)

        if PLOTS:
            plt.imshow(img.data, origin="lower")
            plt.show()
    def test_views_with_rotated_image(self, basic_fov_header):
        area = 1 * u.m**2

        # works for angle=0, not working for angle!=0
        src = _image_source(angle=30)
        flux = src.photons_in_range(1 * u.um, 2 * u.um, area=area).value
        in_sum = np.sum(src.fields[0].data) * flux

        the_fov = FieldOfView(basic_fov_header, (1, 2) * u.um, area=area)
        the_fov.extract_from(src)
        view = the_fov.view()
        out_sum = np.sum(view)

        assert out_sum == approx(in_sum, rel=1e-3)

        if PLOTS:
            plt.subplot(121)
            plt.imshow(src.fields[0].data, origin="lower", norm=LogNorm())
            plt.colorbar()

            plt.subplot(122)
            plt.imshow(view, origin="lower", norm=LogNorm())
            plt.colorbar()
            plt.show()
def im_src():
    return _image_source()
Exemple #17
0
def im_src():
    return src_objs._image_source()
Exemple #18
0
class TestMakeCube:
    def test_makes_cube_from_table(self):
        src_table = so._table_source()            # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_190_210_um()
        fov.extract_from(src_table)

        cube = fov.make_cube_hdu()

        in_sum = 0
        waveset = fov.spectra[0].waveset
        for x, y, ref, weight in src_table.fields[0]:
            flux = src_table.spectra[ref](waveset).to(u.ph/u.s/u.m**2/u.um).value
            in_sum += np.sum(flux) * weight

        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum, rel=0.01)

        if PLOTS:
            plt.imshow(cube.data[0, :, :], origin="lower")
            plt.show()

    def test_makes_cube_from_imagehdu(self):
        src_image = so._image_source()            # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_190_210_um()
        fov.extract_from(src_image)

        cube = fov.make_cube_hdu()

        waveset = np.linspace(1.9, 2.1, np.shape(cube)[0]) * u.um
        spec = fov.spectra[0](waveset).to(u.ph/u.s/u.m**2/u.um).value
        in_sum = np.sum(src_image.fields[0].data) * np.sum(spec)
        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum, rel=0.01)

        if PLOTS:
            plt.imshow(cube.data[0, :, :], origin="lower")
            plt.show()

    def test_makes_cube_from_other_cube_imagehdu(self):
        import scopesim as sim
        sim.rc.__currsys__["!SIM.spectral.spectral_bin_width"] = 0.01
        src_cube = so._cube_source()            # 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_197_202_um()
        fov.extract_from(src_cube)

        cube = fov.make_cube_hdu()

        # layer 74 to 77 are extracted by FOV
        in_sum = np.sum(src_cube.fields[0].data[74:77, :, :])

        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum)

        if PLOTS:
            plt.imshow(cube.data[0, :, :], origin="lower")
            plt.show()

    def test_makes_cube_from_two_similar_cube_imagehdus(self):
        src_cube = so._cube_source() + so._cube_source(dx=1)            # 2 cubes 10x10" @ 0.2"/pix, [0.5, 2.5]m @ 0.02µm
        fov = _fov_197_202_um()
        fov.extract_from(src_cube)

        cube = fov.make_cube_hdu()

        # layer 74 to 77 are extracted by FOV
        bin_widths = np.array([0.01, 0.02, 0.01])[:, None, None] * 1e4      # um -> AA
        in_sum = 2 * np.sum(src_cube.fields[0].data[74:77, :, :] * bin_widths)

        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum, rel=1e-3)

        if PLOTS:
            plt.imshow(cube.data[0, :, :], origin="lower")
            plt.show()

    def test_makes_cube_from_all_types_of_source_object(self):
        src_all = so._table_source() + \
                  so._image_source(dx=-4, dy=-4) + \
                  so._cube_source(weight=1e-8, dx=4)

        fov = _fov_190_210_um()
        fov.extract_from(src_all)

        cube = fov.make_cube_hdu()

        # sum up the expected flux in the output cube
        # bin_width * half width edge bin * PHOTLAM -> SI
        waveset = fov.spectra[0].waveset

        table_sum = 0
        for x, y, ref, weight in src_all.fields[0]:
            flux = src_all.spectra[ref](waveset).value
            table_sum += np.sum(flux) * weight

        ref = src_all.fields[1].header["SPEC_REF"]
        spec = fov.spectra[ref](waveset).value
        image_sum = np.sum(src_all.fields[1].data) * np.sum(spec)

        cube_sum = np.sum(src_all.fields[2].data[70:81, :, :]) * 0.02 * 0.95

        in_sum = table_sum + image_sum + cube_sum
        out_sum = np.sum(cube.data)

        assert out_sum == approx(in_sum, rel=0.02)

        if PLOTS:
            im = cube.data[0, :, :]
            plt.imshow(im, origin="lower", norm=LogNorm(), vmin=1e-8)
            plt.show()

    @pytest.mark.parametrize("src", [so._table_source(),
                                     so._image_source(),
                                     so._cube_source()])
    def test_cube_has_full_wcs(self, src):
        fov = _fov_190_210_um()
        fov.extract_from(src)

        cube = fov.make_cube_hdu()

        assert "CDELT3" in cube.header
        assert "CRVAL3" in cube.header
        assert "CRPIX3" in cube.header
        assert "CUNIT3" in cube.header
        assert "CTYPE3" in cube.header