LSST Applications g04e9c324dd+8c5ae1fdc5,g0644efc3f0+366663dc37,g123d84c11c+8c5ae1fdc5,g1ec0fe41b4+6ec6b74de1,g1fd858c14a+1be88e80db,g3533f9d6cb+366663dc37,g35bb328faa+8c5ae1fdc5,g35ef7ab7cf+285dd5b202,g53246c7159+8c5ae1fdc5,g60b5630c4e+366663dc37,g663da51e9b+41529343ca,g6735e52a0d+29de3d959a,g67b6fd64d1+57193d00fb,g7605de067c+8f72e4d2dc,g78460c75b0+7e33a9eb6d,g786e29fd12+668abc6043,g844c57033c+03ddc13274,g8852436030+e345a59dd4,g89139ef638+57193d00fb,g989de1cb63+57193d00fb,g9a0bdda227+852181cf57,g9f33ca652e+a2d35689ce,ga1e959baac+5fbc491aed,ga2f891cd6c+366663dc37,gabe3b4be73+8856018cbb,gabf8522325+cc757f8247,gac2eed3f23+57193d00fb,gb1101e3267+f6b489998a,gb89ab40317+57193d00fb,gcf25f946ba+e345a59dd4,gd107969129+227687db21,gd6cbbdb0b4+8e46defd2a,gde0f65d7ad+2dad650f79,ge278dab8ac+2322f1d6ea,ge410e46f29+57193d00fb,gf30d85a44d+8e3077faf9,gf5e32f922b+8c5ae1fdc5,gff02db199a+5c78c1866e,w.2025.28
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask Class Reference
Inheritance diagram for lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask:

Public Member Functions

 __init__ (self, **kwargs)
 
 run (self, exposure, sources, background)
 
 update_psf_stats (self, summary, psf, bbox, sources=None, image_mask=None, image_ap_corr_map=None, sources_is_astropy=False)
 
 update_wcs_stats (self, summary, wcs, bbox, visitInfo)
 
 update_photo_calib_stats (self, summary, photo_calib)
 
 update_background_stats (self, summary, background)
 
 update_masked_image_stats (self, summary, masked_image)
 
 update_effective_time_stats (self, summary, exposure)
 
 update_magnitude_limit_stats (self, summary, exposure)
 

Static Public Attributes

 ConfigClass = ComputeExposureSummaryStatsConfig
 

Static Protected Attributes

str _DefaultName = "computeExposureSummaryStats"
 

Detailed Description

Task to compute exposure summary statistics.

This task computes various quantities suitable for DPDD and other
downstream processing at the detector centers, including:
- expTime
- psfSigma
- psfArea
- psfIxx
- psfIyy
- psfIxy
- ra
- dec
- pixelScale (arcsec/pixel)
- zenithDistance
- zeroPoint
- skyBg
- skyNoise
- meanVar
- raCorners
- decCorners
- astromOffsetMean
- astromOffsetStd

These additional quantities are computed from the stars in the detector:
- psfStarDeltaE1Median
- psfStarDeltaE2Median
- psfStarDeltaE1Scatter
- psfStarDeltaE2Scatter
- psfStarDeltaSizeMedian
- psfStarDeltaSizeScatter
- psfStarScaledDeltaSizeScatter

These quantities are computed based on the PSF model and image mask
to assess the robustness of the PSF model across a given detector
(against, e.g., extrapolation instability):
- maxDistToNearestPsf
- psfTraceRadiusDelta
- psfApFluxDelta

This quantity is computed based on the aperture correction map, the
psfSigma, and the image mask to assess the robustness of the aperture
corrections across a given detector:
- psfApCorrSigmaScaledDelta

These quantities are computed to assess depth:
- effTime
- effTimePsfSigmaScale
- effTimeSkyBgScale
- effTimeZeroPointScale
- magLim

Definition at line 163 of file computeExposureSummaryStats.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.__init__ ( self,
** kwargs )

Definition at line 218 of file computeExposureSummaryStats.py.

