diff options
-rw-r--r-- | lib/stwcs/distortion/coeff_converter.py | 22 | ||||
-rw-r--r-- | lib/stwcs/distortion/utils.py | 63 | ||||
-rw-r--r-- | lib/stwcs/updatewcs/__init__.py | 45 | ||||
-rw-r--r-- | lib/stwcs/updatewcs/apply_corrections.py | 80 | ||||
-rw-r--r-- | lib/stwcs/updatewcs/det2im.py | 18 | ||||
-rw-r--r-- | lib/stwcs/updatewcs/npol.py | 138 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/altwcs.py | 126 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/convertwcs.py | 6 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/getinput.py | 16 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/headerlet.py | 221 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/hstwcs.py | 32 | ||||
-rw-r--r-- | lib/stwcs/wcsutil/instruments.py | 125 |
12 files changed, 450 insertions, 442 deletions
diff --git a/lib/stwcs/distortion/coeff_converter.py b/lib/stwcs/distortion/coeff_converter.py index f2eb4ad..bbad867 100644 --- a/lib/stwcs/distortion/coeff_converter.py +++ b/lib/stwcs/distortion/coeff_converter.py @@ -7,7 +7,7 @@ import pywcs def sip2idc(wcs): """ Converts SIP style coefficients to IDCTAB coefficients. - + :Parameters: `wcs`: pyfits.Header or pywcs.WCS object """ @@ -47,11 +47,11 @@ def sip2idc(wcs): else: print 'Input to sip2idc must be a PyFITS header or a wcsutil.HSTWCS object\n' return - - + + if None in [ocx10, ocx11, ocy10, ocy11]: print 'First order IDC coefficients not found, exiting ...\n' - return + return idc_coeff = np.array([[ocx11, ocx10], [ocy11, ocy10]]) cx = np.zeros((order+1,order+1), dtype=np.double) cy = np.zeros((order+1,order+1), dtype=np.double) @@ -62,12 +62,12 @@ def sip2idc(wcs): idcval = np.dot(idc_coeff, sipval) cx[n,m] = idcval[0] cy[n,m] = idcval[1] - + cx[1,0] = ocx10 cx[1,1] = ocx11 cy[1,0] = ocy10 cy[1,1] = ocy11 - + return cx, cy def _read_sip_kw(header): @@ -100,7 +100,7 @@ def _read_sip_kw(header): else: a = None b = None - + return a , b @@ -113,7 +113,7 @@ def idc2sip(wcsobj, idctab = None): cy10 = wcsobj.cy10 cy11 = wcsobj.cy11 except AttributeError: - print + print try: order = wcs.sip.a_order except AttributeError: @@ -122,7 +122,7 @@ def idc2sip(wcsobj, idctab = None): else: print 'Input to sip2idc must be a PyFITS header or a wcsutil.HSTWCS object\n' return - + if None in [ocx10, ocx11, ocy10, ocy11]: print 'First order IDC coefficients not found, exiting ...\n' return @@ -136,6 +136,6 @@ def idc2sip(wcsobj, idctab = None): idcval = numpy.dot(idc_coeff, sipval) cx[m,n-m] = idcval[0] cy[m,n-m] = idcval[1] - + return cx, cy -"""
\ No newline at end of file +""" diff --git a/lib/stwcs/distortion/utils.py b/lib/stwcs/distortion/utils.py index b70f474..6cff569 100644 --- a/lib/stwcs/distortion/utils.py +++ b/lib/stwcs/distortion/utils.py @@ -1,8 +1,7 @@ -from __future__ import division # confidence high -import os +from __future__ import division # confidence high +import os import numpy as np import pywcs -import pyfits from stwcs import wcsutil from numpy import sqrt, arctan2 from stsci.tools import fileutil @@ -10,14 +9,14 @@ from stsci.tools import fileutil def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): """ Create an output WCS. - + Parameters ---------- list_of_wcsobj: Python list a list of HSTWCS objects - ref_wcs: an HSTWCS object + ref_wcs: an HSTWCS object to be used as a reference WCS, in case outwcs is None. - if ref_wcs is None (default), the first member of the list + if ref_wcs is None (default), the first member of the list is used as a reference outwcs: an HSTWCS object the tangent plane defined by this object is used as a reference @@ -26,16 +25,16 @@ def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): """ fra_dec = np.vstack([w.calcFootprint() for w in list_of_wcsobj]) wcsname = list_of_wcsobj[0].wcs.name - - # This new algorithm may not be strictly necessary, but it may be more + + # This new algorithm may not be strictly necessary, but it may be more # robust in handling regions near the poles or at 0h RA. - crval1,crval2 = computeFootprintCenter(fra_dec) + crval1,crval2 = computeFootprintCenter(fra_dec) crval = np.array([crval1,crval2], dtype=np.float64) # this value is now zero-based if owcs is None: if ref_wcs == None: ref_wcs = list_of_wcsobj[0].deepcopy() - if undistort: + if undistort: outwcs = undistortWCS(ref_wcs) else: outwcs = ref_wcs.deepcopy() @@ -58,7 +57,7 @@ def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): tanpix = outwcs.wcs.s2p(fra_dec, 0)['pixcrd'] # shift crpix to take into account (floating-point value of) position of - # corner pixel relative to output frame size: no rounding necessary... + # corner pixel relative to output frame size: no rounding necessary... newcrpix = np.array([crpix[0]+tanpix[:,0].min(), crpix[1]+ tanpix[:,1].min()]) @@ -71,37 +70,37 @@ def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): def computeFootprintCenter(edges): """ Geographic midpoint in spherical coords for points defined by footprints. Algorithm derived from: http://www.geomidpoint.com/calculation.html - - This algorithm should be more robust against discontinuities at the poles. + + This algorithm should be more robust against discontinuities at the poles. """ alpha = np.deg2rad(edges[:,0]) dec = np.deg2rad(edges[:,1]) - + xmean = np.mean(np.cos(dec)*np.cos(alpha)) ymean = np.mean(np.cos(dec)*np.sin(alpha)) zmean = np.mean(np.sin(dec)) - + crval1 = np.rad2deg(np.arctan2(ymean,xmean))%360.0 crval2 = np.rad2deg(np.arctan2(zmean,np.sqrt(xmean*xmean+ymean*ymean))) - + return crval1,crval2 def undistortWCS(wcsobj): """ Creates an undistorted linear WCS by applying the IDCTAB distortion model - to a 3-point square. The new ORIENTAT angle is calculated as well as the + to a 3-point square. The new ORIENTAT angle is calculated as well as the plate scale in the undistorted frame. """ assert isinstance(wcsobj, pywcs.WCS) import coeff_converter - + cx, cy = coeff_converter.sip2idc(wcsobj) - # cx, cy can be None because either there is no model available + # cx, cy can be None because either there is no model available # or updatewcs was not run. if cx == None or cy == None: if foundIDCTAB(wcsobj.idctab): m = """IDCTAB is present but distortion model is missing. - Run updatewcs() to update the headers or + Run updatewcs() to update the headers or pass 'undistort=False' keyword to output_wcs().\n """ raise RuntimeError, m @@ -116,7 +115,7 @@ def undistortWCS(wcsobj): #order = wcsobj.sip.a_order pscale = wcsobj.idcscale #pixref = np.array([wcsobj.sip.SIPREF1, wcsobj.sip.SIPREF2]) - + tan_pix = apply_idc(px, cx, cy, wcsobj.wcs.crpix, pscale, order=1) xc = tan_pix[:,0] yc = tan_pix[:,1] @@ -131,8 +130,8 @@ def undistortWCS(wcsobj): if ( _det == 0.0): print 'Singular matrix in updateWCS, aborting ...' return - - lin_wcsobj = pywcs.WCS() + + lin_wcsobj = pywcs.WCS() cd_inv = np.linalg.inv(cd_mat) cd = np.dot(wcsobj.wcs.cd, cd_inv).astype(np.float64) lin_wcsobj.wcs.cd = cd @@ -149,16 +148,16 @@ def apply_idc(pixpos, cx, cy, pixref, pscale= None, order=None): """ Apply the IDCTAB polynomial distortion model to pixel positions. pixpos must be already corrected for ltv1/2. - + Parameters ---------- pixpos: a 2D numpy array of (x,y) pixel positions to be distortion corrected cx, cy: IDC model distortion coefficients pixref: reference opixel position - + """ if cx == None: - return pixpos + return pixpos if order is None: print 'Unknown order of distortion model \n' @@ -166,23 +165,23 @@ def apply_idc(pixpos, cx, cy, pixref, pscale= None, order=None): if pscale is None: print 'Unknown model plate scale\n' return pixpos - + # Apply in the same way that 'drizzle' would... _cx = cx/pscale _cy = cy/ pscale _p = pixpos - + # Do NOT include any zero-point terms in CX,CY here # as they should not be scaled by plate-scale like rest # of coeffs... This makes the computations consistent # with 'drizzle'. WJH 17-Feb-2004 _cx[0,0] = 0. _cy[0,0] = 0. - + dxy = _p - pixref # Apply coefficients from distortion model here... - - c = _p * 0. + + c = _p * 0. for i in range(order+1): for j in range(i+1): c[:,0] = c[:,0] + _cx[i][j] * pow(dxy[:,0],j) * pow(dxy[:,1],(i-j)) @@ -194,7 +193,7 @@ def foundIDCTAB(idctab): idctab_found = True try: idctab = fileutil.osfn(idctab) - if idctab == 'N/A' or idctab == "": + if idctab == 'N/A' or idctab == "": idctab_found = False if os.path.exists(idctab): idctab_found = True diff --git a/lib/stwcs/updatewcs/__init__.py b/lib/stwcs/updatewcs/__init__.py index 4859343..622ac35 100644 --- a/lib/stwcs/updatewcs/__init__.py +++ b/lib/stwcs/updatewcs/__init__.py @@ -11,7 +11,7 @@ try: from pywcs import __version__ as pywcsversion except: pywcsversion = 'UNKNOWN' - + import utils, corrections, makewcs import npol, det2im from stsci.tools import parseinput, fileutil @@ -100,7 +100,7 @@ def updatewcs(input, vacorr=True, tddcorr=True, npolcorr=True, d2imcorr=True, cleanWCS(f) makecorr(f, acorr) - + return files def makecorr(fname, allowed_corr): @@ -153,14 +153,14 @@ def makecorr(fname, allowed_corr): utils.extract_rootname(idcname,suffix='_idc')]) else: wname = " " hdr.update('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 @@ -170,28 +170,30 @@ def makecorr(fname, allowed_corr): f[1].header.update(kw, kw2update[kw]) # Finally record the version of the software which updated the WCS if f[0].header.has_key('HISTORY'): - f[0].header.update(key='UPWCSVER', value=stwcsversion, + f[0].header.update(key='UPWCSVER', value=stwcsversion, comment="Version of STWCS used to updated the WCS", before='HISTORY') - f[0].header.update(key='PYWCSVER', value=pywcsversion, + f[0].header.update(key='PYWCSVER', value=pywcsversion, comment="Version of PYWCS used to updated the WCS", before='HISTORY') elif f[0].header.has_key('ASN_MTYP'): - f[0].header.update(key='UPWCSVER', value=stwcsversion, + f[0].header.update(key='UPWCSVER', value=stwcsversion, comment="Version of STWCS used to updated the WCS", after='ASN_MTYP') - f[0].header.update(key='PYWCSVER', value=pywcsversion, + f[0].header.update(key='PYWCSVER', value=pywcsversion, 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.ascard)-1,0,-1): - if f[0].header[i].strip() != '': - break - f[0].header.update(key='UPWCSVER', value=stwcsversion, - comment="Version of STWCS used to updated the WCS",after=i) - f[0].header.update(key='PYWCSVER', value=pywcsversion, - comment="Version of PYWCS used to updated the WCS",after=i) + for i in range(len(f[0].header) - 1, 0, -1): + if f[0].header[i].strip() != '': + break + f[0].header.set('UPWCSVER', stwcsversion, + "Version of STWCS used to updated the WCS", + after=i) + f[0].header.set('PYWCSVER', pywcsversion, + "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.update('DISTNAME', distdict['DISTNAME']) - f[0].header.update('SIPNAME', distdict['SIPNAME']) + f[0].header['DISTNAME'] = distdict['DISTNAME'] + f[0].header['SIPNAME'] = distdict['SIPNAME'] f.close() def copyWCS(w, ehdr): @@ -330,10 +332,11 @@ def checkFiles(input): def newIDCTAB(fname): #When this is called we know there's a kw IDCTAB in the header - idctab = fileutil.osfn(pyfits.getval(fname, 'IDCTAB')) + hdul = pyfits.open(fname) + idctab = fileutil.osfn(hdul[0].header['IDCTAB']) try: #check for the presence of IDCTAB in the first extension - oldidctab = fileutil.osfn(pyfits.getval(fname, 'IDCTAB', ext=1)) + oldidctab = fileutil.osfn(hdul[1].header['IDCTAB']) except KeyError: return False if idctab == oldidctab: @@ -344,11 +347,11 @@ def newIDCTAB(fname): def cleanWCS(fname): # A new IDCTAB means all previously computed WCS's are invalid # We are deleting all of them except the original OPUS WCS.nvalidates all WCS's. - keys = wcsutil.wcskeys(pyfits.getheader(fname, ext=1)) f = pyfits.open(fname, mode='update') + keys = wcsutil.wcskeys(f[1].header) fext = range(len(f)) for key in keys: - wcsutil.deleteWCS(fname, ext=fext,wcskey=key) + wcsutil.deleteWCS(fname, ext=fext, wcskey=key) def getCorrections(instrument): """ diff --git a/lib/stwcs/updatewcs/apply_corrections.py b/lib/stwcs/updatewcs/apply_corrections.py index fbcb502..fe1c1af 100644 --- a/lib/stwcs/updatewcs/apply_corrections.py +++ b/lib/stwcs/updatewcs/apply_corrections.py @@ -31,7 +31,7 @@ cnames = {'DET2IMCorr': 'Detector to Image Correction', 'VACorr': 'Velocity Aberration Correction', 'NPOLCorr': 'Lookup Table Distortion' } - + def setCorrections(fname, vacorr=True, tddcorr=True, npolcorr=True, d2imcorr=True): """ Creates a list of corrections to be applied to a file @@ -41,20 +41,20 @@ def setCorrections(fname, vacorr=True, tddcorr=True, npolcorr=True, d2imcorr=Tru instrument = pyfits.getval(fname, 'INSTRUME') # make a copy of this list ! acorr = allowed_corrections[instrument][:] - + # Check if idctab is present on disk - # If kw IDCTAB is present in the header but the file is + # If kw IDCTAB is present in the header but the file is # not found on disk, do not run TDDCorr, MakeCWS and CompSIP if not foundIDCTAB(fname): if 'TDDCorr' in acorr: acorr.remove('TDDCorr') if 'MakeWCS' in acorr: acorr.remove('MakeWCS') - if 'CompSIP' in acorr: acorr.remove('CompSIP') - + if 'CompSIP' in acorr: acorr.remove('CompSIP') + if 'VACorr' in acorr and vacorr==False: acorr.remove('VACorr') if 'TDDCorr' in acorr: tddcorr = applyTDDCorr(fname, tddcorr) if tddcorr == False: acorr.remove('TDDCorr') - + if 'NPOLCorr' in acorr: npolcorr = applyNpolCorr(fname, npolcorr) if npolcorr == False: acorr.remove('NPOLCorr') @@ -69,13 +69,13 @@ def foundIDCTAB(fname): idctab = fileutil.osfn(pyfits.getval(fname, 'IDCTAB')) except KeyError: return False - if idctab == 'N/A' or idctab == "": + if idctab == 'N/A' or idctab == "": return False if os.path.exists(idctab): return True else: return False - + def applyTDDCorr(fname, utddcorr): """ The default value of tddcorr for all ACS images is True. @@ -84,20 +84,22 @@ def applyTDDCorr(fname, utddcorr): - the detector is WFC - the idc table specified in the primary header is available. """ - instrument = pyfits.getval(fname, 'INSTRUME') + + phdr = pyfits.getheader(fname) + instrument = phdr['INSTRUME'] try: - detector = pyfits.getval(fname, 'DETECTOR') + detector = phdr['DETECTOR'] except KeyError: detector = None try: - tddswitch = pyfits.getval(fname, 'TDDCORR') + tddswitch = phdr['TDDCORR'] except KeyError: tddswitch = 'PERFORM' - + if instrument == 'ACS' and detector == 'WFC' and utddcorr == True and tddswitch == 'PERFORM': tddcorr = True try: - idctab = pyfits.getval(fname, 'IDCTAB') + idctab = phdr['IDCTAB'] except KeyError: tddcorr = False #print "***IDCTAB keyword not found - not applying TDD correction***\n" @@ -106,21 +108,21 @@ def applyTDDCorr(fname, utddcorr): else: tddcorr = False #print "***IDCTAB file not found - not applying TDD correction***\n" - else: + else: tddcorr = False return tddcorr def applyNpolCorr(fname, unpolcorr): """ - Determines whether non-polynomial distortion lookup tables should be added - as extensions to the science file based on the 'NPOLFILE' keyword in the + 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 + The file used to generate the extensions is 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' npolfile, + 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' npolfile, then the lookup tables will be updated as 'WCSDVARR' extensions. """ applyNPOLCorr = True @@ -136,7 +138,7 @@ def applyNpolCorr(fname, unpolcorr): """ % fnpol0 logger.critical(msg) applyNPOLCorr = False - return applyNPOLCorr + return applyNPOLCorr try: # get NPOLEXT kw from first extension header fnpol1 = pyfits.getval(fname, 'NPOLEXT', ext=1) @@ -149,32 +151,34 @@ def applyNpolCorr(fname, unpolcorr): NPOL correction will not be applied.""" logger.info(msg) applyNPOLCorr = False - else: + else: # npl file defined in first extension may not be found - # but if a valid kw exists in the primary header, non-polynomial + # but if a valid kw exists in the primary header, non-polynomial #distortion correction should be applied. applyNPOLCorr = True except KeyError: - # the case of "NPOLFILE" kw present in primary header but "NPOLEXT" missing + # the case of "NPOLFILE" kw present in primary header but "NPOLEXT" missing # in first extension header applyNPOLCorr = True except KeyError: logger.info('\n\t"NPOLFILE" keyword not found in primary header') applyNPOLCorr = False - return applyNPOLCorr - + return applyNPOLCorr + if isOldStyleDGEO(fname, fnpol0): - applyNPOLCorr = False + applyNPOLCorr = False return (applyNPOLCorr and unpolcorr) def isOldStyleDGEO(fname, dgname): - # checks if the file defined in a NPOLFILE 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) - sci_naxis2 = pyfits.getval(fname, 'NAXIS2', ext=1) - dg_naxis1 = pyfits.getval(dgname, 'NAXIS1', ext=1) - dg_naxis2 = pyfits.getval(dgname, 'NAXIS2', ext=1) + + sci_hdr = pyfits.getheader(fname, ext=1) + dgeo_hdr = pyfits.getheader(dgname, ext=1) + sci_naxis1 = sci_hdr['NAXIS1'] + sci_naxis2 = sci_hdr['NAXIS2'] + dg_naxis1 = dgeo_hdr['NAXIS1'] + dg_naxis2 = dgeo_hdr['NAXIS2'] if sci_naxis1 <= dg_naxis1 or sci_naxis2 <= dg_naxis2: msg = """\n\tOnly full size (old style) DGEO file was found.\n Non-polynomial distortion correction will not be applied.""" @@ -182,7 +186,7 @@ def isOldStyleDGEO(fname, dgname): return True else: return False - + def applyD2ImCorr(fname, d2imcorr): applyD2IMCorr = True try: @@ -197,7 +201,7 @@ def applyD2ImCorr(fname, d2imcorr): logger.critical(msg) print msg applyD2IMCorr = False - return applyD2IMCorr + return applyD2IMCorr try: # get D2IMEXT kw from first extension header fd2imext = pyfits.getval(fname, 'D2IMEXT', ext=1) @@ -207,17 +211,17 @@ def applyD2ImCorr(fname, d2imcorr): applyD2IMCorr = True else: applyD2IMCorr = False - else: + else: # D2IM file defined in first extension may not be found - # but if a valid kw exists in the primary header, + # but if a valid kw exists in the primary header, # detector to image correction should be applied. applyD2IMCorr = True except KeyError: - # the case of D2IMFILE kw present in primary header but D2IMEXT missing + # the case of D2IMFILE kw present in primary header but D2IMEXT missing # in first extension header applyD2IMCorr = True except KeyError: print 'D2IMFILE keyword not found in primary header' applyD2IMCorr = False - return applyD2IMCorr + return applyD2IMCorr diff --git a/lib/stwcs/updatewcs/det2im.py b/lib/stwcs/updatewcs/det2im.py index b658d53..8235d83 100644 --- a/lib/stwcs/updatewcs/det2im.py +++ b/lib/stwcs/updatewcs/det2im.py @@ -126,8 +126,11 @@ class DET2IMCorr(object): 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, 'NAXIS', ext=1 ) + d2im = pyfits.open(d2imfile) + data_shape = d2im[1].shape + naxis = d2im[1].header['NAXIS'] + d2im_phdr = d2im[0].header + d2im.close() kw = { 'NAXIS': 'Size of the axis', 'CRPIX': 'Coordinate system reference pixel', @@ -170,24 +173,23 @@ class DET2IMCorr(object): } - cdl = pyfits.CardList() + cdl = [] for key in kw_comm0.keys(): - cdl.append(pyfits.Card(key=key, value=kw_val0[key], comment=kw_comm0[key])) + cdl.append((key, kw_val0[key], kw_comm0[key])) for key in kw_comm1.keys(): - cdl.append(pyfits.Card(key=key, value=kw_val1[key], comment=kw_comm1[key])) + cdl.append((key, kw_val1[key], kw_comm1[key])) # Now add keywords from NPOLFILE header to document source of calibration # include all keywords after and including 'FILENAME' from header - d2im_phdr = pyfits.getheader(d2imfile) start_indx = -1 end_indx = 0 - for c,i in zip(d2im_phdr,range(len(d2im_phdr))): + for i, c in enumerate(d2im_phdr): if c == 'FILENAME': start_indx = i if c == '': # remove blanks from end of header end_indx = i+1 break if start_indx >= 0: - for card in d2im_phdr[start_indx:end_indx]: + for card in d2im_phdr.cards[start_indx:end_indx]: cdl.append(card) hdr = pyfits.Header(cards=cdl) diff --git a/lib/stwcs/updatewcs/npol.py b/lib/stwcs/updatewcs/npol.py index 2607e48..a7b84da 100644 --- a/lib/stwcs/updatewcs/npol.py +++ b/lib/stwcs/updatewcs/npol.py @@ -11,35 +11,35 @@ logger = logging.getLogger('stwcs.updatewcs.npol') class NPOLCorr(object): """ Defines a Lookup table prior distortion correction as per WCS paper IV. - It uses a reference file defined by the NPOLFILE (suffix 'NPL') keyword + It uses a reference file defined by the NPOLFILE (suffix 'NPL') keyword in the primary header. - + Notes ----- - - Using extensions in the reference file create a WCSDVARR extensions + - Using extensions in the reference file create a WCSDVARR extensions and add them to the science file. - - Add record-valued keywords to the science extension header to describe + - Add record-valued keywords to the science extension header to describe the lookup tables. - Add a keyword 'NPOLEXT' to the science extension header to store the name of the reference file used to create the WCSDVARR extensions. - - If WCSDVARR extensions exist and `NPOLFILE` is different from `NPOLEXT`, - a subsequent update will overwrite the existing extensions. + + If WCSDVARR extensions exist and `NPOLFILE` is different from `NPOLEXT`, + a subsequent update will overwrite the existing extensions. If WCSDVARR extensions were not found in the science file, they will be added. - + 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 + 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. """ - + def updateWCS(cls, fobj): """ Parameters ---------- fobj: pyfits object Science file, for which a distortion correction in a NPOLFILE is available - + """ logger.info("\n\tStarting CompSIP: %s" %time.asctime()) try: @@ -47,14 +47,14 @@ class NPOLCorr(object): except AssertionError: logger.exception('\n\tInput must be a pyfits.HDUList object') raise - + cls.applyNPOLCorr(fobj) nplfile = fobj[0].header['NPOLFILE'] - + new_kw = {'NPOLEXT': nplfile} return new_kw - - updateWCS = classmethod(updateWCS) + + updateWCS = classmethod(updateWCS) def applyNPOLCorr(cls, fobj): """ @@ -79,15 +79,15 @@ class NPOLCorr(object): # get the data arrays from the reference file and transform them for use with SIP 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 NPL file (EXTNAME, EXTVER) kw. # This is used to populate DPj.EXTVER kw wcsdvarr_x_version = 2 * extversion -1 - wcsdvarr_y_version = 2 * extversion - + 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], npol_extname=ename[0]) hdu = cls.createNpolHDU(header, npolfile=nplfile, \ @@ -96,14 +96,14 @@ class NPOLCorr(object): fobj[wcsdvarr_ind[ename[1]]] = hdu else: fobj.append(hdu) - - + + applyNPOLCorr = classmethod(applyNPOLCorr) - + def getWCSIndex(cls, fobj): - + """ - If fobj has WCSDVARR extensions: + If fobj has WCSDVARR extensions: returns a mapping of their EXTVER kw to file object extension numbers if fobj does not have WCSDVARR extensions: an empty dictionary is returned @@ -118,19 +118,19 @@ class NPOLCorr(object): wcsd[fobj[e].header['EXTVER']] = e logger.debug("A map of WSCDVARR externsions %s" % wcsd) return wcsd - + getWCSIndex = classmethod(getWCSIndex) - + def addSciExtKw(cls, hdr, wdvarr_ver=None, npol_extname=None): """ Adds kw to sci extension to define WCSDVARR lookup table extensions - + """ if npol_extname =='DX': j=1 else: j=2 - + cperror = 'CPERROR%s' %j cpdis = 'CPDIS%s' %j dpext = 'DP%s.' %j + 'EXTVER' @@ -140,24 +140,24 @@ class NPOLCorr(object): keys = [cperror, cpdis, dpext, dpnaxes, dpaxis1, dpaxis2] values = {cperror: 0.0, cpdis: 'Lookup', dpext: wdvarr_ver, dpnaxes: 2, dpaxis1: 1, dpaxis2: 2} - - comments = {cperror: 'Maximum error of NPOL correction for axis %s' % j, - cpdis: 'Prior distortion funcion type', - dpext: 'Version number of WCSDVARR extension containing lookup distortion table', + + comments = {cperror: 'Maximum error of NPOL correction for axis %s' % j, + cpdis: 'Prior distortion funcion type', + dpext: 'Version number of WCSDVARR extension containing lookup distortion table', dpnaxes: 'Number of independent variables in distortion function', - dpaxis1: 'Axis number of the jth independent variable in a distortion function', + dpaxis1: 'Axis number of the jth independent variable in a distortion function', dpaxis2: 'Axis number of the jth independent variable in a distortion function' } # Look for HISTORY keywords. If present, insert new keywords before them - before_key = 'HISTORY' - if before_key not in hdr.ascard: + before_key = 'HISTORY' + if before_key not in hdr: before_key = None for key in keys: hdr.update(key=key, value=values[key], comment=comments[key], before=before_key) - + addSciExtKw = classmethod(addSciExtKw) - + def getData(cls,nplfile, ccdchip): """ Get the data arrays from the reference NPOL files @@ -178,7 +178,7 @@ class NPOLCorr(object): npl.close() return xdata, ydata getData = classmethod(getData) - + def transformData(cls, dx, dy, coeffs): """ Transform the NPOL data arrays for use with SIP @@ -187,9 +187,9 @@ class NPOLCorr(object): ndx.shape = dx.shape ndy.shape=dy.shape return ndx, ndy - + transformData = classmethod(transformData) - + def getIDCCoeffs(cls, header): """ Return a matrix of the scaled first order IDC coefficients. @@ -209,11 +209,11 @@ class NPOLCorr(object): except KeyError: logger.exception("IDCSCALE not found in header - setting it to 1.") idcscale = 1 - + return np.linalg.inv(coeffs/idcscale) - + getIDCCoeffs = classmethod(getIDCCoeffs) - + 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. @@ -221,15 +221,15 @@ class NPOLCorr(object): 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 - + createNpolHDU = classmethod(createNpolHDU) - + def createNpolHdr(cls, sciheader, npolfile, wdvarr_ver, npl_extname, ccdchip, binned): """ - Creates a header for the WCSDVARR extension based on the NPOL reference file + Creates a header for the WCSDVARR extension based on the NPOL reference file and sci extension header. The goal is to always work in image coordinates - (also for subarrays and binned images. The WCS for the WCSDVARR extension - i ssuch that a full size npol table is created and then shifted or scaled + (also for subarrays and binned images. The WCS for the WCSDVARR extension + i ssuch that a full size npol table is created and then shifted or scaled if the science image is a subarray or binned image. """ npl = pyfits.open(npolfile) @@ -247,30 +247,30 @@ class NPOLCorr(object): else: continue npl.close() - - naxis = pyfits.getval(npolfile, 'NAXIS', ext=1) + + naxis = npl[1].header['NAXIS'] ccdchip = nplextname #npol_header['CCDCHIP'] - - kw = { 'NAXIS': 'Size of the axis', + + kw = { 'NAXIS': 'Size of the axis', 'CDELT': 'Coordinate increment along axis', - 'CRPIX': 'Coordinate system reference pixel', + 'CRPIX': 'Coordinate system reference pixel', 'CRVAL': 'Coordinate system value at reference pixel', } - + 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] = npol_header.get('NAXIS'+si) kw_val1['CDELT'+si] = npol_header.get('CDELT'+si, 1.0) kw_val1['CRPIX'+si] = npol_header.get('CRPIX'+si, 0.0) kw_val1['CRVAL'+si] = npol_header.get('CRVAL'+si, 0.0) - + kw_comm0 = {'XTENSION': 'Image extension', 'BITPIX': 'IEEE floating point', 'NAXIS': 'Number of axes', @@ -279,7 +279,7 @@ class NPOLCorr(object): 'PCOUNT': 'Special data area of size 0', 'GCOUNT': 'One data group', } - + kw_val0 = { 'XTENSION': 'IMAGE', 'BITPIX': -32, 'NAXIS': naxis, @@ -289,32 +289,32 @@ class NPOLCorr(object): 'GCOUNT': 1, 'CCDCHIP': ccdchip, } - - cdl = pyfits.CardList() + + cdl = [] for key in kw_comm0.keys(): - cdl.append(pyfits.Card(key=key, value=kw_val0[key], comment=kw_comm0[key])) + cdl.append((key, kw_val0[key], kw_comm0[key])) for key in kw_comm1.keys(): - cdl.append(pyfits.Card(key=key, value=kw_val1[key], comment=kw_comm1[key])) + cdl.append((key, kw_val1[key], kw_comm1[key])) # Now add keywords from NPOLFILE header to document source of calibration # include all keywords after and including 'FILENAME' from header start_indx = -1 end_indx = 0 - for c,i in zip(npol_phdr,range(len(npol_phdr))): + for i, c in enumerate(npol_phdr): if c == 'FILENAME': start_indx = i if c == '': # remove blanks from end of header end_indx = i+1 break if start_indx >= 0: - for card in npol_phdr[start_indx:end_indx]: + for card in npol_phdr.cards[start_indx:end_indx]: cdl.append(card) - + hdr = pyfits.Header(cards=cdl) - + return hdr - + createNpolHdr = classmethod(createNpolHdr) - + def get_ccdchip(cls, fobj, extname, extver): """ Given a science file or npol file determine CCDCHIP @@ -331,6 +331,6 @@ class NPOLCorr(object): elif fobj[0].header['INSTRUME'] == 'NICMOS': ccdchip = fobj[extname, extver].header['CAMERA'] return ccdchip - + get_ccdchip = classmethod(get_ccdchip) -
\ No newline at end of file + diff --git a/lib/stwcs/wcsutil/altwcs.py b/lib/stwcs/wcsutil/altwcs.py index 064b2ca..d68a0d8 100644 --- a/lib/stwcs/wcsutil/altwcs.py +++ b/lib/stwcs/wcsutil/altwcs.py @@ -35,9 +35,9 @@ def archiveWCS(fname, ext, wcskey=" ", wcsname=" ", reusekey=False): Examples -------- - Copy the primary WCS of an in memory headrlet object to an + Copy the primary WCS of an in memory headrlet object to an alternate WCS with key 'T' - + >>> hlet=headerlet.createHeaderlet('junk.fits', 'hdr1.fits') >>> altwcs.wcskeys(hlet[1].header) ['A'] @@ -45,7 +45,7 @@ def archiveWCS(fname, ext, wcskey=" ", wcsname=" ", reusekey=False): >>> altwcs.wcskeys(hlet[1].header) ['A', 'T'] - + See Also -------- wcsutil.restoreWCS: Copy an alternate WCS to the primary WCS @@ -63,10 +63,10 @@ def archiveWCS(fname, ext, wcskey=" ", wcsname=" ", reusekey=False): # Interpret input 'ext' value to get list of extensions to process ext = _buildExtlist(f, ext) - + if not wcskey and not wcsname: raise KeyError("Either wcskey or wcsname should be specified") - + wcsext = ext[0] if wcskey != " " and wcskey in wcskeys(f[wcsext].header) and not reusekey: closefobj(fname, f) @@ -112,23 +112,23 @@ def archiveWCS(fname, ext, wcskey=" ", wcsname=" ", reusekey=False): else: wkey = wcskey wname = wcsname - + for e in ext: hwcs = readAltWCS(f,e,wcskey=' ') if hwcs is None: continue wcsnamekey = 'WCSNAME' + wkey - f[e].header.update(key=wcsnamekey, value=wname) + f[e].header[wcsnamekey] = wname try: old_wcsname=hwcs.pop('WCSNAME') except: pass for k in hwcs.keys(): - + key = k[:7] + wkey - f[e].header.update(key=key, value=hwcs[k]) + f[e].header[key] = hwcs[k] closefobj(fname, f) def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "): @@ -138,16 +138,16 @@ def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "): Reads in a WCS defined with wcskey and saves it as the primary WCS. Goes sequentially through the list of extensions in ext. Alternatively uses 'fromext' and 'toext'. - + Parameters ---------- f: string or pyfits.HDUList object a file name or a file object - fromext: string + fromext: string extname from which to read in the alternate WCS, for example 'SCI' toext: string or python list - extname or a list of extnames to which the WCS will be copied as + extname or a list of extnames to which the WCS will be copied as primary, for example ['SCI', 'ERR', 'DQ'] wcskey: a charater "A"-"Z" - Used for one of 26 alternate WCS definitions. @@ -177,16 +177,16 @@ def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "): toext = [toext] # the case of an HDUList object in memory without an associated file - - #if fobj.filename() is not None: + + #if fobj.filename() is not None: # name = fobj.filename() - + simplefits = fu.isFits(fobj)[1] is 'simple' if simplefits: wcskeyext = 0 else: wcskeyext = 1 - + if wcskey == " ": if wcsname.strip(): wkey = getKeyFromName(fobj[wcskeyext].header, wcsname) @@ -199,7 +199,7 @@ def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "): closefobj(f, fobj) return wkey = wcskey - + countext = fu.countExtn(fobj, fromext) if not countext: raise KeyError("File does not have extension with extname %s", fromext) @@ -211,7 +211,7 @@ def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "): if fobj.filename() is not None: #fobj.writeto(name) closefobj(f, fobj) - + def restoreWCS(f, ext, wcskey=" ", wcsname=" "): """ Copy a WCS with key "WCSKEY" to the primary WCS @@ -219,7 +219,7 @@ def restoreWCS(f, ext, wcskey=" ", wcsname=" "): Reads in a WCS defined with wcskey and saves it as the primary WCS. Goes sequentially through the list of extensions in ext. Alternatively uses 'fromext' and 'toext'. - + Parameters ---------- @@ -255,16 +255,16 @@ def restoreWCS(f, ext, wcskey=" ", wcsname=" "): # the case of an HDUList object in memory without an associated file - - #if fobj.filename() is not None: + + #if fobj.filename() is not None: # name = fobj.filename() - + simplefits = fu.isFits(fobj)[1] is 'simple' if simplefits: wcskeyext = 0 else: wcskeyext = 1 - + if wcskey == " ": if wcsname.strip(): wkey = getKeyFromName(fobj[wcskeyext].header, wcsname) @@ -277,11 +277,11 @@ def restoreWCS(f, ext, wcskey=" ", wcsname=" "): closefobj(f, fobj) return wkey = wcskey - - + + for e in ext: _restore(fobj, wkey, fromextnum=e) - + if fobj.filename() is not None: #fobj.writeto(name) closefobj(f, fobj) @@ -325,10 +325,10 @@ def deleteWCS(fname, ext, wcskey=" ", wcsname=" "): wcskeyext = 0 else: wcskeyext = 1 - + if not wcskeys and not wcsname: raise KeyError("Either wcskey or wcsname should be specified") - + if wcskey == " ": # try getting the key from WCSNAME wkey = getKeyFromName(fobj[wcskeyext].header, wcsname) @@ -336,11 +336,11 @@ def deleteWCS(fname, ext, wcskey=" ", wcsname=" "): closefobj(fname, fobj) raise KeyError("Could not get a key: wcsname '%s' not found in header." % wcsname) else: - if wcskey not in wcskeys(fobj[wcskeyext].header): + if wcskey not in wcskeys(fobj[wcskeyext].header): closefobj(fname, fobj) raise KeyError("Could not find alternate WCS with key %s in this file" % wcskey) wkey = wcskey - + prexts = [] for i in ext: hdr = fobj[i].header @@ -359,10 +359,10 @@ def deleteWCS(fname, ext, wcskey=" ", wcsname=" "): def _buildExtlist(fobj, ext): """ - Utility function to interpret the provided value of 'ext' and return a list - of 'valid' values which can then be used by the rest of the functions in + Utility function to interpret the provided value of 'ext' and return a list + of 'valid' values which can then be used by the rest of the functions in this module. - + Parameters ---------- fobj: HDUList @@ -373,7 +373,7 @@ def _buildExtlist(fobj, ext): with WCSs to be archived """ if not isinstance(ext,list): - if isinstance(ext,str): + if isinstance(ext,str): extstr = ext ext = [] for extn in range(1, len(fobj)): @@ -434,7 +434,7 @@ def _check_headerpars(fobj, ext): if not isinstance(fobj, pyfits.Header) and not isinstance(fobj, pyfits.HDUList) \ and not isinstance(fobj, str): raise ValueError("Expected a file name, a file object or a header\n") - + if not isinstance(fobj, pyfits.Header): #raise ValueError("Expected a valid ext parameter when input is a file") if not isinstance(ext, int) and not isinstance(ext, tuple): @@ -448,7 +448,7 @@ def _getheader(fobj, ext): else: hdr = fobj[ext].header return hdr - + def readAltWCS(fobj, ext, wcskey=' ',verbose=False): """ Reads in alternate WCS from specified extension @@ -461,12 +461,12 @@ def readAltWCS(fobj, ext, wcskey=' ',verbose=False): alternate/primary WCS key that will be replaced by the new key ext: int extension number - + Returns ------- hdr: pyfits.Header header object with ONLY the keywords for specified alternate WCS - """ + """ if isinstance(fobj, str): fobj = pyfits.open(fobj) @@ -475,33 +475,33 @@ def readAltWCS(fobj, ext, wcskey=' ',verbose=False): nwcs = pywcs.WCS(hdr, fobj=fobj, key=wcskey) except KeyError: if verbose: - print 'readAltWCS: Could not read WCS with key %s' %wcskey + print 'readAltWCS: Could not read WCS with key %s' %wcskey print ' Skipping %s[%s]' % (fobj.filename(), str(ext)) return None hwcs = nwcs.to_header() if nwcs.wcs.has_cd(): hwcs = pc2cd(hwcs, key=wcskey) - + return hwcs - + def convertAltWCS(fobj,ext,oldkey=" ",newkey=' '): - """ - Translates the alternate/primary WCS with one key to an alternate/primary WCS with + """ + Translates the alternate/primary WCS with one key to an alternate/primary WCS with another key. - + Parameters ---------- fobj: string, pyfits.HDUList, or pyfits.Header - fits filename, pyfits file object or pyfits header + fits filename, pyfits file object or pyfits header containing alternate/primary WCS(s) to be converted ext: int extension number oldkey: string [" ",A-Z] alternate/primary WCS key that will be replaced by the new key newkey: string [" ",A-Z] - new alternate/primary WCS key - + new alternate/primary WCS key + Returns ------- hdr: pyfits.Header @@ -530,14 +530,14 @@ def wcskeys(fobj, ext=None): fobj: string, pyfits.HDUList or pyfits.Header fits file name, pyfits file object or pyfits header ext: int or None - extension number + extension number if None, fobj must be a header """ _check_headerpars(fobj, ext) hdr = _getheader(fobj, ext) names = hdr["WCSNAME*"] d = [] - for key in names.keys(): + for key in names: wkey = key.replace('WCSNAME','') if wkey == '': wkey = ' ' d.append(wkey) @@ -552,18 +552,18 @@ def wcsnames(fobj, ext=None): fobj: string, pyfits.HDUList or pyfits.Header fits file name, pyfits file object or pyfits header ext: int or None - extension number + extension number if None, fobj must be a header - + """ _check_headerpars(fobj, ext) hdr = _getheader(fobj, ext) names = hdr["WCSNAME*"] d = {} - for c in names: - wkey = c.key.replace('WCSNAME','') + for keyword, value in names.items(): + wkey = keyword.replace('WCSNAME','') if wkey == '': wkey = ' ' - d[wkey] = c.value + d[wkey] = value return d def available_wcskeys(fobj, ext=None): @@ -577,7 +577,7 @@ def available_wcskeys(fobj, ext=None): fobj: string, pyfits.HDUList or pyfits.Header fits file name, pyfits file object or pyfits header ext: int or None - extension number + extension number if None, fobj must be a header """ _check_headerpars(fobj, ext) @@ -600,7 +600,7 @@ def next_wcskey(fobj, ext=None): fobj: string, pyfits.HDUList or pyfits.Header fits file name, pyfits file object or pyfits header ext: int or None - extension number + extension number if None, fobj must be a header """ _check_headerpars(fobj, ext) @@ -661,7 +661,7 @@ def pc2cd(hdr, key=' '): def _parpasscheck(fobj, ext, wcskey, fromext=None, toext=None, reusekey=False): """ Check input parameters to altwcs functions - + fobj: string or pyfits.HDUList object a file name or a file object ext: an int, a tuple, a python list of integers or a python list @@ -677,10 +677,10 @@ def _parpasscheck(fobj, ext, wcskey, fromext=None, toext=None, reusekey=False): if not isinstance(fobj,pyfits.HDUList): print "First parameter must be a fits file object or a file name." return False - - # first one covers the case of an object created in memory + + # first one covers the case of an object created in memory # (e.g. headerlet) for which fileinfo returns None - if fobj.fileinfo(0) is None: + if fobj.fileinfo(0) is None: pass else: # an HDUList object with associated file @@ -694,7 +694,7 @@ def _parpasscheck(fobj, ext, wcskey, fromext=None, toext=None, reusekey=False): print "Ext must be integer, tuple, string,a list of int extension numbers, \n\ or a list of tuples representing a fits extension, for example ('sci', 1)." return False - + if not isinstance(fromext, str) and fromext is not None: print "fromext must be a string representing a valid extname" return False @@ -703,11 +703,11 @@ def _parpasscheck(fobj, ext, wcskey, fromext=None, toext=None, reusekey=False): toext is not None : print "toext must be a string or a list of strings representing extname" return False - + if len(wcskey) != 1: print 'Parameter wcskey must be a character - one of "A"-"Z" or " "' return False - + return True def closefobj(fname, f): diff --git a/lib/stwcs/wcsutil/convertwcs.py b/lib/stwcs/wcsutil/convertwcs.py index 80276c3..0fa61af 100644 --- a/lib/stwcs/wcsutil/convertwcs.py +++ b/lib/stwcs/wcsutil/convertwcs.py @@ -65,7 +65,7 @@ def archive_prefix_OPUS_WCS(fobj,extname='SCI'): for key in wcskeys: okey = 'O'+key[:7] hdr = fobj[(extname,e)].header - if hdr.has_key(okey): + if okey in hdr: # Update alternate WCS keyword with prefix-O OPUS keyword value hdr[key] = hdr[okey] @@ -102,7 +102,7 @@ def create_prefix_OPUS_WCS(fobj,extname='SCI'): raise IOError # check for existance of O-prefix WCS - if not fobj['sci',1].header.has_key(owcskeys[0]): + if owcskeys[0] not in fobj['sci',1].header: # find out how many SCI extensions are in the image numextn = fileutil.countExtn(fobj,extname=extname) @@ -111,7 +111,7 @@ def create_prefix_OPUS_WCS(fobj,extname='SCI'): for extn in xrange(1,numextn+1): hdr = fobj[(extname,extn)].header for okey in owcskeys: - hdr.update(okey,hdr[okey[1:]+'O']) + hdr[okey] = hdr[okey[1:]+'O'] # Close FITS image if we had to open it... if closefits: diff --git a/lib/stwcs/wcsutil/getinput.py b/lib/stwcs/wcsutil/getinput.py index 2f64f46..bfe4234 100644 --- a/lib/stwcs/wcsutil/getinput.py +++ b/lib/stwcs/wcsutil/getinput.py @@ -21,12 +21,11 @@ def parseSingleInput(f=None, ext=None): else: extnum = ext phdu = pyfits.open(filename) - hdr0 = pyfits.getheader(filename) + hdr0 = phdu[0].header try: - ehdr = pyfits.getheader(filename, ext=extnum) - except (IndexError,KeyError): - print 'Unable to get extension.', extnum - raise + ehdr = phdu[extnum].header + except (IndexError, KeyError), e: + raise e.__class__('Unable to get extension %s.' % extnum) elif isinstance(f, pyfits.HDUList): phdu = f @@ -37,9 +36,10 @@ def parseSingleInput(f=None, ext=None): ehdr = f[extnum].header hdr0 = f[0].header filename = hdr0.get('FILENAME', "") - + else: - raise ValueError('Input must be a file name string or a pyfits file object') + raise ValueError('Input must be a file name string or a pyfits file ' + 'object') return filename, hdr0, ehdr, phdu @@ -59,4 +59,4 @@ def parseMultipleInput(input): return input else: filelist = input[:] - return filelist
\ No newline at end of file + return filelist diff --git a/lib/stwcs/wcsutil/headerlet.py b/lib/stwcs/wcsutil/headerlet.py index 37738f9..da7b6dc 100644 --- a/lib/stwcs/wcsutil/headerlet.py +++ b/lib/stwcs/wcsutil/headerlet.py @@ -451,21 +451,17 @@ def update_ref_files(source, dest): """ logger.info("Updating reference files") phdukw = {'IDCTAB': True, - 'NPOLFILE': True, - 'D2IMFILE': True} + 'NPOLFILE': True, + 'D2IMFILE': True} - if 'HISTORY' in dest: - wind = dest.ascard.index_of('HISTORY') - else: - wind = len(dest) - - for key in phdukw.keys(): + for key in phdukw: try: - srckey = source.ascard[key] - dest.update(key, srckey.value, after=wind, comment=srckey.comment) + try: + del dest[key] + except: + pass + dest.append((key, source[key], source.comments[key]), bottom=True) except KeyError: - # TODO: I don't understand what the point of this is. Is it meant - # for logging purposes? Right now it isn't used. phdukw[key] = False return phdukw @@ -474,10 +470,11 @@ def get_rootname(fname): returns the value of ROOTNAME or DESTIM """ + hdr = pyfits.getheader(fname) try: - rootname = pyfits.getval(fname, 'ROOTNAME') + rootname = hdr['ROOTNAME'] except KeyError: - rootname = pyfits.getval(fname, 'DESTIM') + rootname = hdr['DESTIM'] return rootname def print_summary(summary_cols, summary_dict, pad=2, maxwidth=None, idcol=None, @@ -554,25 +551,32 @@ def _create_primary_HDU(destim, hdrname, distname, wcsname, # build Primary HDU phdu = pyfits.PrimaryHDU() - phdu.header.update('DESTIM', destim, - comment='Destination observation root name') - phdu.header.update('HDRNAME', hdrname, comment='Headerlet name') + phdu.header['DESTIM'] = (destim, 'Destination observation root name') + phdu.header['HDRNAME'] = (hdrname, 'Headerlet name') fmt = "%Y-%m-%dT%H:%M:%S" - phdu.header.update('DATE', time.strftime(fmt), - comment='Date FITS file was generated') - phdu.header.update('WCSNAME', wcsname, comment='WCS name') - phdu.header.update('DISTNAME', distname, comment='Distortion model name') - phdu.header.update('SIPNAME', sipname, comment='origin of SIP polynomial distortion model') - phdu.header.update('NPOLFILE', npolfile, comment='origin of non-polynmial distortion model') - phdu.header.update('D2IMFILE', d2imfile, comment='origin of detector to image correction') - phdu.header.update('AUTHOR', author, comment='headerlet created by this user') - phdu.header.update('DESCRIP', descrip, comment='Short description of headerlet solution') - phdu.header.update('RMS_RA', rms_ra, comment='RMS in RA at ref pix of headerlet solution') - phdu.header.update('RMS_DEC', rms_dec, comment='RMS in Dec at ref pix of headerlet solution') - phdu.header.update('NMATCH', nmatch, comment='Number of sources used for headerlet solution') - phdu.header.update('CATALOG', catalog, comment='Astrometric catalog used for headerlet solution') - phdu.header.update('UPWCSVER', upwcsver.value, comment=upwcsver.comment) - phdu.header.update('PYWCSVER', pywcsver.value, comment=pywcsver.comment) + phdu.header['DATE'] = (time.strftime(fmt), 'Date FITS file was generated') + phdu.header['WCSNAME'] = (wcsname, 'WCS name') + phdu.header['DISTNAME'] = (distname, 'Distortion model name') + phdu.header['SIPNAME'] = (sipname, + 'origin of SIP polynomial distortion model') + phdu.header['NPOLFILE'] = (npolfile, + 'origin of non-polynmial distortion model') + phdu.header['D2IMFILE'] = (d2imfile, + 'origin of detector to image correction') + phdu.header['AUTHOR'] = (author, 'headerlet created by this user') + phdu.header['DESCRIP'] = (descrip, + 'Short description of headerlet solution') + phdu.header['RMS_RA'] = (rms_ra, + 'RMS in RA at ref pix of headerlet solution') + phdu.header['RMS_DEC'] = (rms_dec, + 'RMS in Dec at ref pix of headerlet solution') + phdu.header['NMATCH'] = (nmatch, + 'Number of sources used for headerlet solution') + phdu.header['CATALOG'] = (catalog, + 'Astrometric catalog used for headerlet ' + 'solution') + phdu.header['UPWCSVER'] = (upwcsver.value, upwcsver.comment) + phdu.header['PYWCSVER'] = (pywcsver.value, pywcsver.comment) # clean up history string in order to remove whitespace characters that # would cause problems with FITS @@ -777,7 +781,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI', if wcsname in [None, ' ', '', 'INDEF'] and wcskey is None: message = """\n No valid WCS found found in %s. - A valid value for either "wcsname" or "wcskey" + A valid value for either "wcsname" or "wcskey" needs to be specified. """ % fname logger.critical(message) @@ -816,7 +820,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI', descrip=descrip, history=history, nmatch=nmatch, catalog=catalog, logging=False) - + if attach: # Check to see whether or not a HeaderletHDU with #this hdrname already exists @@ -1050,12 +1054,12 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None, # get the version of STWCS used to create the WCS of the science file. try: - upwcsver = fobj[0].header.ascard['UPWCSVER'] + upwcsver = fobj[0].header.cards[fobj[0].header.index('UPWCSVER')] except KeyError: upwcsver = pyfits.Card("UPWCSVER", " ", "Version of STWCS used to update the WCS") try: - pywcsver = fobj[0].header.ascard['PYWCSVER'] + pywcsver = fobj[0].header.cards[fobj[0].header.index('PYWCSVER')] except KeyError: pywcsver = pyfits.Card("PYWCSVER", " ", "Version of PYWCS used to update the WCS") @@ -1121,42 +1125,36 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None, if wcskey != ' ': # Now read in specified linear WCS terms from alternate WCS try: - althdr = altwcs.convertAltWCS(fobj, fext, oldkey=wcskey, newkey=" ") + althdr = altwcs.convertAltWCS(fobj, fext, oldkey=wcskey, + newkey=" ") althdrwcs = HSTWCS(fobj, fext, wcskey=wcskey) except KeyError: continue # Skip over any extension which does not have a WCS - althdr = althdr.ascard # Update full WCS with values from alternate WCS - for card in althdr: - h.update(card.key, card.value) + for keyword, value in althdr.items(): + h[keyword] = value if hasattr(althdrwcs, 'orientat'): - h.update('ORIENTAT', althdrwcs.orientat, comment=orient_comment) - h = h.ascard - + h['ORIENTAT'] = (althdrwcs.orientat, orient_comment) if hasattr(hwcs, 'vafactor'): - h.append(pyfits.Card(key='VAFACTOR', value=hwcs.vafactor, - comment='Velocity aberration plate scale factor')) - h.insert(0, pyfits.Card(key='EXTNAME', value='SIPWCS', - comment='Extension name')) + h.append(('VAFACTOR', hwcs.vafactor, + 'Velocity aberration plate scale factor')) + h.insert(0, ('EXTNAME', 'SIPWCS', 'Extension name')) if isinstance(fext, int): if 'extver' in fobj[fext].header: val = fobj[fext].header['extver'] else: val = fext else: val = fext[1] - h.insert(1, pyfits.Card(key='EXTVER', value=val, - comment='Extension version')) - h.append(pyfits.Card(key="SCIEXT", value=e, - comment="Target science data extension")) - fhdr = fobj[fext].header.ascard + h.insert(1, ('EXTVER', val, 'Extension version')) + h.append(('SCIEXT', e, 'Target science data extension')) + fhdr = fobj[fext].header if npolfile is not 'NOMODEL': cpdis = fhdr['CPDIS*...'] for c in range(1, len(cpdis) + 1): h.append(cpdis[c - 1]) dp = fhdr['DP%s*...' % c] - for kw in dp: - dpval = kw.value - if 'EXTVER' in kw.key: + for kw, dpval in dp.items(): + if 'EXTVER' in kw: wcsdvarr_extns.append(dpval) break @@ -1834,8 +1832,9 @@ class Headerlet(pyfits.HDUList): self.fit_kws = ['HDRNAME', 'NMATCH', 'CATALOG'] self.history = '' - for card in self[0].header['HISTORY*']: - self.history += card.value+'\n' + # header['HISTORY'] returns an iterable of all HISTORY values + for hist in self[0].header['HISTORY']: + self.history += hist + '\n' self.d2imerr = 0 self.axiscorr = 1 @@ -1985,7 +1984,7 @@ class Headerlet(pyfits.HDUList): numsip = countExtn(self, 'SIPWCS') for idx in range(1, numsip + 1): fhdr = fobj[('SCI', idx)].header - siphdr = self[('SIPWCS', idx)].header.ascard + siphdr = self[('SIPWCS', idx)].header if dist_models_equal: hwcs = HSTWCS(fobj, ext=('SCI', idx)) @@ -2004,40 +2003,41 @@ class Headerlet(pyfits.HDUList): bkeywd = 'HISTORY' logger.debug( "Updating WCS keywords after %s and/or before %s " % - (akeywd,bkeywd)) + (akeywd, bkeywd)) update_cpdis = False - for k in siphdr[-1::-1]: + for c in siphdr.cards[-1::-1]: # Replace or add WCS keyword from headerlet as PRIMARY WCS # In the case that the distortion models are not equal, # this will copy all keywords from headerlet into fobj # When the distortion models are equal, though, it will # only copy the primary WCS keywords (CRVAL,CRPIX,...) - if (dist_models_equal and (k.key in hwcshdr)) or \ - (not dist_models_equal and k.key not in FITS_STD_KW): + if ((dist_models_equal and (c.keyword in hwcshdr)) or + (not dist_models_equal and + c.keyword not in FITS_STD_KW)): if 'DP' not in k.key: - fhdr.update(k.key, k.value, comment=k.comment, - after=akeywd, before=bkeywd) + fhdr.set(c.keyword, c.value, c.comment, + after=akeywd, before=bkeywd) else: update_cpdis = True else: pass # Update WCS with optional CRDER (error) kws from headerlet if 'crder1' in siphdr: - for kw in siphdr['crder*']: - fhdr.update(kw.key, kw.value, comment=kw.comment, - after='WCSNAME') + for card in siphdr['crder*'].cards: + fhdr.set(card.keyword, card.value, card.comment, + after='WCSNAME') # Update WCS with HDRNAME as well for kw in self.fit_kws: - fhdr.update(kw, self[0].header[kw], after='WCSNAME') + fhdr.set(kw, self[0].header[kw], after='WCSNAME') # Update header with record-valued keywords here if update_cpdis: numdp = len(siphdr['CPDIS*']) for dpaxis in range(1, numdp+1): - cpdis_indx = fhdr.ascard.index_of('CPDIS%d' % (dpaxis)) - for dpcard in siphdr['DP%d*' % (dpaxis)][-1::-1]: - fhdr.ascard.insert(cpdis_indx, dpcard) + cpdis_indx = fhdr.index('CPDIS%d' % (dpaxis)) + for dpcard in siphdr['DP%d*' % (dpaxis)][-1::-1].cards: + fhdr.insert(cpdis_indx, dpcard) # Update the WCSCORR table with new rows from the headerlet's WCSs wcscorr.update_wcscorr(fobj, self, 'SIPWCS') @@ -2094,7 +2094,7 @@ class Headerlet(pyfits.HDUList): distname = self.build_distname(fobj) except: distname = 'UNKNOWN' - + if distname == 'UNKNOWN' or self.distname != distname: message = """ Observation %s cannot be updated with headerlet %s @@ -2144,32 +2144,33 @@ class Headerlet(pyfits.HDUList): except ValueError: sciext = fu.parseExtn(sciext) fhdr = fobj[sciext].header - siphdr = self[('SIPWCS', idx)].header.ascard + siphdr = self[('SIPWCS', idx)].header # a minimal attempt to get the position of the WCS keywords group # in the header by looking for the PA_APER kw. # at least make sure the WCS kw are written before the HISTORY kw # if everything fails, append the kw to the header try: - wind = fhdr.ascard.index_of('HISTORY') + wind = fhdr.index('HISTORY') except KeyError: wind = len(fhdr) logger.debug("Inserting WCS keywords at index %s" % wind) - for k in siphdr: + for card in siphdr.cards: for akw in altwcs.altwcskw: - if akw in k.key: - fhdr.ascard.insert(wind, pyfits.Card( - key=k.key[:7]+wkey, value=k.value, - comment=k.comment)) + if akw in card.keyword: + fhdr.insert(wind, + pyfits.Card(card.keyword[:7] + wkey, + value=card.value, + comment=card.comment)) else: pass - fhdr.ascard.insert(wind, pyfits.Card('WCSNAME'+wkey, wname)) + fhdr.insert(wind, pyfits.Card('WCSNAME' + wkey, wname)) # also update with HDRNAME (a non-WCS-standard kw) for kw in self.fit_kws: - fhdr.ascard.insert(wind, pyfits.Card(kw+wkey, - self[0].header[kw])) + fhdr.insert(wind, pyfits.Card(kw + wkey, + self[0].header[kw])) # Update the WCSCORR table with new rows from the headerlet's WCSs wcscorr.update_wcscorr(fobj, self, 'SIPWCS') @@ -2322,11 +2323,11 @@ class Headerlet(pyfits.HDUList): return unique def verify_model(self, dest): - """ + """ Verifies that the headerlet can be applied to the observation - + Determines whether or not the file specifies the same distortion - model/reference files. + model/reference files. """ destim_opened = False if not isinstance(dest, pyfits.HDUList): @@ -2334,8 +2335,8 @@ class Headerlet(pyfits.HDUList): destim_opened = True else: destim = dest - - if 'distname' in destim[0].header: + + if 'distname' in destim[0].header: dname = destim[0].header['DISTNAME'] else: dname = self.build_distname(dest) @@ -2345,7 +2346,7 @@ class Headerlet(pyfits.HDUList): return True else: return False - + def verify_dest(self, dest): """ verifies that the headerlet can be applied to the observation @@ -2371,14 +2372,14 @@ class Headerlet(pyfits.HDUList): def build_distname(self, dest): """ - Builds the DISTNAME for dest based on reference file names. + Builds the DISTNAME for dest based on reference file names. """ sipname = utils.build_sipname(dest) npolname = utils.build_npolname(dest) d2imname = utils.build_d2imname(dest) dname = utils.build_distname(sipname,npolname,d2imname) return dname - + def tofile(self, fname, destim=None, hdrname=None, clobber=False): """ Write this headerlet to a file @@ -2417,7 +2418,7 @@ class Headerlet(pyfits.HDUList): self._remove_idc_coeffs(dest[idx]) self._remove_fit_values(dest[idx]) try: - del dest[idx].header.ascard['VAFACTOR'] + del dest[idx].header['VAFACTOR'] except KeyError: pass @@ -2437,7 +2438,7 @@ class Headerlet(pyfits.HDUList): refkw = ['IDCTAB', 'NPOLFILE', 'D2IMFILE'] for kw in refkw: try: - del phdu.header.ascard[kw] + del phdu.header[kw] except KeyError: pass @@ -2495,7 +2496,7 @@ class Headerlet(pyfits.HDUList): try: for c in range(1, len(cpdis) + 1): del ext.header['DP%s*...' % c] - del ext.header[cpdis[c - 1].key] + del ext.header[cpdis.cards[c - 1].keyword] del ext.header['CPERR*'] del ext.header['NPOLFILE'] del ext.header['NPOLEXT'] @@ -2538,15 +2539,15 @@ class Headerlet(pyfits.HDUList): hdr_logger.debug("Removing Primary WCS from (%s, %s)" % (ext.name, ext._extver)) - naxis = ext.header.ascard['NAXIS'].value + naxis = ext.header['NAXIS'] for key in basic_wcs: for i in range(1, naxis + 1): try: - del ext.header.ascard[key + str(i)] + del ext.header[key + str(i)] except KeyError: pass try: - del ext.header.ascard['WCSAXES'] + del ext.header['WCSAXES'] except KeyError: pass @@ -2560,7 +2561,7 @@ class Headerlet(pyfits.HDUList): coeffs = ['OCX10', 'OCX11', 'OCY10', 'OCY11', 'IDCSCALE'] for k in coeffs: try: - del ext.header.ascard[k] + del ext.header[k] except KeyError: pass @@ -2628,19 +2629,19 @@ class HeaderletHDU(pyfits.hdu.nonstandard.FitsHDU): else: sipname = phdu.header['WCSNAME'] - hlet.header.update('HDRNAME', phdu.header['HDRNAME'], - phdu.header.ascard['HDRNAME'].comment) - hlet.header.update('DATE', phdu.header['DATE'], - phdu.header.ascard['DATE'].comment) - hlet.header.update('SIPNAME', sipname, 'SIP distortion model name') - hlet.header.update('WCSNAME', phdu.header['WCSNAME'], 'WCS name'), - hlet.header.update('DISTNAME', phdu.header['DISTNAME'], - 'Distortion model name'), - hlet.header.update('NPOLFILE', phdu.header['NPOLFILE'], - phdu.header.ascard['NPOLFILE'].comment) - hlet.header.update('D2IMFILE', phdu.header['D2IMFILE'], - phdu.header.ascard['D2IMFILE'].comment) - hlet.header.update('EXTNAME', cls._extension, 'Extension name') + hlet.header['HDRNAME'] = (phdu.header['HDRNAME'], + phdu.header.comments['HDRNAME']) + hlet.header['DATE'] = (phdu.header['DATE'], + phdu.header.comments['DATE']) + hlet.header['SIPNAME'] = (sipname, 'SIP distortion model name') + hlet.header['WCSNAME'] = (phdu.header['WCSNAME'], 'WCS name'), + hlet.header['DISTNAME'] = (phdu.header['DISTNAME'], + 'Distortion model name'), + hlet.header['NPOLFILE'] = (phdu.header['NPOLFILE'], + phdu.header.comments['NPOLFILE']) + hlet.header['D2IMFILE'] = (phdu.header['D2IMFILE'], + phdu.header.comments['D2IMFILE']) + hlet.header['EXTNAME'] = (cls._extension, 'Extension name') return hlet diff --git a/lib/stwcs/wcsutil/hstwcs.py b/lib/stwcs/wcsutil/hstwcs.py index d138f08..371de0f 100644 --- a/lib/stwcs/wcsutil/hstwcs.py +++ b/lib/stwcs/wcsutil/hstwcs.py @@ -40,7 +40,7 @@ def extract_rootname(kwvalue,suffix=""): fullval = kwvalue # Extract filename without path from kwvalue fname = os.path.basename(fullval).strip() - + # Now, rip out just the rootname from the full filename rootname = fileutil.buildNewRootname(fname) @@ -54,7 +54,7 @@ def build_default_wcsname(idctab): wcsname = 'IDC_' + idcname return wcsname -# +# #### HSTWCS Class definition # class HSTWCS(WCS): @@ -173,7 +173,7 @@ class HSTWCS(WCS): to a CD matrix, if reasonable, by running pc2.cd() method.\n \ The plate scale can be set then by calling setPscale() method.\n" self.pscale = None - + def setOrient(self): """ Computes ORIENTAT from the CD matrix @@ -278,7 +278,7 @@ class HSTWCS(WCS): chip=self.chip, direction='forward', date=self.date_obs, filter1=self.filter1, filter2=self.filter2, offtab=self.offtab, binned=self.binned) - + if self.ltv1 != 0. or self.ltv2 != 0.: self.resetLTV() @@ -287,26 +287,26 @@ class HSTWCS(WCS): print 'Update header with IDC model kw requested but header was not provided\n.' else: self._updatehdr(header) - + def resetLTV(self): """ Reset LTV values for polarizer data - - The polarizer field is smaller than the detector field. - The distortion coefficients are defined for the entire - polarizer field and the LTV values are set as with subarray + + The polarizer field is smaller than the detector field. + The distortion coefficients are defined for the entire + polarizer field and the LTV values are set as with subarray data. This may also be true for other special filters. - This is a special case when the observation is considered - a subarray in terms of detector field but a full frame in + This is a special case when the observation is considered + a subarray in terms of detector field but a full frame in terms of distortion model. - To avoid shifting the distortion coefficients the LTV values + To avoid shifting the distortion coefficients the LTV values are reset to 0. """ if self.naxis1 == self.idcmodel.refpix['XSIZE'] and \ self.naxis2 == self.idcmodel.refpix['YSIZE']: self.ltv1 = 0. self.ltv2 = 0. - + def wcs2header(self, sip2hdr=False, idc2hdr=True): """ Create a pyfits.Header object from WCS keywords. @@ -329,13 +329,13 @@ class HSTWCS(WCS): else: wname = 'DEFAULT' h.update('wcsname',value=wname) - + if idc2hdr: for card in self._idc2hdr(): h.update(card.key,value=card.value,comment=card.comment) try: - del h.ascard['RESTFRQ'] - del h.ascard['RESTWAV'] + del h['RESTFRQ'] + del h['RESTWAV'] except KeyError: pass if sip2hdr and self.sip: diff --git a/lib/stwcs/wcsutil/instruments.py b/lib/stwcs/wcsutil/instruments.py index 997bdc8..8641e51 100644 --- a/lib/stwcs/wcsutil/instruments.py +++ b/lib/stwcs/wcsutil/instruments.py @@ -1,8 +1,7 @@ from __future__ import division # confidence high -import pyfits from mappings import ins_spec_kw - + class InstrWCS(object): """ A base class for instrument specific keyword definition. @@ -10,15 +9,15 @@ class InstrWCS(object): all set_kw methods. """ def __init__(self, hdr0=None, hdr=None): - self.exthdr = hdr + self.exthdr = hdr self.primhdr = hdr0 self.set_ins_spec_kw() - + def set_ins_spec_kw(self): """ This method MUST call all set_kw methods. - There should be a set_kw method for all kw listed in - mappings.ins_spec_kw. TypeError handles the case when + There should be a set_kw method for all kw listed in + mappings.ins_spec_kw. TypeError handles the case when fobj='DEFAULT'. """ self.set_idctab() @@ -38,13 +37,13 @@ class InstrWCS(object): self.set_binned() self.set_chip() self.set_parity() - + def set_idctab(self): try: self.idctab = self.primhdr['IDCTAB'] except (KeyError, TypeError): self.idctab = None - + def set_offtab(self): try: self.offtab = self.primhdr['OFFTAB'] @@ -56,13 +55,13 @@ class InstrWCS(object): self.date_obs = self.primhdr['DATE-OBS'] except (KeyError, TypeError): self.date_obs = None - + def set_ra_targ(self): try: self.ra_targ = self.primhdr['RA-TARG'] except (KeyError, TypeError): self.ra_targ = None - + def set_dec_targ(self): try: self.dec_targ = self.primhdr['DEC-TARG'] @@ -74,25 +73,25 @@ class InstrWCS(object): self.pav3 = self.primhdr['PA_V3'] except (KeyError, TypeError): self.pav3 = None - + def set_filter1(self): try: self.filter1 = self.primhdr['FILTER1'] except (KeyError, TypeError): self.filter1 = None - + def set_filter2(self): try: self.filter2 = self.primhdr['FILTER2'] except (KeyError, TypeError): self.filter2 = None - - def set_vafactor(self): + + def set_vafactor(self): try: self.vafactor = self.exthdr['VAFACTOR'] except (KeyError, TypeError): self.vafactor = 1 - + def set_naxis1(self): try: self.naxis1 = self.exthdr['naxis1'] @@ -101,7 +100,7 @@ class InstrWCS(object): self.naxis1 = self.exthdr['npix1'] except (KeyError, TypeError): self.naxis1 = None - + def set_naxis2(self): try: self.naxis2 = self.exthdr['naxis2'] @@ -110,69 +109,69 @@ class InstrWCS(object): self.naxis2 = self.exthdr['npix2'] except (KeyError, TypeError): self.naxis2 = None - + def set_ltv1(self): try: self.ltv1 = self.exthdr['LTV1'] except (KeyError, TypeError): self.ltv1 = 0.0 - + def set_ltv2(self): try: self.ltv2 = self.exthdr['LTV2'] except (KeyError, TypeError): self.ltv2 = 0.0 - + def set_binned(self): try: self.binned = self.exthdr['BINAXIS1'] except (KeyError, TypeError): self.binned = 1 - + def set_chip(self): try: self.chip = self.exthdr['CCDCHIP'] except (KeyError, TypeError): self.chip = 1 - + def set_parity(self): self.parity = [[1.0,0.0],[0.0,-1.0]] - + def set_detector(self): - # each instrument has a different kw for detector and it can be - # in a different header, so this is to be handled by the instrument classes + # each instrument has a different kw for detector and it can be + # in a different header, so this is to be handled by the instrument classes self.detector = 'DEFAULT' - + class ACSWCS(InstrWCS): """ - get instrument specific kw + get instrument specific kw """ - + def __init__(self, hdr0, hdr): self.primhdr = hdr0 self.exthdr = hdr InstrWCS.__init__(self,hdr0, hdr) self.set_ins_spec_kw() - + def set_detector(self): try: - self.detector = self.primhdr['DETECTOR'] + self.detector = self.primhdr['DETECTOR'] except KeyError: print 'ERROR: Detector kw not found.\n' raise - + def set_parity(self): parity = {'WFC':[[1.0,0.0],[0.0,-1.0]], 'HRC':[[-1.0,0.0],[0.0,1.0]], 'SBC':[[-1.0,0.0],[0.0,1.0]]} - + if self.detector not in parity.keys(): parity = InstrWCS.set_parity(self) else: self.parity = parity[self.detector] - - -class WFPC2WCS(InstrWCS): + + +class WFPC2WCS(InstrWCS): def __init__(self, hdr0, hdr): @@ -180,7 +179,7 @@ class WFPC2WCS(InstrWCS): self.exthdr = hdr InstrWCS.__init__(self,hdr0, hdr) self.set_ins_spec_kw() - + def set_filter1(self): self.filter1 = self.primhdr.get('FILTNAM1', None) if self.filter1 == " " or self.filter1 == None: @@ -190,8 +189,8 @@ class WFPC2WCS(InstrWCS): self.filter2 = self.primhdr.get('FILTNAM2', None) if self.filter2 == " " or self.filter2 == None: self.filter2 = 'CLEAR2' - - + + def set_binned(self): mode = self.primhdr.get('MODE', 1) if mode == 'FULL': @@ -201,68 +200,68 @@ class WFPC2WCS(InstrWCS): def set_chip(self): self.chip = self.exthdr.get('DETECTOR', 1) - + def set_parity(self): self.parity = [[-1.0,0.],[0.,1.0]] - + def set_detector(self): try: self.detector = self.exthdr['DETECTOR'] except KeyError: print 'ERROR: Detector kw not found.\n' raise - + class WFC3WCS(InstrWCS): """ Create a WFC3 detector specific class """ - + def __init__(self, hdr0, hdr): self.primhdr = hdr0 self.exthdr = hdr InstrWCS.__init__(self,hdr0, hdr) self.set_ins_spec_kw() - + def set_detector(self): try: - self.detector = self.primhdr['DETECTOR'] + self.detector = self.primhdr['DETECTOR'] except KeyError: print 'ERROR: Detector kw not found.\n' raise - + def set_filter1(self): self.filter1 = self.primhdr.get('FILTER', None) if self.filter1 == " " or self.filter1 == None: self.filter1 = 'CLEAR' - + def set_filter2(self): #Nicmos idc tables do not allow 2 filters. self.filter2 = 'CLEAR' - + def set_parity(self): - parity = {'UVIS':[[-1.0,0.0],[0.0,1.0]], + parity = {'UVIS':[[-1.0,0.0],[0.0,1.0]], 'IR':[[-1.0,0.0],[0.0,1.0]]} - + if self.detector not in parity.keys(): parity = InstrWCS.set_parity(self) else: self.parity = parity[self.detector] - + class NICMOSWCS(InstrWCS): """ Create a NICMOS specific class """ - + def __init__(self, hdr0, hdr): self.primhdr = hdr0 self.exthdr = hdr InstrWCS.__init__(self,hdr0, hdr) self.set_ins_spec_kw() - + def set_parity(self): self.parity = [[-1.0,0.],[0.,1.0]] - + def set_filter1(self): self.filter1 = self.primhdr.get('FILTER', None) if self.filter1 == " " or self.filter1 == None: @@ -271,31 +270,31 @@ class NICMOSWCS(InstrWCS): def set_filter2(self): #Nicmos idc tables do not allow 2 filters. self.filter2 = 'CLEAR' - + def set_chip(self): self.chip = self.detector - + def set_detector(self): try: - self.detector = self.primhdr['CAMERA'] + self.detector = self.primhdr['CAMERA'] except KeyError: print 'ERROR: Detector kw not found.\n' raise - + class STISWCS(InstrWCS): """ A STIS specific class """ - + def __init__(self, hdr0, hdr): self.primhdr = hdr0 self.exthdr = hdr InstrWCS.__init__(self,hdr0, hdr) self.set_ins_spec_kw() - + def set_parity(self): self.parity = [[-1.0,0.],[0.,1.0]] - + def set_filter1(self): self.filter1 = self.exthdr.get('OPT_ELEM', None) if self.filter1 == " " or self.filter1 == None: @@ -305,17 +304,17 @@ class STISWCS(InstrWCS): self.filter2 = self.exthdr.get('FILTER', None) if self.filter2 == " " or self.filter2 == None: self.filter2 = 'CLEAR2' - + def set_detector(self): try: - self.detector = self.primhdr['DETECTOR'] + self.detector = self.primhdr['DETECTOR'] except KeyError: print 'ERROR: Detector kw not found.\n' raise - + def set_date_obs(self): try: self.date_obs = self.exthdr['DATE-OBS'] except (KeyError, TypeError): self.date_obs = None -
\ No newline at end of file + |