LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
Classes | Functions | Variables
lsst.pipe.tasks.assembleCoadd Namespace Reference

Classes

class  AssembleCoaddConnections
 
class  AssembleCoaddDataIdContainer
 
class  CompareWarpAssembleCoaddConfig
 
class  CompareWarpAssembleCoaddConnections
 
class  CompareWarpAssembleCoaddTask
 
class  SafeClipAssembleCoaddConfig
 
class  SafeClipAssembleCoaddTask
 

Functions

def processResults (self, coaddExposure, brightObjectMasks=None, dataId=None)
 
def makeSupplementaryData (self, dataRef, selectDataList=None, warpRefList=None)
 
def makeSupplementaryDataGen3 (self, butlerQC, inputRefs, outputRefs)
 
def getTempExpRefList (self, patchRef, calExpRefList)
 
def prepareInputs (self, refList)
 
def prepareStats (self, mask=None)
 
def run (self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=None)
 
def assembleMetadata (self, coaddExposure, tempExpRefList, weightList)
 
def assembleSubregion (self, coaddExposure, bbox, tempExpRefList, imageScalerList, weightList, altMaskList, statsFlags, statsCtrl, nImage=None)
 
def assembleOnlineMeanCoadd (self, coaddExposure, tempExpRefList, imageScalerList, weightList, altMaskList, statsCtrl, nImage=None)
 
def removeMaskPlanes (self, maskedImage)
 
def applyAltMaskPlanes (self, mask, altMaskSpans)
 
def shrinkValidPolygons (self, coaddInputs)
 
def readBrightObjectMasks (self, dataRef)
 
def setBrightObjectMasks (self, exposure, brightObjectMasks, dataId=None)
 
def setInexactPsf (self, mask)
 
def filterWarps (self, inputs, goodVisits)
 
def countMaskFromFootprint (mask, footprint, bitmask, ignoreMask)
 

Variables

 log = logging.getLogger(__name__)
 
 id
 
 KEY
 
 patch
 
 tract
 
 filter
 
 visit
 
 ccd
 
 skyInfo
 
 calExpRefList
 
 warpRefList
 
 inputData
 
 supplementaryData
 
 retStruct
 
 brightObjects
 
 coaddDatasetName
 
 warpType
 

Function Documentation

◆ applyAltMaskPlanes()

def lsst.pipe.tasks.assembleCoadd.applyAltMaskPlanes (   self,
  mask,
  altMaskSpans 
)
Apply in place alt mask formatted as SpanSets to a mask.

Parameters
----------
mask : `lsst.afw.image.Mask`
    Original mask.
