Example #1
0
def test_skycoord_to_pixel_swapped():

    # Regression test for a bug that caused skycoord_to_pixel and
    # pixel_to_skycoord to not work correctly if the axes were swapped in the
    # WCS.

    # Import astropy.coordinates here to avoid circular imports
    from astropy.coordinates import SkyCoord

    header = get_pkg_data_contents('data/maps/1904-66_TAN.hdr',
                                   encoding='binary')
    wcs = WCS(header)

    wcs_swapped = wcs.sub([WCSSUB_LATITUDE, WCSSUB_LONGITUDE])

    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')

    xp1, yp1 = skycoord_to_pixel(ref, wcs)
    xp2, yp2 = skycoord_to_pixel(ref, wcs_swapped)

    assert_allclose(xp1, xp2)
    assert_allclose(yp1, yp2)

    # WCS is in FK5 so we need to transform back to ICRS
    new1 = pixel_to_skycoord(xp1, yp1, wcs).transform_to('icrs')
    new2 = pixel_to_skycoord(xp1, yp1, wcs_swapped).transform_to('icrs')

    assert_allclose(new1.ra.degree, new2.ra.degree)
    assert_allclose(new1.dec.degree, new2.dec.degree)
Example #2
0
def test_skycoord_to_pixel(mode):

    # Import astropy.coordinates here to avoid circular imports
    from astropy.coordinates import SkyCoord

    header = get_pkg_data_contents('data/maps/1904-66_TAN.hdr',
                                   encoding='binary')
    wcs = WCS(header)

    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')

    xp, yp = skycoord_to_pixel(ref, wcs, mode=mode)

    # WCS is in FK5 so we need to transform back to ICRS
    new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs')

    assert_allclose(new.ra.degree, ref.ra.degree)
    assert_allclose(new.dec.degree, ref.dec.degree)

    # Make sure you can specify a different class using ``cls`` keyword
    class SkyCoord2(SkyCoord):
        pass

    new2 = pixel_to_skycoord(xp, yp, wcs, mode=mode,
                             cls=SkyCoord2).transform_to('icrs')

    assert new2.__class__ is SkyCoord2
    assert_allclose(new2.ra.degree, ref.ra.degree)
    assert_allclose(new2.dec.degree, ref.dec.degree)
Example #3
0
def test_skycoord_to_pixel_swapped():

    # Regression test for a bug that caused skycoord_to_pixel and
    # pixel_to_skycoord to not work correctly if the axes were swapped in the
    # WCS.

    # Import astropy.coordinates here to avoid circular imports
    from astropy.coordinates import SkyCoord

    header = get_pkg_data_contents('maps/1904-66_TAN.hdr', encoding='binary')
    wcs = WCS(header)

    wcs_swapped = wcs.sub([WCSSUB_LATITUDE, WCSSUB_LONGITUDE])

    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')

    xp1, yp1 = skycoord_to_pixel(ref, wcs)
    xp2, yp2 = skycoord_to_pixel(ref, wcs_swapped)

    assert_allclose(xp1, xp2)
    assert_allclose(yp1, yp2)

    # WCS is in FK5 so we need to transform back to ICRS
    new1 = pixel_to_skycoord(xp1, yp1, wcs).transform_to('icrs')
    new2 = pixel_to_skycoord(xp1, yp1, wcs_swapped).transform_to('icrs')

    assert_allclose(new1.ra.degree, new2.ra.degree)
    assert_allclose(new1.dec.degree, new2.dec.degree)
Example #4
0
def test_skycoord_to_pixel(mode):

    # Import astropy.coordinates here to avoid circular imports
    from astropy.coordinates import SkyCoord

    header = get_pkg_data_contents('maps/1904-66_TAN.hdr', encoding='binary')
    wcs = WCS(header)

    ref = SkyCoord(0.1 * u.deg, -89. * u.deg, frame='icrs')

    xp, yp = skycoord_to_pixel(ref, wcs, mode=mode)

    # WCS is in FK5 so we need to transform back to ICRS
    new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs')

    assert_allclose(new.ra.degree, ref.ra.degree)
    assert_allclose(new.dec.degree, ref.dec.degree)

    # Make sure you can specify a different class using ``cls`` keyword
    class SkyCoord2(SkyCoord):
        pass

    new2 = pixel_to_skycoord(xp, yp, wcs, mode=mode,
                             cls=SkyCoord2).transform_to('icrs')

    assert new2.__class__ is SkyCoord2
    assert_allclose(new2.ra.degree, ref.ra.degree)
    assert_allclose(new2.dec.degree, ref.dec.degree)
Example #5
0
def build_plotting_moc(moc, wcs):
    # Get the WCS cdelt giving the deg.px^(-1) resolution.
    cdelt = wcs.wcs.cdelt
    # Convert in rad.px^(-1)
    cdelt = np.abs((2 * np.pi / 360) * cdelt[0])
    # Get the minimum depth such as the resolution of a cell is contained in 1px.
    depth_res = int(np.floor(np.log2(np.sqrt(np.pi / 3) / cdelt)))
    depth_res = max(depth_res, 0)
    # Degrade the moc to that depth for plotting purposes. It is not necessary to plot pixels
    # that we will not see because they are contained in 1px.
    moc_plot = moc
    if moc.max_order > depth_res:
        moc_plot = moc.degrade_to_order(depth_res)

    moc_plot = moc_plot.refine_to_order(min_depth=2)

    # Get the MOC delimiting the FOV polygon
    width_px = int(wcs.wcs.crpix[0] *
                   2.)  # Supposing the wcs is centered in the axis
    heigth_px = int(wcs.wcs.crpix[1] * 2.)

    # Compute the sky coordinate path delimiting the viewport.
    # It consists of a closed polygon of (4 - 1)*4 = 12 vertices
    x_px = np.linspace(0, width_px, 4)
    y_px = np.linspace(0, heigth_px, 4)

    X, Y = np.meshgrid(x_px, y_px)

    X_px = np.append(X[0, :-1], X[:-1, -1])
    X_px = np.append(X_px, X[-1, 1:][::-1])
    X_px = np.append(X_px, X[:-1, 0])

    Y_px = np.append(Y[0, :-1], Y[:-1, -1])
    Y_px = np.append(Y_px, Y[-1, :-1])
    Y_px = np.append(Y_px, Y[1:, 0][::-1])

    # Disable the output of warnings when encoutering NaNs.
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        # Inverse projection from pixel coordinate space to the world coordinate space
        viewport = pixel_to_skycoord(X_px, Y_px, wcs)
        # If one coordinate is a NaN we exit the function and do not go further
        ra_deg, dec_deg = viewport.icrs.ra.deg, viewport.icrs.dec.deg

    if np.isnan(ra_deg).any() or np.isnan(dec_deg).any():
        return moc_plot

    center_x_px, center_y_px = wcs.wcs.crpix[0], wcs.wcs.crpix[1]
    inside = pixel_to_skycoord(center_x_px, center_y_px, wcs)

    # Import MOC here to avoid circular imports
    from ..moc import MOC
    # Create a rough MOC (depth=3 is sufficient) from the viewport
    moc_viewport = MOC.from_polygon_skycoord(viewport, max_depth=3)

    # The moc to plot is the INPUT_MOC & MOC_VIEWPORT. For small FOVs this can reduce
    # a lot the time to draw the MOC along with its borders.
    moc_plot = moc_plot.intersection(moc_viewport)
    return moc_plot
Example #6
0
File: utils.py Project: tboch/mocpy
def build_plotting_moc(moc, wcs):
    # Get the WCS cdelt giving the deg.px^(-1) resolution.
    cdelt = wcs.wcs.cdelt
    # Convert in rad.px^(-1)
    cdelt = np.abs((2*np.pi/360)*cdelt[0])
    # Get the minimum depth such as the resolution of a cell is contained in 1px. 
    depth_res = int(np.floor(np.log2(np.sqrt(np.pi/3)/cdelt)))
    depth_res = max(depth_res, 0)
    # Degrade the moc to that depth for plotting purposes. It is not necessary to plot pixels
    # that we will not see because they are contained in 1px.
    moc_plot = moc
    if moc.max_order > depth_res:
        moc_plot = moc.degrade_to_order(depth_res)

    moc_plot = moc_plot.refine_to_order(min_depth=2)

    # Get the MOC delimiting the FOV polygon
    width_px = int(wcs.wcs.crpix[0]*2.) # Supposing the wcs is centered in the axis
    heigth_px = int(wcs.wcs.crpix[1]*2.)

    # Compute the sky coordinate path delimiting the viewport.
    # It consists of a closed polygon of (4 - 1)*4 = 12 vertices
    x_px = np.linspace(0, width_px, 4)
    y_px = np.linspace(0, heigth_px, 4)

    X, Y = np.meshgrid(x_px, y_px)

    X_px = np.append(X[0, :-1], X[:-1, -1])
    X_px = np.append(X_px, np.flip(X[-1, 1:]))
    X_px = np.append(X_px, X[:-1, 0])

    Y_px = np.append(Y[0, :-1], Y[:-1, -1])
    Y_px = np.append(Y_px, Y[-1, :-1])
    Y_px = np.append(Y_px, np.flip(Y[1:, 0]))

    # Disable the output of warnings when encoutering NaNs.
    warnings.filterwarnings("ignore")
    # Inverse projection from pixel coordinate space to the world coordinate space
    viewport = pixel_to_skycoord(X_px, Y_px, wcs)
    # If one coordinate is a NaN we exit the function and do not go further
    ra_deg, dec_deg = viewport.icrs.ra.deg, viewport.icrs.dec.deg
    warnings.filterwarnings("default")

    if np.isnan(ra_deg).any() or np.isnan(dec_deg).any():
        return moc_plot

    center_x_px, center_y_px = wcs.wcs.crpix[0], wcs.wcs.crpix[1]
    inside = pixel_to_skycoord(center_x_px, center_y_px, wcs)

    # Import MOC here to avoid circular imports
    from ..moc import MOC
    # Create a rough MOC (depth=3 is sufficient) from the viewport
    moc_viewport = MOC.from_polygon_skycoord(viewport, max_depth=3, inside=inside)

    # The moc to plot is the INPUT_MOC & MOC_VIEWPORT. For small FOVs this can reduce
    # a lot the time to draw the MOC along with its borders.
    moc_plot = moc_plot.intersection(moc_viewport)
    return moc_plot
