def build_pixel_transform(chip, output_wcs): driz_pars = {} driz_pars['pxg'] = np.zeros([2, 2], dtype=np.float32) driz_pars['pyg'] = np.zeros([2, 2], dtype=np.float32) # Use default C mapping function _inwcs = np.zeros([8], dtype=np.float64) driz_pars['inwcs'] = convertWCS(output_wcs.wcs, _inwcs) indx = chip.outputNames['data'].find('.fits') driz_pars['coeffs_name'] = chip.outputNames['data'][:indx] + '_coeffs' + str(chip.detnum) + '.dat' # # Need to compute and write out coeffs files for each chip as well. # xcoeffs, ycoeffs = coeff_converter.sip2idc(chip.wcs) # account for the case where no IDCSCALE has been set, due to a # lack of IDCTAB or to 'coeffs=False'. idcscale = chip.wcs.idcscale if idcscale is None: idcscale = chip.wcs.pscale xcoeffs /= idcscale ycoeffs /= idcscale driz_pars['coeffs'] = [xcoeffs, ycoeffs] abxt, cdyt = wcsfit(chip.wcs, output_wcs) driz_pars['abxt'] = abxt driz_pars['cdyt'] = cdyt driz_pars['delta_rot'] = np.rad2deg(np.arctan2(abxt[1], cdyt[0])) # Compute scale from fit to allow WFPC2 (and similar) data to be handled correctly driz_pars['scale'] = 1. / np.sqrt(abxt[0]**2 + abxt[1]**2) driz_pars['tddalpha'] = chip.header['tddalpha'] driz_pars['tddbeta'] = chip.header['tddbeta'] return driz_pars
def build_pixel_transform(chip,output_wcs): driz_pars = {} driz_pars['pxg'] = np.zeros([2,2],dtype=np.float32) driz_pars['pyg'] = np.zeros([2,2],dtype=np.float32) # Use default C mapping function _inwcs = np.zeros([8],dtype=np.float64) driz_pars['inwcs'] = convertWCS(output_wcs.wcs,_inwcs) indx = chip.outputNames['data'].find('.fits') driz_pars['coeffs_name'] = chip.outputNames['data'][:indx]+'_coeffs'+str(chip.detnum)+'.dat' # # Need to compute and write out coeffs files for each chip as well. # xcoeffs,ycoeffs = coeff_converter.sip2idc(chip.wcs) # account for the case where no IDCSCALE has been set, due to a # lack of IDCTAB or to 'coeffs=False'. idcscale = chip.wcs.idcscale if idcscale is None: idcscale = chip.wcs.pscale xcoeffs /= idcscale ycoeffs /= idcscale driz_pars['coeffs'] = [xcoeffs,ycoeffs] abxt,cdyt = wcsfit(chip.wcs,output_wcs) #abxt[2] -= xzero #cdyt[2] -= yzero driz_pars['abxt'] = abxt driz_pars['cdyt'] = cdyt driz_pars['delta_rot'] = np.rad2deg(np.arctan2(abxt[1],cdyt[0])) # Compute scale from fit to allow WFPC2 (and similar) data to be handled correctly driz_pars['scale'] = 1./np.sqrt(abxt[0]**2 + abxt[1]**2) driz_pars['tddalpha'] = chip.header['tddalpha'] driz_pars['tddbeta'] = chip.header['tddbeta'] return driz_pars
def _readModelFromHeader(self, header): # Recreate idc model from SIP coefficients and header kw print('Restoring IDC model from SIP coefficients\n') model = models.GeometryModel() cx, cy = coeff_converter.sip2idc(self) model.cx = cx model.cy = cy model.name = "sip" model.norder = header['A_ORDER'] refpix = {} refpix['XREF'] = header['IDCXREF'] refpix['YREF'] = header['IDCYREF'] refpix['PSCALE'] = header['IDCSCALE'] refpix['V2REF'] = header['IDCV2REF'] refpix['V3REF'] = header['IDCV3REF'] refpix['THETA'] = header['IDCTHETA'] model.refpix = refpix self.idcmodel = model
def wcsfit(img_wcs, ref_wcs): """ Perform a linear fit between 2 WCS for shift, rotation and scale. Based on the WCSLIN function from 'drutil.f'(Drizzle V2.9) and modified to allow for differences in reference positions assumed by PyDrizzle's distortion model and the coeffs used by 'drizzle'. Parameters ---------- img : obj ObsGeometry instance for input image ref_wcs : obj Undistorted WCSObject instance for output frame """ # Define objects that we need to use for the fit... #in_refpix = img_geom.model.refpix wmap = WCSMap(img_wcs,ref_wcs) cx, cy = coeff_converter.sip2idc(img_wcs) # Convert the RA/Dec positions back to X/Y in output product image #_cpix_xyref = np.zeros((4,2),dtype=np.float64) # Start by setting up an array of points +/-0.5 pixels around CRVAL1,2 # However, we must shift these positions by 1.0pix to match what # drizzle will use as its reference position for 'align=center'. _cpix = (img_wcs.wcs.crpix[0],img_wcs.wcs.crpix[1]) _cpix_arr = np.array([_cpix,(_cpix[0],_cpix[1]+1.), (_cpix[0]+1.,_cpix[1]+1.),(_cpix[0]+1.,_cpix[1])], dtype=np.float64) # Convert these positions to RA/Dec _cpix_rd = wmap.xy2rd(img_wcs,_cpix_arr[:,0],_cpix_arr[:,1]) #for pix in xrange(len(_cpix_rd[0])): _cpix_xref,_cpix_yref = wmap.rd2xy(ref_wcs,_cpix_rd[0],_cpix_rd[1]) _cpix_xyref = np.zeros((4,2),dtype=np.float64) _cpix_xyref[:,0] = _cpix_xref _cpix_xyref[:,1] = _cpix_yref """ # needed to handle correctly subarrays and wfpc2 data if img_wcs.delta_refx == 0.0 and img_wcs.delta_refy == 0.0: offx, offy = (0.0,0.0) else: offx, offy = (1.0, 1.0) """ offx, offy = (0.0,0.0) # Now, apply distortion model to input image XY positions #_cpix_xyc = np.zeros((4,2),dtype=np.float64) _cpix_xyc = utils.apply_idc(_cpix_arr, cx, cy, img_wcs.wcs.crpix, img_wcs.pscale, order=1) # Need to get the XDELTA,YDELTA values included here in order to get this # to work with MDTng. #if in_refpix: # _cpix_xyc += (in_refpix['XDELTA'], in_refpix['YDELTA']) # Perform a fit between: # - undistorted, input positions: _cpix_xyc # - X/Y positions in reference frame: _cpix_xyref abxt,cdyt = fitlin(_cpix_xyc,_cpix_xyref) # This correction affects the final fit when you are fitting # a WCS to itself (no distortion coeffs), so it needs to be # taken out in the coeffs file by modifying the zero-point value. # WJH 17-Mar-2005 abxt[2] -= ref_wcs.wcs.crpix[0] + offx cdyt[2] -= ref_wcs.wcs.crpix[1] + offy return abxt,cdyt