Ejemplo n.º 1
0
    def test_all_two_mm_imagehdus_are_inside_header_wcs(
            self, image_hdu_square_mm, image_hdu_rect_mm):

        image_hdu_rect_mm.header["CRVAL1D"] -= 40
        image_hdu_square_mm.header["CRVAL2D"] += 80

        hdr = imp_utils._make_bounding_header_from_imagehdus(
            [image_hdu_square_mm, image_hdu_rect_mm], pixel_scale=1 * u.mm)
        for imhdr in [image_hdu_square_mm.header, image_hdu_rect_mm.header]:
            x, y = imp_utils.calc_footprint(imhdr, "D")
            x, y = imp_utils.val2pix(hdr, x, y, "D")
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:
            for imhdr in [
                    image_hdu_square_mm.header, image_hdu_rect_mm.header, hdr
            ]:
                x, y = imp_utils.calc_footprint(imhdr, "D")
                xp, yp = imp_utils.val2pix(imhdr, x, y, "D")
                plt.plot(x, y, "r-")

            plt.plot(0, 0, "ro")
            plt.gca().set_aspect(1)
            plt.show()
Ejemplo n.º 2
0
    def test_returns_the_desired_number_of_fovs(self, mvs_effects_list,
                                                mvs_usr_cmds):
        rc.__currsys__ = UserCommands(yamls=mvs_usr_cmds)
        rc.__currsys__["!SIM.computing.max_segment_size"] = 2**20

        fov_man = FOVManager(mvs_effects_list)
        fovs = fov_man.generate_fovs_list()

        implane_size = mvs_effects_list[-2].image_plane_header["NAXIS1"]
        chunk_size = sim.rc.__currsys__["!SIM.computing.chunk_size"]
        wave_layers = 1

        assert len(fovs) == np.round(
            implane_size / chunk_size)**2 * wave_layers

        # ..todo:: go searching for the white line
        if PLOTS:
            plt.subplot(121)
            for fov in fovs:
                from scopesim.optics.image_plane_utils import calc_footprint
                x, y = calc_footprint(fov.hdu.header)
                plt.fill(x * 3600, y * 3600)

            plt.subplot(122)
            for fov in fovs:
                from scopesim.optics.image_plane_utils import calc_footprint
                x, y = calc_footprint(fov.hdu.header, "D")
                plt.plot(x, y)

            plt.show()
Ejemplo n.º 3
0
    def test_returns_set_of_headers_from_detector_list_effect(self):
        # det = eo._full_detector_list()
        det = eo._detector_list()
        kwargs = {
            "pixel_scale": 0.004,
            "plate_scale": 0.26666666666,
            "max_segment_size": 2048**2,
            "chunk_size": 1024
        }
        hdrs = fm_utils.get_imaging_headers([det], **kwargs)

        area_sum = np.sum([hdr["NAXIS1"] * hdr["NAXIS2"] for hdr in hdrs])
        assert area_sum == 4096**2

        if PLOTS:
            plt.subplot(121)
            for hdr in hdrs:
                from scopesim.optics.image_plane_utils import calc_footprint
                x, y = calc_footprint(hdr)
                plt.plot(x * 3600, y * 3600)
                plt.title("Sky plane")
                plt.xlabel("[arcsec]")

            plt.subplot(122)
            for hdr in hdrs:
                from scopesim.optics.image_plane_utils import calc_footprint
                x, y = calc_footprint(hdr, "D")
                plt.plot(x, y)
                plt.title("Detector focal plane")
                plt.xlabel("[mm]")

            plt.show()
Ejemplo n.º 4
0
def is_field_in_fov(fov_header, table_or_imagehdu, wcs_suffix=""):

    s = wcs_suffix
    pixel_scale = utils.quantify(fov_header["CDELT1" + s], u.deg)

    if isinstance(table_or_imagehdu, Table):
        ext_hdr = imp_utils._make_bounding_header_for_tables(
            [table_or_imagehdu], pixel_scale)
    elif isinstance(table_or_imagehdu, fits.ImageHDU):
        ext_hdr = imp_utils._make_bounding_header_from_imagehdus(
            [table_or_imagehdu], pixel_scale)
    else:
        warnings.warn("Input was neither Table nor ImageHDU: {}"
                      "".format(table_or_imagehdu))
        return False

    ext_xsky, ext_ysky = imp_utils.calc_footprint(ext_hdr, wcs_suffix)
    fov_xsky, fov_ysky = imp_utils.calc_footprint(fov_header, wcs_suffix)

    is_inside_fov = min(ext_xsky) < max(fov_xsky) and \
                    max(ext_xsky) > min(fov_xsky) and \
                    min(ext_ysky) < max(fov_ysky) and \
                    max(ext_ysky) > min(fov_ysky)

    return is_inside_fov
