LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
repair.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2016 AURA/LSST.
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 <https://www.lsstcorp.org/LegalNotices/>.
21 #
22 import lsst.pex.config as pexConfig
23 import lsst.afw.math as afwMath
24 import lsst.afw.detection as afwDet
25 import lsst.meas.algorithms as measAlg
26 import lsst.pipe.base as pipeBase
27 from lsstDebug import getDebugFrame
28 from lsst.afw.display import getDisplay
29 from lsst.pipe.tasks.interpImage import InterpImageTask
30 
31 class RepairConfig(pexConfig.Config):
32  doInterpolate = pexConfig.Field(
33  dtype = bool,
34  doc = "Interpolate over defects? (ignored unless you provide a list of defects)",
35  default = True,
36  )
37  doCosmicRay = pexConfig.Field(
38  dtype = bool,
39  doc = "Find and mask out cosmic rays?",
40  default = True,
41  )
42  cosmicray = pexConfig.ConfigField(
43  dtype = measAlg.FindCosmicRaysConfig,
44  doc = "Options for finding and masking cosmic rays",
45  )
46  interp = pexConfig.ConfigurableField(
47  target = InterpImageTask,
48  doc = "Interpolate over bad image pixels",
49  )
50 
51  def setDefaults(self):
52  self.interp.useFallbackValueAtEdge = True
53  self.interp.fallbackValueType = "MEANCLIP"
54  self.interp.negativeFallbackAllowed = True
55 
56 ## \addtogroup LSST_task_documentation
57 ## \{
58 ## \page RepairTask
59 ## \ref RepairTask_ "RepairTask"
60 ## \copybrief RepairTask
61 ## \}
62 
63 class RepairTask(pipeBase.Task):
64  """!
65  \anchor RepairTask_
66 
67  \brief Interpolate over defects in an exposure and handle cosmic rays
68 
69  \section pipe_tasks_repair_Contents Contents
70 
71  - \ref pipe_tasks_repair_Purpose
72  - \ref pipe_tasks_repair_Initialize
73  - \ref pipe_tasks_repair_IO
74  - \ref pipe_tasks_repair_Config
75  - \ref pipe_tasks_repair_Debug
76  - \ref pipe_tasks_repair_Example
77 
78  \section pipe_tasks_repair_Purpose Description
79 
80  \copybrief RepairTask
81 
82  This task operates on an lsst.afw.image.Exposure in place to interpolate over a set of
83  lsst.meas.algorithms.Defect objects.
84  It will also, optionally, find and interpolate any cosmic rays in the lsst.afw.image.Exposure.
85 
86  \section pipe_tasks_repair_Initialize Task initialization
87 
88  See: lsst.pipe.base.task.Task.__init__
89 
90  \section pipe_tasks_repair_IO Inputs/Outputs to the run method
91 
92  \copydoc run
93 
94  \section pipe_tasks_repair_Config Configuration parameters
95 
96  See \ref RepairConfig
97 
98  \section pipe_tasks_repair_Debug Debug variables
99 
100  The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a
101  flag \c -d to import \b debug.py from your \c PYTHONPATH; see <a
102  href="http://lsst-web.ncsa.illinois.edu/~buildbot/doxygen/x_masterDoxyDoc/base_debug.html">
103  Using lsstDebug to control debugging output</a> for more about \b debug.py files.
104 
105  The available variables in RepairTask are:
106  <DL>
107  <DT> \c display
108  <DD> A dictionary containing debug point names as keys with frame number as value. Valid keys are:
109  <DL>
110  <DT> repair.before
111  <DD> display image before any repair is done
112  <DT> repair.after
113  <DD> display image after cosmic ray and defect correction
114  </DL>
115  <DT> \c displayCR
116  <DD> If True, display the exposure on ds9's frame 1 and overlay bounding boxes around detects CRs.
117  </DL>
118  \section pipe_tasks_repair_Example A complete example of using RepairTask
119 
120  This code is in runRepair.py in the examples directory, and can be run as \em e.g.
121  \code
122  examples/runRepair.py
123  \endcode
124  \dontinclude runRepair.py
125  Import the task. There are other imports. Read the source file for more info.
126  \skipline RepairTask
127 
128  For this example, we manufacture a test image to run on.
129 
130  First, create a pure Poisson noise image and a Psf to go with it. The mask plane
131  and variance can be constructed at the same time.
132  \skip poisson
133  \until mask
134 
135  Inject some cosmic rays and generate the Exposure. Exposures are MaskedImages (image + mask + variance)
136  with other metadata (e.g. Psf and Wcs objects).
137  \skip some CRs
138  \until setPsf
139 
140  Defects are represented as bad columns of random lengths. A defect list must be constructed to pass
141  on to the RepairTask.
142  \bug This is addressed in <a href="https://jira.lsstcorp.org/browse/DM-963"> DM-963</a>
143 
144  \skip addDefects
145  \until push_back
146 
147  Finally, the exposure can be repaired. Create an instance of the task and run it. The exposure
148  is modified in place.
149  \skip RepairTask
150  \until repair.run
151 
152  <HR>
153  To investigate the \ref pipe_tasks_repair_Debug, put something like
154  \code{.py}
155  import lsstDebug
156  def DebugInfo(name):
157  di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively
158  if name == "lsst.pipe.tasks.repair":
159  di.display = {'repair.before':2, 'repair.after':3}
160  di.displayCR = True
161  return di
162 
163  lsstDebug.Info = DebugInfo
164  \endcode
165  into your debug.py file and run runRepair.py with the \c --debug flag.
166 
167 
168  Conversion notes:
169  Display code should be updated once we settle on a standard way of controlling what is displayed.
170  """
171  ConfigClass = RepairConfig
172  _DefaultName = "repair"
173 
174  def __init__(self, **kwargs):
175  pipeBase.Task.__init__(self, **kwargs)
176  if self.config.doInterpolate:
177  self.makeSubtask("interp")
178 
179  @pipeBase.timeMethod
180  def run(self, exposure, defects=None, keepCRs=None):
181  """!Repair an Exposure's defects and cosmic rays
182 
183  \param[in, out] exposure lsst.afw.image.Exposure to process. Exposure must have a valid Psf.
184  Modified in place.
185  \param[in] defects an lsst.meas.algorithms.DefectListT object. If None, do no
186  defect correction.
187  \param[in] keepCRs don't interpolate over the CR pixels (defer to RepairConfig if None)
188 
189  \throws AssertionError with the following strings:
190 
191  <DL>
192  <DT> No exposure provided
193  <DD> The object provided as exposure evaluates to False
194  <DT> No PSF provided
195  <DD> The Exposure has no associated Psf
196  </DL>
197  """
198  assert exposure, "No exposure provided"
199  psf = exposure.getPsf()
200  assert psf, "No PSF provided"
201 
202  frame = getDebugFrame(self._display, "repair.before")
203  if frame:
204  getDisplay(frame).mtv(exposure)
205 
206  if defects is not None and self.config.doInterpolate:
207  self.interp.run(exposure, defects=defects)
208 
209  if self.config.doCosmicRay:
210  self.cosmicRay(exposure, keepCRs=keepCRs)
211 
212  frame = getDebugFrame(self._display, "repair.after")
213  if frame:
214  getDisplay(frame).mtv(exposure)
215 
216  def cosmicRay(self, exposure, keepCRs=None):
217  """Mask cosmic rays
218 
219  \param[in,out] exposure Exposure to process
220  \param[in] keepCRs Don't interpolate over the CR pixels (defer to pex_config if None)
221  """
222  import lsstDebug
223  display = lsstDebug.Info(__name__).display
224  displayCR = lsstDebug.Info(__name__).displayCR
225 
226  assert exposure, "No exposure provided"
227  psf = exposure.getPsf()
228  assert psf, "No psf provided"
229 
230  # Blow away old mask
231  try:
232  mask = exposure.getMaskedImage().getMask()
233  crBit = mask.getMaskPlane("CR")
234  mask.clearMaskPlane(crBit)
235  except Exception:
236  pass
237 
238  exposure0 = exposure # initial value of exposure
239  binSize = self.config.cosmicray.background.binSize
240  nx, ny = exposure.getWidth()/binSize, exposure.getHeight()/binSize
241  # Treat constant background as a special case to avoid the extra complexity in calling
242  # measAlg.SubtractBackgroundTask().
243  if nx*ny <= 1:
244  medianBg = afwMath.makeStatistics(exposure.getMaskedImage(), afwMath.MEDIAN).getValue()
245  modelBg = None
246  else:
247  # make a deep copy of the exposure before subtracting its background,
248  # because this routine is only allowed to modify the exposure by setting mask planes
249  # and interpolating over defects, not changing the background level
250  exposure = exposure.Factory(exposure, True)
251  subtractBackgroundTask = measAlg.SubtractBackgroundTask(config=self.config.cosmicray.background)
252  modelBg = subtractBackgroundTask.run(exposure).background
253  medianBg = 0.0
254 
255  if keepCRs is None:
256  keepCRs = self.config.cosmicray.keepCRs
257  try:
258  crs = measAlg.findCosmicRays(exposure.getMaskedImage(), psf, medianBg,
259  pexConfig.makePolicy(self.config.cosmicray), keepCRs)
260  if modelBg:
261  # Add back background image
262  img = exposure.getMaskedImage()
263  img += modelBg.getImageF()
264  del img
265  # Replace original image with CR subtracted image
266  exposure0.setMaskedImage(exposure.getMaskedImage())
267 
268  except Exception:
269  if display:
270  import lsst.afw.display.ds9 as ds9
271  ds9.mtv(exposure0, title="Failed CR")
272  raise
273 
274  num = 0
275  if crs is not None:
276  mask = exposure0.getMaskedImage().getMask()
277  crBit = mask.getPlaneBitMask("CR")
278  afwDet.setMaskFromFootprintList(mask, crs, crBit)
279  num = len(crs)
280 
281  if display and displayCR:
282  import lsst.afw.display.ds9 as ds9
283  import lsst.afw.display.utils as displayUtils
284 
285  ds9.incrDefaultFrame()
286  ds9.mtv(exposure0, title="Post-CR")
287 
288  with ds9.Buffering():
289  for cr in crs:
290  displayUtils.drawBBox(cr.getBBox(), borderWidth=0.55)
291 
292  self.log.info("Identified %s cosmic rays." % (num,))
def run
Repair an Exposure&#39;s defects and cosmic rays.
Definition: repair.py:180
std::vector< detection::Footprint::Ptr > findCosmicRays(MaskedImageT &mimage, detection::Psf const &psf, double const bkgd, lsst::pex::policy::Policy const &policy, bool const keep)
Find cosmic rays in an Image, and mask and remove them.
Definition: CR.cc:347
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
Definition: Statistics.cc:1107
MaskT setMaskFromFootprintList(lsst::afw::image::Mask< MaskT > *mask, boost::shared_ptr< std::vector< boost::shared_ptr< Footprint >> const > const &footprints, MaskT const bitmask)
OR bitmask into all the Mask&#39;s pixels which are in the set of Footprints.
def getDebugFrame
Definition: lsstDebug.py:66
Interpolate over defects in an exposure and handle cosmic rays.
Definition: repair.py:63