altMaskSpans : `dict`
    SpanSet lists to apply. Each element contains the new mask
    plane name (e.g. "CLIPPED and/or "NO_DATA") as the key,
    and list of SpanSets to apply to the mask.

Returns
-------
mask : `lsst.afw.image.Mask`
    Updated mask.

Definition at line 1136 of file assembleCoadd.py.

1136 def applyAltMaskPlanes(self, mask, altMaskSpans):
1137 """Apply in place alt mask formatted as SpanSets to a mask.
1138
1139 Parameters
1140 ----------
1141 mask : `lsst.afw.image.Mask`
1142 Original mask.
1143 altMaskSpans : `dict`
1144 SpanSet lists to apply. Each element contains the new mask
1145 plane name (e.g. "CLIPPED and/or "NO_DATA") as the key,
1146 and list of SpanSets to apply to the mask.
1147
1148 Returns
1149 -------
1150 mask : `lsst.afw.image.Mask`
1151 Updated mask.
1152 """
1153 if self.config.doUsePsfMatchedPolygons:
1154 if ("NO_DATA" in altMaskSpans) and ("NO_DATA" in self.config.badMaskPlanes):
1155 # Clear away any other masks outside the validPolygons. These pixels are no longer
1156 # contributing to inexact PSFs, and will still be rejected because of NO_DATA
1157 # self.config.doUsePsfMatchedPolygons should be True only in CompareWarpAssemble
1158 # This mask-clearing step must only occur *before* applying the new masks below
1159 for spanSet in altMaskSpans['NO_DATA']:
1160 spanSet.clippedTo(mask.getBBox()).clearMask(mask, self.getBadPixelMask())
1161
1162 for plane, spanSetList in altMaskSpans.items():
1163 maskClipValue = mask.addMaskPlane(plane)
1164 for spanSet in spanSetList:
1165 spanSet.clippedTo(mask.getBBox()).setMask(mask, 2**maskClipValue)
1166 return mask
1167
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
def applyAltMaskPlanes(self, mask, altMaskSpans)

◆ assembleMetadata()

def lsst.pipe.tasks.assembleCoadd.assembleMetadata (   self,
  coaddExposure,
  tempExpRefList,
  weightList 
)
Set the metadata for the coadd.

This basic implementation sets the filter from the first input.

Parameters
----------
coaddExposure : `lsst.afw.image.Exposure`
    The target exposure for the coadd.
tempExpRefList : `list`
    List of data references to tempExp.
weightList : `list`
    List of weights.

Definition at line 869 of file assembleCoadd.py.

869 def assembleMetadata(self, coaddExposure, tempExpRefList, weightList):
870 """Set the metadata for the coadd.
871
872 This basic implementation sets the filter from the first input.
873
874 Parameters
875 ----------
876 coaddExposure : `lsst.afw.image.Exposure`
877 The target exposure for the coadd.
878 tempExpRefList : `list`
879 List of data references to tempExp.
880 weightList : `list`
881 List of weights.
882 """
883 assert len(tempExpRefList) == len(weightList), "Length mismatch"
884 tempExpName = self.getTempExpDatasetName(self.warpType)
885 # We load a single pixel of each coaddTempExp, because we just want to get at the metadata
886 # (and we need more than just the PropertySet that contains the header), which is not possible
887 # with the current butler (see #2777).
888 bbox = geom.Box2I(coaddExposure.getBBox().getMin(), geom.Extent2I(1, 1))
889
890 if isinstance(tempExpRefList[0], DeferredDatasetHandle):
891 # Gen 3 API
892 tempExpList = [tempExpRef.get(parameters={'bbox': bbox}) for tempExpRef in tempExpRefList]
893 else:
894 # Gen 2 API. Delete this when Gen 2 retired
895 tempExpList = [tempExpRef.get(tempExpName + "_sub", bbox=bbox, immediate=True)
896 for tempExpRef in tempExpRefList]
897 numCcds = sum(len(tempExp.getInfo().getCoaddInputs().ccds) for tempExp in tempExpList)
898
899 # Set the coadd FilterLabel to the band of the first input exposure:
900 # Coadds are calibrated, so the physical label is now meaningless.
901 coaddExposure.setFilter(afwImage.FilterLabel(tempExpList[0].getFilter().bandLabel))
902 coaddInputs = coaddExposure.getInfo().getCoaddInputs()
903 coaddInputs.ccds.reserve(numCcds)
904 coaddInputs.visits.reserve(len(tempExpList))
905
906 for tempExp, weight in zip(tempExpList, weightList):
907 self.inputRecorder.addVisitToCoadd(coaddInputs, tempExp, weight)
908
909 if self.config.doUsePsfMatchedPolygons:
910 self.shrinkValidPolygons(coaddInputs)
911
912 coaddInputs.visits.sort()
913 coaddInputs.ccds.sort()
914 if self.warpType == "psfMatched":
915 # The modelPsf BBox for a psfMatchedWarp/coaddTempExp was dynamically defined by
916 # ModelPsfMatchTask as the square box bounding its spatially-variable, pre-matched WarpedPsf.
917 # Likewise, set the PSF of a PSF-Matched Coadd to the modelPsf
918 # having the maximum width (sufficient because square)
919 modelPsfList = [tempExp.getPsf() for tempExp in tempExpList]
920 modelPsfWidthList = [modelPsf.computeBBox(modelPsf.getAveragePosition()).getWidth()
921 for modelPsf in modelPsfList]
922 psf = modelPsfList[modelPsfWidthList.index(max(modelPsfWidthList))]
923 else:
924 psf = measAlg.CoaddPsf(coaddInputs.ccds, coaddExposure.getWcs(),
925 self.config.coaddPsf.makeControl())
926 coaddExposure.setPsf(psf)
927 apCorrMap = measAlg.makeCoaddApCorrMap(coaddInputs.ccds, coaddExposure.getBBox(afwImage.PARENT),
928 coaddExposure.getWcs())
929 coaddExposure.getInfo().setApCorrMap(apCorrMap)
930 if self.config.doAttachTransmissionCurve:
931 transmissionCurve = measAlg.makeCoaddTransmissionCurve(coaddExposure.getWcs(), coaddInputs.ccds)
932 coaddExposure.getInfo().setTransmissionCurve(transmissionCurve)
933
int max
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
A group of labels for a filter in an exposure or coadd.
Definition: FilterLabel.h:58
An integer coordinate rectangle.
Definition: Box.h:55
def assembleMetadata(self, coaddExposure, tempExpRefList, weightList)

◆ assembleOnlineMeanCoadd()

def lsst.pipe.tasks.assembleCoadd.assembleOnlineMeanCoadd (   self,
  coaddExposure,
  tempExpRefList,
  imageScalerList,
  weightList,
  altMaskList,
  statsCtrl,
  nImage = None 
)
Assemble the coadd using the "online" method.

This method takes a running sum of images and weights to save memory.
It only works for MEAN statistics.

Parameters
----------
coaddExposure : `lsst.afw.image.Exposure`
    The target exposure for the coadd.
tempExpRefList : `list`
    List of data reference to tempExp.
imageScalerList : `list`
    List of image scalers.
weightList : `list`
    List of weights.
altMaskList : `list`
    List of alternate masks to use rather than those stored with
    tempExp, or None.  Each element is dict with keys = mask plane
    name to which to add the spans.
statsCtrl : `lsst.afw.math.StatisticsControl`
    Statistics control object for coadd
nImage : `lsst.afw.image.ImageU`, optional
    Keeps track of exposure count for each pixel.

Definition at line 1015 of file assembleCoadd.py.

1016 altMaskList, statsCtrl, nImage=None):
1017 """Assemble the coadd using the "online" method.
1018
1019 This method takes a running sum of images and weights to save memory.
1020 It only works for MEAN statistics.
1021
1022 Parameters
1023 ----------
1024 coaddExposure : `lsst.afw.image.Exposure`
1025 The target exposure for the coadd.
1026 tempExpRefList : `list`
1027 List of data reference to tempExp.
1028 imageScalerList : `list`
1029 List of image scalers.
1030 weightList : `list`
1031 List of weights.
1032 altMaskList : `list`
1033 List of alternate masks to use rather than those stored with
1034 tempExp, or None. Each element is dict with keys = mask plane
1035 name to which to add the spans.
1037 Statistics control object for coadd
1038 nImage : `lsst.afw.image.ImageU`, optional
1039 Keeps track of exposure count for each pixel.
1040 """
1041 self.log.debug("Computing online coadd.")
1042 tempExpName = self.getTempExpDatasetName(self.warpType)
1043 coaddExposure.mask.addMaskPlane("REJECTED")
1044 coaddExposure.mask.addMaskPlane("CLIPPED")
1045 coaddExposure.mask.addMaskPlane("SENSOR_EDGE")
1046 maskMap = self.setRejectedMaskMapping(statsCtrl)
1047 thresholdDict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(statsCtrl)
1048
1049 bbox = coaddExposure.maskedImage.getBBox()
1050
1051 stacker = AccumulatorMeanStack(
1052 coaddExposure.image.array.shape,
1053 statsCtrl.getAndMask(),
1054 mask_threshold_dict=thresholdDict,
1055 mask_map=maskMap,
1056 no_good_pixels_mask=statsCtrl.getNoGoodPixelsMask(),
1057 calc_error_from_input_variance=self.config.calcErrorFromInputVariance,
1058 compute_n_image=(nImage is not None)
1059 )
1060
1061 for tempExpRef, imageScaler, altMask, weight in zip(tempExpRefList,
1062 imageScalerList,
1063 altMaskList,
1064 weightList):
1065 if isinstance(tempExpRef, DeferredDatasetHandle):
1066 # Gen 3 API
1067 exposure = tempExpRef.get()
1068 else:
1069 # Gen 2 API. Delete this when Gen 2 retired
1070 exposure = tempExpRef.get(tempExpName)
1071
1072 maskedImage = exposure.getMaskedImage()
1073 mask = maskedImage.getMask()
1074 if altMask is not None:
1075 self.applyAltMaskPlanes(mask, altMask)
1076 imageScaler.scaleMaskedImage(maskedImage)
1077 if self.config.removeMaskPlanes:
1078 self.removeMaskPlanes(maskedImage)
1079
1080 stacker.add_masked_image(maskedImage, weight=weight)
1081
1082 if self.config.doInputMap:
1083 visit = exposure.getInfo().getCoaddInputs().visits[0].getId()
1084 self.inputMapper.mask_warp_bbox(bbox, visit, mask, statsCtrl.getAndMask())
1085
1086 stacker.fill_stacked_masked_image(coaddExposure.maskedImage)
1087
1088 if nImage is not None:
1089 nImage.array[:, :] = stacker.n_image
1090
Pass parameters to a Statistics object.
Definition: Statistics.h:92

◆ assembleSubregion()

def lsst.pipe.tasks.assembleCoadd.assembleSubregion (   self,
  coaddExposure,
  bbox,
  tempExpRefList,
  imageScalerList,
  weightList,
  altMaskList,
  statsFlags,
  statsCtrl,
  nImage = None 
)
Assemble the coadd for a sub-region.

For each coaddTempExp, check for (and swap in) an alternative mask
if one is passed. Remove mask planes listed in
`config.removeMaskPlanes`. Finally, stack the actual exposures using
`lsst.afw.math.statisticsStack` with the statistic specified by
statsFlags. Typically, the statsFlag will be one of lsst.afw.math.MEAN for
a mean-stack or `lsst.afw.math.MEANCLIP` for outlier rejection using
an N-sigma clipped mean where N and iterations are specified by
statsCtrl.  Assign the stacked subregion back to the coadd.

Parameters
----------
coaddExposure : `lsst.afw.image.Exposure`
    The target exposure for the coadd.
bbox : `lsst.geom.Box`
    Sub-region to coadd.
tempExpRefList : `list`
    List of data reference to tempExp.
imageScalerList : `list`
    List of image scalers.
weightList : `list`
    List of weights.
altMaskList : `list`
    List of alternate masks to use rather than those stored with
    tempExp, or None.  Each element is dict with keys = mask plane
    name to which to add the spans.
statsFlags : `lsst.afw.math.Property`
    Property object for statistic for coadd.
statsCtrl : `lsst.afw.math.StatisticsControl`
    Statistics control object for coadd.
nImage : `lsst.afw.image.ImageU`, optional
    Keeps track of exposure count for each pixel.

Definition at line 934 of file assembleCoadd.py.

