Source code for siriushla.as_ti_control.monitor

"""."""

from qtpy.QtCore import Qt, QPoint
from qtpy.QtGui import QPainter
from qtpy.QtWidgets import QLabel, QWidget, QGridLayout, QGroupBox, \
    QHBoxLayout, QApplication, QVBoxLayout
import qtawesome as qta

from siriuspy.namesys import SiriusPVName as PVName
from siriuspy.search import LLTimeSearch, HLTimeSearch

from ..widgets import SiriusLedAlert, PyDMLedMultiChannel
from ..util import get_appropriate_color, connect_window
from ..widgets.windows import create_window_from_widget

from .low_level_devices import EVG, FOUT, AFC, EVR, EVE
from .hl_trigger import HLTriggerDetailed


[docs] class LLButton(QWidget): def __init__(self, device, link, prefix='', parent=None): super().__init__(parent) self.device = PVName(device) self.link = link self.prefix = prefix self._dic = { 'EVG': EVG, 'EVR': EVR, 'EVE': EVE, 'AMCFPGAEVR': AFC, 'Fout': FOUT} self.setupui()
[docs] def setupui(self): if self.device.dev == 'Fout': name = self.device.dev + ( '-' + self.device.idx if self.device.idx else '') elif self.device.dev == 'AMCFPGAEVR': name = 'AMC-' + ( 'TL' if 'TL' in self.device.sub else self.device.sub[:2]) elif self.device.sec == 'LA': if 'RaCtrl' in self.device.sub: name = 'PS-TL' elif 'BIH01' in self.device.sub: name = 'LI-Diag' else: name = 'LI-Glob' elif self.device.sec == 'PA': name = 'PS-' + ('BO' if self.device.idx == '1' else 'SI') elif self.device.sec == 'RA': name = 'RF-' + ('BO' if 'BO' in self.device.sub else 'SI') elif 'RaInj' in self.device.sub: name = 'PU' elif 'BbB' in self.device.sub: name = 'DI-BbB' elif 'Diag' in self.device.sub: name = 'DI-' + ( 'DCCT' if self.device.sub[:2] == '14' else 'Tune' if self.device.sub[:2] == '18' else 'TL' if self.device.sub[:2] == '20' else '?') elif self.device.sec == 'BA': name = self.device.sec + '-' + self.device.sub else: name = self.device.dev clss = self._dic[self.device.dev] props = ['DevEnbl', 'Network', 'LinkStatus', 'IntlkStatus'] suffs = ['-Sts', '-Mon', '-Mon', '-Mon'] chng = [True, True, True, False] if self.device.dev == 'EVG': props[2] = 'RFStatus' props[3] = 'ACStatus' chng[3] = True elif self.device.dev == 'AMCFPGAEVR': props[1] = 'RefClkLocked' props = props[:-1] elif self.device.dev == 'Fout': props = props[:-1] channels2values = dict() for i, prop in enumerate(props): pvn = self.device.substitute(prefix=self.prefix, propty=prop+suffs[i]) channels2values[pvn] = 1 if chng[i] else 0 led = PyDMLedMultiChannel( parent=self, channels2values=channels2values) led.setToolTip(self.device) icon = qta.icon('mdi.timer', color=get_appropriate_color('AS')) Window = create_window_from_widget( clss, title=self.device.device_name, icon=icon) connect_window( led, Window, None, signal=led.clicked, device=self.device, prefix=self.prefix) lay = QVBoxLayout(self) lay.setContentsMargins(0, 2, 0, 2) lay.setSpacing(4) lay.addWidget(QLabel(name, self, alignment=Qt.AlignCenter)) lay.addWidget(led, alignment=Qt.AlignCenter)
[docs] class HLButton(QWidget): def __init__(self, trigger, prefix='', parent=None): super().__init__(parent=parent) self.trigger = trigger self.prefix = prefix hl = QHBoxLayout() self.setLayout(hl) self.layout().setContentsMargins(0, 0, 0, 0) led = SiriusLedAlert(self) led.setToolTip(trigger) led.channel = trigger.substitute( prefix=self.prefix, propty='Status-Mon') self.layout().addWidget(led) icon = qta.icon('mdi.timer', color=get_appropriate_color(trigger.sec)) Window = create_window_from_widget( HLTriggerDetailed, title=trigger, icon=icon) led.clicked.connect(lambda: QApplication.instance().open_window( Window, parent=None, device=trigger, prefix=prefix))
[docs] class MonitorHL(QGroupBox): def __init__(self, parent=None, prefix=''): super().__init__('High Level Monitor', parent=parent) self.prefix = prefix self._setupui() self.setObjectName('ASApp') def _setupui(self): lay = QGridLayout() self.setLayout(lay) hltrigs = HLTimeSearch.get_hl_triggers() secs = sorted(set(map(lambda x: x.sec, hltrigs))) secs = {sec: [] for sec in secs} nrcols = 10 for trig in hltrigs: secs[trig.sec].append(trig) for sec, trigs in secs.items(): lab = QLabel(sec) lab.setStyleSheet('font-weight: bold;') lay.addWidget(lab, lay.rowCount(), 0, 1, nrcols) row = lay.rowCount() for i, trig in enumerate(sorted(trigs)): if i and not i % nrcols: row = lay.rowCount() but = HLButton(trig, self.prefix, self) lay.addWidget(but, row, i % nrcols)
[docs] class MonitorLL(QGroupBox): def __init__(self, parent=None, prefix=''): super().__init__('Low Level Monitor', parent=parent) self.prefix = prefix self._setupui() self.setObjectName('ASApp') def _setupui(self): evg = PVName(LLTimeSearch.get_evg_name()) g1 = LLButton(evg, '', self.prefix, self) self.g1 = g1 fouts = LLTimeSearch.get_evg2fout_mapping() fouts = [(out, down) for out, down in fouts.items()] g2 = self.setupdown(fouts) self.g2 = g2 g3 = list() trgsrcs = LLTimeSearch.get_fout2trigsrc_mapping() for _, down in fouts: downs = trgsrcs[down.device_name] downs = sorted([(ou, dwn) for ou, dwn in downs.items()]) g3.append(self.setupdown(downs)) lay = QGridLayout(self) lay.setHorizontalSpacing(12) lay.setVerticalSpacing(20) align = Qt.AlignHCenter | Qt.AlignTop lay.addWidget(g1, 0, 0, 1, len(g3), align) for i, g in enumerate(g2): lay.addWidget(g, 1, i, align) self.g3 = list() for i, gs in enumerate(g3): for j, g in enumerate(gs): if not j: self.g3.append(g) lay.addWidget(g, j+2, i)
[docs] def setupdown(self, down): return [LLButton(pre, lnk, self.prefix, self) for lnk, pre in down]
[docs] def paintEvent(self, event): super().paintEvent(event) sz = self.g1.size() p1 = self.g1.pos() + QPoint(sz.width()//2, sz.height()) for i, g2 in enumerate(self.g2): sz = g2.size() p2 = g2.pos() + QPoint(sz.width()//2, 0) self.drawarrow(p1, p2) p2 += QPoint(0, sz.height()) g3 = self.g3[i] p3 = g3.pos() + QPoint(g3.size().width()//2, 0) self.drawarrow(p2, p3)
[docs] def drawarrow(self, p1, p2): self.drawline(p1, p2, 0) self.drawline(p2, p1, 10, True) self.drawline(p2, p1, -10, True)
[docs] def drawline(self, p1, p2, angle, tip=False): painter = QPainter() painter.begin(self) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(Qt.blue) pen = painter.pen() pen.setWidth(2) painter.setPen(pen) painter.setBrush(Qt.blue) painter.translate(p1) painter.rotate(angle) pt = (p2-p1) if tip: pt /= (pt.x()**2 + pt.y()**2)**0.5 / 10 # painter.scale(scale, scale) # painter.drawLine(QPoint(0, 0), (p2-p1)*scale) painter.drawLine(QPoint(0, 0), pt) return painter
[docs] class MonitorWindow(QWidget): def __init__(self, parent=None, prefix=''): super().__init__(parent=parent) self.prefix = prefix self._setupui() self.setObjectName('ASApp') def _setupui(self): self.title = QLabel( '<h2>Timing Monitor</h2>', alignment=Qt.AlignCenter) vl = QVBoxLayout(self) vl.addWidget(self.title) vl.addWidget(MonitorLL(self, prefix=self.prefix)) vl.addWidget(MonitorHL(self, prefix=self.prefix)) self.setStyleSheet(""" QLed { min-height: 1.1em; max-height: 1.1em; min-width: 1.1em; max-width: 1.1em;} """)