Example #7
0
    def coordinates(self, coord_type='skycoord', origin=0, mode='center'):
        """
        Sky coordinate images.

        Parameters
        ----------
        coord_type : {'pix', 'skycoord', 'galactic'}
            Which type of coordinates to return.
        origin : {0, 1}
            Pixel coordinate origin.
        mode : {'center', 'edges'}
            Return coordinate values at the pixels edges or pixel centers.
        """
        if mode == 'center':
            y, x = np.indices(self.data.shape)
        elif mode == 'edges':
            shape = self.data.shape[0] + 1, self.data.shape[1] + 1
            y, x = np.indices(shape)
            y, x = y - 0.5, x - 0.5
        else:
            raise ValueError('Invalid mode to compute coordinates.')

        if coord_type == 'pix':
            return x, y
        else:
            coordinates = pixel_to_skycoord(x, y, self.wcs, origin)
            if coord_type == 'skycoord':
                return coordinates
            elif coord_type == 'galactic':
                l = coordinates.galactic.l.wrap_at('180d')
                b = coordinates.galactic.b
                return l, b
            else:
                raise ValueError("Not a valid coordinate type. Choose either"
                                 " 'pix' or 'skycoord'.")
def find_skycomponent(im: Image, params={}):
    """ Find components in Image, return SkyComponent, just find the peak for now

    :param im: Image to be searched
    :type Image:
    :returns: SkyComponent
    """
    # TODO: Implement full image fitting of components
    log_parameters(params)
    log.debug("point_source_find: Finding components in Image")

    # Beware: The index sequencing is opposite in wcs and Python!
    locpeak = numpy.array(
        numpy.unravel_index((numpy.abs(im.data)).argmax(), im.data.shape))
    log.debug("point_source_find: Found peak at pixel coordinates %s" %
              str(locpeak))
    w = im.wcs.sub(['longitude', 'latitude'])
    sc = pixel_to_skycoord(locpeak[3], locpeak[2], im.wcs, 0, 'wcs')
    log.debug("point_source_find: Found peak at world coordinates %s" %
              str(sc))
    flux = im.data[:, :, locpeak[2], locpeak[3]]
    log.debug("point_source_find: Flux is %s" % flux)
    # We also need the frequency values
    w = im.wcs.sub(['spectral'])
    frequency = w.wcs_pix2world(range(im.data.shape[0]), 1)
    return create_skycomponent(direction=sc,
                               flux=flux,
                               frequency=frequency,
                               shape='point')
    def test_auto_rotate_systematic(self, angle):

        # This is a test to make sure for a number of angles that the corners
        # of the image are inside the final WCS but the next pixels outwards are
        # not. We test the full 360 range of angles.

        angle = np.radians(angle)
        pc = np.array([[np.cos(angle), -np.sin(angle)],
                       [np.sin(angle), np.cos(angle)]])
        self.wcs.wcs.pc = pc

        wcs, shape = find_optimal_celestial_wcs([(self.array, self.wcs)],
                                                auto_rotate=True)

        ny, nx = self.array.shape

        xp = np.array([0, 0, nx - 1, nx - 1, -1, -1, nx, nx])
        yp = np.array([0, ny - 1, ny - 1, 0, -1, ny, ny, -1])

        c = pixel_to_skycoord(xp, yp, self.wcs, origin=0)
        xp_final, yp_final = skycoord_to_pixel(c, wcs, origin=0)

        ny_final, nx_final = shape

        inside = ((xp_final >= -0.5) & (xp_final <= nx_final - 0.5) &
                  (yp_final >= -0.5) & (yp_final <= ny_final - 0.5))

        assert_equal(inside, [1, 1, 1, 1, 0, 0, 0, 0])
Example #10
0
    def wcs_pixel_to_skycoord(self, xp, yp):
        """
        Convert a set of pixel coordinates into a `~astropy.coordinates.SkyCoord` coordinate.

        Calls `~astropy.wcs.utils.pixel_to_skycoord`, passing ``xp``, ``yp`` to it.

        Parameters
        ----------
        xp, yp : float or `~numpy.ndarray`
            The coordinates to convert.

        Returns
        -------
        coordinates : `~astropy.coordinates.SkyCoord`
            The celestial coordinates.

        Examples
        --------
        >>> from gammapy.image import SkyImage
        >>> image = SkyImage.empty(nxpix=10, nypix=15)
        >>> x, y = [5, 3.4], [8, 11.2]
        >>> image.wcs_pixel_to_skycoord(xp=x, yp=y)
        <SkyCoord (Galactic): (l, b) in deg
            [(359.99, 0.02), (0.022, 0.084)]>
        """
        return pixel_to_skycoord(xp=xp,
                                 yp=yp,
                                 wcs=self.wcs,
                                 origin=_DEFAULT_WCS_ORIGIN,
                                 mode=_DEFAULT_WCS_MODE)
Example #11
0
def generate_pv_line_coordinates(angle, box, wcs, n_points):
    """
    This function generates the PV pixel and sky position given
    the its PA in degrees.
    """
    angle_pvline = np.pi / 180 * (angle + 90)

    def y_pv(xp, m, x0, y0):
        return m * (xp - x0) + y0

    vla4b_sky = SkyCoord(*mf.default_params['vla4b_deg'], unit='deg')
    vla4b_pixel = skycoord_to_pixel(vla4b_sky, wcs)
    #   aframe = vla4b_sky.skyoffset_frame()
    #   vla4b_offset = vla4b_sky.transform_to(aframe)

    x_first, y_first = box[1]
    x_last, y_last = box[0]
    xs_pixel = np.array([x for x in np.linspace(x_first, x_last, n_points)])

    ys_pixel = np.array([
        y_pv(
            x,
            np.tan(angle_pvline),
            vla4b_pixel[0],
            vla4b_pixel[1],
        ) for x in xs_pixel
    ])

    xys_sky_PV = np.array(
        [pixel_to_skycoord(x, y, wcs) for x, y in zip(xs_pixel, ys_pixel)])

    return xys_sky_PV