218 def __init__(self, **kwargs):
219 super().__init__(**kwargs)
220
221 self.makeSubtask("starSelector")
222

Member Function Documentation

◆ run()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.run ( self,
exposure,
sources,
background )
Measure exposure statistics from the exposure, sources, and
background.

Parameters
----------
exposure : `lsst.afw.image.ExposureF`
sources : `lsst.afw.table.SourceCatalog`
background : `lsst.afw.math.BackgroundList`

Returns
-------
summary : `lsst.afw.image.ExposureSummary`

Definition at line 224 of file computeExposureSummaryStats.py.

224 def run(self, exposure, sources, background):
225 """Measure exposure statistics from the exposure, sources, and
226 background.
227
228 Parameters
229 ----------
230 exposure : `lsst.afw.image.ExposureF`
231 sources : `lsst.afw.table.SourceCatalog`
232 background : `lsst.afw.math.BackgroundList`
233
234 Returns
235 -------
236 summary : `lsst.afw.image.ExposureSummary`
237 """
238 self.log.info("Measuring exposure statistics")
239
241
242 # Set exposure time.
243 exposureTime = exposure.getInfo().getVisitInfo().getExposureTime()
244 summary.expTime = exposureTime
245
246 bbox = exposure.getBBox()
247
248 psf = exposure.getPsf()
249 self.update_psf_stats(
250 summary, psf, bbox, sources, image_mask=exposure.mask, image_ap_corr_map=exposure.apCorrMap
251 )
252
253 wcs = exposure.getWcs()
254 visitInfo = exposure.getInfo().getVisitInfo()
255 self.update_wcs_stats(summary, wcs, bbox, visitInfo)
256
257 photoCalib = exposure.getPhotoCalib()
258 self.update_photo_calib_stats(summary, photoCalib)
259
260 self.update_background_stats(summary, background)
261
262 self.update_masked_image_stats(summary, exposure.getMaskedImage())
263
264 self.update_magnitude_limit_stats(summary, exposure)
265
266 self.update_effective_time_stats(summary, exposure)
267
268 md = exposure.getMetadata()
269 if 'SFM_ASTROM_OFFSET_MEAN' in md:
270 summary.astromOffsetMean = md['SFM_ASTROM_OFFSET_MEAN']
271 summary.astromOffsetStd = md['SFM_ASTROM_OFFSET_STD']
272
273 return summary
274

◆ update_background_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_background_stats ( self,
summary,
background )
Compute summary-statistic fields that depend only on the
background model.

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
background : `lsst.afw.math.BackgroundList` or `None`
    Background model.  If `None`, all fields that depend on the
    background will be reset (generally to NaN).

Notes
-----
This does not include fields that depend on the background-subtracted
masked image; when the background changes, it should generally be
applied to the image and `update_masked_image_stats` should be called
as well.

Definition at line 518 of file computeExposureSummaryStats.py.

518 def update_background_stats(self, summary, background):
519 """Compute summary-statistic fields that depend only on the
520 background model.
521
522 Parameters
523 ----------
524 summary : `lsst.afw.image.ExposureSummaryStats`
525 Summary object to update in-place.
526 background : `lsst.afw.math.BackgroundList` or `None`
527 Background model. If `None`, all fields that depend on the
528 background will be reset (generally to NaN).
529
530 Notes
531 -----
532 This does not include fields that depend on the background-subtracted
533 masked image; when the background changes, it should generally be
534 applied to the image and `update_masked_image_stats` should be called
535 as well.
536 """
537 if background is not None:
538 bgStats = (bg[0].getStatsImage().getImage().array
539 for bg in background)
540 summary.skyBg = float(sum(np.median(bg[np.isfinite(bg)]) for bg in bgStats))
541 else:
542 summary.skyBg = float("nan")
543

◆ update_effective_time_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_effective_time_stats ( self,
summary,
exposure )
Compute effective exposure time statistics to estimate depth.

