summaryrefslogtreecommitdiff
path: root/lib/stwcs/updatewcs/det2im.py
diff options
context:
space:
mode:
authorembray <embray@stsci.edu>2011-06-22 19:24:07 -0400
committerembray <embray@stsci.edu>2011-06-22 19:24:07 -0400
commitd93a10017d62f39d80167b45c1044a5e113f5994 (patch)
tree07967ea82a8550f8a8423bbe30046e798cf6c98e /lib/stwcs/updatewcs/det2im.py
parent708b4f32ac133fdb6157ec6e243dc76e32f9a84b (diff)
downloadstwcs_hcf-d93a10017d62f39d80167b45c1044a5e113f5994.tar.gz
Redoing the r13221-13223 merge in the actual trunk now. This updates trunk to the setup_refactoring branch (however, coords, pysynphot, and pywcs are still being pulled from the astrolib setup_refactoring branch. Will have to do that separately then update the svn:externals)
git-svn-id: http://svn.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/stwcs@13225 fe389314-cf27-0410-b35b-8c050e845b92
Diffstat (limited to 'lib/stwcs/updatewcs/det2im.py')
-rw-r--r--lib/stwcs/updatewcs/det2im.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/lib/stwcs/updatewcs/det2im.py b/lib/stwcs/updatewcs/det2im.py
new file mode 100644
index 0000000..fe683b4
--- /dev/null
+++ b/lib/stwcs/updatewcs/det2im.py
@@ -0,0 +1,200 @@
+from __future__ import division # confidence high
+
+import time
+import pyfits
+from stsci.tools import fileutil
+import utils
+
+import logging
+logger = logging.getLogger('stwcs.updatewcs.Det2IM')
+
+class DET2IMCorr(object):
+ """
+ Stores a small correction to the detector coordinates as a d2imarr
+ extension in the science file.
+
+ Notes
+ -----
+ For the case of ACS/WFC every 68th column is wider than the rest.
+ To compensate for this a small correction needs to be applied to the
+ detector coordinates. We call this a detector to image transformation.
+ The so obtained image coordinates are the input to all other distortion
+ corrections. The correction is originally stored in an external
+ reference file pointed to by 'D2IMFILE' keyword in the primary header.
+ This class attaches the correction array as an extension to the science
+ file with extname = `d2imarr`.
+
+ Other keywords used in this correction are:
+
+ `AXISCORR`: integer (1 or 2) - axis to which the detector to image
+ correction is applied
+
+ `D2IMEXT`: string = name of reference file which was used to create
+ the lookup table extension
+
+ `D2IMERR`: float, optional - maximum value of the correction
+
+ """
+ def updateWCS(cls, fobj):
+ """
+ Parameters
+ ----------
+ fobj: pyfits object
+ Science file, for which a detector to image correction
+ is available
+
+ Notes
+ -----
+ Uses the file pointed to in the primary header keyword 'D2IMFILE'
+ to create an extension with a detector to image correction.
+ """
+ logger.info("\n\tStarting Det2IM Correction: %s" % time.asctime())
+ try:
+ assert isinstance(fobj, pyfits.HDUList)
+ except AssertionError:
+ logger.exception('\n\tInput must be a pyfits.HDUList object')
+ raise
+
+ d2imfile = fileutil.osfn(fobj[0].header['D2IMFILE'])
+ axiscorr = cls.getAxisCorr(d2imfile)
+ d2imerr = pyfits.getdata(d2imfile, ext=1).max()
+ if axiscorr == None:
+ new_kw = {}
+ else:
+ new_kw = {'D2IMEXT': d2imfile, 'AXISCORR': axiscorr, 'D2IMERR': d2imerr}
+ cls.applyDet2ImCorr(fobj,axiscorr)
+ cls.updatehdr(fobj, new_kw)
+
+ updateWCS = classmethod(updateWCS)
+
+ def getAxisCorr(cls, refname):
+ try:
+ direction = pyfits.getval(refname, ext=1, key='EXTNAME')
+ if direction == 'DX': return 1
+ elif direction == 'DY': return 2
+ else:
+ logger.warning('\n\tDET2IM correction expects the reference file to have \
+ an EXTNAME keyword of value "DX" or "DY", EXTNAMe %s detected' % direction)
+ return None
+ except KeyError:
+ logger.exception("\n\tD2IMFILE %s is missing EXTNAME keyword. Unable to determine axis \
+ to which to apply the correction." % refname)
+ direction = None
+ return direction
+ getAxisCorr = classmethod(getAxisCorr)
+
+ def applyDet2ImCorr(cls,fobj, axiscorr):
+ binned = utils.getBinning(fobj)
+ hdu = cls.createDgeoHDU(fobj, axiscorr, binned)
+ d2imarr_ind = cls.getD2imIndex(fobj)
+ if d2imarr_ind:
+ fobj[d2imarr_ind] = hdu
+ else:
+ fobj.append(hdu)
+ applyDet2ImCorr = classmethod(applyDet2ImCorr)
+
+ def getD2imIndex(cls,fobj):
+ index = None
+ for e in range(len(fobj)):
+ try:
+ ename = fobj[e].header['EXTNAME']
+ except KeyError:
+ continue
+ if ename == 'D2IMARR':
+ index = e
+ return index
+ getD2imIndex = classmethod(getD2imIndex)
+
+ def createDgeoHDU(cls, fobj, axiscorr, binned=1):
+ d2imfile = fileutil.osfn(fobj[0].header['D2IMFILE'])
+ d2im_data = pyfits.getdata(d2imfile, ext=1)
+ sci_hdr = fobj['sci',1].header
+ d2im_hdr = cls.createDet2ImHdr(fobj, binned)
+ hdu = pyfits.ImageHDU(header=d2im_hdr, data=d2im_data)
+
+ return hdu
+
+ createDgeoHDU = classmethod(createDgeoHDU)
+
+ def createDet2ImHdr(cls, fobj, binned=1):
+ """
+ Creates a header for the D2IMARR extension based on the
+ reference file recorded in D2IMFILE keyword in the primary header.
+ fobj - the science file
+
+ """
+ d2imfile = fileutil.osfn(fobj[0].header['D2IMFILE'])
+ axiscorr = cls.getAxisCorr(d2imfile)
+ sci_hdr = fobj[1].header
+ data_shape = pyfits.getdata(d2imfile, ext=1).shape
+ naxis = pyfits.getval(d2imfile, ext=1, key='NAXIS')
+
+ kw = { 'NAXIS': 'Size of the axis',
+ 'CRPIX': 'Coordinate system reference pixel',
+ 'CRVAL': 'Coordinate system value at reference pixel',
+ 'CDELT': 'Coordinate increment along axis'}
+
+ kw_comm1 = {}
+ kw_val1 = {}
+ for key in kw.keys():
+ for i in range(1, naxis+1):
+ si = str(i)
+ kw_comm1[key+si] = kw[key]
+
+ for i in range(1, naxis+1):
+ si = str(i)
+ kw_val1['NAXIS'+si] = data_shape[i-1]
+ kw_val1['CRPIX'+si] = data_shape[i-1]/2.
+ kw_val1['CDELT'+si] = 1./binned
+ kw_val1['CRVAL'+si] = (sci_hdr.get('NAXIS'+si, 1)/2. + \
+ sci_hdr.get('LTV'+si, 0.)) / binned
+
+
+ kw_comm0 = {'XTENSION': 'Image extension',
+ 'BITPIX': 'IEEE floating point',
+ 'NAXIS': 'Number of axes',
+ 'EXTNAME': 'WCS distortion array',
+ 'EXTVER': 'Distortion array version number',
+ 'PCOUNT': 'Special data area of size 0',
+ 'GCOUNT': 'One data group',
+ 'AXISCORR': 'Direction in which the det2im correction is applied'}
+
+ kw_val0 = { 'XTENSION': 'IMAGE',
+ 'BITPIX': -32,
+ 'NAXIS': naxis,
+ 'EXTNAME': 'D2IMARR',
+ 'EXTVER': 1,
+ 'PCOUNT': 0,
+ 'GCOUNT': 1,
+ 'AXISCORR': axiscorr
+ }
+
+
+ cdl = pyfits.CardList()
+ for key in kw_comm0.keys():
+ cdl.append(pyfits.Card(key=key, value=kw_val0[key], comment=kw_comm0[key]))
+ for key in kw_comm1.keys():
+ cdl.append(pyfits.Card(key=key, value=kw_val1[key], comment=kw_comm1[key]))
+
+ hdr = pyfits.Header(cards=cdl)
+ return hdr
+
+ createDet2ImHdr = classmethod(createDet2ImHdr)
+
+ def updatehdr(cls, fobj, kwdict):
+ """
+ Update extension headers to keep record of the files used for the
+ detector to image correction.
+ """
+ for ext in fobj:
+ try:
+ extname = ext.header['EXTNAME'].lower()
+ except KeyError:
+ continue
+ if extname == 'sci':
+ for kw in kwdict:
+ ext.header.update(kw, kwdict[kw])
+ else:
+ continue
+ updatehdr = classmethod(updatehdr)
+