22 import lsst.pex.config 
as pexConfig
 
   31 from .selectImages 
import WcsSelectImagesTask, SelectStruct
 
   32 from .coaddInputRecorder 
import CoaddInputRecorderTask
 
   33 from .scaleVariance 
import ScaleVarianceTask
 
   35 __all__ = [
"CoaddBaseTask", 
"getSkyInfo", 
"makeSkyInfo", 
"makeCoaddSuffix"]
 
   39     """!Configuration parameters for CoaddBaseTask 
   41     @anchor CoaddBaseConfig_ 
   43     @brief Configuration parameters shared between MakeCoaddTempExp and AssembleCoadd 
   45     coaddName = pexConfig.Field(
 
   46         doc=
"Coadd name: typically one of deep or goodSeeing.",
 
   50     select = pexConfig.ConfigurableField(
 
   51         doc=
"Image selection subtask.",
 
   52         target=WcsSelectImagesTask,
 
   54     badMaskPlanes = pexConfig.ListField(
 
   56         doc=
"Mask planes that, if set, the associated pixel should not be included in the coaddTempExp.",
 
   59     inputRecorder = pexConfig.ConfigurableField(
 
   60         doc=
"Subtask that helps fill CoaddInputs catalogs added to the final Exposure",
 
   61         target=CoaddInputRecorderTask
 
   63     doPsfMatch = pexConfig.Field(
 
   65         doc=
"Match to modelPsf? Deprecated. Sets makePsfMatched=True, makeDirect=False",
 
   68     modelPsf = measAlg.GaussianPsfFactory.makeField(doc=
"Model Psf factory")
 
   69     doApplyUberCal = pexConfig.Field(
 
   71         doc=(
"Apply ubercalibrated WCS and PhotoCalib results to input calexps? " 
   72              "This field is no longer used, and has been deprecated by DM-21308. " 
   73              "It will be removed after v20. Use doApplyExternalPhotoCalib and " 
   74              "doApplyExternalSkyWcs instead."),
 
   77     doApplyExternalPhotoCalib = pexConfig.Field(
 
   80         doc=(
"Whether to apply external photometric calibration via an " 
   81              "`lsst.afw.image.PhotoCalib` object.  Uses the " 
   82              "`externalPhotoCalibName` field to determine which calibration " 
   85     externalPhotoCalibName = pexConfig.ChoiceField(
 
   87         doc=
"Type of external PhotoCalib if `doApplyExternalPhotoCalib` is True.",
 
   90             "jointcal": 
"Use jointcal_photoCalib",
 
   91             "fgcm": 
"Use fgcm_photoCalib",
 
   92             "fgcm_tract": 
"Use fgcm_tract_photoCalib" 
   95     doApplyExternalSkyWcs = pexConfig.Field(
 
   98         doc=(
"Whether to apply external astrometric calibration via an " 
   99              "`lsst.afw.geom.SkyWcs` object.  Uses `externalSkyWcsName` " 
  100              "field to determine which calibration to load.")
 
  102     externalSkyWcsName = pexConfig.ChoiceField(
 
  104         doc=
"Type of external SkyWcs if `doApplyExternalSkyWcs` is True.",
 
  107             "jointcal": 
"Use jointcal_wcs" 
  110     includeCalibVar = pexConfig.Field(
 
  112         doc=
"Add photometric calibration variance to warp variance plane.",
 
  115     matchingKernelSize = pexConfig.Field(
 
  117         doc=
"Size in pixels of matching kernel. Must be odd.",
 
  119         check=
lambda x: x % 2 == 1
 
  127         return pipeBase.TaskRunner.getTargetList(parsedCmd, selectDataList=parsedCmd.selectId.dataList,
 
  132     """!Base class for coaddition. 
  134     Subclasses must specify _DefaultName 
  136     ConfigClass = CoaddBaseConfig
 
  137     RunnerClass = CoaddTaskRunner
 
  141         self.makeSubtask(
"select")
 
  142         self.makeSubtask(
"inputRecorder")
 
  146         @brief Select exposures to coadd 
  148         Get the corners of the bbox supplied in skyInfo using @ref geom.Box2D and convert the pixel 
  149         positions of the bbox corners to sky coordinates using @ref skyInfo.wcs.pixelToSky. Use the 
  150         @ref WcsSelectImagesTask_ "WcsSelectImagesTask" to select exposures that lie inside the patch 
  151         indicated by the dataRef. 
  153         @param[in] patchRef  data reference for sky map patch. Must include keys "tract", "patch", 
  154                              plus the camera-specific filter key (e.g. "filter" or "band") 
  155         @param[in] skyInfo   geometry for the patch; output from getSkyInfo 
  156         @return    a list of science exposures to coadd, as butler data references 
  160         cornerPosList = 
