def calc(self, *args, **kwargs): if self.model is None: raise PSFErr('nofold') psf_space_evaluation = self.model.calc(*args, **kwargs) if self._must_rebin: return rebin_2d(psf_space_evaluation, self.psf_space, self.data_space).ravel() else: return psf_space_evaluation
def _set_origin(self, vals): par = vals if type(vals) in (str, numpy.string_): raise PSFErr('notstr') elif type(vals) not in (list, tuple, numpy.ndarray): par = [vals] self._origin = tuple(par) if par is None: self._origin = None
def get_kernel(self, data, subkernel=True): indep, dep, kshape, lo, hi = self._get_kernel_data(data, subkernel) ndim = len(kshape) if ndim == 1: dataset = Data1D('kernel', indep[0], dep) elif ndim == 2: dataset = Data2D('kernel', indep[0], indep[1], dep, kshape[::-1]) else: raise PSFErr('ndim') return dataset
def __call__(self, model, session=None): if self.kernel is None: raise PSFErr('notset') kernel = self.kernel if isinstance(kernel, Data): kernel = numpy.asarray(kernel.get_dep()) if isinstance(model, string_types): if session is None: model = sherpa.astro.ui._session._eval_model_expression(model) else: model = session._eval_model_expression(model) return ConvolutionModel(kernel, model, self)
def _get_kernel_data(self, data, subkernel=True): self.fold(data) if self.kernel is None: raise PSFErr('notset') kernel = self.kernel dep = None indep = None lo = None hi = None if isinstance(kernel, Data): dep = numpy.asarray(kernel.get_dep()) indep = kernel.get_indep() elif callable(kernel): dep = kernel(*self.model.args, **self.model.kwargs) indep = self.model.args kshape = self.model.kshape if subkernel: (dep, newshape) = self.model.init_kernel(dep) if (numpy.array(kshape) != numpy.array(newshape)).any(): newindep = [] for axis in indep: args = extract_kernel(axis, self.model.kshape, self.model.size, self.model.center, self.model.lo, self.model.hi, self.model.width, self.model.radial) newaxis = args[0] lo = args[3] # subkernel offsets (lower bound) hi = args[4] # subkernel offsets (upper bound) newindep.append(newaxis) indep = newindep kshape = newshape if self.model.frac is not None: info('PSF frac: %s' % self.model.frac) if numpy.isscalar(kshape): kshape = [kshape] return (indep, dep, kshape, lo, hi)
def get_kernel(self, data, subkernel=True): indep, dep, kshape, lo, hi = self._get_kernel_data(data, subkernel) # Use kernel data set WCS if available eqpos = getattr(self.kernel, 'eqpos', None) sky = getattr(self.kernel, 'sky', None) # If kernel is a model, use WCS from data if available if callable(self.kernel): eqpos = getattr(data, 'eqpos', None) sky = getattr(data, 'sky', None) dataset = None ndim = len(kshape) if ndim == 1: dataset = Data1D('kernel', indep[0], dep) elif ndim == 2: # Edit WCS to reflect the subkernel extraction in # physical coordinates. if (subkernel and sky is not None and lo is not None and hi is not None): if (WCS is not None): sky = WCS(sky.name, sky.type, sky.crval, sky.crpix - lo, sky.cdelt, sky.crota, sky.epoch, sky.equinox) # FIXME: Support for WCS only (non-Chandra) coordinate # transformations? dataset = DataIMG('kernel', indep[0], indep[1], dep, kshape[::-1], sky=sky, eqpos=eqpos) else: raise PSFErr('ndim') return dataset
def fold(self, data): # FIXME how will we know the native dimensionality of the # raveled model without the values? kargs = {} kshape = None dshape = data.get_dims() (size, center, origin, kargs['norm'], radial) = (self.size, self.center, self.origin, bool_cast(self.norm.val), int(self.radial.val)) kargs['size'] = size kargs['center'] = center kargs['origin'] = origin kargs['is_model'] = False kargs['do_pad'] = False kargs['args'] = data.get_indep() pixel_size_comparison = self._check_pixel_size(data) if pixel_size_comparison == self.SAME_RESOLUTION: # Don't do anything special self.data_space = EvaluationSpace2D(*data.get_indep()) self._must_rebin = False elif pixel_size_comparison == self.BETTER_RESOLUTION: # Evaluate model in PSF space self.data_space = EvaluationSpace2D(*data.get_indep()) self.psf_space = PSFSpace2D(self.data_space, self, data.sky.cdelt) kargs['args'] = self.psf_space.grid dshape = self.psf_space.shape self._must_rebin = True else: # PSF has worse resolution, error out raise AttributeError( "The PSF has a worse resolution than the data.") if isinstance(self.kernel, Data): kshape = self.kernel.get_dims() # (kargs['lo'], kargs['hi'], # kargs['width']) = _get_axis_info(self.kernel.get_indep(), kshape) kargs['lo'] = [1] * len(kshape) kargs['hi'] = kshape kargs['width'] = [1] * len(kshape) if center is None: kargs['center'] = [int(dim / 2.) for dim in kshape] # update center param to default self.center = kargs['center'] if size is None: kargs['size'] = kshape # update size param to default self.size = kargs['size'] else: if (self.kernel is None) or (not callable(self.kernel)): raise PSFErr('nopsf', self._name) kshape = data.get_dims() # (kargs['lo'], kargs['hi'], # kargs['width']) = _get_axis_info(kargs['args'], dshape) kargs['lo'] = [1] * len(kshape) kargs['hi'] = kshape kargs['width'] = [1] * len(kshape) if center is None: kargs['center'] = [int(dim / 2.) for dim in dshape] # update center param to default self.center = kargs['center'] if size is None: kargs['size'] = dshape # update size param to default self.size = kargs['size'] kargs['is_model'] = True if hasattr(self.kernel, 'pars'): # freeze all PSF model parameters if not already. for par in self.kernel.pars: par.freeze() if hasattr(self.kernel, 'thawedpars'): kargs['frozen'] = (len(self.kernel.thawedpars) == 0) is_kernel = (kargs['is_model'] and not kargs['norm'] and len(kshape) == 1) # Handle noticed regions for convolution if numpy.iterable(data.mask): kargs['do_pad'] = True kargs['pad_mask'] = data.mask if is_kernel: for id in ['is_model', 'lo', 'hi', 'width', 'size']: kargs.pop(id) self.model = Kernel(dshape, kshape, **kargs) return if radial: self.model = RadialProfileKernel(dshape, kshape, **kargs) return self.model = PSFKernel(dshape, kshape, **kargs) return
def __str__(self): if self.kernel is None: raise PSFErr('notset') return "Convolution Kernel:\n" + self.kernel.__str__()
def fold(self, data): # FIXME how will we know the native dimensionality of the # raveled model without the values? self._check_pixel_size(data) kargs = {} kshape = None dshape = data.get_dims() (size, center, origin, kargs['norm'], radial) = (self.size, self.center, self.origin, bool_cast(self.norm.val), int(self.radial.val)) kargs['size'] = size kargs['center'] = center kargs['origin'] = origin kargs['is_model'] = False kargs['do_pad'] = False kargs['args'] = data.get_indep() if isinstance(self.kernel, Data): kshape = self.kernel.get_dims() # (kargs['lo'], kargs['hi'], # kargs['width']) = _get_axis_info(self.kernel.get_indep(), kshape) kargs['lo'] = [1] * len(kshape) kargs['hi'] = kshape kargs['width'] = [1] * len(kshape) if center is None: kargs['center'] = [int(dim / 2.) for dim in kshape] # update center param to default self.center = kargs['center'] if size is None: kargs['size'] = kshape # update size param to default self.size = kargs['size'] else: if (self.kernel is None) or (not callable(self.kernel)): raise PSFErr('nopsf', self._name) kshape = data.get_dims() # (kargs['lo'], kargs['hi'], # kargs['width']) = _get_axis_info(kargs['args'], dshape) kargs['lo'] = [1] * len(kshape) kargs['hi'] = kshape kargs['width'] = [1] * len(kshape) if center is None: kargs['center'] = [int(dim / 2.) for dim in dshape] # update center param to default self.center = kargs['center'] if size is None: kargs['size'] = dshape # update size param to default self.size = kargs['size'] kargs['is_model'] = True if hasattr(self.kernel, 'pars'): # freeze all PSF model parameters if not already. for par in self.kernel.pars: par.freeze() if hasattr(self.kernel, 'thawedpars'): kargs['frozen'] = (len(self.kernel.thawedpars) == 0) # check size of self.size to ensure <= dshape for 2D # if len(dshape) > 1: # dsize = numpy.asarray(dshape) # ksize = numpy.asarray(self.size) # if True in (ksize>dsize): # raise PSFErr('badsize', ksize, dsize) is_kernel = (kargs['is_model'] and not kargs['norm'] and len(kshape) == 1) # Handle noticed regions for convolution if numpy.iterable(data.mask): kargs['do_pad'] = True kargs['pad_mask'] = data.mask if is_kernel: for id in ['is_model', 'lo', 'hi', 'width', 'size']: kargs.pop(id) self.model = Kernel(dshape, kshape, **kargs) return if radial: self.model = RadialProfileKernel(dshape, kshape, **kargs) return self.model = PSFKernel(dshape, kshape, **kargs) return
def calc(self, *args, **kwargs): if self.model is None: raise PSFErr('nofold') return self.model.calc(*args, **kwargs)