Example #1
0
    def __init__(self, parent, device, orbits, idx, prefix='', acc='SI'):
        """Initialize the Context Menu."""
        super(OrbitRegister, self).__init__(parent)
        self.idx = idx
        self.prefix = prefix
        self.device = _PVName(device)
        self.devpref = self.device.substitute(prefix=prefix)
        text = acc.lower() + 'orb'
        self.setObjectName(text + str(idx))
        self.EXT = (f'.{acc.lower()}orb', f'.{acc.lower()}dorb')
        self.EXT_FLT = f'Sirius Orbit Files (*.{text});;' +\
            f'Sirius Delta Orbit Files (*.{acc.lower()}dorb)'
        self._config_type = acc.lower() + '_orbit'
        self._client = ConfigDBClient(config_type=self._config_type)
        self._csorb = SOFBFactory.create(acc.upper())
        self.string_status = 'Empty'
        self.name = 'Register {0:d}'.format(self.idx)
        self.setup_ui()

        self._orbits = orbits
        self.last_dir = self.DEFAULT_DIR
        self.filename = ''
        self._orbx = _np.zeros(self._csorb.nr_bpms)
        self._orby = _np.zeros(self._csorb.nr_bpms)

        self.new_string_signal.emit(self.string_status)
def get_correctors_strength():
    clt_gbl = ConfigDBClient(config_type='global_config')
    conf = clt_gbl.get_config_value('energy2p963gev_delta_quads_bo_config_A')
    conf = {n: v for n, v, d in conf['pvs']}

    vals = []
    for name in sofb.data.CH_NAMES:
        vals.append(conf[name + ':Current-SP'])
    return np.array(vals) * 39.0969 * 1e-6
Example #3
0
 def save(self):
     """Save data."""
     db = ConfigDBClient()
     if self._is_new or self._renamed or self._dirty_pvs:
         # Insert configuration
         db.insert_config(self._name, {'pvs': self._values},
                          config_type=self._config_type)
         # Clear flags
         self._is_new = False
         self._renamed = False
         self._dirty_pvs = dict()
def rename_global_config():
    """."""
    conn = CDBClient(config_type='global_config')
    configs = conn.find_configs()

    for config in configs:
        config_name = config['name']
        # config_name = 'si_chromcorr_orbcorr_tmp'
        config_value = conn.get_config_value(config_name)
        changed = rename_in_config(conn, config_name, config_value)
        if changed:
            break
Example #5
0
    def __init__(self, parent, device, prefix='', acc='SI'):
        super().__init__(parent, device, prefix=prefix, acc=acc)
        self.setupui()
        self._config_type = acc.lower() + '_orbcorr_respm'
        self._client = ConfigDBClient(config_type=self._config_type)
        self.EXT = self._csorb.respmat_fname.split('.')[1]
        self.EXT_FLT = 'RespMat Files (*.{})'.format(self.EXT)
        self.last_dir = self.DEFAULT_DIR

        self._respmat_sp = _ConnSig(
            self.devpref.substitute(propty='RespMat-SP'))
        self._respmat_rb = _ConnSig(
            self.devpref.substitute(propty='RespMat-RB'))
Example #6
0
    def _setVerticalHeader(self):
        # Used to sort section elements dict
        def subSection(elem):
            if re.search('-Fam', elem):
                return 0
            else:
                return 1

        def elem(elem):
            name = elem
            if re.search('-B', name):
                return 0
            elif re.search('-QF', name):
                return 2
            elif re.search('-QD', name):
                return 4
            elif re.search('-Q[0-9]', name):
                return 6
            elif re.search('-SF', name):
                return 8
            elif re.search('-SD', name):
                return 10
            elif re.search('-CH', name):
                return 12
            elif re.search('-CV', name):
                return 14
            elif re.search('-FCH', name):
                return 16
            elif re.search('-FCV', name):
                return 18
            else:
                return 20

        self._vertical_header = list()
        client = ConfigDBClient()
        if self._config_type == 'bo_normalized':
            pvs = client.get_value_from_template('bo_normalized')['pvs']
        elif self._config_type == 'si_normalized':
            pvs = client.get_value_from_template('si_normalized')['pvs']
        else:
            raise Exception("Module {} not found".format(self._config_type))
        # pvs = get_dict()["value"]
        # pvs = getattr(ConfigurationPvs, self._config_type)().pvs()
        for name, value, _ in pvs:
            self._vertical_header.append({'name': name, 'type': type(value)})
        self._vertical_header.sort(
            key=lambda x: elem(x['name']) + subSection(x['name']))
Example #7
0
 def setupModelData(self):
     """Setup model data."""
     if self._config_type is None:
         return
     self.beginResetModel()
     config = ConfigDBClient().get_value_from_template(self._config_type)
     if 'pvs' in config:
         self._data = config['pvs']
         # self._data.sort(key=lambda x: x[0])
     self.endResetModel()
Example #8
0
 def __init__(self, config_type, parent=None):
     """Constructor."""
     super().__init__(parent)
     self._client = ConfigDBClient()
     self._config_type = config_type
     self._logger = logging.getLogger(__name__)
     self._logger.setLevel(logging.INFO)
     self._setupui()
     self._config = ''
     self._status = False
     self.setWindowTitle("Configuration Database Manager")
