22 import lsst.pex.config 
as pexConfig
 
   30 __all__ = [
"WarpAndPsfMatchTask"]
 
   34     """Config for WarpAndPsfMatchTask 
   36     psfMatch = pexConfig.ConfigurableField(
 
   37         target=ModelPsfMatchTask,
 
   38         doc=
"PSF matching model to model task",
 
   40     warp = pexConfig.ConfigField(
 
   41         dtype=afwMath.Warper.ConfigClass,
 
   42         doc=
"warper configuration",
 
   47     """A task to warp and PSF-match an exposure 
   49     ConfigClass = WarpAndPsfMatchConfig
 
   52         pipeBase.Task.__init__(self, *args, **kwargs)
 
   53         self.makeSubtask(
"psfMatch")
 
   54         self.
warper = afwMath.Warper.fromConfig(self.config.warp)
 
   56     def run(self, exposure, wcs, modelPsf=None, maxBBox=None, destBBox=None,
 
   57             makeDirect=True, makePsfMatched=False):
 
   58         """Warp and optionally PSF-match exposure 
   62         exposure : :cpp:class: `lsst::afw::image::Exposure` 
   63             Exposure to preprocess. 
   64         wcs : :cpp:class:`lsst::afw::image::Wcs` 
   65             Desired WCS of temporary images. 
   66         modelPsf : :cpp:class: `lsst::meas::algorithms::KernelPsf` or None 
   67             Target PSF to which to match. 
   68         maxBBox : :cpp:class:`lsst::afw::geom::Box2I` or None 
   69             Maximum allowed parent bbox of warped exposure. 
   70             If None then the warped exposure will be just big enough to contain all warped pixels; 
   71             if provided then the warped exposure may be smaller, and so missing some warped pixels; 
   72             ignored if destBBox is not None. 
   73         destBBox: :cpp:class: `lsst::afw::geom::Box2I` or None 
   74             Exact parent bbox of warped exposure. 
   75             If None then maxBBox is used to determine the bbox, otherwise maxBBox is ignored. 
   77             Return an exposure that has been only warped? 
   79             Return an exposure that has been warped and PSF-matched? 
   83         An lsst.pipe.base.Struct with the following fields: 
   85         direct : :cpp:class:`lsst::afw::image::Exposure` 
   87         psfMatched : :cpp:class: `lsst::afw::image::Exposure` 
   88             warped and psf-Matched temporary exposure 
   90         if makePsfMatched 
and modelPsf 
is None:
 
   91             raise RuntimeError(
"makePsfMatched=True, but no model PSF was provided")
 
   93         if not makePsfMatched 
and not makeDirect:
 
   94             self.log.
warn(
"Neither makeDirect nor makePsfMatched requested")
 
   98         psfWarped = 
WarpedPsf(exposure.getPsf(), xyTransform)
 
  100         if makePsfMatched 
and maxBBox 
is not None:
 
  102             pixToGrow = 2 * 
max(self.psfMatch.kConfig.sizeCellX,
 
  103                                 self.psfMatch.kConfig.sizeCellY)
 
  106             maxBBox.grow(pixToGrow)
 
  108         with self.timer(
"warp"):
 
  109             exposure = self.
warper.
warpExposure(wcs, exposure, maxBBox=maxBBox, destBBox=destBBox)
 
  110             exposure.setPsf(psfWarped)
 
  114                 exposurePsfMatched = self.psfMatch.
run(exposure, modelPsf).psfMatchedExposure
 
  115             except Exception 
as e:
 
  116                 exposurePsfMatched = 
None 
  117                 self.log.
info(
"Cannot PSF-Match: %s" % (e))
 
  119         return pipeBase.Struct(
 
  120             direct=exposure 
if makeDirect 
else None,
 
  121             psfMatched=exposurePsfMatched 
if makePsfMatched 
else None