diff options
author | embray <embray@stsci.edu> | 2012-02-22 13:17:23 -0500 |
---|---|---|
committer | embray <embray@stsci.edu> | 2012-02-22 13:17:23 -0500 |
commit | 8cbc50fe21cfb148e9ef48b4d1700bbdd2af1d63 (patch) | |
tree | cb4939bc290bb413bed4132a2a188a33fc18dd5e /lib/stwcs/wcsutil | |
parent | 3c9cc9b532095b83b3e66333ca74cd29e3ee56c6 (diff) | |
download | stwcs_hcf-8cbc50fe21cfb148e9ef48b4d1700bbdd2af1d63.tar.gz |
Should fix most problems in stwcs due to pyfits Header updates. The main issue that caused incompatibility is that slices of headers (including by wildcard patterns) now returns a new Header rather than a list of cards.
git-svn-id: http://svn.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/stwcs@15198 fe389314-cf27-0410-b35b-8c050e845b92
Diffstat (limited to 'lib/stwcs/wcsutil')
-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 |
6 files changed, 263 insertions, 263 deletions
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 + |