summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/stwcs/wcsutil/headerlet.py61
-rw-r--r--lib/stwcs/wcsutil/wcscorr.py82
2 files changed, 89 insertions, 54 deletions
diff --git a/lib/stwcs/wcsutil/headerlet.py b/lib/stwcs/wcsutil/headerlet.py
index fe26393..557057f 100644
--- a/lib/stwcs/wcsutil/headerlet.py
+++ b/lib/stwcs/wcsutil/headerlet.py
@@ -797,14 +797,31 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI',
umode = 'readonly'
fobj, fname, close_fobj = parse_filename(f, mode=umode)
- wnames = altwcs.wcsnames(fobj,ext=('sci',1))
+ # Interpret sciext input for this file
+ if isinstance(sciext, int):
+ sciextlist = [sciext] # allow for specification of simple FITS header
+ elif isinstance(sciext, str):
+ numsciext = countExtn(fobj, sciext)
+ if numsciext > 0:
+ sciextlist = [tuple((sciext,i)) for i in range(1, numsciext+1)]
+ else:
+ sciextlist = [0]
+ elif isinstance(sciext, list):
+ sciextlist = sciext
+ else:
+ errstr = "Expected sciext to be a list of FITS extensions with science data\n"+\
+ " a valid EXTNAME string, or an integer."
+ logger.critical(errstr)
+ raise ValueError
+
+ wnames = altwcs.wcsnames(fobj,ext=sciextlist[0])
# Insure that WCSCORR table has been created with all original
# WCS's recorded prior to adding the headerlet WCS
wcscorr.init_wcscorr(fobj)
if wcsname is None:
- scihdr = fobj[sciext, 1].header
+ scihdr = fobj[sciextlist[0]].header
wname = scihdr['wcsname'+wcskey]
else:
wname = wcsname
@@ -812,7 +829,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI',
hdrname = wcsname
logger.critical('Creating the headerlet from image %s' % fname)
- hdrletobj = create_headerlet(fobj, sciext=sciext,
+ hdrletobj = create_headerlet(fobj, sciext=sciextlist,
wcsname=wname, wcskey=wcskey,
hdrname=hdrname,
sipname=sipname, npolfile=npolfile,
@@ -829,7 +846,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI',
hdrlet_hdu = HeaderletHDU.fromheaderlet(hdrletobj)
if destim is not None:
- hdrlet_hdu[0].header['destim'] = destim
+ hdrlet_hdu.header['destim'] = destim
fobj.append(hdrlet_hdu)
@@ -846,6 +863,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI',
logger.critical(message)
if close_fobj:
+ logger.info('Closing image in write_headerlet()...')
fobj.close()
frootname = fu.buildNewRootname(fname)
@@ -862,6 +880,7 @@ def write_headerlet(filename, hdrname, output=None, sciext='SCI',
hdrletobj.tofile(outname, clobber=clobber)
logger.critical( 'Created Headerlet file %s ' % outname)
+ del hdrletobj
@with_logging
def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
@@ -947,9 +966,18 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
"""
fobj, fname, close_file = parse_filename(filename)
+
+ # initial interpretation of sciext value for determination of input file type
+ sciextn = sciext
+ if not isinstance(sciext,str):
+ sciextn = 'SCI'
+ elif isinstance(sciext,list) and not isinstance(sciext[0],int):
+ sciextn = sciext[0][0]
+ numsci = countExtn(fobj,extname=sciextn)
+
# Define extension to evaluate for verification of input parameters
wcsext = 1
- if fu.isFits(fname)[1] == 'simple':
+ if fu.isFits(fname)[1] == 'simple' or numsci == 0:
wcsext = 0
# Translate 'wcskey' value for PRIMARY WCS to valid altwcs value of ' '
if wcskey == 'PRIMARY':
@@ -960,7 +988,6 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
hdrnamekw = "".join(["HDRNAME", wcskey.upper()]).rstrip()
wnames = altwcs.wcsnames(fobj,ext=wcsext)
-
if not wcsname:
# User did not specify a value for 'wcsname'
if wcsnamekw in fobj[wcsext].header:
@@ -1068,7 +1095,7 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
sciext = [sciext] # allow for specification of simple FITS header
elif isinstance(sciext, str):
numsciext = countExtn(fobj, sciext)
- sciext = [(sciext + ", " + str(i)) for i in range(1, numsciext+1)]
+ sciext = [tuple((sciext,i)) for i in range(1, numsciext+1)]
elif isinstance(sciext, list):
pass
else:
@@ -1101,10 +1128,11 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
wcsdvarr_extns = []
if fu.isFits(fobj)[1] is not 'simple':
for e in sciext:
- try:
- fext = int(e)
- except ValueError:
- fext = fu.parseExtn(e)
+ fext = e
+ if not isinstance(e,int):
+ if isinstance(e,str):
+ fext = fu.parseExtn(e)
+ fext = fu.findExtname(fobj,fext[0],extver=fext[1])
wkeys = altwcs.wcskeys(fobj, ext=fext)
if wcskey != ' ':
if wcskey not in wkeys:
@@ -1148,7 +1176,7 @@ def create_headerlet(filename, sciext='SCI', hdrname=None, destim=None,
val = fext
else: val = fext[1]
h.insert(1, ('EXTVER', val, 'Extension version'))
- h.append(('SCIEXT', e, 'Target science data extension'))
+ h.append(('SCIEXT', fext, 'Target science data extension'))
fhdr = fobj[fext].header
if npolfile is not 'NOMODEL':
cpdis = fhdr['CPDIS*...']
@@ -2018,7 +2046,10 @@ class Headerlet(pyfits.HDUList):
(not dist_models_equal and
c.keyword not in FITS_STD_KW)):
if 'DP' not in c.keyword:
- fhdr.set(c.keyword, c.value, c.comment,
+ if c.keyword in fhdr:
+ fhdr[c.keyword] = c.value
+ else:
+ fhdr.set(c.keyword, c.value, c.comment,
after=akeywd, before=bkeywd)
else:
update_cpdis = True
@@ -2215,8 +2246,8 @@ class Headerlet(pyfits.HDUList):
new_hlt = HeaderletHDU.fromheaderlet(self)
new_hlt.header.update('extver', numhlt + 1)
fobj.append(new_hlt)
- if archive:
- wcscorr.update_wcscorr(fobj, self, 'SIPWCS', active=False)
+ #if archive:
+ #wcscorr.update_wcscorr(fobj, self, 'SIPWCS', active=False)
else:
message = "Observation %s cannot be updated with headerlet" % (fname)
diff --git a/lib/stwcs/wcsutil/wcscorr.py b/lib/stwcs/wcsutil/wcscorr.py
index c767e09..d716f89 100644
--- a/lib/stwcs/wcsutil/wcscorr.py
+++ b/lib/stwcs/wcsutil/wcscorr.py
@@ -28,7 +28,7 @@ def init_wcscorr(input, force=False):
This function will NOT overwrite any rows already present.
This function works on all SCI extensions at one time.
- """
+ """
# TODO: Create some sort of decorator or (for Python2.5) context for
# opening a FITS file and closing it when done, if necessary
if not isinstance(input, pyfits.HDUList):
@@ -42,8 +42,8 @@ def init_wcscorr(input, force=False):
# Do not try to generate a WCSCORR table for a simple FITS file
numsci = fileutil.countExtn(fimg)
if len(fimg) == 1 or numsci == 0:
- return
-
+ return
+
enames = []
for e in fimg: enames.append(e.name)
if 'WCSCORR' in enames:
@@ -54,11 +54,11 @@ def init_wcscorr(input, force=False):
print 'Initializing new WCSCORR table for ',fimg.filename()
used_wcskeys = altwcs.wcskeys(fimg['SCI', 1].header)
-
+
# define the primary columns of the WCSEXT table with initial rows for each
# SCI extension for the original OPUS solution
- numsci = fileutil.countExtn(fimg)
numwcs = len(used_wcskeys)
+ if numwcs == 0: numwcs = 1
# create new table with more rows than needed initially to make it easier to
# add new rows later
@@ -82,7 +82,7 @@ def init_wcscorr(input, force=False):
pri_funcs = {'SIPNAME':stwcs.updatewcs.utils.build_sipname,
'NPOLNAME':stwcs.updatewcs.utils.build_npolname,
'D2IMNAME':stwcs.updatewcs.utils.build_d2imname}
-
+
# Now copy original OPUS values into table
for extver in xrange(1, numsci + 1):
rowind = find_wcscorr_row(wcsext.data,
@@ -142,7 +142,7 @@ def init_wcscorr(input, force=False):
wcsid = wcshdr['WCSNAME' + uwkey]
# identify next empty row
- rowind = find_wcscorr_row(wcsext.data,
+ rowind = find_wcscorr_row(wcsext.data,
selections={'wcs_id':['','0.0']})
rows = np.where(rowind)
if len(rows[0]) > 0:
@@ -194,10 +194,10 @@ def find_wcscorr_row(wcstab, selections):
mask = None
for i in selections:
icol = wcstab.field(i)
- if isinstance(icol,np.chararray): icol = icol.rstrip()
+ if isinstance(icol,np.chararray): icol = icol.rstrip()
selecti = selections[i]
if not isinstance(selecti,list):
- if isinstance(selecti,str):
+ if isinstance(selecti,str):
selecti = selecti.rstrip()
bmask = (icol == selecti)
if mask is None:
@@ -207,7 +207,7 @@ def find_wcscorr_row(wcstab, selections):
del bmask
else:
for si in selecti:
- if isinstance(si,str):
+ if isinstance(si,str):
si = si.rstrip()
bmask = (icol == si)
if mask is None:
@@ -215,7 +215,7 @@ def find_wcscorr_row(wcstab, selections):
else:
mask = np.logical_or(mask,bmask)
del bmask
-
+
return mask
@@ -281,11 +281,15 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
% extname)
# Initialize the WCSCORR table extension in dest if not already present
init_wcscorr(dest)
+ try:
+ dest.index_of('WCSCORR')
+ except KeyError:
+ return
# check to see whether or not this is an up-to-date table
# replace with newly initialized table with current format
old_table = dest['WCSCORR']
- wcscorr_cols = ['WCS_ID','EXTVER', 'SIPNAME',
+ wcscorr_cols = ['WCS_ID','EXTVER', 'SIPNAME',
'HDRNAME', 'NPOLNAME', 'D2IMNAME']
for colname in wcscorr_cols:
@@ -294,7 +298,7 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
outdated_table = old_table.copy()
del dest['WCSCORR']
init_wcscorr(dest)
- old_table = dest['WCSCORR']
+ old_table = dest['WCSCORR']
break
# Current implementation assumes the same WCS keywords are in each
@@ -303,7 +307,7 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
wcs_keys = altwcs.wcskeys(source[(extname, 1)].header)
wcs_keys = filter(None, wcs_keys)
if ' ' not in wcs_keys: wcs_keys.append(' ') # Insure that primary WCS gets used
- # apply logic for only updating WCSCORR table with specified keywords
+ # apply logic for only updating WCSCORR table with specified keywords
# corresponding to the WCS with WCSNAME=wcs_id
if wcs_id is not None:
wnames = altwcs.wcsnames(source[(extname, 1)].header)
@@ -314,17 +318,17 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
if len(wkeys) > 1 and ' ' in wkeys:
wkeys.remove(' ')
wcs_keys = wkeys
-
+
wcshdr = stwcs.wcsutil.HSTWCS(source, ext=(extname, 1)).wcs2header()
wcs_keywords = wcshdr.keys()
if 'O' in wcs_keys:
wcs_keys.remove('O') # 'O' is reserved for original OPUS WCS
-
+
# create new table for hdr and populate it with the newly updated values
new_table = create_wcscorr(descrip=True,numrows=0, padding=len(wcs_keys)*numext)
prihdr = source[0].header
-
+
# Get headerlet related keywords here
sipname = utils.build_sipname(source)
npolname = utils.build_npolname(source)
@@ -333,7 +337,7 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
hdrname = prihdr['hdrname']
else:
hdrname = ''
-
+
idx = -1
for wcs_key in wcs_keys:
for extver in range(1, numext + 1):
@@ -352,7 +356,7 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
'SIPNAME':sipname, 'HDRNAME': hdrname,
'NPOLNAME': npolname, 'D2IMNAME':d2imname
}
-
+
# Ensure that an entry for this WCS is not already in the dest
# table; if so just skip it
rowind = find_wcscorr_row(old_table.data, selection)
@@ -363,11 +367,11 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
wcs = stwcs.wcsutil.HSTWCS(source, ext=extn, wcskey=wcs_key)
wcshdr = wcs.wcs2header()
-
+
# Update selection column values
for key, val in selection.iteritems():
if key in new_table.data.names:
- new_table.data.field(key)[idx] = val
+ new_table.data.field(key)[idx] = val
for key in wcs_keywords:
if key in new_table.data.names:
@@ -376,21 +380,21 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
for key in DEFAULT_PRI_KEYS:
if key in new_table.data.names and key in prihdr:
new_table.data.field(key)[idx] = prihdr[key]
- # Now look for additional, non-WCS-keyword table column data
+ # Now look for additional, non-WCS-keyword table column data
for key in COL_FITSKW_DICT:
fitkw = COL_FITSKW_DICT[key]
- # Interpret any 'pri.hdrname' or
+ # Interpret any 'pri.hdrname' or
# 'sci.crpix1' formatted keyword names
- if '.' in fitkw:
+ if '.' in fitkw:
srchdr,fitkw = fitkw.split('.')
if 'pri' in srchdr.lower(): srchdr = prihdr
else: srchdr = source[extn].header
else:
srchdr = source[extn].header
-
+
if fitkw+wcs_key in srchdr:
new_table.data.field(key)[idx] = srchdr[fitkw+wcs_key]
-
+
# If idx was never incremented, no rows were added, so there's nothing else
# to do...
@@ -421,7 +425,7 @@ def update_wcscorr(dest, source=None, extname='SCI', wcs_id=None, active=True):
upd_table.data.field(name)[old_nrows:old_nrows + new_nrows] = \
new_table.data.field(name)
upd_table.header.update('TROWS', old_nrows + new_nrows)
-
+
# replace old extension with newly updated table extension
dest['WCSCORR'] = upd_table
@@ -523,7 +527,7 @@ def create_wcscorr(descrip=False, numrows=1, padding=0):
dtype='S'))
# create list of remaining columns to be added to table
col_list = [id_col, extver_col, wcskey_col] # start with selector columns
-
+
for c in col_names:
cdef = copy.deepcopy(c[1])
col_list.append(pyfits.Column(name=c[0], format=cdef['format'],
@@ -548,12 +552,12 @@ def create_wcscorr(descrip=False, numrows=1, padding=0):
def delete_wcscorr_row(wcstab,selections=None,rows=None):
"""
Sets all values in a specified row or set of rows to default values
-
- This function will essentially erase the specified row from the table
- without actually removing the row from the table. This avoids the problems
- with trying to resize the number of rows in the table while preserving the
+
+ This function will essentially erase the specified row from the table
+ without actually removing the row from the table. This avoids the problems
+ with trying to resize the number of rows in the table while preserving the
ability to update the table with new rows again without resizing the table.
-
+
Parameters
----------
wcstab: object
@@ -565,12 +569,12 @@ def delete_wcscorr_row(wcstab,selections=None,rows=None):
If specified, will specify what rows from the table to erase regardless
of the value of 'selections'
"""
-
+
if selections is None and rows is None:
print 'ERROR: Some row selection information must be provided!'
print ' Either a row numbers or "selections" must be provided.'
raise ValueError
-
+
delete_rows = None
if rows is None:
if 'wcs_id' in selections and selections['wcs_id'] == 'OPUS':
@@ -584,7 +588,7 @@ def delete_wcscorr_row(wcstab,selections=None,rows=None):
if not isinstance(rows,list):
rows = [rows]
delete_rows = rows
-
+
# Insure that rows pointing to OPUS WCS do not get deleted, even by accident
for row in delete_rows:
if wcstab['WCS_key'][row] == 'O' or wcstab['WCS_ID'][row] == 'OPUS':
@@ -596,7 +600,7 @@ def delete_wcscorr_row(wcstab,selections=None,rows=None):
# identify next empty row
rowind = find_wcscorr_row(wcstab, selections={'wcs_id':['','0.0']})
last_blank_row = np.where(rowind)[0][-1]
-
+
# copy values from blank row into user-specified rows
for colname in wcstab.names:
wcstab[colname][delete_rows] = wcstab[colname][last_blank_row]
@@ -624,7 +628,7 @@ def update_wcscorr_column(wcstab, column, values, selections=None, rows=None):
print 'ERROR: Some row selection information must be provided!'
print ' Either a row numbers or "selections" must be provided.'
raise ValueError
-
+
if not isinstance(values, list):
values = [values]
@@ -653,7 +657,7 @@ def update_wcscorr_column(wcstab, column, values, selections=None, rows=None):
print ' as there are rows to be updated.'
print ' Table will not be updated...'
raise ValueError
-
+
if len(values) == 1 and len(values) < len(update_rows):
values = values * len(update_rows)
# copy values from blank row into user-specified rows