LSSTApplications  19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
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 984 of file assembleCoadd.py.

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

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

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

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

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

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

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

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

588  def getTempExpRefList(self, patchRef, calExpRefList):
589  """Generate list data references corresponding to warped exposures
590  that lie within the patch to be coadded.
591 
592  Parameters
593  ----------
594  patchRef : `dataRef`
595  Data reference for patch.
596  calExpRefList : `list`
597  List of data references for input calexps.
598 
599  Returns
600  -------
601  tempExpRefList : `list`
602  List of Warp/CoaddTempExp data references.
603  """
604  butler = patchRef.getButler()
605  groupData = groupPatchExposures(patchRef, calExpRefList, self.getCoaddDatasetName(self.warpType),
606  self.getTempExpDatasetName(self.warpType))
607  tempExpRefList = [getGroupDataRef(butler, self.getTempExpDatasetName(self.warpType),
608  g, groupData.keys) for
609  g in groupData.groups.keys()]
610  return tempExpRefList
611 

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

545  def makeSupplementaryData(self, dataRef, selectDataList=None, warpRefList=None):
546  """Make additional inputs to run() specific to subclasses (Gen2)
547 
548  Duplicates interface of `runDataRef` method
549  Available to be implemented by subclasses only if they need the
550  coadd dataRef for performing preliminary processing before
551  assembling the coadd.
552 
553  Parameters
554  ----------
555  dataRef : `lsst.daf.persistence.ButlerDataRef`
556  Butler data reference for supplementary data.
557  selectDataList : `list` (optional)
558  Optional List of data references to Calexps.
559  warpRefList : `list` (optional)
560  Optional List of data references to Warps.
561  """
562  return pipeBase.Struct()
563 

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

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

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

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

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

687  def prepareStats(self, mask=None):
688  """Prepare the statistics for coadding images.
689 
690  Parameters
691  ----------
692  mask : `int`, optional
693  Bit mask value to exclude from coaddition.
694 
695  Returns
696  -------
697  stats : `lsst.pipe.base.Struct`
698  Statistics structure with the following fields:
699 
700  - ``statsCtrl``: Statistics control object for coadd
701  (`lsst.afw.math.StatisticsControl`)
702  - ``statsFlags``: Statistic for coadd (`lsst.afw.math.Property`)
703  """
704  if mask is None:
705  mask = self.getBadPixelMask()
706  statsCtrl = afwMath.StatisticsControl()
707  statsCtrl.setNumSigmaClip(self.config.sigmaClip)
708  statsCtrl.setNumIter(self.config.clipIter)
709  statsCtrl.setAndMask(mask)
710  statsCtrl.setNanSafe(True)
711  statsCtrl.setWeighted(True)
712  statsCtrl.setCalcErrorFromInputVariance(self.config.calcErrorFromInputVariance)
713  for plane, threshold in self.config.maskPropagationThresholds.items():
714  bit = afwImage.Mask.getMaskPlane(plane)
715  statsCtrl.setMaskPropagationThreshold(bit, threshold)
716  statsFlags = afwMath.stringToStatisticsProperty(self.config.statistic)
717  return pipeBase.Struct(ctrl=statsCtrl, flags=statsFlags)
718 

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

525  def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None):
526  """Interpolate over missing data and mask bright stars.
527 
528  Parameters
529  ----------
530  coaddExposure : `lsst.afw.image.Exposure`
531  The coadded exposure to process.
532  dataRef : `lsst.daf.persistence.ButlerDataRef`
533  Butler data reference for supplementary data.
534  """
535  if self.config.doInterp:
536  self.interpImage.run(coaddExposure.getMaskedImage(), planeName="NO_DATA")
537  # The variance must be positive; work around for DM-3201.
538  varArray = coaddExposure.variance.array
539  with numpy.errstate(invalid="ignore"):
540  varArray[:] = numpy.where(varArray > 0, varArray, numpy.inf)
541 
542  if self.config.doMaskBrightObjects:
543  self.setBrightObjectMasks(coaddExposure, brightObjectMasks, dataId)
544 

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

1038  def readBrightObjectMasks(self, dataRef):
1039  """Retrieve the bright object masks.
1040 
1041  Returns None on failure.
1042 
1043  Parameters
1044  ----------
1045  dataRef : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1046  A Butler dataRef.
1047 
1048  Returns
1049  -------
1050  result : `lsst.daf.persistence.butlerSubset.ButlerDataRef`
1051  Bright object mask from the Butler object, or None if it cannot
1052  be retrieved.
1053  """
1054  try:
1055  return dataRef.get(datasetType="brightObjectMask", immediate=True)
1056  except Exception as e:
1057  self.log.warn("Unable to read brightObjectMask for %s: %s", dataRef.dataId, e)
1058  return None
1059 

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