The effective exposure time is the equivalent shutter open
time that would be needed under nominal conditions to give the
same signal-to-noise for a point source as what is achieved by
the observation of interest. This metric combines measurements
of the point-spread function, the sky brightness, and the
transparency. It assumes that the observation is
sky-background dominated.

.. _teff_definitions:

The effective exposure time and its subcomponents are defined in [1]_.

References
----------

.. [1] Neilsen, E.H., Bernstein, G., Gruendl, R., and Kent, S. (2016).
       Limiting Magnitude, \tau, teff, and Image Quality in DES Year 1
       https://www.osti.gov/biblio/1250877/

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
exposure : `lsst.afw.image.ExposureF`
    Exposure to grab band and exposure time metadata

Definition at line 576 of file computeExposureSummaryStats.py.

576 def update_effective_time_stats(self, summary, exposure):
577 """Compute effective exposure time statistics to estimate depth.
578
579 The effective exposure time is the equivalent shutter open
580 time that would be needed under nominal conditions to give the
581 same signal-to-noise for a point source as what is achieved by
582 the observation of interest. This metric combines measurements
583 of the point-spread function, the sky brightness, and the
584 transparency. It assumes that the observation is
585 sky-background dominated.
586
587 .. _teff_definitions:
588
589 The effective exposure time and its subcomponents are defined in [1]_.
590
591 References
592 ----------
593
594 .. [1] Neilsen, E.H., Bernstein, G., Gruendl, R., and Kent, S. (2016).
595 Limiting Magnitude, \tau, teff, and Image Quality in DES Year 1
596 https://www.osti.gov/biblio/1250877/
597
598 Parameters
599 ----------
600 summary : `lsst.afw.image.ExposureSummaryStats`
601 Summary object to update in-place.
602 exposure : `lsst.afw.image.ExposureF`
603 Exposure to grab band and exposure time metadata
604
605 """
606 nan = float("nan")
607 summary.effTime = nan
608 summary.effTimePsfSigmaScale = nan
609 summary.effTimeSkyBgScale = nan
610 summary.effTimeZeroPointScale = nan
611
612 exposureTime = exposure.getInfo().getVisitInfo().getExposureTime()
613 filterLabel = exposure.getFilter()
614 if (filterLabel is None) or (not filterLabel.hasBandLabel):
615 band = None
616 else:
617 band = filterLabel.bandLabel
618
619 if band is None:
620 self.log.warning("No band associated with exposure; effTime not calculated.")
621 return
622
623 # PSF component
624 if np.isnan(summary.psfSigma):
625 self.log.debug("PSF sigma is NaN")
626 f_eff = nan
627 elif band not in self.config.fiducialPsfSigma:
628 self.log.debug(f"Fiducial PSF value not found for {band}")
629 f_eff = nan
630 else:
631 fiducialPsfSigma = self.config.fiducialPsfSigma[band]
632 f_eff = (summary.psfSigma / fiducialPsfSigma)**-2
633
634 # Transparency component
635 # Note: Assumes that the zeropoint includes the exposure time
636 if np.isnan(summary.zeroPoint):
637 self.log.debug("Zero point is NaN")
638 c_eff = nan
639 elif band not in self.config.fiducialZeroPoint:
640 self.log.debug(f"Fiducial zero point value not found for {band}")
641 c_eff = nan
642 else:
643 fiducialZeroPoint = self.config.fiducialZeroPoint[band]
644 zeroPointDiff = fiducialZeroPoint - (summary.zeroPoint - 2.5*np.log10(exposureTime))
645 c_eff = min(10**(-2.0*(zeroPointDiff)/2.5), self.config.maxEffectiveTransparency)
646
647 # Sky brightness component (convert to cts/s)
648 if np.isnan(summary.skyBg):
649 self.log.debug("Sky background is NaN")
650 b_eff = nan
651 elif band not in self.config.fiducialSkyBackground:
652 self.log.debug(f"Fiducial sky background value not found for {band}")
653 b_eff = nan
654 else:
655 fiducialSkyBackground = self.config.fiducialSkyBackground[band]
656 b_eff = fiducialSkyBackground/(summary.skyBg/exposureTime)
657
658 # Effective exposure time scale factor
659 t_eff = f_eff * c_eff * b_eff
660
661 # Effective exposure time (seconds)
662 effectiveTime = t_eff * exposureTime
663
664 # Output quantities
665 summary.effTime = float(effectiveTime)
666 summary.effTimePsfSigmaScale = float(f_eff)
667 summary.effTimeSkyBgScale = float(b_eff)
668 summary.effTimeZeroPointScale = float(c_eff)
669

