LSSTApplications  18.0.0+56,19.0.0+1,19.0.0+18,19.0.0+19,19.0.0+21,19.0.0+26,19.0.0+5,19.0.0-1-g20d9b18+12,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+12,19.0.0-1-g6fe20d0+4,19.0.0-1-g8c57eb9+12,19.0.0-1-ga72da6b,19.0.0-1-gbfe0924+3,19.0.0-1-gdc0e4a7+17,19.0.0-1-ge272bc4+12,19.0.0-1-ge3aa853+3,19.0.0-16-g3a790c8c,19.0.0-18-g955d782+1,19.0.0-2-g0d9f9cd+19,19.0.0-2-g260436e+3,19.0.0-2-g9b11441+6,19.0.0-2-gd955cfd+25,19.0.0-3-g6513920+3,19.0.0-3-gc4f6e04+2,19.0.0-4-g41ffa1d+5,19.0.0-4-g725f80e+21,19.0.0-5-g0745e3f+3,19.0.0-6-g5a632bb5+1,19.0.0-6-gb6b8b0a+3,19.0.0-7-g686a884,19.0.0-7-gea0a0fe+8,19.0.0-9-gd2f60f3c3,w.2020.03
LSSTDataManagementBasePackage
Classes | Functions | Variables
lsst.pipe.tasks.assembleCoadd Namespace Reference

Classes

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

Functions

def processResults (self, coaddExposure, brightObjectMasks=None, dataId=None)
 
def makeSupplementaryData (self, dataRef, selectDataList=None, warpRefList=None)
 
def makeSupplementaryDataGen3 (self, butlerQC, inputRefs, outputRefs)
 
def getTempExpRefList (self, patchRef, calExpRefList)
 
def prepareInputs (self, refList)
 
def prepareStats (self, mask=None)
 
def run (self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=None)
 
def assembleMetadata (self, coaddExposure, tempExpRefList, weightList)
 
def assembleSubregion (self, coaddExposure, bbox, tempExpRefList, imageScalerList, weightList, altMaskList, statsFlags, statsCtrl, nImage=None)
 
def 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 countMaskFromFootprint (mask, footprint, bitmask, ignoreMask)
 
def reorderAndPadList (inputList, inputKeys, outputKeys, padWith=None)
 

Variables

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

976  def applyAltMaskPlanes(self, mask, altMaskSpans):
977  """Apply in place alt mask formatted as SpanSets to a mask.
978 
979  Parameters
980  ----------
981  mask : `lsst.afw.image.Mask`
982  Original mask.
983  altMaskSpans : `dict`
984  SpanSet lists to apply. Each element contains the new mask
985  plane name (e.g. "CLIPPED and/or "NO_DATA") as the key,
986  and list of SpanSets to apply to the mask.
987 
988  Returns
989  -------
990  mask : `lsst.afw.image.Mask`
991  Updated mask.
992  """
993  if self.config.doUsePsfMatchedPolygons:
994  if ("NO_DATA" in altMaskSpans) and ("NO_DATA" in self.config.badMaskPlanes):
995  # Clear away any other masks outside the validPolygons. These pixels are no longer
996  # contributing to inexact PSFs, and will still be rejected because of NO_DATA
997  # self.config.doUsePsfMatchedPolygons should be True only in CompareWarpAssemble
998  # This mask-clearing step must only occur *before* applying the new masks below
999  for spanSet in altMaskSpans['NO_DATA']:
1000  spanSet.clippedTo(mask.getBBox()).clearMask(mask, self.getBadPixelMask())
1001 
1002  for plane, spanSetList in altMaskSpans.items():
1003  maskClipValue = mask.addMaskPlane(plane)
1004  for spanSet in spanSetList:
1005  spanSet.clippedTo(mask.getBBox()).setMask(mask, 2**maskClipValue)
1006  return mask
1007 
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 793 of file assembleCoadd.py.

