예제 #1
0
def world2pix(wcs, x_world, y_world):
    if np.isscalar(x_world) and np.isscalar(y_world):
        x_pix, y_pix = wcs.wcs_world2pix(np.array([x_world]), np.array([y_world]), 1)
        return x_pix[0], y_pix[0]
    elif (type(x_world) == list) and (type(y_world) == list):
        x_pix, y_pix = wcs.wcs_world2pix(np.array(x_world), np.array(y_world), 1)
        return x_pix.tolist(), y_pix.tolist()
    elif isinstance(x_world, np.ndarray) and isinstance(y_world, np.ndarray):
        return wcs.wcs_world2pix(x_world, y_world, 1)
    else:
        raise Exception("world2pix should be provided either with two scalars, two lists, or two numpy arrays")
예제 #2
0
파일: utils.py 프로젝트: cdeil/fermipy
def skydir_to_pix(skydir,wcs):
    """Convert skydir object to pixel coordinates."""
    
    if 'RA' in wcs.wcs.ctype[0]:    
        xpix, ypix = wcs.wcs_world2pix(skydir.ra.deg,skydir.dec.deg,0)
    elif 'GLON' in wcs.wcs.ctype[0]:
        xpix, ypix = wcs.wcs_world2pix(skydir.galactic.l.deg,skydir.galactic.b.deg,0)
    else:
        raise Exception('Unrecognized WCS coordinate system.')

    return xpix,ypix
예제 #3
0
def world2pix(wcs, x_world, y_world):
    if np.isscalar(x_world) and np.isscalar(y_world):
        x_pix, y_pix = wcs.wcs_world2pix(np.array([x_world]),
                                         np.array([y_world]), 1)
        return x_pix[0], y_pix[0]
    elif (type(x_world) == list) and (type(y_world) == list):
        x_pix, y_pix = wcs.wcs_world2pix(np.array(x_world), np.array(y_world),
                                         1)
        return x_pix.tolist(), y_pix.tolist()
    elif isinstance(x_world, np.ndarray) and isinstance(y_world, np.ndarray):
        return wcs.wcs_world2pix(x_world, y_world, 1)
    else:
        raise Exception(
            "world2pix should be provided either with two scalars, two lists, or two numpy arrays"
        )
예제 #4
0
파일: wcs.py 프로젝트: arlewis/astrogrid
def fit_cdmatrix(x, y, lon, lat, hdr):
    """Fit a CD matrix for a set of points with known pixel and world
    coordinates.

    The world coordinates are transformed to projection plane coordinates
    for a given projection, and then a 2d least squares fitting method is
    used to determine the best-fit CD matrix that transforms the pixel
    coordinates into projection plane coordinates.

    Parameters
    ----------
    x, y : ndarray
        x and y pixel coordinates.
    lon, lat : ndarray
        Celestial longitude and latitude (world) coordinates.
    hdr : astropy.io.fits.Header
        A FITS header. Required keywords:

        - CTYPE1, CTYPE2
        - CRPIX1, CRPIX2
        - CRVAL1, CRVAL2

    Returns
    -------
    ndarray
        The best-fit CD matrix, ``[[CD1_1, CD1_2], [CD2_1, CD2_2]]``.

    """
    def residuals(p, dx, dy, ip):
        # i represents x or y;
        # xp - (cd11*dx + cd12*dy) and yp - (cd21*dx + cd22*dy)
        cdi1, cdi2 = p
        err = ip - (cdi1*dx + cdi2*dy)
        return err

    # Calculate projection plane coords Converting celestial coordinates
    # into pixel coordinates involves 1) celestial spherical to native
    # spherical, 2) native spherical to projection plane, and 3) projection
    # plane to pixel. Steps 1 and 2 depend on the CTYPEi and CRVALi. Step 3
    # depends on CDi_j and CRPIXi. All are known except CDi_j. By setting
    # the CD matrix to a unity matrix, the `wcs_world2pix` method converts
    # celestial coordinates through step 2 to projection plane coordinates.
    # The CD matrix can then be fit because the coordinates before and
    # after step 3 are known.
    wcs = astropy.wcs.WCS(hdr)
    wcs.wcs.cd = np.array([[1, 0], [0, 1]])
    xp, yp = wcs.wcs_world2pix(lon, lat, 1)
    xp, yp = xp - hdr['CRPIX1'], yp - hdr['CRPIX2']

    # Solve for CD elements
    dx, dy = x - hdr['CRPIX1'], y - hdr['CRPIX2']
    p_init1 = (1, 0)
    p_init2 = (0, 1)
    args1 = (dx.ravel(), dy.ravel(), xp.ravel())
    args2 = (dx.ravel(), dy.ravel(), yp.ravel())
    cd11, cd12 = scipy.optimize.leastsq(residuals, p_init1, args=args1)[0]
    cd21, cd22 = scipy.optimize.leastsq(residuals, p_init2, args=args2)[0]

    return np.array([[cd11, cd12], [cd21, cd22]])
예제 #5
0
파일: wcs.py 프로젝트: jesaerys/astrogrid
def fit_cdmatrix(x, y, lon, lat, hdr):
    """Fit a CD matrix for a set of points with known pixel and world
    coordinates.

    The world coordinates are transformed to projection plane coordinates
    for a given projection, and then a 2d least squares fitting method is
    used to determine the best-fit CD matrix that transforms the pixel
    coordinates into projection plane coordinates.

    Parameters
    ----------
    x, y : ndarray
        x and y pixel coordinates.
    lon, lat : ndarray
        Celestial longitude and latitude (world) coordinates.
    hdr : astropy.io.fits.Header
        A FITS header. Required keywords:

        - CTYPE1, CTYPE2
        - CRPIX1, CRPIX2
        - CRVAL1, CRVAL2

    Returns
    -------
    ndarray
        The best-fit CD matrix, ``[[CD1_1, CD1_2], [CD2_1, CD2_2]]``.

    """
    def residuals(p, dx, dy, ip):
        # i represents x or y;
        # xp - (cd11*dx + cd12*dy) and yp - (cd21*dx + cd22*dy)
        cdi1, cdi2 = p
        err = ip - (cdi1*dx + cdi2*dy)
        return err

    # Calculate projection plane coords Converting celestial coordinates
    # into pixel coordinates involves 1) celestial spherical to native
    # spherical, 2) native spherical to projection plane, and 3) projection
    # plane to pixel. Steps 1 and 2 depend on the CTYPEi and CRVALi. Step 3
    # depends on CDi_j and CRPIXi. All are known except CDi_j. By setting
    # the CD matrix to a unity matrix, the `wcs_world2pix` method converts
    # celestial coordinates through step 2 to projection plane coordinates.
    # The CD matrix can then be fit because the coordinates before and
    # after step 3 are known.
    wcs = astropy.wcs.WCS(hdr)
    wcs.wcs.cd = np.array([[1, 0], [0, 1]])
    xp, yp = wcs.wcs_world2pix(lon, lat, 1)
    xp, yp = xp - hdr['CRPIX1'], yp - hdr['CRPIX2']

    # Solve for CD elements
    dx, dy = x - hdr['CRPIX1'], y - hdr['CRPIX2']
    p_init1 = (1, 0)
    p_init2 = (0, 1)
    args1 = (dx.ravel(), dy.ravel(), xp.ravel())
    args2 = (dx.ravel(), dy.ravel(), yp.ravel())
    cd11, cd12 = scipy.optimize.leastsq(residuals, p_init1, args=args1)[0]
    cd21, cd22 = scipy.optimize.leastsq(residuals, p_init2, args=args2)[0]

    return np.array([[cd11, cd12], [cd21, cd22]])
예제 #6
0
def _wcs_topixel (wcs, world, wcscale, naxis):
    world = np.asarray (world)
    if world.shape != (naxis, ):
        raise ValueError ('world coordinate must be a %d-element vector', naxis)

    world = (world / wcscale)[::-1].reshape ((1, naxis))
    pixel = wcs.wcs_world2pix (world, 0)
    return pixel[0,::-1]
예제 #7
0
파일: astimage.py 프로젝트: vlslv/pwkit
def _wcs_topixel(wcs, world, wcscale, naxis):
    world = np.asarray(world)
    if world.shape != (naxis, ):
        raise ValueError('world coordinate must be a %d-element vector', naxis)

    world = (world / wcscale)[::-1].reshape((1, naxis))
    pixel = wcs.wcs_world2pix(world, 0)
    return pixel[0, ::-1]
예제 #8
0
 def convert_ifuslot_xy_to_new_xy(self, x, y, wcs):
     ''' Fplane functionality required for this '''
     if self.tp_ifuslot is None or not pyhetdex_flag:
         self.log.error('You have not setup the ifuslot projection yet.')
         self.log.error('To do so, call '
                        '"get_ifuslot_projection(ifuslot, imscale')
         return None
     ra, dec = self.tp_ifuslot.wcs.wcs_pix2world(x, y, 1)
     return wcs.wcs_world2pix(ra, dec, 1)
