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.
@@ -9,9 +9,42 @@ from vidavis.plot.ms_plot._ms_plot_selectors import (file_selector, title_select
9
9
 
10
10
  def create_raster_gui(callbacks, data_dims, x_axis, y_axis):
11
11
  ''' Use Holoviz Panel to create a dashboard for plot inputs and raster plot display. '''
12
- # ------------------
13
- # PLOT INPUTS COLUMN
14
- # ------------------
12
+ # Accordion of widgets for plot inputs
13
+ selectors = get_plot_input_selectors(callbacks, data_dims, x_axis, y_axis)
14
+
15
+ # Plot button and spinner while plotting
16
+ init_plot = plot_starter(callbacks['plot_updating'])
17
+
18
+ # Dynamic map for plot, with callback when inputs change or location needed
19
+ dmap, points = get_plot_dmap(callbacks, selectors, init_plot)
20
+
21
+ return pn.Row(
22
+ pn.Tabs( # Row [0]
23
+ ('Plot', # Tabs[0]
24
+ pn.Column(
25
+ dmap * points, # [0] plot with hv.Points overlay for point_draw
26
+ pn.WidgetBox(), # [1] cursor location
27
+ )
28
+ ),
29
+ ('Plot Inputs', pn.Column()), # Tabs[1]
30
+ ('Locate Selected Points', pn.Column()), # Tabs[2]
31
+ ('Locate Selected Box', pn.Column()), # Tabs[3]
32
+ sizing_mode='stretch_width',
33
+ ),
34
+ pn.Spacer(width=10), # Row [1]
35
+ pn.Column( # Row [2]
36
+ pn.Spacer(height=25), # Column[0]
37
+ selectors, # Column[1]
38
+ init_plot, # Column[2]
39
+ width_policy='min',
40
+ width=400,
41
+ sizing_mode='stretch_height',
42
+ ),
43
+ sizing_mode='stretch_height',
44
+ )
45
+
46
+ def get_plot_input_selectors(callbacks, data_dims, x_axis, y_axis):
47
+ ''' Create accordion of widgets for plot inputs selection '''
15
48
  # Select MS
16
49
  file_selectors = file_selector('Path to MeasurementSet (ms or zarr) for plot', '~' , callbacks['filename'])
17
50
 
@@ -47,50 +80,26 @@ def create_raster_gui(callbacks, data_dims, x_axis, y_axis):
47
80
  ("Plot title", title_input), # [6]
48
81
  )
49
82
  selectors.toggle = True
83
+ return selectors
50
84
 
51
- # Plot button and spinner while plotting
52
- init_plot = plot_starter(callbacks['plot_updating'])
53
-
54
- # ----------------------------------------
55
- # PLOT WITH CURSOR POSITION AND BOX SELECT
56
- # ----------------------------------------
57
- # Connect plot to filename and plot button; add streams for cursor position and selected box
58
- # 'update_plot' callback must have parameters (ms, do_plot, x, y, data)
85
+ def get_plot_dmap(callbacks, selectors, init_plot):
86
+ ''' Dynamic map for updating plot from callback function '''
87
+ # Connect plot to filename and plot button; add streams for cursor position, drawn points, and selected box
88
+ # 'update_plot' callback must have parameters (ms, do_plot, x, y, data, bounds)
89
+ points = hv.Points([]).opts(
90
+ size=5,
91
+ fill_color='white'
92
+ )
59
93
  dmap = hv.DynamicMap(
60
94
  pn.bind(
61
95
  callbacks['update_plot'],
62
- ms=file_selectors[0][0],
96
+ ms=selectors[0][0][0],
63
97
  do_plot=init_plot[0],
64
98
  ),
65
99
  streams=[
66
- hv.streams.PointerXY(), # cursor location (x, y)
67
- hv.streams.BoundsXY() # box location (bounds)
100
+ hv.streams.PointerXY(), # cursor location (x, y)
101
+ hv.streams.PointDraw(source=points), # fixed cursor location (data)
102
+ hv.streams.BoundsXY() # box location (bounds)
68
103
  ]
69
104
  )
