Coverage for python/lsst/faro/measurement/ForcedSourceTableMeasurement.py: 38%

46 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-19 02:30 -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 

22 

23import lsst.pipe.base as pipeBase 

24import lsst.pex.config as pexConfig 

25 

26from lsst.faro.base.CatalogMeasurementBase import ( 

27 CatalogMeasurementBaseConnections, 

28 CatalogMeasurementBaseConfig, 

29 CatalogMeasurementBaseTask, 

30) 

31 

32__all__ = ( 

33 "ForcedSourceTableMeasurementConnections", 

34 "ForcedSourceTableMeasurementConfig", 

35 "ForcedSourceTableMeasurementTask", 

36 "ForcedSourceMultiBandTableMeasurementConnections", 

37 "ForcedSourceMultiBandTableMeasurementConfig", 

38 "ForcedSourceMultiBandTableMeasurementTask", 

39) 

40 

41 

42class ForcedSourceTableMeasurementConnections( 

43 CatalogMeasurementBaseConnections, 

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

45): 

46 

47 catalog = pipeBase.connectionTypes.Input( 

48 doc="Forced source table in parquet format, per tract", 

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

50 storageClass="DataFrame", 

51 name="forcedSourceTable_tract", 

52 deferLoad=True, 

53 ) 

54 

55 measurement = pipeBase.connectionTypes.Output( 

56 doc="Per-tract measurement.", 

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

58 storageClass="MetricValue", 

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

60 ) 

61 

62 

63class ForcedSourceTableMeasurementConfig( 

64 CatalogMeasurementBaseConfig, pipelineConnections=ForcedSourceTableMeasurementConnections 

65): 

66 """Configuration for ForcedSourceTableMeasurementTask.""" 

67 

68 

69class ForcedSourceTableMeasurementTask(CatalogMeasurementBaseTask): 

70 """Base class for per-band science performance metrics measured on multi-visit forced source catalogs.""" 

71 

72 ConfigClass = ForcedSourceTableMeasurementConfig 

73 _DefaultName = "forcedSourceTableMeasurementTask" 

74 

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

76 inputs = butlerQC.get(inputRefs) 

77 kwargs = {"currentBands": butlerQC.quantum.dataId['band']} 

78 

79 columns = list(self.config.measure.columns.values()) 

80 for column in self.config.measure.columnsBand.values(): 

81 columns.append(kwargs["currentBands"] + "_" + column) 

82 

83 columnsWithSelectors = self._getTableColumnsSelectors(columns, kwargs["currentBands"]) 

84 tmp_catalog = inputs["catalog"].get(parameters={"columns": columnsWithSelectors}) 

85 

86 # Extract only the entries from the band of interest: 

87 kwargs["catalog"] = tmp_catalog[tmp_catalog.band == kwargs["currentBands"]] 

88 

89 outputs = self.run(**kwargs) 

90 if outputs.measurement is not None: 

91 butlerQC.put(outputs, outputRefs) 

92 else: 

93 self.log.debug( 

94 "Skipping measurement of %r on %s as not applicable.", 

95 self, 

96 inputRefs, 

97 ) 

98 

99 

100class ForcedSourceMultiBandTableMeasurementConnections( 

101 CatalogMeasurementBaseConnections, 

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

103): 

104 

105 catalog = pipeBase.connectionTypes.Input( 

106 doc="Forced source table in parquet format, per tract", 

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

108 storageClass="DataFrame", 

109 name="forcedSourceTable_tract", 

110 deferLoad=True, 

111 ) 

112 

113 measurement = pipeBase.connectionTypes.Output( 

114 doc="Per-tract measurement.", 

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

116 storageClass="MetricValue", 

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

118 ) 

119 

120 

121class ForcedSourceMultiBandTableMeasurementConfig( 

122 ForcedSourceTableMeasurementConfig, 

123 pipelineConnections=ForcedSourceMultiBandTableMeasurementConnections 

124): 

125 """Configuration for ForcedSourceMultiBandTableMeasurementTask.""" 

126 

127 bands = pexConfig.ListField( 

128 doc="Bands for band-specific column loading from ForcedSourceTable_tract.", 

129 dtype=str, 

130 default=["g", "r", "i", "z", "y"], 

131 ) 

132 

133 

134class ForcedSourceMultiBandTableMeasurementTask(CatalogMeasurementBaseTask): 

135 """Base class for multi-band science performance metrics measured on 

136 multi-visit forced source catalogs.""" 

137 

138 ConfigClass = ForcedSourceMultiBandTableMeasurementConfig 

139 _DefaultName = "forcedSourceMultiBandTableMeasurementTask" 

140 

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

142 inputs = butlerQC.get(inputRefs) 

143 kwargs = {"currentBands": self.config.bands.list()} 

144 

145 columns = list(self.config.measure.columns.values()) 

146 for band in kwargs["currentBands"]: 

147 for column in self.config.measure.columnsBand.values(): 

148 columns.append(band + "_" + column) 

149 

150 columnsWithSelectors = self._getTableColumnsSelectors(columns, kwargs["currentBands"]) 

151 tmp_catalog = inputs["catalog"].get(parameters={"columns": columnsWithSelectors}) 

152 # Extract only the entries from the band of interest: 

153 kwargs["catalog"] = tmp_catalog[tmp_catalog.band.isin(kwargs["currentBands"])] 

154 

155 outputs = self.run(**kwargs) 

156 if outputs.measurement is not None: 

157 butlerQC.put(outputs, outputRefs) 

158 else: 

159 self.log.debug( 

160 "Skipping measurement of %r on %s as not applicable.", 

161 self, 

162 inputRefs, 

163 )