935 altMaskList, statsFlags, statsCtrl, nImage=None):
936 """Assemble the coadd for a sub-region.
937
938 For each coaddTempExp, check for (and swap in) an alternative mask
939 if one is passed. Remove mask planes listed in
940 `config.removeMaskPlanes`. Finally, stack the actual exposures using
941 `lsst.afw.math.statisticsStack` with the statistic specified by
942 statsFlags. Typically, the statsFlag will be one of lsst.afw.math.MEAN for
943 a mean-stack or `lsst.afw.math.MEANCLIP` for outlier rejection using
944 an N-sigma clipped mean where N and iterations are specified by
945 statsCtrl. Assign the stacked subregion back to the coadd.
946
947 Parameters
948 ----------
949 coaddExposure : `lsst.afw.image.Exposure`
950 The target exposure for the coadd.
951 bbox : `lsst.geom.Box`
952 Sub-region to coadd.
953 tempExpRefList : `list`
954 List of data reference to tempExp.
955 imageScalerList : `list`
956 List of image scalers.
957 weightList : `list`
958 List of weights.
959 altMaskList : `list`
960 List of alternate masks to use rather than those stored with
961 tempExp, or None. Each element is dict with keys = mask plane
962 name to which to add the spans.
963 statsFlags : `lsst.afw.math.Property`
964 Property object for statistic for coadd.
966 Statistics control object for coadd.
967 nImage : `lsst.afw.image.ImageU`, optional
968 Keeps track of exposure count for each pixel.
969 """
970 self.log.debug("Computing coadd over %s", bbox)
971 tempExpName = self.getTempExpDatasetName(self.warpType)
972 coaddExposure.mask.addMaskPlane("REJECTED")
973 coaddExposure.mask.addMaskPlane("CLIPPED")
974 coaddExposure.mask.addMaskPlane("SENSOR_EDGE")
975 maskMap = self.setRejectedMaskMapping(statsCtrl)
976 clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")
977 maskedImageList = []
978 if nImage is not None:
979 subNImage = afwImage.ImageU(bbox.getWidth(), bbox.getHeight())
980 for tempExpRef, imageScaler, altMask in zip(tempExpRefList, imageScalerList, altMaskList):
981
982 if isinstance(tempExpRef, DeferredDatasetHandle):
983 # Gen 3 API
984 exposure = tempExpRef.get(parameters={'bbox': bbox})
985 else:
986 # Gen 2 API. Delete this when Gen 2 retired
987 exposure = tempExpRef.get(tempExpName + "_sub", bbox=bbox)
988
989 maskedImage = exposure.getMaskedImage()
990 mask = maskedImage.getMask()
991 if altMask is not None:
992 self.applyAltMaskPlanes(mask, altMask)
993 imageScaler.scaleMaskedImage(maskedImage)
994
995 # Add 1 for each pixel which is not excluded by the exclude mask.
996 # In legacyCoadd, pixels may also be excluded by afwMath.statisticsStack.
997 if nImage is not None:
998 subNImage.getArray()[maskedImage.getMask().getArray() & statsCtrl.getAndMask() == 0] += 1
999 if self.config.removeMaskPlanes:
1000 self.removeMaskPlanes(maskedImage)
1001 maskedImageList.append(maskedImage)
1002
1003 if self.config.doInputMap:
1004 visit = exposure.getInfo().getCoaddInputs().visits[0].getId()
1005 self.inputMapper.mask_warp_bbox(bbox, visit, mask, statsCtrl.getAndMask())
1006
1007 with self.timer("stack"):
1008 coaddSubregion = afwMath.statisticsStack(maskedImageList, statsFlags, statsCtrl, weightList,
1009 clipped, # also set output to CLIPPED if sigma-clipped
1010 maskMap)
1011 coaddExposure.maskedImage.assign(coaddSubregion, bbox)
1012 if nImage is not None:
1013 nImage.assign(subNImage, bbox)
1014
std::shared_ptr< lsst::afw::image::Image< PixelT > > statisticsStack(std::vector< std::shared_ptr< lsst::afw::image::Image< PixelT > > > &images, Property flags, StatisticsControl const &sctrl=StatisticsControl(), std::vector< lsst::afw::image::VariancePixel > const &wvector=std::vector< lsst::afw::image::VariancePixel >(0))
A function to compute some statistics of a stack of Images.

◆ countMaskFromFootprint()

def lsst.pipe.tasks.assembleCoadd.countMaskFromFootprint (   mask,
  footprint,
  bitmask,
  ignoreMask 
)
Function to count the number of pixels with a specific mask in a
footprint.

Find the intersection of mask & footprint. Count all pixels in the mask
that are in the intersection that have bitmask set but do not have
ignoreMask set. Return the count.

Parameters
----------
mask : `lsst.afw.image.Mask`
    Mask to define intersection region by.
footprint : `lsst.afw.detection.Footprint`
    Footprint to define the intersection region by.
bitmask
    Specific mask that we wish to count the number of occurances of.
ignoreMask
    Pixels to not consider.

Returns
-------
result : `int`
    Count of number of pixels in footprint with specified mask.

Definition at line 1372 of file assembleCoadd.py.

1372def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask):
1373 """Function to count the number of pixels with a specific mask in a
1374 footprint.
1375
1376 Find the intersection of mask & footprint. Count all pixels in the mask
1377 that are in the intersection that have bitmask set but do not have
1378 ignoreMask set. Return the count.
1379
1380 Parameters
1381 ----------
1382 mask : `lsst.afw.image.Mask`
1383 Mask to define intersection region by.
1384 footprint : `lsst.afw.detection.Footprint`
1385 Footprint to define the intersection region by.
1386 bitmask
1387 Specific mask that we wish to count the number of occurances of.
1388 ignoreMask
1389 Pixels to not consider.
1390
1391 Returns
1392 -------
1393 result : `int`
1394 Count of number of pixels in footprint with specified mask.
1395 """
1396 bbox = footprint.getBBox()
1397 bbox.clip(mask.getBBox(afwImage.PARENT))
1398 fp = afwImage.Mask(bbox)
1399 subMask = mask.Factory(mask, bbox, afwImage.PARENT)
1400 footprint.spans.setMask(fp, bitmask)
1401 return numpy.logical_and((subMask.getArray() & fp.getArray()) > 0,
1402 (subMask.getArray() & ignoreMask) == 0).sum()
1403
1404
Class to describe the properties of a detected object from an image.
Definition: Footprint.h:63
def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask)

◆ filterWarps()

def lsst.pipe.tasks.assembleCoadd.filterWarps (   self,
  inputs,
  goodVisits 
)
Return list of only inputRefs with visitId in goodVisits ordered by goodVisit

Parameters
----------
inputs : list
    List of `lsst.pipe.base.connections.DeferredDatasetRef` with dataId containing visit
goodVisit : `dict`
    Dictionary with good visitIds as the keys. Value ignored.

Returns:
--------
filteredInputs : `list`
    Filtered and sorted list of `lsst.pipe.base.connections.DeferredDatasetRef`

Definition at line 1321 of file assembleCoadd.py.

1321 def filterWarps(self, inputs, goodVisits):
1322 """Return list of only inputRefs with visitId in goodVisits ordered by goodVisit
1323
1324 Parameters
1325 ----------
1326 inputs : list
1327 List of `lsst.pipe.base.connections.DeferredDatasetRef` with dataId containing visit
1328 goodVisit : `dict`
1329 Dictionary with good visitIds as the keys. Value ignored.
1330
1331 Returns:
1332 --------
1333 filteredInputs : `list`
1334 Filtered and sorted list of `lsst.pipe.base.connections.DeferredDatasetRef`
1335 """
1336 inputWarpDict = {inputRef.ref.dataId['visit']: inputRef for inputRef in inputs}
1337 filteredInputs = []
1338 for visit in goodVisits.keys():
1339 if visit in inputWarpDict:
1340 filteredInputs.append(inputWarpDict[visit])
1341 return filteredInputs
1342
1343
def filterWarps(self, inputs, goodVisits)