예제 #9
0
파일: ArgusCal.py 프로젝트: low-sky/gbtpipe
def SpatialSpectralMask(integrations,
                        mask=None,
                        wcs=None,
                        off_frac=0.25,
                        floatvalues=False,
                        offpct=50,
                        **kwargs):
    scanshape = integrations.data['DATA'].shape  # Nscans x Nchans
    OffMask = np.array(scanshape, dtype=np.bool)
    freq = ((np.linspace(1, scanshape[1], scanshape[1])[np.newaxis, :] -
             integrations.data['CRPIX1'][:, np.newaxis]) *
            integrations.data['CDELT1'][:, np.newaxis] +
            integrations.data['CRVAL1'][:, np.newaxis])
    x, y, z = wcs.wcs_world2pix(integrations.data['CRVAL2'][:, np.newaxis],
                                integrations.data['CRVAL3'][:, np.newaxis],
                                freq, 0)
    y = np.clip(y, 0, mask.shape[1] - 1)
    x = np.clip(x, 0, mask.shape[2] - 1)
    z = np.clip(z, 0, mask.shape[0] - 1)
    badx = ~np.isfinite(x)
    bady = ~np.isfinite(y)
    badz = ~np.isfinite(z)
    x[badx] = 0
    y[bady] = 0
    z[badz] = 0
    # OffMask = True where OFF the galaxy)
    if floatvalues:
        OffEmission = np.array(mask[z.astype(np.int),
                                    y.astype(np.int),
                                    x.astype(np.int)],
                               dtype=np.float)
        OffMask = OffEmission > 0
        EmScans = np.sum(OffEmission, axis=1)
        BetterScans = (EmScans <= np.percentile(EmScans, offpct))
        OffMask = (BetterScans[:, np.newaxis] * np.ones(
            (1, OffEmission.shape[1]), dtype=np.bool))
        # blank_chans = np.all(OffEmission == 0, axis=0)
        AllOn = np.all(~OffMask, axis=0)
    else:
        OffMask = np.array(mask[z.astype(np.int),
                                y.astype(np.int),
                                x.astype(np.int)],
                           dtype=np.bool)
        OffMask = ~OffMask
        AllOn = np.all(~OffMask, axis=0)

        # mask[x.astype(np.int)[badx], y.astype(np.int)[bady]] = False
    if np.any(AllOn):
        warnings.warn("Some channels always on emission")
        OffMask[:, AllOn] = True
    return (OffMask, 'SpatialSpectralMask')
    return (OffMask, 'SpatialSpectralMask')
예제 #10
0
def xy_th(BSCatalogue, wcs, data, edge=250, hdr=None):
    '''
    Нахождение прямоугольных координат (x, y) на снимке для звёзд каталога без учёта дисторсии.
    '''
    BSCatalogue.add_column(Column(np.zeros(len(BSCatalogue))), name='x')
    BSCatalogue.add_column(Column(np.zeros(len(BSCatalogue))), name='y')
    BSCatalogue.add_column(Column(np.zeros(len(BSCatalogue))), name='ch')
    a, b = len(data[0]), len(data)
    for i in BSCatalogue:
        if hdr is not None:
            xt, yt = wcs.wcs_world2pix(i['ra'], i['dec'], 0)
            obs = ascii.read('BSCatalogue_calibrate.csv',
                             format='csv',
                             fast_reader=False)
            if i['name'] in obs['name']:
                i['x'], i['y'] = xt, yt
            else:
                x, y = real_xy(xt, yt, hdr=hdr)
                i['x'], i['y'], i['ch'] = x, y, 1
        else:
            i['x'], i['y'] = wcs.wcs_world2pix(i['ra'], i['dec'], 0)
    return BSCatalogue
예제 #11
0
def radec_to_xy(wcs, ra_dec):
    '''
    Convert the ra/dec coordinates of a celestial body
    into the x/y coordinates of an image pixel.
    :param wcs: a wcs object, as returned by get_wcs()
    :param ra_dec: an instance of RaDec
    :return: an instance of PixelXL
    '''

    coord = np.array([
        [ra_dec.ra, ra_dec.dec],
    ], np.float_)
    result = wcs.wcs_world2pix(coord, 0)
    return PixelXY(x=result[0][0], y=result[0][1])
    def skyPA(self):
        """
        Finds the North by checking two points plus/minus a small angle from decDeg.
        And East is 90 deg from North.

        Returns North, East in degrees
        """
        raDeg, decDeg = self.raDeg, self.decDeg
        smallAng = 100.0 / 3600.0

        decDeg1 = decDeg + smallAng
        raDeg1 = raDeg + smallAng

        wcs = self.wcs

        x0, y0 = wcs.wcs_world2pix([raDeg], [decDeg], 0)
        x1, y1 = wcs.wcs_world2pix([raDeg], [decDeg1], 0)
        x2, y2 = wcs.wcs_world2pix([raDeg1], [decDeg], 0)

        north = math.degrees(math.atan2(y1 - y0, x1 - x0))
        east = math.degrees(math.atan2(y2 - y0, x2 - x0))

        return north, east
예제 #13
0
 def maskLookup(ra, dec, freq):
     xx, yy, zz = wcs.wcs_world2pix(ra, dec, freq, 0)
     if (0 <= xx[0] < spatial_mask.shape[1]
             and 0 <= yy[0] < spatial_mask.shape[0]):
         emission = spatial_mask[int(yy[0]), int(xx[0])]
     else:
         emission = False
     if emission:
         zz = np.array(nuinterp(freq), dtype=np.int)
         zz[zz < 0] = 0
         zz[zz >= mask.shape[0]] = mask.shape[0] - 1
         return (mask[zz, yy.astype(np.int), xx.astype(np.int)])
     else:
         return (np.zeros_like(freq, dtype=np.bool))
예제 #14
0
def nearest_neighbor_wcs(wcs, img, wcs_new):
    """
    Generate image according to new wcs
    no interpolation is done.
    """
    img_new = zeros([wcs_new.naxis2, wcs_new.naxis1])
    
    for irow, row in enumerate(img_new):
        for icol, pix in enumerate(row):
            ra, dec = wcs_new.wcs_pix2world(icol, irow, 1)
            iicol, iirow = wcs.wcs_world2pix(ra, dec, 1)
            iicol, iirow = int(iicol), int(iirow)
            try:
                img_new[irow, icol] = img[iirow, iicol].copy()
            except IndexError:
                img_new[irow, icol] = -1
    return img_new
예제 #15
0
def radec_to_xy(data, wcs=None, **kwargs):
    """Converts ``(RA, Dec)`` to ``(x, y)`` for a given GFA.

    Creates a mock WCS transformation for a given GFA and converts star RA, Dec
    to x, y on what would be a GFA image. This conversion is not carefully
    done and is not a proper transformation between on-sky coordinates and
    focal coordinates, but should be sufficient for the purposes of the
    simulation.

    Parameters
    ----------
    data : pandas.DataFrame
        A dataframe with the star data. Must contain at least two columns,
        ``ra`` and ``dec``, in degrees.
    wcs : ~astropy.wcs.WCS
        The WCS object to use. If `None`, it calls `.create_gfa_wcs`.
    kwargs : dict
        Arguments to pass to `.create_gfa_wcs`.

    Returns
    -------
    `~pandas.DataFrame`, `~astropy.wcs.WCS`
        The input dataframe with two columns, ``x`` and ``y`` indicating the
        position of the star on the GFA chip, and the `~astropy.wcs.WCS`
        object.

    """

    if len(data) == 0:
        data['x'] = numpy.nan
        data['y'] = numpy.nan
        return data

    if not wcs:
        wcs = create_gfa_wcs(**kwargs)

    # Convert coordinates to x, y
    coords = data[['ra', 'dec']].to_numpy()

    x, y = wcs.wcs_world2pix(coords, 0).T
    data['x'] = x
    data['y'] = y

    return data, wcs
예제 #16
0
def ang2msk(lon, lat):
    maskfiles = sorted(glob.glob(DATADIR + '/W4*_izrgu_finalmask_mosaic.fits'))

    values = np.zeros(len(lon), dtype=int)
    index = np.arange(len(lon), dtype=int)
    warnings.simplefilter('ignore', category=astropy.wcs.FITSFixedWarning)

    idxs = []

    for f in maskfiles:
        logging.debug(f)
        mask = fitsio.read(f)

        wcs = astropy.wcs.WCS(f)

        crval = wcs.wcs.crval
        radius = max(wcs.wcs.cdelt * np.array([wcs._naxis1, wcs._naxis2]))

        xpix, ypix = wcs.wcs_world2pix(lon, lat, 0)

        xedge = np.where(mask[wcs._naxis1 / 2, :] < EDGE)[0]
        yedge = np.where(mask[:, wcs._naxis2 / 2] < EDGE)[0]
        XMIN, XMAX = xedge.min(), xedge.max()
        YMIN, YMAX = yedge.min(), yedge.max()

        sel = (xpix > XMIN) & (xpix < XMAX)
        sel &= (ypix > YMIN) & (ypix < YMAX)

        xpix = xpix[sel].astype(int)
        ypix = ypix[sel].astype(int)
        idx = index[sel]
        idxs.append(idx)

        val = mask[ypix, xpix]
        values[idx] |= val

    # Set objects outside the footprint to EDGE
    idxs = np.hstack(idxs)
    idx = index[~np.in1d(index, idxs)]
    values[idx] = EDGE

    return values
예제 #17
0
def Stars_on_image(BSCatalogue, data_obs, wcs=None, CRIT_m=5.):
    '''
    Фильтр звёзд, проходят только с (x, y) внутри изображения и m меньше заданной в главной части программы.
    Непрошедшие звёзды удаляются из каталога.
    '''
    a, b = len(data_obs[0]), len(data_obs)
    i = 0
    while i < len(BSCatalogue):
        x, y = BSCatalogue[i]['x'], BSCatalogue[i]['y']
        m = BSCatalogue[i]['vmag']
        if math.isnan(x) or math.isnan(y) or (x <= 0 or x >= a) or (y <= 0 or y >= b) or (m > CRIT_m):
            BSCatalogue.remove_row(i)
            i -= 1
        else:
            if wcs is not None and BSCatalogue[i]['ch'] == 1:
                xt, yt = wcs.wcs_world2pix(
                    BSCatalogue[i]['ra'], BSCatalogue[i]['dec'], 0)
                BSCatalogue[i]['x'], BSCatalogue[i]['y'] = xt, yt
        i += 1
    return BSCatalogue
예제 #18
0
        # objidからfitsファイルを特定する情報を取り出す
        params = unwrap_objid(objid)
        run = str(params['run'])
        camcol = str(params['camcol'])
        frame = str(params['frame'])

        # objidの銀河が含まれるfitsファイルを開く
        fits = astropy.io.fits.open('data/fits/fpC-' + run.zfill(6) + '-r' +
                                    camcol + '-' + frame.zfill(4) + '.fit.gz')
        data = fits[0].data
        header = fits[0].header

        # fitsファイルのheaderと銀河のra, decから,
        # 画像内の座標を得る
        wcs = astropy.wcs.WCS(header)
        px, py = wcs.wcs_world2pix(ra_deg, dec_deg, 0)
        px = int(px)
        py = int(py)

        # 得られた座標を中心として画像を切り出し、保存する
        r = 50
        img_galaxy = data[py - r:py + r, px - r:px + r]
        plt.title('RA = {}, Dec = {}'.format(ra_hms, dec_hms))
        plt.imshow(np.log10(img_galaxy.T[::-1, ::-1]),
                   cmap='gray',
                   vmin=3.05,
                   vmax=3.09)

        # 画像上で5秒角に対応する長さの線を描画する
        cd1_2 = header['CD1_2']
        pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S / cd1_2)
