Coverage for python/lsst/cell_coadds/_identifiers.py: 89%

43 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-12 14:15 +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/>. 

21 

22from __future__ import annotations 

23 

24__all__ = ( 

25 "PatchIdentifiers", 

26 "CellIdentifiers", 

27 "ObservationIdentifiers", 

28) 

29 

30 

31from dataclasses import dataclass 

32from typing import cast 

33 

34from lsst.daf.butler import DataCoordinate, DimensionRecord 

35from lsst.pipe.base import Instrument 

36from lsst.skymap import Index2D 

37 

38 

39@dataclass(frozen=True) 

40class PatchIdentifiers: 

41 """Struct of identifiers for a coadd patch.""" 

42 

43 skymap: str 

44 """The name of the skymap this patch belongs to. 

45 """ 

46 

47 tract: int 

48 """The name of the tract this patch belongs to. 

49 """ 

50 

51 patch: Index2D 

52 """Identifiers for the patch itself. 

53 """ 

54 

55 band: str | None 

56 """Name of the band, if any. 

57 """ 

58 

59 @classmethod 

60 def from_data_id(cls, data_id: DataCoordinate) -> PatchIdentifiers: 

61 """Construct from a data ID. 

62 

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. 

68 

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=data_id.get("band"), 

80 ) 

81 

82 

83@dataclass(frozen=True) 

84class CellIdentifiers(PatchIdentifiers): 

85 """Struct of identifiers for a coadd cell.""" 

86 

87 cell: Index2D 

88 """Identifiers for the cell itself.""" 

89 

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. 

95 

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. 

103 

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=data_id.get("band"), 

115 cell=cell, 

116 ) 

117 

118 

119@dataclass(frozen=True) 

120class ObservationIdentifiers: 

121 """Struct of identifiers for an observation that contributed to a coadd 

122 cell. 

123 """ 

124 

125 instrument: str 

126 """Name of the instrument that this observation was taken with. 

127 """ 

128 

129 packed: int 

130 """ID that uniquely identifies both the visit and detector by packing 

131 together their IDs. 

132 """ 

133 

134 visit: int 

135 """Unique identifier for the visit. 

136 

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 """ 

142 

143 detector: int 

144 """Unique identifier for the detector. 

145 """ 

146 

147 @classmethod 

148 def from_data_id(cls, data_id: DataCoordinate) -> ObservationIdentifiers: 

149 """Construct from a data ID. 

150 

151 Parameters 

152 ---------- 

153 data_id : `~lsst.daf.butler.DataCoordinate` 

154 Fully-expanded data ID that includes the 'visit' and 'detector' 

155 dimensions. 

156 

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 )