Example #12
0
def _pixel_to_world(xpos, ypos, wcs):
    """
    Calculate the sky coordinates at the input pixel positions.

    Parameters
    ----------
    xpos, ypos : float or array-like
        The x and y pixel position(s).

    wcs : WCS object or `None`
        A world coordinate system (WCS) transformation that supports the
        `astropy shared interface for WCS
        <https://docs.astropy.org/en/stable/wcs/wcsapi.html>`_ (e.g.
        `astropy.wcs.WCS`, `gwcs.wcs.WCS`).

    Returns
    -------
    skycoord : `~astropy.coordinates.SkyCoord`
        The sky coordinate(s) at the input position(s).
    """

    if wcs is None:
        return None

    try:
        return wcs.pixel_to_world(xpos, ypos)
    except AttributeError:
        if isinstance(wcs, WCS):
            # for Astropy < 3.1 WCS support
            return pixel_to_skycoord(xpos, ypos, wcs, origin=0)
        else:
            raise ValueError('Input wcs does not support the shared WCS '
                             'interface.')
    def test_psf_location_2d(self):

        self.actualSetUp()
        self.componentvis = create_visibility(
            self.lowcore,
            self.times,
            self.frequency,
            channel_bandwidth=self.channel_bandwidth,
            phasecentre=self.phasecentre,
            weight=1.0,
            polarisation_frame=self.vis_pol)
        self.componentvis.data['uvw'][:, 2] = 0.0
        self.componentvis.data['vis'] *= 0.0

        psf2d = create_empty_image_like(self.model)
        psf2d, sumwt = invert_2d(self.componentvis,
                                 psf2d,
                                 dopsf=True,
                                 **self.params)

        export_image_to_fits(
            psf2d,
            '%s/test_imaging_functions_invert_psf_location.fits' % self.dir)

        nchan, npol, ny, nx = psf2d.shape

        assert numpy.abs(psf2d.data[0, 0, ny // 2, nx // 2] - 1.0) < 2e-3
        imagecentre = pixel_to_skycoord(nx // 2 + 1.0,
                                        ny // 2 + 1.0,
                                        wcs=psf2d.wcs,
                                        origin=1)
        assert imagecentre.separation(self.phasecentre).value < 1e-15, \
            "Image phase centre %s not as expected %s" % (imagecentre, self.phasecentre)
Example #14
0
def ellipse_points_calc(x0, y0, sma, eps, pa, n_points, wcs):
    """
    Calculates the points of an ellipse and returns them in pixel and sky
    coordinates. Cannot work with inputs in skycoordinates: it would render the
    wrong pixel, remember that distances in RA depends on the latitud. Use
    pixel coordinates instead, and convert them later.
    """
    def x(theta):
        return sma * np.cos(theta)

    def y(theta):
        return sma * (1 - eps) * np.sin(theta)

    thetas = np.linspace(0, 2 * np.pi, n_points)
    xs = np.array([x(theta) for theta in thetas])
    ys = np.array([y(theta) for theta in thetas])
    rot_coords = [
        main_functions.rot({
            'x': x,
            'y': y,
            'z': 0
        }, 'z', pa) for x, y in zip(xs, ys)
    ]
    xs_rot = [rot_coord['x'] + x0 for rot_coord in rot_coords]
    ys_rot = [rot_coord['y'] + y0 for rot_coord in rot_coords]
    xys_sky = np.array(
        [pixel_to_skycoord(_x, _y, wcs) for _x, _y in zip(xs_rot, ys_rot)])
    xys_pixel = np.array([[x, y] for x, y in zip(xs_rot, ys_rot)])
    return xys_pixel, xys_sky
Example #15
0
def pixel_to_icrs_coords(x, y, wcs):
    """
    Convert pixel coordinates to ICRS Right Ascension and Declination.

    This is merely a convenience function to extract RA and Dec. from a
    `~astropy.coordinates.SkyCoord` instance so they can be put in
    separate columns in a `~astropy.table.Table`.

    Parameters
    ----------
    x : float or array-like
        The x pixel coordinate.

    y : float or array-like
        The y pixel coordinate.

    wcs : `~astropy.wcs.WCS`
        The WCS transformation to use to convert from pixel coordinates
        to ICRS world coordinates.
        `~astropy.table.Table`.

    Returns
    -------
    ra : `~astropy.units.Quantity`
        The ICRS Right Ascension in degrees.

    dec : `~astropy.units.Quantity`
        The ICRS Declination in degrees.
    """

    icrs_coords = pixel_to_skycoord(x, y, wcs).icrs
    icrs_ra = icrs_coords.ra.degree * u.deg
    icrs_dec = icrs_coords.dec.degree * u.deg

    return icrs_ra, icrs_dec
Example #16
0
 def to_sky(self, wcs):
     center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
     _, scale, _ = skycoord_to_pixel_scale_angle(center, wcs)
     inner_radius = self.inner_radius / scale * u.deg
     outer_radius = self.outer_radius / scale * u.deg
     return CircleAnnulusSkyRegion(center, inner_radius, outer_radius,
                                   self.meta, self.visual)
Example #17
0
def arcs2skycoord(arcs_pix, header):
    wcs = WCS(header).celestial
    arcs_sky = {arc: {} for arc in arcs_pix}
    for arc in arcs_pix:
        arcs_sky[arc]['x0'] = pixel_to_skycoord(arcs_pix[arc]['x0'],
                                                arcs_pix[arc]['y0'], wcs).ra
        arcs_sky[arc]['y0'] = pixel_to_skycoord(arcs_pix[arc]['x0'],
                                                arcs_pix[arc]['y0'], wcs).dec
        arcs_sky[arc][
            'width'] = arcs_pix[arc]['width'] * header['CDELT2'] * u.deg
        arcs_sky[arc][
            'height'] = arcs_pix[arc]['height'] * header['CDELT2'] * u.deg
        arcs_sky[arc]['angle'] = arcs_pix[arc]['angle']
        arcs_sky[arc]['theta1'] = arcs_pix[arc]['theta1']
        arcs_sky[arc]['theta2'] = arcs_pix[arc]['theta2']
    return arcs_sky
Example #18
0
    def coordinates(self, coord_type='skycoord', origin=0, mode='center'):
        """
        Sky coordinate images.

        Parameters
        ----------
        coord_type : {'pix', 'skycoord', 'galactic'}
            Which type of coordinates to return.
        origin : {0, 1}
            Pixel coordinate origin.
        mode : {'center', 'edges'}
            Return coordinate values at the pixels edges or pixel centers.
        """
        if mode == 'center':
            y, x = np.indices(self.data.shape)
        elif mode == 'edges':
            shape = self.data.shape[0] + 1, self.data.shape[1] + 1
            y, x = np.indices(shape)
            y, x = y - 0.5, x - 0.5
        else:
            raise ValueError('Invalid mode to compute coordinates.')

        if coord_type == 'pix':
            return x, y
        else:
            coordinates = pixel_to_skycoord(x, y, self.wcs, origin)
            if coord_type == 'skycoord':
                return coordinates
            elif coord_type == 'galactic':
                l = coordinates.galactic.l.wrap_at('180d')
                b = coordinates.galactic.b
                return l, b
            else:
                raise ValueError("Not a valid coordinate type. Choose either"
                                 " 'pix' or 'skycoord'.")
Example #19
0
def interp_band_to_band(img, ref_map, map):

    map_size = map['signal'].shape
    ref_size = ref_map['signal'].shape

    #create a grid of RA/DEC coordinates for image we want to interpolate
    w = world(map['shead'])

    #holder for the x, y pixel coordinates that we want.
    x = np.arange(0, map_size[0])
    y = np.arange(0, map_size[1])
    xvec = np.repeat(x[:, np.newaxis], map_size[1], axis=1)
    yvec = np.repeat(y[np.newaxis, :], map_size[0], axis=0)

    c = pixel_to_skycoord(xvec, yvec, w, origin=0)
    #this is converting the pixel coords to right ascension and declination in fk4
    ra = np.asarray(c.ra.to_string(decimal=True), dtype=float)
    dec = np.asarray(c.dec.to_string(decimal=True), dtype=float)
    # reformat map data and coordinates
    data = np.ravel(img)
    points = np.column_stack((np.ravel(ra), np.ravel(dec)))

    #create a agrid of RA/DEC coordinates that we want to interpolate over
    ref_w = world(ref_map['shead'])
    ref_grid_x, ref_grid_y = np.mgrid[0:ref_size[0], 0:ref_size[1]]
    ref_grid_ra, ref_grid_dec = ref_w.wcs_pix2world(ref_grid_x, ref_grid_y, 0)

    #do the interpolation
    interp_map = griddata(points,
                          data, (ref_grid_ra, ref_grid_dec),
                          method='linear')
    return interp_map
Example #20
0
 def ingest_visibility(self, freq=None, chan_width=None, times=None, reffrequency=None, add_errors=False,
                       block=True):
     if freq is None:
         freq = [1e8]
     if times is None:
         ntimes = 5
         times = numpy.linspace(-numpy.pi / 3.0, numpy.pi / 3.0, ntimes)
     if chan_width is None:
         chan_width = [1e6]
     
     if reffrequency is None:
         reffrequency = [1e8]
     lowcore = create_named_configuration('LOWBD2-CORE')
     frequency = numpy.array([freq])
     channel_bandwidth = numpy.array([chan_width])
     
     phasecentre = SkyCoord(ra=+180.0 * u.deg, dec=-60.0 * u.deg, frame='icrs', equinox='J2000')
     if block:
         vt = create_blockvisibility(lowcore, times, frequency, channel_bandwidth=channel_bandwidth,
                                     weight=1.0, phasecentre=phasecentre,
                                     polarisation_frame=PolarisationFrame("stokesI"))
     else:
         vt = create_visibility(lowcore, times, frequency, channel_bandwidth=channel_bandwidth,
                                weight=1.0, phasecentre=phasecentre,
                                polarisation_frame=PolarisationFrame("stokesI"))
     cellsize = 0.001
     model = create_image_from_visibility(vt, npixel=self.npixel, cellsize=cellsize, npol=1,
                                          frequency=reffrequency, phasecentre=phasecentre,
                                          polarisation_frame=PolarisationFrame("stokesI"))
     flux = numpy.array([[100.0]])
     facets = 4
     
     rpix = model.wcs.wcs.crpix - 1.0
     spacing_pixels = self.npixel // facets
     centers = [-1.5, -0.5, 0.5, 1.5]
     comps = list()
     for iy in centers:
         for ix in centers:
             p = int(round(rpix[0] + ix * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[0]))), \
                 int(round(rpix[1] + iy * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[1])))
             sc = pixel_to_skycoord(p[0], p[1], model.wcs, origin=1)
             comp = create_skycomponent(flux=flux, frequency=frequency, direction=sc,
                                        polarisation_frame=PolarisationFrame("stokesI"))
             comps.append(comp)
     if block:
         predict_skycomponent_blockvisibility(vt, comps)
     else:
         predict_skycomponent_visibility(vt, comps)
     insert_skycomponent(model, comps)
     self.model = copy_image(model)
     self.empty_model = create_empty_image_like(model)
     export_image_to_fits(model, '%s/test_pipeline_bags_model.fits' % self.dir)
     
     if add_errors:
         # These will be the same for all calls
         numpy.random.seed(180555)
         gt = create_gaintable_from_blockvisibility(vt)
         gt = simulate_gaintable(gt, phase_error=1.0, amplitude_error=0.0)
         vt = apply_gaintable(vt, gt)
     return vt