◆ getTempExpRefList()

def lsst.pipe.tasks.assembleCoadd.getTempExpRefList (   self,
  patchRef,
  calExpRefList 
)
Generate list data references corresponding to warped exposures
that lie within the patch to be coadded.

Parameters
----------
patchRef : `dataRef`
    Data reference for patch.
calExpRefList : `list`
    List of data references for input calexps.

Returns
-------
tempExpRefList : `list`
    List of Warp/CoaddTempExp data references.

Definition at line 631 of file assembleCoadd.py.

631 def getTempExpRefList(self, patchRef, calExpRefList):
632 """Generate list data references corresponding to warped exposures
633 that lie within the patch to be coadded.
634
635 Parameters
636 ----------
637 patchRef : `dataRef`
638 Data reference for patch.
639 calExpRefList : `list`
640 List of data references for input calexps.
641
642 Returns
643 -------
644 tempExpRefList : `list`
645 List of Warp/CoaddTempExp data references.
646 """
647 butler = patchRef.getButler()
648 groupData = groupPatchExposures(patchRef, calExpRefList, self.getCoaddDatasetName(self.warpType),
649 self.getTempExpDatasetName(self.warpType))
650 tempExpRefList = [getGroupDataRef(butler, self.getTempExpDatasetName(self.warpType),
651 g, groupData.keys) for
652 g in groupData.groups.keys()]
653 return tempExpRefList
654
def getTempExpRefList(self, patchRef, calExpRefList)
def getGroupDataRef(butler, datasetType, groupTuple, keys)
Definition: coaddHelpers.py:99
def groupPatchExposures(patchDataRef, calexpDataRefList, coaddDatasetType="deepCoadd", tempExpDatasetType="deepCoadd_directWarp")
Definition: coaddHelpers.py:60

◆ makeSupplementaryData()

def lsst.pipe.tasks.assembleCoadd.makeSupplementaryData (   self,
  dataRef,
  selectDataList = None,
  warpRefList = None 
)
Make additional inputs to run() specific to subclasses (Gen2)

Duplicates interface of `runDataRef` method
Available to be implemented by subclasses only if they need the
coadd dataRef for performing preliminary processing before
assembling the coadd.

Parameters
----------
dataRef : `lsst.daf.persistence.ButlerDataRef`
    Butler data reference for supplementary data.
selectDataList : `list` (optional)
    Optional List of data references to Calexps.
warpRefList : `list` (optional)
    Optional List of data references to Warps.

Definition at line 588 of file assembleCoadd.py.

588 def makeSupplementaryData(self, dataRef, selectDataList=None, warpRefList=None):
589 """Make additional inputs to run() specific to subclasses (Gen2)
590
591 Duplicates interface of `runDataRef` method
592 Available to be implemented by subclasses only if they need the
593 coadd dataRef for performing preliminary processing before
594 assembling the coadd.
595
596 Parameters
597 ----------
599 Butler data reference for supplementary data.
600 selectDataList : `list` (optional)
601 Optional List of data references to Calexps.
602 warpRefList : `list` (optional)
603 Optional List of data references to Warps.
604 """
605 return pipeBase.Struct()
606
def makeSupplementaryData(self, dataRef, selectDataList=None, warpRefList=None)

◆ makeSupplementaryDataGen3()

def lsst.pipe.tasks.assembleCoadd.makeSupplementaryDataGen3 (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)
Make additional inputs to run() specific to subclasses (Gen3)

Duplicates interface of `runQuantum` method.
Available to be implemented by subclasses only if they need the
coadd dataRef for performing preliminary processing before
assembling the coadd.

Parameters
----------
butlerQC : `lsst.pipe.base.ButlerQuantumContext`
    Gen3 Butler object for fetching additional data products before
    running the Task specialized for quantum being processed
inputRefs : `lsst.pipe.base.InputQuantizedConnection`
    Attributes are the names of the connections describing input dataset types.
    Values are DatasetRefs that task consumes for corresponding dataset type.
    DataIds are guaranteed to match data objects in ``inputData``.
outputRefs : `lsst.pipe.base.OutputQuantizedConnection`
    Attributes are the names of the connections describing output dataset types.
    Values are DatasetRefs that task is to produce
    for corresponding dataset type.

Definition at line 607 of file assembleCoadd.py.

607 def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs):
608 """Make additional inputs to run() specific to subclasses (Gen3)
609
610 Duplicates interface of `runQuantum` method.
611 Available to be implemented by subclasses only if they need the
612 coadd dataRef for performing preliminary processing before
613 assembling the coadd.
614
615 Parameters
616 ----------
617 butlerQC : `lsst.pipe.base.ButlerQuantumContext`
618 Gen3 Butler object for fetching additional data products before
619 running the Task specialized for quantum being processed
620 inputRefs : `lsst.pipe.base.InputQuantizedConnection`
621 Attributes are the names of the connections describing input dataset types.
622 Values are DatasetRefs that task consumes for corresponding dataset type.
623 DataIds are guaranteed to match data objects in ``inputData``.
624 outputRefs : `lsst.pipe.base.OutputQuantizedConnection`
625 Attributes are the names of the connections describing output dataset types.
626 Values are DatasetRefs that task is to produce
627 for corresponding dataset type.
628 """
629 return pipeBase.Struct()
630
def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs)

◆ prepareInputs()

def lsst.pipe.tasks.assembleCoadd.prepareInputs (   self,
  refList 
)
Prepare the input warps for coaddition by measuring the weight for
each warp and the scaling for the photometric zero point.

Each Warp has its own photometric zeropoint and background variance.
Before coadding these Warps together, compute a scale factor to
normalize the photometric zeropoint and compute the weight for each Warp.

Parameters
----------
refList : `list`
    List of data references to tempExp

Returns
-------
result : `lsst.pipe.base.Struct`
   Result struct with components:

   - ``tempExprefList``: `list` of data references to tempExp.
   - ``weightList``: `list` of weightings.
   - ``imageScalerList``: `list` of image scalers.

Definition at line 655 of file assembleCoadd.py.

