diff options
-rw-r--r-- | updatewcs/apply_corrections.py | 52 | ||||
-rw-r--r-- | updatewcs/det2im.py | 3 | ||||
-rw-r--r-- | updatewcs/dgeo.py | 88 |
3 files changed, 74 insertions, 69 deletions
diff --git a/updatewcs/apply_corrections.py b/updatewcs/apply_corrections.py index 1b729ac..af1a081 100644 --- a/updatewcs/apply_corrections.py +++ b/updatewcs/apply_corrections.py @@ -115,29 +115,31 @@ def applyDgeoCorr(fname, udgeocorr): """ Purpose ======= - Adds dgeo extensions to files based on the DGEOFILE keyword in the primary - header. This is a default correction and will always run in the pipeline. + Determines whether non-polynomial distortion lookup tables should be added + as extensions to the science file based on the 'NPOLFILE' keyword in the + primary header and NPOLEXT kw in the first extension. + This is a default correction and will always run in the pipeline. The file used to generate the extensions is - recorded in the DGEOEXT keyword in each science extension. - If 'DGEOFILE' in the primary header is different from 'DGEOEXT' in the + recorded in the NPOLEXT keyword in the first science extension. + If 'NPOLFILE' in the primary header is different from 'NPOLEXT' in the extension header and the file exists on disk and is a 'new type' dgeofile, - then the dgeo extensions will be updated. + then the lookup tables will be updated as 'WCSDVARR' extensions. """ applyDGEOCorr = True try: - # get DGEOFILE kw from primary header - fdgeo0 = pyfits.getval(fname, 'DGEOFILE') + # get NPOLFILE kw from primary header + fdgeo0 = pyfits.getval(fname, 'NPOLFILE') if fdgeo0 == 'N/A': return False fdgeo0 = fileutil.osfn(fdgeo0) if not fileutil.findFile(fdgeo0): - print 'Kw DGEOFILE exists in primary header but file %s not found\n' % fdgeo0 - print 'DGEO correction will not be applied\n' + print 'Kw "NPOLFILE" exists in primary header but file %s not found\n' % fdgeo0 + print 'Non-polynomial distortion correction will not be applied\n' applyDGEOCorr = False return applyDGEOCorr try: - # get DGEOEXT kw from first extension header - fdgeo1 = pyfits.getval(fname, 'DGEOEXT', ext=1) + # get NPOLEXT kw from first extension header + fdgeo1 = pyfits.getval(fname, 'NPOLEXT', ext=1) fdgeo1 = fileutil.osfn(fdgeo1) if fdgeo1 and fileutil.findFile(fdgeo1): if fdgeo0 != fdgeo1: @@ -145,15 +147,16 @@ def applyDgeoCorr(fname, udgeocorr): else: applyDGEOCorr = False else: - # dgeo file defined in first extension may not be found - # but if a valid kw exists in the primary header, dgeo should be applied. + # npl file defined in first extension may not be found + # but if a valid kw exists in the primary header, non-polynomial + #distortion correction should be applied. applyDGEOCorr = True except KeyError: - # the case of DGEOFILE kw present in primary header but DGEOEXT missing + # the case of "NPOLFILE" kw present in primary header but "NPOLEXT" missing # in first extension header applyDGEOCorr = True except KeyError: - print 'DGEOFILE keyword not found in primary header' + print '"NPOLFILE" keyword not found in primary header' applyDGEOCorr = False return applyDGEOCorr @@ -162,7 +165,7 @@ def applyDgeoCorr(fname, udgeocorr): return (applyDGEOCorr and udgeocorr) def isOldStyleDGEO(fname, dgname): - # checks if the file defined in a DGEOFILE kw is a full size + # checks if the file defined in a NPOLFILE kw is a full size # (old style) image sci_naxis1 = pyfits.getval(fname, 'NAXIS1', ext=1) @@ -170,8 +173,8 @@ def isOldStyleDGEO(fname, dgname): dg_naxis1 = pyfits.getval(dgname, 'NAXIS1', ext=1) dg_naxis2 = pyfits.getval(dgname, 'NAXIS2', ext=1) if sci_naxis1 <= dg_naxis1 or sci_naxis2 <= dg_naxis2: - print 'Only full size (old style) XY file was found.' - print 'DGEO correction will not be applied.\n' + print 'Only full size (old style) NPL file was found.' + print 'Non-polynomial distortion correction will not be applied.\n' return True else: return False @@ -179,18 +182,18 @@ def isOldStyleDGEO(fname, dgname): def applyD2ImCorr(fname, d2imcorr): applyD2IMCorr = True try: - # get DGEOFILE kw from primary header + # get D2IMFILE kw from primary header fd2im0 = pyfits.getval(fname, 'D2IMFILE') if fd2im0 == 'N/A': return False fd2im0 = fileutil.osfn(fd2im0) if not fileutil.findFile(fd2im0): print 'Kw D2IMFILE exists in primary header but file %s not found\n' % fd2im0 - print 'DGEO correction will not be applied\n' + print 'Detector to image correction will not be applied\n' applyD2IMCorr = False return applyD2IMCorr try: - # get DGEOEXT kw from first extension header + # get D2IMEXT kw from first extension header fd2imext = pyfits.getval(fname, 'D2IMEXT', ext=1) fd2imext = fileutil.osfn(fd2imext) if fd2imext and fileutil.findFile(fd2imext): @@ -199,11 +202,12 @@ def applyD2ImCorr(fname, d2imcorr): else: applyD2IMCorr = False else: - # dgeo file defined in first extension may not be found - # but if a valid kw exists in the primary header, dgeo should be applied. + # D2IM file defined in first extension may not be found + # but if a valid kw exists in the primary header, + # detector to image correction should be applied. applyD2IMCorr = True except KeyError: - # the case of DGEOFILE kw present in primary header but DGEOEXT missing + # the case of D2IMFILE kw present in primary header but D2IMEXT missing # in first extension header applyD2IMCorr = True except KeyError: diff --git a/updatewcs/det2im.py b/updatewcs/det2im.py index 9009317..0aa8f2a 100644 --- a/updatewcs/det2im.py +++ b/updatewcs/det2im.py @@ -11,7 +11,8 @@ class DET2IMCorr(object): `fobj`: pyfits object Science file, for which a detector to image correction is available - + Uses a kw 'D2IMFILE' in the primary header to create an extension with + a detector to image correction. """ assert isinstance(fobj, pyfits.NP_pyfits.HDUList) diff --git a/updatewcs/dgeo.py b/updatewcs/dgeo.py index 11562ef..8f6b4d4 100644 --- a/updatewcs/dgeo.py +++ b/updatewcs/dgeo.py @@ -10,7 +10,7 @@ class DGEOCorr(object): Purpose ======= Defines a Lookup table prior distortion correction as per WCS paper IV. - It uses a reference file defined by the DGEOFILE keyword in the primary header. + It uses a reference file defined by the NPLOFILE (suffix 'NPL') keyword in the primary header. Algorithm ========= @@ -18,13 +18,13 @@ class DGEOCorr(object): and add it to the file object. - Add record-valued keywords which describe the lookup tables to the science extension header - - Add a keyword 'DGEOFILE' to the science extension header, whose - value is the reference file used to create the WCSVARR extension + - Add a keyword 'NPOLEXT' to the science extension header, whose + value is the reference file used to create the WCSDVARR extension If WCSDVARR extensions exist, subsequent updates will overwrite them. If not, they will be added to the file object. - It is assumed that the DGEO reference files were created to work with IDC tables + It is assumed that the NPL reference files were created to work with IDC tables but will be applied with SIP coefficients. A transformation is applied to correct for the fact that the lookup tables will be applied before the first order coefficients which are in the CD matrix when the SIP convention is used. @@ -34,26 +34,26 @@ class DGEOCorr(object): """ :Parameters: `fobj`: pyfits object - Science file, for which a distortion correction in a DGEOFILE is available + Science file, for which a distortion correction in a NPOLFILE is available """ assert isinstance(fobj, pyfits.NP_pyfits.HDUList) - cls.applyDgeoCorr(fobj) - dgfile = fobj[0].header['DGEOFILE'] + cls.applyNPOLCorr(fobj) + nplfile = fobj[0].header['NPOLFILE'] - new_kw = {'DGEOEXT': dgfile} + new_kw = {'NPOLEXT': nplfile} return new_kw updateWCS = classmethod(updateWCS) - def applyDgeoCorr(cls, fobj): + def applyNPOLCorr(cls, fobj): """ For each science extension in a pyfits file object: - create a WCSDVARR extension - update science header - add/update DGEOEXT keyword """ - dgfile = fileutil.osfn(fobj[0].header['DGEOFILE']) + nplfile = fileutil.osfn(fobj[0].header['NPOLFILE']) # Map WCSDVARR EXTVER numbers to extension numbers wcsdvarr_ind = cls.getWCSIndex(fobj) for ext in fobj: @@ -67,27 +67,27 @@ class DGEOCorr(object): binned = utils.getBinning(fobj, extversion) header = ext.header # get the data arrays from the reference file and transform them for use with SIP - dx,dy = cls.getData(dgfile, ccdchip) + dx,dy = cls.getData(nplfile, ccdchip) idccoeffs = cls.getIDCCoeffs(header) if idccoeffs != None: dx, dy = cls.transformData(dx,dy, idccoeffs) - # Determine EXTVER for the WCSDVARR extension from the DGEO file (EXTNAME, EXTVER) kw. + # Determine EXTVER for the WCSDVARR extension from the NPL file (EXTNAME, EXTVER) kw. # This is used to populate DPj.EXTVER kw wcsdvarr_x_version = 2 * extversion -1 wcsdvarr_y_version = 2 * extversion for ename in zip(['DX', 'DY'], [wcsdvarr_x_version,wcsdvarr_y_version],[dx, dy]): - cls.addSciExtKw(header, wdvarr_ver=ename[1], dgeo_extname=ename[0]) - hdu = cls.createDgeoHDU(header, dgeofile=dgfile, \ - wdvarr_ver=ename[1], dgeo_extname=ename[0], data=ename[2],ccdchip=ccdchip, binned=binned) + cls.addSciExtKw(header, wdvarr_ver=ename[1], npol_extname=ename[0]) + hdu = cls.createNpolHDU(header, npolfile=nplfile, \ + wdvarr_ver=ename[1], npl_extname=ename[0], data=ename[2],ccdchip=ccdchip, binned=binned) if wcsdvarr_ind: fobj[wcsdvarr_ind[ename[1]]] = hdu else: fobj.append(hdu) - applyDgeoCorr = classmethod(applyDgeoCorr) + applyNPOLCorr = classmethod(applyNPOLCorr) def getWCSIndex(cls, fobj): @@ -110,12 +110,12 @@ class DGEOCorr(object): getWCSIndex = classmethod(getWCSIndex) - def addSciExtKw(cls, hdr, wdvarr_ver=None, dgeo_extname=None): + def addSciExtKw(cls, hdr, wdvarr_ver=None, npol_extname=None): """ Adds kw to sci extension to define WCSDVARR lookup table extensions """ - if dgeo_extname =='DX': + if npol_extname =='DX': j=1 else: j=2 @@ -143,24 +143,24 @@ class DGEOCorr(object): addSciExtKw = classmethod(addSciExtKw) - def getData(cls,dgfile, ccdchip): + def getData(cls,nplfile, ccdchip): """ Get the data arrays from the reference DGEO files Make sure 'CCDCHIP' in the dgeo file matches "CCDCHIP' in the science file. """ - dgf = pyfits.open(dgfile) - for ext in dgf: - dgextname = ext.header.get('EXTNAME',"") - dgccdchip = ext.header.get('CCDCHIP',1) - if dgextname == 'DX' and dgccdchip == ccdchip: + npl = pyfits.open(nplfile) + for ext in npl: + nplextname = ext.header.get('EXTNAME',"") + nplccdchip = ext.header.get('CCDCHIP',1) + if nplextname == 'DX' and nplccdchip == ccdchip: xdata = ext.data.copy() continue - elif dgextname == 'DY' and dgccdchip == ccdchip: + elif nplextname == 'DY' and nplccdchip == ccdchip: ydata = ext.data.copy() continue else: continue - dgf.close() + npl.close() return xdata, ydata getData = classmethod(getData) @@ -198,17 +198,17 @@ class DGEOCorr(object): getIDCCoeffs = classmethod(getIDCCoeffs) - def createDgeoHDU(cls, sciheader, dgeofile=None, wdvarr_ver=1, dgeo_extname=None,data = None, ccdchip=1, binned=1): + def createNpolHDU(cls, sciheader, npolfile=None, wdvarr_ver=1, npl_extname=None,data = None, ccdchip=1, binned=1): """ Creates an HDU to be added to the file object. """ - hdr = cls.createDgeoHdr(sciheader, dgeofile=dgeofile, wdvarr_ver=wdvarr_ver, dg_extname=dgeo_extname, ccdchip=ccdchip, binned=binned) + hdr = cls.createNpolHdr(sciheader, npolfile=npolfile, wdvarr_ver=wdvarr_ver, npl_extname=npl_extname, ccdchip=ccdchip, binned=binned) hdu=pyfits.ImageHDU(header=hdr, data=data) return hdu - createDgeoHDU = classmethod(createDgeoHDU) + createNpolHDU = classmethod(createNpolHDU) - def createDgeoHdr(cls, sciheader, dgeofile, wdvarr_ver, dg_extname, ccdchip, binned): + def createNpolHdr(cls, sciheader, npolfile, wdvarr_ver, npl_extname, ccdchip, binned): """ Creates a header for the WCSDVARR extension based on the DGEO reference file and sci extension header. The goal is to always work in image coordinates @@ -216,25 +216,25 @@ class DGEOCorr(object): i ssuch that a full size dgeo table is created and then shifted or scaled if the science image is a subarray or binned image. """ - dgf = pyfits.open(dgeofile) - for ext in dgf: + npl = pyfits.open(npolfile) + for ext in npl: #for i in range(len(dgf)): try: - dgextname = ext.header['EXTNAME'] - dgextver = ext.header['EXTVER'] + nplextname = ext.header['EXTNAME'] + nplextver = ext.header['EXTVER'] except KeyError: continue #dgccdchip = ext.header.get('CCDCHIP', 0) - dgccdchip = cls.get_ccdchip(dgf, extname=dgextname, extver=dgextver) - if dgextname == dg_extname and dgccdchip == ccdchip: - dgeo_header = ext.header + nplccdchip = cls.get_ccdchip(npl, extname=nplextname, extver=nplextver) + if nplextname == npl_extname and nplccdchip == ccdchip: + npol_header = ext.header break else: continue - dgf.close() + npl.close() - naxis = pyfits.getval(dgeofile, ext=1, key='NAXIS') - ccdchip = dgextname #dgeo_header['CCDCHIP'] + naxis = pyfits.getval(npolfile, ext=1, key='NAXIS') + ccdchip = nplextname #dgeo_header['CCDCHIP'] kw = { 'NAXIS': 'Size of the axis', 'CRPIX': 'Coordinate system reference pixel', @@ -250,10 +250,10 @@ class DGEOCorr(object): for i in range(1, naxis+1): si = str(i) - kw_val1['NAXIS'+si] = dgeo_header.get('NAXIS'+si) + kw_val1['NAXIS'+si] = npol_header.get('NAXIS'+si) kw_val1['CRPIX'+si] = kw_val1['NAXIS'+si]/2. - kw_val1['CDELT'+si] = float(dgeo_header.get('ONAXIS'+si))/ (kw_val1['NAXIS'+si] * binned) - kw_val1['CRVAL'+si] = (dgeo_header.get('ONAXIS'+si)/2. + \ + kw_val1['CDELT'+si] = float(npol_header.get('ONAXIS'+si))/ (kw_val1['NAXIS'+si] * binned) + kw_val1['CRVAL'+si] = (npol_header.get('ONAXIS'+si)/2. + \ sciheader.get('LTV'+si, 0.)) / binned @@ -287,7 +287,7 @@ class DGEOCorr(object): return hdr - createDgeoHdr = classmethod(createDgeoHdr) + createNpolHdr = classmethod(createNpolHdr) def get_ccdchip(cls, fobj, extname, extver): """ |