70
-
71
- # ----------------------------------------------
72
- # GUI LAYOUT OF PLOT TABS AND PLOT INPUTS COLUMN
73
- # ----------------------------------------------
74
- return pn.Row(
75
- pn.Tabs( # Row [0]
76
- ('Plot',
77
- pn.Column( # Tabs [0]
78
- dmap, # [0]
79
- pn.WidgetBox(), # [1] cursor location
80
- )
81
- ),
82
- ('Plot Inputs', pn.Column()), # Tabs [1]
83
- ('Locate Selected Box', pn.Column()), # Tabs [2]
84
- sizing_mode='stretch_width',
85
- ),
86
- pn.Spacer(width=10), # Row [1]
87
- pn.Column( # Row [2]
88
- pn.Spacer(height=25), # Column [0]
89
- selectors, # Column [1]
90
- init_plot, # Column [2]
91
- width_policy='min',
92
- width=400,
93
- sizing_mode='stretch_height',
94
- ),
95
- sizing_mode='stretch_height',
96
- )
105
+ return dmap, points
@@ -1,107 +1,114 @@
1
1
  '''
2
- Check inputs to MsRaster plot() or its GUI
2
+ Class to check and hold inputs for raster plot.
3
3
  '''
4
4
 
5
- from vidavis.plot.ms_plot._ms_plot_constants import VIS_AXIS_OPTIONS, AGGREGATOR_OPTIONS
6
-
7
- def check_inputs(inputs):
8
- ''' Check plot input types, and axis input values. '''
9
- _set_baseline_antenna_axis(inputs)
10
- _check_axis_inputs(inputs)
11
- _check_agg_inputs(inputs)
12
- _check_color_inputs(inputs)
13
- _check_other_inputs(inputs)
14
-
15
- def _set_baseline_antenna_axis(inputs):
16
- ''' Set baseline axis to dimension in data_dims '''
17
- if 'data_dims' not in inputs:
18
- return
19
-
20
- data_dims = inputs['data_dims']
21
- baseline_dim = 'antenna_name' if 'antenna_name' in data_dims else 'baseline'
22
-
23
- # Convert baseline axis to existing baseline dimension
24
- baseline_dims = ['baseline', 'antenna_name']
25
- for axis in ['x_axis', 'y_axis', 'iter_axis', 'agg_axis']:
26
- if inputs[axis] in baseline_dims:
27
- inputs[axis] = baseline_dim
28
-
29
- def _check_axis_inputs(inputs):
30
- ''' Check x_axis, y_axis, vis_axis, and iter_axis inputs. '''
31
- x_axis = inputs['x_axis']
32
- y_axis = inputs['y_axis']
33
- if x_axis == y_axis:
34
- raise ValueError(f"Invalid parameter values: x_axis {x_axis} cannot be same as y_axis {y_axis}.")
35
-
36
- iter_axis = inputs['iter_axis']
37
- if iter_axis and iter_axis in (x_axis, y_axis):
38
- raise ValueError(f"Invalid parameter value: iter_axis {iter_axis} cannot be x_axis ({x_axis}) or y_axis ({y_axis}).")
39
-
40
- data_dims = inputs['data_dims'] if 'data_dims' in inputs else None
41
- if data_dims:
42
- if x_axis not in data_dims or y_axis not in data_dims:
43
- raise ValueError(f"Invalid parameter value: x and y axis must be a data dimension in {data_dims}.")
44
- if iter_axis and iter_axis not in data_dims:
45
- raise ValueError(f"Invalid parameter value: iter_axis {iter_axis} must be a data dimension in {data_dims}.")
46
-
47
- vis_axis = inputs['vis_axis']
48
- if vis_axis not in VIS_AXIS_OPTIONS:
49
- raise ValueError(f"Invalid parameter value: vis_axis {vis_axis} must be one of {VIS_AXIS_OPTIONS}")
50
-
51
- def _check_agg_inputs(inputs):
52
- ''' Check aggregator and agg_axis. Set agg_axis if not set. '''
53
- aggregator = inputs['aggregator']
54
- agg_axis = inputs['agg_axis']
55
-
56
- x_axis = inputs['x_axis']
57
- y_axis = inputs['y_axis']
58
- data_dims = inputs['data_dims'] if 'data_dims' in inputs else None
59
-
60
- if aggregator and aggregator not in AGGREGATOR_OPTIONS:
61
- raise ValueError(f"Invalid parameter value: aggregator {aggregator} must be None or one of {AGGREGATOR_OPTIONS}.")
62
-
63
- if agg_axis:
64
- if not isinstance(agg_axis, str) and not isinstance(agg_axis, list):
65
- raise TypeError(f"Invalid parameter type: agg_axis {agg_axis} must be str or list.")
66
-
67
- # Make agg_axis a list
68
- if isinstance(agg_axis, str):
69
- agg_axis = [agg_axis]
70
-
71
- for axis in agg_axis:
72
- if axis in (x_axis, y_axis):
73
- raise ValueError(f"Invalid parameter value: agg_axis {agg_axis} cannot be x_axis ({x_axis}) or y_axis ({y_axis}).")
74
- if data_dims and axis not in data_dims:
75
- raise ValueError(f"Invalid parameter value: agg_axis {axis} must be a data dimension in {data_dims}.")
76
- elif aggregator and data_dims:
77
- # Set agg_axis to non-plotted dim axes
78
- agg_axis = data_dims.copy()
79
- agg_axis.remove(x_axis)
80
- agg_axis.remove(y_axis)
81
- if 'iter_axis' in inputs and inputs['iter_axis']:
82
- agg_axis.remove(inputs['iter_axis'])
83
- inputs['agg_axis'] = agg_axis
84
-
85
- def _check_color_inputs(inputs):
86
- if inputs['color_mode']:
87
- color_mode = inputs['color_mode'].lower()
88
- valid_color_modes = ['auto', 'manual']
89
- if color_mode not in valid_color_modes:
90
- raise ValueError(f"Invalid parameter value: color_mode {color_mode} must be None or one of {valid_color_modes}.")
91
- inputs['color_mode'] = color_mode
92
-
93
- if inputs['color_range']:
94
- if not (isinstance(inputs['color_range'], tuple) and len(inputs['color_range']) == 2):
95
- raise ValueError("Invalid parameter type: color_range must be None or a tuple of (min, max).")
96
-
97
- def _check_other_inputs(inputs):
98
- if inputs['iter_range']:
99
- if not (isinstance(inputs['iter_range'], tuple) and len(inputs['iter_range']) == 2):
100
- raise ValueError("Invalid parameter type: iter_range must be None or a tuple of (start, end).")
101
-
102
- if inputs['subplots']:
103
- if not (isinstance(inputs['subplots'], tuple) and len(inputs['subplots']) == 2):
104
- raise ValueError("Invalid parameter type: subplots must be None or a tuple of (rows, columns).")
105
-
106
- if inputs['title'] and not isinstance(inputs['title'], str):
107
- raise TypeError("Invalid parameter type: title must be None or a string.")
5
+ from vidavis.plot.ms_plot._check_raster_inputs import check_inputs
6
+
7
+ class RasterPlotInputs:
8
+ '''
9
+ Class to set inputs for raster plots from MsRaster functions or GUI.
10
+ '''
11
+
12
+ def __init__(self):
13
+ self._plot_inputs = {}
14
+
15
+ def get_inputs(self):
16
+ ''' Getter for stored plot inputs '''
17
+ return self._plot_inputs
18
+
19
+ def get_input(self, name):
20
+ ''' Getter for stored plot input by name '''
21
+ try:
22
+ return self._plot_inputs[name]
23
+ except KeyError:
24
+ return None
25
+
26
+ def set_input(self, name, value):
27
+ ''' Set plot input by name and value '''
28
+ self._plot_inputs[name] = value
29
+ if name == 'selection' and 'data_group_name' in value:
30
+ self._plot_inputs['data_group'] = value['data_group_name']
31
+
32
+ def set_selection(self, selection):
33
+ ''' Add selection dict to existing selection in plot inputs '''
34
+ if 'selection' not in self._plot_inputs:
35
+ self._plot_inputs['selection'] = {}
36
+ self._plot_inputs['selection'] |= selection
37
+ if 'data_group_name' in selection:
38
+ self._plot_inputs['data_group'] = selection['data_group_name']
39
+
40
+ def get_selection(self, key):
41
+ ''' Return value for selection key '''
42
+ try:
43
+ return self.get_input('selection')[key]
44
+ except (TypeError, KeyError):
45
+ # TypeError: get_input returned None for 'selection'
46
+ # KeyError: key not in selection
47
+ return None
48
+
49
+ def set_inputs(self, plot_inputs):
50
+ ''' Setter for storing plot inputs from MsRaster.plot() '''
51
+ check_inputs(plot_inputs)
52
+ for key, val in plot_inputs.items():
53
+ self._plot_inputs[key] = val
54
+
55
+ def remove_input(self, name):
56
+ ''' Remove plot input with name, if it exists '''
57
+ try:
58
+ del self._plot_inputs[name]
59
+ except KeyError:
60
+ pass
61
+
62
+ def check_inputs(self):
63
+ ''' Check input values are valid, adjust for data dims '''
64
+ check_inputs(self._plot_inputs)
65
+
66
+ def is_layout(self):
67
+ ''' Determine if plot is a layout using plot inputs '''
68
+ # Check if subplots is a layout
69
+ subplots = self.get_input('subplots')
70
+ if subplots is None or subplots == (1, 1):
71
+ return False
72
+
73
+ # Subplots is a layout, check if multi plot
74
+ if not self.get_input('clear_plots'):
75
+ return True
76
+
77
+ # Check if iteration set and iter_range more than one plot
78
+ iter_length = 0
79
+ if self.get_input('iter_axis') is not None:
80
+ iter_range = self.get_input('iter_range')
81
+ if iter_range is None or iter_range[1] == -1:
82
+ iter_range = self.get_input('auto_iter_range')
83
+ iter_length = len(range(iter_range[0], iter_range[1] + 1))
84
+ return iter_length > 1
85
+
86
+ #--------------
87
+ # GUI CALLBACKS
88
+ #--------------
89
+
90
+ def set_color_inputs(self, color_mode, color_range):
91
+ ''' Set style params from gui '''
92
+ color_mode = color_mode.split()[0]
93
+ color_mode = None if color_mode == 'No' else color_mode
94
+ self.set_input('color_mode', color_mode)
95
+ self.set_input('color_range', color_range)
96
+
97
+ def set_axis_inputs(self, x_axis, y_axis, vis_axis):
98
+ ''' Set plot axis inputs from gui '''
99
+ self.set_input('x_axis', x_axis)
100
+ self.set_input('y_axis', y_axis)
101
+ self.set_input('vis_axis', vis_axis)
102
+
103
+ def set_aggregation_inputs(self, aggregator, agg_axes):
104
+ ''' Set aggregation inputs from gui '''
105
+ aggregator = None if aggregator== 'None' else aggregator
106
+ self.set_input('aggregator', aggregator)
107
+ self.set_input('agg_axis', agg_axes) # ignored if aggregator not set
108
+
109
+ def set_iteration_inputs(self, iter_axis, iter_range, subplot_rows, subplot_columns):
110
+ ''' Set iteration inputs from gui '''
111
+ iter_axis = None if iter_axis == 'None' else iter_axis
112
+ self.set_input('iter_axis', iter_axis)
113
+ self.set_input('iter_range', iter_range)
114
+ self.set_input('subplots', (subplot_rows, subplot_columns))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vidavis
3
- Version: 0.0.12
3
+ Version: 0.0.14
4
4
  Summary: Radio astronomy visibility data visualization