Ejemplo n.º 5
0
    def test_all_5_objects_are_inside_header_wcs(self, image_hdu_square,
                                                 image_hdu_rect, input_table):

        tbl1 = deepcopy(input_table)
        tbl2 = deepcopy(input_table)
        tbl3 = deepcopy(input_table)

        tbl2["x"] -= 150
        tbl3["y"] -= 100

        image_hdu_rect.header["CRVAL1"] += 100 * u.arcsec.to(u.deg)
        image_hdu_square.header["CRVAL1"] += 0 * u.arcsec.to(u.deg)
        image_hdu_square.header["CRVAL2"] += 100 * u.arcsec.to(u.deg)

        hdr = imp_utils.get_canvas_header(
            [image_hdu_square, tbl1, tbl2, tbl3, image_hdu_rect],
            pixel_scale=1 * u.arcsec)

        for im in [image_hdu_square.header, image_hdu_rect.header]:
            x, y = imp_utils.calc_footprint(im)
            x, y = imp_utils.val2pix(hdr, x, y)
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        as2deg = u.arcsec.to(u.deg)
        for tbl in [tbl1, tbl2, tbl3]:
            x, y = imp_utils.val2pix(hdr, tbl["x"] * as2deg, tbl["y"] * as2deg)
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:

            x, y = imp_utils.calc_footprint(hdr)
            x, y = imp_utils.val2pix(hdr, x, y)
            plt.plot(x, y, "b")
            x0, y0 = imp_utils.val2pix(hdr, 0, 0)
            plt.plot(x0, y0, "ro")

            for tbl in [tbl1, tbl2, tbl3]:
                x, y = imp_utils.val2pix(hdr, tbl["x"] * as2deg,
                                         tbl["y"] * as2deg)
                plt.plot(x, y, "k.")

            for im in [image_hdu_square.header, image_hdu_rect.header]:
                x, y = imp_utils.calc_footprint(im)
                x, y = imp_utils.val2pix(hdr, x, y)
                plt.plot(x, y, "r-")

            plt.gca().set_aspect(1)
            plt.show()
Ejemplo n.º 6
0
    def test_all_5_objects_are_inside_mm_header_wcs(self, image_hdu_square_mm,
                                                    image_hdu_rect_mm,
                                                    input_table_mm):

        tbl1 = deepcopy(input_table_mm)
        tbl2 = deepcopy(input_table_mm)
        tbl3 = deepcopy(input_table_mm)

        tbl2["x_mm"] -= 150
        tbl3["y_mm"] -= 100

        image_hdu_rect_mm.header["CRVAL1D"] += 100
        image_hdu_square_mm.header["CRVAL1D"] += 0
        image_hdu_square_mm.header["CRVAL2D"] += 100

        hdr = imp_utils.get_canvas_header(
            [image_hdu_square_mm, tbl1, tbl2, tbl3, image_hdu_rect_mm],
            pixel_scale=1 * u.mm)

        for im in [image_hdu_square_mm.header, image_hdu_rect_mm.header]:
            x, y = imp_utils.calc_footprint(im, "D")
            x, y = imp_utils.val2pix(hdr, x, y, "D")
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        for tbl in [tbl1, tbl2, tbl3]:
            x, y = imp_utils.val2pix(hdr, tbl["x_mm"], tbl["y_mm"], "D")
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:

            x, y = imp_utils.calc_footprint(hdr, "D")
            x, y = imp_utils.val2pix(hdr, x, y, "D")
            plt.plot(x, y, "b")
            x0, y0 = imp_utils.val2pix(hdr, 0, 0, "D")
            plt.plot(x0, y0, "ro")

            for tbl in [tbl1, tbl2, tbl3]:
                x, y = imp_utils.val2pix(hdr, tbl["x_mm"], tbl["y_mm"], "D")
                plt.plot(x, y, "k.")

            for im in [image_hdu_square_mm.header, image_hdu_rect_mm.header]:
                x, y = imp_utils.calc_footprint(im, "D")
                x, y = imp_utils.val2pix(hdr, x, y, "D")
                plt.plot(x, y, "r-")

            plt.gca().set_aspect(1)
            plt.show()