def shift_vis_to_image(vis: Union[Visibility, BlockVisibility], im: Image, tangent: bool = True, inverse: bool = False) \
        -> Union[Visibility, BlockVisibility]:
    """Shift visibility to the FFT phase centre of the image in place

    :param vis: Visibility data
    :param im: Image model used to determine phase centre
    :param tangent: Is the shift purely on the tangent plane True|False
    :param inverse: Do the inverse operation True|False
    :return: visibility with phase shift applied and phasecentre updated

    """
    assert isinstance(vis, Visibility) or isinstance(vis, BlockVisibility), "vis is not a Visibility or " \
                                                                            "BlockVisibility: %r" % vis
    
    nchan, npol, ny, nx = im.data.shape
    
    # Convert the FFT definition of the phase center to world coordinates (1 relative)
    # This is the only place in ARL where the relationship between the image and visibility
    # frames is defined.
    
    image_phasecentre = pixel_to_skycoord(nx // 2 + 1, ny // 2 + 1, im.wcs, origin=1)
    if vis.phasecentre.separation(image_phasecentre).rad > 1e-15:
        if inverse:
            log.debug("shift_vis_from_image: shifting phasecentre from image phase centre %s to visibility phasecentre "
                      "%s" % (image_phasecentre, vis.phasecentre))
        else:
            log.debug("shift_vis_from_image: shifting phasecentre from vis phasecentre %s to image phasecentre %s" %
                      (vis.phasecentre, image_phasecentre))
        vis = phaserotate_visibility(vis, image_phasecentre, tangent=tangent, inverse=inverse)
        vis.phasecentre = im.phasecentre
    
    return vis
Example #22
0
def test_nddata_input():
    data = np.arange(400).reshape((20, 20))
    error = np.sqrt(data)
    mask = np.zeros((20, 20), dtype=bool)
    mask[8:13, 8:13] = True
    unit = 'adu'
    wcs = make_wcs(data.shape)
    try:
        skycoord = wcs.pixel_to_world(10, 10)
    except AttributeError:
        # for Astropy < 3.1
        skycoord = pixel_to_skycoord(10, 10, wcs)

    aper = SkyCircularAperture(skycoord, r=0.7*u.arcsec)

    tbl1 = aperture_photometry(data*u.adu, aper, error=error*u.adu, mask=mask,
                               wcs=wcs)

    uncertainty = StdDevUncertainty(error)
    nddata = NDData(data, uncertainty=uncertainty, mask=mask, wcs=wcs,
                    unit=unit)
    tbl2 = aperture_photometry(nddata, aper)

    for column in tbl1.columns:
        if column == 'sky_center':  # cannot test SkyCoord equality
            continue
        assert_allclose(tbl1[column], tbl2[column])
Example #23
0
 def sky_bbox_ur(self):
     if self.wcs is not None:
         return pixel_to_skycoord(self.xmax.value + 0.5,
                                  self.ymax.value + 0.5,
                                  self.wcs, origin=0)
     else:
         return None
Example #24
0
    def wcs_pixel_to_skycoord(self, xp, yp):
        """
        Convert a set of pixel coordinates into a `~astropy.coordinates.SkyCoord` coordinate.

        Calls `~astropy.wcs.utils.pixel_to_skycoord`, passing ``xp``, ``yp`` to it.

        Parameters
        ----------
        xp, yp : float or `~numpy.ndarray`
            The coordinates to convert.

        Returns
        -------
        coordinates : `~astropy.coordinates.SkyCoord`
            The celestial coordinates.

        Examples
        --------
        >>> from gammapy.image import SkyImage
        >>> image = SkyImage.empty(nxpix=10, nypix=15)
        >>> x, y = [5, 3.4], [8, 11.2]
        >>> image.wcs_pixel_to_skycoord(xp=x, yp=y)
        <SkyCoord (Galactic): (l, b) in deg
            [(359.99, 0.02), (0.022, 0.084)]>
        """
        return pixel_to_skycoord(xp=xp, yp=yp, wcs=self.wcs,
                                 origin=_DEFAULT_WCS_ORIGIN,
                                 mode=_DEFAULT_WCS_MODE)
Example #25
0
    def test_auto_rotate_systematic(self, angle):

        # This is a test to make sure for a number of angles that the corners
        # of the image are inside the final WCS but the next pixels outwards are
        # not. We test the full 360 range of angles.

        angle = np.radians(angle)
        pc = np.array([[np.cos(angle), -np.sin(angle)],
                       [np.sin(angle), np.cos(angle)]])
        self.wcs.wcs.pc = pc

        wcs, shape = find_optimal_celestial_wcs([(self.array, self.wcs)], auto_rotate=True)

        ny, nx = self.array.shape

        xp = np.array([0, 0, nx - 1, nx - 1, -1, -1, nx, nx])
        yp = np.array([0, ny - 1, ny - 1, 0, -1, ny, ny, -1])

        c = pixel_to_skycoord(xp, yp, self.wcs, origin=0)
        xp_final, yp_final = skycoord_to_pixel(c, wcs, origin=0)

        ny_final, nx_final = shape

        inside = ((xp_final >= -0.5) & (xp_final <= nx_final - 0.5) &
                  (yp_final >= -0.5) & (yp_final <= ny_final - 0.5))

        assert_equal(inside, [1, 1, 1, 1, 0, 0, 0, 0])
Example #26
0
 def sky_bbox_ll(self):
     if self.wcs is not None:
         return pixel_to_skycoord(self.xmin.value - 0.5,
                                  self.ymin.value - 0.5,
                                  self.wcs, origin=0)
     else:
         return None
Example #27
0
def do_photometry(hdu, extensions=None, threshold=5, fwhm=2.5):

    if extensions is None:
        extensions = np.arange(1, len(hdu))
    if not isiterable(extensions):
        extensions = (extensions, )

    output = {}
    for ext in extensions:
        header = hdu[ext].header
        data = hdu[ext].data
        image_wcs = WCS(header)

        background = mad_std(data)

        sources = daofind(data, threshold=threshold * background, fwhm=fwhm)
        positions = (sources['xcentroid'], sources['ycentroid'])
        sky_positions = pixel_to_skycoord(*positions, wcs=image_wcs)

        apertures = CircularAperture(positions, r=2.)
        photometry_table = aperture_photometry(data, apertures)
        photometry_table['sky_center'] = sky_positions

        output[str(ext)] = photometry_table

    return output
Example #28
0
 def to_sky(self, wcs):
     center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
     _, scale, _ = skycoord_to_pixel_scale_angle(center, wcs)
     inner_radius = self.inner_radius / scale * u.deg
     outer_radius = self.outer_radius / scale * u.deg
     return CircleAnnulusSkyRegion(center, inner_radius, outer_radius,
                                   self.meta, self.visual)
Example #29
0
 def radec(self, l, m):
     x = self.xpix0 + l / -self.xscale
     y = self.ypix0 + m / self.yscale
     coord = utils.pixel_to_skycoord(xp=x, yp=y, wcs=self.wcs, origin=0, mode='all')
     ra = coord.ra.value
     dec = coord.dec.value
     return ra * DEG, dec * DEG
Example #30
0
def reproj_binning(data, wcs, bin_num):

    map_in_shape = np.shape(data)
    nx_in, ny_in = map_in_shape
    nx_out = math.trunc(nx_in / bin_num)
    ny_out = math.trunc(ny_in / bin_num)
    xs, ys = np.meshgrid(np.arange(nx_out), np.arange(ny_out))
    wcs_out = wcs.deepcopy()
    wcs_out.wcs.crpix = [math.trunc(nx_out / 2), math.trunc(ny_out / 2)]
    wcs_out.wcs.cdelt = wcs.wcs.cdelt * bin_num
    wcs_out.wcs.ctype = ['RA---SIN', 'DEC--SIN']
    coords_out = pixel_to_skycoord(xs, ys, wcs_out)
    coords_out_flat = coords_out.flatten()
    pixel_labels_out = np.arange(xs.size)
    data_binned = np.zeros((nx_out, ny_out)).flatten()
    map_out_shape = (nx_out, ny_out)

    xs_in, ys_in = np.meshgrid(np.arange(nx_in), np.arange(ny_in))
    coords_in = pixel_to_skycoord(xs_in, ys_in, wcs)
    pixel_map_arr = np.full((nx_in, ny_in), np.nan).flatten()

    i_in = 0
    npix_in = coords_in.flatten().size
    dra, ddec = np.zeros(npix_in), np.zeros(npix_in)
    i_out, d2d, d3d = match_coordinates_sky(coords_in.flatten(),
                                            coords_out_flat)
    dra, ddec = (coords_in.flatten()).spherical_offsets_to(
        coords_out_flat[i_out])
    dra = dra.arcsec
    ddec = ddec.arcsec

    good = (-0.5001 <= dra) & (dra < 0.5001) & (-0.5001 <= ddec) & (ddec <
                                                                    0.5001)
    pixel_map_arr[good] = pixel_labels_out[i_out[good]]
    data_labeled = np.stack((data.flatten(), pixel_map_arr), axis=1)
    nan_index = np.where(np.isnan(data_labeled[:, 1]))
    data_labeled = np.delete(data_labeled, nan_index, axis=0)
    data_labeled = data_labeled[np.argsort(data_labeled[:, 1])]
    data_group = np.split(
        data_labeled[:, 0],
        np.cumsum(np.unique(data_labeled[:, 1], return_counts=True)[1])[:-1])
    for i in pixel_labels_out:
        data_binned[i] = np.nanmean(data_group[i])

    data_binned = data_binned.reshape(map_out_shape)

    return wcs_out, data_binned
Example #31
0
    def ingest_visibility(self,
                          freq=1e8,
                          chan_width=1e6,
                          times=None,
                          reffrequency=None,
                          add_errors=False):
        if times is None:
            times = (numpy.pi / 12.0) * numpy.linspace(-3.0, 3.0, 5)

        if reffrequency is None:
            reffrequency = [1e8]
        lowcore = create_named_configuration('LOWBD2-CORE')
        frequency = numpy.array([freq])
        channel_bandwidth = numpy.array([chan_width])

        phasecentre = SkyCoord(ra=+180.0 * u.deg,
                               dec=-60.0 * u.deg,
                               frame='icrs',
                               equinox='J2000')
        vt = create_visibility(lowcore,
                               times,
                               frequency,
                               channel_bandwidth=channel_bandwidth,
                               weight=1.0,
                               phasecentre=phasecentre,
                               polarisation_frame=PolarisationFrame("stokesI"))
        cellsize = 0.001
        model = create_image_from_visibility(
            vt,
            npixel=self.npixel,
            cellsize=cellsize,
            npol=1,
            frequency=reffrequency,
            phasecentre=phasecentre,
            polarisation_frame=PolarisationFrame("stokesI"))
        flux = numpy.array([[100.0]])
        facets = 4

        rpix = model.wcs.wcs.crpix
        spacing_pixels = self.npixel // facets
        centers = [-1.5, -0.5, 0.5, 1.5]
        comps = list()
        for iy in centers:
            for ix in centers:
                p = int(round(rpix[0] + ix * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[0]))), \
                    int(round(rpix[1] + iy * spacing_pixels * numpy.sign(model.wcs.wcs.cdelt[1])))
                sc = pixel_to_skycoord(p[0], p[1], model.wcs, origin=0)
                comp = create_skycomponent(
                    flux=flux,
                    frequency=frequency,
                    direction=sc,
                    polarisation_frame=PolarisationFrame("stokesI"))
                comps.append(comp)
        predict_skycomponent_visibility(vt, comps)
        insert_skycomponent(model, comps)
        self.model = copy_image(model)
        export_image_to_fits(model,
                             '%s/test_bags_model.fits' % (self.results_dir))
        return vt