Example #9
0
    def __init__(self, parent, ctrls, setpoint=None, readback=None, acc='SI'):
        """."""
        QComboBox.__init__(self, parent)
        PyDMPrimitiveWidget.__init__(self)
        self.setpoint = setpoint or dict()
        self.readback = readback or dict()
        self.ctrls = ctrls
        self._csorb = SOFBFactory.create(acc)
        self._config_type = acc.lower() + '_orbit'
        self._client = ConfigDBClient(config_type=self._config_type)
        self.orbits = {
            'x': _np.zeros(self._csorb.nr_bpms, dtype=float),
            'y': _np.zeros(self._csorb.nr_bpms, dtype=float)
        }
        self.signals_to_watch = dict()
        self.slots = {
            'x': _part(self._watch_if_changed, 'x'),
            'y': _part(self._watch_if_changed, 'y')
        }

        self.setup_ui()
        self.connect_signals()
Example #10
0
        def _applyconfig(self):
            sender_text = self.sender().text()
            if 'Standby' in sender_text:
                config_name = 'standby'
            elif 'TurnOff' in sender_text:
                config_name = 'turnoff'

            ans = QMessageBox.question(
                self, 'Are you Sure?',
                "Do you really want to apply the Configuration '" +
                config_name + "' to the machine?", QMessageBox.Yes,
                QMessageBox.Cancel)
            if ans != QMessageBox.Yes:
                return

            current, ok = QInputDialog.getDouble(
                self,
                'Enter value: ', 'Enter FilaPS standby current [A]\n'
                'or cancel to not set it: ',
                value=0.7,
                min=0.0,
                max=1.5,
                decimals=3)
            if ok:
                fila_pv = _PV(_prefix + 'LI-01:EG-FilaPS:currentoutsoft',
                              connection_timeout=0.05)
                fila_pv.get()  # force connection
                if fila_pv.connected:
                    fila_pv.put(current)
                else:
                    QMessageBox.warning(
                        self, 'Message',
                        'Could not connect to LI-01:EG-FilaPS!')

            client = ConfigDBClient()

            WinClass = create_window_from_widget(
                SelectAndApplyPVsWidget, 'Select PVs to Apply Standby')
            wind = WinClass(self, client)
            wind.widget.settingFinished.connect(wind.close)
            wind.widget.fill_config('global_config', config_name)
            wind.exec_()
Example #11
0
    def _test_conv_timestamp(self):
        """Test timestamp conversion."""
        # TODO: NOT WORKING ON TRAVIS
        samples = {
            ("Dec 11, 2017", 1512957600.0),
            ("12/11/2017", 1512957600.0),
            ("2017/12/11", 1512957600.0),
            ("2017-12-11", 1512957600.0),
            ("Dec 11 2017 14:00:00", 1513008000.0),
            ("12/11/2017 14:00:00", 1513008000.0),
            ("2017/12/11 14:00:00", 1513008000.0),
            ("2017-12-11 14:00:00", 1513008000.0),
            ("2017-12-11T14:00:00", 1513008000.0),
            ("2017-12-11 14:00:00+01:00", 1512997200.0),
            ("2017-12-11T14:00:00+01:00", 1512997200.0),
            ("2017-12-11T14:00:00.45", 1513008000.45),
        }

        for sample in samples:
            date_string = sample[0]
            timestamp = sample[1]
            self.assertEqual(
                ConfigDBClient.conv_timestamp_txt_2_flt(date_string),
                timestamp)