655 def prepareInputs(self, refList):
656 """Prepare the input warps for coaddition by measuring the weight for
657 each warp and the scaling for the photometric zero point.
658
659 Each Warp has its own photometric zeropoint and background variance.
660 Before coadding these Warps together, compute a scale factor to
661 normalize the photometric zeropoint and compute the weight for each Warp.
662
663 Parameters
664 ----------
665 refList : `list`
666 List of data references to tempExp
667
668 Returns
669 -------
670 result : `lsst.pipe.base.Struct`
671 Result struct with components:
672
673 - ``tempExprefList``: `list` of data references to tempExp.
674 - ``weightList``: `list` of weightings.
675 - ``imageScalerList``: `list` of image scalers.
676 """
677 statsCtrl = afwMath.StatisticsControl()
678 statsCtrl.setNumSigmaClip(self.config.sigmaClip)
679 statsCtrl.setNumIter(self.config.clipIter)
680 statsCtrl.setAndMask(self.getBadPixelMask())
681 statsCtrl.setNanSafe(True)
682 # compute tempExpRefList: a list of tempExpRef that actually exist
683 # and weightList: a list of the weight of the associated coadd tempExp
684 # and imageScalerList: a list of scale factors for the associated coadd tempExp
685 tempExpRefList = []
686 weightList = []
687 imageScalerList = []
688 tempExpName = self.getTempExpDatasetName(self.warpType)
689 for tempExpRef in refList:
690 # Gen3's DeferredDatasetHandles are guaranteed to exist and
691 # therefore have no datasetExists() method
692 if not isinstance(tempExpRef, DeferredDatasetHandle):
693 if not tempExpRef.datasetExists(tempExpName):
694 self.log.warning("Could not find %s %s; skipping it", tempExpName, tempExpRef.dataId)
695 continue
696
697 tempExp = tempExpRef.get(datasetType=tempExpName, immediate=True)
698 # Ignore any input warp that is empty of data
699 if numpy.isnan(tempExp.image.array).all():
700 continue
701 maskedImage = tempExp.getMaskedImage()
702 imageScaler = self.scaleZeroPoint.computeImageScaler(
703 exposure=tempExp,
704 dataRef=tempExpRef,
705 )
706 try:
707 imageScaler.scaleMaskedImage(maskedImage)
708 except Exception as e:
709 self.log.warning("Scaling failed for %s (skipping it): %s", tempExpRef.dataId, e)
710 continue
711 statObj = afwMath.makeStatistics(maskedImage.getVariance(), maskedImage.getMask(),
712 afwMath.MEANCLIP, statsCtrl)
713 meanVar, meanVarErr = statObj.getResult(afwMath.MEANCLIP)
714 weight = 1.0 / float(meanVar)
715 if not numpy.isfinite(weight):
716 self.log.warning("Non-finite weight for %s: skipping", tempExpRef.dataId)
717 continue
718 self.log.info("Weight of %s %s = %0.3f", tempExpName, tempExpRef.dataId, weight)
719
720 del maskedImage
721 del tempExp
722
723 tempExpRefList.append(tempExpRef)
724 weightList.append(weight)
725 imageScalerList.append(imageScaler)
726
727 return pipeBase.Struct(tempExpRefList=tempExpRefList, weightList=weightList,
728 imageScalerList=imageScalerList)
729
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition: Statistics.h:359
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.
def prepareInputs(self, refList)

◆ prepareStats()

def lsst.pipe.tasks.assembleCoadd.prepareStats (   self,
  mask = None 
)
Prepare the statistics for coadding images.

Parameters
----------
mask : `int`, optional
    Bit mask value to exclude from coaddition.

Returns
-------
stats : `lsst.pipe.base.Struct`
    Statistics structure with the following fields:

    - ``statsCtrl``: Statistics control object for coadd
        (`lsst.afw.math.StatisticsControl`)
    - ``statsFlags``: Statistic for coadd (`lsst.afw.math.Property`)

Definition at line 730 of file assembleCoadd.py.

730 def prepareStats(self, mask=None):
731 """Prepare the statistics for coadding images.
732
733 Parameters
734 ----------
735 mask : `int`, optional
736 Bit mask value to exclude from coaddition.
737
738 Returns
739 -------
740 stats : `lsst.pipe.base.Struct`
741 Statistics structure with the following fields:
742
743 - ``statsCtrl``: Statistics control object for coadd
745 - ``statsFlags``: Statistic for coadd (`lsst.afw.math.Property`)
746 """
747 if mask is None:
748 mask = self.getBadPixelMask()
749 statsCtrl = afwMath.StatisticsControl()
750 statsCtrl.setNumSigmaClip(self.config.sigmaClip)
751 statsCtrl.setNumIter(self.config.clipIter)
752 statsCtrl.setAndMask(mask)
753 statsCtrl.setNanSafe(True)
754 statsCtrl.setWeighted(True)
755 statsCtrl.setCalcErrorFromInputVariance(self.config.calcErrorFromInputVariance)
756 for plane, threshold in self.config.maskPropagationThresholds.items():
757 bit = afwImage.Mask.getMaskPlane(plane)
758 statsCtrl.setMaskPropagationThreshold(bit, threshold)
759 statsFlags = afwMath.stringToStatisticsProperty(self.config.statistic)
760 return pipeBase.Struct(ctrl=statsCtrl, flags=statsFlags)
761
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
Definition: Statistics.cc:738
def prepareStats(self, mask=None)

◆ processResults()

def lsst.pipe.tasks.assembleCoadd.processResults (   self,
  coaddExposure,
  brightObjectMasks = None,
  dataId = None 
)
Interpolate over missing data and mask bright stars.

Parameters
----------
coaddExposure : `lsst.afw.image.Exposure`
    The coadded exposure to process.
dataRef : `lsst.daf.persistence.ButlerDataRef`
    Butler data reference for supplementary data.

Definition at line 568 of file assembleCoadd.py.

568 def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None):
569 """Interpolate over missing data and mask bright stars.
570
571 Parameters
572 ----------
573 coaddExposure : `lsst.afw.image.Exposure`
574 The coadded exposure to process.
576 Butler data reference for supplementary data.
577 """
578 if self.config.doInterp:
579 self.interpImage.run(coaddExposure.getMaskedImage(), planeName="NO_DATA")
580 # The variance must be positive; work around for DM-3201.
581 varArray = coaddExposure.variance.array
582 with numpy.errstate(invalid="ignore"):
583 varArray[:] = numpy.where(varArray > 0, varArray, numpy.inf)
584
585 if self.config.doMaskBrightObjects:
586 self.setBrightObjectMasks(coaddExposure, brightObjectMasks, dataId)
587
def run(self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=None)
def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None)

◆ readBrightObjectMasks()

def lsst.pipe.tasks.assembleCoadd.readBrightObjectMasks (   self,
  dataRef 
)
Retrieve the bright object masks.

Returns None on failure.

Parameters
----------
dataRef : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
    A Butler dataRef.

Returns
-------
result : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
    Bright object mask from the Butler object, or None if it cannot
    be retrieved.

Definition at line 1190 of file assembleCoadd.py.

1190 def readBrightObjectMasks(self, dataRef):
1191 """Retrieve the bright object masks.
1192
1193 Returns None on failure.
1194
1195 Parameters
1196 ----------
1198 A Butler dataRef.
1199
1200 Returns
1201 -------
1203 Bright object mask from the Butler object, or None if it cannot
1204 be retrieved.
1205 """
1206 try:
1207 return dataRef.get(datasetType="brightObjectMask", immediate=True)
1208 except Exception as e:
1209 self.log.warning("Unable to read brightObjectMask for %s: %s", dataRef.dataId, e)
1210 return None
1211
def readBrightObjectMasks(self, dataRef)

◆ removeMaskPlanes()

def lsst.pipe.tasks.assembleCoadd.removeMaskPlanes (   self,
  maskedImage 
)
Unset the mask of an image for mask planes specified in the config.

Parameters
----------
maskedImage : `lsst.afw.image.MaskedImage`
    The masked image to be modified.

Definition at line 1091 of file assembleCoadd.py.

1091 def removeMaskPlanes(self, maskedImage):
1092 """Unset the mask of an image for mask planes specified in the config.
1093
1094 Parameters
1095 ----------
1096 maskedImage : `lsst.afw.image.MaskedImage`
1097 The masked image to be modified.
1098 """
1099 mask = maskedImage.getMask()
1100 for maskPlane in self.config.removeMaskPlanes:
1101 try:
1102 mask &= ~mask.getPlaneBitMask(maskPlane)
1104 self.log.debug("Unable to remove mask plane %s: no mask plane with that name was found.",
1105 maskPlane)
1106
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:73
Reports invalid arguments.
Definition: Runtime.h:66
def removeMaskPlanes(self, maskedImage)

◆ run()

def lsst.pipe.tasks.assembleCoadd.run (   self,
  skyInfo,
  tempExpRefList,
  imageScalerList,
  weightList,
  altMaskList = None,
  mask = None,
  supplementaryData = None 
)
Assemble a coadd from input warps

Assemble the coadd using the provided list of coaddTempExps. Since
the full coadd covers a patch (a large area), the assembly is
performed over small areas on the image at a time in order to
conserve memory usage. Iterate over subregions within the outer
bbox of the patch using `assembleSubregion` to stack the corresponding
subregions from the coaddTempExps with the statistic specified.
Set the edge bits the coadd mask based on the weight map.

