lsst.pipe.tasks  16.0-44-ga6515cd1
coaddBase.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2015 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 <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 import lsst.pex.config as pexConfig
23 import lsst.afw.geom as afwGeom
24 import lsst.afw.image as afwImage
25 import lsst.pipe.base as pipeBase
26 import lsst.meas.algorithms as measAlg
27 
28 from lsst.afw.fits import FitsError
29 from lsst.coadd.utils import CoaddDataIdContainer
30 from .selectImages import WcsSelectImagesTask, SelectStruct
31 from .coaddInputRecorder import CoaddInputRecorderTask
32 from .scaleVariance import ScaleVarianceTask
33 
34 __all__ = ["CoaddBaseTask", "getSkyInfo"]
35 
36 
37 class CoaddBaseConfig(pexConfig.Config):
38  """!Configuration parameters for CoaddBaseTask
39 
40  @anchor CoaddBaseConfig_
41 
42  @brief Configuration parameters shared between MakeCoaddTempExp and AssembleCoadd
43  """
44  coaddName = pexConfig.Field(
45  doc="Coadd name: typically one of deep or goodSeeing.",
46  dtype=str,
47  default="deep",
48  )
49  select = pexConfig.ConfigurableField(
50  doc="Image selection subtask.",
51  target=WcsSelectImagesTask,
52  )
53  badMaskPlanes = pexConfig.ListField(
54  dtype=str,
55  doc="Mask planes that, if set, the associated pixel should not be included in the coaddTempExp.",
56  default=("NO_DATA",),
57  )
58  inputRecorder = pexConfig.ConfigurableField(
59  doc="Subtask that helps fill CoaddInputs catalogs added to the final Exposure",
60  target=CoaddInputRecorderTask
61  )
62  doPsfMatch = pexConfig.Field(
63  dtype=bool,
64  doc="Match to modelPsf? Deprecated. Sets makePsfMatched=True, makeDirect=False",
65  default=False
66  )
67  modelPsf = measAlg.GaussianPsfFactory.makeField(doc="Model Psf factory")
68  doApplyUberCal = pexConfig.Field(
69  dtype=bool,
70  doc="Apply jointcal WCS and PhotoCalib results to input calexps?",
71  default=False
72  )
73  useMeasMosaic = pexConfig.Field(
74  dtype=bool,
75  doc="Use meas_mosaic's applyMosaicResultsExposure() to do the photometric "
76  "calibration/wcs update (deprecated).",
77  default=False
78  )
79  matchingKernelSize = pexConfig.Field(
80  dtype=int,
81  doc="Size in pixels of matching kernel. Must be odd.",
82  default=21,
83  check=lambda x: x % 2 == 1
84  )
85 
86 
87 class CoaddTaskRunner(pipeBase.TaskRunner):
88 
89  @staticmethod
90  def getTargetList(parsedCmd, **kwargs):
91  return pipeBase.TaskRunner.getTargetList(parsedCmd, selectDataList=parsedCmd.selectId.dataList,
92  **kwargs)
93 
94 
95 class CoaddBaseTask(pipeBase.CmdLineTask):
96  """!Base class for coaddition.
97 
98  Subclasses must specify _DefaultName
99  """
100  ConfigClass = CoaddBaseConfig
101  RunnerClass = CoaddTaskRunner
102 
103  def __init__(self, *args, **kwargs):
104  pipeBase.Task.__init__(self, *args, **kwargs)
105  self.makeSubtask("select")
106  self.makeSubtask("inputRecorder")
107 
108  def selectExposures(self, patchRef, skyInfo=None, selectDataList=[]):
109  """!
110  @brief Select exposures to coadd
111 
112  Get the corners of the bbox supplied in skyInfo using @ref afwGeom.Box2D and convert the pixel
113  positions of the bbox corners to sky coordinates using @ref skyInfo.wcs.pixelToSky. Use the
114  @ref WcsSelectImagesTask_ "WcsSelectImagesTask" to select exposures that lie inside the patch
115  indicated by the dataRef.
116 
117  @param[in] patchRef data reference for sky map patch. Must include keys "tract", "patch",
118  plus the camera-specific filter key (e.g. "filter" or "band")
119  @param[in] skyInfo geometry for the patch; output from getSkyInfo
120  @return a list of science exposures to coadd, as butler data references
121  """
122  if skyInfo is None:
123  skyInfo = self.getSkyInfo(patchRef)
124  cornerPosList = afwGeom.Box2D(skyInfo.bbox).getCorners()
125  coordList = [skyInfo.wcs.pixelToSky(pos) for pos in cornerPosList]
126  return self.select.runDataRef(patchRef, coordList, selectDataList=selectDataList).dataRefList
127 
128  def getSkyInfo(self, patchRef):
129  """!
130  @brief Use @ref getSkyinfo to return the skyMap, tract and patch information, wcs and the outer bbox
131  of the patch.
132 
133  @param[in] patchRef data reference for sky map. Must include keys "tract" and "patch"
134 
135  @return pipe_base Struct containing:
136  - skyMap: sky map
137  - tractInfo: information for chosen tract of sky map
138  - patchInfo: information about chosen patch of tract
139  - wcs: WCS of tract
140  - bbox: outer bbox of patch, as an afwGeom Box2I
141  """
142  return getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
143 
144  def getCoaddDatasetName(self, warpType="direct"):
145  """Return coadd name for given warpType and task config
146 
147  Parameters
148  ----------
149  warpType : string
150  Either 'direct' or 'psfMatched'
151 
152  Returns
153  -------
154  CoaddDatasetName : `string`
155  """
156  suffix = "" if warpType == "direct" else warpType[0].upper() + warpType[1:]
157  return self.config.coaddName + "Coadd" + suffix
158 
159  def getTempExpDatasetName(self, warpType="direct"):
160  """Return warp name for given warpType and task config
161 
162  Parameters
163  ----------
164  warpType : string
165  Either 'direct' or 'psfMatched'
166 
167  Returns
168  -------
169  WarpDatasetName : `string`
170  """
171  return self.config.coaddName + "Coadd_" + warpType + "Warp"
172 
173  @classmethod
174  def _makeArgumentParser(cls):
175  """Create an argument parser
176  """
177  parser = pipeBase.ArgumentParser(name=cls._DefaultName)
178  parser.add_id_argument("--id", "deepCoadd", help="data ID, e.g. --id tract=12345 patch=1,2",
179  ContainerClass=CoaddDataIdContainer)
180  parser.add_id_argument("--selectId", "calexp", help="data ID, e.g. --selectId visit=6789 ccd=0..9",
181  ContainerClass=SelectDataIdContainer)
182  return parser
183 
184  def _getConfigName(self):
185  """Return the name of the config dataset
186  """
187  return "%s_%s_config" % (self.config.coaddName, self._DefaultName)
188 
189  def _getMetadataName(self):
190  """Return the name of the metadata dataset
191  """
192  return "%s_%s_metadata" % (self.config.coaddName, self._DefaultName)
193 
194  def getBadPixelMask(self):
195  """!
196  @brief Convenience method to provide the bitmask from the mask plane names
197  """
198  return afwImage.Mask.getPlaneBitMask(self.config.badMaskPlanes)
199 
200 
201 class SelectDataIdContainer(pipeBase.DataIdContainer):
202  """!
203  @brief A dataId container for inputs to be selected.
204 
205  Read the header (including the size and Wcs) for all specified
206  inputs and pass those along, ultimately for the SelectImagesTask.
207  This is most useful when used with multiprocessing, as input headers are
208  only read once.
209  """
210 
211  def makeDataRefList(self, namespace):
212  """Add a dataList containing useful information for selecting images"""
213  super(SelectDataIdContainer, self).makeDataRefList(namespace)
214  self.dataList = []
215  for ref in self.refList:
216  try:
217  md = ref.get("calexp_md", immediate=True)
218  wcs = afwGeom.makeSkyWcs(md)
219  data = SelectStruct(dataRef=ref, wcs=wcs, bbox=afwImage.bboxFromMetadata(md))
220  except FitsError:
221  namespace.log.warn("Unable to construct Wcs from %s" % (ref.dataId))
222  continue
223  self.dataList.append(data)
224 
225 
226 def getSkyInfo(coaddName, patchRef):
227  """!
228  @brief Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded.
229 
230  @param[in] coaddName coadd name; typically one of deep or goodSeeing
231  @param[in] patchRef data reference for sky map. Must include keys "tract" and "patch"
232 
233  @return pipe_base Struct containing:
234  - skyMap: sky map
235  - tractInfo: information for chosen tract of sky map
236  - patchInfo: information about chosen patch of tract
237  - wcs: WCS of tract
238  - bbox: outer bbox of patch, as an afwGeom Box2I
239  """
240  skyMap = patchRef.get(coaddName + "Coadd_skyMap")
241  tractId = patchRef.dataId["tract"]
242  tractInfo = skyMap[tractId]
243 
244  # patch format is "xIndex,yIndex"
245  patchIndex = tuple(int(i) for i in patchRef.dataId["patch"].split(","))
246  patchInfo = tractInfo.getPatchInfo(patchIndex)
247 
248  return pipeBase.Struct(
249  skyMap=skyMap,
250  tractInfo=tractInfo,
251  patchInfo=patchInfo,
252  wcs=tractInfo.getWcs(),
253  bbox=patchInfo.getOuterBBox(),
254  )
255 
256 
257 def scaleVariance(maskedImage, maskPlanes, log=None):
258  """!
259  @brief Scale the variance in a maskedImage
260 
261  The variance plane in a convolved or warped image (or a coadd derived
262  from warped images) does not accurately reflect the noise properties of
263  the image because variance has been lost to covariance. This function
264  attempts to correct for this by scaling the variance plane to match
265  the observed variance in the image. This is not perfect (because we're
266  not tracking the covariance) but it's simple and is often good enough.
267 
268  @deprecated Use the ScaleVarianceTask instead.
269 
270  @param maskedImage MaskedImage to operate on; variance will be scaled
271  @param maskPlanes List of mask planes for pixels to reject
272  @param log Log for reporting the renormalization factor; or None
273  @return renormalisation factor
274  """
275  config = ScaleVarianceTask.ConfigClass()
276  config.maskPlanes = maskPlanes
277  task = ScaleVarianceTask(config=config, name="scaleVariance", log=log)
278  return task.run(maskedImage)
def getCoaddDatasetName(self, warpType="direct")
Definition: coaddBase.py:144
Base class for coaddition.
Definition: coaddBase.py:95
Configuration parameters for CoaddBaseTask.
Definition: coaddBase.py:37
A dataId container for inputs to be selected.
Definition: coaddBase.py:201
def __init__(self, args, kwargs)
Definition: coaddBase.py:103
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:128
def getTempExpDatasetName(self, warpType="direct")
Definition: coaddBase.py:159
def getBadPixelMask(self)
Convenience method to provide the bitmask from the mask plane names.
Definition: coaddBase.py:194
def getTargetList(parsedCmd, kwargs)
Definition: coaddBase.py:90
def selectExposures(self, patchRef, skyInfo=None, selectDataList=[])
Select exposures to coadd.
Definition: coaddBase.py:108
def scaleVariance(maskedImage, maskPlanes, log=None)
Scale the variance in a maskedImage.
Definition: coaddBase.py:257
def getSkyInfo(coaddName, patchRef)
Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded...
Definition: coaddBase.py:226