Example #12
0
class RespMatWidget(BaseWidget):

    DEFAULT_DIR = _pathlib.Path.home().as_posix()

    def __init__(self, parent, device, prefix='', acc='SI'):
        super().__init__(parent, device, prefix=prefix, acc=acc)
        self.setupui()
        self._config_type = acc.lower() + '_orbcorr_respm'
        self._client = ConfigDBClient(config_type=self._config_type)
        self.EXT = self._csorb.respmat_fname.split('.')[1]
        self.EXT_FLT = 'RespMat Files (*.{})'.format(self.EXT)
        self.last_dir = self.DEFAULT_DIR

        self._respmat_sp = _ConnSig(
            self.devpref.substitute(propty='RespMat-SP'))
        self._respmat_rb = _ConnSig(
            self.devpref.substitute(propty='RespMat-RB'))

    def setupui(self):
        """."""
        gbox = QGroupBox('Matrix', self)
        gbox.setObjectName('grbx')
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(gbox)
        vbl = QVBoxLayout(gbox)
        tabw = QTabWidget(gbox)
        vbl.addWidget(tabw)

        main_wid = self.get_main_widget(tabw)
        tabw.addTab(main_wid, 'Main')

        svs_wid = self.get_singular_values_widget(tabw)
        tabw.addTab(svs_wid, 'SVs')

        if self.acc != 'BO':
            meas_wid = self.get_measurement_widget(tabw)
            tabw.addTab(meas_wid, 'Meas')

    def get_main_widget(self, parent):
        main_wid = QWidget(parent)
        main_lay = QVBoxLayout(main_wid)
        main_lay.setContentsMargins(0, 0, 0, 0)

        sel_gp = QGroupBox('Sel.')
        sel_gp.setLayout(QHBoxLayout())
        sel_gp.layout().setContentsMargins(0, 0, 0, 0)
        sel_wid = self.get_selection_lists_widget(sel_gp)
        sel_gp.layout().addWidget(sel_wid)
        main_lay.addWidget(sel_gp)

        svld_gp = QGroupBox('Load and Save')
        svld_gp.setLayout(QHBoxLayout())
        svld_gp.layout().setContentsMargins(0, 0, 0, 0)
        svld_wid = self.get_saveload_widget(svld_gp)
        svld_gp.layout().addWidget(svld_wid)
        main_lay.addWidget(svld_gp)

        return main_wid

    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

    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

    def get_measurement_widget(self, parent):
        """."""
        meas_wid = QWidget(parent)
        meas_lay = QVBoxLayout(meas_wid)

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

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

        return meas_wid

    def get_saveload_widget(self, parent):
        """."""
        svld_wid = QWidget(parent)
        svld_lay = QGridLayout(svld_wid)

        lbl = QLabel('Load:', svld_wid)
        svld_lay.addWidget(lbl, 0, 0, alignment=Qt.AlignRight)
        pbtn = QPushButton('', svld_wid)
        pbtn.setIcon(qta.icon('mdi.file-upload-outline'))
        pbtn.setToolTip('Load RespMat from file')
        pbtn.clicked.connect(self._load_respmat_from_file)
        svld_lay.addWidget(pbtn, 0, 1)
        pbtn = QPushButton('', svld_wid)
        pbtn.setIcon(qta.icon('mdi.cloud-upload-outline'))
        pbtn.setToolTip('Load RespMat from ServConf')
        pbtn.clicked.connect(self._open_load_config_servconf)
        svld_lay.addWidget(pbtn, 0, 2)

        lbl = QLabel('Save:', svld_wid)
        svld_lay.addWidget(lbl, 0, 3, alignment=Qt.AlignRight)
        pbtn = QPushButton('', svld_wid)
        pbtn.setIcon(qta.icon('mdi.file-download-outline'))
        pbtn.setToolTip('Save RespMat to file')
        pbtn.clicked.connect(self._save_respmat_to_file)
        svld_lay.addWidget(pbtn, 0, 4)
        pbtn = QPushButton('', svld_wid)
        pbtn.setIcon(qta.icon('mdi.cloud-download-outline'))
        pbtn.setToolTip('Save RespMat to ServConf')
        pbtn.clicked.connect(self._open_save_config_servconf)
        svld_lay.addWidget(pbtn, 0, 5)
        self.respmat_label = QLabel('')
        svld_lay.addWidget(self.respmat_label, 1, 0, 1, 5)

        svld_lay.setRowStretch(2, 10)
        return svld_wid

    def _save_respmat_to_file(self, _):
        header = '# ' + _datetime.now().strftime('%Y/%m/%d-%H:%M:%S') + '\n'
        if self.acc in {'SI', 'BO'}:
            header += '# (BPMX, BPMY) [um] x (CH, CV, RF) [urad, Hz]' + '\n'
        else:
            header += '# (BPMX, BPMY) [um] x (CH, CV) [urad]' + '\n'
        filename = QFileDialog.getSaveFileName(
            caption='Define a File Name to Save the Response Matrix',
            directory=self.last_dir,
            filter=self.EXT_FLT)
        fname = filename[0]
        if not fname:
            return
        fname += '' if fname.endswith(self.EXT) else ('.' + self.EXT)
        respm = self._respmat_rb.getvalue()
        respm = respm.reshape(-1, self._csorb.nr_corrs)
        _np.savetxt(fname, respm, header=header)

    def _load_respmat_from_file(self):
        filename = QFileDialog.getOpenFileName(
            caption='Select a Response Matrix File.',
            directory=self.last_dir,
            filter=self.EXT_FLT)
        if not filename[0]:
            return
        respm = _np.loadtxt(filename[0])
        self._respmat_sp.send_value_signal[_np.ndarray].emit(respm.flatten())
        self.respmat_label.setText('Loaded from file: \n\n' + filename[0])

    def _open_load_config_servconf(self):
        win = LoadConfigDialog(self._config_type, self)
        win.configname.connect(self._set_respm)
        win.show()

    def _set_respm(self, confname):
        data = self._client.get_config_value(confname)
        self._respmat_sp.send_value_signal[_np.ndarray].emit(
            _np.array(data).flatten())
        self.respmat_label.setText('Loaded from ServConf: \n\n' + confname)

    def _open_save_config_servconf(self):
        win = SaveConfigDialog(self._config_type, self)
        win.configname.connect(self._save_respm)
        win.show()

    def _save_respm(self, confname):
        val = self._respmat_rb.getvalue()
        val = val.reshape(-1, self._csorb.nr_corrs)
        try:
            self._client.insert_config(confname, val.tolist())
        except (ConfigDBException, TypeError) as err:
            QMessageBox.warning(self, 'Warning', str(err), QMessageBox.Ok)
Example #13
0
 def delete_config(config_type, name):
     """Delete configuration."""
     db = ConfigDBClient()
     return db.delete_config(name, config_type=config_type)
Example #14
0
 def _load(config_type, name):
     db = ConfigDBClient()
     data = db.get_config_info(name, config_type=config_type)
     data['value'] = db.get_config_value(name, config_type=config_type)
     return data
Example #15
0
 def getTuneMatrix(self):
     """Get tune matrix from db."""
     db = ConfigDBClient()
     return db.get_config_value("tune_matrix", "tune_matrix")
