42 _persistence_name =
'ExposureSummaryStats'
44 _factory = StorableHelperFactory(__name__, _persistence_name)
48 psfSigma: float = float(
'nan')
49 """PSF determinant radius (pixels)."""
51 psfArea: float = float(
'nan')
52 """PSF effective area (pixels**2)."""
54 psfIxx: float = float(
'nan')
55 """PSF shape Ixx (pixels**2)."""
57 psfIyy: float = float(
'nan')
58 """PSF shape Iyy (pixels**2)."""
60 psfIxy: float = float(
'nan')
61 """PSF shape Ixy (pixels**2)."""
63 ra: float = float(
'nan')
64 """Bounding box center Right Ascension (degrees)."""
66 dec: float = float(
'nan')
67 """Bounding box center Declination (degrees)."""
69 pixelScale: float = float(
'nan')
70 """Measured detector pixel scale (arcsec/pixel)."""
72 zenithDistance: float = float(
'nan')
73 """Bounding box center zenith distance (degrees)."""
75 expTime: float = float(
'nan')
76 """Exposure time of the exposure (seconds)."""
78 zeroPoint: float = float(
'nan')
79 """Mean zeropoint in detector (mag)."""
81 skyBg: float = float(
'nan')
82 """Average sky background (ADU)."""
84 skyNoise: float = float(
'nan')
85 """Average sky noise (ADU)."""
87 meanVar: float = float(
'nan')
88 """Mean variance of the weight plane (ADU**2)."""
90 raCorners: list[float] = dataclasses.field(default_factory=_default_corners)
91 """Right Ascension of bounding box corners (degrees)."""
93 decCorners: list[float] = dataclasses.field(default_factory=_default_corners)
94 """Declination of bounding box corners (degrees)."""
96 astromOffsetMean: float = float(
'nan')
97 """Astrometry match offset mean."""
99 astromOffsetStd: float = float(
'nan')
100 """Astrometry match offset stddev."""
103 """Number of stars used for psf model."""
105 psfStarDeltaE1Median: float = float(
'nan')
106 """Psf stars median E1 residual (starE1 - psfE1)."""
108 psfStarDeltaE2Median: float = float(
'nan')
109 """Psf stars median E2 residual (starE2 - psfE2)."""
111 psfStarDeltaE1Scatter: float = float(
'nan')
112 """Psf stars MAD E1 scatter (starE1 - psfE1)."""
114 psfStarDeltaE2Scatter: float = float(
'nan')
115 """Psf stars MAD E2 scatter (starE2 - psfE2)."""
117 psfStarDeltaSizeMedian: float = float(
'nan')
118 """Psf stars median size residual (starSize - psfSize)."""
120 psfStarDeltaSizeScatter: float = float(
'nan')
121 """Psf stars MAD size scatter (starSize - psfSize)."""
123 psfStarScaledDeltaSizeScatter: float = float(
'nan')
124 """Psf stars MAD size scatter scaled by psfSize**2."""
126 psfTraceRadiusDelta: float = float(
'nan')
127 """Delta (max - min) of the model psf trace radius values evaluated on a
128 grid of unmasked pixels (pixels).
131 psfApFluxDelta: float = float(
'nan')
132 """Delta (max - min) of the model psf aperture flux (with aperture radius of
133 max(2, 3*psfSigma)) values evaluated on a grid of unmasked pixels.
136 psfApCorrSigmaScaledDelta: float = float(
'nan')
137 """Delta (max - min) of the psf flux aperture correction factors scaled (divided)
138 by the psfSigma evaluated on a grid of unmasked pixels.
141 maxDistToNearestPsf: float = float(
'nan')
142 """Maximum distance of an unmasked pixel to its nearest model psf star
146 effTime: float = float(
'nan')
147 """Effective exposure time calculated from psfSigma, skyBg, and
151 effTimePsfSigmaScale: float = float(
'nan')
152 """PSF scaling of the effective exposure time."""
154 effTimeSkyBgScale: float = float(
'nan')
155 """Sky background scaling of the effective exposure time."""
157 effTimeZeroPointScale: float = float(
'nan')
158 """Zeropoint scaling of the effective exposure time."""
160 magLim: float = float(
'nan')
161 """Magnitude limit at fixed SNR (default SNR=5) calculated from psfSigma, skyBg,
162 zeroPoint, and readNoise.
166 Storable.__init__(self)
178 return yaml.dump(dataclasses.asdict(self), encoding=
'utf-8')
182 yamlDict = yaml.load(bytes, Loader=yaml.SafeLoader)
185 forwardFieldDict = {
"decl":
"dec"}
190 for _field
in list(yamlDict.keys()):
191 if _field
not in ExposureSummaryStats.__dataclass_fields__:
192 if _field
in forwardFieldDict
and forwardFieldDict[_field]
not in yamlDict:
193 yamlDict[forwardFieldDict[_field]] = yamlDict[_field]
195 droppedFields.append(_field)
197 if len(droppedFields) > 0:
198 droppedFieldString =
", ".join([str(f)
for f
in droppedFields])
199 plural =
"s" if len(droppedFields) != 1
else ""
200 them =
"them" if len(droppedFields) > 1
else "it"
202 f
"Summary field{plural} [{droppedFieldString}] not recognized by this software version;"
203 f
" ignoring {them}.",
211 """Update an schema to includes for all summary statistic fields.
215 schema : `lsst.afw.table.Schema`
216 Schema to add which fields will be added.
221 doc=
"PSF model second-moments determinant radius (center of chip) (pixel)",
227 doc=
"PSF model effective area (center of chip) (pixel**2)",
233 doc=
"PSF model Ixx (center of chip) (pixel**2)",
239 doc=
"PSF model Iyy (center of chip) (pixel**2)",
245 doc=
"PSF model Ixy (center of chip) (pixel**2)",
252 doc=
"Right Ascension of bounding box corners (degrees)",
259 doc=
"Declination of bounding box corners (degrees)",
265 doc=
"Right Ascension of bounding box center (degrees)",
271 doc=
"Declination of bounding box center (degrees)",
277 doc=
"Zenith distance of bounding box center (degrees)",
283 doc=
"Measured detector pixel scale (arcsec/pixel)",
284 units=
"arcsec/pixel",
289 doc=
"Exposure time of the exposure (seconds)",
295 doc=
"Mean zeropoint in detector (mag)",
301 doc=
"Average sky background (ADU)",
307 doc=
"Average sky noise (ADU)",
313 doc=
"Mean variance of the weight plane (ADU**2)",
319 doc=
"Mean offset of astrometric calibration matches (arcsec)",
325 doc=
"Standard deviation of offsets of astrometric calibration matches (arcsec)",
328 schema.addField(
"nPsfStar", type=
"I", doc=
"Number of stars used for PSF model")
330 "psfStarDeltaE1Median",
332 doc=
"Median E1 residual (starE1 - psfE1) for psf stars",
335 "psfStarDeltaE2Median",
337 doc=
"Median E2 residual (starE2 - psfE2) for psf stars",
340 "psfStarDeltaE1Scatter",
342 doc=
"Scatter (via MAD) of E1 residual (starE1 - psfE1) for psf stars",
345 "psfStarDeltaE2Scatter",
347 doc=
"Scatter (via MAD) of E2 residual (starE2 - psfE2) for psf stars",
350 "psfStarDeltaSizeMedian",
352 doc=
"Median size residual (starSize - psfSize) for psf stars (pixel)",
356 "psfStarDeltaSizeScatter",
358 doc=
"Scatter (via MAD) of size residual (starSize - psfSize) for psf stars (pixel)",
362 "psfStarScaledDeltaSizeScatter",
364 doc=
"Scatter (via MAD) of size residual scaled by median size squared",
367 "psfTraceRadiusDelta",
369 doc=
"Delta (max - min) of the model psf trace radius values evaluated on a grid of "
370 "unmasked pixels (pixel).",
376 doc=
"Delta (max - min) of the model psf aperture flux (with aperture radius of "
377 "max(2, 3*psfSigma)) values evaluated on a grid of unmasked pixels.",
380 "psfApCorrSigmaScaledDelta",
382 doc=
"Delta (max - min) of the model psf aperture correction factors scaled (divided) "
383 "by the psfSigma evaluated on a grid of unmasked pixels.",
386 "maxDistToNearestPsf",
388 doc=
"Maximum distance of an unmasked pixel to its nearest model psf star (pixel).",
394 doc=
"Effective exposure time calculated from psfSigma, skyBg, and "
395 "zeroPoint (seconds).",
399 "effTimePsfSigmaScale",
401 doc=
"PSF scaling of the effective exposure time."
406 doc=
"Sky background scaling of the effective exposure time."
409 "effTimeZeroPointScale",
411 doc=
"Zeropoint scaling of the effective exposure time."
416 doc=
"Magnitude limit at SNR=5 (M5) calculated from psfSigma, "
417 "skyBg, zeroPoint, and readNoise.",
422 """Write summary-statistic columns into a record.
426 record : `lsst.afw.table.BaseRecord`
427 Record to update. This is expected to frequently be an
428 `ExposureRecord` instance (with higher-level code adding other
429 columns and objects), but this method can work with any record
432 for field
in dataclasses.fields(self):
433 value = getattr(self, field.name)
434 if field.name ==
"version":
436 elif field.type.startswith(
"list"):
437 record[field.name][:] = value
439 record[field.name] = value
443 """Read summary-statistic columns from a record into ``self``.
447 record : `lsst.afw.table.BaseRecord`
448 Record to read from. This is expected to frequently be an
449 `ExposureRecord` instance (with higher-level code adding other
450 columns and objects), but this method can work with any record
451 type, ignoring any attributes or columns it doesn't recognize.
455 summary : `ExposureSummaryStats`
456 Summary statistics object created from the given record.
461 record[field.name]
if not field.type.startswith(
"list")
462 else [float(v)
for v
in record[field.name]]
464 for field
in dataclasses.fields(cls)
465 if field.name !=
"version"