LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
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__.partition(".")[2])
 
 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 1132 of file assembleCoadd.py.

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

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

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

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

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

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

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

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

1087  def removeMaskPlanes(self, maskedImage):
1088  """Unset the mask of an image for mask planes specified in the config.
1089 
1090  Parameters
1091  ----------
1092  maskedImage : `lsst.afw.image.MaskedImage`
1093  The masked image to be modified.
1094  """
1095  mask = maskedImage.getMask()
1096  for maskPlane in self.config.removeMaskPlanes:
1097  try:
1098  mask &= ~mask.getPlaneBitMask(maskPlane)
1100  self.log.debug("Unable to remove mask plane %s: no mask plane with that name was found.",
1101  maskPlane)
1102 
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
805  ``lsst.daf.persistence.ButlerDataRef``)
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.fatal("Cannot compute online coadd %s", e)
843  else:
844  for subBBox in self._subBBoxIter(skyInfo.bbox, subregionSize):
845  try:
846  self.assembleSubregion(coaddExposure, subBBox, tempExpRefList, imageScalerList,
847  weightList, altMaskList, stats.flags, stats.ctrl,
848  nImage=nImage)
849  except Exception as e:
850  self.log.fatal("Cannot compute coadd %s: %s", subBBox, e)
851 
852  # If inputMap is requested, we must finalize the map after the accumulation.
853  if self.config.doInputMap:
854  self.inputMapper.finalize_ccd_input_map_mask()
855  inputMap = self.inputMapper.ccd_input_map
856  else:
857  inputMap = None
858 
859  self.setInexactPsf(coaddMaskedImage.getMask())
860  # Despite the name, the following doesn't really deal with "EDGE" pixels: it identifies
861  # pixels that didn't receive any unmasked inputs (as occurs around the edge of the field).
862  coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), coaddMaskedImage.getVariance())
863  return pipeBase.Struct(coaddExposure=coaddExposure, nImage=nImage,
864  warpRefList=tempExpRefList, imageScalerList=imageScalerList,
865  weightList=weightList, inputMap=inputMap)
866 
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 1208 of file assembleCoadd.py.

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

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

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

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

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

@pipeBase.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 911 of file assembleCoadd.py.