793  def assembleMetadata(self, coaddExposure, tempExpRefList, weightList):
794  """Set the metadata for the coadd.
795 
796  This basic implementation sets the filter from the first input.
797 
798  Parameters
799  ----------
800  coaddExposure : `lsst.afw.image.Exposure`
801  The target exposure for the coadd.
802  tempExpRefList : `list`
803  List of data references to tempExp.
804  weightList : `list`
805  List of weights.
806  """
807  assert len(tempExpRefList) == len(weightList), "Length mismatch"
808  tempExpName = self.getTempExpDatasetName(self.warpType)
809  # We load a single pixel of each coaddTempExp, because we just want to get at the metadata
810  # (and we need more than just the PropertySet that contains the header), which is not possible
811  # with the current butler (see #2777).
812  bbox = geom.Box2I(coaddExposure.getBBox().getMin(), geom.Extent2I(1, 1))
813 
814  if isinstance(tempExpRefList[0], DeferredDatasetHandle):
815  # Gen 3 API
816  tempExpList = [tempExpRef.get(parameters={'bbox': bbox}) for tempExpRef in tempExpRefList]
817  else:
818  # Gen 2 API. Delete this when Gen 2 retired
819  tempExpList = [tempExpRef.get(tempExpName + "_sub", bbox=bbox, immediate=True)
820  for tempExpRef in tempExpRefList]
821  numCcds = sum(len(tempExp.getInfo().getCoaddInputs().ccds) for tempExp in tempExpList)
822 
823  coaddExposure.setFilter(tempExpList[0].getFilter())
824  coaddInputs = coaddExposure.getInfo().getCoaddInputs()
825  coaddInputs.ccds.reserve(numCcds)
826  coaddInputs.visits.reserve(len(tempExpList))
827 
828  for tempExp, weight in zip(tempExpList, weightList):
829  self.inputRecorder.addVisitToCoadd(coaddInputs, tempExp, weight)
830 
831  if self.config.doUsePsfMatchedPolygons:
832  self.shrinkValidPolygons(coaddInputs)
833 
834  coaddInputs.visits.sort()
835  if self.warpType == "psfMatched":
836  # The modelPsf BBox for a psfMatchedWarp/coaddTempExp was dynamically defined by
837  # ModelPsfMatchTask as the square box bounding its spatially-variable, pre-matched WarpedPsf.
838  # Likewise, set the PSF of a PSF-Matched Coadd to the modelPsf
839  # having the maximum width (sufficient because square)
840  modelPsfList = [tempExp.getPsf() for tempExp in tempExpList]
841  modelPsfWidthList = [modelPsf.computeBBox().getWidth() for modelPsf in modelPsfList]
842  psf = modelPsfList[modelPsfWidthList.index(max(modelPsfWidthList))]
843  else:
844  psf = measAlg.CoaddPsf(coaddInputs.ccds, coaddExposure.getWcs(),
845  self.config.coaddPsf.makeControl())
846  coaddExposure.setPsf(psf)
847  apCorrMap = measAlg.makeCoaddApCorrMap(coaddInputs.ccds, coaddExposure.getBBox(afwImage.PARENT),
848  coaddExposure.getWcs())
849  coaddExposure.getInfo().setApCorrMap(apCorrMap)
850  if self.config.doAttachTransmissionCurve:
851  transmissionCurve = measAlg.makeCoaddTransmissionCurve(coaddExposure.getWcs(), coaddInputs.ccds)
852  coaddExposure.getInfo().setTransmissionCurve(transmissionCurve)
853 
int max
An integer coordinate rectangle.
Definition: Box.h:55
def assembleMetadata(self, coaddExposure, tempExpRefList, weightList)

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

