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 CatalogMeasurementBaseConfig, CatalogMeasurementBaseTask 

24 

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

26 

27 

28class DetectorMeasurementConnections(MetricConnections, 

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

30 defaultTemplates={"photoCalibName": "calexp.photoCalib", 

31 "externalPhotoCalibName": "fgcm", 

32 "wcsName": "calexp.wcs", 

33 "externalWcsName": "jointcal"}): 

34 

35 catalog = pipeBase.connectionTypes.Input( 

36 doc="Source catalog.", 

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

38 storageClass="SourceCatalog", 

39 name="src" 

40 ) 

41 skyWcs = pipeBase.connectionTypes.Input( 

42 doc="WCS for the catalog.", 

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

44 storageClass="Wcs", 

45 name="{wcsName}" 

46 ) 

47 photoCalib = pipeBase.connectionTypes.Input( 

48 doc="Photometric calibration object.", 

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

50 storageClass="PhotoCalib", 

51 name="{photoCalibName}" 

52 ) 

53 externalSkyWcsTractCatalog = pipeBase.connectionTypes.Input( 

54 doc=("Per-tract, per-visit wcs calibrations. These catalogs use the detector " 

55 "id for the catalog id, sorted on id for fast lookup."), 

56 name="{externalWcsName}SkyWcsCatalog", 

57 storageClass="ExposureCatalog", 

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

59 ) 

60 externalSkyWcsGlobalCatalog = pipeBase.connectionTypes.Input( 

61 doc=("Per-visit wcs calibrations computed globally (with no tract information). " 

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

63 "fast lookup."), 

64 name="{externalWcsName}SkyWcsCatalog", 

65 storageClass="ExposureCatalog", 

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

67 ) 

68 externalPhotoCalibTractCatalog = pipeBase.connectionTypes.Input( 

69 doc=("Per-tract, per-visit photometric calibrations. These catalogs use the " 

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

71 name="{externalPhotoCalibName}PhotoCalibCatalog", 

72 storageClass="ExposureCatalog", 

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

74 ) 

75 externalPhotoCalibGlobalCatalog = pipeBase.connectionTypes.Input( 

76 doc=("Per-visit photometric calibrations computed globally (with no tract " 

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

78 "sorted on id for fast lookup."), 

79 name="{externalPhotoCalibName}PhotoCalibCatalog", 

80 storageClass="ExposureCatalog", 

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

82 ) 

83 measurement = pipeBase.connectionTypes.Output( 

84 doc="Per-detector measurement.", 

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

86 storageClass="MetricValue", 

87 name="metricvalue_{package}_{metric}" 

88 ) 

89 

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

91 super().__init__(config=config) 

92 if config.doApplyExternalSkyWcs: 

93 if config.useGlobalExternalSkyWcs: 

94 self.inputs.remove("externalSkyWcsTractCatalog") 

95 else: 

96 self.inputs.remove("externalSkyWcsGlobalCatalog") 

97 else: 

98 self.inputs.remove("externalSkyWcsTractCatalog") 

99 self.inputs.remove("externalSkyWcsGlobalCatalog") 

100 if config.doApplyExternalPhotoCalib: 

101 if config.useGlobalExternalPhotoCalib: 

102 self.inputs.remove("externalPhotoCalibTractCatalog") 

103 else: 

104 self.inputs.remove("externalPhotoCalibGlobalCatalog") 

105 else: 

106 self.inputs.remove("externalPhotoCalibTractCatalog") 

107 self.inputs.remove("externalPhotoCalibGlobalCatalog") 

108 

109 

110class DetectorMeasurementConfig(CatalogMeasurementBaseConfig, 

111 pipelineConnections=DetectorMeasurementConnections): 

112 doApplyExternalSkyWcs = pexConfig.Field(doc="Whether or not to use the external wcs.", 

113 dtype=bool, default=False) 

114 useGlobalExternalSkyWcs = pexConfig.Field(doc="Whether or not to use the global external wcs.", 

115 dtype=bool, default=False) 

116 doApplyExternalPhotoCalib = pexConfig.Field(doc="Whether or not to use the external photoCalib.", 

117 dtype=bool, default=False) 

118 useGlobalExternalPhotoCalib = pexConfig.Field(doc="Whether or not to use the global external photoCalib.", 

119 dtype=bool, default=False) 

120 

121 

122class DetectorMeasurementTask(CatalogMeasurementBaseTask): 

123 ConfigClass = DetectorMeasurementConfig 

124 _DefaultName = "detectorMeasurementTask" 

125 

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

127 inputs = butlerQC.get(inputRefs) 

128 if self.config.doApplyExternalPhotoCalib: 

129 detector = inputRefs.catalog.dataId['detector'] 

130 if self.config.useGlobalExternalPhotoCalib: 

131 externalPhotoCalibCatalog = inputs.pop('externalPhotoCalibGlobalCatalog') 

132 else: 

133 externalPhotoCalibCatalog = inputs.pop('externalPhotoCalibTractCatalog') 

134 row = externalPhotoCalibCatalog.find(detector) 

135 externalPhotoCalib = row.getPhotoCalib() 

136 inputs['photoCalib'] = externalPhotoCalib 

137 if self.config.doApplyExternalSkyWcs: 

138 detector = inputRefs.catalog.dataId['detector'] 

139 if self.config.useGlobalExternalSkyWcs: 

140 externalSkyWcsCatalog = inputs.pop('externalSkyWcsGlobalCatalog') 

141 else: 

142 externalSkyWcsCatalog = inputs.pop('externalSkyWcsTractCatalog') 

143 row = externalSkyWcsCatalog.find(detector) 

144 externalSkyWcs = row.getWcs() 

145 inputs['skyWcs'] = externalSkyWcs 

146 

147 outputs = self.run(**inputs) 

148 if outputs.measurement is not None: 

149 butlerQC.put(outputs, outputRefs) 

150 else: 

151 self.log.debug("Skipping measurement of {!r} on {} " 

152 "as not applicable.", self, inputRefs)