21from __future__
import annotations
24from typing
import TYPE_CHECKING
28from ..typehandling
import Storable, StorableHelperFactory
31 from ..table
import BaseRecord, Schema
33__all__ = (
"ExposureSummaryStats", )
36def _default_corners():
37 return [float(
"nan")] * 4
42 _persistence_name =
'ExposureSummaryStats'
44 _factory = StorableHelperFactory(__name__, _persistence_name)
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 zenithDistance: float =
float(
'nan')
70 """Bounding box center zenith distance (degrees)."""
72 zeroPoint: float =
float(
'nan')
73 """Mean zeropoint in detector (mag)."""
75 skyBg: float =
float(
'nan')
76 """Average sky background (ADU)."""
78 skyNoise: float =
float(
'nan')
79 """Average sky noise (ADU)."""
81 meanVar: float =
float(
'nan')
82 """Mean variance of the weight plane (ADU**2)."""
84 raCorners: list[float] = dataclasses.field(default_factory=_default_corners)
85 """Right Ascension of bounding box corners (degrees)."""
87 decCorners: list[float] = dataclasses.field(default_factory=_default_corners)
88 """Declination of bounding box corners (degrees)."""
90 astromOffsetMean: float =
float(
'nan')
91 """Astrometry match offset mean."""
93 astromOffsetStd: float =
float(
'nan')
94 """Astrometry match offset stddev."""
97 """Number of stars used for psf model."""
99 psfStarDeltaE1Median: float =
float(
'nan')
100 """Psf stars median E1 residual (starE1 - psfE1)."""
102 psfStarDeltaE2Median: float =
float(
'nan')
103 """Psf stars median E2 residual (starE2 - psfE2)."""
105 psfStarDeltaE1Scatter: float =
float(
'nan')
106 """Psf stars MAD E1 scatter (starE1 - psfE1)."""
108 psfStarDeltaE2Scatter: float =
float(
'nan')
109 """Psf stars MAD E2 scatter (starE2 - psfE2)."""
111 psfStarDeltaSizeMedian: float =
float(
'nan')
112 """Psf stars median size residual (starSize - psfSize)."""
114 psfStarDeltaSizeScatter: float =
float(
'nan')
115 """Psf stars MAD size scatter (starSize - psfSize)."""
117 psfStarScaledDeltaSizeScatter: float =
float(
'nan')
118 """Psf stars MAD size scatter scaled by psfSize**2."""
120 psfTraceRadiusDelta: float =
float(
'nan')
121 """Delta (max - min) of the model psf trace radius values evaluated on a
122 grid of unmasked pixels (pixels).
125 maxDistToNearestPsf: float = float('nan')
126 """Maximum distance of an unmasked pixel to its nearest model psf star
131 Storable.__init__(self)
136 def _getPersistenceName(self):
139 def _getPythonModule(self):
143 return yaml.dump(dataclasses.asdict(self), encoding=
'utf-8')
147 yamlDict = yaml.load(bytes, Loader=yaml.SafeLoader)
151 for _field
in list(yamlDict.keys()):
152 if _field
not in ExposureSummaryStats.__dataclass_fields__:
153 droppedFields.append(_field)
155 if len(droppedFields) > 0:
156 droppedFieldString =
", ".join([
str(f)
for f
in droppedFields])
159 f
"Could not read summary fields [{droppedFieldString}]. "
160 "Please use a newer stack."
168 """Update an schema to includes for all summary statistic fields.
173 Schema to add which fields will be added.
178 doc=
"PSF model second-moments determinant radius (center of chip) (pixel)",
183 doc=
"PSF model effective area (center of chip) (pixel**2)",
186 "psfIxx", type=
"F", doc=
"PSF model Ixx (center of chip) (pixel**2)"
189 "psfIyy", type=
"F", doc=
"PSF model Iyy (center of chip) (pixel**2)"
192 "psfIxy", type=
"F", doc=
"PSF model Ixy (center of chip) (pixel**2)"
198 doc=
"Right Ascension of bounding box corners (degrees)",
204 doc=
"Declination of bounding box corners (degrees)",
207 "ra", type=
"D", doc=
"Right Ascension of bounding box center (degrees)"
210 "dec", type=
"D", doc=
"Declination of bounding box center (degrees)"
215 doc=
"Zenith distance of bounding box center (degrees)",
217 schema.addField(
"zeroPoint", type=
"F", doc=
"Mean zeropoint in detector (mag)")
218 schema.addField(
"skyBg", type=
"F", doc=
"Average sky background (ADU)")
219 schema.addField(
"skyNoise", type=
"F", doc=
"Average sky noise (ADU)")
221 "meanVar", type=
"F", doc=
"Mean variance of the weight plane (ADU**2)"
226 doc=
"Mean offset of astrometric calibration matches (arcsec)",
231 doc=
"Standard deviation of offsets of astrometric calibration matches (arcsec)",
233 schema.addField(
"nPsfStar", type=
"I", doc=
"Number of stars used for PSF model")
235 "psfStarDeltaE1Median",
237 doc=
"Median E1 residual (starE1 - psfE1) for psf stars",
240 "psfStarDeltaE2Median",
242 doc=
"Median E2 residual (starE2 - psfE2) for psf stars",
245 "psfStarDeltaE1Scatter",
247 doc=
"Scatter (via MAD) of E1 residual (starE1 - psfE1) for psf stars",
250 "psfStarDeltaE2Scatter",
252 doc=
"Scatter (via MAD) of E2 residual (starE2 - psfE2) for psf stars",
255 "psfStarDeltaSizeMedian",
257 doc=
"Median size residual (starSize - psfSize) for psf stars (pixel)",
260 "psfStarDeltaSizeScatter",
262 doc=
"Scatter (via MAD) of size residual (starSize - psfSize) for psf stars (pixel)",
265 "psfStarScaledDeltaSizeScatter",
267 doc=
"Scatter (via MAD) of size residual scaled by median size squared",
270 "psfTraceRadiusDelta",
272 doc=
"Delta (max - min) of the model psf trace radius values evaluated on a grid of "
273 "unmasked pixels (pixel).",
276 "maxDistToNearestPsf",
278 doc=
"Maximum distance of an unmasked pixel to its nearest model psf star (pixel).",
282 """Write summary-statistic columns into a record.
287 Record to update. This is expected to frequently be an
288 `ExposureRecord` instance (
with higher-level code adding other
289 columns
and objects), but this method can work
with any record
292 for field
in dataclasses.fields(self):
293 value = getattr(self, field.name)
294 if field.name ==
"version":
296 elif field.type.startswith(
"list"):
297 record[field.name][:] = value
299 record[field.name] = value
303 """Read summary-statistic columns from a record into ``self``.
308 Record to read from. This
is expected to frequently be an
309 `ExposureRecord` instance (
with higher-level code adding other
310 columns
and objects), but this method can work
with any record
311 type, ignoring any attributes
or columns it doesn
't recognize.
315 summary : `ExposureSummaryStats`
316 Summary statistics object created from the given record.
321 record[field.name]
if not field.type.startswith(
"list")
322 else [
float(v)
for v
in record[field.name]]
324 for field
in dataclasses.fields(cls)
325 if field.name !=
"version"
None update_schema(cls, Schema schema)
None update_record(self, BaseRecord record)
ExposureSummaryStats from_record(cls, BaseRecord record)
Base class for all records.
Defines the fields and offsets for a table.
virtual bool isPersistable() const noexcept
Return true if this particular object can be persisted using afw::table::io.
Interface supporting iteration over heterogenous containers.
daf::base::PropertyList * list