Source code for jwst.resample.resample_step

import logging

import numpy as np

from ..stpipe import Step
from ..extern.configobj.validate import Validator
from ..extern.configobj.configobj import ConfigObj
from .. import datamodels
from . import resample
from ..assign_wcs import util

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

__all__ = ["ResampleStep"]


[docs]class ResampleStep(Step): """ Resample input data onto a regular grid using the drizzle algorithm. Parameters ----------- input : DataModel or Association Single filename for either a single image or an association table. """ spec = """ pixfrac = float(default=None) kernel = string(default=None) fillval = string(default=None) weight_type = option('exptime', default=None) good_bits = integer(min=0, default=4) single = boolean(default=False) blendheaders = boolean(default=True) """ reference_file_types = ['drizpars']
[docs] def process(self, input): input = datamodels.open(input) # If single input, wrap in a ModelContainer if not isinstance(input, datamodels.ModelContainer): input_models = datamodels.ModelContainer([input]) input_models.meta.resample.output = input.meta.filename self.blendheaders = False else: input_models = input # Check that input models are 2D images if len(input_models[0].data.shape) != 2: # resample can only handle 2D images, not 3D cubes, etc raise RuntimeError("Input {} is not a 2D image.".format(input_models[0])) # Get drizzle parameters reference file for reftype in self.reference_file_types: ref_filename = self.get_reference_file(input_models[0], reftype) if ref_filename != 'N/A': self.log.info('Drizpars reference file: {}'.format(ref_filename)) kwargs = self.get_drizpars(ref_filename, input_models) else: # Deal with NIRSpec which currently has no default drizpars reffile self.log.info("No NIRSpec DIRZPARS reffile") kwargs = self._set_spec_defaults() # Call the resampling routine resamp = resample.ResampleData(input_models, **kwargs) resamp.do_drizzle() for model in resamp.output_models: model.meta.cal_step.resample = "COMPLETE" util.update_s_region_imaging(model) model.meta.asn.pool_name = input_models.meta.pool_name model.meta.asn.table_name = input_models.meta.table_name if len(resamp.output_models) == 1: result = resamp.output_models[0] else: result = resamp.output_models return result
[docs] def get_drizpars(self, ref_filename, input_models): """ Extract drizzle parameters from reference file. This method extracts parameters from the drizpars reference file and uses those to set defaults on the following ResampleStep configuration parameters: pixfrac = float(default=None) kernel = string(default=None) fillval = string(default=None) weight_type = option('exptime', default=None) Once the defaults are set from the reference file, if the user has used a resample.cfg file or run ResampleStep using command line args, then these will overwerite the defaults pulled from the reference file. """ drizpars_table = datamodels.DrizParsModel(ref_filename).data num_groups = len(input_models.group_names) filtname = input_models[0].meta.instrument.filter row = None filter_match = False # look for row that applies to this set of input data models for n, filt, num in zip( range(0, len(drizpars_table)), drizpars_table['filter'], drizpars_table['numimages'] ): # only remember this row if no exact match has already been made for # the filter. This allows the wild-card row to be anywhere in the # table; since it may be placed at beginning or end of table. if str(filt) == "ANY" and not filter_match and num_groups >= num: row = n # always go for an exact match if present, though... if filtname == filt and num_groups >= num: row = n filter_match = True # With presence of wild-card rows, code should never trigger this logic if row is None: self.log.error("No row found in %s matching input data.", ref_filename) raise ValueError # Define the keys to pull from drizpars reffile table. Note the # step param 'weight_type' is 'wht_type' in the FITS binary table. # All values should be None unless the user set them on the command # line or in the call to the step drizpars = dict( pixfrac=self.pixfrac, kernel=self.kernel, fillval=self.fillval, wht_type=self.weight_type ) # For parameters that are set in drizpars table but not set by the # user, use these. Otherwise, use values set by user. reffile_drizpars = {k:v for k,v in drizpars.items() if v is None} user_drizpars = {k:v for k,v in drizpars.items() if v is not None} # read in values from that row for each parameter for k in reffile_drizpars: if k in drizpars_table.names: reffile_drizpars[k] = drizpars_table[k][row] # Convert the strings in the FITS binary table from np.bytes_ to str for k,v in reffile_drizpars.items(): if isinstance(v, np.bytes_): reffile_drizpars[k] = v.decode('UTF-8') all_drizpars = {**reffile_drizpars, **user_drizpars} # Convert the 'wht_type' key to a 'weight_type' key all_drizpars['weight_type'] = all_drizpars.pop('wht_type') kwargs = dict( good_bits=self.good_bits, single=self.single, blendheaders=self.blendheaders ) kwargs.update(all_drizpars) if 'wht_type' in kwargs: raise DeprecationWarning('`wht_type` config keyword has changed ' + 'to `weight_type`; ' + 'please update calls to ResampleStep and resample.cfg files') kwargs.pop('wht_type') for k,v in kwargs.items(): self.log.debug(' {}={}'.format(k, v)) return kwargs
@classmethod def _set_spec_defaults(cls): """NIRSpec currently has no default drizpars reference file, so default drizzle parameters are not set properly. This method sets them. Remove this class method when a drizpars reffile is delivered. """ configspec = cls.load_spec_file() config = ConfigObj(configspec=configspec) if config.validate(Validator()): kwargs = config.dict() if kwargs['pixfrac'] is None: kwargs['pixfrac'] = 1.0 if kwargs['kernel'] is None: kwargs['kernel'] = 'square' if kwargs['fillval'] is None: kwargs['fillval'] = 'INDEF' if kwargs['weight_type'] is None: kwargs['weight_type'] = 'exptime' for k,v in kwargs.items(): if k in ['pixfrac', 'kernel', 'fillval', 'weight_type']: log.info(' setting: %s=%s', k, repr(v)) return kwargs