Exemple #1
0
def test_array_signal_send_value(qapp, qtbot):
    sig = Signal(name='my_array', value=np.ones(4))
    register_signal(sig)
    widget = PyDMLineEdit()
    qtbot.addWidget(widget)
    widget.channel = 'sig://my_array'
    qapp.processEvents()
    assert all(widget.value == np.ones(4))
Exemple #2
0
    def _setupFBSettingsWidget(self):
        gbox_settings = QGroupBox('FeedBack Settings', self)

        ld_fbpatt = QLabel('Feedback Mask', self)
        le_fbpatt = PyDMLineEdit(self, self.dev_pref + ':FB_PATTERN')

        ld_cfpatt = QLabel('Alternate Mask', self)
        le_cfpatt = PyDMLineEdit(self, self.dev_pref + ':CF_PATTERN')

        ld_alter_inuse = QLabel('Alternate Set In Use', self)
        led_alter_inuse = SiriusLedState(
            self, self.dev_pref + ':CF_PATTERN_SUB.VALB')

        ld_fbenbl = QLabel('Enable', self)
        pb_fbenbl = PyDMStateButton(self, self.dev_pref + ':FBCTRL')

        ld_coefsel = QLabel('Coeficient Set', self)
        cb_coefsel = PyDMEnumComboBox(self, self.dev_pref + ':SETSEL')

        ld_sftgain = QLabel('Shift Gain', self)
        sb_sftgain = PyDMSpinbox(self, self.dev_pref + ':SHIFTGAIN')
        sb_sftgain.showStepExponent = False

        ld_downspl = QLabel('Downsampling', self)
        sb_downspl = PyDMSpinbox(self, self.dev_pref + ':PROC_DS')
        sb_downspl.showStepExponent = False

        ld_satthrs = QLabel('Sat. Threshold [%]', self)
        sb_satthrs = PyDMSpinbox(self, self.dev_pref + ':SAT_THRESHOLD')
        sb_satthrs.showStepExponent = False

        lay_patt = QGridLayout()
        lay_patt.addWidget(ld_fbpatt, 0, 0)
        lay_patt.addWidget(le_fbpatt, 0, 1)
        lay_patt.addWidget(ld_cfpatt, 1, 0)
        lay_patt.addWidget(le_cfpatt, 1, 1)
        lay_patt.addWidget(ld_alter_inuse, 2, 0)
        lay_patt.addWidget(led_alter_inuse, 2, 1)

        lay = QGridLayout(gbox_settings)
        lay.addWidget(ld_fbenbl, 0, 1)
        lay.addWidget(pb_fbenbl, 0, 2)
        lay.addWidget(ld_downspl, 0, 4)
        lay.addWidget(sb_downspl, 0, 5)
        lay.addWidget(ld_coefsel, 1, 1)
        lay.addWidget(cb_coefsel, 1, 2)
        lay.addWidget(ld_sftgain, 1, 4)
        lay.addWidget(sb_sftgain, 1, 5)
        lay.addWidget(ld_satthrs, 2, 1)
        lay.addWidget(sb_satthrs, 2, 2)
        lay.addLayout(lay_patt, 4, 1, 1, 5)
        lay.setColumnStretch(0, 3)
        lay.setColumnStretch(6, 3)
        lay.setColumnStretch(3, 2)
        lay.setRowStretch(3, 2)
        lay.setRowStretch(5, 3)

        return gbox_settings
Exemple #3
0
def test_array_signal_put_value(qapp, qtbot):
    sig = Signal(name='my_array_write', value=np.ones(4))
    register_signal(sig)
    widget = PyDMLineEdit()
    qtbot.addWidget(widget)
    widget.channel = 'sig://my_array_write'
    widget.send_value_signal[np.ndarray].emit(np.zeros(4))
    qapp.processEvents()
    assert all(sig.value == np.zeros(4))
Exemple #4
0
def test_metadata(qapp, qtbot):
    widget = PyDMLineEdit()
    qtbot.addWidget(widget)
    widget.channel = 'sig://md_signal'
    listener = widget.channels()[0]
    # Create a signal and attach our listener
    sig = RichSignal(name='md_signal', value=1)
    register_signal(sig)
    sig_conn = SignalConnection(listener, 'md_signal')
    qapp.processEvents()
    # Check that metadata the metadata got there
    assert widget.enum_strings == ('a', 'b', 'c')
    assert widget._unit == 'urad'
    assert widget._prec == 2
Exemple #5
0
    def _setupBCSettingsWidget(self):
        gbox_settings = QGroupBox('Bunch Cleaning Settings', self)

        ld_bcenbl = QLabel('Enable', self)
        cb_bcenbl = PyDMStateButton(self, self.dev_pref + ':CLEAN_ENABLE')

        ld_bcamp = QLabel('Amplitude', self)
        sb_bcamp = PyDMSpinbox(self, self.dev_pref + ':CLEAN_AMPL')
        sb_bcamp.showStepExponent = False
        lb_svamp = PyDMLabel(self, self.dev_pref + ':CLEAN_SAVE_AMPL')

        ld_bctune = QLabel('Tune', self)
        sb_bctune = PyDMSpinbox(self, self.dev_pref + ':CLEAN_TUNE')
        sb_bctune.showStepExponent = False
        lb_svfreq = PyDMLabel(self, self.dev_pref + ':CLEAN_SAVE_FREQ')

        ld_bcspan = QLabel('Span', self)
        le_bcspan = PyDMLineEdit(self, self.dev_pref + ':CLEAN_SPAN')
        lb_svspan = PyDMLabel(self, self.dev_pref + ':CLEAN_SAVE_SPAN')

        ld_bcper = QLabel('Period', self)
        le_bcper = PyDMLineEdit(self, self.dev_pref + ':CLEAN_PERIOD')
        lb_svper = PyDMLabel(self, self.dev_pref + ':CLEAN_SAVE_PERIOD')

        ld_bcpatt = QLabel('Mask', self)
        le_bcpatt = PyDMLineEdit(self, self.dev_pref + ':CLEAN_PATTERN')

        lay_clean = QGridLayout(gbox_settings)
        lay_clean.addWidget(QLabel('SAVED VALS.'), 0, 2)

        lay_clean.addWidget(ld_bcamp, 1, 0)
        lay_clean.addWidget(sb_bcamp, 1, 1)
        lay_clean.addWidget(lb_svamp, 1, 2)
        lay_clean.addWidget(ld_bctune, 2, 0)
        lay_clean.addWidget(sb_bctune, 2, 1)
        lay_clean.addWidget(lb_svfreq, 2, 2)
        lay_clean.addWidget(ld_bcspan, 3, 0)
        lay_clean.addWidget(le_bcspan, 3, 1)
        lay_clean.addWidget(lb_svspan, 3, 2)
        lay_clean.addWidget(ld_bcper, 4, 0)
        lay_clean.addWidget(le_bcper, 4, 1)
        lay_clean.addWidget(lb_svper, 4, 2)
        lay_clean.addWidget(ld_bcenbl, 5, 0)
        lay_clean.addWidget(cb_bcenbl, 5, 1)
        lay = QGridLayout()
        lay.addWidget(ld_bcpatt, 0, 0)
        lay.addWidget(le_bcpatt, 0, 1)
        lay_clean.addLayout(lay, 6, 0, 1, 3)
        return gbox_settings
Exemple #6
0
def test_disconnection(qtbot):
    widget = PyDMLineEdit()
    qtbot.addWidget(widget)
    widget.channel = 'sig://invalid'
    listener = widget.channels()[0]
    # Non-existant signal doesn't raise an error
    listener.connect()
    # Create a signal that will raise a TimeoutError
    sig = DeadSignal(name='broken_signal', value=1)
    register_signal(sig)
    listener.address = 'sig://broken_signal'
    # This should fail on the subscribe
    listener.connect()
    # This should fail on the get
    sig.subscribable = True
    _ = SignalConnection(listener, 'broken_signal')
