Source code for drizzlepac.mdzhandler

"""
This module supports the interpretation of the ``MDRIZTAB`` for
processing as used in the pipeline. The MDRIZTAB reference table contains 
AstroDrizzle task parameters optimized for a wide range of observations. 
AstroDrizzle uses this table to match the best parameter values with the 
type of observations being processed. Each instrument detector has its own 
MDRIZTAB reference table.

:Authors: Warren Hack, Ivo Busko, Christopher Hanley

:License: :doc:`/LICENSE`

"""
import string, os

from astropy.io import fits
import numpy as np

from stsci.tools import fileutil

[docs] def getMdriztabParameters(files): """ Gets entry in MDRIZTAB where task parameters live. This method returns a record array mapping the selected row. """ # Get the MDRIZTAB table file name from the primary header. # It is gotten from the first file in the input list. No # consistency checks are performed. _fileName = files[0] _header = fileutil.getHeader(_fileName) if 'MDRIZTAB' in _header: _tableName = _header['MDRIZTAB'] else: raise KeyError("No MDRIZTAB found in file " + _fileName) _tableName = fileutil.osfn(_tableName) # Now get the filters from the primary header. _filters = fileutil.getFilterNames(_header) # Specifically check to see whether the MDRIZTAB file can be found mtab_path = os.path.split(_tableName)[0] # protect against no path given for _tableName if mtab_path and not os.path.exists(mtab_path): # check path first, if given raise IOError("Directory for MDRIZTAB '%s' could not be accessed!"%mtab_path) if not os.path.exists(_tableName): # then check for the table itself raise IOError("MDRIZTAB table '%s' could not be found!"%_tableName) # Open MDRIZTAB file. try: _mdriztab = fits.open(_tableName, memmap=False) except: raise IOError("MDRIZTAB table '%s' not valid!" % _tableName) # Look for matching rows based on filter name. If no # match, pick up rows for the default filter. _rows = _getRowsByFilter(_mdriztab, _filters) if _rows == []: _rows = _getRowsByFilter(_mdriztab, 'ANY') # Now look for the row that matches the number of images. # The logic below assumes that rows for a given filter # are arranged in ascending order of the 'numimage' field. _nimages = len(files) _row = 0 for i in _rows: _numimages = _mdriztab[1].data.field('numimages')[i] if _nimages >= _numimages: _row = i print('- MDRIZTAB: AstroDrizzle parameters read from row %s.'%(_row+1)) mpars = _mdriztab[1].data[_row] _mdriztab.close() interpreted = _interpretMdriztabPars(mpars) if "staticfile" in interpreted: interpreted.pop("staticfile") return interpreted
def _getRowsByFilter(table, filters): rows = [] for i in range(table[1].data.shape[0]): _tfilters = table[1].data.field('filter')[i] if _tfilters == filters: rows.append(i) return rows def _interpretMdriztabPars(rec): """ Collect task parameters from the MDRIZTAB record and update the master parameters list with those values Note that parameters read from the MDRIZTAB record must be cleaned up in a similar way that parameters read from the user interface are. """ tabdict = {} # for each entry in the record... for indx in range(len(rec.array.names)): # ... get the name, format, and value. _name = rec.array.names[indx] _format = rec.array.formats[indx] _value = rec.field(_name) # Translate names from MDRIZTAB columns names to # input parameter names found in IRAF par file. # #if _name.find('final') > -1: _name = 'driz_'+_name if _name in ['shiftfile','mdriztab']: continue drizstep_names = ['driz_sep_','final_'] if _name in ['refimage','bits']: for dnames in drizstep_names: tabdict[dnames+_name] = _value continue if _name in ['driz_sep_bits','final_bits']: tabdict[_name] = str(_value) continue if _name == 'coeffs': _val = True if _value in ['INDEF',None,"None",'',' ']: _val = False tabdict[_name] = _val continue par_table = {'subsky':'skysub','crbitval':'crbit','readnoise':'rdnoise'} if _name in par_table: _name = par_table[_name] # We do not care about the first two columns at this point # as they are only used for selecting the rows if _name != 'filter' and _name != 'numimages': # start by determining the format type of the parameter _fmt = findFormat(_format) # Based on format type, apply proper conversion/cleaning if (_fmt == 'a') or (_fmt == 'A'): _val = cleanBlank(_value) if _val is None: _val = '' elif (_format == 'i1') or (_format=='1L'): _val = toBoolean(_value) elif (_format == 'i4') or (_format == '1J'): _val = cleanInt(_value) elif ('E' in _format) or (_format == 'f4') : _val = cleanNaN(_value) else: print('MDRIZTAB column ',_name,' has unrecognized format',_format) raise ValueError if _name in ['ra','dec']: for dnames in drizstep_names: tabdict[dnames+_name] = _val else: tabdict[_name] = _val return tabdict
[docs] def toBoolean(flag): if (flag == 1): return True return False
[docs] def cleanNaN(value): a = np.array(value) # b = np.where(np.isnan(a)) if np.any(np.isnan(a)): return None return float(value)
[docs] def cleanInt(value): # THIS MAY BE MACHINE-DEPENDENT !!! if value == -2147483647: # Try to use 'sys.maxint' as value (WJH) #if value == -sys.maxint: return None return int(value)
[docs] def cleanBlank(value): if value.strip() == '': return None return value
[docs] def findFormat(format): # Parses record array format string for type _fmt = None for ltr in string.ascii_letters: if format.find(ltr) > -1: _fmt = ltr break return _fmt