lsst.pipe.tasks  16.0-49-g42e581f7+7
makeCoaddTempExp.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 numpy
23 
24 import lsst.pex.config as pexConfig
25 import lsst.daf.persistence as dafPersist
26 import lsst.afw.image as afwImage
27 import lsst.coadd.utils as coaddUtils
28 import lsst.pipe.base as pipeBase
29 import lsst.log as log
30 from lsst.meas.algorithms import CoaddPsf, CoaddPsfConfig
31 from .coaddBase import CoaddBaseTask
32 from .warpAndPsfMatch import WarpAndPsfMatchTask
33 from .coaddHelpers import groupPatchExposures, getGroupDataRef
34 
35 __all__ = ["MakeCoaddTempExpTask"]
36 
37 
38 class MissingExposureError(Exception):
39  """Raised when data cannot be retrieved for an exposure.
40  When processing patches, sometimes one exposure is missing; this lets us
41  distinguish bewteen that case, and other errors.
42  """
43  pass
44 
45 
46 class MakeCoaddTempExpConfig(CoaddBaseTask.ConfigClass):
47  """Config for MakeCoaddTempExpTask
48  """
49  warpAndPsfMatch = pexConfig.ConfigurableField(
50  target=WarpAndPsfMatchTask,
51  doc="Task to warp and PSF-match calexp",
52  )
53  doWrite = pexConfig.Field(
54  doc="persist <coaddName>Coadd_<warpType>Warp",
55  dtype=bool,
56  default=True,
57  )
58  bgSubtracted = pexConfig.Field(
59  doc="Work with a background subtracted calexp?",
60  dtype=bool,
61  default=True,
62  )
63  coaddPsf = pexConfig.ConfigField(
64  doc="Configuration for CoaddPsf",
65  dtype=CoaddPsfConfig,
66  )
67  makeDirect = pexConfig.Field(
68  doc="Make direct Warp/Coadds",
69  dtype=bool,
70  default=True,
71  )
72  makePsfMatched = pexConfig.Field(
73  doc="Make Psf-Matched Warp/Coadd?",
74  dtype=bool,
75  default=False,
76  )
77  doApplySkyCorr = pexConfig.Field(dtype=bool, default=False, doc="Apply sky correction?")
78 
79  def validate(self):
80  CoaddBaseTask.ConfigClass.validate(self)
81  if not self.makePsfMatched and not self.makeDirect:
82  raise RuntimeError("At least one of config.makePsfMatched and config.makeDirect must be True")
83  if self.doPsfMatch:
84  # Backwards compatibility.
85  log.warn("Config doPsfMatch deprecated. Setting makePsfMatched=True and makeDirect=False")
86  self.makePsfMatched = True
87  self.makeDirect = False
88 
89  def setDefaults(self):
90  CoaddBaseTask.ConfigClass.setDefaults(self)
91  self.warpAndPsfMatch.psfMatch.kernel.active.kernelSize = self.matchingKernelSize
92 
93 
99 
100 
102  r"""!Warp and optionally PSF-Match calexps onto an a common projection.
103 
104  @anchor MakeCoaddTempExpTask_
105 
106  @section pipe_tasks_makeCoaddTempExp_Contents Contents
107 
108  - @ref pipe_tasks_makeCoaddTempExp_Purpose
109  - @ref pipe_tasks_makeCoaddTempExp_Initialize
110  - @ref pipe_tasks_makeCoaddTempExp_IO
111  - @ref pipe_tasks_makeCoaddTempExp_Config
112  - @ref pipe_tasks_makeCoaddTempExp_Debug
113  - @ref pipe_tasks_makeCoaddTempExp_Example
114 
115  @section pipe_tasks_makeCoaddTempExp_Purpose Description
116 
117  Warp and optionally PSF-Match calexps onto a common projection, by
118  performing the following operations:
119  - Group calexps by visit/run
120  - For each visit, generate a Warp by calling method @ref makeTempExp.
121  makeTempExp loops over the visit's calexps calling @ref WarpAndPsfMatch
122  on each visit
123 
124  The result is a `directWarp` (and/or optionally a `psfMatchedWarp`).
125 
126  @section pipe_tasks_makeCoaddTempExp_Initialize Task Initialization
127 
128  @copydoc \_\_init\_\_
129 
130  This task has one special keyword argument: passing reuse=True will cause
131  the task to skip the creation of warps that are already present in the
132  output repositories.
133 
134  @section pipe_tasks_makeCoaddTempExp_IO Invoking the Task
135 
136  This task is primarily designed to be run from the command line.
137 
138  The main method is `runDataRef`, which takes a single butler data reference for the patch(es)
139  to process.
140 
141  @copydoc run
142 
143  WarpType identifies the types of convolutions applied to Warps (previously CoaddTempExps).
144  Only two types are available: direct (for regular Warps/Coadds) and psfMatched
145  (for Warps/Coadds with homogenized PSFs). We expect to add a third type, likelihood,
146  for generating likelihood Coadds with Warps that have been correlated with their own PSF.
147 
148  @section pipe_tasks_makeCoaddTempExp_Config Configuration parameters
149 
150  See @ref MakeCoaddTempExpConfig and parameters inherited from
151  @link lsst.pipe.tasks.coaddBase.CoaddBaseConfig CoaddBaseConfig @endlink
152 
153  @subsection pipe_tasks_MakeCoaddTempExp_psfMatching Guide to PSF-Matching Configs
154 
155  To make `psfMatchedWarps`, select `config.makePsfMatched=True`. The subtask
156  @link lsst.ip.diffim.modelPsfMatch.ModelPsfMatchTask ModelPsfMatchTask @endlink
157  is responsible for the PSF-Matching, and its config is accessed via `config.warpAndPsfMatch.psfMatch`.
158  The optimal configuration depends on aspects of dataset: the pixel scale, average PSF FWHM and
159  dimensions of the PSF kernel. These configs include the requested model PSF, the matching kernel size,
160  padding of the science PSF thumbnail and spatial sampling frequency of the PSF.
161 
162  *Config Guidelines*: The user must specify the size of the model PSF to which to match by setting
163  `config.modelPsf.defaultFwhm` in units of pixels. The appropriate values depends on science case.
164  In general, for a set of input images, this config should equal the FWHM of the visit
165  with the worst seeing. The smallest it should be set to is the median FWHM. The defaults
166  of the other config options offer a reasonable starting point.
167  The following list presents the most common problems that arise from a misconfigured
168  @link lsst.ip.diffim.modelPsfMatch.ModelPsfMatchTask ModelPsfMatchTask @endlink
169  and corresponding solutions. All assume the default Alard-Lupton kernel, with configs accessed via
170  ```config.warpAndPsfMatch.psfMatch.kernel['AL']```. Each item in the list is formatted as:
171  Problem: Explanation. *Solution*
172 
173  *Troublshooting PSF-Matching Configuration:*
174  - Matched PSFs look boxy: The matching kernel is too small. _Increase the matching kernel size.
175  For example:_
176 
177  config.warpAndPsfMatch.psfMatch.kernel['AL'].kernelSize=27 # default 21
178 
179  Note that increasing the kernel size also increases runtime.
180  - Matched PSFs look ugly (dipoles, quadropoles, donuts): unable to find good solution
181  for matching kernel. _Provide the matcher with more data by either increasing
182  the spatial sampling by decreasing the spatial cell size,_
183 
184  config.warpAndPsfMatch.psfMatch.kernel['AL'].sizeCellX = 64 # default 128
185  config.warpAndPsfMatch.psfMatch.kernel['AL'].sizeCellY = 64 # default 128
186 
187  _or increasing the padding around the Science PSF, for example:_
188 
189  config.warpAndPsfMatch.psfMatch.autoPadPsfTo=1.6 # default 1.4
190 
191  Increasing `autoPadPsfTo` increases the minimum ratio of input PSF dimensions to the
192  matching kernel dimensions, thus increasing the number of pixels available to fit
193  after convolving the PSF with the matching kernel.
194  Optionally, for debugging the effects of padding, the level of padding may be manually
195  controlled by setting turning off the automatic padding and setting the number
196  of pixels by which to pad the PSF:
197 
198  config.warpAndPsfMatch.psfMatch.doAutoPadPsf = False # default True
199  config.warpAndPsfMatch.psfMatch.padPsfBy = 6 # pixels. default 0
200 
201  - Deconvolution: Matching a large PSF to a smaller PSF produces
202  a telltale noise pattern which looks like ripples or a brain.
203  _Increase the size of the requested model PSF. For example:_
204 
205  config.modelPsf.defaultFwhm = 11 # Gaussian sigma in units of pixels.
206 
207  - High frequency (sometimes checkered) noise: The matching basis functions are too small.
208  _Increase the width of the Gaussian basis functions. For example:_
209 
210  config.warpAndPsfMatch.psfMatch.kernel['AL'].alardSigGauss=[1.5, 3.0, 6.0]
211  # from default [0.7, 1.5, 3.0]
212 
213 
214  @section pipe_tasks_makeCoaddTempExp_Debug Debug variables
215 
216  MakeCoaddTempExpTask has no debug output, but its subtasks do.
217 
218  @section pipe_tasks_makeCoaddTempExp_Example A complete example of using MakeCoaddTempExpTask
219 
220  This example uses the package ci_hsc to show how MakeCoaddTempExp fits
221  into the larger Data Release Processing.
222  Set up by running:
223 
224  setup ci_hsc
225  cd $CI_HSC_DIR
226  # if not built already:
227  python $(which scons) # this will take a while
228 
229  The following assumes that `processCcd.py` and `makeSkyMap.py` have previously been run
230  (e.g. by building `ci_hsc` above) to generate a repository of calexps and an
231  output respository with the desired SkyMap. The command,
232 
233  makeCoaddTempExp.py $CI_HSC_DIR/DATA --rerun ci_hsc \
234  --id patch=5,4 tract=0 filter=HSC-I \
235  --selectId visit=903988 ccd=16 --selectId visit=903988 ccd=17 \
236  --selectId visit=903988 ccd=23 --selectId visit=903988 ccd=24 \
237  --config doApplyUberCal=False makePsfMatched=True modelPsf.defaultFwhm=11
238 
239  writes a direct and PSF-Matched Warp to
240  - `$CI_HSC_DIR/DATA/rerun/ci_hsc/deepCoadd/HSC-I/0/5,4/warp-HSC-I-0-5,4-903988.fits` and
241  - `$CI_HSC_DIR/DATA/rerun/ci_hsc/deepCoadd/HSC-I/0/5,4/psfMatchedWarp-HSC-I-0-5,4-903988.fits`
242  respectively.
243 
244  @note PSF-Matching in this particular dataset would benefit from adding
245  `--configfile ./matchingConfig.py` to
246  the command line arguments where `matchingConfig.py` is defined by:
247 
248  echo "
249  config.warpAndPsfMatch.psfMatch.kernel['AL'].kernelSize=27
250  config.warpAndPsfMatch.psfMatch.kernel['AL'].alardSigGauss=[1.5, 3.0, 6.0]" > matchingConfig.py
251 
252 
253  Add the option `--help` to see more options.
254  """
255  ConfigClass = MakeCoaddTempExpConfig
256  _DefaultName = "makeCoaddTempExp"
257 
258  def __init__(self, reuse=False, **kwargs):
259  CoaddBaseTask.__init__(self, **kwargs)
260  self.reuse = reuse
261  self.makeSubtask("warpAndPsfMatch")
262 
263  @pipeBase.timeMethod
264  def runDataRef(self, patchRef, selectDataList=[]):
265  """!Produce <coaddName>Coadd_<warpType>Warp images by warping and optionally PSF-matching.
266 
267  @param[in] patchRef: data reference for sky map patch. Must include keys "tract", "patch",
268  plus the camera-specific filter key (e.g. "filter" or "band")
269  @return: dataRefList: a list of data references for the new <coaddName>Coadd_directWarps
270  if direct or both warp types are requested and <coaddName>Coadd_psfMatchedWarps if only psfMatched
271  warps are requested.
272 
273  @warning: this task assumes that all exposures in a warp (coaddTempExp) have the same filter.
274 
275  @warning: this task sets the Calib of the coaddTempExp to the Calib of the first calexp
276  with any good pixels in the patch. For a mosaic camera the resulting Calib should be ignored
277  (assembleCoadd should determine zeropoint scaling without referring to it).
278  """
279  skyInfo = self.getSkyInfo(patchRef)
280 
281  # DataRefs to return are of type *_directWarp unless only *_psfMatchedWarp requested
282  if self.config.makePsfMatched and not self.config.makeDirect:
283  primaryWarpDataset = self.getTempExpDatasetName("psfMatched")
284  else:
285  primaryWarpDataset = self.getTempExpDatasetName("direct")
286 
287  calExpRefList = self.selectExposures(patchRef, skyInfo, selectDataList=selectDataList)
288  if len(calExpRefList) == 0:
289  self.log.warn("No exposures to coadd for patch %s", patchRef.dataId)
290  return None
291  self.log.info("Selected %d calexps for patch %s", len(calExpRefList), patchRef.dataId)
292  calExpRefList = [calExpRef for calExpRef in calExpRefList if calExpRef.datasetExists("calexp")]
293  self.log.info("Processing %d existing calexps for patch %s", len(calExpRefList), patchRef.dataId)
294 
295  groupData = groupPatchExposures(patchRef, calExpRefList, self.getCoaddDatasetName(),
296  primaryWarpDataset)
297  self.log.info("Processing %d warp exposures for patch %s", len(groupData.groups), patchRef.dataId)
298 
299  dataRefList = []
300  for i, (tempExpTuple, calexpRefList) in enumerate(groupData.groups.items()):
301  tempExpRef = getGroupDataRef(patchRef.getButler(), primaryWarpDataset,
302  tempExpTuple, groupData.keys)
303  if self.reuse and tempExpRef.datasetExists(datasetType=primaryWarpDataset, write=True):
304  self.log.info("Skipping makeCoaddTempExp for %s; output already exists.", tempExpRef.dataId)
305  dataRefList.append(tempExpRef)
306  continue
307  self.log.info("Processing Warp %d/%d: id=%s", i, len(groupData.groups), tempExpRef.dataId)
308 
309  # TODO: mappers should define a way to go from the "grouping keys" to a numeric ID (#2776).
310  # For now, we try to get a long integer "visit" key, and if we can't, we just use the index
311  # of the visit in the list.
312  try:
313  visitId = int(tempExpRef.dataId["visit"])
314  except (KeyError, ValueError):
315  visitId = i
316 
317  exps = self.run(calexpRefList, skyInfo, visitId).exposures
318 
319  if any(exps.values()):
320  dataRefList.append(tempExpRef)
321  else:
322  self.log.warn("Warp %s could not be created", tempExpRef.dataId)
323 
324  if self.config.doWrite:
325  for (warpType, exposure) in exps.items(): # compatible w/ Py3
326  if exposure is not None:
327  self.log.info("Persisting %s" % self.getTempExpDatasetName(warpType))
328  tempExpRef.put(exposure, self.getTempExpDatasetName(warpType))
329 
330  return dataRefList
331 
332  def run(self, calexpRefList, skyInfo, visitId=0):
333  """Create a Warp from inputs
334 
335  We iterate over the multiple calexps in a single exposure to construct
336  the warp (previously called a coaddTempExp) of that exposure to the
337  supplied tract/patch.
338 
339  Pixels that receive no pixels are set to NAN; this is not correct
340  (violates LSST algorithms group policy), but will be fixed up by
341  interpolating after the coaddition.
342 
343  @param calexpRefList: List of data references for calexps that (may)
344  overlap the patch of interest
345  @param skyInfo: Struct from CoaddBaseTask.getSkyInfo() with geometric
346  information about the patch
347  @param visitId: integer identifier for visit, for the table that will
348  produce the CoaddPsf
349  @return a pipeBase Struct containing:
350  - exposures: a dictionary containing the warps requested:
351  "direct": direct warp if config.makeDirect
352  "psfMatched": PSF-matched warp if config.makePsfMatched
353  """
354  warpTypeList = self.getWarpTypeList()
355 
356  totGoodPix = {warpType: 0 for warpType in warpTypeList}
357  didSetMetadata = {warpType: False for warpType in warpTypeList}
358  coaddTempExps = {warpType: self._prepareEmptyExposure(skyInfo) for warpType in warpTypeList}
359  inputRecorder = {warpType: self.inputRecorder.makeCoaddTempExpRecorder(visitId, len(calexpRefList))
360  for warpType in warpTypeList}
361 
362  modelPsf = self.config.modelPsf.apply() if self.config.makePsfMatched else None
363  for calExpInd, calExpRef in enumerate(calexpRefList):
364  self.log.info("Processing calexp %d of %d for this Warp: id=%s",
365  calExpInd+1, len(calexpRefList), calExpRef.dataId)
366  try:
367  ccdId = calExpRef.get("ccdExposureId", immediate=True)
368  except Exception:
369  ccdId = calExpInd
370  try:
371  # We augment the dataRef here with the tract, which is harmless for loading things
372  # like calexps that don't need the tract, and necessary for meas_mosaic outputs,
373  # which do.
374  calExpRef = calExpRef.butlerSubset.butler.dataRef("calexp", dataId=calExpRef.dataId,
375  tract=skyInfo.tractInfo.getId())
376  calExp = self.getCalibratedExposure(calExpRef, bgSubtracted=self.config.bgSubtracted)
377  except Exception as e:
378  self.log.warn("Calexp %s not found; skipping it: %s", calExpRef.dataId, e)
379  continue
380 
381  if self.config.doApplySkyCorr:
382  self.applySkyCorr(calExpRef, calExp)
383 
384  try:
385  warpedAndMatched = self.warpAndPsfMatch.run(calExp, modelPsf=modelPsf,
386  wcs=skyInfo.wcs, maxBBox=skyInfo.bbox,
387  makeDirect=self.config.makeDirect,
388  makePsfMatched=self.config.makePsfMatched)
389  except Exception as e:
390  self.log.warn("WarpAndPsfMatch failed for calexp %s; skipping it: %s", calExpRef.dataId, e)
391  continue
392  try:
393  numGoodPix = {warpType: 0 for warpType in warpTypeList}
394  for warpType in warpTypeList:
395  exposure = warpedAndMatched.getDict()[warpType]
396  if exposure is None:
397  continue
398  coaddTempExp = coaddTempExps[warpType]
399  if didSetMetadata[warpType]:
400  mimg = exposure.getMaskedImage()
401  mimg *= (coaddTempExp.getCalib().getFluxMag0()[0] /
402  exposure.getCalib().getFluxMag0()[0])
403  del mimg
404  numGoodPix[warpType] = coaddUtils.copyGoodPixels(
405  coaddTempExp.getMaskedImage(), exposure.getMaskedImage(), self.getBadPixelMask())
406  totGoodPix[warpType] += numGoodPix[warpType]
407  self.log.debug("Calexp %s has %d good pixels in this patch (%.1f%%) for %s",
408  calExpRef.dataId, numGoodPix[warpType],
409  100.0*numGoodPix[warpType]/skyInfo.bbox.getArea(), warpType)
410  if numGoodPix[warpType] > 0 and not didSetMetadata[warpType]:
411  coaddTempExp.setCalib(exposure.getCalib())
412  coaddTempExp.setFilter(exposure.getFilter())
413  coaddTempExp.getInfo().setVisitInfo(exposure.getInfo().getVisitInfo())
414  # PSF replaced with CoaddPsf after loop if and only if creating direct warp
415  coaddTempExp.setPsf(exposure.getPsf())
416  didSetMetadata[warpType] = True
417 
418  # Need inputRecorder for CoaddApCorrMap for both direct and PSF-matched
419  inputRecorder[warpType].addCalExp(calExp, ccdId, numGoodPix[warpType])
420 
421  except Exception as e:
422  self.log.warn("Error processing calexp %s; skipping it: %s", calExpRef.dataId, e)
423  continue
424 
425  for warpType in warpTypeList:
426  self.log.info("%sWarp has %d good pixels (%.1f%%)",
427  warpType, totGoodPix[warpType], 100.0*totGoodPix[warpType]/skyInfo.bbox.getArea())
428 
429  if totGoodPix[warpType] > 0 and didSetMetadata[warpType]:
430  inputRecorder[warpType].finish(coaddTempExps[warpType], totGoodPix[warpType])
431  if warpType == "direct":
432  coaddTempExps[warpType].setPsf(
433  CoaddPsf(inputRecorder[warpType].coaddInputs.ccds, skyInfo.wcs,
434  self.config.coaddPsf.makeControl()))
435  else:
436  # No good pixels. Exposure still empty
437  coaddTempExps[warpType] = None
438 
439  result = pipeBase.Struct(exposures=coaddTempExps)
440  return result
441 
442  def getCalibratedExposure(self, dataRef, bgSubtracted):
443  """Return one calibrated Exposure, possibly with an updated SkyWcs.
444 
445  @param[in] dataRef a sensor-level data reference
446  @param[in] bgSubtracted return calexp with background subtracted? If False get the
447  calexp's background background model and add it to the calexp.
448  @return calibrated exposure
449 
450  @raises MissingExposureError If data for the exposure is not available.
451 
452  If config.doApplyUberCal, the exposure will be photometrically
453  calibrated via the `jointcal_photoCalib` dataset and have its SkyWcs
454  updated to the `jointcal_wcs`, otherwise it will be calibrated via the
455  Exposure's own Calib and have the original SkyWcs.
456  """
457  try:
458  exposure = dataRef.get("calexp", immediate=True)
459  except dafPersist.NoResults as e:
460  raise MissingExposureError('Exposure not found: %s ' % str(e)) from e
461 
462  if not bgSubtracted:
463  background = dataRef.get("calexpBackground", immediate=True)
464  mi = exposure.getMaskedImage()
465  mi += background.getImage()
466  del mi
467 
468  # TODO: this is needed until DM-10153 is done and Calib is gone
469  referenceFlux = 1e23 * 10**(48.6 / -2.5) * 1e9
470  if self.config.doApplyUberCal:
471  if self.config.useMeasMosaic:
472  from lsst.meas.mosaic import applyMosaicResultsExposure
473  # NOTE: this changes exposure in-place, updating its Calib and Wcs.
474  # Save the calibration error, as it gets overwritten with zero.
475  fluxMag0Err = exposure.getCalib().getFluxMag0()[1]
476  try:
477  applyMosaicResultsExposure(dataRef, calexp=exposure)
478  except dafPersist.NoResults as e:
479  raise MissingExposureError('Mosaic calibration not found: %s ' % str(e)) from e
480  fluxMag0 = exposure.getCalib().getFluxMag0()[0]
481  photoCalib = afwImage.PhotoCalib(referenceFlux/fluxMag0,
482  referenceFlux*fluxMag0Err/fluxMag0**2,
483  exposure.getBBox())
484  else:
485  photoCalib = dataRef.get("jointcal_photoCalib")
486  skyWcs = dataRef.get("jointcal_wcs")
487  exposure.setWcs(skyWcs)
488  else:
489  fluxMag0 = exposure.getCalib().getFluxMag0()
490  photoCalib = afwImage.PhotoCalib(referenceFlux/fluxMag0[0],
491  referenceFlux*fluxMag0[1]/fluxMag0[0]**2,
492  exposure.getBBox())
493 
494  exposure.maskedImage = photoCalib.calibrateImage(exposure.maskedImage,
495  includeScaleUncertainty=self.config.includeCalibVar)
496  exposure.maskedImage /= photoCalib.getCalibrationMean()
497  exposure.setCalib(afwImage.Calib(photoCalib.getInstFluxAtZeroMagnitude()))
498  # TODO: The images will have a calibration of 1.0 everywhere once RFC-545 is implemented.
499  # exposure.setCalib(afwImage.Calib(1.0))
500  return exposure
501 
502  @staticmethod
503  def _prepareEmptyExposure(skyInfo):
504  """Produce an empty exposure for a given patch"""
505  exp = afwImage.ExposureF(skyInfo.bbox, skyInfo.wcs)
506  exp.getMaskedImage().set(numpy.nan, afwImage.Mask
507  .getPlaneBitMask("NO_DATA"), numpy.inf)
508  return exp
509 
510  def getWarpTypeList(self):
511  """Return list of requested warp types per the config.
512  """
513  warpTypeList = []
514  if self.config.makeDirect:
515  warpTypeList.append("direct")
516  if self.config.makePsfMatched:
517  warpTypeList.append("psfMatched")
518  return warpTypeList
519 
520  def applySkyCorr(self, dataRef, calexp):
521  """Apply correction to the sky background level
522 
523  Sky corrections can be generated with the 'skyCorrection.py'
524  executable in pipe_drivers. Because the sky model used by that
525  code extends over the entire focal plane, this can produce
526  better sky subtraction.
527 
528  The calexp is updated in-place.
529 
530  Parameters
531  ----------
532  dataRef : `lsst.daf.persistence.ButlerDataRef`
533  Data reference for calexp.
534  calexp : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage`
535  Calibrated exposure.
536  """
537  bg = dataRef.get("skyCorr")
538  if isinstance(calexp, afwImage.Exposure):
539  calexp = calexp.getMaskedImage()
540  calexp -= bg.getImage()
def getCoaddDatasetName(self, warpType="direct")
Definition: coaddBase.py:149
def getGroupDataRef(butler, datasetType, groupTuple, keys)
Definition: coaddHelpers.py:99
Base class for coaddition.
Definition: coaddBase.py:100
Warp and optionally PSF-Match calexps onto an a common projection.
def getSkyInfo(self, patchRef)
Use getSkyinfo to return the skyMap, tract and patch information, wcs and the outer bbox of the patch...
Definition: coaddBase.py:133
def getTempExpDatasetName(self, warpType="direct")
Definition: coaddBase.py:164
def getBadPixelMask(self)
Convenience method to provide the bitmask from the mask plane names.
Definition: coaddBase.py:199
def run(self, calexpRefList, skyInfo, visitId=0)
def getCalibratedExposure(self, dataRef, bgSubtracted)
def selectExposures(self, patchRef, skyInfo=None, selectDataList=[])
Select exposures to coadd.
Definition: coaddBase.py:113
def runDataRef(self, patchRef, selectDataList=[])
Produce <coaddName>Coadd_<warpType>Warp images by warping and optionally PSF-matching.
def groupPatchExposures(patchDataRef, calexpDataRefList, coaddDatasetType="deepCoadd", tempExpDatasetType="deepCoadd_directWarp")
Definition: coaddHelpers.py:60