Coverage for python/lsst/faro/measurement/PatchTableMeasurement.py: 27%
66 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-27 10:21 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-27 10:21 +0000
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/>.
23import lsst.pipe.base as pipeBase
24import lsst.pex.config as pexConfig
26from lsst.faro.base.CatalogMeasurementBase import (
27 CatalogMeasurementBaseConnections,
28 CatalogMeasurementBaseConfig,
29 CatalogMeasurementBaseTask,
30)
31from lsst.faro.utils.filter_map import FilterMap
33__all__ = (
34 "PatchTableMeasurementConnections",
35 "PatchTableMeasurementConfig",
36 "PatchTableMeasurementTask",
37 "PatchMultiBandTableMeasurementConnections",
38 "PatchMultiBandTableMeasurementConfig",
39 "PatchMultiBandTableMeasurementTask",
40)
43class PatchTableMeasurementConnections(
44 CatalogMeasurementBaseConnections,
45 dimensions=("tract", "patch", "skymap", "band"),
46):
48 catalog = pipeBase.connectionTypes.Input(
49 doc="Object table in parquet format, per tract.",
50 dimensions=("tract", "skymap"),
51 storageClass="DataFrame",
52 name="objectTable_tract",
53 deferLoad=True,
54 )
56 measurement = pipeBase.connectionTypes.Output(
57 doc="Per-tract measurement.",
58 dimensions=("tract", "patch", "skymap", "band"),
59 storageClass="MetricValue",
60 name="metricvalue_{package}_{metric}",
61 )
64class PatchTableMeasurementConfig(
65 CatalogMeasurementBaseConfig, pipelineConnections=PatchTableMeasurementConnections
66):
67 """Configuration for PatchTableMeasurementTask."""
69 instrument = pexConfig.Field(
70 doc="Instrument.",
71 dtype=str,
72 default='hsc',
73 )
76class PatchTableMeasurementTask(CatalogMeasurementBaseTask):
77 """Base class for per-band science performance metrics measured on single-patch object catalogs."""
79 ConfigClass = PatchTableMeasurementConfig
80 _DefaultName = "patchTableMeasurementTask"
82 def runQuantum(self, butlerQC, inputRefs, outputRefs):
83 inputs = butlerQC.get(inputRefs)
84 kwargs = {"currentBands": butlerQC.quantum.dataId['band']}
86 columns = list(self.config.measure.columns.values())
87 columns.append("patch")
89 for column in self.config.measure.columnsBand.values():
90 columns.append(kwargs["currentBands"] + "_" + column)
91 columnsWithSelectors = self._getTableColumnsSelectors(columns, kwargs["currentBands"])
92 catalog = inputs["catalog"].get(parameters={"columns": columnsWithSelectors})
94 selection = (catalog["patch"] == butlerQC.quantum.dataId["patch"])
95 kwargs["catalog"] = catalog[selection]
97 if self.config.connections.refDataset != "":
98 refCats = inputs.pop("refCat")
99 filter_map = FilterMap()
100 filterList = filter_map.getFilters(self.config.instrument,
101 [kwargs["currentBands"]])
103 # TODO: add capability to select the reference epoch
104 epoch = None
105 refCat = self._getReferenceCatalog(
106 butlerQC,
107 [ref.datasetRef.dataId for ref in inputRefs.refCat],
108 refCats,
109 filterList,
110 epoch,
111 )
112 kwargs["refCat"] = refCat
114 outputs = self.run(**kwargs)
115 if outputs.measurement is not None:
116 butlerQC.put(outputs, outputRefs)
117 else:
118 self.log.debug(
119 "Skipping measurement of %r on %s as not applicable.",
120 self,
121 inputRefs,
122 )
125class PatchMultiBandTableMeasurementConnections(
126 PatchTableMeasurementConnections,
127 dimensions=("tract", "patch", "skymap"),
128):
130 catalog = pipeBase.connectionTypes.Input(
131 doc="Object table in parquet format, per tract.",
132 dimensions=("tract", "skymap"),
133 storageClass="DataFrame",
134 name="objectTable_tract",
135 deferLoad=True,
136 )
138 measurement = pipeBase.connectionTypes.Output(
139 doc="Per-tract measurement.",
140 dimensions=("tract", "patch", "skymap"),
141 storageClass="MetricValue",
142 name="metricvalue_{package}_{metric}",
143 )
146class PatchMultiBandTableMeasurementConfig(
147 PatchTableMeasurementConfig,
148 pipelineConnections=PatchMultiBandTableMeasurementConnections,
149):
150 """Configuration for PatchMultiBandTableMeasurementTask."""
152 bands = pexConfig.ListField(
153 doc="Bands for band-specific column loading from objectTable_tract.",
154 dtype=str,
155 default=["g", "r", "i", "z", "y"],
156 )
159class PatchMultiBandTableMeasurementTask(PatchTableMeasurementTask):
161 """Base class for science performance metrics measured on single-patch source catalogs, multi-band."""
163 ConfigClass = PatchMultiBandTableMeasurementConfig
164 _DefaultName = "patchMultiBandTableMeasurementTask"
166 def runQuantum(self, butlerQC, inputRefs, outputRefs):
167 inputs = butlerQC.get(inputRefs)
169 kwargs = {"currentBands": self.config.bands.list()}
171 columns = list(self.config.measure.columns.values())
172 columns.append("patch")
174 for band in self.config.bands:
175 for column in self.config.measure.columnsBand.values():
176 columns.append(band + "_" + column)
177 columnsWithSelectors = self._getTableColumnsSelectors(columns, kwargs["currentBands"])
178 catalog = inputs["catalog"].get(parameters={"columns": columnsWithSelectors})
180 selection = (catalog["patch"] == butlerQC.quantum.dataId["patch"])
181 kwargs["catalog"] = catalog[selection]
183 if self.config.connections.refDataset != "":
184 refCats = inputs.pop("refCat")
185 filter_map = FilterMap()
186 filterList = filter_map.getFilters(self.config.instrument,
187 self.config.bands)
189 # TODO: add capability to select the reference epoch
190 epoch = None
191 refCat = self._getReferenceCatalog(
192 butlerQC,
193 [ref.datasetRef.dataId for ref in inputRefs.refCat],
194 refCats,
195 filterList,
196 epoch,
197 )
198 kwargs["refCat"] = refCat
200 outputs = self.run(**kwargs)
201 if outputs.measurement is not None:
202 butlerQC.put(outputs, outputRefs)
203 else:
204 self.log.debug(
205 "Skipping measurement of %r on %s as not applicable.",
206 self,
207 inputRefs,
208 )