855  altMaskList, statsFlags, statsCtrl, nImage=None):
856  """Assemble the coadd for a sub-region.
857 
858  For each coaddTempExp, check for (and swap in) an alternative mask
859  if one is passed. Remove mask planes listed in
860  `config.removeMaskPlanes`. Finally, stack the actual exposures using
861  `lsst.afw.math.statisticsStack` with the statistic specified by
862  statsFlags. Typically, the statsFlag will be one of lsst.afw.math.MEAN for
863  a mean-stack or `lsst.afw.math.MEANCLIP` for outlier rejection using
864  an N-sigma clipped mean where N and iterations are specified by
865  statsCtrl. Assign the stacked subregion back to the coadd.
866 
867  Parameters
868  ----------
869  coaddExposure : `lsst.afw.image.Exposure`
870  The target exposure for the coadd.
871  bbox : `lsst.geom.Box`
872  Sub-region to coadd.
873  tempExpRefList : `list`
874  List of data reference to tempExp.
875  imageScalerList : `list`
876  List of image scalers.
877  weightList : `list`
878  List of weights.
879  altMaskList : `list`
880  List of alternate masks to use rather than those stored with
881  tempExp, or None. Each element is dict with keys = mask plane
882  name to which to add the spans.
883  statsFlags : `lsst.afw.math.Property`
884  Property object for statistic for coadd.
885  statsCtrl : `lsst.afw.math.StatisticsControl`
886  Statistics control object for coadd.
887  nImage : `lsst.afw.image.ImageU`, optional
888  Keeps track of exposure count for each pixel.
889  """
890  self.log.debug("Computing coadd over %s", bbox)
891  tempExpName = self.getTempExpDatasetName(self.warpType)
892  coaddExposure.mask.addMaskPlane("REJECTED")
893  coaddExposure.mask.addMaskPlane("CLIPPED")
894  coaddExposure.mask.addMaskPlane("SENSOR_EDGE")
895  maskMap = self.setRejectedMaskMapping(statsCtrl)
896  clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")
897  maskedImageList = []
898  if nImage is not None:
899  subNImage = afwImage.ImageU(bbox.getWidth(), bbox.getHeight())
900  for tempExpRef, imageScaler, altMask in zip(tempExpRefList, imageScalerList, altMaskList):
901 
902  if isinstance(tempExpRef, DeferredDatasetHandle):
903  # Gen 3 API
904  exposure = tempExpRef.get(parameters={'bbox': bbox})
905  else:
906  # Gen 2 API. Delete this when Gen 2 retired
907  exposure = tempExpRef.get(tempExpName + "_sub", bbox=bbox)
908 
909  maskedImage = exposure.getMaskedImage()
910  mask = maskedImage.getMask()
911  if altMask is not None:
912  self.applyAltMaskPlanes(mask, altMask)
913  imageScaler.scaleMaskedImage(maskedImage)
914 
915  # Add 1 for each pixel which is not excluded by the exclude mask.
916  # In legacyCoadd, pixels may also be excluded by afwMath.statisticsStack.
917  if nImage is not None:
918  subNImage.getArray()[maskedImage.getMask().getArray() & statsCtrl.getAndMask() == 0] += 1
919  if self.config.removeMaskPlanes:
920  self.removeMaskPlanes(maskedImage)
921  maskedImageList.append(maskedImage)
922 
923  with self.timer("stack"):
924  coaddSubregion = afwMath.statisticsStack(maskedImageList, statsFlags, statsCtrl, weightList,
925  clipped, # also set output to CLIPPED if sigma-clipped
926  maskMap)
927  coaddExposure.maskedImage.assign(coaddSubregion, bbox)
928  if nImage is not None:
929  nImage.assign(subNImage, bbox)
930 
std::shared_ptr< image::MaskedImage< PixelT > > statisticsStack(image::MaskedImage< PixelT > const &image, Property flags, char dimension, StatisticsControl const &sctrl)
A function to compute statistics on the rows or columns of an image.
Definition: Stack.cc:478

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

1190 def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask):
1191  """Function to count the number of pixels with a specific mask in a
1192  footprint.
1193 
1194  Find the intersection of mask & footprint. Count all pixels in the mask
1195  that are in the intersection that have bitmask set but do not have
1196  ignoreMask set. Return the count.
1197 
1198  Parameters
1199  ----------
1200  mask : `lsst.afw.image.Mask`
1201  Mask to define intersection region by.
1202  footprint : `lsst.afw.detection.Footprint`
1203  Footprint to define the intersection region by.
1204  bitmask
1205  Specific mask that we wish to count the number of occurances of.
1206  ignoreMask
1207  Pixels to not consider.
1208 
1209  Returns
1210  -------
1211  result : `int`
1212  Count of number of pixels in footprint with specified mask.
1213  """
1214  bbox = footprint.getBBox()
1215  bbox.clip(mask.getBBox(afwImage.PARENT))
1216  fp = afwImage.Mask(bbox)
1217  subMask = mask.Factory(mask, bbox, afwImage.PARENT)
1218  footprint.spans.setMask(fp, bitmask)
1219  return numpy.logical_and((subMask.getArray() & fp.getArray()) > 0,
1220  (subMask.getArray() & ignoreMask) == 0).sum()
1221 
1222 
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask)

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

