예제 #1
0
파일: status.py 프로젝트: lnls-sirius/hla
    def setupui(self):
        vbl = QVBoxLayout(self)

        tip = 'Configure ' + ('Acquisition' if self.is_orb else 'Correctors')
        pv = 'TrigAcqConfig-Cmd' if self.is_orb else 'CorrConfig-Cmd'
        conf = PyDMPushButton(self,
                              init_channel=self.devpref.substitute(propty=pv),
                              pressValue=1)
        conf.setToolTip(tip)
        conf.setIcon(qta.icon('fa5s.sync'))
        conf.setObjectName('conf')
        conf.setStyleSheet(
            '#conf{min-width:25px; max-width:25px; icon-size:20px;}')
        vbl.addWidget(conf)

        pv = 'Orb' if self.is_orb else 'Corr'
        pdm_led = SiriusLedAlert(
            self, self.devpref.substitute(propty=pv + 'Status-Mon'))

        hbl = QHBoxLayout()
        hbl.setSpacing(9)
        hbl.addWidget(pdm_led)
        hbl.addWidget(QLabel('Global Status', self))
        hbl.addStretch()
        hbl.addWidget(conf)
        vbl.addItem(hbl)

        grpbx = self.creategroupbox()
        vbl.addWidget(grpbx)
예제 #2
0
    def _get_multturn_acq_grpbx(self):
        grp_bx = QWidget(self)
        fbl = QFormLayout(grp_bx)
        lbl = QLabel('Downsampling', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnDownSample')
        fbl.addRow(lbl, wid)

        lbl = QLabel('Index', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnIdx')
        fbl.addRow(lbl, wid)

        lbl = QLabel('Index Time', grp_bx, alignment=Qt.AlignCenter)
        wid = QWidget(grp_bx)
        pdm_lbl = SiriusLabel(
            wid, self.devpref.substitute(propty='MTurnIdxTime-Mon'))
        pdm_lbl.showUnits = True
        pdm_lbl.setAlignment(Qt.AlignCenter)
        conf = PyDMPushButton(
            wid,
            pressValue=1,
            init_channel=self.devpref.substitute(propty='MTurnAcquire-Cmd'))
        conf.setToolTip('Update MTurn PVs')
        conf.setIcon(qta.icon('fa5s.sync'))
        conf.setObjectName('conf')
        conf.setStyleSheet(
            '#conf{min-width:25px; max-width:25px; icon-size:20px;}')
        hbl = QHBoxLayout(wid)
        hbl.addWidget(pdm_lbl)
        hbl.addWidget(conf)
        fbl.addRow(lbl, wid)

        lbl = QLabel('TbT Sync', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_butled(grp_bx, 'MTurnSyncTim')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        lbl = QLabel('TbT Mask', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_butled(grp_bx, 'MTurnUseMask')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        lbl = QLabel('Mask Begin', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnMaskSplBeg')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        lbl = QLabel('Mask End', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnMaskSplEnd')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])
        return grp_bx
예제 #3
0
class ModEmerStopDialog(SiriusDialog):
    """Modulator Emergency Stop Window."""
    def __init__(self, parent=None, device='', prefix=VACA_PREFIX):
        """Init."""
        super().__init__(parent)
        self.setObjectName('LIApp')
        self._prefix = prefix
        self._device = _PVName(device)
        self._mod_prefix = self._device.substitute(prefix=prefix)

        self.setWindowTitle(self._device.dev + ' ' + self._device.idx +
                            ' - Emergency Stop')
        self._setupUi()

    def _setupUi(self):
        self._lb_desc = QLabel('<h3>Are you sure to Poweroff ' +
                               self._device.dev + ' ' + self._device.idx +
                               '?</h3>')

        self._pb_yes = PyDMPushButton(self,
                                      label='YES',
                                      pressValue=1,
                                      init_channel=self._mod_prefix +
                                      ':EMER_STOP')
        self._pb_yes.setObjectName('yes')
        self._pb_yes.setStyleSheet('#yes{background-color:red;}')

        self._pb_exit = QPushButton('EXIT', self)
        self._pb_exit.clicked.connect(self.close)

        lay = QGridLayout(self)
        lay.setHorizontalSpacing(20)
        lay.setVerticalSpacing(20)
        lay.addWidget(self._lb_desc, 0, 0, 1, 2)
        lay.addWidget(self._pb_yes, 1, 0, alignment=Qt.AlignCenter)
        lay.addWidget(self._pb_exit, 1, 1, alignment=Qt.AlignCenter)
예제 #4
0
class APUControlWindow(SiriusMainWindow):
    """APU Control Window."""
    def __init__(self, parent=None, prefix=_vaca_prefix, device=''):
        """Init."""
        super().__init__(parent)
        self._prefix = prefix
        self._device = _PVName(device)
        self._beamline = IDSearch.conv_idname_2_beamline(self._device)
        self.dev_pref = self._device.substitute(prefix=prefix)
        self.setWindowTitle(device + ' Control Window - ' + self._beamline)
        self.setObjectName('IDApp')
        self.setWindowIcon(get_id_icon())
        self._setupUi()

    def _setupUi(self):
        self._label_title = QLabel('<h3>' + self._device + ' Control - ' +
                                   self._beamline + '</h3 >',
                                   self,
                                   alignment=Qt.AlignCenter)
        self._label_title.setStyleSheet('max-height:1.29em;')

        self.wid_mainControls = self._mainControlsWidget()
        self.wid_ctrlMode = self._ctrlModeWidget()
        self.wid_beamLinesCtrl = self._beamLinesCtrlWidget()
        self.wid_auxCommands = self._auxCommandsWidget()
        self.wid_status = self._statusWidget()

        cw = QWidget()
        self.setCentralWidget(cw)
        lay = QGridLayout(cw)
        lay.addWidget(self._label_title, 0, 0, 1, 3)
        lay.addWidget(self.wid_mainControls, 1, 0, 2, 1)
        lay.addWidget(self.wid_ctrlMode, 1, 1)
        lay.addWidget(self.wid_beamLinesCtrl, 2, 1)
        lay.addWidget(self.wid_auxCommands, 3, 0)
        lay.addWidget(self.wid_status, 3, 1)
        lay.setRowStretch(0, 1)
        lay.setRowStretch(1, 1)
        lay.setRowStretch(2, 2)
        lay.setRowStretch(3, 3)

    def _mainControlsWidget(self):
        self._ld_phs = QLabel('Phase [mm]', self)
        self._sb_phs = PyDMSpinbox(self,
                                   self.dev_pref.substitute(propty='Phase-SP'))
        self._sb_phs.showStepExponent = False
        self._lb_phs = PyDMLabel(self,
                                 self.dev_pref.substitute(propty='Phase-Mon'))

        self._ld_kx = QLabel('Kx', self)
        self._sb_kx = PyDMSpinbox(self,
                                  self.dev_pref.substitute(propty='Kx-SP'))
        self._sb_kx.showStepExponent = False
        self._lb_kx = PyDMLabel(self,
                                self.dev_pref.substitute(propty='Kx-Mon'))

        self._ld_phsspd = QLabel('Phase Speed\n[mm/s]', self)
        self._sb_phsspd = PyDMSpinbox(
            self, self.dev_pref.substitute(propty='PhaseSpeed-SP'))
        self._sb_phsspd.showStepExponent = False
        self._lb_phsspd = PyDMLabel(
            self, self.dev_pref.substitute(propty='PhaseSpeed-Mon'))

        self._ld_ismov = QLabel('Motion', self)
        self._pb_start = PyDMPushButton(self,
                                        label='',
                                        icon=qta.icon('fa5s.play'))
        self._pb_start.setToolTip(
            'Start automatic motion towards previously entered setpoint.')
        self._pb_start.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_start.pressValue = 3  # Start
        self._pb_start.setObjectName('Start')
        self._pb_start.setStyleSheet(
            '#Start{min-width:30px; max-width:30px; icon-size:25px;}')
        self._pb_stop = PyDMPushButton(self,
                                       label='',
                                       icon=qta.icon('fa5s.stop'))
        self._pb_stop.setToolTip('Stop all motion, lock all brakes.')
        self._pb_stop.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_stop.pressValue = 1  # Stop
        self._pb_stop.setObjectName('Stop')
        self._pb_stop.setStyleSheet(
            '#Stop{min-width:30px; max-width:30px; icon-size:25px;}')
        self._led_ismov = SiriusLedState(self, self.dev_pref + ':Moving-Mon')
        self._led_motenbl = SiriusLedState(
            self, self.dev_pref.substitute(propty='MotorsEnbld-Mon'))
        hbox_motion = QHBoxLayout()
        hbox_motion.setSpacing(15)
        hbox_motion.addWidget(self._pb_start)
        hbox_motion.addWidget(self._pb_stop)
        hbox_motion.addWidget(self._led_ismov)
        hbox_motion.addWidget(self._led_motenbl)

        gbox_main = QGroupBox('Main Controls', self)
        lay_main = QGridLayout(gbox_main)
        lay_main.addWidget(self._ld_phs, 0, 0)
        lay_main.addWidget(self._sb_phs, 0, 1)
        lay_main.addWidget(self._lb_phs, 0, 2)
        lay_main.addWidget(self._ld_kx, 1, 0)
        lay_main.addWidget(self._sb_kx, 1, 1)
        lay_main.addWidget(self._lb_kx, 1, 2)
        lay_main.addWidget(self._ld_phsspd, 2, 0)
        lay_main.addWidget(self._sb_phsspd, 2, 1)
        lay_main.addWidget(self._lb_phsspd, 2, 2)
        lay_main.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Fixed), 3,
                         0)
        lay_main.addWidget(self._ld_ismov, 4, 0)
        lay_main.addLayout(hbox_motion, 4, 1, 1, 2)
        return gbox_main

    def _statusWidget(self):
        self._ld_alarm = QLabel('Alarms', self, alignment=Qt.AlignCenter)
        self._led_alarm = SiriusLedAlert(
            self, self.dev_pref.substitute(propty='Alarm-Mon'))
        self._pb_alarmdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '',
                                           self)
        self._pb_alarmdetail.setObjectName('dtl')
        self._pb_alarmdetail.setStyleSheet(
            "#dtl{min-width:25px; max-width:25px; icon-size:20px;}")
        connect_window(self._pb_alarmdetail,
                       APUAlarmDetails,
                       self,
                       prefix=self._prefix,
                       device=self._device)

        self._ld_intlk = QLabel('Interlocks', self, alignment=Qt.AlignCenter)
        self._led_intlkresume = PyDMLedMultiChannel(
            self, {
                self.dev_pref.substitute(propty='IntlkInStop-Mon'): 0,
                self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon'): 0,
                self.dev_pref.substitute(propty='IntlkOutPwrEnbld-Mon'): 1
            })
        self._pb_intlkdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '',
                                           self)
        self._pb_intlkdetail.setObjectName('dtl')
        self._pb_intlkdetail.setStyleSheet(
            "#dtl{min-width:25px; max-width:25px; icon-size:20px;}")
        connect_window(self._pb_intlkdetail,
                       APUInterlockDetails,
                       self,
                       prefix=self._prefix,
                       device=self._device)

        self._ld_hwsys = QLabel('Hardware\n&LowLevel',
                                self,
                                alignment=Qt.AlignCenter)
        self._led_hwsysresume = PyDMLedMultiChannel(
            self, {
                self.dev_pref.substitute(propty='StateHw-Mon'): {
                    'value': [0x4C, 0x3C],
                    'comp': 'in'
                },
                self.dev_pref.substitute(propty='State-Mon'): {
                    'value': [1, 4],
                    'comp': 'in'
                },
                self.dev_pref.substitute(propty='IsOperational-Mon'): 1
            })
        self._led_hwsysresume.offColor = PyDMLed.Yellow
        self._led_hwsysresume.onColor = PyDMLed.LightGreen
        self._pb_hwsysdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '',
                                           self)
        self._pb_hwsysdetail.setObjectName('dtl')
        self._pb_hwsysdetail.setStyleSheet(
            "#dtl{min-width:25px; max-width:25px; icon-size:20px;}")
        connect_window(self._pb_hwsysdetail,
                       APUHardLLDetails,
                       self,
                       prefix=self._prefix,
                       device=self._device)

        self._ld_reset = QLabel('Reset', self, alignment=Qt.AlignCenter)
        self._pb_reset = PyDMPushButton(self,
                                        label='',
                                        icon=qta.icon('fa5s.sync'))
        self._pb_reset.setToolTip('Reset active alarms.')
        self._pb_reset.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_reset.pressValue = 2  # Reset
        self._pb_reset.setObjectName('Reset')
        self._pb_reset.setStyleSheet(
            '#Reset{min-width:30px; max-width:30px; icon-size:25px;}')

        gbox_alrmintlk = QGroupBox('Status')
        lay_alrmintlk = QGridLayout(gbox_alrmintlk)
        lay_alrmintlk.addWidget(self._pb_alarmdetail, 0, 0)
        lay_alrmintlk.addWidget(self._ld_alarm, 0, 1)
        lay_alrmintlk.addWidget(self._led_alarm, 0, 2)
        lay_alrmintlk.addWidget(self._pb_intlkdetail, 1, 0)
        lay_alrmintlk.addWidget(self._ld_intlk, 1, 1)
        lay_alrmintlk.addWidget(self._led_intlkresume, 1, 2)
        lay_alrmintlk.addWidget(self._pb_hwsysdetail, 2, 0)
        lay_alrmintlk.addWidget(self._ld_hwsys, 2, 1)
        lay_alrmintlk.addWidget(self._led_hwsysresume, 2, 2)
        lay_alrmintlk.addWidget(self._ld_reset, 3, 1)
        lay_alrmintlk.addWidget(self._pb_reset, 3, 2)
        return gbox_alrmintlk

    def _ctrlModeWidget(self):
        self._led_ctrlmode = PyDMLed(
            self, self.dev_pref.substitute(propty='IsRemote-Mon'))
        self._led_ctrlmode.offColor = PyDMLed.Red
        self._led_ctrlmode.onColor = PyDMLed.LightGreen
        self._lb_ctrlmode = PyDMLabel(
            self, self.dev_pref.substitute(propty='Interface-Mon'))

        gbox_ctrlmode = QGroupBox('Control Mode')
        lay_ctrlmode = QHBoxLayout(gbox_ctrlmode)
        lay_ctrlmode.setAlignment(Qt.AlignCenter)
        lay_ctrlmode.addWidget(self._led_ctrlmode)
        lay_ctrlmode.addWidget(self._lb_ctrlmode)
        return gbox_ctrlmode

    def _beamLinesCtrlWidget(self):
        self._ld_blinesenbl = QLabel('Enable', self)
        self._sb_blinesenbl = PyDMStateButton(
            self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sel'))
        self._led_blinesenbl = SiriusLedState(
            self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sts'))
        self._ld_blinesmon = QLabel('Status', self)
        self._led_blinesmon = SiriusLedState(
            self, self.dev_pref.substitute(propty='BeamLineCtrl-Mon'))

        gbox_blines = QGroupBox('Beam Lines Control', self)
        lay_blines = QGridLayout(gbox_blines)
        lay_blines.addWidget(self._ld_blinesenbl, 0, 0)
        lay_blines.addWidget(self._sb_blinesenbl, 0, 1)
        lay_blines.addWidget(self._led_blinesenbl, 0, 2)
        lay_blines.addWidget(self._ld_blinesmon, 1, 0)
        lay_blines.addWidget(self._led_blinesmon, 1, 1, 1, 2)
        return gbox_blines

    def _auxCommandsWidget(self):
        self._ld_speedlim = QLabel('Max Phase Speed\n[mm/s]', self)
        self._sb_speedlim = PyDMSpinbox(
            self, self.dev_pref.substitute(propty='MaxPhaseSpeed-SP'))
        self._sb_speedlim.showStepExponent = False
        self._sb_speedlim.setStyleSheet('max-width:4.5em;')
        self._lb_speedlim = PyDMLabel(
            self, self.dev_pref.substitute(propty='MaxPhaseSpeed-RB'))

        self._ld_homeaxis = QLabel('Do homing', self)
        self._pb_home = PyDMPushButton(self,
                                       label='',
                                       icon=qta.icon('mdi.keyboard-return'))
        self._pb_home.setToolTip('Execute homing for selected axis.')
        self._pb_home.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_home.pressValue = 10  # Home
        self._pb_home.setObjectName('Home')
        self._pb_home.setStyleSheet(
            '#Home{min-width:30px; max-width:30px; icon-size:25px;}')

        self._ld_standby = QLabel('Enable Standby Mode', self)
        self._pb_standby = PyDMPushButton(
            self, label='', icon=qta.icon('mdi.alpha-a-box-outline'))
        self._pb_standby.setToolTip(
            'Enable standby mode for automatic motion.')
        self._pb_standby.channel = \
            self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_standby.pressValue = 5  # Standby
        self._pb_standby.setObjectName('Standby')
        self._pb_standby.setStyleSheet(
            '#Standby{min-width:30px; max-width:30px; icon-size:25px;}')

        self._ld_lastcomm = QLabel('Last Command', self)
        self._lb_lastcomm = PyDMLabel(
            self, self.dev_pref.substitute(propty='LastDevCtrlCmd-Mon'))

        gbox_auxcmd = QGroupBox('Auxiliary Commands', self)
        lay_auxcmd = QGridLayout(gbox_auxcmd)
        lay_auxcmd.addWidget(self._ld_speedlim, 0, 0)
        lay_auxcmd.addWidget(self._sb_speedlim, 0, 1)
        lay_auxcmd.addWidget(self._lb_speedlim, 0, 2)
        lay_auxcmd.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Fixed),
                           1, 0)
        lay_auxcmd.addWidget(self._ld_homeaxis, 2, 0)
        lay_auxcmd.addWidget(self._pb_home,
                             2,
                             1,
                             1,
                             2,
                             alignment=Qt.AlignCenter)
        lay_auxcmd.addWidget(self._ld_standby, 3, 0)
        lay_auxcmd.addWidget(self._pb_standby,
                             3,
                             1,
                             1,
                             2,
                             alignment=Qt.AlignCenter)
        lay_auxcmd.addWidget(self._ld_lastcomm, 4, 0)
        lay_auxcmd.addWidget(self._lb_lastcomm, 4, 1, 1, 2)
        return gbox_auxcmd

    def contextMenuEvent(self, event):
        point = event.pos()
        if self._label_corrsH.underMouse():
            menu = self.corrsH.contextMenuEvent(event, return_menu=True)
            menu.popup(self.mapToGlobal(point))
        if self._label_corrsV.underMouse():
            menu = self.corrsV.contextMenuEvent(event, return_menu=True)
            menu.popup(self.mapToGlobal(point))
예제 #5
0
class APUSummaryWidget(APUSummaryBase):
    """APU Summary Widget."""
    def __init__(self, parent=None, prefix=_vaca_prefix, device=''):
        """Init."""
        super().__init__(parent)
        self._prefix = prefix
        self._device = _PVName(device)
        self._beamline = IDSearch.conv_idname_2_beamline(self._device)
        self.dev_pref = self._device.substitute(prefix=prefix)
        self._setupUi()

    def _setupUi(self):
        self._lb_bl = QLabel('<h4>' + self._beamline + '</h4>',
                             self,
                             alignment=Qt.AlignCenter)

        self._pb_dev = QPushButton(self._device, self)
        connect_newprocess(
            self._pb_dev,
            ['sirius-hla-si-id-control.py', '-dev', self._device])

        self._sb_phs = PyDMSpinbox(self,
                                   self.dev_pref.substitute(propty='Phase-SP'))
        self._sb_phs.showStepExponent = False
        self._lb_phs = PyDMLabel(self,
                                 self.dev_pref.substitute(propty='Phase-Mon'))

        self._sb_kx = PyDMSpinbox(self,
                                  self.dev_pref.substitute(propty='Kx-SP'))
        self._sb_kx.showStepExponent = False
        self._lb_kx = PyDMLabel(self,
                                self.dev_pref.substitute(propty='Kx-Mon'))

        self._sb_phsspd = PyDMSpinbox(
            self, self.dev_pref.substitute(propty='PhaseSpeed-SP'))
        self._sb_phsspd.showStepExponent = False
        self._lb_phsspd = PyDMLabel(
            self, self.dev_pref.substitute(propty='PhaseSpeed-Mon'))

        self._pb_start = PyDMPushButton(self,
                                        label='',
                                        icon=qta.icon('fa5s.play'))
        self._pb_start.setToolTip(
            'Start automatic motion towards previously entered setpoint.')
        self._pb_start.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_start.pressValue = 3  # Start
        self._pb_start.setObjectName('Start')
        self._pb_start.setStyleSheet(
            '#Start{min-width:30px; max-width:30px; icon-size:25px;}')

        self._pb_stop = PyDMPushButton(self,
                                       label='',
                                       icon=qta.icon('fa5s.stop'))
        self._pb_stop.setToolTip('Stop all motion, lock all brakes.')
        self._pb_stop.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd')
        self._pb_stop.pressValue = 1  # Stop
        self._pb_stop.setObjectName('Stop')
        self._pb_stop.setStyleSheet(
            '#Stop{min-width:30px; max-width:30px; icon-size:25px;}')

        self._led_ismov = SiriusLedState(
            self, self.dev_pref.substitute(propty='Moving-Mon'))

        self._led_status = PyDMLedMultiChannel(
            self, {
                self.dev_pref.substitute(propty='Alarm-Mon'): 0,
                self.dev_pref.substitute(propty='IntlkInStop-Mon'): 0,
                self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon'): 0,
                self.dev_pref.substitute(propty='IntlkOutPwrEnbld-Mon'): 1,
                self.dev_pref.substitute(propty='IsOperational-Mon'): 1
            })

        self._sb_blenbl = PyDMStateButton(
            self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sel'))
        self._led_blenbl = SiriusLedState(
            self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sts'))

        self._led_blmon = SiriusLedState(
            self, self.dev_pref.substitute(propty='BeamLineCtrl-Mon'))

        self.widgets = {
            'Beamline': ([
                self._lb_bl,
            ], 'v'),
            'Device': ([
                self._pb_dev,
            ], 'v'),
            'Alarms': ([
                self._led_status,
            ], 'v'),
            'Phase': ([self._sb_phs, self._lb_phs], 'v'),
            'Kx': ([self._sb_kx, self._lb_kx], 'v'),
            'Phase Speed': ([self._sb_phsspd, self._lb_phsspd], 'v'),
            'Start': ([
                self._pb_start,
            ], 'v'),
            'Stop': ([
                self._pb_stop,
            ], 'v'),
            'Moving': ([
                self._led_ismov,
            ], 'v'),
            'BeamLine Enable': ([self._sb_blenbl, self._led_blenbl], 'h'),
            'Beamline Control': ([
                self._led_blmon,
            ], 'v'),
        }

        layout = QHBoxLayout(self)
        for name, size in self.widgets_widths:
            objname = name.replace(' ', '')
            group = self.widgets[name]
            items, ori = group

            widget = QWidget(self)
            lay = QVBoxLayout() if ori == 'v' else QHBoxLayout()
            lay.setContentsMargins(0, 0, 0, 0)
            lay.setAlignment(Qt.AlignCenter)
            lay.setSpacing(0)
            widget.setLayout(lay)

            for item in items:
                lay.addWidget(item)

            widget.setObjectName(objname)
            widget.setStyleSheet(
                '#' + objname +
                '{{min-width:{0}em; max-width:{0}em;}}'.format(str(size)))
            layout.addWidget(widget)

    def enable_beamline_control(self):
        """Enable beamline control."""
        if self._sb_blenbl.isEnabled():
            if not self._sb_blenbl.value:
                self._sb_blenbl.send_value()

    def disable_beamline_control(self):
        """Disable beamline control."""
        if self._sb_blenbl.isEnabled():
            if self._sb_blenbl.value:
                self._sb_blenbl.send_value()
예제 #6
0
class TuneDetails(SiriusMainWindow):
    """Tune Details."""
    def __init__(self,
                 parent=None,
                 prefix='',
                 section='',
                 orientation='H',
                 background=None):
        """Init."""
        super().__init__(parent)
        self.prefix = prefix
        self.section = section.upper()
        self.orientation = orientation
        self.device = SiriusPVName('AC-Glob:DI-Tune-O')
        self.device = self.device.substitute(sec=self.section,
                                             idx=self.orientation,
                                             prefix=self.prefix)
        if self.section == 'BO':
            self.trigger = SiriusPVName('BO-Glob:TI-TuneProc')
        self.background = background
        self.setWindowTitle(self.device + ' Detailed Settings')
        self.setObjectName(self.section + 'App')
        self._setupUi()
        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        cw = QWidget(self)
        self.setCentralWidget(cw)

        # title
        self.title_label = QLabel(
            '<h3>Tune ' + self.orientation + ' Detailed Settings<h3>', self)
        self.title_label.setObjectName('title')
        pal = self.title_label.palette()
        pal.setColor(QPalette.Background, self.background)
        self.title_label.setAutoFillBackground(True)
        self.title_label.setPalette(pal)

        # measurement
        self.meas_gbox = QGroupBox('Measurement', self)
        self.meas_gbox.setLayout(self._measLayout())

        # config
        self.config_gbox = QGroupBox('Configuration', self)
        self.config_gbox.setLayout(self._configLayout())

        if self.section == 'BO':
            # trigger
            self.trg_gbox = QGroupBox('Trigger', self)
            self.trg_gbox.setLayout(QHBoxLayout())
            self.trg_gbox.layout().addWidget(
                HLTriggerSimple(self.trg_gbox,
                                device='BO-Glob:TI-TuneProc',
                                prefix=self.prefix,
                                duration=True,
                                nrpulses=True))
            # spectrogram view
            self.spec_gbox = QGroupBox('Spectrogram View', self)
            self.spec_gbox.setLayout(self._specViewLayout())
            # roi
            self.roi_gbox = QGroupBox('ROI', self)
            self.roi_gbox.setLayout(self._roiLayout())

            vbox = QVBoxLayout()
            vbox.addWidget(self.trg_gbox)
            vbox.addWidget(self.spec_gbox)
            vbox.addWidget(self.roi_gbox)
            vbox.addWidget(self.config_gbox)

            lay = QGridLayout(cw)
            lay.addWidget(self.title_label, 0, 0, 1, 2)
            lay.addWidget(self.meas_gbox, 1, 0)
            lay.addLayout(vbox, 1, 1)
        else:
            lay = QVBoxLayout(cw)
            lay.addWidget(self.title_label)
            lay.addWidget(self.meas_gbox)
            lay.addWidget(self.config_gbox)

        self.setStyleSheet("""
            QLed{
                min-width:1.29em; max-width:1.29em;
            }
            #title {
                min-height:1.29em; max-height:1.29em;
                qproperty-alignment: "AlignVCenter | AlignHCenter";
            }
            PyDMLabel, PyDMSpinbox, PyDMEnumComboBox,
            PyDMStateButton{
                min-width:6em; max-width:6em;
            }""")

    def _measLayout(self):
        # Acquisition
        lbl_acq = QLabel('Acquisition', self)
        self.bt_acq = PyDMStateButton(
            self, self.device.substitute(propty='SpecAnaGetSpec-Sel'))
        self.bt_acq.shape = 1
        self.led_acq = SiriusLedState(
            self, self.device.substitute(propty='SpecAnaGetSpec-Sts'))
        hbox_acq = QHBoxLayout()
        hbox_acq.addWidget(self.bt_acq)
        hbox_acq.addWidget(self.led_acq)

        # Excitation
        lbl_drive = QLabel('Excitation', self)
        self.bt_drive = PyDMStateButton(
            self, self.device.substitute(propty='Enbl-Sel'))
        self.bt_drive.shape = 1
        value = 0b111 if self.section == 'BO' else 1
        self.led_drive = PyDMLedMultiChannel(
            parent=self,
            channels2values={self.device.substitute(propty='Enbl-Sts'): value})
        self.led_drive.setOffColor(PyDMLed.DarkGreen)
        hbox_drive = QHBoxLayout()
        hbox_drive.addWidget(self.bt_drive)
        hbox_drive.addWidget(self.led_drive)

        # Excitation Status Detailed
        gbox_enblsts = QGridLayout()
        lbl_enblsts = QLabel('Excitation\nEnable Status\nDetailed',
                             self,
                             alignment=Qt.AlignVCenter | Qt.AlignRight)
        if self.section == 'BO':
            # # Carrier Generator
            self.led_carrier = SiriusLedState(
                self, self.device.substitute(propty='EnblCarrierGen-Sts'))
            gbox_enblsts.addWidget(self.led_carrier, 0, 0)
            gbox_enblsts.addWidget(QLabel('Carrier Generator'), 0, 1)
            # # Noise Generator
            self.led_noise = SiriusLedState(
                self, self.device.substitute(propty='EnblNoiseGen-Sts'))
            gbox_enblsts.addWidget(self.led_noise, 1, 0)
            gbox_enblsts.addWidget(QLabel('Noise Generator'), 1, 1)
        else:
            # # Noise Generator
            self.led_trkgen = SiriusLedState(
                self, self.device.substitute(propty='SpecAnaTrkGen-Sts'))
            gbox_enblsts.addWidget(self.led_trkgen, 1, 0)
            gbox_enblsts.addWidget(QLabel('Tracking Generator'), 1, 1)
        # # Amplifier
        self.led_amp = SiriusLedState(
            self, self.device.substitute(propty='EnblAmp-Sts'))
        gbox_enblsts.addWidget(self.led_amp, 2, 0)
        gbox_enblsts.addWidget(QLabel('Amplifier'), 2, 1)

        if self.section == 'BO':
            # Frame Count
            lbl_acqcnt = QLabel('Frame Count', self)
            dev = self.device.substitute(dev='TuneProc')
            self.lb_acqcnt = PyDMLabel(self,
                                       dev.substitute(propty='FrameCount-Mon'))
            self.lb_acqcnt.setAlignment(Qt.AlignCenter)
            self.led_acqcnt = PyDMLedMultiChannel(parent=self)
            self.trigNrPulseChannel = SiriusConnectionSignal(
                self.trigger.substitute(prefix=self.prefix,
                                        propty='NrPulses-RB'))
            self.trigNrPulseChannel.new_value_signal[int].connect(
                self._updateNrAcq)
            hbox_acqcnt = QHBoxLayout()
            hbox_acqcnt.addWidget(self.lb_acqcnt)
            hbox_acqcnt.addWidget(self.led_acqcnt)

        # Nr. Samples p/ spec
        lbl_nrsmp = QLabel('Nr. Samples p/ Spec.', self)
        self.lb_nrsmp = PyDMLabel(parent=self,
                                  init_channel=self.device.substitute(
                                      dev='TuneProc',
                                      propty_name='SwePts',
                                      propty_suffix='RB'))

        if self.section == 'SI':
            # Acquisition Time
            lbl_acqtime = QLabel('Acq. Time', self)
            self.cb_acqtime = PyDMEnumComboBox(
                parent=self,
                init_channel=self.device.substitute(dev='TuneProc',
                                                    propty_name='Trace',
                                                    propty_suffix='Mon',
                                                    field='SCAN'))

            # Sweep time
            lbl_swetime = QLabel('Sweep Time [ms]', self)
            self.lb_swetime = PyDMLabel(parent=self,
                                        init_channel=self.device.substitute(
                                            dev='TuneProc',
                                            propty_name='SweTime',
                                            propty_suffix='Mon'))

        # Span
        lbl_span = QLabel('Span [kHz]', self)
        self.le_span = PyDMLineEdit(self,
                                    self.device.substitute(propty='Span-SP'))
        self.le_span.precisionFromPV = True
        self.lb_span = PyDMLabel(self,
                                 self.device.substitute(propty='Span-RB'))
        hbox_span = QHBoxLayout()
        hbox_span.addWidget(self.le_span)
        hbox_span.addWidget(self.lb_span)

        # RBW
        lbl_rbw = QLabel('RBW', self)
        if self.section == 'BO':
            self.cb_rbw = PyDMEnumComboBox(
                self, self.device.substitute(propty='SpecAnaRBW-Sel'))
        else:
            items = [
                '1 Hz', '2 Hz', '3 Hz', '5 Hz', '10 Hz', '20 Hz', '30 Hz',
                '50 Hz', '100 Hz', '200 Hz', '300 Hz', '500 Hz', '1 kHz',
                '2 kHz', '3 kHz', '5 kHz', '6.25 kHz', '10 kHz', '20 kHz',
                '30 kHz', '50 kHz', '100 kHz', '200 kHz', '300 kHz', '500 kHz',
                '1 MHz', '2 MHz', '3 MHz', '5 MHz', '10 MHz'
            ]
            self.cb_rbw = SiriusStringComboBox(
                self,
                self.device.substitute(propty='SpecAnaRBW-Sel'),
                items=items)
        self.lb_rbw = PyDMLabel(
            self, self.device.substitute(propty='SpecAnaRBW-Sts'))
        hbox_rbw = QHBoxLayout()
        hbox_rbw.addWidget(self.cb_rbw)
        hbox_rbw.addWidget(self.lb_rbw)

        # Harmonic
        lbl_h = QLabel('Harmonic (n)', self)
        self.sb_h = PyDMSpinbox(self, self.device.substitute(propty='RevN-SP'))
        self.sb_h.showStepExponent = False
        self.sb_h.precisionFromPV = True
        self.lb_h = PyDMLabel(self, self.device.substitute(propty='RevN-RB'))
        hbox_h = QHBoxLayout()
        hbox_h.addWidget(self.sb_h)
        hbox_h.addWidget(self.lb_h)

        # Harmonic Frequency
        lbl_Fh = QLabel('Harm. Freq. [kHz]', self)
        self.lb_Fh = PyDMLabel(parent=self)
        self.lb_Fh.setToolTip('Frf/(h*n)')
        self.lb_Fh.channel = self.device.substitute(propty='FreqRevN-Mon')

        # Frequency Offset
        lbl_foff = QLabel('Frequency Offset [kHz]', self)
        self.sb_foff = PyDMSpinbox(self,
                                   self.device.substitute(propty='FreqOff-SP'))
        self.sb_foff.showStepExponent = False
        self.sb_foff.precisionFromPV = True
        self.lb_foff = PyDMLabel(self,
                                 self.device.substitute(propty='FreqOff-RB'))
        hbox_foff = QHBoxLayout()
        hbox_foff.addWidget(self.sb_foff)
        hbox_foff.addWidget(self.lb_foff)

        # Center Frequency
        lbl_Fc = QLabel('Center Frequency [MHz]', self)
        self.le_Fc = PyDMLineEdit(
            self, self.device.substitute(propty='CenterFreq-SP'))
        self.le_Fc.precisionFromPV = True
        self.lb_Fc = PyDMLabel(self,
                               self.device.substitute(propty='CenterFreq-RB'))
        hbox_Fc = QHBoxLayout()
        hbox_Fc.addWidget(self.le_Fc)
        hbox_Fc.addWidget(self.lb_Fc)

        # Lock Center Freq.
        lbl_autoFc = QLabel('Lock Center Frequency ', self)
        self.bt_autoFc = PyDMStateButton(
            self, self.device.substitute(propty='CenterFreqAuto-Sel'))
        self.bt_autoFc.shape = 1
        self.led_autoFc = SiriusLedState(
            self, self.device.substitute(propty='CenterFreqAuto-Sts'))
        hbox_autoFc = QHBoxLayout()
        hbox_autoFc.addWidget(self.bt_autoFc)
        hbox_autoFc.addWidget(self.led_autoFc)

        # Amplifier Gain
        lbl_drivegain = QLabel('Amplifier Gain [dB]', self)
        self.sb_drivegain = PyDMSpinbox(
            self, self.device.substitute(propty='AmpGain-SP'))
        self.sb_drivegain.showStepExponent = False
        self.sb_drivegain.precisionFromPV = True
        self.lb_drivegain = PyDMLabel(
            self, self.device.substitute(propty='AmpGain-RB'))
        hbox_drivegain = QHBoxLayout()
        hbox_drivegain.addWidget(self.sb_drivegain)
        hbox_drivegain.addWidget(self.lb_drivegain)

        if self.section == 'BO':
            # Auto Configure Excitation
            lbl_driveauto = QLabel('Auto Config. Excit.', self)
            self.bt_driveauto = PyDMStateButton(
                self, self.device.substitute(propty='DriveAuto-Sel'))
            self.bt_driveauto.shape = 1
            self.led_driveauto = SiriusLedState(
                self, self.device.substitute(propty='DriveAuto-Sts'))
            hbox_driveauto = QHBoxLayout()
            hbox_driveauto.addWidget(self.bt_driveauto)
            hbox_driveauto.addWidget(self.led_driveauto)

            # Noise Amplitude
            lbl_noiseamp = QLabel('Noise Amplitude [V]', self)
            self.sb_noiseamp = PyDMSpinbox(
                self, self.device.substitute(propty='NoiseAmpl-SP'))
            self.sb_noiseamp.showStepExponent = False
            self.sb_noiseamp.precisionFromPV = True
            self.lb_noiseamp = PyDMLabel(
                self, self.device.substitute(propty='NoiseAmpl-RB'))
            hbox_noiseamp = QHBoxLayout()
            hbox_noiseamp.addWidget(self.sb_noiseamp)
            hbox_noiseamp.addWidget(self.lb_noiseamp)
        else:
            # Noise Amplitude
            lbl_trkgenlvl = QLabel('Trk. Gen. Power [dBm]', self)
            self.sb_trkgenlvl = PyDMLineEdit(
                self, self.device.substitute(propty='SpecAnaTrkGenLvl-SP'))
            self.lb_trkgenlvl = PyDMLabel(
                self, self.device.substitute(propty='SpecAnaTrkGenLvl-RB'))
            hbox_trkgenlvl = QHBoxLayout()
            hbox_trkgenlvl.addWidget(self.sb_trkgenlvl)
            hbox_trkgenlvl.addWidget(self.lb_trkgenlvl)

            # Spectrum Acquisition
            lbl_getspec = QLabel('Spectrum Acq.', self)
            self.cb_getspec = PyDMStateButton(
                parent=self,
                init_channel=self.device.substitute(dev='TuneProc',
                                                    propty_name='GetSpectrum',
                                                    propty_suffix='Sel'))
            self.cb_getspec.shape = 1
            self.lb_getspec = PyDMLed(parent=self,
                                      init_channel=self.device.substitute(
                                          dev='TuneProc',
                                          propty_name='GetSpectrum',
                                          propty_suffix='Sts'))
            hbox_getspec = QHBoxLayout()
            hbox_getspec.addWidget(self.cb_getspec)
            hbox_getspec.addWidget(self.lb_getspec)

        lay = QFormLayout()
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow(lbl_acq, hbox_acq)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(lbl_drive, hbox_drive)
        lay.addRow(lbl_enblsts, gbox_enblsts)
        if self.section == 'BO':
            lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
            lay.addRow(lbl_acqcnt, hbox_acqcnt)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(lbl_nrsmp, self.lb_nrsmp)
        if self.section == 'SI':
            lay.addRow(lbl_acqtime, self.cb_acqtime)
            lay.addRow(lbl_swetime, self.lb_swetime)
        lay.addRow(lbl_span, hbox_span)
        lay.addRow(lbl_rbw, hbox_rbw)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(lbl_h, hbox_h)
        lay.addRow(lbl_Fh, self.lb_Fh)
        lay.addRow(lbl_foff, hbox_foff)
        lay.addRow(lbl_Fc, hbox_Fc)
        lay.addRow(lbl_autoFc, hbox_autoFc)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(lbl_drivegain, hbox_drivegain)
        if self.section == 'BO':
            lay.addRow(lbl_driveauto, hbox_driveauto)
            lay.addRow(lbl_noiseamp, hbox_noiseamp)
        else:
            lay.addRow(lbl_trkgenlvl, hbox_trkgenlvl)
            lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
            lay.addRow(lbl_getspec, hbox_getspec)
        return lay

    def _configLayout(self):
        self.bt_rst = PyDMPushButton(
            parent=self,
            init_channel=self.device.substitute(propty='Rst-Cmd'),
            pressValue=1,
            icon=qta.icon('fa5s.sync'))
        self.bt_rst.setObjectName('bt_rst')
        self.bt_rst.setStyleSheet(
            '#bt_rst{min-width:25px; max-width:25px; icon-size:20px;}')
        lay = QFormLayout()
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow('Restore Default', self.bt_rst)
        return lay

    def _specViewLayout(self):
        dev = self.device.substitute(dev='TuneProc')

        # Mode
        lbl_mode = QLabel('Mode', self)
        self.cb_mode = PyDMEnumComboBox(self,
                                        dev.substitute(propty='SpecMode-Sel'))
        self.lb_mode = PyDMLabel(self, dev.substitute(propty='SpecMode-Sts'))
        hbox_mode = QHBoxLayout()
        hbox_mode.addWidget(self.cb_mode)
        hbox_mode.addWidget(self.lb_mode)

        # Time window
        lbl_timewdw = QLabel('Time Window [ms]', self)
        self.le_timewdw = PyDMLineEdit(self,
                                       dev.substitute(propty='SpecTime-SP'))
        self.le_timewdw.precisionFromPV = True
        self.lb_timewdw = PyDMLabel(self, dev.substitute(propty='SpecTime-RB'))
        hbox_timewdw = QHBoxLayout()
        hbox_timewdw.addWidget(self.le_timewdw)
        hbox_timewdw.addWidget(self.lb_timewdw)

        lay = QFormLayout()
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow(lbl_mode, hbox_mode)
        lay.addRow(lbl_timewdw, hbox_timewdw)
        return lay

    def _roiLayout(self):
        # StartX
        lbl_roistartx = QLabel('Start X [MHz]', self)
        self.le_roistartx = PyDMLineEdit(
            self, self.device.substitute(propty='ROIOffsetX-SP'))
        self.le_roistartx.precisionFromPV = True
        self.lb_roistartx = PyDMLabel(
            self, self.device.substitute(propty='ROIOffsetX-RB'))
        hbox_roistartx = QHBoxLayout()
        hbox_roistartx.addWidget(self.le_roistartx)
        hbox_roistartx.addWidget(self.lb_roistartx)

        # Width
        lbl_roiwidth = QLabel('Width [MHz]', self)
        self.le_roiwidth = PyDMLineEdit(
            self, self.device.substitute(propty='ROIWidth-SP'))
        self.le_roiwidth.precisionFromPV = True
        self.lb_roiwidth = PyDMLabel(
            self, self.device.substitute(propty='ROIWidth-RB'))
        hbox_roiwidth = QHBoxLayout()
        hbox_roiwidth.addWidget(self.le_roiwidth)
        hbox_roiwidth.addWidget(self.lb_roiwidth)

        # StartY
        lbl_roistarty = QLabel('Start Y [ms]', self)
        self.le_roistarty = PyDMLineEdit(
            self, self.device.substitute(propty='ROIOffsetY-SP'))
        self.le_roistarty.precisionFromPV = True
        self.lb_roistarty = PyDMLabel(
            self, self.device.substitute(propty='ROIOffsetY-RB'))
        hbox_roistarty = QHBoxLayout()
        hbox_roistarty.addWidget(self.le_roistarty)
        hbox_roistarty.addWidget(self.lb_roistarty)

        # Height
        lbl_roiheight = QLabel('Height [ms]', self)
        self.le_roiheight = PyDMLineEdit(
            self, self.device.substitute(propty='ROIHeight-SP'))
        self.le_roiheight.precisionFromPV = True
        self.lb_roiheight = PyDMLabel(
            self, self.device.substitute(propty='ROIHeight-RB'))
        hbox_roiheight = QHBoxLayout()
        hbox_roiheight.addWidget(self.le_roiheight)
        hbox_roiheight.addWidget(self.lb_roiheight)

        # Auto adjust
        lbl_roiauto = QLabel('Auto Positioning', self)
        self.bt_roiauto = PyDMStateButton(
            self, self.device.substitute(propty='ROIAuto-Sel'))
        self.bt_roiauto.shape = 1
        self.led_roiauto = SiriusLedState(
            self, self.device.substitute(propty='ROIAuto-Sts'))
        hbox_roiauto = QHBoxLayout()
        hbox_roiauto.addWidget(self.bt_roiauto)
        hbox_roiauto.addWidget(self.led_roiauto)

        lay = QFormLayout()
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow(lbl_roistartx, hbox_roistartx)
        lay.addRow(lbl_roiwidth, hbox_roiwidth)
        lay.addRow(lbl_roistarty, hbox_roistarty)
        lay.addRow(lbl_roiheight, hbox_roiheight)
        lay.addRow(lbl_roiauto, hbox_roiauto)
        return lay

    def _updateNrAcq(self, new_value):
        dev = self.device.substitute(dev='TuneProc')
        self.led_acqcnt.set_channels2values(
            {dev.substitute(propty='FrameCount-Mon'): new_value})
예제 #7
0
파일: motor.py 프로젝트: marcosase/E-MA
class QMotor(QWidget):
    '''
    Widget based on EPICS motor record
    Details about motor record parameters are found at: https://www3.aps.anl.gov/bcda/synApps/motor/R6-9/motorRecord.html
    '''
    def __init__(self, parent=None, init_channel=None):
        super(QMotor, self).__init__(parent)
        self._channel = init_channel
        self.app = QCoreApplication.instance()
        self.ui = None
        self.settings_window = None
        self.config_fields_file = None
        self.fields_map = None
        self.motor_style = '''
                QFrame#frame_motor > PyDMLabel{
                  color: rgb(255, 255, 255);
                }

                QPushButton#PyDMPushButton_stop{
                  color: rgb(255, 0, 0);
                }

                QFrame#frame_motor{
                  background-color: rgb(20, 20, 20);
                }

                QFrame#frame_controls{
                  background-color: rgb(255, 255, 255);
                }

                QCheckBox#check_set{
                  color: rgb(0, 0, 0);
                }
        '''
        self._orientation = Qt.Horizontal
        self._flipped = False
        self._inverted_scale = False

        self.setup_widgets()
        self.build_layout(self._orientation, self._flipped,
                          self._inverted_scale)
        self.setStyleSheet(self.motor_style)
        self.set_fields()
        self.load_images()
        self.set_all_channels(self._channel)
        self.show()
        self.set_limits_minimum_width()
        self.repaint()

        self.lineEdit_rlv.textEdited.connect(self.set_press_values)
        self.pushButton_settings.clicked.connect(self.load_settings_ui)

    def init_for_designer(self):
        '''
        This is called by PyDM qtplugin_factory.
        If in QtDesigner, initialize all PyDM child widgets.
        '''
        widgets = self.findChildren(QWidget)
        for child_widget in widgets:
            try:
                child_widget.init_for_designer()
            except:
                pass

    def get_ui_filename(self):
        return 'motor_horizontal.ui'

    def setup_widgets(self):
        base_width = 55
        base_height = 26

        self.frame_motor = QFrame()
        #Header
        self.widget_offset = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        self.widget_offset.setSizePolicy(sizePolicy)
        self.widget_offset.setFixedWidth(15)
        self.widget_offset.setMinimumHeight(base_height)

        self.PyDMLabel_desc = PyDMLabel()
        self.PyDMLabel_desc.setText('<DESC>')
        self.PyDMLabel_desc.setAlignment(Qt.AlignCenter)
        self.PyDMLabel_desc.setMinimumHeight(base_height)

        self.pushButton_settings = QPushButton('⋮')
        self.pushButton_settings.setSizePolicy(sizePolicy)
        self.pushButton_settings.setFixedWidth(15)
        self.pushButton_settings.setMinimumHeight(base_height)

        # Control
        self.frame_controls = QFrame()
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.frame_controls.setSizePolicy(sizePolicy)

        self.lineEdit_rlv = QLineEdit()
        self.lineEdit_rlv.setPlaceholderText('RLV')
        self.lineEdit_rlv.setAlignment(Qt.AlignCenter)

        self.PyDMLineEdit_val = PyDMLineEdit()
        self.PyDMLineEdit_val.alarmSensitiveBorder = False
        self.PyDMLineEdit_val.setPlaceholderText('VAL')
        self.PyDMLineEdit_val.setAlignment(Qt.AlignCenter)

        self.PyDMPushButton_rlv_minus = PyDMPushButton('-')
        self.PyDMPushButton_rlv_minus.setMinimumSize(base_width, base_height)

        self.PyDMPushButton_rlv_plus = PyDMPushButton('+')
        self.PyDMPushButton_rlv_plus.setMinimumSize(base_width, base_height)

        self.PyDMCheckbox_set = PyDMCheckbox()
        self.PyDMCheckbox_set.setText('SET')
        self.PyDMCheckbox_set.setLayoutDirection(Qt.RightToLeft)

        self.PyDMPushButton_stop = PyDMPushButton('STOP')
        self.PyDMPushButton_stop.setMinimumSize(base_width, base_height)
        self.PyDMPushButton_stop.pressValue = 1

        # Readback
        self.PyDMLabel_rbv = PyDMLabel()
        self.PyDMLabel_rbv.setText('<RBV>')
        self.PyDMLabel_rbv.setAlignment(Qt.AlignCenter)

        self.PyDMSymbol_lvio = PyDMSymbol()
        self.PyDMSymbol_lvio.setMinimumSize(base_height, base_height)

        self.PyDMSymbol_movn = PyDMSymbol()
        self.PyDMSymbol_movn.setMinimumSize(base_height, base_height)

        # Scale
        self.scale = PyDMScaleIndicator()
        self.scale.showValue = False
        self.scale.showLimits = False
        self.scale.scaleHeight = 30
        self.scale.backgroundColor = QColor('#393939')
        self.scale.tickColor = QColor('#FFFFFF')
        self.scale.indicatorColor = QColor('#2076DB')
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.scale.setSizePolicy(sizePolicy)

        self.PyDMLabel_llm = PyDMLabel()
        self.PyDMLabel_llm.setText('<LLM>')
        self.PyDMLabel_llm.setMinimumHeight(QWIDGETSIZE_MAX)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        #sizePolicy.setHeightForWidth(True)
        self.PyDMLabel_llm.setSizePolicy(sizePolicy)

        self.PyDMLabel_hlm = PyDMLabel()
        self.PyDMLabel_hlm.setText('<HLM>')
        self.PyDMLabel_hlm.setMinimumHeight(QWIDGETSIZE_MAX)
        self.PyDMLabel_hlm.setSizePolicy(sizePolicy)

        self.PyDMSymbol_lls = PyDMSymbol()
        self.PyDMSymbol_lls.setMinimumSize(base_height, base_height)
        self.PyDMSymbol_athm = PyDMSymbol()
        self.PyDMSymbol_athm.setMinimumSize(base_height, base_height)
        self.PyDMSymbol_hls = PyDMSymbol()
        self.PyDMSymbol_hls.setMinimumSize(base_height, base_height)

        # Set name of objects for easily styling them with stylesheet
        # (when a ui is made in designer, this step is not needed)
        self.frame_motor.setObjectName('frame_motor')
        self.frame_controls.setObjectName('frame_controls')
        self.PyDMPushButton_stop.setObjectName('PyDMPushButton_stop')
        self.scale.setObjectName('scale')
        self.PyDMCheckbox_set.setObjectName('check_set')

    def build_layout(self, orientation, flipped, inverted):
        self.header_layout = None
        self.control_layout = None
        self.readback_layout = None
        self.scale_layout = None
        self.motor_layout = None
        self.top_layout = None

        # Recreate spaces each time layout is rebuilt to prevent segfault
        # because they may be deleted by Python GC
        self.hspacer_lvio_left = QSpacerItem(0, 0,
                                             QSizePolicy.MinimumExpanding,
                                             QSizePolicy.Minimum)
        self.hspacer_lvio_right = QSpacerItem(0, 0,
                                              QSizePolicy.MinimumExpanding,
                                              QSizePolicy.Minimum)
        self.hspacer_movn_left = QSpacerItem(0, 0,
                                             QSizePolicy.MinimumExpanding,
                                             QSizePolicy.Minimum)
        self.hspacer_movn_right = QSpacerItem(0, 0,
                                              QSizePolicy.MinimumExpanding,
                                              QSizePolicy.Minimum)

        self.hspacer_llm = QSpacerItem(3, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Minimum)
        self.hspacer_hlm = QSpacerItem(3, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Minimum)
        self.vspacer_llm = QSpacerItem(0, 3, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Minimum)
        self.vspacer_hlm = QSpacerItem(0, 3, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Minimum)

        # Header
        self.header_layout = QGridLayout()

        # Control
        self.control_layout = QGridLayout()
        self.control_layout.setContentsMargins(1, 1, 1, 1)
        self.control_layout.setHorizontalSpacing(2)
        self.control_layout.setVerticalSpacing(2)

        # Readback
        self.readback_layout = QGridLayout()

        # Motor frame
        self.motor_layout = QGridLayout()
        self.motor_layout.setContentsMargins(1, 1, 1, 1)
        self.motor_layout.setHorizontalSpacing(2)
        self.motor_layout.setVerticalSpacing(3)

        # Scale
        self.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
        self.scale_layout = QGridLayout()
        self.scale_layout.setContentsMargins(0, 0, 1, 1)
        self.scale_layout.setHorizontalSpacing(1)
        self.scale_layout.setVerticalSpacing(1)

        if self._orientation == Qt.Horizontal:
            self.header_layout.addWidget(self.widget_offset, 0, 0)
            self.header_layout.addWidget(self.PyDMLabel_desc, 0, 1)
            self.header_layout.addWidget(self.pushButton_settings, 0, 2)

            self.readback_layout.addItem(self.hspacer_lvio_left, 0, 0)
            self.readback_layout.addWidget(self.PyDMSymbol_lvio, 0, 1)
            self.readback_layout.addItem(self.hspacer_lvio_right, 0, 2)
            self.readback_layout.addWidget(self.PyDMLabel_rbv, 0, 3)
            self.readback_layout.addItem(self.hspacer_movn_left, 0, 4)
            self.readback_layout.addWidget(self.PyDMSymbol_movn, 0, 5)
            self.readback_layout.addItem(self.hspacer_movn_right, 0, 6)

            self.scale.orientation = Qt.Horizontal
            if flipped == False:
                self.scale.flipScale = False
                self.scale_layout.addWidget(self.scale, 0, 0, 1, 0)
                self.scale_layout.addWidget(self.PyDMSymbol_lls, 1, 1)
                self.scale_layout.addItem(self.hspacer_llm, 1, 2)
                self.scale_layout.addWidget(self.PyDMSymbol_athm, 1, 3)
                self.scale_layout.addItem(self.hspacer_hlm, 1, 4)
                self.scale_layout.addWidget(self.PyDMSymbol_hls, 1, 5)

                if inverted == False:
                    self.scale.invertedAppearance = False
                    self.scale_layout.addWidget(self.PyDMLabel_llm, 1, 0)
                    self.scale_layout.addWidget(self.PyDMLabel_hlm, 1, 6)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignLeft | Qt.AlignTop)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignRight
                                                    | Qt.AlignTop)
                elif inverted == True:
                    self.scale.invertedAppearance = True
                    self.scale_layout.addWidget(self.PyDMLabel_llm, 1, 6)
                    self.scale_layout.addWidget(self.PyDMLabel_hlm, 1, 0)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignRight
                                                    | Qt.AlignTop)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignLeft | Qt.AlignTop)

                self.control_layout.addWidget(self.PyDMPushButton_rlv_minus, 0,
                                              0)
                self.control_layout.addWidget(self.lineEdit_rlv, 0, 1)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_plus, 0,
                                              2)
                self.control_layout.addWidget(self.PyDMCheckbox_set, 1, 0)
                self.control_layout.addWidget(self.PyDMLineEdit_val, 1, 1)
                self.control_layout.addWidget(self.PyDMPushButton_stop, 1, 2)

                self.motor_layout.addItem(self.header_layout, 0, 0)
                self.motor_layout.addWidget(self.frame_controls, 1, 0)
                self.motor_layout.addItem(self.readback_layout, 2, 0)
                self.motor_layout.addItem(self.scale_layout, 3, 0)

            elif flipped == True:
                self.scale.flipScale = True
                self.scale_layout.addWidget(self.scale, 1, 0, 1, 0)
                self.scale_layout.addWidget(self.PyDMSymbol_lls, 0, 1)
                self.scale_layout.addItem(self.hspacer_llm, 0, 2)
                self.scale_layout.addWidget(self.PyDMSymbol_athm, 0, 3)
                self.scale_layout.addItem(self.hspacer_hlm, 0, 4)
                self.scale_layout.addWidget(self.PyDMSymbol_hls, 0, 5)

                if inverted == False:
                    self.scale.invertedAppearance = False
                    self.scale_layout.addWidget(self.PyDMLabel_llm, 0, 0)
                    self.scale_layout.addWidget(self.PyDMLabel_hlm, 0, 6)

                    self.PyDMLabel_llm.setAlignment(Qt.AlignLeft
                                                    | Qt.AlignBottom)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignRight
                                                    | Qt.AlignBottom)
                elif inverted == True:
                    self.scale.invertedAppearance = True
                    self.scale_layout.addWidget(self.PyDMLabel_llm, 0, 6)
                    self.scale_layout.addWidget(self.PyDMLabel_hlm, 0, 0)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignRight
                                                    | Qt.AlignBottom)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignLeft
                                                    | Qt.AlignBottom)

                self.control_layout.addWidget(self.PyDMCheckbox_set, 0, 0)
                self.control_layout.addWidget(self.PyDMLineEdit_val, 0, 1)
                self.control_layout.addWidget(self.PyDMPushButton_stop, 0, 2)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_minus, 1,
                                              0)
                self.control_layout.addWidget(self.lineEdit_rlv, 1, 1)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_plus, 1,
                                              2)

                self.motor_layout.addItem(self.scale_layout, 0, 0)
                self.motor_layout.addItem(self.readback_layout, 1, 0)
                self.motor_layout.addWidget(self.frame_controls, 2, 0)
                self.motor_layout.addItem(self.header_layout, 3, 0)

        elif self._orientation == Qt.Vertical:
            self.scale.orientation = Qt.Vertical
            if flipped == False:
                self.readback_layout.addItem(self.hspacer_lvio_left, 0, 0)
                self.readback_layout.addWidget(self.PyDMSymbol_lvio, 0, 1)
                self.readback_layout.addItem(self.hspacer_lvio_right, 0, 2)
                self.readback_layout.addWidget(self.PyDMLabel_rbv, 0, 3)
                self.readback_layout.addItem(self.hspacer_movn_left, 0, 4)
                self.readback_layout.addWidget(self.PyDMSymbol_movn, 0, 5)
                self.readback_layout.addItem(self.hspacer_movn_right, 0, 6)

                self.header_layout.addWidget(self.pushButton_settings, 0, 0)
                self.header_layout.addWidget(self.PyDMLabel_desc, 0, 1)
                self.header_layout.addWidget(self.widget_offset, 0, 2)

                self.scale.flipScale = False
                self.scale_layout.addWidget(self.scale, 0, 0, 5, 1)
                self.scale_layout.addItem(self.hspacer_llm, 0, 1, 5, 1)
                self.scale_layout.addWidget(self.PyDMSymbol_lls, 0, 2)
                self.scale_layout.addItem(self.vspacer_llm, 1, 2)
                self.scale_layout.addWidget(self.PyDMSymbol_athm, 2, 2)
                self.scale_layout.addItem(self.vspacer_hlm, 3, 2)
                self.scale_layout.addWidget(self.PyDMSymbol_hls, 4, 2)

                self.control_layout.addWidget(self.PyDMPushButton_rlv_plus, 0,
                                              0)
                self.control_layout.addWidget(self.lineEdit_rlv, 1, 0)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_minus, 2,
                                              0)
                self.control_layout.addWidget(self.PyDMCheckbox_set,
                                              0,
                                              1,
                                              alignment=Qt.AlignCenter)
                self.control_layout.addWidget(self.PyDMLineEdit_val, 1, 1)
                self.control_layout.addWidget(self.PyDMPushButton_stop, 2, 1)

                self.motor_layout.addItem(self.header_layout, 0, 0)
                self.motor_layout.addWidget(self.frame_controls, 1, 0)
                self.motor_layout.addItem(self.readback_layout, 2, 0)
                self.motor_layout.addItem(self.scale_layout, 1, 1)

                if inverted == False:
                    self.scale.invertedAppearance = False
                    self.motor_layout.addWidget(self.PyDMLabel_hlm, 0, 1)
                    self.motor_layout.addWidget(self.PyDMLabel_llm, 2, 1)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignTop)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignBottom)
                elif inverted == True:
                    self.scale.invertedAppearance = True
                    self.motor_layout.addWidget(self.PyDMLabel_hlm, 2, 1)
                    self.motor_layout.addWidget(self.PyDMLabel_llm, 0, 1)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignBottom)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignTop)

            elif flipped == True:
                self.readback_layout.addItem(self.hspacer_movn_left, 0, 0)
                self.readback_layout.addWidget(self.PyDMSymbol_movn, 0, 1)
                self.readback_layout.addItem(self.hspacer_movn_right, 0, 2)
                self.readback_layout.addWidget(self.PyDMLabel_rbv, 0, 3)
                self.readback_layout.addItem(self.hspacer_lvio_left, 0, 4)
                self.readback_layout.addWidget(self.PyDMSymbol_lvio, 0, 5)
                self.readback_layout.addItem(self.hspacer_lvio_right, 0, 6)

                self.header_layout.addWidget(self.widget_offset, 0, 0)
                self.header_layout.addWidget(self.PyDMLabel_desc, 0, 1)
                self.header_layout.addWidget(self.pushButton_settings, 0, 2)

                self.scale.flipScale = True
                self.scale_layout.addWidget(self.scale, 0, 1, 5, 1)
                self.scale_layout.addWidget(self.PyDMSymbol_lls, 0, 0)
                self.scale_layout.addItem(self.vspacer_llm, 1, 0)
                self.scale_layout.addWidget(self.PyDMSymbol_athm, 2, 0)
                self.scale_layout.addItem(self.vspacer_hlm, 3, 0)
                self.scale_layout.addWidget(self.PyDMSymbol_hls, 4, 0)

                self.control_layout.addWidget(self.PyDMCheckbox_set,
                                              0,
                                              0,
                                              alignment=Qt.AlignCenter)
                self.control_layout.addWidget(self.PyDMLineEdit_val, 1, 0)
                self.control_layout.addWidget(self.PyDMPushButton_stop, 2, 0)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_plus, 0,
                                              1)
                self.control_layout.addWidget(self.lineEdit_rlv, 1, 1)
                self.control_layout.addWidget(self.PyDMPushButton_rlv_minus, 2,
                                              1)

                self.motor_layout.addItem(self.scale_layout, 1, 0)
                self.motor_layout.addItem(self.header_layout, 0, 1)
                self.motor_layout.addWidget(self.frame_controls, 1, 1)
                self.motor_layout.addItem(self.readback_layout, 2, 1)

                if inverted == False:
                    self.scale.invertedAppearance = False
                    self.motor_layout.addWidget(self.PyDMLabel_hlm, 0, 0)
                    self.motor_layout.addWidget(self.PyDMLabel_llm, 2, 0)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignTop)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignBottom)
                elif inverted == True:
                    self.scale.invertedAppearance = True
                    self.motor_layout.addWidget(self.PyDMLabel_hlm, 2, 0)
                    self.motor_layout.addWidget(self.PyDMLabel_llm, 0, 0)
                    self.PyDMLabel_llm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignBottom)
                    self.PyDMLabel_hlm.setAlignment(Qt.AlignHCenter
                                                    | Qt.AlignTop)

        if self.frame_controls.layout() is not None:
            # Trick to remove the existing layout by re-parenting it in an empty widget.
            QWidget().setLayout(self.frame_controls.layout())
        self.frame_controls.setLayout(self.control_layout)

        if self.frame_motor.layout() is not None:
            QWidget().setLayout(self.frame_motor.layout())
        self.frame_motor.setLayout(self.motor_layout)

        # Top widget
        self.top_layout = QGridLayout()
        self.top_layout.addWidget(self.frame_motor, 0, 0)
        self.top_layout.setContentsMargins(1, 1, 1, 1)
        self.top_layout.setHorizontalSpacing(2)
        self.top_layout.setVerticalSpacing(2)

        if self.layout() is not None:
            QWidget().setLayout(self.layout())
        self.setLayout(self.top_layout)

        self.adjustSize()

    def set_limits_minimum_width(self):
        self.PyDMLabel_llm.adjustSize()
        self.PyDMLabel_hlm.adjustSize()

        llm_w = self.PyDMLabel_llm.width()
        hlm_w = self.PyDMLabel_hlm.width()

        self.PyDMLabel_llm.setMaximumSize(QWIDGETSIZE_MAX,
                                          QWIDGETSIZE_MAX)  # Unset fixed size
        self.PyDMLabel_hlm.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)

        if hlm_w > llm_w:
            minimum = hlm_w
            self.PyDMLabel_llm.setMinimumWidth(minimum)
        else:
            minimum = llm_w
        self.PyDMLabel_llm.setMinimumWidth(minimum + 20)
        self.PyDMLabel_hlm.setMinimumWidth(minimum + 20)

        self.PyDMLabel_rbv.adjustSize()
        w = self.PyDMLabel_rbv.width()
        self.lineEdit_rlv.setMinimumWidth(w + 20)
        self.PyDMLineEdit_val.setMinimumWidth(w + 20)

    def set_fields(self):
        if self.config_fields_file is None:
            self.config_fields_file = THIS_FOLDER + '/' + CONFIG_FIELDS_FILE  #Use fields default configuration

        with open(self.config_fields_file) as f:
            self.fields_map = yaml.load(f)

    def load_images(self):
        json_format = '{"0": "%s", "1": "%s"}'
        self.PyDMSymbol_lvio.imageFiles = json_format % (
            THIS_FOLDER + '/icons/exclamation0.svg',
            THIS_FOLDER + '/icons/exclamation1.svg')
        self.PyDMSymbol_movn.imageFiles = json_format % (
            THIS_FOLDER + '/icons/cached0.svg',
            THIS_FOLDER + '/icons/cached1.svg')
        self.PyDMSymbol_lls.imageFiles = json_format % (
            THIS_FOLDER + '/icons/exclamation0.svg',
            THIS_FOLDER + '/icons/exclamation1.svg')
        self.PyDMSymbol_athm.imageFiles = json_format % (
            THIS_FOLDER + '/icons/home0.svg', THIS_FOLDER + '/icons/home1.svg')
        self.PyDMSymbol_hls.imageFiles = json_format % (
            THIS_FOLDER + '/icons/exclamation0.svg',
            THIS_FOLDER + '/icons/exclamation1.svg')

    def load_ui(self):
        f = THIS_FOLDER + '/' + self.get_ui_filename()
        self.ui = uic.loadUi(f, baseinstance=self)
        self.load_images()

    def load_settings_ui(self):
        if self.settings_window != None:
            self.settings_window.show()
            self.settings_window.raise_()
            return
        self.fields_map[
            'MOTOR'] = self._channel  # Add motor prefix to fields dict
        self.settings_window = QMotorSettings(parent=self,
                                              fields_map=self.fields_map)
        try:
            self.app.make_connections()  # Connect settings window to PVs
        except:
            pass

    def set_press_values(self, value):
        self.PyDMPushButton_rlv_minus.pressValue = '-' + str(value)
        self.PyDMPushButton_rlv_plus.pressValue = str(value)

    def set_all_channels(self, channel):
        if channel is None:
            return
        # Monitors
        self.PyDMLabel_desc.channel = channel + self.fields_map['DESC']
        self.PyDMLabel_rbv.channel = channel + self.fields_map['RBV']
        self.PyDMSymbol_lvio.channel = channel + self.fields_map['LVIO']
        self.PyDMSymbol_movn.channel = channel + self.fields_map['MOVN']
        self.scale.channel = channel + self.fields_map['RBV']
        self.PyDMSymbol_athm.channel = channel + self.fields_map['ATHM']
        self.PyDMSymbol_lls.channel = channel + self.fields_map['LLS']
        self.PyDMSymbol_hls.channel = channel + self.fields_map['HLS']
        self.PyDMLabel_hlm.channel = channel + self.fields_map['HLM']
        self.PyDMLabel_llm.channel = channel + self.fields_map['LLM']
        # Controls
        self.PyDMPushButton_rlv_minus.channel = channel + self.fields_map['RLV']
        self.PyDMPushButton_rlv_plus.channel = channel + self.fields_map['RLV']
        self.PyDMCheckbox_set.channel = channel + self.fields_map['SET']
        self.PyDMLineEdit_val.channel = channel + self.fields_map['VAL']
        self.PyDMPushButton_stop.channel = channel + self.fields_map['STOP']
        # Icon tooltips
        self.PyDMSymbol_lvio.setToolTip(self.fields_map['LVIO_TOOLTIP'])
        self.PyDMSymbol_movn.setToolTip(self.fields_map['MOVN_TOOLTIP'])
        self.PyDMSymbol_lls.setToolTip(self.fields_map['LLS_TOOLTIP'])
        self.PyDMSymbol_athm.setToolTip(self.fields_map['ATHM_TOOLTIP'])
        self.PyDMSymbol_hls.setToolTip(self.fields_map['HLS_TOOLTIP'])

    @pyqtProperty(str)
    def channel(self):
        """
        The channel address in use for this widget.

        Returns
        -------
        channel : str
            Channel address
        """
        return str(self._channel)

    @channel.setter
    def channel(self, value):
        """
        The channel address to use for this widget.

        Parameters
        ----------
        value : str
            Channel address
        """
        if self._channel != value:
            self._channel = str(value)
            self.set_all_channels(self._channel)

    @pyqtProperty(Qt.Orientation)
    def orientation(self):
        """
        The orientation of the motor scale.

        Returns
        -------
        orientation : Qt.Orientation
            Orientation of the motor scale
        """
        return self._orientation

    @orientation.setter
    def orientation(self, orientation):
        """
        The orientation of the motor scale.

        Parameters
        ----------
        orientation : Qt.Orientation
            Channel address
        """
        if self._orientation != orientation:
            self._orientation = orientation
            self.build_layout(orientation, self._flipped, self._inverted_scale)

    @pyqtProperty(bool)
    def flipped(self):
        """
        Whether or not the motor layout is flipped.

        Returns
        -------
        bool
        """
        return self._flipped

    @flipped.setter
    def flipped(self, flipped):
        """
        Whether or not the motor layout is flipped.

        Parameters
        ----------
        flipped : bool
        """
        if self._flipped != flipped:
            self._flipped = flipped
            self.build_layout(self._orientation, flipped, self._inverted_scale)

    @pyqtProperty(bool)
    def invertedScale(self):
        """
        Whether or not the motor scale is inverted.

        Returns
        -------
        bool
        """
        return self._inverted_scale

    @invertedScale.setter
    def invertedScale(self, inverted):
        """
        Whether or not the motor scale is inverted.

        Parameters
        ----------
        flipped : bool
        """
        if self._inverted_scale != inverted:
            self._inverted_scale = inverted
            self.build_layout(self._orientation, self._flipped, inverted)
예제 #8
0
    def setglobalparameters(self):
        wid = QWidget(self.centralWidget())
        wid.setSizePolicy(QSzPol.Preferred, QSzPol.Maximum)
        lay = QGridLayout(wid)

        evg_dev = SiriusPVName(LLTimeSearch.get_evg_name())
        evg_pref = evg_dev.substitute(prefix=self.prefix)
        sp = PyDMPushButton(
            self,
            init_channel=evg_pref.substitute(propty='UpdateEvt-Cmd'),
            pressValue=1)
        sp.setIcon(qta.icon('fa5s.sync'))
        sp.setToolTip('Update Events Table')
        sp.setObjectName('but')
        sp.setStyleSheet(
            '#but{min-width:25px; max-width:25px; icon-size:20px;}')
        rb = PyDMLed(
            self, init_channel=evg_pref.substitute(propty='EvtSyncStatus-Mon'))
        rb.setOffColor(rb.Red)
        rb.setOnColor(rb.LightGreen)
        lay.addWidget(
            self._create_prop_widget('<h4>Update Evts</h4>', wid, (sp, rb)), 0,
            0)

        sp = PyDMStateButton(
            self, init_channel=evg_pref.substitute(propty='ContinuousEvt-Sel'))
        rb = PyDMLed(
            self, init_channel=evg_pref.substitute(propty='ContinuousEvt-Sts'))
        lay.addWidget(
            self._create_prop_widget('<h4>Continuous</h4>', wid, (sp, rb)), 0,
            1)

        sp = PyDMStateButton(
            self, init_channel=evg_pref.substitute(propty='InjectionEvt-Sel'))
        rb = PyDMLed(
            self, init_channel=evg_pref.substitute(propty='InjectionEvt-Sts'))
        lay.addWidget(
            self._create_prop_widget('<h4>Injection</h4>', wid, (sp, rb)), 0,
            2)

        bucketlist_wid = BucketList(self.centralWidget(), evg_dev, self.prefix)
        bucketlist_wid.setSizePolicy(QSzPol.MinimumExpanding, QSzPol.Preferred)
        lay.addWidget(bucketlist_wid, 0, 3, 2, 1)

        hlay = QHBoxLayout()
        lab = QLabel('Inj Count:', wid)
        pydmlab = PyDMLabel(
            wid, init_channel=evg_pref.substitute(propty='InjCount-Mon'))
        pydmlab.setStyleSheet('min-width:5em;')
        pydmlab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        hlay.addStretch()
        hlay.addWidget(lab)
        hlay.addWidget(pydmlab)
        hlay.addStretch()
        pydmlab = PyDMLabel(
            wid, init_channel=evg_pref.substitute(propty='STATEMACHINE'))
        pydmlab.setStyleSheet('min-width:10em;')
        hlay.addWidget(pydmlab)
        hlay.addStretch()
        pydmlab = PyDMLabel(
            wid, init_channel=evg_pref.substitute(propty='SeqCount-SP'))
        pydmlab.rules =\
            '[{"name": "VisibleRule", "property": "Visible", ' +\
            '"expression": "ch[0]==5", "channels": [{"channel": "' +\
            evg_pref.substitute(propty_name='STATEMACHINE') +\
            '", "trigger": true}]}]'
        pydmlab.setStyleSheet('min-width:3em;')
        hlay.addWidget(pydmlab)
        hlay.addStretch()
        lay.addItem(hlay, 1, 0, 1, 3)
        return wid
예제 #9
0
파일: main.py 프로젝트: lnls-sirius/hla
class InjCtrlWindow(SiriusMainWindow):
    """InjCtrl Main Window."""

    showMonitor = Signal()
    showStatus = Signal()
    showEgun = Signal()

    def __init__(self, parent=None, prefix=''):
        """Init."""
        super().__init__(parent)
        self._prefix = prefix
        self._inj_dev = SiriusPVName('AS-Glob:AP-InjCtrl')
        self._inj_prefix = self._inj_dev.substitute(prefix=prefix)
        self.setWindowTitle('Injection Controls')
        self.setObjectName('ASApp')
        self.setWindowIcon(
            qta.icon('fa5s.syringe', color=get_appropriate_color('AS')))

        self._setupUi()

        self.setFocus(True)
        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        self.title = QLabel('<h3>Injection Control<h3>',
                            self,
                            alignment=Qt.AlignCenter)
        self.title.setStyleSheet('QLabel{max-height:1.6em;}')

        self.wid_comm = self._setupMainBarWidget()
        self.wid_comm.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed)

        self.wid_sett = self._setupSettingsWidget()
        self.wid_sett.setSizePolicy(QSzPlcy.Preferred,
                                    QSzPlcy.MinimumExpanding)

        self.wid_mon = self._setupMonitorWidget()
        self.wid_log = self._setupLogWidget()
        wid_row = QWidget()
        wid_row.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed)
        hbox_row = QHBoxLayout(wid_row)
        hbox_row.setContentsMargins(0, 0, 0, 0)
        hbox_row.setStretch(0, 3)
        hbox_row.setStretch(1, 5)
        hbox_row.addWidget(self.wid_mon)
        hbox_row.addWidget(self.wid_log)

        wid = QWidget(self)
        lay = QVBoxLayout(wid)
        lay.addWidget(self.title)
        lay.addWidget(self.wid_comm)
        lay.addWidget(self.wid_comm)
        lay.addWidget(self.wid_sett)
        lay.addWidget(wid_row)
        lay.setStretch(1, 1)
        lay.setStretch(2, 3)
        lay.setStretch(3, 2)
        self.setCentralWidget(wid)

        self._ch_injmode = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='Mode-Sel'))
        self._ch_injmode.new_value_signal[int].connect(
            self._handle_injmode_settings_vis)

        # connect window signals
        connect_newprocess(self,
                           'sirius-hla-as-ap-monitor.py',
                           parent=self,
                           signal=self.showMonitor)
        connect_newprocess(self,
                           'sirius-hla-si-ap-genstatus.py',
                           parent=self,
                           signal=self.showStatus)
        connect_newprocess(self,
                           'sirius-hla-li-eg-control.py',
                           parent=self,
                           signal=self.showEgun)

    def _setupMainBarWidget(self):
        # Shift
        machshift_pvname = SiriusPVName(
            'AS-Glob:AP-MachShift:Mode-Sel').substitute(prefix=self._prefix)
        self._cb_shift = SiriusEnumComboBox(self, machshift_pvname)
        self._lb_shift = MachShiftLabel(self, prefix=self._prefix)
        self._lb_shift.setStyleSheet(
            'QLabel{max-height: 2em; min-width: 7em;}')
        self.wid_shift = QGroupBox('Mach.Shift', self)
        lay_shift = QVBoxLayout(self.wid_shift)
        lay_shift.addWidget(self._cb_shift)
        lay_shift.addWidget(self._lb_shift)

        # Injection System
        self.wid_is_summ = InjSysStbyControlWidget(self, is_summary=True)
        self.wid_injsys = QGroupBox('Inj.System', self)
        lay_injsys = QGridLayout(self.wid_injsys)
        lay_injsys.setContentsMargins(0, 0, 0, 0)
        lay_injsys.addWidget(self.wid_is_summ, 0, 0)
        # self.wid_is_full = InjSysStbyControlWidget(self, is_summary=False)
        # self.wid_is_full.setVisible(False)
        # lay_injsys.addWidget(self.wid_is_full, 0, 0)
        # self._icon_expd = qta.icon('fa5s.plus')
        # self._icon_comp = qta.icon('fa5s.minus')
        # self.bt_is_tgl = QPushButton(self._icon_expd, '', self)
        # self.bt_is_tgl.clicked.connect(self._handle_injsys_details_vis)
        # self.bt_is_tgl.setObjectName('bt')
        # self.bt_is_tgl.setStyleSheet("""
        #     #bt{
        #         min-width: 0.8em; max-width: 0.8em;
        #         min-height: 0.8em; max-height: 0.8em;
        #         icon-size:12px;}
        # """)
        # lay_injsys.addWidget(
        #     self.bt_is_tgl, 0, 1, alignment=Qt.AlignRight | Qt.AlignBottom)

        # EGun
        egun_dev = SiriusPVName('LI-01:EG-TriggerPS').substitute(
            prefix=self._prefix)
        self._sb_eguntrg = PyDMStateButton(
            self, egun_dev.substitute(propty_name='enable'))
        self._led_eguntrg = SiriusLedState(
            self, egun_dev.substitute(propty_name='enablereal'))
        self._led_eguntrg.setStyleSheet(
            'QLed{min-width: 1.29em; max-width: 1.29em;}')
        self.wid_egun = self._create_groupwidget('EGun Trig.', [
            self._sb_eguntrg,
        ], [
            self._led_eguntrg,
        ])

        # Injection
        self._pb_tiinj = EVGInjectionButton(self, self._prefix)
        self._pb_topup = PyDMStateButton(
            self,
            init_channel=self._inj_prefix.substitute(propty='TopUpState-Sel'))
        self._pb_topup.setVisible(False)
        self._led_injti = EVGInjectionLed(self, self._prefix)
        self._lb_injcnt = PyDMLabel(self)
        self._lb_injcnt.setToolTip(
            'Count injection pulses when Egun Trigger is enabled.')
        ch_injcnt = SiriusPVName(
            'AS-Glob:AP-CurrInfo:InjCount-Mon').substitute(prefix=self._prefix)
        self._lb_injcnt.channel = ch_injcnt
        self._lb_injcnt.setStyleSheet('QLabel{max-width: 3.5em;}')
        hbox_injsts = QHBoxLayout()
        hbox_injsts.setContentsMargins(0, 0, 0, 0)
        hbox_injsts.addWidget(self._led_injti)
        hbox_injsts.addWidget(self._lb_injcnt)
        self.wid_inj = QGroupBox('Injection', self)
        lay_inj = QGridLayout(self.wid_inj)
        lay_inj.setAlignment(Qt.AlignCenter)
        lay_inj.addWidget(self._pb_tiinj, 0, 0)
        lay_inj.addWidget(self._pb_topup, 0, 0)
        lay_inj.addLayout(hbox_injsts, 1, 0)

        # Current
        curr_pvname = SiriusPVName(
            'SI-Glob:AP-CurrInfo:Current-Mon').substitute(prefix=self._prefix)
        self._lb_curr = PyDMLabel(self, curr_pvname)
        self._lb_curr.showUnits = True
        self._lb_curr.setStyleSheet("""
            QLabel{
                font-size: 18pt; qproperty-alignment: AlignCenter;
                min-width: 5.5em; max-width: 5.5em;
        }""")
        self.wid_curr = QGroupBox('Current', self)
        lay_curr = QHBoxLayout(self.wid_curr)
        lay_curr.addWidget(self._lb_curr)

        # TopUp status
        self._lb_tusts = PyDMLabel(
            self, self._inj_prefix.substitute(propty='TopUpState-Sts'))
        self._lb_tusts.setAlignment(Qt.AlignCenter)
        self._lb_tusts.setStyleSheet('QLabel{max-height:2em;}')
        self._ld_tunow = QLabel('Now:',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        self._lb_tunow = ClockLabel(self)
        self._lb_tunow.setStyleSheet('QLabel{max-height:2em;}')
        self._ld_tunxt = QLabel('Next:',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        self._lb_tunxt = SiriusLabel(
            self, self._inj_prefix.substitute(propty='TopUpNextInj-Mon'))
        self._lb_tunxt.displayFormat = SiriusLabel.DisplayFormat.Time
        self._lb_tunxt.setAlignment(Qt.AlignCenter)
        self._lb_tunxt.setStyleSheet('QLabel{max-height:2em;}')
        self._pb_round = PyDMPushButton(
            self,
            label='',
            icon=qta.icon('mdi.tilde'),
            pressValue=1,
            init_channel=self._inj_prefix.substitute(
                propty='TopUpNextInjRound-Cmd'))
        self._pb_round.setObjectName('but')
        self._pb_round.setStyleSheet(
            '#but{min-width:18px; max-width:18px; icon-size:16px;}')
        self.wid_tusts = QGroupBox('Top-up status')
        self.wid_tusts.setVisible(False)
        lay_tusts = QGridLayout(self.wid_tusts)
        lay_tusts.addWidget(self._lb_tusts, 0, 0, 1, 2)
        lay_tusts.addWidget(self._ld_tunow, 1, 0)
        lay_tusts.addWidget(self._lb_tunow, 1, 1)
        lay_tusts.addWidget(self._ld_tunxt, 2, 0)
        lay_tusts.addWidget(self._lb_tunxt, 2, 1)
        lay_tusts.addWidget(self._pb_round, 2, 2)

        wid = QWidget()
        lay = QGridLayout(wid)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addWidget(self.wid_shift, 0, 0)
        lay.addWidget(self.wid_injsys, 0, 1)
        lay.addWidget(self.wid_egun, 0, 2)
        lay.addWidget(self.wid_inj, 0, 3)
        lay.addWidget(self.wid_tusts, 0, 4)
        lay.addWidget(self.wid_curr, 0, 5)
        lay.setColumnStretch(0, 3)
        lay.setColumnStretch(1, 2)
        lay.setColumnStretch(2, 2)
        lay.setColumnStretch(3, 2)
        lay.setColumnStretch(4, 4)
        lay.setColumnStretch(5, 3)
        wid.setStyleSheet('.QLabel{min-height: 1em; max-height: 1em;}')
        return wid

    def _setupSettingsWidget(self):
        # group of labels to set the same stylesheet
        labelsdesc, labelsmon = list(), list()

        # Mode
        self._ld_injmode = QLabel('Mode', self)
        labelsdesc.append(self._ld_injmode)
        self._cb_injmode = SiriusEnumComboBox(
            self, self._inj_prefix.substitute(propty='Mode-Sel'))
        self._lb_injmode = PyDMLabel(
            self, self._inj_prefix.substitute(propty='Mode-Sts'))
        self._lb_injmode.showUnits = True
        labelsmon.append(self._lb_injmode)

        # Target current
        self._ld_currtgt = QLabel('Target Curr.', self)
        labelsdesc.append(self._ld_currtgt)
        self._sb_currtgt = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='TargetCurrent-SP'))
        self._sb_currtgt.showStepExponent = False
        self._lb_currtgt = PyDMLabel(
            self, self._inj_prefix.substitute(propty='TargetCurrent-RB'))
        self._lb_currtgt.showUnits = True
        labelsmon.append(self._lb_currtgt)

        # mode specific configurations
        self.wid_dcdtls = self._setupDecayModeWidget()
        self.wid_tudtls = self._setupTopUpModeWidget()
        self.wid_tudtls.setVisible(False)

        # Mon
        self._ld_injset = QLabel('Setup ok', self)
        labelsdesc.append(self._ld_injset)
        self._led_injset = InjDiagLed(self)

        # Type
        self._ld_injtype = QLabel('Type', self)
        labelsdesc.append(self._ld_injtype)
        self._cb_injtype = SiriusEnumComboBox(
            self, self._inj_prefix.substitute(propty='Type-Sel'))
        self._lb_injtype = PyDMLabel(
            self, self._inj_prefix.substitute(propty='Type-Sts'))
        labelsmon.append(self._lb_injtype)
        self._lb_injtype_mon = PyDMLabel(
            self, self._inj_prefix.substitute(propty='Type-Mon'))
        labelsmon.append(self._lb_injtype_mon)
        self._ch_injtype = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='Type-Sel'))
        self._ch_injtype.new_value_signal[int].connect(
            self._handle_injtype_settings_vis)

        # Single bunch bias voltage
        self._ld_sbbias = QLabel('SB Bias Voltage', self)
        labelsdesc.append(self._ld_sbbias)
        self._sb_sbbias = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='SglBunBiasVolt-SP'))
        self._sb_sbbias.showStepExponent = False
        self._lb_sbbias = PyDMLabel(
            self, self._inj_prefix.substitute(propty='SglBunBiasVolt-RB'))
        self._lb_sbbias.showUnits = True
        labelsmon.append(self._lb_sbbias)
        self._ld_sbbias.setVisible(False)
        self._sb_sbbias.setVisible(False)
        self._lb_sbbias.setVisible(False)

        # Multi bunch bias voltage
        self._ld_mbbias = QLabel('MB Bias Volt.', self)
        labelsdesc.append(self._ld_mbbias)
        self._sb_mbbias = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='MultBunBiasVolt-SP'))
        self._sb_mbbias.showStepExponent = False
        self._lb_mbbias = PyDMLabel(
            self, self._inj_prefix.substitute(propty='MultBunBiasVolt-RB'))
        self._lb_mbbias.showUnits = True
        labelsmon.append(self._lb_mbbias)

        # bias voltage mon
        ch_bias_mon = SiriusPVName('LI-01:EG-BiasPS').substitute(
            prefix=self._prefix, propty_name='voltinsoft')
        self._lb_bias_mon = PyDMLabel(self, ch_bias_mon)
        self._lb_bias_mon.showUnits = True
        labelsmon.append(self._lb_bias_mon)

        # Filament current op value
        self._ld_filaopcurr = QLabel('Fila.Op. Curr.', self)
        labelsdesc.append(self._ld_filaopcurr)
        self._sb_filaopcurr = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='FilaOpCurr-SP'))
        self._sb_filaopcurr.showStepExponent = False
        self._lb_filaopcurr = PyDMLabel(
            self, self._inj_prefix.substitute(propty='FilaOpCurr-RB'))
        self._lb_filaopcurr.showUnits = True
        labelsmon.append(self._lb_filaopcurr)
        ch_filacurr_mon = SiriusPVName('LI-01:EG-FilaPS').substitute(
            prefix=self._prefix, propty_name='currentinsoft')
        self._lb_filaopcurr_mon = PyDMLabel(self, ch_filacurr_mon)
        self._lb_filaopcurr_mon.showUnits = True
        labelsmon.append(self._lb_filaopcurr_mon)

        # High voltage op value
        self._ld_hvopvolt = QLabel('HV.Op. Volt.', self)
        labelsdesc.append(self._ld_hvopvolt)
        self._sb_hvopvolt = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='HVOpVolt-SP'))
        self._sb_hvopvolt.showStepExponent = False
        self._lb_hvopvolt = PyDMLabel(
            self, self._inj_prefix.substitute(propty='HVOpVolt-RB'))
        self._lb_hvopvolt.showUnits = True
        labelsmon.append(self._lb_hvopvolt)
        ch_hvvolt_mon = SiriusPVName('LI-01:EG-HVPS').substitute(
            prefix=self._prefix, propty_name='voltinsoft')
        self._lb_hvopvolt_mon = PyDMLabel(self, ch_hvvolt_mon)
        self._lb_hvopvolt_mon.showUnits = True
        labelsmon.append(self._lb_hvopvolt_mon)

        # header
        ld_sp = QLabel('<h4>SP</h4>', self, alignment=Qt.AlignCenter)
        ld_rb = QLabel('<h4>RB</h4>', self, alignment=Qt.AlignCenter)
        ld_mon = QLabel('<h4>Mon</h4>', self, alignment=Qt.AlignCenter)

        # Bucket list
        self._wid_bl = BucketList(self,
                                  prefix=self._prefix,
                                  min_size=15,
                                  show_graph=True)
        self._wid_bl.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.MinimumExpanding)

        wid1 = QWidget()
        wid1.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed)
        glay1 = QGridLayout(wid1)
        glay1.setAlignment(Qt.AlignTop)
        glay1.addWidget(self._ld_injset, 0, 0)
        glay1.addWidget(self._led_injset, 0, 1)
        glay1.addWidget(self._ld_injmode, 1, 0)
        glay1.addWidget(self._cb_injmode, 1, 1)
        glay1.addWidget(self._lb_injmode, 1, 2)
        glay1.addWidget(self._ld_currtgt, 2, 0)
        glay1.addWidget(self._sb_currtgt, 2, 1)
        glay1.addWidget(self._lb_currtgt, 2, 2)
        glay1.addWidget(self.wid_tudtls, 3, 0, 2, 3)
        glay1.addWidget(self.wid_dcdtls, 3, 0, 2, 3)
        glay1.setColumnStretch(0, 3)
        glay1.setColumnStretch(1, 2)
        glay1.setColumnStretch(2, 2)

        wid2 = QWidget()
        wid2.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed)
        glay2 = QGridLayout(wid2)
        glay2.setAlignment(Qt.AlignTop)
        glay2.addWidget(ld_sp, 0, 1)
        glay2.addWidget(ld_rb, 0, 2)
        glay2.addWidget(ld_mon, 0, 3)
        glay2.addWidget(self._ld_injtype, 1, 0)
        glay2.addWidget(self._cb_injtype, 1, 1)
        glay2.addWidget(self._lb_injtype, 1, 2)
        glay2.addWidget(self._lb_injtype_mon, 1, 3)
        glay2.addWidget(self._ld_sbbias, 2, 0)
        glay2.addWidget(self._sb_sbbias, 2, 1)
        glay2.addWidget(self._lb_sbbias, 2, 2)
        glay2.addWidget(self._ld_mbbias, 2, 0)
        glay2.addWidget(self._sb_mbbias, 2, 1)
        glay2.addWidget(self._lb_mbbias, 2, 2)
        glay2.addWidget(self._lb_bias_mon, 2, 3)
        glay2.addWidget(self._ld_filaopcurr, 4, 0)
        glay2.addWidget(self._sb_filaopcurr, 4, 1)
        glay2.addWidget(self._lb_filaopcurr, 4, 2)
        glay2.addWidget(self._lb_filaopcurr_mon, 4, 3)
        glay2.addWidget(self._ld_hvopvolt, 5, 0)
        glay2.addWidget(self._sb_hvopvolt, 5, 1)
        glay2.addWidget(self._lb_hvopvolt, 5, 2)
        glay2.addWidget(self._lb_hvopvolt_mon, 5, 3)
        glay2.setColumnStretch(0, 3)
        glay2.setColumnStretch(1, 2)
        glay2.setColumnStretch(2, 2)
        glay2.setColumnStretch(3, 2)

        wid = QGroupBox('Settings')
        lay = QGridLayout(wid)
        lay.addWidget(wid1, 0, 0, alignment=Qt.AlignTop)
        lay.addWidget(wid2, 0, 1, alignment=Qt.AlignTop)
        lay.addWidget(self._wid_bl, 1, 0, 1, 2)
        lay.setColumnStretch(0, 3)
        lay.setColumnStretch(1, 4)

        for lbl in labelsdesc:
            lbl.setStyleSheet("""
                QLabel{
                    min-width: 6.5em; max-width: 6.5em; min-height: 1.5em;
                    qproperty-alignment: 'AlignRight | AlignVCenter';
                }""")
        for lbl in labelsmon:
            lbl.setStyleSheet("PyDMLabel{qproperty-alignment: AlignCenter;}")

        return wid

    def _setupTopUpModeWidget(self):
        self._ld_tuperd = QLabel('Period', self)
        self._sb_tuperd = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='TopUpPeriod-SP'))
        self._sb_tuperd.showStepExponent = False
        self._lb_tuperd = PyDMLabel(
            self, self._inj_prefix.substitute(propty='TopUpPeriod-RB'))
        self._lb_tuperd.showUnits = True

        self._ld_tumaxpu = QLabel('Max.Nr.Pulses', self)
        self._sb_tumaxpu = SiriusSpinbox(
            self, self._inj_prefix.substitute(propty='TopUpMaxNrPulses-SP'))
        self._sb_tumaxpu.showStepExponent = False
        self._lb_tumaxpu = PyDMLabel(
            self, self._inj_prefix.substitute(propty='TopUpMaxNrPulses-RB'))
        self._lb_tumaxpu.showUnits = True

        wid = QWidget()
        lay = QGridLayout(wid)
        lay.setContentsMargins(0, 6, 0, 0)
        lay.setAlignment(Qt.AlignTop)
        lay.addWidget(self._ld_tuperd, 0, 0)
        lay.addWidget(self._sb_tuperd, 0, 1)
        lay.addWidget(self._lb_tuperd, 0, 2)
        lay.addWidget(self._ld_tumaxpu, 1, 0)
        lay.addWidget(self._sb_tumaxpu, 1, 1)
        lay.addWidget(self._lb_tumaxpu, 1, 2)
        lay.setColumnStretch(0, 3)
        lay.setColumnStretch(1, 2)
        lay.setColumnStretch(2, 2)

        wid.setStyleSheet("""
            .QLabel{
                min-width: 6.5em; max-width: 6.5em; min-height: 1.5em;
                qproperty-alignment: 'AlignRight | AlignVCenter';
            }
            PyDMLabel{
                qproperty-alignment: AlignCenter;
            }""")
        return wid

    def _setupDecayModeWidget(self):
        self._ld_autostop = QLabel('Auto Stop', self)
        self._cb_autostop = PyDMStateButton(
            self, self._inj_prefix.substitute(propty='AutoStop-Sel'))
        self._cb_autostop.shape = 1
        self._led_autostop = SiriusLedState(
            self, self._inj_prefix.substitute(propty='AutoStop-Sts'))

        wid = QWidget()
        lay = QGridLayout(wid)
        lay.setAlignment(Qt.AlignTop)
        lay.setContentsMargins(0, 6, 0, 0)
        lay.addWidget(self._ld_autostop, 0, 0)
        lay.addWidget(self._cb_autostop, 0, 1)
        lay.addWidget(self._led_autostop, 0, 2)
        lay.setColumnStretch(0, 3)
        lay.setColumnStretch(1, 2)
        lay.setColumnStretch(2, 2)

        wid.setStyleSheet("""
            .QLabel{
                min-width: 6.5em; max-width: 6.5em; min-height: 1.5em;
                qproperty-alignment: 'AlignRight | AlignVCenter';
            }
            PyDMLabel{
                qproperty-alignment: AlignCenter;
            }""")
        return wid

    def _setupLogWidget(self):
        self._log = PyDMLogLabel(self,
                                 self._inj_prefix.substitute(propty='Log-Mon'),
                                 [
                                     'Remaining time',
                                 ])

        wid = QGroupBox('Log')
        lay = QHBoxLayout(wid)
        lay.addWidget(self._log)
        return wid

    def _setupMonitorWidget(self):
        self.wid_mon = MonitorSummaryWidget(self)

        wid = QWidget(self)
        lay = QGridLayout(wid)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addWidget(self.wid_mon, 0, 0)
        return wid

    # ---- auxiliary commands ----

    @Slot(int)
    def _handle_injtype_settings_vis(self, new_type):
        is_sb = new_type == _Const.InjType.SingleBunch
        self._ld_sbbias.setVisible(is_sb)
        self._sb_sbbias.setVisible(is_sb)
        self._lb_sbbias.setVisible(is_sb)
        self._ld_mbbias.setVisible(not is_sb)
        self._sb_mbbias.setVisible(not is_sb)
        self._lb_mbbias.setVisible(not is_sb)
        self.centralWidget().adjustSize()
        self.adjustSize()

    @Slot(int)
    def _handle_injmode_settings_vis(self, new_mode):
        is_topoup = new_mode == _Const.InjMode.TopUp
        self.wid_tudtls.setVisible(is_topoup)
        self._pb_topup.setVisible(is_topoup)
        self.wid_dcdtls.setVisible(not is_topoup)
        self._pb_tiinj.setVisible(not is_topoup)
        self.wid_tusts.setVisible(is_topoup)

    def _handle_injsys_details_vis(self):
        exp = self.wid_is_summ.isVisible()
        icon = self._icon_comp if exp else self._icon_expd
        self.sender().setIcon(icon)
        self.wid_is_summ.setVisible(not exp)
        self.wid_is_full.setVisible(exp)
        self.centralWidget().adjustSize()
        self.adjustSize()

    def _create_groupwidget(self, title, sp_wids, rb_wids, aux_wids=None):
        hbox_sp = QHBoxLayout()
        hbox_sp.setAlignment(Qt.AlignCenter)
        hbox_sp.setContentsMargins(0, 0, 0, 0)
        for wid in sp_wids:
            hbox_sp.addWidget(wid)

        hbox_rb = QHBoxLayout()
        hbox_rb.setAlignment(Qt.AlignCenter)
        hbox_rb.setContentsMargins(0, 0, 0, 0)
        for wid in rb_wids:
            hbox_rb.addWidget(wid)

        box = QGroupBox(title, self) if title else QWidget(self)
        lay = QVBoxLayout(box)
        lay.setAlignment(Qt.AlignCenter)
        if not isinstance(box, QGroupBox):
            lay.setContentsMargins(0, 0, 0, 0)
        lay.addLayout(hbox_sp)
        lay.addLayout(hbox_rb)

        if aux_wids:
            hbox_aux = QHBoxLayout()
            hbox_aux.setAlignment(Qt.AlignCenter)
            hbox_aux.setContentsMargins(0, 0, 0, 0)
            for wid in aux_wids:
                hbox_aux.addWidget(wid)
            lay.addLayout(hbox_aux)
        return box

    # ---- events ----

    def mouseDoubleClickEvent(self, event):
        """Implement mouseDoubleClickEvent."""
        if event.button() == Qt.LeftButton:
            if self.wid_curr.underMouse():
                self.showStatus.emit()
            elif self.wid_shift.underMouse():
                self.showStatus.emit()
            elif self.wid_egun.underMouse():
                self.showEgun.emit()
            elif self.wid_mon.underMouse():
                self.showMonitor.emit()
        super().mouseDoubleClickEvent(event)

    def changeEvent(self, event):
        """Implement changeEvent."""
        if event.type() == QEvent.FontChange:
            fontsize = self.app.font().pointSize()
            self._lb_curr.setStyleSheet('QLabel{'
                                        '    font-size: ' + str(fontsize + 8) +
                                        'pt;'
                                        '    qproperty-alignment: AlignCenter;'
                                        '    min-width: 6em; max-width: 6em;'
                                        '}')
            self.ensurePolished()
예제 #10
0
class SummaryWidget(QWidget):
    """General widget for controlling a power supply."""
    def __init__(self, name, visible_props, parent=None):
        """Build UI with dclink name."""
        super().__init__(parent)
        self._name = PVName(name)
        self._psmodel = PSSearch.conv_psname_2_psmodel(name)
        self._pstype = PSSearch.conv_psname_2_pstype(name)
        self.visible_props = sort_propties(visible_props)
        self.filled_widgets = set()
        self._prefixed_name = self._name.substitute(prefix=VACA_PREFIX)

        self._analog_name = get_analog_name(self._name)
        self._strength_name = get_strength_name(self._name)
        self._is_pulsed = IsPulsed.match(self._name)
        self._is_linac = IsLinac.match(self._name)
        self._li_has_not_strength = LIQuadHasNotStrength.match(self._name)
        self._is_fofb = FastCorrector.match(self._name)
        self._is_dclink = IsDCLink.match(self._name)
        self._is_regatron = self._psmodel == 'REGATRON_DCLink'
        self._is_reg_slave = self._pstype == 'as-dclink-regatron-slave'

        self._bbb_name = ''
        self._udc_name = ''
        if not self._is_pulsed and not self._is_linac and \
                not self._is_regatron and not self._is_fofb:
            self._bbb_name = PSSearch.conv_psname_2_bbbname(self._name)
            self._udc_name = PSSearch.conv_psname_2_udc(self._name)
        self._has_opmode = not self._is_linac and not self._is_pulsed\
            and not self._is_fofb
        self._has_ctrlmode = not self._is_regatron and not self._is_linac\
            and not self._is_fofb
        self._has_pwrstate = not self._is_reg_slave
        self._has_reset = not self._is_linac and not self._is_fofb\
            and not self._is_reg_slave
        self._has_ctrlloop = not self._is_linac and not self._is_pulsed\
            and not self._is_regatron
        self._has_parmupdt = not self._is_linac and not self._is_regatron\
            and not self._is_fofb
        self._has_wfmupdt = self._has_parmupdt and not self._is_dclink
        self._has_analsp = not self._is_reg_slave
        self._has_analrb = not self._is_regatron
        self._has_analmon = not self._is_fofb
        self._has_strength = bool(self._strength_name
                                  and not self._li_has_not_strength)
        self._has_strength_mon = self._has_strength and not self._is_fofb
        self._has_trim = HasTrim.match(self._name)

        self._create_pvs()
        self._setup_ui()

    @property
    def devname(self):
        """PS name."""
        return self._name

    @property
    def bbbname(self):
        """BBB name."""
        return self._bbb_name

    @property
    def udcname(self):
        """UDC name."""
        return self._udc_name

    def _setup_ui(self):
        """Setups widget UI."""
        lay = QHBoxLayout()
        lay.setContentsMargins(0, 0, 0, 0)
        lay.setSpacing(10)
        self._widgets_dict = dict()

        self.detail_wid = self._build_widget(name='detail', orientation='v')
        self._widgets_dict['detail'] = self.detail_wid
        lay.addWidget(self.detail_wid)

        if self._bbb_name:
            self.bbb_wid = self._build_widget(name='bbb', orientation='v')
            self._widgets_dict['bbb'] = self.bbb_wid
            lay.addWidget(self.bbb_wid)

        if self._udc_name:
            self.udc_wid = self._build_widget(name='udc', orientation='v')
            self._widgets_dict['udc'] = self.udc_wid
            lay.addWidget(self.udc_wid)

        if self._has_opmode:
            self.opmode_wid = self._build_widget(name='opmode',
                                                 orientation='v')
            self._widgets_dict['opmode'] = self.opmode_wid
            lay.addWidget(self.opmode_wid)

        if self._has_ctrlmode:
            self.ctrlmode_wid = self._build_widget(name='ctrlmode',
                                                   orientation='v')
            self._widgets_dict['ctrlmode'] = self.ctrlmode_wid
            lay.addWidget(self.ctrlmode_wid)

        self.state_wid = self._build_widget(name='state')
        self._widgets_dict['state'] = self.state_wid
        lay.addWidget(self.state_wid)

        if self._is_pulsed:
            self.pulse_wid = self._build_widget(name='pulse')
            self._widgets_dict['pulse'] = self.pulse_wid
            lay.addWidget(self.pulse_wid)

        self.intlk_wid = self._build_widget(name='intlk')
        self._widgets_dict['intlk'] = self.intlk_wid
        lay.addWidget(self.intlk_wid)

        if self._is_linac:
            self.conn_wid = self._build_widget(name='conn')
            self._widgets_dict['conn'] = self.conn_wid
            lay.addWidget(self.conn_wid)

        if self._has_reset:
            self.reset_wid = self._build_widget(name='reset')
            self._widgets_dict['reset'] = self.reset_wid
            lay.addWidget(self.reset_wid)

        if self._has_ctrlloop:
            self.ctrlloop_wid = self._build_widget(name='ctrlloop')
            self._widgets_dict['ctrlloop'] = self.ctrlloop_wid
            lay.addWidget(self.ctrlloop_wid)

        if self._has_wfmupdt:
            self.wfmupdate_wid = self._build_widget(name='wfmupdate')
            self._widgets_dict['wfmupdate'] = self.wfmupdate_wid
            lay.addWidget(self.wfmupdate_wid)

        if self._has_parmupdt:
            self.updparms_wid = self._build_widget(name='updparms')
            self._widgets_dict['updparms'] = self.updparms_wid
            lay.addWidget(self.updparms_wid)

        self.setpoint_wid = self._build_widget(name='setpoint',
                                               orientation='v')
        self._widgets_dict['setpoint'] = self.setpoint_wid
        lay.addWidget(self.setpoint_wid)

        if self._has_analrb:
            self.readback_wid = self._build_widget(name='readback',
                                                   orientation='v')
            self._widgets_dict['readback'] = self.readback_wid
            lay.addWidget(self.readback_wid)

        if self._has_analmon:
            self.monitor_wid = self._build_widget(name='monitor',
                                                  orientation='v')
            self._widgets_dict['monitor'] = self.monitor_wid
            lay.addWidget(self.monitor_wid)

        if self._has_strength:
            self.strength_sp_wid = self._build_widget(name='strength_sp',
                                                      orientation='v')
            self._widgets_dict['strength_sp'] = self.strength_sp_wid
            lay.addWidget(self.strength_sp_wid)

            self.strength_rb_wid = self._build_widget(name='strength_rb',
                                                      orientation='v')
            self._widgets_dict['strength_rb'] = self.strength_rb_wid
            lay.addWidget(self.strength_rb_wid)

        if self._has_strength_mon:
            self.strength_mon_wid = self._build_widget(name='strength_mon',
                                                       orientation='v')
            self._widgets_dict['strength_mon'] = self.strength_mon_wid
            lay.addWidget(self.strength_mon_wid)

        if self._has_trim:
            self.trim_wid = self._build_widget(name='trim', orientation='v')
            self._widgets_dict['trim'] = self.trim_wid
            lay.addWidget(self.trim_wid)

        _widths = get_prop2width(self._name)
        for name, widget in self._widgets_dict.items():
            width = _widths[name]
            widget.setStyleSheet('#' + name + '{min-width:' + str(width) +
                                 'em;'
                                 'max-width:' + str(width) + 'em;}')
            widget.setSizePolicy(QSzPlcy.Fixed, QSzPlcy.Fixed)
            widget.setVisible(name in self.visible_props)

        self.setStyleSheet("""
            PyDMStateButton{
                min-width: 2.5em; max-width: 2.5em;
                min-height: 1.5em; max-height: 1.5em;
            }
            QLed{
                min-width: 1.5em; max-width: 1.5em;
                min-height: 1.5em; max-height: 1.5em;
            }
            QLabel{
                min-height: 1.5em; max-height: 1.5em;
                qproperty-alignment: AlignCenter;
            }
        """)

        lay.addStretch()
        self.setLayout(lay)

        for prop in self.visible_props:
            self.fillWidget(prop)

    def _create_pvs(self):
        if self._has_opmode:
            if self._is_reg_slave:
                self._opmode_sts = self._prefixed_name.substitute(
                    propty='ModState-Mon')
            elif self._is_regatron:
                self._opmode_sts = self._prefixed_name.substitute(
                    propty='OpMode-Sts')
            else:
                self._opmode_sel = self._prefixed_name.substitute(
                    propty='OpMode-Sel')
                self._opmode_sts = self._prefixed_name.substitute(
                    propty='OpMode-Sts')

        if self._has_ctrlmode:
            self._ctrlmode_sts = self._prefixed_name.substitute(
                propty='CtrlMode-Mon')

        if self._has_pwrstate:
            self._pwrstate_sel = self._prefixed_name.substitute(
                propty='PwrState-Sel')
            self._pwrstate_sts = self._prefixed_name.substitute(
                propty='PwrState-Sts')

        if self._is_pulsed:
            self._pulse_sel = self._prefixed_name.substitute(
                propty='Pulse-Sel')
            self._pulse_sts = self._prefixed_name.substitute(
                propty='Pulse-Sts')

        # interlock
        if self._is_pulsed:
            self._intlk = list()
            for i in range(1, 8):
                self._intlk.append(
                    self._prefixed_name.substitute(propty='Intlk' + str(i) +
                                                   '-Mon'))
            if 'Sept' not in self._name.dev:
                self._intlk.append(
                    self._prefixed_name.substitute(propty='Intlk8-Mon'))
        elif self._is_linac:
            self._intlk = self._prefixed_name.substitute(
                propty='StatusIntlk-Mon')
        elif self._is_regatron:
            if not self._is_reg_slave:
                self._generr = self._prefixed_name.substitute(
                    propty='GenIntlk-Mon')
                self._genwrn = self._prefixed_name.substitute(
                    propty='GenWarn-Mon')
        elif self._is_fofb:
            self._intlk = [
                self._prefixed_name.substitute(
                    propty='PSAmpOverCurrFlagL-Sts'),
                self._prefixed_name.substitute(
                    propty='PSAmpOverCurrFlagR-Sts'),
                self._prefixed_name.substitute(
                    propty='PSAmpOverTempFlagL-Sts'),
                self._prefixed_name.substitute(
                    propty='PSAmpOverTempFlagR-Sts'),
            ]
        else:
            self._soft_intlk = self._prefixed_name.substitute(
                propty='IntlkSoft-Mon')
            self._hard_intlk = self._prefixed_name.substitute(
                propty='IntlkHard-Mon')

        if self._is_linac:
            self._conn = self._prefixed_name.substitute(propty='Connected-Mon')

        if self._has_reset:
            self._reset_intlk = self._prefixed_name.substitute(
                propty='Reset-Cmd')

        if self._has_ctrlloop:
            self._ctrlloop_sel = self._prefixed_name.substitute(
                propty='CtrlLoop-Sel')
            self._ctrlloop_sts = self._prefixed_name.substitute(
                propty='CtrlLoop-Sts')

        if self._has_wfmupdt:
            self._wfmupdate_sel = self._prefixed_name.substitute(
                propty='WfmUpdateAuto-Sel')
            self._wfmupdate_sts = self._prefixed_name.substitute(
                propty='WfmUpdateAuto-Sts')

        if self._has_parmupdt:
            self._updparms_cmd = self._prefixed_name.substitute(
                propty='ParamUpdate-Cmd')

        # analog control
        sp = self._analog_name
        if self._has_analsp:
            self._analog_sp = self._prefixed_name.substitute(
                propty='{}-SP'.format(sp))
        if self._has_analrb:
            self._analog_rb = self._prefixed_name.substitute(
                propty='{}-RB'.format(sp))
        if self._has_analmon:
            if self._is_reg_slave:
                self._analog_mon = self._prefixed_name.substitute(
                    propty='ModOutVolt-Mon')
            else:
                self._analog_mon = self._prefixed_name.substitute(
                    propty='{}-Mon'.format(sp))

        # strength
        if self._has_strength:
            st = self._strength_name
            self._strength_sp = self._prefixed_name.substitute(
                propty='{}-SP'.format(st))
            self._strength_rb = self._prefixed_name.substitute(
                propty='{}-RB'.format(st))
        if self._has_strength_mon:
            self._strength_mon = self._prefixed_name.substitute(
                propty='{}-Mon'.format(st))

    def _build_widget(self, name='', orientation='h'):
        widget = QWidget(self)
        widget.setObjectName(name)
        if orientation == 'h':
            lay = QHBoxLayout(widget)
        else:
            lay = QVBoxLayout(widget)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 3, 0, 3)
        return widget

    def fillWidget(self, name):
        if name in self.filled_widgets:
            return
        if name == 'detail':
            self.detail_bt = QPushButton(self)
            if self._name.dev == 'DCLink':
                self.detail_bt.setIcon(qta.icon('fa5s.list-ul'))
                self.detail_bt.setToolTip(self._name)
            else:
                self.detail_bt.setText(self._name)
            self.detail_wid.layout().addWidget(self.detail_bt)
        elif name == 'bbb' and self._bbb_name:
            self.bbb_lb = QLabel(self._bbb_name, self)
            self.bbb_wid.layout().addWidget(self.bbb_lb)
        elif name == 'udc' and self._udc_name:
            self.udc_lb = QLabel(self._udc_name, self)
            self.udc_wid.layout().addWidget(self.udc_lb)
        elif name == 'opmode' and self._has_opmode:
            opmode_list = list()
            if 'Voltage' not in self._analog_name:
                self.opmode_cb = SiriusEnumComboBox(self, self._opmode_sel)
                opmode_list.append(self.opmode_cb)
            self.opmode_lb = PyDMLabel(self, self._opmode_sts)
            opmode_list.append(self.opmode_lb)
            for wid in opmode_list:
                self.opmode_wid.layout().addWidget(wid)
        elif name == 'ctrlmode' and self._has_ctrlmode:
            self.ctrlmode_lb = PyDMLabel(self, self._ctrlmode_sts)
            self.ctrlmode_wid.layout().addWidget(self.ctrlmode_lb)
        elif name == 'state' and self._has_pwrstate:
            self.state_bt = PyDMStateButton(self, self._pwrstate_sel)
            self.state_led = SiriusLedState(self, self._pwrstate_sts)
            self.state_wid.layout().addWidget(self.state_bt)
            self.state_wid.layout().addWidget(self.state_led)
        elif name == 'pulse' and self._is_pulsed:
            self.pulse_bt = PyDMStateButton(self, self._pulse_sel)
            self.pulse_led = SiriusLedState(self, self._pulse_sts)
            self.pulse_wid.layout().addWidget(self.pulse_bt)
            self.pulse_wid.layout().addWidget(self.pulse_led)
        elif name == 'intlk':
            if self._is_pulsed:
                self.intlk_led = PyDMLedMultiChannel(
                    self, channels2values={ch: 1
                                           for ch in self._intlk})
                self.intlk_wid.layout().addWidget(self.intlk_led)
            elif self._is_linac:
                if IsLinacSpect.match(self.devname):
                    self.intlk_led = LISpectIntlkLed(self)
                else:
                    self.intlk_led = PyDMLedMultiChannel(self,
                                                         channels2values={
                                                             self._intlk: {
                                                                 'value':
                                                                 _PS_LI_INTLK,
                                                                 'comp': 'lt'
                                                             }
                                                         })
                self.intlk_wid.layout().addWidget(self.intlk_led)
            elif self._is_regatron:
                if not self._is_reg_slave:
                    self.generr_led = SiriusLedAlert(self, self._generr)
                    self.genwrn_led = SiriusLedAlert(self, self._genwrn)
                    self.intlk_wid.layout().addWidget(self.generr_led)
                    self.intlk_wid.layout().addWidget(self.genwrn_led)
            elif self._is_fofb:
                self.intlk_led = PyDMLedMultiChannel(
                    self, channels2values={ch: 1
                                           for ch in self._intlk})
                self.intlk_wid.layout().addWidget(self.intlk_led)
            else:
                self.soft_intlk_led = SiriusLedAlert(self, self._soft_intlk)
                self.hard_intlk_led = SiriusLedAlert(self, self._hard_intlk)
                self.intlk_wid.layout().addWidget(self.soft_intlk_led)
                self.intlk_wid.layout().addWidget(self.hard_intlk_led)
        elif name == 'conn' and self._is_linac:
            self.conn_led = PyDMLedMultiChannel(
                self, channels2values={self._conn: 0})
            self.conn_wid.layout().addWidget(self.conn_led)
        elif name == 'reset' and self._has_reset:
            self.reset_bt = PyDMPushButton(parent=self,
                                           init_channel=self._reset_intlk,
                                           pressValue=1)
            self.reset_bt.setIcon(qta.icon('fa5s.sync'))
            self.reset_bt.setObjectName('reset_bt')
            self.reset_bt.setStyleSheet(
                '#reset_bt{min-width:25px; max-width:25px; icon-size:20px;}')
            self.reset_wid.layout().addWidget(self.reset_bt)
        elif name == 'ctrlloop' and self._has_ctrlloop:
            if self._is_fofb:
                self.ctrlloop_bt = PyDMStateButton(self, self._ctrlloop_sel)
            else:
                self.ctrlloop_bt = PyDMStateButton(self,
                                                   self._ctrlloop_sel,
                                                   invert=True)
            self.ctrlloop_lb = PyDMLabel(self, self._ctrlloop_sts)
            self.ctrlloop_wid.layout().addWidget(self.ctrlloop_bt)
            self.ctrlloop_wid.layout().addWidget(self.ctrlloop_lb)
        elif name == 'wfmupdate' and self._has_wfmupdt:
            self.wfmupdate_bt = PyDMStateButton(self, self._wfmupdate_sel)
            self.wfmupdate_led = SiriusLedState(self, self._wfmupdate_sts)
            self.wfmupdate_wid.layout().addWidget(self.wfmupdate_bt)
            self.wfmupdate_wid.layout().addWidget(self.wfmupdate_led)
        elif name == 'updparms' and self._has_parmupdt:
            self.updparms_bt = PyDMPushButton(parent=self,
                                              init_channel=self._updparms_cmd,
                                              pressValue=1)
            self.updparms_bt.setIcon(qta.icon('fa5s.redo-alt'))
            self.updparms_bt.setObjectName('updparms_bt')
            self.updparms_bt.setStyleSheet(
                '#updparms_bt{min-width:25px;max-width:25px;icon-size:20px;}')
            self.updparms_wid.layout().addWidget(self.updparms_bt)
        elif name == 'setpoint' and self._has_analsp:
            self.setpoint = PyDMSpinboxScrollbar(self, self._analog_sp)
            if self._is_fofb:
                self.setpoint.spinbox.precisionFromPV = False
                self.setpoint.spinbox.precision = 6
            self.setpoint_wid.layout().addWidget(self.setpoint)
        elif name == 'readback' and self._has_analrb:
            self.readback = PyDMLabel(self, self._analog_rb)
            if self._is_fofb:
                self.readback.precisionFromPV = False
                self.readback.precision = 6
            self.readback_wid.layout().addWidget(self.readback)
        elif name == 'monitor' and self._has_analmon:
            self.monitor = PyDMLabel(self, self._analog_mon)
            self.monitor_wid.layout().addWidget(self.monitor)
        elif name == 'strength_sp' and self._has_strength:
            self.strength_sp_le = PyDMSpinboxScrollbar(self, self._strength_sp)
            self.strength_sp_wid.layout().addWidget(self.strength_sp_le)
        elif name == 'strength_rb' and self._has_strength:
            self.strength_rb_lb = PyDMLabel(parent=self,
                                            init_channel=self._strength_rb)
            self.strength_rb_lb.showUnits = True
            self.strength_rb_wid.layout().addWidget(self.strength_rb_lb)
        elif name == 'strength_mon' and self._has_strength_mon:
            self.strength_mon_lb = PyDMLabel(parent=self,
                                             init_channel=self._strength_mon)
            self.strength_mon_lb.showUnits = True
            self.strength_mon_wid.layout().addWidget(self.strength_mon_lb)
        elif name == 'trim' and self._has_trim:
            self.trim_bt = QPushButton(qta.icon('fa5s.angle-right'), '', self)
            self.trim_wid.layout().addWidget(self.trim_bt)
        self.filled_widgets.add(name)

    def get_detail_button(self):
        """Return psname button."""
        return self.detail_bt

    def get_trim_button(self):
        """Return trim button."""
        if self._has_trim:
            return self.trim_bt
        return None

    def set_opmode_slowref(self):
        """Set power supply OpMode to SlowRef."""
        if hasattr(self, 'opmode_cb'):
            if self.opmode_cb.isEnabled():
                index = self.opmode_cb.findText('SlowRef')
                self.opmode_cb.internal_combo_box_activated_int(index)

    def turn_on(self):
        """Turn power supply on."""
        if hasattr(self, 'state_bt'):
            if self.state_bt.isEnabled():
                if not self.state_bt.value:
                    self.state_bt.send_value()

    def turn_off(self):
        """Turn power supply off."""
        if hasattr(self, 'state_bt'):
            if self.state_bt.isEnabled():
                if self.state_bt.value:
                    self.state_bt.send_value()

    def ctrlloop_close(self):
        """Close control loop."""
        if hasattr(self, 'ctrlloop_bt'):
            if self.ctrlloop_bt.isEnabled():
                if not self.ctrlloop_bt.value:
                    self.ctrlloop_bt.send_value()

    def ctrlloop_open(self):
        """Open control loop."""
        if hasattr(self, 'ctrlloop_bt'):
            if self.ctrlloop_bt.isEnabled():
                if self.ctrlloop_bt.value:
                    self.ctrlloop_bt.send_value()

    def pulse_on(self):
        """Turn power supply on."""
        if hasattr(self, 'pulse_bt'):
            if self.pulse_bt.isEnabled():
                if not self.pulse_bt.value:
                    self.pulse_bt.send_value()

    def pulse_off(self):
        """Turn power supply off."""
        if hasattr(self, 'pulse_bt'):
            if self.pulse_bt.isEnabled():
                if self.pulse_bt.value:
                    self.pulse_bt.send_value()

    def wfmupdate_on(self):
        """Enable WfmUpdateAuto."""
        if hasattr(self, 'wfmupdate_bt'):
            if self.wfmupdate_bt.isEnabled():
                if not self.wfmupdate_bt.value:
                    self.wfmupdate_bt.send_value()

    def wfmupdate_off(self):
        """Disable WfmUpdateAuto."""
        if hasattr(self, 'wfmupdate_bt'):
            if self.wfmupdate_bt.isEnabled():
                if self.wfmupdate_bt.value:
                    self.wfmupdate_bt.send_value()

    def reset(self):
        """Reset power supply."""
        if hasattr(self, 'reset_bt'):
            if self.reset_bt.isEnabled():
                self.reset_bt.sendValue()

    def update_params(self):
        """Update power supply parameters."""
        if hasattr(self, 'updparms_bt'):
            if self.updparms_bt.isEnabled():
                self.updparms_bt.sendValue()
예제 #11
0
파일: main.py 프로젝트: lnls-sirius/hla
class SiriusScrnView(QWidget):
    """
    Class to read Sirius screen cameras image data.

    To allow saving a grid correctly, control calibrationgrid_flag, which
    indicates if the screen is in calibration grid position.
    You can control it by using the method/Slot updateCalibrationGridFlag.
    """

    save_files = Signal()

    def __init__(self, parent=None, prefix=_VACA_PREFIX, device=None):
        """Initialize object."""
        QWidget.__init__(self, parent=parent)
        self.prefix = prefix
        self.device = SiriusPVName(device)
        self.scrn_prefix = self.device.substitute(prefix=prefix)
        self._receivedData = False
        self.setObjectName(self.scrn_prefix.sec + 'App')

        self.screen_type_conn = SiriusConnectionSignal(
            self.scrn_prefix.substitute(propty='ScrnType-Sts'))
        self.screen_type_conn.new_value_signal.connect(
            self.updateCalibrationGridFlag)
        self._calibrationgrid_flag = self.screen_type_conn.getvalue()
        self.save_files.connect(self._saveGridLocalFiles)
        self.ch_ImgROIHeight = SiriusConnectionSignal(
            self.scrn_prefix.substitute(propty='ImgROIHeight-RB'))
        self.ch_ImgROIWidth = SiriusConnectionSignal(
            self.scrn_prefix.substitute(propty='ImgROIWidth-RB'))
        self.ch_ImgROIOffsetX = SiriusConnectionSignal(
            self.scrn_prefix.substitute(propty='ImgROIOffsetX-RB'))
        self.ch_ImgROIOffsetY = SiriusConnectionSignal(
            self.scrn_prefix.substitute(propty='ImgROIOffsetY-RB'))

        self._setupUi()
        self.setFocus(True)
        self.setFocusPolicy(Qt.StrongFocus)
        self._loadCalibrationGrid(default=True)

    @property
    def calibrationgrid_flag(self):
        """Indicate if the screen device is in calibration grid position."""
        return self._calibrationgrid_flag

    @Slot(int)
    def updateCalibrationGridFlag(self, new_state):
        """Update calibrationgrid_flag property."""
        self._calibrationgrid_flag = new_state
        if new_state == 1:
            self.pushbutton_savegrid.setEnabled(True)
        else:
            self.pushbutton_savegrid.setEnabled(False)

    def _setupUi(self):
        self.cameraview_widget = QWidget()
        self.cameraview_widget.setLayout(self._cameraviewLayout())

        self.settings_widget = QWidget(self)
        self.settings_widget.setLayout(self._settingsLayout())
        self.settings_widget.setStyleSheet("""
            .QLabel{
                min-width: 5em;}
            QLabel{
                qproperty-alignment: AlignCenter;}""")

        self.calibrationgrid_widget = QWidget(self)
        self.calibrationgrid_widget.setLayout(self._calibrationgridLayout())
        self.calibrationgrid_widget.setSizePolicy(QSzPlcy.Expanding,
                                                  QSzPlcy.Expanding)
        self.calibrationgrid_widget.layout().setAlignment(Qt.AlignHCenter)
        self.tab = QTabWidget(self)
        self.tab.setStyleSheet("""
            QTabWidget::pane {
                border-left: 2px solid gray;
                border-bottom: 2px solid gray;
                border-right: 2px solid gray;
            }""")
        self.tab.addTab(self.settings_widget, 'Camera Settings')
        self.tab.addTab(self.calibrationgrid_widget, 'Calibration')

        self.statistics_groupBox = QGroupBox('Statistics', self)
        self.statistics_groupBox.setLayout(self._statisticsLayout())
        self.statistics_groupBox.setSizePolicy(QSzPlcy.Expanding,
                                               QSzPlcy.Expanding)
        self.statistics_groupBox.setStyleSheet("""
            .QLabel{
                min-width:0.28em; max-width:0.28em;
                min-height:1.29em; max-height:1.29em;}
            QLabel{
                qproperty-alignment: AlignCenter;}
            PyDMWidget{
                min-width:4.84em; max-width:4.84em;
                min-height:1.29em; max-height:1.29em;}""")

        self.trigger_groupBox = QGroupBox('Trigger', self)
        if 'TB' in self.device or 'BO' in self.device:
            trg_prefix = 'AS-Fam:TI-Scrn-TBBO'
        elif 'TS' in self.device:
            trg_prefix = 'TS-Fam:TI-Scrn'
        hbl = QHBoxLayout(self.trigger_groupBox)
        hbl.addWidget(
            HLTriggerSimple(parent=self.trigger_groupBox,
                            device=trg_prefix,
                            prefix=self.prefix))
        self.trigger_groupBox.setLayout(hbl)
        self.trigger_groupBox.setStyleSheet("""
            PyDMWidget{
                min-width:4.84em; max-width:4.84em;
                min-height:1.29em; max-height:1.29em;}""")

        vlay = QVBoxLayout()
        vlay.addWidget(self.statistics_groupBox)
        vlay.addWidget(self.trigger_groupBox)
        vlay.setSpacing(10)

        lay = QGridLayout(self)
        lay.setHorizontalSpacing(10)
        lay.setVerticalSpacing(10)
        lay.addWidget(self.cameraview_widget, 0, 0, 1, 2)
        lay.addWidget(self.tab, 1, 0)
        lay.addLayout(vlay, 1, 1)
        lay.setRowStretch(0, 15)
        lay.setRowStretch(1, 7)

    def _cameraviewLayout(self):
        label = QLabel(self.device, self)
        label.setStyleSheet("""font-weight: bold;max-height:1.29em;""")
        label.setAlignment(Qt.AlignCenter)
        self.image_view = _SiriusImageView(
            parent=self,
            image_channel=self.scrn_prefix.substitute(propty='ImgData-Mon'),
            width_channel=self.scrn_prefix.substitute(propty='ImgROIWidth-RB'),
            offsetx_channel=self.scrn_prefix.substitute(
                propty='ImgROIOffsetX-RB'),
            offsety_channel=self.scrn_prefix.substitute(
                propty='ImgROIOffsetY-RB'),
            maxwidth_channel=self.scrn_prefix.substitute(
                propty='ImgMaxWidth-Cte'),
            maxheight_channel=self.scrn_prefix.substitute(
                propty='ImgMaxHeight-Cte'))
        self.image_view.setObjectName('ScrnView')
        self.image_view.normalizeData = True
        self.image_view.readingOrder = self.image_view.Clike
        self.image_view.maxRedrawRate = 15
        self.image_view.setStyleSheet("""
            #ScrnView{min-width:30em; min-height:24em;}""")
        self.image_view.failToSaveGrid.connect(self._showFailToSaveGridMsg)
        self.image_view.receivedData.connect(self._setReceivedDataFlag)

        lay = QGridLayout()
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addWidget(label, 0, 1)
        lay.addItem(QSpacerItem(40, 2, QSzPlcy.Preferred, QSzPlcy.Fixed), 1, 1)
        lay.addWidget(self.image_view, 2, 1)
        return lay

    def _calibrationgridLayout(self):
        self.checkBox_showgrid = QCheckBox('Show', self)
        self.checkBox_showgrid.setEnabled(False)
        self.checkBox_showgrid.setStyleSheet("""
            min-width:4em; max-width:4em;
            min-height:1.29em; max-height:1.29em;""")
        self.checkBox_showgrid.toggled.connect(
            self.image_view.showCalibrationGrid)
        self.pushbutton_savegrid = QPushButton('Save', self)
        self.pushbutton_savegrid.setEnabled(False)
        self.pushbutton_savegrid.setStyleSheet("""
            min-width:4em; max-width:4em;
            min-height:1.29em; max-height:1.29em;""")
        self.pushbutton_savegrid.clicked.connect(self._saveCalibrationGrid)
        self.pushbutton_loadgrid = QPushButton('Load', self)
        self.pushbutton_loadgrid.setStyleSheet("""
            min-width:4em; max-width:4em;
            min-height:1.29em; max-height:1.29em;""")
        self.pushbutton_loadgrid.clicked.connect(self._loadCalibrationGrid)
        hbox_grid = QHBoxLayout()
        hbox_grid.addWidget(self.checkBox_showgrid)
        hbox_grid.addWidget(self.pushbutton_savegrid)
        hbox_grid.addWidget(self.pushbutton_loadgrid)

        lb = QLabel('Show levels <')
        lb.setStyleSheet("min-width:7em;max-width:7em;")
        self.spinbox_gridfilterfactor = QSpinBoxPlus()
        self.spinbox_gridfilterfactor.setMaximum(100)
        self.spinbox_gridfilterfactor.setMinimum(0)
        self.spinbox_gridfilterfactor.setValue(
            self.image_view.calibration_grid_filterfactor)
        self.spinbox_gridfilterfactor.editingFinished.connect(
            self._setCalibrationGridFilterFactor)
        self.spinbox_gridfilterfactor.setStyleSheet("""
            min-width:4em; max-width:4em;""")
        hbox_filter = QHBoxLayout()
        hbox_filter.setSpacing(0)
        hbox_filter.addWidget(lb)
        hbox_filter.addWidget(self.spinbox_gridfilterfactor)
        hbox_filter.addWidget(QLabel(' %'))

        lb = QLabel('Remove border: ')
        lb.setStyleSheet("min-width:7em;max-width:7em;")
        self.spinbox_removeborder = QSpinBoxPlus()
        self.spinbox_removeborder.setMaximum(512)
        self.spinbox_removeborder.setMinimum(0)
        self.spinbox_removeborder.setValue(
            self.image_view.calibration_grid_removeborder)
        self.spinbox_removeborder.editingFinished.connect(
            self._setCalibrationGridBorder2Remove)
        self.spinbox_removeborder.setStyleSheet("""
            min-width:4em; max-width:4em;""")
        hbox_remove = QHBoxLayout()
        hbox_remove.setSpacing(0)
        hbox_remove.addWidget(lb)
        hbox_remove.addWidget(self.spinbox_removeborder)
        hbox_remove.addWidget(QLabel(' px'))

        hbox_EnblLED = _create_propty_layout(parent=self,
                                             prefix=self.scrn_prefix,
                                             propty='EnblLED',
                                             propty_type='enbldisabl',
                                             width=4.68)

        lay = QFormLayout()
        lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred))
        lay.addRow('  Grid: ', hbox_grid)
        lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred))
        lay.addRow('  ', hbox_filter)
        lay.addRow('  ', hbox_remove)
        lay.addItem(QSpacerItem(1, 20, QSzPlcy.Ignored, QSzPlcy.Preferred))
        lay.addRow('  LED: ', hbox_EnblLED)
        lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred))
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        return lay

    def _settingsLayout(self):
        label_CamEnbl = QLabel('Enable: ', self)
        hbox_CamEnbl = _create_propty_layout(parent=self,
                                             prefix=self.scrn_prefix,
                                             propty='CamEnbl',
                                             propty_type='enbldisabl')

        label_CamAcqPeriod = QLabel('Acquire\nPeriod [s]:', self)
        hbox_CamAcqPeriod = _create_propty_layout(parent=self,
                                                  prefix=self.scrn_prefix,
                                                  propty='CamAcqPeriod',
                                                  propty_type='sprb',
                                                  width=5.0)

        label_CamExposureTime = QLabel('Exposure\nTime [us]:', self)
        hbox_CamExposureTime = _create_propty_layout(parent=self,
                                                     prefix=self.scrn_prefix,
                                                     propty='CamExposureTime',
                                                     propty_type='sprb',
                                                     width=5.0)

        label_CamGain = QLabel('Gain[dB]:', self)
        hbox_CamGain = _create_propty_layout(parent=self,
                                             prefix=self.scrn_prefix,
                                             propty='CamGain',
                                             width=5.0,
                                             propty_type='sprb')

        label_AutoGain = QLabel('Auto Gain: ', self)
        self.pb_autogain = PyDMPushButton(
            label='',
            icon=qta.icon('mdi.auto-fix'),
            parent=self,
            pressValue=1,
            init_channel=self.scrn_prefix.substitute(propty='CamAutoGain-Cmd'))
        self.pb_autogain.setObjectName('autog')
        self.pb_autogain.setStyleSheet(
            "#autog{min-width:25px; max-width:25px; icon-size:20px;}")

        cam_prefix = SiriusPVName(self.scrn_prefix).substitute(dev='ScrnCam')
        label_Reset = QLabel('Reset: ', self)
        self.pb_dtl = PyDMPushButton(
            label='',
            icon=qta.icon('fa5s.sync'),
            parent=self,
            pressValue=1,
            init_channel=cam_prefix.substitute(propty='Rst-Cmd'))
        self.pb_dtl.setObjectName('reset')
        self.pb_dtl.setStyleSheet(
            "#reset{min-width:25px; max-width:25px; icon-size:20px;}")

        self.pb_details = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self)
        self.pb_details.setToolTip('More settings')
        self.pb_details.setObjectName('detail')
        self.pb_details.setStyleSheet(
            "#detail{min-width:25px; max-width:25px; icon-size:20px;}")
        self.pb_details.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Preferred)
        util.connect_window(self.pb_details,
                            _ScrnSettingsDetails,
                            parent=self,
                            prefix=self.prefix,
                            device=self.device)

        hbox_aux = QHBoxLayout()
        hbox_aux.addWidget(self.pb_dtl, alignment=Qt.AlignLeft)
        hbox_aux.addWidget(self.pb_details, alignment=Qt.AlignRight)

        lay = QFormLayout()
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow(label_CamEnbl, hbox_CamEnbl)
        lay.addRow(label_CamAcqPeriod, hbox_CamAcqPeriod)
        lay.addRow(label_CamExposureTime, hbox_CamExposureTime)
        lay.addRow(label_CamGain, hbox_CamGain)
        lay.addRow(label_AutoGain, self.pb_autogain)
        lay.addRow(label_Reset, hbox_aux)
        return lay

    def _statisticsLayout(self):
        # - Method
        label_Method = QLabel('CalcMethod:', self)
        label_Method.setStyleSheet("min-width:7em;")

        self.comboBox_Method = QComboBox(self)
        self.comboBox_Method.addItem('DimFei', 0)
        self.comboBox_Method.addItem('NDStats', 1)
        self.comboBox_Method.setCurrentIndex(0)
        self.comboBox_Method.setStyleSheet("""
            QComboBox::item {height: 1em;}
            QComboBox{min-width:6em;}""")
        self.comboBox_Method.currentIndexChanged.connect(
            self._handleShowStatistics)

        # - Centroid
        label_Centroid = QLabel('Centroid [mm]: ', self)
        label_Centroid.setStyleSheet("min-width:7em;")
        label_i_Center = QLabel('(', self)
        self.PyDMLabel_CenterXDimFei = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='CenterXDimFei-Mon'))
        self.PyDMLabel_CenterXDimFei.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_CenterXNDStats = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='CenterXNDStats-Mon'))
        self.PyDMLabel_CenterXNDStats.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_CenterXNDStats.setVisible(False)
        label_m_Center = QLabel(',', self)
        self.PyDMLabel_CenterYDimFei = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='CenterYDimFei-Mon'))
        self.PyDMLabel_CenterYDimFei.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_CenterYNDStats = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='CenterYNDStats-Mon'))
        self.PyDMLabel_CenterYNDStats.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_CenterYNDStats.setVisible(False)
        label_f_Center = QLabel(')', self)

        # - Sigma
        label_Sigma = QLabel('Sigma [mm]: ', self)
        label_Sigma.setStyleSheet("min-width:7em;")
        label_i_Sigma = QLabel('(', self)
        self.PyDMLabel_SigmaXDimFei = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='SigmaXDimFei-Mon'))
        self.PyDMLabel_SigmaXDimFei.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_SigmaXNDStats = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='SigmaXNDStats-Mon'))
        self.PyDMLabel_SigmaXNDStats.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_SigmaXNDStats.setVisible(False)
        label_m_Sigma = QLabel(',', self)
        self.PyDMLabel_SigmaYDimFei = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='SigmaYDimFei-Mon'))
        self.PyDMLabel_SigmaYDimFei.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_SigmaYNDStats = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='SigmaYNDStats-Mon'))
        self.PyDMLabel_SigmaYNDStats.setStyleSheet(
            'min-width:4em; max-width:4em;')
        self.PyDMLabel_SigmaYNDStats.setVisible(False)
        label_f_Sigma = QLabel(')', self)

        # - Theta
        label_Theta = QLabel('Theta [rad]: ')
        label_Theta.setStyleSheet("min-width:7em;")
        label_i_Theta = QLabel('(', self)
        self.PyDMLabel_ThetaDimFei = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(propty='ThetaDimFei-Mon'))
        self.PyDMLabel_ThetaDimFei.setStyleSheet("max-width:12em;")
        self.PyDMLabel_ThetaNDStats = PyDMLabel(
            parent=self,
            init_channel=self.scrn_prefix.substitute(
                propty='ThetaNDStats-Mon'))
        self.PyDMLabel_ThetaNDStats.setStyleSheet("max-width:12em;")
        self.PyDMLabel_ThetaNDStats.setVisible(False)
        label_f_Theta = QLabel(')', self)

        lay = QGridLayout()
        lay.addWidget(label_Method, 1, 1, 1, 3)
        lay.addWidget(self.comboBox_Method, 1, 3, 1, 3)
        lay.addWidget(label_Centroid, 3, 1, alignment=Qt.AlignCenter)
        lay.addWidget(label_i_Center, 3, 2)
        lay.addWidget(self.PyDMLabel_CenterXDimFei, 3, 3)
        lay.addWidget(self.PyDMLabel_CenterXNDStats, 3, 3)
        lay.addWidget(label_m_Center, 3, 4)
        lay.addWidget(self.PyDMLabel_CenterYDimFei, 3, 5)
        lay.addWidget(self.PyDMLabel_CenterYNDStats, 3, 5)
        lay.addWidget(label_f_Center, 3, 6)
        lay.addWidget(label_Sigma, 5, 1, alignment=Qt.AlignCenter)
        lay.addWidget(label_i_Sigma, 5, 2)
        lay.addWidget(self.PyDMLabel_SigmaXDimFei, 5, 3)
        lay.addWidget(self.PyDMLabel_SigmaXNDStats, 5, 3)
        lay.addWidget(label_m_Sigma, 5, 4)
        lay.addWidget(self.PyDMLabel_SigmaYDimFei, 5, 5)
        lay.addWidget(self.PyDMLabel_SigmaYNDStats, 5, 5)
        lay.addWidget(label_f_Sigma, 5, 6)
        lay.addWidget(label_Theta, 7, 1, alignment=Qt.AlignCenter)
        lay.addWidget(label_i_Theta, 7, 2)
        lay.addWidget(self.PyDMLabel_ThetaDimFei, 7, 3, 1, 3)
        lay.addWidget(self.PyDMLabel_ThetaNDStats, 7, 3, 1, 3)
        lay.addWidget(label_f_Theta, 7, 6)
        return lay

    def _handleShowStatistics(self, visible):
        self.PyDMLabel_CenterXDimFei.setVisible(not visible)
        self.PyDMLabel_CenterXNDStats.setVisible(visible)
        self.PyDMLabel_CenterYDimFei.setVisible(not visible)
        self.PyDMLabel_CenterYNDStats.setVisible(visible)
        self.PyDMLabel_ThetaDimFei.setVisible(not visible)
        self.PyDMLabel_ThetaNDStats.setVisible(visible)
        self.PyDMLabel_SigmaXDimFei.setVisible(not visible)
        self.PyDMLabel_SigmaXNDStats.setVisible(visible)
        self.PyDMLabel_SigmaYDimFei.setVisible(not visible)
        self.PyDMLabel_SigmaYNDStats.setVisible(visible)

    def _saveCalibrationGrid(self):
        t = Thread(target=self._saveCalibrationGrid_thread, daemon=True)
        t.start()

    def _saveCalibrationGrid_thread(self):
        roi_h = float(self.ch_ImgROIHeight.value)
        roi_w = float(self.ch_ImgROIWidth.value)
        roi_offsetx = float(self.ch_ImgROIOffsetX.value)
        roi_offsety = float(self.ch_ImgROIOffsetY.value)

        cond = roi_h != float(self.image_view.image_maxheight) or \
            roi_w != float(self.image_view.image_maxwidth) or \
            roi_offsetx != 0 or roi_offsety != 0
        if cond:
            # Disable camera acquisition and wait for disabling
            self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(0)
            state = self.SiriusLedState_CamEnbl.state
            while state == 1:
                time.sleep(0.1)
                state = self.SiriusLedState_CamEnbl.state

            # Change ROI to get entire image
            self.ch_ImgROIHeight.send_value_signal[float].emit(
                float(self.image_view.image_maxheight))
            self.ch_ImgROIWidth.send_value_signal[float].emit(
                float(self.image_view.image_maxwidth))
            self.ch_ImgROIOffsetX.send_value_signal[float].emit(0)
            self.ch_ImgROIOffsetY.send_value_signal[float].emit(0)

        # Enable led and wait for status
        self.PyDMStateButton_EnblLED.send_value_signal[int].emit(1)
        while not self.SiriusLedState_EnblLED.state:
            time.sleep(0.1)

        # Enable camera acquisition and wait for receiveing first frame
        self._receivedData = False
        self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(1)
        while not self._receivedData:
            time.sleep(0.1)

        # Save grid
        self.image_view.saveCalibrationGrid()

        if cond:
            # Disable camera acquisition and wait for disabling
            self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(0)
            state = self.SiriusLedState_CamEnbl.state
            while state == 1:
                time.sleep(0.1)
                state = self.SiriusLedState_CamEnbl.state

            # Change ROI to original size
            self.ch_ImgROIHeight.send_value_signal[float].emit(roi_h)
            self.ch_ImgROIWidth.send_value_signal[float].emit(roi_w)
            self.ch_ImgROIOffsetX.send_value_signal[float].emit(roi_offsetx)
            self.ch_ImgROIOffsetY.send_value_signal[float].emit(roi_offsety)

            # Enable camera acquisition
            self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(1)

        # Enable showing saved grid
        time.sleep(0.1)
        self.checkBox_showgrid.setEnabled(True)
        self.save_files.emit()

    def _saveGridLocalFiles(self):
        home = os.path.expanduser('~')
        folder_month = datetime.now().strftime('%Y-%m')
        folder_day = datetime.now().strftime('%Y-%m-%d')
        path = os.path.join(home, 'mounts', 'screens-iocs', folder_month,
                            folder_day)
        if not os.path.exists(path):
            os.makedirs(path)
        fn, _ = QFileDialog.getSaveFileName(
            self, 'Save Grid As...', path + '/' + self.device +
            datetime.now().strftime('_%Y-%m-%d_%Hh%Mmin'), '*.npy')
        if not fn:
            return False

        path_default = os.path.join(home, 'mounts', 'screens-iocs', 'default')
        if not os.path.exists(path_default):
            os.makedirs(path_default)
        fn_default = path_default + '/' + self.device

        grid = self.image_view.calibrationGrid
        width = self.image_view.imageWidth
        data = np.append(width, grid)
        np.save(fn, data)
        np.save(fn_default, data)

    def _loadCalibrationGrid(self, default=False):
        home = os.path.expanduser('~')
        if not default:
            folder_month = datetime.now().strftime('%Y-%m')
            path = os.path.join(home, 'mounts', 'screens-iocs', folder_month)
            fn, _ = QFileDialog.getOpenFileName(self, 'Load Grid...', path,
                                                '*.npy')
            if not fn:
                return
            if self.device not in fn:
                ans = QMessageBox.question(
                    self, 'Warning',
                    'The name of the selected file does not contain the name' +
                    ' of this screen. Are you sure you\'re loading this grid?',
                    QMessageBox.Yes, QMessageBox.Cancel)
                if ans == QMessageBox.Cancel:
                    return
        else:
            path = os.path.join(home, 'mounts', 'screens-iocs', 'default')
            fn = path + '/' + self.device + '.npy'

        try:
            data = np.load(fn)
            self.image_view.calibrationGrid = data
        except Exception as e:
            if not default:
                QMessageBox.critical(
                    self, 'Error',
                    'Could not load calibration grid from file ' + fn + '. ' +
                    '\nError message: ' + str(e), QMessageBox.Ok)
            return

        # Enable showing saved grid
        self.checkBox_showgrid.setEnabled(True)

    def _setReceivedDataFlag(self):
        self._receivedData = True

    def _setCalibrationGridFilterFactor(self):
        self.image_view.set_calibration_grid_filterfactor(
            self.spinbox_gridfilterfactor.value())

    def _setCalibrationGridBorder2Remove(self):
        self.image_view.set_calibration_grid_border2remove(
            self.spinbox_removeborder.value())

    @Slot()
    def _showFailToSaveGridMsg(self):
        QMessageBox.warning(self, 'Warning',
                            'Could not save calibration grid!', QMessageBox.Ok)
예제 #12
0
파일: settings.py 프로젝트: lnls-sirius/hla
class DCCTSettingsDetails(QWidget):
    """DCCT Settings Details Widget."""
    def __init__(self, parent=None, prefix='', device=''):
        """Initialize object."""
        super().__init__(parent)
        self.prefix = prefix
        self.device = _PVName(device)
        if 'BO' in device:
            self.setObjectName('BOApp')
        else:
            self.setObjectName('SIApp')
        self.dcct_prefix = device.substitute(prefix=self.prefix)
        self._db = get_dcct_database()
        self._setupUi()

    def _setupUi(self):
        self.gbox_reliablemeas = self._setupReliableMeasWidget()

        self.gbox_generalsettings = self._setupGeneralSettingsWidget()

        self.gbox_trigger = self._setupTriggerWidget()

        self.gbox_config = self._setupConfigurationWidget()

        self.gbox_normalmode = self._setupMeasSettingsWidget('Normal')
        self.gbox_fastmode = self._setupMeasSettingsWidget('Fast')
        lay_mode = QGridLayout()
        lay_mode.addWidget(self.gbox_normalmode, 0, 0)
        lay_mode.addWidget(self.gbox_fastmode, 0, 0)
        self.mode_channel = SiriusConnectionSignal(
            self.dcct_prefix.substitute(propty='MeasMode-Sel'))
        self.mode_channel.new_value_signal.connect(self._showMeasModeSettings)

        lay = QGridLayout()
        lay.addWidget(
            QLabel('<h3>' + self.device + ' Settings Details</h3>',
                   self,
                   alignment=Qt.AlignCenter), 0, 0, 1, 2)
        lay.addWidget(self.gbox_reliablemeas, 1, 0)
        lay.addWidget(self.gbox_generalsettings, 2, 0)
        lay.addWidget(self.gbox_config, 3, 0)
        lay.addWidget(self.gbox_trigger, 3, 1)
        lay.addLayout(lay_mode, 1, 1, 2, 1)
        lay.setVerticalSpacing(15)
        lay.setHorizontalSpacing(15)
        lay.setRowStretch(0, 1)
        lay.setRowStretch(1, 3)
        lay.setRowStretch(2, 7)
        lay.setRowStretch(3, 2)
        self.setLayout(lay)

        self.setStyleSheet("""
            PyDMSpinbox, PyDMLabel{
                min-width:6em; max-width:6em;
                qproperty-alignment: AlignCenter;}
            PyDMLedMultiChannel, PyDMStateButton, PyDMEnumComboBox{
                min-width:6em; max-width:6em;}""")

    def _setupReliableMeasWidget(self):
        gbox_reliablemeas = QGroupBox('Measure Reliability Status', self)
        gbox_reliablemeas.setStyleSheet("""
            .QLabel{min-height:1.29em; max-height:1.29em;}
        """)

        lay_reliablemeas = QGridLayout(gbox_reliablemeas)
        relmeas_count = self._db['ReliableMeasLabels-Cte']['count']
        self.relmeas_labels = list()
        for idx in range(relmeas_count):
            led = SiriusLedAlert(parent=self,
                                 init_channel=self.dcct_prefix.substitute(
                                     propty='ReliableMeas-Mon'),
                                 bit=idx)
            lay_reliablemeas.addWidget(led, idx, 0)
            lbl = QLabel('', self)
            self.relmeas_labels.append(lbl)
            lay_reliablemeas.addWidget(lbl, idx, 1)
        lay_reliablemeas.setColumnStretch(0, 1)
        lay_reliablemeas.setColumnStretch(1, 10)

        self.reliablemeas_channel = _PV(
            self.dcct_prefix.substitute(propty='ReliableMeasLabels-Cte'),
            callback=self._updateReliableMeasLabels)

        return gbox_reliablemeas

    def _setupGeneralSettingsWidget(self):
        gbox_generalsettings = QGroupBox('General Measurement Settings', self)

        l_enbl = QLabel('Enable:', self)
        self.pydmstatebutton_Enbl = PyDMStateButton(
            self, self.dcct_prefix.substitute(propty='Enbl-Sel'))
        self.pydmstatebutton_Enbl.shape = 1
        self.led_Enbl = SiriusLedState(
            self, self.dcct_prefix.substitute(propty='Enbl-Sts'))
        hlay_enbl = QHBoxLayout()
        hlay_enbl.addWidget(self.pydmstatebutton_Enbl)
        hlay_enbl.addWidget(self.led_Enbl)

        l_meastrig = QLabel('Trigger Source: ', self)
        self.pydmenumcombobox_MeasTrg = PyDMEnumComboBox(
            self, self.dcct_prefix.substitute(propty='MeasTrg-Sel'))
        self.pydmlabel_MeasTrg = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='MeasTrg-Sts'))
        hlay_meastrig = QHBoxLayout()
        hlay_meastrig.addWidget(self.pydmenumcombobox_MeasTrg)
        hlay_meastrig.addWidget(self.pydmlabel_MeasTrg)

        l_trigmiss = QLabel('Trigger Is Missing?', self)
        self.led_TrgMiss = SiriusLedAlert(
            self, self.dcct_prefix.substitute(propty='TrgIsMissing-Mon'))
        hlay_trigmiss = QHBoxLayout()
        hlay_trigmiss.addWidget(self.led_TrgMiss)
        hlay_trigmiss.setAlignment(Qt.AlignLeft)

        l_range = QLabel('Range: ', self)
        self.pydmenumcombobox_Range = PyDMEnumComboBox(
            self, self.dcct_prefix.substitute(propty='Range-Sel'))
        self.pydmlabel_Range = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='Range-Sts'))
        hlay_range = QHBoxLayout()
        hlay_range.addWidget(self.pydmenumcombobox_Range)
        hlay_range.addWidget(self.pydmlabel_Range)

        l_lowlimenbl = QLabel('Low Beam Current Detection: ', self)
        self.pydmstatebutton_LowLimEnbl = PyDMStateButton(
            self, self.dcct_prefix.substitute(propty='LowLimEnbl-Sel'))
        self.pydmstatebutton_LowLimEnbl.shape = 1
        self.pydmlabel_LowLimEnbl = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='LowLimEnbl-Sts'))
        hlay_lowlimenbl = QHBoxLayout()
        hlay_lowlimenbl.addWidget(self.pydmstatebutton_LowLimEnbl)
        hlay_lowlimenbl.addWidget(self.pydmlabel_LowLimEnbl)

        l_currthold = QLabel('Current Threshold [mA]: ', self)
        self.pydmspinbox_CurrThold = PyDMSpinbox(
            self, self.dcct_prefix.substitute(propty='CurrThold-SP'))
        self.pydmspinbox_CurrThold.showStepExponent = False
        self.pydmlabel_CurrThold = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='CurrThold-RB'))
        hlay_currthold = QHBoxLayout()
        hlay_currthold.addWidget(self.pydmspinbox_CurrThold)
        hlay_currthold.addWidget(self.pydmlabel_CurrThold)

        l_hfreject = QLabel('High Frequency Rejection: ', self)
        self.pydmstatebutton_HFReject = PyDMStateButton(
            self, self.dcct_prefix.substitute(propty='HFReject-Sel'))
        self.pydmstatebutton_HFReject.shape = 1
        self.pydmlabel_HFReject = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='HFReject-Sts'))
        hlay_hfreject = QHBoxLayout()
        hlay_hfreject.addWidget(self.pydmstatebutton_HFReject)
        hlay_hfreject.addWidget(self.pydmlabel_HFReject)

        l_measmode = QLabel('Mode: ', self)
        self.pydmenumcombobox_MeasMode = PyDMEnumComboBox(
            self, self.dcct_prefix.substitute(propty='MeasMode-Sel'))
        self.pydmlabel_MeasMode = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='MeasMode-Sts'))
        hlay_measmode = QHBoxLayout()
        hlay_measmode.addWidget(self.pydmenumcombobox_MeasMode)
        hlay_measmode.addWidget(self.pydmlabel_MeasMode)

        flay_generalsettings = QFormLayout()
        flay_generalsettings.setLabelAlignment(Qt.AlignRight)
        flay_generalsettings.setFormAlignment(Qt.AlignCenter)
        flay_generalsettings.addRow(l_enbl, hlay_enbl)
        flay_generalsettings.addRow(l_meastrig, hlay_meastrig)
        flay_generalsettings.addRow(l_trigmiss, hlay_trigmiss)
        flay_generalsettings.addRow(l_range, hlay_range)
        flay_generalsettings.addItem(
            QSpacerItem(1, 10, QSzPly.Ignored, QSzPly.Preferred))
        flay_generalsettings.addRow(l_lowlimenbl, hlay_lowlimenbl)
        flay_generalsettings.addRow(l_currthold, hlay_currthold)
        flay_generalsettings.addRow(l_hfreject, hlay_hfreject)
        flay_generalsettings.addItem(
            QSpacerItem(1, 10, QSzPly.Ignored, QSzPly.Preferred))
        flay_generalsettings.addRow(l_measmode, hlay_measmode)
        gbox_generalsettings.setLayout(flay_generalsettings)
        return gbox_generalsettings

    def _setupMeasSettingsWidget(self, mode):
        if mode == 'Normal':
            prefix = self.dcct_prefix
            visible = True
        elif mode == 'Fast':
            prefix = self.dcct_prefix.substitute(propty_name=mode)
            visible = False

        gbox_modesettings = QGroupBox(mode + ' Measurement Mode Settings',
                                      self)

        l_smpcnt = QLabel('Sample Count: ', self)
        spinbox_SampleCnt = PyDMSpinbox(
            self,
            prefix.substitute(propty=prefix.propty_name + 'SampleCnt-SP'))
        spinbox_SampleCnt.showStepExponent = False
        label_SampleCnt = PyDMLabel(
            self,
            prefix.substitute(propty=prefix.propty_name + 'SampleCnt-RB'))
        hlay_smpcnt = QHBoxLayout()
        hlay_smpcnt.addWidget(spinbox_SampleCnt)
        hlay_smpcnt.addWidget(label_SampleCnt)

        l_measperiod = QLabel('Period [s]: ', self)
        spinbox_MeasPeriod = PyDMSpinbox(
            self,
            prefix.substitute(propty=prefix.propty_name + 'MeasPeriod-SP'))
        spinbox_MeasPeriod.showStepExponent = False
        label_MeasPeriod = PyDMLabel(
            self,
            prefix.substitute(propty=prefix.propty_name + 'MeasPeriod-RB'))
        hlay_measperiod = QHBoxLayout()
        hlay_measperiod.addWidget(spinbox_MeasPeriod)
        hlay_measperiod.addWidget(label_MeasPeriod)

        l_measupdateperiod = QLabel('Measured Period [s]: ', self)
        label_MeasUpdatePeriod = PyDMLabel(
            self, self.dcct_prefix.substitute(propty='MeasUpdatePeriod-Mon'))

        l_imped = QLabel('Impedance: ', self)
        enumcombobox_Imped = PyDMEnumComboBox(
            self, prefix.substitute(propty=prefix.propty_name + 'Imped-Sel'))
        label_Imped = PyDMLabel(
            self, prefix.substitute(propty=prefix.propty_name + 'Imped-Sts'))
        hlay_imped = QHBoxLayout()
        hlay_imped.addWidget(enumcombobox_Imped)
        hlay_imped.addWidget(label_Imped)

        l_offset = QLabel('Relative Offset Enable: ', self)
        statebutton_RelEnbl = PyDMStateButton(
            self, prefix.substitute(propty=prefix.propty_name + 'RelEnbl-Sel'))
        statebutton_RelEnbl.shape = 1
        statebutton_RelEnbl.setStyleSheet('min-width:6em; max-width:6em;')
        label_RelEnbl = PyDMLabel(
            self, prefix.substitute(propty=prefix.propty_name + 'RelEnbl-Sts'))
        hlay_offset = QHBoxLayout()
        hlay_offset.addWidget(statebutton_RelEnbl)
        hlay_offset.addWidget(label_RelEnbl)

        l_rellvl = QLabel('Relative Offset Level [V]: ', self)
        spinbox_RelLvl = PyDMSpinbox(
            self, prefix.substitute(propty=prefix.propty_name + 'RelLvl-SP'))
        spinbox_RelLvl.showStepExponent = False
        label_RelLvl = PyDMLabel(
            self, prefix.substitute(propty=prefix.propty_name + 'RelLvl-RB'))
        label_RelLvl.precisionFromPV = False
        label_RelLvl.precision = 9
        pushbutton_RelAcq = PyDMPushButton(
            parent=self,
            label='Acquire Offset',
            pressValue=1,
            init_channel=prefix.substitute(propty=prefix.propty_name +
                                           'RelAcq-Cmd'))
        pushbutton_RelAcq.setAutoDefault(False)
        pushbutton_RelAcq.setDefault(False)
        hlay_rellvl = QHBoxLayout()
        hlay_rellvl.addWidget(spinbox_RelLvl)
        hlay_rellvl.addWidget(label_RelLvl)
        hlay_rellvl.addWidget(pushbutton_RelAcq)

        flay_modesettings = QFormLayout()
        flay_modesettings.setLabelAlignment(Qt.AlignRight)
        flay_modesettings.setFormAlignment(Qt.AlignHCenter)
        flay_modesettings.addRow(l_smpcnt, hlay_smpcnt)
        flay_modesettings.addRow(l_measperiod, hlay_measperiod)
        flay_modesettings.addRow(l_measupdateperiod, label_MeasUpdatePeriod)
        flay_modesettings.addRow(l_imped, hlay_imped)
        flay_modesettings.addRow(l_offset, hlay_offset)
        flay_modesettings.addRow(l_rellvl, hlay_rellvl)

        if mode == 'Normal':
            l_linesync = QLabel('Line Synchronization: ', self)
            statebutton_LineSync = PyDMStateButton(
                self,
                prefix.substitute(propty=prefix.propty_name + 'LineSync-Sel'))
            statebutton_LineSync.shape = 1
            statebutton_LineSync.setStyleSheet('min-width:6em; max-width:6em;')
            label_LineSync = PyDMLabel(
                self,
                prefix.substitute(propty=prefix.propty_name + 'LineSync-Sts'))
            hlay_linesync = QHBoxLayout()
            hlay_linesync.addWidget(statebutton_LineSync)
            hlay_linesync.addWidget(label_LineSync)

            label_avg = QLabel('<h4>Average Filter</h4>', self)
            l_avgenbl = QLabel('Enable: ', self)
            statebutton_AvgFilterEnbl = PyDMStateButton(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterEnbl-Sel'))
            statebutton_AvgFilterEnbl.shape = 1
            label_AvgFilterEnbl = PyDMLabel(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterEnbl-Sts'))
            hlay_avgenbl = QHBoxLayout()
            hlay_avgenbl.addWidget(statebutton_AvgFilterEnbl)
            hlay_avgenbl.addWidget(label_AvgFilterEnbl)

            l_avgcnt = QLabel('Samples: ', self)
            spinbox_AvgFilterCount = PyDMSpinbox(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterCnt-SP'))
            spinbox_AvgFilterCount.showStepExponent = False
            label_AvgFilterCount = PyDMLabel(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterCnt-RB'))
            hlay_avgcnt = QHBoxLayout()
            hlay_avgcnt.addWidget(spinbox_AvgFilterCount)
            hlay_avgcnt.addWidget(label_AvgFilterCount)

            l_avgtyp = QLabel('Type: ', self)
            enumcombobox_AvgFilterTyp = PyDMEnumComboBox(
                self, self.dcct_prefix.substitute(propty='AvgFilterTyp-Sel'))
            label_AvgFilterTyp = PyDMLabel(
                self, self.dcct_prefix.substitute(propty='AvgFilterTyp-Sts'))
            hlay_avgtyp = QHBoxLayout()
            hlay_avgtyp.addWidget(enumcombobox_AvgFilterTyp)
            hlay_avgtyp.addWidget(label_AvgFilterTyp)

            l_avgwin = QLabel('Noise window size [%]: ', self)
            spinbox_AvgFilterWind = PyDMSpinbox(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterWind-SP'))
            spinbox_AvgFilterWind.showStepExponent = False
            label_AvgFilterWind = PyDMLabel(
                self,
                prefix.substitute(propty=prefix.propty_name +
                                  'AvgFilterWind-RB'))
            hlay_avgwin = QHBoxLayout()
            hlay_avgwin.addWidget(spinbox_AvgFilterWind)
            hlay_avgwin.addWidget(label_AvgFilterWind)

            flay_modesettings.addRow(l_linesync, hlay_linesync)
            flay_modesettings.addRow(QLabel(''))
            flay_modesettings.addRow(label_avg)
            flay_modesettings.addRow(l_avgenbl, hlay_avgenbl)
            flay_modesettings.addRow(l_avgcnt, hlay_avgcnt)
            flay_modesettings.addRow(l_avgtyp, hlay_avgtyp)
            flay_modesettings.addRow(l_avgwin, hlay_avgwin)

        gbox_modesettings.setLayout(flay_modesettings)
        gbox_modesettings.setVisible(visible)
        gbox_modesettings.setStyleSheet("""
            PyDMSpinbox, PyDMLabel{
                min-width:6em; max-width:6em;
                qproperty-alignment: AlignCenter;}
            PyDMLedMultiChannel, PyDMStateButton, PyDMEnumComboBox{
                min-width:6em; max-width:6em;}""")
        return gbox_modesettings

    def _setupConfigurationWidget(self):
        statebutton_Test = PyDMStateButton(
            self, self.dcct_prefix.substitute(propty='Test-Sel'))
        statebutton_Test.shape = 1
        statebutton_Test.setStyleSheet('min-width:6em; max-width:6em;')
        label_Test = PyDMLabel(self,
                               self.dcct_prefix.substitute(propty='Test-Sts'))
        hlay_test = QHBoxLayout()
        hlay_test.addWidget(statebutton_Test)
        hlay_test.addWidget(label_Test)

        self.bt_dl = PyDMPushButton(
            parent=self,
            pressValue=1,
            icon=qta.icon('fa5s.sync'),
            init_channel=self.dcct_prefix.substitute(propty='Download-Cmd'))
        self.bt_dl.setObjectName('bt_dl')
        self.bt_dl.setStyleSheet(
            '#bt_dl{min-width:25px; max-width:25px; icon-size:20px;}')

        gbox_test = QGroupBox('Configurations')
        lay = QFormLayout(gbox_test)
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)
        lay.addRow('Enable test current: ', hlay_test)
        lay.addRow('Download Configurations: ', self.bt_dl)
        return gbox_test

    def _setupTriggerWidget(self):
        gbox_trigger = QGroupBox('Trigger', self)
        hbl = QHBoxLayout(gbox_trigger)
        hbl.addWidget(
            HLTriggerSimple(gbox_trigger,
                            device=self.device.substitute(dis='TI'),
                            prefix=self.prefix))
        return gbox_trigger

    def _updateReliableMeasLabels(self, pvname, value, **kwargs):
        if value:
            for idx, lbl in enumerate(self.relmeas_labels):
                lbl.setText(value[idx])

    def _showMeasModeSettings(self, value):
        if value == _DCCTc.MeasModeSel.Normal:
            self.gbox_normalmode.setVisible(True)
            self.gbox_fastmode.setVisible(False)
        elif value == _DCCTc.MeasModeSel.Fast:
            self.gbox_normalmode.setVisible(False)
            self.gbox_fastmode.setVisible(True)
예제 #13
0
    def _setupUi(self):
        # Machine Shift
        self.wid_shift = QGroupBox('Machine Shift')
        machshift_pvname = SiriusPVName(
            'AS-Glob:AP-MachShift:Mode-Sel').substitute(prefix=self._prefix)
        cbox_shift_mode = SiriusEnumComboBox(self, machshift_pvname)
        label_shift_mode = MachShiftLabel(self, self._prefix)
        label_shift_mode.label.setStyleSheet(
            'QLabel{max-height: 2em; min-width: 7em;}')
        lay_shift = QGridLayout(self.wid_shift)
        lay_shift.setVerticalSpacing(5)
        lay_shift.setAlignment(Qt.AlignCenter)
        lay_shift.addWidget(cbox_shift_mode, 1, 0)
        lay_shift.addWidget(label_shift_mode, 2, 0)

        # Injection System
        self.wid_injsys = QGroupBox('Inj.System')
        wid_injsys = InjSysStbyControlWidget(self,
                                             self._prefix,
                                             is_summary=True)
        lay_injsys = QGridLayout(self.wid_injsys)
        lay_injsys.setAlignment(Qt.AlignCenter)
        lay_injsys.setContentsMargins(0, 0, 0, 0)
        lay_injsys.addWidget(wid_injsys)

        # Egun triggers
        self.wid_egun = QGroupBox('Egun Trig.')
        self.wid_egun.setStyleSheet('min-width: 5em;')
        egun_dev = SiriusPVName('LI-01:EG-TriggerPS').substitute(
            prefix=self._prefix)
        but_egun_trigger = PyDMStateButton(
            self, egun_dev.substitute(propty_name='enable'))
        led_egun_trigger = SiriusLedState(
            self, egun_dev.substitute(propty_name='enablereal'))
        lay_egun = QGridLayout(self.wid_egun)
        lay_egun.setVerticalSpacing(5)
        lay_egun.addWidget(but_egun_trigger, 1, 0)
        lay_egun.addWidget(led_egun_trigger, 2, 0)

        # injection control
        injctrl_dev = SiriusPVName('AS-Glob:AP-InjCtrl')
        injctrl_dev = injctrl_dev.substitute(prefix=self._prefix)

        self.wid_inject = QGroupBox('Injection')
        self.ch_injmode = SiriusConnectionSignal(
            injctrl_dev.substitute(propty='Mode-Sts'))
        self.ch_injmode.new_value_signal[int].connect(
            self._handle_injmode_settings_vis)

        # # Settings
        label_sett = QLabel('<h4>Sett.</h4>', self, alignment=Qt.AlignCenter)
        led_sett = InjDiagLed(self)
        self.wid_injsett = QWidget()
        lay_injsett = QGridLayout(self.wid_injsett)
        lay_injsett.setContentsMargins(0, 0, 0, 0)
        lay_injsett.setAlignment(Qt.AlignTop)
        lay_injsett.addWidget(label_sett, 0, 0)
        lay_injsett.addWidget(led_sett, 1, 0)

        # # Auto Stop
        self.label_injauto = QLabel('<h4>AutoStop</h4>',
                                    self,
                                    alignment=Qt.AlignCenter)
        self.but_injauto = PyDMStateButton(
            self, injctrl_dev.substitute(propty='AutoStop-Sel'))
        self.led_injauto = SiriusLedState(
            self, injctrl_dev.substitute(propty='AutoStop-Sts'))
        self.wid_injauto = QWidget()
        self.wid_injauto.setObjectName('wid')
        self.wid_injauto.setStyleSheet("#wid{min-width: 8em; max-width: 8em;}")
        lay_injauto = QGridLayout(self.wid_injauto)
        lay_injauto.setContentsMargins(0, 0, 0, 0)
        lay_injauto.setAlignment(Qt.AlignTop)
        lay_injauto.addWidget(self.label_injauto, 0, 0)
        lay_injauto.addWidget(self.but_injauto, 1, 0)
        lay_injauto.addWidget(self.led_injauto, 2, 0)

        # # Top-up status
        label_tusts = QLabel('<h4>Status</h4>', self, alignment=Qt.AlignCenter)
        label_tunow = ClockLabel(self)
        label_tunow.setStyleSheet('max-height:2em;')
        label_tunxt = SiriusLabel(
            self, injctrl_dev.substitute(propty='TopUpNextInj-Mon'))
        label_tunxt.displayFormat = SiriusLabel.DisplayFormat.Time
        label_tunxt.setAlignment(Qt.AlignCenter)
        label_tunxt.setStyleSheet('max-height:2em;')
        but_round = PyDMPushButton(
            self, '', qta.icon('mdi.tilde'), 1, False,
            injctrl_dev.substitute(propty='TopUpNextInjRound-Cmd'))
        but_round.setObjectName('but')
        but_round.setStyleSheet(
            '#but{min-width:18px; max-width:18px; icon-size:16px;}')
        self.wid_tusts = QWidget()
        self.wid_tusts.setObjectName('wid')
        self.wid_tusts.setStyleSheet("#wid{min-width: 8em; max-width: 8em;}")
        lay_tusts = QGridLayout(self.wid_tusts)
        lay_tusts.setContentsMargins(0, 0, 0, 0)
        lay_tusts.setAlignment(Qt.AlignTop)
        lay_tusts.addWidget(label_tusts, 0, 0, 1, 2)
        lay_tusts.addWidget(QLabel('Now:', self), 1, 0)
        lay_tusts.addWidget(label_tunow, 1, 1)
        lay_tusts.addWidget(QLabel('Next:', self), 2, 0)
        lay_tusts.addWidget(label_tunxt, 2, 1)
        lay_tusts.addWidget(but_round, 2, 2)
        self.wid_tusts.setVisible(False)

        # # Control
        label_inj = QLabel('<h4>Control</h4>', self, alignment=Qt.AlignCenter)
        self.but_tiinj = EVGInjectionButton(self, self._prefix)
        self.but_topup = PyDMStateButton(
            self, injctrl_dev.substitute(propty='TopUpState-Sel'))
        self.but_topup.setVisible(False)
        lay_inject_sel = QGridLayout()
        lay_inject_sel.setAlignment(Qt.AlignCenter)
        lay_inject_sel.addWidget(self.but_tiinj, 0, 0)
        lay_inject_sel.addWidget(self.but_topup, 0, 0)
        led_injsts = EVGInjectionLed(self, self._prefix)
        label_injcnt = PyDMLabel(self)
        label_injcnt.setToolTip(
            'Count injection pulses when Egun Trigger is enabled.')
        label_injcnt.channel = SiriusPVName(
            'AS-Glob:AP-CurrInfo:InjCount-Mon').substitute(prefix=self._prefix)
        label_injcnt.setStyleSheet('QLabel{max-width: 3.5em;}')
        lay_inject_sts = QHBoxLayout()
        lay_inject_sts.setContentsMargins(0, 0, 0, 0)
        lay_inject_sts.setAlignment(Qt.AlignTop)
        lay_inject_sts.addWidget(led_injsts)
        lay_inject_sts.addWidget(label_injcnt)
        self.wid_injctrl = QWidget()
        lay_injctrl = QGridLayout(self.wid_injctrl)
        lay_injctrl.setContentsMargins(0, 0, 0, 0)
        lay_injctrl.setAlignment(Qt.AlignTop)
        lay_injctrl.addWidget(label_inj, 0, 2, alignment=Qt.AlignCenter)
        lay_injctrl.addLayout(lay_inject_sel, 1, 2, alignment=Qt.AlignCenter)
        lay_injctrl.addLayout(lay_inject_sts, 2, 2, alignment=Qt.AlignCenter)

        # # Injection Auxiliary section
        self.wid_injlog = QGroupBox('Injection Log')
        label_injlog = PyDMLogLabel(self,
                                    injctrl_dev.substitute(propty='Log-Mon'),
                                    replace=[
                                        'Remaining time',
                                    ])
        lay_injlog = QGridLayout(self.wid_injlog)
        lay_injlog.addWidget(label_injlog, 0, 0)
        self.wid_injlog.setVisible(False)

        self.wid_mon = MonitorSummaryWidget(self, self._prefix)
        self.wid_mon.setVisible(False)

        # # Target Current
        self._ld_currtgt = QLabel('<h4>Target Curr.</h4>',
                                  self,
                                  alignment=Qt.AlignCenter)
        self._sb_currtgt = SiriusSpinbox(
            self, injctrl_dev.substitute(propty='TargetCurrent-SP'))
        self._sb_currtgt.showStepExponent = False
        self._lb_currtgt = PyDMLabel(
            self, injctrl_dev.substitute(propty='TargetCurrent-RB'))
        self._lb_currtgt.showUnits = True
        self._wid_tcurr = QWidget()
        lay_tcurr = QGridLayout(self._wid_tcurr)
        lay_tcurr.setContentsMargins(0, 0, 0, 0)
        lay_tcurr.setAlignment(Qt.AlignTop)
        lay_tcurr.addWidget(self._ld_currtgt, 0, 0)
        lay_tcurr.addWidget(self._sb_currtgt, 1, 0)
        lay_tcurr.addWidget(self._lb_currtgt, 2, 0)

        # # Bucket List
        self._bucket_list = BucketList(self, prefix=self._prefix, min_size=15)

        self.wid_fill = QWidget()
        lay_fill = QGridLayout(self.wid_fill)
        lay_fill.setContentsMargins(0, 0, 0, 0)
        lay_fill.setHorizontalSpacing(9)
        lay_fill.addWidget(self._wid_tcurr, 0, 0)
        lay_fill.addWidget(self._bucket_list, 0, 1)
        self.wid_fill.setVisible(False)

        pbt_aux = QPushButton('v', self)
        pbt_aux.setToolTip('Show Injection Auxiliary section.')
        pbt_aux.clicked.connect(self._toggle_show_injaux)
        pbt_aux.setStyleSheet('QPushButton{max-width: 0.8em;}')
        pbt_bl = QPushButton('>', self)
        pbt_bl.setToolTip('Show bucket list and target current controls.')
        pbt_bl.clicked.connect(self._toggle_show_bucketlist)
        pbt_bl.setStyleSheet('QPushButton{max-width: 0.8em;}')

        lay_inj = QGridLayout(self.wid_inject)
        lay_inj.setAlignment(Qt.AlignTop)
        lay_inj.setVerticalSpacing(5)
        lay_inj.setHorizontalSpacing(12)
        lay_inj.addWidget(self.wid_injsett, 0, 0, 2, 1)
        lay_inj.addWidget(self.wid_injauto, 0, 1, 2, 1)
        lay_inj.addWidget(self.wid_tusts, 0, 1, 2, 1)
        lay_inj.addWidget(self.wid_injctrl, 0, 2, 2, 1)
        lay_inj.addWidget(pbt_bl, 0, 3, alignment=Qt.AlignTop)
        lay_inj.addWidget(pbt_aux, 1, 3, alignment=Qt.AlignBottom)
        lay_inj.addWidget(self.wid_fill, 0, 4, 2, 1)

        # Current
        curr_pvname = SiriusPVName(
            'SI-Glob:AP-CurrInfo:Current-Mon').substitute(prefix=self._prefix)
        self.label_curr = PyDMLabel(self, curr_pvname)
        self.label_curr.showUnits = True
        self.label_curr.setStyleSheet("""
            QLabel{
                font-size: 18pt; qproperty-alignment: AlignCenter;
                min-width: 6em; max-width: 6em;
            }""")
        self.wid_curr = QGroupBox('Current')
        lay_curr = QHBoxLayout(self.wid_curr)
        lay_curr.addWidget(self.label_curr)

        # RF Kill Beam
        self.wid_rfkill = QGroupBox('RF Kill Beam')
        self.wid_rfkill.setObjectName('RFKillBeam')
        rfkill_bt = RFKillBeamButton(self, self._prefix)
        rfkill_lay = QGridLayout(self.wid_rfkill)
        rfkill_lay.addWidget(rfkill_bt)

        # menu buttons
        self.wid_pbt = QPushButton('v', self)
        self.wid_pbt.clicked.connect(self._toggle_show_menubutton)
        self.wid_pbt.setStyleSheet('QPushButton{max-width: 0.8em;}')
        self._menubutton = get_object(ismenubar=False, parent=self)
        self._menubutton.layout().setContentsMargins(0, 0, 0, 0)
        self._menubutton.layout().setSpacing(4)
        self._menubutton.setVisible(False)

        hlay1 = QHBoxLayout()
        hlay1.setContentsMargins(0, 0, 0, 0)
        hlay1.addWidget(self.wid_shift)
        hlay1.addWidget(self.wid_injsys)
        hlay1.addWidget(self.wid_egun)
        hlay1.addWidget(self.wid_inject)
        hlay1.addWidget(self.wid_curr)
        hlay1.addWidget(self.wid_rfkill)

        hlay2 = QHBoxLayout()
        hlay2.setContentsMargins(0, 0, 0, 0)
        hlay2.addWidget(self.wid_injlog)
        hlay2.addWidget(self.wid_mon)

        cwid = QWidget(self)
        lay = QGridLayout(cwid)
        lay.addLayout(hlay1, 0, 0)
        lay.addLayout(hlay2, 1, 0)
        lay.addWidget(self._menubutton, 2, 0, 1, 2)
        lay.addWidget(self.wid_pbt,
                      0,
                      1,
                      2,
                      1,
                      alignment=Qt.AlignRight | Qt.AlignBottom)
        self.setCentralWidget(cwid)
예제 #14
0
파일: main.py 프로젝트: lnls-sirius/hla
    def get_orbit_widget(self, parent):
        """."""
        orb_wid = QWidget(parent)
        orb_wid.setObjectName('grp')
        orb_wid.setStyleSheet('#grp{min-height: 11em; max-height: 15em;}')
        orb_wid.setLayout(QGridLayout())

        conf = PyDMPushButton(
            orb_wid, pressValue=1,
            init_channel=self.devpref.substitute(propty='TrigAcqConfig-Cmd'))
        conf.setToolTip('Refresh Configurations')
        conf.setIcon(qta.icon('fa5s.sync'))
        conf.setObjectName('conf')
        conf.setStyleSheet(
            '#conf{min-width:25px; max-width:25px; icon-size:20px;}')

        sts = QPushButton('', orb_wid)
        sts.setIcon(qta.icon('fa5s.list-ul'))
        sts.setToolTip('Open Detailed Status View')
        sts.setObjectName('sts')
        sts.setStyleSheet(
            '#sts{min-width:25px; max-width:25px; icon-size:20px;}')
        icon = qta.icon(
            'fa5s.hammer', color=_util.get_appropriate_color(self.acc))
        window = create_window_from_widget(
            StatusWidget, title='Orbit Status', icon=icon)
        _util.connect_window(
            sts, window, orb_wid, device=self.device,
            prefix=self.prefix, acc=self.acc, is_orb=True)

        pdm_led = SiriusLedAlert(
            orb_wid, self.devpref.substitute(propty='OrbStatus-Mon'))

        lbl = QLabel('Status:', orb_wid)
        hbl = QHBoxLayout()
        hbl.setSpacing(9)
        hbl.addStretch()
        hbl.addWidget(lbl)
        hbl.addWidget(pdm_led)
        hbl.addWidget(sts)
        hbl.addWidget(conf)
        orb_wid.layout().addItem(hbl, 0, 0, 1, 2)

        lbl = QLabel('SOFB Mode', orb_wid)
        wid = self.create_pair_sel(orb_wid, 'SOFBMode')
        orb_wid.layout().addWidget(lbl, 1, 0, alignment=Qt.AlignVCenter)
        orb_wid.layout().addWidget(wid, 1, 1)

        lbl = QLabel('RefOrb:', orb_wid)
        combo = RefControl(
            self, self.device, self.ctrls, prefix=self.prefix, acc=self.acc)
        lbl2 = QLabel('', orb_wid)
        combo.configname.connect(lbl2.setText)
        vbl_ref = QVBoxLayout()
        vbl_ref.addWidget(combo)
        vbl_ref.addWidget(lbl2)
        orb_wid.layout().addWidget(lbl, 3, 0, alignment=Qt.AlignVCenter)
        orb_wid.layout().addLayout(vbl_ref, 3, 1)

        lbl = QLabel('Num. Pts.', orb_wid)
        stp = SiriusSpinbox(
            orb_wid, self.devpref.substitute(propty='SmoothNrPts-SP'))
        stp.showStepExponent = False
        rdb = PyDMLabel(
            orb_wid, self.devpref.substitute(propty='SmoothNrPts-RB'))
        rdb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slsh = QLabel('/', orb_wid, alignment=Qt.AlignCenter)
        slsh.setStyleSheet('min-width:0.7em; max-width:0.7em;')
        cnt = PyDMLabel(
            orb_wid, self.devpref.substitute(propty='BufferCount-Mon'))
        cnt.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        cnt.setToolTip('Current Buffer Size')
        rst = PyDMPushButton(
            orb_wid, pressValue=1,
            init_channel=self.devpref.substitute(propty='SmoothReset-Cmd'))
        rst.setToolTip('Reset Buffer')
        rst.setIcon(qta.icon('mdi.delete-empty'))
        rst.setObjectName('rst')
        rst.setStyleSheet(
            '#rst{min-width:25px; max-width:25px; icon-size:20px;}')
        hbl = QHBoxLayout()
        hbl.addWidget(stp)
        hbl.addWidget(cnt)
        hbl.addWidget(slsh)
        hbl.addWidget(rdb)
        hbl.addWidget(rst)
        orb_wid.layout().addWidget(lbl, 4, 0, alignment=Qt.AlignVCenter)
        orb_wid.layout().addItem(hbl, 4, 1)

        orb_wid.layout().setColumnStretch(1, 2)
        return orb_wid
예제 #15
0
파일: main.py 프로젝트: lnls-sirius/hla
    def get_manual_correction_widget(self, parent):
        """."""
        man_wid = QWidget(parent)
        man_wid.setObjectName('grp')
        gdl = QGridLayout(man_wid)
        gdl.setSpacing(9)

        calc = PyDMPushButton(
            man_wid, '', pressValue=1,
            init_channel=self.devpref.substitute(propty='CalcDelta-Cmd'))
        calc.setIcon(qta.icon('mdi.calculator-variant'))
        calc.setToolTip('Calculate Kicks')
        calc.setObjectName('button')
        calc.setStyleSheet('#button {\
            min-height: 45px; min-width: 45px;\
            max-height: 45px; max-width: 45px;\
            icon-size: 40px;}')
        rules = (
            '[{"name": "EnblRule", "property": "Enable", ' +
            '"expression": "not ch[0]", "channels": [{"channel": "' +
            self.devpref.substitute(propty='LoopState-Sts') +
            '", "trigger": true}]}]')
        calc.rules = rules

        if self.acc == 'BO':
            gdl.addWidget(calc, 1, 1)
            gdl.setColumnStretch(0, 2)
            gdl.setColumnStretch(2, 2)
            gdl.setRowStretch(0, 2)
            gdl.setRowStretch(2, 2)
            return man_wid

        exp = 'ch[0] in (1, 2, 3)'
        ch = ''
        if self.isring:
            exp = 'ch[1] in (1, 2, 3) and not ch[0]'
            ch = '{"channel": "' + self.devpref.substitute(
                 propty='LoopState-Sts') + '", "trigger": true},'
        rules = (
            '[{"name": "EnblRule", "property": "Enable", ' +
            '"expression": "'+exp+'", "channels": ['+ch +
            '{"channel": "'+self.devpref.substitute(propty='SOFBMode-Sts') +
            '", "trigger": true}]}]')

        lst = [
            ('All', self._csorb.ApplyDelta.All),
            ('CH', self._csorb.ApplyDelta.CH),
            ('CV', self._csorb.ApplyDelta.CV)]
        if self.acc in {'SI', 'BO'}:
            lst.append(('RF', self._csorb.ApplyDelta.RF))
        btns = dict()
        for itm, val in lst:
            btn = PyDMPushButton(
                man_wid, ' '+itm, pressValue=val,
                init_channel=self.devpref.substitute(propty='ApplyDelta-Cmd'))
            btn.rules = rules
            btn.setIcon(qta.icon('fa5s.hammer'))
            btn.setToolTip('Apply ' + itm)
            btn.setObjectName('button')
            btn.setStyleSheet('#button {\
                min-height: 25px; min-width: 45px;\
                max-height: 25px;\
                icon-size: 20px;}')
            if self.acc == 'BO':
                btn.setVisible(False)
            btns[itm] = btn

        gdl.addWidget(calc, 0, 0, 2, 1)
        gdl.addWidget(btns['CH'], 0, 1)
        gdl.addWidget(btns['CV'], 0, 2)
        if self.acc in {'SI', 'BO'}:
            gdl.addWidget(btns['RF'], 0, 3)
            gdl.addWidget(btns['All'], 1, 1, 1, 3)
        else:
            gdl.addWidget(btns['All'], 1, 1, 1, 2)
        gdl.setColumnMinimumWidth(0, 60)

        grpbx = QWidget(man_wid)
        grpbx.setObjectName('gbx')
        if self.acc in {'SI', 'BO'}:
            planes = ('CH', 'CV', 'RF')
            gdl.addWidget(grpbx, 2, 0, 1, 4)
        else:
            planes = ('CH', 'CV')
            gdl.addWidget(grpbx, 2, 0, 1, 3)
        fbl = QFormLayout(grpbx)
        for pln in planes:
            lbl = QLabel(pln+' [%] ', grpbx)
            lbl.setObjectName('lbl')
            lbl.setStyleSheet('#lbl{min-height:1em;}')
            wid = self.create_pair(grpbx, 'ManCorrGain'+pln)
            wid.setObjectName('wid')
            wid.setStyleSheet('#wid{min-height:1.2em;}')
            if self.acc == 'BO':
                lbl.setVisible(False)
                wid.setVisible(False)
            fbl.addRow(lbl, wid)

        vlay = QVBoxLayout()
        vlay.addStretch()
        gdl.addLayout(vlay, 3, 0)
        return man_wid
예제 #16
0
    def _get_acq_commom_params_grpbx(self):
        grp_bx = QGroupBox('Common Parameters', self)
        fbl = QFormLayout(grp_bx)

        lbl = QLabel('Non-linear Corr.', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_butled(grp_bx, 'PolyCalibration')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        lbl = QLabel('Channel Rate', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_sel(grp_bx, 'TrigAcqChan')
        fbl.addRow(lbl, wid)

        lbl = QLabel('Trigger Type', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_sel(grp_bx, 'TrigAcqTrigger')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        lbl = QLabel('Repeat', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair_butled(grp_bx, 'TrigAcqRepeat')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])

        if self.isring:
            lbl = QLabel('Nr of Shots', grp_bx, alignment=Qt.AlignCenter)
            wid = self.create_pair(grp_bx, 'TrigNrShots')
            fbl.addRow(lbl, wid)
            self._set_detailed([lbl, wid])

        lbl = QLabel('SamplesPre', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'TrigNrSamplesPre')
        fbl.addRow(lbl, wid)
        lbl = QLabel('SamplesPost', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'TrigNrSamplesPost')
        fbl.addRow(lbl, wid)

        lbl = QLabel('Acquisition:', grp_bx, alignment=Qt.AlignCenter)
        strt = PyDMPushButton(
            grp_bx,
            label='',
            init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'),
            pressValue=self._csorb.TrigAcqCtrl.Start)
        strt.setToolTip('Start Acquisition')
        strt.setIcon(qta.icon('fa5s.play'))
        strt.setObjectName('strt')
        strt.setStyleSheet(
            '#strt{min-width:25px; max-width:25px; icon-size:20px;}')
        stop = PyDMPushButton(
            grp_bx,
            label='',
            init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'),
            pressValue=self._csorb.TrigAcqCtrl.Stop)
        stop.setToolTip('Stop Acquisition')
        stop.setIcon(qta.icon('fa5s.stop'))
        stop.setObjectName('stop')
        stop.setStyleSheet(
            '#stop{min-width:25px; max-width:25px; icon-size:20px;}')
        abrt = PyDMPushButton(
            grp_bx,
            label='',
            init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'),
            pressValue=self._csorb.TrigAcqCtrl.Abort)
        abrt.setToolTip('Abort Acquisition')
        abrt.setIcon(qta.icon('fa5s.ban'))
        abrt.setObjectName('abrt')
        abrt.setStyleSheet(
            '#abrt{min-width:25px; max-width:25px; icon-size:20px;}')

        pdmlbl = PyDMLabel(grp_bx,
                           self.devpref.substitute(propty='TrigAcqCtrl-Sts'))
        pdmlbl.setObjectName('pdmlbl')
        pdmlbl.setStyleSheet('#pdmlbl{min-width:6em; max-width:6em;}')
        pdmlbl.setAlignment(Qt.AlignCenter)
        hbl = QHBoxLayout()
        fbl.addRow(hbl)
        hbl.addStretch()
        hbl.addWidget(lbl)
        hbl.addWidget(strt)
        hbl.addWidget(stop)
        hbl.addWidget(abrt)
        hbl.addWidget(pdmlbl)

        conf = PyDMPushButton(
            grp_bx,
            pressValue=1,
            init_channel=self.devpref.substitute(propty='TrigAcqConfig-Cmd'))
        conf.setToolTip('Resend Configurations')
        conf.setIcon(qta.icon('fa5s.sync'))
        conf.setObjectName('conf')
        conf.setStyleSheet(
            '#conf{min-width:25px; max-width:25px; icon-size:20px;}')

        sts = QPushButton('', grp_bx)
        sts.setIcon(qta.icon('fa5s.list-ul'))
        sts.setToolTip('Open Detailed Status View')
        sts.setObjectName('sts')
        sts.setStyleSheet(
            '#sts{min-width:25px; max-width:25px; icon-size:20px;}')
        Window = create_window_from_widget(StatusWidget, title='Orbit Status')
        connect_window(sts,
                       Window,
                       grp_bx,
                       device=self.device,
                       prefix=self.prefix,
                       acc=self.acc,
                       is_orb=True)

        pdm_led = SiriusLedAlert(
            grp_bx, self.devpref.substitute(propty='OrbStatus-Mon'))

        lbl = QLabel('Status:', grp_bx)
        hbl = QHBoxLayout()
        hbl.setSpacing(9)
        hbl.addStretch()
        hbl.addWidget(lbl)
        hbl.addWidget(pdm_led)
        hbl.addWidget(sts)
        hbl.addWidget(conf)
        fbl.addRow(hbl)

        return grp_bx
예제 #17
0
class OpticsCorrWindow(SiriusMainWindow):
    """Class to include some intelligence in the .ui files."""

    def __init__(self, acc, opticsparam, parent=None, prefix=_VACA_PREFIX):
        """Initialize some widgets."""
        super(OpticsCorrWindow, self).__init__(parent)
        self.prefix = prefix
        self.acc = acc.upper()
        self.param = opticsparam
        self.ioc_prefix = _PVName(
            self.acc+'-Glob:AP-'+self.param.title()+'Corr')
        self.ioc_prefix = self.ioc_prefix.substitute(prefix=self.prefix)
        self.title = self.acc + ' ' + self.param.title() + ' Correction'

        if self.param == 'tune':
            self.param_pv = 'DeltaTune{0}-{1}'
            self.intstrength = 'KL'
            self.intstrength_calcdesc = 'DeltaKL-Mon'
            self.intstrength_calcpv = 'DeltaKL{}-Mon'
            self.fams = list(_Const.SI_QFAMS_TUNECORR) if self.acc == 'SI' \
                else list(_Const.BO_QFAMS_TUNECORR)
        elif self.param == 'chrom':
            self.param_pv = 'Chrom{0}-{1}'
            self.intstrength = 'SL'
            self.intstrength_calcdesc = 'CalcSL-Mon'
            self.intstrength_calcpv = 'SL{}-Mon'
            self.fams = list(_Const.SI_SFAMS_CHROMCORR) if self.acc == 'SI' \
                else list(_Const.BO_SFAMS_CHROMCORR)

        self.setWindowTitle(self.title)
        self.setObjectName(self.acc+'App')
        self._setupUi()
        self.setFocus(True)
        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        label = QLabel('<h3>'+self.title+'</h3>', self)
        label.setStyleSheet("""
            min-height:1.55em; max-height: 1.55em;
            qproperty-alignment: 'AlignVCenter | AlignRight';
            background-color: qlineargradient(spread:pad, x1:1, y1:0.0227273,
                              x2:0, y2:0, stop:0 rgba(173, 190, 207, 255),
                              stop:1 rgba(213, 213, 213, 255));""")

        self.gb_status = QGroupBox('Status', self)
        self.gb_status.setLayout(self._setupStatusLayout())

        self.wid_optics = QWidget()
        lay_optics = QGridLayout(self.wid_optics)
        lay_optics.setContentsMargins(0, 0, 0, 0)
        self.gb_optprm = QGroupBox(
            'ΔTune' if self.param == 'tune' else 'Chromaticity', self)
        self.gb_optprm.setLayout(self._setupOpticsParamLayout())
        if self.param == 'tune':
            self.pb_updref = PyDMPushButton(
                self, label='Update Reference', pressValue=1,
                init_channel=self.ioc_prefix.substitute(propty='SetNewRefKL-Cmd'))
            self.pb_updref.setStyleSheet('min-height:2.4em; max-height:2.4em;')
            lay_optics.addWidget(self.pb_updref, 0, 0, 1, 2)
            lay_optics.addWidget(self.gb_optprm, 1, 0)

            if self.acc == 'SI':
                self.gb_digmon = QGroupBox('Tune Monitor', self)
                self.gb_digmon.setLayout(self._setupDigMonLayout())
                lay_optics.addWidget(self.gb_digmon, 1, 1)
                lay_optics.setColumnStretch(0, 3)
                lay_optics.setColumnStretch(1, 1)
        else:
            lay_optics.addWidget(self.gb_optprm, 0, 0)

        self.gb_fams = QGroupBox('Families', self)
        self.gb_fams.setLayout(self._setupFamiliesLayout())
        self.gb_fams.setSizePolicy(QSzPly.Preferred, QSzPly.Expanding)

        self.gb_iocctrl = QGroupBox('IOC Control', self)
        self.gb_iocctrl.setLayout(self._setupIOCControlLayout())

        cwt = QWidget()
        self.setCentralWidget(cwt)
        if self.acc == 'SI':
            vlay1 = QVBoxLayout()
            vlay1.setAlignment(Qt.AlignTop)
            vlay1.addWidget(self.wid_optics)
            vlay1.addWidget(self.gb_fams)
            lay = QGridLayout(cwt)
            lay.addWidget(label, 0, 0, 1, 2)
            lay.addLayout(vlay1, 1, 0, alignment=Qt.AlignTop)
            lay.addWidget(self.gb_iocctrl, 1, 1)
            lay.addWidget(self.gb_status, 2, 0, 1, 2)
            lay.setColumnStretch(0, 1)
            lay.setColumnStretch(1, 1)
            lay.setRowStretch(0, 1)
            lay.setRowStretch(1, 15)
            lay.setRowStretch(2, 5)
        else:
            lay = QVBoxLayout(cwt)
            lay.addWidget(label)
            lay.addWidget(self.wid_optics)
            lay.addWidget(self.gb_fams)
            lay.addWidget(self.gb_iocctrl)
            lay.addWidget(self.gb_status)

        self.setStyleSheet("""
            PyDMLabel{
                qproperty-alignment: AlignCenter;
            }""")

    def _setupStatusLayout(self):
        self.log_label = PyDMLogLabel(
            self, self.ioc_prefix.substitute(propty='Log-Mon'))

        lay = QVBoxLayout()
        lay.addWidget(self.log_label)
        return lay

    def _setupOpticsParamLayout(self):
        self.lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter)
        self.lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter)
        self.lb_sp = QLabel('<h4>SP</h4>', self, alignment=Qt.AlignCenter)
        self.lb_rb = QLabel('<h4>RB</h4>', self, alignment=Qt.AlignCenter)
        self.lb_mon = QLabel(
            '<h4>Estimative</h4>', self, alignment=Qt.AlignCenter)

        self.sb_paramx = PyDMSpinbox(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('X', 'SP')))
        self.sb_paramx.showStepExponent = False
        self.sb_paramy = PyDMSpinbox(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('Y', 'SP')))
        self.sb_paramy.showStepExponent = False

        self.lb_paramx = PyDMLabel(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('X', 'RB')))
        self.lb_paramy = PyDMLabel(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('Y', 'RB')))

        self.lb_prmmonx = PyDMLabel(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('X', 'Mon')))
        self.lb_prmmony = PyDMLabel(self, self.ioc_prefix.substitute(
            propty=self.param_pv.format('Y', 'Mon')))

        self.bt_apply = PyDMPushButton(
            self, label='Apply', pressValue=1,
            init_channel=self.ioc_prefix.substitute(
                propty='ApplyDelta-Cmd'))

        lay = QGridLayout()
        lay.addWidget(self.lb_sp, 0, 1)
        lay.addWidget(self.lb_rb, 0, 2)
        lay.addWidget(self.lb_x, 1, 0)
        lay.addWidget(self.sb_paramx, 1, 1)
        lay.addWidget(self.lb_paramx, 1, 2)
        lay.addWidget(self.lb_y, 2, 0)
        lay.addWidget(self.sb_paramy, 2, 1)
        lay.addWidget(self.lb_paramy, 2, 2)
        lay.addWidget(self.lb_mon, 0, 3)
        lay.addWidget(self.lb_prmmonx, 1, 3)
        lay.addWidget(self.lb_prmmony, 2, 3)
        lay.addWidget(self.bt_apply, 3, 1)
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 5)
        lay.setColumnStretch(2, 5)
        lay.setColumnStretch(3, 5)

        if self.acc == 'SI' and self.param == 'chrom':
            self._icon_absval = qta.icon(
                'mdi.alpha-a', 'mdi.alpha-b', 'mdi.alpha-s', options=[
                    dict(scale_factor=1.5, offset=(-0.4, 0.0)),
                    dict(scale_factor=1.5, offset=(0.0, 0.0)),
                    dict(scale_factor=1.5, offset=(+0.4, 0.0))])
            self._icon_delta = qta.icon('mdi.delta')
            self._is_setting = 'absolut'
            self.pb_change_sp = QPushButton(self._icon_absval, '', self)
            self.pb_change_sp.clicked.connect(self._change_chrom_sp)

            self.sb_paramx_delta = PyDMSpinbox(
                self, self.ioc_prefix.substitute(propty='DeltaChromX-SP'))
            self.sb_paramx_delta.showStepExponent = False
            self.sb_paramx_delta.setVisible(False)

            self.sb_paramy_delta = PyDMSpinbox(
                self, self.ioc_prefix.substitute(propty='DeltaChromY-SP'))
            self.sb_paramy_delta.showStepExponent = False
            self.sb_paramy_delta.setVisible(False)

            self.lb_paramx_delta = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='DeltaChromX-RB'))
            self.lb_paramx_delta.setVisible(False)
            self.lb_paramy_delta = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='DeltaChromY-RB'))
            self.lb_paramy_delta.setVisible(False)

            self.lb_mon.setText('Implem.\nEstimative')
            self.lb_mon.setStyleSheet('font-weight: bold;')
            self.lb_calcmon = QLabel(
                'Calcd.\nEstimative', self, alignment=Qt.AlignCenter)
            self.lb_calcmon.setStyleSheet('font-weight: bold;')

            self.lb_prmcalcmonx = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='CalcChromX-Mon'))
            self.lb_prmcalcmony = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='CalcChromY-Mon'))

            lay.addWidget(self.pb_change_sp, 0, 0)
            lay.addWidget(self.sb_paramx_delta, 1, 1)
            lay.addWidget(self.sb_paramy_delta, 2, 1)
            lay.addWidget(self.lb_paramx_delta, 1, 2)
            lay.addWidget(self.lb_paramy_delta, 2, 2)
            lay.addWidget(self.lb_calcmon, 0, 4)
            lay.addWidget(self.lb_prmcalcmonx, 1, 4)
            lay.addWidget(self.lb_prmcalcmony, 2, 4)
        return lay

    def _setupDigMonLayout(self):
        lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter)
        lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter)
        self.lb_tunex = PyDMLabel(self, 'SI-Glob:DI-Tune-H:TuneFrac-Mon')
        self.lb_tuney = PyDMLabel(self, 'SI-Glob:DI-Tune-V:TuneFrac-Mon')

        lay = QGridLayout()
        lay.addWidget(lb_x, 0, 0)
        lay.addWidget(self.lb_tunex, 0, 1)
        lay.addWidget(lb_y, 1, 0)
        lay.addWidget(self.lb_tuney, 1, 1)
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 5)
        return lay

    def _setupFamiliesLayout(self):
        lay = QGridLayout()

        lb_family = QLabel('<h4>Family</h4>', self, alignment=Qt.AlignCenter)
        lb_family.setStyleSheet('max-height:1.29em;')
        lay.addWidget(lb_family, 0, 1)

        lb_rbdesc = QLabel('<h4>'+self.intstrength+'-RB</h4>', self,
                           alignment=Qt.AlignCenter)
        lb_rbdesc.setStyleSheet('max-height:1.29em;')
        lay.addWidget(lb_rbdesc, 0, 2)

        if self.param == 'tune':
            lb_refdesc = QLabel('<h4>RefKL-Mon</h4>', self,
                                alignment=Qt.AlignCenter)
            lb_refdesc.setStyleSheet('max-height:1.29em;')
            lay.addWidget(lb_refdesc, 0, 3)

        lb_lastddesc = QLabel('<h4>'+self.intstrength_calcdesc+'</h4>', self,
                              alignment=Qt.AlignCenter)
        lb_lastddesc.setStyleSheet('max-height:1.29em;')
        lay.addWidget(lb_lastddesc, 0, 4)

        row = 1
        for fam in self.fams:
            dev_name = _PVName(self.acc+'-Fam:PS-'+fam)
            pref_name = dev_name.substitute(prefix=self.prefix)

            pbt = QPushButton(qta.icon('fa5s.list-ul'), '', self)
            pbt.setObjectName('pbt')
            pbt.setStyleSheet("""
                #pbt{
                    min-width:25px; max-width:25px;
                    min-height:25px; max-height:25px;
                    icon-size:20px;}""")
            _hlautil.connect_window(
                pbt, _PSDetailWindow, parent=self, psname=dev_name)
            lay.addWidget(pbt, row, 0)

            lb_name = QLabel(fam, self, alignment=Qt.AlignCenter)
            lay.addWidget(lb_name, row, 1)

            lb_rb = PyDMLabel(self, pref_name.substitute(
                propty=self.intstrength+'-RB'))
            lay.addWidget(lb_rb, row, 2)

            if self.param == 'tune':
                lb_ref = PyDMLabel(self, self.ioc_prefix.substitute(
                    propty='RefKL'+fam+'-Mon'))
                lay.addWidget(lb_ref, row, 3)

            lb_calc = PyDMLabel(self, self.ioc_prefix.substitute(
                propty=self.intstrength_calcpv.format(fam)))
            lay.addWidget(lb_calc, row, 4)
            row += 1
        return lay

    def _setupIOCControlLayout(self):
        lay = QGridLayout()

        lb_sts = QLabel('<h4>Status</h4>', self)
        self.led_sts = _StatusLed(self, self.ioc_prefix.substitute(
            propty='Status-Mon'))
        lay.addWidget(lb_sts, 0, 0)
        lay.addWidget(self.led_sts, 0, 1, alignment=Qt.AlignLeft)

        lb_conf = QLabel('<h4>Configuration</h4>')
        self.bt_dtls = QPushButton(qta.icon('fa5s.list-ul'), '', self)
        _hlautil.connect_window(
            self.bt_dtls, _CorrParamsDetailWindow, parent=self,
            acc=self.acc, opticsparam=self.param,
            prefix=self.prefix, fams=self.fams)
        lay.addWidget(lb_conf, 2, 0, 1, 2)
        lay.addWidget(self.bt_dtls, 2, 2, alignment=Qt.AlignRight)

        lb_cname = QLabel('Name', self)
        self.le_cname = _ConfigLineEdit(
            self, self.ioc_prefix.substitute(
                propty='ConfigName-SP'))
        self.lb_cname = PyDMLabel(self, self.ioc_prefix.substitute(
            propty='ConfigName-RB'))
        lay.addWidget(lb_cname, 3, 0)
        lay.addWidget(self.le_cname, 3, 1, 1, 2)
        lay.addWidget(self.lb_cname, 4, 1, 1, 2)

        row = 5
        if self.acc == 'SI':
            lay.addItem(
                QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 5, 0)
            row = 6

            if self.param == 'chrom':
                lb_meas_chrom = QLabel('<h4>Chrom. Measurement</h4>')
                lay.addWidget(lb_meas_chrom, 6, 0, 1, 3)

                lb_meas_chrom_dfRF = QLabel('ΔFreq RF [Hz]', self)
                self.sb_meas_chrom_dfRF = PyDMSpinbox(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromDeltaFreqRF-SP'))
                self.sb_meas_chrom_dfRF.showStepExponent = False
                self.lb_meas_chrom_dfRF = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromDeltaFreqRF-RB'))
                lay.addWidget(lb_meas_chrom_dfRF, 7, 0)
                lay.addWidget(self.sb_meas_chrom_dfRF, 7, 1)
                lay.addWidget(self.lb_meas_chrom_dfRF, 7, 2)

                lb_meas_chrom_wait = QLabel('Wait Tune [s]', self)
                self.sb_meas_chrom_wait = PyDMSpinbox(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromWaitTune-SP'))
                self.sb_meas_chrom_wait.showStepExponent = False
                self.lb_meas_chrom_wait = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromWaitTune-RB'))
                lay.addWidget(lb_meas_chrom_wait, 8, 0)
                lay.addWidget(self.sb_meas_chrom_wait, 8, 1)
                lay.addWidget(self.lb_meas_chrom_wait, 8, 2)

                lb_meas_chrom_nrsteps = QLabel('Nr Steps', self)
                self.sb_meas_chrom_nrsteps = PyDMSpinbox(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromNrSteps-SP'))
                self.sb_meas_chrom_nrsteps.showStepExponent = False
                self.lb_meas_chrom_nrsteps = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromNrSteps-RB'))
                lay.addWidget(lb_meas_chrom_nrsteps, 9, 0)
                lay.addWidget(self.sb_meas_chrom_nrsteps, 9, 1)
                lay.addWidget(self.lb_meas_chrom_nrsteps, 9, 2)

                lay.addItem(
                    QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 10, 0)

                lb_meas_chrom_x = QLabel('Meas. Chrom X', self)
                self.lb_meas_chrom_x = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromX-Mon'))
                lay.addWidget(lb_meas_chrom_x, 11, 0)
                lay.addWidget(self.lb_meas_chrom_x, 11, 1)

                lb_meas_chrom_y = QLabel('Meas. Chrom Y', self)
                self.lb_meas_chrom_y = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromY-Mon'))
                lay.addWidget(lb_meas_chrom_y, 12, 0)
                lay.addWidget(self.lb_meas_chrom_y, 12, 1)

                lay.addItem(
                    QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 13, 0)

                self.lb_meas_chrom_sts = PyDMLabel(
                    self, self.ioc_prefix.substitute(
                        propty='MeasChromStatus-Mon'))
                self.bt_meas_chrom_start = PyDMPushButton(
                    self, icon=qta.icon('fa5s.play'), label='',
                    init_channel=self.ioc_prefix.substitute(
                        propty='MeasChrom-Cmd'),
                    pressValue=_Const.MeasCmd.Start)
                self.bt_meas_chrom_start.setObjectName('start')
                self.bt_meas_chrom_start.setStyleSheet(
                    '#start{min-width:25px; max-width:25px; icon-size:20px;}')
                self.bt_meas_chrom_stop = PyDMPushButton(
                    self, icon=qta.icon('fa5s.stop'), label='',
                    init_channel=self.ioc_prefix.substitute(
                        propty='MeasChrom-Cmd'),
                    pressValue=_Const.MeasCmd.Stop)
                self.bt_meas_chrom_stop.setObjectName('stop')
                self.bt_meas_chrom_stop.setStyleSheet(
                    '#stop{min-width:25px; max-width:25px; icon-size:20px;}')
                self.bt_meas_chrom_rst = PyDMPushButton(
                    self, icon=qta.icon('fa5s.sync'), label='',
                    init_channel=self.ioc_prefix.substitute(
                        propty='MeasChrom-Cmd'),
                    pressValue=_Const.MeasCmd.Reset)
                self.bt_meas_chrom_rst.setObjectName('rst')
                self.bt_meas_chrom_rst.setStyleSheet(
                    '#rst{min-width:25px; max-width:25px; icon-size:20px;}')
                hbox_cmd = QHBoxLayout()
                hbox_cmd.addWidget(self.bt_meas_chrom_start)
                hbox_cmd.addWidget(self.bt_meas_chrom_stop)
                hbox_cmd.addWidget(self.bt_meas_chrom_rst)
                lay.addWidget(self.lb_meas_chrom_sts, 14, 0, 1, 2)
                lay.addLayout(hbox_cmd, 14, 2)

                lay.addItem(
                    QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 15, 0)
                row = 15

            # configuration measurement
            lb_meas_conf = QLabel('<h4>Config. Measurement</h4>')
            lay.addWidget(lb_meas_conf, row+1, 0, 1, 3)

            mag_type = 'Q' if self.param == 'tune' else 'S'
            unit = '[1/m]' if self.param == 'tune' else '[1/m2]'

            lb_meas_conf_dfamF = QLabel(
                'Fam. Δ'+self.intstrength+' '+mag_type+'F '+unit, self)
            self.sb_meas_conf_dfamF = PyDMSpinbox(
                self, self.ioc_prefix.substitute(
                    propty='MeasConfigDelta'+self.intstrength +
                           'Fam'+mag_type+'F-SP'))
            self.sb_meas_conf_dfamF.showStepExponent = False
            self.lb_meas_conf_dfamF = PyDMLabel(
                self, self.ioc_prefix.substitute(
                    propty='MeasConfigDelta'+self.intstrength +
                           'Fam'+mag_type+'F-RB'))
            lay.addWidget(lb_meas_conf_dfamF, row+2, 0)
            lay.addWidget(self.sb_meas_conf_dfamF, row+2, 1)
            lay.addWidget(self.lb_meas_conf_dfamF, row+2, 2)

            lb_meas_conf_dfamD = QLabel(
                'Fam. Δ'+self.intstrength+' '+mag_type+'D '+unit, self)
            self.sb_meas_conf_dfamD = PyDMSpinbox(
                self, self.ioc_prefix.substitute(
                    propty='MeasConfigDelta'+self.intstrength +
                           'Fam'+mag_type+'D-SP'))
            self.sb_meas_conf_dfamD.showStepExponent = False
            self.lb_meas_conf_dfamD = PyDMLabel(
                self, self.ioc_prefix.substitute(
                    propty='MeasConfigDelta'+self.intstrength +
                           'Fam'+mag_type+'D-RB'))
            lay.addWidget(lb_meas_conf_dfamD, row+3, 0)
            lay.addWidget(self.sb_meas_conf_dfamD, row+3, 1)
            lay.addWidget(self.lb_meas_conf_dfamD, row+3, 2)

            lb_meas_conf_wait = QLabel('Wait [s]', self)
            self.sb_meas_conf_wait = PyDMSpinbox(
                self, self.ioc_prefix.substitute(propty='MeasConfigWait-SP'))
            self.sb_meas_conf_wait.showStepExponent = False
            self.lb_meas_conf_wait = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='MeasConfigWait-RB'))
            lay.addWidget(lb_meas_conf_wait, row+4, 0)
            lay.addWidget(self.sb_meas_conf_wait, row+4, 1)
            lay.addWidget(self.lb_meas_conf_wait, row+4, 2)

            lb_meas_conf_cname = QLabel('Name to save', self)
            self.le_meas_conf_name = PyDMLineEdit(
                self, self.ioc_prefix.substitute(propty='MeasConfigName-SP'))
            self.lb_meas_conf_name = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='MeasConfigName-RB'))
            lay.addWidget(lb_meas_conf_cname, row+5, 0)
            lay.addWidget(self.le_meas_conf_name, row+5, 1, 1, 2)
            lay.addWidget(self.lb_meas_conf_name, row+6, 1, 1, 2)

            lb_meas_conf_save = QLabel('Force Save', self)
            self.bt_meas_conf_save = PyDMPushButton(
                self, icon=qta.icon('mdi.content-save'), label='',
                init_channel=self.ioc_prefix.substitute(
                    propty='MeasConfigSave-Cmd'),
                pressValue=1)
            self.bt_meas_conf_save.setObjectName('save')
            self.bt_meas_conf_save.setStyleSheet(
                '#save{min-width:25px; max-width:25px; icon-size:20px;}')
            lay.addWidget(lb_meas_conf_save, row+7, 0)
            lay.addWidget(
                self.bt_meas_conf_save, row+7, 1, alignment=Qt.AlignLeft)

            lay.addItem(
                QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+8, 0)

            self.lb_meas_conf_sts = PyDMLabel(
                self, self.ioc_prefix.substitute(
                    propty='MeasConfigStatus-Mon'))
            self.bt_meas_conf_start = PyDMPushButton(
                self, icon=qta.icon('fa5s.play'), label='',
                init_channel=self.ioc_prefix.substitute(
                    propty='MeasConfig-Cmd'),
                pressValue=_Const.MeasCmd.Start)
            self.bt_meas_conf_start.setObjectName('start')
            self.bt_meas_conf_start.setStyleSheet(
                '#start{min-width:25px; max-width:25px; icon-size:20px;}')
            self.bt_meas_conf_stop = PyDMPushButton(
                self, icon=qta.icon('fa5s.stop'), label='',
                init_channel=self.ioc_prefix.substitute(
                    propty='MeasConfig-Cmd'),
                pressValue=_Const.MeasCmd.Stop)
            self.bt_meas_conf_stop.setObjectName('stop')
            self.bt_meas_conf_stop.setStyleSheet(
                '#stop{min-width:25px; max-width:25px; icon-size:20px;}')
            self.bt_meas_conf_rst = PyDMPushButton(
                self, icon=qta.icon('fa5s.sync'), label='',
                init_channel=self.ioc_prefix.substitute(
                    propty='MeasConfig-Cmd'),
                pressValue=_Const.MeasCmd.Reset)
            self.bt_meas_conf_rst.setObjectName('rst')
            self.bt_meas_conf_rst.setStyleSheet(
                '#rst{min-width:25px; max-width:25px; icon-size:20px;}')
            hbox_cmd = QHBoxLayout()
            hbox_cmd.addWidget(self.bt_meas_conf_start)
            hbox_cmd.addWidget(self.bt_meas_conf_stop)
            hbox_cmd.addWidget(self.bt_meas_conf_rst)
            lay.addWidget(self.lb_meas_conf_sts, row+9, 0, 1, 2)
            lay.addLayout(hbox_cmd, row+9, 2)

            lay.addItem(
                QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+10, 0)

            # correction settings
            lb_corr = QLabel('<h4>Settings</h4>')
            lay.addWidget(lb_corr, row+11, 0, 1, 3)

            lb_meth = QLabel('Method', self)
            self.cb_method = PyDMEnumComboBox(
                self, self.ioc_prefix.substitute(propty='CorrMeth-Sel'))
            self.lb_method = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='CorrMeth-Sts'))
            lay.addWidget(lb_meth, row+12, 0)
            lay.addWidget(self.cb_method, row+12, 1)
            lay.addWidget(self.lb_method, row+12, 2)

            lb_grp = QLabel('Grouping', self)
            self.cb_group = PyDMEnumComboBox(
                self, self.ioc_prefix.substitute(propty='CorrGroup-Sel'))
            self.lb_group = PyDMLabel(
                self, self.ioc_prefix.substitute(propty='CorrGroup-Sts'))
            lay.addWidget(lb_grp, row+13, 0)
            lay.addWidget(self.cb_group, row+13, 1)
            lay.addWidget(self.lb_group, row+13, 2)

            if self.param == 'tune':
                lb_sync = QLabel('Sync', self)
                self.bt_sync = PyDMStateButton(
                    self, self.ioc_prefix.substitute(propty='SyncCorr-Sel'))
                self.bt_sync.shape = 1
                self.lb_sync = PyDMLabel(
                    self, self.ioc_prefix.substitute(propty='SyncCorr-Sts'))
                lay.addWidget(lb_sync, row+14, 0)
                lay.addWidget(self.bt_sync, row+14, 1)
                lay.addWidget(self.lb_sync, row+14, 2)
            row = row + 15

        lay.addItem(
            QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Expanding), row, 0)
        return lay

    def _change_chrom_sp(self):
        cond = self._is_setting == 'absolut'
        self._is_setting = 'delta' if cond else 'absolut'
        icon = self._icon_delta if cond else self._icon_absval
        textX = '<h4>Δ-SP</h4>' if cond else '<h4>SP</h4>'
        textY = '<h4>Δ-RB</h4>' if cond else '<h4>RB</h4>'
        self.sb_paramx.setVisible(not cond)
        self.lb_paramx.setVisible(not cond)
        self.sb_paramy.setVisible(not cond)
        self.lb_paramy.setVisible(not cond)
        self.sb_paramx_delta.setVisible(cond)
        self.lb_paramx_delta.setVisible(cond)
        self.sb_paramy_delta.setVisible(cond)
        self.lb_paramy_delta.setVisible(cond)
        self.pb_change_sp.setIcon(icon)
        self.lb_sp.setText(textX)
        self.lb_rb.setText(textY)
예제 #18
0
    def _get_config_widget(self, parent):
        gb_pos = QGroupBox('Image Processing ', parent)

        meth_sp = PyDMEnumComboBox(
            gb_pos, init_channel=self._dev+':CalcMethod-Sel')
        meth_lb = SiriusLabel(gb_pos, init_channel=self._dev+':CalcMethod-Sts')
        meth_ld = QLabel('Method', gb_pos)

        nrpt_ld = QLabel('Num. Pts.', gb_pos)
        nrpt_sp = SiriusSpinbox(
            gb_pos, init_channel=self._dev+':NrAverages-SP')
        nrpt_sp.showStepExponent = False
        rdb = PyDMLabel(gb_pos, init_channel=self._dev+':NrAverages-RB')
        rdb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slsh = QLabel('/', gb_pos, alignment=Qt.AlignCenter)
        slsh.setStyleSheet('min-width:0.7em; max-width:0.7em;')
        cnt = PyDMLabel(gb_pos, init_channel=self._dev+':BufferSize-Mon')
        cnt.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        cnt.setToolTip('Current Buffer Size')
        pbt = PyDMPushButton(
            gb_pos, init_channel=self._dev+':ResetBuffer-Cmd', pressValue=1)
        pbt.setToolTip('Reset Buffer')
        pbt.setIcon(qta.icon('mdi.delete-empty'))
        pbt.setObjectName('rst')
        pbt.setStyleSheet(
            '#rst{min-width:25px; max-width:25px; icon-size:20px;}')
        nrpt_wd = QWidget(gb_pos)
        hbl = QHBoxLayout(nrpt_wd)
        hbl.addWidget(pbt)
        hbl.addStretch()
        hbl.addWidget(cnt)
        hbl.addWidget(slsh)
        hbl.addWidget(rdb)

        rsx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeX-SP')
        rsx_sp.showStepExponent = False
        rsx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeX-RB')
        rsx_ld = QLabel('ROI Size X', gb_pos)

        rsy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeY-SP')
        rsy_sp.showStepExponent = False
        rsy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeY-RB')
        rsy_ld = QLabel('ROI Size Y', gb_pos)

        ra_bt = PyDMStateButton(
            gb_pos, init_channel=self._dev+':ROIAutoCenter-Sel')
        ra_lb = SiriusLabel(
            gb_pos, init_channel=self._dev+':ROIAutoCenter-Sts')
        ra_ld = QLabel('Auto Center:', gb_pos)

        rcx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterX-SP')
        rcx_sp.showStepExponent = False
        rcx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterX-RB')
        rcx_ld = QLabel('ROI Center X', gb_pos)

        rcy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterY-SP')
        rcy_sp.showStepExponent = False
        rcy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterY-RB')
        rcy_ld = QLabel('ROI Center Y', gb_pos)

        sts_bt = QPushButton(qta.icon('fa5s.ellipsis-h'), '', gb_pos)
        sts_bt.setToolTip('Open Detailed Configs')
        sts_bt.setObjectName('sts')
        sts_bt.setStyleSheet(
            '#sts{min-width:25px; max-width:25px; icon-size:20px;}')
        Window = create_window_from_widget(
            _DetailedWidget, title='Image Processing Detailed Configs')
        connect_window(
            sts_bt, Window, gb_pos, device=self._dev,
            convertion_set=self._conv_set)
        hlay = QHBoxLayout()
        hlay.addWidget(sts_bt, alignment=Qt.AlignRight)

        lay = QGridLayout(gb_pos)
        if self._ori == 'V':
            lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(meth_sp, 0, 1)
            lay.addWidget(meth_lb, 1, 1)
            lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft)
            lay.addWidget(nrpt_sp, 2, 1)
            lay.addWidget(nrpt_wd, 3, 0, 1, 2)
            lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsx_sp, 4+0, 1)
            lay.addWidget(rsx_lb, 4+1, 1)
            lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsy_sp, 6+0, 1)
            lay.addWidget(rsy_lb, 6+1, 1)
            lay.addWidget(sts_bt, 0, 0+4, alignment=Qt.AlignRight)
            lay.addWidget(ra_ld, 2+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(ra_bt, 2+0, 1+3)
            lay.addWidget(ra_lb, 2+1, 1+3, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_ld, 4+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_sp, 4+0, 1+3)
            lay.addWidget(rcx_lb, 4+1, 1+3)
            lay.addWidget(rcy_ld, 6+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcy_sp, 6+0, 1+3)
            lay.addWidget(rcy_lb, 6+1, 1+3)
        else:
            lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(meth_sp, 0, 1)
            lay.addWidget(meth_lb, 1, 1)
            lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft)
            lay.addWidget(nrpt_sp, 2, 1)
            lay.addWidget(nrpt_wd, 3, 0, 1, 2)
            lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsx_sp, 4+0, 1)
            lay.addWidget(rsx_lb, 4+1, 1)
            lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsy_sp, 6+0, 1)
            lay.addWidget(rsy_lb, 6+1, 1)
            lay.addWidget(ra_ld, 8+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(ra_bt, 8+0, 1)
            lay.addWidget(ra_lb, 8+1, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_ld, 10+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_sp, 10+0, 1)
            lay.addWidget(rcx_lb, 10+1, 1)
            lay.addWidget(rcy_ld, 12+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcy_sp, 12+0, 1)
            lay.addWidget(rcy_lb, 12+1, 1)
            lay.addWidget(sts_bt, 14, 0, alignment=Qt.AlignLeft)
            lay.setRowStretch(15, 5)

        return gb_pos
예제 #19
0
    def get_measurement_widget(self, parent):
        """."""
        meas_wid = QWidget(parent)
        meas_lay = QVBoxLayout(meas_wid)

        strt = PyDMPushButton(
            meas_wid,
            init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"),
            pressValue=ConstTLines.MeasRespMatCmd.Start)
        strt.setEnabled(True)
        strt.setToolTip('Start Measurement')
        strt.setIcon(qta.icon('fa5s.play'))
        strt.setObjectName('strt')
        strt.setStyleSheet(
            '#strt{min-width:25px; max-width:25px; icon-size:20px;}')
        stop = PyDMPushButton(
            meas_wid,
            init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"),
            pressValue=ConstTLines.MeasRespMatCmd.Stop)
        stop.setEnabled(True)
        stop.setToolTip('Stop Measurement')
        stop.setIcon(qta.icon('fa5s.stop'))
        stop.setObjectName('stop')
        stop.setStyleSheet(
            '#stop{min-width:25px; max-width:25px; icon-size:20px;}')
        rst = PyDMPushButton(
            meas_wid,
            init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"),
            pressValue=ConstTLines.MeasRespMatCmd.Reset)
        rst.setEnabled(True)
        rst.setToolTip('Reset Measurement Status')
        rst.setIcon(qta.icon('fa5s.sync'))
        rst.setObjectName('conf')
        rst.setStyleSheet(
            '#conf{min-width:25px; max-width:25px; icon-size:20px;}')
        lbl = PyDMLabel(
            meas_wid, self.devpref.substitute(propty='MeasRespMat-Mon'))
        lbl.setAlignment(Qt.AlignCenter)
        hbl = QHBoxLayout()
        hbl.setSpacing(8)
        meas_lay.addItem(hbl)
        hbl.addWidget(strt)
        hbl.addWidget(stop)
        hbl.addWidget(rst)
        hbl.addStretch()
        hbl.addWidget(lbl)

        fml = QFormLayout()
        meas_lay.addSpacing(20)
        meas_lay.addItem(fml)
        lbl = QLabel('CH [urad]', meas_wid)
        wid = self.create_pair(meas_wid, 'MeasRespMatKickCH')
        fml.addRow(lbl, wid)
        lbl = QLabel('CV [urad]', meas_wid)
        wid = self.create_pair(meas_wid, 'MeasRespMatKickCV')
        fml.addRow(lbl, wid)
        if self.acc in {'SI', 'BO'}:
            lbl = QLabel('RF [Hz]', meas_wid)
            wid = self.create_pair(meas_wid, 'MeasRespMatKickRF')
            fml.addRow(lbl, wid)
        lbl = QLabel('Wait [s]', meas_wid)
        lbl.setToolTip('Time to wait between kicks')
        wid = self.create_pair(meas_wid, 'MeasRespMatWait')
        fml.addRow(lbl, wid)

        return meas_wid
예제 #20
0
class BaslerCamSettings(QTabWidget):
    def __init__(self, parent=None, device='', prefix=''):
        super().__init__(parent)
        self.prefix = prefix
        self.device = SiriusPVName(device).substitute(prefix=prefix)
        self.cam_prefix = self.device.substitute(prefix=prefix)
        self.setObjectName(self.device.sec + 'App')
        self._setupUi()

    def _setupUi(self):
        self.addTab(self._infoWidget(), 'Gen. Info')
        self.addTab(self._statusWidget(), 'Status')
        self.addTab(self._acquisitionWidget(), 'Acquisition')
        self.addTab(self._imgIntesityAndBGWidget(), 'Intensity and BG')
        self.addTab(self._ROIWidget(), 'ROI')
        self.setCurrentIndex(2)
        self.setStyleSheet('#' + self.device.sec +
                           'App{min-width: 31em; max-width: 31em;}')

    def _infoWidget(self):
        label_DevID = QLabel('Device ID:', self)
        hbox_DevID = create_propty_layout(parent=self,
                                          prefix=self.cam_prefix,
                                          width=15,
                                          propty='DeviceID',
                                          propty_type='cte')
        hbox_DevID.setAlignment(Qt.AlignLeft)

        label_DevVers = QLabel('Device Version:', self)
        hbox_DevVers = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            width=15,
                                            propty='DeviceVersion',
                                            propty_type='cte')
        hbox_DevVers.setAlignment(Qt.AlignLeft)

        label_DevModelName = QLabel('Device Model Name:', self)
        hbox_DevModelName = create_propty_layout(parent=self,
                                                 prefix=self.cam_prefix,
                                                 width=15,
                                                 propty='DeviceModelName',
                                                 propty_type='cte')
        hbox_DevModelName.setAlignment(Qt.AlignLeft)

        label_DevVendorName = QLabel('Device Vendor Name:', self)
        hbox_DevVendorName = create_propty_layout(parent=self,
                                                  prefix=self.cam_prefix,
                                                  width=15,
                                                  propty='DeviceVendorName',
                                                  propty_type='cte')
        hbox_DevVendorName.setAlignment(Qt.AlignLeft)

        label_DevFirmVers = QLabel('Firmware Version:', self)
        hbox_DevFirmVers = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                width=15,
                                                propty='DeviceFirmwareVersion',
                                                propty_type='cte')
        hbox_DevFirmVers.setAlignment(Qt.AlignLeft)

        label_SensorHeight = QLabel('Sensor Height [pixels]:', self)
        hbox_SensorHeight = create_propty_layout(parent=self,
                                                 prefix=self.cam_prefix,
                                                 width=15,
                                                 propty='SensorHeight',
                                                 propty_type='cte')
        hbox_SensorHeight.setAlignment(Qt.AlignLeft)

        label_SensorWidth = QLabel('Sensor Width [pixels]:', self)
        hbox_SensorWidth = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                width=15,
                                                propty='SensorWidth',
                                                propty_type='cte')
        hbox_SensorWidth.setAlignment(Qt.AlignLeft)

        wid = QWidget()
        flay = QFormLayout(wid)
        flay.setLabelAlignment(Qt.AlignRight)
        flay.setFormAlignment(Qt.AlignHCenter)
        flay.addRow(label_DevID, hbox_DevID)
        flay.addRow(label_DevVers, hbox_DevVers)
        flay.addRow(label_DevModelName, hbox_DevModelName)
        flay.addRow(label_DevVendorName, hbox_DevVendorName)
        flay.addRow(label_DevFirmVers, hbox_DevFirmVers)
        flay.addRow(label_SensorHeight, hbox_SensorHeight)
        flay.addRow(label_SensorWidth, hbox_SensorWidth)
        return wid

    def _statusWidget(self):
        label_Conn = QLabel('Connection:', self)
        hbox_Conn = create_propty_layout(parent=self,
                                         prefix=self.cam_prefix,
                                         propty='Connection',
                                         propty_type='mon')

        label_Temp = QLabel('Temperature State:', self)
        self.lb_Temp = PyDMLabel(self,
                                 self.cam_prefix.substitute(propty='Temp-Mon'))
        self.lb_Temp.setStyleSheet('min-width:7.1em; max-width:7.1em;')
        self.lb_Temp.setAlignment(Qt.AlignCenter)
        self.led_TempState = SiriusLedAlert(
            self, self.cam_prefix.substitute(propty='TempState-Mon'))
        self.led_TempState.setStyleSheet('min-width:1.29em; max-width:1.29em;')
        self.lb_TempState = PyDMLabel(
            self, self.cam_prefix.substitute(propty='TempState-Mon'))
        self.lb_TempState.setStyleSheet('min-width:2.5em; max-width:2.5em;')
        hbox_Temp = QHBoxLayout()
        hbox_Temp.addWidget(self.lb_Temp)
        hbox_Temp.addWidget(self.led_TempState)
        hbox_Temp.addWidget(self.lb_TempState)

        label_LastErr = QLabel('Last Error:', self)
        hbox_LastErr = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='LastErr',
                                            propty_type='mon',
                                            cmd={
                                                'label': 'Clear Last Error',
                                                'pressValue': 1,
                                                'name': 'ClearLastErr'
                                            })

        label_Reset = QLabel('Reset Camera:', self)
        self.pb_dtl = PyDMPushButton(
            label='',
            icon=qta.icon('fa5s.sync'),
            parent=self,
            pressValue=1,
            init_channel=self.cam_prefix.substitute(propty='Rst-Cmd'))
        self.pb_dtl.setObjectName('reset')
        self.pb_dtl.setStyleSheet(
            "#reset{min-width:25px; max-width:25px; icon-size:20px;}")

        wid = QWidget()
        flay = QFormLayout(wid)
        flay.setLabelAlignment(Qt.AlignRight)
        flay.setFormAlignment(Qt.AlignHCenter)
        flay.addRow(label_Conn, hbox_Conn)
        flay.addRow(label_Temp, hbox_Temp)
        flay.addRow(label_LastErr, hbox_LastErr)
        flay.addRow(label_Reset, self.pb_dtl)
        return wid

    def _acquisitionWidget(self):
        label_CamEnbl = QLabel('Acquire Enable Status:', self)
        hbox_CamEnbl = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='Enbl',
                                            propty_type='enbldisabl')

        label_FrameCnt = QLabel('Frame Count:', self)
        hbox_FrameCnt = create_propty_layout(parent=self,
                                             prefix=self.cam_prefix,
                                             propty='FrameCnt',
                                             propty_type='mon')

        label_AcqMode = QLabel('Acquire Mode:', self)
        hbox_AcqMode = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='AcqMode',
                                            propty_type='enum')

        label_AcqPeriod = QLabel('Acquire Period [s]:', self)
        hbox_AcqPeriod = create_propty_layout(parent=self,
                                              prefix=self.cam_prefix,
                                              propty='AcqPeriod',
                                              propty_type='sprb')

        label_AcqPeriodLowLim = QLabel('Acquire Period Low Limit [s]:', self)
        hbox_AcqPeriodLowLim = create_propty_layout(parent=self,
                                                    prefix=self.cam_prefix,
                                                    propty='AcqPeriodLowLim',
                                                    propty_type='sprb')

        label_ExpMode = QLabel('Exposure Mode:', self)
        hbox_ExpMode = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='ExposureMode',
                                            propty_type='enum')

        label_ExpTime = QLabel('Exposure Time [us]:', self)
        hbox_ExpTime = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='ExposureTime',
                                            propty_type='sprb')

        label_Gain = QLabel('Gain [dB]:', self)
        hbox_Gain = create_propty_layout(parent=self,
                                         prefix=self.cam_prefix,
                                         propty='Gain',
                                         propty_type='sprb',
                                         cmd={
                                             'label': '',
                                             'pressValue': 1,
                                             'width': '25',
                                             'height': '25',
                                             'icon': qta.icon('mdi.auto-fix'),
                                             'icon-size': '20',
                                             'toolTip': 'Auto Gain',
                                             'name': 'AutoGain'
                                         })

        label_TransformType = QLabel('Transform Type:', self)
        hbox_TransformType = create_propty_layout(parent=self,
                                                  prefix=self.cam_prefix,
                                                  propty='TransformType',
                                                  propty_type='enum')

        label_BlackLevel = QLabel('Black Level [gray va]:', self)
        hbox_BlackLevel = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='BlackLevel',
                                               propty_type='sprb')

        label_DebouncerPeriod = QLabel('Debouncer Period [us]:', self)
        hbox_DebouncerPeriod = create_propty_layout(parent=self,
                                                    prefix=self.cam_prefix,
                                                    propty='DebouncerPeriod',
                                                    propty_type='sprb')

        self.pb_advanced = QPushButton('Advanced', self)
        my_window = create_window_from_widget(
            BaslerCamAcqAdvSettings,
            is_main=False,
            title='Basler Camera Advanced Acquisition Settings')
        util.connect_window(self.pb_advanced,
                            my_window,
                            parent=self,
                            device=self.device,
                            prefix=self.prefix)
        hbox_adv = QHBoxLayout()
        hbox_adv.addWidget(self.pb_advanced, alignment=Qt.AlignRight)

        wid = QWidget()
        flay = QFormLayout(wid)
        flay.setLabelAlignment(Qt.AlignRight)
        flay.setFormAlignment(Qt.AlignHCenter)
        flay.addRow(label_CamEnbl, hbox_CamEnbl)
        flay.addRow(label_FrameCnt, hbox_FrameCnt)
        flay.addRow(label_AcqMode, hbox_AcqMode)
        flay.addRow(label_AcqPeriod, hbox_AcqPeriod)
        flay.addRow(label_AcqPeriodLowLim, hbox_AcqPeriodLowLim)
        flay.addRow(label_ExpMode, hbox_ExpMode)
        flay.addRow(label_ExpTime, hbox_ExpTime)
        flay.addRow(label_Gain, hbox_Gain)
        flay.addRow(label_BlackLevel, hbox_BlackLevel)
        flay.addRow(label_DebouncerPeriod, hbox_DebouncerPeriod)
        flay.addRow(label_TransformType, hbox_TransformType)
        flay.addRow(hbox_adv)
        return wid

    def _imgIntesityAndBGWidget(self):
        label_EnblAdjust = QLabel('Enable Scale and Offset Adjust:', self)
        hbox_EnblAdjust = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='EnblOffsetScale',
                                               propty_type='enbldisabl')

        label_AutoAdjust = QLabel('Automatic Intensity Adjust:', self)
        hbox_AutoAdjust = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='AutoOffsetScale',
                                               cmd={
                                                   'label': 'Auto Adjust',
                                                   'pressValue': 1,
                                                   'name': 'AutoOffsetScale'
                                               })

        label_PixelScale = QLabel('Pixel Scale:', self)
        hbox_PixelScale = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='PixelScale',
                                               propty_type='sprb',
                                               use_linedit=True)

        label_PixelOffset = QLabel('Pixel Offset:', self)
        hbox_PixelOffset = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                propty='PixelOffset',
                                                propty_type='sprb',
                                                use_linedit=True)

        label_EnblLowClip = QLabel('Enable Low Cliping:', self)
        hbox_EnblLowClip = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                propty='EnblLowClip',
                                                propty_type='enbldisabl')

        label_LowClip = QLabel('Minimum Intensity for Low Cliping:', self)
        hbox_LowClip = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='LowClip',
                                            propty_type='sprb',
                                            use_linedit=True)

        label_EnblHighClip = QLabel('Enable High Cliping:', self)
        hbox_EnblHighClip = create_propty_layout(parent=self,
                                                 prefix=self.cam_prefix,
                                                 propty='EnblHighClip',
                                                 propty_type='enbldisabl')

        label_HighClip = QLabel('Maximum Intensity for High Cliping:', self)
        hbox_HighClip = create_propty_layout(parent=self,
                                             prefix=self.cam_prefix,
                                             propty='HighClip',
                                             propty_type='sprb',
                                             use_linedit=True)

        label_EnblBG = QLabel('Enable BG Subtraction:', self)
        hbox_EnblBG = create_propty_layout(parent=self,
                                           prefix=self.cam_prefix,
                                           propty='EnblBGSubtraction',
                                           propty_type='enbldisabl')

        label_SaveBG = QLabel('Save BG:', self)
        hbox_SaveBG = create_propty_layout(parent=self,
                                           prefix=self.cam_prefix,
                                           propty='SaveBG',
                                           cmd={
                                               'label': 'Save',
                                               'pressValue': 1,
                                               'name': 'SaveBG'
                                           })

        label_ValidBG = QLabel('Is valid BG?', self)
        hbox_ValidBG = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='ValidBG',
                                            propty_type='mon')

        wid = QWidget()
        flay = QFormLayout(wid)
        flay.setLabelAlignment(Qt.AlignRight)
        flay.setFormAlignment(Qt.AlignHCenter)
        flay.addRow(label_EnblAdjust, hbox_EnblAdjust)
        flay.addRow(label_AutoAdjust, hbox_AutoAdjust)
        flay.addRow(label_PixelScale, hbox_PixelScale)
        flay.addRow(label_PixelOffset, hbox_PixelOffset)
        flay.addRow(label_EnblLowClip, hbox_EnblLowClip)
        flay.addRow(label_LowClip, hbox_LowClip)
        flay.addRow(label_EnblHighClip, hbox_EnblHighClip)
        flay.addRow(label_HighClip, hbox_HighClip)
        flay.addRow(label_EnblBG, hbox_EnblBG)
        flay.addRow(label_SaveBG, hbox_SaveBG)
        flay.addRow(label_ValidBG, hbox_ValidBG)
        return wid

    def _ROIWidget(self):
        label_MaxWidth = QLabel('Maximum Width [pixels]:', self)
        self.PyDMLabel_MaxWidth = PyDMLabel(
            self, self.cam_prefix.substitute(propty='SensorWidth-Cte'))
        self.PyDMLabel_MaxWidth.setStyleSheet(
            """max-width:7.10em; max-height:1.29em;""")

        label_MaxHeight = QLabel('Maximum Height [pixels]:', self)
        self.PyDMLabel_MaxHeight = PyDMLabel(
            self, self.cam_prefix.substitute(propty='SensorHeight-Cte'))
        self.PyDMLabel_MaxHeight.setStyleSheet(
            """max-width:7.10em; max-height:1.29em;""")

        label_ROIWidth = QLabel('Width [pixels]:', self)
        hbox_ROIWidth = create_propty_layout(parent=self,
                                             prefix=self.cam_prefix,
                                             propty='AOIWidth',
                                             propty_type='sprb')

        label_ROIHeight = QLabel('Heigth [pixels]:', self)
        hbox_ROIHeight = create_propty_layout(parent=self,
                                              prefix=self.cam_prefix,
                                              propty='AOIHeight',
                                              propty_type='sprb')

        label_ROIOffsetX = QLabel('Offset X [pixels]:', self)
        hbox_ROIOffsetX = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='AOIOffsetX',
                                               propty_type='sprb')

        label_ROIOffsetY = QLabel('Offset Y [pixels]:', self)
        hbox_ROIOffsetY = create_propty_layout(parent=self,
                                               prefix=self.cam_prefix,
                                               propty='AOIOffsetY',
                                               propty_type='sprb')

        label_AutoCenterX = QLabel('Auto Center X:', self)
        hbox_AutoCenterX = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                propty='AOIAutoCenterX',
                                                propty_type='offon')

        label_AutoCenterY = QLabel('Auto Center Y:', self)
        hbox_AutoCenterY = create_propty_layout(parent=self,
                                                prefix=self.cam_prefix,
                                                propty='AOIAutoCenterY',
                                                propty_type='offon')

        wid = QWidget()
        flay = QFormLayout(wid)
        flay.setLabelAlignment(Qt.AlignRight)
        flay.setFormAlignment(Qt.AlignHCenter)
        flay.addRow(label_MaxWidth, self.PyDMLabel_MaxWidth)
        flay.addRow(label_MaxHeight, self.PyDMLabel_MaxHeight)
        flay.addRow(label_ROIWidth, hbox_ROIWidth)
        flay.addRow(label_ROIHeight, hbox_ROIHeight)
        flay.addRow(label_ROIOffsetX, hbox_ROIOffsetX)
        flay.addRow(label_ROIOffsetY, hbox_ROIOffsetY)
        flay.addRow(label_AutoCenterX, hbox_AutoCenterX)
        flay.addRow(label_AutoCenterY, hbox_AutoCenterY)
        return wid
예제 #21
0
class PUDetailWidget(QWidget):
    """Detailed widget for controlling a pulsed magnet."""
    def __init__(self, devname, parent=None):
        """Receive a parent and a pulsed mangnet name."""
        super().__init__(parent)
        self._devname = _PVName(devname)
        self._section = self._devname.sec
        self._prefix = _VACA_PREFIX
        self._pdev = self._devname.substitute(prefix=self._prefix)
        self.setObjectName(self._section + 'App')
        self.setWindowIcon(
            qta.icon('mdi.current-ac',
                     color=util.get_appropriate_color(self._section)))

        self._create_pvs()
        self._setup_ui()
        self.setStyleSheet("""
            #pulses_box,
            #pwrstate_box {
                max-width: 8em;
            }
        """)
        self.setFocusPolicy(Qt.StrongFocus)

    def _create_pvs(self):
        """Create variables with pvs that'll be used."""
        self._voltage_sp_pv = self._pdev.substitute(propty='Voltage-SP')
        self._voltage_rb_pv = self._pdev.substitute(propty='Voltage-RB')
        self._voltage_mon_pv = self._pdev.substitute(propty='Voltage-Mon')
        self._kick_sp_pv = self._pdev.substitute(propty='Kick-SP')
        self._kick_rb_pv = self._pdev.substitute(propty='Kick-RB')
        self._kick_mon_pv = self._pdev.substitute(propty='Kick-Mon')
        self._pwrstate_sel_pv = self._pdev.substitute(propty='PwrState-Sel')
        self._pwrstate_sts_pv = self._pdev.substitute(propty='PwrState-Sts')
        self._enablepulses_sel_pv = self._pdev.substitute(propty='Pulse-Sel')
        self._enablepulses_sts_pv = self._pdev.substitute(propty='Pulse-Sts')
        self._reset_cmd_pv = self._pdev.substitute(propty='Reset-Cmd')
        self._intlk1_mon_pv = self._pdev.substitute(propty='Intlk1-Mon')
        self._intlk2_mon_pv = self._pdev.substitute(propty='Intlk2-Mon')
        self._intlk3_mon_pv = self._pdev.substitute(propty='Intlk3-Mon')
        self._intlk4_mon_pv = self._pdev.substitute(propty='Intlk4-Mon')
        self._intlk5_mon_pv = self._pdev.substitute(propty='Intlk5-Mon')
        self._intlk6_mon_pv = self._pdev.substitute(propty='Intlk6-Mon')
        self._intlk7_mon_pv = self._pdev.substitute(propty='Intlk7-Mon')
        self._intlk1_lbcte_pv = self._pdev.substitute(propty='Intlk1Label-Cte')
        self._intlk2_lbcte_pv = self._pdev.substitute(propty='Intlk2Label-Cte')
        self._intlk3_lbcte_pv = self._pdev.substitute(propty='Intlk3Label-Cte')
        self._intlk4_lbcte_pv = self._pdev.substitute(propty='Intlk4Label-Cte')
        self._intlk5_lbcte_pv = self._pdev.substitute(propty='Intlk5Label-Cte')
        self._intlk6_lbcte_pv = self._pdev.substitute(propty='Intlk6Label-Cte')
        self._intlk7_lbcte_pv = self._pdev.substitute(propty='Intlk7Label-Cte')
        if 'Sept' not in self._devname:
            self._intlk8_mon_pv = self._pdev.substitute(propty='Intlk8-Mon')
            self._intlk8_lbcte_pv = \
                self._pdev.substitute(propty='Intlk8Label-Cte')
        self._ctrlmode_pv = self._pdev.substitute(propty='CtrlMode-Mon')

        self._trigname = self._devname.substitute(dis='TI')

    def _setup_ui(self):
        self.header_label = QLabel("<h1>" + self._devname + "</h1>")
        self.header_label.setObjectName("header_label")
        interlock_box = QGroupBox(parent=self, title="Interlock")
        interlock_box.setObjectName("interlock_box")
        interlock_box.setLayout(self._interlock_layout())
        pwrstate_box = QGroupBox(parent=self, title="Power")
        pwrstate_box.setObjectName("pwrstate_box")
        pwrstate_box.setLayout(self._pwrstate_layout())
        pulses_box = QGroupBox(parent=self, title="Pulses")
        pulses_box.setObjectName("pulses_box")
        pulses_box.setLayout(self._pulses_layout())
        voltage_box = QGroupBox(parent=self, title="Voltage")
        voltage_box.setObjectName("voltage_box")
        voltage_box.setLayout(self._voltage_layout())
        kick_box = QGroupBox(parent=self, title="Kick")
        kick_box.setObjectName("kick_box")
        kick_box.setLayout(self._kick_layout())
        timing_box = QGroupBox(parent=self, title='Trigger')
        timing_box.setObjectName('timing_box')
        hbl = QHBoxLayout(timing_box)
        hbl.addWidget(HLTriggerSimple(timing_box, self._trigname,
                                      self._prefix))

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.header_label, 0, 0, 1, 3)
        self.layout.addWidget(interlock_box, 1, 0, 3, 1)
        vbl1 = QVBoxLayout()
        vbl1.addWidget(pwrstate_box)
        vbl1.addWidget(pulses_box)
        self.layout.addLayout(vbl1, 1, 1, 2, 1)
        vbl2 = QVBoxLayout()
        vbl2.addWidget(voltage_box)
        vbl2.addWidget(kick_box)
        self.layout.addLayout(vbl2, 1, 2, 2, 1)
        self.layout.addWidget(timing_box, 3, 1, 1, 3)
        self.layout.addLayout(self._ctrlmode_layout(), 4, 1, 1, 3)

    def _interlock_layout(self):
        interlock_layout = QGridLayout()

        intlk_cnt = 8 if 'Sept' not in self._devname else 7
        for i in range(intlk_cnt):
            label = PyDMLabel(
                self, getattr(self, '_intlk' + str(i + 1) + '_lbcte_pv'))
            led = PyDMLed(self, getattr(self,
                                        '_intlk' + str(i + 1) + '_mon_pv'))
            led.onColor = led.LightGreen
            led.offColor = led.Red
            interlock_layout.addWidget(led, i, 0)
            interlock_layout.addWidget(label, i, 1)

        self.reset_bt = PyDMPushButton(parent=self,
                                       init_channel=self._reset_cmd_pv,
                                       pressValue=1)
        self.reset_bt.setIcon(qta.icon('fa5s.sync'))
        self.reset_bt.setObjectName('reset_bt')
        self.reset_bt.setStyleSheet(
            '#reset_bt{min-width:25px; max-width:25px; icon-size:20px;}')
        interlock_layout.addWidget(self.reset_bt,
                                   i + 1,
                                   0,
                                   1,
                                   2,
                                   alignment=Qt.AlignHCenter)

        return interlock_layout

    def _pwrstate_layout(self):
        pwrstate_layout = QHBoxLayout()

        self.state_button = PyDMStateButton(parent=self,
                                            init_channel=self._pwrstate_sel_pv)
        self.state_led = SiriusLedState(self, self._pwrstate_sts_pv)

        pwrstate_layout.addWidget(self.state_button)
        pwrstate_layout.addWidget(self.state_led)

        return pwrstate_layout

    def _pulses_layout(self):
        pulses_layout = QHBoxLayout()

        self.pulses_state_button = PyDMStateButton(
            parent=self, init_channel=self._enablepulses_sel_pv)
        self.pulses_state_led = SiriusLedState(
            parent=self, init_channel=self._enablepulses_sts_pv)

        pulses_layout.addWidget(self.pulses_state_button)
        pulses_layout.addWidget(self.pulses_state_led)

        return pulses_layout

    def _voltage_layout(self):
        voltage_layout = QVBoxLayout()

        self.voltage_sp_widget = PyDMSpinboxScrollbar(self,
                                                      self._voltage_sp_pv)
        self.voltage_rb_label = PyDMLabel(self, self._voltage_rb_pv)
        self.voltage_rb_label.showUnits = True
        self.voltage_rb_label.precisionFromPV = True
        self.voltage_mon_label = PyDMLabel(self, self._voltage_mon_pv)
        self.voltage_mon_label.showUnits = True
        self.voltage_mon_label.precisionFromPV = True

        voltage_layout = QFormLayout()
        voltage_layout.setLabelAlignment(Qt.AlignRight)
        voltage_layout.setFormAlignment(Qt.AlignHCenter)
        voltage_layout.addRow('SP:', self.voltage_sp_widget)
        voltage_layout.addRow('RB:', self.voltage_rb_label)
        voltage_layout.addRow('Mon:', self.voltage_mon_label)

        return voltage_layout

    def _kick_layout(self):
        self.kick_sp_widget = PyDMSpinboxScrollbar(self, self._kick_sp_pv)
        self.kick_rb_label = PyDMLabel(self, self._kick_rb_pv)
        self.kick_rb_label.showUnits = True
        self.kick_rb_label.precisionFromPV = True
        self.kick_mon_label = PyDMLabel(self, self._kick_mon_pv)
        self.kick_mon_label.showUnits = True
        self.kick_mon_label.precisionFromPV = True

        kick_layout = QFormLayout()
        kick_layout.setLabelAlignment(Qt.AlignRight)
        kick_layout.setFormAlignment(Qt.AlignHCenter)
        kick_layout.addRow('SP:', self.kick_sp_widget)
        kick_layout.addRow('RB:', self.kick_rb_label)
        kick_layout.addRow('Mon:', self.kick_mon_label)

        return kick_layout

    def _ctrlmode_layout(self):
        ctrlmode_layout = QHBoxLayout()

        self.ctrlmode_led = SiriusLedAlert(parent=self,
                                           init_channel=self._ctrlmode_pv)
        self.ctrlmode_label = PyDMLabel(parent=self,
                                        init_channel=self._ctrlmode_pv)

        ctrlmode_layout.addStretch()
        ctrlmode_layout.addWidget(self.ctrlmode_led)
        ctrlmode_layout.addWidget(self.ctrlmode_label)

        return ctrlmode_layout
예제 #22
0
    def _setupIntlkTypeLayout(self, intlk):
        unit = 'nm'

        ld_enbl = QLabel('Enable: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignBottom)
        sb_enbl = PyDMStateButton(
            self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sel'))
        led_enbl = SiriusLedState(
            self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sts'))

        ld_clr = QLabel('Reset: ',
                        self,
                        alignment=Qt.AlignRight | Qt.AlignBottom)
        bt_clr = PyDMPushButton(self,
                                init_channel=self.devpref.substitute(
                                    propty='Intlk' + intlk + 'Clr-Sel'),
                                pressValue=1)
        bt_clr.setIcon(qta.icon('fa5s.sync'))
        bt_clr.setObjectName('clr')
        bt_clr.setStyleSheet(
            '#clr{min-width:25px; max-width:25px; icon-size:20px;}')

        ld_minx = QLabel('Min.X Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_minx = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-SP'))
        sb_minx.showStepExponent = False
        sb_minx.limitsFromChannel = False
        sb_minx.setMinimum(-1e9)
        sb_minx.setMaximum(+1e9)
        lb_minx = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-RB'))

        ld_maxx = QLabel('Max.X Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_maxx = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-SP'))
        sb_maxx.showStepExponent = False
        sb_maxx.limitsFromChannel = False
        sb_maxx.setMinimum(-1e9)
        sb_maxx.setMaximum(+1e9)
        lb_maxx = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-RB'))

        ld_miny = QLabel('Min.Y Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_miny = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-SP'))
        sb_miny.showStepExponent = False
        sb_miny.limitsFromChannel = False
        sb_miny.setMinimum(-1e9)
        sb_miny.setMaximum(+1e9)
        lb_miny = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-RB'))

        ld_maxy = QLabel('Max.Y Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_maxy = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-SP'))
        sb_maxy.showStepExponent = False
        sb_maxy.limitsFromChannel = False
        sb_maxy.setMinimum(-1e9)
        sb_maxy.setMaximum(+1e9)
        lb_maxy = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-RB'))

        ld_leglow = QLabel('Smaller', self, alignment=Qt.AlignCenter)
        ld_leghigh = QLabel('Bigger', self, alignment=Qt.AlignCenter)

        ld_legmask = QLabel('<h4>Masked By Enable</h4>',
                            self,
                            alignment=Qt.AlignCenter)
        ld_legmask_any = QLabel('X or Y',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_mask_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'Smaller-Mon'))
        led_mask_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'Bigger-Mon'))

        ld_leginst = QLabel('<h4>Instantaneous</h4>',
                            self,
                            alignment=Qt.AlignCenter)
        ld_leginst_any = QLabel('X or Y',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerAny-Mon'))
        led_inst_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerAny-Mon'))
        ld_leginst_x = QLabel('X',
                              self,
                              alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_xlow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerX-Mon'))
        led_inst_xhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerX-Mon'))
        ld_leginst_y = QLabel('Y',
                              self,
                              alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_ylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerY-Mon'))
        led_inst_yhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerY-Mon'))

        ld_legltc = QLabel('<h4>Latch</h4>', self, alignment=Qt.AlignCenter)
        ld_legltc_any = QLabel('X or Y',
                               self,
                               alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtc-Mon'))
        led_ltc_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtc-Mon'))
        ld_legltc_x = QLabel('X',
                             self,
                             alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_xlow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk +
                                    'SmallerLtcX-Mon'))
        led_ltc_xhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcX-Mon'))
        ld_legltc_y = QLabel('Y',
                             self,
                             alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_ylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk +
                                    'SmallerLtcY-Mon'))
        led_ltc_yhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcY-Mon'))

        lay_mon = QGridLayout()
        lay_mon.setAlignment(Qt.AlignCenter)
        lay_mon.addWidget(ld_leglow, 0, 1)
        lay_mon.addWidget(ld_leghigh, 0, 2)
        lay_mon.addWidget(ld_legmask, 1, 0)
        lay_mon.addWidget(ld_legmask_any, 2, 0)
        lay_mon.addWidget(led_mask_anylow, 2, 1)
        lay_mon.addWidget(led_mask_anyhigh, 2, 2)
        lay_mon.addWidget(ld_leginst, 3, 0)
        lay_mon.addWidget(ld_leginst_any, 4, 0)
        lay_mon.addWidget(led_inst_anylow, 4, 1)
        lay_mon.addWidget(led_inst_anyhigh, 4, 2)
        lay_mon.addWidget(ld_leginst_x, 5, 0)
        lay_mon.addWidget(led_inst_xlow, 5, 1)
        lay_mon.addWidget(led_inst_xhigh, 5, 2)
        lay_mon.addWidget(ld_leginst_y, 6, 0)
        lay_mon.addWidget(led_inst_ylow, 6, 1)
        lay_mon.addWidget(led_inst_yhigh, 6, 2)
        lay_mon.addWidget(ld_legltc, 7, 0)
        lay_mon.addWidget(ld_legltc_any, 8, 0)
        lay_mon.addWidget(led_ltc_anylow, 8, 1)
        lay_mon.addWidget(led_ltc_anyhigh, 8, 2)
        lay_mon.addWidget(ld_legltc_x, 9, 0)
        lay_mon.addWidget(led_ltc_xlow, 9, 1)
        lay_mon.addWidget(led_ltc_xhigh, 9, 2)
        lay_mon.addWidget(ld_legltc_y, 10, 0)
        lay_mon.addWidget(led_ltc_ylow, 10, 1)
        lay_mon.addWidget(led_ltc_yhigh, 10, 2)

        lay = QGridLayout()
        lay.setAlignment(Qt.AlignTop)
        lay.addWidget(ld_enbl, 0, 0)
        lay.addWidget(sb_enbl, 0, 1)
        lay.addWidget(led_enbl, 0, 2)
        lay.addWidget(ld_clr, 1, 0)
        lay.addWidget(bt_clr, 1, 1, alignment=Qt.AlignCenter)
        lay.addWidget(ld_minx, 2, 0)
        lay.addWidget(sb_minx, 2, 1)
        lay.addWidget(lb_minx, 2, 2)
        lay.addWidget(ld_maxx, 3, 0)
        lay.addWidget(sb_maxx, 3, 1)
        lay.addWidget(lb_maxx, 3, 2)
        lay.addWidget(ld_miny, 4, 0)
        lay.addWidget(sb_miny, 4, 1)
        lay.addWidget(lb_miny, 4, 2)
        lay.addWidget(ld_maxy, 5, 0)
        lay.addWidget(sb_maxy, 5, 1)
        lay.addWidget(lb_maxy, 5, 2)
        lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 6, 0)
        lay.addLayout(lay_mon, 7, 0, 1, 3)
        return lay
예제 #23
0
class CurrLTWindow(SiriusMainWindow):
    """Current and Lifetime Window."""
    def __init__(self, parent=None, prefix=_VACA_PREFIX):
        """Initialize some widgets."""
        super(CurrLTWindow, self).__init__(parent)
        self.prefix = prefix
        self.device = _PVName('SI-Glob:AP-CurrInfo')
        self.devname = self.device.substitute(prefix=self.prefix)
        self.setObjectName('SIApp')
        self.setWindowTitle('SI Current Info: Current and Lifetime')
        self._setupUi()
        self.setFocus(True)
        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        self.label_title = QLabel('SI Current and Lifetime')
        self.label_title.setStyleSheet("""
            font-size:1.2em; font-weight:bold;
            background-color: qlineargradient(spread:pad, x1:1, y1:0.0227273,
                              x2:0, y2:0, stop:0 rgba(173, 190, 207, 255),
                              stop:1 rgba(213, 213, 213, 255));""")
        self.label_title.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.settings = QWidget()
        vlay_sett = QVBoxLayout(self.settings)
        vlay_sett.setContentsMargins(0, 0, 0, 0)
        vlay_sett.addWidget(self._setupCurrentSettingsWidget())
        vlay_sett.addWidget(self._setupLifetimeSettigsWidget())
        vlay_sett.addWidget(self._setupGraphSettingsWidget())

        self.pb_showsett = QPushButton('<', self)
        self.pb_showsett.setObjectName('showsett')
        self.pb_showsett.setToolTip('Hide settings')
        self.pb_showsett.setStyleSheet(
            '#showsett{min-width:0.7em;max-width:0.7em;}')
        self.pb_showsett.released.connect(self._handle_settings_vis)

        self.pb_showeff = QPushButton('v', self)
        self.pb_showeff.setObjectName('showeff')
        self.pb_showeff.setToolTip('Show efficiency graph')
        self.pb_showeff.setStyleSheet(
            '#showeff{min-width:0.7em;max-width:0.7em;}')
        self.pb_showeff.released.connect(self._handle_efficiency_vis)

        hbox_visi = QHBoxLayout()
        hbox_visi.addStretch()
        hbox_visi.addWidget(self.pb_showsett)
        hbox_visi.addWidget(self.pb_showeff)

        self.eff_graph = EffMonitor(self, self.prefix, self.device.sec)
        self.eff_graph.setVisible(False)

        cw = QWidget()
        self.setCentralWidget(cw)
        lay = QGridLayout(cw)
        lay.addWidget(self.label_title, 0, 0, 1, 2)
        lay.addLayout(self._setupGraphPanelLayout(), 1, 0)
        lay.addWidget(self.settings, 1, 1)
        lay.addLayout(hbox_visi, 2, 0, 1, 2, alignment=Qt.AlignRight)
        lay.addWidget(self.eff_graph, 3, 0, 1, 2)
        lay.setColumnStretch(0, 6)
        lay.setColumnStretch(1, 1)

    def _setupGraphPanelLayout(self):
        # Main Panel
        # # Labels
        self._ld_current = QLabel('Current', self, alignment=Qt.AlignCenter)
        self._ld_current.setStyleSheet("font-weight:bold; max-height1.5em;")
        self._lb_current = PyDMLabel(
            self, self.devname.substitute(propty='Current-Mon'))
        self._lb_current.setStyleSheet("font-size:40px;")
        self._lb_current.precision = 0
        self._lb_current.showUnits = True

        self._ld_lifetime = QLabel('Lifetime', self)
        self._ld_lifetime.setStyleSheet("font-weight:bold; max-height1.5em;")
        self._ld_lifetime.setAlignment(Qt.AlignCenter)
        self._lb_lifetime = QLabel('0:00:00', self)
        self._lb_lifetime.channel = self.devname.substitute(
            propty='Lifetime-Mon')
        self._lb_lifetime.setStyleSheet("font-size:40px;")
        self.lifetime_dcct_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='Lifetime-Mon'))
        self.lifetime_dcct_pv.new_value_signal[float].connect(
            self._format_lifetime_label)
        self.lifetime_bpm_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='LifetimeBPM-Mon'))
        self.lifetime_bpm_pv.new_value_signal[float].connect(
            self._format_lifetime_label)

        # # Graph
        self.graph = SiriusTimePlot(self, background='w')
        self.graph.plotItem.getAxis('left').setLabel('Current [mA]',
                                                     color='blue')
        self.graph.plotItem.getAxis('right').setLabel('Lifetime [h]',
                                                      color='red')
        self.graph.showLegend = False
        self.graph.showXGrid = True
        self.graph.showYGrid = True
        self.graph.autoRangeY = True
        self.graph.setObjectName('graph')
        self.graph.setStyleSheet('#graph{min-width:40em;min-height:32em;}')
        self.graph.bufferSize = 60 * 60 * 10
        self.graph.timeSpan = 30 * 60

        t_end = Time.now()
        t_init = t_end - 30 * 60
        t_end_iso = t_end.get_iso8601()
        t_init_iso = t_init.get_iso8601()

        pvname = self.devname.substitute(propty='Current-Mon')
        self.graph.addYChannel(y_channel=pvname,
                               axis='left',
                               name='Current',
                               color='blue',
                               lineWidth=1)
        self._curve_current = self.graph.curveAtIndex(0)
        self.graph.fill_curve_with_archdata(self._curve_current,
                                            pvname,
                                            t_init=t_init_iso,
                                            t_end=t_end_iso)

        pvname = _PVName('SI-01M1:DI-BPM:Sum-Mon').substitute(
            prefix=self.prefix)
        self.graph.addYChannel(y_channel=pvname,
                               axis='left',
                               name='Current',
                               color='blue',
                               lineWidth=1)
        self._curve_bpmsum = self.graph.curveAtIndex(1)
        self.graph.fill_curve_with_archdata(self._curve_bpmsum,
                                            pvname,
                                            t_init=t_init_iso,
                                            t_end=t_end_iso)

        self.graph.addYChannel(y_channel='FAKE:Lifetime',
                               axis='right',
                               name='Lifetime',
                               color='red',
                               lineWidth=1)
        self._curve_lifetimedcct = self.graph.curveAtIndex(2)
        self.graph.fill_curve_with_archdata(
            self._curve_lifetimedcct,
            self.devname.substitute(propty='Lifetime-Mon'),
            t_init=t_init_iso,
            t_end=t_end_iso,
            factor=3600)

        self.graph.addYChannel(y_channel='FAKE:LifetimeBPM',
                               axis='right',
                               name='Lifetime',
                               color='red',
                               lineWidth=1)
        self._curve_lifetimebpm = self.graph.curveAtIndex(3)
        self.graph.fill_curve_with_archdata(
            self._curve_lifetimebpm,
            self.devname.substitute(propty='LifetimeBPM-Mon'),
            t_init=t_init_iso,
            t_end=t_end_iso,
            factor=3600)

        self.lifetime_dcct_pv.new_value_signal[float].connect(
            self._update_graph)
        self.lifetime_bpm_pv.new_value_signal[float].connect(
            self._update_graph)

        self._flag_need_dcctx = True
        self._flag_need_dccty = True
        self._flag_need_bpmx = True
        self._flag_need_bpmy = True
        self.dcct_wavx = _np.array([])
        self.dcct_wavy = _np.array([])
        self.bpm_wavx = _np.array([])
        self.bpm_wavy = _np.array([])
        self.dcct_buff_y_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='BufferValue-Mon'))
        self.dcct_buff_x_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='BufferTimestamp-Mon'))
        self.bpm_buff_y_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='BufferValueBPM-Mon'))
        self.bpm_buff_x_pv = SiriusConnectionSignal(
            self.devname.substitute(propty='BufferTimestampBPM-Mon'))
        self.dcct_buff_y_pv.new_value_signal[_np.ndarray].connect(
            self._update_waveforms)
        self.dcct_buff_x_pv.new_value_signal[_np.ndarray].connect(
            self._update_waveforms)
        self.bpm_buff_y_pv.new_value_signal[_np.ndarray].connect(
            self._update_waveforms)
        self.bpm_buff_x_pv.new_value_signal[_np.ndarray].connect(
            self._update_waveforms)

        self.graph.addYChannel(y_channel='FAKE:DCCTBuffer',
                               axis='left',
                               name='DCCTBuffer',
                               color='blue',
                               lineStyle=Qt.NoPen,
                               symbolSize=10,
                               symbol='o')
        self._curve_dcct_buff = self.graph.curveAtIndex(4)
        self.graph.addYChannel(y_channel='FAKE:BPMBuffer',
                               axis='left',
                               name='BPMBuffer',
                               color='blue',
                               lineStyle=Qt.NoPen,
                               symbolSize=10,
                               symbol='o')
        self._curve_bpm_buff = self.graph.curveAtIndex(5)

        self._curve_bpmsum.setVisible(False)
        self._curve_lifetimebpm.setVisible(False)
        self._curve_bpm_buff.setVisible(False)

        lay = QGridLayout()
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    0)
        lay.addWidget(self._ld_current, 0, 1)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    2)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    3)
        lay.addWidget(self._ld_lifetime, 0, 4)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    5)
        lay.addWidget(self._lb_current, 1, 1)
        lay.addWidget(self._lb_lifetime, 1, 4)
        lay.addWidget(self.graph, 2, 0, 1, 6)
        return lay

    def _setupCurrentSettingsWidget(self):
        self._ld_storedebeam = QLabel('Stored EBeam?', self)
        self._ld_storedebeam.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                          | Qt.AlignVCenter)
        self._led_storedebeam = SiriusLedState(
            self, self.devname.substitute(propty='StoredEBeam-Mon'))

        self._ld_dcctfault = QLabel('DCCT Fault Check:', self)
        self._ld_dcctfault.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                        | Qt.AlignVCenter)
        self._bt_dcctfault = PyDMStateButton(
            self, self.devname.substitute(propty='DCCTFltCheck-Sel'))
        self._bt_dcctfault.shape = PyDMStateButton.Rounded
        self._led_dcctfault = SiriusLedState(
            self, self.devname.substitute(propty='DCCTFltCheck-Sts'))

        self._ld_seldcct = QLabel('Select DCCT:', self)
        self._ld_seldcct.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                      | Qt.AlignVCenter)
        self._cb_seldcct = PyDMEnumComboBox(
            self, self.devname.substitute(propty='DCCT-Sel'))
        self._lb_seldcct = PyDMLabel(
            self, self.devname.substitute(propty='DCCT-Sts'))
        self._lb_seldcct.setAlignment(Qt.AlignCenter)
        self._lb_seldcct.precision = 0

        self._led_dcct13c4 = SiriusLedAlert(
            self,
            _PVName('SI-13C4:DI-DCCT:ReliableMeas-Mon').substitute(
                prefix=self.prefix))
        self._lb_dcct13c4 = QLabel('DCCT 13C4', self)
        self._lb_dcct13c4.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                       | Qt.AlignVCenter)
        self._pb_13c4_detail = QPushButton(self)
        self._pb_13c4_detail.setObjectName('DCCT13C4_dtl')
        self._pb_13c4_detail.setStyleSheet(
            "#DCCT13C4_dtl{min-width:25px; max-width:25px; icon-size:20px;}")
        self._pb_13c4_detail.setIcon(qta.icon('fa5s.ellipsis-h'))
        connect_window(self._pb_13c4_detail,
                       DCCTMain,
                       self,
                       prefix=self.prefix,
                       device='SI-13C4:DI-DCCT')
        hlay_dcct13c4 = QHBoxLayout()
        hlay_dcct13c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))
        hlay_dcct13c4.addWidget(self._led_dcct13c4)
        hlay_dcct13c4.addWidget(self._lb_dcct13c4)
        hlay_dcct13c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))
        hlay_dcct13c4.addWidget(self._pb_13c4_detail)
        hlay_dcct13c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))

        self._led_dcct14c4 = SiriusLedAlert(
            self,
            _PVName('SI-14C4:DI-DCCT:ReliableMeas-Mon').substitute(
                prefix=self.prefix))
        self._lb_dcct14c4 = QLabel('DCCT 14C4', self)
        self._lb_dcct14c4.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                       | Qt.AlignVCenter)
        self._pb_14c4_detail = QPushButton(self)
        self._pb_14c4_detail.setObjectName('DCCT14C4_dtl')
        self._pb_14c4_detail.setStyleSheet(
            "#DCCT14C4_dtl{min-width:25px; max-width:25px; icon-size:20px;}")
        self._pb_14c4_detail.setIcon(qta.icon('fa5s.ellipsis-h'))
        connect_window(self._pb_14c4_detail,
                       DCCTMain,
                       self,
                       prefix=self.prefix,
                       device='SI-14C4:DI-DCCT')
        hlay_dcct14c4 = QHBoxLayout()
        hlay_dcct14c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))
        hlay_dcct14c4.addWidget(self._led_dcct14c4)
        hlay_dcct14c4.addWidget(self._lb_dcct14c4)
        hlay_dcct14c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))
        hlay_dcct14c4.addWidget(self._pb_14c4_detail)
        hlay_dcct14c4.addItem(
            QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum))

        gbox = QGroupBox('Current Settings and Status', self)
        lay = QGridLayout(gbox)
        lay.addWidget(self._ld_storedebeam, 0, 0)
        lay.addWidget(self._led_storedebeam, 0, 1)
        lay.addWidget(self._ld_dcctfault, 1, 0)
        lay.addWidget(self._bt_dcctfault, 1, 1)
        lay.addWidget(self._led_dcctfault, 1, 2)
        lay.addWidget(self._ld_seldcct, 2, 0)
        lay.addWidget(self._cb_seldcct, 2, 1)
        lay.addWidget(self._lb_seldcct, 2, 2)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 3,
                    0)
        lay.addLayout(hlay_dcct13c4, 4, 0, 1, 3)
        lay.addLayout(hlay_dcct14c4, 5, 0, 1, 3)
        lay.setColumnStretch(0, 2)
        lay.setColumnStretch(1, 1)
        lay.setColumnStretch(2, 1)
        return gbox

    def _setupLifetimeSettigsWidget(self):
        self._ld_calcmode = QLabel('Calc Mode:',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)
        self._cb_calcmode = PyDMEnumComboBox(
            self, self.devname.substitute(propty='LtFitMode-Sel'))
        self._lb_calcmode = SiriusLabel(
            self, self.devname.substitute(propty='LtFitMode-Sts'))
        self._lb_calcmode.setAlignment(Qt.AlignCenter)

        self._ld_curroffset = QLabel('Current\nOffset [mA]:',
                                     self,
                                     alignment=Qt.AlignRight | Qt.AlignTrailing
                                     | Qt.AlignVCenter)
        self._sb_curroffset = SiriusSpinbox(
            self, self.devname.substitute(propty='CurrOffset-SP'))
        self._sb_curroffset.showStepExponent = False
        self._lb_curroffset = PyDMLabel(
            self, self.devname.substitute(propty='CurrOffset-RB'))
        self._lb_curroffset.setAlignment(Qt.AlignCenter)

        self._ld_buffer = QLabel('<h4>Buffer</h4>',
                                 self,
                                 alignment=Qt.AlignCenter)

        self._pb_plussett = QPushButton('+', self)
        self._pb_plussett.setStyleSheet('max-height:0.9em; max-width:0.9em;')
        self._pb_plussett.released.connect(self._handle_intvl_sett_visibility)
        self._ld_maxintvl = QLabel('Max. Sampling\nInterval [s]:',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)
        self._ld_maxintvl.setToolTip(
            "Timestamp settings use 2 parameters to define the\n"
            "timestamp interval.\n\n"
            "If 'Max. Sampling Interval' == -1:\n"
            "    use 'Last Time' and 'First Time' parameters.\n"
            "Else:\n"
            "    use 'Max. Sampling Interval' and last timestamp set.\n\n"
            "Default: use 'Max. Sampling Interval' and 'Last Time'.")
        hlay_maxintvl = QHBoxLayout()
        hlay_maxintvl.addWidget(self._pb_plussett)
        hlay_maxintvl.addWidget(self._ld_maxintvl)
        self._sb_maxintvl = PyDMSpinbox(
            self, self.devname.substitute(propty='MaxSplIntvl-SP'))
        self._sb_maxintvl.precisionFromPV = True
        self._sb_maxintvl.showStepExponent = False
        self._lb_maxintvl = PyDMLabel(
            self, self.devname.substitute(propty='MaxSplIntvl-RB'))
        self._lb_maxintvl.setAlignment(Qt.AlignCenter)
        self._lb_maxintvl.precisionFromPV = True

        self._ld_firstsmpl = QLabel('First Time [s]:',
                                    self,
                                    alignment=Qt.AlignRight | Qt.AlignTrailing
                                    | Qt.AlignVCenter)
        self._ld_firstsmpl.setVisible(False)
        self._le_firstsmpl = PyDMLineEdit(
            self, self.devname.substitute(propty='FrstSplTime-SP'))
        self._le_firstsmpl.setVisible(False)
        self._lb_firstsmpl_dcct = PyDMLabel(
            self, self.devname.substitute(propty='FrstSplTime-RB'))
        self._lb_firstsmpl_dcct.setVisible(False)
        self._lb_firstsmpl_bpm = PyDMLabel(
            self, self.devname.substitute(propty='FrstSplTimeBPM-RB'))
        self._lb_firstsmpl_bpm.setVisible(False)
        self._pb_firstnow = QPushButton(qta.icon('mdi.clock-end'), '', self)
        self._pb_firstnow.setObjectName('firstnow')
        self._pb_firstnow.setStyleSheet(
            '#firstnow{min-width:25px; max-width:25px; icon-size:20px;}')
        self._pb_firstnow.setToolTip('Click to set current timestamp')
        self._pb_firstnow.released.connect(self._update_first_time)
        self._pb_firstnow.setVisible(False)
        hbox_sp_first = QHBoxLayout()
        hbox_sp_first.addWidget(self._le_firstsmpl)
        hbox_sp_first.addWidget(self._pb_firstnow)

        self._ld_lastsmpl = QLabel('Last Time [s]:',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)
        self._ld_lastsmpl.setToolTip(
            "If 'Last Time' == -1, use current timestamp.")
        self._ld_lastsmpl.setVisible(False)
        self._le_lastsmpl = PyDMLineEdit(
            self, self.devname.substitute(propty='LastSplTime-SP'))
        self._le_lastsmpl.setVisible(False)
        self._lb_lastsmpl_dcct = PyDMLabel(
            self, self.devname.substitute(propty='LastSplTime-RB'))
        self._lb_lastsmpl_dcct.setVisible(False)
        self._lb_lastsmpl_bpm = PyDMLabel(
            self, self.devname.substitute(propty='LastSplTimeBPM-RB'))
        self._lb_lastsmpl_bpm.setVisible(False)
        self._pb_lastnow = QPushButton(qta.icon('mdi.clock-end'), '', self)
        self._pb_lastnow.setObjectName('lastnow')
        self._pb_lastnow.setStyleSheet(
            '#lastnow{min-width:25px; max-width:25px; icon-size:20px;}')
        self._pb_lastnow.setToolTip('Click to set current timestamp')
        self._pb_lastnow.released.connect(self._update_last_time)
        self._pb_lastnow.setVisible(False)
        hbox_sp_last = QHBoxLayout()
        hbox_sp_last.addWidget(self._le_lastsmpl)
        hbox_sp_last.addWidget(self._pb_lastnow)

        self._ld_smplintvl = QLabel('Samples\nInterval [s]:',
                                    self,
                                    alignment=Qt.AlignRight | Qt.AlignTrailing
                                    | Qt.AlignVCenter)
        self._lb_smplintvl_dcct = PyDMLabel(
            self, self.devname.substitute(propty='SplIntvl-Mon'))
        self._lb_smplintvl_bpm = PyDMLabel(
            self, self.devname.substitute(propty='SplIntvlBPM-Mon'))
        self._lb_smplintvl_bpm.setVisible(False)

        self._ld_intvlbtwspl = QLabel('Interval Between\nSamples [s]:',
                                      self,
                                      alignment=Qt.AlignRight
                                      | Qt.AlignTrailing | Qt.AlignVCenter)
        self._sb_intvlbtwspl = PyDMSpinbox(
            self, self.devname.substitute(propty='MinIntvlBtwSpl-SP'))
        self._sb_intvlbtwspl.precisionFromPV = True
        self._sb_intvlbtwspl.showStepExponent = False
        self._lb_intvlbtwspl = PyDMLabel(
            self, self.devname.substitute(propty='MinIntvlBtwSpl-RB'))
        self._lb_intvlbtwspl.setAlignment(Qt.AlignCenter)
        self._lb_intvlbtwspl.precisionFromPV = True

        self._ld_bufautoreset = QLabel('Auto Reset:',
                                       self,
                                       alignment=Qt.AlignRight
                                       | Qt.AlignTrailing | Qt.AlignVCenter)
        self._cb_bufautoreset = PyDMEnumComboBox(
            self, self.devname.substitute(propty='BuffAutoRst-Sel'))
        self._lb_bufautoreset = PyDMLabel(
            self, self.devname.substitute(propty='BuffAutoRst-Sts'))

        self._ld_bufdcurr = QLabel('Auto Reset Delta\nCurrent [mA]:',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)
        self._sb_bufdcurr = PyDMSpinbox(
            self, self.devname.substitute(propty='BuffAutoRstDCurr-SP'))
        self._sb_bufdcurr.showStepExponent = False
        self._lb_bufdcurr = PyDMLabel(
            self, self.devname.substitute(propty='BuffAutoRstDCurr-RB'))

        self._ld_bufsize = QLabel('Size:',
                                  self,
                                  alignment=Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)
        self._lb_bufsize_dcct = PyDMLabel(
            self, self.devname.substitute(propty='BuffSize-Mon'))
        self._lb_bufsize_dcct.setAlignment(Qt.AlignCenter)
        self._lb_bufsize_bpm = PyDMLabel(
            self, self.devname.substitute(propty='BuffSizeBPM-Mon'))
        self._lb_bufsize_bpm.setAlignment(Qt.AlignCenter)
        self._lb_bufsize_bpm.setVisible(False)
        self._pb_bufreset = PyDMPushButton(
            self,
            label='',
            icon=qta.icon('mdi.delete-empty'),
            pressValue=1,
            init_channel=self.devname.substitute(propty='BuffRst-Cmd'))
        self._pb_bufreset.setObjectName('reset')
        self._pb_bufreset.setStyleSheet(
            "#reset{min-width:25px; max-width:25px; icon-size:20px;}")
        self._ld_sep = QLabel('/', self)
        self._lb_bufsizetot_dcct = PyDMLabel(
            self, self.devname.substitute(propty='BuffSizeTot-Mon'))
        self._lb_bufsizetot_dcct.setStyleSheet("min-width:5em; max-width:5em;")
        self._lb_bufsizetot_dcct.setAlignment(Qt.AlignCenter)
        self._lb_bufsizetot_dcct.precision = 0
        self._lb_bufsizetot_bpm = PyDMLabel(
            self, self.devname.substitute(propty='BuffSizeTotBPM-Mon'))
        self._lb_bufsizetot_bpm.setStyleSheet("min-width:5em; max-width:5em;")
        self._lb_bufsizetot_bpm.setAlignment(Qt.AlignCenter)
        self._lb_bufsizetot_bpm.precision = 0
        self._lb_bufsizetot_bpm.setVisible(False)
        glay_bufsize = QGridLayout()
        glay_bufsize.addWidget(self._lb_bufsize_dcct, 0, 0)
        glay_bufsize.addWidget(self._lb_bufsize_bpm, 0, 0)
        glay_bufsize.addWidget(self._pb_bufreset, 0, 1)
        glay_bufsize.addWidget(self._ld_sep, 0, 2)
        glay_bufsize.addWidget(self._lb_bufsizetot_dcct, 0, 3)
        glay_bufsize.addWidget(self._lb_bufsizetot_bpm, 0, 3)
        glay_bufsize.setColumnStretch(0, 5)
        glay_bufsize.setColumnStretch(1, 2)
        glay_bufsize.setColumnStretch(2, 1)
        glay_bufsize.setColumnStretch(3, 5)

        gbox = QGroupBox('Lifetime Settings', self)
        lay = QGridLayout(gbox)
        lay.addWidget(self._ld_calcmode, 0, 0)
        lay.addWidget(self._cb_calcmode, 0, 1)
        lay.addWidget(self._lb_calcmode, 0, 2)
        lay.addWidget(self._ld_curroffset, 1, 0)
        lay.addWidget(self._sb_curroffset, 1, 1)
        lay.addWidget(self._lb_curroffset, 1, 2)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 2,
                    1)
        lay.addWidget(self._ld_buffer, 3, 0, 1, 3)
        lay.addLayout(hlay_maxintvl, 4, 0)
        lay.addWidget(self._sb_maxintvl, 4, 1)
        lay.addWidget(self._lb_maxintvl, 4, 2)
        lay.addWidget(self._ld_firstsmpl, 5, 0)
        lay.addLayout(hbox_sp_first, 5, 1, 1, 2)
        lay.addWidget(self._lb_firstsmpl_dcct, 6, 1, 1, 2)
        lay.addWidget(self._lb_firstsmpl_bpm, 6, 1, 1, 2)
        lay.addWidget(self._ld_lastsmpl, 7, 0)
        lay.addLayout(hbox_sp_last, 7, 1, 1, 2)
        lay.addWidget(self._lb_lastsmpl_dcct, 8, 1, 1, 2)
        lay.addWidget(self._lb_lastsmpl_bpm, 8, 1, 1, 2)
        lay.addWidget(self._ld_smplintvl, 9, 0)
        lay.addWidget(self._lb_smplintvl_dcct, 9, 1)
        lay.addWidget(self._lb_smplintvl_bpm, 9, 1)
        lay.addWidget(self._ld_intvlbtwspl, 10, 0)
        lay.addWidget(self._sb_intvlbtwspl, 10, 1)
        lay.addWidget(self._lb_intvlbtwspl, 10, 2)
        lay.addItem(QSpacerItem(20, 5, QSzPlcy.Minimum, QSzPlcy.Fixed), 11, 1)
        lay.addWidget(self._ld_bufautoreset, 12, 0)
        lay.addWidget(self._cb_bufautoreset, 12, 1)
        lay.addWidget(self._lb_bufautoreset, 12, 2)
        lay.addWidget(self._ld_bufdcurr, 13, 0)
        lay.addWidget(self._sb_bufdcurr, 13, 1)
        lay.addWidget(self._lb_bufdcurr, 13, 2)
        lay.addItem(QSpacerItem(20, 5, QSzPlcy.Minimum, QSzPlcy.Fixed), 14, 1)
        lay.addWidget(self._ld_bufsize, 15, 0)
        lay.addLayout(glay_bufsize, 15, 1, 1, 2)
        return gbox

    def _setupGraphSettingsWidget(self):
        self._ld_ltfrom = QLabel('Show lifetime from:',
                                 self,
                                 alignment=Qt.AlignRight | Qt.AlignTrailing
                                 | Qt.AlignVCenter)
        self._cb_ltfrom = QComboBox()
        self._cb_ltfrom.addItem('DCCT')
        self._cb_ltfrom.addItem('BPM')
        self._cb_ltfrom.currentTextChanged.connect(
            self._handle_lifetime_type_sel)

        self._ld_showsmpl = QLabel('Show samples: ',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignTrailing
                                   | Qt.AlignVCenter)
        self._cb_showsmpl = QCheckBox(self)
        self._cb_showsmpl.setChecked(True)
        self._cb_showsmpl.stateChanged.connect(self._handle_samples_visibility)

        gbox = QGroupBox('Graphs Settings', self)
        lay = QGridLayout(gbox)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    0)
        lay.addWidget(self._ld_ltfrom, 0, 1)
        lay.addWidget(self._cb_ltfrom, 0, 2)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0,
                    3)
        lay.addItem(QSpacerItem(1, 1, QSzPlcy.Minimum, QSzPlcy.Expanding), 1,
                    1, 1, 2)
        lay.addWidget(self._ld_showsmpl, 2, 1)
        lay.addWidget(self._cb_showsmpl, 2, 2)
        return gbox

    # ---------- auxiliar methods ----------

    def _format_lifetime_label(self, value):
        """Format lifetime label."""
        if self._lb_lifetime.channel != self.sender().address:
            return
        lt = 0 if _np.isnan(value) else value
        H = int(lt // 3600)
        m = int((lt % 3600) // 60)
        s = int((lt % 3600) % 60)
        lt_str = '{:d}:{:02d}:{:02d}'.format(H, m, s)
        self._lb_lifetime.setText(lt_str)

    @Slot(str)
    def _handle_lifetime_type_sel(self, text):
        """Handle lifetime type selection."""
        cond = bool(text == 'DCCT')
        self._curve_current.setVisible(cond)
        self._curve_lifetimedcct.setVisible(cond)
        self._curve_dcct_buff.setVisible(cond)
        self._lb_bufsizetot_dcct.setVisible(cond)
        self._lb_bufsize_dcct.setVisible(cond)
        self._lb_smplintvl_dcct.setVisible(cond)

        self._curve_bpmsum.setVisible(not cond)
        self._curve_lifetimebpm.setVisible(not cond)
        self._curve_bpm_buff.setVisible(not cond)
        self._lb_bufsizetot_bpm.setVisible(not cond)
        self._lb_bufsize_bpm.setVisible(not cond)
        self._lb_smplintvl_bpm.setVisible(not cond)

        visi = self._pb_plussett.text() == '-'
        self._lb_firstsmpl_dcct.setVisible(cond and visi)
        self._lb_lastsmpl_dcct.setVisible(cond and visi)
        self._lb_firstsmpl_bpm.setVisible(not cond and visi)
        self._lb_lastsmpl_bpm.setVisible(not cond and visi)

        if not cond:
            self.graph.plotItem.getAxis('left').setLabel('01M1 BPM Sum',
                                                         color='blue')
            self._lb_lifetime.channel = \
                self.devname.substitute(propty='LifetimeBPM-Mon')
        else:
            self.graph.plotItem.getAxis('left').setLabel('Current [mA]',
                                                         color='blue')
            self._lb_lifetime.channel = \
                self.devname.substitute(propty='Lifetime-Mon')

    def _handle_intvl_sett_visibility(self):
        """Handle sampling interval settings."""
        text = self.sender().text()
        visi = text == '+'
        self._ld_firstsmpl.setVisible(visi)
        self._le_firstsmpl.setVisible(visi)
        self._pb_firstnow.setVisible(visi)
        self._ld_lastsmpl.setVisible(visi)
        self._le_lastsmpl.setVisible(visi)
        self._pb_lastnow.setVisible(visi)

        showingdcct = self._cb_ltfrom.currentText() == 'DCCT'
        self._lb_firstsmpl_dcct.setVisible(showingdcct and visi)
        self._lb_lastsmpl_dcct.setVisible(showingdcct and visi)
        self._lb_firstsmpl_bpm.setVisible(not showingdcct and visi)
        self._lb_lastsmpl_bpm.setVisible(not showingdcct and visi)

        self.sender().setText('+' if text == '-' else '-')

    @Slot(int)
    def _handle_samples_visibility(self, state):
        """Handle samples visibility."""
        showingdcct = self._cb_ltfrom.currentText() == 'DCCT'
        self._curve_dcct_buff.setVisible(showingdcct and state)
        self._curve_bpm_buff.setVisible(not showingdcct and state)

    def _handle_settings_vis(self):
        vis = self.settings.isVisible()
        text = '>' if vis else '<'
        ttip = 'Show' if vis else 'Hide'
        self.pb_showsett.setText(text)
        self.pb_showsett.setToolTip(ttip + ' settings')
        self.settings.setVisible(not vis)
        self.sender().parent().adjustSize()
        self.centralWidget().adjustSize()
        self.adjustSize()

    def _handle_efficiency_vis(self):
        vis = self.eff_graph.isVisible()
        text = 'v' if vis else '^'
        ttip = 'Show' if vis else 'Hide'
        self.pb_showeff.setText(text)
        self.pb_showeff.setToolTip(ttip + ' efficiency graph')
        self.eff_graph.setVisible(not vis)
        self.sender().parent().adjustSize()
        self.centralWidget().adjustSize()
        self.adjustSize()

    def _update_first_time(self):
        """Update first sample time to current timestamp."""
        now = _time.time()
        self._le_firstsmpl.send_value_signal[float].emit(now)

    def _update_last_time(self):
        """Update last sample time to current timestamp."""
        now = _time.time()
        self._le_lastsmpl.send_value_signal[float].emit(now)

    @Slot(float)
    def _update_graph(self, value):
        """Receive new lifetime values and update curves in hours."""
        if 'BPM' in self.sender().address:
            self._curve_lifetimebpm.receiveNewValue(value / 3600)
        else:
            self._curve_lifetimedcct.receiveNewValue(value / 3600)

    @Slot(_np.ndarray)
    def _update_waveforms(self, value):
        """Update samples waveforms."""
        address = self.sender().address
        if 'BPM' in address:
            if 'Timestamp' in address:
                self.bpm_wavx = value + _time.time()
                self._flag_need_bpmx = False
            elif 'Value' in address:
                self.bpm_wavy = value
                self._flag_need_bpmy = False
            if not self._flag_need_bpmy and not self._flag_need_bpmx:
                if len(self.bpm_wavx) != len(self.bpm_wavy):
                    return
                self.graph.fill_curve_buffer(self._curve_bpm_buff,
                                             self.bpm_wavx, self.bpm_wavy)
                self._flag_need_bpmx = True
                self._flag_need_bpmy = True
        else:
            if 'Timestamp' in address:
                self.dcct_wavx = value + _time.time()
                self._flag_need_dcctx = False
            elif 'Value' in address:
                self.dcct_wavy = value
                self._flag_need_dccty = False
            if not self._flag_need_dccty and not self._flag_need_dcctx:
                if len(self.dcct_wavx) != len(self.dcct_wavy):
                    return
                self.graph.fill_curve_buffer(self._curve_dcct_buff,
                                             self.dcct_wavx, self.dcct_wavy)
                self._flag_need_dcctx = True
                self._flag_need_dccty = True
예제 #24
0
class BPMOrbIntlkDetailWindow(BaseObject, SiriusMainWindow):
    """Individual BPM Orbit Interlock Window."""
    def __init__(self, parent=None, prefix=_vaca_prefix, device=''):
        """Init."""
        BaseObject.__init__(self, prefix)
        SiriusMainWindow.__init__(self, parent)

        self.prefix = prefix
        self.device = SiriusPVName(device)
        self.devpref = self.device.substitute(prefix=prefix)

        self.setObjectName('SIApp')
        self.setWindowTitle(device + ' Orbit Interlock Control Window')

        self._setupUi()

        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        wid = QWidget(self)
        self.setCentralWidget(wid)

        title = QLabel('<h3>' + self.device + ' Orbit Interlock Control</h3>',
                       self,
                       alignment=Qt.AlignCenter)
        title.setStyleSheet("font-weight: bold;")

        # General Interlock
        self._gb_gen = QGroupBox('General Interlock')
        lay_gen = self._setupIntlkGenLayout()
        self._gb_gen.setLayout(lay_gen)

        # Translation Interlock
        self._gb_trans = QGroupBox('Translation Interlock')
        lay_trans = self._setupIntlkTypeLayout('Trans')
        self._gb_trans.setLayout(lay_trans)

        # Angulation Interlock
        self._gb_ang = QGroupBox('Angulation Interlock')
        lay_ang = self._setupIntlkTypeLayout('Ang')
        self._gb_ang.setLayout(lay_ang)

        lay = QGridLayout(wid)
        lay.addWidget(title, 0, 0, 1, 2)
        lay.addWidget(self._gb_gen, 1, 0, 1, 2)
        lay.addWidget(self._gb_trans, 2, 0)
        lay.addWidget(self._gb_ang, 2, 1)

    def _setupIntlkGenLayout(self):
        self._ld_genenbl = QLabel('Enable: ',
                                  self,
                                  alignment=Qt.AlignRight | Qt.AlignBottom)
        self._sb_genenbl = PyDMStateButton(
            self, self.devpref.substitute(propty='IntlkEn-Sel'))
        self._led_genenbl = SiriusLedState(
            self, self.devpref.substitute(propty='IntlkEn-Sts'))

        self._ld_genclr = QLabel('Reset: ',
                                 self,
                                 alignment=Qt.AlignRight | Qt.AlignBottom)
        self._bt_genclr = PyDMPushButton(
            self,
            init_channel=self.devpref.substitute(propty='IntlkClr-Sel'),
            pressValue=1)
        self._bt_genclr.setIcon(qta.icon('fa5s.sync'))
        self._bt_genclr.setObjectName('clr')
        self._bt_genclr.setStyleSheet(
            '#clr{min-width:25px; max-width:25px; icon-size:20px;}')

        self._ld_intlkinst = QLabel('Intantaneous Interlock: ',
                                    self,
                                    alignment=Qt.AlignRight | Qt.AlignBottom)
        self._led_intlkinst = SiriusLedAlert(
            self, self.devpref.substitute(propty='Intlk-Mon'))

        self._ld_intlkltc = QLabel('Latch Interlock: ',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignBottom)
        self._led_intlkltc = SiriusLedAlert(
            self, self.devpref.substitute(propty='IntlkLtc-Mon'))

        self._ld_minsumenbl = QLabel('Min.Sum.Thres. Enable: ',
                                     self,
                                     alignment=Qt.AlignRight | Qt.AlignBottom)
        self._ld_minsumenbl.setToolTip(
            'If enabled, enable interlock only if minimum sum'
            ' threshold is exceeded.')
        self._sb_minsumenbl = PyDMStateButton(
            self, self.devpref.substitute(propty='IntlkMinSumEn-Sel'))
        self._led_minsumenbl = SiriusLedState(
            self, self.devpref.substitute(propty='IntlkMinSumEn-Sts'))

        self._ld_minsumlim = QLabel('Min.Sum.Thres.[sum count]: ',
                                    self,
                                    alignment=Qt.AlignRight | Qt.AlignVCenter)
        self._sb_minsumlim = SiriusSpinbox(
            self, self.devpref.substitute(propty='IntlkLmtMinSum-SP'))
        self._sb_minsumlim.showStepExponent = False
        self._sb_minsumlim.limitsFromChannel = False
        self._sb_minsumlim.setMinimum(-1e12)
        self._sb_minsumlim.setMaximum(+1e12)
        self._lb_minsumlim = PyDMLabel(
            self, self.devpref.substitute(propty='IntlkLmtMinSum-RB'))

        lay = QGridLayout()
        lay.setAlignment(Qt.AlignCenter)
        lay.addWidget(self._ld_genenbl, 0, 0)
        lay.addWidget(self._sb_genenbl, 0, 1)
        lay.addWidget(self._led_genenbl, 0, 2)
        lay.addWidget(self._ld_genclr, 1, 0)
        lay.addWidget(self._bt_genclr, 1, 1, alignment=Qt.AlignCenter)
        lay.addWidget(self._ld_intlkinst, 2, 0)
        lay.addWidget(self._led_intlkinst, 2, 1)
        lay.addWidget(self._ld_intlkltc, 3, 0)
        lay.addWidget(self._led_intlkltc, 3, 1)
        lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 4, 0)
        lay.addWidget(self._ld_minsumenbl, 5, 0)
        lay.addWidget(self._sb_minsumenbl, 5, 1)
        lay.addWidget(self._led_minsumenbl, 5, 2)
        lay.addWidget(self._ld_minsumlim, 6, 0)
        lay.addWidget(self._sb_minsumlim, 6, 1)
        lay.addWidget(self._lb_minsumlim, 6, 2)
        return lay

    def _setupIntlkTypeLayout(self, intlk):
        unit = 'nm'

        ld_enbl = QLabel('Enable: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignBottom)
        sb_enbl = PyDMStateButton(
            self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sel'))
        led_enbl = SiriusLedState(
            self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sts'))

        ld_clr = QLabel('Reset: ',
                        self,
                        alignment=Qt.AlignRight | Qt.AlignBottom)
        bt_clr = PyDMPushButton(self,
                                init_channel=self.devpref.substitute(
                                    propty='Intlk' + intlk + 'Clr-Sel'),
                                pressValue=1)
        bt_clr.setIcon(qta.icon('fa5s.sync'))
        bt_clr.setObjectName('clr')
        bt_clr.setStyleSheet(
            '#clr{min-width:25px; max-width:25px; icon-size:20px;}')

        ld_minx = QLabel('Min.X Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_minx = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-SP'))
        sb_minx.showStepExponent = False
        sb_minx.limitsFromChannel = False
        sb_minx.setMinimum(-1e9)
        sb_minx.setMaximum(+1e9)
        lb_minx = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-RB'))

        ld_maxx = QLabel('Max.X Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_maxx = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-SP'))
        sb_maxx.showStepExponent = False
        sb_maxx.limitsFromChannel = False
        sb_maxx.setMinimum(-1e9)
        sb_maxx.setMaximum(+1e9)
        lb_maxx = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-RB'))

        ld_miny = QLabel('Min.Y Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_miny = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-SP'))
        sb_miny.showStepExponent = False
        sb_miny.limitsFromChannel = False
        sb_miny.setMinimum(-1e9)
        sb_miny.setMaximum(+1e9)
        lb_miny = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-RB'))

        ld_maxy = QLabel('Max.Y Thres.[' + unit + ']: ',
                         self,
                         alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_maxy = SiriusSpinbox(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-SP'))
        sb_maxy.showStepExponent = False
        sb_maxy.limitsFromChannel = False
        sb_maxy.setMinimum(-1e9)
        sb_maxy.setMaximum(+1e9)
        lb_maxy = PyDMLabel(
            self,
            self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-RB'))

        ld_leglow = QLabel('Smaller', self, alignment=Qt.AlignCenter)
        ld_leghigh = QLabel('Bigger', self, alignment=Qt.AlignCenter)

        ld_legmask = QLabel('<h4>Masked By Enable</h4>',
                            self,
                            alignment=Qt.AlignCenter)
        ld_legmask_any = QLabel('X or Y',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_mask_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'Smaller-Mon'))
        led_mask_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'Bigger-Mon'))

        ld_leginst = QLabel('<h4>Instantaneous</h4>',
                            self,
                            alignment=Qt.AlignCenter)
        ld_leginst_any = QLabel('X or Y',
                                self,
                                alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerAny-Mon'))
        led_inst_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerAny-Mon'))
        ld_leginst_x = QLabel('X',
                              self,
                              alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_xlow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerX-Mon'))
        led_inst_xhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerX-Mon'))
        ld_leginst_y = QLabel('Y',
                              self,
                              alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_inst_ylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerY-Mon'))
        led_inst_yhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerY-Mon'))

        ld_legltc = QLabel('<h4>Latch</h4>', self, alignment=Qt.AlignCenter)
        ld_legltc_any = QLabel('X or Y',
                               self,
                               alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_anylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtc-Mon'))
        led_ltc_anyhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtc-Mon'))
        ld_legltc_x = QLabel('X',
                             self,
                             alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_xlow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk +
                                    'SmallerLtcX-Mon'))
        led_ltc_xhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcX-Mon'))
        ld_legltc_y = QLabel('Y',
                             self,
                             alignment=Qt.AlignRight | Qt.AlignVCenter)
        led_ltc_ylow = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk +
                                    'SmallerLtcY-Mon'))
        led_ltc_yhigh = SiriusLedAlert(
            self,
            self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcY-Mon'))

        lay_mon = QGridLayout()
        lay_mon.setAlignment(Qt.AlignCenter)
        lay_mon.addWidget(ld_leglow, 0, 1)
        lay_mon.addWidget(ld_leghigh, 0, 2)
        lay_mon.addWidget(ld_legmask, 1, 0)
        lay_mon.addWidget(ld_legmask_any, 2, 0)
        lay_mon.addWidget(led_mask_anylow, 2, 1)
        lay_mon.addWidget(led_mask_anyhigh, 2, 2)
        lay_mon.addWidget(ld_leginst, 3, 0)
        lay_mon.addWidget(ld_leginst_any, 4, 0)
        lay_mon.addWidget(led_inst_anylow, 4, 1)
        lay_mon.addWidget(led_inst_anyhigh, 4, 2)
        lay_mon.addWidget(ld_leginst_x, 5, 0)
        lay_mon.addWidget(led_inst_xlow, 5, 1)
        lay_mon.addWidget(led_inst_xhigh, 5, 2)
        lay_mon.addWidget(ld_leginst_y, 6, 0)
        lay_mon.addWidget(led_inst_ylow, 6, 1)
        lay_mon.addWidget(led_inst_yhigh, 6, 2)
        lay_mon.addWidget(ld_legltc, 7, 0)
        lay_mon.addWidget(ld_legltc_any, 8, 0)
        lay_mon.addWidget(led_ltc_anylow, 8, 1)
        lay_mon.addWidget(led_ltc_anyhigh, 8, 2)
        lay_mon.addWidget(ld_legltc_x, 9, 0)
        lay_mon.addWidget(led_ltc_xlow, 9, 1)
        lay_mon.addWidget(led_ltc_xhigh, 9, 2)
        lay_mon.addWidget(ld_legltc_y, 10, 0)
        lay_mon.addWidget(led_ltc_ylow, 10, 1)
        lay_mon.addWidget(led_ltc_yhigh, 10, 2)

        lay = QGridLayout()
        lay.setAlignment(Qt.AlignTop)
        lay.addWidget(ld_enbl, 0, 0)
        lay.addWidget(sb_enbl, 0, 1)
        lay.addWidget(led_enbl, 0, 2)
        lay.addWidget(ld_clr, 1, 0)
        lay.addWidget(bt_clr, 1, 1, alignment=Qt.AlignCenter)
        lay.addWidget(ld_minx, 2, 0)
        lay.addWidget(sb_minx, 2, 1)
        lay.addWidget(lb_minx, 2, 2)
        lay.addWidget(ld_maxx, 3, 0)
        lay.addWidget(sb_maxx, 3, 1)
        lay.addWidget(lb_maxx, 3, 2)
        lay.addWidget(ld_miny, 4, 0)
        lay.addWidget(sb_miny, 4, 1)
        lay.addWidget(lb_miny, 4, 2)
        lay.addWidget(ld_maxy, 5, 0)
        lay.addWidget(sb_maxy, 5, 1)
        lay.addWidget(lb_maxy, 5, 2)
        lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 6, 0)
        lay.addLayout(lay_mon, 7, 0, 1, 3)
        return lay
예제 #25
0
파일: widgets.py 프로젝트: lnls-sirius/hla
class InjSysStbyControlWidget(QWidget):
    """Injection System Control Widget."""

    expand = Signal()

    def __init__(self,
                 parent=None,
                 prefix=VACA_PREFIX,
                 is_summary=False,
                 handler=None):
        """Init."""
        super().__init__(parent)
        self.prefix = prefix
        self._inj_prefix = SiriusPVName('AS-Glob:AP-InjCtrl').substitute(
            prefix=prefix)
        self._is_summary = is_summary
        self._last_comm = None

        self._handler = handler or InjSysStandbyHandler()
        self._icon_off = qta.icon('mdi.power-off')
        self._icon_on = qta.icon('mdi.power-on')
        self._icon_check = qta.icon('fa5s.check')
        self._pixmap_check = self._icon_check.pixmap(
            self._icon_check.actualSize(QSize(16, 16)))
        self._icon_not = qta.icon('fa5s.times')
        self._pixmap_not = self._icon_not.pixmap(
            self._icon_not.actualSize(QSize(16, 16)))

        self.menu = QMenu(self)
        self.rstord_act = self.menu.addAction('Reset Commands')
        self.rstord_act.triggered.connect(self._reset_commands_order)

        if is_summary:
            self._setupSummary()
        else:
            self._setupFull()

        self._ch_cmdsts = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='InjSysCmdSts-Mon'))

        self._ch_off_order_sp = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='InjSysTurnOffOrder-SP'))
        self._ch_off_order_rb = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='InjSysTurnOffOrder-RB'))
        self._ch_on_order_sp = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='InjSysTurnOnOrder-SP'))
        self._ch_on_order_rb = SiriusConnectionSignal(
            self._inj_prefix.substitute(propty='InjSysTurnOnOrder-RB'))
        if not is_summary:
            self._ch_cmdone = SiriusConnectionSignal(
                self._inj_prefix.substitute(propty='InjSysCmdDone-Mon'))

        self._ch_cmdsts.new_value_signal[int].connect(
            self._handle_cmdsts_buttons_enbl)
        self._ch_off_order_rb.new_value_signal[str].connect(
            self._handle_buttons_color)
        self._ch_on_order_rb.new_value_signal[str].connect(
            self._handle_buttons_color)
        self._ch_off_order_rb.new_value_signal[str].connect(
            self._handle_actions_state)
        self._ch_on_order_rb.new_value_signal[str].connect(
            self._handle_actions_state)
        if not is_summary:
            self._ch_cmdone.new_value_signal[str].connect(
                self._handle_cmdone_labels)
            self._ch_cmdsts.new_value_signal[int].connect(
                self._handle_cmdsts_labels)

    def _setupSummary(self):
        self._pb_off = PyDMPushButton(self,
                                      label='',
                                      icon=self._icon_off,
                                      init_channel=self._inj_prefix.substitute(
                                          propty='InjSysTurnOff-Cmd'),
                                      pressValue=0)
        self._pb_off.setObjectName('bt')
        self._pb_off.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;}')
        self._pb_on = PyDMPushButton(self,
                                     label='',
                                     icon=self._icon_on,
                                     init_channel=self._inj_prefix.substitute(
                                         propty='InjSysTurnOn-Cmd'),
                                     pressValue=0)
        self._pb_on.setObjectName('bt')
        self._pb_on.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;}')

        self._led_sts = InjSysStbyLed(self)
        self._led_sts.setStyleSheet(
            'QLed{min-width:1.29em; max-width:1.29em;}')

        lay = QGridLayout(self)
        lay.setAlignment(Qt.AlignCenter)
        lay.addWidget(self._pb_off, 0, 0)
        lay.addWidget(self._pb_on, 0, 1)
        lay.addWidget(self._led_sts, 1, 0, 1, 2, alignment=Qt.AlignCenter)

        # menu
        for cmmtype in ['on', 'off']:
            order = getattr(self._handler, cmmtype + '_order')
            menu = QMenu('Select Turn ' + cmmtype.upper() + ' Commands', self)
            setattr(self, cmmtype + '_menu', menu)
            self.menu.addMenu(menu)
            for cmm in order:
                act = menu.addAction(self._handler.HANDLER_DESC[cmm])
                act.setObjectName(cmm)
                act.setCheckable(True)

    def _setupFull(self):
        lay = QGridLayout(self)

        lay.addWidget(QLabel('Off', self, alignment=Qt.AlignCenter), 0, 1)
        lay.addWidget(QLabel('On', self, alignment=Qt.AlignCenter), 0, 2)
        lay.addWidget(QLabel('Status', self, alignment=Qt.AlignCenter), 0, 3)

        self._checkbox_off = dict()
        self._checkbox_on = dict()
        self._labels_sts = dict()
        for idx, name in enumerate(self._handler.DEF_ON_ORDER):
            cb_off = QCheckBox(self)
            cb_off.setObjectName(name)
            self._checkbox_off[name] = cb_off
            cb_on = QCheckBox(self)
            cb_on.setObjectName(name)
            self._checkbox_on[name] = cb_on
            desc = self._handler.HANDLER_DESC[name]
            splitd = desc.split('(')
            lbl_txt = splitd[0]
            tip = ''
            if len(splitd) > 1:
                lbl_txt, tip = splitd
            lb_dsc = QLabel(lbl_txt, self, alignment=Qt.AlignLeft)
            if tip:
                lb_dsc.setToolTip(tip[:-1])
            lb_sts = QLabel('', self, alignment=Qt.AlignCenter)
            lb_sts.setObjectName(name)
            self._labels_sts[name] = lb_sts
            lay.addWidget(lb_dsc, idx + 1, 0)
            lay.addWidget(cb_off, idx + 1, 1, alignment=Qt.AlignCenter)
            lay.addWidget(cb_on, idx + 1, 2, alignment=Qt.AlignCenter)
            lay.addWidget(lb_sts, idx + 1, 3)

        self._pb_off = PyDMPushButton(self,
                                      label='',
                                      icon=self._icon_off,
                                      init_channel=self._inj_prefix.substitute(
                                          propty='InjSysTurnOff-Cmd'),
                                      pressValue=0)
        self._pb_off.setObjectName('bt')
        self._pb_off.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;}')
        self._pb_on = PyDMPushButton(self,
                                     label='',
                                     icon=self._icon_on,
                                     init_channel=self._inj_prefix.substitute(
                                         propty='InjSysTurnOn-Cmd'),
                                     pressValue=0)
        self._pb_on.setObjectName('bt')
        self._pb_on.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;}')

        self._led_sts = InjSysStbyLed(self)

        lay.addWidget(self._pb_off, 6, 1)
        lay.addWidget(self._pb_on, 6, 2)
        lay.addWidget(self._led_sts, 6, 3)

    @Slot(int)
    def _handle_cmdsts_buttons_enbl(self, new_sts):
        if new_sts == _Const.InjSysCmdSts.On:
            self._pb_on.setEnabled(False)
            self._pb_on.setIcon(
                qta.icon('fa5s.spinner', animation=qta.Spin(self._pb_on)))
            self._pb_off.setEnabled(False)
        elif new_sts == _Const.InjSysCmdSts.Off:
            self._pb_on.setEnabled(False)
            self._pb_off.setEnabled(False)
            self._pb_off.setIcon(
                qta.icon('fa5s.spinner', animation=qta.Spin(self._pb_off)))
        else:
            if not self._pb_on.isEnabled():
                self._pb_on.setEnabled(True)
                self._pb_off.setEnabled(True)
                self._pb_on.setIcon(self._icon_on)
                self._pb_off.setIcon(self._icon_off)

    @Slot(str)
    def _handle_cmdone_labels(self, new_done):
        for name in self._handler.DEF_ON_ORDER:
            lbl = self._labels_sts[name]
            if name in new_done:
                lbl.setPixmap(self._pixmap_check)
            elif self._ch_cmdsts.value == _Const.InjSysCmdSts.Idle:
                lbl.setPixmap(self._pixmap_not)

    @Slot(int)
    def _handle_cmdsts_labels(self, new_sts):
        if new_sts == _Const.InjSysCmdSts.On:
            self._last_comm = new_sts
            for name in self._handler.DEF_ON_ORDER:
                if self._ch_on_order_rb.value is None:
                    break
                lbl = self._labels_sts[name]
                if name in self._ch_on_order_rb.value:
                    icon = qta.icon('fa5s.spinner')
                    pixmap = icon.pixmap(icon.actualSize(QSize(16, 16)))
                    lbl.setPixmap(pixmap)
                else:
                    lbl.setPixmap(QPixmap())
        elif new_sts == _Const.InjSysCmdSts.Off:
            self._last_comm = new_sts
            for name in self._handler.DEF_OFF_ORDER:
                if self._ch_off_order_rb.value is None:
                    break
                lbl = self._labels_sts[name]
                if name in self._ch_off_order_rb.value:
                    icon = qta.icon('fa5s.spinner')
                    pixmap = icon.pixmap(icon.actualSize(QSize(16, 16)))
                    lbl.setPixmap(pixmap)
                else:
                    lbl.setPixmap(QPixmap())
        else:
            done = self._ch_cmdone.value
            for name in self._handler.DEF_ON_ORDER:
                if done is None or name in done:
                    continue
                lbl = self._labels_sts[name]
                if self._last_comm == _Const.InjSysCmdSts.On and \
                        name in self._ch_on_order_rb.value:
                    lbl.setPixmap(self._pixmap_not)
                elif self._last_comm == _Const.InjSysCmdSts.Off and \
                        name in self._ch_off_order_rb.value:
                    lbl.setPixmap(self._pixmap_not)
            self._last_comm = None

    @Slot()
    def _set_commands_order(self):
        if self._is_summary:
            if self.sender() in self.on_menu.actions():
                on_order = [
                    a.objectName() for a in self.on_menu.actions()
                    if a.isChecked()
                ]
                self._ch_on_order_sp.send_value_signal[str].emit(
                    ','.join(on_order))
            elif self.sender() in self.off_menu.actions():
                off_order = [
                    a.objectName() for a in self.off_menu.actions()
                    if a.isChecked()
                ]
                self._ch_off_order_sp.send_value_signal[str].emit(
                    ','.join(off_order))
        else:
            if self.sender() in self._checkbox_on.values():
                checked = [
                    w.objectName() for w in self._checkbox_on.values()
                    if w.isChecked()
                ]
                on_order = [
                    h for h in self._handler.DEF_ON_ORDER if h in checked
                ]
                self._ch_on_order_sp.send_value_signal[str].emit(
                    ','.join(on_order))
            elif self.sender() in self._checkbox_off.values():
                checked = [
                    w.objectName() for w in self._checkbox_off.values()
                    if w.isChecked()
                ]
                off_order = [
                    h for h in self._handler.DEF_OFF_ORDER if h in checked
                ]
                self._ch_off_order_sp.send_value_signal[str].emit(
                    ','.join(off_order))

    @Slot()
    def _reset_commands_order(self):
        self._ch_off_order_sp.send_value_signal[str].emit(','.join(
            self._handler.DEF_OFF_ORDER))
        self._ch_on_order_sp.send_value_signal[str].emit(','.join(
            self._handler.DEF_ON_ORDER))
        if self._is_summary:
            for menu in [self.off_menu, self.on_menu]:
                for act in menu.actions():
                    act.toggled.disconnect()
                    act.setChecked(True)
                    act.toggled.connect(self._set_commands_order)
        else:
            for group in [self._checkbox_off, self._checkbox_on]:
                for wid in group.values():
                    wid.toggled.disconnect()
                    wid.setChecked(True)
                    wid.toggled.connect(self._set_commands_order)

    @Slot()
    def _handle_buttons_color(self):
        off_color = 'yellow' if self._ch_off_order_rb.value != \
            ','.join(self._handler.DEF_OFF_ORDER) else 'white'
        self._pb_off.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;'
            'background-color: ' + off_color + ';}')
        on_color = 'yellow' if self._ch_on_order_rb.value != \
            ','.join(self._handler.DEF_ON_ORDER) else 'white'
        self._pb_on.setStyleSheet(
            '#bt{min-width:25px; max-width:25px; icon-size:20px;'
            'background-color: ' + on_color + ';}')

    @Slot(str)
    def _handle_actions_state(self, sts):
        state = 'on' if 'On' in self.sender().address else 'off'
        channel = getattr(self, '_ch_' + state + '_order_rb')
        if channel.value is None:
            return

        if self._is_summary:
            group = getattr(self, state + '_menu').actions()
        else:
            group = getattr(self, '_checkbox_' + state).values()
        for obj in group:
            obj.disconnect()
            ost = obj.objectName() in sts
            obj.setChecked(ost)
            obj.toggled.connect(self._set_commands_order)

    def contextMenuEvent(self, event):
        """Show a custom context menu."""
        self.menu.popup(self.mapToGlobal(event.pos()))
예제 #26
0
파일: main.py 프로젝트: lnls-sirius/hla
class VLightCamView(QWidget):
    """VLight Cam Viewer."""
    def __init__(self, parent=None, prefix=VACA_PREFIX, section=''):
        """Init."""
        super().__init__(parent)
        self.prefix = prefix
        self.section = section.upper()
        self.device = _PVName(conv_sec_2_device(self.section))
        self.cam_prefix = self.device.substitute(prefix=prefix)
        self.setObjectName(self.section + 'App')
        self.setWindowTitle(self.device + ' View')
        self._setupUi()

    def _setupUi(self):
        label = QLabel('<h2>' + self.device + ' View</h2>',
                       self,
                       alignment=Qt.AlignCenter)

        self.cam_viewer = SiriusImageView(
            parent=self,
            image_channel=self.cam_prefix.substitute(propty='Data-Mon'),
            width_channel=self.cam_prefix.substitute(propty='AOIWidth-RB'),
            offsetx_channel=self.cam_prefix.substitute(propty='AOIOffsetX-RB'),
            offsety_channel=self.cam_prefix.substitute(propty='AOIOffsetY-RB'),
            maxwidth_channel=self.cam_prefix.substitute(
                propty='SensorWidth-Cte'),
            maxheight_channel=self.cam_prefix.substitute(
                propty='SensorHeight-Cte'))
        self.cam_viewer.setObjectName('camview')
        self.cam_viewer.setStyleSheet("""
            #camview{min-width:42em; min-height:32em;}""")

        self.settings = QGroupBox('Settings', self)
        self.settings.setLayout(self._setupSettingsLayout())

        lay = QVBoxLayout(self)
        lay.addWidget(label)
        lay.addWidget(self.cam_viewer)
        lay.addWidget(self.settings)

    def _setupSettingsLayout(self):
        label_CamEnbl = QLabel('Enable:', self)
        hbox_CamEnbl = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='Enbl',
                                            propty_type='enbldisabl',
                                            width=3)

        label_FrameCnt = QLabel('Frame Count:', self)
        hbox_FrameCnt = create_propty_layout(parent=self,
                                             prefix=self.cam_prefix,
                                             propty='FrameCnt',
                                             propty_type='mon')

        label_Conn = QLabel('Connection:', self)
        hbox_Conn = create_propty_layout(parent=self,
                                         prefix=self.cam_prefix,
                                         propty='Connection',
                                         propty_type='mon')

        label_Reset = QLabel('Reset Camera:', self)
        self.pb_dtl = PyDMPushButton(
            label='',
            icon=qta.icon('fa5s.sync'),
            parent=self,
            pressValue=1,
            init_channel=self.cam_prefix.substitute(propty='Rst-Cmd'))
        self.pb_dtl.setObjectName('reset')
        self.pb_dtl.setStyleSheet(
            "#reset{min-width:25px; max-width:25px; icon-size:20px;}")

        flay_sts = QFormLayout()
        flay_sts.setSpacing(6)
        flay_sts.setFormAlignment(Qt.AlignHCenter)
        flay_sts.setLabelAlignment(Qt.AlignRight)
        flay_sts.addRow(label_CamEnbl, hbox_CamEnbl)
        flay_sts.addRow(label_FrameCnt, hbox_FrameCnt)
        flay_sts.addRow(label_Conn, hbox_Conn)
        flay_sts.addRow(label_Reset, self.pb_dtl)

        label_AcqMode = QLabel('Acq. Mode:', self)
        hbox_AcqMode = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='AcqMode',
                                            propty_type='enum')

        label_AcqPeriod = QLabel('Acq. Period [s]:', self)
        hbox_AcqPeriod = create_propty_layout(parent=self,
                                              prefix=self.cam_prefix,
                                              propty='AcqPeriod',
                                              propty_type='sprb')

        label_ExpTime = QLabel('Exp. Time [us]:', self)
        hbox_ExpTime = create_propty_layout(parent=self,
                                            prefix=self.cam_prefix,
                                            propty='ExposureTime',
                                            propty_type='sprb')

        label_Gain = QLabel('Gain [dB]:', self)
        hbox_Gain = create_propty_layout(parent=self,
                                         prefix=self.cam_prefix,
                                         propty='Gain',
                                         propty_type='sprb',
                                         cmd={
                                             'label': '',
                                             'pressValue': 1,
                                             'width': '25',
                                             'height': '25',
                                             'icon': qta.icon('mdi.auto-fix'),
                                             'icon-size': '20',
                                             'toolTip': 'Auto Gain',
                                             'name': 'AutoGain'
                                         })

        flay_ctrl = QFormLayout()
        flay_ctrl.setSpacing(6)
        flay_ctrl.setFormAlignment(Qt.AlignHCenter)
        flay_ctrl.setLabelAlignment(Qt.AlignRight)
        flay_ctrl.addRow(label_AcqMode, hbox_AcqMode)
        flay_ctrl.addRow(label_AcqPeriod, hbox_AcqPeriod)
        flay_ctrl.addRow(label_ExpTime, hbox_ExpTime)
        flay_ctrl.addRow(label_Gain, hbox_Gain)

        self.pb_details = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self)
        self.pb_details.setToolTip('More settings')
        self.pb_details.setObjectName('detail')
        self.pb_details.setStyleSheet(
            "#detail{min-width:25px; max-width:25px; icon-size:20px;}")
        self.pb_details.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Preferred)
        MyWindow = create_window_from_widget(BaslerCamSettings,
                                             title=self.device +
                                             ' Settings Details',
                                             is_main=True)
        util.connect_window(self.pb_details,
                            MyWindow,
                            parent=self,
                            prefix=self.prefix,
                            device=self.device)

        lay = QHBoxLayout()
        lay.setSpacing(20)
        lay.addLayout(flay_sts)
        lay.addLayout(flay_ctrl)
        lay.addWidget(self.pb_details, alignment=Qt.AlignTop)
        return lay