def test_crpix_maps_to_crval(): twcs = wcs.WCS(naxis=2) twcs.wcs.crval = [251.29, 57.58] twcs.wcs.cdelt = [1, 1] twcs.wcs.crpix = [507, 507] twcs.wcs.pc = np.array([[7.7e-6, 3.3e-5], [3.7e-5, -6.8e-6]]) twcs._naxis = [1014, 1014] twcs.wcs.ctype = ['RA---TAN-SIP', 'DEC--TAN-SIP'] a = np.array([[0, 0, 5.33092692e-08, 3.73753773e-11, -2.02111473e-13], [0, 2.44084308e-05, 2.81394789e-11, 5.17856895e-13, 0.0], [-2.41334657e-07, 1.29289255e-10, 2.35753629e-14, 0.0, 0.0], [-2.37162007e-10, 5.43714947e-13, 0.0, 0.0, 0.0], [-2.81029767e-13, 0.0, 0.0, 0.0, 0.0]]) b = np.array([[0, 0, 2.99270374e-05, -2.38136074e-10, 7.23205168e-13], [0, -1.71073858e-07, 6.31243431e-11, -5.16744347e-14, 0.0], [6.95458963e-06, -3.08278961e-10, -1.75800917e-13, 0.0, 0.0], [3.51974159e-11, 5.60993016e-14, 0.0, 0.0, 0.0], [-5.92438525e-13, 0.0, 0.0, 0.0, 0.0]]) twcs.sip = wcs.Sip(a, b, None, None, twcs.wcs.crpix) twcs.wcs.set() pscale = np.sqrt(wcs.utils.proj_plane_pixel_area(twcs)) # test that CRPIX maps to CRVAL: assert_allclose(twcs.wcs_pix2world(*twcs.wcs.crpix, 1), twcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale) # test that CRPIX maps to CRVAL: assert_allclose(twcs.all_pix2world(*twcs.wcs.crpix, 1), twcs.wcs.crval, rtol=0.0, atol=1e-6 * pscale)
def get_wcs_mcs(cent, rot): """Get WCS parameters For PFSC (MCS) file (WCS on PFI coordinates) Parameters ---------- cent : `np.ndarray`, (2, 1) The FoV center, i.e., telescope pointing center, (ra, dec) in unit of degree. rot : `float` Telescope instrument rotator angle in unit of degree. Returns ------- w: `astropy.wcs.WCS` registered wcs keywords s: `astropy.wcs.Sip` registered SIP keywords """ c = disco.Coeff('mcs_pfi') rot *= np.pi / 180. w = wcs.WCS(naxis=2) # pixel -> intermediate pixel w.wcs.crpix = [cent[0], cent[1]] w.wcs.pc = [[np.cos(rot), -1. * np.sin(rot)], [np.sin(rot), np.cos(rot)]] # intermediate pixel to intermediate worlds w.wcs.cdelt = np.array([disco.mcspix * c.rsc[0], disco.mcspix * c.rsc[0]]) # Simple Imaging Polynomial (no inverse func is defined) # Here, r~x~y is assumed order = 7 a = np.zeros((order + 1, order + 1)) a[3][0] = c.rsc[1] / c.rsc[0] a[5][0] = c.rsc[2] / c.rsc[0] a[7][0] = c.rsc[3] / c.rsc[0] ap = np.zeros((order + 1, order + 1)) b = np.swapaxes(a, 0, 1) bp = np.swapaxes(ap, 0, 1) s = wcs.Sip(a, b, ap, bp, w.wcs.crpix) # intermeriate worlds to worlds w.wcs.crval = [0., 0.] w.wcs.ctype = ["PIXEL", "PIXEL"] # w.wcs.set_pv([(2, 1, 45.0)]) # Others w.wcs.cunit = ['mm', 'mm'] return w, s
def fit_wcs(x, y, ra, dec, x0, y0, ra0, dec0, order, projection="TAN"): """ Fit an astropy WCS object to given coordinates Args: x (array[float]): Pixel x coordinates y (array[float]): Pixel y coordinates ra (array[float]: RA coordinates in degrees dec (array[float]: Dec coordinates in degrees x0 (float): center pixel x y0 (float): center pixel y ra0 (float): center pixel RA in degrees dec0 (float) center pixel DEC in degrees order: order of imaging polynomials Returns: WCS instance """ dx, dy = x - x0, y - y0 ixs, iys = np.meshgrid(np.arange(order + 1), np.arange(order + 1)) c = ixs + iys <= order ix, iy = ixs[c], iys[c] a = np.array([dx**ix[i] * dy**iy[i] for i in range(len(iy))]).T for k in range(5): w = wcs.WCS(naxis=2) w.wcs.ctype = ["RA---" + projection, "DEC--" + projection] w.wcs.cd = [[1.0, 0.0], [0.0, 1.0]] w.wcs.crval = [ra0, dec0] w.wcs.crpix = [0.0, 0.0] rx, ry = w.wcs_world2pix(np.stack((ra, dec), axis=-1), 1).T ax = solve_linear_equation(a, rx) ay = solve_linear_equation(a, ry) ra0, dec0 = w.wcs_pix2world(([[ax[0], ay[0]]]), 1)[0] cd = np.array([[ax[1], ax[order + 1]], [ay[1], ay[order + 1]]]) cdinv = np.linalg.inv(cd) axm = np.zeros_like(ixs).astype("float32") aym = np.zeros_like(ixs).astype("float32") for i in range(len(ix)): if ix[i] + iy[i] >= 2: p = np.matmul(cdinv, np.array([ax[i], ay[i]])) axm[iy[i], ix[i]] = p[0] aym[iy[i], ix[i]] = p[1] w = wcs.WCS(naxis=2) w.wcs.ctype = ["RA---ZEA-SIP", "DEC--ZEA-SIP"] w.wcs.cd = cd w.wcs.crval = [ra0, dec0] w.wcs.crpix = [x0, y0] w.sip = wcs.Sip(axm.T, aym.T, None, None, w.wcs.crpix) return w
def func(p): w.wcs.crpix = [p[0], p[1]] w.wcs.crval = [p[2], p[3]] w.wcs.cdelt = [p[4], p[5]] w.wcs.pc = [[p[6], p[7]], [p[8], p[9]]] if wcstype == 'tan-sip': a = np.zeros((order + 1, order + 1)) b = np.zeros((order + 1, order + 1)) ap = np.zeros(a.shape) bp = np.zeros(b.shape) n = 0 for i in range(order + 1): for j in range(order + 1): if i + j <= 1 or i + j > order: continue a[i, j] = p[n + 10] b[i, j] = p[n + len(p) / 2 + 5] n += 1 w.sip = wcs.Sip(a, b, ap, bp, w.wcs.crpix) return (w)
if args.drizzled: w.wcs.cd /= 2 # set up quadratic distortions [xy->uv and uv->xy] m = 2 a = np.zeros((m + 1, m + 1), np.double) a[0, 2] = a_02 a[1, 1] = a_11 a[2, 0] = a_20 b = np.zeros((m + 1, m + 1), np.double) b[0, 2] = b_02 b[1, 1] = b_11 b[2, 0] = b_20 if args.drizzled: a /= 2 b /= 2 ap = np.zeros((m + 1, m + 1), np.double) bp = np.zeros((m + 1, m + 1), np.double) w.sip = wcs.Sip(a, b, ap, bp, w.wcs.crpix) # header['BLALA'] = 'LALA' # turn WCS object into header new_header = w.to_header(relax=True) # merge with old header: for key in header.keys(): new_header[key] = header[key] export_fits(args.fits_in.replace('.fits', '.wcs.fits'), img, _header=new_header)