Example #32
0
 def sky_bbox_ur(self):
     if self.wcs is not None:
         return pixel_to_skycoord(self.xmax.value + 0.5,
                                  self.ymax.value + 0.5,
                                  self.wcs,
                                  origin=0)
     else:
         return None
Example #33
0
 def sky_bbox_ll(self):
     if self.wcs is not None:
         return pixel_to_skycoord(self.xmin.value - 0.5,
                                  self.ymin.value - 0.5,
                                  self.wcs,
                                  origin=0)
     else:
         return None
Example #34
0
    def to_sky(self, wcs, mode='local', tolerance=None):
        if mode != 'local':
            raise NotImplementedError
        if tolerance is not None:
            raise NotImplementedError

        vertices_sky = pixel_to_skycoord(self.vertices.x, self.vertices.y, wcs)
        return PolygonSkyRegion(vertices=vertices_sky)
Example #35
0
 def to_sky(self, wcs):
     # TODO: write a pixel_to_skycoord_scale_angle
     center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
     _, scale, north_angle = skycoord_to_pixel_scale_angle(center, wcs)
     width = Angle(self.width / scale, 'deg')
     height = Angle(self.height / scale, 'deg')
     return RectangleSkyRegion(center, width, height,
                               angle=self.angle - (north_angle - 90 * u.deg),
                               meta=self.meta, visual=self.visual)
Example #36
0
def pixel_to_skycoord(xsrc, ysrc, wcs):
    """Transform pixel coordinates (x, y) to sky coordinates (ra, dec in deg) given a wcs.

    :param float xsrc: x coordinate of the source
    :param float ysrc: y coordinate of the source
    :param wcs: an astropy.wcs.WCS object
    :return: an astropy.coordinates.SkyCoord object.
    """
    return utils.pixel_to_skycoord(xsrc, ysrc, wcs)
Example #37
0
 def to_sky(self, wcs):
     # TODO: write a pixel_to_skycoord_scale_angle
     center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
     _, scale, north_angle = skycoord_to_pixel_scale_angle(center, wcs)
     width = Angle(self.width / scale, 'deg')
     height = Angle(self.height / scale, 'deg')
     return RectangleSkyRegion(center, width, height,
                               angle=self.angle - (north_angle - 90 * u.deg),
                               meta=self.meta, visual=self.visual)
Example #38
0
def pixel_to_skycoord(xsrc, ysrc, wcs):
    """Transform pixel coordinates (x, y) to sky coordinates (ra, dec in deg) given a wcs.

    :param float xsrc: x coordinate of the source
    :param float ysrc: y coordinate of the source
    :param wcs: an astropy.wcs.WCS object
    :return: an astropy.coordinates.SkyCoord object.
    """
    return utils.pixel_to_skycoord(xsrc, ysrc, wcs)
Example #39
0
def one_map(name, header, band):

    if 'CDELT1' in header.keys():
        #calculating the pixsize based off of astrometry parameters.
        pixsize = 3600 * np.mean(
            [abs(header['CDELT1']),
             abs(header['CDELT2'])])
        #if the given astrometry has CDELT values and not a cd matrix create a cd matrix.
        header['cd_1'] = header['CDELT1']
        header['cd_2'] = 0
        header['cd_1'] = 0
        header['cd_2'] = header['CDELT2']

    else:
        #if the astrometry is given with a cd matrix calculate the pixsize this way.
        pixsize = 3600 * \
                  np.mean([abs(header['CD1_1']+  header['CD2_1']), \
                        abs(header['CD2_1'] + header['CD2_2'])])

    #this is to call IRIS code
    ra_c = header['crval1'] * u.deg
    dec_c = header['crval2'] * u.deg
    cent = [ra_c.value, dec_c.value]
    coord = SkyCoord(ra=ra_c, dec=dec_c)
    b1950_coord = coord.transform_to(FK4(equinox='B1950'))
    ra_c_b = float(b1950_coord.ra.to_string(decimal=True))
    dec_c_b = float(b1950_coord.dec.to_string(decimal=True))
    #square patch of sky, this can be changed if desired.
    naxis = [header['naxis1'], header['naxis2']]

    iris_head = make_header(pixsize, naxis, ra_c_b, dec_c_b)
    iris_map = mosaic(iris_head, band=4)

    x = np.arange(0, iris_head['NAXIS1'])
    y = np.arange(0, iris_head['NAXIS2'])
    yvec = np.repeat(x[:, np.newaxis], iris_head['NAXIS2'], axis=1)
    xvec = np.repeat(y[np.newaxis, :], iris_head['NAXIS1'], axis=0)
    w = world(iris_head)
    c = pixel_to_skycoord(xvec, yvec, w, origin=0)
    c = c.transform_to('icrs')

    #this is converting the pixel coords to right ascension and declination in fk4
    ra = np.asarray(c.ra.to_string(decimal=True), dtype=float)
    dec = np.asarray(c.dec.to_string(decimal=True), dtype=float)

    iris_interp, r, d = interp_back_to_ref(iris_map, ra.ravel(), dec.ravel(),
                                           header)

    c = 2.99792458e8  #m/s

    nu = c / clus_get_lambdas(band, center=False)

    planck, ra, dec, avg_T, avg_beta, avg_tau = create_map(header, nu=nu)
    planck_head = save_header(header, avg_beta, avg_T, avg_tau,
                              'Planck_' + band, 'Jy/Beam', cent)
    return planck, iris_interp, avg_T, avg_beta, avg_tau, planck_head
Example #40
0
def pixtosky(self, pixel):
    """
    Given a pixel location returns the skycoord
    """
    hdu = self.sci
    hdr = hdu.header
    wcs, frame = WCS(hdr), hdr['RADESYS'].lower()
    xp, yp = pixel
    sky = pixel_to_skycoord(xp, yp, wcs)
    return sky
Example #41
0
    def to_sky_args(self, wcs):
        center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
        _, scale, north_angle = skycoord_to_pixel_scale_angle(center, wcs)

        inner_width = self.inner_width / scale * u.deg
        inner_height = self.inner_height / scale * u.deg
        outer_width = self.outer_width / scale * u.deg
        outer_height = self.outer_height / scale * u.deg
        angle = self.angle - (north_angle - 90 * u.deg)

        return center, inner_width, inner_height, outer_width, outer_height, angle
def test_scalar_skycoord():
    """
    Regression test to check that scalar SkyCoords are added to the table
    as a length-1 SkyCoord array.
    """

    data = make_4gaussians_image()
    wcs = make_wcs(data.shape)
    skycoord = pixel_to_skycoord(90, 60, wcs)
    aper = SkyCircularAperture(skycoord, r=0.1*u.arcsec)
    tbl = aperture_photometry(data, aper, wcs=wcs)
    assert isinstance(tbl['celestial_center'], SkyCoord)
Example #43
0
    def to_sky_args(self, wcs):

        center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
        _, scale, north_angle = skycoord_to_pixel_scale_angle(center, wcs)

        inner_width = self.inner_width / scale * u.deg
        inner_height = self.inner_height / scale * u.deg
        outer_width = self.outer_width / scale * u.deg
        outer_height = self.outer_height / scale * u.deg
        angle = self.angle - (north_angle - 90 * u.deg)

        return center, inner_width, inner_height, outer_width, outer_height, angle
Example #44
0
    def to_sky(self, wcs, mode='local', tolerance=None):
        if mode != 'local':
            raise NotImplementedError
        if tolerance is not None:
            raise NotImplementedError

        center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
        # TODO: this is just called to compute `scale`
        # This is inefficient ... we should have that as a separate function.
        _, scale, _ = skycoord_to_pixel_scale_angle(center, wcs)

        radius = Angle(self.radius / scale, 'deg')
        return CircleSkyRegion(center, radius)
Example #45
0
 def sky_centroid(self):
     if self.wcs is not None:
         # For a large catalog, it's much faster to calculate world
         # coordinates using the complete list of (x, y) instead of
         # looping through the individual (x, y).  It's also much
         # faster to recalculate the world coordinates than to create a
         # SkyCoord array from a loop-generated SkyCoord list.  The
         # assumption here is that the wcs is the same for each
         # SourceProperties instance.
         return pixel_to_skycoord(self.xcentroid, self.ycentroid,
                                  self.wcs, origin=0)
     else:
         return None
