LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Classes | Functions | Variables
lsst.pipe.tasks.assembleCoadd Namespace Reference

Classes

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

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 1133 of file assembleCoadd.py.

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

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

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

◆ 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 931 of file assembleCoadd.py.

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

1369 def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask):
1370  """Function to count the number of pixels with a specific mask in a
1371  footprint.
1372 
1373  Find the intersection of mask & footprint. Count all pixels in the mask
1374  that are in the intersection that have bitmask set but do not have
1375  ignoreMask set. Return the count.
1376 
1377  Parameters
1378  ----------
1379  mask : `lsst.afw.image.Mask`
1380  Mask to define intersection region by.
1381  footprint : `lsst.afw.detection.Footprint`
1382  Footprint to define the intersection region by.
1383  bitmask
1384  Specific mask that we wish to count the number of occurances of.
1385  ignoreMask
1386  Pixels to not consider.
1387 
1388  Returns
1389  -------
1390  result : `int`
1391  Count of number of pixels in footprint with specified mask.
1392  """
1393  bbox = footprint.getBBox()
1394  bbox.clip(mask.getBBox(afwImage.PARENT))
1395  fp = afwImage.Mask(bbox)
1396  subMask = mask.Factory(mask, bbox, afwImage.PARENT)
1397  footprint.spans.setMask(fp, bitmask)
1398  return numpy.logical_and((subMask.getArray() & fp.getArray()) > 0,
1399  (subMask.getArray() & ignoreMask) == 0).sum()
1400 
1401 
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
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 1318 of file assembleCoadd.py.

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

632  def getTempExpRefList(self, patchRef, calExpRefList):
633  """Generate list data references corresponding to warped exposures
634  that lie within the patch to be coadded.
635 
636  Parameters
637  ----------
638  patchRef : `dataRef`
639  Data reference for patch.
640  calExpRefList : `list`
641  List of data references for input calexps.
642 
643  Returns
644  -------
645  tempExpRefList : `list`
646  List of Warp/CoaddTempExp data references.
647  """
648  butler = patchRef.getButler()
649  groupData = groupPatchExposures(patchRef, calExpRefList, self.getCoaddDatasetName(self.warpType),
650  self.getTempExpDatasetName(self.warpType))
651  tempExpRefList = [getGroupDataRef(butler, self.getTempExpDatasetName(self.warpType),
652  g, groupData.keys) for
653  g in groupData.groups.keys()]
654  return tempExpRefList
655 
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 589 of file assembleCoadd.py.

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

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

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

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

569  def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None):
570  """Interpolate over missing data and mask bright stars.
571 
572  Parameters
573  ----------
574  coaddExposure : `lsst.afw.image.Exposure`
575  The coadded exposure to process.
576  dataRef : `lsst.daf.persistence.ButlerDataRef`
577  Butler data reference for supplementary data.
578  """
579  if self.config.doInterp:
580  self.interpImage.run(coaddExposure.getMaskedImage(), planeName="NO_DATA")
581  # The variance must be positive; work around for DM-3201.
582  varArray = coaddExposure.variance.array
583  with numpy.errstate(invalid="ignore"):
584  varArray[:] = numpy.where(varArray > 0, varArray, numpy.inf)
585 
586  if self.config.doMaskBrightObjects:
587  self.setBrightObjectMasks(coaddExposure, brightObjectMasks, dataId)
588 
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 1187 of file assembleCoadd.py.

1187  def readBrightObjectMasks(self, dataRef):
1188  """Retrieve the bright object masks.
1189 
1190  Returns None on failure.
1191 
1192  Parameters
1193  ----------
1194  dataRef : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1195  A Butler dataRef.
1196 
1197  Returns
1198  -------
1199  result : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1200  Bright object mask from the Butler object, or None if it cannot
1201  be retrieved.
1202  """
1203  try:
1204  return dataRef.get(datasetType="brightObjectMask", immediate=True)
1205  except Exception as e:
1206  self.log.warning("Unable to read brightObjectMask for %s: %s", dataRef.dataId, e)
1207  return None
1208 
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 1088 of file assembleCoadd.py.

1088  def removeMaskPlanes(self, maskedImage):
1089  """Unset the mask of an image for mask planes specified in the config.
1090 
1091  Parameters
1092  ----------
1093  maskedImage : `lsst.afw.image.MaskedImage`
1094  The masked image to be modified.
1095  """
1096  mask = maskedImage.getMask()
1097  for maskPlane in self.config.removeMaskPlanes:
1098  try:
1099  mask &= ~mask.getPlaneBitMask(maskPlane)
1101  self.log.debug("Unable to remove mask plane %s: no mask plane with that name was found.",
1102  maskPlane)
1103 
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 764 of file assembleCoadd.py.

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

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

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

◆ 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 1165 of file assembleCoadd.py.

1165  def shrinkValidPolygons(self, coaddInputs):
1166  """Shrink coaddInputs' ccds' ValidPolygons in place.
1167 
1168  Either modify each ccd's validPolygon in place, or if CoaddInputs
1169  does not have a validPolygon, create one from its bbox.
1170 
1171  Parameters
1172  ----------
1173  coaddInputs : `lsst.afw.image.coaddInputs`
1174  Original mask.
1175 
1176  """
1177  for ccd in coaddInputs.ccds:
1178  polyOrig = ccd.getValidPolygon()
1179  validPolyBBox = polyOrig.getBBox() if polyOrig else ccd.getBBox()
1180  validPolyBBox.grow(-self.config.matchingKernelSize//2)
1181  if polyOrig:
1182  validPolygon = polyOrig.intersectionSingle(validPolyBBox)
1183  else:
1184  validPolygon = afwGeom.polygon.Polygon(geom.Box2D(validPolyBBox))
1185  ccd.setValidPolygon(validPolygon)
1186 
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 554 of file assembleCoadd.py.

◆ calExpRefList

lsst.pipe.tasks.assembleCoadd.calExpRefList

Definition at line 534 of file assembleCoadd.py.

◆ ccd

lsst.pipe.tasks.assembleCoadd.ccd

Definition at line 383 of file assembleCoadd.py.

◆ coaddDatasetName

lsst.pipe.tasks.assembleCoadd.coaddDatasetName

Definition at line 559 of file assembleCoadd.py.

◆ filter

lsst.pipe.tasks.assembleCoadd.filter

Definition at line 382 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 344 of file assembleCoadd.py.

◆ inputData

lsst.pipe.tasks.assembleCoadd.inputData

Definition at line 542 of file assembleCoadd.py.

◆ KEY

lsst.pipe.tasks.assembleCoadd.KEY

Definition at line 344 of file assembleCoadd.py.

◆ log

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

Definition at line 56 of file assembleCoadd.py.

◆ patch

lsst.pipe.tasks.assembleCoadd.patch

Definition at line 382 of file assembleCoadd.py.

◆ retStruct

lsst.pipe.tasks.assembleCoadd.retStruct

Definition at line 551 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 532 of file assembleCoadd.py.

◆ supplementaryData

lsst.pipe.tasks.assembleCoadd.supplementaryData

Definition at line 549 of file assembleCoadd.py.

◆ tract

lsst.pipe.tasks.assembleCoadd.tract

Definition at line 382 of file assembleCoadd.py.

◆ visit

lsst.pipe.tasks.assembleCoadd.visit

Definition at line 383 of file assembleCoadd.py.

◆ warpRefList

lsst.pipe.tasks.assembleCoadd.warpRefList

Definition at line 540 of file assembleCoadd.py.

◆ warpType

lsst.pipe.tasks.assembleCoadd.warpType

Definition at line 912 of file assembleCoadd.py.