◆ update_magnitude_limit_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_magnitude_limit_stats ( self,
summary,
exposure )
Compute a summary statistic for the point-source magnitude limit at
a given signal-to-noise ratio using exposure-level metadata.

The magnitude limit is calculated at a given SNR from the PSF,
sky, zeropoint, and readnoise in accordance with SMTN-002 [1]_,
LSE-40 [2]_, and DMTN-296 [3]_.

References
----------

.. [1] "Calculating LSST limiting magnitudes and SNR" (SMTN-002)
.. [2] "Photon Rates and SNR Calculations" (LSE-40)
.. [3] "Calculations of Image and Catalog Depth" (DMTN-296)


Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
exposure : `lsst.afw.image.ExposureF`
    Exposure to grab band and exposure time metadata

Definition at line 670 of file computeExposureSummaryStats.py.

670 def update_magnitude_limit_stats(self, summary, exposure):
671 """Compute a summary statistic for the point-source magnitude limit at
672 a given signal-to-noise ratio using exposure-level metadata.
673
674 The magnitude limit is calculated at a given SNR from the PSF,
675 sky, zeropoint, and readnoise in accordance with SMTN-002 [1]_,
676 LSE-40 [2]_, and DMTN-296 [3]_.
677
678 References
679 ----------
680
681 .. [1] "Calculating LSST limiting magnitudes and SNR" (SMTN-002)
682 .. [2] "Photon Rates and SNR Calculations" (LSE-40)
683 .. [3] "Calculations of Image and Catalog Depth" (DMTN-296)
684
685
686 Parameters
687 ----------
688 summary : `lsst.afw.image.ExposureSummaryStats`
689 Summary object to update in-place.
690 exposure : `lsst.afw.image.ExposureF`
691 Exposure to grab band and exposure time metadata
692 """
693 if exposure.getDetector() is None:
694 summary.magLim = float("nan")
695 return
696
697 # Calculate the average readnoise [e-]
698 readNoiseList = list(ipIsr.getExposureReadNoises(exposure).values())
699 readNoise = np.nanmean(readNoiseList)
700 if np.isnan(readNoise):
701 readNoise = 0.0
702 self.log.warning("Read noise set to NaN! Setting readNoise to 0.0 to proceed.")
703
704 # Calculate the average gain [e-/ADU]
705 gainList = list(ipIsr.getExposureGains(exposure).values())
706 gain = np.nanmean(gainList)
707 if np.isnan(gain):
708 self.log.warning("Gain set to NaN! Setting magLim to NaN.")
709 summary.magLim = float("nan")
710 return
711
712 # Get the image units (default to 'adu' if metadata key absent)
713 md = exposure.getMetadata()
714 if md.get("LSST ISR UNITS", "adu") == "electron":
715 gain = 1.0
716
717 # Convert readNoise to image units
718 readNoise /= gain
719
720 # Calculate the limiting magnitude.
721 # Note 1: Assumes that the image and readnoise have the same units
722 # Note 2: Assumes that the zeropoint includes the exposure time
723 magLim = compute_magnitude_limit(summary.psfArea, summary.skyBg,
724 summary.zeroPoint, readNoise,
725 gain, self.config.magLimSnr)
726
727 summary.magLim = float(magLim)
728
729