581  def getTempExpRefList(self, patchRef, calExpRefList):
582  """Generate list data references corresponding to warped exposures
583  that lie within the patch to be coadded.
584 
585  Parameters
586  ----------
587  patchRef : `dataRef`
588  Data reference for patch.
589  calExpRefList : `list`
590  List of data references for input calexps.
591 
592  Returns
593  -------
594  tempExpRefList : `list`
595  List of Warp/CoaddTempExp data references.
596  """
597  butler = patchRef.getButler()
598  groupData = groupPatchExposures(patchRef, calExpRefList, self.getCoaddDatasetName(self.warpType),
599  self.getTempExpDatasetName(self.warpType))
600  tempExpRefList = [getGroupDataRef(butler, self.getTempExpDatasetName(self.warpType),
601  g, groupData.keys) for
602  g in groupData.groups.keys()]
603  return tempExpRefList
604 
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 538 of file assembleCoadd.py.

538  def makeSupplementaryData(self, dataRef, selectDataList=None, warpRefList=None):
539  """Make additional inputs to run() specific to subclasses (Gen2)
540 
541  Duplicates interface of `runDataRef` method
542  Available to be implemented by subclasses only if they need the
543  coadd dataRef for performing preliminary processing before
544  assembling the coadd.
545 
546  Parameters
547  ----------
548  dataRef : `lsst.daf.persistence.ButlerDataRef`
549  Butler data reference for supplementary data.
550  selectDataList : `list` (optional)
551  Optional List of data references to Calexps.
552  warpRefList : `list` (optional)
553  Optional List of data references to Warps.
554  """
555  return pipeBase.Struct()
556 
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 557 of file assembleCoadd.py.

557  def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs):
558  """Make additional inputs to run() specific to subclasses (Gen3)
559 
560  Duplicates interface of `runQuantum` method.
561  Available to be implemented by subclasses only if they need the
562  coadd dataRef for performing preliminary processing before
563  assembling the coadd.
564 
565  Parameters
566  ----------
567  butlerQC : `lsst.pipe.base.ButlerQuantumContext`
568  Gen3 Butler object for fetching additional data products before
569  running the Task specialized for quantum being processed
570  inputRefs : `lsst.pipe.base.InputQuantizedConnection`
571  Attributes are the names of the connections describing input dataset types.
572  Values are DatasetRefs that task consumes for corresponding dataset type.
573  DataIds are guaranteed to match data objects in ``inputData``.
574  outputRefs : `lsst.pipe.base.OutputQuantizedConnection`
575  Attributes are the names of the connections describing output dataset types.
576  Values are DatasetRefs that task is to produce
577  for corresponding dataset type.
578  """
579  return pipeBase.Struct()
580 
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 605 of file assembleCoadd.py.

605  def prepareInputs(self, refList):
606  """Prepare the input warps for coaddition by measuring the weight for
607  each warp and the scaling for the photometric zero point.
608 
609  Each Warp has its own photometric zeropoint and background variance.
610  Before coadding these Warps together, compute a scale factor to
611  normalize the photometric zeropoint and compute the weight for each Warp.
612 
613  Parameters
614  ----------
615  refList : `list`
616  List of data references to tempExp
617 
618  Returns
619  -------
620  result : `lsst.pipe.base.Struct`
621  Result struct with components:
622 
623  - ``tempExprefList``: `list` of data references to tempExp.
624  - ``weightList``: `list` of weightings.
625  - ``imageScalerList``: `list` of image scalers.
626  """
627  statsCtrl = afwMath.StatisticsControl()
628  statsCtrl.setNumSigmaClip(self.config.sigmaClip)
629  statsCtrl.setNumIter(self.config.clipIter)
630  statsCtrl.setAndMask(self.getBadPixelMask())
631  statsCtrl.setNanSafe(True)
632  # compute tempExpRefList: a list of tempExpRef that actually exist
633  # and weightList: a list of the weight of the associated coadd tempExp
634  # and imageScalerList: a list of scale factors for the associated coadd tempExp
635  tempExpRefList = []
636  weightList = []
637  imageScalerList = []
638  tempExpName = self.getTempExpDatasetName(self.warpType)
639  for tempExpRef in refList:
640  # Gen3's DeferredDatasetHandles are guaranteed to exist and
641  # therefore have no datasetExists() method
642  if not isinstance(tempExpRef, DeferredDatasetHandle):
643  if not tempExpRef.datasetExists(tempExpName):
644  self.log.warn("Could not find %s %s; skipping it", tempExpName, tempExpRef.dataId)
645  continue
646 
647  tempExp = tempExpRef.get(datasetType=tempExpName, immediate=True)
648  # Ignore any input warp that is empty of data
649  if numpy.isnan(tempExp.image.array).all():
650  continue
651  maskedImage = tempExp.getMaskedImage()
652  imageScaler = self.scaleZeroPoint.computeImageScaler(
653  exposure=tempExp,
654  dataRef=tempExpRef,
655  )
656  try:
657  imageScaler.scaleMaskedImage(maskedImage)
658  except Exception as e:
659  self.log.warn("Scaling failed for %s (skipping it): %s", tempExpRef.dataId, e)
660  continue
661  statObj = afwMath.makeStatistics(maskedImage.getVariance(), maskedImage.getMask(),
662  afwMath.MEANCLIP, statsCtrl)
663  meanVar, meanVarErr = statObj.getResult(afwMath.MEANCLIP)
664  weight = 1.0 / float(meanVar)
665  if not numpy.isfinite(weight):
666  self.log.warn("Non-finite weight for %s: skipping", tempExpRef.dataId)
667  continue
668  self.log.info("Weight of %s %s = %0.3f", tempExpName, tempExpRef.dataId, weight)
669 
670  del maskedImage
671  del tempExp
672 
673  tempExpRefList.append(tempExpRef)
674  weightList.append(weight)
675  imageScalerList.append(imageScaler)
676 
677  return pipeBase.Struct(tempExpRefList=tempExpRefList, weightList=weightList,
678  imageScalerList=imageScalerList)
679 
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<>
Definition: Statistics.h:520
def prepareInputs(self, refList)
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.
Pass parameters to a Statistics object.
Definition: Statistics.h:93

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

