Coverage for python/lsst/obs/rubinGenericCamera/_instrument.py: 98%

44 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-10 10:01 +0000

1# This file is part of obs_rubinGenericCamera 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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 <http://www.gnu.org/licenses/>. 

21 

22__all__ = ("RubinGenericCamera", "StarTrackerNarrow", "StarTrackerWide", "StarTrackerFast") 

23 

24import lsst.obs.base.yamlCamera as yamlCamera 

25from lsst.obs.base import VisitSystem 

26from lsst.obs.lsst import LsstCam 

27from lsst.resources import ResourcePath 

28from .filters import RUBIN_GENERIC_CAMERA_FILTER_DEFINITIONS 

29from .translator import StarTrackerNarrowTranslator, StarTrackerWideTranslator, StarTrackerFastTranslator 

30 

31 

32class RubinGenericCamera(LsstCam): 

33 """Gen3 Butler specialization for the Rubin Generic Cameras 

34 

35 Parameters 

36 ---------- 

37 camera : `lsst.cameraGeom.Camera` 

38 Camera object from which to extract detector information. 

39 filters : `list` of `FilterDefinition` 

40 An ordered list of filters to define the set of PhysicalFilters 

41 associated with this instrument in the registry. 

42 

43 While both the camera geometry and the set of filters associated with a 

44 camera are expected to change with time in general, their Butler Registry 

45 representations defined by an Instrument do not. Instead: 

46 

47 - We only extract names, IDs, and purposes from the detectors in the 

48 camera, which should be static information that actually reflects 

49 detector "slots" rather than the physical sensors themselves. Because 

50 the distinction between physical sensors and slots is unimportant in 

51 the vast majority of Butler use cases, we just use "detector" even 

52 though the concept really maps better to "detector slot". Ideally in 

53 the future this distinction between static and time-dependent 

54 information would be encoded in cameraGeom itself (e.g. by making the 

55 time-dependent Detector class inherit from a related class that only 

56 carries static content). 

57 

58 - The Butler Registry is expected to contain physical_filter entries for 

59 all filters an instrument has ever had, because we really only care 

60 about which filters were used for particular observations, not which 

61 filters were *available* at some point in the past. And changes in 

62 individual filters over time will be captured as changes in their 

63 TransmissionCurve datasets, not changes in the registry content (which 

64 is really just a label). While at present Instrument and Registry 

65 do not provide a way to add new physical_filters, they will in the 

66 future. 

67 """ 

68 filterDefinitions = RUBIN_GENERIC_CAMERA_FILTER_DEFINITIONS 

69 instrument = None # you must specialise this class 

70 policyName = None # you must specialise this class 

71 translatorClass = None # you must specialise this class 

72 visitSystem = VisitSystem.BY_SEQ_START_END 

73 

74 @classmethod 

75 def getCamera(cls): 

76 # Constructing a YAML camera takes a long time but we rely on 

77 # yamlCamera to cache for us. 

78 cameraYamlFile = ResourcePath( 

79 f"resource://lsst.obs.rubinGenericCamera/resources/policy/{cls.policyName}.yaml" 

80 ) 

81 with cameraYamlFile.as_local() as local_file: 

82 return yamlCamera.makeCamera(local_file.ospath) 

83 

84 def getRawFormatter(self, dataId): 

85 return None 

86 

87 def extractDetectorRecord(self, camGeomDetector): 

88 """Create a Gen3 Detector entry dict from a cameraGeom.Detector. 

89 """ 

90 purpose = str(camGeomDetector.getType()).split(".")[-1] 

91 

92 return dict( 

93 instrument=self.getName(), 

94 id=camGeomDetector.getId(), 

95 full_name=camGeomDetector.getName(), 

96 purpose=purpose, 

97 ) 

98 

99 

100class StarTrackerNarrow(RubinGenericCamera): 

101 """Specialization of Rubin Generic Camera for the narrow-field StarTracker 

102 

103 Parameters 

104 ---------- 

105 camera : `lsst.cameraGeom.Camera` 

106 Camera object from which to extract detector information. 

107 filters : `list` of `FilterDefinition` 

108 An ordered list of filters to define the set of PhysicalFilters 

109 associated with this instrument in the registry. 

110 """ 

111 instrument = "StarTrackerNarrow" 

112 policyName = "starTrackerNarrow" 

113 translatorClass = StarTrackerNarrowTranslator 

114 

115 def getRawFormatter(self, dataId): 

116 # Docstring inherited from Instrument.getRawFormatter 

117 # local import to prevent circular dependency 

118 from .rawFormatter import StarTrackerNarrowRawFormatter 

119 return StarTrackerNarrowRawFormatter 

120 

121 

122class StarTrackerWide(StarTrackerNarrow): 

123 """Specialization of Rubin Generic Camera for the wide-field StarTracker 

124 

125 Parameters 

126 ---------- 

127 camera : `lsst.cameraGeom.Camera` 

128 Camera object from which to extract detector information. 

129 filters : `list` of `FilterDefinition` 

130 An ordered list of filters to define the set of PhysicalFilters 

131 associated with this instrument in the registry. 

132 """ 

133 instrument = "StarTrackerWide" 

134 policyName = "starTrackerWide" 

135 translatorClass = StarTrackerWideTranslator 

136 

137 def getRawFormatter(self, dataId): 

138 # Docstring inherited from Instrument.getRawFormatter 

139 # local import to prevent circular dependency 

140 from .rawFormatter import StarTrackerWideRawFormatter 

141 return StarTrackerWideRawFormatter 

142 

143 

144class StarTrackerFast(StarTrackerNarrow): 

145 """Specialization of Rubin Generic Camera for the high-cadence Star Tracker 

146 

147 Parameters 

148 ---------- 

149 camera : `lsst.cameraGeom.Camera` 

150 Camera object from which to extract detector information. 

151 filters : `list` of `FilterDefinition` 

152 An ordered list of filters to define the set of PhysicalFilters 

153 associated with this instrument in the registry. 

154 """ 

155 instrument = "StarTrackerFast" 

156 policyName = "starTrackerFast" 

157 translatorClass = StarTrackerFastTranslator 

158 

159 def getRawFormatter(self, dataId): 

160 # Docstring inherited from Instrument.getRawFormatter 

161 # local import to prevent circular dependency 

162 from .rawFormatter import StarTrackerFastRawFormatter 

163 return StarTrackerFastRawFormatter