LSST Applications g0265f82a02+776ea6fe0d,g159b3db504+2ad2e847e4,g1e7d6db67d+6147fcb7b1,g22560d942e+17f6891819,g2ab4ef6978+36a80bf878,g2bbee38e9b+776ea6fe0d,g2cc88a2952+157e6a7dfa,g3273194fdb+f6908454ef,g337abbeb29+776ea6fe0d,g44018dc512+776ea6fe0d,g4500d70958+2faa5faad4,g4728e35f0d+70f2b761fb,g47da3c6c86+ce8e72185e,g58be5f913a+8b80975358,g6ae5381d9b+81bc2a20b4,g7dc46dff8f+ce8e72185e,g91cdbf1c4d+d35db57202,g93973518b8+696ec083d0,g98ffbb4407+81bc2a20b4,g9ddcbc5298+7f7571301f,ga1e77700b3+9fd6c7179d,ga7ab7f6f60+8eb3636680,gae46bcf261+776ea6fe0d,gb2715bf1a1+8eb3636680,gb957171fc7+21ad70029f,gc86a011abf+8eb3636680,gcd84e84c5d+c77ce436e7,gcf0d15dbbd+ce8e72185e,gd162630629+677de33a64,gdaeeff99f8+0d8dbea60f,gdb4ec4c597+776ea6fe0d,ge24ae8ed47+4a28407819,gf041782ebf+6cd16f14a6,gf36cf20d7f+8eb3636680,w.2023.37
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Static Protected Attributes | List of all members
lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask Class Reference
Inheritance diagram for lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask:
lsst.pipe.tasks.coaddBase.CoaddBaseTask lsst.pipe.tasks.assembleCoadd.CompareWarpAssembleCoaddTask

Public Member Functions

 __init__ (self, *args, **kwargs)
 
 runQuantum (self, butlerQC, inputRefs, outputRefs)
 
 processResults (self, coaddExposure, brightObjectMasks=None, dataId=None)
 
 makeSupplementaryDataGen3 (self, butlerQC, inputRefs, outputRefs)
 
 prepareInputs (self, refList)
 
 prepareStats (self, mask=None)
 
 run (self, skyInfo, tempExpRefList, imageScalerList, weightList, altMaskList=None, mask=None, supplementaryData=None)
 
 assembleMetadata (self, coaddExposure, tempExpRefList, weightList)
 
 assembleSubregion (self, coaddExposure, bbox, tempExpRefList, imageScalerList, weightList, altMaskList, statsFlags, statsCtrl, nImage=None)
 
 assembleOnlineMeanCoadd (self, coaddExposure, tempExpRefList, imageScalerList, weightList, altMaskList, statsCtrl, nImage=None)
 
 removeMaskPlanes (self, maskedImage)
 
 applyAltMaskPlanes (self, mask, altMaskSpans)
 
 shrinkValidPolygons (self, coaddInputs)
 
 setBrightObjectMasks (self, exposure, brightObjectMasks, dataId=None)
 
 setInexactPsf (self, mask)
 
 filterWarps (self, inputs, goodVisits)
 

Static Public Member Functions

 setRejectedMaskMapping (statsCtrl)
 

Public Attributes

 brightObjectBitmask
 
 warpType
 

Static Public Attributes

 ConfigClass = AssembleCoaddConfig
 

Protected Member Functions

 _makeSupplementaryData (self, butlerQC, inputRefs, outputRefs)
 

Static Protected Member Functions

 _subBBoxIter (bbox, subregionSize)
 

Static Protected Attributes

str _DefaultName = "assembleCoadd"
 

Detailed Description

Assemble a coadded image from a set of warps.

Each Warp that goes into a coadd will typically have an independent
photometric zero-point. Therefore, we must scale each Warp to set it to
a common photometric zeropoint. WarpType may be one of 'direct' or
'psfMatched', and the boolean configs `config.makeDirect` and
`config.makePsfMatched` set which of the warp types will be coadded.
The coadd is computed as a mean with optional outlier rejection.
Criteria for outlier rejection are set in `AssembleCoaddConfig`.
Finally, Warps can have bad 'NaN' pixels which received no input from the
source calExps. We interpolate over these bad (NaN) pixels.

`AssembleCoaddTask` uses several sub-tasks. These are

- `~lsst.pipe.tasks.ScaleZeroPointTask`
- create and use an ``imageScaler`` object to scale the photometric zeropoint for each Warp
- `~lsst.pipe.tasks.InterpImageTask`
- interpolate across bad pixels (NaN) in the final coadd

You can retarget these subtasks if you wish.

Raises
------
RuntimeError
    Raised if unable to define mask plane for bright objects.

Notes
-----
Debugging:
`AssembleCoaddTask` has no debug variables of its own. Some of the
subtasks may support `~lsst.base.lsstDebug` variables. See the
documentation for the subtasks for further information.

Examples
--------
`AssembleCoaddTask` assembles a set of warped images into a coadded image.
The `AssembleCoaddTask` can be invoked by running ``assembleCoadd.py``
with the flag '--legacyCoadd'. Usage of assembleCoadd.py expects two
inputs: a data reference to the tract patch and filter to be coadded, and
a list of Warps to attempt to coadd. These are specified using ``--id`` and
``--selectId``, respectively:

