22 from __future__
import absolute_import, division, print_function
25 import lsst.pex.config
as pexConfig
26 import lsst.afw.geom
as afwGeom
27 import lsst.afw.image
as afwImage
28 import lsst.pipe.base
as pipeBase
29 import lsst.meas.algorithms
as measAlg
31 from lsst.afw.fits
import FitsError
32 from lsst.coadd.utils
import CoaddDataIdContainer
33 from .selectImages
import WcsSelectImagesTask, SelectStruct
34 from .coaddInputRecorder
import CoaddInputRecorderTask
37 from lsst.meas.mosaic
import applyMosaicResults
39 applyMosaicResults =
None 41 __all__ = [
"CoaddBaseTask",
"getSkyInfo"]
45 """!Configuration parameters for CoaddBaseTask 47 \anchor CoaddBaseConfig_ 49 \brief Configuration parameters shared between MakeCoaddTempExp and AssembleCoadd 51 coaddName = pexConfig.Field(
52 doc=
"Coadd name: typically one of deep or goodSeeing.",
56 select = pexConfig.ConfigurableField(
57 doc=
"Image selection subtask.",
58 target=WcsSelectImagesTask,
60 badMaskPlanes = pexConfig.ListField(
62 doc=
"Mask planes that, if set, the associated pixel should not be included in the coaddTempExp.",
65 inputRecorder = pexConfig.ConfigurableField(
66 doc=
"Subtask that helps fill CoaddInputs catalogs added to the final Exposure",
67 target=CoaddInputRecorderTask
69 doPsfMatch = pexConfig.Field(
71 doc=
"Match to modelPsf? Deprecated. Sets makePsfMatched=True, makeDirect=False",
74 modelPsf = measAlg.GaussianPsfFactory.makeField(doc=
"Model Psf factory")
75 doApplyUberCal = pexConfig.Field(
77 doc=
"Apply meas_mosaic ubercal results to input calexps?",
86 return pipeBase.TaskRunner.getTargetList(parsedCmd, selectDataList=parsedCmd.selectId.dataList,
91 """!Base class for coaddition. 93 Subclasses must specify _DefaultName 95 ConfigClass = CoaddBaseConfig
96 RunnerClass = CoaddTaskRunner
99 pipeBase.Task.__init__(self, *args, **kwargs)
100 self.makeSubtask(
"select")
101 self.makeSubtask(
"inputRecorder")
105 \brief Select exposures to coadd 107 Get the corners of the bbox supplied in skyInfo using \ref afwGeom.Box2D and convert the pixel 108 positions of the bbox corners to sky coordinates using \ref skyInfo.wcs.pixelToSky. Use the 109 \ref WcsSelectImagesTask_ "WcsSelectImagesTask" to select exposures that lie inside the patch 110 indicated by the dataRef. 112 \param[in] patchRef data reference for sky map patch. Must include keys "tract", "patch", 113 plus the camera-specific filter key (e.g. "filter" or "band") 114 \param[in] skyInfo geometry for the patch; output from getSkyInfo 115 \return a list of science exposures to coadd, as butler data references 119 cornerPosList = afwGeom.Box2D(skyInfo.bbox).getCorners()
120 coordList = [skyInfo.wcs.pixelToSky(pos)
for pos
in cornerPosList]
121 return self.select.runDataRef(patchRef, coordList, selectDataList=selectDataList).dataRefList
125 \brief Use \ref getSkyinfo to return the skyMap, tract and patch information, wcs and the outer bbox 128 \param[in] patchRef data reference for sky map. Must include keys "tract" and "patch" 130 \return pipe_base Struct containing: 132 - tractInfo: information for chosen tract of sky map 133 - patchInfo: information about chosen patch of tract 135 - bbox: outer bbox of patch, as an afwGeom Box2I 137 return getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
140 """!Return one "calexp" calibrated exposure 142 @param[in] dataRef a sensor-level data reference 143 @param[in] bgSubtracted return calexp with background subtracted? If False get the 144 calexp's background background model and add it to the calexp. 145 @return calibrated exposure 147 If config.doApplyUberCal, meas_mosaic calibrations will be applied to 148 the returned exposure using applyMosaicResults. 150 exposure = dataRef.get(
"calexp", immediate=
True)
152 background = dataRef.get(
"calexpBackground", immediate=
True)
153 mi = exposure.getMaskedImage()
154 mi += background.getImage()
156 if not self.config.doApplyUberCal:
158 if applyMosaicResults
is None:
160 "Cannot use improved calibrations for %s because meas_mosaic could not be imported." 168 """Return coadd name for given warpType and task config 173 Either 'direct' or 'psfMatched' 177 CoaddDatasetName : `string` 179 suffix =
"" if warpType ==
"direct" else warpType[0].upper() + warpType[1:]
180 return self.config.coaddName +
"Coadd" + suffix
183 """Return warp name for given warpType and task config 188 Either 'direct' or 'psfMatched' 192 WarpDatasetName : `string` 194 return self.config.coaddName +
"Coadd_" + warpType +
"Warp" 197 def _makeArgumentParser(cls):
198 """Create an argument parser 200 parser = pipeBase.ArgumentParser(name=cls._DefaultName)
201 parser.add_id_argument(
"--id",
"deepCoadd", help=
"data ID, e.g. --id tract=12345 patch=1,2",
202 ContainerClass=CoaddDataIdContainer)
203 parser.add_id_argument(
"--selectId",
"calexp", help=
"data ID, e.g. --selectId visit=6789 ccd=0..9",
204 ContainerClass=SelectDataIdContainer)
207 def _getConfigName(self):
208 """Return the name of the config dataset 210 return "%s_%s_config" % (self.config.coaddName, self._DefaultName)
212 def _getMetadataName(self):
213 """Return the name of the metadata dataset 215 return "%s_%s_metadata" % (self.config.coaddName, self._DefaultName)
219 \brief Convenience method to provide the bitmask from the mask plane names 221 return afwImage.Mask.getPlaneBitMask(self.config.badMaskPlanes)
226 \brief A dataId container for inputs to be selected. 228 Read the header (including the size and Wcs) for all specified 229 inputs and pass those along, ultimately for the SelectImagesTask. 230 This is most useful when used with multiprocessing, as input headers are 235 """Add a dataList containing useful information for selecting images""" 238 for ref
in self.refList:
240 md = ref.get(
"calexp_md", immediate=
True)
241 wcs = afwImage.makeWcs(md)
242 data =
SelectStruct(dataRef=ref, wcs=wcs, bbox=afwImage.bboxFromMetadata(md))
243 except FitsError
as e:
244 namespace.log.warn(
"Unable to construct Wcs from %s" % (ref.dataId))
251 \brief Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded. 253 \param[in] coaddName coadd name; typically one of deep or goodSeeing 254 \param[in] patchRef data reference for sky map. Must include keys "tract" and "patch" 256 \return pipe_base Struct containing: 258 - tractInfo: information for chosen tract of sky map 259 - patchInfo: information about chosen patch of tract 261 - bbox: outer bbox of patch, as an afwGeom Box2I 263 skyMap = patchRef.get(coaddName +
"Coadd_skyMap")
264 tractId = patchRef.dataId[
"tract"]
265 tractInfo = skyMap[tractId]
268 patchIndex = tuple(int(i)
for i
in patchRef.dataId[
"patch"].split(
","))
269 patchInfo = tractInfo.getPatchInfo(patchIndex)
271 return pipeBase.Struct(
275 wcs=tractInfo.getWcs(),
276 bbox=patchInfo.getOuterBBox(),
282 \brief Scale the variance in a maskedImage 284 The variance plane in a convolved or warped image (or a coadd derived 285 from warped images) does not accurately reflect the noise properties of 286 the image because variance has been lost to covariance. This function 287 attempts to correct for this by scaling the variance plane to match 288 the observed variance in the image. This is not perfect (because we're 289 not tracking the covariance) but it's simple and is often good enough. 291 @param maskedImage MaskedImage to operate on; variance will be scaled 292 @param maskPlanes List of mask planes for pixels to reject 293 @param log Log for reporting the renormalization factor; or None 294 @return renormalisation factor 296 variance = maskedImage.getVariance()
297 sigNoise = maskedImage.getImage().getArray()/numpy.sqrt(variance.getArray())
298 maskVal = maskedImage.getMask().getPlaneBitMask(maskPlanes)
299 good = (maskedImage.getMask().getArray() & maskVal) == 0
301 q1, q3 = numpy.percentile(sigNoise[good], (25, 75))
302 stdev = 0.74*(q3 - q1)
305 log.info(
"Renormalizing variance by %f" % (ratio,))
def getCoaddDatasetName(self, warpType="direct")
def makeDataRefList(self, namespace)
Base class for coaddition.
Configuration parameters for CoaddBaseTask.
A dataId container for inputs to be selected.
def __init__(self, args, kwargs)
def getSkyInfo(self, patchRef)
Use getSkyinfo to return the skyMap, tract and patch information, wcs and the outer bbox of the patch...
def getTempExpDatasetName(self, warpType="direct")
def getBadPixelMask(self)
Convenience method to provide the bitmask from the mask plane names.
def getTargetList(parsedCmd, kwargs)
def selectExposures(self, patchRef, skyInfo=None, selectDataList=[])
Select exposures to coadd.
def getCalExp(self, dataRef, bgSubtracted)
Return one "calexp" calibrated exposure.
def scaleVariance(maskedImage, maskPlanes, log=None)
Scale the variance in a maskedImage.
def getSkyInfo(coaddName, patchRef)
Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded...