Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# This product includes software developed by the LSST Project 

2# (https://www.lsst.org). 

3# See the COPYRIGHT file at the top-level directory of this distribution 

4# for details of code ownership. 

5# 

6# This program is free software: you can redistribute it and/or modify 

7# it under the terms of the GNU General Public License as published by 

8# the Free Software Foundation, either version 3 of the License, or 

9# (at your option) any later version. 

10# 

11# This program is distributed in the hope that it will be useful, 

12# but WITHOUT ANY WARRANTY; without even the implied warranty of 

13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14# GNU General Public License for more details. 

15# 

16# You should have received a copy of the GNU General Public License 

17# along with this program. If not, see <https://www.gnu.org/licenses/>. 

18 

19import lsst.pipe.base as pipeBase 

20from lsst.verify.tasks import MetricConnections 

21import lsst.pex.config as pexConfig 

22 

23from lsst.faro.base.CatalogMeasurementBase import ( 

24 CatalogMeasurementBaseConfig, 

25 CatalogMeasurementBaseTask, 

26) 

27 

28__all__ = ("DetectorMeasurementConfig", "DetectorMeasurementTask") 

29 

30 

31class DetectorMeasurementConnections( 

32 MetricConnections, 

33 dimensions=("instrument", "visit", "detector", "band"), 

34 defaultTemplates={ 

35 "photoCalibName": "calexp.photoCalib", 

36 "externalPhotoCalibName": "fgcm", 

37 "wcsName": "calexp.wcs", 

38 "externalWcsName": "jointcal", 

39 }, 

40): 

41 

42 catalog = pipeBase.connectionTypes.Input( 

43 doc="Source catalog.", 

44 dimensions=("instrument", "visit", "detector", "band"), 

45 storageClass="SourceCatalog", 

46 name="src", 

47 ) 

48 skyWcs = pipeBase.connectionTypes.Input( 

49 doc="WCS for the catalog.", 

50 dimensions=("instrument", "visit", "detector", "band"), 

51 storageClass="Wcs", 

52 name="{wcsName}", 

53 ) 

54 photoCalib = pipeBase.connectionTypes.Input( 

55 doc="Photometric calibration object.", 

56 dimensions=("instrument", "visit", "detector", "band"), 

57 storageClass="PhotoCalib", 

58 name="{photoCalibName}", 

59 ) 

60 externalSkyWcsTractCatalog = pipeBase.connectionTypes.Input( 

61 doc=( 

62 "Per-tract, per-visit wcs calibrations. These catalogs use the detector " 

63 "id for the catalog id, sorted on id for fast lookup." 

64 ), 

65 name="{externalWcsName}SkyWcsCatalog", 

66 storageClass="ExposureCatalog", 

67 dimensions=("instrument", "visit", "tract"), 

68 ) 

69 externalSkyWcsGlobalCatalog = pipeBase.connectionTypes.Input( 

70 doc=( 

71 "Per-visit wcs calibrations computed globally (with no tract information). " 

72 "These catalogs use the detector id for the catalog id, sorted on id for " 

73 "fast lookup." 

74 ), 

75 name="{externalWcsName}SkyWcsCatalog", 

76 storageClass="ExposureCatalog", 

77 dimensions=("instrument", "visit"), 

78 ) 

79 externalPhotoCalibTractCatalog = pipeBase.connectionTypes.Input( 

80 doc=( 

81 "Per-tract, per-visit photometric calibrations. These catalogs use the " 

82 "detector id for the catalog id, sorted on id for fast lookup." 

83 ), 

84 name="{externalPhotoCalibName}PhotoCalibCatalog", 

85 storageClass="ExposureCatalog", 

86 dimensions=("instrument", "visit", "tract"), 

87 ) 

88 externalPhotoCalibGlobalCatalog = pipeBase.connectionTypes.Input( 

89 doc=( 

90 "Per-visit photometric calibrations computed globally (with no tract " 

91 "information). These catalogs use the detector id for the catalog id, " 

92 "sorted on id for fast lookup." 

93 ), 

94 name="{externalPhotoCalibName}PhotoCalibCatalog", 

95 storageClass="ExposureCatalog", 

96 dimensions=("instrument", "visit"), 

97 ) 

98 measurement = pipeBase.connectionTypes.Output( 

99 doc="Per-detector measurement.", 

100 dimensions=("instrument", "visit", "detector", "band"), 

101 storageClass="MetricValue", 

102 name="metricvalue_{package}_{metric}", 

103 ) 

104 

105 def __init__(self, *, config=None): 

106 super().__init__(config=config) 

107 if config.doApplyExternalSkyWcs: 

108 if config.useGlobalExternalSkyWcs: 

109 self.inputs.remove("externalSkyWcsTractCatalog") 

110 else: 

111 self.inputs.remove("externalSkyWcsGlobalCatalog") 

112 else: 

113 self.inputs.remove("externalSkyWcsTractCatalog") 

114 self.inputs.remove("externalSkyWcsGlobalCatalog") 

115 if config.doApplyExternalPhotoCalib: 

116 if config.useGlobalExternalPhotoCalib: 

117 self.inputs.remove("externalPhotoCalibTractCatalog") 

118 else: 

119 self.inputs.remove("externalPhotoCalibGlobalCatalog") 

120 else: 

121 self.inputs.remove("externalPhotoCalibTractCatalog") 

122 self.inputs.remove("externalPhotoCalibGlobalCatalog") 

123 

124 

125class DetectorMeasurementConfig( 

126 CatalogMeasurementBaseConfig, pipelineConnections=DetectorMeasurementConnections 

127): 

128 doApplyExternalSkyWcs = pexConfig.Field( 

129 doc="Whether or not to use the external wcs.", dtype=bool, default=False 

130 ) 

131 useGlobalExternalSkyWcs = pexConfig.Field( 

132 doc="Whether or not to use the global external wcs.", dtype=bool, default=False 

133 ) 

134 doApplyExternalPhotoCalib = pexConfig.Field( 

135 doc="Whether or not to use the external photoCalib.", dtype=bool, default=False 

136 ) 

137 useGlobalExternalPhotoCalib = pexConfig.Field( 

138 doc="Whether or not to use the global external photoCalib.", 

139 dtype=bool, 

140 default=False, 

141 ) 

142 

143 

144class DetectorMeasurementTask(CatalogMeasurementBaseTask): 

145 ConfigClass = DetectorMeasurementConfig 

146 _DefaultName = "detectorMeasurementTask" 

147 

148 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

149 inputs = butlerQC.get(inputRefs) 

150 if self.config.doApplyExternalPhotoCalib: 

151 detector = inputRefs.catalog.dataId["detector"] 

152 if self.config.useGlobalExternalPhotoCalib: 

153 externalPhotoCalibCatalog = inputs.pop( 

154 "externalPhotoCalibGlobalCatalog" 

155 ) 

156 else: 

157 externalPhotoCalibCatalog = inputs.pop("externalPhotoCalibTractCatalog") 

158 row = externalPhotoCalibCatalog.find(detector) 

159 externalPhotoCalib = row.getPhotoCalib() 

160 inputs["photoCalib"] = externalPhotoCalib 

161 if self.config.doApplyExternalSkyWcs: 

162 detector = inputRefs.catalog.dataId["detector"] 

163 if self.config.useGlobalExternalSkyWcs: 

164 externalSkyWcsCatalog = inputs.pop("externalSkyWcsGlobalCatalog") 

165 else: 

166 externalSkyWcsCatalog = inputs.pop("externalSkyWcsTractCatalog") 

167 row = externalSkyWcsCatalog.find(detector) 

168 externalSkyWcs = row.getWcs() 

169 inputs["skyWcs"] = externalSkyWcs 

170 

171 outputs = self.run(**inputs) 

172 if outputs.measurement is not None: 

173 butlerQC.put(outputs, outputRefs) 

174 else: 

175 self.log.debug( 

176 "Skipping measurement of {!r} on {} " "as not applicable.", 

177 self, 

178 inputRefs, 

179 )