22__all__ = [
"WarpAndPsfMatchTask"]
28import lsst.pipe.base
as pipeBase
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.warning(
"Neither makeDirect nor makePsfMatched requested")
97 xyTransform = afwGeom.makeWcsPairTransform(exposure.getWcs(), wcs)
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
def __init__(self, *args, **kwargs)