◆ update_masked_image_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_masked_image_stats ( self,
summary,
masked_image )
Compute summary-statistic fields that depend on the masked image
itself.

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
masked_image : `lsst.afw.image.MaskedImage` or `None`
    Masked image.  If `None`, all fields that depend
    on the masked image will be reset (generally to NaN).

Definition at line 544 of file computeExposureSummaryStats.py.

544 def update_masked_image_stats(self, summary, masked_image):
545 """Compute summary-statistic fields that depend on the masked image
546 itself.
547
548 Parameters
549 ----------
550 summary : `lsst.afw.image.ExposureSummaryStats`
551 Summary object to update in-place.
552 masked_image : `lsst.afw.image.MaskedImage` or `None`
553 Masked image. If `None`, all fields that depend
554 on the masked image will be reset (generally to NaN).
555 """
556 nan = float("nan")
557 if masked_image is None:
558 summary.skyNoise = nan
559 summary.meanVar = nan
560 return
561 statsCtrl = afwMath.StatisticsControl()
562 statsCtrl.setNumSigmaClip(self.config.sigmaClip)
563 statsCtrl.setNumIter(self.config.clipIter)
564 statsCtrl.setAndMask(afwImage.Mask.getPlaneBitMask(self.config.badMaskPlanes))
565 statsCtrl.setNanSafe(True)
566
567 statObj = afwMath.makeStatistics(masked_image, afwMath.STDEVCLIP, statsCtrl)
568 skyNoise, _ = statObj.getResult(afwMath.STDEVCLIP)
569 summary.skyNoise = skyNoise
570
571 statObj = afwMath.makeStatistics(masked_image.variance, masked_image.mask, afwMath.MEANCLIP,
572 statsCtrl)
573 meanVar, _ = statObj.getResult(afwMath.MEANCLIP)
574 summary.meanVar = meanVar
575
Pass parameters to a Statistics object.
Definition Statistics.h:83
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

◆ update_photo_calib_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_photo_calib_stats ( self,
summary,
photo_calib )
Compute all summary-statistic fields that depend on the photometric
calibration model.

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
photo_calib : `lsst.afw.image.PhotoCalib` or `None`
    Photometric calibration model.  If `None`, all fields that depend
    on the photometric calibration will be reset (generally to NaN).

Definition at line 501 of file computeExposureSummaryStats.py.

501 def update_photo_calib_stats(self, summary, photo_calib):
502 """Compute all summary-statistic fields that depend on the photometric
503 calibration model.
504
505 Parameters
506 ----------
507 summary : `lsst.afw.image.ExposureSummaryStats`
508 Summary object to update in-place.
509 photo_calib : `lsst.afw.image.PhotoCalib` or `None`
510 Photometric calibration model. If `None`, all fields that depend
511 on the photometric calibration will be reset (generally to NaN).
512 """
513 if photo_calib is not None:
514 summary.zeroPoint = float(2.5*np.log10(photo_calib.getInstFluxAtZeroMagnitude()))
515 else:
516 summary.zeroPoint = float("nan")
517

◆ update_psf_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_psf_stats ( self,
summary,
psf,
bbox,
sources = None,
image_mask = None,
image_ap_corr_map = None,
sources_is_astropy = False )
Compute all summary-statistic fields that depend on the PSF model.

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
psf : `lsst.afw.detection.Psf` or `None`
    Point spread function model.  If `None`, all fields that depend on
    the PSF will be reset (generally to NaN).
bbox : `lsst.geom.Box2I`
    Bounding box of the image for which summary stats are being
    computed.
sources : `lsst.afw.table.SourceCatalog` or `astropy.table.Table`
    Catalog for quantities that are computed from source table columns.
    If `None`, these quantities will be reset (generally to NaN).
    The type of this table must correspond to the
    ``sources_is_astropy`` argument.
image_mask : `lsst.afw.image.Mask`, optional
    Mask image that may be used to compute distance-to-nearest-star
    metrics.
