diff options
Diffstat (limited to 'updatewcs/__init__.py')
-rw-r--r-- | updatewcs/__init__.py | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/updatewcs/__init__.py b/updatewcs/__init__.py new file mode 100644 index 0000000..db89d13 --- /dev/null +++ b/updatewcs/__init__.py @@ -0,0 +1,262 @@ +import os +import pyfits +#from .. wcsutil import HSTWCS +from hstwcs.wcsutil import HSTWCS +from hstwcs.mappings import allowed_corrections +#from .. mappings import allowed_corrections +import corrections, makewcs +import dgeo +import time +from pytools import parseinput, fileutil + +#NB! the order of corrections matters + +__docformat__ = 'restructuredtext' + + +def updatewcs(input, vacorr=True, tddcorr=True, checkfiles=True): + """ + Purpose + ======= + Applies corrections to the WCS keywords. + + Example + ======= + >>>from hstwcs import updatewcs + >>>updatewcs.updatewcs(filename) + + Dependencies + ============ + `pytools` + `pyfits` + `pywcs` + `numpy` + + :Parameters: + `input`: a python list of file names or a string (wild card characters allowed) + input files may be in fits, geis or waiver fits format + `vacorr`: boolean + If True, vecocity aberration correction will be applied + `tddcorr`: boolean + If True, time dependen correction will be applied to the distortion model + `checkfiles`: boolean + If True, the format of the input files will be checked, + geis and waiver fits files will be converted to MEF format. + Default value is True for standalone mode. + """ + + files = parseinput.parseinput(input)[0] + if checkfiles: + files = checkFiles(files) + if not files: + print 'No valid input, quitting ...\n' + return + for f in files: + instr = pyfits.getval(f, 'INSTRUME') + try: + acorr = setCorrections(instr,vacorr=vacorr, tddcorr=tddcorr) + except KeyError: + print 'Unsupported instrument %s ' %instr + print 'Removing %s from list of processed files\n' % f + files.remove(f) + continue + + makecorr(f, acorr) + return files + +def makecorr(fname, acorr): + """ + Purpose + ======= + Applies corrections to a single file + + :Parameters: + `fname`: string + file name + `acorr`: list + list of corrections to be applied + + """ + f = pyfits.open(fname, mode='update') + nrefchip, nrefext = getNrefchip(f) + primhdr = f[0].header + + + for extn in f: + refwcs = HSTWCS(primhdr, f[nrefext].header) + refwcs.archive_kw() + refwcs.readModel() + if extn.header.has_key('extname') and extn.header['extname'].lower() == 'sci': + hdr = extn.header + owcs = HSTWCS(primhdr, hdr) + owcs.archive_kw() + owcs.readModel() + for c in acorr: + owcs.__setattr__('DO'+c, 'PERFORM') + corr_klass = corrections.__getattribute__(c) + corr_klass(owcs, refwcs) + + + + #always do dgeo correction + if applyDgeoCorr(fname): + dgeo.DGEO(f) + f.close() + + +def setCorrections(instrument, vacorr=True, tddcorr=True): + """ + Purpose + ======= + Creates a list of corrections to be applied to a file. + based on user input paramters and allowed corrections + for the instrument, which are defined in mappings.py. + """ + acorr = allowed_corrections[instrument] + if 'VACorr' in acorr and not vacorr: acorr.remove('VACorr') + if 'TDDCorr' in acorr and not tddcorr: acorr.remove('TDDCorr') + if 'DGEOCorr' in acorr and not dgeocorr: acorr.remove('DGEOCorr') + + return acorr + + + +def applyDgeoCorr(fname): + """ + Purpose + ======= + Adds dgeo extensions to files based on the DGEOFILE keyword in the primary + header. This is a default correction and will always run in the pipeline. + The file used to generate the extensions is + recorded in the DGEOFILE keyword in each science extension. + If 'DGEOFILE' in the primary header is different from 'DGEOFILE' in the + extension header and the file exists on disk and is a 'new type' dgeofile, + then the dgeo extensions will be updated. + """ + applyDGEOCorr = True + try: + # get DGEOFILE kw from primary header + fdgeo0 = pyfits.getval(fname, 'DGEOFILE') + fdgeo0 = fileutil.osfn(fdgeo0) + if not fileutil.findFile(fdgeo0): + print 'Kw DGEOFILE exists in primary header but file %s not found\n' % fdgeo0 + print 'DGEO correction will not be applied\n' + applyDGEOCorr = False + return applyDGEOCorr + try: + # get DGEOFILE kw from first extension header + fdgeo1 = pyfits.getval(fname, 'DGEOFILE', ext=1) + fdgeo1 = fileutil.osfn(fdgeo1) + if fdgeo1 and fileutil.findFile(fdgeo1): + if fdgeo0 != fdgeo1: + applyDGEOCorr = True + else: + applyDGEOCorr = False + else: + # dgeo file defined in first extension may not be found + # but if a valid kw exists in the primary header, dgeo should be applied. + applyDGEOCorr = True + except KeyError: + # the case of DGEOFILE kw present in primary header but missing + # in first extension header + applyDGEOCorr = True + except KeyError: + + print 'DGEOFILE keyword not found in primary header' + applyDGEOCorr = False + + if isOldStyleDGEO(fname, fdgeo0): + applyDGEOCorr = False + + return applyDGEOCorr + +def isOldStyleDGEO(fname, dgname): + # checks if the file defined in a DGEOFILE 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) + if sci_naxis1 <= dg_naxis1 or sci_naxis2 <= dg_naxis2: + print 'Only full size (old style) XY file was found.' + print 'DGEO correction will not be applied.\n' + return True + else: + return False + +def getNrefchip(fobj): + """ + This handles the fact that WFPC2 subarray observations + may not include chip 3 which is the default reference chip for + full observations. Also for subarrays chip 3 may not be the third + extension in a MEF file. + """ + Nrefext = 1 + instrument = fobj[0].header['INSTRUME'] + if instrument == 'WFPC2': + detectors = [img.header['DETECTOR'] for img in fobj[1:]] + + if 3 not in detectors: + Nrefchip=detectors[0] + Nrefext = 1 + else: + Nrefchip = 3 + Nrefext = detectors.index(3) + 1 + elif instrument == 'ACS': + detector = fobj[0].header['DETECTOR'] + if detector == 'WCS': + Nrefchip =2 + else: + Nrefchip = 1 + elif instrument == 'NICMOS': + Nrefchip = fobj[0].header['CAMERA'] + return Nrefchip, Nrefext + +def checkFiles(input): + """ + Purpose + ======= + Checks that input files are in the correct format. + Converts geis and waiver fits files to multietension fits. + """ + from pytools.check_files import geis2mef, waiver2mef + removed_files = [] + newfiles = [] + for file in input: + try: + imgfits,imgtype = fileutil.isFits(file) + except IOError: + print "Warning: File %s could not be found\n" %file + print "Removing file %s from input list" %file + removed_files.append(file) + continue + # Check for existence of waiver FITS input, and quit if found. + # Or should we print a warning and continue but not use that file + if imgfits: + if imgtype == 'waiver': + newfilename = waiver2mef(file, convert_dq=True) + if newfilename == None: + print "Removing file %s from input list - could not convert waiver to mef" %file + removed_files.append(file) + else: + newfiles.append(newfilename) + else: + newfiles.append(file) + + # If a GEIS image is provided as input, create a new MEF file with + # a name generated using 'buildFITSName()' + # Convert the corresponding data quality file if present + if not imgfits: + newfilename = geis2mef(file, convert_dq=True) + if newfilename == None: + print "Removing file %s from input list - could not convert geis to mef" %file + removed_files.append(file) + else: + newfiles.append(newfilename) + if removed_files: + print 'The following files will be removed from the list of files to be processed :\n' + for f in removed_files: + print f + return newfiles + |