Coverage for python/lsst/faro/measurement/PatchTableMeasurement.py : 30%

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 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 columns = pexConfig.ListField(
70 doc="Band-independent columns from objectTable_tract to load.",
71 dtype=str,
72 default=["coord_ra", "coord_dec", "detect_isPrimary", "patch"],
73 )
75 columnsBand = pexConfig.ListField(
76 doc="Band-specific columns from objectTable_tract to load.",
77 dtype=str,
78 default=["psfFlux", "psfFluxErr"],
79 )
81 instrument = pexConfig.Field(
82 doc="Instrument.",
83 dtype=str,
84 default='hsc',
85 )
88class PatchTableMeasurementTask(CatalogMeasurementBaseTask):
89 """Base class for per-band science performance metrics measured on single-tract object catalogs."""
91 ConfigClass = PatchTableMeasurementConfig
92 _DefaultName = "tractTableMeasurementTask"
94 def runQuantum(self, butlerQC, inputRefs, outputRefs):
95 inputs = butlerQC.get(inputRefs)
96 kwargs = {"band": butlerQC.quantum.dataId['band']}
98 columns = self.config.columns.list()
99 for column in self.config.columnsBand:
100 columns.append(kwargs["band"] + column)
101 catalog = inputs["catalog"].get(parameters={"columns": columns})
102 selection = (catalog["patch"] == butlerQC.quantum.dataId["patch"])
103 kwargs["catalog"] = catalog[selection]
105 if self.config.connections.refDataset != "":
106 refCats = inputs.pop("refCat")
107 filter_map = FilterMap()
108 filterList = filter_map.getFilters(self.config.instrument,
109 [kwargs["band"]])
111 # TODO: add capability to select the reference epoch
112 epoch = None
113 refCat, refCatCorrected = self._getReferenceCatalog(
114 butlerQC,
115 [ref.datasetRef.dataId for ref in inputRefs.refCat],
116 refCats,
117 filterList,
118 epoch,
119 )
120 kwargs["refCat"] = refCat
121 kwargs["refCatCorrected"] = refCatCorrected
123 outputs = self.run(**kwargs)
124 if outputs.measurement is not None:
125 butlerQC.put(outputs, outputRefs)
126 else:
127 self.log.debugf(
128 "Skipping measurement of {!r} on {} " "as not applicable.",
129 self,
130 inputRefs,
131 )
134class PatchMultiBandTableMeasurementConnections(
135 PatchTableMeasurementConnections,
136 dimensions=("tract", "patch", "skymap"),
137):
139 catalog = pipeBase.connectionTypes.Input(
140 doc="Object table in parquet format, per tract.",
141 dimensions=("tract", "skymap"),
142 storageClass="DataFrame",
143 name="objectTable_tract",
144 deferLoad=True,
145 )
147 measurement = pipeBase.connectionTypes.Output(
148 doc="Per-tract measurement.",
149 dimensions=("tract", "patch", "skymap"),
150 storageClass="MetricValue",
151 name="metricvalue_{package}_{metric}",
152 )
155class PatchMultiBandTableMeasurementConfig(
156 PatchTableMeasurementConfig,
157 pipelineConnections=PatchMultiBandTableMeasurementConnections,
158):
159 """Configuration for PatchMultiBandTableMeasurementTask."""
161 bands = pexConfig.ListField(
162 doc="Bands for band-specific column loading from objectTable_tract.",
163 dtype=str,
164 default=["g", "r", "i", "z", "y"],
165 )
168class PatchMultiBandTableMeasurementTask(PatchTableMeasurementTask):
170 """Base class for science performance metrics measured on single-tract source catalogs, multi-band."""
172 ConfigClass = PatchMultiBandTableMeasurementConfig
173 _DefaultName = "tractMultiBandTableMeasurementTask"
175 def runQuantum(self, butlerQC, inputRefs, outputRefs):
176 inputs = butlerQC.get(inputRefs)
178 kwargs = {"bands": self.config.bands.list()}
180 columns = self.config.columns.list()
181 for band in self.config.bands:
182 for column in self.config.columnsBand:
183 columns.append(band + column)
184 catalog = inputs["catalog"].get(parameters={"columns": columns})
185 selection = (catalog["patch"] == butlerQC.quantum.dataId["patch"])
186 kwargs["catalog"] = catalog[selection]
188 if self.config.connections.refDataset != "":
189 refCats = inputs.pop("refCat")
190 filter_map = FilterMap()
191 filterList = filter_map.getFilters(self.config.instrument,
192 self.config.bands)
194 # TODO: add capability to select the reference epoch
195 epoch = None
196 refCat, refCatCorrected = self._getReferenceCatalog(
197 butlerQC,
198 [ref.datasetRef.dataId for ref in inputRefs.refCat],
199 refCats,
200 filterList,
201 epoch,
202 )
203 kwargs["refCat"] = refCat
204 kwargs["refCatCorrected"] = refCatCorrected
206 outputs = self.run(**kwargs)
207 if outputs.measurement is not None:
208 butlerQC.put(outputs, outputRefs)
209 else:
210 self.log.debugf(
211 "Skipping measurement of {!r} on {} " "as not applicable.",
212 self,
213 inputRefs,
214 )