Exemple #7
0
    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
Exemple #8
0
def test_signal_connection(qapp, qtbot):
    # Create a signal and attach our listener
    sig = Signal(name='my_signal', value=1)
    register_signal(sig)
    widget = PyDMLineEdit()
    qtbot.addWidget(widget)
    widget.channel = 'sig://my_signal'
    listener = widget.channels()[0]
    # If PyDMChannel can not connect, we need to connect it ourselves
    # In PyDM > 1.5.0 this will not be neccesary as the widget will be
    # connected after we set the channel name
    if not hasattr(listener, 'connect'):
        pydm.utilities.establish_widget_connections(widget)
    # Check that our widget receives the initial value
    qapp.processEvents()
    assert widget._write_access
    assert widget._connected
    assert widget.value == 1
    # Check that we can push values back to the signal which in turn causes the
    # internal value at the widget to update
    widget.send_value_signal[int].emit(2)
    qapp.processEvents()
    qapp.processEvents()  # Must be called twice. Multiple rounds of signals
    assert sig.get() == 2
    assert widget.value == 2
    # Try changing types
    qapp.processEvents()
    qapp.processEvents()  # Must be called twice. Multiple rounds of signals
    # In PyDM > 1.5.0 we will not need the application to disconnect the
    # widget, but until then we have to check for the attribute
    if hasattr(listener, 'disconnect'):
        listener.disconnect()
    else:
        qapp.close_widget_connections(widget)
    # Check that our signal is disconnected completely and maintains the same
    # value as the signal updates in the background
    sig.put(3)
    qapp.processEvents()
    assert widget.value == 2
    widget.send_value_signal.emit(1)
    qapp.processEvents()
    assert sig.get() == 3
Exemple #9
0
    def add_pv(self, read_pv, name, write_pv=None):
        """
        Add PVs to the SignalPanel

        Parameters
        ---------
        read_pv : pyepics.PV

        name : str
            Name of signal to display

        write_pv : pyepics.PV, optional

        Returns
        -------
        loc : int
            Row number that the signal information was added to in the
            `SignalPanel.layout()``
        """
        logger.debug("Adding PV %s", name)
        # Create label
        label = QLabel(self)
        label.setText(name)
        label_font = QFont()
        label.setFont(label_font)
        # Create signal display
        val_display = QHBoxLayout()
        # Add readback
        ro = TyphonLabel(init_channel=channel_name(read_pv.pvname),
                         parent=self)
        val_display.addWidget(ro)
        # Add our write_pv if available
        if write_pv:
            ch = channel_name(write_pv.pvname)
            # Check whether our device is an enum or not
            if write_pv.enum_strs:
                edit = TyphonComboBox(init_channel=ch, parent=self)
            else:
                logger.debug("Adding LineEdit for %s", name)
                edit = PyDMLineEdit(init_channel=ch, parent=self)
            # Add our control widget to layout
            val_display.addWidget(edit)
        # Add displays to panel
        loc = len(self.pvs)
        self.layout().addWidget(label, loc, 0)
        self.layout().addLayout(val_display, loc, 1)
        # Store signal
        self.pvs[name] = (read_pv, write_pv)
        return loc
Exemple #10
0
    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
Exemple #11
0
    def _setupCoefficientsEditWidget(self, parent=None):
        wid = QGroupBox('Edit Coefficients', parent or self)

        le_coefdesc = PyDMLineEdit(self, self.dev_pref + ':DESC_COEFF')
        graph_coefs = WfmGraph(wid)
        graph_coefs.add_scatter_curve(ychannel=self.dev_pref + ':COEFF',
                                      lineStyle=Qt.SolidLine)

        graph_fftmag = WfmGraph(wid)
        graph_fftmag.setObjectName('graph')
        graph_fftmag.setStyleSheet('#graph{min-height: 12em;}')
        graph_fftmag.setLabel('left', text='Magnitude [dB]')
        graph_fftmag.setLabel('bottom', text='Fractional Freq.')
        graph_fftmag.add_scatter_curve(ychannel=self.dev_pref + ':FTF_MAG',
                                       xchannel=self.dev_pref + ':FTF_FREQ',
                                       color=QColor('blue'),
                                       lineWidth=2,
                                       lineStyle=Qt.SolidLine,
                                       symbolSize=4)
        graph_fftmag.add_scatter_curve(ychannel=self.dev_pref + ':FTF_GTUNE',
                                       xchannel=self.dev_pref + ':FTF_FTUNE',
                                       name='Tune',
                                       color=QColor('red'))

        graph_fftphs = WfmGraph(wid)
        graph_fftphs.setLabel('left', text='Phase [°]')
        graph_fftphs.setLabel('bottom', text='Fractional Freq.')
        graph_fftphs.add_scatter_curve(ychannel=self.dev_pref + ':FTF_PHASE',
                                       xchannel=self.dev_pref + ':FTF_FREQ',
                                       color=QColor('blue'),
                                       lineWidth=2,
                                       lineStyle=Qt.SolidLine,
                                       symbolSize=4)
        graph_fftphs.add_scatter_curve(ychannel=self.dev_pref + ':FTF_PTUNE',
                                       xchannel=self.dev_pref + ':FTF_FTUNE',
                                       name='Tune',
                                       color=QColor('red'))

        ld_fractune = QLabel('<h4> Marker:</h4>',
                             wid,
                             alignment=Qt.AlignLeft | Qt.AlignVCenter)
        ld_ftval = QLabel('Frequency [0-1]',
                          wid,
                          alignment=Qt.AlignRight | Qt.AlignVCenter)
        sb_ftval = PyDMSpinbox(wid, self.dev_pref + ':FTF_TUNE')
        sb_ftval.showStepExponent = False
        ld_ftgain = QLabel('Gain [dB]',
                           wid,
                           alignment=Qt.AlignRight | Qt.AlignVCenter)
        lb_ftgain = Label(wid, self.dev_pref + ':FTF_GTUNE')
        lb_ftgain.precisionFromPV = False
        lb_ftgain.precision = 2
        ld_ftphs = QLabel('Phase [°]',
                          wid,
                          alignment=Qt.AlignRight | Qt.AlignVCenter)
        lb_ftphs = Label(wid, self.dev_pref + ':FTF_PTUNE')
        lb_ftphs.precisionFromPV = False
        lb_ftphs.precision = 2

        lay_genft = QGridLayout()
        lay_genft.setVerticalSpacing(6)
        lay_genft.setHorizontalSpacing(9)
        lay_genft.addWidget(ld_fractune, 0, 0)
        lay_genft.addWidget(ld_ftval, 0, 2)
        lay_genft.addWidget(sb_ftval, 0, 3)
        lay_genft.addWidget(ld_ftgain, 0, 5)
        lay_genft.addWidget(lb_ftgain, 0, 6)
        lay_genft.addWidget(ld_ftphs, 0, 8)
        lay_genft.addWidget(lb_ftphs, 0, 9)
        lay_genft.setRowStretch(1, 2)
        lay_genft.setRowStretch(4, 2)
        lay_genft.setRowStretch(7, 2)
        lay_genft.setRowStretch(10, 2)

        coef_edit_wid = self._setupCoeffSettingsWidget()

        lay = QGridLayout(wid)
        lay.setVerticalSpacing(15)
        lay.addWidget(coef_edit_wid, 0, 0, 2, 1)
        lay.addWidget(le_coefdesc, 0, 1)
        lay.addWidget(graph_coefs, 1, 1)
        lay.addWidget(graph_fftmag, 2, 0)
        lay.addWidget(graph_fftphs, 2, 1)
        lay.addLayout(lay_genft, 3, 0, 1, 2)
        return wid