예제 #19
0
 def rd2xy(self, wcs, ra, dec):
     """ Transform input sky positions into pixel positions in the WCS provided.
     """
     return wcs.wcs_world2pix(ra, dec, 1)
예제 #20
0
        min_ra, max_ra = numpy.min(cand['sex'][:,0]), numpy.max(cand['sex'][:,0])
        min_dec, max_dec = numpy.min(cand['sex'][:,1]), numpy.max(cand['sex'][:,1])
        cos_dec = numpy.cos(numpy.radians(numpy.max(numpy.fabs(cand['sex'][:,1]))))

        ra_width = margin / 60. / cos_dec
        dec_width = margin / 60.

        corners = [[min_ra - ra_width, min_dec - dec_width],
                   [min_ra - ra_width, max_dec + dec_width],
                   [max_ra + ra_width, min_dec - dec_width],
                   [max_ra + ra_width, max_dec + dec_width],
               ]
        print corners

        corners_xy = wcs.wcs_world2pix(corners, 0)
        corner_min = numpy.floor(numpy.min(corners_xy, axis=0)).astype(numpy.int)
        corner_max = numpy.ceil(numpy.max(corners_xy, axis=0)).astype(numpy.int)

        print wcs
        print corners
        print corners_xy
        print "corner min/max", corner_min, corner_max

        print "\n"*10,name,"\n"*10

        # Now open each of the input files, and extract the sub-image
        for infile in inputlist:
            inhdu = astropy.io.fits.open(infile)
            data = inhdu[0].data.T
    else:
        rad = float(0.5 * 16.6 + (1.27 * z))
        chandra_r.append(rad)

wcs = wcs.WCS(naxis=2)
wcs.wcs.crpix = [25921, 25921]  # sky (x,y) pixel coordinate referece pixel
wcs.wcs.cdelt = np.array([-1.38888889e-05, 1.38888889e-05])  # pixel size 0.05"
wcs.wcs.crval = [float(cra), float(cdec)]  # (ra,dec) value at reference pixel
wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN']
num = len(chandra_ra)
x = np.zeros((num))
y = np.zeros((num))
r = np.zeros((num))
for i in range(0, num):
    skycoord = np.array([[chandra_ra[i], chandra_dec[i]]])
    pixcoord = wcs.wcs_world2pix(skycoord, 1)
    radius = chandra_r[i] / 0.05
    x[i] = pixcoord[0][0]
    y[i] = pixcoord[0][1]
    r[i] = radius
# print "circle(",pixcoord[0][0],",",pixcoord[0][1],",",radius,")"

data2 = np.recarray((num, ),
                    dtype=(numpy.record, [('TYPE', 'S16'), ('X', '>f4', (4, )),
                                          ('Y', '>f4', (4, )),
                                          ('R', '>f4', (4, )),
                                          ('FLUX', '>f4', (1, )),
                                          ('ROTANG', '>f4', (4, ))]))
for i in range(0, num):
    #if chandra_type[i] == 'GALAXY':
    data2[i][0] = chandra_type[i]
예제 #22
0
파일: main.py 프로젝트: bonu-kun/cnn_galaxy
def main():
    gz_table = Table.read('GalaxyZoo1_DR_table2.fits')

    # Galaxy Zooの表の上から 1000行目までを順に取り出す
    for galaxy_info in gz_table[:1000]:

        # Galaxy Zooの表からobjid, ra, decを取り出す
        objid = galaxy_info[0]
        ra_hms = galaxy_info[1]
        dec_hms = galaxy_info[2]

        # ra,decを60進数から10進数に変換
        c = SkyCoord(ra_hms + ' ' + dec_hms, unit=(u.hourangle, u.deg))
        ra_deg = c.ra.degree
        dec_deg = c.dec.degree

        # objidからfitsファイルを特定する情報を取り出す
        params = unwrap_objid(objid)
        run = str(params['run'])
        camcol = str(params['camcol'])
        frame = str(params['frame'])

        # objidの銀河が含まれるfitsファイルを開く
        fits = astropy.io.fits.open('../' + run.zfill(6) + '/fpC-' +
                                    run.zfill(6) + '-r' + camcol + '-' +
                                    frame.zfill(4) + '.fit.gz')
        data = fits[0].data
        header = fits[0].header

        # fitsファイルのheaderと銀河のra, decから,
        # 画像内の座標を得る
        wcs = astropy.wcs.WCS(header)
        px, py = wcs.wcs_world2pix(ra_deg, dec_deg, 0, ra_dec_order=True)
        px = int(px)
        py = int(py)

        # 得られた座標を中心として画像を切り出し、保存する
        r = 30
        img_galaxy = data[py - r:py + r, px - r:px + r]
        plt.title('RA = {}, Dec = {}'.format(ra_hms, dec_hms))
        plt.imshow(np.log10(img_galaxy.T[::-1, ::-1]),
                   cmap='gray',
                   vmin=3.05,
                   vmax=3.09)

        # 画像上で5秒角に対応する長さの線を描画する
        if header['CTYPE1'] == 'DEC--TAN':
            pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S /
                                            header['cd1_1'])
        else:
            pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S /
                                            header['cd1_2'])

        # cd1_2 = abs(header['CD1_2'])
        # pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S / cd1_2)

        plt.hlines(y=17, xmin=10, xmax=10 + pix_corresponding_to_5s)
        plt.savefig('data/img/' + str(objid), bbox_inches='tight')
        plt.close()

        # 画像をnpyで保存する
        np.save('data/npz/' + str(objid), img_galaxy)

        # 画像とGalaxy Zooのデータをnpzで保存する
        #np.savez('data/npz/' + str(objid), img_galaxy, galaxy_info)
        # img = Image.fromarray(np.uint8(fits[0].data[py-r:py+r, px-r:px+r]))

    csv_obj.close()
예제 #23
0
        cutouts[freq] = {}
        mpfits[freq] = {}
        gpars[freq] = {}
        gparerrs[freq] = {}
        gfits[freq] = {}
        reg_centers[freq] = {}
    
    data = fits.getdata(fn).squeeze()
    header = flatten_header(fits.getheader(fn))
    wcs = astropy.wcs.WCS(header).sub([astropy.wcs.WCSSUB_CELESTIAL])
    beam = radio_beam.Beam.from_fits_header(header)
    beams[freq] = beam
    frequencies[freq] = header.get('CRVAL3') or header.get('ACRVAL3')

    if wcs.wcs.radesys == 'FK4' or wcs.wcs.equinox == 1950:
        (blx,bly),(tr_x,tr_y) = wcs.wcs_world2pix([(290.35090,14.42627),(290.34560,14.43126),],0)
    else:
        (blx,bly),(tr_x,tr_y) = wcs.wcs_world2pix([(290.92445,14.524376),(290.91912,14.529338)],0)
    error[freq] = data[bly:tr_y,blx:tr_x].std()
    obsdate[freq] = fits.getheader(fn)['DATE-OBS']
    print("file: {0}".format(fn))

    for reg in ProgressBar(reglist):

        name = reg.attr[1]['text']
        if name in peaks[freq]:
            continue

        if reg.name == 'circle':
            ra,dec,rad = reg.coord_list
        elif reg.name == 'point':
