22 from __future__
import absolute_import, division, print_function
23 import lsst.pex.config
as pexConfig
24 import lsst.afw.math
as afwMath
25 import lsst.afw.image
as afwImage
26 import lsst.afw.geom
as afwGeom
27 import lsst.pipe.base
as pipeBase
28 from lsst.ip.diffim
import ModelPsfMatchTask
29 from lsst.meas.algorithms
import WarpedPsf
31 __all__ = [
"WarpAndPsfMatchTask"]
35 """Config for WarpAndPsfMatchTask 37 psfMatch = pexConfig.ConfigurableField(
38 target=ModelPsfMatchTask,
39 doc=
"PSF matching model to model task",
41 warp = pexConfig.ConfigField(
42 dtype=afwMath.Warper.ConfigClass,
43 doc=
"warper configuration",
48 """A task to warp and PSF-match an exposure 50 ConfigClass = WarpAndPsfMatchConfig
53 pipeBase.Task.__init__(self, *args, **kwargs)
54 self.makeSubtask(
"psfMatch")
55 self.
warper = afwMath.Warper.fromConfig(self.config.warp)
57 def run(self, exposure, wcs, modelPsf=None, maxBBox=None, destBBox=None,
58 makeDirect=True, makePsfMatched=False):
59 """Warp and optionally PSF-match exposure 63 exposure : :cpp:class: `lsst::afw::image::Exposure` 64 Exposure to preprocess. 65 wcs : :cpp:class:`lsst::afw::image::Wcs` 66 Desired WCS of temporary images. 67 modelPsf : :cpp:class: `lsst::meas::algorithms::KernelPsf` or None 68 Target PSF to which to match. 69 maxBBox : :cpp:class:`lsst::afw::geom::Box2I` or None 70 Maximum allowed parent bbox of warped exposure. 71 If None then the warped exposure will be just big enough to contain all warped pixels; 72 if provided then the warped exposure may be smaller, and so missing some warped pixels; 73 ignored if destBBox is not None. 74 destBBox: :cpp:class: `lsst::afw::geom::Box2I` or None 75 Exact parent bbox of warped exposure. 76 If None then maxBBox is used to determine the bbox, otherwise maxBBox is ignored. 78 Return an exposure that has been only warped? 80 Return an exposure that has been warped and PSF-matched? 84 An lsst.pipe.base.Struct with the following fields: 86 direct : :cpp:class:`lsst::afw::image::Exposure` 88 psfMatched : :cpp:class: `lsst::afw::image::Exposure` 89 warped and psf-Matched temporary exposure 91 if makePsfMatched
and modelPsf
is None:
92 raise RuntimeError(
"makePsfMatched=True, but no model PSF was provided")
94 if not makePsfMatched
and not makeDirect:
95 self.log.warn(
"Neither makeDirect nor makePsfMatched requested")
98 xyTransform = afwImage.XYTransformFromWcsPair(wcs, exposure.getWcs())
99 psfWarped = WarpedPsf(exposure.getPsf(), xyTransform)
101 if makePsfMatched
and maxBBox
is not None:
103 pixToGrow = 2 * max(self.psfMatch.kConfig.sizeCellX,
104 self.psfMatch.kConfig.sizeCellY)
106 maxBBox = afwGeom.Box2I(maxBBox)
107 maxBBox.grow(pixToGrow)
109 with self.timer(
"warp"):
110 exposure = self.
warper.warpExposure(wcs, exposure, maxBBox=maxBBox, destBBox=destBBox)
111 exposure.setPsf(psfWarped)
115 exposurePsfMatched = self.psfMatch.
run(exposure, modelPsf).psfMatchedExposure
116 except Exception
as e:
117 exposurePsfMatched =
None 118 self.log.info(
"Cannot PSF-Match: %s" % (e))
120 return pipeBase.Struct(
121 direct=exposure
if makeDirect
else None,
122 psfMatched=exposurePsfMatched
if makePsfMatched
else None
def run(self, exposure, wcs, modelPsf=None, maxBBox=None, destBBox=None, makeDirect=True, makePsfMatched=False)
def __init__(self, args, kwargs)