Parameters
----------
skyInfo : `lsst.pipe.base.Struct`
    Struct with geometric information about the patch.
tempExpRefList : `list`
    List of data references to Warps (previously called CoaddTempExps).
imageScalerList : `list`
    List of image scalers.
weightList : `list`
    List of weights
altMaskList : `list`, optional
    List of alternate masks to use rather than those stored with
    tempExp.
mask : `int`, optional
    Bit mask value to exclude from coaddition.
supplementaryData : lsst.pipe.base.Struct, optional
    Struct with additional data products needed to assemble coadd.
    Only used by subclasses that implement `makeSupplementaryData`
    and override `run`.

Returns
-------
result : `lsst.pipe.base.Struct`
   Result struct with components:

   - ``coaddExposure``: coadded exposure (``lsst.afw.image.Exposure``).
   - ``nImage``: exposure count image (``lsst.afw.image.Image``), if requested.
   - ``inputMap``: bit-wise map of inputs, if requested.
   - ``warpRefList``: input list of refs to the warps (
                      ``lsst.daf.butler.DeferredDatasetHandle`` or
                      ``lsst.daf.persistence.ButlerDataRef``)
                      (unmodified)
   - ``imageScalerList``: input list of image scalers (unmodified)
   - ``weightList``: input list of weights (unmodified)

Definition at line 763 of file assembleCoadd.py.

764 altMaskList=None, mask=None, supplementaryData=None):
765 """Assemble a coadd from input warps
766
767 Assemble the coadd using the provided list of coaddTempExps. Since
768 the full coadd covers a patch (a large area), the assembly is
769 performed over small areas on the image at a time in order to
770 conserve memory usage. Iterate over subregions within the outer
771 bbox of the patch using `assembleSubregion` to stack the corresponding
772 subregions from the coaddTempExps with the statistic specified.
773 Set the edge bits the coadd mask based on the weight map.
774
775 Parameters
776 ----------
777 skyInfo : `lsst.pipe.base.Struct`
778 Struct with geometric information about the patch.
779 tempExpRefList : `list`
780 List of data references to Warps (previously called CoaddTempExps).
781 imageScalerList : `list`
782 List of image scalers.
783 weightList : `list`
784 List of weights
785 altMaskList : `list`, optional
786 List of alternate masks to use rather than those stored with
787 tempExp.
788 mask : `int`, optional
789 Bit mask value to exclude from coaddition.
790 supplementaryData : lsst.pipe.base.Struct, optional
791 Struct with additional data products needed to assemble coadd.
792 Only used by subclasses that implement `makeSupplementaryData`
793 and override `run`.
794
795 Returns
796 -------
797 result : `lsst.pipe.base.Struct`
798 Result struct with components:
799
800 - ``coaddExposure``: coadded exposure (``lsst.afw.image.Exposure``).
801 - ``nImage``: exposure count image (``lsst.afw.image.Image``), if requested.
802 - ``inputMap``: bit-wise map of inputs, if requested.
803 - ``warpRefList``: input list of refs to the warps (
804 ``lsst.daf.butler.DeferredDatasetHandle`` or
806 (unmodified)
807 - ``imageScalerList``: input list of image scalers (unmodified)
808 - ``weightList``: input list of weights (unmodified)
809 """
810 tempExpName = self.getTempExpDatasetName(self.warpType)
811 self.log.info("Assembling %s %s", len(tempExpRefList), tempExpName)
812 stats = self.prepareStats(mask=mask)
813
814 if altMaskList is None:
815 altMaskList = [None]*len(tempExpRefList)
816
817 coaddExposure = afwImage.ExposureF(skyInfo.bbox, skyInfo.wcs)
818 coaddExposure.setPhotoCalib(self.scaleZeroPoint.getPhotoCalib())
819 coaddExposure.getInfo().setCoaddInputs(self.inputRecorder.makeCoaddInputs())
820 self.assembleMetadata(coaddExposure, tempExpRefList, weightList)
821 coaddMaskedImage = coaddExposure.getMaskedImage()
822 subregionSizeArr = self.config.subregionSize
823 subregionSize = geom.Extent2I(subregionSizeArr[0], subregionSizeArr[1])
824 # if nImage is requested, create a zero one which can be passed to assembleSubregion
825 if self.config.doNImage:
826 nImage = afwImage.ImageU(skyInfo.bbox)
827 else:
828 nImage = None
829 # If inputMap is requested, create the initial version that can be masked in
830 # assembleSubregion.
831 if self.config.doInputMap:
832 self.inputMapper.build_ccd_input_map(skyInfo.bbox,
833 skyInfo.wcs,
834 coaddExposure.getInfo().getCoaddInputs().ccds)
835
836 if self.config.doOnlineForMean and self.config.statistic == "MEAN":
837 try:
838 self.assembleOnlineMeanCoadd(coaddExposure, tempExpRefList, imageScalerList,
839 weightList, altMaskList, stats.ctrl,
840 nImage=nImage)
841 except Exception as e:
842 self.log.exception("Cannot compute online coadd %s", e)
843 raise
844 else:
845 for subBBox in self._subBBoxIter(skyInfo.bbox, subregionSize):
846 try:
847 self.assembleSubregion(coaddExposure, subBBox, tempExpRefList, imageScalerList,
848 weightList, altMaskList, stats.flags, stats.ctrl,
849 nImage=nImage)
850 except Exception as e:
851 self.log.exception("Cannot compute coadd %s: %s", subBBox, e)
852 raise
853
854 # If inputMap is requested, we must finalize the map after the accumulation.
855 if self.config.doInputMap:
856 self.inputMapper.finalize_ccd_input_map_mask()
857 inputMap = self.inputMapper.ccd_input_map
858 else:
859 inputMap = None
860
861 self.setInexactPsf(coaddMaskedImage.getMask())
862 # Despite the name, the following doesn't really deal with "EDGE" pixels: it identifies
863 # pixels that didn't receive any unmasked inputs (as occurs around the edge of the field).
864 coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), coaddMaskedImage.getVariance())
865 return pipeBase.Struct(coaddExposure=coaddExposure, nImage=nImage,
866 warpRefList=tempExpRefList, imageScalerList=imageScalerList,
867 weightList=weightList, inputMap=inputMap)
868
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
void setCoaddEdgeBits(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > &coaddMask, lsst::afw::image::Image< WeightPixelT > const &weightMap)
set edge bits of coadd mask based on weight map

◆ setBrightObjectMasks()

def lsst.pipe.tasks.assembleCoadd.setBrightObjectMasks (   self,
  exposure,
  brightObjectMasks,
  dataId = None 
)
Set the bright object masks.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
    Exposure under consideration.
dataId : `lsst.daf.persistence.dataId`
    Data identifier dict for patch.
brightObjectMasks : `lsst.afw.table`
    Table of bright objects to mask.

Definition at line 1212 of file assembleCoadd.py.

