def makecorr(fname, allowed_corr): """ Purpose ======= Applies corrections to the WCS of a single file :Parameters: `fname`: string file name `acorr`: list list of corrections to be applied """ logger.info("Allowed corrections: {0}".format(allowed_corr)) f = fits.open(fname, mode='update') #Determine the reference chip and create the reference HSTWCS object nrefchip, nrefext = getNrefchip(f) wcsutil.restoreWCS(f, nrefext, wcskey='O') rwcs = HSTWCS(fobj=f, ext=nrefext) rwcs.readModel(update=True, header=f[nrefext].header) if 'DET2IMCorr' in allowed_corr: kw2update = det2im.DET2IMCorr.updateWCS(f) for kw in kw2update: f[1].header[kw] = kw2update[kw] for i in range(len(f))[1:]: extn = f[i] if 'extname' in extn.header: extname = extn.header['extname'].lower() if extname == 'sci': wcsutil.restoreWCS(f, ext=i, wcskey='O') sciextver = extn.header['extver'] ref_wcs = rwcs.deepcopy() hdr = extn.header ext_wcs = HSTWCS(fobj=f, ext=i) ### check if it exists first!!! # 'O ' can be safely archived again because it has been restored first. wcsutil.archiveWCS(f, ext=i, wcskey="O", wcsname="OPUS", reusekey=True) ext_wcs.readModel(update=True, header=hdr) for c in allowed_corr: if c != 'NPOLCorr' and c != 'DET2IMCorr': corr_klass = corrections.__getattribute__(c) kw2update = corr_klass.updateWCS(ext_wcs, ref_wcs) for kw in kw2update: hdr[kw] = kw2update[kw] # give the primary WCS a WCSNAME value idcname = f[0].header.get('IDCTAB', " ") if idcname.strip() and 'idc.fits' in idcname: wname = ''.join([ 'IDC_', utils.extract_rootname(idcname, suffix='_idc') ]) else: wname = " " hdr['WCSNAME'] = wname elif extname in ['err', 'dq', 'sdq', 'samp', 'time']: cextver = extn.header['extver'] if cextver == sciextver: hdr = f[('SCI', sciextver)].header w = pywcs.WCS(hdr, f) copyWCS(w, extn.header) else: continue if 'NPOLCorr' in allowed_corr: kw2update = npol.NPOLCorr.updateWCS(f) for kw in kw2update: f[1].header[kw] = kw2update[kw] # Finally record the version of the software which updated the WCS if 'HISTORY' in f[0].header: f[0].header.set('UPWCSVER', value=stwcs.__version__, comment="Version of STWCS used to updated the WCS", before='HISTORY') f[0].header.set('PYWCSVER', value=astropy.__version__, comment="Version of PYWCS used to updated the WCS", before='HISTORY') elif 'ASN_MTYP' in f[0].header: f[0].header.set('UPWCSVER', value=stwcs.__version__, comment="Version of STWCS used to updated the WCS", after='ASN_MTYP') f[0].header.set('PYWCSVER', value=astropy.__version__, comment="Version of PYWCS used to updated the WCS", after='ASN_MTYP') else: # Find index of last non-blank card, and insert this new keyword after that card for i in range(len(f[0].header) - 1, 0, -1): if f[0].header[i].strip() != '': break f[0].header.set('UPWCSVER', stwcs.__version__, "Version of STWCS used to updated the WCS", after=i) f[0].header.set('PYWCSVER', astropy.__version__, "Version of PYWCS used to updated the WCS", after=i) # add additional keywords to be used by headerlets distdict = utils.construct_distname(f, rwcs) f[0].header['DISTNAME'] = distdict['DISTNAME'] f[0].header['SIPNAME'] = distdict['SIPNAME'] # Make sure NEXTEND keyword remains accurate f[0].header['NEXTEND'] = len(f) - 1 f.close()
def _align_1image(resample, image, image_ext, primary_cutouts, seg, image_sky=None, wcslin=None, fitgeom='general', nclip=3, sigma=3.0, use_weights=True, cc_type='NCC', combine_seg_mask=True): img_info = { 'file_name': image, 'wcs_info': [], # a list of: [extension, original WCS, corrected WCS] 'fits_ext': [], # image ext. from which an image cutout was extracted 'image_cutouts': [], 'driz_cutouts': [], 'blotted_cutouts': [], # non-shifted blot images of drizzled cutouts 'ICC': [] # interlaced (oversampled) cross-correlation images } drz_sci_fname, drz_sci_ext = parse_file_name(resample.output_sci) with fits.open(drz_sci_fname) as hdulist: drz_sci = hdulist[drz_sci_ext].data drz_wcs = HSTWCS(hdulist, ext=drz_sci_ext) if 'EXPTIME' in hdulist[drz_sci_ext].header: drz_exptime = hdulist[drz_sci_ext].header['EXPTIME'] else: drz_exptime = hdulist[0].header['EXPTIME'] drz_units = hdulist[drz_sci_ext].header['BUNIT'] drz_units = 'rate' if '/' in drz_units else 'counts' # get image data, info and create cutouts: with fits.open(image) as hdulist: for ext in image_ext: img_sci = hdulist[ext].data img_wcs = HSTWCS(hdulist, ext=ext) orig_img_wcs = img_wcs.deepcopy() img_exptime = hdulist[0].header['EXPTIME'] img_units = hdulist[ext].header['BUNIT'] img_units = 'rate' if '/' in img_units else 'counts' if image_sky is not None and image_sky[ext] is not None: img_sci -= image_sky[ext] imgct_ext, drzct_ext = cutout.create_cutouts( primary_cutouts, seg, drz_sci, drz_wcs, img_sci, img_wcs, drz_data_units=drz_units, drz_exptime=drz_exptime, flt_data_units=img_units, flt_exptime=img_exptime, combine_seg_mask=combine_seg_mask) img_info['wcs_info'].append([ext, orig_img_wcs, img_wcs]) img_info['fits_ext'].extend(len(imgct_ext) * [ext]) img_info['image_cutouts'].extend(imgct_ext) img_info['driz_cutouts'].extend(drzct_ext) # find linear fit: fit, interlaced_cc, nonshifted_blts = find_linear_fit( img_cutouts=imgct_ext, drz_cutouts=drzct_ext, wcslin=wcslin, fitgeom=fitgeom, nclip=nclip, sigma=sigma, use_weights=use_weights, cc_type=cc_type) img_info['blotted_cutouts'].extend(nonshifted_blts) img_info['ICC'].extend(interlaced_cc) print("\nComputed '{:s}' fit for image {:s}:".format(fitgeom, image)) if fitgeom == 'shift': print("XSH: {:.4f} YSH: {:.4f}".format(fit['offset'][0], fit['offset'][1])) elif fitgeom == 'rscale' and fit['proper']: print( "XSH: {:.4f} YSH: {:.4f} ROT: {:.10g} SCALE: {:.6f}".format( fit['offset'][0], fit['offset'][1], fit['rot'], fit['scale'][0])) elif (fitgeom == 'general' or (fitgeom == 'rscale' and not fit['proper'])): print("XSH: {:.4f} YSH: {:.4f} PROPER ROT: {:.10g} ".format( fit['offset'][0], fit['offset'][1], fit['rot'])) print("<ROT>: {:.10g} SKEW: {:.10g} ROT_X: {:.10g} " "ROT_Y: {:.10g}".format(fit['rotxy'][2], fit['skew'], fit['rotxy'][0], fit['rotxy'][1])) print("<SCALE>: {:.10g} SCALE_X: {:.10g} SCALE_Y: {:.10g}".format( fit['scale'][0], fit['scale'][1], fit['scale'][2])) print('FIT RMSE: {:.3g} FIT MAE: {:.3g} IMAGE FIT RMSE: {:.3g}\n'. format(fit['rmse'], fit['mae'], fit['irmse'])) nmatch = fit['resids'].shape[0] print('Final solution based on {:d} objects.'.format(nmatch)) # correct WCS: for ext, owcs, wcs in img_info['wcs_info']: correct_wcs(imwcs=wcs, wcslin=drz_wcs, rotmat=fit['matrix'], shifts=fit['offset'], fitgeom=fitgeom) print("\n------- ORIGINAL WCS for '{:s}[{}]': ------".format( image, ext)) print(owcs) print("\n------- CORRECTED WCS for '{:s}[{}]': ------".format( image, ext)) print(wcs) return fit, img_info