Example #16
0
 def getConfigurations(self, deleted=False):
     """Return name of saved configurations."""
     db = ConfigDBClient()
     return db.find_configs(config_type=self._config_type,
                            discarded=deleted)
Example #17
0
 def delete(self):
     """Delete configuration."""
     db = ConfigDBClient()
     db.delete_config(self._name, config_type=self._config_type)
Example #18
0
class OrbitRegister(QWidget):
    """Create the Context Menu for the Registers."""

    DEFAULT_DIR = '/home/sirius/mounts/screens-iocs'

    new_orbx_signal = Signal(_np.ndarray)
    new_orby_signal = Signal(_np.ndarray)
    new_string_signal = Signal(str)

    def __init__(self, parent, device, orbits, idx, prefix='', acc='SI'):
        """Initialize the Context Menu."""
        super(OrbitRegister, self).__init__(parent)
        self.idx = idx
        self.prefix = prefix
        self.device = _PVName(device)
        self.devpref = self.device.substitute(prefix=prefix)
        text = acc.lower() + 'orb'
        self.setObjectName(text + str(idx))
        self.EXT = (f'.{acc.lower()}orb', f'.{acc.lower()}dorb')
        self.EXT_FLT = f'Sirius Orbit Files (*.{text});;' +\
            f'Sirius Delta Orbit Files (*.{acc.lower()}dorb)'
        self._config_type = acc.lower() + '_orbit'
        self._client = ConfigDBClient(config_type=self._config_type)
        self._csorb = SOFBFactory.create(acc.upper())
        self.string_status = 'Empty'
        self.name = 'Register {0:d}'.format(self.idx)
        self.setup_ui()

        self._orbits = orbits
        self.last_dir = self.DEFAULT_DIR
        self.filename = ''
        self._orbx = _np.zeros(self._csorb.nr_bpms)
        self._orby = _np.zeros(self._csorb.nr_bpms)

        self.new_string_signal.emit(self.string_status)

    def getorbx(self):
        """Return the horizontal orbit."""
        return self._orbx.copy()

    orbx = property(fget=getorbx)

    def getorby(self):
        """Return the Vertical orbit."""
        return self._orby.copy()

    orby = property(fget=getorby)

    def setup_ui(self):
        """Set up Ui of Context Menu."""
        self.setStyleSheet("""
            #{}{{
                min-width:11.29em;
            }}""".format(self.objectName()))
        hbl = QHBoxLayout(self)

        btn = QPushButton(self.name, self)
        hbl.addWidget(btn)
        btn.setEnabled(True)
        btn.setAutoDefault(False)

        lbl = QLabel(self)
        hbl.addWidget(lbl)
        sz_pol = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sz_pol.setHorizontalStretch(1)
        lbl.setSizePolicy(sz_pol)
        lbl.setMouseTracking(True)
        lbl.setAcceptDrops(True)
        lbl.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.new_string_signal.connect(lbl.setText)

        menu = QMenu(btn)
        btn.setContextMenuPolicy(Qt.CustomContextMenu)
        btn.setMenu(menu)
        btn.clicked.connect(btn.showMenu)

        act = menu.addAction('Get From &File')
        act.setIcon(qta.icon('mdi.file-download-outline'))
        act.triggered.connect(self._load_orbit_from_file)
        act = menu.addAction('Get From &ServConf')
        act.setIcon(qta.icon('mdi.cloud-download-outline'))
        act.triggered.connect(self._load_orbit_from_servconf)
        menu2 = menu.addMenu('Get from &IOC')
        menu2.setIcon(qta.icon('mdi.download-network-outline'))
        if self._csorb.acc == 'SI':
            act = menu2.addAction('&SlowOrb')
            act.setIcon(qta.icon('mdi.turtle'))
            act.triggered.connect(_part(self._register_orbit, 'orb'))
        if self._csorb.isring:
            act = menu2.addAction('&MTurnOrb')
            act.setIcon(qta.icon('mdi.alarm-multiple'))
            act.triggered.connect(_part(self._register_orbit, 'mti'))
        act = menu2.addAction('S&PassOrb')
        act.setIcon(qta.icon('mdi.clock-fast'))
        act.triggered.connect(_part(self._register_orbit, 'sp'))
        act = menu2.addAction('&RefOrb')
        act.triggered.connect(_part(self._register_orbit, 'ref'))
        act = menu2.addAction('&OfflineOrb')
        act.setIcon(qta.icon('mdi.signal-off'))
        act.triggered.connect(_part(self._register_orbit, 'off'))
        act = menu2.addAction('&BPM Offsets')
        act.setIcon(qta.icon('mdi.currency-sign'))
        act.triggered.connect(_part(self._register_orbit, 'bpm'))
        act = menu2.addAction('RespMat')
        act.setIcon(qta.icon('mdi.matrix'))
        act.triggered.connect(self._open_matrix_sel)
        act = menu.addAction('&Edit Orbit')
        act.setIcon(qta.icon('mdi.table-edit'))
        act.triggered.connect(self._edit_orbit)
        if self._csorb.acc == 'SI':
            act = menu.addAction('Create &Bump')
            act.setIcon(
                qta.icon('mdi.chart-bell-curve',
                         scale_factor=1.2,
                         offset=(-0.2, 0.2)))
            act.triggered.connect(self._create_bump)
        act = menu.addAction('&Clear')
        act.setIcon(qta.icon('mdi.delete-empty'))
        act.triggered.connect(self._reset_orbit)
        act = menu.addAction('Save To File')
        act.setIcon(qta.icon('mdi.file-upload-outline'))
        act.triggered.connect(self._save_orbit_to_file)
        act = menu.addAction('Save To ServConf')
        act.setIcon(qta.icon('mdi.cloud-upload-outline'))
        act.triggered.connect(self._save_orbit_to_servconf)

    def _reset_orbit(self):
        zer = _np.zeros(self._orbx.shape)
        self._update_and_emit('Empty', zer, zer.copy(), '')

    def _register_orbit(self, flag, _):
        pvx, pvy = self._orbits.get(flag, (None, None))
        if not pvx or not pvy:
            self._update_and_emit('Error: wrong specification.')
            return
        if not pvx.connected or not pvy.connected:
            self._update_and_emit('Error: PV {0:s} not connected.'.format(
                pvx.address))
            return
        self._update_and_emit('Orbit Registered.', pvx.getvalue(),
                              pvy.getvalue())

    def _open_matrix_sel(self):
        wid = QDialog(self)
        wid.setObjectName(self._csorb.acc + 'App')
        wid.setLayout(QVBoxLayout())

        cbbox = QComboBox(wid)
        cbbox.setEditable(True)
        cbbox.setMaxVisibleItems(10)
        corrnames = self._csorb.ch_names + self._csorb.cv_names
        if self._csorb.acc in {'SI', 'BO'}:
            corrnames.append('RF')
        cbbox.addItems(corrnames)
        wid.layout().addWidget(QLabel('Choose the corrector:', wid))
        wid.layout().addWidget(cbbox)

        ledit = QDoubleSpinBoxPlus(wid)
        ledit.setMinimum(float('-inf'))
        ledit.setMaximum(float('inf'))
        ledit.setValue(1.0)
        wid.layout().addWidget(QLabel('Choose the Kick [urad]:', wid))
        wid.layout().addWidget(ledit)
        ledit.valueChanged.connect(_part(self._accept_mat_sel, ledit, cbbox))
        cbbox.currentIndexChanged.connect(
            _part(self._accept_mat_sel, ledit, cbbox))

        hlay = QHBoxLayout()
        cancel = QPushButton('Cancel', wid)
        confirm = QPushButton('Ok', wid)
        cancel.clicked.connect(wid.reject)
        confirm.clicked.connect(wid.accept)
        confirm.clicked.connect(_part(self._accept_mat_sel, ledit, cbbox))
        confirm.setDefault(True)
        hlay.addStretch()
        hlay.addWidget(cancel)
        hlay.addStretch()
        hlay.addWidget(confirm)
        hlay.addStretch()
        wid.layout().addItem(hlay)
        res = wid.exec_()

        if res != QDialog.Accepted:
            self._reset_orbit()

    def _accept_mat_sel(self, ledit, cbbox, _):
        idx = cbbox.currentIndex()
        corr = cbbox.currentText()
        kick = ledit.value()
        pvm = self._orbits.get('mat')
        if pvm is None or not pvm.connected:
            self._update_and_emit('Error: PV {0:s} not connected.'.format(
                pvm.address))
            return
        val = pvm.getvalue()
        orbs = val.reshape(-1, self._csorb.nr_corrs)[:, idx]
        orbx = orbs[:len(orbs) // 2] * kick
        orby = orbs[len(orbs) // 2:] * kick
        self._update_and_emit('RespMat: {0:s}'.format(corr), orbx, orby)

    def _edit_orbit(self):
        orbx = self.orbx
        orby = self.orby

        wid = QDialog(self)
        wid.setObjectName(self._csorb.acc + 'App')
        wid.setLayout(QVBoxLayout())

        hbl = QHBoxLayout()
        wid.layout().addItem(hbl)
        hbl.addWidget(QLabel('X = ', wid))
        multx = QLineEdit(wid)
        multx.setValidator(QDoubleValidator())
        multx.setText('1.0')
        # multx.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
        multx.setAlignment(Qt.AlignCenter)
        multx.setStyleSheet('max-width:5em;')
        hbl.addWidget(multx)
        hbl.addWidget(QLabel('*X   +   ', wid))
        addx = QLineEdit(wid)
        addx.setValidator(QDoubleValidator())
        addx.setText('0.0')
        addx.setAlignment(Qt.AlignCenter)
        addx.setStyleSheet('max-width:5em;')
        hbl.addWidget(addx)
        hbl.addWidget(QLabel(' [um]', wid))

        hbl = QHBoxLayout()
        wid.layout().addItem(hbl)
        hbl.addWidget(QLabel('Y = ', wid))
        multy = QLineEdit(wid)
        multy.setValidator(QDoubleValidator())
        multy.setText('1.0')
        # multy.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
        multy.setAlignment(Qt.AlignCenter)
        multy.setStyleSheet('max-width:5em;')
        hbl.addWidget(multy)
        hbl.addWidget(QLabel('*Y   +   ', wid))
        addy = QLineEdit(wid)
        addy.setValidator(QDoubleValidator())
        addy.setText('0.0')
        addy.setAlignment(Qt.AlignCenter)
        addy.setStyleSheet('max-width:5em;')
        hbl.addWidget(addy)
        hbl.addWidget(QLabel(' [um]', wid))

        hlay = QHBoxLayout()
        cancel = QPushButton('Cancel', wid)
        confirm = QPushButton('Ok', wid)
        confirm.setDefault(True)
        cancel.clicked.connect(wid.reject)
        confirm.clicked.connect(wid.accept)
        hlay.addStretch()
        hlay.addWidget(cancel)
        hlay.addStretch()
        hlay.addWidget(confirm)
        hlay.addStretch()
        wid.layout().addItem(hlay)
        res = wid.exec_()

        if res != QDialog.Accepted:
            return
        mltx = float(multx.text())
        mlty = float(multy.text())
        plusx = float(addx.text())
        plusy = float(addy.text())
        orbx = mltx * orbx + plusx
        orby = mlty * orby + plusy
        txt = ''
        txt += f'multx = {mltx:5.1f} offx = {plusx:7.1f}\n'
        txt += f'multy = {mlty:5.1f} offy = {plusy:7.1f}'
        self._update_and_emit(txt, orbx, orby)

    def _create_bump(self):
        def _add_entry(index):
            cbox = self.sender()
            text = cbox.itemText(index)
            if not text.startswith('other'):
                return
            win = LoadConfigDialog(self._config_type, self)
            confname, status = win.exec_()
            if not status:
                cbox.setCurrentIndex(0)
                return
            cbox.insertItem(index, confname)
            cbox.setCurrentIndex(index)

        wid = QDialog(self)
        wid.setObjectName(self._csorb.acc + 'App')
        lay = QGridLayout()
        wid.setLayout(lay)

        row = 0
        lay.addWidget(QLabel('Base Orbit ', wid), row, 0)
        orbcombo = QComboBox(wid)
        orbcombo.addItems(['Register', 'ref_orb', 'bba_orb', 'other...'])
        orbcombo.setCurrentIndex(1)
        orbcombo.activated.connect(_add_entry)
        lay.addWidget(orbcombo, row, 1)

        row += 1
        lay.addWidget(QLabel('Subsection', wid), row, 0)
        sscombo = QComboBox(wid)
        sub = ['SA', 'SB', 'SP', 'SB']
        ssnames = [f'{d+1:02d}{sub[d%len(sub)]}' for d in range(20)]
        bcnames = [f'{d+1:02d}BC' for d in range(20)]
        names = []
        for aaa, bbb in zip(ssnames, bcnames):
            names.extend([aaa, bbb])
        sscombo.addItems(names)
        lay.addWidget(sscombo, row, 1)

        row += 1
        lay.addWidget(QLabel('\u03B8<sub>x</sub> [urad]', wid), row, 0)
        angx = QLineEdit(wid)
        angx.setValidator(QDoubleValidator())
        angx.setText('0.0')
        angx.setAlignment(Qt.AlignCenter)
        angx.setStyleSheet('max-width:5em;')
        lay.addWidget(angx, row, 1)

        row += 1
        lay.addWidget(QLabel('X [um] ', wid), row, 0)
        posx = QLineEdit(wid)
        posx.setValidator(QDoubleValidator())
        posx.setText('0.0')
        posx.setAlignment(Qt.AlignCenter)
        posx.setStyleSheet('max-width:5em;')
        lay.addWidget(posx, row, 1)

        row += 1
        lay.addWidget(QLabel('\u03B8<sub>y</sub> [urad]', wid), row, 0)
        angy = QLineEdit(wid)
        angy.setValidator(QDoubleValidator())
        angy.setText('0.0')
        angy.setAlignment(Qt.AlignCenter)
        angy.setStyleSheet('max-width:5em;')
        lay.addWidget(angy, row, 1)

        row += 1
        lay.addWidget(QLabel('Y [um] ', wid), row, 0)
        posy = QLineEdit(wid)
        posy.setValidator(QDoubleValidator())
        posy.setText('0.0')
        posy.setAlignment(Qt.AlignCenter)
        posy.setStyleSheet('max-width:5em;')
        lay.addWidget(posy, row, 1)

        row += 1
        hlay = QHBoxLayout()
        cancel = QPushButton('Cancel', wid)
        confirm = QPushButton('Ok', wid)
        confirm.setDefault(True)
        cancel.clicked.connect(wid.reject)
        confirm.clicked.connect(wid.accept)
        hlay.addStretch()
        hlay.addWidget(cancel)
        hlay.addStretch()
        hlay.addWidget(confirm)
        hlay.addStretch()
        wid.layout().addItem(hlay, row, 0, 1, 2)
        res = wid.exec_()
        if res != QDialog.Accepted:
            return

        index = orbcombo.currentIndex()
        confname = orbcombo.itemText(index)
        if not index:
            orbx = _np.array(self.orbx)
            orby = _np.array(self.orby)
        elif index == orbcombo.count() - 1:
            return
        else:
            orbs = self._client.get_config_value(confname)
            orbx = _np.array(orbs['x'])
            orby = _np.array(orbs['y'])

        agx = float(angx.text())
        agy = float(angy.text())
        psx = float(posx.text())
        psy = float(posy.text())
        sub = sscombo.currentText()
        orbx, orby = _calculate_bump(orbx, orby, sub, agx, agy, psx, psy)

        txt = f'Bump@{sub}: ref={confname}\n'
        txt += f'ax={agx:.1f} ay={agy:.1f} dx={psx:.1f} dy={psy:.1f}'
        self._update_and_emit(txt, orbx, orby)

    def _save_orbit_to_file(self, _):
        header = '# ' + _datetime.now().strftime('%Y/%m/%d-%H:%M:%S') + '\n'
        header += '# ' + 'BPMX [um]         BPMY [um]             Name' + '\n'
        filename = QFileDialog.getSaveFileName(
            caption='Define a File Name to Save the Orbit',
            directory=self.last_dir,
            filter=self.EXT_FLT)
        fname = filename[0]
        if not fname:
            return
        fname += '' if fname.endswith(self.EXT) else self.EXT[0]
        data = _np.array([self.orbx, self.orby, self._csorb.bpm_names],
                         dtype=object)
        _np.savetxt(fname,
                    data.T,
                    header=header,
                    fmt='%+18.8e %+18.8e      %s')
        self._update_and_emit('Orbit Saved: ', self.orbx, self.orby, fname)

    def _load_orbit_from_file(self):
        filename = QFileDialog.getOpenFileName(caption='Select an Orbit File.',
                                               directory=self.last_dir,
                                               filter=self.EXT_FLT)
        if not filename[0]:
            return
        orbx, orby = _np.loadtxt(filename[0], unpack=True, usecols=(0, 1))
        self._update_and_emit('Orbit Loaded: ', orbx, orby, filename[0])

    def _load_orbit_from_servconf(self):
        win = LoadConfigDialog(self._config_type, self)
        win.configname.connect(self._set_orbit)
        win.show()

    def _set_orbit(self, confname):
        data = self._client.get_config_value(confname)
        self._update_and_emit('Orbit Loaded: ' + confname,
                              _np.array(data['x']), _np.array(data['y']))

    def _save_orbit_to_servconf(self):
        win = SaveConfigDialog(self._config_type, self)
        win.configname.connect(self._save_orbit)
        win.show()

    def _save_orbit(self, confname):
        data = {'x': self._orbx.tolist(), 'y': self.orby.tolist()}
        try:
            self._client.insert_config(confname, data)
        except (ConfigDBException, TypeError) as err:
            QMessageBox.warning(self, 'Warning', str(err), QMessageBox.Ok)

    def _update_and_emit(self, string, orbx=None, orby=None, fname=''):
        if orbx is None or orby is None:
            self.string_status = string
            self.new_string_signal.emit(self.string_status)
            return
        self._orbx = orbx
        self._orby = orby
        pure_name = ''
        path = self.last_dir
        if fname:
            path, pure_name = fname.rsplit('/', 1)
        self.string_status = string + pure_name
        self.filename = fname
        self.last_dir = path
        self.new_orbx_signal.emit(orbx)
        self.new_orby_signal.emit(orby)
        self.new_string_signal.emit(self.string_status)
Example #19
0
 def __init__(self, prefix=VACA_PREFIX):
     super().__init__()
     self._client = ConfigDBClient(config_type='si_orbit')
     self._prefix = prefix
Example #20
0
class BaseCombo(QComboBox, PyDMPrimitiveWidget):
    """."""

    configname = Signal(str)

    def __init__(self, parent, ctrls, setpoint=None, readback=None, acc='SI'):
        """."""
        QComboBox.__init__(self, parent)
        PyDMPrimitiveWidget.__init__(self)
        self.setpoint = setpoint or dict()
        self.readback = readback or dict()
        self.ctrls = ctrls
        self._csorb = SOFBFactory.create(acc)
        self._config_type = acc.lower() + '_orbit'
        self._client = ConfigDBClient(config_type=self._config_type)
        self.orbits = {
            'x': _np.zeros(self._csorb.nr_bpms, dtype=float),
            'y': _np.zeros(self._csorb.nr_bpms, dtype=float)
        }
        self.signals_to_watch = dict()
        self.slots = {
            'x': _part(self._watch_if_changed, 'x'),
            'y': _part(self._watch_if_changed, 'y')
        }

        self.setup_ui()
        self.connect_signals()

    @property
    def acc(self):
        """."""
        return self._csorb.acc

    @property
    def acc_idx(self):
        """."""
        return self._csorb.acc_idx

    @property
    def isring(self):
        """."""
        return self._csorb.isring

    def channels(self):
        """."""
        chans = list(self.readback.values())
        chans += list(self.setpoint.values())
        return chans

    def connect_signals(self):
        """."""
        for pln in ('x', 'y'):
            self.readback[pln].new_value_signal[_np.ndarray].connect(
                _part(self.ioc_orbit_changed, pln))

    def setup_ui(self, add_items=None):
        """."""
        sz_pol = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        self.setSizePolicy(sz_pol)
        add_items = add_items or []
        add_items.extend(['Zero', 'ServConf'])
        for item in add_items:
            self.addItem(item)
        for reg in sorted(self.ctrls.keys()):
            self.addItem(reg)
        self.addItem('Out of Date')
        self.setCurrentIndex(self.count() - 1)
        self.activated.connect(self._item_selected)

    def _item_selected(self, index):
        text = self.itemText(index)
        self._selection_changed(text)

    def _selection_changed(self, text, sigs=None):
        sigs = sigs or dict()
        if not text.lower().startswith('servconf'):
            self.configname.emit('')
        if text.lower().startswith('zero'):
            for pln in ('x', 'y'):
                if self.orbits[pln] is not None:
                    self.orbits[pln] *= 0
                    self.setpoint[pln].send_value_signal[_np.ndarray].emit(
                        self.orbits[pln])
        elif text.lower().startswith('servconf'):
            win = LoadConfigDialog(self._config_type, self)
            confname, status = win.exec_()
            if not status:
                return
            data = self._client.get_config_value(confname)
            self.configname.emit(confname)
            for pln in ('x', 'y'):
                self.orbits[pln] = _np.array(data[pln])
                self.setpoint[pln].send_value_signal[_np.ndarray].emit(
                    self.orbits[pln])
        elif text in self.ctrls:
            for pln in ('x', 'y'):
                orb = self.ctrls[text][pln]['getvalue']()
                if orb is None:
                    return
                self.orbits[pln] = orb
                sigs[pln] = self.ctrls[text][pln]['signal']
                self.setpoint[pln].send_value_signal[_np.ndarray].emit(
                    self.orbits[pln])
        for pln in ('x', 'y'):
            if self.signals_to_watch:
                self.signals_to_watch[pln].disconnect(self.slots[pln])
            if sigs:
                sigs[pln].connect(self.slots[pln])
        self.signals_to_watch = sigs

    def ioc_orbit_changed(self, pln, orb):
        """."""
        self._orbit_changed(pln, orb)

    def _watch_if_changed(self, pln, orb):
        self._orbit_changed(pln, orb)

    def _orbit_changed(self, pln, orb):
        myorb = self.orbits[pln]
        if myorb is not None and myorb.size == orb.size and \
                _np.allclose(orb, myorb, rtol=1e-7):
            return
        self.setCurrentIndex(self.count() - 1)
        self.configname.emit('')
Example #21
0
 def __init__(self, parent=None, url=None):
     """Setup UI."""
     super().__init__(parent)
     self._client = ConfigDBClient(url)
     self._setup_ui()
     self.setWindowTitle("PVs Configuration Manager")
Example #22
0
class BaseObject(BaseOrbitIntlk):
    """Base SI BPM info object."""

    CONV_NM2M = 1e-9  # [nm] --> [m]
    CONV_UM2NM = 1e+3  # [um] --> [nm]

    CONV_POLY_MONIT1_2_MONIT = OrbitInterlock.CONV_POLY_MONIT1_2_MONIT

    _pvs = dict()

    def __init__(self, prefix=VACA_PREFIX):
        super().__init__()
        self._client = ConfigDBClient(config_type='si_orbit')
        self._prefix = prefix

    def get_ref_orb(self, configname):
        """Get reference orbit from config [um].

        Args:
            configname (str): si orbit configuration name.

        Returns:
            si_orbit: si orbit configuration value from ConfigDB
        """
        try:
            configvalue = self._client.get_config_value(configname)
            value = dict()
            value['x'] = _np.array(configvalue['x']) * self.CONV_UM2NM
            value['y'] = _np.array(configvalue['y']) * self.CONV_UM2NM
        except:
            value = dict()
            value['x'] = _np.zeros(len(self.BPM_NAMES), dtype=float)
            value['y'] = _np.zeros(len(self.BPM_NAMES), dtype=float)
        return value

    # --- pv handler methods ---

    def _create_pvs(self, propty):
        new_pvs = dict()
        for psn in self.BPM_NAMES:
            pvname = SiriusPVName(psn).substitute(prefix=self._prefix,
                                                  propty=propty)
            if pvname in self._pvs:
                continue
            new_pvs[pvname] = _PV(pvname,
                                  auto_monitor=False,
                                  connection_timeout=0.01)
        self._pvs.update(new_pvs)

    def _get_values(self, propty):
        for psn in self.BPM_NAMES:
            pvname = SiriusPVName(psn).substitute(prefix=self._prefix,
                                                  propty=propty)
            self._pvs[pvname].wait_for_connection()

        values = list()
        for psn in self.BPM_NAMES:
            pvname = SiriusPVName(psn).substitute(prefix=self._prefix,
                                                  propty=propty)
            try:
                val = self._pvs[pvname].get()
            except ChannelAccessException:
                val = None
            if val is None:
                val = 0
            elif propty.startswith('Intlk') and propty.endswith('-Mon'):
                val = 1 if val == 0 else 0
            values.append(val)
        return values
#!/usr/bin/env python-sirius
"""Lauch PVs configuration manager."""
import sys
from siriushla.sirius_application import SiriusApplication
from siriuspy.clientconfigdb import ConfigDBClient
from siriushla.as_ap_configdb.pvsconfigs import \
    LoadAndApplyConfig2MachineWindow

app = SiriusApplication()
client = ConfigDBClient()
app.open_window(LoadAndApplyConfig2MachineWindow, parent=None, client=client)
sys.exit(app.exec_())
Example #24
0
#!/usr/bin/env python-sirius
"""Lauch configuration database manager."""
import sys

from siriushla.sirius_application import SiriusApplication
from siriuspy.clientconfigdb import ConfigDBClient
from siriushla.as_ap_configdb import ConfigurationManager

app = SiriusApplication()
model = ConfigDBClient()
app.open_window(ConfigurationManager, parent=None, model=model)
sys.exit(app.exec_())