Exemplo n.º 1
0
    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
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
 def __str__(self):
     if self.kernel is None:
         raise PSFErr('notset')
     return "Convolution Kernel:\n" + self.kernel.__str__()
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
 def calc(self, *args, **kwargs):
     if self.model is None:
         raise PSFErr('nofold')
     return self.model.calc(*args, **kwargs)