Exemple #12
0
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)
Exemple #13
0
    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')
Exemple #14
0
    def _setupUi(self):
        if self._driver_num is None:
            ld_drive = QLabel(
                '<h3>Drive Pattern Generator</h3>', self,
                alignment=Qt.AlignCenter)
        else:
            ld_drive = QWidget(self)
            ld_drive.setLayout(QHBoxLayout())
            labd = QLabel(
                f'<h3>Driver {self._driver_num:d}, NCO BITS: </h3>',
                ld_drive, alignment=Qt.AlignRight)
            labd.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            lab = PyDMLabel(
                ld_drive, self.dev_pref+'BITS')
            lab.setStyleSheet('font-size: 13pt; font-weight: bold;')
            lab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            ld_drive.layout().addStretch()
            ld_drive.layout().addWidget(labd)
            ld_drive.layout().addWidget(lab)
            ld_drive.layout().addStretch()

        ld_amp = QLabel('Amplitude', self)
        sb_amp = PyDMSpinbox(self, self.dev_pref+'AMPL')
        sb_amp.showStepExponent = False

        ld_freq = QLabel('Frequency', self)
        sb_freq = PyDMSpinbox(self, self.dev_pref+'FREQ')
        sb_freq.showStepExponent = False

        ld_wav = QLabel('Waveform', self)
        cb_wav = PyDMEnumComboBox(self, self.dev_pref+'WAVEFORM')

        ld_tmod = QLabel('Time MODulation', self)
        cb_tmod = PyDMStateButton(self, self.dev_pref+'MOD')

        ld_span = QLabel('Span', self)
        sb_span = PyDMSpinbox(self, self.dev_pref+'SPAN')
        sb_span.showStepExponent = False

        ld_perd = QLabel('Period', self)
        sb_perd = PyDMSpinbox(self, self.dev_pref+'PERIOD')
        sb_perd.showStepExponent = False

        ld_patt = QLabel('Drive Pattern', self)
        le_patt = PyDMLineEdit(self, self.dev_pref+'PATTERN')

        lb_actfreq = PyDMLabel(self, self.dev_pref+'FREQ_ACT_STRING')
        lb_actspan = PyDMLabel(self, self.dev_pref+'SPAN_ACT_STRING')
        lb_actperd = PyDMLabel(self, self.dev_pref+'PERIOD_ACT')

        lay = QGridLayout(self)
        lay.addWidget(ld_drive, 0, 1, 1, 3)
        lay.addWidget(ld_tmod, 2, 1)
        lay.addWidget(cb_tmod, 2, 2)
        lay.addWidget(ld_amp, 3, 1)
        lay.addWidget(sb_amp, 3, 2)
        lay.addWidget(ld_freq, 4, 1)
        lay.addWidget(lb_actfreq, 4, 3)
        lay.addWidget(sb_freq, 4, 2)
        lay.addWidget(ld_wav, 5, 1)
        lay.addWidget(cb_wav, 5, 2)
        lay.addWidget(ld_span, 6, 1)
        lay.addWidget(sb_span, 6, 2)
        lay.addWidget(lb_actspan, 6, 3)
        lay.addWidget(ld_perd, 7, 1)
        lay.addWidget(sb_perd, 7, 2)
        lay.addWidget(lb_actperd, 7, 3)
        lay.addWidget(ld_patt, 8, 1)
        lay.addWidget(le_patt, 8, 2, 1, 2)
        lay.addItem(QSpacerItem(1, 10), 9, 1)
        lay.addItem(QSpacerItem(1, 10), 13, 1)
        if self._driver_num in {None, 1}:
            pixmap = QPixmap(_os.path.join(
                _os.path.abspath(_os.path.dirname(__file__)), 'drive.png'))
            il_drive = QLabel(self)
            il_drive.setPixmap(pixmap)
            il_drive.setScaledContents(True)
            lay.addWidget(il_drive, 14, 1, 1, 3, alignment=Qt.AlignCenter)
        else:
            wid = QWidget(self)
            wid.setLayout(QHBoxLayout())
            wid.layout().addStretch()

            propty = f':PHTRK_LOOPCTRL{self._driver_num:d}'
            pv = self._prefix + self._device + propty
            lab = SiriusLabel(self, init_channel=pv)
            lab.enum_strings = ['Tracking Off', 'Tracking On']
            lab.displayFormat = lab.DisplayFormat.String
            frame = SiriusFrame(self, pv, is_float=True)
            frame.borderWidth = 2
            frame.add_widget(lab)
            wid.layout().addWidget(frame)
            wid.layout().addStretch()

            lab = QLabel('Track. Freq: ', self)
            wid.layout().addWidget(lab)
            propty = f':PHTRK_FREQ{self._driver_num:d}'
            pv = self._prefix + self._device + propty
            freq = PyDMLabel(self, init_channel=pv)
            wid.layout().addWidget(freq)
            wid.layout().addStretch()

            lay.addWidget(wid, 14, 1, 1, 3)
        lay.setRowStretch(15, 5)
        lay.setColumnStretch(0, 5)
        lay.setColumnStretch(4, 5)
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
Exemple #16
0
    def _setupUi(self):
        gp_mode = WfmGraph(self)
        gp_mode.setStyleSheet('min-height: 10em;')
        gp_mode.setPlotTitle('Modal Amplitudes')
        gp_mode.getAxis('bottom').setLabel('Mode Number')
        gp_mode.getAxis('left').setLabel('CNT')
        gp_mode.add_scatter_curve(ychannel=self.prop_pref + 'MD_MODES',
                                  color=QColor('red'),
                                  lineStyle=Qt.SolidLine)

        gp_spec = WfmGraph(self)
        gp_spec.setStyleSheet('min-height: 10em;')
        gp_spec.setPlotTitle('Single Mode Spectrum')
        gp_spec.getAxis('bottom').setLabel('Frequency (kHz)')
        gp_spec.getAxis('left').setLabel('CNT')
        gp_spec.add_scatter_curve(ychannel=self.prop_pref + 'MD_SPEC',
                                  xchannel=self.prop_pref + 'FREQ',
                                  color=QColor('blue'),
                                  lineStyle=Qt.SolidLine)
        gp_spec.add_marker(name='Marker',
                           xchannel=self.prop_pref + 'MD_PEAKFREQ',
                           ychannel=self.prop_pref + 'MD_PEAK',
                           color=QColor('red'),
                           symbol='o')

        ld_enbl = QLabel('Acq. Enable', self)
        cb_enbl = PyDMStateButton(self, self.prop_pref + 'MD_ENABLE')

        ld_sel = QLabel('Acq. Mode', self)
        cb_sel = PyDMEnumComboBox(self, self.prop_pref + 'MD_SMODE')

        ld_sbnd = QLabel('Sideband', self, alignment=Qt.AlignRight)
        sb_sbnd = PyDMSpinbox(self, self.prop_pref + 'MD_FTUNE')
        sb_sbnd.showStepExponent = False
        sb_sbnd.showUnits = True

        ld_span = QLabel('Span', self, alignment=Qt.AlignRight)
        sb_span = PyDMSpinbox(self, self.prop_pref + 'MD_FSPAN')
        sb_span.showStepExponent = False
        sb_span.showUnits = True

        ld_mode = QLabel('Mode', self, alignment=Qt.AlignRight)
        sb_mode = PyDMSpinbox(self, self.prop_pref + 'MD_MSEL')
        sb_mode.showStepExponent = False

        ld_avg = QLabel('Sample Avg', self, alignment=Qt.AlignRight)
        sb_avg = PyDMSpinbox(self, self.prop_pref + 'MD_AVG')
        sb_avg.showStepExponent = False

        gb_ctrl = QGroupBox('Acquisition control', self)
        lay_ctrl = QGridLayout(gb_ctrl)
        lay_ctrl.addWidget(ld_enbl, 0, 0)
        lay_ctrl.addWidget(cb_enbl, 1, 0)
        lay_ctrl.addWidget(ld_sel, 2, 0)
        lay_ctrl.addWidget(cb_sel, 3, 0)
        lay_ctrl.addWidget(ld_sbnd, 0, 1)
        lay_ctrl.addWidget(sb_sbnd, 0, 2)
        lay_ctrl.addWidget(ld_span, 1, 1)
        lay_ctrl.addWidget(sb_span, 1, 2)
        lay_ctrl.addWidget(ld_mode, 2, 1)
        lay_ctrl.addWidget(sb_mode, 2, 2)
        lay_ctrl.addWidget(ld_avg, 3, 1)
        lay_ctrl.addWidget(sb_avg, 3, 2)

        # Markers
        ld_rng = QLabel('Range (kHz)', self, alignment=Qt.AlignCenter)
        le_low = PyDMLineEdit(self, self.prop_pref + 'MD_SP_LOW')
        le_high = PyDMLineEdit(self, self.prop_pref + 'MD_SP_HIGH')
        cb_mode = PyDMEnumComboBox(self, self.prop_pref + 'MD_SP_SEARCH')

        ld_mnum = QLabel('Mode #', self, alignment=Qt.AlignRight)
        lb_mnum = PyDMLabel(self, self.prop_pref + 'MD_MAXMODE')

        ld_mamp = QLabel('Mode Amp.', self, alignment=Qt.AlignRight)
        lb_mamp = PyDMLabel(self, self.prop_pref + 'MD_MAXVAL')

        ld_peak = QLabel('Value', self, alignment=Qt.AlignRight)
        lb_peak = PyDMLabel(self, self.prop_pref + 'MD_PEAK')

        ld_pfrq = QLabel('Freq', self, alignment=Qt.AlignRight)
        lb_pfrq = PyDMLabel(self, self.prop_pref + 'MD_PEAKFREQ')
        lb_pfrq.showUnits = True

        ld_tune = QLabel('Tune', self, alignment=Qt.AlignRight)
        lb_tune = PyDMLabel(self, self.prop_pref + 'MD_PEAKTUNE')

        gb_mark = QGroupBox('Marker', self)
        lay_mark = QGridLayout(gb_mark)
        lay_mark.addWidget(ld_rng, 0, 0)
        lay_mark.addWidget(le_low, 1, 0)
        lay_mark.addWidget(le_high, 2, 0)
        lay_mark.addWidget(cb_mode, 3, 0)
        lay_mark.addWidget(ld_mnum, 0, 1)
        lay_mark.addWidget(lb_mnum, 0, 2)
        lay_mark.addWidget(ld_mamp, 1, 1)
        lay_mark.addWidget(lb_mamp, 1, 2)
        lay_mark.addWidget(ld_peak, 2, 1)
        lay_mark.addWidget(lb_peak, 2, 2)
        lay_mark.addWidget(ld_pfrq, 3, 1)
        lay_mark.addWidget(lb_pfrq, 3, 2)
        lay_mark.addWidget(ld_tune, 4, 1)
        lay_mark.addWidget(lb_tune, 4, 2)

        ld_name = QLabel('<h2>' + self.acq_type + ' Modal Analysis</h2>',
                         self,
                         alignment=Qt.AlignCenter)

        self.setLayout(QHBoxLayout())
        wid = QWidget(self)
        self.layout().addWidget(wid)
        set_bbb_color(wid, self._device)
        lay = QGridLayout(wid)
        lay.addWidget(ld_name, 0, 0, 1, 2)
        lay.addWidget(gp_mode, 1, 0, 1, 2)
        lay.addWidget(gp_spec, 2, 0, 1, 2)
        lay.addWidget(gb_ctrl, 3, 0)
        lay.addWidget(gb_mark, 3, 1)
        lay.setRowStretch(1, 2)
        lay.setRowStretch(2, 2)
