Coverage for python/lsst/faro/measurement/TractMeasurement.py: 73%

42 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-17 01:37 -0700

1# This file is part of faro. 

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 lsst.afw.geom import SkyWcs 

23from lsst.afw.image import PhotoCalib 

24from lsst.afw.table import SourceCatalog 

25import lsst.pex.config as pexConfig 

26import lsst.pipe.base as pipeBase 

27 

28from lsst.faro.base.BaseSubTasks import NumSourcesMergeTask 

29from lsst.faro.base.CatalogMeasurementBase import ( 

30 CatalogMeasurementBaseConnections, 

31 CatalogMeasurementBaseConfig, 

32 CatalogMeasurementBaseTask, 

33) 

34from lsst.faro.utils.calibrated_catalog import CalibratedCatalog 

35 

36from collections import defaultdict 

37from typing import List 

38 

39__all__ = ( 

40 "TractMeasurementConnections", 

41 "TractMeasurementConfig", 

42 "TractMeasurementTask", 

43 "TractMultiBandMeasurementConnections", 

44 "TractMultiBandMeasurementConfig", 

45 "TractMultiBandMeasurementTask", 

46) 

47 

48 

49class TractMeasurementConnections( 

50 CatalogMeasurementBaseConnections, 

51 dimensions=("tract", "skymap", "band"), 

52 defaultTemplates={ 

53 "coaddName": "deepCoadd", 

54 "photoCalibName": "deepCoadd_calexp.photoCalib", 

55 "wcsName": "deepCoadd_calexp.wcs", 

56 }, 

57): 

58 

59 catalogs = pipeBase.connectionTypes.Input( 

60 doc="Object catalog.", 

61 dimensions=("tract", "patch", "skymap", "band"), 

62 storageClass="SourceCatalog", 

63 name="deepCoadd_meas", 

64 multiple=True, 

65 ) 

66 

67 photoCalibs = pipeBase.connectionTypes.Input( 

68 doc="Photometric calibration object.", 

69 dimensions=("tract", "patch", "skymap", "band"), 

70 storageClass="PhotoCalib", 

71 name="{photoCalibName}", 

72 multiple=True, 

73 ) 

74 

75 astromCalibs = pipeBase.connectionTypes.Input( 

76 doc="WCS for the catalog.", 

77 dimensions=("tract", "patch", "skymap", "band"), 

78 storageClass="Wcs", 

79 name="{wcsName}", 

80 multiple=True, 

81 ) 

82 

83 measurement = pipeBase.connectionTypes.Output( 

84 doc="Per-tract measurement.", 

85 dimensions=("tract", "skymap", "band"), 

86 storageClass="MetricValue", 

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

88 ) 

89 

90 

91class TractMeasurementConfig( 

92 CatalogMeasurementBaseConfig, pipelineConnections=TractMeasurementConnections 

93): 

94 measure = pexConfig.ConfigurableField( 

95 # The (plain old) Task that actually measures the desired metric 

96 # Should be overridden in pipelines 

97 target=NumSourcesMergeTask, 

98 doc="Measure task", 

99 ) 

100 

101 

102class TractMeasurementTask(CatalogMeasurementBaseTask): 

103 

104 ConfigClass = TractMeasurementConfig 

105 _DefaultName = "tractMeasurementTask" 

106 

107 def run( 

108 self, 

109 catalogs: List[SourceCatalog], 

110 photoCalibs: List[PhotoCalib], 

111 astromCalibs: List[SkyWcs], 

112 dataIds, 

113 ): 

114 data = defaultdict(list) 

115 for catalog, photoCalib, astromCalib, dataId in zip(catalogs, photoCalibs, astromCalibs, dataIds): 

116 data[dataId['band']].append(CalibratedCatalog(catalog, photoCalib, astromCalib)) 

117 

118 return self.measure.run(self.config.connections.metric, data) 

119 

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

121 inputs = butlerQC.get(inputRefs) 

122 inputs["dataIds"] = [ 

123 butlerQC.registry.expandDataId(cat.dataId) for cat in inputRefs.catalogs 

124 ] 

125 outputs = self.run(**inputs) 

126 if outputs.measurement is not None: 

127 butlerQC.put(outputs, outputRefs) 

128 else: 

129 self.log.debug( 

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

131 self, 

132 inputRefs, 

133 ) 

134 

135 

136class TractMultiBandMeasurementConnections( 

137 TractMeasurementConnections, 

138 dimensions=("tract", "skymap"), 

139 defaultTemplates={ 

140 "coaddName": "deepCoadd", 

141 "photoCalibName": "deepCoadd_calexp.photoCalib", 

142 }, 

143): 

144 

145 catalogs = pipeBase.connectionTypes.Input( 

146 doc="Object catalog.", 

147 dimensions=("tract", "skymap", "patch", "band"), 

148 storageClass="SourceCatalog", 

149 name="deepCoadd_forced_src", 

150 multiple=True, 

151 ) 

152 

153 photoCalibs = pipeBase.connectionTypes.Input( 

154 doc="Photometric calibration object.", 

155 dimensions=("tract", "skymap", "patch", "band"), 

156 storageClass="PhotoCalib", 

157 name="{photoCalibName}", 

158 multiple=True, 

159 ) 

160 

161 measurement = pipeBase.connectionTypes.Output( 

162 doc="Per-tract measurement.", 

163 dimensions=("tract", "skymap"), 

164 storageClass="MetricValue", 

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

166 ) 

167 

168 

169class TractMultiBandMeasurementConfig( 

170 CatalogMeasurementBaseConfig, 

171 pipelineConnections=TractMultiBandMeasurementConnections, 

172): 

173 pass 

174 

175 

176class TractMultiBandMeasurementTask(TractMeasurementTask): 

177 

178 ConfigClass = TractMultiBandMeasurementConfig 

179 _DefaultName = "tractMultiBandMeasurementTask"