5
5
  License: LGPL
6
6
  Author-email: Darrell Schiebel <darrell@schiebel.us>,Pam Harris <pharris@nrao.edu>
@@ -1,7 +1,7 @@
1
1
  vidavis/LICENSE.rst,sha256=qzGpkvhDzf_MgF1PIn6rCmYPrcEhkfrBUchosLJj-U4,26371
2
2
  vidavis/__init__.py,sha256=FVM92yTXUplR7tVHiGao0Y3Hd80pRTrwVIYDLjzICws,1709
3
3
  vidavis/apps/__init__.py,sha256=ZQ5v1VFtjn3ztmuOHLOk5WbC1uLNIgL9rbHQ4v0zJwY,87
4
- vidavis/apps/_ms_raster.py,sha256=lbq9GRGeyIV1a_kyS8nU0XfadMwQbOC7JZj6Zcp2uo8,47260
4
+ vidavis/apps/_ms_raster.py,sha256=MtW55gRm9EYKR-E86-YrfSnNiYg-xa6WJNar-0-Rsac,43139
5
5
  vidavis/bokeh/__init__.py,sha256=gdPPxBCe0enCSjvPFxkgMlhpVnAMFXKcw9GN28tVdXM,95
6
6
  vidavis/bokeh/_palette.py,sha256=gzfJHuUgqxd8hJpZe-gQPFTCPq9f5I8uLEkHAK5FNDM,2480