1212 def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None):
1213 """Set the bright object masks.
1214
1215 Parameters
1216 ----------
1217 exposure : `lsst.afw.image.Exposure`
1218 Exposure under consideration.
1220 Data identifier dict for patch.
1221 brightObjectMasks : `lsst.afw.table`
1222 Table of bright objects to mask.
1223 """
1224
1225 if brightObjectMasks is None:
1226 self.log.warning("Unable to apply bright object mask: none supplied")
1227 return
1228 self.log.info("Applying %d bright object masks to %s", len(brightObjectMasks), dataId)
1229 mask = exposure.getMaskedImage().getMask()
1230 wcs = exposure.getWcs()
1231 plateScale = wcs.getPixelScale().asArcseconds()
1232
1233 for rec in brightObjectMasks:
1234 center = geom.PointI(wcs.skyToPixel(rec.getCoord()))
1235 if rec["type"] == "box":
1236 assert rec["angle"] == 0.0, ("Angle != 0 for mask object %s" % rec["id"])
1237 width = rec["width"].asArcseconds()/plateScale # convert to pixels
1238 height = rec["height"].asArcseconds()/plateScale # convert to pixels
1239
1240 halfSize = geom.ExtentI(0.5*width, 0.5*height)
1241 bbox = geom.Box2I(center - halfSize, center + halfSize)
1242
1243 bbox = geom.BoxI(geom.PointI(int(center[0] - 0.5*width), int(center[1] - 0.5*height)),
1244 geom.PointI(int(center[0] + 0.5*width), int(center[1] + 0.5*height)))
1245 spans = afwGeom.SpanSet(bbox)
1246 elif rec["type"] == "circle":
1247 radius = int(rec["radius"].asArcseconds()/plateScale) # convert to pixels
1248 spans = afwGeom.SpanSet.fromShape(radius, offset=center)
1249 else:
1250 self.log.warning("Unexpected region type %s at %s", rec["type"], center)
1251 continue
1252 spans.clippedTo(mask.getBBox()).setMask(mask, self.brightObjectBitmask)
1253
A compact representation of a collection of pixels.
Definition: SpanSet.h:78
def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None)

◆ setInexactPsf()

def lsst.pipe.tasks.assembleCoadd.setInexactPsf (   self,
  mask 
)
Set INEXACT_PSF mask plane.

If any of the input images isn't represented in the coadd (due to
clipped pixels or chip gaps), the `CoaddPsf` will be inexact. Flag
these pixels.

Parameters
----------
mask : `lsst.afw.image.Mask`
    Coadded exposure's mask, modified in-place.

Definition at line 1254 of file assembleCoadd.py.

1254 def setInexactPsf(self, mask):
1255 """Set INEXACT_PSF mask plane.
1256
1257 If any of the input images isn't represented in the coadd (due to
1258 clipped pixels or chip gaps), the `CoaddPsf` will be inexact. Flag
1259 these pixels.
1260
1261 Parameters
1262 ----------
1263 mask : `lsst.afw.image.Mask`
1264 Coadded exposure's mask, modified in-place.
1265 """
1266 mask.addMaskPlane("INEXACT_PSF")
1267 inexactPsf = mask.getPlaneBitMask("INEXACT_PSF")
1268 sensorEdge = mask.getPlaneBitMask("SENSOR_EDGE") # chip edges (so PSF is discontinuous)
1269 clipped = mask.getPlaneBitMask("CLIPPED") # pixels clipped from coadd
1270 rejected = mask.getPlaneBitMask("REJECTED") # pixels rejected from coadd due to masks
1271 array = mask.getArray()
1272 selected = array & (sensorEdge | clipped | rejected) > 0
1273 array[selected] |= inexactPsf
1274

◆ shrinkValidPolygons()

def lsst.pipe.tasks.assembleCoadd.shrinkValidPolygons (   self,
  coaddInputs 
)
Shrink coaddInputs' ccds' ValidPolygons in place.

Either modify each ccd's validPolygon in place, or if CoaddInputs
does not have a validPolygon, create one from its bbox.

Parameters
----------
coaddInputs : `lsst.afw.image.coaddInputs`
    Original mask.

Definition at line 1168 of file assembleCoadd.py.

