Coverage for python/lsst/faro/measurement/DetectorMeasurement.py : 32%

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 product includes software developed by the LSST Project
2# (https://www.lsst.org).
3# See the COPYRIGHT file at the top-level directory of this distribution
4# for details of code ownership.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <https://www.gnu.org/licenses/>.
19import lsst.pipe.base as pipeBase
20from lsst.verify.tasks import MetricConnections
21import lsst.pex.config as pexConfig
23from lsst.faro.base.CatalogMeasurementBase import (
24 CatalogMeasurementBaseConfig,
25 CatalogMeasurementBaseTask,
26)
28__all__ = ("DetectorMeasurementConfig", "DetectorMeasurementTask")
31class DetectorMeasurementConnections(
32 MetricConnections,
33 dimensions=("instrument", "visit", "detector", "band"),
34 defaultTemplates={
35 "photoCalibName": "calexp.photoCalib",
36 "externalPhotoCalibName": "fgcm",
37 "wcsName": "calexp.wcs",
38 "externalWcsName": "jointcal",
39 },
40):
42 catalog = pipeBase.connectionTypes.Input(
43 doc="Source catalog.",
44 dimensions=("instrument", "visit", "detector", "band"),
45 storageClass="SourceCatalog",
46 name="src",
47 )
48 skyWcs = pipeBase.connectionTypes.Input(
49 doc="WCS for the catalog.",
50 dimensions=("instrument", "visit", "detector", "band"),
51 storageClass="Wcs",
52 name="{wcsName}",
53 )
54 photoCalib = pipeBase.connectionTypes.Input(
55 doc="Photometric calibration object.",
56 dimensions=("instrument", "visit", "detector", "band"),
57 storageClass="PhotoCalib",
58 name="{photoCalibName}",
59 )
60 externalSkyWcsTractCatalog = pipeBase.connectionTypes.Input(
61 doc=(
62 "Per-tract, per-visit wcs calibrations. These catalogs use the detector "
63 "id for the catalog id, sorted on id for fast lookup."
64 ),
65 name="{externalWcsName}SkyWcsCatalog",
66 storageClass="ExposureCatalog",
67 dimensions=("instrument", "visit", "tract"),
68 )
69 externalSkyWcsGlobalCatalog = pipeBase.connectionTypes.Input(
70 doc=(
71 "Per-visit wcs calibrations computed globally (with no tract information). "
72 "These catalogs use the detector id for the catalog id, sorted on id for "
73 "fast lookup."
74 ),
75 name="{externalWcsName}SkyWcsCatalog",
76 storageClass="ExposureCatalog",
77 dimensions=("instrument", "visit"),
78 )
79 externalPhotoCalibTractCatalog = pipeBase.connectionTypes.Input(
80 doc=(
81 "Per-tract, per-visit photometric calibrations. These catalogs use the "
82 "detector id for the catalog id, sorted on id for fast lookup."
83 ),
84 name="{externalPhotoCalibName}PhotoCalibCatalog",
85 storageClass="ExposureCatalog",
86 dimensions=("instrument", "visit", "tract"),
87 )
88 externalPhotoCalibGlobalCatalog = pipeBase.connectionTypes.Input(
89 doc=(
90 "Per-visit photometric calibrations computed globally (with no tract "
91 "information). These catalogs use the detector id for the catalog id, "
92 "sorted on id for fast lookup."
93 ),
94 name="{externalPhotoCalibName}PhotoCalibCatalog",
95 storageClass="ExposureCatalog",
96 dimensions=("instrument", "visit"),
97 )
98 measurement = pipeBase.connectionTypes.Output(
99 doc="Per-detector measurement.",
100 dimensions=("instrument", "visit", "detector", "band"),
101 storageClass="MetricValue",
102 name="metricvalue_{package}_{metric}",
103 )
105 def __init__(self, *, config=None):
106 super().__init__(config=config)
107 if config.doApplyExternalSkyWcs:
108 if config.useGlobalExternalSkyWcs:
109 self.inputs.remove("externalSkyWcsTractCatalog")
110 else:
111 self.inputs.remove("externalSkyWcsGlobalCatalog")
112 else:
113 self.inputs.remove("externalSkyWcsTractCatalog")
114 self.inputs.remove("externalSkyWcsGlobalCatalog")
115 if config.doApplyExternalPhotoCalib:
116 if config.useGlobalExternalPhotoCalib:
117 self.inputs.remove("externalPhotoCalibTractCatalog")
118 else:
119 self.inputs.remove("externalPhotoCalibGlobalCatalog")
120 else:
121 self.inputs.remove("externalPhotoCalibTractCatalog")
122 self.inputs.remove("externalPhotoCalibGlobalCatalog")
125class DetectorMeasurementConfig(
126 CatalogMeasurementBaseConfig, pipelineConnections=DetectorMeasurementConnections
127):
128 doApplyExternalSkyWcs = pexConfig.Field(
129 doc="Whether or not to use the external wcs.", dtype=bool, default=False
130 )
131 useGlobalExternalSkyWcs = pexConfig.Field(
132 doc="Whether or not to use the global external wcs.", dtype=bool, default=False
133 )
134 doApplyExternalPhotoCalib = pexConfig.Field(
135 doc="Whether or not to use the external photoCalib.", dtype=bool, default=False
136 )
137 useGlobalExternalPhotoCalib = pexConfig.Field(
138 doc="Whether or not to use the global external photoCalib.",
139 dtype=bool,
140 default=False,
141 )
144class DetectorMeasurementTask(CatalogMeasurementBaseTask):
145 ConfigClass = DetectorMeasurementConfig
146 _DefaultName = "detectorMeasurementTask"
148 def runQuantum(self, butlerQC, inputRefs, outputRefs):
149 inputs = butlerQC.get(inputRefs)
150 if self.config.doApplyExternalPhotoCalib:
151 detector = inputRefs.catalog.dataId["detector"]
152 if self.config.useGlobalExternalPhotoCalib:
153 externalPhotoCalibCatalog = inputs.pop(
154 "externalPhotoCalibGlobalCatalog"
155 )
156 else:
157 externalPhotoCalibCatalog = inputs.pop("externalPhotoCalibTractCatalog")
158 row = externalPhotoCalibCatalog.find(detector)
159 externalPhotoCalib = row.getPhotoCalib()
160 inputs["photoCalib"] = externalPhotoCalib
161 if self.config.doApplyExternalSkyWcs:
162 detector = inputRefs.catalog.dataId["detector"]
163 if self.config.useGlobalExternalSkyWcs:
164 externalSkyWcsCatalog = inputs.pop("externalSkyWcsGlobalCatalog")
165 else:
166 externalSkyWcsCatalog = inputs.pop("externalSkyWcsTractCatalog")
167 row = externalSkyWcsCatalog.find(detector)
168 externalSkyWcs = row.getWcs()
169 inputs["skyWcs"] = externalSkyWcs
171 outputs = self.run(**inputs)
172 if outputs.measurement is not None:
173 butlerQC.put(outputs, outputRefs)
174 else:
175 self.log.debug(
176 "Skipping measurement of {!r} on {} " "as not applicable.",
177 self,
178 inputRefs,
179 )