Coverage for python/lsst/analysis/tools/atools/calibQuantityProfile.py: 29%
140 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-02 04:48 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-02 04:48 -0700
1# This file is part of analysis_tools.
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/>.
21from __future__ import annotations
23from lsst.analysis.tools.interfaces._interfaces import KeyedDataSchema
25__all__ = (
26 "CalibQuantityBaseTool",
27 "CalibQuantityAmpProfileScatterTool",
28 "CalibQuantityAmpProfileHistTool",
29 "CalibAmpScatterTool",
30 "CalibDivisaderoScatterTool",
31 "CalibPtcCovarScatterTool",
32)
34from typing import cast
36from lsst.pex.config import Field
37from lsst.pex.config.configurableActions import ConfigurableActionField
39from ..actions.plot.elements import HistElement, ScatterElement
40from ..actions.plot.gridPlot import GridPanelConfig, GridPlot
41from ..interfaces import AnalysisTool, KeyedData, KeyedDataAction, PlotElement, Vector
44class PrepRepacker(KeyedDataAction):
45 """Prep action to repack data."""
47 panelKey = Field[str](
48 doc="Panel selector. Data will be separated into multiple panels based on this key.",
49 )
50 dataKey = Field[str](
51 doc="Data selector. Data will be separated into multiple groups in a single panel based on this key.",
52 )
53 quantityKey = Field[str](
54 doc="Quantity selector. The actual data quantities to be plotted.",
55 )
57 def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
58 repackedData = {}
59 # Loop over the length of the data vector and repack row by row
60 for i in range(len(cast(Vector, data[self.panelKey]))):
61 panelVec = cast(Vector, data[self.panelKey])
62 dataVec = cast(Vector, data[self.dataKey])
63 quantityVec = cast(Vector, data[self.quantityKey])
64 repackedData[f"{panelVec[i]}_{dataVec[i]}_{self.quantityKey}"] = quantityVec[i]
65 return repackedData
67 def getInputSchema(self) -> KeyedDataSchema:
68 return (
69 (self.panelKey, Vector),
70 (self.dataKey, Vector),
71 (self.quantityKey, Vector),
72 )
74 def addInputSchema(self, inputSchema: KeyedDataSchema) -> None:
75 pass
78class SingleValueRepacker(KeyedDataAction):
79 """Prep action to repack data."""
81 panelKey = Field[str](
82 doc="Panel selector. Data will be separated into multiple panels based on this key.",
83 )
84 dataKey = Field[str](
85 doc="Data selector. Data will be separated into multiple groups in a single panel based on this key.",
86 )
87 quantityKey = Field[str](
88 doc="Quantity selector. The actual data quantities to be plotted.",
89 )
91 def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
92 repackedData = {}
93 uniquePanelKeys = list(set(data[self.panelKey]))
95 # Loop over data vector to repack information as it is expected.
96 for i in range(len(uniquePanelKeys)):
97 repackedData[f"{uniquePanelKeys[i]}_x"] = []
98 repackedData[f"{uniquePanelKeys[i]}"] = []
100 panelVec = cast(Vector, data[self.panelKey])
101 dataVec = cast(Vector, data[self.dataKey])
102 quantityVec = cast(Vector, data[self.quantityKey])
104 for i in range(len(panelVec)):
105 repackedData[f"{panelVec[i]}_x"].append(dataVec[i])
106 repackedData[f"{panelVec[i]}"].append(quantityVec[i])
108 return repackedData
110 def getInputSchema(self) -> KeyedDataSchema:
111 return (
112 (self.panelKey, Vector),
113 (self.dataKey, Vector),
114 (self.quantityKey, Vector),
115 )
117 def addInputSchema(self, inputSchema: KeyedDataSchema) -> None:
118 pass
121class PassThrough(KeyedDataAction):
122 def __call__(self, data: KeyedData, **kwargs) -> KeyedData:
123 return data
125 def getInputSchema(self) -> KeyedDataSchema:
126 # In general this method should be implemented, but here we are ALSO
127 # implementing the prep step. We therefore know the method results are
128 # not needed because it is doing something special with the inputs.
129 return ()
132class CalibQuantityBaseTool(AnalysisTool):
133 parameterizedBand: bool = False
135 plotElement = ConfigurableActionField[PlotElement](
136 doc="Plot element.",
137 )
139 def setDefaults(self):
140 super().setDefaults()
142 # Repack the input data into a usable format
143 self.prep = PrepRepacker()
145 # A simple pass-through process action to keep the data unchanged
146 self.process = PassThrough()
148 # Plot the repacked data in a 4x4 grid
149 self.produce.plot = GridPlot()
150 self.produce.plot.panels = {}
151 self.produce.plot.numRows = 4
152 self.produce.plot.numCols = 4
154 # Values to group by to distinguish between data in differing panels
155 self.produce.plot.valsGroupBy = {
156 0: "C00",
157 1: "C01",
158 2: "C02",
159 3: "C03",
160 4: "C04",
161 5: "C05",
162 6: "C06",
163 7: "C07",
164 8: "C10",
165 9: "C11",
166 10: "C12",
167 11: "C13",
168 12: "C14",
169 13: "C15",
170 14: "C16",
171 15: "C17",
172 }
174 def finalize(self):
175 super().finalize()
177 # Configure each panel
178 for key, value in self.produce.plot.valsGroupBy.items():
179 gridPanelConfig = GridPanelConfig(
180 plotElement=self.plotElement,
181 title={"label": str(value), "fontsize": "10"},
182 titleY=0.85,
183 )
184 self.produce.plot.panels[key] = gridPanelConfig
187class CalibQuantityAmpProfileScatterTool(CalibQuantityBaseTool):
188 def setDefaults(self):
189 super().setDefaults()
190 self.plotElement = ScatterElement()
191 self.prep.panelKey = "amplifier"
192 self.prep.dataKey = "mjd"
195class CalibQuantityAmpProfileHistTool(CalibQuantityBaseTool):
196 def setDefaults(self):
197 super().setDefaults()
198 self.plotElement = HistElement()
199 self.prep.panelKey = "amplifier"
200 self.prep.dataKey = "mjd"
203class CalibAmpScatterTool(CalibQuantityBaseTool):
204 def setDefaults(self):
205 super().setDefaults()
206 self.plotElement = ScatterElement()
208 # Repack the input data into a usable format
209 self.prep = SingleValueRepacker()
211 self.produce.plot = GridPlot()
212 self.produce.plot.panels = {}
213 self.produce.plot.numRows = 4
214 self.produce.plot.numCols = 4
216 # Values to use for x-axis data
217 self.produce.plot.xDataKeys = {
218 0: "C00_x",
219 1: "C01_x",
220 2: "C02_x",
221 3: "C03_x",
222 4: "C04_x",
223 5: "C05_x",
224 6: "C06_x",
225 7: "C07_x",
226 8: "C10_x",
227 9: "C11_x",
228 10: "C12_x",
229 11: "C13_x",
230 12: "C14_x",
231 13: "C15_x",
232 14: "C16_x",
233 15: "C17_x",
234 }
236 # Values to group by to distinguish between data in differing panels
237 self.produce.plot.valsGroupBy = {
238 0: "C00",
239 1: "C01",
240 2: "C02",
241 3: "C03",
242 4: "C04",
243 5: "C05",
244 6: "C06",
245 7: "C07",
246 8: "C10",
247 9: "C11",
248 10: "C12",
249 11: "C13",
250 12: "C14",
251 13: "C15",
252 14: "C16",
253 15: "C17",
254 }
256 self.prep.panelKey = "amplifier"
257 self.prep.dataKey = "mjd"
259 def finalize(self):
260 super().finalize()
262 # Configure each panel
263 for key, value in self.produce.plot.valsGroupBy.items():
264 gridPanelConfig = GridPanelConfig(
265 plotElement=self.plotElement,
266 title={"label": str(value), "fontsize": "10"},
267 titleY=0.85,
268 )
269 self.produce.plot.panels[key] = gridPanelConfig
270 self.produce.plot.panels[key].plotElement.xKey = f"{value}_x"
271 self.produce.plot.panels[key].plotElement.valsKey = value
274class CalibDivisaderoScatterTool(CalibQuantityBaseTool):
275 def setDefaults(self):
276 super().setDefaults()
277 self.plotElement = ScatterElement()
279 # Repack the input data into a usable format
280 self.prep = SingleValueRepacker()
282 self.produce.plot = GridPlot()
283 self.produce.plot.panels = {}
284 self.produce.plot.numRows = 2
285 self.produce.plot.numCols = 1
287 # Values to group by to distinguish between data in differing panels
288 self.produce.plot.valsGroupBy = {0: "bank1", 1: "bank0"}
290 self.produce.plot.xDataKeys = {
291 0: "bank1_x",
292 1: "bank0_x",
293 }
294 self.prep.panelKey = "amplifier"
295 self.prep.dataKey = "mjd"
297 def finalize(self):
298 super().finalize()
300 # Configure each panel
301 for key, value in self.produce.plot.valsGroupBy.items():
302 gridPanelConfig = GridPanelConfig(
303 plotElement=self.plotElement,
304 title={"label": str(value), "fontsize": "10"},
305 titleY=0.85,
306 )
307 self.produce.plot.panels[key] = gridPanelConfig
308 self.produce.plot.panels[key].plotElement.xKey = f"{value}_x"
309 self.produce.plot.panels[key].plotElement.valsKey = value
312class CalibPtcCovarScatterTool(CalibQuantityBaseTool):
313 def setDefaults(self):
314 super().setDefaults()
315 self.plotElement = ScatterElement()
317 # Repack the input data into a usable format
318 self.prep = PrepRepacker()
320 self.produce.plot = GridPlot()
321 self.produce.plot.panels = {}
322 self.produce.plot.numRows = 3
323 self.produce.plot.numCols = 2
325 # Values to group by to distinguish between data in differing panels
326 self.produce.plot.valsGroupBy = {
327 0: "PTC_COV_10",
328 1: "PTC_COV_20",
329 2: "PTC_COV_01",
330 3: "PTC_COV_02",
331 4: "PTC_COV_11",
332 5: None,
333 }
335 self.produce.plot.xDataKeys = {
336 0: "PTC_PTC_RAW_MEANS",
337 1: "PTC_PTC_RAW_MEANS",
338 2: "PTC_PTC_RAW_MEANS",
339 3: "PTC_PTC_RAW_MEANS",
340 4: "PTC_PTC_RAW_MEANS",
341 5: None,
342 }
343 self.prep.panelKey = "amplifier"
344 self.prep.dataKey = "mjd"
346 def finalize(self):
347 super().finalize()
349 # Configure each panel
350 for key, value in self.produce.plot.valsGroupBy.items():
351 gridPanelConfig = GridPanelConfig(
352 plotElement=self.plotElement,
353 title={"label": str(value), "fontsize": "10"},
354 titleY=0.85,
355 )
356 self.produce.plot.panels[key] = gridPanelConfig
357 self.produce.plot.panels[key].plotElement.xKey = "PTC_PTC_RAW_MEANS"
358 self.produce.plot.panels[key].plotElement.valsKey = f"PTC_{value}"