1168 def shrinkValidPolygons(self, coaddInputs):
1169 """Shrink coaddInputs' ccds' ValidPolygons in place.
1170
1171 Either modify each ccd's validPolygon in place, or if CoaddInputs
1172 does not have a validPolygon, create one from its bbox.
1173
1174 Parameters
1175 ----------
1176 coaddInputs : `lsst.afw.image.coaddInputs`
1177 Original mask.
1178
1179 """
1180 for ccd in coaddInputs.ccds:
1181 polyOrig = ccd.getValidPolygon()
1182 validPolyBBox = polyOrig.getBBox() if polyOrig else ccd.getBBox()
1183 validPolyBBox.grow(-self.config.matchingKernelSize//2)
1184 if polyOrig:
1185 validPolygon = polyOrig.intersectionSingle(validPolyBBox)
1186 else:
1187 validPolygon = afwGeom.polygon.Polygon(geom.Box2D(validPolyBBox))
1188 ccd.setValidPolygon(validPolygon)
1189
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
def shrinkValidPolygons(self, coaddInputs)

Variable Documentation

◆ brightObjects

lsst.pipe.tasks.assembleCoadd.brightObjects

Definition at line 553 of file assembleCoadd.py.

◆ calExpRefList

lsst.pipe.tasks.assembleCoadd.calExpRefList

Definition at line 533 of file assembleCoadd.py.

◆ ccd

lsst.pipe.tasks.assembleCoadd.ccd

Definition at line 382 of file assembleCoadd.py.

◆ coaddDatasetName

lsst.pipe.tasks.assembleCoadd.coaddDatasetName

Definition at line 558 of file assembleCoadd.py.

◆ filter

lsst.pipe.tasks.assembleCoadd.filter

Definition at line 381 of file assembleCoadd.py.

◆ id

lsst.pipe.tasks.assembleCoadd.id
warpType = pexConfig.Field(
    doc="Warp name: one of 'direct' or 'psfMatched'",
    dtype=str,
    default="direct",
)
subregionSize = pexConfig.ListField(
    dtype=int,
    doc="Width, height of stack subregion size; "
    "make small enough that a full stack of images will fit into memory at once.",
    length=2,
    default=(2000, 2000),
)
statistic = pexConfig.Field(
    dtype=str,
    doc="Main stacking statistic for aggregating over the epochs.",
    default="MEANCLIP",
)
doOnlineForMean = pexConfig.Field(
    dtype=bool,
    doc="Perform online coaddition when statistic=\"MEAN\" to save memory?",
    default=False,
)
doSigmaClip = pexConfig.Field(
    dtype=bool,
    doc="Perform sigma clipped outlier rejection with MEANCLIP statistic? (DEPRECATED)",
    default=False,
)
sigmaClip = pexConfig.Field(
    dtype=float,
    doc="Sigma for outlier rejection; ignored if non-clipping statistic selected.",
    default=3.0,
)
clipIter = pexConfig.Field(
    dtype=int,
    doc="Number of iterations of outlier rejection; ignored if non-clipping statistic selected.",
    default=2,
)
calcErrorFromInputVariance = pexConfig.Field(
    dtype=bool,
    doc="Calculate coadd variance from input variance by stacking statistic."
        "Passed to StatisticsControl.setCalcErrorFromInputVariance()",
    default=True,
)
scaleZeroPoint = pexConfig.ConfigurableField(
    target=ScaleZeroPointTask,
    doc="Task to adjust the photometric zero point of the coadd temp exposures",
)
doInterp = pexConfig.Field(
    doc="Interpolate over NaN pixels? Also extrapolate, if necessary, but the results are ugly.",
    dtype=bool,
    default=True,
)
interpImage = pexConfig.ConfigurableField(
    target=InterpImageTask,
    doc="Task to interpolate (and extrapolate) over NaN pixels",
)
doWrite = pexConfig.Field(
    doc="Persist coadd?",
    dtype=bool,
    default=True,
)
doNImage = pexConfig.Field(
    doc="Create image of number of contributing exposures for each pixel",
    dtype=bool,
    default=False,
)
doUsePsfMatchedPolygons = pexConfig.Field(
    doc="Use ValidPolygons from shrunk Psf-Matched Calexps? Should be set to True by CompareWarp only.",
    dtype=bool,
    default=False,
)
maskPropagationThresholds = pexConfig.DictField(
    keytype=str,
    itemtype=float,
    doc=("Threshold (in fractional weight) of rejection at which we propagate a mask plane to "
         "the coadd; that is, we set the mask bit on the coadd if the fraction the rejected frames "
         "would have contributed exceeds this value."),
    default={"SAT": 0.1},
)
removeMaskPlanes = pexConfig.ListField(dtype=str, default=["NOT_DEBLENDED"],
                                       doc="Mask planes to remove before coadding")
doMaskBrightObjects = pexConfig.Field(dtype=bool, default=False,
                                      doc="Set mask and flag bits for bright objects?")
brightObjectMaskName = pexConfig.Field(dtype=str, default="BRIGHT_OBJECT",
                                       doc="Name of mask bit used for bright objects")
coaddPsf = pexConfig.ConfigField(
    doc="Configuration for CoaddPsf",
    dtype=measAlg.CoaddPsfConfig,
)
doAttachTransmissionCurve = pexConfig.Field(
    dtype=bool, default=False, optional=False,
    doc=("Attach a piecewise TransmissionCurve for the coadd? "
         "(requires all input Exposures to have TransmissionCurves).")
)
hasFakes = pexConfig.Field(
    dtype=bool,
    default=False,
    doc="Should be set to True if fake sources have been inserted into the input data."
)
doSelectVisits = pexConfig.Field(
    doc="Coadd only visits selected by a SelectVisitsTask",
    dtype=bool,
    default=False,
)
doInputMap = pexConfig.Field(
    doc="Create a bitwise map of coadd inputs",
    dtype=bool,
    default=False,
)
inputMapper = pexConfig.ConfigurableField(
    doc="Input map creation subtask.",
    target=HealSparseInputMapTask,
)

def setDefaults(self):
    super().setDefaults()
    self.badMaskPlanes = ["NO_DATA", "BAD", "SAT", "EDGE"]

def validate(self):
    super().validate()
    if self.doPsfMatch:
        # Backwards compatibility.
        # Configs do not have loggers
        log.warning("Config doPsfMatch deprecated. Setting warpType='psfMatched'")
        self.warpType = 'psfMatched'
    if self.doSigmaClip and self.statistic != "MEANCLIP":
        log.warning('doSigmaClip deprecated. To replicate behavior, setting statistic to "MEANCLIP"')
        self.statistic = "MEANCLIP"
    if self.doInterp and self.statistic not in ['MEAN', 'MEDIAN', 'MEANCLIP', 'VARIANCE', 'VARIANCECLIP']:
        raise ValueError("Must set doInterp=False for statistic=%s, which does not "
                         "compute and set a non-zero coadd variance estimate." % (self.statistic))

    unstackableStats = ['NOTHING', 'ERROR', 'ORMASK']
    if not hasattr(afwMath.Property, self.statistic) or self.statistic in unstackableStats:
        stackableStats = [str(k) for k in afwMath.Property.__members__.keys()
                          if str(k) not in unstackableStats]
        raise ValueError("statistic %s is not allowed. Please choose one of %s."
                         % (self.statistic, stackableStats))


class AssembleCoaddTask(CoaddBaseTask, pipeBase.PipelineTask):

Definition at line 343 of file assembleCoadd.py.

◆ inputData

lsst.pipe.tasks.assembleCoadd.inputData

Definition at line 541 of file assembleCoadd.py.

◆ KEY

lsst.pipe.tasks.assembleCoadd.KEY

Definition at line 343 of file assembleCoadd.py.

◆ log

lsst.pipe.tasks.assembleCoadd.log = logging.getLogger(__name__)

Definition at line 55 of file assembleCoadd.py.

◆ patch

lsst.pipe.tasks.assembleCoadd.patch

Definition at line 381 of file assembleCoadd.py.

◆ retStruct

lsst.pipe.tasks.assembleCoadd.retStruct

Definition at line 550 of file assembleCoadd.py.

◆ skyInfo

lsst.pipe.tasks.assembleCoadd.skyInfo
ConfigClass = AssembleCoaddConfig
_DefaultName = "assembleCoadd"

def __init__(self, *args, **kwargs):
    # TODO: DM-17415 better way to handle previously allowed passed args e.g.`AssembleCoaddTask(config)`
    if args:
        argNames = ["config", "name", "parentTask", "log"]
        kwargs.update({k: v for k, v in zip(argNames, args)})
        warnings.warn("AssembleCoadd received positional args, and casting them as kwargs: %s. "
                      "PipelineTask will not take positional args" % argNames, FutureWarning)

    super().__init__(**kwargs)
    self.makeSubtask("interpImage")
    self.makeSubtask("scaleZeroPoint")

    if self.config.doMaskBrightObjects:
        mask = afwImage.Mask()
        try:
            self.brightObjectBitmask = 1 << mask.addMaskPlane(self.config.brightObjectMaskName)
        except pexExceptions.LsstCppException:
            raise RuntimeError("Unable to define mask plane for bright objects; planes used are %s" %
                               mask.getMaskPlaneDict().keys())
        del mask

    if self.config.doInputMap:
        self.makeSubtask("inputMapper")

    self.warpType = self.config.warpType

@utils.inheritDoc(pipeBase.PipelineTask)
def runQuantum(self, butlerQC, inputRefs, outputRefs):
    # Docstring to be formatted with info from PipelineTask.runQuantum
inputData = butlerQC.get(inputRefs)

# Construct skyInfo expected by run
# Do not remove skyMap from inputData in case makeSupplementaryDataGen3 needs it
skyMap = inputData["skyMap"]
outputDataId = butlerQC.quantum.dataId

inputData['skyInfo'] = makeSkyInfo(skyMap,
                                   tractId=outputDataId['tract'],
                                   patchId=outputDataId['patch'])

if self.config.doSelectVisits:
    warpRefList = self.filterWarps(inputData['inputWarps'], inputData['selectedVisits'])
else:
    warpRefList = inputData['inputWarps']

# Perform same middle steps as `runDataRef` does
inputs = self.prepareInputs(warpRefList)
self.log.info("Found %d %s", len(inputs.tempExpRefList),
              self.getTempExpDatasetName(self.warpType))
if len(inputs.tempExpRefList) == 0:
    raise pipeBase.NoWorkFound("No coadd temporary exposures found")

supplementaryData = self.makeSupplementaryDataGen3(butlerQC, inputRefs, outputRefs)
retStruct = self.run(inputData['skyInfo'], inputs.tempExpRefList, inputs.imageScalerList,
                     inputs.weightList, supplementaryData=supplementaryData)

inputData.setdefault('brightObjectMask', None)
self.processResults(retStruct.coaddExposure, inputData['brightObjectMask'], outputDataId)

if self.config.doWrite:
    butlerQC.put(retStruct, outputRefs)
return retStruct

@timeMethod
def runDataRef(self, dataRef, selectDataList=None, warpRefList=None):

Definition at line 531 of file assembleCoadd.py.

◆ supplementaryData

lsst.pipe.tasks.assembleCoadd.supplementaryData

Definition at line 548 of file assembleCoadd.py.

◆ tract

lsst.pipe.tasks.assembleCoadd.tract

Definition at line 381 of file assembleCoadd.py.

◆ visit

lsst.pipe.tasks.assembleCoadd.visit

Definition at line 382 of file assembleCoadd.py.

◆ warpRefList

lsst.pipe.tasks.assembleCoadd.warpRefList

Definition at line 539 of file assembleCoadd.py.

◆ warpType

lsst.pipe.tasks.assembleCoadd.warpType

Definition at line 914 of file assembleCoadd.py.