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