2020# along with this program. If not, see <https://www.gnu.org/licenses/>.
2121from __future__ import annotations
2222
23- from lsst .analysis .tools .interfaces ._interfaces import KeyedDataSchema
24-
2523__all__ = (
2624 "CalibQuantityBaseTool" ,
2725 "CalibQuantityAmpProfileScatterTool" ,
3129 "CalibPtcCovarScatterTool" ,
3230)
3331
34- from typing import cast
32+ from typing import Optional
3533
36- from lsst .pex .config import Field
34+ import numpy as np
35+ from lsst .pex .config import Field , ListField
3736from lsst .pex .config .configurableActions import ConfigurableActionField
3837
3938from ..actions .plot .elements import HistElement , ScatterElement
4039from ..actions .plot .gridPlot import GridPanelConfig , GridPlot
41- from ..interfaces import AnalysisTool , KeyedData , KeyedDataAction , PlotElement , Vector
40+ from ..interfaces import AnalysisTool , KeyedData , KeyedDataAction , KeyedDataSchema , PlotElement , Vector
41+
42+ _CALIB_AMP_NAME_DICT : dict [int , str ] = {
43+ 0 : "C00" ,
44+ 1 : "C01" ,
45+ 2 : "C02" ,
46+ 3 : "C03" ,
47+ 4 : "C04" ,
48+ 5 : "C05" ,
49+ 6 : "C06" ,
50+ 7 : "C07" ,
51+ 8 : "C10" ,
52+ 9 : "C11" ,
53+ 10 : "C12" ,
54+ 11 : "C13" ,
55+ 12 : "C14" ,
56+ 13 : "C15" ,
57+ 14 : "C16" ,
58+ 15 : "C17" ,
59+ }
4260
4361
4462class PrepRepacker (KeyedDataAction ):
@@ -50,61 +68,23 @@ class PrepRepacker(KeyedDataAction):
5068 dataKey = Field [str ](
5169 doc = "Data selector. Data will be separated into multiple groups in a single panel based on this key." ,
5270 )
53- quantityKey = Field [str ](
54- doc = "Quantity selector. The actual data quantities to be plotted." ,
71+ quantityKey = ListField [str ](
72+ doc = "Quantity selector. The actual data quantities to be plotted." , minLength = 1 , optional = False
5573 )
5674
5775 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
66-
67- def getInputSchema (self ) -> KeyedDataSchema :
68- return (
69- (self .panelKey , Vector ),
70- (self .dataKey , Vector ),
71- (self .quantityKey , Vector ),
72- )
73-
74- def addInputSchema (self , inputSchema : KeyedDataSchema ) -> None :
75- pass
76-
77-
78- class SingleValueRepacker (KeyedDataAction ):
79- """Prep action to repack data."""
80-
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- )
90-
91- def __call__ (self , data : KeyedData , ** kwargs ) -> KeyedData :
92- repackedData = {}
76+ repackedData : dict [str , Vector ] = {}
9377 uniquePanelKeys = list (set (data [self .panelKey ]))
9478
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 ]} " ] = []
99-
100- panelVec = cast (Vector , data [self .panelKey ])
101- dataVec = cast (Vector , data [self .dataKey ])
102- quantityVec = cast (Vector , data [self .quantityKey ])
103-
104- for i in range (len (panelVec )):
105- repackedData [f"{ panelVec [i ]} _x" ].append (dataVec [i ])
106- repackedData [f"{ panelVec [i ]} " ].append (quantityVec [i ])
79+ for pKey in uniquePanelKeys :
80+ # Make a boolean array that selects the correct panel data
81+ sel : np .ndarray = data [self .panelKey ] == pKey
10782
83+ # Setup the x axis
84+ repackedData [f"{ pKey } _x" ] = data [self .dataKey ][sel ]
85+ for qkey in self .quantityKey :
86+ # Setup a y axis series for each quantityKey
87+ repackedData [f"{ pKey } _{ qkey } " ] = data [qkey ][sel ]
10888 return repackedData
10989
11090 def getInputSchema (self ) -> KeyedDataSchema :
@@ -136,6 +116,12 @@ class CalibQuantityBaseTool(AnalysisTool):
136116 doc = "Plot element." ,
137117 )
138118
119+ def _get_xKey_dict (self , yKeys : Optional [dict [int , str ]] = None ) -> dict [int , str ]:
120+ """Generate the dictionary of x axis keys from the y axis ones"""
121+ if yKeys is None :
122+ yKeys = self .produce .plot .valsGroupBy
123+ return {k : f"{ v } _x" for k , v in yKeys .items ()}
124+
139125 def setDefaults (self ):
140126 super ().setDefaults ()
141127
@@ -152,24 +138,7 @@ def setDefaults(self):
152138 self .produce .plot .numCols = 4
153139
154140 # 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- }
141+ self .produce .plot .valsGroupBy = _CALIB_AMP_NAME_DICT
173142
174143 def finalize (self ):
175144 super ().finalize ()
@@ -206,52 +175,17 @@ def setDefaults(self):
206175 self .plotElement = ScatterElement ()
207176
208177 # Repack the input data into a usable format
209- self .prep = SingleValueRepacker ()
178+ self .prep = PrepRepacker ()
210179
211180 self .produce .plot = GridPlot ()
212181 self .produce .plot .panels = {}
213182 self .produce .plot .numRows = 4
214183 self .produce .plot .numCols = 4
215184
216185 # 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- }
235-
236186 # 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- }
187+ self .produce .plot .valsGroupBy = _CALIB_AMP_NAME_DICT
188+ self .produce .plot .xDataKeys = self ._get_xKey_dict ()
255189
256190 self .prep .panelKey = "amplifier"
257191 self .prep .dataKey = "mjd"
@@ -277,7 +211,7 @@ def setDefaults(self):
277211 self .plotElement = ScatterElement ()
278212
279213 # Repack the input data into a usable format
280- self .prep = SingleValueRepacker ()
214+ self .prep = PrepRepacker ()
281215
282216 self .produce .plot = GridPlot ()
283217 self .produce .plot .panels = {}
@@ -287,10 +221,7 @@ def setDefaults(self):
287221 # Values to group by to distinguish between data in differing panels
288222 self .produce .plot .valsGroupBy = {0 : "bank1" , 1 : "bank0" }
289223
290- self .produce .plot .xDataKeys = {
291- 0 : "bank1_x" ,
292- 1 : "bank0_x" ,
293- }
224+ self .produce .plot .xDataKeys = self ._get_xKey_dict ()
294225 self .prep .panelKey = "amplifier"
295226 self .prep .dataKey = "mjd"
296227
0 commit comments