680  def prepareStats(self, mask=None):
681  """Prepare the statistics for coadding images.
682 
683  Parameters
684  ----------
685  mask : `int`, optional
686  Bit mask value to exclude from coaddition.
687 
688  Returns
689  -------
690  stats : `lsst.pipe.base.Struct`
691  Statistics structure with the following fields:
692 
693  - ``statsCtrl``: Statistics control object for coadd
694  (`lsst.afw.math.StatisticsControl`)
695  - ``statsFlags``: Statistic for coadd (`lsst.afw.math.Property`)
696  """
697  if mask is None:
698  mask = self.getBadPixelMask()
699  statsCtrl = afwMath.StatisticsControl()
700  statsCtrl.setNumSigmaClip(self.config.sigmaClip)
701  statsCtrl.setNumIter(self.config.clipIter)
702  statsCtrl.setAndMask(mask)
703  statsCtrl.setNanSafe(True)
704  statsCtrl.setWeighted(True)
705  statsCtrl.setCalcErrorFromInputVariance(self.config.calcErrorFromInputVariance)
706  for plane, threshold in self.config.maskPropagationThresholds.items():
707  bit = afwImage.Mask.getMaskPlane(plane)
708  statsCtrl.setMaskPropagationThreshold(bit, threshold)
709  statsFlags = afwMath.stringToStatisticsProperty(self.config.statistic)
710  return pipeBase.Struct(ctrl=statsCtrl, flags=statsFlags)
711 
def prepareStats(self, mask=None)
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
Definition: Statistics.cc:747
Pass parameters to a Statistics object.
Definition: Statistics.h:93

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

