44 _persistence_name =
'ExposureSummaryStats'
46 _factory = StorableHelperFactory(__name__, _persistence_name)
50 psfSigma: float = float(
'nan')
51 """PSF determinant radius (pixels)."""
53 psfArea: float = float(
'nan')
54 """PSF effective area (pixels**2)."""
56 psfIxx: float = float(
'nan')
57 """PSF shape Ixx (pixels**2)."""
59 psfIyy: float = float(
'nan')
60 """PSF shape Iyy (pixels**2)."""
62 psfIxy: float = float(
'nan')
63 """PSF shape Ixy (pixels**2)."""
65 ra: float = float(
'nan')
66 """Bounding box center Right Ascension (degrees)."""
68 dec: float = float(
'nan')
69 """Bounding box center Declination (degrees)."""
71 pixelScale: float = float(
'nan')
72 """Measured detector pixel scale (arcsec/pixel)."""
74 zenithDistance: float = float(
'nan')
75 """Bounding box center zenith distance (degrees)."""
77 expTime: float = float(
'nan')
78 """Exposure time of the exposure (seconds)."""
80 zeroPoint: float = float(
'nan')
81 """Mean zeropoint in detector (mag)."""
83 skyBg: float = float(
'nan')
84 """Average sky background (ADU)."""
86 skyNoise: float = float(
'nan')
87 """Average sky noise (ADU)."""
89 meanVar: float = float(
'nan')
90 """Mean variance of the weight plane (ADU**2)."""
92 raCorners: list[float] = dataclasses.field(default_factory=_default_corners)
93 """Right Ascension of bounding box corners (degrees)."""
95 decCorners: list[float] = dataclasses.field(default_factory=_default_corners)
96 """Declination of bounding box corners (degrees)."""
98 psfAdaptiveThresholdValue: float = float(
'nan')
99 """Threshold value used in the adaptive threshold detection pass for PSF modelling."""
101 psfAdaptiveIncludeThresholdMultiplier: float = float(
'nan')
102 """Threshold multiplier used in the adaptive threshold detection pass for PSF modelling."""
104 nShapeletsStar: int = 0
105 """Number of sources used in the shapelet decomposition."""
107 shapeletsOnlyIqScore: float = float(
'nan')
108 """The dimensionless image quality score as determined from the shapelets decomposition
109 that includes power only from the non-atmospheric decomposition coefficients. The
110 score spans the range [0.0, 1.0] with lower values indicating better image quality.
113 shapeletsIqScore: float = float(
'nan')
114 """The dimensionless image quality score as determined from the shapelets decomposition
115 that includes power from the median centroid offset between those used in the decomposition
116 and those of the centroid slot in addition to non-atmospheric decomposition coefficients.
117 The score spans the range [0.0, 1.0] with lower values indicating better image quality.
120 shapeletsCoeffs: list[float] = dataclasses.field(default_factory=list)
121 """List of coefficients from the PSF star shapelet decomposition."""
123 centroidDiffShapeletsVsSlotMedian: float = float(
'nan')
124 """Median centroid difference (sqrt((slot_x - shapelet_x)**2 + (slot_y - shapelet_y)**2)) for
125 sources used in the shapelet decomposition (pixels).
128 shapeletsStarEMedian: float = float(
'nan')
129 """Median ellipticity (sqrt(starE1**2.0 + starE2**2.0)) of the sources used in the
130 shapelet decomposition.
133 shapeletsStarUnNormalizedEMedian: float = float(
'nan')
134 """Median un-normalized ellipticity (sqrt((starXX - starYY)**2.0 + (2.0*starXY)**2.0))
135 of the sources used in the shapelet decomposition (pixels**2).
138 astromOffsetMean: float = float(
'nan')
139 """Astrometry match offset mean."""
141 astromOffsetStd: float = float(
'nan')
142 """Astrometry match offset stddev."""
145 """Number of stars used for psf model."""
147 psfStarDeltaE1Median: float = float(
'nan')
148 """Psf stars median E1 residual (starE1 - psfE1)."""
150 psfStarDeltaE2Median: float = float(
'nan')
151 """Psf stars median E2 residual (starE2 - psfE2)."""
153 psfStarDeltaE1Scatter: float = float(
'nan')
154 """Psf stars MAD E1 scatter (starE1 - psfE1)."""
156 psfStarDeltaE2Scatter: float = float(
'nan')
157 """Psf stars MAD E2 scatter (starE2 - psfE2)."""
159 psfStarDeltaSizeMedian: float = float(
'nan')
160 """Psf stars median size residual (starSize - psfSize)."""
162 psfStarDeltaSizeScatter: float = float(
'nan')
163 """Psf stars MAD size scatter (starSize - psfSize)."""
165 psfStarScaledDeltaSizeScatter: float = float(
'nan')
166 """Psf stars MAD size scatter scaled by psfSize**2."""
168 psfTraceRadiusDelta: float = float(
'nan')
169 """Delta (max - min) of the model psf trace radius values evaluated on a
170 grid of unmasked pixels (pixels).
173 psfApFluxDelta: float = float(
'nan')
174 """Delta (max - min) of the model psf aperture flux (with aperture radius of
175 max(2, 3*psfSigma)) values evaluated on a grid of unmasked pixels.
178 psfApCorrSigmaScaledDelta: float = float(
'nan')
179 """Delta (max - min) of the psf flux aperture correction factors scaled (divided)
180 by the psfSigma evaluated on a grid of unmasked pixels.
183 maxDistToNearestPsf: float = float(
'nan')
184 """Maximum distance of an unmasked pixel to its nearest model psf star
188 starEMedian: float = float(
'nan')
189 """Median ellipticity (sqrt(starE1**2.0 + starE2**2.0)) of the stars used
193 starUnNormalizedEMedian: float = float(
'nan')
194 """Median un-normalized ellipticity (sqrt((starXX - starYY)**2.0 + (2.0*starXY)**2.0))
195 of the stars used in the PSF model (pixel**2).
198 starComa1Median: float = float(
'nan')
199 """Coma-like higher-order moment combination: median M30 + M12
200 of the stars used in the PSF model.
203 starComa2Median: float = float(
'nan')
204 """Coma-like higher-order moment combination: median M21 + M03
205 of the stars used in the PSF model.
208 starTrefoil1Median: float = float(
'nan')
209 """Trefoil-like higher-order moment combination: median M30 - 3*M12
210 of the stars used in the PSF model.
213 starTrefoil2Median: float = float(
'nan')
214 """Trefoil-like higher-order moment combination: median 3*M21 - M03
215 of the stars used in the PSF model.
218 starKurtosisMedian: float = float(
'nan')
219 """Kurtosis-like higher-order moment combination: median M40 + 2*M22 + M04
220 of the stars used in the PSF model.
223 starE41Median: float = float(
'nan')
224 """Fourth-order ellipticity-like higher-order moment combination: median M40 - M04
225 of the stars used in the PSF model.
228 starE42Median: float = float(
'nan')
229 """Fourth-order ellipticity-like higher-order moment combination: median 2*(M31 + M13)
230 of the stars used in the PSF model.
233 effTime: float = float(
'nan')
234 """Effective exposure time calculated from psfSigma, skyBg, and
238 effTimePsfSigmaScale: float = float(
'nan')
239 """PSF scaling of the effective exposure time."""
241 effTimeSkyBgScale: float = float(
'nan')
242 """Sky background scaling of the effective exposure time."""
244 effTimeZeroPointScale: float = float(
'nan')
245 """Zeropoint scaling of the effective exposure time."""
247 magLim: float = float(
'nan')
248 """Magnitude limit at fixed SNR (default SNR=5) calculated from psfSigma, skyBg,
249 zeroPoint, and readNoise.
253 Storable.__init__(self)
265 return yaml.dump(dataclasses.asdict(self), encoding=
'utf-8')
269 yamlDict = yaml.load(bytes, Loader=yaml.SafeLoader)
272 forwardFieldDict = {
"decl":
"dec"}
277 for _field
in list(yamlDict.keys()):
278 if _field
not in ExposureSummaryStats.__dataclass_fields__:
279 if _field
in forwardFieldDict
and forwardFieldDict[_field]
not in yamlDict:
280 yamlDict[forwardFieldDict[_field]] = yamlDict[_field]
282 droppedFields.append(_field)
284 if len(droppedFields) > 0:
285 droppedFieldString =
", ".join([str(f)
for f
in droppedFields])
286 plural =
"s" if len(droppedFields) != 1
else ""
287 them =
"them" if len(droppedFields) > 1
else "it"
289 f
"Summary field{plural} [{droppedFieldString}] not recognized by this software version;"
290 f
" ignoring {them}.",
298 """Update an schema to includes for all summary statistic fields.
302 schema : `lsst.afw.table.Schema`
303 Schema to add which fields will be added.
308 doc=
"PSF model second-moments determinant radius (center of chip) (pixel)",
314 doc=
"PSF model effective area (center of chip) (pixel**2)",
320 doc=
"PSF model Ixx (center of chip) (pixel**2)",
326 doc=
"PSF model Iyy (center of chip) (pixel**2)",
332 doc=
"PSF model Ixy (center of chip) (pixel**2)",
339 doc=
"Right Ascension of bounding box corners (degrees)",
346 doc=
"Declination of bounding box corners (degrees)",
352 doc=
"Right Ascension of bounding box center (degrees)",
358 doc=
"Declination of bounding box center (degrees)",
364 doc=
"Zenith distance of bounding box center (degrees)",
370 doc=
"Measured detector pixel scale (arcsec/pixel)",
371 units=
"arcsec/pixel",
376 doc=
"Exposure time of the exposure (seconds)",
382 doc=
"Mean zeropoint in detector (mag)",
388 doc=
"Average sky background (ADU)",
394 doc=
"Average sky noise (ADU)",
400 doc=
"Mean variance of the weight plane (ADU**2)",
404 "psfAdaptiveThresholdValue",
406 doc=
"Threshold value used in the adaptive threshold detection pass for PSF modelling.",
410 "psfAdaptiveIncludeThresholdMultiplier",
412 doc=
"Threshold multiplier used in the adaptive threshold detection pass for PSF modelling.",
418 doc=
"Number of sources used in the shapelet decomposition.",
422 "shapeletsOnlyIqScore",
424 doc=
"The dimensionless image quality score as determined from the shapelets "
425 "decomposition that includes power only from the non-atmospheric decomposition "
426 "coefficients. The score spans the range [0.0, 1.0] with lower values indicating "
427 "better image quality.",
433 doc=
"The dimensionless image quality score as determined from the shapelets "
434 "decomposition that includes power from the median centroid offset between those "
435 "used in the decomposition and those of the centroid slot in addition to "
436 "non-atmospheric decomposition coefficients. The score spans the range [0.0, 1.0] "
437 "with lower values indicating better image quality.",
444 doc=
"List of coefficients from the PSF star shapelet decomposition.",
448 "centroidDiffShapeletsVsSlotMedian",
450 doc=
"Median centroid difference (sqrt((slot_x - shapelet_x)**2 + (slot_y - shapelet_y)**2)) "
451 "for sources used in the shapelet decomposition.",
455 "shapeletsStarEMedian",
457 doc=
"Median ellipticity (sqrt(starE1**2.0 + starE2**2.0)) of the stars used in the "
458 "shapelet decomposition.",
462 "shapeletsStarUnNormalizedEMedian",
464 doc=
"Median un-normalized ellipticity (sqrt((starXX - starYY)**2.0 + (2.0*starXY)**2.0)) "
465 "of the stars used in the shapelet decomposition.",
471 doc=
"Mean offset of astrometric calibration matches (arcsec)",
477 doc=
"Standard deviation of offsets of astrometric calibration matches (arcsec)",
480 schema.addField(
"nPsfStar", type=
"I", doc=
"Number of stars used for PSF model")
482 "psfStarDeltaE1Median",
484 doc=
"Median E1 residual (starE1 - psfE1) for psf stars",
487 "psfStarDeltaE2Median",
489 doc=
"Median E2 residual (starE2 - psfE2) for psf stars",
492 "psfStarDeltaE1Scatter",
494 doc=
"Scatter (via MAD) of E1 residual (starE1 - psfE1) for psf stars",
497 "psfStarDeltaE2Scatter",
499 doc=
"Scatter (via MAD) of E2 residual (starE2 - psfE2) for psf stars",
502 "psfStarDeltaSizeMedian",
504 doc=
"Median size residual (starSize - psfSize) for psf stars (pixel)",
508 "psfStarDeltaSizeScatter",
510 doc=
"Scatter (via MAD) of size residual (starSize - psfSize) for psf stars (pixel)",
514 "psfStarScaledDeltaSizeScatter",
516 doc=
"Scatter (via MAD) of size residual scaled by median size squared",
519 "psfTraceRadiusDelta",
521 doc=
"Delta (max - min) of the model psf trace radius values evaluated on a grid of "
522 "unmasked pixels (pixel).",
528 doc=
"Delta (max - min) of the model psf aperture flux (with aperture radius of "
529 "max(2, 3*psfSigma)) values evaluated on a grid of unmasked pixels.",
532 "psfApCorrSigmaScaledDelta",
534 doc=
"Delta (max - min) of the model psf aperture correction factors scaled (divided) "
535 "by the psfSigma evaluated on a grid of unmasked pixels.",
538 "maxDistToNearestPsf",
540 doc=
"Maximum distance of an unmasked pixel to its nearest model psf star (pixel).",
546 doc=
"Median ellipticity (sqrt(starE1**2.0 + starE2**2.0)) of the stars used in "
550 "starUnNormalizedEMedian",
552 doc=
"Median un-normalized ellipticity (sqrt((starXX - starYY)**2.0 + (2.0*starXY)**2.0)) "
553 "of the stars used in the PSF model.",
558 doc=
"Coma-like higher-order moment combination: median M30 + M12 "
559 "of the stars used in the PSF model.",
564 doc=
"Coma-like higher-order moment combination: median M21 + M03 "
565 "of the stars used in the PSF model.",
568 "starTrefoil1Median",
570 doc=
"Trefoil-like higher-order moment combination: median M30 - 3*M12 "
571 "of the stars used in the PSF model.",
574 "starTrefoil2Median",
576 doc=
"Trefoil-like higher-order moment combination: median 3*M21 - M03 "
577 "of the stars used in the PSF model.",
580 "starKurtosisMedian",
582 doc=
"Kurtosis-like higher-order moment combination: median M40 + 2*M22 + M04 "
583 "of the stars used in the PSF model.",
588 doc=
"Fourth-order ellipticity-like higher-order moment combination: median M40 - M04 "
589 "of the stars used in the PSF model.",
594 doc=
"Fourth-order ellipticity-like higher-order moment combination: median 2*(M31 + M13) "
595 "of the stars used in the PSF model.",
600 doc=
"Effective exposure time calculated from psfSigma, skyBg, and "
601 "zeroPoint (seconds).",
605 "effTimePsfSigmaScale",
607 doc=
"PSF scaling of the effective exposure time."
612 doc=
"Sky background scaling of the effective exposure time."
615 "effTimeZeroPointScale",
617 doc=
"Zeropoint scaling of the effective exposure time."
622 doc=
"Magnitude limit at SNR=5 (M5) calculated from psfSigma, "
623 "skyBg, zeroPoint, and readNoise.",
628 """Write summary-statistic columns into a record.
632 record : `lsst.afw.table.BaseRecord`
633 Record to update. This is expected to frequently be an
634 `ExposureRecord` instance (with higher-level code adding other
635 columns and objects), but this method can work with any record
638 for field
in dataclasses.fields(self):
639 value = getattr(self, field.name)
640 if field.name ==
"version":
642 elif field.type.startswith(
"list"):
643 record[field.name] = np.array(value, dtype=record[field.name].dtype)
645 record[field.name] = value
649 """Read summary-statistic columns from a record into ``self``.
653 record : `lsst.afw.table.BaseRecord`
654 Record to read from. This is expected to frequently be an
655 `ExposureRecord` instance (with higher-level code adding other
656 columns and objects), but this method can work with any record
657 type, ignoring any attributes or columns it doesn't recognize.
661 summary : `ExposureSummaryStats`
662 Summary statistics object created from the given record.
667 record[field.name]
if not field.type.startswith(
"list")
668 else [float(v)
for v
in record[field.name]]
670 for field
in dataclasses.fields(cls)
671 if field.name !=
"version"