23 from __future__
import absolute_import, division, print_function
25 __all__ = (
"SourceDetectionConfig",
"SourceDetectionTask",
"addExposures")
35 from .subtractBackground
import SubtractBackgroundTask
39 """!Configuration parameters for the SourceDetectionTask 41 minPixels = pexConfig.RangeField(
42 doc=
"detected sources with fewer than the specified number of pixels will be ignored",
43 dtype=int, optional=
False, default=1, min=0,
45 isotropicGrow = pexConfig.Field(
46 doc=
"Pixels should be grown as isotropically as possible (slower)",
47 dtype=bool, optional=
False, default=
False,
49 nSigmaToGrow = pexConfig.Field(
50 doc=
"Grow detections by nSigmaToGrow * [PSF RMS width]; if 0 then do not grow",
51 dtype=float, default=2.4,
53 returnOriginalFootprints = pexConfig.Field(
54 doc=
"Grow detections to set the image mask bits, but return the original (not-grown) footprints",
55 dtype=bool, optional=
False, default=
False,
57 thresholdValue = pexConfig.RangeField(
58 doc=
"Threshold for footprints",
59 dtype=float, optional=
False, default=5.0, min=0.0,
61 includeThresholdMultiplier = pexConfig.RangeField(
62 doc=
"Include threshold relative to thresholdValue",
63 dtype=float, default=1.0, min=0.0,
65 thresholdType = pexConfig.ChoiceField(
66 doc=
"specifies the desired flavor of Threshold",
67 dtype=str, optional=
False, default=
"stdev",
69 "variance":
"threshold applied to image variance",
70 "stdev":
"threshold applied to image std deviation",
71 "value":
"threshold applied to image value",
72 "pixel_stdev":
"threshold applied to per-pixel std deviation",
75 thresholdPolarity = pexConfig.ChoiceField(
76 doc=
"specifies whether to detect positive, or negative sources, or both",
77 dtype=str, optional=
False, default=
"positive",
79 "positive":
"detect only positive sources",
80 "negative":
"detect only negative sources",
81 "both":
"detect both positive and negative sources",
84 adjustBackground = pexConfig.Field(
86 doc=
"Fiddle factor to add to the background; debugging only",
89 reEstimateBackground = pexConfig.Field(
91 doc=
"Estimate the background again after final source detection?",
92 default=
True, optional=
False,
94 background = pexConfig.ConfigurableField(
95 doc=
"Background re-estimation; ignored if reEstimateBackground false",
96 target=SubtractBackgroundTask,
98 tempLocalBackground = pexConfig.ConfigurableField(
99 doc=(
"A small-scale, temporary background estimation step run between " 100 "detecting above-threshold regions and detecting the peaks within " 101 "them; used to avoid detecting spuerious peaks in the wings."),
102 target=SubtractBackgroundTask,
104 doTempLocalBackground = pexConfig.Field(
106 doc=
"Enable temporary local background subtraction? (see tempLocalBackground)",
109 nPeaksMaxSimple = pexConfig.Field(
111 doc=(
"The maximum number of peaks in a Footprint before trying to " 112 "replace its peaks using the temporary local background"),
115 nSigmaForKernel = pexConfig.Field(
117 doc=(
"Multiple of PSF RMS size to use for convolution kernel bounding box size; " 118 "note that this is not a half-size. The size will be rounded up to the nearest odd integer"),
121 statsMask = pexConfig.ListField(
123 doc=
"Mask planes to ignore when calculating statistics of image (for thresholdType=stdev)",
124 default=[
'BAD',
'SAT',
'EDGE',
'NO_DATA'],
142 \anchor SourceDetectionTask_ 144 \brief Detect positive and negative sources on an exposure and return a new \link table.SourceCatalog\endlink. 146 \section meas_algorithms_detection_Contents Contents 148 - \ref meas_algorithms_detection_Purpose 149 - \ref meas_algorithms_detection_Initialize 150 - \ref meas_algorithms_detection_Invoke 151 - \ref meas_algorithms_detection_Config 152 - \ref meas_algorithms_detection_Debug 153 - \ref meas_algorithms_detection_Example 155 \section meas_algorithms_detection_Purpose Description 157 \copybrief SourceDetectionTask 159 \section meas_algorithms_detection_Initialize Task initialisation 161 \copydoc \_\_init\_\_ 163 \section meas_algorithms_detection_Invoke Invoking the Task 167 \section meas_algorithms_detection_Config Configuration parameters 169 See \ref SourceDetectionConfig 171 \section meas_algorithms_detection_Debug Debug variables 173 The \link lsst.pipe.base.cmdLineTask.CmdLineTask command line task\endlink interface supports a 174 flag \c -d to import \b debug.py from your \c PYTHONPATH; see \ref baseDebug for more about \b debug.py files. 176 The available variables in SourceDetectionTask are: 180 - If True, display the exposure on ds9's frame 0. +ve detections in blue, -ve detections in cyan 181 - If display > 1, display the convolved exposure on frame 1 184 \section meas_algorithms_detection_Example A complete example of using SourceDetectionTask 186 This code is in \link measAlgTasks.py\endlink in the examples directory, and can be run as \em e.g. 188 examples/measAlgTasks.py --ds9 190 \dontinclude measAlgTasks.py 191 The example also runs the SourceMeasurementTask; see \ref meas_algorithms_measurement_Example for more 194 Import the task (there are some other standard imports; read the file if you're confused) 195 \skipline SourceDetectionTask 197 We need to create our task before processing any data as the task constructor 198 can add an extra column to the schema, but first we need an almost-empty Schema 199 \skipline makeMinimalSchema 200 after which we can call the constructor: 201 \skip SourceDetectionTask.ConfigClass 204 We're now ready to process the data (we could loop over multiple exposures/catalogues using the same 205 task objects). First create the output table: 208 And process the image 210 (You may not be happy that the threshold was set in the config before creating the Task rather than being set 211 separately for each exposure. You \em can reset it just before calling the run method if you must, but we 212 should really implement a better solution). 214 We can then unpack and use the results: 219 To investigate the \ref meas_algorithms_detection_Debug, put something like 223 di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively 224 if name == "lsst.meas.algorithms.detection": 229 lsstDebug.Info = DebugInfo 231 into your debug.py file and run measAlgTasks.py with the \c --debug flag. 233 ConfigClass = SourceDetectionConfig
234 _DefaultName =
"sourceDetection" 237 """!Create the detection task. Most arguments are simply passed onto pipe.base.Task. 239 \param schema An lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog 240 \param **kwds Keyword arguments passed to lsst.pipe.base.task.Task.__init__. 242 If schema is not None and configured for 'both' detections, 243 a 'flags.negative' field will be added to label detections made with a 246 \note This task can add fields to the schema, so any code calling this task must ensure that 247 these columns are indeed present in the input match list; see \ref Example 249 pipeBase.Task.__init__(self, **kwds)
250 if schema
is not None and self.config.thresholdPolarity ==
"both":
252 "flags_negative", type=
"Flag",
253 doc=
"set if source was detected as significantly negative" 256 if self.config.thresholdPolarity ==
"both":
257 self.log.warn(
"Detection polarity set to 'both', but no flag will be " 258 "set to distinguish between positive and negative detections")
260 if self.config.reEstimateBackground:
261 self.makeSubtask(
"background")
262 if self.config.doTempLocalBackground:
263 self.makeSubtask(
"tempLocalBackground")
266 def run(self, table, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None):
267 """!Run source detection and create a SourceCatalog. 269 \param table lsst.afw.table.SourceTable object that will be used to create the SourceCatalog. 270 \param exposure Exposure to process; DETECTED mask plane will be set in-place. 271 \param doSmooth if True, smooth the image before detection using a Gaussian of width sigma 273 \param sigma sigma of PSF (pixels); used for smoothing and to grow detections; 274 if None then measure the sigma of the PSF of the exposure (default: None) 275 \param clearMask Clear DETECTED{,_NEGATIVE} planes before running detection (default: True) 276 \param expId Exposure identifier (integer); unused by this implementation, but used for 277 RNG seed by subclasses. 279 \return a lsst.pipe.base.Struct with: 280 - sources -- an lsst.afw.table.SourceCatalog object 281 - fpSets --- lsst.pipe.base.Struct returned by \link detectFootprints \endlink 283 \throws ValueError if flags.negative is needed, but isn't in table's schema 284 \throws lsst.pipe.base.TaskError if sigma=None, doSmooth=True and the exposure has no PSF 287 If you want to avoid dealing with Sources and Tables, you can use detectFootprints() 288 to just get the afw::detection::FootprintSet%s. 291 raise ValueError(
"Table has incorrect Schema")
292 results = self.
detectFootprints(exposure=exposure, doSmooth=doSmooth, sigma=sigma,
293 clearMask=clearMask, expId=expId)
294 sources = afwTable.SourceCatalog(table)
295 table.preallocate(results.numPos + results.numNeg)
297 results.negative.makeSources(sources)
299 for record
in sources:
302 results.positive.makeSources(sources)
303 results.fpSets = results.copy()
304 results.sources = sources
308 makeSourceCatalog = run
310 def display(self, exposure, results, convolvedImage=None):
311 """Display detections if so configured 313 Displays the ``exposure`` in frame 0, overlays the detection peaks. 315 Requires that ``lsstDebug`` has been set up correctly, so that 316 ``lsstDebug.Info("lsst.meas.algorithms.detection")`` evaluates `True`. 318 If the ``convolvedImage`` is non-`None` and 319 ``lsstDebug.Info("lsst.meas.algorithms.detection") > 1``, the 320 ``convolvedImage`` will be displayed in frame 1. 324 exposure : `lsst.afw.image.Exposure` 325 Exposure to display, on which will be plotted the detections. 326 results : `lsst.pipe.base.Struct` 327 Results of the 'detectFootprints' method, containing positive and 328 negative footprints (which contain the peak positions that we will 329 plot). This is a `Struct` with ``positive`` and ``negative`` 330 elements that are of type `lsst.afw.detection.FootprintSet`. 331 convolvedImage : `lsst.afw.image.Image`, optional 332 Convolved image used for thresholding. 345 disp0 = lsst.afw.display.Display(frame=0)
346 disp0.mtv(exposure, title=
"detection")
348 def plotPeaks(fps, ctype):
351 with disp0.Buffering():
352 for fp
in fps.getFootprints():
353 for pp
in fp.getPeaks():
354 disp0.dot(
"+", pp.getFx(), pp.getFy(), ctype=ctype)
355 plotPeaks(results.positive,
"yellow")
356 plotPeaks(results.negative,
"red")
358 if convolvedImage
and display > 1:
359 disp1 = Display(frame=1)
360 disp1.mtv(convolvedImage, title=
"PSF smoothed")
363 """Apply a temporary local background subtraction 365 This temporary local background serves to suppress noise fluctuations 366 in the wings of bright objects. 368 Peaks in the footprints will be updated. 372 exposure : `lsst.afw.image.Exposure` 373 Exposure for which to fit local background. 374 middle : `lsst.afw.image.MaskedImage` 375 Convolved image on which detection will be performed 376 (typically smaller than ``exposure`` because the 377 half-kernel has been removed around the edges). 378 results : `lsst.pipe.base.Struct` 379 Results of the 'detectFootprints' method, containing positive and 380 negative footprints (which contain the peak positions that we will 381 plot). This is a `Struct` with ``positive`` and ``negative`` 382 elements that are of type `lsst.afw.detection.FootprintSet`. 387 bg = self.tempLocalBackground.fitBackground(exposure.getMaskedImage())
388 bgImage = bg.getImageF()
389 middle -= bgImage.Factory(bgImage, middle.getBBox())
392 if self.config.thresholdPolarity !=
"negative":
393 self.
updatePeaks(results.positive, middle, thresholdPos)
394 if self.config.thresholdPolarity !=
"positive":
395 self.
updatePeaks(results.negative, middle, thresholdNeg)
398 """Clear the DETECTED and DETECTED_NEGATIVE mask planes 400 Removes any previous detection mask in preparation for a new 405 mask : `lsst.afw.image.Mask` 408 mask &= ~(mask.getPlaneBitMask(
"DETECTED") | mask.getPlaneBitMask(
"DETECTED_NEGATIVE"))
411 """Calculate size of smoothing kernel 413 Uses the ``nSigmaForKernel`` configuration parameter. Note 414 that that is the full width of the kernel bounding box 415 (so a value of 7 means 3.5 sigma on either side of center). 416 The value will be rounded up to the nearest odd integer. 421 Gaussian sigma of smoothing kernel. 426 Size of the smoothing kernel. 428 return (int(sigma * self.config.nSigmaForKernel + 0.5)//2)*2 + 1
431 """Retrieve the PSF for an exposure 433 If ``sigma`` is provided, we make a ``GaussianPsf`` with that, 434 otherwise use the one from the ``exposure``. 438 exposure : `lsst.afw.image.Exposure` 439 Exposure from which to retrieve the PSF. 440 sigma : `float`, optional 441 Gaussian sigma to use if provided. 445 psf : `lsst.afw.detection.Psf` 446 PSF to use for detection. 449 psf = exposure.getPsf()
451 raise RuntimeError(
"Unable to determine PSF to use for detection: no sigma provided")
452 sigma = psf.computeShape().getDeterminantRadius()
454 psf = afwDet.GaussianPsf(size, size, sigma)
458 """Convolve the image with the PSF 460 We convolve the image with a Gaussian approximation to the PSF, 461 because this is separable and therefore fast. It's technically a 462 correlation rather than a convolution, but since we use a symmetric 463 Gaussian there's no difference. 465 The convolution can be disabled with ``doSmooth=False``. If we do 466 convolve, we mask the edges as ``EDGE`` and return the convolved image 467 with the edges removed. This is because we can't convolve the edges 468 because the kernel would extend off the image. 472 maskedImage : `lsst.afw.image.MaskedImage` 474 psf : `lsst.afw.detection.Psf` 475 PSF to convolve with (actually with a Gaussian approximation 478 Actually do the convolution? 480 Return Struct contents 481 ---------------------- 482 middle : `lsst.afw.image.MaskedImage` 483 Convolved image, without the edges. 485 Gaussian sigma used for the convolution. 487 self.metadata.set(
"doSmooth", doSmooth)
488 sigma = psf.computeShape().getDeterminantRadius()
489 self.metadata.set(
"sigma", sigma)
492 middle = maskedImage.Factory(maskedImage)
493 return pipeBase.Struct(middle=middle, sigma=sigma)
498 self.metadata.set(
"smoothingKernelWidth", kWidth)
499 gaussFunc = afwMath.GaussianFunction1D(sigma)
502 convolvedImage = maskedImage.Factory(maskedImage.getBBox())
508 goodBBox = gaussKernel.shrinkBBox(convolvedImage.getBBox())
509 middle = convolvedImage.Factory(convolvedImage, goodBBox, afwImage.PARENT,
False)
513 self.
setEdgeBits(maskedImage, goodBBox, maskedImage.getMask().getPlaneBitMask(
"EDGE"))
515 return pipeBase.Struct(middle=middle, sigma=sigma)
518 """Apply thresholds to the convolved image 520 Identifies ``Footprint``s, both positive and negative. 522 The threshold can be modified by the provided multiplication 527 middle : `lsst.afw.image.MaskedImage` 528 Convolved image to threshold. 529 bbox : `lsst.afw.geom.Box2I` 530 Bounding box of unconvolved image. 532 Multiplier for the configured threshold. 534 Return Struct contents 535 ---------------------- 536 positive : `lsst.afw.detection.FootprintSet` or `None` 537 Positive detection footprints, if configured. 538 negative : `lsst.afw.detection.FootprintSet` or `None` 539 Negative detection footprints, if configured. 541 Multiplier for the configured threshold. 543 results = pipeBase.Struct(positive=
None, negative=
None, factor=factor)
545 if self.config.reEstimateBackground
or self.config.thresholdPolarity !=
"negative":
546 threshold = self.
makeThreshold(middle,
"positive", factor=factor)
547 results.positive = afwDet.FootprintSet(
551 self.config.minPixels
553 results.positive.setRegion(bbox)
554 if self.config.reEstimateBackground
or self.config.thresholdPolarity !=
"positive":
555 threshold = self.
makeThreshold(middle,
"negative", factor=factor)
556 results.negative = afwDet.FootprintSet(
560 self.config.minPixels
562 results.negative.setRegion(bbox)
567 """Finalize the detected footprints 569 Grows the footprints, sets the ``DETECTED`` and ``DETECTED_NEGATIVE`` 570 mask planes, and logs the results. 572 ``numPos`` (number of positive footprints), ``numPosPeaks`` (number 573 of positive peaks), ``numNeg`` (number of negative footprints), 574 ``numNegPeaks`` (number of negative peaks) entries are added to the 579 mask : `lsst.afw.image.Mask` 580 Mask image on which to flag detected pixels. 581 results : `lsst.pipe.base.Struct` 582 Struct of detection results, including ``positive`` and 583 ``negative`` entries; modified. 585 Gaussian sigma of PSF. 587 Multiplier for the configured threshold. 589 for polarity, maskName
in ((
"positive",
"DETECTED"), (
"negative",
"DETECTED_NEGATIVE")):
590 fpSet = getattr(results, polarity)
593 if self.config.nSigmaToGrow > 0:
594 nGrow = int((self.config.nSigmaToGrow * sigma) + 0.5)
595 self.metadata.set(
"nGrow", nGrow)
596 fpSet = afwDet.FootprintSet(fpSet, nGrow, self.config.isotropicGrow)
597 fpSet.setMask(mask, maskName)
598 if not self.config.returnOriginalFootprints:
599 setattr(results, polarity, fpSet)
602 results.numPosPeaks = 0
604 results.numNegPeaks = 0
608 if results.positive
is not None:
609 results.numPos = len(results.positive.getFootprints())
610 results.numPosPeaks = sum(len(fp.getPeaks())
for fp
in results.positive.getFootprints())
611 positive =
" %d positive peaks in %d footprints" % (results.numPosPeaks, results.numPos)
612 if results.negative
is not None:
613 results.numNeg = len(results.negative.getFootprints())
614 results.numNegPeaks = sum(len(fp.getPeaks())
for fp
in results.negative.getFootprints())
615 negative =
" %d negative peaks in %d footprints" % (results.numNegPeaks, results.numNeg)
617 self.log.info(
"Detected%s%s%s to %g %s" %
618 (positive,
" and" if positive
and negative
else "", negative,
619 self.config.thresholdValue*self.config.includeThresholdMultiplier*factor,
620 "DN" if self.config.thresholdType ==
"value" else "sigma"))
623 """Estimate the background after detection 627 maskedImage : `lsst.afw.image.MaskedImage` 628 Image on which to estimate the background. 629 results : `lsst.pipe.base.Struct` 630 Detection results; modified. 634 bg : `lsst.afw.math.backgroundMI` 635 Empirical background model. 637 bg = self.background.fitBackground(maskedImage)
638 if self.config.adjustBackground:
639 self.log.warn(
"Fiddling the background by %g", self.config.adjustBackground)
640 bg += self.config.adjustBackground
641 self.log.info(
"Resubtracting the background after object detection")
642 maskedImage -= bg.getImageF()
643 results.background = bg
647 """Clear unwanted results from the Struct of results 649 If we specifically want only positive or only negative detections, 650 drop the ones we don't want, and its associated mask plane. 654 mask : `lsst.afw.image.Mask` 656 results : `lsst.pipe.base.Struct` 657 Detection results, with ``positive`` and ``negative`` elements; 660 if self.config.thresholdPolarity ==
"positive":
661 if self.config.reEstimateBackground:
662 mask &= ~mask.getPlaneBitMask(
"DETECTED_NEGATIVE")
663 results.negative =
None 664 elif self.config.thresholdPolarity ==
"negative":
665 if self.config.reEstimateBackground:
666 mask &= ~mask.getPlaneBitMask(
"DETECTED")
667 results.positive =
None 670 def detectFootprints(self, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None):
671 """Detect footprints. 675 exposure : `lsst.afw.image.Exposure` 676 Exposure to process; DETECTED{,_NEGATIVE} mask plane will be 678 doSmooth : `bool`, optional 679 If True, smooth the image before detection using a Gaussian 681 sigma : `float`, optional 682 Gaussian Sigma of PSF (pixels); used for smoothing and to grow 683 detections; if `None` then measure the sigma of the PSF of the 685 clearMask : `bool`, optional 686 Clear both DETECTED and DETECTED_NEGATIVE planes before running 688 expId : `dict`, optional 689 Exposure identifier; unused by this implementation, but used for 690 RNG seed by subclasses. 692 Return Struct contents 693 ---------------------- 694 positive : `lsst.afw.detection.FootprintSet` 695 Positive polarity footprints (may be `None`) 696 negative : `lsst.afw.detection.FootprintSet` 697 Negative polarity footprints (may be `None`) 699 Number of footprints in positive or 0 if detection polarity was 702 Number of footprints in negative or 0 if detection polarity was 704 background : `lsst.afw.math.BackgroundMI` 705 Re-estimated background. `None` if 706 ``reEstimateBackground==False``. 708 Multiplication factor applied to the configured detection 711 maskedImage = exposure.maskedImage
716 psf = self.
getPsf(exposure, sigma=sigma)
717 convolveResults = self.
convolveImage(maskedImage, psf, doSmooth=doSmooth)
718 middle = convolveResults.middle
719 sigma = convolveResults.sigma
722 if self.config.doTempLocalBackground:
726 if self.config.reEstimateBackground:
730 self.
display(exposure, results, middle)
735 """Make an afw.detection.Threshold object corresponding to the task's 736 configuration and the statistics of the given image. 740 image : `afw.image.MaskedImage` 741 Image to measure noise statistics from if needed. 742 thresholdParity: `str` 743 One of "positive" or "negative", to set the kind of fluctuations 744 the Threshold will detect. 746 Factor by which to multiply the configured detection threshold. 747 This is useful for tweaking the detection threshold slightly. 751 threshold : `lsst.afw.detection.Threshold` 754 parity =
False if thresholdParity ==
"negative" else True 755 thresholdValue = self.config.thresholdValue
756 thresholdType = self.config.thresholdType
757 if self.config.thresholdType ==
'stdev':
758 bad = image.getMask().getPlaneBitMask(self.config.statsMask)
760 sctrl.setAndMask(bad)
762 thresholdValue *= stats.getValue(afwMath.STDEVCLIP)
763 thresholdType =
'value' 765 threshold = afwDet.createThreshold(thresholdValue*factor, thresholdType, parity)
766 threshold.setIncludeMultiplier(self.config.includeThresholdMultiplier)
770 """Update the Peaks in a FootprintSet by detecting new Footprints and 771 Peaks in an image and using the new Peaks instead of the old ones. 775 fpSet : `afw.detection.FootprintSet` 776 Set of Footprints whose Peaks should be updated. 777 image : `afw.image.MaskedImage` 778 Image to detect new Footprints and Peak in. 779 threshold : `afw.detection.Threshold` 780 Threshold object for detection. 782 Input Footprints with fewer Peaks than self.config.nPeaksMaxSimple 783 are not modified, and if no new Peaks are detected in an input 784 Footprint, the brightest original Peak in that Footprint is kept. 786 for footprint
in fpSet.getFootprints():
787 oldPeaks = footprint.getPeaks()
788 if len(oldPeaks) <= self.config.nPeaksMaxSimple:
793 sub = image.Factory(image, footprint.getBBox())
794 fpSetForPeaks = afwDet.FootprintSet(
798 self.config.minPixels
800 newPeaks = afwDet.PeakCatalog(oldPeaks.getTable())
801 for fpForPeaks
in fpSetForPeaks.getFootprints():
802 for peak
in fpForPeaks.getPeaks():
803 if footprint.contains(peak.getI()):
804 newPeaks.append(peak)
805 if len(newPeaks) > 0:
807 oldPeaks.extend(newPeaks)
813 """Set the edgeBitmask bits for all of maskedImage outside goodBBox 817 maskedImage : `lsst.afw.image.MaskedImage` 818 Image on which to set edge bits in the mask. 819 goodBBox : `lsst.afw.geom.Box2I` 820 Bounding box of good pixels, in ``LOCAL`` coordinates. 821 edgeBitmask : `lsst.afw.image.MaskPixel` 822 Bit mask to OR with the existing mask bits in the region 823 outside ``goodBBox``. 825 msk = maskedImage.getMask()
827 mx0, my0 = maskedImage.getXY0()
828 for x0, y0, w, h
in ([0, 0,
829 msk.getWidth(), goodBBox.getBeginY() - my0],
830 [0, goodBBox.getEndY() - my0, msk.getWidth(),
831 maskedImage.getHeight() - (goodBBox.getEndY() - my0)],
833 goodBBox.getBeginX() - mx0, msk.getHeight()],
834 [goodBBox.getEndX() - mx0, 0,
835 maskedImage.getWidth() - (goodBBox.getEndX() - mx0), msk.getHeight()],
839 edgeMask |= edgeBitmask
843 """Add a set of exposures together. 847 exposureList : `list` of `lsst.afw.image.Exposure` 848 Sequence of exposures to add. 852 addedExposure : `lsst.afw.image.Exposure` 853 An exposure of the same size as each exposure in ``exposureList``, 854 with the metadata from ``exposureList[0]`` and a masked image equal 855 to the sum of all the exposure's masked images. 857 exposure0 = exposureList[0]
858 image0 = exposure0.getMaskedImage()
860 addedImage = image0.Factory(image0,
True)
861 addedImage.setXY0(image0.getXY0())
863 for exposure
in exposureList[1:]:
864 image = exposure.getMaskedImage()
867 addedExposure = exposure0.Factory(addedImage, exposure0.getWcs())
def updatePeaks(self, fpSet, image, threshold)
def applyThreshold(self, middle, bbox, factor=1.0)
def addExposures(exposureList)
def detectFootprints(self, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None)
def convolveImage(self, maskedImage, psf, doSmooth=True)
def applyTempLocalBackground(self, exposure, middle, results)
def calculateKernelSize(self, sigma)
def display(self, exposure, results, convolvedImage=None)
Detect positive and negative sources on an exposure and return a new table.SourceCatalog.
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
def makeThreshold(self, image, thresholdParity, factor=1.0)
Configuration parameters for the SourceDetectionTask.
def clearUnwantedResults(self, mask, results)
def reEstimateBackground(self, maskedImage, results)
def getPsf(self, exposure, sigma=None)
def finalizeFootprints(self, mask, results, sigma, factor=1.0)
def __init__(self, schema=None, kwds)
Create the detection task.
def run(self, table, exposure, doSmooth=True, sigma=None, clearMask=True, expId=None)
Run source detection and create a SourceCatalog.
def clearMask(self, mask)
def setEdgeBits(maskedImage, goodBBox, edgeBitmask)
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, bool doNormalize, bool doCopyEdge=false)