Exemple #17
0
    def __init__(self, parent=None, init_channel=None):
        PyDMLineEdit.__init__(self, parent=parent, init_channel=init_channel)

        self.textEdited.connect(self.text_edited)
        self._dirty = False
Exemple #18
0
    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
Exemple #19
0
    def _setupWaveformsWidget(self):
        gp_mean = WfmGraph(self)
        gp_mean.setPlotTitle('Mean')
        gp_mean.getAxis('bottom').setLabel('Bunch number')
        gp_mean.getAxis('left').setLabel('CNT')
        gp_mean.add_scatter_curve(
            ychannel=self.dev_pref + ':' + self.TYPE + '_MEAN',
            xchannel=self.dev_pref + ':' + self.TYPE + '_XSC',
            color=QColor('red'),
            lineStyle=Qt.SolidLine)

        gp_maxrms = WfmGraph(self)
        gp_maxrms.setPlotTitle('Max RMS Channel (filtered)')
        gp_maxrms.getAxis('bottom').setLabel('Time (ms)')
        gp_maxrms.getAxis('left').setLabel('CNT')
        gp_maxrms.add_scatter_curve(
            ychannel=self.dev_pref + ':' + self.TYPE + '_MAXRMS',
            xchannel=self.dev_pref + ':' + self.TYPE + '_TSC',
            color=QColor('blue'),
            lineStyle=Qt.SolidLine)

        gp_rms = WfmGraph(self)
        gp_rms.setPlotTitle('RMS')
        gp_rms.getAxis('bottom').setLabel('Bunch number')
        gp_rms.getAxis('left').setLabel('CNT')
        gp_rms.add_scatter_curve(
            ychannel=self.dev_pref + ':' + self.TYPE + '_RMS',
            xchannel=self.dev_pref + ':' + self.TYPE + '_XSC',
            color=QColor('green'),
            lineStyle=Qt.SolidLine)

        gp_avgspe = WfmGraph(self)
        gp_avgspe.setPlotTitle('Average spectrum')
        gp_avgspe.getAxis('bottom').setLabel('Frequency (kHz)')
        gp_avgspe.getAxis('left').setLabel('dB')
        gp_avgspe.add_scatter_curve(
            ychannel=self.dev_pref + ':' + self.TYPE + '_SPEC',
            xchannel=self.dev_pref + ':' + self.TYPE + '_FREQ',
            color=QColor('blue'),
            lineStyle=Qt.SolidLine)
        gp_avgspe.add_marker(
            name='Marker 1',
            xchannel=self.dev_pref + ':' + self.TYPE + '_PEAKFREQ1',
            ychannel=self.dev_pref + ':' + self.TYPE + '_PEAK1',
            color=QColor('red'),
            symbol='o')
        gp_avgspe.add_marker(
            name='Marker 2',
            xchannel=self.dev_pref + ':' + self.TYPE + '_PEAKFREQ2',
            ychannel=self.dev_pref + ':' + self.TYPE + '_PEAK2',
            color=QColor('magenta'),
            symbol='s')

        lay_graph = QGridLayout()
        lay_graph.setContentsMargins(9, 9, 9, 9)
        lay_graph.addWidget(gp_mean, 0, 0)
        lay_graph.addWidget(gp_maxrms, 0, 1)
        lay_graph.addWidget(gp_rms, 1, 0)
        lay_graph.addWidget(gp_avgspe, 1, 1)

        ld_acqenbl = QLabel('Acq. Enable', self)
        cb_acqenbl = PyDMStateButton(
            self, self.dev_pref + ':' + self.TYPE + '_ACQ_EN')

        ld_acqsing = QLabel('Acq. Mode', self)
        cb_acqsing = PyDMEnumComboBox(
            self, self.dev_pref + ':' + self.TYPE + '_ACQ_SINGLE')

        ld_mean = QLabel('Mean', self, alignment=Qt.AlignCenter)
        lb_mean = PyDMLabel(self, self.dev_pref + ':' + self.TYPE + '_MEANVAL')

        ld_rms = QLabel('RMS', self, alignment=Qt.AlignCenter)
        lb_rms = PyDMLabel(self, self.dev_pref + ':' + self.TYPE + '_RMSVAL')

        ld_ampp2p = QLabel('Amp P-P', self, alignment=Qt.AlignCenter)
        lb_ampp2p = PyDMLabel(self,
                              self.dev_pref + ':' + self.TYPE + '_AMP_PP')

        ld_maxrms = QLabel('Max RMS', self, alignment=Qt.AlignCenter)
        lb_maxrms = PyDMLabel(self,
                              self.dev_pref + ':' + self.TYPE + '_MAXRMSVAL')

        ld_bunpatt = QLabel('Bunch\npattern', self)
        le_bunpatt = PyDMLineEdit(
            self, self.dev_pref + ':' + self.TYPE + '_ACQ_PATTERN')

        ld_avg = QLabel('Sample Avg', self)
        sb_avg = PyDMSpinbox(self, self.dev_pref + ':' + self.TYPE + '_SP_AVG')
        sb_avg.showStepExponent = False

        gbox_acqctrl = QGroupBox('Acquisition control', self)
        lay_acqctrl = QGridLayout(gbox_acqctrl)
        lay_acqctrl.addWidget(ld_acqenbl, 0, 0)
        lay_acqctrl.addWidget(cb_acqenbl, 0, 1)
        lay_acqctrl.addWidget(ld_acqsing, 1, 0)
        lay_acqctrl.addWidget(cb_acqsing, 1, 1)
        lay_acqctrl.addWidget(ld_avg, 2, 0)
        lay_acqctrl.addWidget(sb_avg, 2, 1)
        lay_acqctrl.addItem(QSpacerItem(15, 1, QSzPlcy.Fixed, QSzPlcy.Ignored),
                            0, 2, 3, 1)
        lay_acqctrl.addWidget(ld_mean, 0, 3)
        lay_acqctrl.addWidget(lb_mean, 0, 4)
        lay_acqctrl.addWidget(ld_ampp2p, 0, 5)
        lay_acqctrl.addWidget(lb_ampp2p, 0, 6)
        lay_acqctrl.addWidget(ld_rms, 1, 3)
        lay_acqctrl.addWidget(lb_rms, 1, 4)
        lay_acqctrl.addWidget(ld_maxrms, 1, 5)
        lay_acqctrl.addWidget(lb_maxrms, 1, 6)
        lay_acqctrl.addWidget(ld_bunpatt, 2, 3)
        lay_acqctrl.addWidget(le_bunpatt, 2, 4, 1, 3)

        # Markers
        ld_mk1 = QLabel('1', self, alignment=Qt.AlignCenter)
        ld_mk2 = QLabel('2', self, alignment=Qt.AlignCenter)
        ld_span = QLabel('Span (kHz)', self, alignment=Qt.AlignCenter)
        ld_mode = QLabel('Mode', self, alignment=Qt.AlignCenter)
        ld_val = QLabel('Value', self, alignment=Qt.AlignCenter)
        ld_pfrq = QLabel('Freq', self, alignment=Qt.AlignCenter)
        ld_tune = QLabel('Tune', self, alignment=Qt.AlignCenter)

        le_low1 = PyDMLineEdit(self,
                               self.dev_pref + ':' + self.TYPE + '_SP_LOW1')
        le_high1 = PyDMLineEdit(self,
                                self.dev_pref + ':' + self.TYPE + '_SP_HIGH1')
        cb_mode1 = PyDMEnumComboBox(
            self, self.dev_pref + ':' + self.TYPE + '_SP_SEARCH1')
        lb_peak1 = PyDMLabel(self, self.dev_pref + ':' + self.TYPE + '_PEAK1')
        lb_peak1.showUnits = True
        lb_pfrq1 = PyDMLabel(self,
                             self.dev_pref + ':' + self.TYPE + '_PEAKFREQ1')
        lb_pfrq1.showUnits = True
        lb_tune1 = PyDMLabel(self,
                             self.dev_pref + ':' + self.TYPE + '_PEAKTUNE1')

        le_low2 = PyDMLineEdit(self,
                               self.dev_pref + ':' + self.TYPE + '_SP_LOW2')
        le_high2 = PyDMLineEdit(self,
                                self.dev_pref + ':' + self.TYPE + '_SP_HIGH2')
        cb_mode2 = PyDMEnumComboBox(
            self, self.dev_pref + ':' + self.TYPE + '_SP_SEARCH2')
        lb_peak2 = PyDMLabel(self, self.dev_pref + ':' + self.TYPE + '_PEAK2')
        lb_peak2.showUnits = True
        lb_pfrq2 = PyDMLabel(self,
                             self.dev_pref + ':' + self.TYPE + '_PEAKFREQ2')
        lb_pfrq2.showUnits = True
        lb_tune2 = PyDMLabel(self,
                             self.dev_pref + ':' + self.TYPE + '_PEAKTUNE2')

        gbox_mark = QGroupBox('Markers', self)
        lay_mark = QGridLayout(gbox_mark)
        lay_mark.addWidget(ld_span, 0, 1, 1, 2)
        lay_mark.addWidget(ld_mode, 0, 3)
        lay_mark.addWidget(ld_val, 0, 4)
        lay_mark.addWidget(ld_pfrq, 0, 5)
        lay_mark.addWidget(ld_tune, 0, 6)
        lay_mark.addWidget(ld_mk1, 1, 0)
        lay_mark.addWidget(le_low1, 1, 1)
        lay_mark.addWidget(le_high1, 1, 2)
        lay_mark.addWidget(cb_mode1, 1, 3)
        lay_mark.addWidget(lb_peak1, 1, 4)
        lay_mark.addWidget(lb_pfrq1, 1, 5)
        lay_mark.addWidget(lb_tune1, 1, 6)
        lay_mark.addWidget(ld_mk2, 2, 0)
        lay_mark.addWidget(le_low2, 2, 1)
        lay_mark.addWidget(le_high2, 2, 2)
        lay_mark.addWidget(cb_mode2, 2, 3)
        lay_mark.addWidget(lb_peak2, 2, 4)
        lay_mark.addWidget(lb_pfrq2, 2, 5)
        lay_mark.addWidget(lb_tune2, 2, 6)

        wid = QWidget()
        lay = QGridLayout(wid)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addLayout(lay_graph, 0, 0, 1, 2)
        lay.addWidget(gbox_acqctrl, 1, 0)
        lay.addWidget(gbox_mark, 1, 1)
        lay.setRowStretch(0, 5)
        lay.setRowStretch(1, 1)
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 1)
        return wid