예제 #24
0
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 28 21:03:38 2020
https://qiita.com/nishimuraatsushi/items/f422c624027dcd34b820
@author: PC
"""

import astropy.wcs
import astropy.io.fits

fits = astropy.io.fits.open(
    'http://www.astro.s.osakafu-u.ac.jp/~nishimura/Orion/data/Orion.CO1221.Osaka.beam204.mom0.fits.gz'
)

wcs = astropy.wcs.WCS(fits[0].header)
print(wcs)

# WCS[geg]→画像座標系[pix]変換
print(wcs.wcs_world2pix([[215, -13.0]], 0))
print(wcs.wcs_world2pix([[214, -13.2]], 0))
print(wcs.wcs_world2pix([[213, -13.4]], 0))
print(wcs.wcs_world2pix([[212, -13.6]], 0))
print(wcs.wcs_world2pix([[211, -13.8]], 0))
print(wcs.wcs_world2pix([[210, -14.0]], 0))
print(wcs.wcs_world2pix([[209, -14.2]], 0))
print(wcs.wcs_world2pix([[208, -14.4]], 0))
print(wcs.wcs_world2pix([[207, -14.6]], 0))
예제 #25
0
def cut_fits_downloaded(filename, xc, yc, xw=1, yw=1, units='pixels', outfile=None, clobber=True, useMontage=False, coordsys='celestial', verbose=False):
    """
    credit: http://code.google.com/p/agpy/source/browse/trunk/agpy/cutout.py
    changed by Hongquan on 25 May 2015: move the imports into the defination part
    Generate a cutout image from a .fits file
    Inputs:
        file  - .fits filename or pyfits HDUList (must be 2D)
        xc,yc - x and y coordinates in the fits files' coordinate system (CTYPE)
        xw,yw - x and y width (pixels or wcs); xw and yw is half width of the output file
        units - specify units to use: either pixels or wcs
        outfile - optional output file
    """     
    try:
        import astropy.io.fits as pyfits
        import astropy.wcs as pywcs
    except ImportError:
        import pyfits
        import pywcs
    import numpy
    try:
        import coords
    except ImportError:
        pass # maybe should do something smarter here, but I want agpy to install...
    try:
        import montage_wrapper as montage
        import os
        CanUseMontage=True
    except ImportError:
        CanUseMontage=False

    class DimensionError(ValueError):
        pass

    if isinstance(filename,str):
        file = pyfits.open(filename)
        opened=True
    elif isinstance(filename,pyfits.HDUList):
        file = filename
        opened=False
    else:
        raise Exception("cutout: Input file is wrong type (string or HDUList are acceptable).")

    head = file[0].header.copy()

    if head['NAXIS'] > 2:
        raise DimensionError("Too many (%i) dimensions!" % head['NAXIS'])
    cd1 = head.get('CDELT1') if head.get('CDELT1') else head.get('CD1_1')
    cd2 = head.get('CDELT2') if head.get('CDELT2') else head.get('CD2_2')
    if cd1 is None or cd2 is None:
        raise Exception("Missing CD or CDELT keywords in header")
    wcs = pywcs.WCS(head)

    if units == 'wcs':
        if coordsys=='celestial' and wcs.wcs.lngtyp=='GLON':
            xc,yc = coords.Position((xc,yc),system=coordsys).galactic()
        elif coordsys=='galactic' and wcs.wcs.lngtyp=='RA':
            xc,yc = coords.Position((xc,yc),system=coordsys).j2000()

    if useMontage and CanUseMontage:
        head['CRVAL1'] = xc
        head['CRVAL2'] = yc
        if units == 'pixels':
            head['CRPIX1'] = xw
            head['CRPIX2'] = yw
            head['NAXIS1'] = int(xw*2)
            head['NAXIS2'] = int(yw*2)
        elif units == 'wcs':
            
            cdelt = numpy.sqrt(cd1**2+cd2**2)
            head['CRPIX1'] = xw   / cdelt
            head['CRPIX2'] = yw   / cdelt
            head['NAXIS1'] = int(xw*2 / cdelt)
            head['NAXIS2'] = int(yw*2 / cdelt)

        head.toTxtFile('temp_montage.hdr',clobber=True)
        newfile = montage.wrappers.reproject_hdu(file[0],header='temp_montage.hdr',exact_size=True)
        os.remove('temp_montage.hdr')
    else:

        xx,yy = wcs.wcs_world2pix(xc,yc,0)

        if units=='pixels':
            xmin,xmax = numpy.max([0,xx-xw]),numpy.min([head['NAXIS1'],xx+xw])
            ymin,ymax = numpy.max([0,yy-yw]),numpy.min([head['NAXIS2'],yy+yw])
        elif units=='wcs':
            xmin,xmax = numpy.max([0,xx-xw/numpy.abs(cd1)]),numpy.min([head['NAXIS1'],xx+xw/numpy.abs(cd1)])
            ymin,ymax = numpy.max([0,yy-yw/numpy.abs(cd2)]),numpy.min([head['NAXIS2'],yy+yw/numpy.abs(cd2)])
        else:
            raise Exception("Can't use units %s." % units)

        if xmax < 0 or ymax < 0:
            raise ValueError("Max Coordinate is outside of map: %f,%f." % (xmax,ymax))
        if ymin >= head.get('NAXIS2') or xmin >= head.get('NAXIS1'):
            raise ValueError("Min Coordinate is outside of map: %f,%f." % (xmin,ymin))

        head['CRPIX1']-=xmin
        head['CRPIX2']-=ymin
        head['NAXIS1']=int(xmax-xmin)
        head['NAXIS2']=int(ymax-ymin)

        if head.get('NAXIS1') == 0 or head.get('NAXIS2') == 0:
            raise ValueError("Map has a 0 dimension: %i,%i." % (head.get('NAXIS1'),head.get('NAXIS2')))

        img = file[0].data[ymin:ymax,xmin:xmax]
        newfile = pyfits.PrimaryHDU(data=img,header=head)
        if verbose: print("Cut image %s with dims %s to %s.  xrange: %f:%f, yrange: %f:%f" % (filename, file[0].data.shape,img.shape,xmin,xmax,ymin,ymax))

    if isinstance(outfile,str):
        newfile.writeto(outfile,clobber=clobber)

    if opened:
        file.close()

    return newfile
예제 #26
0
def convertCoords(coords, mode='sky', wcs=None, xyorig='center', shape=None):
    """Converts input coordinates to array indices.

    Converts input positions in x, y or RA, Dec coordinates to array indices
    (in Numpy style) or spaxel extraction. In case of pixel coordinates, the
    origin of reference (either the center of the cube or the lower left
    corner) can be specified via ``xyorig``.

    If ``shape`` is defined (mandatory for ``mode='pix'``, optional for
    ``mode='sky'``) and one or more of the resulting indices are outside the
    size of the input shape, an error is raised.

    This functions is mostly intended for internal use.

    Parameters:
        coords (array):
            The input coordinates, as an array of shape Nx2.
        mode ({'sky', 'pix'}:
            The type of input coordinates, either `'sky'` for celestial
            coordinates (in the format defined in the WCS header information),
            or `'pix'` for pixel coordinates.
        wcs (None or ``astropy.wcs.WCS`` object):
            If ``mode='sky'``, the WCS solution from which the cube coordinates
            can be derived.
        xyorig (str):
            If ``mode='pix'``, the reference point from which the coordinates
            are measured. Valid values are ``'center'``, for the centre of the
            spatial dimensions of the cube, or ``'lower'`` for the lower-left
            corner.
        shape (None or array):
            If ``mode='pix'``, the shape of the spatial dimensions of the cube,
            so that the central position can be calculated.

    Returns:
        result (Numpy array):
            An array with the same shape as ``coords``, containing the cube
            index positions for the input coordinates, in Numpy style (i.e.,
            the first element being the row and the second the column).

    """

    coords = np.atleast_2d(coords)
    assert coords.shape[1] == 2, 'coordinates must be an array Nx2'

    if mode == 'sky':
        assert wcs, 'if mode==sky, wcs must be defined.'
        coordsSpec = np.ones((coords.shape[0], 3), np.float32)
        coordsSpec[:, :-1] = coords
        cubeCoords = wcs.wcs_world2pix(coordsSpec, 0)
        cubeCoords = np.fliplr(np.array(np.round(cubeCoords[:, :-1]), np.int))

    elif mode in ['pix', 'pixel']:
        assert xyorig, 'if mode==pix, xyorig must be defined.'
        x = coords[:, 0]
        y = coords[:, 1]

        assert shape, 'if mode==pix, shape must be defined.'
        shape = np.atleast_1d(shape)

        if xyorig == 'center':
            yMid, xMid = shape / 2.
            xCube = np.round(xMid + x)
            yCube = np.round(yMid + y)
        elif xyorig == 'lower':
            xCube = np.round(x)
            yCube = np.round(y)
        else:
            raise ValueError('xyorig must be center or lower.')

        cubeCoords = np.array([yCube, xCube], np.int).T

    else:
        raise ValueError('mode must be pix or sky.')

    if shape is not None:
        if ((cubeCoords < 0).any() or (cubeCoords[:, 0] >
                                       (shape[0] - 1)).any()
                or (cubeCoords[:, 1] > (shape[1] - 1)).any()):
            raise MarvinError('some indices are out of limits.'
                              '``xyorig`` is currently set to "{0}". '
                              'Try setting ``xyorig`` to "{1}".'.format(
                                  xyorig,
                                  'center' if xyorig is 'lower' else 'lower'))

    return cubeCoords
예제 #27
0
    def app_phot(self, imagefile, ras, decs, fwhm, plot=False, save=False):
        '''
        Computes the aperture photometry on the image, for the coordinates given.
        
        Parameters
        ----------
        imagefile : str
            The name of the fits file with the image.
        ras : array
            Array of floats with the RA positions for which aperture photometry is needed.
        decs : array
            Array of floats with the DEC positions for which aperture photometry is needed.
        fwhm : float
            Average FWHM of the field used to compute the aperture.
        plot : boolean
            Shall the apertures be plotted in the plot directory?
        save : boolean
            Save the aperture measurement to a file.

        Returns
        -------
        
        phot : QTable
            A table of the photometry with the following columns:
    
            'id': The source ID.
            'xcenter', 'ycenter': The x and y pixel coordinates of the input aperture center(s).
            'celestial_center': 
             'aperture_sum': The sum of the values within the aperture.
             'aperture_sum_err': The corresponding uncertainty in the 'aperture_sum' values. Returned only if the input error is not None.

        '''
        data = fits.open(imagefile)[self.ext].data
        filt = fitsutils.get_par(imagefile, 'FILTER', self.ext)
        mjd = Time(fitsutils.get_par(imagefile, "DATE-OBS", ext=self.ext)).mjd
        zp = fitsutils.get_par(imagefile, 'ZP', self.ext)
        color = fitsutils.get_par(imagefile, 'COLOR', self.ext)
        kcoef = fitsutils.get_par(imagefile, 'KCOEF', self.ext)
        zperr = fitsutils.get_par(imagefile, 'ZPERR', self.ext)
        if zp is None:
            zp = 0
        if zperr is None:
            zperr = 0

        wcs = astropy.wcs.WCS(fits.open(imagefile)[self.ext].header)
        
        positions = SkyCoord(ras*u.deg, decs*u.deg, frame='icrs')
        
        # Set aperture radius to three times the fwhm radius
        aperture_rad = np.median(fwhm)*2* u.arcsec    
        aperture = SkyCircularAperture(positions, r=aperture_rad)
        
        annulus_apertures = SkyCircularAnnulus(positions, r_in=aperture_rad*2, r_out=aperture_rad*4)
    
        #Convert to pixels
        pix_aperture = aperture.to_pixel(wcs)
        pix_annulus = annulus_apertures.to_pixel(wcs)
        pix_annulus_masks = pix_annulus.to_mask(method='center')
        
        #Plot apertures
        from astropy.visualization import simple_norm
        
        try:
            if np.ndim(ras) == 0:
                c = wcs.wcs_world2pix(np.array([[ras, decs]]), 0)                
            else:
                c = wcs.wcs_world2pix(np.array([ras, decs]).T, 0)
        except ValueError:
            self.logger.error('The vectors of RAs, DECs could not be converted into pixels using the WCS!')
            self.logger.error(str(np.array([ras, decs]).T))
    
        if plot:
            x = c[:,0]
            y = c[:,1]
            
            plt.figure(figsize=(10,10))
            norm = simple_norm(data, 'sqrt', percent=99)
            plt.imshow(data, norm=norm)
            pix_aperture.plot(color='white', lw=2)
            pix_annulus.plot(color='red', lw=2)
            plt.xlim(x[0]-200, x[0]+200)
            plt.ylim(y[0]-200, y[0]+200)
            plt.title('Apertures for filter %s'%filt)
            plt.savefig(os.path.join(self._plotpath, "apertures_cutout_%s.png"%os.path.basename(imagefile)))
            plt.clf()
        
        #Divide each pixel in 5 subpixels to make apertures
        apers = [pix_aperture, pix_annulus]
        phot_table = aperture_photometry(data, apers, method='subpixel', subpixels=5)
        for col in phot_table.colnames:
            phot_table[col].info.format = '%.8g'  # for consistent table output
        
    
        bkg_median = []
        std_counts = []
        for mask in pix_annulus_masks:
            annulus_data = mask.multiply(data)
            annulus_data_1d = annulus_data[mask.data > 0]
            _, median_sigclip, stdv_clip = sigma_clipped_stats(annulus_data_1d)
            bkg_median.append(median_sigclip)
            std_counts.append(stdv_clip)
            
        bkg_median = np.array(bkg_median)
        std_counts = np.array(std_counts)
        
        phot = aperture_photometry(data, pix_aperture)
        phot['annulus_median'] = bkg_median
        phot['annulus_std'] = std_counts
        phot['aper_bkg'] = bkg_median * pix_aperture.area()
        phot['aper_sum_bkgsub'] = phot['aperture_sum'] - phot['aper_bkg']
    
    
        # Flux = Gain * Counts / Exptime.
        exptime = fitsutils.get_par(imagefile, 'EXPTIME', self.ext)
        gain = fitsutils.get_par(imagefile, self.gain_keyword, self.ext)
        
        flux =  gain * phot['aper_sum_bkgsub'] / exptime
        inst_mag = -2.5*np.log10(flux)
    
        phot['flux'] = flux
        phot['inst_mag'] = inst_mag
        
        #Noise is the poisson noise of the source plus the background noise for the extracted area
        err = np.sqrt (flux + pix_aperture.area() * std_counts**2)
    
        #Transform pixels to magnitudes
        flux2 = gain * (phot['aper_sum_bkgsub']+err) / exptime
        inst_mag2 = -2.5*np.log10(flux2)
        
        errmag = np.abs(inst_mag2 - inst_mag)
        
        phot['err_counts'] = err
        phot['err_mag'] = errmag
        
        for col in phot.colnames:
            phot[col].info.format = '%.8g'  # for consistent table output
        
        if save:
            appfile = os.path.join(self._photpath, fitsutils.get_par(imagefile, "OBJECT", self.ext)+".app.phot.txt")
            self.logger.info('Creating aperture photometry out file as %s'%appfile)
            #Save the photometry into a file
            if (not os.path.isfile(appfile)):
                with open(appfile, 'w') as f:
                    f.write("mjd filter instr_mag zp zperr color kcoef mag magerr\n")
            
    
            with open(appfile, 'a') as f:
                self.logger.info('Adding aperture photometry to file %s'%appfile)

                f.write("%.3f %s %.4f %.4f %.4f %s %.4f %.4f %.4f\n"%(mjd, filt, phot['inst_mag'].data[0], \
                    zp, zperr, color, kcoef, phot['inst_mag'].data[0]+ zp, phot['err_mag'].data[0]))


        return phot
예제 #28
0
def main():
    gz_table = Table.read('GalaxyZoo1_DR_table2.fits')

    # Galaxy Zooの表の上から i行目までを順に取り出す
    for galaxy_info in tqdm(gz_table[:15000]):

        # Galaxy Zooの表からobjid, ra, decを取り出す
        objid = galaxy_info[0]
        ra_hms = galaxy_info[1]
        dec_hms = galaxy_info[2]

        # ra,decを60進数から10進数に変換
        c = SkyCoord(ra_hms + ' ' + dec_hms, unit=(u.hourangle, u.deg))
        ra_deg = c.ra.degree
        dec_deg = c.dec.degree

        # objidからfitsファイルを特定する情報を取り出す
        params = unwrap_objid(objid)
        run = str(params['run'])
        camcol = str(params['camcol'])
        frame = str(params['frame'])

        # objidの銀河が含まれるfitsファイルを開く
        fits = astropy.io.fits.open('/home/homma/hdd/hdd2/data_set/r_bands/data_rbands/' + run.zfill(6) + '/fpC-' + run.zfill(6) + '-r' + camcol\
         + '-' + frame.zfill(4) + '.fit.gz')
        data = fits[0].data
        header = fits[0].header

        # fitsファイルのheaderと銀河のra, decから,
        # 画像内の座標を得る
        wcs = astropy.wcs.WCS(header)
        px, py = wcs.wcs_world2pix(ra_deg, dec_deg, 0, ra_dec_order=True)
        px = int(px)
        py = int(py)

        # 得られた座標を中心として画像を切り出し、保存する
        r = 32
        img_galaxy = data[py - r:py + r, px - r:px + r]
        plt.title('RA = {}, Dec = {}'.format(ra_hms, dec_hms))
        plt.imshow(np.log10(img_galaxy.T[::-1, ::-1]),
                   cmap='gray',
                   vmin=3.05,
                   vmax=3.09)

        # 画像上で5秒角に対応する長さの線を描画する
        if header['CTYPE1'] == 'DEC--TAN':
            pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S /
                                            header['cd1_1'])
        else:
            pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S /
                                            header['cd1_2'])
        # cd1_2 = abs(header['CD1_2'])
        # pix_corresponding_to_5s = round(DEG_CORRESPONDING_TO_5S / cd1_2)

        # printで確認
        # if objid == 587724198813433876 or objid == 587724199349518483:
        # print(count,ra_deg,dec_deg,px, py, pix_corresponding_to_5s, header['CTYPE1'])

        plt.hlines(y=17, xmin=10, xmax=10 + pix_corresponding_to_5s)
        plt.savefig('data/img/' + str(objid), bbox_inches='tight')
        plt.close()

        # Tableの情報をcsvに保存する

        # 画像のnparray保存
        np.save('data/npz/' + str(objid), img_galaxy)
예제 #29
0
    def solve(self, scale):
        if not self.error and not self.is_solved:
            name, extension = os.path.splitext(self.filename)
            self.savePpm()
            scale_low = str(scale * 80.0 / 100.0)
            scale_high = str(scale * 120.0 / 100.0)
            subprocess.call([
                "/usr/local/astrometry/bin/solve-field", "--downsample", "2",
                "--tweak-order", "2", "--scale-units", "arcsecperpix",
                "--scale-low", scale_low, "--scale-high", scale_high,
                "--no-plots", "--overwrite", name + ".ppm"
            ])
            if os.path.isfile(name + '.solved'):
                correlation = astropy.io.fits.open(name + '.corr')
                self.correlation = correlation[1].data
                wcs = astropy.wcs.WCS(
                    astropy.io.fits.open(name + '.new')[0].header)
                # Search for deep sky objects
                galaxy = astropy.io.fits.open(
                    '/usr/local/astrometry/extra/ngc2000.fits')
                self.galaxy = numpy.empty((1000, 4), dtype=numpy.int)
                galaxy_num = 0
                galaxy_scale = astropy.wcs.utils.proj_plane_pixel_scales(
                    wcs).mean()
                for i in galaxy[1].data:
                    galaxy_pix = wcs.wcs_world2pix(numpy.array([[i[1], i[2]]]),
                                                   1)
                    if galaxy_pix[0][0] > 0 and galaxy_pix[0][
                            0] < self.rgb16.shape[0] and galaxy_pix[0][
                                1] > 0 and galaxy_pix[0][1] < self.rgb16.shape[
                                    1]:
                        self.galaxy[galaxy_num, 0] = i[0]
                        self.galaxy[galaxy_num, 1] = galaxy_pix[0][0]
                        self.galaxy[galaxy_num, 2] = galaxy_pix[0][1]
                        self.galaxy[galaxy_num, 3] = i[3] / galaxy_scale
                        galaxy_num = galaxy_num + 1
                self.galaxy = self.galaxy[0:galaxy_num]

                self.stars = numpy.empty((len(correlation[1].data), 3))
                for i in range(0, len(correlation[1].data)):
                    star_x = correlation[1].data[i][5]
                    star_y = correlation[1].data[i][4]
                    self.stars[i][0] = star_x
                    self.stars[i][1] = star_y
                    self.stars[i][2] = correlation[1].data[i][11]

                self.stars = self.stars[self.stars[:, 2].argsort()[::-1]]
                if self.stars.shape[0] > 20:
                    self.stars = self.stars[0:20]

                self.is_solved = True

            try:
                os.remove(name + '-indx.xyls')
                os.remove(name + '.axy')
                os.remove(name + '.corr')
                os.remove(name + '.match')
                os.remove(name + '.new')
                os.remove(name + '.ppm')
                os.remove(name + '.rdls')
                os.remove(name + '.solved')
                os.remove(name + '.wcs')
            except:
                print "    Some file was not here."
예제 #30
0
def get_finder(ra,
               dec,
               name,
               rad,
               debug=False,
               starlist=None,
               print_starlist=True,
               telescope="P200",
               directory=".",
               minmag=15,
               maxmag=18.5,
               mag=np.nan,
               image_file=None):
    '''
    Creates a PDF with the finder chart for the object with the specified name and coordinates.
    It queries the PS1 catalogue to obtain nearby offset stars and get an R-band image as background.
    
    Parameters
    ----------
    ra : float
        RA of our target in degrees.
    dec : float
        DEC of our target in degrees.
    name : str
        The name of your target
    rad : float
        Search radius for the finder in degrees.
    debug : bool (optional)
        Option to activate/ deactivate additional output.
    starlist : str (optional)
        Path/name of the file where the coordinates for the object are going to be saved. 
        If the file exists, the content will be appended at the end.
        If no value is provided, the output just writes to the standard output (in case print_starlist is True).
    print_starlist : boolean (optional)
        Indicates if the starlist shall be printed in the standard output.
    telescope : str (optional)
        The current two values accepted are "Keck" and "P200".
    directory : str (optional)
        The directory where the PDF with the finder chart shall be stored. 
        If no value given, the file will be store in the current directory where the script is run.
    minmag : float (optional)
        The minimum magnitud (brightest in this case) star that we would like to use as an offset star.
    maxmag : float (optional)
        The maximum magnitude (faintest) star that we would like to use as an offset star.
    mag : float or `None` (optional)
        The magnitude of our target.
    '''

    try:
        ra = float(ra)
        dec = float(dec)
    except:
        ra, dec = hour2deg(ra, dec)

    if dec < -30:
        catalog = query_sky_mapper_catalogue(ra,
                                             dec, (rad / 2.) * 0.95,
                                             minmag=minmag,
                                             maxmag=maxmag)
    else:
        catalog = query_ps1_catalogue(ra,
                                      dec, (rad / 2.) * 0.95,
                                      minmag=minmag,
                                      maxmag=maxmag)

    if (debug):
        print(catalog)

    if (len(catalog) < 3):
        if debug:
            print("Looking for a bit fainter stars up to mag: %.2f" %
                  (maxmag + 0.25))
        catalog = query_ps1_catalogue(ra,
                                      dec, (rad / 2.) * 0.95,
                                      minmag=minmag,
                                      maxmag=maxmag + 0.5)

    if (len(catalog) < 3):
        print("Restarting with larger radius %.2f arcmin" % (rad * 60 + 0.5))
        get_finder(ra,
                   dec,
                   name,
                   rad + 0.5 / 60,
                   directory=directory,
                   minmag=minmag,
                   maxmag=maxmag + 0.5,
                   mag=mag,
                   starlist=starlist,
                   telescope=telescope)
        return

    if (not catalog is None and len(catalog) > 0):
        np.random.shuffle(catalog)

    no_self_object = (np.abs(catalog["ra"] - ra) * np.cos(np.deg2rad(dec)) >
                      2. / 3600) * (np.abs(catalog["dec"] - dec) > 2. / 3600)
    catalog = catalog[no_self_object]
    catalog.sort(order='mag')

    if (debug): print(catalog)

    if image_file is None:
        image_file = get_fits_image(ra, dec, rad, debug=debug)
        image = fits.open(image_file)
    else:
        image = fits.open(image_file)
        image = np.rot90(np.rot90(image))

    if image_file is None or image is None:
        print("FATAL ERROR! Your FITS image could not be retrieved.")
        return

    # Get pixel coordinates of SN, reference stars in DSS image
    wcs = astropy.wcs.WCS(image[0].header)

    if (len(catalog) > 0):
        #w = astropy.wcs.find_all_wcs(ps1_image[0].header, relax=True, keysel=None)[0]
        ref1_pix = wcs.wcs_world2pix(
            np.array([[catalog["ra"][0], catalog["dec"][0]]], np.float_), 1)
    if (len(catalog) > 1):
        ref2_pix = wcs.wcs_world2pix(
            np.array([[catalog["ra"][1], catalog["dec"][1]]], np.float_), 1)
        #ref3_pix = wcs.wcs_world2pix(np.array([[catalog["ra"][2], catalog["dec"][2]]], np.float_), 1)
    target_pix = wcs.wcs_world2pix([(np.array([ra, dec], np.float_))], 1)

    # Plot finder chart

    #Adjust some of the counts to make easier the plotting.
    image[0].data[image[0].data > 30000] = 30000
    image[0].data[np.isnan(image[0].data)] = 0

    plt.figure(figsize=(8, 6))
    plt.set_cmap('gray_r')
    smoothedimage = gaussian_filter(image[0].data, 1.3)
    plt.imshow(smoothedimage, origin='lower',vmin=np.percentile(image[0].data.flatten(), 10), \
    vmax=np.percentile(image[0].data.flatten(), 99.0))

    # Mark target
    plt.plot([target_pix[0, 0] + 15, (target_pix[0, 0] + 10)],
             [target_pix[0, 1], (target_pix[0, 1])],
             'g-',
             lw=2)
    plt.plot([target_pix[0, 0], (target_pix[0, 0])],
             [target_pix[0, 1] + 10, (target_pix[0, 1]) + 15],
             'g-',
             lw=2)
    plt.annotate(name,
                 xy=(target_pix[0, 0], target_pix[0, 1]),
                 xycoords='data',
                 xytext=(22, -3),
                 textcoords='offset points')

    # Mark and label reference stars
    if (len(catalog) > 0):
        plt.plot([ref1_pix[0, 0] + 15, (ref1_pix[0, 0] + 10)],
                 [ref1_pix[0, 1], (ref1_pix[0, 1])],
                 'b-',
                 lw=2)
        plt.plot([ref1_pix[0, 0], (ref1_pix[0, 0])],
                 [ref1_pix[0, 1] + 10, (ref1_pix[0, 1]) + 15],
                 'b-',
                 lw=2)
        plt.annotate("R1",
                     xy=(ref1_pix[0, 0], ref1_pix[0, 1]),
                     xycoords='data',
                     xytext=(22, -3),
                     textcoords='offset points',
                     color="b")
    if (len(catalog) > 1):
        plt.plot([ref2_pix[0, 0] + 15, (ref2_pix[0, 0] + 10)],
                 [ref2_pix[0, 1], (ref2_pix[0, 1])],
                 'r-',
                 lw=2)
        plt.plot([ref2_pix[0, 0], (ref2_pix[0, 0])],
                 [ref2_pix[0, 1] + 10, (ref2_pix[0, 1]) + 15],
                 'r-',
                 lw=2)
        plt.annotate("R2",
                     xy=(ref2_pix[0, 0], ref2_pix[0, 1]),
                     xycoords='data',
                     xytext=(22, -3),
                     textcoords='offset points',
                     color="r")

    # Set limits to size of DSS image
    pylab.xlim([0, (image[0].data.shape[0])])
    pylab.ylim([0, (image[0].data.shape[1])])

    # Plot compass
    plt.plot([(image[0].data.shape[0]) - 10, (image[0].data.shape[0] - 40)],
             [10, 10],
             'k-',
             lw=2)
    plt.plot([(image[0].data.shape[0]) - 10, (image[0].data.shape[0]) - 10],
             [10, 40],
             'k-',
             lw=2)
    plt.annotate("N",
                 xy=((image[0].data.shape[0]) - 20, 40),
                 xycoords='data',
                 xytext=(-4, 5),
                 textcoords='offset points')
    plt.annotate("E",
                 xy=((image[0].data.shape[0]) - 40, 20),
                 xycoords='data',
                 xytext=(-12, -5),
                 textcoords='offset points')

    # Set axis tics (not implemented correctly yet)
    plt.tick_params(labelbottom='off')
    plt.tick_params(labelleft='off')
    plt.axes().xaxis.set_major_locator(MaxNLocator(5))
    plt.axes().yaxis.set_major_locator(MaxNLocator(5))
    plt.axes().set_xlabel('%.1f\'' % (rad * 60))
    plt.axes().set_ylabel('%.1f\'' % (rad * 60))

    # Set size of window (leaving space to right for ref star coords)
    plt.subplots_adjust(right=0.65, left=0.05, top=0.99, bottom=0.05)

    #If no magnitude was supplied, just do not put it on the chart.
    if not np.isnan(mag):
        target_mag = "mag=%.2f" % mag
    else:
        target_mag = ""

    # List name, coords, mag of references etc
    plt.text(1.02,
             0.85,
             name,
             transform=plt.axes().transAxes,
             fontweight='bold')
    plt.text(1.02,
             0.80,
             "%s" % target_mag,
             transform=plt.axes().transAxes,
             fontweight='bold')
    plt.text(1.02,
             0.75,
             "%.5f %.5f" % (ra, dec),
             transform=plt.axes().transAxes)
    rah, dech = deg2hour(ra, dec)
    plt.text(1.02, 0.7, rah + "  " + dech, transform=plt.axes().transAxes)

    #Put the text for the offset stars.
    if (len(catalog) > 0):
        ofR1 = get_offset(catalog["ra"][0], catalog["dec"][0], ra, dec)
        S1 = deg2hour(catalog["ra"][0], catalog["dec"][0], sep=":")

        plt.text(1.02,
                 0.60,
                 'R1, mag=%.2f' % catalog["mag"][0],
                 transform=plt.axes().transAxes,
                 color="b")
        plt.text(1.02,
                 0.55,
                 '%s %s' % (S1[0], S1[1]),
                 transform=plt.axes().transAxes,
                 color="b")
        plt.text(1.02,
                 0.5,
                 "E: %.2f N: %.2f" % (ofR1[0], ofR1[1]),
                 transform=plt.axes().transAxes,
                 color="b")

    if (len(catalog) > 1):
        ofR2 = get_offset(catalog["ra"][1], catalog["dec"][1], ra, dec)
        S2 = deg2hour(catalog["ra"][1], catalog["dec"][1], sep=":")

        plt.text(1.02,
                 0.4,
                 'R2, mag=%.2f' % catalog["mag"][1],
                 transform=plt.axes().transAxes,
                 color="r")
        plt.text(1.02,
                 0.35,
                 '%s %s' % (S2[0], S2[1]),
                 transform=plt.axes().transAxes,
                 color="r")
        plt.text(1.02,
                 0.3,
                 "E: %.2f N: %.2f" % (ofR2[0], ofR2[1]),
                 transform=plt.axes().transAxes,
                 color="r")

    # Save to pdf
    pylab.savefig(os.path.join(directory, str(name + '_finder.pdf')))
    if debug:
        print("Saved to %s" %
              os.path.join(directory, str(name + '_finder.pdf')))
    pylab.close("all")

    #Print starlist
    if telescope == "Keck":
        commentchar = "#"
        separator = ""
    else:
        commentchar = "!"
        separator = "!"

    if (len(catalog) > 0 and (print_starlist or not starlist is None)):
        print("{0} {2} {3}  2000.0 {1} ".format(name.ljust(20), commentchar,
                                                *deg2hour(ra, dec, sep=" ")))
        S1 = deg2hour(catalog["ra"][0], catalog["dec"][0], sep=" ")
        print(
            "{:s} {:s} {:s}  2000.0 {:s} raoffset={:.2f} decoffset={:.2f} r={:.1f} {:s} "
            .format((name + "_S1").ljust(20), S1[0], S1[1], separator, ofR1[0],
                    ofR1[1], catalog["mag"][0], commentchar))

    if (len(catalog) > 1 and (print_starlist or not starlist is None)):
        S2 = deg2hour(catalog["ra"][1], catalog["dec"][1], sep=" ")
        print(
            "{:s} {:s} {:s}  2000.0 {:s} raoffset={:.2f} decoffset={:.2f} r={:.1f} {:s} "
            .format((name + "_S2").ljust(20), S2[0], S2[1], separator, ofR2[0],
                    ofR2[1], catalog["mag"][1], commentchar))

    r, d = deg2hour(ra, dec, sep=" ")

    #Write to the starlist if the name of the starlist was provided.
    if (not starlist is None) and (telescope == "Keck"):
        with open(starlist, "a") as f:
            f.write("{0} {1} {2}  2000.0 # {3} \n".format(
                name.ljust(17), r, d, target_mag))
            if (len(catalog) > 0):
                f.write(
                    "{:s} {:s} {:s}  2000.0 raoffset={:.2f} decoffset={:.2f} r={:.1f} # \n"
                    .format((name + "_S1").ljust(17), S1[0], S1[1], ofR1[0],
                            ofR1[1], catalog["mag"][0]))
            if (len(catalog) > 1):
                f.write(
                    "{:s} {:s} {:s}  2000.0 raoffset={:.2f} decoffset={:.2f} r={:.1f} # \n"
                    .format((name + "_S2").ljust(17), S2[0], S2[1], ofR2[0],
                            ofR2[1], catalog["mag"][1]))
            f.write('\n')

    if (not starlist is None) and (telescope == "P200"):
        with open(starlist, "a") as f:
            f.write("{0} {1} {2}  2000.0 ! {3}\n".format(
                name.ljust(19), r, d, target_mag))
            if (len(catalog) > 0):
                f.write(
                    "{:s} {:s} {:s}  2000.0 ! raoffset={:.2f} decoffset={:.2f} r={:.1f}  \n"
                    .format((name + "_S1").ljust(19), S1[0], S1[1], ofR1[0],
                            ofR1[1], catalog["mag"][0]))
            if (len(catalog) > 1):
                f.write(
                    "{:s} {:s} {:s}  2000.0 ! raoffset={:.2f} decoffset={:.2f} r={:.1f}  \n"
                    .format((name + "_S2").ljust(19), S2[0], S2[1], ofR2[0],
                            ofR2[1], catalog["mag"][1]))
            f.write('\n')
예제 #31
0
def img_cutout(img,
               wcs,
               coord_1,
               coord_2,
               size=60.0,
               pix=0.168,
               prefix='img_cutout',
               pixel_unit=False,
               img_header=None,
               out_dir=None,
               save=True):
    """(From kungpao) Generate image cutout with updated WCS information.
    ----------
    Parameters:
        pixel_unit: boolen, optional
                    When True, coord_1, cooord_2 becomes X, Y pixel coordinates.
                    Size will also be treated as in pixels.
        img: 2d array.
        wcs: astropy wcs object of the input image.
        coord_1: ra of the center.
        coord_2: dec of the center.
        size: image size, default in arcsec unit.
        pix: pixel size.
        img_header: the astropy header object of the input image. 
                    In case you can save the infomation in this header to the new header.
    """
    from astropy.nddata import Cutout2D
    if not pixel_unit:
        # imgsize in unit of arcsec
        cutout_size = np.asarray(size) / pix
        cen_x, cen_y = wcs.wcs_world2pix(coord_1, coord_2, 0)
    else:
        cutout_size = np.asarray(size)
        cen_x, cen_y = coord_1, coord_2

    cen_pos = (int(cen_x), int(cen_y))
    dx = -1.0 * (cen_x - int(cen_x))
    dy = -1.0 * (cen_y - int(cen_y))

    # Generate cutout
    cutout = Cutout2D(img, cen_pos, cutout_size, wcs=wcs)

    # Update the header
    cutout_header = cutout.wcs.to_header()
    if img_header is not None:
        intersect = [k for k in img_header if k not in cutout_header]
        for keyword in intersect:
            cutout_header.set(keyword, img_header[keyword],
                              img_header.comments[keyword])

    # Build a HDU
    hdu = fits.PrimaryHDU(header=cutout_header)
    hdu.data = cutout.data

    # Save FITS image
    if save:
        fits_file = prefix + '.fits'
        if out_dir is not None:
            fits_file = os.path.join(out_dir, fits_file)

        hdu.writeto(fits_file, overwrite=True)

    return cutout, [cen_pos, dx, dy], cutout_header
예제 #32
0
def get_finder(ra,
               dec,
               name,
               rad=0.01,
               target_mag=np.nan,
               starlist=None,
               print_starlist=True,
               telescope="P200",
               main_comment="",
               minmag=15,
               maxmag=18.5,
               figdir=None):
    """ 
    Aim: Generate finder chart 
    
    Parameters:
    ra: float or string. 
        eg: ra="18h24m25.36s", 210.437583
        
    dec: float or string, type must be consistent with ra. 
        eg: dec="+44d07m50.0s", 46.215583
        
    name: ZTFname or host name. 
        eg: name="18aaslhxt_h", "ZTF18abclfee"
        
    rad: search radius in the unit of degree
    
    target_mag: magnitude of the target at time of observation, 
        default shoudl be r band
    
    starlist: name of the starlist
        eg: starlist="/Users/yuhanyao/Desktop/observation/20190428_LRIS/starlist"
        
        
    References:
    Keck starlist format: https://www2.keck.hawaii.edu/observing/starlist.html
        First field is the target name in columns 1-16 (tabs and spaces allowed). Maximum length is 15 characters.
        Next three space-separated tokens (beginning in column 17) are RA in the form HH MM SS.SS (including an arbitrary number of decimal places).
        Next three space-separated tokens are Dec in the form (-)DD MM SS.S (again, to an arbitrary number of decimal places). Note: if the Dec is between 0 and -1, the DD field MUST be -00).
        Next token is equinox in the form YYYY.YY (no parentheses; arbitrary number of decimal places), with <=1950 meaning FK4 and 2000 meaning FK5 and APP meaning apparent.
        
    """
    print('Using search radius of %.1f arcsec.' % (rad * 3600))

    name = str(name)
    #assert len(name) in [12, 11]

    assert type(ra) == type(dec)
    if type(ra) == str:
        c1 = SkyCoord(ra, dec, frame='icrs')
        ra = c1.ra.degree
        dec = c1.dec.degree
    ra = float(ra)
    dec = float(dec)

    # prepare to print starlist
    if telescope == "Keck":
        name_length = 16  # maximum length of name is 15
        commentchar = "#"
        separator = ""
        rah_length = 11
    elif telescope == "P200":
        name_length = 20
        commentchar = "!"
        separator = "|"
        rah_length = 12

    #Write to the starlist if the name of the starlist was provided.
    rah, dech = deg2hour(ra, dec, sep=" ")
    if (not starlist is None):
        s_target_mag = "yyao: (r={0:.1f})".format(target_mag)
        if telescope == "Keck":
            with open(starlist, "a") as f:
                f.write("{:s}{:s} {:s} 2000.0 {:s} {:s} {:s} {:s} \n".format(
                    name.ljust(name_length), rah.ljust(rah_length), dech,
                    commentchar, main_comment, separator, s_target_mag))
                f.close()
        elif telescope == "P200":
            with open(starlist, "a") as f:
                f.write("{:s}{:s} {:s} 2000.0 {:s} {:s} {:s} {:s} \n".format(
                    name.ljust(name_length), rah.ljust(rah_length), dech,
                    commentchar, main_comment, separator, s_target_mag))
                f.close()

    # Get metadata of all images at this location
    print("Querying for metadata...")
    zquery = query.ZTFQuery()
    zquery.load_metadata(radec=[ra, dec], size=rad)
    out = zquery.metatable

    # Do you need to use a reference image?
    need_ref = len(out) == 0
    if need_ref or name[:4] == "ZTFJ":
        print("Using a reference image")
        imfile, catfile = choose_ref(zquery, ra, dec)
    else:
        print("Using a science image")
        imfile, catfile = choose_sci(zquery, out, name, ra, dec)

    # get the cutout
    inputf = pyfits.open(imfile)
    im = inputf[0].data
    inputf.close()
    head = fits.getheader(imfile)

    # Get the x and y position of the target,
    # as per the IPAC catalog
    wcs = astropy.wcs.WCS(head)
    world = np.array([[ra, dec]], np.float_)
    target_pix = wcs.wcs_world2pix(world, 0)[0]
    xpos = target_pix[0]
    ypos = target_pix[1]

    # adjust counts
    im[np.isnan(im)] = 0
    im[im > 30000] = 30000

    # extract 600x600 region around the position of the target
    width = 600
    height = 600
    xmax = xpos + width / 2
    xmin = xpos - width / 2
    ymax = ypos + height / 2
    ymin = ypos - height / 2

    plt.figure(figsize=(8, 6))
    plt.set_cmap('gray_r')
    smoothedimage = gaussian_filter(im, 1.3)
    # pad the image
    im_padded = np.pad(smoothedimage, 300, mode='constant', constant_values=0)

    # If it's a reference image, you have to flip it up/down and left/right
    if need_ref:
        croppedimage = np.fliplr(
            np.flipud(im_padded[int(ymin) + 300:int(ymax) + 300,
                                int(xmin) + 300:int(xmax) + 300]))

    # If it's a science image, you just flip it up/down
    else:
        croppedimage = np.flipud(im_padded[int(ymin) + 300:int(ymax) + 300,
                                           int(xmin) + 300:int(xmax) + 300])

    plt.imshow(
        croppedimage,
        origin='lower',  # convention for IPAC images
        vmin=np.percentile(im.flatten(), 10),
        vmax=np.percentile(im.flatten(), 99.0))

    # Mark target: should just be the center of the image, now
    # horizontal line
    plt.plot([300 + 5, 300 + 20], [300, 300], 'g-', lw=2)
    # vertical line
    plt.plot([300, 300], [300 + 5, 300 + 20], 'g-', lw=2)

    # and the offset of the original coordinate system with the new coordinates
    offset_x = xpos - 300
    offset_y = ypos - 300

    # Choose offset stars
    cat = pyfits.open(catfile)[1].data
    zp = pyfits.open(catfile)[0].header['MAGZP']
    sep_pix = np.sqrt(
            (xpos-cat['xpos'])**2 + \
            (ypos-cat['ypos'])**2)

    # should be separated by at least 10 pixels
    crit_a = np.logical_and(sep_pix > 10, cat['flags'] == 0)
    crit_b = np.logical_and(cat['chi'] < 2, cat['snr'] > 10)
    crit_c = cat['sharp'] < 0.3
    crit_ab = np.logical_and(crit_a, crit_b)
    crit = np.logical_and(crit_ab, crit_c)

    # should be bright
    mag_crit = np.logical_and(cat['mag'] + zp >= minmag,
                              cat['mag'] + zp <= maxmag)
    choose_ind = np.where(np.logical_and(crit, mag_crit))

    # mark the closest three stars
    nref = 3
    order = np.argsort(sep_pix[choose_ind])
    cols = ['orange', 'purple', 'red']

    for ii in np.arange(nref):
        ref_xpos_original = cat['xpos'][choose_ind][order][ii] - offset_x
        ref_ypos_original = cat['ypos'][choose_ind][order][ii] - offset_y

        # transform to flipped plot
        if need_ref:
            ref_xpos = 600 - ref_xpos_original
            ref_ypos = 600 - ref_ypos_original
        else:
            ref_xpos = ref_xpos_original
            ref_ypos = 600 - ref_ypos_original

        plt.plot([ref_xpos + 5, ref_xpos + 20], [ref_ypos, ref_ypos],
                 c=cols[ii],
                 ls='-',
                 lw=2)
        plt.plot([ref_xpos, ref_xpos], [ref_ypos + 5, ref_ypos + 20],
                 c=cols[ii],
                 ls='-',
                 lw=2)
        refra = cat['ra'][choose_ind][order][ii]
        refdec = cat['dec'][choose_ind][order][ii]
        if telescope == 'Keck':
            refrah, refdech = deg2hour(refra, refdec, sep=" ")
        elif telescope == 'P200':
            refrah, refdech = deg2hour(refra, refdec, sep=":")
        else:
            print("I don't recognize this telescope")
        refmag = cat['mag'][choose_ind][order][ii] + zp
        dra, ddec = get_offset(refra, refdec, ra, dec)

        offsetnum = 0.2
        plt.text(1.02,
                 0.60 - offsetnum * ii,
                 'Ref S%s, mag %s' % ((ii + 1), np.round(refmag, 1)),
                 transform=plt.axes().transAxes,
                 fontweight='bold',
                 color=cols[ii])
        plt.text(1.02,
                 0.55 - offsetnum * ii,
                 '%s %s' % (refrah, refdech),
                 color=cols[ii],
                 transform=plt.axes().transAxes)
        plt.text(1.02,
                 0.50 - offsetnum * ii,
                 str(np.round(ddec, 2)) + "'' N, " + str(np.round(dra, 2)) +
                 "'' E",
                 color=cols[ii],
                 transform=plt.axes().transAxes)

        # Print starlist for telescope
        if telescope == 'Keck':
            # Target name is columns 1-16
            # RA must begin in 17, separated by spaces
            print(
                "{:s}{:s} {:s} 2000.0 {:s} raoffset={:.2f} decoffset={:.2f} {:s} r={:.1f} "
                .format((name + "_S%s" % (ii + 1)).ljust(name_length),
                        refrah.ljust(rah_length), refdech, separator, dra,
                        ddec, commentchar, refmag))
        elif telescope == 'P200':
            print(
                "{:s}{:s} {:s} 2000.0 {:s} raoffset={:.2f} decoffset={:.2f} r={:.1f} \n"
                .format((name + "_S%s" % (ii + 1)).ljust(name_length),
                        refrah.ljust(rah_length), refdech, commentchar, dra,
                        ddec, refmag))

        # and save to file if starlist name is provided
        if (not starlist is None):
            if telescope == "Keck":
                with open(starlist, "a") as f:
                    f.write(
                        "{:s}{:s} {:s} 2000.0 {:s} raoffset={:.2f} decoffset={:.2f} {:s} r={:.1f} \n"
                        .format((name + "_S%s" % (ii + 1)).ljust(name_length),
                                refrah.ljust(rah_length), refdech, commentchar,
                                dra, ddec, separator, refmag))
                    f.close()
            elif telescope == "P200":
                with open(starlist, "a") as f:
                    f.write(
                        "{:s}{:s} {:s} 2000.0 {:s} raoffset={:.2f} decoffset={:.2f} r={:.1f} \n"
                        .format((name + "_S%s" % (ii + 1)).ljust(name_length),
                                refrah.ljust(rah_length), refdech, commentchar,
                                dra, ddec, refmag))
                    f.close()

    # Plot compass
    plt.plot([width - 10, height - 40], [10, 10], 'k-', lw=2)
    plt.plot([width - 10, height - 10], [10, 40], 'k-', lw=2)
    plt.annotate("N",
                 xy=(width - 20, 40),
                 xycoords='data',
                 xytext=(-4, 5),
                 textcoords='offset points')
    plt.annotate("E",
                 xy=(height - 40, 20),
                 xycoords='data',
                 xytext=(-12, -5),
                 textcoords='offset points')

    # Get rid of axis labels
    plt.gca().get_xaxis().set_visible(False)
    plt.gca().get_yaxis().set_visible(False)

    # Set size of window (leaving space to right for ref star coords)
    plt.subplots_adjust(right=0.65, left=0.05, top=0.99, bottom=0.05)

    # List name, coords, mag of the target
    plt.text(1.02,
             0.85,
             name,
             transform=plt.axes().transAxes,
             fontweight='bold')
    # Can't print mag, because we don't know how bright the target is
    #plt.text(1.02, 0.80, "%s"%mag, transform=plt.axes().transAxes, fontweight='bold')
    plt.text(1.02,
             0.80,
             "%.5f %.5f" % (ra, dec),
             transform=plt.axes().transAxes)
    rah, dech = deg2hour(ra, dec)
    plt.text(1.02, 0.75, rah + "  " + dech, transform=plt.axes().transAxes)

    if figdir == None:
        plt.savefig("finder_chart_%s.png" % name)
    else:
        plt.savefig(figdir + "finder_chart_%s.png" % name)
    plt.close()
예제 #33
0
def make_finder(image='A2744_DSS_r.fits', ra=3.5313884, dec=-30.389218, pa=53.8-90, target='A2744 (Ks)', image_label='DSS-r',     progID = '092.A-0472(A)', PI = 'G. Brammer', vscale=None):
    
    import matplotlib.pyplot as plt
    import astropy.wcs 
    
    import finder
    
    # plt.gray()
    
    im = pyfits.open(image)[0].data
    wcs = astropy.wcs.WCS(pyfits.getheader(image))
    
    px, py = finder.make_regions(ra=ra, dec=dec, pa=pa)
    
    fig = unicorn.plotting.plot_init(xs=6, aspect=1.1, left=0.01, right=0.01, top=0.01, bottom=0.01)
    ax = fig.add_axes((0.01, 0.01, 0.98, 0.88)) #(111)
    if vscale is None:
        vscale = np.percentile(im, [0.1,99.8])
        print 'Vscale: %.2f, %.2f' %(vscale[0], vscale[1])
        
    ai = ax.imshow(0-im, vmin=-vscale[1], vmax=-vscale[0], aspect='auto', interpolation='nearest', label=image_label)
    
    colors = ['magenta', 'black','black','black']
    for i in range(4):
        bx, by = wcs.wcs_world2pix(px[i], py[i], 0)
        ax.plot(bx, by, color=colors[i], label='HAWKI, Chip 1'*(i==0))
    
    ### 10x10 box
    bx, by = wcs.wcs_world2pix(px[-1], py[-1], 0)
    ax.plot(bx, by, color='black', linestyle='--', label=r"$10\times10$ arcmin")
    
    ax.set_xlim(0, im.shape[1])
    ax.set_xticks([0, im.shape[1]])
    ax.set_ylim(0, im.shape[0])
    ax.set_yticks([0, im.shape[0]])
    ax.set_xticklabels([])
    ax.set_yticklabels([])
    
    ax.text(0.02, 0.98, 'Image: %s' %(image_label), ha='left', va='top', transform=ax.transAxes, size=14)
        
    axt = fig.add_axes((0.01, 0.89, 0.98, 0.1))
    axt.text(0.02, 0.9, '%s,  PI: %s' %(progID, PI), ha='left', va='top', size=17, transform=axt.transAxes)
    axt.text(0.02, 0.1, 'Target: %s' %(target), ha='left', va='bottom', size=17, transform=axt.transAxes)
    axt.text(0.98, 0.1, 'PA = %.1f' %(pa), ha='right', va='bottom', size=12, transform=axt.transAxes)

    axt.set_xticklabels([])
    axt.set_yticklabels([])
    axt.set_xlim(0,1); axt.set_xticks([])
    axt.set_ylim(0,1); axt.set_yticks([])
    
    ax.legend(loc='lower right')
    
    ax.arrow(0.15,0.05, -0.1, 0, transform=ax.transAxes, color='black', head_length=0.01, head_width=0.01)
    ax.arrow(0.15,0.05, 0, 0.1, transform=ax.transAxes, color='black', head_length=0.01, head_width=0.01)
    ax.text(0.05, 0.05+0.02, 'E', ha='center', va='bottom', transform=ax.transAxes)
    ax.text(0.15-0.02, 0.15, 'N', ha='right', va='center', transform=ax.transAxes)
    
    return fig, ax