Ejemplo n.º 7
0
    def test_image_is_added_to_small_canvas(self, image_hdu_rect,
                                            image_hdu_square):
        im_hdu = image_hdu_rect
        im_hdu.header["CRVAL1"] -= 150 * u.arcsec.to(u.deg)
        im_hdu.header["CRVAL2"] += 40 * u.arcsec.to(u.deg)
        hdr = imp_utils.get_canvas_header([im_hdu, image_hdu_square])

        im = np.zeros((hdr["NAXIS2"], hdr["NAXIS1"]))
        canvas_hdu = fits.ImageHDU(header=hdr, data=im)
        canvas_hdu = imp_utils.add_imagehdu_to_imagehdu(im_hdu, canvas_hdu)
        canvas_hdu = imp_utils.add_imagehdu_to_imagehdu(
            image_hdu_square, canvas_hdu)

        flux = np.sum(im_hdu.data) + np.sum(image_hdu_square.data)
        assert np.sum(canvas_hdu.data) == approx(flux, rel=1e-2)

        if PLOTS:
            for im in [im_hdu, image_hdu_square]:
                x, y = imp_utils.calc_footprint(im.header)
                x, y = imp_utils.val2pix(canvas_hdu.header, x, y)
                plt.plot(x, y, "r-")

            x0, y0 = imp_utils.val2pix(canvas_hdu.header, 0, 0)
            plt.plot(x0, y0, "ro")
            plt.gca().set_aspect(1)

            plt.imshow(canvas_hdu.data, origin="lower")

            plt.show()
Ejemplo n.º 8
0
    def test_mm_image_is_added_to_small_canvas(self, image_hdu_rect_mm,
                                               image_hdu_square_mm):
        im_hdu = image_hdu_rect_mm
        im_hdu.header["CRVAL1D"] -= 150
        im_hdu.header["CRVAL2D"] += 40
        hdr = imp_utils.get_canvas_header([im_hdu, image_hdu_square_mm],
                                          pixel_scale=1 * u.mm)

        im = np.zeros((hdr["NAXIS2"], hdr["NAXIS1"]))
        canvas_hdu = fits.ImageHDU(header=hdr, data=im)
        canvas_hdu = imp_utils.add_imagehdu_to_imagehdu(im_hdu,
                                                        canvas_hdu,
                                                        wcs_suffix="D")

        assert np.sum(canvas_hdu.data) == approx(np.sum(im_hdu.data))

        if PLOTS:
            for im in [im_hdu, image_hdu_square_mm]:
                x, y = imp_utils.calc_footprint(im.header, "D")
                x, y = imp_utils.val2pix(canvas_hdu.header, x, y, "D")
                plt.plot(x, y, "r-")

            x0, y0 = imp_utils.val2pix(canvas_hdu.header, 0, 0, "D")
            plt.plot(x0, y0, "ro")
            plt.gca().set_aspect(1)

            plt.imshow(canvas_hdu.data, origin="lower")

            plt.show()
Ejemplo n.º 9
0
    def test_all_three_tables_are_inside_header_wcs(self, input_table):
        tbl1 = deepcopy(input_table)
        tbl2 = deepcopy(input_table)
        tbl3 = deepcopy(input_table)

        tbl2["x"] -= 25
        tbl3["y"] -= 60

        hdr = imp_utils._make_bounding_header_for_tables([tbl1, tbl2, tbl3])
        as2deg = u.arcsec.to(u.deg)
        for tbl in [tbl1, tbl2, tbl3]:
            x, y = imp_utils.val2pix(hdr, tbl["x"] * as2deg, tbl["y"] * as2deg)
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:
            x, y = imp_utils.calc_footprint(hdr)
            x, y = imp_utils.val2pix(hdr, x, y)
            x0, y0 = imp_utils.val2pix(hdr, 0, 0)

            plt.plot(x, y, "b")
            plt.plot(x0, y0, "ro")
            for tbl in [tbl1, tbl2, tbl3]:
                x, y = imp_utils.val2pix(hdr, tbl["x"] / 3600.,
                                         tbl["y"] / 3600.)
                plt.plot(x, y, "k.")

            plt.show()
Ejemplo n.º 10
0
    def test_all_three_mm_tables_are_inside_header_wcs(self, input_table_mm):
        tbl1 = deepcopy(input_table_mm)
        tbl2 = deepcopy(input_table_mm)
        tbl3 = deepcopy(input_table_mm)

        tbl2["x_mm"] += 50
        tbl3["y_mm"] += 25

        hdr = imp_utils._make_bounding_header_for_tables([tbl1, tbl2, tbl3],
                                                         100 * u.um)
        for tbl in [tbl1, tbl2, tbl3]:
            x, y = imp_utils.val2pix(hdr, tbl["x_mm"], tbl["y_mm"], "D")
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:
            x, y = imp_utils.calc_footprint(hdr, "D")
            x, y = imp_utils.val2pix(hdr, x, y, "D")
            x0, y0 = imp_utils.val2pix(hdr, 0, 0, "D")

            plt.plot(x, y, "b")
            plt.plot(x0, y0, "ro")
            for tbl in [tbl1, tbl2, tbl3]:
                x, y = imp_utils.val2pix(hdr, tbl["x_mm"], tbl["y_mm"], "D")
                plt.plot(x, y, "k.")

            plt.show()
