Coverage for python/lsst/faro/measurement/TractMeasurement.py: 73%
42 statements
« prev ^ index » next coverage.py v6.4.4, created at 2022-08-26 03:25 -0700
« prev ^ index » next coverage.py v6.4.4, created at 2022-08-26 03:25 -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/>.
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
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
36from collections import defaultdict
37from typing import List
39__all__ = (
40 "TractMeasurementConnections",
41 "TractMeasurementConfig",
42 "TractMeasurementTask",
43 "TractMultiBandMeasurementConnections",
44 "TractMultiBandMeasurementConfig",
45 "TractMultiBandMeasurementTask",
46)
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):
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 )
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 )
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 )
83 measurement = pipeBase.connectionTypes.Output(
84 doc="Per-tract measurement.",
85 dimensions=("tract", "skymap", "band"),
86 storageClass="MetricValue",
87 name="metricvalue_{package}_{metric}",
88 )
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 )
102class TractMeasurementTask(CatalogMeasurementBaseTask):
104 ConfigClass = TractMeasurementConfig
105 _DefaultName = "tractMeasurementTask"
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))
118 return self.measure.run(self.config.connections.metric, data)
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 )
136class TractMultiBandMeasurementConnections(
137 TractMeasurementConnections,
138 dimensions=("tract", "skymap"),
139 defaultTemplates={
140 "coaddName": "deepCoadd",
141 "photoCalibName": "deepCoadd_calexp.photoCalib",
142 },
143):
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 )
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 )
161 measurement = pipeBase.connectionTypes.Output(
162 doc="Per-tract measurement.",
163 dimensions=("tract", "skymap"),
164 storageClass="MetricValue",
165 name="metricvalue_{package}_{metric}",
166 )
169class TractMultiBandMeasurementConfig(
170 CatalogMeasurementBaseConfig,
171 pipelineConnections=TractMultiBandMeasurementConnections,
172):
173 pass
176class TractMultiBandMeasurementTask(TractMeasurementTask):
178 ConfigClass = TractMultiBandMeasurementConfig
179 _DefaultName = "tractMultiBandMeasurementTask"