Exemple #1
0
    def _get_multturn_acq_grpbx(self):
        grp_bx = QWidget(self)
        fbl = QFormLayout(grp_bx)
        lbl = QLabel('Downsampling', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnDownSample')
        fbl.addRow(lbl, wid)

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

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

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

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

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

        lbl = QLabel('Mask End', grp_bx, alignment=Qt.AlignCenter)
        wid = self.create_pair(grp_bx, 'MTurnMaskSplEnd')
        fbl.addRow(lbl, wid)
        self._set_detailed([lbl, wid])
        return grp_bx
Exemple #2
0
    def create_statistics(self, wid, position=True):
        text, unit, names, _ = self._get_properties(position)

        wid = QWidget(wid)
        hbl = QHBoxLayout(wid)
        hbl.addStretch()
        grpbx = QGroupBox('Statistics', wid)
        hbl.addWidget(grpbx)
        hbl.addStretch()

        gdl = QGridLayout(grpbx)
        gdl.setHorizontalSpacing(20)
        gdl.setVerticalSpacing(20)

        stats = ('MeanValue', 'Sigma', 'MinValue', 'MaxValue')
        for j, stat in enumerate(('Average', 'Sigma', 'Minimum', 'Maximum')):
            lab = QLabel(stat, wid)
            lab.setAlignment(Qt.AlignCenter)
            gdl.addWidget(lab, 0, j+1)
        for i, name in enumerate(names):
            lab = QLabel(text[:3] + name, wid)
            lab.setAlignment(Qt.AlignCenter)
            gdl.addWidget(lab, i+1, 0)
            for j, stat in enumerate(stats):
                lab = SiriusLabel(wid, init_channel=self.get_pvname(
                    name+'_STATS'+stat+'_RBV'))
                lab.setAlignment(Qt.AlignCenter)
                lab.unit_changed(unit)
                lab.showUnits = True
                lab.precisionFromPV = False
                lab.precision = 3
                gdl.addWidget(lab, i+1, j+1)
        return wid
Exemple #3
0
    def get_selection_lists_widget(self, parent):
        """."""
        sel_wid = QWidget(parent)
        sel_lay = QHBoxLayout(sel_wid)

        icon = qta.icon('fa5s.hammer', color=get_appropriate_color(self.acc))
        Window = create_window_from_widget(
            SelectionMatrix, title='Corrs and BPMs selection', icon=icon)
        btn = QPushButton('', sel_wid)
        btn.setObjectName('btn')
        btn.setIcon(qta.icon('fa5s.tasks'))
        btn.setToolTip('Open window to select BPMs and correctors')
        btn.setStyleSheet(
            '#btn{min-width:3.8em; max-width:3.8em;\
            min-height:2em; max-height:2em; icon-size:25px;}')
        connect_window(
            btn, Window, None, device=self.device,
            prefix=self.prefix, acc=self.acc)
        sel_lay.addWidget(btn)

        lay = QVBoxLayout()
        sel_lay.addStretch()
        sel_lay.addLayout(lay)

        hlay = QHBoxLayout()
        lay.addLayout(hlay)
        hlay.addWidget(SiriusEnumComboBox(
            sel_wid, self.devpref.substitute(propty='RespMatMode-Sel')))
        hlay.addWidget(SiriusLabel(
            sel_wid, self.devpref.substitute(propty='RespMatMode-Sts')))

        if self.acc in {'SI', 'BO'}:
            hlay = QHBoxLayout()
            lay.addLayout(hlay)
            pdm_chbx = PyDMCheckbox(
                sel_wid, self.devpref.substitute(propty='RFEnbl-Sel'))
            pdm_chbx.setText('use RF')
            pdm_led = SiriusLedState(
                sel_wid, self.devpref.substitute(propty='RFEnbl-Sts'))
            hlay.addWidget(pdm_chbx)
            hlay.addWidget(pdm_led)

        btn = QPushButton('', sel_wid)
        btn.setToolTip('Visualize RespMat')
        btn.setIcon(qta.icon('mdi.chart-line'))
        btn.setObjectName('btn')
        btn.setStyleSheet('#btn{max-width:40px; icon-size:40px;}')
        connect_newprocess(
            btn, [f'sirius-hla-{self.acc.lower():s}-ap-sofb.py', '--matrix'])
        sel_lay.addWidget(btn)

        return sel_wid
Exemple #4
0
    def get_singular_values_widget(self, parent):
        """."""
        svs_wid = QWidget(parent)
        svs_lay = QGridLayout(svs_wid)

        wid = self.create_pair(svs_wid, 'MinSingValue')
        lbl = QLabel('Min. SV: ')
        svs_lay.addWidget(lbl, 0, 0)
        svs_lay.addWidget(wid, 0, 1)

        wid = self.create_pair(svs_wid, 'TikhonovRegConst')
        lbl = QLabel('Tikhonov: ')
        svs_lay.addWidget(lbl, 1, 0)
        svs_lay.addWidget(wid, 1, 1)

        lbl = QLabel('Nr Sing Vals')
        lbls = SiriusLabel(
            svs_wid, self.devpref.substitute(propty='NrSingValues-Mon'))
        btn = QPushButton('', svs_wid)
        btn.setToolTip('Check Singular Values')
        btn.setIcon(qta.icon('mdi.chart-line'))
        btn.setObjectName('btn')
        btn.setStyleSheet('#btn{max-width:30px; icon-size:30px;}')
        hbl = QHBoxLayout()
        hbl.addWidget(btn)
        hbl.addStretch()
        hbl.addWidget(lbl)
        hbl.addWidget(lbls)
        svs_lay.addLayout(hbl, 2, 0, 1, 2)

        Window = create_window_from_widget(
            SingularValues, title='Check Singular Values')
        connect_window(
            btn, Window, svs_wid, device=self.device, prefix=self.prefix)

        return svs_wid
Exemple #5
0
    def _setupUi(self):
        gl = QGridLayout(self)
        fig = mplt.figure()
        wid = MatplotlibWidget(fig, parent=self)
        wid.setObjectName('fig_result')
        wid.setStyleSheet('#fig_result{min-width: 25em;}')
        self.fig_res = wid

        gs = mgs.GridSpec(3, 1)
        gs.update(left=0.18, right=0.98, top=0.97, bottom=0.08, hspace=0.25)

        axes = wid.figure.add_subplot(gs[0, 0])
        axes.set_xlabel('Index')
        axes.set_ylabel('Normalized Emit. [mm.mrad]')
        axes.grid(True)
        axes.set_aspect('auto')
        self.line_nemitx_tm = axes.plot(
            self.nemitx_tm, '-bo', lw=1, label='Hor. Trans. Mat.')[0]
        self.line_nemitx_parf = axes.plot(
            self.nemitx_parf, '--bd', lw=1, label='Hor. Parab. Fit')[0]
        self.line_nemity_tm = axes.plot(
            self.nemity_tm, '--ro', lw=1, label='Vert. Trans. Mat.')[0]
        self.line_nemity_parf = axes.plot(
            self.nemity_parf, '--rd', lw=1, label='Vert. Parab. Fit')[0]
        axes.legend(loc='best')

        axes = wid.figure.add_subplot(gs[1, 0])
        axes.set_xlabel('Index')
        axes.set_ylabel(r'$\beta$ [m]')
        self.line_betax_tm = axes.plot(
            self.betax_tm, '-bo', lw=1, label='Hor. Trans. Mat.')[0]
        self.line_betax_parf = axes.plot(
            self.betax_parf, '--bd', lw=1, label='Hor. Parab. Fit')[0]
        self.line_betay_tm = axes.plot(
            self.betay_tm, '--ro', lw=1, label='Vert. Trans. Mat.')[0]
        self.line_betay_parf = axes.plot(
            self.betay_parf, '--rd', lw=1, label='Vert. Parab. Fit')[0]

        axes = wid.figure.add_subplot(gs[2, 0])
        axes.set_xlabel('Index')
        axes.set_ylabel(r'$\alpha$')
        self.line_alphax_tm = axes.plot(
            self.alphax_tm, '-bo', lw=1, label='Hor. Trans. Mat.')[0]
        self.line_alphax_parf = axes.plot(
            self.alphax_parf, '--bd', lw=1, label='Hor. Parab. Fit')[0]
        self.line_alphay_tm = axes.plot(
            self.alphay_tm, '--ro', lw=1, label='Vert. Trans. Mat.')[0]
        self.line_alphay_parf = axes.plot(
            self.alphay_parf, '--rd', lw=1, label='Vert. Parab. Fit')[0]

        measlay = QVBoxLayout()

        gb = QGroupBox('QF3 Current [A]', self)
        measlay.addWidget(gb)
        gb.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(
            gb, _PVName('LI-01:PS-QF3:Current-SP').substitute(
                prefix=self._prefix))
        lbl = SiriusLabel(
            gb, _PVName('LI-01:PS-QF3:Current-Mon').substitute(
                prefix=self._prefix))
        spnbox.showStepExponent = False
        gb.layout().addWidget(spnbox)
        gb.layout().addWidget(lbl)
        gb.layout().setAlignment(Qt.AlignTop)

        gb = QGroupBox('Data Acquisition Configs.', self)
        fl = QFormLayout(gb)
        measlay.addWidget(gb)
        self.pb_start = QPushButton('Start', gb)
        self.pb_start.clicked.connect(self.pb_start_clicked)
        self.pb_stop = QPushButton('Stop', gb)
        self.pb_stop.clicked.connect(self.pb_stop_clicked)
        self.pb_stop.setEnabled(False)
        hbox_bts = QHBoxLayout()
        hbox_bts.addWidget(self.pb_start)
        hbox_bts.addWidget(self.pb_stop)
        fl.addRow(hbox_bts)
        self.cbbox_plane = QComboBox(gb)
        self.cbbox_plane.addItem('Horizontal')
        self.cbbox_plane.addItem('Vertical')
        fl.addRow(QLabel('Plane', gb), self.cbbox_plane)
        self.spbox_steps = QSpinBoxPlus(gb)
        self.spbox_steps.setValue(11)
        fl.addRow(QLabel('Nr Steps', gb), self.spbox_steps)
        self.spbox_samples = QSpinBoxPlus(gb)
        self.spbox_samples.setMinimum(1)
        self.spbox_samples.setValue(16)
        fl.addRow(QLabel('Nr Samples per step', gb), self.spbox_samples)
        self.spbox_outliers = QSpinBoxPlus(gb)
        self.spbox_outliers.setMinimum(0)
        self.spbox_outliers.setValue(12)
        fl.addRow(QLabel('Nr Outliers', gb), self.spbox_outliers)
        self.spbox_I_ini = QDoubleSpinBoxPlus(gb)
        self.spbox_I_ini.setMinimum(-4)
        self.spbox_I_ini.setMaximum(4)
        self.spbox_I_ini.setValue(-0.7)
        self.spbox_I_ini.setDecimals(3)
        fl.addRow(QLabel('Initial Current [A]', gb), self.spbox_I_ini)
        self.spbox_I_end = QDoubleSpinBoxPlus(gb)
        self.spbox_I_end.setMinimum(-4)
        self.spbox_I_end.setMaximum(4)
        self.spbox_I_end.setValue(0.7)
        self.spbox_I_end.setDecimals(3)
        fl.addRow(QLabel('Final Current [A]', gb), self.spbox_I_end)
        self.spbox_threshold = QDoubleSpinBoxPlus(gb)
        self.spbox_threshold.setMinimum(0)
        self.spbox_threshold.setMaximum(20)
        self.spbox_threshold.setValue(4)
        self.spbox_threshold.setDecimals(2)
        fl.addRow(QLabel('Max. Size Accpbl. [mm]', gb), self.spbox_threshold)

        measlay.setStretch(0, 2)
        measlay.setStretch(1, 8)

        anllay = QVBoxLayout()

        gb = QGroupBox('Analysis Configs.', self)
        vl = QVBoxLayout(gb)
        anllay.addWidget(gb)
        self.spbox_energy = QDoubleSpinBoxPlus(gb)
        self.spbox_energy.setMinimum(0.511)
        self.spbox_energy.setMaximum(200)
        self.spbox_energy.setValue(150)
        self.spbox_energy.setDecimals(2)
        self.pb_analyse_data = QPushButton('Analyse', gb)
        self.pb_analyse_data.clicked.connect(self.pb_analyse_data_clicked)
        hl = QHBoxLayout()
        hl.addWidget(QLabel('Energy [MeV]', gb))
        hl.addWidget(self.spbox_energy)
        hl.addWidget(self.pb_analyse_data)
        vl.addLayout(hl)
        self.pb_save_data = QPushButton('Save Raw', gb)
        self.pb_save_data.clicked.connect(self.pb_save_data_clicked)
        self.pb_load_data = QPushButton('Load Raw', gb)
        self.pb_load_data.clicked.connect(self.pb_load_data_clicked)
        hl = QHBoxLayout()
        hl.addWidget(self.pb_save_data)
        hl.addWidget(self.pb_load_data)
        vl.addLayout(hl)
        self.logdisplay = PyDMLogDisplay(self, level=_log.INFO)
        vl.addWidget(self.logdisplay)

        resultsgb = QGroupBox('Results', self)
        gl2 = QGridLayout(resultsgb)
        gl2.addWidget(QLabel('Trans. Matrix', resultsgb), 0, 1, 1, 2)
        gl2.addWidget(QLabel('Parabola Fit', resultsgb), 0, 3, 1, 2)
        gl2.addWidget(QLabel('Hor.', resultsgb), 1, 1)
        gl2.addWidget(QLabel('Vert.', resultsgb), 1, 2)
        gl2.addWidget(QLabel('Hor.', resultsgb), 1, 3)
        gl2.addWidget(QLabel('Vert.', resultsgb), 1, 4)
        gl2.addWidget(QLabel('Norm. emitt.\n[mm.mrad]', resultsgb), 2, 0)
        gl2.addWidget(QLabel('beta [m]', resultsgb), 3, 0)
        gl2.addWidget(QLabel('alpha', resultsgb), 4, 0)
        for i, pref in enumerate(('nemit', 'beta', 'alpha')):
            for j, tp in enumerate(('x_tm', 'y_tm', 'x_parf', 'y_parf')):
                name = pref + tp
                lb = QLabel('----', resultsgb)
                setattr(self, 'lb_' + name, lb)
                gl2.addWidget(lb, i+2, j+1)

        wid = MatplotlibWidget(parent=self)
        axes = wid.figure.add_subplot(111)
        axes.set_xlabel('Quad. Current [A]')
        axes.set_ylabel('Beam Size [mm]')
        wid.figure.set_tight_layout(True)
        self.line_sigmax = axes.plot([], 'bo', lw=1, label='Horizontal')[0]
        self.line_sigmay = axes.plot([], 'ro', lw=1, label='Vertical')[0]
        self.line_fit = axes.plot([], '-k', lw=1)[0]
        wid.setObjectName('fig_sigma')
        wid.setStyleSheet('#fig_sigma{min-width: 25em;}')
        self.fig_sigma = wid

        gl.addWidget(self.plt_image, 0, 0, 2, 1)
        gl.addItem(measlay, 0, 1)
        gl.addWidget(self.fig_sigma, 1, 1)
        gl.addItem(anllay, 0, 2)
        gl.addWidget(resultsgb, 1, 2)
        gl.addWidget(self.fig_res, 0, 3, 2, 1)
    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
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 #8
0
    def _setupUi(self):
        pref = _PVName('LI-Glob:AP-MeasEnergy').substitute(prefix=self.prefix)
        self.plt_energy = SiriusTimePlot(
            self,
            init_y_channels=[pref.substitute(propty='Energy-Mon')],
            background=QColor('white'))
        self.plt_energy.setLabel('left', text='Energy [MeV]')
        self.plt_energy.setShowXGrid(True)
        self.plt_energy.setShowYGrid(True)
        c = self.plt_energy.curveAtIndex(0)
        c.color = QColor('blue')
        c.symbol = c.symbols['Circle']
        c.symbolSize = 10
        c.lineWidth = 3
        c.data_changed.connect(self._update_energy_stats)
        self.plt_energy.setTimeSpan(100)

        self.plt_spread = SiriusTimePlot(
            self,
            init_y_channels=[pref.substitute(propty='Spread-Mon')],
            background=QColor('white'))
        self.plt_spread.setLabel('left', text='Spread [%]')
        self.plt_spread.setShowXGrid(True)
        self.plt_spread.setShowYGrid(True)
        c = self.plt_spread.curveAtIndex(0)
        c.color = QColor('red')
        c.symbol = c.symbols['Circle']
        c.symbolSize = 10
        c.lineWidth = 3
        c.data_changed.connect(self._update_spread_stats)
        self.plt_spread.setTimeSpan(100)

        gb_ctrl = QGroupBox('Control', self)
        hl_ctrl = QHBoxLayout(gb_ctrl)

        vl = QVBoxLayout()
        wid = QWidget(gb_ctrl)
        wid.setLayout(QHBoxLayout())
        btn = PyDMStateButton(gb_ctrl,
                              pref.substitute(propty='MeasureCtrl-Sel'))
        led = SiriusLedState(gb_ctrl,
                             pref.substitute(propty='MeasureCtrl-Sts'))
        wid.layout().addWidget(btn)
        wid.layout().addWidget(led)
        vl.addWidget(QLabel('Start/Stop Acq.', gb_ctrl))
        vl.addWidget(wid)
        hl_ctrl.addLayout(vl)

        vl = QVBoxLayout()
        wid = QWidget(gb_ctrl)
        wid.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(
            wid,
            _PVName('LI-01:PS-Spect:Current-SP').substitute(
                prefix=self.prefix))
        lbl = SiriusLabel(
            wid,
            _PVName('LI-01:PS-Spect:Current-Mon').substitute(
                prefix=self.prefix))
        spnbox.showStepExponent = False
        wid.layout().addWidget(spnbox)
        wid.layout().addWidget(lbl)
        vl.addWidget(QLabel('Spectrometer Current [A]', gb_ctrl))
        vl.addWidget(wid)
        hl_ctrl.addLayout(vl)

        gb_ener = QGroupBox('Properties', self)
        fl_ener = QFormLayout(gb_ener)

        wid = QWidget(gb_ener)
        wid.setLayout(QHBoxLayout())
        self.lb_ave_en = QLabel('0.000', wid)
        self.lb_std_en = QLabel('0.000', wid)
        wid.layout().addWidget(self.lb_ave_en)
        wid.layout().addWidget(
            QLabel('<html><head/><body><p>&#177;</p></body></html>', wid))
        wid.layout().addWidget(self.lb_std_en)
        fl_ener.addRow('Energy [MeV]', wid)

        wid = QWidget(gb_ener)
        wid.setLayout(QHBoxLayout())
        self.lb_ave_sp = QLabel('0.000', wid)
        self.lb_std_sp = QLabel('0.000', wid)
        wid.layout().addWidget(self.lb_ave_sp)
        wid.layout().addWidget(
            QLabel('<html><head/><body><p>&#177;</p></body></html>', wid))
        wid.layout().addWidget(self.lb_std_sp)
        fl_ener.addRow('Spread [%]', wid)

        hl_span = QHBoxLayout()
        hl_span.setSpacing(0)
        self.spbox_npoints = QSpinBoxPlus(self)
        self.spbox_npoints.setKeyboardTracking(False)
        self.spbox_npoints.setMinimum(10)
        self.spbox_npoints.setMaximum(200000)
        self.spbox_npoints.setValue(100)
        self.spbox_npoints.editingFinished.connect(self.nrpoints_edited)
        hl_span.addWidget(QLabel('Choose TimeSpan [s]:', self))
        hl_span.addWidget(self.spbox_npoints)
        self.pb_reset_data = QPushButton('Reset Data', self)
        self.pb_reset_data.clicked.connect(self.pb_reset_data_clicked)
        hl_span.addWidget(self.pb_reset_data)

        self.plt_image = SiriusProcessImage(self, device=pref)

        gb_trig = QGroupBox('Trigger', self)
        hbl = QHBoxLayout(gb_trig)
        hbl.addWidget(
            HLTriggerSimple(parent=self,
                            device='LI-Fam:TI-Scrn',
                            prefix=self.prefix))
        gb_trig.setLayout(hbl)

        gl = QGridLayout(self)
        gl.addLayout(hl_span, 0, 0, 1, 2)
        gl.addWidget(self.plt_image, 0, 2, 3, 1)
        gl.addWidget(self.plt_energy, 1, 0, 1, 2)
        gl.addWidget(self.plt_spread, 2, 0, 1, 2)
        gl.addWidget(gb_ctrl, 3, 0)
        gl.addWidget(gb_ener, 3, 1)
        gl.addWidget(gb_trig, 3, 2)
        gl.setColumnStretch(0, 3)
        gl.setColumnStretch(1, 2)
        gl.setColumnStretch(2, 3)
Exemple #9
0
    def _create_formlayout_groupbox(self, title, props):
        grpbx = CustomGroupBox(title, self)
        fbl = QFormLayout(grpbx)
        grpbx.layoutf = fbl
        fbl.setLabelAlignment(Qt.AlignVCenter)
        for prop in props:
            if len(prop) == 2:
                pv1, txt = prop
                isdata = True
            elif len(prop) == 3:
                pv1, txt, isdata = prop
            hbl = QHBoxLayout()
            not_enum = pv1.endswith('-SP')
            pv2 = pv1.replace('-SP', '-RB').replace('-Sel', '-Sts')
            if pv2 != pv1:
                if not_enum:
                    chan1 = self.get_pvname(pv1, is_data=isdata)
                    wid = SiriusSpinbox(self, init_channel=chan1)
                    wid.setStyleSheet("min-width:5em;")
                    wid.showStepExponent = False
                    wid.limitsFromChannel = False
                    pvn = self.data_prefix + pv1
                    wid.setMinimum(self.bpmdb[pvn].get('low', -1e10))
                    wid.setMaximum(self.bpmdb[pvn].get('high', 1e10))
                else:
                    wid = PyDMEnumComboBox(
                        self,
                        init_channel=self.get_pvname(pv1, is_data=isdata))
                    wid.setStyleSheet("min-width:5em;")
                wid.setObjectName(pv1.replace('-', ''))
                hbl.addWidget(wid)

            lab = SiriusLabel(
                self, init_channel=self.get_pvname(pv2, is_data=isdata))
            lab.setObjectName(pv2.replace('-', ''))
            lab.showUnits = True
            lab.setStyleSheet("min-width:5em;")
            hbl.addWidget(lab)
            lab = QLabel(txt)
            lab.setObjectName(pv1.split('-')[0])
            lab.setStyleSheet("min-width:8em;")
            fbl.addRow(lab, hbl)
        return grpbx
Exemple #10
0
    def _setupUi(self):
        label = QLabel('<h3>' + self._title + '</h3>',
                       self,
                       alignment=Qt.AlignCenter)

        self._process_image = SiriusProcessImage(self,
                                                 device=self._device_analysis,
                                                 orientation='H',
                                                 convertion_set=False)
        self._process_image.image_view.colorMapMax = 2**16 - 1

        # IOC control
        gbox_ctrl = QGroupBox('Analysis Control')
        lay_ctrl = QGridLayout(gbox_ctrl)

        self._ld_enbl = QLabel('Start/Stop: ')
        self._sb_enbl = PyDMStateButton(
            gbox_ctrl, self._device_analysis + ':MeasureCtrl-Sel')
        self._lb_enbl = PyDMLabel(gbox_ctrl,
                                  self._device_analysis + ':MeasureCtrl-Sts')

        self._ld_rate = QLabel('Acq. Rate: ')
        self._sb_rate = SiriusSpinbox(
            gbox_ctrl, self._device_analysis + ':MeasureRate-SP')
        self._sb_rate.showStepExponent = False
        self._lb_rate = PyDMLabel(gbox_ctrl,
                                  self._device_analysis + ':MeasureRate-RB')

        self._ld_tgtx = QLabel('Target X: ')
        self._sb_tgtx = SiriusSpinbox(gbox_ctrl,
                                      self._device_analysis + ':TargetPosX-SP')
        self._sb_tgtx.showStepExponent = False
        self._lb_tgtx = PyDMLabel(gbox_ctrl,
                                  self._device_analysis + ':TargetPosX-RB')

        self._ld_tgty = QLabel('Target Y: ')
        self._sb_tgty = SiriusSpinbox(gbox_ctrl,
                                      self._device_analysis + ':TargetPosY-SP')
        self._sb_tgty.showStepExponent = False
        self._lb_tgty = PyDMLabel(gbox_ctrl,
                                  self._device_analysis + ':TargetPosY-RB')

        lay_ctrl.setAlignment(Qt.AlignTop)
        lay_ctrl.addWidget(self._ld_enbl, 0, 0, 2, 1)
        lay_ctrl.addWidget(self._sb_enbl, 0, 1)
        lay_ctrl.addWidget(self._lb_enbl, 1, 1)
        lay_ctrl.addWidget(self._ld_rate, 2, 0, 2, 1)
        lay_ctrl.addWidget(self._sb_rate, 2, 1)
        lay_ctrl.addWidget(self._lb_rate, 3, 1)
        lay_ctrl.addWidget(self._ld_tgtx, 4, 0, 2, 1)
        lay_ctrl.addWidget(self._sb_tgtx, 4, 1)
        lay_ctrl.addWidget(self._lb_tgtx, 5, 1)
        lay_ctrl.addWidget(self._ld_tgty, 6, 0, 2, 1)
        lay_ctrl.addWidget(self._sb_tgty, 6, 1)
        lay_ctrl.addWidget(self._lb_tgty, 7, 1)

        gbox_sofb = QGroupBox('SOFB Bump [urad]')
        lay_sofb = QGridLayout(gbox_sofb)

        ldx = QLabel('X:')
        ldy = QLabel('Y:')
        ldd = QLabel('Delta')
        lda = QLabel('Applied')
        pre = self._device_analysis
        lb_dbmpx = SiriusLabel(gbox_sofb, pre + ':NeededDeltaBumpX-Mon')
        lb_dbmpy = SiriusLabel(gbox_sofb, pre + ':NeededDeltaBumpY-Mon')
        lb_bmpx = SiriusLabel(gbox_sofb, pre + ':AppliedBumpX-Mon')
        lb_bmpy = SiriusLabel(gbox_sofb, pre + ':AppliedBumpY-Mon')
        pb_app = PyDMPushButton(gbox_sofb,
                                'Apply',
                                pressValue=1,
                                init_channel=pre + ':ApplyBump-Cmd')
        pb_app.showConfirmDialog = True
        pb_app.confirmMessage = \
            'This action will change the reference orbit used in SOFB.\n' +\
            pb_app.confirmMessage
        lb_app = PyDMLabel(gbox_sofb, init_channel=pre + ':ApplyStatus-Mon')

        lay_sofb.setAlignment(Qt.AlignTop)
        lay_sofb.addWidget(ldd, 0, 1, alignment=Qt.AlignCenter)
        lay_sofb.addWidget(lda, 0, 2, alignment=Qt.AlignCenter)
        lay_sofb.addWidget(ldx, 1, 0, alignment=Qt.AlignLeft)
        lay_sofb.addWidget(ldy, 2, 0, alignment=Qt.AlignLeft)
        lay_sofb.addWidget(lb_dbmpx, 1, 1)
        lay_sofb.addWidget(lb_dbmpy, 2, 1)
        lay_sofb.addWidget(lb_bmpx, 1, 2)
        lay_sofb.addWidget(lb_bmpy, 2, 2)
        hbl = QHBoxLayout()
        hbl.addStretch()
        hbl.addWidget(pb_app)
        hbl.addWidget(lb_app)
        hbl.addStretch()
        lay_sofb.addLayout(hbl, 3, 0, 1, 3)
        lay_sofb.setRowStretch(4, 5)

        # Camera Acquisition Status
        gbox_acqsett = QGroupBox('Camera Acquisition Statuses')
        lay_acqsett = QGridLayout(gbox_acqsett)

        self._ld_acqtime = QLabel('Acquire Time: ')
        self._sb_acqtime = SiriusSpinbox(
            gbox_ctrl, self._device_cam + ':cam1:AcquireTime')
        self._sb_acqtime.showStepExponent = False
        self._sb_acqtime.limitsFromChannel = False
        self._sb_acqtime.setRange(0.001, 10)
        self._lb_acqtime = PyDMLabel(
            gbox_acqsett, self._device_cam + ':cam1:AcquireTime_RBV')
        self._lb_acqtime.showUnits = True

        self._ld_acqperd = QLabel('Acquire Period: ')
        self._sb_acqperd = SiriusSpinbox(
            gbox_ctrl, self._device_cam + ':cam1:AcquirePeriod')
        self._sb_acqperd.showStepExponent = False
        self._sb_acqperd.limitsFromChannel = False
        self._sb_acqperd.setRange(0.001, 10)
        self._lb_acqperd = PyDMLabel(
            gbox_acqsett, self._device_cam + ':cam1:AcquirePeriod_RBV')
        self._lb_acqperd.showUnits = True

        self._ld_numimgs = QLabel('# Images: ')
        self._lb_numimgs = PyDMLabel(gbox_acqsett,
                                     self._device_cam + ':cam1:NumImages_RBV')

        self._ld_imgmode = QLabel('Image Mode: ')
        self._lb_imgmode = PyDMLabel(gbox_acqsett,
                                     self._device_cam + ':cam1:ImageMode_RBV')

        self._ld_acqsts = QLabel('Acquire Status: ')
        self._pb_acqsts = PyDMStateButton(gbox_acqsett,
                                          self._device_cam + ':cam1:Acquire')
        self._lb_acqsts = SiriusLedState(
            gbox_acqsett, self._device_cam + ':cam1:Acquire_RBV')

        self._ld_capsts = QLabel('Capture Status: ')
        self._pb_capsts = PyDMStateButton(gbox_acqsett,
                                          self._device_cam + ':HDF1:Capture')
        self._lb_capsts = SiriusLedState(
            gbox_acqsett, self._device_cam + ':HDF1:Capture_RBV')

        lay_acqsett.addWidget(self._ld_acqtime, 0, 0, 2, 1)
        lay_acqsett.addWidget(self._sb_acqtime, 0, 1)
        lay_acqsett.addWidget(self._lb_acqtime, 1, 1)
        lay_acqsett.addWidget(self._ld_acqperd, 2, 0, 2, 1)
        lay_acqsett.addWidget(self._sb_acqperd, 2, 1)
        lay_acqsett.addWidget(self._lb_acqperd, 3, 1)
        lay_acqsett.addWidget(self._ld_acqsts, 4, 0, 2, 1)
        lay_acqsett.addWidget(self._pb_acqsts, 4, 1)
        lay_acqsett.addWidget(self._lb_acqsts, 5, 1)
        lay_acqsett.addWidget(self._ld_capsts, 6, 0, 2, 1)
        lay_acqsett.addWidget(self._pb_capsts, 6, 1)
        lay_acqsett.addWidget(self._lb_capsts, 7, 1)
        lay_acqsett.addWidget(self._ld_numimgs, 8, 0)
        lay_acqsett.addWidget(self._lb_numimgs, 8, 1)
        lay_acqsett.addWidget(self._ld_imgmode, 9, 0)
        lay_acqsett.addWidget(self._lb_imgmode, 9, 1)
        lay_acqsett.setRowStretch(10, 20)

        self.cw = QWidget()
        self.cw.setStyleSheet('PyDMLabel{qproperty-alignment: AlignCenter;}')
        lay = QGridLayout(self.cw)
        lay.addWidget(label, 0, 0, 1, 3)
        lay.addWidget(self._process_image, 1, 0, 2, 1)
        lay.addWidget(gbox_ctrl, 1, 1)
        lay.addWidget(gbox_sofb, 2, 1)
        lay.addWidget(gbox_acqsett, 1, 2, 2, 1)
        lay.setColumnStretch(0, 7)
        lay.setColumnStretch(1, 2)
        self.setCentralWidget(self.cw)
Exemple #11
0
    def setupui(self):
        """."""
        vbl = QVBoxLayout(self)
        if self.orbtype.startswith('sum'):
            img_propty = 'MTurnSum-Mon'
            orb_propty = 'MTurnIdxSum-Mon'
            unit = 'count'
            color = 'black'
        elif self.orbtype.startswith('x'):
            img_propty = 'MTurnOrbX-Mon'
            orb_propty = 'MTurnIdxOrbX-Mon'
            unit = 'm'
            color = 'blue'
        else:
            img_propty = 'MTurnOrbY-Mon'
            orb_propty = 'MTurnIdxOrbY-Mon'
            unit = 'm'
            color = 'red'
        lbl_text = img_propty.split('-')[0]

        self.spect = Spectrogram(
            parent=self,
            device=self.device,
            prefix=self.prefix,
            image_channel=self.devpref.substitute(propty=img_propty),
            xaxis_channel=self.devpref.substitute(propty='BPMPosS-Mon'),
            yaxis_channel=self.devpref.substitute(propty='MTurnTime-Mon'))
        self.spect.new_data_sig.connect(self.update_graph)
        self.spect.normalizeData = True
        self.spect.yaxis.setLabel('Time', units='s')
        self.spect.xaxis.setLabel('BPM Position', units='m')
        self.spect.colorbar.label_format = '{:<8.1f}'
        lab = QLabel(lbl_text + ' Orbit', self, alignment=Qt.AlignCenter)
        lab.setStyleSheet("font-weight: bold;")
        vbl.addWidget(lab)
        vbl.addWidget(self.spect)

        vbl.addStretch()
        lab = QLabel('Average ' + lbl_text + ' vs Time',
                     self,
                     alignment=Qt.AlignCenter)
        lab.setStyleSheet("font-weight: bold;")
        hbl = QHBoxLayout()
        hbl.addStretch()
        hbl.addWidget(lab)
        hbl.addStretch()
        if self.orbtype.startswith('sum'):
            hbl.addWidget(QLabel('  Eff [%] =', self))
            ratio_avg = QLabel('000.0', self, alignment=Qt.AlignRight)
            ratio_std = QLabel('000.0', self, alignment=Qt.AlignLeft)
            hbl.addWidget(ratio_avg, alignment=Qt.AlignRight)
            hbl.addWidget(
                QLabel('<html><head/><body><p>&#177;</p></body></html>', self))
            hbl.addWidget(ratio_std, alignment=Qt.AlignLeft)
            hbl.addStretch()
            self.ratio_sum_avg.connect(ratio_avg.setText)
            self.ratio_sum_std.connect(ratio_std.setText)
        vbl.addLayout(hbl)

        graph = Graph(self)
        graph.setLabel('bottom', text='Time', units='s')
        graph.setLabel('left', text='Avg ' + lbl_text, units=unit)
        opts = dict(y_channel='A',
                    x_channel=self.devpref.substitute(propty='MTurnTime-Mon'),
                    name='',
                    color=color,
                    redraw_mode=2,
                    lineStyle=1,
                    lineWidth=3,
                    symbol='o',
                    symbolSize=10)
        graph.addChannel(**opts)
        graph.setShowLegend(False)
        graph.plotItem.scene().sigMouseMoved.connect(self._show_tooltip_time)
        self.curve = graph.curveAtIndex(0)
        self.graph_time = graph
        vbl.addWidget(graph)

        if not self.orbtype.startswith('sum'):
            return

        vbl.addStretch()
        wid = QWidget(self)
        lab = QLabel(lbl_text + ' orbit at index:',
                     wid,
                     alignment=Qt.AlignRight | Qt.AlignVCenter)
        lab.setStyleSheet("font-weight: bold;")
        pdmlab = SiriusLabel(wid,
                             self.devpref.substitute(propty='MTurnIdx-RB'))
        pdmlab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        pdmlab.setStyleSheet('min-width:4em;')
        wid.setLayout(QHBoxLayout())
        wid.layout().addStretch()
        wid.layout().addWidget(lab)
        wid.layout().addWidget(pdmlab)
        wid.layout().addStretch()
        vbl.addWidget(wid)
        graph = Graph(self)
        vbl.addWidget(graph)
        graph.setLabel('bottom', text='BPM Position', units='m')
        graph.setLabel('left', text='Sum', units='count')
        opts = dict(y_channel=self.devpref.substitute(propty=orb_propty),
                    x_channel=self.devpref.substitute(propty='BPMPosS-Mon'),
                    name='',
                    color=color,
                    redraw_mode=2,
                    lineStyle=1,
                    lineWidth=3,
                    symbol='o',
                    symbolSize=10)
        graph.addChannel(**opts)
        graph.setShowLegend(False)
        graph.plotItem.scene().sigMouseMoved.connect(self._show_tooltip)
        self.graph = graph