939  def removeMaskPlanes(self, maskedImage):
940  """Unset the mask of an image for mask planes specified in the config.
941 
942  Parameters
943  ----------
944  maskedImage : `lsst.afw.image.MaskedImage`
945  The masked image to be modified.
946  """
947  mask = maskedImage.getMask()
948  for maskPlane in self.config.removeMaskPlanes:
949  try:
950  mask &= ~mask.getPlaneBitMask(maskPlane)
952  self.log.debug("Unable to remove mask plane %s: no mask plane with that name was found.",
953  maskPlane)
954 

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

2445 def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None):
2446  """Match the order of one list to another, padding if necessary
2447 
2448  Parameters
2449  ----------
2450  inputList : list
2451  List to be reordered and padded. Elements can be any type.
2452  inputKeys : iterable
2453  Iterable of values to be compared with outputKeys.
2454  Length must match `inputList`
2455  outputKeys : iterable
2456  Iterable of values to be compared with inputKeys.
2457  padWith :
2458  Any value to be inserted where inputKey not in outputKeys
2459 
2460  Returns
2461  -------
2462  list
2463  Copy of inputList reordered per outputKeys and padded with `padWith`
2464  so that the length matches length of outputKeys.
2465  """
2466  outputList = []
2467  for d in outputKeys:
2468  if d in inputKeys:
2469  outputList.append(inputList[inputKeys.index(d)])
2470  else:
2471  outputList.append(padWith)
2472  return outputList

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

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

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

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

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

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

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