Ejemplo n.º 11
0
def is_field_in_fov(fov_header, field, wcs_suffix=""):
    """
    Returns True if Source.field footprint is inside the FieldOfView footprint

    Parameters
    ----------
    fov_header : fits.Header
        Header from a FieldOfView object
    field : [astropy.Table, astropy.ImageHDU]
        Field object from a Source object
    wcs_suffix : str
        ["S", "D"] Coordinate system: Sky or Detector

    Returns
    -------
    is_inside_fov : bool

    """

    if isinstance(field, fits.ImageHDU) and \
            field.header.get("BG_SRC") is not None:
        is_inside_fov = True
    else:
        if isinstance(field, Table):
            x = list(utils.quantity_from_table("x", field,
                                               u.arcsec).to(u.deg).value)
            y = list(utils.quantity_from_table("y", field,
                                               u.arcsec).to(u.deg).value)
            s = wcs_suffix
            cdelt = utils.quantify(fov_header["CDELT1" + s], u.deg).value
            field_header = imp_utils.header_from_list_of_xy(x, y, cdelt, s)
        elif isinstance(field, (fits.ImageHDU, fits.PrimaryHDU)):
            field_header = field.header
        else:
            logging.warning("Input was neither Table nor ImageHDU: {}"
                          "".format(field))
            return False

        ext_xsky, ext_ysky = imp_utils.calc_footprint(field_header, wcs_suffix)
        fov_xsky, fov_ysky = imp_utils.calc_footprint(fov_header, wcs_suffix)

        is_inside_fov = min(ext_xsky) < max(fov_xsky) and \
                        max(ext_xsky) > min(fov_xsky) and \
                        min(ext_ysky) < max(fov_ysky) and \
                        max(ext_ysky) > min(fov_ysky)

    return is_inside_fov
Ejemplo n.º 12
0
    def test_add_many_mm_tables_and_imagehdus(self, input_table_mm,
                                              image_hdu_rect_mm,
                                              image_hdu_square_mm):
        image_hdu_rect = image_hdu_rect_mm
        image_hdu_square = image_hdu_square_mm
        tbl1 = deepcopy(input_table_mm)
        tbl2 = deepcopy(input_table_mm)

        tbl1["y_mm"] -= 50
        tbl2["x_mm"] += 50
        tbl2["y_mm"] += 50

        im_hdu = image_hdu_rect
        im_hdu.header["CRVAL1D"] -= 150  # mm
        im_hdu.header["CRVAL2D"] += 20

        fields = [im_hdu, tbl1, tbl2, image_hdu_square]
        hdr = imp_utils.get_canvas_header(fields, pixel_scale=1 * u.mm)
        implane = opt_imp.ImagePlane(hdr)
        implane.add(fields, wcs_suffix="D")

        total_flux = np.sum(tbl1["flux"]) + np.sum(tbl2["flux"]) + \
                     np.sum(im_hdu.data) + np.sum(image_hdu_square.data)
        assert np.sum(implane.data) == approx(total_flux)

        if PLOTS:
            for im in [im_hdu, image_hdu_square]:
                x, y = imp_utils.calc_footprint(im.header, "D")
                x, y = imp_utils.val2pix(implane.header, x, y, "D")
                plt.plot(x, y, "r-")

            for tbl in [tbl1, tbl2]:
                hdr = imp_utils._make_bounding_header_for_tables(
                    [tbl], pixel_scale=1 * u.mm)
                x, y = imp_utils.calc_footprint(hdr, "D")
                x, y = imp_utils.val2pix(implane.header, x, y, "D")
                plt.plot(x, y, "r-")

            x0, y0 = imp_utils.val2pix(implane.header, 0, 0, "D")
            plt.plot(x0, y0, "ro")
            plt.gca().set_aspect(1)

            plt.imshow(implane.data, origin="lower", norm=LogNorm())
            plt.show()
