Coverage for python/lsst/cell_coadds/_identifiers.py: 89%
43 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-01 13:29 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-01 13:29 +0000
1# This file is part of cell_coadds.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22from __future__ import annotations
24__all__ = (
25 "PatchIdentifiers",
26 "CellIdentifiers",
27 "ObservationIdentifiers",
28)
31from dataclasses import dataclass
32from typing import cast
34from lsst.daf.butler import DataCoordinate, DimensionRecord
35from lsst.pipe.base import Instrument
36from lsst.skymap import Index2D
39@dataclass(frozen=True)
40class PatchIdentifiers:
41 """Struct of identifiers for a coadd patch."""
43 skymap: str
44 """The name of the skymap this patch belongs to.
45 """
47 tract: int
48 """The name of the tract this patch belongs to.
49 """
51 patch: Index2D
52 """Identifiers for the patch itself.
53 """
55 band: str | None
56 """Name of the band, if any.
57 """
59 @classmethod
60 def from_data_id(cls, data_id: DataCoordinate) -> PatchIdentifiers:
61 """Construct from a data ID.
63 Parameters
64 ----------
65 data_id : `~lsst.daf.butler.DataCoordinate`
66 Fully-expanded data ID that includes the 'patch' dimension and
67 optionally the `band` dimension.
69 Returns
70 -------
71 identifiers : `PatchIdentifiers`
72 Struct of identifiers for this patch.
73 """
74 patch_record = cast(DimensionRecord, data_id.records["patch"])
75 return cls(
76 skymap=cast(str, data_id["skymap"]),
77 tract=cast(int, data_id["tract"]),
78 patch=Index2D(x=patch_record.cell_x, y=patch_record.cell_y),
79 band=cast(str, data_id.get("band")),
80 )
83@dataclass(frozen=True)
84class CellIdentifiers(PatchIdentifiers):
85 """Struct of identifiers for a coadd cell."""
87 cell: Index2D
88 """Identifiers for the cell itself."""
90 @classmethod
91 def from_data_id( # type: ignore [override]
92 cls, data_id: DataCoordinate, cell: Index2D
93 ) -> CellIdentifiers:
94 """Construct from a data ID and a cell index.
96 Parameters
97 ----------
98 data_id : `~lsst.daf.butler.DataCoordinate`
99 Fully-expanded data ID that includes the 'patch' dimension and
100 optionally the `band` dimension.
101 cell : `~lsst.skymap.Index2D`
102 Index of the cell within the patch.
104 Returns
105 -------
106 identifiers : `CellIdentifiers`
107 Struct of identifiers for this cell within a patch.
108 """
109 patch_record = cast(DimensionRecord, data_id.records["patch"])
110 return cls(
111 skymap=cast(str, data_id["skymap"]),
112 tract=cast(int, data_id["tract"]),
113 patch=Index2D(x=patch_record.cell_x, y=patch_record.cell_y),
114 band=cast(str, data_id.get("band")),
115 cell=cell,
116 )
119@dataclass(frozen=True)
120class ObservationIdentifiers:
121 """Struct of identifiers for an observation that contributed to a coadd
122 cell.
123 """
125 instrument: str
126 """Name of the instrument that this observation was taken with.
127 """
129 packed: int
130 """ID that uniquely identifies both the visit and detector by packing
131 together their IDs.
132 """
134 visit: int
135 """Unique identifier for the visit.
137 A visit may be comprised of more than one exposure only if all were
138 observed back-to-back with no dithers, allowing them to be combined early
139 the processing with no resampling. All detector-level images in a visit
140 share the same visit ID.
141 """
143 detector: int
144 """Unique identifier for the detector.
145 """
147 @classmethod
148 def from_data_id(cls, data_id: DataCoordinate) -> ObservationIdentifiers:
149 """Construct from a data ID.
151 Parameters
152 ----------
153 data_id : `~lsst.daf.butler.DataCoordinate`
154 Fully-expanded data ID that includes the 'visit' and 'detector'
155 dimensions.
157 Returns
158 -------
159 identifiers : `ObservationIdentifiers`
160 Struct of identifiers for this observation.
161 """
162 packer = Instrument.make_default_dimension_packer(data_id, is_exposure=False)
163 return cls(
164 instrument=cast(str, data_id["instrument"]),
165 packed=cast(int, packer.pack(data_id, returnMaxBits=False)),
166 visit=cast(int, data_id["visit"]),
167 detector=cast(int, data_id["detector"]),
168 )