sources_is_astropy : `bool`, optional
    Whether ``sources`` is an `astropy.table.Table` instance instead
    of an `lsst.afw.table.Catalog` instance.  Default is `False` (the
    latter).

Definition at line 275 of file computeExposureSummaryStats.py.

284 ):
285 """Compute all summary-statistic fields that depend on the PSF model.
286
287 Parameters
288 ----------
289 summary : `lsst.afw.image.ExposureSummaryStats`
290 Summary object to update in-place.
291 psf : `lsst.afw.detection.Psf` or `None`
292 Point spread function model. If `None`, all fields that depend on
293 the PSF will be reset (generally to NaN).
294 bbox : `lsst.geom.Box2I`
295 Bounding box of the image for which summary stats are being
296 computed.
297 sources : `lsst.afw.table.SourceCatalog` or `astropy.table.Table`
298 Catalog for quantities that are computed from source table columns.
299 If `None`, these quantities will be reset (generally to NaN).
300 The type of this table must correspond to the
301 ``sources_is_astropy`` argument.
302 image_mask : `lsst.afw.image.Mask`, optional
303 Mask image that may be used to compute distance-to-nearest-star
304 metrics.
305 sources_is_astropy : `bool`, optional
306 Whether ``sources`` is an `astropy.table.Table` instance instead
307 of an `lsst.afw.table.Catalog` instance. Default is `False` (the
308 latter).
309 """
310 nan = float("nan")
311 summary.psfSigma = nan
312 summary.psfIxx = nan
313 summary.psfIyy = nan
314 summary.psfIxy = nan
315 summary.psfArea = nan
316 summary.nPsfStar = 0
317 summary.psfStarDeltaE1Median = nan
318 summary.psfStarDeltaE2Median = nan
319 summary.psfStarDeltaE1Scatter = nan
320 summary.psfStarDeltaE2Scatter = nan
321 summary.psfStarDeltaSizeMedian = nan
322 summary.psfStarDeltaSizeScatter = nan
323 summary.psfStarScaledDeltaSizeScatter = nan
324 summary.maxDistToNearestPsf = nan
325 summary.psfTraceRadiusDelta = nan
326 summary.psfApFluxDelta = nan
327 summary.psfApCorrSigmaScaledDelta = nan
328
329 if psf is None:
330 return
331 shape = psf.computeShape(bbox.getCenter())
332 summary.psfSigma = shape.getDeterminantRadius()
333 summary.psfIxx = shape.getIxx()
334 summary.psfIyy = shape.getIyy()
335 summary.psfIxy = shape.getIxy()
336 im = psf.computeKernelImage(bbox.getCenter())
337 # The calculation of effective psf area is taken from
338 # meas_base/src/PsfFlux.cc#L112. See
339 # https://github.com/lsst/meas_base/blob/
340 # 750bffe6620e565bda731add1509507f5c40c8bb/src/PsfFlux.cc#L112
341 summary.psfArea = float(np.sum(im.array)/np.sum(im.array**2.))
342
343 if image_mask is not None:
344 psfApRadius = max(self.config.minPsfApRadiusPix, 3.0*summary.psfSigma)
345 self.log.debug("Using radius of %.3f (pixels) for psfApFluxDelta metric", psfApRadius)
346 psfTraceRadiusDelta, psfApFluxDelta = compute_psf_image_deltas(
347 image_mask,
348 psf,
349 sampling=self.config.psfGridSampling,
350 ap_radius_pix=psfApRadius,
351 bad_mask_bits=self.config.psfBadMaskPlanes
352 )
353 summary.psfTraceRadiusDelta = float(psfTraceRadiusDelta)
354 summary.psfApFluxDelta = float(psfApFluxDelta)
355 if image_ap_corr_map is not None:
356 if self.config.psfApCorrFieldName not in image_ap_corr_map.keys():
357 self.log.warning(f"{self.config.psfApCorrFieldName} not found in "
358 "image_ap_corr_map. Setting psfApCorrSigmaScaledDelta to NaN.")
359 psfApCorrSigmaScaledDelta = nan
360 else:
361 image_ap_corr_field = image_ap_corr_map[self.config.psfApCorrFieldName]
362 psfApCorrSigmaScaledDelta = compute_ap_corr_sigma_scaled_delta(
363 image_mask,
364 image_ap_corr_field,
365 summary.psfSigma,
366 sampling=self.config.psfGridSampling,
367 bad_mask_bits=self.config.psfBadMaskPlanes,
368 )
369 summary.psfApCorrSigmaScaledDelta = float(psfApCorrSigmaScaledDelta)
370
371 if sources is None:
372 # No sources are available (as in some tests and rare cases where
373 # the selection criteria in finalizeCharacterization lead to no
374 # good sources).
375 return
376
377 # Count the total number of psf stars used (prior to stats selection).
378 nPsfStar = sources[self.config.starSelection].sum()
379 summary.nPsfStar = int(nPsfStar)
380
381 psf_mask = self.starSelector.run(sources).selected
382 nPsfStarsUsedInStats = psf_mask.sum()
383
384 if nPsfStarsUsedInStats == 0:
385 # No stars to measure statistics, so we must return the defaults
386 # of 0 stars and NaN values.
387 return
388
389 if sources_is_astropy:
390 psf_cat = sources[psf_mask]
391 else:
392 psf_cat = sources[psf_mask].copy(deep=True)
393
394 starXX = psf_cat[self.config.starShape + '_xx']
395 starYY = psf_cat[self.config.starShape + '_yy']
396 starXY = psf_cat[self.config.starShape + '_xy']
397 psfXX = psf_cat[self.config.psfShape + '_xx']
398 psfYY = psf_cat[self.config.psfShape + '_yy']
399 psfXY = psf_cat[self.config.psfShape + '_xy']
400
401 # Use the trace radius for the star size.
402 starSize = np.sqrt(starXX/2. + starYY/2.)
403
404 starE1 = (starXX - starYY)/(starXX + starYY)
405 starE2 = 2*starXY/(starXX + starYY)
406 starSizeMedian = np.median(starSize)
407
408 # Use the trace radius for the psf size.
409 psfSize = np.sqrt(psfXX/2. + psfYY/2.)
410 psfE1 = (psfXX - psfYY)/(psfXX + psfYY)
411 psfE2 = 2*psfXY/(psfXX + psfYY)
412
413 psfStarDeltaE1Median = np.median(starE1 - psfE1)
414 psfStarDeltaE1Scatter = sigmaMad(starE1 - psfE1, scale='normal')
415 psfStarDeltaE2Median = np.median(starE2 - psfE2)
416 psfStarDeltaE2Scatter = sigmaMad(starE2 - psfE2, scale='normal')
417
418 psfStarDeltaSizeMedian = np.median(starSize - psfSize)
419 psfStarDeltaSizeScatter = sigmaMad(starSize - psfSize, scale='normal')
420 psfStarScaledDeltaSizeScatter = psfStarDeltaSizeScatter/starSizeMedian
421
422 summary.psfStarDeltaE1Median = float(psfStarDeltaE1Median)
423 summary.psfStarDeltaE2Median = float(psfStarDeltaE2Median)
424 summary.psfStarDeltaE1Scatter = float(psfStarDeltaE1Scatter)
425 summary.psfStarDeltaE2Scatter = float(psfStarDeltaE2Scatter)
426 summary.psfStarDeltaSizeMedian = float(psfStarDeltaSizeMedian)
427 summary.psfStarDeltaSizeScatter = float(psfStarDeltaSizeScatter)
428 summary.psfStarScaledDeltaSizeScatter = float(psfStarScaledDeltaSizeScatter)
429
430 if image_mask is not None:
431 maxDistToNearestPsf = maximum_nearest_psf_distance(
432 image_mask,
433 psf_cat,
434 sampling=self.config.psfSampling,
435 bad_mask_bits=self.config.psfBadMaskPlanes
436 )
437 summary.maxDistToNearestPsf = float(maxDistToNearestPsf)
438