1016  def shrinkValidPolygons(self, coaddInputs):
1017  """Shrink coaddInputs' ccds' ValidPolygons in place.
1018 
1019  Either modify each ccd's validPolygon in place, or if CoaddInputs
1020  does not have a validPolygon, create one from its bbox.
1021 
1022  Parameters
1023  ----------
1024  coaddInputs : `lsst.afw.image.coaddInputs`
1025  Original mask.
1026 
1027  """
1028  for ccd in coaddInputs.ccds:
1029  polyOrig = ccd.getValidPolygon()
1030  validPolyBBox = polyOrig.getBBox() if polyOrig else ccd.getBBox()
1031  validPolyBBox.grow(-self.config.matchingKernelSize//2)
1032  if polyOrig:
1033  validPolygon = polyOrig.intersectionSingle(validPolyBBox)
1034  else:
1035  validPolygon = afwGeom.polygon.Polygon(geom.Box2D(validPolyBBox))
1036  ccd.setValidPolygon(validPolygon)
1037 

Variable Documentation

◆ brightObjects

lsst.pipe.tasks.assembleCoadd.brightObjects

Definition at line 510 of file assembleCoadd.py.

◆ calExpRefList

lsst.pipe.tasks.assembleCoadd.calExpRefList

Definition at line 490 of file assembleCoadd.py.

◆ ccd

lsst.pipe.tasks.assembleCoadd.ccd

Definition at line 343 of file assembleCoadd.py.

◆ coaddDatasetName

lsst.pipe.tasks.assembleCoadd.coaddDatasetName

Definition at line 515 of file assembleCoadd.py.

◆ filter

lsst.pipe.tasks.assembleCoadd.filter

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

◆ inputData

lsst.pipe.tasks.assembleCoadd.inputData

Definition at line 498 of file assembleCoadd.py.

◆ KEY

lsst.pipe.tasks.assembleCoadd.KEY

Definition at line 304 of file assembleCoadd.py.

◆ patch

lsst.pipe.tasks.assembleCoadd.patch

Definition at line 342 of file assembleCoadd.py.

◆ retStruct

lsst.pipe.tasks.assembleCoadd.retStruct

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

◆ supplementaryData

lsst.pipe.tasks.assembleCoadd.supplementaryData

Definition at line 505 of file assembleCoadd.py.

◆ tract

lsst.pipe.tasks.assembleCoadd.tract

Definition at line 342 of file assembleCoadd.py.

◆ visit

lsst.pipe.tasks.assembleCoadd.visit

Definition at line 343 of file assembleCoadd.py.

◆ warpRefList

lsst.pipe.tasks.assembleCoadd.warpRefList

Definition at line 496 of file assembleCoadd.py.

◆ warpType

lsst.pipe.tasks.assembleCoadd.warpType

Definition at line 843 of file assembleCoadd.py.

lsst::log.log.logContinued.warn
def warn(fmt, *args)
Definition: logContinued.py:205
lsst.pipe.tasks.assembleCoadd.getTempExpRefList
def getTempExpRefList(self, patchRef, calExpRefList)
Definition: assembleCoadd.py:588
lsst::log.log.logContinued.info
def info(fmt, *args)
Definition: logContinued.py:201
lsst::afw::image::Mask
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
lsst.pipe.tasks.assembleCoadd.assembleSubregion
def assembleSubregion(self, coaddExposure, bbox, tempExpRefList, imageScalerList, weightList, altMaskList, statsFlags, statsCtrl, nImage=None)
Definition: assembleCoadd.py:862
lsst.gdb.afw.printers.debug
bool debug
Definition: printers.py:9
lsst.pipe.tasks.assembleCoadd.processResults
def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None)
Definition: assembleCoadd.py:525
lsst::afw::math::makeStatistics
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
lsst::afw::math::stringToStatisticsProperty
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)
Definition: Statistics.cc:747
lsst.pipe.tasks.assembleCoadd.reorderAndPadList
def reorderAndPadList(inputList, inputKeys, outputKeys, padWith=None)
Definition: assembleCoadd.py:2445
lsst::geom::all
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.
Definition: CoordinateExpr.h:81
lsst.pipe.tasks.assembleCoadd.removeMaskPlanes
def removeMaskPlanes(self, maskedImage)
Definition: assembleCoadd.py:939
lsst.pipe.tasks.assembleCoadd.assembleMetadata
def assembleMetadata(self, coaddExposure, tempExpRefList, weightList)
Definition: assembleCoadd.py:801
lsst::afw::geom::SpanSet
A compact representation of a collection of pixels.
Definition: SpanSet.h:78
lsst::log.log.logContinued.fatal
def fatal(fmt, *args)
Definition: logContinued.py:217
lsst.pipe.tasks.assembleCoadd.run
def run(self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=None)
Definition: assembleCoadd.py:720
lsst.pipe.tasks.assembleCoadd.prepareStats
def prepareStats(self, mask=None)
Definition: assembleCoadd.py:687
lsst.pipe.tasks.assembleCoadd.makeSupplementaryData
def makeSupplementaryData(self, dataRef, selectDataList=None, warpRefList=None)
Definition: assembleCoadd.py:545
max
int max
Definition: BoundedField.cc:104
lsst.pipe.tasks.assembleCoadd.setInexactPsf
def setInexactPsf(self, mask)
Definition: assembleCoadd.py:1102
lsst.pipe.tasks.coaddHelpers.getGroupDataRef
def getGroupDataRef(butler, datasetType, groupTuple, keys)
Definition: coaddHelpers.py:99
lsst::afw::math::StatisticsControl
Pass parameters to a Statistics object.
Definition: Statistics.h:93
lsst.pipe.tasks.assembleCoadd.countMaskFromFootprint
def countMaskFromFootprint(mask, footprint, bitmask, ignoreMask)
Definition: assembleCoadd.py:1198
lsst.pipe.tasks.assembleCoadd.readBrightObjectMasks
def readBrightObjectMasks(self, dataRef)
Definition: assembleCoadd.py:1038
lsst.pex::exceptions::InvalidParameterError
Reports invalid arguments.
Definition: Runtime.h:66
lsst.pipe.tasks.assembleCoadd.prepareInputs
def prepareInputs(self, refList)
Definition: assembleCoadd.py:612
lsst.pipe.tasks.assembleCoadd.makeSupplementaryDataGen3
def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs)
Definition: assembleCoadd.py:564
lsst::geom::Point< int, 2 >
lsst.pipe.tasks.assembleCoadd.setBrightObjectMasks
def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None)
Definition: assembleCoadd.py:1060
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::coadd::utils::setCoaddEdgeBits
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
Definition: setCoaddEdgeBits.cc:42
lsst::geom::Box2D
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
lsst::afw::math::statisticsStack
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:488
lsst.pipe.tasks.assembleCoadd.applyAltMaskPlanes
def applyAltMaskPlanes(self, mask, altMaskSpans)
Definition: assembleCoadd.py:984
lsst.pipe.tasks.coaddHelpers.groupPatchExposures
def groupPatchExposures(patchDataRef, calexpDataRefList, coaddDatasetType="deepCoadd", tempExpDatasetType="deepCoadd_directWarp")
Definition: coaddHelpers.py:59
lsst::geom::Extent< int, 2 >
lsst.pipe.tasks.assembleCoadd.shrinkValidPolygons
def shrinkValidPolygons(self, coaddInputs)
Definition: assembleCoadd.py:1016