7
7
  vidavis/data/__init__.py,sha256=-RDRe0PYK6vPlhdRV2Dy1vGbnDGoXWDATmfxaR-gXcE,48
@@ -18,21 +18,23 @@ vidavis/data/measurement_set/processing_set/_ps_stats.py,sha256=4uLImKCANXLUM8jO
18
18
  vidavis/data/measurement_set/processing_set/_xds_data.py,sha256=qLO2VkLINkSAQ7CGRFmpWQYpHrP4XoJJkwA4pp9DO8M,5253
19
19
  vidavis/plot/__init__.py,sha256=thxe5vAGdpEiqoKPHLJoWUqKMVrUVx0ajpsGf5pVP98,95
20
20
  vidavis/plot/ms_plot/__init__.py,sha256=wY0_7gY9M6K1D6tKQsr89L_uSs3seJlD-uicx7dx5Mo,74
21
- vidavis/plot/ms_plot/_locate_points.py,sha256=TsfklqCB-rab8VKsnSwnFy-hh7JSY7Wp7Lo498ad10M,6161
22
- vidavis/plot/ms_plot/_ms_plot.py,sha256=AZe4WbW5QCjX5hIir1W4H8Nd69NvxBQUiJhIHPCOTGE,12764
21
+ vidavis/plot/ms_plot/_check_raster_inputs.py,sha256=a7u5wlDKTxWYW36-Xp3xd4c756SbYURdFkGHbUaX440,4786
22
+ vidavis/plot/ms_plot/_locate_points.py,sha256=f2sOeq1Ba6SR7uk7pX2vS2TLPsQsWZti2VJkOcFx6Gw,10899
23
+ vidavis/plot/ms_plot/_ms_plot.py,sha256=B0_81JtBD9k7M8frwlgoJNH6vZzW17aGmytPjD_xQqw,18706
23
24
  vidavis/plot/ms_plot/_ms_plot_constants.py,sha256=cX_TQhKJ3hJzPuRYmuRJxue1sjq82yl_ZN2_w6TshmI,930
