vidavis 0.0.12__py3-none-any.whl → 0.0.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vidavis/__version__.py +1 -1
- vidavis/apps/_ms_raster.py +183 -290
- vidavis/plot/ms_plot/_check_raster_inputs.py +107 -0
- vidavis/plot/ms_plot/_locate_points.py +126 -12
- vidavis/plot/ms_plot/_ms_plot.py +182 -51
- vidavis/plot/ms_plot/_plot_inputs.py +19 -0
- vidavis/plot/ms_plot/_raster_plot_gui.py +50 -41
- vidavis/plot/ms_plot/_raster_plot_inputs.py +111 -104
- {vidavis-0.0.12.dist-info → vidavis-0.0.14.dist-info}/METADATA +1 -1
- {vidavis-0.0.12.dist-info → vidavis-0.0.14.dist-info}/RECORD +12 -10
- {vidavis-0.0.12.dist-info → vidavis-0.0.14.dist-info}/WHEEL +0 -0
- {vidavis-0.0.12.dist-info → vidavis-0.0.14.dist-info}/licenses/LICENSE +0 -0
vidavis/apps/_ms_raster.py
CHANGED
|
@@ -8,17 +8,16 @@ from bokeh.models.formatters import NumeralTickFormatter
|
|
|
8
8
|
import holoviews as hv
|
|
9
9
|
import numpy as np
|
|
10
10
|
from pandas import to_datetime
|
|
11
|
-
import panel as pn
|
|
12
11
|
|
|
13
12
|
from vidavis.bokeh._palette import available_palettes
|
|
14
13
|
from vidavis.data.measurement_set.processing_set._ps_coords import set_index_coordinates
|
|
15
|
-
from vidavis.plot.ms_plot._time_ticks import get_time_formatter
|
|
16
|
-
from vidavis.plot.ms_plot._locate_points import locate_point, locate_box
|
|
17
14
|
from vidavis.plot.ms_plot._ms_plot import MsPlot
|
|
18
15
|
from vidavis.plot.ms_plot._ms_plot_constants import VIS_AXIS_OPTIONS, SPECTRUM_AXIS_OPTIONS, PS_SELECTION_OPTIONS, MS_SELECTION_OPTIONS
|
|
19
|
-
from vidavis.plot.ms_plot.
|
|
20
|
-
from vidavis.plot.ms_plot._raster_plot_inputs import check_inputs
|
|
16
|
+
from vidavis.plot.ms_plot._plot_inputs import inputs_changed
|
|
21
17
|
from vidavis.plot.ms_plot._raster_plot import RasterPlot
|
|
18
|
+
from vidavis.plot.ms_plot._raster_plot_gui import create_raster_gui
|
|
19
|
+
from vidavis.plot.ms_plot._raster_plot_inputs import RasterPlotInputs
|
|
20
|
+
from vidavis.plot.ms_plot._time_ticks import get_time_formatter
|
|
22
21
|
|
|
23
22
|
class MsRaster(MsPlot):
|
|
24
23
|
'''
|
|
@@ -44,21 +43,15 @@ class MsRaster(MsPlot):
|
|
|
44
43
|
def __init__(self, ms=None, log_level="info", log_to_file=True, show_gui=False):
|
|
45
44
|
super().__init__(ms, log_level, log_to_file, show_gui, "MsRaster")
|
|
46
45
|
self._raster_plot = RasterPlot()
|
|
47
|
-
self.
|
|
46
|
+
self._plot_inputs = RasterPlotInputs()
|
|
47
|
+
self._plot_inputs.set_input('ms', self._ms_info['ms'])
|
|
48
48
|
|
|
49
49
|
# Calculations for color limits
|
|
50
50
|
self._spw_stats = {}
|
|
51
51
|
self._spw_color_limits = {}
|
|
52
52
|
|
|
53
53
|
if show_gui:
|
|
54
|
-
#
|
|
55
|
-
self._last_plot_inputs = None
|
|
56
|
-
self._last_style_inputs = None
|
|
57
|
-
self._last_cursor = None
|
|
58
|
-
self._last_box = None
|
|
59
|
-
|
|
60
|
-
# Return plot for gui DynamicMap:
|
|
61
|
-
# Empty plot when ms not set or plot fails
|
|
54
|
+
# Return plot for gui DynamicMap: empty plot when ms not set or plot fails
|
|
62
55
|
self._empty_plot = self._create_empty_plot()
|
|
63
56
|
|
|
64
57
|
# Set default style and plot inputs to use when launching gui
|
|
@@ -66,7 +59,7 @@ class MsRaster(MsPlot):
|
|
|
66
59
|
self.plot()
|
|
67
60
|
self._launch_gui()
|
|
68
61
|
|
|
69
|
-
# Set filename TextInput to input ms, which triggers default plot
|
|
62
|
+
# Set filename TextInput widget to input ms, which triggers default plot
|
|
70
63
|
if 'ms' in self._ms_info and self._ms_info['ms']:
|
|
71
64
|
self._set_filename([self._ms_info['ms']]) # function expects list from FileBrowser widget
|
|
72
65
|
|
|
@@ -97,10 +90,8 @@ class MsRaster(MsPlot):
|
|
|
97
90
|
string_exact_match (bool): whether to require exact matches for string and string list columns (default True) or partial matches (False).
|
|
98
91
|
query (str): a Pandas query string to apply additional filtering.
|
|
99
92
|
**kwargs (dict): keyword arguments representing summary column names and values.
|
|
100
|
-
See
|
|
101
|
-
|
|
102
|
-
'field_name', 'source_name', 'field_coords', 'start_frequency', 'end_frequency'.
|
|
103
|
-
The selection is applied to the data within the MeasurementSets where applicable (polarization, scan_name, field_name)
|
|
93
|
+
See data_groups() and summary(data_group) and for selection keyword options. Use keyword 'data_group_name' for data group selection.
|
|
94
|
+
The selection is also applied to the data within the MeasurementSets where keyword is a coordinate (polarization, scan_name, field_name) and
|
|
104
95
|
string_exact_match=True, else the entire MS is selected.
|
|
105
96
|
Selections are cumulative until clear_selection() is called.
|
|
106
97
|
Raises exception with message if selection fails.
|
|
@@ -108,12 +99,10 @@ class MsRaster(MsPlot):
|
|
|
108
99
|
For explanation and examples, see:
|
|
109
100
|
https://xradio.readthedocs.io/en/latest/measurement_set/schema_and_api/measurement_set_api.html#xradio.measurement_set.ProcessingSetXdt.query
|
|
110
101
|
'''
|
|
111
|
-
if self.
|
|
102
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
112
103
|
try:
|
|
113
|
-
self._plot_inputs
|
|
114
|
-
|
|
115
|
-
self._plot_inputs['data_group'] = kwargs['data_group_name']
|
|
116
|
-
self._data.select_ps(query=query, string_exact_match=string_exact_match, **kwargs)
|
|
104
|
+
self._plot_inputs.set_selection(kwargs)
|
|
105
|
+
self._ms_data.select_ps(query=query, string_exact_match=string_exact_match, **kwargs)
|
|
117
106
|
except KeyError as ke:
|
|
118
107
|
error = "ProcessingSet selection yielded empty ProcessingSet."
|
|
119
108
|
if not self._show_gui:
|
|
@@ -137,12 +126,10 @@ class MsRaster(MsPlot):
|
|
|
137
126
|
For explanation of parameters and examples, see:
|
|
138
127
|
https://xradio.readthedocs.io/en/latest/measurement_set/schema_and_api/measurement_set_api.html#xradio.measurement_set.MeasurementSetXdt.sel
|
|
139
128
|
'''
|
|
140
|
-
if self.
|
|
129
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
141
130
|
try:
|
|
142
|
-
self._plot_inputs
|
|
143
|
-
self.
|
|
144
|
-
if 'data_group_name' in indexers_kwargs:
|
|
145
|
-
self._plot_inputs['data_group'] |= indexers_kwargs['data_group_name']
|
|
131
|
+
self._plot_inputs.set_selection(indexers_kwargs)
|
|
132
|
+
self._ms_data.select_ms(indexers=indexers, method=method, tolerance=tolerance, drop=drop, **indexers_kwargs)
|
|
146
133
|
except KeyError as ke:
|
|
147
134
|
error = str(ke).strip("\'")
|
|
148
135
|
if not self._show_gui:
|
|
@@ -156,8 +143,8 @@ class MsRaster(MsPlot):
|
|
|
156
143
|
iter_axis=None, iter_range=None, subplots=None, color_mode=None, color_range=None, title=None, clear_plots=True):
|
|
157
144
|
'''
|
|
158
145
|
Create a raster plot of vis_axis data.
|
|
159
|
-
Plot axes include data dimensions (time, baseline/
|
|
160
|
-
The first spectral window
|
|
146
|
+
Plot axes include data dimensions (time, baseline/antenna_name, frequency, polarization).
|
|
147
|
+
The first spectral window by time and dimensions not set as plot axes will be automatically selected by first value if no user selection has been made, unless aggregated.
|
|
161
148
|
|
|
162
149
|
Args:
|
|
163
150
|
x_axis (str): Plot x-axis. Default 'baseline' ('antenna_name' for spectrum data).
|
|
@@ -188,9 +175,7 @@ class MsRaster(MsPlot):
|
|
|
188
175
|
|
|
189
176
|
If plot is successful, use show() or save() to view/save the plot.
|
|
190
177
|
'''
|
|
191
|
-
inputs = locals() # collect arguments into dict
|
|
192
|
-
if self._plot_inputs['selection']:
|
|
193
|
-
self._logger.info("Create raster plot with selection: %s", self._plot_inputs['selection'])
|
|
178
|
+
inputs = locals() # collect arguments into dict
|
|
194
179
|
|
|
195
180
|
start = time.time()
|
|
196
181
|
|
|
@@ -199,23 +184,28 @@ class MsRaster(MsPlot):
|
|
|
199
184
|
|
|
200
185
|
# Get data dimensions if valid MS is set to check input axes
|
|
201
186
|
if 'data_dims' in self._ms_info:
|
|
202
|
-
|
|
187
|
+
data_dims = self._ms_info['data_dims'] if 'data_dims' in self._ms_info else None
|
|
188
|
+
inputs['data_dims'] = data_dims
|
|
203
189
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
190
|
+
self._plot_inputs.set_inputs(inputs)
|
|
191
|
+
selection = self._plot_inputs.get_input('selection')
|
|
192
|
+
if selection:
|
|
193
|
+
self._logger.info("Create raster plot with selection: %s", selection)
|
|
194
|
+
|
|
195
|
+
# If previous plot was shown, unlink from data streams
|
|
196
|
+
super().unlink_plot_streams()
|
|
207
197
|
|
|
208
198
|
if not self._show_gui:
|
|
209
199
|
# Cannot plot if no MS
|
|
210
|
-
if not self.
|
|
200
|
+
if not self._ms_data or not self._ms_data.is_valid():
|
|
211
201
|
raise RuntimeError("Cannot plot MS: input MS path is invalid or missing.")
|
|
212
202
|
|
|
213
203
|
# Create raster plot and add to plot list
|
|
214
204
|
try:
|
|
215
|
-
if self._plot_inputs
|
|
216
|
-
self._do_iter_plot(
|
|
205
|
+
if self._plot_inputs.get_input('iter_axis'):
|
|
206
|
+
self._do_iter_plot()
|
|
217
207
|
else:
|
|
218
|
-
plot = self._do_plot(
|
|
208
|
+
plot = self._do_plot()
|
|
219
209
|
self._plots.append(plot)
|
|
220
210
|
except RuntimeError as e:
|
|
221
211
|
error = f"Plot failed: {str(e)}"
|
|
@@ -248,137 +238,155 @@ class MsRaster(MsPlot):
|
|
|
248
238
|
filename = f"{self._ms_info['basename']}_raster.png"
|
|
249
239
|
super().save(filename, fmt, width, height)
|
|
250
240
|
|
|
251
|
-
def
|
|
252
|
-
''' Set inputs from latest plot() call '''
|
|
253
|
-
for key, val in plot_inputs.items():
|
|
254
|
-
self._plot_inputs[key] = val
|
|
255
|
-
|
|
256
|
-
def _do_plot(self, plot_inputs):
|
|
241
|
+
def _do_plot(self, is_gui_plot=False):
|
|
257
242
|
''' Create plot using plot inputs '''
|
|
258
243
|
if not self._plot_init:
|
|
259
|
-
self._init_plot(
|
|
244
|
+
self._init_plot()
|
|
260
245
|
|
|
261
246
|
# Select vis_axis data to plot and update selection; returns xarray Dataset
|
|
262
|
-
raster_data = self.
|
|
263
|
-
|
|
247
|
+
raster_data = self._ms_data.get_raster_data(self._plot_inputs.get_inputs())
|
|
248
|
+
|
|
249
|
+
# Save plot data for plot location callbacks unless layout (location not supported)
|
|
250
|
+
if not self._plot_inputs.is_layout():
|
|
251
|
+
x_axis = self._plot_inputs.get_input('x_axis')
|
|
252
|
+
y_axis = self._plot_inputs.get_input('y_axis')
|
|
253
|
+
if is_gui_plot:
|
|
254
|
+
self._gui_plot_data = set_index_coordinates(raster_data, (x_axis, y_axis))
|
|
255
|
+
else:
|
|
256
|
+
self._plot_data = set_index_coordinates(raster_data, (x_axis, y_axis))
|
|
264
257
|
|
|
265
258
|
# Add params needed for plot: auto color range and ms name
|
|
266
|
-
self._set_auto_color_range(
|
|
259
|
+
self._set_auto_color_range() # set calculated limits if auto mode
|
|
267
260
|
ms_name = self._ms_info['basename'] # for title
|
|
261
|
+
plot_inputs = self._plot_inputs.get_inputs()
|
|
268
262
|
self._raster_plot.set_plot_params(raster_data, plot_inputs, ms_name)
|
|
269
263
|
|
|
270
264
|
# Show plot inputs in log
|
|
271
265
|
super()._set_plot_params(plot_inputs | self._raster_plot.get_plot_params()['style'])
|
|
272
|
-
|
|
266
|
+
plot_params = [f"{key}={value}" for key, value in self._plot_params.items()]
|
|
267
|
+
self._logger.info("MsRaster plot parameters: %s", ", ".join(plot_params))
|
|
273
268
|
|
|
274
269
|
# Make plot. Add data min/max if GUI is shown to update color limits range.
|
|
275
270
|
return self._raster_plot.raster_plot(raster_data, self._logger, self._show_gui)
|
|
276
271
|
|
|
277
|
-
def _do_iter_plot(self
|
|
272
|
+
def _do_iter_plot(self):
|
|
278
273
|
''' Create one plot per iteration value in iter_range which fits into subplots '''
|
|
279
274
|
# Default (0, 0) (first iteration only). Use (0, -1) for all iterations.
|
|
280
275
|
# If subplots is a grid, end iteration index is limited by the grid size.
|
|
281
276
|
# If subplots is a single plot, all iteration plots in the range can be saved using export_range in save().
|
|
282
|
-
iter_axis =
|
|
283
|
-
iter_range =
|
|
284
|
-
subplots =
|
|
285
|
-
|
|
286
|
-
iter_range = (0, 0) if iter_range is None else iter_range
|
|
287
|
-
start_idx, end_idx = iter_range
|
|
277
|
+
iter_axis = self._plot_inputs.get_input('iter_axis')
|
|
278
|
+
iter_range = self._plot_inputs.get_input('iter_range')
|
|
279
|
+
subplots = self._plot_inputs.get_input('subplots')
|
|
288
280
|
|
|
289
281
|
# Init plot before getting iter values
|
|
290
|
-
self._init_plot(
|
|
291
|
-
|
|
292
|
-
iter_values = self._data.get_dimension_values(iter_axis)
|
|
282
|
+
self._init_plot()
|
|
283
|
+
iter_values = self._ms_data.get_dimension_values(iter_axis)
|
|
293
284
|
n_iter = len(iter_values)
|
|
294
285
|
|
|
286
|
+
iter_range = (0, 0) if iter_range is None else iter_range
|
|
287
|
+
start_idx, end_idx = iter_range
|
|
288
|
+
auto_range = end_idx == -1
|
|
289
|
+
|
|
295
290
|
if start_idx >= n_iter:
|
|
296
291
|
raise IndexError(f"iter_range start {start_idx} is greater than number of iterations {n_iter}")
|
|
297
292
|
end_idx = n_iter if (end_idx == -1 or end_idx >= n_iter) else end_idx + 1
|
|
298
293
|
num_iter_plots = end_idx - start_idx
|
|
299
294
|
|
|
300
|
-
# Plot the minimum of iter range or subplots number of plots
|
|
295
|
+
# Plot the minimum of iter range or subplots number of plots.
|
|
296
|
+
# If subplots is single plot, plot all for save()
|
|
301
297
|
num_subplots = np.prod(subplots) if subplots else 1
|
|
302
298
|
num_iter_plots = min(num_iter_plots, num_subplots) if num_subplots > 1 else num_iter_plots
|
|
303
299
|
end_idx = start_idx + num_iter_plots
|
|
304
300
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
301
|
+
if auto_range:
|
|
302
|
+
# For listing plot inputs
|
|
303
|
+
start_idx = start_idx.item() if isinstance(start_idx, np.int64) else start_idx
|
|
304
|
+
end_idx = end_idx.item() if isinstance(end_idx, np.int64) else end_idx
|
|
305
|
+
self._plot_inputs.set_input('auto_iter_range', (start_idx, end_idx - 1))
|
|
308
306
|
|
|
309
307
|
for i in range(start_idx, end_idx):
|
|
310
308
|
# Select iteration value and make plot
|
|
311
309
|
value = iter_values[i]
|
|
312
310
|
self._logger.info("Plot %s iteration index %s value %s", iter_axis, i, value)
|
|
313
|
-
|
|
311
|
+
self._plot_inputs.set_selection({iter_axis: value})
|
|
314
312
|
try:
|
|
315
|
-
plot = self._do_plot(
|
|
313
|
+
plot = self._do_plot()
|
|
316
314
|
self._plots.append(plot)
|
|
317
315
|
except RuntimeError as e:
|
|
318
316
|
self._logger.info("Iteration plot for value %s failed: %s", str(value), str(e))
|
|
319
317
|
continue
|
|
320
318
|
|
|
321
|
-
def _init_plot(self
|
|
319
|
+
def _init_plot(self):
|
|
322
320
|
''' Apply automatic selection '''
|
|
323
321
|
# Remove previous auto selections
|
|
324
322
|
for key in ['dim_selection', 'auto_spw']:
|
|
325
|
-
|
|
326
|
-
del self._plot_inputs[key]
|
|
327
|
-
except KeyError:
|
|
328
|
-
pass
|
|
323
|
+
self._plot_inputs.remove_input(key)
|
|
329
324
|
|
|
330
325
|
# Automatically select data group and spw name if not user-selected
|
|
331
326
|
auto_selection = {}
|
|
332
|
-
if 'data_group'
|
|
327
|
+
if not self._plot_inputs.get_input('data_group'):
|
|
333
328
|
auto_selection['data_group_name'] = 'base'
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
329
|
+
self._plot_inputs.set_input('data_group', 'base')
|
|
330
|
+
|
|
331
|
+
data_group = self._plot_inputs.get_input('data_group')
|
|
332
|
+
spw_selection = self._plot_inputs.get_selection('spw_name')
|
|
333
|
+
if not spw_selection:
|
|
334
|
+
first_spw = self._ms_data.get_first_spw(data_group)
|
|
337
335
|
auto_selection['spw_name'] = first_spw
|
|
338
|
-
|
|
336
|
+
self._plot_inputs.set_input('auto_spw', first_spw) # keep separate from user selection
|
|
339
337
|
|
|
340
338
|
if auto_selection:
|
|
341
339
|
# Do selection and save to plot inputs
|
|
342
340
|
self._logger.info("Automatic selection of data group and/or spw: %s", auto_selection)
|
|
343
|
-
self.
|
|
341
|
+
self._ms_data.select_ps(query=None, string_exact_match=True, **auto_selection)
|
|
344
342
|
|
|
345
343
|
# Print data info for spw selection
|
|
346
|
-
self._logger.info("Plotting %s msv4 datasets.", self.
|
|
347
|
-
self._logger.info("Maximum dimensions for selected spw: %s", self.
|
|
344
|
+
self._logger.info("Plotting %s msv4 datasets.", self._ms_data.get_num_ms())
|
|
345
|
+
self._logger.info("Maximum dimensions for selected spw: %s", self._ms_data.get_max_data_dims())
|
|
348
346
|
self._plot_init = True
|
|
349
347
|
|
|
350
|
-
def _set_auto_color_range(self
|
|
348
|
+
def _set_auto_color_range(self):
|
|
351
349
|
''' Calculate stats for color limits for non-gui amplitude plots. '''
|
|
352
|
-
color_mode =
|
|
353
|
-
|
|
350
|
+
color_mode = self._plot_inputs.get_input('color_mode')
|
|
351
|
+
auto_color_limits = None
|
|
354
352
|
|
|
355
353
|
if color_mode == 'auto':
|
|
356
|
-
if
|
|
354
|
+
if self._plot_inputs.get_input('vis_axis') == 'amp' and not self._plot_inputs.get_input('aggregator'):
|
|
357
355
|
# For amplitude, limit colorbar range using stored per-spw ms stats
|
|
358
|
-
spw_name = self._plot_inputs
|
|
356
|
+
spw_name = self._plot_inputs.get_selection('spw_name')
|
|
357
|
+
if not spw_name:
|
|
358
|
+
spw_name = self._plot_inputs.get_input('auto_spw')
|
|
359
|
+
|
|
359
360
|
if spw_name in self._spw_color_limits:
|
|
360
|
-
|
|
361
|
+
auto_color_limits = self._spw_color_limits[spw_name]
|
|
361
362
|
else:
|
|
362
363
|
# Select spw name and data group only, no dimensions
|
|
363
|
-
data_group = self._plot_inputs
|
|
364
|
+
data_group = self._plot_inputs.get_input('data_group')
|
|
364
365
|
spw_data_selection = {'spw_name': spw_name, 'data_group_name': data_group}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
366
|
+
auto_color_limits = self._calc_amp_color_limits(spw_data_selection)
|
|
367
|
+
|
|
368
|
+
if auto_color_limits:
|
|
369
|
+
# Convert to float for listing plot inputs
|
|
370
|
+
start, end = auto_color_limits
|
|
371
|
+
start = start.item() if isinstance(start, np.float64) else start
|
|
372
|
+
end = end.item() if isinstance(end, np.float64) else end
|
|
373
|
+
auto_color_limits = (start, end)
|
|
374
|
+
self._spw_color_limits[spw_name] = auto_color_limits
|
|
375
|
+
self._plot_inputs.set_input('auto_color_range', auto_color_limits)
|
|
376
|
+
|
|
377
|
+
if auto_color_limits:
|
|
378
|
+
self._logger.info("Setting amplitude color range: (%.4f, %.4f).", auto_color_limits[0], auto_color_limits[1])
|
|
371
379
|
elif color_mode is None:
|
|
372
380
|
self._logger.info("Autoscale color range")
|
|
373
381
|
else:
|
|
374
|
-
self._logger.info("Using manual color range: %s",
|
|
382
|
+
self._logger.info("Using manual color range: %s", self._plot_inputs.get_input('color_range'))
|
|
375
383
|
|
|
376
384
|
def _calc_amp_color_limits(self, selection):
|
|
377
385
|
# Calculate colorbar limits from amplitude stats for unflagged data in selected spw
|
|
378
386
|
self._logger.info("Calculating stats for colorbar limits.")
|
|
379
387
|
start = time.time()
|
|
380
388
|
|
|
381
|
-
ms_stats = self.
|
|
389
|
+
ms_stats = self._ms_data.get_vis_stats(selection, 'amp')
|
|
382
390
|
self._spw_stats['spw_name'] = ms_stats
|
|
383
391
|
if not ms_stats:
|
|
384
392
|
return None # autoscale
|
|
@@ -403,7 +411,7 @@ class MsRaster(MsPlot):
|
|
|
403
411
|
if clear_plots:
|
|
404
412
|
super().clear_plots()
|
|
405
413
|
|
|
406
|
-
# Clear params
|
|
414
|
+
# Clear params for last plot
|
|
407
415
|
self._raster_plot.reset_plot_params()
|
|
408
416
|
|
|
409
417
|
# Unitialize plot to redo auto selections if needed
|
|
@@ -429,8 +437,8 @@ class MsRaster(MsPlot):
|
|
|
429
437
|
'update_plot': self._update_plot,
|
|
430
438
|
}
|
|
431
439
|
data_dims = self._ms_info['data_dims'] if 'data_dims' in self._ms_info else None
|
|
432
|
-
x_axis = self._plot_inputs
|
|
433
|
-
y_axis = self._plot_inputs
|
|
440
|
+
x_axis = self._plot_inputs.get_input('x_axis')
|
|
441
|
+
y_axis = self._plot_inputs.get_input('y_axis')
|
|
434
442
|
self._gui_layout = create_raster_gui(callbacks, data_dims, x_axis, y_axis)
|
|
435
443
|
self._gui_layout.show(title=self._app_name, threaded=True)
|
|
436
444
|
|
|
@@ -438,13 +446,14 @@ class MsRaster(MsPlot):
|
|
|
438
446
|
### Main callback to create plot if inputs changed
|
|
439
447
|
###
|
|
440
448
|
# pylint: disable=too-many-arguments, too-many-positional-arguments
|
|
441
|
-
def _update_plot(self, ms, do_plot, x, y, bounds):
|
|
449
|
+
def _update_plot(self, ms, do_plot, x, y, data, bounds):
|
|
442
450
|
''' Create plot with inputs from GUI, or update cursor/box location.
|
|
443
451
|
Callbacks:
|
|
444
452
|
ms (first plot) - return plot with default inputs
|
|
445
453
|
do_plot (Plot button clicked) - return plot with inputs from GUI
|
|
446
|
-
x, y (
|
|
447
|
-
|
|
454
|
+
x, y (PointerXY) - update cursor location box
|
|
455
|
+
data (PointDraw from point_draw tool) - update location of drawn points in tab and log
|
|
456
|
+
bounds (Bounds from box_select tool) - update location of points in box in tab and log
|
|
448
457
|
This function *must* return plot, even if empty plot or last plot, for DynamicMap.
|
|
449
458
|
'''
|
|
450
459
|
# Remove toast notification and collapse selection accordion
|
|
@@ -458,40 +467,36 @@ class MsRaster(MsPlot):
|
|
|
458
467
|
|
|
459
468
|
# User changed inputs without clicking Plot button, or callback for cursor/box.
|
|
460
469
|
if not do_plot and not self._first_gui_plot:
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if self._box_changed(bounds):
|
|
467
|
-
# new box_select position - update location for points in box
|
|
468
|
-
self._update_box_location(bounds)
|
|
469
|
-
self._last_box = bounds
|
|
470
|
-
|
|
470
|
+
# Locate callbacks
|
|
471
|
+
super()._locate_cursor(x, y, self._gui_plot_data, self._gui_layout[0])
|
|
472
|
+
super()._locate_points(data, self._gui_plot_data, self._gui_layout[0])
|
|
473
|
+
super()._locate_box(bounds, self._gui_plot_data, self._gui_layout[0])
|
|
471
474
|
# Not ready to update plot yet, return last plot.
|
|
472
|
-
return self.
|
|
475
|
+
return self._last_plot
|
|
473
476
|
|
|
474
477
|
# First plot for input ms, or user clicked Plot button for new inputs
|
|
475
|
-
if (self._set_ms(ms) or self._first_gui_plot) and self.
|
|
478
|
+
if (self._set_ms(ms) or self._first_gui_plot) and self._ms_data and self._ms_data.is_valid():
|
|
476
479
|
# New MS set and is valid
|
|
477
480
|
self._update_gui_axis_options()
|
|
478
481
|
|
|
479
482
|
# Add ms path to detect change and make new plot
|
|
480
|
-
self._plot_inputs
|
|
483
|
+
self._plot_inputs.set_input('ms', ms)
|
|
481
484
|
|
|
482
485
|
# Do new plot or resend last plot
|
|
483
486
|
self._reset_plot()
|
|
484
487
|
self.clear_selection()
|
|
485
488
|
gui_plot = None
|
|
486
489
|
|
|
490
|
+
# Make plot if first plot or changed plot
|
|
487
491
|
style_inputs = self._raster_plot.get_plot_params()['style']
|
|
488
|
-
|
|
489
|
-
|
|
492
|
+
plot_inputs = self._plot_inputs.get_inputs()
|
|
493
|
+
if inputs_changed(plot_inputs, self._last_plot_inputs) or inputs_changed(style_inputs, self._last_style_inputs):
|
|
490
494
|
try:
|
|
491
495
|
# Check inputs from GUI then plot
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
496
|
+
data_dims = self._ms_info['data_dims']
|
|
497
|
+
self._plot_inputs.set_input('data_dims', data_dims)
|
|
498
|
+
self._plot_inputs.check_inputs()
|
|
499
|
+
if 'ps_selection' in self._gui_selection or 'ms_selection' in self._gui_selection:
|
|
495
500
|
self._do_gui_selection()
|
|
496
501
|
gui_plot = self._do_gui_plot()
|
|
497
502
|
except (ValueError, TypeError, KeyError, RuntimeError) as e:
|
|
@@ -500,101 +505,57 @@ class MsRaster(MsPlot):
|
|
|
500
505
|
gui_plot = self._empty_plot
|
|
501
506
|
else:
|
|
502
507
|
# Subparam values changed but not applied to plot
|
|
503
|
-
gui_plot = self.
|
|
508
|
+
gui_plot = self._last_plot
|
|
504
509
|
|
|
505
510
|
# Update plot inputs for gui
|
|
506
|
-
self._set_plot_params(
|
|
511
|
+
self._set_plot_params(plot_inputs | style_inputs)
|
|
507
512
|
|
|
508
513
|
# Save inputs to see if changed next time
|
|
509
|
-
self._last_plot_inputs =
|
|
514
|
+
self._last_plot_inputs = plot_inputs.copy()
|
|
510
515
|
self._last_style_inputs = style_inputs.copy()
|
|
511
|
-
self._last_plot_inputs['ps_selection'] = self._plot_inputs['ps_selection'].copy()
|
|
512
|
-
self._last_plot_inputs['ms_selection'] = self._plot_inputs['ms_selection'].copy()
|
|
513
|
-
if self._first_gui_plot and not do_plot:
|
|
514
|
-
self._plot_inputs['ps_selection'].clear()
|
|
515
|
-
self._plot_inputs['ms_selection'].clear()
|
|
516
516
|
|
|
517
517
|
# Save plot for return value if plot update not requested
|
|
518
|
-
self.
|
|
518
|
+
self._last_plot = gui_plot
|
|
519
519
|
self._first_gui_plot = False
|
|
520
520
|
|
|
521
|
-
# Add plot inputs, change plot button to outline, and stop spinner
|
|
522
|
-
self.
|
|
521
|
+
# Add plot inputs to GUI, change plot button to outline, and stop spinner
|
|
522
|
+
self._show_plot_inputs()
|
|
523
523
|
self._update_plot_status(False)
|
|
524
524
|
self._update_plot_spinner(False)
|
|
525
525
|
|
|
526
526
|
return gui_plot
|
|
527
527
|
# pylint: enable=too-many-arguments, too-many-positional-arguments
|
|
528
528
|
|
|
529
|
-
def _cursor_changed(self, x, y):
|
|
530
|
-
''' Check whether cursor position changed '''
|
|
531
|
-
if not x and not y:
|
|
532
|
-
return False # not cursor callback
|
|
533
|
-
if self._last_cursor and self._last_cursor == (x, y):
|
|
534
|
-
return False # same cursor
|
|
535
|
-
return True # new cursor or cursor changed
|
|
536
|
-
|
|
537
|
-
def _box_changed(self, bounds):
|
|
538
|
-
''' Check whether box position changed '''
|
|
539
|
-
if not bounds:
|
|
540
|
-
return False # no data, not box select callback
|
|
541
|
-
if self._last_box and self._last_box == bounds:
|
|
542
|
-
return False # same box
|
|
543
|
-
return True # new box or box changed
|
|
544
|
-
|
|
545
|
-
def _inputs_changed(self, style_inputs):
|
|
546
|
-
''' Check if inputs changed and need new plot '''
|
|
547
|
-
if not self._last_plot_inputs:
|
|
548
|
-
return True
|
|
549
|
-
|
|
550
|
-
for key, val in self._plot_inputs.items():
|
|
551
|
-
if not self._values_equal(val, self._last_plot_inputs[key]):
|
|
552
|
-
return True
|
|
553
|
-
|
|
554
|
-
for key, val in style_inputs.items():
|
|
555
|
-
if not self._values_equal(val, self._last_style_inputs[key]):
|
|
556
|
-
return True
|
|
557
|
-
return False
|
|
558
|
-
|
|
559
|
-
def _values_equal(self, val1, val2):
|
|
560
|
-
''' Test if values are set and equal, or not set (cannot compare value with None) '''
|
|
561
|
-
if val1 is not None and val2 is not None: # both set
|
|
562
|
-
return val1 == val2
|
|
563
|
-
if val1 is None and val2 is None: # both None
|
|
564
|
-
return True
|
|
565
|
-
return False # one set and other is None
|
|
566
|
-
|
|
567
529
|
def _do_gui_selection(self):
|
|
568
530
|
''' Apply selections selected in GUI '''
|
|
569
|
-
if self.
|
|
570
|
-
self.select_ps(**self.
|
|
571
|
-
if self.
|
|
572
|
-
self.select_ms(**self.
|
|
531
|
+
if self._gui_selection['ps_selection']:
|
|
532
|
+
self.select_ps(**self._gui_selection['ps_selection'])
|
|
533
|
+
if self._gui_selection['ms_selection']:
|
|
534
|
+
self.select_ms(**self._gui_selection['ms_selection'])
|
|
573
535
|
|
|
574
536
|
###
|
|
575
537
|
### Create plot for DynamicMap
|
|
576
538
|
###
|
|
577
539
|
def _do_gui_plot(self):
|
|
578
540
|
''' Create plot based on gui plot inputs '''
|
|
579
|
-
if self.
|
|
541
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
580
542
|
try:
|
|
581
|
-
if self._plot_inputs
|
|
543
|
+
if self._plot_inputs.get_input('iter_axis'):
|
|
582
544
|
# Make iter plot (possibly with subplots layout)
|
|
583
|
-
self._do_iter_plot(
|
|
584
|
-
subplots = self._plot_inputs
|
|
545
|
+
self._do_iter_plot()
|
|
546
|
+
subplots = self._plot_inputs.get_input('subplots')
|
|
585
547
|
layout_plot, is_layout = super()._layout_plots(subplots)
|
|
586
|
-
|
|
587
548
|
if is_layout:
|
|
588
549
|
# Cannot show Layout in DynamicMap, show in new tab
|
|
589
550
|
super().show()
|
|
590
551
|
self._logger.info("Plot update complete")
|
|
591
|
-
return self.
|
|
552
|
+
return self._last_plot
|
|
592
553
|
# Overlay raster plot for DynamicMap
|
|
593
554
|
self._logger.info("Plot update complete")
|
|
594
555
|
return layout_plot
|
|
595
556
|
|
|
596
557
|
# Make single Overlay raster plot for DynamicMap
|
|
597
|
-
plot = self._do_plot(
|
|
558
|
+
plot = self._do_plot(True)
|
|
598
559
|
plot_params = self._raster_plot.get_plot_params()
|
|
599
560
|
|
|
600
561
|
# Update color limits in gui with data range
|
|
@@ -606,7 +567,11 @@ class MsRaster(MsPlot):
|
|
|
606
567
|
|
|
607
568
|
self._logger.info("Plot update complete")
|
|
608
569
|
return plot.opts(
|
|
609
|
-
hv.opts.QuadMesh(
|
|
570
|
+
hv.opts.QuadMesh(
|
|
571
|
+
tools=['hover', 'box_select'],
|
|
572
|
+
selection_fill_alpha=0.2, # dim selected areas of plot
|
|
573
|
+
nonselection_fill_alpha=1.0, # do not dim unselected areas of plot
|
|
574
|
+
)
|
|
610
575
|
)
|
|
611
576
|
except RuntimeError as e:
|
|
612
577
|
error = f"Plot failed: {str(e)}"
|
|
@@ -631,7 +596,11 @@ class MsRaster(MsPlot):
|
|
|
631
596
|
)
|
|
632
597
|
)
|
|
633
598
|
return plot.opts(
|
|
634
|
-
hv.opts.QuadMesh(
|
|
599
|
+
hv.opts.QuadMesh(
|
|
600
|
+
tools=['hover', 'box_select'],
|
|
601
|
+
selection_fill_alpha=0.5, # dim selected areas of plot
|
|
602
|
+
nonselection_fill_alpha=1.0, # do not dim unselected areas of plot
|
|
603
|
+
)
|
|
635
604
|
)
|
|
636
605
|
|
|
637
606
|
def _set_plot_colorbar(self, plot, plot_params, plot_type):
|
|
@@ -712,7 +681,7 @@ class MsRaster(MsPlot):
|
|
|
712
681
|
# Update options for vis_axis selector
|
|
713
682
|
vis_axis_selector = axis_selectors.objects[2]
|
|
714
683
|
vis_axis_value = vis_axis_selector.value
|
|
715
|
-
if self.
|
|
684
|
+
if self._ms_data.get_correlated_data('base') == 'SPECTRUM':
|
|
716
685
|
vis_axis_selector.options = SPECTRUM_AXIS_OPTIONS
|
|
717
686
|
else:
|
|
718
687
|
vis_axis_selector.options = VIS_AXIS_OPTIONS
|
|
@@ -738,8 +707,8 @@ class MsRaster(MsPlot):
|
|
|
738
707
|
|
|
739
708
|
def _update_ps_selection_options(self, ps_selectors):
|
|
740
709
|
''' Set ProcessingSet gui options from ms summary '''
|
|
741
|
-
if self.
|
|
742
|
-
summary = self.
|
|
710
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
711
|
+
summary = self._ms_data.get_summary()
|
|
743
712
|
if summary is None:
|
|
744
713
|
return
|
|
745
714
|
|
|
@@ -756,7 +725,7 @@ class MsRaster(MsPlot):
|
|
|
756
725
|
|
|
757
726
|
def _update_ms_selection_options(self, ms_selectors):
|
|
758
727
|
''' Set MeasurementSet gui options from ms data '''
|
|
759
|
-
if self.
|
|
728
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
760
729
|
for selector in ms_selectors:
|
|
761
730
|
selection_key = MS_SELECTION_OPTIONS[selector.name] if selector.name in MS_SELECTION_OPTIONS else None
|
|
762
731
|
if selection_key:
|
|
@@ -789,7 +758,7 @@ class MsRaster(MsPlot):
|
|
|
789
758
|
''' Set up player with values when iter_axis is selected '''
|
|
790
759
|
iter_axis = None if iter_axis == 'None' else iter_axis
|
|
791
760
|
if iter_axis and self._gui_layout:
|
|
792
|
-
iter_values = self.
|
|
761
|
+
iter_values = self._ms_data.get_dimension_values(iter_axis)
|
|
793
762
|
if iter_values:
|
|
794
763
|
|
|
795
764
|
iter_selectors = self._get_selector('iter')
|
|
@@ -819,7 +788,7 @@ class MsRaster(MsPlot):
|
|
|
819
788
|
|
|
820
789
|
def _get_datetime_values(self, float_times):
|
|
821
790
|
''' Return list of float time values as list of datetime values for gui options '''
|
|
822
|
-
time_attrs = self.
|
|
791
|
+
time_attrs = self._ms_data.get_dimension_attrs('time')
|
|
823
792
|
datetime_values = []
|
|
824
793
|
try:
|
|
825
794
|
datetime_values = to_datetime(float_times, unit=time_attrs['units'], origin=time_attrs['format'])
|
|
@@ -834,92 +803,24 @@ class MsRaster(MsPlot):
|
|
|
834
803
|
spinner = self._gui_layout[2][2][1]
|
|
835
804
|
spinner.value = plot_clicked
|
|
836
805
|
|
|
837
|
-
def _update_plot_status(self,
|
|
838
|
-
''' Change button color when inputs change. '''
|
|
806
|
+
def _update_plot_status(self, plot_changed):
|
|
807
|
+
''' Change button color when plot inputs change. '''
|
|
839
808
|
if self._gui_layout:
|
|
840
809
|
# Set button color
|
|
841
810
|
button = self._gui_layout[2][2][0]
|
|
842
|
-
button.button_style = 'solid' if
|
|
843
|
-
|
|
844
|
-
def
|
|
845
|
-
''' Show inputs for raster plot in GUI '''
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
inputs_column.clear()
|
|
849
|
-
for param in self._plot_params:
|
|
850
|
-
str_pane = pn.pane.Str(param)
|
|
851
|
-
str_pane.margin = (0, 10)
|
|
852
|
-
inputs_column.append(str_pane)
|
|
853
|
-
|
|
854
|
-
def _update_cursor_location(self, x, y):
|
|
855
|
-
''' Show data values for cursor x,y position in cursor location box below plot '''
|
|
856
|
-
# Convert plot values to selection values to select plot data
|
|
857
|
-
x_axis = self._plot_inputs['x_axis']
|
|
858
|
-
y_axis = self._plot_inputs['y_axis']
|
|
859
|
-
plot_data = set_index_coordinates(self._plot_data, (x_axis, y_axis))
|
|
860
|
-
cursor_position = {x_axis: x, y_axis: y}
|
|
861
|
-
cursor_location = locate_point(plot_data, cursor_position, self._plot_inputs['vis_axis'])
|
|
862
|
-
self._update_cursor_box(cursor_location)
|
|
863
|
-
|
|
864
|
-
def _update_cursor_box(self, cursor_location):
|
|
865
|
-
''' Update cursor location widget box with list of Panel StaticText widgets '''
|
|
866
|
-
cursor_location_box = self._gui_layout[0][0][1] # row 0 tab 0 row 1 in column
|
|
867
|
-
cursor_location_box.clear() # pn.WidgetBox
|
|
868
|
-
location_layout = pn.Column(pn.widgets.StaticText(name="Cursor Location"))
|
|
869
|
-
location_row = self._layout_point_location(cursor_location)
|
|
870
|
-
# Add row of columns to column layout
|
|
871
|
-
location_layout.append(location_row)
|
|
872
|
-
# Add column layout to widget box
|
|
873
|
-
cursor_location_box.append(location_layout)
|
|
874
|
-
|
|
875
|
-
def _layout_point_location(self, text_list):
|
|
876
|
-
''' Layout list of StaticText in row of columns containing 3 rows '''
|
|
877
|
-
location_row = pn.Row()
|
|
878
|
-
location_col = pn.Column()
|
|
879
|
-
|
|
880
|
-
for static_text in text_list:
|
|
881
|
-
# 3 entries per column; append to row and start new column
|
|
882
|
-
if len(location_col.objects) == 3:
|
|
883
|
-
location_row.append(location_col)
|
|
884
|
-
location_col = pn.Column()
|
|
885
|
-
|
|
886
|
-
static_text.margin = (0, 10) # default (5, 10)
|
|
887
|
-
location_col.append(static_text)
|
|
888
|
-
|
|
889
|
-
# Add last column
|
|
890
|
-
location_row.append(location_col)
|
|
891
|
-
return location_row
|
|
892
|
-
|
|
893
|
-
def _update_box_location(self, bounds):
|
|
894
|
-
''' Show data values for points in box in box location tab and log '''
|
|
895
|
-
x_axis = self._plot_inputs['x_axis']
|
|
896
|
-
y_axis = self._plot_inputs['y_axis']
|
|
897
|
-
plot_data = set_index_coordinates(self._plot_data, (x_axis, y_axis))
|
|
898
|
-
box_bounds = {x_axis: (bounds[0], bounds[2]), y_axis: (bounds[1], bounds[3])}
|
|
899
|
-
npoints, point_locations = locate_box(plot_data, box_bounds, self._plot_inputs['vis_axis'])
|
|
900
|
-
|
|
901
|
-
locate_column = self._gui_layout[0][2] # row 0 tab 2
|
|
902
|
-
locate_column.clear()
|
|
903
|
-
message = f"Locate {npoints} points"
|
|
904
|
-
message += " (only first 100 shown):" if npoints > 100 else ":"
|
|
905
|
-
self._logger.info(message)
|
|
906
|
-
|
|
907
|
-
for point in point_locations:
|
|
908
|
-
# Format and add to locate column
|
|
909
|
-
location_layout = self._layout_point_location(point)
|
|
910
|
-
locate_column.append(location_layout)
|
|
911
|
-
locate_column.append(pn.layout.Divider())
|
|
912
|
-
|
|
913
|
-
# Format and add to log
|
|
914
|
-
location_list = [f"{static_text.name}={static_text.value}" for static_text in point]
|
|
915
|
-
self._logger.info(", ".join(location_list))
|
|
811
|
+
button.button_style = 'solid' if plot_changed else 'outline'
|
|
812
|
+
|
|
813
|
+
def _show_plot_inputs(self):
|
|
814
|
+
''' Show inputs for raster plot in column in GUI tab '''
|
|
815
|
+
inputs_column = self._gui_layout[0][1]
|
|
816
|
+
super()._fill_inputs_column(inputs_column)
|
|
916
817
|
|
|
917
818
|
###
|
|
918
819
|
### Callbacks for widgets which update plot inputs
|
|
919
820
|
###
|
|
920
821
|
def _set_title(self, title):
|
|
921
822
|
''' Set title from gui text input '''
|
|
922
|
-
self._plot_inputs
|
|
823
|
+
self._plot_inputs.set_input('title', title)
|
|
923
824
|
self._update_plot_status(True) # Change plot button to solid
|
|
924
825
|
|
|
925
826
|
def _set_style_params(self, unflagged_cmap, flagged_cmap, show_colorbar, show_flagged_colorbar):
|
|
@@ -928,67 +829,59 @@ class MsRaster(MsPlot):
|
|
|
928
829
|
|
|
929
830
|
def _set_color_range(self, color_mode, color_range):
|
|
930
831
|
''' Set style params from gui '''
|
|
931
|
-
color_mode
|
|
932
|
-
color_mode = None if color_mode == 'No' else color_mode
|
|
933
|
-
self._plot_inputs['color_mode'] = color_mode
|
|
934
|
-
self._plot_inputs['color_range'] = color_range
|
|
832
|
+
self._plot_inputs.set_color_inputs(color_mode, color_range)
|
|
935
833
|
self._update_plot_status(True) # Change plot button to solid
|
|
936
834
|
|
|
937
835
|
def _set_axes(self, x_axis, y_axis, vis_axis):
|
|
938
|
-
''' Set plot axis
|
|
939
|
-
self._plot_inputs
|
|
940
|
-
self._plot_inputs['y_axis'] = y_axis
|
|
941
|
-
self._plot_inputs['vis_axis'] = vis_axis
|
|
836
|
+
''' Set plot axis inputs from gui '''
|
|
837
|
+
self._plot_inputs.set_axis_inputs(x_axis, y_axis, vis_axis)
|
|
942
838
|
self._update_plot_status(True) # Change plot button to solid
|
|
943
839
|
|
|
944
840
|
def _set_aggregation(self, aggregator, agg_axes):
|
|
945
841
|
''' Set aggregation params from gui '''
|
|
946
|
-
aggregator
|
|
947
|
-
self._plot_inputs['aggregator'] = aggregator
|
|
948
|
-
self._plot_inputs['agg_axis'] = agg_axes # ignored if aggregator not set
|
|
842
|
+
self._plot_inputs.set_aggregation_inputs(aggregator, agg_axes)
|
|
949
843
|
self._update_plot_status(True) # Change plot button to solid
|
|
950
844
|
|
|
951
845
|
# pylint: disable=too-many-arguments, too-many-positional-arguments
|
|
952
846
|
def _set_iteration(self, iter_axis, iter_value_type, iter_value, iter_start, iter_end, subplot_rows, subplot_columns):
|
|
953
847
|
''' Set iteration params from gui '''
|
|
954
848
|
iter_axis = None if iter_axis == 'None' else iter_axis
|
|
955
|
-
|
|
956
|
-
self._plot_inputs['subplots'] = (subplot_rows, subplot_columns)
|
|
957
|
-
|
|
849
|
+
iter_range = None
|
|
958
850
|
if iter_axis:
|
|
851
|
+
# Set iter_range
|
|
959
852
|
if iter_value_type == 'By Value':
|
|
960
853
|
# Use index of iter_value for tuple
|
|
961
|
-
if self.
|
|
962
|
-
iter_values = self.
|
|
854
|
+
if self._ms_data and self._ms_data.is_valid():
|
|
855
|
+
iter_values = self._ms_data.get_dimension_values(iter_axis)
|
|
963
856
|
iter_index = iter_values.index(iter_value)
|
|
964
|
-
|
|
857
|
+
iter_range = (iter_index, iter_index)
|
|
965
858
|
else:
|
|
966
859
|
# 'By Range': use range start and end values for tuple
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
860
|
+
iter_range = (iter_start, iter_end)
|
|
861
|
+
|
|
862
|
+
self._plot_inputs.set_iteration_inputs(iter_axis, iter_range, subplot_rows, subplot_columns)
|
|
970
863
|
self._update_plot_status(True) # Change plot button to solid
|
|
971
864
|
# pylint: enable=too-many-arguments, too-many-positional-arguments
|
|
972
865
|
|
|
973
866
|
# pylint: disable=too-many-arguments, too-many-positional-arguments, unused-argument
|
|
974
867
|
def _set_ps_selection(self, query, name, intents, scan_name, spw_name, field_name, source_name, line_name):
|
|
975
|
-
'''
|
|
868
|
+
''' Set ProcessingSet selection from gui using summary columns '''
|
|
976
869
|
inputs = locals()
|
|
977
870
|
ps_selection = {}
|
|
978
871
|
for key, val in inputs.items():
|
|
979
872
|
if key in PS_SELECTION_OPTIONS.values() and val:
|
|
980
873
|
ps_selection[key] = val
|
|
981
|
-
self.
|
|
874
|
+
self._gui_selection['ps_selection'] = ps_selection
|
|
982
875
|
self._update_plot_status(True) # Change plot button to solid
|
|
983
876
|
|
|
984
877
|
def _set_ms_selection(self, data_group, datetime, baseline, antenna1, antenna2, frequency, polarization):
|
|
985
|
-
'''
|
|
878
|
+
''' Set MeasurementSet selection from gui using data group, dimensions, and coordinates '''
|
|
986
879
|
inputs = locals()
|
|
987
880
|
inputs['time'] = inputs.pop('datetime')
|
|
988
881
|
ms_selection = {}
|
|
989
882
|
for key, val in inputs.items():
|
|
990
883
|
if key in MS_SELECTION_OPTIONS.values() and val:
|
|
991
884
|
ms_selection[key] = val
|
|
992
|
-
self.
|
|
885
|
+
self._gui_selection['ms_selection'] = ms_selection
|
|
993
886
|
self._update_plot_status(True) # Change plot button to solid
|
|
994
887
|
# pylint: enable=too-many-arguments, too-many-positional-arguments, unused-argument
|