Exemple #20
0
class SITuneMarkerDetails(SiriusMainWindow):
    """SI Tune Marker Details."""
    def __init__(self,
                 parent=None,
                 prefix='',
                 orientation='',
                 index=1,
                 isdelta=False,
                 background=None):
        super().__init__(parent)
        self.prefix = prefix
        self.orientation = orientation
        self.idx = str(index)
        self.mtyp = 'D' if isdelta else ''
        self.dev = SiriusPVName('SI-Glob:DI-TuneProc-O')
        self.dev = self.dev.substitute(prefix=prefix, idx=self.orientation)
        self.background = background
        self.title = (self.dev.device_name +
                      (' ' if self.mtyp == '' else ' Delta ') + 'Marker ' +
                      self.idx + ' Settings')
        self.setWindowTitle(self.title)
        self.setObjectName('SIApp')
        self._setupUi()
        self.setFocusPolicy(Qt.StrongFocus)

    def _setupUi(self):
        cw = QWidget(self)
        self.setCentralWidget(cw)
        lay = QFormLayout(cw)
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)

        # title
        self.title_label = QLabel('<h3>' + self.title + '<h3>',
                                  self,
                                  alignment=Qt.AlignCenter)
        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)
        lay.addRow(self.title_label)

        label_enbl = QLabel('Enable: ', self)
        self.bt_enbl = PyDMStateButton(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'Mark' + self.idx +
                                '-Sel'))
        self.bt_enbl.shape = 1
        self.led_enbl = SiriusLedState(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'Mark' + self.idx +
                                '-Sts'))
        hbox_enbl = QHBoxLayout()
        hbox_enbl.addWidget(self.bt_enbl)
        hbox_enbl.addWidget(self.led_enbl)
        lay.addRow(label_enbl, hbox_enbl)

        label_enblautomax = QLabel('Auto Max Peak: ', self)
        ch_enblautomax = self.dev.substitute(propty='Enbl' + self.mtyp +
                                             'MaxAuto' + self.idx + '-Sel')
        self.enblAutoMaxChannel = SiriusConnectionSignal(ch_enblautomax)
        self.enblAutoMaxChannel.new_value_signal[int].connect(
            self._handle_values_visibility)
        self.bt_enblautomax = PyDMStateButton(self, ch_enblautomax)
        self.bt_enblautomax.shape = 1
        self.led_enblautomax = SiriusLedState(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'MaxAuto' +
                                self.idx + '-Sts'))
        hbox_enblautomax = QHBoxLayout()
        hbox_enblautomax.addWidget(self.bt_enblautomax)
        hbox_enblautomax.addWidget(self.led_enblautomax)
        lay.addRow(label_enblautomax, hbox_enblautomax)

        label_x = QLabel(' X: ', self)
        self.sb_x = PyDMLineEdit(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkX' + self.idx + '-SP'))
        self.lb_x = PyDMLabel(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkX' + self.idx + '-RB'))
        hbox_x = QHBoxLayout()
        hbox_x.addWidget(self.sb_x)
        hbox_x.addWidget(self.lb_x)
        lay.addRow(label_x, hbox_x)

        label_y = QLabel(' Y: ', self)
        self.lb_y = PyDMLabel(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkY' + self.idx +
                                '-Mon'))
        hbox_y = QHBoxLayout()
        hbox_y.addWidget(self.lb_y)
        if self.mtyp == 'D':
            self.lb_dynamicY = PyDMLabel(
                self,
                self.dev.substitute(propty='DynamicDX' + self.idx + '-Mon'))
            self.lb_dynamicY.setVisible(False)
            hbox_y.addWidget(self.lb_dynamicY)
        lay.addRow(label_y, hbox_y)

        self.pb_max = PyDMPushButton(
            parent=self,
            label='Mark Max Peak',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMax' +
                                             self.idx + '-Cmd'))
        self.pb_maxnext = PyDMPushButton(
            parent=self,
            label='Mark Max Next',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMaxNext' +
                                             self.idx + '-Cmd'))
        self.pb_maxright = PyDMPushButton(
            parent=self,
            label='Mark Max Right',
            pressValue=1,
            init_channel=self.dev.substitute(
                propty=self.mtyp + 'MarkMaxRight' + self.idx + '-Cmd'))
        self.pb_maxleft = PyDMPushButton(
            parent=self,
            label='Mark Max Left',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMaxLeft' +
                                             self.idx + '-Cmd'))
        vbox_cmd = QVBoxLayout()
        vbox_cmd.addWidget(self.pb_max)
        vbox_cmd.addWidget(self.pb_maxnext)
        vbox_cmd.addWidget(self.pb_maxright)
        vbox_cmd.addWidget(self.pb_maxleft)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(vbox_cmd)

        if self.mtyp == '' and self.idx == '1':
            lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))

            label_enblautomin = QLabel('Enable Auto Min: ', self)
            self.bt_enblautomin = PyDMStateButton(
                self, self.dev.substitute(propty='EnblMinAuto-Sel'))
            self.bt_enblautomin.shape = 1
            self.led_enblautomin = SiriusLedState(
                self, self.dev.substitute(propty='EnblMinAuto-Sts'))
            hbox_enblautomin = QHBoxLayout()
            hbox_enblautomin.addWidget(self.bt_enblautomin)
            hbox_enblautomin.addWidget(self.led_enblautomin)
            lay.addRow(label_enblautomin, hbox_enblautomin)

            label_enbllimit = QLabel('Enable Mark Limit: ', self)
            self.bt_enbllimit = PyDMStateButton(
                self, self.dev.substitute(propty='EnblMarkLimit-Sel'))
            self.bt_enbllimit.shape = 1
            self.led_enbllimit = SiriusLedState(
                self, self.dev.substitute(propty='EnblMarkLimit-Sts'))
            hbox_enbllimit = QHBoxLayout()
            hbox_enbllimit.addWidget(self.bt_enbllimit)
            hbox_enbllimit.addWidget(self.led_enbllimit)
            lay.addRow(label_enbllimit, hbox_enbllimit)

            label_limright = QLabel('Mark Limit Right: ', self)
            self.sb_limright = PyDMLineEdit(
                self, self.dev.substitute(propty='MarkLimitRight-SP'))
            self.lb_limright = PyDMLabel(
                self, self.dev.substitute(propty='MarkLimitRight-RB'))
            hbox_limright = QHBoxLayout()
            hbox_limright.addWidget(self.sb_limright)
            hbox_limright.addWidget(self.lb_limright)
            lay.addRow(label_limright, hbox_limright)

            label_limleft = QLabel('Mark Limit Left: ', self)
            self.sb_limleft = PyDMLineEdit(
                self, self.dev.substitute(propty='MarkLimitLeft-SP'))
            self.lb_limleft = PyDMLabel(
                self, self.dev.substitute(propty='MarkLimitLeft-RB'))
            hbox_limleft = QHBoxLayout()
            hbox_limleft.addWidget(self.sb_limleft)
            hbox_limleft.addWidget(self.lb_limleft)
            lay.addRow(label_limleft, hbox_limleft)

        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 _handle_values_visibility(self, value):
        self.sb_x.setVisible(not value)
        if self.mtyp == 'D':
            self.lb_y.setVisible(not value)
            self.lb_dynamicY.setVisible(value)
