def __init__(self, session): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(session, direct=not self.multi_step) self.corrector.start() self.init_controls() self.set_initial_values() self.connect_signals()
def __init__(self, session): super().__init__() load_ui(self, __package__, self.ui_file) self.control = session.control self.model = session.model() self.corrector = Corrector(session, False) self.corrector.setup({ 'monitors': [], }) self.corrector.start() self.bot = ProcBot(self, self.corrector) self.init_controls() self.set_initial_values() self.connect_signals()
def __init__(self, corrector): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(corrector.session, False) self.corrector.setup({ 'monitors': corrector.monitors, 'optics': corrector.variables, }) self.corrector.start() self.bot = ProcBot(self, self.corrector) elem_by_knob = {} for elem in corrector.model.elements: for knob in corrector.model.get_elem_knobs(elem): elem_by_knob.setdefault(knob.lower(), elem) self.steerers = [ elem_by_knob[v.lower()] for v in corrector.variables ] self.corrector.add_record = self.add_record self.raw_records = [] self.init_controls() self.set_initial_values() self.connect_signals()
def test_simple_procedure(session): session.load_model('sample_model/sample') session.control.set_backend('hit_acs.plugin:TestACS') session.control.connect() corrector = Corrector(session) assert corrector is not None # for lack of a better test;) for now
def corrector(session): session.load_model('sample_model/sample') session.control.set_backend('hit_acs.plugin:TestACS') session.control.connect() corrector = Corrector(session) corrector.setup({ 'monitors': [ 'monitor1', 'monitor2', ], 'optics': [ 'kL_q31', 'kL_q32', 'ax_K1', 'ay_K1', ], }) return corrector
def corrector(session): session.load_model('hit_models/hht3') session.control.set_backend('hit_acs.plugin:TestACS') session.control.connect() corrector = Corrector(session) corrector.setup({ 'monitors': [ 't3dg2g', 't3dg1g', 't3df1', ], 'optics': [ 'ax_g3mw2', 'ax_g3ms2', 'ay_g3mw1', 'ay_g3ms1', ], }) return corrector
def __init__(self, corrector): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(corrector.session, False) self.corrector.setup({ 'monitors': corrector.monitors, 'optics': corrector.variables, }) self.corrector.start() self.bot = ProcBot(self, self.corrector) elem_by_knob = {} for elem in corrector.model.elements: for knob in corrector.model.get_elem_knobs(elem): elem_by_knob.setdefault(knob.lower(), elem) self.steerers = [elem_by_knob[v.lower()] for v in corrector.variables] self.corrector.add_record = self.add_record self.raw_records = [] self.init_controls() self.set_initial_values() self.connect_signals()
class MeasureWidget(QWidget): ui_file = 'orm_measure.ui' extension = '.orm_measurement.yml' def __init__(self, corrector): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(corrector.session, False) self.corrector.setup({ 'monitors': corrector.monitors, 'optics': corrector.variables, }) self.corrector.start() self.bot = ProcBot(self, self.corrector) elem_by_knob = {} for elem in corrector.model.elements: for knob in corrector.model.get_elem_knobs(elem): elem_by_knob.setdefault(knob.lower(), elem) self.steerers = [ elem_by_knob[v.lower()] for v in corrector.variables ] self.corrector.add_record = self.add_record self.raw_records = [] self.init_controls() self.set_initial_values() self.connect_signals() def add_record(self, step, shot): if shot == 0: self.raw_records.append([]) records = {r.name: r.data for r in self.corrector.readouts} self.raw_records[-1].append(records) self.corrector.write_shot(step, shot, { monitor: [data['posx'], data['posy'], data['envx'], data['envy']] for monitor, data in records.items() }) def sizeHint(self): return QSize(600, 400) def init_controls(self): self.opticsTable.set_viewmodel( self.get_corrector_row, unit=(None, 'kick')) def set_initial_values(self): self.d_phi = {} self.default_dphi = 2e-4 self.opticsTable.rows[:] = self.steerers self.fileEdit.setText( "{date}_{time}_{sequence}_{monitor}"+self.extension) self.update_ui() def connect_signals(self): self.startButton.clicked.connect(self.start_bot) self.cancelButton.clicked.connect(self.cancel) def get_corrector_row(self, i, c) -> ("Kicker", "ΔΦ"): return [ TableItem(c.name), TableItem(self.d_phi.get(c.name.lower(), self.default_dphi), name='kick', set_value=self.set_kick, delegate=delegates[float]), ] def set_kick(self, i, c, value): self.d_phi[c.name.lower()] = value @property def running(self): return bool(self.bot) and self.bot.running def closeEvent(self, event): self.bot.cancel() super().closeEvent(event) def update_ui(self): running = self.running valid = bool(self.corrector.optic_params) self.cancelButton.setEnabled(running) self.startButton.setEnabled(not running and valid) self.numIgnoredSpinBox.setEnabled(not running) self.numUsedSpinBox.setEnabled(not running) self.opticsTable.setEnabled(not running) self.progressBar.setEnabled(running) self.progressBar.setRange(0, self.bot.totalops) self.progressBar.setValue(self.bot.progress) def set_progress(self, progress): self.progressBar.setValue(progress) def update_fit(self): """Called when procedure finishes succesfully.""" full_data = np.array([ [ np.mean([ [shot[monitor]['posx'], shot[monitor]['posy']] for shot in series ], axis=0) for monitor in self.corrector.monitors ] for series in self.raw_records ]) differences = full_data[1:] - full_data[[0]] deltas = [ self.d_phi.get(v.lower(), self.default_dphi) for v in self.corrector.variables ] self.final_orm = [ ORM_Entry(mon, var, *differences[i_var, i_mon] / deltas[i_var]) for i_var, var in enumerate(self.corrector.variables) for i_mon, mon in enumerate(self.corrector.monitors) ] self.window().accept() def start_bot(self): self.corrector.set_optics_delta(self.d_phi, self.default_dphi) self.bot.start( self.numIgnoredSpinBox.value(), self.numUsedSpinBox.value()) now = time.localtime(time.time()) fname = os.path.join( '.', self.fileEdit.text().format( date=time.strftime("%Y-%m-%d", now), time=time.strftime("%H-%M-%S", now), sequence=self.corrector.model.seq_name, monitor=self.corrector.monitors[-1], )) self.corrector.open_export(fname) def cancel(self): self.bot.cancel() self.window().reject() def log(self, text, *args, **kwargs): formatted = text.format(*args, **kwargs) self.logEdit.appendPlainText(formatted)
class CorrectorWidget(QWidget): ui_file = 'multi_grid.ui' data_key = 'multi_grid' multi_step = False def __init__(self, session): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(session, direct=not self.multi_step) self.corrector.start() self.init_controls() self.set_initial_values() self.connect_signals() def closeEvent(self, event): self.corrector.stop() self.view.hide_monitor_readouts() super().closeEvent(event) def on_execute_corrections(self): """Apply calculated corrections.""" self.corrector.apply() self.update_status() def init_controls(self): self.configSelect.set_corrector(self.corrector, self.data_key) self.fitSettingsWidget.set_corrector(self.corrector) self.monitorTable.set_corrector(self.corrector) self.targetsTable.set_corrector(self.corrector) self.resultsTable.set_corrector(self.corrector) self.view = self.corrector.session.window().open_graph('orbit') def set_initial_values(self): self.fitButton.setFocus() self.update_status() def connect_signals(self): self.corrector.setup_changed.connect(self.update_status) self.corrector.saved_optics.changed.connect(self.update_ui) self.corrector.strategy.changed.connect(self.update_fit) self.corrector.use_backtracking.changed.connect(self.update_fit) self.fitButton.clicked.connect(self.update_fit) self.applyButton.clicked.connect(self.on_execute_corrections) self.prevButton.setDefaultAction( self.corrector.saved_optics.create_undo_action(self)) self.nextButton.setDefaultAction( self.corrector.saved_optics.create_redo_action(self)) def update_status(self): self.corrector.update_vars() self.corrector.update_records() self.update_ui() def update_fit(self, *_): """Calculate initial positions / corrections.""" self.corrector.update_vars() self.corrector.update_records() self.corrector.update_fit() self.update_ui() @Queued.method def update_ui(self): saved_optics = self.corrector.saved_optics self.applyButton.setEnabled( self.corrector.online_optic != saved_optics()) if saved_optics() is not None: self.corrector.variables.touch() self.view.show_monitor_readouts(self.corrector.monitors[:])
class MeasureWidget(QWidget): ui_file = 'orm_measure.ui' extension = '.orm_measurement.yml' def __init__(self, corrector): super().__init__() load_ui(self, __package__, self.ui_file) self.corrector = Corrector(corrector.session, False) self.corrector.setup({ 'monitors': corrector.monitors, 'optics': corrector.variables, }) self.corrector.start() self.bot = ProcBot(self, self.corrector) elem_by_knob = {} for elem in corrector.model.elements: for knob in corrector.model.get_elem_knobs(elem): elem_by_knob.setdefault(knob.lower(), elem) self.steerers = [elem_by_knob[v.lower()] for v in corrector.variables] self.corrector.add_record = self.add_record self.raw_records = [] self.init_controls() self.set_initial_values() self.connect_signals() def add_record(self, step, shot): if shot == 0: self.raw_records.append([]) records = {r.name: r.data for r in self.corrector.readouts} self.raw_records[-1].append(records) self.corrector.write_shot( step, shot, { monitor: [data['posx'], data['posy'], data['envx'], data['envy']] for monitor, data in records.items() }) def sizeHint(self): return QSize(600, 400) def init_controls(self): self.opticsTable.set_viewmodel(self.get_corrector_row, unit=(None, 'kick')) def set_initial_values(self): self.d_phi = {} self.default_dphi = 2e-4 self.opticsTable.rows[:] = self.steerers self.fileEdit.setText("{date}_{time}_{sequence}_{monitor}" + self.extension) self.update_ui() def connect_signals(self): self.startButton.clicked.connect(self.start_bot) self.cancelButton.clicked.connect(self.cancel) def get_corrector_row(self, i, c) -> ("Kicker", "ΔΦ"): return [ TableItem(c.name), TableItem(self.d_phi.get(c.name.lower(), self.default_dphi), name='kick', set_value=self.set_kick, delegate=delegates[float]), ] def set_kick(self, i, c, value): self.d_phi[c.name.lower()] = value @property def running(self): return bool(self.bot) and self.bot.running def closeEvent(self, event): self.bot.cancel() super().closeEvent(event) def update_ui(self): running = self.running valid = bool(self.corrector.optic_params) self.cancelButton.setEnabled(running) self.startButton.setEnabled(not running and valid) self.numIgnoredSpinBox.setEnabled(not running) self.numUsedSpinBox.setEnabled(not running) self.opticsTable.setEnabled(not running) self.progressBar.setEnabled(running) self.progressBar.setRange(0, self.bot.totalops) self.progressBar.setValue(self.bot.progress) def set_progress(self, progress): self.progressBar.setValue(progress) def update_fit(self): """Called when procedure finishes succesfully.""" full_data = np.array([[ np.mean([[shot[monitor]['posx'], shot[monitor]['posy']] for shot in series], axis=0) for monitor in self.corrector.monitors ] for series in self.raw_records]) differences = full_data[1:] - full_data[[0]] deltas = [ self.d_phi.get(v.lower(), self.default_dphi) for v in self.corrector.variables ] self.final_orm = [ ORM_Entry(mon, var, *differences[i_var, i_mon] / deltas[i_var]) for i_var, var in enumerate(self.corrector.variables) for i_mon, mon in enumerate(self.corrector.monitors) ] self.window().accept() def start_bot(self): self.corrector.set_optics_delta(self.d_phi, self.default_dphi) self.bot.start(self.numIgnoredSpinBox.value(), self.numUsedSpinBox.value()) now = time.localtime(time.time()) fname = os.path.join( '.', self.fileEdit.text().format( date=time.strftime("%Y-%m-%d", now), time=time.strftime("%H-%M-%S", now), sequence=self.corrector.model.seq_name, monitor=self.corrector.monitors[-1], )) self.corrector.open_export(fname) def cancel(self): self.bot.cancel() self.window().reject() def log(self, text, *args, **kwargs): formatted = text.format(*args, **kwargs) self.logEdit.appendPlainText(formatted)
class MeasureWidget(QWidget): ui_file = 'orm_measure.ui' extension = '.orm_measurement.yml' def __init__(self, session): super().__init__() load_ui(self, __package__, self.ui_file) self.control = session.control self.model = session.model() self.corrector = Corrector(session, False) self.corrector.setup({ 'monitors': [], }) self.corrector.start() self.bot = ProcBot(self, self.corrector) self.init_controls() self.set_initial_values() self.connect_signals() def sizeHint(self): return QSize(600, 400) def init_controls(self): self.opticsTable.set_viewmodel(self.get_corrector_row) self.monitorTable.set_viewmodel(self.get_monitor_row) self.view = self.corrector.session.window().open_graph('orbit') def set_initial_values(self): self.set_folder('.') # FIXME self.fileEdit.setText( "{date}_{time}_{sequence}_{monitor}"+self.extension) self.d_phi = {} self.opticsTable.rows[:] = [] self.monitorTable.rows[:] = self.corrector.all_monitors self.update_ui() def connect_signals(self): self.folderButton.clicked.connect(self.change_output_file) self.startButton.clicked.connect(self.start_bot) self.cancelButton.clicked.connect(self.bot.cancel) self.monitorTable.selectionModel().selectionChanged.connect( self.monitor_selection_changed) self.filterEdit.textChanged.connect(lambda _: self._update_knobs()) self.defaultSpinBox.valueChanged.connect( lambda _: self.opticsTable.rows.touch()) def get_monitor_row(self, i, m) -> ("Monitor",): return [ TableItem(m), ] def get_corrector_row(self, i, c) -> ("Param", "Δ"): default = self.defaultSpinBox.value() or None return [ TableItem(c.name), TableItem( self.d_phi.get(c.name.lower(), default), set_value=self.set_delta, delegate=delegates[float]), ] def set_delta(self, i, c, value): self.d_phi[c.name.lower()] = value def monitor_selection_changed(self, selected, deselected): self.corrector.setup({ 'monitors': [ self.corrector.all_monitors[idx.row()] for idx in self.monitorTable.selectedIndexes() ], }) self._update_knobs() self.update_ui() def _update_knobs(self): match = self._get_filter() if not match: return elements = self.model.elements last_mon = elements.index(self.corrector.monitors[-1]) self.opticsTable.rows = [ self.corrector._knobs[knob.lower()] for elem in elements if elem.index < last_mon for knob in self.model.get_elem_knobs(elem) if knob.lower() in self.corrector._knobs and match.search(knob.lower()) ] def _get_filter(self): text = self.filterEdit.text() text = text.replace(' ', '') try: return re.compile(text, re.ASCII | re.IGNORECASE) except re.error: return None def change_output_file(self): from madgui.widget.filedialog import getSaveFolderName folder = getSaveFolderName( self.window(), 'Output folder', self.folder) if folder: self.set_folder(folder) def set_folder(self, folder): self.folder = os.path.abspath(folder) self.folderEdit.setText(self.folder) @property def running(self): return bool(self.bot) and self.bot.running def closeEvent(self, event): self.bot.cancel() super().closeEvent(event) def update_ui(self): running = self.running valid = bool(self.opticsTable.rows and self._get_filter()) self.cancelButton.setEnabled(running) self.startButton.setEnabled(not running and valid) self.folderButton.setEnabled(not running) self.numIgnoredSpinBox.setEnabled(not running) self.numUsedSpinBox.setEnabled(not running) self.monitorTable.setEnabled(not running) self.opticsTable.setEnabled(not running) self.progressBar.setEnabled(running) self.progressBar.setRange(0, self.bot.totalops) self.progressBar.setValue(self.bot.progress) def set_progress(self, progress): self.progressBar.setValue(progress) def update_fit(self): """Called when procedure finishes succesfully.""" pass def start_bot(self): self.corrector.set_optics_delta(self.d_phi, self.defaultSpinBox.value()) now = time.localtime(time.time()) fname = os.path.join( self.folderEdit.text(), self.fileEdit.text().format( date=time.strftime("%Y-%m-%d", now), time=time.strftime("%H-%M-%S", now), sequence=self.model.seq_name, monitor=self.corrector.monitors[-1], )) self.corrector.open_export(fname) self.bot.start( self.numIgnoredSpinBox.value(), self.numUsedSpinBox.value()) def log(self, text, *args, **kwargs): formatted = text.format(*args, **kwargs) logging.info(formatted) self.logEdit.appendPlainText(formatted)
def main(model_file, spec_file, record_file): """ Usage: analysis MODEL PARAMS RECORDS MODEL must be the path of the model/sequence file to initialize MAD-X. PARAMS is a YAML file with arguments for the "measurement" procedure, it must contain at least a list of `monitors` and `optics` and should contain keys for errors to be inserted: `knobs`, `ealign`, `efcomp` RECORDS is the name of the YAML output file where """ init_app([], gui=False) config = load_config(isolated=True) with ExitStack() as stack: setup_args = yaml.load_file(spec_file)['procedure'] session = stack.enter_context(Session(config)) session.control._settings.update({ 'shot_interval': 0.001, 'jitter': setup_args.get('jitter', True), 'auto_params': False, 'auto_sd': True, }) session.load_model(model_file, stdout=False, command_log=lambda text: print("X:>", text)) session.control.set_backend('hit_acs.plugin:TestACS') session.control.connect() session.control.write_all() corrector = Corrector(session) corrector.setup({ 'monitors': setup_args['monitors'], 'optics': setup_args['optics'], }) # FIXME: this is not yet compatible with general parameter errors. In # order to fix this, the hit_acs test backend will have to use an # independent model! model = session.model() import_errors(model, setup_args['errors']) model.twiss.invalidate() corrector.set_optics_delta(setup_args.get('optics_deltas', {}), setup_args.get('default_delta', 1e-4)) corrector.open_export(record_file) widget = mock.Mock() procbot = ProcBot(widget, corrector) num_mons = len(setup_args['monitors']) num_optics = len(setup_args['optics']) + 1 if setup_args.get('jitter', True): num_ignore = setup_args.get('num_ignore', 1) num_shots = setup_args.get('num_shots', 5) else: num_ignore = 0 num_shots = 1 procbot.start(num_ignore, num_shots, gui=False) total_steps = num_mons * (num_optics + 1) * (num_ignore + num_shots) i = 0 while procbot.running and i < 2 * total_steps: procbot._feed(None, None) time.sleep(0.010) i += 1 assert not procbot.running
class MeasureWidget(QWidget): ui_file = 'orm_measure.ui' extension = '.orm_measurement.yml' def __init__(self, session): super().__init__() load_ui(self, __package__, self.ui_file) self.control = session.control self.model = session.model() self.corrector = Corrector(session, False) self.corrector.setup({ 'monitors': [], }) self.corrector.start() self.bot = ProcBot(self, self.corrector) self.init_controls() self.set_initial_values() self.connect_signals() def sizeHint(self): return QSize(600, 600) def init_controls(self): self.opticsTable.set_viewmodel(self.get_corrector_row) self.monitorTable.set_viewmodel(self.get_monitor_row) self.view = self.corrector.session.window().open_graph('orbit') def set_initial_values(self): self.set_folder('.') # FIXME self.fileEdit.setText("{date}_{time}_{sequence}_{monitor}" + self.extension) self.d_phi = {} self.opticsTable.rows[:] = [] self.monitorTable.rows[:] = self.corrector.all_monitors self.update_ui() def connect_signals(self): self.folderButton.clicked.connect(self.change_output_file) self.startButton.clicked.connect(self.start_bot) self.cancelButton.clicked.connect(self.bot.cancel) self.monitorTable.selectionModel().selectionChanged.connect( self.monitor_selection_changed) self.filterEdit.textChanged.connect(lambda _: self._update_knobs()) self.defaultSpinBox.valueChanged.connect( lambda _: self.opticsTable.rows.touch()) def get_monitor_row(self, i, m) -> ("Monitor", ): return [ TableItem(m), ] def get_corrector_row(self, i, c) -> ("Param", "Δ [rad]"): default = self.defaultSpinBox.value() or None return [ TableItem(c.name), TableItem(self.d_phi.get(c.name.lower(), default), set_value=self.set_delta, delegate=delegates[float]), ] def set_delta(self, i, c, value): self.d_phi[c.name.lower()] = value def monitor_selection_changed(self, selected, deselected): self.corrector.setup({ 'monitors': [ self.corrector.all_monitors[idx.row()] for idx in self.monitorTable.selectedIndexes() ], }) self._update_knobs() self.update_ui() def _update_knobs(self): match = self._get_filter() if not match: return elements = self.model.elements last_mon = elements.index(self.corrector.monitors[-1]) self.opticsTable.rows = [ self.corrector._knobs[knob.lower()] for elem in elements if elem.index < last_mon for knob in self.model.get_elem_knobs(elem) if knob.lower() in self.corrector._knobs and match.search(knob.lower()) ] def _get_filter(self): text = self.filterEdit.text() text = text.replace(' ', '') try: return re.compile(text, re.ASCII | re.IGNORECASE) except re.error: return None def change_output_file(self): from madgui.widget.filedialog import getSaveFolderName folder = getSaveFolderName(self.window(), 'Output folder', self.folder) if folder: self.set_folder(folder) def set_folder(self, folder): self.folder = os.path.abspath(folder) self.folderEdit.setText(self.folder) @property def running(self): return bool(self.bot) and self.bot.running def closeEvent(self, event): self.bot.cancel() super().closeEvent(event) def update_ui(self): running = self.running valid = bool(self.opticsTable.rows and self._get_filter()) self.cancelButton.setEnabled(running) self.startButton.setEnabled(not running and valid) self.folderButton.setEnabled(not running) self.numIgnoredSpinBox.setEnabled(not running) self.numUsedSpinBox.setEnabled(not running) self.monitorTable.setEnabled(not running) self.opticsTable.setEnabled(not running) self.progressBar.setEnabled(running) self.progressBar.setRange(0, self.bot.totalops) self.progressBar.setValue(self.bot.progress) def set_progress(self, progress): self.progressBar.setValue(progress) def update_fit(self): """Called when procedure finishes succesfully.""" pass def start_bot(self): self.corrector.set_optics_delta(self.d_phi, self.defaultSpinBox.value()) now = time.localtime(time.time()) fname = os.path.join( self.folderEdit.text(), self.fileEdit.text().format( date=time.strftime("%Y-%m-%d", now), time=time.strftime("%H-%M-%S", now), sequence=self.model.seq_name, monitor=self.corrector.monitors[-1], )) self.corrector.open_export(fname) self.bot.start(self.numIgnoredSpinBox.value(), self.numUsedSpinBox.value()) def log(self, text, *args, **kwargs): formatted = text.format(*args, **kwargs) logging.info(formatted) self.logEdit.appendPlainText(formatted)