Example #46
0
    def icrs_centroid(self):
        """
        The International Celestial Reference System (ICRS) coordinates
        of the centroid within the source segment, returned as a
        `~astropy.coordinates.SkyCoord` object.
        """

        if self._wcs is not None:
            return pixel_to_skycoord(self.xcentroid.value,
                                     self.ycentroid.value,
                                     self._wcs, origin=1).icrs
        else:
            return None
Example #47
0
    def sky_centroid(self):
        """
        The sky coordinates of the centroid within the source segment,
        returned as a `~astropy.coordinates.SkyCoord` object.

        The output coordinate frame is the same as the input WCS.
        """

        if self._wcs is not None:
            return pixel_to_skycoord(self.xcentroid.value,
                                     self.ycentroid.value,
                                     self._wcs, origin=0)
        else:
            return None
Example #48
0
    def sky_bbox_ur(self):
        """
        The sky coordinates of the upper-right vertex of the minimal
        bounding box of the source segment, returned as a
        `~astropy.coordinates.SkyCoord` object.

        The bounding box encloses all of the source segment pixels in
        their entirety, thus the vertices are at the pixel *corners*.
        """

        if self._wcs is not None:
            return pixel_to_skycoord(self.xmax.value + 0.5,
                                     self.ymax.value + 0.5,
                                     self._wcs, origin=0)
        else:
            return None
Example #49
0
def fill_acceptance_image(header, center, offset, acceptance, offset_max = Angle(2.5,"deg"), interp_kwargs=None):
    """Generate a 2D image of a radial acceptance curve.

    The radial acceptance curve is given as an array of values
    defined at the specified offsets.

    Parameters
    ----------
    header : `~astropy.io.fits.Header`
        Fits header of the reference image
    center : `~astropy.coordinates.SkyCoord`
        Coordinate of the center of the image.
    offset : `~astropy.coordinates.Angle`
        1D array of offset values where acceptance is defined.
    acceptance : `~numpy.ndarray`
        Array of acceptance values.
    interp_kwargs : dict
        option for interpolation for `~scipy.interpolate.interp1d`

    Returns
    -------
    image : `~astropy.io.fits.ImageHDU`
        New image filled with radial acceptance.
    """
    from scipy.interpolate import interp1d
    if offset_max > Angle(offset)[-1]:
        raise ValueError("Offset max used for the acceptance curve ({} deg) is "
                         "inferior to the one you asked to fill the map ({} deg)".format(offset[-1],offset_max.value))
    if not interp_kwargs:
        interp_kwargs = dict(bounds_error=False, fill_value=acceptance[0])

    # initialize WCS to the header of the image
    wcs = WCS(header)
    data = np.zeros((header["NAXIS2"], header["NAXIS1"]))
    image = fits.ImageHDU(data=data, header=header)

    # define grids of pixel coorinates
    xpix_coord_grid, ypix_coord_grid = coordinates(image, world=False)
    # calculate pixel offset from center (in world coordinates)
    coord = pixel_to_skycoord(xpix_coord_grid, ypix_coord_grid, wcs, origin=0)
    pix_off = coord.separation(center)

    model = interp1d(offset, acceptance, kind='cubic', **interp_kwargs)
    image.data += model(pix_off)
    image.data[pix_off >= offset_max] = 0

    return image
Example #50
0
def test_skycoord_to_pixel_distortions(mode):

    # Import astropy.coordinates here to avoid circular imports
    from astropy.coordinates import SkyCoord

    header = get_pkg_data_filename('data/sip.fits')
    wcs = WCS(header)

    ref = SkyCoord(202.50 * u.deg, 47.19 * u.deg, frame='icrs')

    xp, yp = skycoord_to_pixel(ref, wcs, mode=mode)

    # WCS is in FK5 so we need to transform back to ICRS
    new = pixel_to_skycoord(xp, yp, wcs, mode=mode).transform_to('icrs')

    assert_allclose(new.ra.degree, ref.ra.degree)
    assert_allclose(new.dec.degree, ref.dec.degree)
Example #51
0
    def to_sky(self, wcs, frame='galactic'):
        """
        Return a `~gammapy.regions.SkyCircleRegion`.

        Parameters
        ----------
        wcs : `~astropy.wcs.WCS`
            WCS object
        """
        val = pixel_to_skycoord(self.pos[0], self.pos[1], wcs, mode='wcs', origin=1)
        if frame == 'galactic':
            sky_position = val.galactic
        elif frame == 'icrs':
            sky_position = val.icrs

        sky_radius = Angle(self.radius * np.abs(wcs.wcs.cdelt[0]), 'deg')

        return SkyCircleRegion(sky_position, sky_radius)
Example #52
0
    def _to_sky_params(self, wcs, mode='all'):
        """
        Convert the pixel aperture parameters to those for a sky
        aperture.

        Parameters
        ----------
        wcs : `~astropy.wcs.WCS`
            The world coordinate system (WCS) transformation to use.

        mode : {'all', 'wcs'}, optional
            Whether to do the transformation including distortions
            (``'all'``; default) or only including only the core WCS
            transformation (``'wcs'``).

        Returns
        -------
        sky_params : dict
            A dictionary of parameters for an equivalent sky aperture.
        """

        sky_params = {}
        x, y = np.transpose(self.positions)
        sky_params['positions'] = pixel_to_skycoord(x, y, wcs, mode=mode)

        # The aperture object must have a single value for each shape
        # parameter so we must use a single pixel scale for all positions.
        # Here, we define the scale at the WCS CRVAL position.
        crval = SkyCoord([wcs.wcs.crval], frame=wcs_to_celestial_frame(wcs),
                         unit=wcs.wcs.cunit)
        scale, angle = pixel_scale_angle_at_skycoord(crval, wcs)

        params = self._params[:]
        theta_key = 'theta'
        if theta_key in self._params:
            sky_params[theta_key] = (self.theta * u.rad) - angle.to(u.rad)
            params.remove(theta_key)

        param_vals = [getattr(self, param) for param in params]
        for param, param_val in zip(params, param_vals):
            sky_params[param] = (param_val * u.pix * scale).to(u.arcsec)

        return sky_params
Example #53
0
def fill_acceptance_image(image, center, offset, acceptance):
    """Generate a 2D image of a radial acceptance curve.

    The radial acceptance curve is given as an array of values
    defined at the specified offsets.

    Parameters
    ----------
    image : `~astropy.io.fits.ImageHDU`
        Empty image to fill.
    center : `~astropy.coordinates.SkyCoord`
        Coordinate of the center of the image.
    offset : `~astropy.coordinates.Angle`
        1D array of offset values where acceptance is defined.
    acceptance : `~numpy.ndarray`
        Array of acceptance values.

    Returns
    -------
    image : `~astropy.io.fits.ImageHDU`
        Image filled with radial acceptance.
    """
    from scipy.interpolate import interp1d

    # initialize WCS to the header of the image
    wcs = WCS(image.header)

    # define grids of pixel coorinates
    xpix_coord_grid, ypix_coord_grid = coordinates(image, world=False)

    # calculate pixel offset from center (in world coordinates)
    coord = pixel_to_skycoord(xpix_coord_grid, ypix_coord_grid, wcs, origin=0)
    pix_off = coord.separation(center)

    # interpolate
    model = interp1d(offset, acceptance, kind='cubic')
    pix_acc = model(pix_off)

    # fill value in image
    image.data = pix_acc

    return image
Example #54
0
def gcentroid_wcs(im, wcs, guess, **kwargs):
    """Gaussian centroid given sky coordinates.

    Parameters
    ----------
    im : ndarray
        2D image for centroiding.

    wcs : astropy WCS
        World coordinate system object.

    guess : SkyCoord or tuple of Quantity
        Location on which to centroid.

    **kwargs
        Any ``gcentroid`` keyword arguments.


    Returns
    -------
    cyx : ndarray
        Pixel coordinates of the computed center.  The lower-left
        corner of a pixel is -0.5, -0.5.

    c : SkyCoord
        World coordinates of the computed center.

    """

    if isinstance(guess, coords.SkyCoord):
        g = guess
    else:
        g = coords.SkyCoord(*guess)

    gx, gy = np.array(skycoord_to_pixel(g, wcs))

    cyx = gcentroid(im, yx=(gy, gx), **kwargs)
    c = pixel_to_skycoord(cyx[1], cyx[0], wcs)

    return cyx, c
