"""Create the Selection Matrices for BPMs and Correctors."""
from functools import partial as _part
import numpy as np
from qtpy.QtCore import QSize
from qtpy.QtWidgets import QHBoxLayout, \
QSizePolicy, QWidget, QDialog, QTabWidget
from pydm.widgets.base import PyDMWidget
from siriushla.widgets import SiriusLedAlert, QLed, \
SiriusConnectionSignal as _ConnSignal, \
SelectionMatrixWidget as SelectionWidget
from siriushla.as_ap_sofb.ioc_control.base import BaseObject, BaseWidget
[docs]
class SingleSelMatrix(BaseObject, SelectionWidget, PyDMWidget):
"""Create the Selection Matrices for BPMs and Correctors."""
def __init__(self, parent, dev, device, prefix='', acc='SI', rules=None):
"""Initialize the matrix data of the specified dev."""
# initialize BaseObject
BaseObject.__init__(self, device, prefix=prefix, acc=acc)
self.dev = dev
bpm_pos = np.array(self._csorb.bpm_pos)
bpm_name = self._csorb.bpm_names
bpm_nknm = self._csorb.bpm_nicknames
self.devpos = {
'BPMX': bpm_pos,
'BPMY': bpm_pos,
'CH': self._csorb.ch_pos,
'CV': self._csorb.cv_pos}
self.devotpl = {
'BPMX': 'BPMY', 'BPMY': 'BPMX', 'CH': 'CV', 'CV': 'CH'}
self.devnames = {
'BPMX': (bpm_name, bpm_nknm),
'BPMY': (bpm_name, bpm_nknm),
'CH': (self._csorb.ch_names, self._csorb.ch_nicknames),
'CV': (self._csorb.cv_names, self._csorb.cv_nicknames)}
# initialize SelectionWidget
SelectionWidget.__init__(
self, parent=parent, title=dev + "List",
has_bothplanes=dev.lower().startswith('bpm'),
rules=rules)
# initialize PyDMWidget
init_channel = self.devpref.substitute(propty=self.dev+'EnblList-RB')
PyDMWidget.__init__(self, init_channel=init_channel)
self.pv_sp = _ConnSignal(init_channel.replace('-RB', '-SP'))
self.pv_otpl = _ConnSignal(self.devpref.substitute(
propty=self.devotpl[self.dev]+'EnblList-SP'))
# connect signals and slots
self.applyChangesClicked.connect(self.send_value)
self.applyBothPlanesClicked.connect(_part(self.send_value, other=True))
[docs]
def sizeHint(self):
"""Return the base size of the widget."""
return QSize(500, 1200)
# --- SelectionWidget specific methods ---
[docs]
def get_positions(self):
top_headers, side_headers = self.headers
positions = list()
for idx in range(len(self.devnames[self.dev][0])):
_, nicks = self.devnames[self.dev]
rsize, hsize, i = len(nicks), len(side_headers), 0
if self.dev.lower().startswith('bpm'):
i = (idx // rsize) * hsize
if self.acc == 'BO':
sec = int(nicks[idx][:2])
j = ((sec-1) % 10) + 1
j = top_headers.index('{0:02d}'.format(j))
if not (idx+1) % rsize and sec == 1:
i += hsize - 1
else:
i += (sec-1) // 10
elif self.acc == 'SI':
j = top_headers.index(nicks[idx][2:])
if not (idx+1) % rsize:
i += hsize-1
else:
i += ((idx % rsize) + 1) // len(top_headers)
else:
j = idx
positions.append((i, j))
return positions
# --- PyDMWidget specific methods ---
[docs]
def send_value(self, other=False):
if self.value is None:
return
value = self.value.copy()
for i in range(value.size):
wid = self.widgets[i]
led = wid.findChild(QLed)
if led.isSelected():
value[i] = not value[i]
led.setSelected(False)
self.pv_sp.send_value_signal[np.ndarray].emit(value)
if other:
self.pv_otpl.send_value_signal[np.ndarray].emit(value)
[docs]
def value_changed(self, new_val):
if not isinstance(new_val, np.ndarray):
return
super(SingleSelMatrix, self).value_changed(new_val)
_, side_header_wids = self.header_widgets
for i, wid in enumerate(self.widgets):
led = wid.findChild(QLed)
if i < self.value.size:
wid.setVisible(True)
led.state = not self.value[i]
else:
wid.setVisible(False)
rsize = self.value.size / len(self.widgets)
ini = int(len(side_header_wids) * rsize)
for i, head in enumerate(side_header_wids):
head.setVisible(i < ini)
self.adjustSize()
parent = self.parent()
while parent is not None:
parent.adjustSize()
if isinstance(parent, QDialog):
break
parent = parent.parent()
[docs]
def connection_changed(self, new_conn):
super(SingleSelMatrix, self).connection_changed(new_conn)
for wid in self.widgets:
led = wid.findChild(QLed)
led.setEnabled(new_conn)
[docs]
class SelectionMatrix(BaseWidget):
def __init__(self, parent, device, prefix='', acc='SI', rules=None):
super().__init__(parent, device, prefix=prefix, acc=acc)
tab = QTabWidget(self)
tab.setObjectName(self.acc.upper() + 'Tab')
hbl = QHBoxLayout(self)
hbl.addWidget(tab)
hbl.setContentsMargins(0, 0, 0, 0)
for dev in ('BPMX', 'BPMY', 'CH', 'CV'):
wid = SingleSelMatrix(
tab, dev, self.device, prefix=self.prefix, acc=self.acc,
rules=rules)
tab.addTab(wid, dev)