Exemple #21
0
    def _setupWaveformsWidget(self):
        gp_bunsig = WfmGraph(self)
        gp_bunsig.setPlotTitle('Bunch Signal')
        gp_bunsig.getAxis('bottom').setLabel('Time (ms)')
        gp_bunsig.getAxis('left').setLabel('CNT')
        gp_bunsig.add_scatter_curve(ychannel=self.dev_pref + ':SB_RAW',
                                    xchannel=self.dev_pref + ':SB_TSC',
                                    color=QColor('blue'),
                                    lineStyle=Qt.SolidLine,
                                    nchannel=self.dev_pref + ':SB_RAW_SAMPLES')

        gp_mag = WfmGraph(self)
        gp_mag.setPlotTitle('Magnitude')
        gp_mag.getAxis('bottom').setLabel('Frequency (kHz)')
        gp_mag.getAxis('left').setLabel('dB')
        gp_mag.add_scatter_curve(ychannel=self.dev_pref + ':SB_MAG',
                                 xchannel=self.dev_pref + ':SB_FREQ',
                                 color=QColor('blue'),
                                 lineStyle=Qt.SolidLine)
        gp_mag.add_marker(self.dev_pref + ':SB_PEAKFREQ1',
                          self.dev_pref + ':SB_PEAK1',
                          name='Mag',
                          color=QColor('magenta'),
                          symbol='o')

        gp_phs = WfmGraph(self)
        gp_phs.setPlotTitle('Phase')
        gp_phs.getAxis('bottom').setLabel('Frequency (kHz)')
        gp_phs.getAxis('left').setLabel('deg')
        gp_phs.add_scatter_curve(ychannel=self.dev_pref + ':SB_PHASE',
                                 xchannel=self.dev_pref + ':SB_FREQ',
                                 color=QColor('blue'),
                                 lineStyle=Qt.SolidLine)
        gp_phs.add_marker(self.dev_pref + ':SB_PEAKFREQ1',
                          self.dev_pref + ':SB_PHASE1',
                          name='Phs',
                          color=QColor('magenta'),
                          symbol='o')

        ld_tfenbl = QLabel('Transfer Function Enable', self)
        cb_tfenbl = PyDMEnumComboBox(self, self.dev_pref + ':SB_TF_ENABLE')

        ld_nrptsfft = QLabel('Number of points for FFT/Window', self)
        cb_nrptsfft = PyDMEnumComboBox(self, self.dev_pref + ':SB_NFFT')

        ld_fftovlap = QLabel('Overlap (Autolimited to NFFT/2)', self)
        cb_fftovlap = PyDMEnumComboBox(self, self.dev_pref + ':SB_NOVERLAP')

        ld_delaycal = QLabel('Delay Cal [ns]', self)
        le_delaycal = PyDMLineEdit(self, self.dev_pref + ':SB_DEL_CAL')

        ld_avg = QLabel('Averaging', self)
        sb_avg = PyDMSpinbox(self, self.dev_pref + ':SB_SP_AVG')
        sb_avg.showStepExponent = False

        gbox_fftsett = QGroupBox(self)
        lay_fftsett = QGridLayout(gbox_fftsett)
        lay_fftsett.addWidget(ld_tfenbl, 0, 0)
        lay_fftsett.addWidget(cb_tfenbl, 0, 1)
        lay_fftsett.addWidget(ld_nrptsfft, 1, 0)
        lay_fftsett.addWidget(cb_nrptsfft, 1, 1)
        lay_fftsett.addWidget(ld_fftovlap, 2, 0)
        lay_fftsett.addWidget(cb_fftovlap, 2, 1)
        lay_fftsett.addWidget(ld_delaycal, 3, 0)
        lay_fftsett.addWidget(le_delaycal, 3, 1)
        lay_fftsett.addWidget(ld_avg, 4, 0)
        lay_fftsett.addWidget(sb_avg, 4, 1)

        lay_graph = QGridLayout()
        lay_graph.addWidget(gp_bunsig, 0, 0)
        lay_graph.addWidget(gp_mag, 0, 1)
        lay_graph.addWidget(gbox_fftsett, 1, 0)
        lay_graph.addWidget(gp_phs, 1, 1)

        ld_acqenbl = QLabel('Acq. Enable', self)
        cb_acqenbl = PyDMStateButton(self, self.dev_pref + ':SB_ACQ_EN')

        ld_acqsing = QLabel('Acq. Mode', self)
        cb_acqsing = PyDMEnumComboBox(self, self.dev_pref + ':SB_ACQ_SINGLE')

        ld_mean = QLabel('Mean', self, alignment=Qt.AlignCenter)
        lb_mean = PyDMLabel(self, self.dev_pref + ':SB_MEANVAL')

        ld_rms = QLabel('RMS', self, alignment=Qt.AlignCenter)
        lb_rms = PyDMLabel(self, self.dev_pref + ':SB_RMSVAL')

        ld_ampp2p = QLabel('Amp P-P', self, alignment=Qt.AlignCenter)
        lb_ampp2p = PyDMLabel(self, self.dev_pref + ':SB_AMP_PP')

        ld_bunid = QLabel('Bunch ID', self, alignment=Qt.AlignCenter)
        lb_bunid = PyDMLabel(self, self.dev_pref + ':SB_RAW_BUNCH_ID')

        gbox_acqctrl = QGroupBox('Acquisition control', self)
        lay_acqctrl = QGridLayout(gbox_acqctrl)
        lay_acqctrl.addWidget(ld_acqenbl, 0, 0)
        lay_acqctrl.addWidget(cb_acqenbl, 0, 1)
        lay_acqctrl.addWidget(ld_acqsing, 1, 0)
        lay_acqctrl.addWidget(cb_acqsing, 1, 1)
        lay_acqctrl.addItem(QSpacerItem(15, 1, QSzPlcy.Fixed, QSzPlcy.Ignored),
                            0, 2, 2, 1)
        lay_acqctrl.addWidget(ld_mean, 0, 3)
        lay_acqctrl.addWidget(lb_mean, 0, 4)
        lay_acqctrl.addWidget(ld_ampp2p, 0, 5)
        lay_acqctrl.addWidget(lb_ampp2p, 0, 6)
        lay_acqctrl.addWidget(ld_rms, 1, 3)
        lay_acqctrl.addWidget(lb_rms, 1, 4)
        lay_acqctrl.addWidget(ld_bunid, 1, 5)
        lay_acqctrl.addWidget(lb_bunid, 1, 6)

        # Marker
        ld_mkspan = QLabel('Span (kHz)', self, alignment=Qt.AlignCenter)
        le_mklow = PyDMLineEdit(self, self.dev_pref + ':SB_SP_LOW1')
        le_mkhigh = PyDMLineEdit(self, self.dev_pref + ':SB_SP_HIGH1')

        ld_mkmode = QLabel('Mode', self, alignment=Qt.AlignCenter)
        cb_mkmode = PyDMEnumComboBox(self, self.dev_pref + ':SB_SP_SEARCH1')

        ld_mkfreq = QLabel('Frequency', self, alignment=Qt.AlignCenter)
        lb_mkfreq = PyDMLabel(self, self.dev_pref + ':SB_PEAKFREQ1')
        lb_mkfreq.showUnits = True

        ld_mktune = QLabel('Tune', self, alignment=Qt.AlignCenter)
        lb_mktune = PyDMLabel(self, self.dev_pref + ':SB_PEAKTUNE1')
        lb_mktune.showUnits = True

        ld_mkmag = QLabel('Magnitude', self, alignment=Qt.AlignCenter)
        lb_mkmag = PyDMLabel(self, self.dev_pref + ':SB_PEAK1')
        lb_mkmag.showUnits = True

        ld_mkphs = QLabel('Phase', self, alignment=Qt.AlignCenter)
        lb_mkphs = PyDMLabel(self, self.dev_pref + ':SB_PHASE1')
        lb_mkphs.showUnits = True

        lay = QGridLayout()
        lay.addWidget(ld_mkfreq, 1, 0)
        lay.addWidget(lb_mkfreq, 2, 0)
        lay.addWidget(ld_mktune, 1, 1)
        lay.addWidget(lb_mktune, 2, 1)
        lay.addWidget(ld_mkmag, 1, 2)
        lay.addWidget(lb_mkmag, 2, 2)
        lay.addWidget(ld_mkphs, 1, 3)
        lay.addWidget(lb_mkphs, 2, 3)
        lay.setRowStretch(0, 2)
        lay.setRowStretch(3, 2)

        gbox_mk = QGroupBox('Marker', self)
        lay_mk = QGridLayout(gbox_mk)
        lay_mk.addWidget(ld_mkmode, 0, 0)
        lay_mk.addWidget(cb_mkmode, 0, 1)
        lay_mk.addWidget(ld_mkspan, 1, 0, 1, 2)
        lay_mk.addWidget(le_mklow, 2, 0)
        lay_mk.addWidget(le_mkhigh, 2, 1)
        lay_mk.addLayout(lay, 0, 2, 3, 1)

        wid = QWidget()
        lay = QGridLayout(wid)
        lay.addLayout(lay_graph, 0, 0, 1, 2)
        lay.addWidget(gbox_acqctrl, 1, 0)
        lay.addWidget(gbox_mk, 1, 1)
        lay.setRowStretch(0, 5)
        lay.setRowStretch(1, 1)
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 1)
        return wid