Example #55
0
def find_peaks(data, threshold, box_size=3, footprint=None, mask=None,
               border_width=None, npeaks=np.inf, centroid_func=None,
               subpixel=False, error=None, wcs=None):
    """
    Find local peaks in an image that are above above a specified
    threshold value.

    Peaks are the maxima above the ``threshold`` within a local region.
    The local regions are defined by either the ``box_size`` or
    ``footprint`` parameters.  ``box_size`` defines the local region
    around each pixel as a square box.  ``footprint`` is a boolean array
    where `True` values specify the region shape.

    If multiple pixels within a local region have identical intensities,
    then the coordinates of all such pixels are returned.  Otherwise,
    there will be only one peak pixel per local region.  Thus, the
    defined region effectively imposes a minimum separation between
    peaks unless there are identical peaks within the region.

    If ``centroid_func`` is input, then it will be used to calculate a
    centroid within the defined local region centered on each detected
    peak pixel.  In this case, the centroid will also be returned in the
    output table.

    Parameters
    ----------
    data : array_like
        The 2D array of the image.

    threshold : float or array-like
        The data value or pixel-wise data values to be used for the
        detection threshold.  A 2D ``threshold`` must have the same
        shape as ``data``.  See `detect_threshold` for one way to create
        a ``threshold`` image.

    box_size : scalar or tuple, optional
        The size of the local region to search for peaks at every point
        in ``data``.  If ``box_size`` is a scalar, then the region shape
        will be ``(box_size, box_size)``.  Either ``box_size`` or
        ``footprint`` must be defined.  If they are both defined, then
        ``footprint`` overrides ``box_size``.

    footprint : `~numpy.ndarray` of bools, optional
        A boolean array where `True` values describe the local footprint
        region within which to search for peaks at every point in
        ``data``.  ``box_size=(n, m)`` is equivalent to
        ``footprint=np.ones((n, m))``.  Either ``box_size`` or
        ``footprint`` must be defined.  If they are both defined, then
        ``footprint`` overrides ``box_size``.

    mask : array_like, bool, optional
        A boolean mask with the same shape as ``data``, where a `True`
        value indicates the corresponding element of ``data`` is masked.

    border_width : bool, optional
        The width in pixels to exclude around the border of the
        ``data``.

    npeaks : int, optional
        The maximum number of peaks to return.  When the number of
        detected peaks exceeds ``npeaks``, the peaks with the highest
        peak intensities will be returned.

    centroid_func : callable, optional
        A callable object (e.g. function or class) that is used to
        calculate the centroid of a 2D array.  The ``centroid_func``
        must accept a 2D `~numpy.ndarray`, have a ``mask`` keyword, and
        optionally an ``error`` keyword.  The callable object must
        return a tuple of two 1D `~numpy.ndarray`\\s, representing the x
        and y centroids, respectively.

    subpixel : bool, optional
        .. warning::

            Note the ``subpixel`` keyword is now deprecated (since
            v0.5).  To get the same centroid values, use the
            ``centroid_func`` keyword with the
            `~photutils.centroids.centroid_2dg` function.

            If `True`, then a cutout of the specified ``box_size`` or
            ``footprint`` will be taken centered on each peak and fit
            with a 2D Gaussian (plus a constant).  In this case, the
            fitted local centroid and peak value (the Gaussian amplitude
            plus the background constant) will also be returned in the
            output table.

    error : array_like, optional
        The 2D array of the 1-sigma errors of the input ``data``.
        ``error`` is used only with the ``centroid_func`` keyword or
        when ``subpixel=True`` (deprecated since v0.5).

    wcs : `~astropy.wcs.WCS`
        The WCS transformation to use to convert from pixel to sky
        coordinates.  If `None`, then the sky coordinates will not be
        returned in the output `~astropy.table.Table`.

    Returns
    -------
    output : `~astropy.table.Table`
        A table containing the x and y pixel location of the peaks and
        their values.  If ``centroid_func`` is input, then the table
        will also contain the centroid position.  If ``subpixel=True``
        (deprecated), then the table will also contain the local
        centroid and fitted peak value.  If no peaks are found then an
        empty table is returned.
    """

    from scipy.ndimage import maximum_filter

    data = np.asanyarray(data)

    if np.all(data == data.flat[0]):
        warnings.warn('Input data is constant. No local peaks can be found.',
                      AstropyUserWarning)
        return Table()  # empty table

    if not np.isscalar(threshold):
        threshold = np.asanyarray(threshold)

        if data.shape != threshold.shape:
            raise ValueError('A threshold array must have the same shape as '
                             'the input data.')

    # remove NaN values to avoid runtime warnings
    nan_mask = np.isnan(data)
    if np.any(nan_mask):
        data = np.copy(data)  # ndarray
        data[nan_mask] = np.nanmin(data)

    if footprint is not None:
        data_max = maximum_filter(data, footprint=footprint, mode='constant',
                                  cval=0.0)
    else:
        data_max = maximum_filter(data, size=box_size, mode='constant',
                                  cval=0.0)

    peak_goodmask = (data == data_max)    # good pixels are True

    if mask is not None:
        mask = np.asanyarray(mask)
        if data.shape != mask.shape:
            raise ValueError('data and mask must have the same shape')
        peak_goodmask = np.logical_and(peak_goodmask, ~mask)

    if border_width is not None:
        for i in range(peak_goodmask.ndim):
            peak_goodmask = peak_goodmask.swapaxes(0, i)
            peak_goodmask[:border_width] = False
            peak_goodmask[-border_width:] = False
            peak_goodmask = peak_goodmask.swapaxes(0, i)

    peak_goodmask = np.logical_and(peak_goodmask, (data > threshold))
    y_peaks, x_peaks = peak_goodmask.nonzero()
    peak_values = data[y_peaks, x_peaks]

    nxpeaks = len(x_peaks)
    if nxpeaks > npeaks:
        idx = np.argsort(peak_values)[::-1][:npeaks]
        x_peaks = x_peaks[idx]
        y_peaks = y_peaks[idx]
        peak_values = peak_values[idx]

    if nxpeaks == 0:
        warnings.warn('No local peaks were found.', AstropyUserWarning)
        return Table()  # empty table

    # construct the output Table
    colnames = ['x_peak', 'y_peak', 'peak_value']
    coldata = [x_peaks, y_peaks, peak_values]
    table = Table(coldata, names=colnames)

    if wcs is not None:
        skycoord_peaks = pixel_to_skycoord(x_peaks, y_peaks, wcs, origin=0)
        table.add_column(skycoord_peaks, name='skycoord_peak', index=2)

    if centroid_func is not None and subpixel:
        raise ValueError('centroid_func and subpixel (deprecated) cannot '
                         'both be used.')

    # perform centroiding
    if centroid_func is not None:
        from ..centroids import centroid_sources  # prevents circular import

        if not callable(centroid_func):
            raise ValueError('centroid_func must be a callable object')

        x_centroids, y_centroids = centroid_sources(
            data, x_peaks, y_peaks, box_size=box_size,
            footprint=footprint, error=error, mask=mask,
            centroid_func=centroid_func)

        table['x_centroid'] = x_centroids
        table['y_centroid'] = y_centroids
    elif subpixel:
        warnings.warn('The subpixel keyword is deprecated and will be '
                      'removed in a future version.  The centroid_func '
                      'keyword can be used to calculate centroid positions.',
                      AstropyDeprecationWarning)

        from ..centroids import fit_2dgaussian  # prevents circular import

        x_centroids, y_centroids = [], []
        fit_peak_values = []
        for (y_peak, x_peak) in zip(y_peaks, x_peaks):
            rdata, rmask, rerror, slc = cutout_footprint(
                data, (x_peak, y_peak), box_size=box_size,
                footprint=footprint, mask=mask, error=error)
            gaussian_fit = fit_2dgaussian(rdata, mask=rmask, error=rerror)
            if gaussian_fit is None:
                x_cen, y_cen, fit_peak_value = np.nan, np.nan, np.nan
            else:
                x_cen = slc[1].start + gaussian_fit.x_mean.value
                y_cen = slc[0].start + gaussian_fit.y_mean.value
                fit_peak_value = (gaussian_fit.constant.value +
                                  gaussian_fit.amplitude.value)
            x_centroids.append(x_cen)
            y_centroids.append(y_cen)
            fit_peak_values.append(fit_peak_value)

        table['x_centroid'] = x_centroids
        table['y_centroid'] = y_centroids
        table['fit_peak_value'] = fit_peak_values

    if (centroid_func is not None or subpixel) and wcs is not None:
        skycoord_centroids = pixel_to_skycoord(x_centroids, y_centroids,
                                               wcs, origin=0)
        idx = table.colnames.index('y_centroid')
        table.add_column(skycoord_centroids, name='skycoord_centroid',
                         index=idx+1)

    return table
Example #56
0
def test_fill_acceptance_image():
    # create empty image
    # odd number of pixels needed for having the center in its own pixel
    n_pix_x = 101
    n_pix_y = 101
    bin_size = Angle(0.1, 'deg')
    image = make_empty_image(n_pix_x, n_pix_y, bin_size.degree,
                             xref=0, yref=0, fill=0,
                             proj='CAR', coordsys='GAL',
                             xrefpix=None, yrefpix=None, dtype='float32')

    # define center coordinate of the image in wolrd and pixel coordinates
    lon = image.header['CRVAL1']
    lat = image.header['CRVAL2']

    center = SkyCoord(lon, lat, unit='deg', frame='galactic')

    # initialize WCS to the header of the image
    w = WCS(image.header)

    x_center_pix, y_center_pix = skycoord_to_pixel(center, w, origin=0)

    # define pixel sizes
    # x_pix_size = Angle(abs(image.header['CDELT1']), 'deg')
    # y_pix_size = Angle(abs(image.header['CDELT2']), 'deg')

    # define radial acceptance and offset angles
    # using bin_size for the offset step makes the test comparison easier
    offset = Angle(np.arange(0., 30., bin_size.degree), 'deg')
    sigma = Angle(1.0, 'deg')
    amplitude = 1.
    mean = 0.
    stddev = sigma.radian
    gaus_model = models.Gaussian1D(amplitude, mean, stddev)
    acceptance = gaus_model(offset.radian)

    # fill acceptance in the image
    image = fill_acceptance_image(image.header, center, offset, acceptance)

    # test: check points at the offsets where the acceptance is defined
    # along the x axis

    # define grids of pixel coorinates
    xpix_coord_grid, ypix_coord_grid = coordinates(image, world=False)

    # calculate pixel offset from center (in world coordinates)
    coord = pixel_to_skycoord(xpix_coord_grid, ypix_coord_grid, w, origin=0)
    pix_off = coord.separation(center)

    # x axis defined in the array positions [y_center_pix,:]
    # only interested in semi axis, so [y_center_pix, x_center_pix:]
    ix_min = int(x_center_pix)
    iy = int(y_center_pix)
    pix_off_x_axis = pix_off[iy, ix_min:]
    image.data_x_axis = image.data[iy, ix_min:]

    # cut offset and acceptance arrays to match image size
    # this is only valid if the offset step matches the pixel size
    n = pix_off_x_axis.size
    acceptance_cut = acceptance[0:n]

    # check acceptance of the image:
    np.testing.assert_almost_equal(image.data_x_axis, acceptance_cut, decimal=4)