Ejemplo n.º 13
0
    def test_returns_wavelength_cut_cube_for_thin_fov(self, cube_source,
                                                      basic_fov_header):
        fov = FieldOfView(basic_fov_header, [1.3, 1.7])
        field = cube_source.fields[0]
        new_field = fov_utils.extract_area_from_imagehdu(field, fov.volume())

        if PLOTS:
            x, y = imp_utils.calc_footprint(basic_fov_header)
            plt.fill(x, y, c="r")
            x, y = imp_utils.calc_footprint(field.header)
            plt.fill(x, y, c="y")
            x, y = imp_utils.calc_footprint(new_field.header)
            plt.fill(x, y, c="g")

            plt.show()

        assert new_field.header["NAXIS1"] == field.header["NAXIS1"]
        assert new_field.header["NAXIS2"] == field.header["NAXIS2"]
        assert new_field.header["NAXIS3"] == 21
Ejemplo n.º 14
0
    def test_returns_fov_objects_for_basic_input(self):
        apm = eo._img_aperture_mask(array_dict={
            "x": [-1.0, 1.0, 1.0, -1.0],
            "y": [-1.0, -1.0, 1.0, 1.0]
        })
        kwargs = {
            "pixel_scale": 0.01,
            "plate_scale": 1,
            "max_segment_size": 100**2,
            "chunk_size": 100
        }

        hdrs = fm_utils.get_imaging_headers([apm], **kwargs)
        waveset = np.linspace(1, 2, 6)
        shifts = {
            "wavelengths": np.array([1, 2]),
            "x_shifts": np.zeros(2),
            "y_shifts": np.array([0, 1]) / 3600
        }  # 0..1 arcsec shift
        fovs = fm_utils.get_imaging_fovs(headers=hdrs,
                                         waveset=waveset,
                                         shifts=shifts)

        assert len(fovs) == (len(waveset) - 1) * len(hdrs)

        if PLOTS:
            from scopesim.optics.image_plane_utils import calc_footprint
            plt.subplot(121)
            for fov in fovs:
                x, y = calc_footprint(fov.hdu.header)
                plt.fill(x * 3600, y * 3600, alpha=0.1, c="b")
                plt.title("Sky plane")
                plt.xlabel("[arcsec]")

            plt.subplot(122)
            for fov in fovs:
                x, y = calc_footprint(fov.hdu.header, "D")
                plt.fill(x, y)
                plt.title("Detector focal plane")
                plt.xlabel("[mm]")

            plt.show()
Ejemplo n.º 15
0
 def test_returns_right_sky_coords_from_known_coords(
         self, image_hdu_square):
     xsky, ysky = imp_utils.calc_footprint(image_hdu_square.header)
     xsky = np.array(xsky)
     xsky[xsky > 180] -= 360
     xsky = np.array(xsky) * u.deg.to(u.arcsec)
     ysky = np.array(ysky) * u.deg.to(u.arcsec)
     dx = max(xsky) - min(xsky)
     dy = max(ysky) - min(ysky)
     assert dx == approx(image_hdu_square.header["NAXIS1"])
     assert dy == approx(image_hdu_square.header["NAXIS2"])
Ejemplo n.º 16
0
    def test_add_many_tables_and_imagehdus(self, input_table, image_hdu_rect,
                                           image_hdu_square):
        tbl1 = deepcopy(input_table)
        tbl2 = deepcopy(input_table)

        tbl1["y"] -= 50
        tbl2["x"] += 50
        tbl2["y"] += 50

        im_hdu = image_hdu_rect
        im_hdu.header["CRVAL1"] -= 150 * u.arcsec.to(u.deg)
        im_hdu.header["CRVAL2"] += 20 * u.arcsec.to(u.deg)

        fields = [im_hdu, tbl1, tbl2, image_hdu_square]
        hdr = imp_utils.get_canvas_header(fields, pixel_scale=1 * u.arcsec)

        implane = opt_imp.ImagePlane(hdr)
        implane.add(fields)

        total_flux = np.sum(tbl1["flux"]) + np.sum(tbl2["flux"]) + \
                     np.sum(im_hdu.data) + np.sum(image_hdu_square.data)
        assert np.sum(implane.data) == approx(total_flux)

        if PLOTS:
            for im in [im_hdu, image_hdu_square]:
                x, y = imp_utils.calc_footprint(im.header)
                x, y = imp_utils.val2pix(implane.header, x, y)
                plt.plot(x, y, "r-")

            for tbl in [tbl1, tbl2]:
                hdr = imp_utils._make_bounding_header_for_tables([tbl])
                x, y = imp_utils.calc_footprint(hdr)
                x, y = imp_utils.val2pix(implane.header, x, y)
                plt.plot(x, y, "r-")

            x0, y0 = imp_utils.val2pix(implane.header, 0, 0)
            plt.plot(x0, y0, "ro")
            plt.gca().set_aspect(1)

            plt.imshow(implane.data, origin="lower", norm=LogNorm())
            plt.show()
