24 __all__ = (
"SourceDetectionConfig",
"SourceDetectionTask",
"addExposures")
26 from contextlib
import contextmanager
39 from .subtractBackground
import SubtractBackgroundTask
43 """Configuration parameters for the SourceDetectionTask
45 minPixels = pexConfig.RangeField(
46 doc=
"detected sources with fewer than the specified number of pixels will be ignored",
47 dtype=int, optional=
False, default=1, min=0,
49 isotropicGrow = pexConfig.Field(
50 doc=
"Pixels should be grown as isotropically as possible (slower)",
51 dtype=bool, optional=
False, default=
False,
53 combinedGrow = pexConfig.Field(
54 doc=
"Grow all footprints at the same time? This allows disconnected footprints to merge.",
55 dtype=bool, default=
True,
57 nSigmaToGrow = pexConfig.Field(
58 doc=
"Grow detections by nSigmaToGrow * [PSF RMS width]; if 0 then do not grow",
59 dtype=float, default=2.4,
61 returnOriginalFootprints = pexConfig.Field(
62 doc=
"Grow detections to set the image mask bits, but return the original (not-grown) footprints",
63 dtype=bool, optional=
False, default=
False,
65 thresholdValue = pexConfig.RangeField(
66 doc=
"Threshold for footprints; exact meaning and units depend on thresholdType.",
67 dtype=float, optional=
False, default=5.0, min=0.0,
69 includeThresholdMultiplier = pexConfig.RangeField(
70 doc=
"Include threshold relative to thresholdValue",
71 dtype=float, default=1.0, min=0.0,
73 thresholdType = pexConfig.ChoiceField(
74 doc=
"specifies the desired flavor of Threshold",
75 dtype=str, optional=
False, default=
"stdev",
77 "variance":
"threshold applied to image variance",
78 "stdev":
"threshold applied to image std deviation",
79 "value":
"threshold applied to image value",
80 "pixel_stdev":
"threshold applied to per-pixel std deviation",
83 thresholdPolarity = pexConfig.ChoiceField(
84 doc=
"specifies whether to detect positive, or negative sources, or both",
85 dtype=str, optional=
False, default=
"positive",
87 "positive":
"detect only positive sources",
88 "negative":
"detect only negative sources",
89 "both":
"detect both positive and negative sources",
92 adjustBackground = pexConfig.Field(
94 doc=
"Fiddle factor to add to the background; debugging only",
97 reEstimateBackground = pexConfig.Field(
99 doc=
"Estimate the background again after final source detection?",
100 default=
True, optional=
False,
102 background = pexConfig.ConfigurableField(
103 doc=
"Background re-estimation; ignored if reEstimateBackground false",
104 target=SubtractBackgroundTask,
106 tempLocalBackground = pexConfig.ConfigurableField(
107 doc=(
"A local (small-scale), temporary background estimation step run between "
108 "detecting above-threshold regions and detecting the peaks within "
109 "them; used to avoid detecting spuerious peaks in the wings."),
110 target=SubtractBackgroundTask,
112 doTempLocalBackground = pexConfig.Field(
114 doc=
"Enable temporary local background subtraction? (see tempLocalBackground)",
117 tempWideBackground = pexConfig.ConfigurableField(
118 doc=(
"A wide (large-scale) background estimation and removal before footprint and peak detection. "
119 "It is added back into the image after detection. The purpose is to suppress very large "
120 "footprints (e.g., from large artifacts) that the deblender may choke on."),
121 target=SubtractBackgroundTask,
123 doTempWideBackground = pexConfig.Field(
125 doc=
"Do temporary wide (large-scale) background subtraction before footprint detection?",
128 nPeaksMaxSimple = pexConfig.Field(
130 doc=(
"The maximum number of peaks in a Footprint before trying to "
131 "replace its peaks using the temporary local background"),
134 nSigmaForKernel = pexConfig.Field(
136 doc=(
"Multiple of PSF RMS size to use for convolution kernel bounding box size; "
137 "note that this is not a half-size. The size will be rounded up to the nearest odd integer"),
140 statsMask = pexConfig.ListField(
142 doc=
"Mask planes to ignore when calculating statistics of image (for thresholdType=stdev)",
143 default=[
'BAD',
'SAT',
'EDGE',
'NO_DATA'],
156 for maskPlane
in (
"DETECTED",
"DETECTED_NEGATIVE"):
162 """Create the detection task. Most arguments are simply passed onto pipe.base.Task.
166 schema : `lsst.afw.table.Schema`
167 Schema object used to create the output `lsst.afw.table.SourceCatalog`
169 Keyword arguments passed to `lsst.pipe.base.task.Task.__init__`
171 If schema is not None and configured for 'both' detections,
172 a 'flags.negative' field will be added to label detections made with a
177 This task can add fields to the schema, so any code calling this task must ensure that
178 these columns are indeed present in the input match list.
181 ConfigClass = SourceDetectionConfig
182 _DefaultName =
"sourceDetection"
185 pipeBase.Task.__init__(self, **kwds)
186 if schema
is not None and self.config.thresholdPolarity ==
"both":
188 "flags_negative", type=
"Flag",
189 doc=
"set if source was detected as significantly negative"
192 if self.config.thresholdPolarity ==
"both":
193 self.log.
warning(
"Detection polarity set to 'both', but no flag will be "
194 "set to distinguish between positive and negative detections")
196 if self.config.reEstimateBackground:
197 self.makeSubtask(
"background")
198 if self.config.doTempLocalBackground:
199 self.makeSubtask(
"tempLocalBackground")
200 if self.config.doTempWideBackground:
201 self.makeSubtask(
"tempWideBackground")
204 def run(self, table, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None):
205 """Run source detection and create a SourceCatalog of detections.
209 table : `lsst.afw.table.SourceTable`
210 Table object that will be used to create the SourceCatalog.
211 exposure : `lsst.afw.image.Exposure`
212 Exposure to process; DETECTED mask plane will be set in-place.
214 If True, smooth the image before detection using a Gaussian of width
215 ``sigma``, or the measured PSF width. Set to False when running on
216 e.g. a pre-convolved image, or a mask plane.
218 Sigma of PSF (pixels); used for smoothing and to grow detections;
219 if None then measure the sigma of the PSF of the exposure
221 Clear DETECTED{,_NEGATIVE} planes before running detection.
223 Exposure identifier; unused by this implementation, but used for
224 RNG seed by subclasses.
228 result : `lsst.pipe.base.Struct`
230 The detected sources (`lsst.afw.table.SourceCatalog`)
232 The result resturned by `detectFootprints`
233 (`lsst.pipe.base.Struct`).
238 If flags.negative is needed, but isn't in table's schema.
239 lsst.pipe.base.TaskError
240 If sigma=None, doSmooth=True and the exposure has no PSF.
244 If you want to avoid dealing with Sources and Tables, you can use
245 detectFootprints() to just get the `lsst.afw.detection.FootprintSet`s.
248 raise ValueError(
"Table has incorrect Schema")
249 results = self.
detectFootprintsdetectFootprints(exposure=exposure, doSmooth=doSmooth, sigma=sigma,
250 clearMask=clearMask, expId=expId)
252 sources.reserve(results.numPos + results.numNeg)
254 results.negative.makeSources(sources)
256 for record
in sources:
259 results.positive.makeSources(sources)
260 results.fpSets = results.copy()
261 results.sources = sources
264 def display(self, exposure, results, convolvedImage=None):
265 """Display detections if so configured
267 Displays the ``exposure`` in frame 0, overlays the detection peaks.
269 Requires that ``lsstDebug`` has been set up correctly, so that
270 ``lsstDebug.Info("lsst.meas.algorithms.detection")`` evaluates `True`.
272 If the ``convolvedImage`` is non-`None` and
273 ``lsstDebug.Info("lsst.meas.algorithms.detection") > 1``, the
274 ``convolvedImage`` will be displayed in frame 1.
278 exposure : `lsst.afw.image.Exposure`
279 Exposure to display, on which will be plotted the detections.
280 results : `lsst.pipe.base.Struct`
281 Results of the 'detectFootprints' method, containing positive and
282 negative footprints (which contain the peak positions that we will
283 plot). This is a `Struct` with ``positive`` and ``negative``
284 elements that are of type `lsst.afw.detection.FootprintSet`.
285 convolvedImage : `lsst.afw.image.Image`, optional
286 Convolved image used for thresholding.
299 afwDisplay.setDefaultMaskTransparency(75)
301 disp0 = afwDisplay.Display(frame=0)
302 disp0.mtv(exposure, title=
"detection")
304 def plotPeaks(fps, ctype):
307 with disp0.Buffering():
308 for fp
in fps.getFootprints():
309 for pp
in fp.getPeaks():
310 disp0.dot(
"+", pp.getFx(), pp.getFy(), ctype=ctype)
311 plotPeaks(results.positive,
"yellow")
312 plotPeaks(results.negative,
"red")
314 if convolvedImage
and display > 1:
315 disp1 = afwDisplay.Display(frame=1)
316 disp1.mtv(convolvedImage, title=
"PSF smoothed")
319 """Apply a temporary local background subtraction
321 This temporary local background serves to suppress noise fluctuations
322 in the wings of bright objects.
324 Peaks in the footprints will be updated.
328 exposure : `lsst.afw.image.Exposure`
329 Exposure for which to fit local background.
330 middle : `lsst.afw.image.MaskedImage`
331 Convolved image on which detection will be performed
332 (typically smaller than ``exposure`` because the
333 half-kernel has been removed around the edges).
334 results : `lsst.pipe.base.Struct`
335 Results of the 'detectFootprints' method, containing positive and
336 negative footprints (which contain the peak positions that we will
337 plot). This is a `Struct` with ``positive`` and ``negative``
338 elements that are of type `lsst.afw.detection.FootprintSet`.
343 bg = self.tempLocalBackground.fitBackground(exposure.getMaskedImage())
344 bgImage = bg.getImageF(self.tempLocalBackground.config.algorithm,
345 self.tempLocalBackground.config.undersampleStyle)
346 middle -= bgImage.Factory(bgImage, middle.getBBox())
347 thresholdPos = self.
makeThresholdmakeThreshold(middle,
"positive")
348 thresholdNeg = self.
makeThresholdmakeThreshold(middle,
"negative")
349 if self.config.thresholdPolarity !=
"negative":
350 self.
updatePeaksupdatePeaks(results.positive, middle, thresholdPos)
351 if self.config.thresholdPolarity !=
"positive":
352 self.
updatePeaksupdatePeaks(results.negative, middle, thresholdNeg)
355 """Clear the DETECTED and DETECTED_NEGATIVE mask planes
357 Removes any previous detection mask in preparation for a new
362 mask : `lsst.afw.image.Mask`
365 mask &= ~(mask.getPlaneBitMask(
"DETECTED") | mask.getPlaneBitMask(
"DETECTED_NEGATIVE"))
368 """Calculate size of smoothing kernel
370 Uses the ``nSigmaForKernel`` configuration parameter. Note
371 that that is the full width of the kernel bounding box
372 (so a value of 7 means 3.5 sigma on either side of center).
373 The value will be rounded up to the nearest odd integer.
378 Gaussian sigma of smoothing kernel.
383 Size of the smoothing kernel.
385 return (int(sigma * self.config.nSigmaForKernel + 0.5)//2)*2 + 1
388 """Retrieve the PSF for an exposure
390 If ``sigma`` is provided, we make a ``GaussianPsf`` with that,
391 otherwise use the one from the ``exposure``.
395 exposure : `lsst.afw.image.Exposure`
396 Exposure from which to retrieve the PSF.
397 sigma : `float`, optional
398 Gaussian sigma to use if provided.
402 psf : `lsst.afw.detection.Psf`
403 PSF to use for detection.
406 psf = exposure.getPsf()
408 raise RuntimeError(
"Unable to determine PSF to use for detection: no sigma provided")
409 sigma = psf.computeShape().getDeterminantRadius()
415 """Convolve the image with the PSF
417 We convolve the image with a Gaussian approximation to the PSF,
418 because this is separable and therefore fast. It's technically a
419 correlation rather than a convolution, but since we use a symmetric
420 Gaussian there's no difference.
422 The convolution can be disabled with ``doSmooth=False``. If we do
423 convolve, we mask the edges as ``EDGE`` and return the convolved image
424 with the edges removed. This is because we can't convolve the edges
425 because the kernel would extend off the image.
429 maskedImage : `lsst.afw.image.MaskedImage`
431 psf : `lsst.afw.detection.Psf`
432 PSF to convolve with (actually with a Gaussian approximation
435 Actually do the convolution? Set to False when running on
436 e.g. a pre-convolved image, or a mask plane.
438 Return Struct contents
439 ----------------------
440 middle : `lsst.afw.image.MaskedImage`
441 Convolved image, without the edges.
443 Gaussian sigma used for the convolution.
445 self.metadata.
set(
"doSmooth", doSmooth)
446 sigma = psf.computeShape().getDeterminantRadius()
447 self.metadata.
set(
"sigma", sigma)
450 middle = maskedImage.Factory(maskedImage, deep=
True)
451 return pipeBase.Struct(middle=middle, sigma=sigma)
456 self.metadata.
set(
"smoothingKernelWidth", kWidth)
457 gaussFunc = afwMath.GaussianFunction1D(sigma)
460 convolvedImage = maskedImage.Factory(maskedImage.getBBox())
466 goodBBox = gaussKernel.shrinkBBox(convolvedImage.getBBox())
467 middle = convolvedImage.Factory(convolvedImage, goodBBox, afwImage.PARENT,
False)
471 self.
setEdgeBitssetEdgeBits(maskedImage, goodBBox, maskedImage.getMask().getPlaneBitMask(
"EDGE"))
473 return pipeBase.Struct(middle=middle, sigma=sigma)
476 """Apply thresholds to the convolved image
478 Identifies ``Footprint``s, both positive and negative.
480 The threshold can be modified by the provided multiplication
485 middle : `lsst.afw.image.MaskedImage`
486 Convolved image to threshold.
487 bbox : `lsst.geom.Box2I`
488 Bounding box of unconvolved image.
490 Multiplier for the configured threshold.
492 Return Struct contents
493 ----------------------
494 positive : `lsst.afw.detection.FootprintSet` or `None`
495 Positive detection footprints, if configured.
496 negative : `lsst.afw.detection.FootprintSet` or `None`
497 Negative detection footprints, if configured.
499 Multiplier for the configured threshold.
501 results = pipeBase.Struct(positive=
None, negative=
None, factor=factor)
503 if self.config.reEstimateBackground
or self.config.thresholdPolarity !=
"negative":
504 threshold = self.
makeThresholdmakeThreshold(middle,
"positive", factor=factor)
509 self.config.minPixels
511 results.positive.setRegion(bbox)
512 if self.config.reEstimateBackground
or self.config.thresholdPolarity !=
"positive":
513 threshold = self.
makeThresholdmakeThreshold(middle,
"negative", factor=factor)
518 self.config.minPixels
520 results.negative.setRegion(bbox)
525 """Finalize the detected footprints
527 Grows the footprints, sets the ``DETECTED`` and ``DETECTED_NEGATIVE``
528 mask planes, and logs the results.
530 ``numPos`` (number of positive footprints), ``numPosPeaks`` (number
531 of positive peaks), ``numNeg`` (number of negative footprints),
532 ``numNegPeaks`` (number of negative peaks) entries are added to the
537 mask : `lsst.afw.image.Mask`
538 Mask image on which to flag detected pixels.
539 results : `lsst.pipe.base.Struct`
540 Struct of detection results, including ``positive`` and
541 ``negative`` entries; modified.
543 Gaussian sigma of PSF.
545 Multiplier for the configured threshold.
547 for polarity, maskName
in ((
"positive",
"DETECTED"), (
"negative",
"DETECTED_NEGATIVE")):
548 fpSet = getattr(results, polarity)
551 if self.config.nSigmaToGrow > 0:
552 nGrow = int((self.config.nSigmaToGrow * sigma) + 0.5)
553 self.metadata.
set(
"nGrow", nGrow)
554 if self.config.combinedGrow:
557 stencil = (afwGeom.Stencil.CIRCLE
if self.config.isotropicGrow
else
558 afwGeom.Stencil.MANHATTAN)
560 fp.dilate(nGrow, stencil)
561 fpSet.setMask(mask, maskName)
562 if not self.config.returnOriginalFootprints:
563 setattr(results, polarity, fpSet)
566 results.numPosPeaks = 0
568 results.numNegPeaks = 0
572 if results.positive
is not None:
573 results.numPos = len(results.positive.getFootprints())
574 results.numPosPeaks = sum(len(fp.getPeaks())
for fp
in results.positive.getFootprints())
575 positive =
" %d positive peaks in %d footprints" % (results.numPosPeaks, results.numPos)
576 if results.negative
is not None:
577 results.numNeg = len(results.negative.getFootprints())
578 results.numNegPeaks = sum(len(fp.getPeaks())
for fp
in results.negative.getFootprints())
579 negative =
" %d negative peaks in %d footprints" % (results.numNegPeaks, results.numNeg)
581 self.log.
info(
"Detected%s%s%s to %g %s",
582 positive,
" and" if positive
and negative
else "", negative,
583 self.config.thresholdValue*self.config.includeThresholdMultiplier*factor,
584 "DN" if self.config.thresholdType ==
"value" else "sigma")
587 """Estimate the background after detection
591 maskedImage : `lsst.afw.image.MaskedImage`
592 Image on which to estimate the background.
593 backgrounds : `lsst.afw.math.BackgroundList`
594 List of backgrounds; modified.
598 bg : `lsst.afw.math.backgroundMI`
599 Empirical background model.
601 bg = self.background.fitBackground(maskedImage)
602 if self.config.adjustBackground:
603 self.log.
warning(
"Fiddling the background by %g", self.config.adjustBackground)
604 bg += self.config.adjustBackground
605 self.log.
info(
"Resubtracting the background after object detection")
606 maskedImage -= bg.getImageF(self.background.config.algorithm,
607 self.background.config.undersampleStyle)
609 actrl = bg.getBackgroundControl().getApproximateControl()
611 bg.getAsUsedUndersampleStyle(), actrl.getStyle(), actrl.getOrderX(),
612 actrl.getOrderY(), actrl.getWeighting()))
616 """Clear unwanted results from the Struct of results
618 If we specifically want only positive or only negative detections,
619 drop the ones we don't want, and its associated mask plane.
623 mask : `lsst.afw.image.Mask`
625 results : `lsst.pipe.base.Struct`
626 Detection results, with ``positive`` and ``negative`` elements;
629 if self.config.thresholdPolarity ==
"positive":
630 if self.config.reEstimateBackground:
631 mask &= ~mask.getPlaneBitMask(
"DETECTED_NEGATIVE")
632 results.negative =
None
633 elif self.config.thresholdPolarity ==
"negative":
634 if self.config.reEstimateBackground:
635 mask &= ~mask.getPlaneBitMask(
"DETECTED")
636 results.positive =
None
639 def detectFootprints(self, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None):
640 """Detect footprints on an exposure.
644 exposure : `lsst.afw.image.Exposure`
645 Exposure to process; DETECTED{,_NEGATIVE} mask plane will be
647 doSmooth : `bool`, optional
648 If True, smooth the image before detection using a Gaussian
649 of width ``sigma``, or the measured PSF width of ``exposure``.
650 Set to False when running on e.g. a pre-convolved image, or a mask
652 sigma : `float`, optional
653 Gaussian Sigma of PSF (pixels); used for smoothing and to grow
654 detections; if `None` then measure the sigma of the PSF of the
656 clearMask : `bool`, optional
657 Clear both DETECTED and DETECTED_NEGATIVE planes before running
659 expId : `dict`, optional
660 Exposure identifier; unused by this implementation, but used for
661 RNG seed by subclasses.
663 Return Struct contents
664 ----------------------
665 positive : `lsst.afw.detection.FootprintSet`
666 Positive polarity footprints (may be `None`)
667 negative : `lsst.afw.detection.FootprintSet`
668 Negative polarity footprints (may be `None`)
670 Number of footprints in positive or 0 if detection polarity was
673 Number of footprints in negative or 0 if detection polarity was
675 background : `lsst.afw.math.BackgroundList`
676 Re-estimated background. `None` if
677 ``reEstimateBackground==False``.
679 Multiplication factor applied to the configured detection
682 maskedImage = exposure.maskedImage
685 self.
clearMaskclearMask(maskedImage.getMask())
687 psf = self.
getPsfgetPsf(exposure, sigma=sigma)
689 convolveResults = self.
convolveImageconvolveImage(maskedImage, psf, doSmooth=doSmooth)
690 middle = convolveResults.middle
691 sigma = convolveResults.sigma
693 results = self.
applyThresholdapplyThreshold(middle, maskedImage.getBBox())
695 if self.config.doTempLocalBackground:
699 if self.config.reEstimateBackground:
703 self.
displaydisplay(exposure, results, middle)
708 """Make an afw.detection.Threshold object corresponding to the task's
709 configuration and the statistics of the given image.
713 image : `afw.image.MaskedImage`
714 Image to measure noise statistics from if needed.
715 thresholdParity: `str`
716 One of "positive" or "negative", to set the kind of fluctuations
717 the Threshold will detect.
719 Factor by which to multiply the configured detection threshold.
720 This is useful for tweaking the detection threshold slightly.
724 threshold : `lsst.afw.detection.Threshold`
727 parity =
False if thresholdParity ==
"negative" else True
728 thresholdValue = self.config.thresholdValue
729 thresholdType = self.config.thresholdType
730 if self.config.thresholdType ==
'stdev':
731 bad = image.getMask().getPlaneBitMask(self.config.statsMask)
733 sctrl.setAndMask(bad)
735 thresholdValue *= stats.getValue(afwMath.STDEVCLIP)
736 thresholdType =
'value'
739 threshold.setIncludeMultiplier(self.config.includeThresholdMultiplier)
743 """Update the Peaks in a FootprintSet by detecting new Footprints and
744 Peaks in an image and using the new Peaks instead of the old ones.
748 fpSet : `afw.detection.FootprintSet`
749 Set of Footprints whose Peaks should be updated.
750 image : `afw.image.MaskedImage`
751 Image to detect new Footprints and Peak in.
752 threshold : `afw.detection.Threshold`
753 Threshold object for detection.
755 Input Footprints with fewer Peaks than self.config.nPeaksMaxSimple
756 are not modified, and if no new Peaks are detected in an input
757 Footprint, the brightest original Peak in that Footprint is kept.
759 for footprint
in fpSet.getFootprints():
760 oldPeaks = footprint.getPeaks()
761 if len(oldPeaks) <= self.config.nPeaksMaxSimple:
766 sub = image.Factory(image, footprint.getBBox())
771 self.config.minPixels
774 for fpForPeaks
in fpSetForPeaks.getFootprints():
775 for peak
in fpForPeaks.getPeaks():
776 if footprint.contains(peak.getI()):
777 newPeaks.append(peak)
778 if len(newPeaks) > 0:
780 oldPeaks.extend(newPeaks)
786 """Set the edgeBitmask bits for all of maskedImage outside goodBBox
790 maskedImage : `lsst.afw.image.MaskedImage`
791 Image on which to set edge bits in the mask.
792 goodBBox : `lsst.geom.Box2I`
793 Bounding box of good pixels, in ``LOCAL`` coordinates.
794 edgeBitmask : `lsst.afw.image.MaskPixel`
795 Bit mask to OR with the existing mask bits in the region
796 outside ``goodBBox``.
798 msk = maskedImage.getMask()
800 mx0, my0 = maskedImage.getXY0()
801 for x0, y0, w, h
in ([0, 0,
802 msk.getWidth(), goodBBox.getBeginY() - my0],
803 [0, goodBBox.getEndY() - my0, msk.getWidth(),
804 maskedImage.getHeight() - (goodBBox.getEndY() - my0)],
806 goodBBox.getBeginX() - mx0, msk.getHeight()],
807 [goodBBox.getEndX() - mx0, 0,
808 maskedImage.getWidth() - (goodBBox.getEndX() - mx0), msk.getHeight()],
812 edgeMask |= edgeBitmask
816 """Context manager for removing wide (large-scale) background
818 Removing a wide (large-scale) background helps to suppress the
819 detection of large footprints that may overwhelm the deblender.
820 It does, however, set a limit on the maximum scale of objects.
822 The background that we remove will be restored upon exit from
827 exposure : `lsst.afw.image.Exposure`
828 Exposure on which to remove large-scale background.
832 context : context manager
833 Context manager that will ensure the temporary wide background
836 doTempWideBackground = self.config.doTempWideBackground
837 if doTempWideBackground:
838 self.log.
info(
"Applying temporary wide background subtraction")
839 original = exposure.maskedImage.image.array[:].copy()
840 self.tempWideBackground.
run(exposure).background
843 image = exposure.maskedImage.image
844 mask = exposure.maskedImage.mask
845 noData = mask.array & mask.getPlaneBitMask(
"NO_DATA") > 0
846 isGood = mask.array & mask.getPlaneBitMask(self.config.statsMask) == 0
847 image.array[noData] = np.median(image.array[~noData & isGood])
851 if doTempWideBackground:
852 exposure.maskedImage.image.array[:] = original
856 """Add a set of exposures together.
860 exposureList : `list` of `lsst.afw.image.Exposure`
861 Sequence of exposures to add.
865 addedExposure : `lsst.afw.image.Exposure`
866 An exposure of the same size as each exposure in ``exposureList``,
867 with the metadata from ``exposureList[0]`` and a masked image equal
868 to the sum of all the exposure's masked images.
870 exposure0 = exposureList[0]
871 image0 = exposure0.getMaskedImage()
873 addedImage = image0.Factory(image0,
True)
874 addedImage.setXY0(image0.getXY0())
876 for exposure
in exposureList[1:]:
877 image = exposure.getMaskedImage()
880 addedExposure = exposure0.Factory(addedImage, exposure0.getWcs())
A circularly symmetric Gaussian Psf class with no spatial variation, intended mostly for testing purp...
Parameters to control convolution.
A kernel described by a pair of functions: func(x, y) = colFunc(x) * rowFunc(y)
Pass parameters to a Statistics object.
An integer coordinate rectangle.
def tempWideBackgroundContext(self, exposure)
def getPsf(self, exposure, sigma=None)
def __init__(self, schema=None, **kwds)
def makeThreshold(self, image, thresholdParity, factor=1.0)
def run(self, table, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None)
def convolveImage(self, maskedImage, psf, doSmooth=True)
def applyTempLocalBackground(self, exposure, middle, results)
def detectFootprints(self, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None)
def reEstimateBackground(self, maskedImage, backgrounds)
def updatePeaks(self, fpSet, image, threshold)
def finalizeFootprints(self, mask, results, sigma, factor=1.0)
def setEdgeBits(maskedImage, goodBBox, edgeBitmask)
def clearUnwantedResults(self, mask, results)
def clearMask(self, mask)
def display(self, exposure, results, convolvedImage=None)
def applyThreshold(self, middle, bbox, factor=1.0)
def calculateKernelSize(self, sigma)
daf::base::PropertySet * set
Threshold createThreshold(const double value, const std::string type="value", const bool polarity=true)
Factory method for creating Threshold objects.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
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)
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image.
def addExposures(exposureList)