518  def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None):
519  """Interpolate over missing data and mask bright stars.
520 
521  Parameters
522  ----------
523  coaddExposure : `lsst.afw.image.Exposure`
524  The coadded exposure to process.
525  dataRef : `lsst.daf.persistence.ButlerDataRef`
526  Butler data reference for supplementary data.
527  """
528  if self.config.doInterp:
529  self.interpImage.run(coaddExposure.getMaskedImage(), planeName="NO_DATA")
530  # The variance must be positive; work around for DM-3201.
531  varArray = coaddExposure.variance.array
532  with numpy.errstate(invalid="ignore"):
533  varArray[:] = numpy.where(varArray > 0, varArray, numpy.inf)
534 
535  if self.config.doMaskBrightObjects:
536  self.setBrightObjectMasks(coaddExposure, brightObjectMasks, dataId)
537 
def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None)
def run(self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=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 1030 of file assembleCoadd.py.

1030  def readBrightObjectMasks(self, dataRef):
1031  """Retrieve the bright object masks.
1032 
1033  Returns None on failure.
1034 
1035  Parameters
1036  ----------
1037  dataRef : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1038  A Butler dataRef.
1039 
1040  Returns
1041  -------
1042  result : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1043  Bright object mask from the Butler object, or None if it cannot
1044  be retrieved.
1045  """
1046  try:
1047  return dataRef.get(datasetType="brightObjectMask", immediate=True)
1048  except Exception as e:
1049  self.log.warn("Unable to read brightObjectMask for %s: %s", dataRef.dataId, e)
1050  return None
1051 
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 931 of file assembleCoadd.py.

931  def removeMaskPlanes(self, maskedImage):
932  """Unset the mask of an image for mask planes specified in the config.
933 
934  Parameters
935  ----------
936  maskedImage : `lsst.afw.image.MaskedImage`
937  The masked image to be modified.
938  """
939  mask = maskedImage.getMask()
940  for maskPlane in self.config.removeMaskPlanes:
941  try:
942  mask &= ~mask.getPlaneBitMask(maskPlane)
944  self.log.debug("Unable to remove mask plane %s: no mask plane with that name was found.",
945  maskPlane)
946 
def removeMaskPlanes(self, maskedImage)
Reports invalid arguments.
Definition: Runtime.h:66

◆ reorderAndPadList()

def lsst.pipe.tasks.assembleCoadd.reorderAndPadList (   inputList,
  inputKeys,
  outputKeys,
  padWith = None 
)
Match the order of one list to another, padding if necessary

Parameters
----------
inputList : list
    List to be reordered and padded. Elements can be any type.
inputKeys :  iterable
    Iterable of values to be compared with outputKeys.
    Length must match `inputList`
outputKeys : iterable
    Iterable of values to be compared with inputKeys.
padWith :
    Any value to be inserted where inputKey not in outputKeys

Returns
-------
list
    Copy of inputList reordered per outputKeys and padded with `padWith`
    so that the length matches length of outputKeys.

Definition at line 2404 of file assembleCoadd.py.

2404 def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None):
2405  """Match the order of one list to another, padding if necessary
2406 
2407  Parameters
2408  ----------
2409  inputList : list
2410  List to be reordered and padded. Elements can be any type.
2411  inputKeys : iterable
2412  Iterable of values to be compared with outputKeys.
2413  Length must match `inputList`
2414  outputKeys : iterable
2415  Iterable of values to be compared with inputKeys.
2416  padWith :
2417  Any value to be inserted where inputKey not in outputKeys
2418 
2419  Returns
2420  -------
2421  list
2422  Copy of inputList reordered per outputKeys and padded with `padWith`
2423  so that the length matches length of outputKeys.
2424  """
2425  outputList = []
2426  for d in outputKeys:
2427  if d in inputKeys:
2428  outputList.append(inputList[inputKeys.index(d)])
2429  else:
2430  outputList.append(padWith)
2431  return outputList
2432 
def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None)

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

713  altMaskList=None, mask=None, supplementaryData=None):
714  """Assemble a coadd from input warps
715 
716  Assemble the coadd using the provided list of coaddTempExps. Since
717  the full coadd covers a patch (a large area), the assembly is
718  performed over small areas on the image at a time in order to
719  conserve memory usage. Iterate over subregions within the outer
720  bbox of the patch using `assembleSubregion` to stack the corresponding
721  subregions from the coaddTempExps with the statistic specified.
722  Set the edge bits the coadd mask based on the weight map.
723 
724  Parameters
725  ----------
726  skyInfo : `lsst.pipe.base.Struct`
727  Struct with geometric information about the patch.
728  tempExpRefList : `list`
729  List of data references to Warps (previously called CoaddTempExps).
730  imageScalerList : `list`
731  List of image scalers.
732  weightList : `list`
733  List of weights
734  altMaskList : `list`, optional
735  List of alternate masks to use rather than those stored with
736  tempExp.
737  mask : `int`, optional
738  Bit mask value to exclude from coaddition.
739  supplementaryData : lsst.pipe.base.Struct, optional
740  Struct with additional data products needed to assemble coadd.
741  Only used by subclasses that implement `makeSupplementaryData`
742  and override `run`.
743 
744  Returns
745  -------
746  result : `lsst.pipe.base.Struct`
747  Result struct with components:
748 
749  - ``coaddExposure``: coadded exposure (``lsst.afw.image.Exposure``).
750  - ``nImage``: exposure count image (``lsst.afw.image.Image``), if requested.
751  - ``warpRefList``: input list of refs to the warps (
752  ``lsst.daf.butler.DeferredDatasetHandle`` or
753  ``lsst.daf.persistence.ButlerDataRef``)
754  (unmodified)
755  - ``imageScalerList``: input list of image scalers (unmodified)
756  - ``weightList``: input list of weights (unmodified)
757  """
758  tempExpName = self.getTempExpDatasetName(self.warpType)
759  self.log.info("Assembling %s %s", len(tempExpRefList), tempExpName)
760  stats = self.prepareStats(mask=mask)
761 
762  if altMaskList is None:
763  altMaskList = [None]*len(tempExpRefList)
764 
765  coaddExposure = afwImage.ExposureF(skyInfo.bbox, skyInfo.wcs)
766  coaddExposure.setPhotoCalib(self.scaleZeroPoint.getPhotoCalib())
767  coaddExposure.getInfo().setCoaddInputs(self.inputRecorder.makeCoaddInputs())
768  self.assembleMetadata(coaddExposure, tempExpRefList, weightList)
769  coaddMaskedImage = coaddExposure.getMaskedImage()
770  subregionSizeArr = self.config.subregionSize
771  subregionSize = geom.Extent2I(subregionSizeArr[0], subregionSizeArr[1])
772  # if nImage is requested, create a zero one which can be passed to assembleSubregion
773  if self.config.doNImage:
774  nImage = afwImage.ImageU(skyInfo.bbox)
775  else:
776  nImage = None
777  for subBBox in self._subBBoxIter(skyInfo.bbox, subregionSize):
778  try:
779  self.assembleSubregion(coaddExposure, subBBox, tempExpRefList, imageScalerList,
780  weightList, altMaskList, stats.flags, stats.ctrl,
781  nImage=nImage)
782  except Exception as e:
783  self.log.fatal("Cannot compute coadd %s: %s", subBBox, e)
784 
785  self.setInexactPsf(coaddMaskedImage.getMask())
786  # Despite the name, the following doesn't really deal with "EDGE" pixels: it identifies
787  # pixels that didn't receive any unmasked inputs (as occurs around the edge of the field).
788  coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), coaddMaskedImage.getVariance())
789  return pipeBase.Struct(coaddExposure=coaddExposure, nImage=nImage,
790  warpRefList=tempExpRefList, imageScalerList=imageScalerList,
791  weightList=weightList)
792 
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 1052 of file assembleCoadd.py.

1052  def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None):
1053  """Set the bright object masks.
1054 
1055  Parameters
1056  ----------
1057  exposure : `lsst.afw.image.Exposure`
1058  Exposure under consideration.
1059  dataId : `lsst.daf.persistence.dataId`
1060  Data identifier dict for patch.
1061  brightObjectMasks : `lsst.afw.table`
1062  Table of bright objects to mask.
1063  """
1064 
1065  if brightObjectMasks is None:
1066  self.log.warn("Unable to apply bright object mask: none supplied")
1067  return
1068  self.log.info("Applying %d bright object masks to %s", len(brightObjectMasks), dataId)
1069  mask = exposure.getMaskedImage().getMask()
1070  wcs = exposure.getWcs()
1071  plateScale = wcs.getPixelScale().asArcseconds()
1072 
1073  for rec in brightObjectMasks:
1074  center = geom.PointI(wcs.skyToPixel(rec.getCoord()))
1075  if rec["type"] == "box":
1076  assert rec["angle"] == 0.0, ("Angle != 0 for mask object %s" % rec["id"])
1077  width = rec["width"].asArcseconds()/plateScale # convert to pixels
1078  height = rec["height"].asArcseconds()/plateScale # convert to pixels
1079 
1080  halfSize = geom.ExtentI(0.5*width, 0.5*height)
1081  bbox = geom.Box2I(center - halfSize, center + halfSize)
1082 
1083  bbox = geom.BoxI(geom.PointI(int(center[0] - 0.5*width), int(center[1] - 0.5*height)),
1084  geom.PointI(int(center[0] + 0.5*width), int(center[1] + 0.5*height)))
1085  spans = afwGeom.SpanSet(bbox)
1086  elif rec["type"] == "circle":
1087  radius = int(rec["radius"].asArcseconds()/plateScale) # convert to pixels
1088  spans = afwGeom.SpanSet.fromShape(radius, offset=center)
1089  else:
1090  self.log.warn("Unexpected region type %s at %s" % rec["type"], center)
1091  continue
1092  spans.clippedTo(mask.getBBox()).setMask(mask, self.brightObjectBitmask)
1093 
def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None)
A compact representation of a collection of pixels.
Definition: SpanSet.h:77
An integer coordinate rectangle.
Definition: Box.h:55

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

