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
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
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 _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']))
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()
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")
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()
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_()
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)
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)
def delete_config(config_type, name): """Delete configuration.""" db = ConfigDBClient() return db.delete_config(name, config_type=config_type)
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
def getTuneMatrix(self): """Get tune matrix from db.""" db = ConfigDBClient() return db.get_config_value("tune_matrix", "tune_matrix")
def getConfigurations(self, deleted=False): """Return name of saved configurations.""" db = ConfigDBClient() return db.find_configs(config_type=self._config_type, discarded=deleted)
def delete(self): """Delete configuration.""" db = ConfigDBClient() db.delete_config(self._name, config_type=self._config_type)
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)
def __init__(self, prefix=VACA_PREFIX): super().__init__() self._client = ConfigDBClient(config_type='si_orbit') self._prefix = prefix
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('')
def __init__(self, parent=None, url=None): """Setup UI.""" super().__init__(parent) self._client = ConfigDBClient(url) self._setup_ui() self.setWindowTitle("PVs Configuration Manager")
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_())
#!/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_())