24
25
  vidavis/plot/ms_plot/_ms_plot_selectors.py,sha256=BZQwARvMPdk78n6Rh2tOaSc8GenZBrxHZb14oFD9gJM,10785
26
+ vidavis/plot/ms_plot/_plot_inputs.py,sha256=pZL63n9FHSoo9cntf7lppQj44nkpiwnCz6VH-9Oh6ho,671
25
27
  vidavis/plot/ms_plot/_raster_plot.py,sha256=lNa9i_eJ8F8Fc2zcHLRcaxKKOELk3x_QmXT__T76pg8,10999
26
- vidavis/plot/ms_plot/_raster_plot_gui.py,sha256=wpVFnnX9jL4G4b9OhCxgGpqrqUq4cvDLy4IIzYRMR18,3738
27
- vidavis/plot/ms_plot/_raster_plot_inputs.py,sha256=vPjZPDuB26ENxwv4z7dUa_c5TqByXejScY6hqEnLFLU,4768
28
+ vidavis/plot/ms_plot/_raster_plot_gui.py,sha256=Kb0BLmkwtYHCqlVaSipbTTStst8RYggqwf1Wf5v8F4Q,4261
29
+ vidavis/plot/ms_plot/_raster_plot_inputs.py,sha256=AMIvEz2b4QLH03P6EJXOAnkQ-v2uNKEukdaoA6g070Y,4166
28
30
  vidavis/plot/ms_plot/_time_ticks.py,sha256=j-DcPh7RfGE8iX2bPjLQDQPIbiAbmjiEWQnKmdMWA3I,1773
29
31
  vidavis/plot/ms_plot/_xds_plot_axes.py,sha256=EeWvAbiKV33nEWdI8V3M0uwLTnycq4bFYBOyVWkxCu0,4429
30
32
  vidavis/toolbox/__init__.py,sha256=jqFa-eziVz_frNnXxwjJFK36qNpz1H38s-VlpBcq-R8,1402
31
33
  vidavis/toolbox/_app_context.py,sha256=H7gtF8RrAH46FqDcMobv3KM1Osbnapgu6aTG-m3VCWA,3049
32
34
  vidavis/toolbox/_logging.py,sha256=OEisrd8FM8VTNBMc7neLh9ekelf29ZILYB5pScebly0,2739
33
35
  vidavis/toolbox/_static.py,sha256=HJLMtClppgOJXWAtV6Umn5EqN80u0oZiIouQ1JsB9PM,2346
34
- vidavis/__version__.py,sha256=28LaL9J1JRdBfN4Edp_03ZUWOZCUdFtygoKFI5dYdXA,22
35
- vidavis-0.0.12.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
36
- vidavis-0.0.12.dist-info/METADATA,sha256=3ZnkBJhcC1bVNAkVvRIVxRGfvo6_wow4DWPOvFOIqVA,2238
37
- vidavis-0.0.12.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
38
- vidavis-0.0.12.dist-info/RECORD,,
36
+ vidavis/__version__.py,sha256=DT3lXVWSM0vxCDfBsBbQ4k1SOUtDSFBhl094H35FE2w,22
37
+ vidavis-0.0.14.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
38
+ vidavis-0.0.14.dist-info/METADATA,sha256=fZDo9_lUcwhVToPrllG6fE5SJj0XcyDcgbzoOvVf_zY,2238
39
+ vidavis-0.0.14.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
40
+ vidavis-0.0.14.dist-info/RECORD,,