lsst.ip.diffim  15.0-4-gd76abed+1
snapPsfMatch.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2016 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 from __future__ import absolute_import, division, print_function
23 
24 __all__ = ["SnapPsfMatchConfigDF", "SnapPsfMatchConfigAL", "SnapPsfMatchConfig", "SnapPsfMatchTask"]
25 
26 import lsst.pex.config as pexConfig
27 from .psfMatch import PsfMatchConfigDF, PsfMatchConfigAL
28 from .imagePsfMatch import ImagePsfMatchTask, ImagePsfMatchConfig
29 
30 
32  """Delta-function Psf-matching config optimized for snap subtraction"""
33 
34  def setDefaults(self):
35  PsfMatchConfigDF.setDefaults(self)
36 
37  # No regularization
38  self.useRegularization = False
39 
40  # Pca
42  self.subtractMeanForPca = True
44 
45 
47  """Sum-of-Gaussian (Alard-Lupton) Psf-matching config optimized for snap subtraction"""
48 
49  def setDefaults(self):
50  PsfMatchConfigAL.setDefaults(self)
51 
52  # Simple basis set
53  self.alardNGauss = 2
54  self.alardDegGauss = (4, 2)
55  self.alardSigGauss = (1.0, 2.5)
56 
57 
59  kernel = pexConfig.ConfigChoiceField(
60  doc="kernel type",
61  typemap=dict(
62  AL=SnapPsfMatchConfigAL,
63  DF=SnapPsfMatchConfigDF
64  ),
65  default="AL",
66  )
67 
68  doWarping = pexConfig.Field(
69  dtype=bool,
70  doc="Warp the snaps?",
71  default=False
72  )
73 
74  def setDefaults(self):
75  ImagePsfMatchConfig.setDefaults(self)
76 
77  # No spatial variation in model
78  self.kernel.active.spatialKernelOrder = 0
79 
80  # Don't fit for differential background
81  self.kernel.active.fitForBackground = False
82 
83  # Small kernel size
84  self.kernel.active.kernelSize = 7
85 
86  # With zero spatial order don't worry about spatial clipping
87  self.kernel.active.spatialKernelClipping = False
88 
89 
95 
96 
98  """!
99 \anchor SnapPsfMatchTask_
100 
101 \brief Image-based Psf-matching of two subsequent snaps from the same visit
102 
103 \section ip_diffim_snappsfmatch_Contents Contents
104 
105  - \ref ip_diffim_snappsfmatch_Purpose
106  - \ref ip_diffim_snappsfmatch_Initialize
107  - \ref ip_diffim_snappsfmatch_IO
108  - \ref ip_diffim_snappsfmatch_Config
109  - \ref ip_diffim_snappsfmatch_Metadata
110  - \ref ip_diffim_snappsfmatch_Debug
111  - \ref ip_diffim_snappsfmatch_Example
112 
113 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
114 
115 \section ip_diffim_snappsfmatch_Purpose Description
116 
117 \copybrief SnapPsfMatchTask
118 
119 This Task differs from ImagePsfMatchTask in that it matches two Exposures assuming that the images have
120 been acquired very closely in time. Under this assumption, the astrometric misalignments and/or
121 relative distortions should be within a pixel, and the Psf-shapes should be very similar. As a
122 consequence, the default configurations for this class assume a very simple solution.
123 
124  . The spatial variation in the kernel (SnapPsfMatchConfig.spatialKernelOrder) is assumed to be zero
125 
126  . With no spatial variation, we turn of the spatial clipping loops (SnapPsfMatchConfig.spatialKernelClipping)
127 
128  . The differential background is _not_ fit for (SnapPsfMatchConfig.fitForBackground)
129 
130  . The kernel is expected to be appx. a delta function, and has a small size (SnapPsfMatchConfig.kernelSize)
131 
132 The sub-configurations for the Alard-Lupton (SnapPsfMatchConfigAL) and delta-function (SnapPsfMatchConfigDF)
133 bases also are designed to generate a small, simple kernel.
134 
135 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
136 
137 \section ip_diffim_snappsfmatch_Initialize Task initialization
138 
139 Initialization is the same as base class ImagePsfMatch.__init__, with the difference being that the Task's
140 ConfigClass is SnapPsfMatchConfig.
141 
142 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
143 
144 \section ip_diffim_snappsfmatch_IO Invoking the Task
145 
146 The Task is only configured to have a subtractExposures method, which in turn calls
147 ImagePsfMatchTask.subtractExposures.
148 
149 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
150 
151 \section ip_diffim_snappsfmatch_Config Configuration parameters
152 
153 See \ref SnapPsfMatchConfig, which uses either \ref SnapPsfMatchConfigDF and \ref SnapPsfMatchConfigAL
154 as its active configuration.
155 
156 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
157 
158 \section ip_diffim_snappsfmatch_Metadata Quantities set in Metadata
159 
160 See \ref ip_diffim_psfmatch_Metadata "PsfMatchTask"
161 
162 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
163 
164 \section ip_diffim_snappsfmatch_Debug Debug variables
165 
166 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a
167 flag \c -d/--debug to import \b debug.py from your \c PYTHONPATH. The relevant contents of debug.py
168 for this Task include:
169 
170 \code{.py}
171  import sys
172  import lsstDebug
173  def DebugInfo(name):
174  di = lsstDebug.getInfo(name)
175  if name == "lsst.ip.diffim.psfMatch":
176  di.display = True # enable debug output
177  di.maskTransparency = 80 # ds9 mask transparency
178  di.displayCandidates = True # show all the candidates and residuals
179  di.displayKernelBasis = False # show kernel basis functions
180  di.displayKernelMosaic = True # show kernel realized across the image
181  di.plotKernelSpatialModel = False # show coefficients of spatial model
182  di.showBadCandidates = True # show the bad candidates (red) along with good (green)
183  elif name == "lsst.ip.diffim.imagePsfMatch":
184  di.display = True # enable debug output
185  di.maskTransparency = 30 # ds9 mask transparency
186  di.displayTemplate = True # show full (remapped) template
187  di.displaySciIm = True # show science image to match to
188  di.displaySpatialCells = True # show spatial cells
189  di.displayDiffIm = True # show difference image
190  di.showBadCandidates = True # show the bad candidates (red) along with good (green)
191  elif name == "lsst.ip.diffim.diaCatalogSourceSelector":
192  di.display = False # enable debug output
193  di.maskTransparency = 30 # ds9 mask transparency
194  di.displayExposure = True # show exposure with candidates indicated
195  di.pauseAtEnd = False # pause when done
196  return di
197  lsstDebug.Info = DebugInfo
198  lsstDebug.frame = 1
199 \endcode
200 
201 Note that if you want addional logging info, you may add to your scripts:
202 \code{.py}
203 import lsst.log.utils as logUtils
204 logUtils.traceSetAt("ip.diffim", 4)
205 \endcode
206 
207 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
208 
209 \section ip_diffim_snappsfmatch_Example A complete example of using SnapPsfMatchTask
210 
211 This code is snapPsfMatchTask.py in the examples directory, and can be run as \em e.g.
212 \code
213 examples/snapPsfMatchTask.py
214 examples/snapPsfMatchTask.py --debug
215 examples/snapPsfMatchTask.py --debug --template /path/to/templateExp.fits --science /path/to/scienceExp.fits
216 \endcode
217 
218 \dontinclude snapPsfMatchTask.py
219 First, create a subclass of SnapPsfMatchTask that accepts two exposures. Ideally these exposures would have
220 been taken back-to-back, such that the pointing/background/Psf does not vary substantially between the two:
221 \skip MySnapPsfMatchTask
222 @until return
223 
224 And allow the user the freedom to either run the script in default mode, or point to their own images on disk.
225 Note that these images must be readable as an lsst.afw.image.Exposure:
226 \skip main
227 @until parse_args
228 
229 We have enabled some minor display debugging in this script via the --debug option. However, if you
230 have an lsstDebug debug.py in your PYTHONPATH you will get additional debugging displays. The following
231 block checks for this script:
232 \skip args.debug
233 @until sys.stderr
234 
235 
236 \dontinclude snapPsfMatchTask.py
237 Finally, we call a run method that we define below. First set up a Config and choose the basis set to use:
238 \skip run(args)
239 @until AL
240 
241 Make sure the images (if any) that were sent to the script exist on disk and are readable. If no images
242 are sent, make some fake data up for the sake of this example script (have a look at the code if you want
243 more details on generateFakeImages; as a detail of how the fake images were made, you do have to fit for a
244 differential background):
245 \skip requested
246 @until sizeCellY
247 
248 Display the two images if --debug:
249 \skip args.debug
250 @until Science
251 
252 Create and run the Task:
253 \skip Create
254 @until result
255 
256 And finally provide optional debugging display of the Psf-matched (via the Psf models) science image:
257 \skip args.debug
258 @until result.subtractedExposure
259 
260 #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
261  """
262  ConfigClass = SnapPsfMatchConfig
263 
264  # Override ImagePsfMatchTask.subtractExposures to set doWarping on config.doWarping
265  def subtractExposures(self, templateExposure, scienceExposure,
266  templateFwhmPix=None, scienceFwhmPix=None,
267  candidateList=None):
268  return ImagePsfMatchTask.subtractExposures(self,
269  templateExposure=templateExposure,
270  scienceExposure=scienceExposure,
271  templateFwhmPix=templateFwhmPix,
272  scienceFwhmPix=scienceFwhmPix,
273  candidateList=candidateList,
274  doWarping=self.config.doWarping,
275  )
The parameters specific to the "Alard-Lupton" (sum-of-Gaussian) Psf-matching basis.
Definition: psfMatch.py:370
The parameters specific to the delta-function (one basis per-pixel) Psf-matching basis.
Definition: psfMatch.py:427
Configuration for image-to-image Psf matching.
Psf-match two MaskedImages or Exposures using the sources in the images.
def subtractExposures(self, templateExposure, scienceExposure, templateFwhmPix=None, scienceFwhmPix=None, candidateList=None)
Image-based Psf-matching of two subsequent snaps from the same visit.
Definition: snapPsfMatch.py:97