geom.Box2D(skyInfo.bbox).getCorners()
 
  161         coordList = [skyInfo.wcs.pixelToSky(pos) 
for pos 
in cornerPosList]
 
  162         return self.select.runDataRef(patchRef, coordList, selectDataList=selectDataList).dataRefList
 
  166         @brief Use @ref getSkyinfo to return the skyMap, tract and patch information, wcs and the outer bbox 
  169         @param[in] patchRef  data reference for sky map. Must include keys "tract" and "patch" 
  171         @return pipe_base Struct containing: 
  173         - tractInfo: information for chosen tract of sky map 
  174         - patchInfo: information about chosen patch of tract 
  176         - bbox: outer bbox of patch, as an geom Box2I 
  178         return getSkyInfo(coaddName=self.config.coaddName, patchRef=patchRef)
 
  181         """Return coadd name for given warpType and task config 
  186             Either 'direct' or 'psfMatched' 
  190         CoaddDatasetName : `string` 
  195         """Return warp name for given warpType and task config 
  200             Either 'direct' or 'psfMatched' 
  204         WarpDatasetName : `string` 
  206         return self.config.coaddName + 
"Coadd_" + warpType + 
"Warp" 
  209     def _makeArgumentParser(cls):
 
  210         """Create an argument parser 
  212         parser = pipeBase.ArgumentParser(name=cls._DefaultName)
 
  213         parser.add_id_argument(
"--id", 
"deepCoadd", help=
"data ID, e.g. --id tract=12345 patch=1,2",
 
  214                                ContainerClass=CoaddDataIdContainer)
 
  215         parser.add_id_argument(
"--selectId", 
"calexp", help=
"data ID, e.g. --selectId visit=6789 ccd=0..9",
 
  216                                ContainerClass=SelectDataIdContainer)
 
  219     def _getConfigName(self):
 
  220         """Return the name of the config dataset 
  222         return "%s_%s_config" % (self.config.coaddName, self._DefaultName)
 
  224     def _getMetadataName(self):
 
  225         """Return the name of the metadata dataset 
  227         return "%s_%s_metadata" % (self.config.coaddName, self._DefaultName)
 
  231         @brief Convenience method to provide the bitmask from the mask plane names 
  233         return afwImage.Mask.getPlaneBitMask(self.config.badMaskPlanes)
 
  238     @brief A dataId container for inputs to be selected. 
  240     Read the header (including the size and Wcs) for all specified 
  241     inputs and pass those along, ultimately for the SelectImagesTask. 
  242     This is most useful when used with multiprocessing, as input headers are 
  247         """Add a dataList containing useful information for selecting images""" 
  250         for ref 
in self.refList:
 
  252                 md = ref.get(
"calexp_md", immediate=
True)
 
  256                 namespace.log.warn(
"Unable to construct Wcs from %s" % (ref.dataId))
 
  263     @brief Return the SkyMap, tract and patch information, wcs, and outer bbox of the patch to be coadded. 
  265     @param[in]  coaddName  coadd name; typically one of deep or goodSeeing 
  266     @param[in]  patchRef   data reference for sky map. Must include keys "tract" and "patch" 
  268     @return pipe_base Struct containing: 
  270     - tractInfo: information for chosen tract of sky map 
  271     - patchInfo: information about chosen patch of tract 
  273     - bbox: outer bbox of patch, as an geom Box2I 
  275     skyMap = patchRef.get(coaddName + 
"Coadd_skyMap")
 
  276     return makeSkyInfo(skyMap, patchRef.dataId[
"tract"], patchRef.dataId[
"patch"])
 
  280     """Return SkyInfo Struct 
  282     Constructs SkyInfo used by coaddition tasks for multiple 
  287     skyMap : `lsst.skyMap.SkyMap` 
  289     patchId : str or int or tuple of int 
  290         Either Gen2-style comma delimited string (e.g. '4,5'), 
  291         tuple of integers (e.g (4, 5), Gen3-style integer. 
  293     tractInfo = skyMap[tractId]
 
  295     if isinstance(patchId, str) 
and ',' in patchId:
 
  297         patchIndex = tuple(int(i) 
for i 
in patchId.split(
","))
 
  301     patchInfo = tractInfo.getPatchInfo(patchIndex)
 
  303     return pipeBase.Struct(
 
  307         wcs=tractInfo.getWcs(),
 
  308         bbox=patchInfo.getOuterBBox(),
 
  314     @brief Scale the variance in a maskedImage 
  316     The variance plane in a convolved or warped image (or a coadd derived 
  317     from warped images) does not accurately reflect the noise properties of 
  318     the image because variance has been lost to covariance. This function 
  319     attempts to correct for this by scaling the variance plane to match 
  320     the observed variance in the image. This is not perfect (because we're 
  321     not tracking the covariance) but it's simple and is often good enough. 
  323     @deprecated Use the ScaleVarianceTask instead. 
  325     @param maskedImage  MaskedImage to operate on; variance will be scaled 
  326     @param maskPlanes  List of mask planes for pixels to reject 
  327     @param log  Log for reporting the renormalization factor; or None 
  328     @return renormalisation factor 
  330     config = ScaleVarianceTask.ConfigClass()
 
  331     config.maskPlanes = maskPlanes
 
  333     return task.run(maskedImage)
 
  337     """Return coadd suffix for warpType 
  342         Either 'direct' or 'psfMatched' 
  346     CoaddSuffix : `string` 
  348     suffix = 
"" if warpType == 
"direct" else warpType[0].upper() + warpType[1:]