Skip to content
This repository has been archived by the owner on Feb 11, 2023. It is now read-only.

Feature store plots #63

Merged
merged 3 commits into from
Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*.pyc
# pycharm
.idea/
# vscode
.vscode/
# eclipse
.project
.pydevproject
Expand Down
67 changes: 33 additions & 34 deletions irrad_control/gui/tabs/monitor_tab.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from PyQt5 import QtWidgets
from collections import OrderedDict
from collections import defaultdict

# Package imports
from irrad_control.gui.widgets import plot_widgets as plots # Actual plots
Expand All @@ -24,16 +24,15 @@ def __init__(self, setup, plot_path=None, parent=None):

self.plot_path = plot_path

self.plots = OrderedDict()
self.plots = defaultdict(dict)
self._plot_wrapper_widgets = defaultdict(dict)

self._init_tabs()

def _init_tabs(self):

for server in self.setup:

self.plots[server] = OrderedDict()

# Tabs per server
self.monitor_tabs[server] = QtWidgets.QTabWidget()

Expand All @@ -47,10 +46,8 @@ def _init_tabs(self):

channels = self.setup[server]['readout']['channels']
daq_device = self.setup[server]['daq']['sem']
self.plots[server]['raw_plot'] = plots.RawDataPlot(channels=channels,
daq_device=daq_device)
monitor_widget = plots.PlotWrapperWidget(self.plots[server]['raw_plot'],
plot_path=self.plot_path)
self.plots[server]['raw_plot'] = plots.RawDataPlot(channels=channels, daq_device=daq_device)
monitor_widget = self._create_plot_wrapper(plot_name='raw_plot', server=server)

elif monitor == 'Beam':

Expand All @@ -59,29 +56,23 @@ def _init_tabs(self):
if 'blm' in self.setup[server]['readout']['types']:
channels += ('beam_loss', )

self.plots[server]['current_plot'] = plots.BeamCurrentPlot(channels=channels,
daq_device=daq_device)
self.plots[server]['pos_plot'] = plots.BeamPositionPlot(self.setup[server],
daq_device=daq_device)
self.plots[server]['current_plot'] = plots.BeamCurrentPlot(channels=channels, daq_device=daq_device)
self.plots[server]['pos_plot'] = plots.BeamPositionPlot(self.setup[server], daq_device=daq_device)

beam_current_wrapper = plots.PlotWrapperWidget(self.plots[server]['current_plot'],
plot_path=self.plot_path)
beam_pos_wrapper = plots.PlotWrapperWidget(self.plots[server]['pos_plot'],
plot_path=self.plot_path)
beam_current_wrapper = self._create_plot_wrapper(plot_name='current_plot', server=server)
beam_pos_wrapper = self._create_plot_wrapper(plot_name='pos_plot', server=server)

monitor_widget = plots.MultiPlotWidget(plots=[beam_current_wrapper, beam_pos_wrapper])

elif monitor == 'SEM':
plot_wrappers = []
if all(x in self.setup[server]['readout']['types'] for x in ('sem_right', 'sem_left')):
self.plots[server]['sem_h_plot'] = plots.SEYFractionHist(rel_sig='sey_horizontal', norm_sig='SEM_{}'.format(u'\u03A3'))
plot_wrappers.append(plots.PlotWrapperWidget(self.plots[server]['sem_h_plot'],
plot_path=self.plot_path))
plot_wrappers.append(self._create_plot_wrapper(plot_name='sem_h_plot', server=server))

if all(x in self.setup[server]['readout']['types'] for x in ('sem_up', 'sem_down')):
self.plots[server]['sem_v_plot'] = plots.SEYFractionHist(rel_sig='sey_vertical', norm_sig='SEM_{}'.format(u'\u03A3'))
plot_wrappers.append(plots.PlotWrapperWidget(self.plots[server]['sem_v_plot'],
plot_path=self.plot_path))
plot_wrappers.append(self._create_plot_wrapper(plot_name='sem_v_plot', server=server))
if len(plot_wrappers) == 1:
monitor_widget = plot_wrappers[0]
elif plot_wrappers:
Expand All @@ -94,17 +85,13 @@ def _init_tabs(self):

if 'ntc' in self.setup[server]['readout']:
channels = list(self.setup[server]['readout']['ntc'].values())
self.plots[server]['temp_daq_board_plot'] = plots.TemperatureDataPlot(channels=channels,
daq_device='DAQBoard')
plot_wrappers.append(plots.PlotWrapperWidget(self.plots[server]['temp_daq_board_plot'],
plot_path=self.plot_path))
self.plots[server]['temp_daq_board_plot'] = plots.TemperatureDataPlot(channels=channels, daq_device='DAQBoard')
plot_wrappers.append(self._create_plot_wrapper(plot_name='temp_daq_board_plot', server=server))

if 'ArduinoTempSens' in self.setup[server]['devices']:
channels = list(self.setup[server]['devices']['ArduinoTempSens']['setup'].values())
self.plots[server]['temp_arduino_plot'] = plots.TemperatureDataPlot(channels=channels,
daq_device='ArduinoTempSens')
plot_wrappers.append(plots.PlotWrapperWidget(self.plots[server]['temp_arduino_plot'],
plot_path=self.plot_path))
self.plots[server]['temp_arduino_plot'] = plots.TemperatureDataPlot(channels=channels, daq_device='ArduinoTempSens')
plot_wrappers.append(self._create_plot_wrapper(plot_name='temp_arduino_plot', server=server))

if len(plot_wrappers) == 1:
monitor_widget = plot_wrappers[0]
Expand All @@ -116,11 +103,23 @@ def _init_tabs(self):

self.daq_tabs.addTab(self.monitor_tabs[server], self.setup[server]['name'])

def add_fluence_hist(self, n_rows, kappa):
def _create_plot_wrapper(self, plot_name, server):

for server in self.setup:
file_name = f"{type(self.plots[server][plot_name]).__name__}_{self.setup[server]['name']}"

self._plot_wrapper_widgets[server][plot_name] = plots.PlotWrapperWidget(plot=self.plots[server][plot_name],
plot_path=self.plot_path,
file_name=file_name)

return self._plot_wrapper_widgets[server][plot_name]


def add_fluence_hist(self, server, n_rows, kappa):
self.plots[server]['fluence_plot'] = plots.FluenceHist(n_rows=n_rows, kappa=kappa)
monitor_widget = self._create_plot_wrapper(plot_name='fluence_plot', server=server)
self.monitor_tabs[server].addTab(monitor_widget, 'Fluence')

self.plots[server]['fluence_plot'] = plots.FluenceHist(n_rows=n_rows, kappa=kappa)
monitor_widget = plots.PlotWrapperWidget(self.plots[server]['fluence_plot'],
plot_path=self.plot_path)
self.monitor_tabs[server].addTab(monitor_widget, 'Fluence')
def save_plots(self):
for _, plot_wrappers in self._plot_wrapper_widgets.items():
for _, wrapper in plot_wrappers.items():
wrapper.save_plot()
17 changes: 9 additions & 8 deletions irrad_control/gui/widgets/plot_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class PlotWrapperWidget(QtWidgets.QWidget):
"""Widget that wraps PlotWidgets and implements some additional features which allow to control the PlotWidgets content.
Also adds button to show the respective PlotWidget in a QMainWindow"""

def __init__(self, plot=None, plot_path=None, parent=None):
def __init__(self, plot=None, plot_path=None, file_name=None, parent=None):
super(PlotWrapperWidget, self).__init__(parent=parent)

# Set a reasonable minimum size
Expand All @@ -63,8 +63,10 @@ def __init__(self, plot=None, plot_path=None, parent=None):
self.setLayout(QtWidgets.QVBoxLayout())
self.plot_options = GridContainer(name='Plot options' if not hasattr(self.pw, 'name') else '{} options'.format(self.pw.name))

# Output path for screenshots
self.plot_path = plot_path
# Output path and file_name for screenshots
self.plot_path = os.getcwd() if plot_path is None else plot_path
self.file_name = type(plot).__name__ if file_name is None else file_name
self.file_format = 'png'

# Setup widget if class instance was initialized with plot
if self.pw is not None:
Expand Down Expand Up @@ -198,13 +200,12 @@ def save_plot(self):

# Generate filename
number = 0
out_file = lambda pw, n: os.path.join(os.getcwd() if self.plot_path is None else self.plot_path,
'{}_{}.png'.format(type(pw).__name__, n))
while os.path.isfile(out_file(self.pw, number)):
out_file = lambda n: os.path.join(self.plot_path, f'{self.file_name}_{n}.{self.file_format}')
while os.path.isfile(out_file(number)):
number += 1

exporter.export(out_file(self.pw, number))
logging.info("Saved plot to {}".format(out_file(self.pw, number)))
exporter.export(out_file(number))
logging.info(f"Saved plot to {out_file(number)}")


class MultiPlotWidget(QtWidgets.QScrollArea):
Expand Down
11 changes: 9 additions & 2 deletions irrad_control/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,9 @@ def handle_reply(self, reply_dict):

elif reply == 'prepare':
self.control_tab.update_scan_parameters(**reply_data)
self.monitor_tab.add_fluence_hist(**{'kappa': self.setup['server'][hostname]['daq']['kappa'],
'n_rows': reply_data['n_rows']})
self.monitor_tab.add_fluence_hist(kappa=self.setup['server'][hostname]['daq']['kappa'],
n_rows=reply_data['n_rows'],
server=hostname)
self.send_cmd(hostname=hostname, target='stage', cmd='scan')
self.control_tab.scan_status('started')

Expand Down Expand Up @@ -755,6 +756,12 @@ def _clean_up(self):
self.stop_recv_log.set()
self.close_timer.stop()

# Store all plots on close; AttributeError when app was not launched fully
try:
self.monitor_tab.save_plots()
except AttributeError:
pass

# Wait 1 second for all threads to finish
self.threadpool.waitForDone(1000)

Expand Down