1094  def setInexactPsf(self, mask):
1095  """Set INEXACT_PSF mask plane.
1096 
1097  If any of the input images isn't represented in the coadd (due to
1098  clipped pixels or chip gaps), the `CoaddPsf` will be inexact. Flag
1099  these pixels.
1100 
1101  Parameters
1102  ----------
1103  mask : `lsst.afw.image.Mask`
1104  Coadded exposure's mask, modified in-place.
1105  """
1106  mask.addMaskPlane("INEXACT_PSF")
1107  inexactPsf = mask.getPlaneBitMask("INEXACT_PSF")
1108  sensorEdge = mask.getPlaneBitMask("SENSOR_EDGE") # chip edges (so PSF is discontinuous)
1109  clipped = mask.getPlaneBitMask("CLIPPED") # pixels clipped from coadd
1110  rejected = mask.getPlaneBitMask("REJECTED") # pixels rejected from coadd due to masks
1111  array = mask.getArray()
1112  selected = array & (sensorEdge | clipped | rejected) > 0
1113  array[selected] |= inexactPsf
1114 

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

1008  def shrinkValidPolygons(self, coaddInputs):
1009  """Shrink coaddInputs' ccds' ValidPolygons in place.
1010 
1011  Either modify each ccd's validPolygon in place, or if CoaddInputs
1012  does not have a validPolygon, create one from its bbox.
1013 
1014  Parameters
1015  ----------
1016  coaddInputs : `lsst.afw.image.coaddInputs`
1017  Original mask.
1018 
1019  """
1020  for ccd in coaddInputs.ccds:
1021  polyOrig = ccd.getValidPolygon()
1022  validPolyBBox = polyOrig.getBBox() if polyOrig else ccd.getBBox()
1023  validPolyBBox.grow(-self.config.matchingKernelSize//2)
1024  if polyOrig:
1025  validPolygon = polyOrig.intersectionSingle(validPolyBBox)
1026  else:
1027  validPolygon = afwGeom.polygon.Polygon(geom.Box2D(validPolyBBox))
1028  ccd.setValidPolygon(validPolygon)
1029 
def shrinkValidPolygons(self, coaddInputs)
A floating-point coordinate rectangle geometry.
Definition: Box.h:413

Variable Documentation

◆ brightObjects

lsst.pipe.tasks.assembleCoadd.brightObjects

Definition at line 503 of file assembleCoadd.py.

◆ calExpRefList

lsst.pipe.tasks.assembleCoadd.calExpRefList

Definition at line 483 of file assembleCoadd.py.

◆ ccd

lsst.pipe.tasks.assembleCoadd.ccd

Definition at line 336 of file assembleCoadd.py.

◆ coaddDatasetName

lsst.pipe.tasks.assembleCoadd.coaddDatasetName

Definition at line 508 of file assembleCoadd.py.

◆ filter

lsst.pipe.tasks.assembleCoadd.filter

Definition at line 335 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",
)
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."
)

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.warn("Config doPsfMatch deprecated. Setting warpType='psfMatched'")
        self.warpType = 'psfMatched'
    if self.doSigmaClip and self.statistic != "MEANCLIP":
        log.warn('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 297 of file assembleCoadd.py.

◆ inputData

lsst.pipe.tasks.assembleCoadd.inputData

Definition at line 491 of file assembleCoadd.py.

◆ KEY

lsst.pipe.tasks.assembleCoadd.KEY

Definition at line 297 of file assembleCoadd.py.

◆ patch

lsst.pipe.tasks.assembleCoadd.patch

Definition at line 335 of file assembleCoadd.py.

◆ retStruct

lsst.pipe.tasks.assembleCoadd.retStruct

Definition at line 500 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

    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'])

# Construct list of input Deferred Datasets
# These quack a bit like like Gen2 DataRefs
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:
    self.log.warn("No coadd temporary exposures found")
    return

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

◆ supplementaryData

lsst.pipe.tasks.assembleCoadd.supplementaryData

Definition at line 498 of file assembleCoadd.py.

◆ tract

lsst.pipe.tasks.assembleCoadd.tract

Definition at line 335 of file assembleCoadd.py.

◆ visit

lsst.pipe.tasks.assembleCoadd.visit

Definition at line 336 of file assembleCoadd.py.

◆ warpRefList

lsst.pipe.tasks.assembleCoadd.warpRefList

Definition at line 489 of file assembleCoadd.py.

◆ warpType

lsst.pipe.tasks.assembleCoadd.warpType

Definition at line 835 of file assembleCoadd.py.