Ejemplo n.º 17
0
    def test_mm_image_and_tables_on_large_canvas(self, input_table_mm,
                                                 image_hdu_rect_mm,
                                                 image_hdu_square_mm):
        image_hdu_rect = image_hdu_rect_mm
        image_hdu_square = image_hdu_square_mm
        tbl1 = deepcopy(input_table_mm)
        tbl2 = deepcopy(input_table_mm)

        tbl1["y_mm"] -= 100
        tbl2["x_mm"] += 100
        tbl2["y_mm"] += 100

        im_hdu = image_hdu_rect
        im_hdu.header["CRVAL1D"] -= 150
        im_hdu.header["CRVAL2D"] += 20

        hdr = imp_utils.get_canvas_header(
            [im_hdu, image_hdu_square, tbl1, tbl2], pixel_scale=3 * u.mm)
        im = np.zeros((hdr["NAXIS2"], hdr["NAXIS1"]))
        canvas_hdu = fits.ImageHDU(header=hdr, data=im)

        canvas_hdu = imp_utils.add_table_to_imagehdu(tbl1,
                                                     canvas_hdu,
                                                     wcs_suffix="D")
        canvas_hdu = imp_utils.add_table_to_imagehdu(tbl2,
                                                     canvas_hdu,
                                                     wcs_suffix="D")
        canvas_hdu = imp_utils.add_imagehdu_to_imagehdu(im_hdu,
                                                        canvas_hdu,
                                                        wcs_suffix="D")
        canvas_hdu = imp_utils.add_imagehdu_to_imagehdu(image_hdu_square,
                                                        canvas_hdu,
                                                        wcs_suffix="D")

        total_flux = np.sum(tbl1["flux"]) + np.sum(tbl2["flux"]) + \
                     np.sum(im_hdu.data) + np.sum(image_hdu_square.data)
        assert np.sum(canvas_hdu.data) == approx(total_flux)

        if PLOTS:

            for im in [im_hdu, image_hdu_square]:
                x, y = imp_utils.calc_footprint(im, "D")
                x, y = imp_utils.val2pix(canvas_hdu, x, y, "D")
                plt.plot(x, y, "r-")

            x0, y0 = imp_utils.val2pix(canvas_hdu, 0, 0, "D")
            plt.plot(x0, y0, "ro")
            plt.gca().set_aspect(1)

            plt.imshow(canvas_hdu.data, origin="lower")

            plt.show()
Ejemplo n.º 18
0
    def test_returns_eigth_cube_for_3d_offset_fov(self, cube_source,
                                                         basic_fov_header):
        hdr = basic_fov_header
        hdr["CRVAL1"] += 75 * hdr["CDELT1"]
        hdr["CRVAL2"] += 75 * hdr["CDELT2"]
        fov = FieldOfView(hdr, [1.5, 2.5])
        field = cube_source.fields[0]
        new_field = fov_utils.extract_area_from_imagehdu(field, fov.volume())

        if PLOTS:
            x, y = imp_utils.calc_footprint(basic_fov_header)
            plt.fill(x, y, c="r")
            x, y = imp_utils.calc_footprint(field.header)
            plt.fill(x, y, c="y")
            x, y = imp_utils.calc_footprint(new_field.header)
            plt.fill(x, y, c="g")

            plt.show()

        assert new_field.header["NAXIS1"] == 26
        assert new_field.header["NAXIS2"] == 26
        assert new_field.header["NAXIS3"] == 51
Ejemplo n.º 19
0
    def test_all_two_imagehdus_are_inside_header_wcs(self, image_hdu_square,
                                                     image_hdu_rect):

        image_hdu_rect.header["CRVAL1"] -= 70 * u.arcsec.to(u.deg)
        image_hdu_square.header["CRVAL2"] += 70 * u.arcsec.to(u.deg)

        hdr = imp_utils._make_bounding_header_from_imagehdus(
            [image_hdu_square, image_hdu_rect])
        for imhdr in [image_hdu_square.header, image_hdu_rect.header]:
            x, y = imp_utils.calc_footprint(imhdr)
            x, y = imp_utils.val2pix(hdr, x, y)
            for xi, yi in zip(x, y):
                assert 0 <= xi < hdr["NAXIS1"]
                assert 0 <= yi < hdr["NAXIS2"]

        if PLOTS:
            for imhdr in [image_hdu_square.header, image_hdu_rect.header, hdr]:
                x, y = imp_utils.calc_footprint(imhdr)
                xp, yp = imp_utils.val2pix(imhdr, x, y)
                plt.plot(x, y, "r-")

            plt.plot(0, 0, "ro")
            plt.gca().set_aspect(1)
            plt.show()