◆ update_wcs_stats()

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.update_wcs_stats ( self,
summary,
wcs,
bbox,
visitInfo )
Compute all summary-statistic fields that depend on the WCS model.

Parameters
----------
summary : `lsst.afw.image.ExposureSummaryStats`
    Summary object to update in-place.
wcs : `lsst.afw.geom.SkyWcs` or `None`
    Astrometric calibration model.  If `None`, all fields that depend
    on the WCS will be reset (generally to NaN).
bbox : `lsst.geom.Box2I`
    Bounding box of the image for which summary stats are being
    computed.
visitInfo : `lsst.afw.image.VisitInfo`
    Observation information used in together with ``wcs`` to compute
    the zenith distance.

Definition at line 439 of file computeExposureSummaryStats.py.

439 def update_wcs_stats(self, summary, wcs, bbox, visitInfo):
440 """Compute all summary-statistic fields that depend on the WCS model.
441
442 Parameters
443 ----------
444 summary : `lsst.afw.image.ExposureSummaryStats`
445 Summary object to update in-place.
446 wcs : `lsst.afw.geom.SkyWcs` or `None`
447 Astrometric calibration model. If `None`, all fields that depend
448 on the WCS will be reset (generally to NaN).
449 bbox : `lsst.geom.Box2I`
450 Bounding box of the image for which summary stats are being
451 computed.
452 visitInfo : `lsst.afw.image.VisitInfo`
453 Observation information used in together with ``wcs`` to compute
454 the zenith distance.
455 """
456 nan = float("nan")
457 summary.raCorners = [nan]*4
458 summary.decCorners = [nan]*4
459 summary.ra = nan
460 summary.dec = nan
461 summary.pixelScale = nan
462 summary.zenithDistance = nan
463
464 if wcs is None:
465 return
466
467 sph_pts = wcs.pixelToSky(geom.Box2D(bbox).getCorners())
468 summary.raCorners = [float(sph.getRa().asDegrees()) for sph in sph_pts]
469 summary.decCorners = [float(sph.getDec().asDegrees()) for sph in sph_pts]
470
471 sph_pt = wcs.pixelToSky(bbox.getCenter())
472 summary.ra = sph_pt.getRa().asDegrees()
473 summary.dec = sph_pt.getDec().asDegrees()
474 summary.pixelScale = wcs.getPixelScale(bbox.getCenter()).asArcseconds()
475
476 date = visitInfo.getDate()
477
478 if date.isValid():
479 # We compute the zenithDistance at the center of the detector
480 # rather than use the boresight value available via the visitInfo,
481 # because the zenithDistance may vary significantly over a large
482 # field of view.
483 observatory = visitInfo.getObservatory()
484 loc = EarthLocation(lat=observatory.getLatitude().asDegrees()*units.deg,
485 lon=observatory.getLongitude().asDegrees()*units.deg,
486 height=observatory.getElevation()*units.m)
487 obstime = Time(visitInfo.getDate().get(system=DateTime.MJD),
488 location=loc, format='mjd')
489 coord = SkyCoord(
490 summary.ra*units.degree,
491 summary.dec*units.degree,
492 obstime=obstime,
493 location=loc,
494 )
495 with warnings.catch_warnings():
496 warnings.simplefilter('ignore')
497 altaz = coord.transform_to(AltAz)
498
499 summary.zenithDistance = float(90.0 - altaz.alt.degree)
500
A floating-point coordinate rectangle geometry.
Definition Box.h:413

Member Data Documentation

◆ _DefaultName

str lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask._DefaultName = "computeExposureSummaryStats"
staticprotected

Definition at line 216 of file computeExposureSummaryStats.py.

◆ ConfigClass

lsst.pipe.tasks.computeExposureSummaryStats.ComputeExposureSummaryStatsTask.ConfigClass = ComputeExposureSummaryStatsConfig
static

Definition at line 215 of file computeExposureSummaryStats.py.


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