22from __future__
import annotations
25 "ExtendedPsfCandidateInfo",
26 "ExtendedPsfCandidateSerializationModel",
27 "ExtendedPsfCandidatesSerializationModel",
28 "ExtendedPsfCandidate",
29 "ExtendedPsfCandidates",
33from collections.abc
import Sequence
34from types
import EllipsisType
37from astro_metadata_translator
import ObservationInfo
38from pydantic
import BaseModel, Field
40from lsst.images
import (
43 ImageSerializationModel,
46 MaskedImageSerializationModel,
51from lsst.images.serialization
import ArchiveTree, InputArchive, MetadataValue, OutputArchive, Quantity
52from lsst.images.utils
import is_none
53from lsst.resources
import ResourcePathExpression
57 """Information about a star in an `ExtendedPsfCandidate`.
61 visit : `int`, optional
62 The visit during which the star was observed.
63 detector : `int`, optional
64 The detector on which the star was observed.
65 ref_id : `int`, optional
66 The reference catalog ID for the star.
67 ref_mag : `float`, optional
68 The reference magnitude for the star.
69 position_x : `float`, optional
70 The x-coordinate of the star in the focal plane.
71 position_y : `float`, optional
72 The y-coordinate of the star in the focal plane.
73 focal_plane_radius : `~lsst.images.utils.Quantity`, optional
74 The radius of the star from the center of the focal plane.
75 focal_plane_angle : `~lsst.images.utils.Quantity`, optional
76 The angle of the star in the focal plane, measured from the +x axis.
79 visit: int |
None =
None
80 detector: int |
None =
None
81 ref_id: int |
None =
None
82 ref_mag: float |
None =
None
83 position_x: float |
None =
None
84 position_y: float |
None =
None
85 focal_plane_radius: Quantity |
None =
None
86 focal_plane_angle: Quantity |
None =
None
89 attrs =
", ".join(f
"{k}={v!r}" for k, v
in self.__dict__.items())
90 return f
"ExtendedPsfCandidateInfo({attrs})"
96 """A Pydantic model to represent a serialized `ExtendedPsfCandidate`."""
98 psf_kernel_image: ImageSerializationModel[P] |
None = Field(
101 description=
"Kernel image of the PSF at the cutout center.",
103 star_info: ExtendedPsfCandidateInfo = Field(description=
"Information about the star in the cutout.")
105 def deserialize(self, archive: InputArchive[Any], *, bbox: Box |
None =
None) -> ExtendedPsfCandidate:
106 masked_image = super().
deserialize(archive, bbox=bbox)
108 self.psf_kernel_image.
deserialize(archive)
if self.psf_kernel_image
is not None else None
112 mask=masked_image.mask,
113 variance=masked_image.variance,
114 psf_kernel_image=psf_kernel_image,
115 star_info=self.star_info,
116 )._finish_deserialize(self)
120 """A Pydantic model to represent serialized `ExtendedPsfCandidates`."""
122 candidates: list[ExtendedPsfCandidateSerializationModel[P]] = Field(
123 default_factory=list,
124 description=
"The candidate cutouts in this collection.",
127 def deserialize(self, archive: InputArchive[Any]) -> ExtendedPsfCandidates:
129 [candidate_model.deserialize(archive)
for candidate_model
in self.candidates],
130 metadata=self.metadata,
135 """A cutout centered on a star, with associated metadata.
139 image : `~lsst.images.Image`
140 The main data image for this star cutout.
141 mask : `~lsst.images.Mask`, optional
142 Bitmask that annotates the main image's pixels.
143 variance : `~lsst.images.Image`, optional
144 Per-pixel variance estimates for the image.
145 mask_schema : `~lsst.images.MaskSchema`, optional
146 Schema for the mask, required if a mask is provided.
147 projection : `~lsst.images.Projection`, optional
148 Projection to map pixels to the sky.
149 obs_info : `~astro_metadata_translator.ObservationInfo`, optional
150 Standardized description of visit metadata.
151 metadata : `dict` [`str`, `MetadataValue`], optional
152 Additional metadata to associate with this cutout.
153 psf_kernel_image : `~lsst.images.Image`, optional
154 Kernel image of the PSF at the cutout center.
155 star_info : `ExtendedPsfCandidateInfo`, optional
156 Information about the star in the cutout.
160 psf_kernel_image : `~lsst.images.Image`
161 Kernel image of the PSF at the cutout center.
162 star_info : `ExtendedPsfCandidateInfo`
163 Information about the star in this cutout.
170 mask: Mask |
None =
None,
171 variance: Image |
None =
None,
172 mask_schema: MaskSchema |
None =
None,
173 projection: Projection |
None =
None,
174 obs_info: ObservationInfo |
None =
None,
175 metadata: dict[str, MetadataValue] |
None =
None,
176 psf_kernel_image: Image |
None =
None,
177 star_info: ExtendedPsfCandidateInfo |
None =
None,
183 mask_schema=mask_schema,
184 projection=projection,
192 def __getitem__(self, bbox: Box | EllipsisType) -> ExtendedPsfCandidate:
196 return self._transfer_metadata(
200 mask=self.mask[bbox],
201 variance=self.variance[bbox],
209 return f
"ExtendedPsfCandidate({self.image!s}, {list(self.mask.schema.names)}, {self.star_info})"
213 f
"ExtendedPsfCandidate({self.image!r}, mask_schema={self.mask.schema!r}, "
214 f
"star_info={self.star_info!r})"
219 """Kernel image of the PSF at the cutout center."""
221 raise RuntimeError(
"No PSF kernel image is attached to this ExtendedPsfCandidate.")
226 """Return the ExtendedPsfCandidateInfo associated with this star."""
229 def copy(self) -> ExtendedPsfCandidate:
230 """Deep-copy the star cutout, metadata, and star info."""
231 return self._transfer_metadata(
233 image=self._image.
copy(),
234 mask=self._mask.
copy(),
235 variance=self._variance.
copy(),
242 def serialize(self, archive: OutputArchive[Any]) -> ExtendedPsfCandidateSerializationModel:
243 masked_image_model = super().
serialize(archive)
244 serialized_psf_kernel_image = (
245 archive.serialize_direct(
253 **masked_image_model.model_dump(),
254 psf_kernel_image=serialized_psf_kernel_image,
259 def _get_archive_tree_type[P: BaseModel](
260 pointer_type: type[P],
261 ) -> type[ExtendedPsfCandidateSerializationModel[P]]:
262 return ExtendedPsfCandidateSerializationModel[pointer_type]
266 """A collection of star cutouts.
270 candidates : `Iterable` [`ExtendedPsfCandidate`]
271 Collection of `ExtendedPsfCandidate` instances.
272 metadata : `dict` [`str`, `MetadataValue`], optional
273 Global metadata associated with the collection.
277 metadata : `dict` [`str`, `MetadataValue`]
278 Global metadata associated with the collection.
279 ref_id_map : `dict` [`int`, `ExtendedPsfCandidate`]
280 A mapping from reference IDs to `ExtendedPsfCandidate` objects.
281 Only includes candidates with valid reference IDs.
286 candidates: Sequence[ExtendedPsfCandidate],
287 metadata: dict[str, MetadataValue] |
None =
None,
290 self.
_metadata = {}
if metadata
is None else dict(metadata)
292 candidate.star_info.ref_id: candidate
293 for candidate
in self
294 if candidate.star_info.ref_id
is not None
301 if isinstance(index, slice):
309 return f
"ExtendedPsfCandidates(length={len(self)})"
315 """Return the collection's global metadata as a dict."""
320 """Map reference IDs to `ExtendedPsfCandidate` objects."""
324 def read_fits(cls, url: ResourcePathExpression) -> ExtendedPsfCandidates:
325 """Read a collection from a FITS file.
330 URL of the file to read; may be any type supported by
331 `lsst.resources.ResourcePath`.
333 return fits.read(cls, url).deserialized
336 """Write the collection to a FITS file.
341 Name of the file to write to. Must not already exist.
343 fits.write(self, filename)
345 def serialize(self, archive: OutputArchive[Any]) -> ExtendedPsfCandidatesSerializationModel:
348 archive.serialize_direct(f
"candidate_{index}", candidate.serialize)
349 for index, candidate
in enumerate(self.
_candidates)
355 def _get_archive_tree_type[P: BaseModel](
356 pointer_type: type[P],
357 ) -> type[ExtendedPsfCandidatesSerializationModel[P]]:
358 return ExtendedPsfCandidatesSerializationModel[pointer_type]
ExtendedPsfCandidateInfo _star_info
__init__(self, Image image, *, Mask|None mask=None, Image|None variance=None, MaskSchema|None mask_schema=None, Projection|None projection=None, ObservationInfo|None obs_info=None, dict[str, MetadataValue]|None metadata=None, Image|None psf_kernel_image=None, ExtendedPsfCandidateInfo|None star_info=None)
ExtendedPsfCandidate copy(self)
ExtendedPsfCandidateSerializationModel serialize(self, OutputArchive[Any] archive)
Image psf_kernel_image(self)
ExtendedPsfCandidateInfo star_info(self)
ExtendedPsfCandidate __getitem__(self, Box|EllipsisType bbox)
ExtendedPsfCandidatesSerializationModel serialize(self, OutputArchive[Any] archive)
None write_fits(self, str filename)
ExtendedPsfCandidates read_fits(cls, ResourcePathExpression url)
__init__(self, Sequence[ExtendedPsfCandidate] candidates, dict[str, MetadataValue]|None metadata=None)
ExtendedPsfCandidate deserialize(self, InputArchive[Any] archive, *, Box|None bbox=None)
ExtendedPsfCandidateInfo star_info
ImageSerializationModel psf_kernel_image