Ejemplo n.º 20
0
def combine_table_fields(fov_header, src, field_indexes):
    """
    Combines a list of Table objects into a single one bounded by the Header WCS

    Parameters
    ----------
    fov_header : fits.Header
        Header from a FieldOfView objects
    src : Source object
    field_indexes : list of int

    Returns
    -------
    tbl : Table

    """

    fov_xsky, fov_ysky = imp_utils.calc_footprint(fov_header)

    x, y, ref, weight = [], [], [], []

    for ii in field_indexes:
        field = src.fields[ii]
        if isinstance(field, Table):
            xcol = utils.quantity_from_table("x", field, u.arcsec)
            ycol = utils.quantity_from_table("y", field, u.arcsec)
            x += list(xcol.to(u.deg).value)
            y += list(ycol.to(u.deg).value)
            ref += list(field["ref"])
            weight += list(field["weight"])

    x = np.array(x)
    y = np.array(y)
    mask = np.array(x < max(fov_xsky)) * np.array(x > min(fov_xsky)) * \
           np.array(y < max(fov_ysky)) * np.array(y > min(fov_ysky))

    x = x[mask]
    y = y[mask]
    ref = np.array(ref)[mask]
    weight = np.array(weight)[mask]

    tbl = Table(names=["x", "y", "ref", "weight"], data=[x, y, ref, weight])
    tbl["x"].unit = u.deg
    tbl["y"].unit = u.deg

    return tbl
Ejemplo n.º 21
0
    def test_works_seamlessly_for_hawki_package(self, capsys):
        cmd = scopesim.UserCommands(use_instrument="HAWKI")
        opt = scopesim.OpticalTrain(cmd)

        # test that the major values have been updated in rc.__currsys__
        assert rc.__currsys__["!TEL.area"].value == approx(52.81, rel=1e-3)
        assert rc.__currsys__["!TEL.etendue"].value == approx(0.5934, rel=1e-3)
        assert rc.__currsys__["!INST.pixel_scale"] == approx(0.106, rel=1e-3)

        # test that OpticalTrain builds properly
        assert isinstance(opt, scopesim.OpticalTrain)

        # test that we have a system throughput
        wave = np.linspace(0.7, 2.5, 181) * u.um
        tc = opt.optics_manager.surfaces_table.throughput
        ec = opt.optics_manager.surfaces_table.emission
        # ..todo:: something super wierd is going on here when running pytest in the top directory
        assert 0.55 < np.max(tc(wave)) < 0.7

        if PLOTS:
            plt.plot(wave, tc(wave))
            plt.show()

        if PLOTS:
            plt.plot(wave, ec(wave))
            plt.show()

        # test that we have the correct number of FOVs for Ks band
        assert len(opt.fov_manager.fovs) == 9

        if PLOTS:
            fovs = opt.fov_manager.fovs
            from scopesim.optics.image_plane_utils import calc_footprint
            plt.subplot(121)
            for fov in fovs:
                x, y = calc_footprint(fov.hdu.header)
                plt.fill(x*3600, y*3600, alpha=0.1, c="b")
                plt.title("Sky plane")
                plt.xlabel("[arcsec]")

            plt.subplot(122)
            for fov in fovs:
                x, y = calc_footprint(fov.hdu.header, "D")
                plt.fill(x, y)
                plt.title("Detector focal plane")
                plt.xlabel("[mm]")

            plt.show()

        # test that the ImagePlane is large enough
        assert opt.image_planes[0].header["NAXIS1"] > 4200
        assert opt.image_planes[0].header["NAXIS2"] > 4200
        assert np.all(opt.image_planes[0].data == 0)

        # test assert there are 4 detectors, each 2048x2048 pixels
        hdu = opt.readout()[0]
        assert len(opt.detector_arrays[0].detectors) == 4
        for detector in opt.detector_arrays[0].detectors:
            assert detector.hdu.header["NAXIS1"] == 2048
            assert detector.hdu.header["NAXIS2"] == 2048

        if PLOTS:
            for i in range(1, 5):
                plt.subplot(2, 2, i)
                plt.imshow(hdu[i].data)
            plt.show()

        dit = rc.__currsys__["!OBS.dit"]
        ndit = rc.__currsys__["!OBS.ndit"]
        assert np.average(hdu[1].data) == approx(ndit * dit * 0.1, abs=0.5)