def test_wcs_based_photometry():
    from astropy.wcs import WCS
    from astropy.wcs.utils import pixel_to_skycoord
    from ..datasets import make_4gaussians_image

    hdu = make_4gaussians_image(hdu=True, wcs=True)
    wcs = WCS(header=hdu.header)

    # hard wired positions in make_4gaussian_image
    pos_orig_pixel = u.Quantity(([160., 25., 150., 90.],
                                 [70., 40., 25., 60.]), unit=u.pixel)

    pos_skycoord = pixel_to_skycoord(pos_orig_pixel[0], pos_orig_pixel[1], wcs)

    pos_skycoord_s = pos_skycoord[2]

    photometry_skycoord_circ = aperture_photometry(
        hdu, SkyCircularAperture(pos_skycoord, 3 * u.deg))
    photometry_skycoord_circ_2 = aperture_photometry(
        hdu, SkyCircularAperture(pos_skycoord, 2 * u.deg))
    photometry_skycoord_circ_s = aperture_photometry(
        hdu, SkyCircularAperture(pos_skycoord_s, 3 * u.deg))

    assert_allclose(photometry_skycoord_circ['aperture_sum'][2],
                    photometry_skycoord_circ_s['aperture_sum'])

    photometry_skycoord_circ_ann = aperture_photometry(
        hdu, SkyCircularAnnulus(pos_skycoord, 2 * u.deg, 3 * u.deg))
    photometry_skycoord_circ_ann_s = aperture_photometry(
        hdu, SkyCircularAnnulus(pos_skycoord_s, 2 * u.deg, 3 * u.deg))

    assert_allclose(photometry_skycoord_circ_ann['aperture_sum'][2],
                    photometry_skycoord_circ_ann_s['aperture_sum'])

    assert_allclose(photometry_skycoord_circ_ann['aperture_sum'],
                    photometry_skycoord_circ['aperture_sum'] -
                    photometry_skycoord_circ_2['aperture_sum'])

    photometry_skycoord_ell = aperture_photometry(
        hdu, SkyEllipticalAperture(pos_skycoord,
                                   3 * u.deg, 3.0001 * u.deg, 45 * u.deg))
    photometry_skycoord_ell_2 = aperture_photometry(
        hdu, SkyEllipticalAperture(pos_skycoord,
                                   2 * u.deg, 2.0001 * u.deg, 45 * u.deg))
    photometry_skycoord_ell_s = aperture_photometry(
        hdu, SkyEllipticalAperture(pos_skycoord_s,
                                   3 * u.deg, 3.0001 * u.deg, 45 * u.deg))
    photometry_skycoord_ell_ann = aperture_photometry(
        hdu, SkyEllipticalAnnulus(pos_skycoord, 2 * u.deg, 3 * u.deg,
                                  3.0001 * u.deg, 45 * u.deg))
    photometry_skycoord_ell_ann_s = aperture_photometry(
        hdu, SkyEllipticalAnnulus(pos_skycoord_s, 2 * u.deg, 3 * u.deg,
                                  3.0001 * u.deg, 45 * u.deg))

    assert_allclose(photometry_skycoord_ell['aperture_sum'][2],
                    photometry_skycoord_ell_s['aperture_sum'])

    assert_allclose(photometry_skycoord_ell_ann['aperture_sum'][2],
                    photometry_skycoord_ell_ann_s['aperture_sum'])

    assert_allclose(photometry_skycoord_ell['aperture_sum'],
                    photometry_skycoord_circ['aperture_sum'], rtol=5e-3)

    assert_allclose(photometry_skycoord_ell_ann['aperture_sum'],
                    photometry_skycoord_ell['aperture_sum'] -
                    photometry_skycoord_ell_2['aperture_sum'], rtol=1e-4)

    photometry_skycoord_rec = aperture_photometry(
        hdu, SkyRectangularAperture(pos_skycoord,
                                    6 * u.deg, 6 * u.deg,
                                    0 * u.deg),
        method='subpixel', subpixels=20)
    photometry_skycoord_rec_4 = aperture_photometry(
        hdu, SkyRectangularAperture(pos_skycoord,
                                    4 * u.deg, 4 * u.deg,
                                    0 * u.deg),
        method='subpixel', subpixels=20)
    photometry_skycoord_rec_s = aperture_photometry(
        hdu, SkyRectangularAperture(pos_skycoord_s,
                                    6 * u.deg, 6 * u.deg,
                                    0 * u.deg),
        method='subpixel', subpixels=20)
    photometry_skycoord_rec_ann = aperture_photometry(
        hdu, SkyRectangularAnnulus(pos_skycoord, 4 * u.deg, 6 * u.deg,
                                   6 * u.deg, 0 * u.deg),
        method='subpixel', subpixels=20)
    photometry_skycoord_rec_ann_s = aperture_photometry(
        hdu, SkyRectangularAnnulus(pos_skycoord_s, 4 * u.deg, 6 * u.deg,
                                   6 * u.deg, 0 * u.deg),
        method='subpixel', subpixels=20)

    assert_allclose(photometry_skycoord_rec['aperture_sum'][2],
                    photometry_skycoord_rec_s['aperture_sum'])

    assert np.all(photometry_skycoord_rec['aperture_sum'] >
                  photometry_skycoord_circ['aperture_sum'])

    assert_allclose(photometry_skycoord_rec_ann['aperture_sum'][2],
                    photometry_skycoord_rec_ann_s['aperture_sum'])

    assert_allclose(photometry_skycoord_rec_ann['aperture_sum'],
                    photometry_skycoord_rec['aperture_sum'] -
                    photometry_skycoord_rec_4['aperture_sum'], rtol=1e-4)
    #pt.savefig("plot/profile_lattitude_avec_CS_bkg_ampl_free_plus_arc_source_fwhmfix_" + str(E1) + "_" + str(E2) + "_TeV.jpg")
    #pt.savefig("plot/profile_lattitude_avec_CS_bkg_ampl_free_plus_central_gauss_" + str(E1) + "_" + str(E2) + "_TeV.jpg")
    #pt.savefig("plot/profile_lattitude_avec_CS_bkg_ampl_free_plus_central_gauss_fwhmfix_" + str(E1) + "_" + str(E2) + "_TeV.jpg")
    #pt.savefig("plot/profile_lattitude_avec_CS_bkg_ampl_free_plus_central_gauss_CSgauss_fwhmfix_" + str(E1) + "_" + str(E2) + "_TeV.jpg")
    #pt.savefig("plot/profile_lattitude_avec_CS_bkg_ampl_free_exposure_"+str(E1)+"_"+str(E2)+"_TeV.jpg")
    # save_resid("residual_avec_CS_method_cstat_neldermead_fwmh_Sgra_etG0p9_fix_"+str(E1)+"_"+str(E2)+"_TeV.fits", clobber=True)
    # save_resid("residual_avec_CS_method_cstat_neldermead_"+str(E1)+"_"+str(E2)+"_TeV.fits", clobber=True)
    # save_resid("residual_sans_CS_method_cstat_neldermead_"+str(E1)+"_"+str(E2)+"_TeV.fits", clobber=True)
    # save_resid("residual_"+str(E1)+"_"+str(E2)+"_TeV.fits", clobber=True)
    # set_full_model(psf_SgrA(mygaus_SgrA+large_gaus*CS)+psf_G0p9(mygaus_G0p9))
    # image_psf()
    # image_model()
    # image_fit()
    # image_resid()
    binsize_carte = np.fabs(data[1].header["CDELT1"])
    x_SgrA, y_SgrA = mygaus_SgrA.xpos.val, mygaus_SgrA.ypos.val
    fwhm_SgrA = mygaus_SgrA.fwhm.val * binsize_carte
    l_SgrA = pixel_to_skycoord(x_SgrA, y_SgrA, on.wcs).l
    b_SgrA = pixel_to_skycoord(x_SgrA, y_SgrA, on.wcs).b

    x_G0p9, y_G0p9 = mygaus_G0p9.xpos.val, mygaus_G0p9.ypos.val
    fwhm_G0p9 = mygaus_G0p9.fwhm.val * binsize_carte
    l_G0p9 = pixel_to_skycoord(x_G0p9, y_G0p9, on.wcs).l
    b_G0p9 = pixel_to_skycoord(x_G0p9, y_G0p9, on.wcs).b

    print("Pour SgrA*, les coord sont (l,b)= (" + str(l_SgrA.value) + "," + str(
        b_SgrA.value) + ") deg et la largeur de la source: " + str(fwhm_SgrA) + " deg")

    print("Pour G0p9, les coord sont (l,b)= (" + str(l_G0p9.value) + "," + str(
        b_G0p9.value) + ") deg et la largeur de la source: " + str(fwhm_G0p9) + " deg")