LSSTApplications  20.0.0
LSSTDataManagementBasePackage
warpAndPsfMatch.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010, 2011, 2012 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 import lsst.pex.config as pexConfig
23 import lsst.afw.math as afwMath
24 import lsst.geom as geom
25 import lsst.afw.geom as afwGeom
26 import lsst.pipe.base as pipeBase
27 from lsst.ip.diffim import ModelPsfMatchTask
28 from lsst.meas.algorithms import WarpedPsf
29 
30 __all__ = ["WarpAndPsfMatchTask"]
31 
32 
33 class WarpAndPsfMatchConfig(pexConfig.Config):
34  """Config for WarpAndPsfMatchTask
35  """
36  psfMatch = pexConfig.ConfigurableField(
37  target=ModelPsfMatchTask,
38  doc="PSF matching model to model task",
39  )
40  warp = pexConfig.ConfigField(
41  dtype=afwMath.Warper.ConfigClass,
42  doc="warper configuration",
43  )
44 
45 
46 class WarpAndPsfMatchTask(pipeBase.Task):
47  """A task to warp and PSF-match an exposure
48  """
49  ConfigClass = WarpAndPsfMatchConfig
50 
51  def __init__(self, *args, **kwargs):
52  pipeBase.Task.__init__(self, *args, **kwargs)
53  self.makeSubtask("psfMatch")
54  self.warper = afwMath.Warper.fromConfig(self.config.warp)
55 
56  def run(self, exposure, wcs, modelPsf=None, maxBBox=None, destBBox=None,
57  makeDirect=True, makePsfMatched=False):
58  """Warp and optionally PSF-match exposure
59 
60  Parameters
61  ----------
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.
76  makeDirect : bool
77  Return an exposure that has been only warped?
78  makePsfMatched : bool
79  Return an exposure that has been warped and PSF-matched?
80 
81  Returns
82  -------
83  An lsst.pipe.base.Struct with the following fields:
84 
85  direct : :cpp:class:`lsst::afw::image::Exposure`
86  warped exposure
87  psfMatched : :cpp:class: `lsst::afw::image::Exposure`
88  warped and psf-Matched temporary exposure
89  """
90  if makePsfMatched and modelPsf is None:
91  raise RuntimeError("makePsfMatched=True, but no model PSF was provided")
92 
93  if not makePsfMatched and not makeDirect:
94  self.log.warn("Neither makeDirect nor makePsfMatched requested")
95 
96  # Warp PSF before overwriting exposure
97  xyTransform = afwGeom.makeWcsPairTransform(exposure.getWcs(), wcs)
98  psfWarped = WarpedPsf(exposure.getPsf(), xyTransform)
99 
100  if makePsfMatched and maxBBox is not None:
101  # grow warped region to provide sufficient area for PSF-matching
102  pixToGrow = 2 * max(self.psfMatch.kConfig.sizeCellX,
103  self.psfMatch.kConfig.sizeCellY)
104  # replace with copy
105  maxBBox = geom.Box2I(maxBBox)
106  maxBBox.grow(pixToGrow)
107 
108  with self.timer("warp"):
109  exposure = self.warper.warpExposure(wcs, exposure, maxBBox=maxBBox, destBBox=destBBox)
110  exposure.setPsf(psfWarped)
111 
112  if makePsfMatched:
113  try:
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))
118 
119  return pipeBase.Struct(
120  direct=exposure if makeDirect else None,
121  psfMatched=exposurePsfMatched if makePsfMatched else None
122  )
lsst.pipe.tasks.warpAndPsfMatch.WarpAndPsfMatchTask.__init__
def __init__(self, *args, **kwargs)
Definition: warpAndPsfMatch.py:51
lsst::ip::diffim
Definition: AssessSpatialKernelVisitor.h:22
lsst::log.log.logContinued.warn
def warn(fmt, *args)
Definition: logContinued.py:202
lsst::log.log.logContinued.info
def info(fmt, *args)
Definition: logContinued.py:198
warpExposure
lsst.pipe.tasks.warpAndPsfMatch.WarpAndPsfMatchConfig
Definition: warpAndPsfMatch.py:33
lsst.pipe.tasks.warpAndPsfMatch.WarpAndPsfMatchTask
Definition: warpAndPsfMatch.py:46
lsst.pipe.tasks.warpAndPsfMatch.WarpAndPsfMatchTask.warper
warper
Definition: warpAndPsfMatch.py:54
max
int max
Definition: BoundedField.cc:104
lsst::meas::algorithms::WarpedPsf
A Psf class that maps an arbitrary Psf through a coordinate transformation.
Definition: WarpedPsf.h:50
lsst::geom
Definition: geomOperators.dox:4
lsst::afw::geom::makeWcsPairTransform
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
A Transform obtained by putting two SkyWcs objects "back to back".
Definition: SkyWcs.cc:151
lsst::afw::math
Definition: statistics.dox:6
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst.pipe.base
Definition: __init__.py:1
lsst::meas::algorithms
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.
Definition: CoaddBoundedField.h:34
lsst.pipe.tasks.warpAndPsfMatch.WarpAndPsfMatchTask.run
def run(self, exposure, wcs, modelPsf=None, maxBBox=None, destBBox=None, makeDirect=True, makePsfMatched=False)
Definition: warpAndPsfMatch.py:56
lsst::afw::geom
Definition: frameSetUtils.h:40