Ejemplo n.º 22
0
def extract_area_from_imagehdu(imagehdu, fov_volume):
    """
    Extracts the part of a ImageHDU that fits inside the fov_volume

    Parameters
    ----------
    imagehdu : fits.ImageHDU
        The field ImageHDU, either an image of a wavelength [um] cube
    fov_volume : dict
        Contains {"xs": [xmin, xmax], "ys": [ymin, ymax],
                  "waves": [wave_min, wave_max],
                  "xy_unit": "deg" or "mm", "wave_unit": "um"}

    Returns
    -------
    new_imagehdu : fits.ImageHDU

    """
    hdr = imagehdu.header
    new_hdr = {}

    x_hdu, y_hdu = imp_utils.calc_footprint(imagehdu)  # field edges in "deg"
    x_fov, y_fov = fov_volume["xs"], fov_volume["ys"]

    x0s, x1s = max(min(x_hdu), min(x_fov)), min(max(x_hdu), max(x_fov))
    y0s, y1s = max(min(y_hdu), min(y_fov)), min(max(y_hdu), max(y_fov))

    xp, yp = imp_utils.val2pix(hdr, np.array([x0s, x1s]), np.array([y0s, y1s]))
    (x0p, x1p), (y0p, y1p) = np.round(xp).astype(int), np.round(yp).astype(int)
    if x0p == x1p:
        x1p += 1
    if y0p == y1p:
        y1p += 1

    new_hdr = imp_utils.header_from_list_of_xy([x0s, x1s], [y0s, y1s],
                                               pixel_scale=hdr["CDELT1"])

    if hdr["NAXIS"] == 3:

        # Look 0.5*wdel past the fov edges in each direction to catch any
        # slices where the middle wavelength value doesn't fall inside the
        # fov waverange, but up to 50% of the slice is actually inside the
        # fov waverange:
        # E.g. FOV: [1.92, 2.095], HDU bin centres: [1.9, 2.0, 2.1]
        # CDELT3 = 0.1, and HDU bin edges: [1.85, 1.95, 2.05, 2.15]
        # So 1.9 slice needs to be multiplied by 0.3, and 2.1 slice should be
        # multipled by 0.45 to reach the scaled contribution of the edge slices
        # This scaling factor is:
        # f = ((hdu_bin_centre - fov_edge [+/-] 0.5 * cdelt3) % cdelt3) / cdelt3

        hdu_waves = get_cube_waveset(hdr)
        wdel = hdr["CDELT3"]
        wunit = u.Unit(hdr.get("CUNIT3", "AA"))
        fov_waves = utils.quantify(fov_volume["waves"], u.um).to(wunit).value
        mask = ((hdu_waves > fov_waves[0] - 0.5 * wdel) *
                (hdu_waves <= fov_waves[1] + 0.5 * wdel))  # need to go [+/-] half a bin

        # OC [2021-12-14] if fov range is not covered by the source return nothing
        if not np.any(mask):
            print("FOV {} um - {} um: not covered by Source".format(fov_waves[0], fov_waves[1]))
            return None

        i0p, i1p = np.where(mask)[0][0], np.where(mask)[0][-1]
        f0 = (abs(hdu_waves[i0p] - fov_waves[0] + 0.5 * wdel) % wdel) / wdel    # blue edge
        f1 = (abs(hdu_waves[i1p] - fov_waves[1] - 0.5 * wdel) % wdel) / wdel    # red edge
        data = imagehdu.data[i0p:i1p+1, y0p:y1p, x0p:x1p]
        data[0, :, :] *= f0
        if i1p > i0p:
            data[-1, :, :] *= f1

        # w0, w1 : the closest cube wavelengths outside the fov edge wavelengths
        # fov_waves : the fov edge wavelengths
        # f0, f1 : the scaling factors for the blue and red edge cube slices
        #
        # w0, w1 = hdu_waves[i0p], hdu_waves[i1p]
        # print(f"\nw0: {w0}, f0: {f0}, {fov_waves}, f1: {f1}, w1: {w1}")

        new_hdr.update({"NAXIS": 3,
                        "NAXIS3": data.shape[0],
                        "CRVAL3": hdu_waves[i0p],
                        "CRPIX3": 0,
                        "CDELT3": hdr["CDELT3"],
                        "CUNIT3": hdr["CUNIT3"],
                        "CTYPE3": hdr["CTYPE3"],
                        "BUNIT":  hdr["BUNIT"]})

    else:
        data = imagehdu.data[y0p:y1p, x0p:x1p]
        new_hdr["SPEC_REF"] = hdr.get("SPEC_REF")

    new_imagehdu = fits.ImageHDU(data=data)
    new_imagehdu.header.update(new_hdr)

    return new_imagehdu