.. code-block:: none

   --id = [KEY=VALUE1[^VALUE2[^VALUE3...] [KEY=VALUE1[^VALUE2[^VALUE3...] ...]]
   --selectId [KEY=VALUE1[^VALUE2[^VALUE3...] [KEY=VALUE1[^VALUE2[^VALUE3...] ...]]

Only the Warps that cover the specified tract and patch will be coadded.
A list of the available optional arguments can be obtained by calling
``assembleCoadd.py`` with the ``--help`` command line argument:

.. code-block:: none

   assembleCoadd.py --help

To demonstrate usage of the `AssembleCoaddTask` in the larger context of
multi-band processing, we will generate the HSC-I & -R band coadds from
HSC engineering test data provided in the ``ci_hsc`` package. To begin,
assuming that the lsst stack has been already set up, we must set up the
obs_subaru and ``ci_hsc`` packages. This defines the environment variable
``$CI_HSC_DIR`` and points at the location of the package. The raw HSC
data live in the ``$CI_HSC_DIR/raw directory``. To begin assembling the
coadds, we must first run:

- processCcd
- process the individual ccds in $CI_HSC_RAW to produce calibrated exposures
- makeSkyMap
- create a skymap that covers the area of the sky present in the raw exposures
- makeCoaddTempExp
- warp the individual calibrated exposures to the tangent plane of the coadd

We can perform all of these steps by running

.. code-block:: none

   $CI_HSC_DIR scons warp-903986 warp-904014 warp-903990 warp-904010 warp-903988

This will produce warped exposures for each visit. To coadd the warped
data, we call assembleCoadd.py as follows:

.. code-block:: none

   assembleCoadd.py --legacyCoadd $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-I \
   --selectId visit=903986 ccd=16 --selectId visit=903986 ccd=22 --selectId visit=903986 ccd=23 \
   --selectId visit=903986 ccd=100 --selectId visit=904014 ccd=1 --selectId visit=904014 ccd=6 \
   --selectId visit=904014 ccd=12 --selectId visit=903990 ccd=18 --selectId visit=903990 ccd=25 \
   --selectId visit=904010 ccd=4 --selectId visit=904010 ccd=10 --selectId visit=904010 ccd=100 \
   --selectId visit=903988 ccd=16 --selectId visit=903988 ccd=17 --selectId visit=903988 ccd=23 \
   --selectId visit=903988 ccd=24

that will process the HSC-I band data. The results are written in
``$CI_HSC_DIR/DATA/deepCoadd-results/HSC-I``.

You may also choose to run:

.. code-block:: none

   scons warp-903334 warp-903336 warp-903338 warp-903342 warp-903344 warp-903346
   assembleCoadd.py --legacyCoadd $CI_HSC_DIR/DATA --id patch=5,4 tract=0 filter=HSC-R \
   --selectId visit=903334 ccd=16 --selectId visit=903334 ccd=22 --selectId visit=903334 ccd=23 \
   --selectId visit=903334 ccd=100 --selectId visit=903336 ccd=17 --selectId visit=903336 ccd=24 \
   --selectId visit=903338 ccd=18 --selectId visit=903338 ccd=25 --selectId visit=903342 ccd=4 \
   --selectId visit=903342 ccd=10 --selectId visit=903342 ccd=100 --selectId visit=903344 ccd=0 \
   --selectId visit=903344 ccd=5 --selectId visit=903344 ccd=11 --selectId visit=903346 ccd=1 \
   --selectId visit=903346 ccd=6 --selectId visit=903346 ccd=12

to generate the coadd for the HSC-R band if you are interested in
following multiBand Coadd processing as discussed in `pipeTasks_multiBand`
(but note that normally, one would use the `SafeClipAssembleCoaddTask`
rather than `AssembleCoaddTask` to make the coadd.

Definition at line 267 of file assembleCoadd.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.__init__ (   self,
args,
**  kwargs 
)

Reimplemented from lsst.pipe.tasks.coaddBase.CoaddBaseTask.

Reimplemented in lsst.pipe.tasks.assembleCoadd.CompareWarpAssembleCoaddTask.

Definition at line 383 of file assembleCoadd.py.

383 def __init__(self, *args, **kwargs):
384 # TODO: DM-17415 better way to handle previously allowed passed args e.g.`AssembleCoaddTask(config)`
385 if args:
386 argNames = ["config", "name", "parentTask", "log"]
387 kwargs.update({k: v for k, v in zip(argNames, args)})
388 warnings.warn("AssembleCoadd received positional args, and casting them as kwargs: %s. "
389 "PipelineTask will not take positional args" % argNames, FutureWarning,
390 stacklevel=2)
391
392 super().__init__(**kwargs)
393 self.makeSubtask("interpImage")
394 self.makeSubtask("scaleZeroPoint")
395
396 if self.config.doMaskBrightObjects:
397 mask = afwImage.Mask()
398 try:
399 self.brightObjectBitmask = 1 << mask.addMaskPlane(self.config.brightObjectMaskName)
400 except pexExceptions.LsstCppException:
401 raise RuntimeError("Unable to define mask plane for bright objects; planes used are %s" %
402 mask.getMaskPlaneDict().keys())
403 del mask
404
405 if self.config.doInputMap:
406 self.makeSubtask("inputMapper")
407
408 self.warpType = self.config.warpType
409
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:77

Member Function Documentation

◆ _makeSupplementaryData()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask._makeSupplementaryData (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)
protected
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.

Reimplemented in lsst.pipe.tasks.assembleCoadd.CompareWarpAssembleCoaddTask.

Definition at line 468 of file assembleCoadd.py.

468 def _makeSupplementaryData(self, butlerQC, inputRefs, outputRefs):
469 """Make additional inputs to run() specific to subclasses (Gen3).
470
471 Duplicates interface of `runQuantum` method.
472 Available to be implemented by subclasses only if they need the
473 coadd dataRef for performing preliminary processing before
474 assembling the coadd.
475
476 Parameters
477 ----------
478 butlerQC : `~lsst.pipe.base.ButlerQuantumContext`
479 Gen3 Butler object for fetching additional data products before
480 running the Task specialized for quantum being processed.
481 inputRefs : `~lsst.pipe.base.InputQuantizedConnection`
482 Attributes are the names of the connections describing input dataset types.
483 Values are DatasetRefs that task consumes for corresponding dataset type.
484 DataIds are guaranteed to match data objects in ``inputData``.
485 outputRefs : `~lsst.pipe.base.OutputQuantizedConnection`
486 Attributes are the names of the connections describing output dataset types.
487 Values are DatasetRefs that task is to produce
488 for corresponding dataset type.
489 """
490 return pipeBase.Struct()
491

◆ _subBBoxIter()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask._subBBoxIter (   bbox,
  subregionSize 
)
staticprotected
Iterate over subregions of a bbox.

Parameters
----------
bbox : `lsst.geom.Box2I`
    Bounding box over which to iterate.
subregionSize : `lsst.geom.Extent2I`
    Size of sub-bboxes.

Yields
------
subBBox : `lsst.geom.Box2I`
    Next sub-bounding box of size ``subregionSize`` or smaller; each ``subBBox``
    is contained within ``bbox``, so it may be smaller than ``subregionSize`` at
    the edges of ``bbox``, but it will never be empty.

Raises
------
RuntimeError
    Raised if any of the following occur:
    - The given bbox is empty.
    - The subregionSize is 0.

Definition at line 1100 of file assembleCoadd.py.

1100 def _subBBoxIter(bbox, subregionSize):
1101 """Iterate over subregions of a bbox.
1102
1103 Parameters
1104 ----------
1105 bbox : `lsst.geom.Box2I`
1106 Bounding box over which to iterate.
1107 subregionSize : `lsst.geom.Extent2I`
1108 Size of sub-bboxes.
1109
1110 Yields
1111 ------
1112 subBBox : `lsst.geom.Box2I`
1113 Next sub-bounding box of size ``subregionSize`` or smaller; each ``subBBox``
1114 is contained within ``bbox``, so it may be smaller than ``subregionSize`` at
1115 the edges of ``bbox``, but it will never be empty.
1116
1117 Raises
1118 ------
1119 RuntimeError
1120 Raised if any of the following occur:
1121 - The given bbox is empty.
1122 - The subregionSize is 0.
1123 """
1124 if bbox.isEmpty():
1125 raise RuntimeError("bbox %s is empty" % (bbox,))
1126 if subregionSize[0] < 1 or subregionSize[1] < 1:
1127 raise RuntimeError("subregionSize %s must be nonzero" % (subregionSize,))
1128
1129 for rowShift in range(0, bbox.getHeight(), subregionSize[1]):
1130 for colShift in range(0, bbox.getWidth(), subregionSize[0]):
1131 subBBox = geom.Box2I(bbox.getMin() + geom.Extent2I(colShift, rowShift), subregionSize)
1132 subBBox.clip(bbox)
1133 if subBBox.isEmpty():
1134 raise RuntimeError("Bug: empty bbox! bbox=%s, subregionSize=%s, "
1135 "colShift=%s, rowShift=%s" %
1136 (bbox, subregionSize, colShift, rowShift))
1137 yield subBBox
1138
An integer coordinate rectangle.
Definition Box.h:55

◆ applyAltMaskPlanes()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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.

Raises
------
AssertionError
    Raised if there is a length mismatch.

Definition at line 723 of file assembleCoadd.py.

723 def assembleMetadata(self, coaddExposure, tempExpRefList, weightList):
724 """Set the metadata for the coadd.
725
726 This basic implementation sets the filter from the first input.
727
728 Parameters
729 ----------
730 coaddExposure : `lsst.afw.image.Exposure`
731 The target exposure for the coadd.
732 tempExpRefList : `list`
733 List of data references to tempExp.
734 weightList : `list`
735 List of weights.
736
737 Raises
738 ------
739 AssertionError
740 Raised if there is a length mismatch.
741 """
742 assert len(tempExpRefList) == len(weightList), "Length mismatch"
743
744 # We load a single pixel of each coaddTempExp, because we just want to get at the metadata
745 # (and we need more than just the PropertySet that contains the header), which is not possible
746 # with the current butler (see #2777).
747 bbox = geom.Box2I(coaddExposure.getBBox().getMin(), geom.Extent2I(1, 1))
748
749 tempExpList = [tempExpRef.get(parameters={'bbox': bbox}) for tempExpRef in tempExpRefList]
750
751 numCcds = sum(len(tempExp.getInfo().getCoaddInputs().ccds) for tempExp in tempExpList)
752
753 # Set the coadd FilterLabel to the band of the first input exposure:
754 # Coadds are calibrated, so the physical label is now meaningless.
755 coaddExposure.setFilter(afwImage.FilterLabel(tempExpList[0].getFilter().bandLabel))
756 coaddInputs = coaddExposure.getInfo().getCoaddInputs()
757 coaddInputs.ccds.reserve(numCcds)
758 coaddInputs.visits.reserve(len(tempExpList))
759
760 for tempExp, weight in zip(tempExpList, weightList):
761 self.inputRecorder.addVisitToCoadd(coaddInputs, tempExp, weight)
762
763 if self.config.doUsePsfMatchedPolygons:
764 self.shrinkValidPolygons(coaddInputs)
765
766 coaddInputs.visits.sort()
767 coaddInputs.ccds.sort()
768 if self.warpType == "psfMatched":
769 # The modelPsf BBox for a psfMatchedWarp/coaddTempExp was dynamically defined by
770 # ModelPsfMatchTask as the square box bounding its spatially-variable, pre-matched WarpedPsf.
771 # Likewise, set the PSF of a PSF-Matched Coadd to the modelPsf
772 # having the maximum width (sufficient because square)
773 modelPsfList = [tempExp.getPsf() for tempExp in tempExpList]
774 modelPsfWidthList = [modelPsf.computeBBox(modelPsf.getAveragePosition()).getWidth()
775 for modelPsf in modelPsfList]
776 psf = modelPsfList[modelPsfWidthList.index(max(modelPsfWidthList))]
777 else:
778 psf = measAlg.CoaddPsf(coaddInputs.ccds, coaddExposure.getWcs(),
779 self.config.coaddPsf.makeControl())
780 coaddExposure.setPsf(psf)
781 apCorrMap = measAlg.makeCoaddApCorrMap(coaddInputs.ccds, coaddExposure.getBBox(afwImage.PARENT),
782 coaddExposure.getWcs())
783 coaddExposure.getInfo().setApCorrMap(apCorrMap)
784 if self.config.doAttachTransmissionCurve:
785 transmissionCurve = measAlg.makeCoaddTransmissionCurve(coaddExposure.getWcs(), coaddInputs.ccds)
786 coaddExposure.getInfo().setTransmissionCurve(transmissionCurve)
787
int max
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition Exposure.h:72
A group of labels for a filter in an exposure or coadd.
Definition FilterLabel.h:58

◆ assembleOnlineMeanCoadd()

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

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

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

Definition at line 864 of file assembleCoadd.py.

865 altMaskList, statsCtrl, nImage=None):
866 """Assemble the coadd using the "online" method.
867
868 This method takes a running sum of images and weights to save memory.
869 It only works for MEAN statistics.
870
871 Parameters
872 ----------
873 coaddExposure : `lsst.afw.image.Exposure`
874 The target exposure for the coadd.
875 tempExpRefList : `list`
876 List of data reference to tempExp.
877 imageScalerList : `list`
878 List of image scalers.
879 weightList : `list`
880 List of weights.
881 altMaskList : `list`
882 List of alternate masks to use rather than those stored with
883 tempExp, or None. Each element is dict with keys = mask plane
884 name to which to add the spans.
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 online coadd.")
891
892 coaddExposure.mask.addMaskPlane("REJECTED")
893 coaddExposure.mask.addMaskPlane("CLIPPED")
894 coaddExposure.mask.addMaskPlane("SENSOR_EDGE")
895 maskMap = self.setRejectedMaskMapping(statsCtrl)
896 thresholdDict = AccumulatorMeanStack.stats_ctrl_to_threshold_dict(statsCtrl)
897
898 bbox = coaddExposure.maskedImage.getBBox()
899
900 stacker = AccumulatorMeanStack(
901 coaddExposure.image.array.shape,
902 statsCtrl.getAndMask(),
903 mask_threshold_dict=thresholdDict,
904 mask_map=maskMap,
905 no_good_pixels_mask=statsCtrl.getNoGoodPixelsMask(),
906 calc_error_from_input_variance=self.config.calcErrorFromInputVariance,
907 compute_n_image=(nImage is not None)
908 )
909
910 for tempExpRef, imageScaler, altMask, weight in zip(tempExpRefList,
911 imageScalerList,
912 altMaskList,
913 weightList):
914 exposure = tempExpRef.get()
915 maskedImage = exposure.getMaskedImage()
916 mask = maskedImage.getMask()
917 if altMask is not None:
918 self.applyAltMaskPlanes(mask, altMask)
919 imageScaler.scaleMaskedImage(maskedImage)
920 if self.config.removeMaskPlanes:
921 self.removeMaskPlanes(maskedImage)
922
923 stacker.add_masked_image(maskedImage, weight=weight)
924
925 if self.config.doInputMap:
926 visit = exposure.getInfo().getCoaddInputs().visits[0].getId()
927 self.inputMapper.mask_warp_bbox(bbox, visit, mask, statsCtrl.getAndMask())
928
929 stacker.fill_stacked_masked_image(coaddExposure.maskedImage)
930
931 if nImage is not None:
932 nImage.array[:, :] = stacker.n_image
933
Pass parameters to a Statistics object.
Definition Statistics.h:83

◆ assembleSubregion()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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 788 of file assembleCoadd.py.

789 altMaskList, statsFlags, statsCtrl, nImage=None):
790 """Assemble the coadd for a sub-region.
791
792 For each coaddTempExp, check for (and swap in) an alternative mask
793 if one is passed. Remove mask planes listed in
794 `config.removeMaskPlanes`. Finally, stack the actual exposures using
795 `lsst.afw.math.statisticsStack` with the statistic specified by
796 statsFlags. Typically, the statsFlag will be one of lsst.afw.math.MEAN for
797 a mean-stack or `lsst.afw.math.MEANCLIP` for outlier rejection using
798 an N-sigma clipped mean where N and iterations are specified by
799 statsCtrl. Assign the stacked subregion back to the coadd.
800
801 Parameters
802 ----------
803 coaddExposure : `lsst.afw.image.Exposure`
804 The target exposure for the coadd.
805 bbox : `lsst.geom.Box`
806 Sub-region to coadd.
807 tempExpRefList : `list`
808 List of data reference to tempExp.
809 imageScalerList : `list`
810 List of image scalers.
811 weightList : `list`
812 List of weights.
813 altMaskList : `list`
814 List of alternate masks to use rather than those stored with
815 tempExp, or None. Each element is dict with keys = mask plane
816 name to which to add the spans.
817 statsFlags : `lsst.afw.math.Property`
818 Property object for statistic for coadd.
820 Statistics control object for coadd.
821 nImage : `lsst.afw.image.ImageU`, optional
822 Keeps track of exposure count for each pixel.
823 """
824 self.log.debug("Computing coadd over %s", bbox)
825
826 coaddExposure.mask.addMaskPlane("REJECTED")
827 coaddExposure.mask.addMaskPlane("CLIPPED")
828 coaddExposure.mask.addMaskPlane("SENSOR_EDGE")
829 maskMap = self.setRejectedMaskMapping(statsCtrl)
830 clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")
831 maskedImageList = []
832 if nImage is not None:
833 subNImage = afwImage.ImageU(bbox.getWidth(), bbox.getHeight())
834 for tempExpRef, imageScaler, altMask in zip(tempExpRefList, imageScalerList, altMaskList):
835
836 exposure = tempExpRef.get(parameters={'bbox': bbox})
837
838 maskedImage = exposure.getMaskedImage()
839 mask = maskedImage.getMask()
840 if altMask is not None:
841 self.applyAltMaskPlanes(mask, altMask)
842 imageScaler.scaleMaskedImage(maskedImage)
843
844 # Add 1 for each pixel which is not excluded by the exclude mask.
845 # In legacyCoadd, pixels may also be excluded by afwMath.statisticsStack.
846 if nImage is not None:
847 subNImage.getArray()[maskedImage.getMask().getArray() & statsCtrl.getAndMask() == 0] += 1
848 if self.config.removeMaskPlanes:
849 self.removeMaskPlanes(maskedImage)
850 maskedImageList.append(maskedImage)
851
852 if self.config.doInputMap:
853 visit = exposure.getInfo().getCoaddInputs().visits[0].getId()
854 self.inputMapper.mask_warp_bbox(bbox, visit, mask, statsCtrl.getAndMask())
855
856 with self.timer("stack"):
857 coaddSubregion = afwMath.statisticsStack(maskedImageList, statsFlags, statsCtrl, weightList,
858 clipped, # also set output to CLIPPED if sigma-clipped
859 maskMap)
860 coaddExposure.maskedImage.assign(coaddSubregion, bbox)
861 if nImage is not None:
862 nImage.assign(subNImage, bbox)
863
std::shared_ptr< lsst::afw::image::Image< PixelT > > statisticsStack(std::vector< std::shared_ptr< lsst::afw::image::Image< PixelT > > > &images, Property flags, StatisticsControl const &sctrl=StatisticsControl(), std::vector< lsst::afw::image::VariancePixel > const &wvector=std::vector< lsst::afw::image::VariancePixel >(0))
A function to compute some statistics of a stack of Images.

◆ filterWarps()

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

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

Returns
-------
filteredInputs : `list` of `~lsst.pipe.base.connections.DeferredDatasetRef`
    Filtered and sorted list of inputRefs with visitId in goodVisits ordered by goodVisit.

Definition at line 1139 of file assembleCoadd.py.

1139 def filterWarps(self, inputs, goodVisits):
1140 """Return list of only inputRefs with visitId in goodVisits ordered by goodVisit.
1141
1142 Parameters
1143 ----------
1144 inputs : `list` of `~lsst.pipe.base.connections.DeferredDatasetRef`
1145 List of `lsst.pipe.base.connections.DeferredDatasetRef` with dataId containing visit.
1146 goodVisit : `dict`
1147 Dictionary with good visitIds as the keys. Value ignored.
1148
1149 Returns
1150 -------
1151 filteredInputs : `list` of `~lsst.pipe.base.connections.DeferredDatasetRef`
1152 Filtered and sorted list of inputRefs with visitId in goodVisits ordered by goodVisit.
1153 """
1154 inputWarpDict = {inputRef.ref.dataId['visit']: inputRef for inputRef in inputs}
1155 filteredInputs = []
1156 for visit in goodVisits.keys():
1157 if visit in inputWarpDict:
1158 filteredInputs.append(inputWarpDict[visit])
1159 return filteredInputs
1160
1161

◆ makeSupplementaryDataGen3()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.makeSupplementaryDataGen3 (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)

Definition at line 497 of file assembleCoadd.py.

497 def makeSupplementaryDataGen3(self, butlerQC, inputRefs, outputRefs):
498 return self._makeSupplementaryData(butlerQC, inputRefs, outputRefs)
499

◆ prepareInputs()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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`
    Results as a struct with attributes:

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

Definition at line 500 of file assembleCoadd.py.

500 def prepareInputs(self, refList):
501 """Prepare the input warps for coaddition by measuring the weight for
502 each warp and the scaling for the photometric zero point.
503
504 Each Warp has its own photometric zeropoint and background variance.
505 Before coadding these Warps together, compute a scale factor to
506 normalize the photometric zeropoint and compute the weight for each Warp.
507
508 Parameters
509 ----------
510 refList : `list`
511 List of data references to tempExp.
512
513 Returns
514 -------
515 result : `~lsst.pipe.base.Struct`
516 Results as a struct with attributes:
517
518 ``tempExprefList``
519 `list` of data references to tempExp.
520 ``weightList``
521 `list` of weightings.
522 ``imageScalerList``
523 `list` of image scalers.
524 """
525 statsCtrl = afwMath.StatisticsControl()
526 statsCtrl.setNumSigmaClip(self.config.sigmaClip)
527 statsCtrl.setNumIter(self.config.clipIter)
528 statsCtrl.setAndMask(self.getBadPixelMask())
529 statsCtrl.setNanSafe(True)
530 # compute tempExpRefList: a list of tempExpRef that actually exist
531 # and weightList: a list of the weight of the associated coadd tempExp
532 # and imageScalerList: a list of scale factors for the associated coadd tempExp
533 tempExpRefList = []
534 weightList = []
535 imageScalerList = []
536 tempExpName = self.getTempExpDatasetName(self.warpType)
537 for tempExpRef in refList:
538 tempExp = tempExpRef.get()
539 # Ignore any input warp that is empty of data
540 if numpy.isnan(tempExp.image.array).all():
541 continue
542 maskedImage = tempExp.getMaskedImage()
543 imageScaler = self.scaleZeroPoint.computeImageScaler(
544 exposure=tempExp,
545 dataRef=tempExpRef, # FIXME
546 )
547 try:
548 imageScaler.scaleMaskedImage(maskedImage)
549 except Exception as e:
550 self.log.warning("Scaling failed for %s (skipping it): %s", tempExpRef.dataId, e)
551 continue
552 statObj = afwMath.makeStatistics(maskedImage.getVariance(), maskedImage.getMask(),
553 afwMath.MEANCLIP, statsCtrl)
554 meanVar, meanVarErr = statObj.getResult(afwMath.MEANCLIP)
555 weight = 1.0 / float(meanVar)
556 if not numpy.isfinite(weight):
557 self.log.warning("Non-finite weight for %s: skipping", tempExpRef.dataId)
558 continue
559 self.log.info("Weight of %s %s = %0.3f", tempExpName, tempExpRef.dataId, weight)
560
561 del maskedImage
562 del tempExp
563
564 tempExpRefList.append(tempExpRef)
565 weightList.append(weight)
566 imageScalerList.append(imageScaler)
567
568 return pipeBase.Struct(tempExpRefList=tempExpRefList, weightList=weightList,
569 imageScalerList=imageScalerList)
570
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition Statistics.h:361

◆ prepareStats()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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 as a struct with attributes:

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

Definition at line 571 of file assembleCoadd.py.

571 def prepareStats(self, mask=None):
572 """Prepare the statistics for coadding images.
573
574 Parameters
575 ----------
576 mask : `int`, optional
577 Bit mask value to exclude from coaddition.
578
579 Returns
580 -------
581 stats : `~lsst.pipe.base.Struct`
582 Statistics as a struct with attributes:
583
584 ``statsCtrl``
585 Statistics control object for coadd (`~lsst.afw.math.StatisticsControl`).
586 ``statsFlags``
587 Statistic for coadd (`~lsst.afw.math.Property`).
588 """
589 if mask is None:
590 mask = self.getBadPixelMask()
591 statsCtrl = afwMath.StatisticsControl()
592 statsCtrl.setNumSigmaClip(self.config.sigmaClip)
593 statsCtrl.setNumIter(self.config.clipIter)
594 statsCtrl.setAndMask(mask)
595 statsCtrl.setNanSafe(True)
596 statsCtrl.setWeighted(True)
597 statsCtrl.setCalcErrorFromInputVariance(self.config.calcErrorFromInputVariance)
598 for plane, threshold in self.config.maskPropagationThresholds.items():
599 bit = afwImage.Mask.getMaskPlane(plane)
600 statsCtrl.setMaskPropagationThreshold(bit, threshold)
601 statsFlags = afwMath.stringToStatisticsProperty(self.config.statistic)
602 return pipeBase.Struct(ctrl=statsCtrl, flags=statsFlags)
603
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)

◆ processResults()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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.
brightObjectMasks : `lsst.afw.table` or `None`, optional
    Table of bright objects to mask.
dataId : `lsst.daf.butler.DataId` or `None`, optional
    Data identification.

Definition at line 446 of file assembleCoadd.py.

446 def processResults(self, coaddExposure, brightObjectMasks=None, dataId=None):
447 """Interpolate over missing data and mask bright stars.
448
449 Parameters
450 ----------
451 coaddExposure : `lsst.afw.image.Exposure`
452 The coadded exposure to process.
453 brightObjectMasks : `lsst.afw.table` or `None`, optional
454 Table of bright objects to mask.
455 dataId : `lsst.daf.butler.DataId` or `None`, optional
456 Data identification.
457 """
458 if self.config.doInterp:
459 self.interpImage.run(coaddExposure.getMaskedImage(), planeName="NO_DATA")
460 # The variance must be positive; work around for DM-3201.
461 varArray = coaddExposure.variance.array
462 with numpy.errstate(invalid="ignore"):
463 varArray[:] = numpy.where(varArray > 0, varArray, numpy.inf)
464
465 if self.config.doMaskBrightObjects:
466 self.setBrightObjectMasks(coaddExposure, brightObjectMasks, dataId)
467

◆ removeMaskPlanes()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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.

Raises
------
InvalidParameterError
    Raised if no mask plane with that name was found.

Definition at line 934 of file assembleCoadd.py.

934 def removeMaskPlanes(self, maskedImage):
935 """Unset the mask of an image for mask planes specified in the config.
936
937 Parameters
938 ----------
939 maskedImage : `lsst.afw.image.MaskedImage`
940 The masked image to be modified.
941
942 Raises
943 ------
944 InvalidParameterError
945 Raised if no mask plane with that name was found.
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
A class to manipulate images, masks, and variance as a single object.
Definition MaskedImage.h:74
Reports invalid arguments.
Definition Runtime.h:66

◆ run()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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`
    Results as a struct with attributes:

    ``coaddExposure``
        Coadded exposure (``lsst.afw.image.Exposure``).
    ``nImage``
        Exposure count image (``lsst.afw.image.Image``), if requested.
    ``inputMap``
        Bit-wise map of inputs, if requested.
    ``warpRefList``
        Input list of refs to the warps (``lsst.daf.butler.DeferredDatasetHandle``)
        (unmodified).
    ``imageScalerList``
        Input list of image scalers (`list`) (unmodified).
    ``weightList``
        Input list of weights (`list`) (unmodified).

Raises
------
lsst.pipe.base.NoWorkFound
    Raised if no data references are provided.

Reimplemented in lsst.pipe.tasks.assembleCoadd.CompareWarpAssembleCoaddTask.

Definition at line 605 of file assembleCoadd.py.

606 altMaskList=None, mask=None, supplementaryData=None):
607 """Assemble a coadd from input warps.
608
609 Assemble the coadd using the provided list of coaddTempExps. Since
610 the full coadd covers a patch (a large area), the assembly is
611 performed over small areas on the image at a time in order to
612 conserve memory usage. Iterate over subregions within the outer
613 bbox of the patch using `assembleSubregion` to stack the corresponding
614 subregions from the coaddTempExps with the statistic specified.
615 Set the edge bits the coadd mask based on the weight map.
616
617 Parameters
618 ----------
619 skyInfo : `~lsst.pipe.base.Struct`
620 Struct with geometric information about the patch.
621 tempExpRefList : `list`
622 List of data references to Warps (previously called CoaddTempExps).
623 imageScalerList : `list`
624 List of image scalers.
625 weightList : `list`
626 List of weights.
627 altMaskList : `list`, optional
628 List of alternate masks to use rather than those stored with
629 tempExp.
630 mask : `int`, optional
631 Bit mask value to exclude from coaddition.
632 supplementaryData : `~lsst.pipe.base.Struct`, optional
633 Struct with additional data products needed to assemble coadd.
634 Only used by subclasses that implement ``_makeSupplementaryData``
635 and override `run`.
636
637 Returns
638 -------
639 result : `~lsst.pipe.base.Struct`
640 Results as a struct with attributes:
641
642 ``coaddExposure``
643 Coadded exposure (``lsst.afw.image.Exposure``).
644 ``nImage``
645 Exposure count image (``lsst.afw.image.Image``), if requested.
646 ``inputMap``
647 Bit-wise map of inputs, if requested.
648 ``warpRefList``
649 Input list of refs to the warps (``lsst.daf.butler.DeferredDatasetHandle``)
650 (unmodified).
651 ``imageScalerList``
652 Input list of image scalers (`list`) (unmodified).
653 ``weightList``
654 Input list of weights (`list`) (unmodified).
655
656 Raises
657 ------
658 lsst.pipe.base.NoWorkFound
659 Raised if no data references are provided.
660 """
661 tempExpName = self.getTempExpDatasetName(self.warpType)
662 self.log.info("Assembling %s %s", len(tempExpRefList), tempExpName)
663 if not tempExpRefList:
664 raise pipeBase.NoWorkFound("No exposures provided for co-addition.")
665
666 stats = self.prepareStats(mask=mask)
667
668 if altMaskList is None:
669 altMaskList = [None]*len(tempExpRefList)
670
671 coaddExposure = afwImage.ExposureF(skyInfo.bbox, skyInfo.wcs)
672 coaddExposure.setPhotoCalib(self.scaleZeroPoint.getPhotoCalib())
673 coaddExposure.getInfo().setCoaddInputs(self.inputRecorder.makeCoaddInputs())
674 self.assembleMetadata(coaddExposure, tempExpRefList, weightList)
675 coaddMaskedImage = coaddExposure.getMaskedImage()
676 subregionSizeArr = self.config.subregionSize
677 subregionSize = geom.Extent2I(subregionSizeArr[0], subregionSizeArr[1])
678 # if nImage is requested, create a zero one which can be passed to assembleSubregion
679 if self.config.doNImage:
680 nImage = afwImage.ImageU(skyInfo.bbox)
681 else:
682 nImage = None
683 # If inputMap is requested, create the initial version that can be masked in
684 # assembleSubregion.
685 if self.config.doInputMap:
686 self.inputMapper.build_ccd_input_map(skyInfo.bbox,
687 skyInfo.wcs,
688 coaddExposure.getInfo().getCoaddInputs().ccds)
689
690 if self.config.doOnlineForMean and self.config.statistic == "MEAN":
691 try:
692 self.assembleOnlineMeanCoadd(coaddExposure, tempExpRefList, imageScalerList,
693 weightList, altMaskList, stats.ctrl,
694 nImage=nImage)
695 except Exception as e:
696 self.log.exception("Cannot compute online coadd %s", e)
697 raise
698 else:
699 for subBBox in self._subBBoxIter(skyInfo.bbox, subregionSize):
700 try:
701 self.assembleSubregion(coaddExposure, subBBox, tempExpRefList, imageScalerList,
702 weightList, altMaskList, stats.flags, stats.ctrl,
703 nImage=nImage)
704 except Exception as e:
705 self.log.exception("Cannot compute coadd %s: %s", subBBox, e)
706 raise
707
708 # If inputMap is requested, we must finalize the map after the accumulation.
709 if self.config.doInputMap:
710 self.inputMapper.finalize_ccd_input_map_mask()
711 inputMap = self.inputMapper.ccd_input_map
712 else:
713 inputMap = None
714
715 self.setInexactPsf(coaddMaskedImage.getMask())
716 # Despite the name, the following doesn't really deal with "EDGE" pixels: it identifies
717 # pixels that didn't receive any unmasked inputs (as occurs around the edge of the field).
718 coaddUtils.setCoaddEdgeBits(coaddMaskedImage.getMask(), coaddMaskedImage.getVariance())
719 return pipeBase.Struct(coaddExposure=coaddExposure, nImage=nImage,
720 warpRefList=tempExpRefList, imageScalerList=imageScalerList,
721 weightList=weightList, inputMap=inputMap)
722
A class to represent a 2-dimensional array of pixels.
Definition Image.h:51
void setCoaddEdgeBits(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > &coaddMask, lsst::afw::image::Image< WeightPixelT > const &weightMap)
set edge bits of coadd mask based on weight map

◆ runQuantum()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.runQuantum (   self,
  butlerQC,
  inputRefs,
  outputRefs 
)

Definition at line 410 of file assembleCoadd.py.

410 def runQuantum(self, butlerQC, inputRefs, outputRefs):
411 inputData = butlerQC.get(inputRefs)
412
413 # Construct skyInfo expected by run
414 # Do not remove skyMap from inputData in case _makeSupplementaryData needs it
415 skyMap = inputData["skyMap"]
416 outputDataId = butlerQC.quantum.dataId
417
418 inputData['skyInfo'] = makeSkyInfo(skyMap,
419 tractId=outputDataId['tract'],
420 patchId=outputDataId['patch'])
421
422 if self.config.doSelectVisits:
423 warpRefList = self.filterWarps(inputData['inputWarps'], inputData['selectedVisits'])
424 else:
425 warpRefList = inputData['inputWarps']
426
427 inputs = self.prepareInputs(warpRefList)
428 self.log.info("Found %d %s", len(inputs.tempExpRefList),
429 self.getTempExpDatasetName(self.warpType))
430 if len(inputs.tempExpRefList) == 0:
431 raise pipeBase.NoWorkFound("No coadd temporary exposures found")
432
433 supplementaryData = self._makeSupplementaryData(butlerQC, inputRefs, outputRefs)
434 retStruct = self.run(inputData['skyInfo'], inputs.tempExpRefList, inputs.imageScalerList,
435 inputs.weightList, supplementaryData=supplementaryData)
436
437 inputData.setdefault('brightObjectMask', None)
438 if self.config.doMaskBrightObjects and inputData["brightObjectMask"] is None:
439 log.warning("doMaskBrightObjects is set to True, but brightObjectMask not loaded")
440 self.processResults(retStruct.coaddExposure, inputData['brightObjectMask'], outputDataId)
441
442 if self.config.doWrite:
443 butlerQC.put(retStruct, outputRefs)
444 return retStruct
445

◆ setBrightObjectMasks()

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

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

Definition at line 1037 of file assembleCoadd.py.

1037 def setBrightObjectMasks(self, exposure, brightObjectMasks, dataId=None):
1038 """Set the bright object masks.
1039
1040 Parameters
1041 ----------
1042 exposure : `lsst.afw.image.Exposure`
1043 Exposure under consideration.
1044 brightObjectMasks : `lsst.afw.table`
1045 Table of bright objects to mask.
1046 dataId : `lsst.daf.butler.DataId`, optional
1047 Data identifier dict for patch.
1048 """
1049 if brightObjectMasks is None:
1050 self.log.warning("Unable to apply bright object mask: none supplied")
1051 return
1052 self.log.info("Applying %d bright object masks to %s", len(brightObjectMasks), dataId)
1053 mask = exposure.getMaskedImage().getMask()
1054 wcs = exposure.getWcs()
1055 plateScale = wcs.getPixelScale().asArcseconds()
1056
1057 for rec in brightObjectMasks:
1058 center = geom.PointI(wcs.skyToPixel(rec.getCoord()))
1059 if rec["type"] == "box":
1060 assert rec["angle"] == 0.0, ("Angle != 0 for mask object %s" % rec["id"])
1061 width = rec["width"].asArcseconds()/plateScale # convert to pixels
1062 height = rec["height"].asArcseconds()/plateScale # convert to pixels
1063
1064 halfSize = geom.ExtentI(0.5*width, 0.5*height)
1065 bbox = geom.Box2I(center - halfSize, center + halfSize)
1066
1067 bbox = geom.BoxI(geom.PointI(int(center[0] - 0.5*width), int(center[1] - 0.5*height)),
1068 geom.PointI(int(center[0] + 0.5*width), int(center[1] + 0.5*height)))
1069 spans = afwGeom.SpanSet(bbox)
1070 elif rec["type"] == "circle":
1071 radius = int(rec["radius"].asArcseconds()/plateScale) # convert to pixels
1072 spans = afwGeom.SpanSet.fromShape(radius, offset=center)
1073 else:
1074 self.log.warning("Unexpected region type %s at %s", rec["type"], center)
1075 continue
1076 spans.clippedTo(mask.getBBox()).setMask(mask, self.brightObjectBitmask)
1077
A compact representation of a collection of pixels.
Definition SpanSet.h:78

◆ setInexactPsf()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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 1078 of file assembleCoadd.py.

1078 def setInexactPsf(self, mask):
1079 """Set INEXACT_PSF mask plane.
1080
1081 If any of the input images isn't represented in the coadd (due to
1082 clipped pixels or chip gaps), the `CoaddPsf` will be inexact. Flag
1083 these pixels.
1084
1085 Parameters
1086 ----------
1087 mask : `lsst.afw.image.Mask`
1088 Coadded exposure's mask, modified in-place.
1089 """
1090 mask.addMaskPlane("INEXACT_PSF")
1091 inexactPsf = mask.getPlaneBitMask("INEXACT_PSF")
1092 sensorEdge = mask.getPlaneBitMask("SENSOR_EDGE") # chip edges (so PSF is discontinuous)
1093 clipped = mask.getPlaneBitMask("CLIPPED") # pixels clipped from coadd
1094 rejected = mask.getPlaneBitMask("REJECTED") # pixels rejected from coadd due to masks
1095 array = mask.getArray()
1096 selected = array & (sensorEdge | clipped | rejected) > 0
1097 array[selected] |= inexactPsf
1098

◆ setRejectedMaskMapping()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.setRejectedMaskMapping (   statsCtrl)
static
Map certain mask planes of the warps to new planes for the coadd.

If a pixel is rejected due to a mask value other than EDGE, NO_DATA,
or CLIPPED, set it to REJECTED on the coadd.
If a pixel is rejected due to EDGE, set the coadd pixel to SENSOR_EDGE.
If a pixel is rejected due to CLIPPED, set the coadd pixel to CLIPPED.

Parameters
----------
statsCtrl : `lsst.afw.math.StatisticsControl`
    Statistics control object for coadd.

Returns
-------
maskMap : `list` of `tuple` of `int`
    A list of mappings of mask planes of the warped exposures to
    mask planes of the coadd.

Definition at line 956 of file assembleCoadd.py.

956 def setRejectedMaskMapping(statsCtrl):
957 """Map certain mask planes of the warps to new planes for the coadd.
958
959 If a pixel is rejected due to a mask value other than EDGE, NO_DATA,
960 or CLIPPED, set it to REJECTED on the coadd.
961 If a pixel is rejected due to EDGE, set the coadd pixel to SENSOR_EDGE.
962 If a pixel is rejected due to CLIPPED, set the coadd pixel to CLIPPED.
963
964 Parameters
965 ----------
967 Statistics control object for coadd.
968
969 Returns
970 -------
971 maskMap : `list` of `tuple` of `int`
972 A list of mappings of mask planes of the warped exposures to
973 mask planes of the coadd.
974 """
975 edge = afwImage.Mask.getPlaneBitMask("EDGE")
976 noData = afwImage.Mask.getPlaneBitMask("NO_DATA")
977 clipped = afwImage.Mask.getPlaneBitMask("CLIPPED")
978 toReject = statsCtrl.getAndMask() & (~noData) & (~edge) & (~clipped)
979 maskMap = [(toReject, afwImage.Mask.getPlaneBitMask("REJECTED")),
980 (edge, afwImage.Mask.getPlaneBitMask("SENSOR_EDGE")),
981 (clipped, clipped)]
982 return maskMap
983

◆ shrinkValidPolygons()

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.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 for ccd in coaddInputs.ccds:
1028 polyOrig = ccd.getValidPolygon()
1029 validPolyBBox = polyOrig.getBBox() if polyOrig else ccd.getBBox()
1030 validPolyBBox.grow(-self.config.matchingKernelSize//2)
1031 if polyOrig:
1032 validPolygon = polyOrig.intersectionSingle(validPolyBBox)
1033 else:
1034 validPolygon = afwGeom.polygon.Polygon(geom.Box2D(validPolyBBox))
1035 ccd.setValidPolygon(validPolygon)
1036
A floating-point coordinate rectangle geometry.
Definition Box.h:413

Member Data Documentation

◆ _DefaultName

str lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask._DefaultName = "assembleCoadd"
staticprotected

Definition at line 381 of file assembleCoadd.py.

◆ brightObjectBitmask

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.brightObjectBitmask

Definition at line 399 of file assembleCoadd.py.

◆ ConfigClass

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.ConfigClass = AssembleCoaddConfig
static

Definition at line 380 of file assembleCoadd.py.

◆ warpType

lsst.pipe.tasks.assembleCoadd.AssembleCoaddTask.warpType

Definition at line 408 of file assembleCoadd.py.


The documentation for this class was generated from the following file: