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

Commit

Permalink
Merge pull request #63 from SiLab-Bonn/feature_store_plots
Browse files Browse the repository at this point in the history
Feature store plots
  • Loading branch information
leloup314 authored Dec 15, 2021
2 parents 22b759c + 638397a commit 00d7084
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 44 deletions.
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

0 comments on commit 00d7084

Please sign in to comment.