Exemple #22
0
    def _setupUi(self):
        cw = QWidget(self)
        self.setCentralWidget(cw)
        lay = QFormLayout(cw)
        lay.setLabelAlignment(Qt.AlignRight)
        lay.setFormAlignment(Qt.AlignCenter)

        # title
        self.title_label = QLabel('<h3>' + self.title + '<h3>',
                                  self,
                                  alignment=Qt.AlignCenter)
        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)
        lay.addRow(self.title_label)

        label_enbl = QLabel('Enable: ', self)
        self.bt_enbl = PyDMStateButton(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'Mark' + self.idx +
                                '-Sel'))
        self.bt_enbl.shape = 1
        self.led_enbl = SiriusLedState(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'Mark' + self.idx +
                                '-Sts'))
        hbox_enbl = QHBoxLayout()
        hbox_enbl.addWidget(self.bt_enbl)
        hbox_enbl.addWidget(self.led_enbl)
        lay.addRow(label_enbl, hbox_enbl)

        label_enblautomax = QLabel('Auto Max Peak: ', self)
        ch_enblautomax = self.dev.substitute(propty='Enbl' + self.mtyp +
                                             'MaxAuto' + self.idx + '-Sel')
        self.enblAutoMaxChannel = SiriusConnectionSignal(ch_enblautomax)
        self.enblAutoMaxChannel.new_value_signal[int].connect(
            self._handle_values_visibility)
        self.bt_enblautomax = PyDMStateButton(self, ch_enblautomax)
        self.bt_enblautomax.shape = 1
        self.led_enblautomax = SiriusLedState(
            self,
            self.dev.substitute(propty='Enbl' + self.mtyp + 'MaxAuto' +
                                self.idx + '-Sts'))
        hbox_enblautomax = QHBoxLayout()
        hbox_enblautomax.addWidget(self.bt_enblautomax)
        hbox_enblautomax.addWidget(self.led_enblautomax)
        lay.addRow(label_enblautomax, hbox_enblautomax)

        label_x = QLabel(' X: ', self)
        self.sb_x = PyDMLineEdit(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkX' + self.idx + '-SP'))
        self.lb_x = PyDMLabel(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkX' + self.idx + '-RB'))
        hbox_x = QHBoxLayout()
        hbox_x.addWidget(self.sb_x)
        hbox_x.addWidget(self.lb_x)
        lay.addRow(label_x, hbox_x)

        label_y = QLabel(' Y: ', self)
        self.lb_y = PyDMLabel(
            self,
            self.dev.substitute(propty=self.mtyp + 'MarkY' + self.idx +
                                '-Mon'))
        hbox_y = QHBoxLayout()
        hbox_y.addWidget(self.lb_y)
        if self.mtyp == 'D':
            self.lb_dynamicY = PyDMLabel(
                self,
                self.dev.substitute(propty='DynamicDX' + self.idx + '-Mon'))
            self.lb_dynamicY.setVisible(False)
            hbox_y.addWidget(self.lb_dynamicY)
        lay.addRow(label_y, hbox_y)

        self.pb_max = PyDMPushButton(
            parent=self,
            label='Mark Max Peak',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMax' +
                                             self.idx + '-Cmd'))
        self.pb_maxnext = PyDMPushButton(
            parent=self,
            label='Mark Max Next',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMaxNext' +
                                             self.idx + '-Cmd'))
        self.pb_maxright = PyDMPushButton(
            parent=self,
            label='Mark Max Right',
            pressValue=1,
            init_channel=self.dev.substitute(
                propty=self.mtyp + 'MarkMaxRight' + self.idx + '-Cmd'))
        self.pb_maxleft = PyDMPushButton(
            parent=self,
            label='Mark Max Left',
            pressValue=1,
            init_channel=self.dev.substitute(propty=self.mtyp + 'MarkMaxLeft' +
                                             self.idx + '-Cmd'))
        vbox_cmd = QVBoxLayout()
        vbox_cmd.addWidget(self.pb_max)
        vbox_cmd.addWidget(self.pb_maxnext)
        vbox_cmd.addWidget(self.pb_maxright)
        vbox_cmd.addWidget(self.pb_maxleft)
        lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))
        lay.addRow(vbox_cmd)

        if self.mtyp == '' and self.idx == '1':
            lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed))

            label_enblautomin = QLabel('Enable Auto Min: ', self)
            self.bt_enblautomin = PyDMStateButton(
                self, self.dev.substitute(propty='EnblMinAuto-Sel'))
            self.bt_enblautomin.shape = 1
            self.led_enblautomin = SiriusLedState(
                self, self.dev.substitute(propty='EnblMinAuto-Sts'))
            hbox_enblautomin = QHBoxLayout()
            hbox_enblautomin.addWidget(self.bt_enblautomin)
            hbox_enblautomin.addWidget(self.led_enblautomin)
            lay.addRow(label_enblautomin, hbox_enblautomin)

            label_enbllimit = QLabel('Enable Mark Limit: ', self)
            self.bt_enbllimit = PyDMStateButton(
                self, self.dev.substitute(propty='EnblMarkLimit-Sel'))
            self.bt_enbllimit.shape = 1
            self.led_enbllimit = SiriusLedState(
                self, self.dev.substitute(propty='EnblMarkLimit-Sts'))
            hbox_enbllimit = QHBoxLayout()
            hbox_enbllimit.addWidget(self.bt_enbllimit)
            hbox_enbllimit.addWidget(self.led_enbllimit)
            lay.addRow(label_enbllimit, hbox_enbllimit)

            label_limright = QLabel('Mark Limit Right: ', self)
            self.sb_limright = PyDMLineEdit(
                self, self.dev.substitute(propty='MarkLimitRight-SP'))
            self.lb_limright = PyDMLabel(
                self, self.dev.substitute(propty='MarkLimitRight-RB'))
            hbox_limright = QHBoxLayout()
            hbox_limright.addWidget(self.sb_limright)
            hbox_limright.addWidget(self.lb_limright)
            lay.addRow(label_limright, hbox_limright)

            label_limleft = QLabel('Mark Limit Left: ', self)
            self.sb_limleft = PyDMLineEdit(
                self, self.dev.substitute(propty='MarkLimitLeft-SP'))
            self.lb_limleft = PyDMLabel(
                self, self.dev.substitute(propty='MarkLimitLeft-RB'))
            hbox_limleft = QHBoxLayout()
            hbox_limleft.addWidget(self.sb_limleft)
            hbox_limleft.addWidget(self.lb_limleft)
            lay.addRow(label_limleft, hbox_limleft)

        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 _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
Exemple #24
0
    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