class AdjustableVirtual(SpecConvenience): def __init__( self, adjustables, foo_get_current_value, foo_set_target_value_current_value, reset_current_value_to=False, append_aliases=False, name=None, ): self.name = name self.alias = Alias(name) if append_aliases: for adj in adjustables: try: self.alias.append(adj.alias) except Exception as e: print(f"could not find alias in {adj}") print(str(e)) self._adjustables = adjustables self._foo_set_target_value_current_value = foo_set_target_value_current_value self._foo_get_current_value = foo_get_current_value self._reset_current_value_to = reset_current_value_to if reset_current_value_to: for adj in self._adjustables: if not hasattr(adj, "reset_current_value_to"): raise Exception( f"No reset_current_value_to method found in {adj}") def set_target_value(self, value, hold=False): vals = self._foo_set_target_value_current_value(value) if not hasattr(vals, "__iter__"): vals = (vals, ) def changer(): self._active_changers = [ adj.set_target_value(val, hold=False) for val, adj in zip(vals, self._adjustables) ] for tc in self._active_changers: tc.wait() def stopper(): for tc in self._active_changers: tc.stop() self._currentChange = Task(changer, hold=hold, stopper=stopper) return self._currentChange def get_current_value(self): return self._foo_get_current_value( *[adj.get_current_value() for adj in self._adjustables]) def set_current_value(self, value): if not self._set_current_value: raise NotImplementedError( "There is no value setting implemented for this virtual adjuster!" ) else: vals = self._foo_set_target_value_current_value(value) for adj, val in zip(self._adjustables, vals): adj.set_current_value(val) #TODO: below from DefaultRepresentation def _get_name(self): if self.alias: return self.alias.get_full_name() elif self.name: return self.name else: return self.ID def __repr__(self): s = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + ": " s += f"{colorama.Style.BRIGHT}{self._get_name()}{colorama.Style.RESET_ALL} at {colorama.Style.BRIGHT}{self.get_current_value():g}{colorama.Style.RESET_ALL}" return s
class SolidTargetDetectorPBPS: def __init__( self, ID, VME_crate=None, link=None, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None, ): self.ID = ID self.name = name self.diode_x = Motor(ID + ":MOTOR_X1", name="diode_x") self.diode_y = Motor(ID + ":MOTOR_Y1", name="diode_y") self.target_pos = Motor(ID + ":MOTOR_PROBE", name="target_pos") self.target = PVEnumAdjustable(ID + ":PROBE_SP", name="target") if VME_crate: self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up)) self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down)) self.diode_left = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_left)) self.diode_right = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_right)) if self.name: self.alias = Alias(name) self.alias.append(self.diode_x.alias) self.alias.append(self.diode_y.alias) self.alias.append(self.target_pos.alias) self.alias.append(self.target.alias) def __repr__(self): s = f"**Intensity monitor {self.name}**\n\n" s += f"Target in: {self.target.get_current_value().name}\n\n" try: sd = "**Biasd voltage**\n" sd += " - Diode up: %.4f\n" % (sdelf.diode_up.get_biasd()) sd += " - Diode down: %.4f\n" % (sdelf.diode_down.get_biasd()) sd += " - Diode left: %.4f\n" % (sdelf.diode_left.get_biasd()) sd += " - Diode right: %.4f\n" % (sdelf.diode_right.get_biasd()) sd += "\n" sd += "**Gain**\n" sd += " - Diode up: %i\n" % (sdelf.diode_up.gain.get()) sd += " - Diode down: %i\n" % (sdelf.diode_down.gain.get()) sd += " - Diode left: %i\n" % (sdelf.diode_left.gain.get()) sd += " - Diode right: %i\n" % (sdelf.diode_right.gain.get()) s += sd except: pass return s def set_gains(self, value): try: self.diode_up.gain.set(value) self.diode_down.gain.set(value) self.diode_left.gain.set(value) self.diode_right.gain.set(value) except: print("No diodes configured, can not change any gain!") def get_available_gains(self): try: nu = self.diode_up.gain.names nd = self.diode_down.gain.names nl = self.diode_left.gain.names nr = self.diode_right.gain.names assert nu == nd == nl == nr, "NB: the gain options of the four diodes are not equal!!!" return nu except: print("No diodes configured, can not change any gain!") def get_gains(self): try: gains = dict() gains["up"] = (self.diode_up.gain.get_name(), self.diode_up.gain.get()) gains["down"] = ( self.diode_down.gain.get_name(), self.diode_down.gain.get(), ) gains["left"] = ( self.diode_left.gain.get_name(), self.diode_left.gain.get(), ) gains["right"] = ( self.diode_right.gain.get_name(), self.diode_right.gain.get(), ) return gains except: print("No diodes configured, can not change any gain!")
class AttenuatorAramis: def __init__(self, ID, E_min=1500, sleeptime=1, name=None, limits=[-52, 2], pulse_picker=None): self.ID = ID self._pv_status_str = PV(ID + ":MOT2TRANS.VALD") self._pv_status_int = PV(ID + ":IDX_RB") self.E_min = E_min self._sleeptime = sleeptime self.name = name self.alias = Alias(name) self.pulse_picker = pulse_picker self.motors = [Motor(f"{self.ID}:MOTOR_{n+1}", name=f"motor{n+1}") for n in range(6)] for n, mot in enumerate(self.motors): self.__dict__[f"motor_{n+1}"] = mot self.alias.append(mot.alias) if limits: mot.set_epics_limits(*limits) def updateE(self, energy=None): while not energy: energy = PV("SARUN03-UIND030:FELPHOTENE").value energy = energy * 1000 if energy < self.E_min: energy = None print(f"Machine photon energy is below {self.E_min} - waiting for the machine to recover") sleep(self._sleeptime) PV(self.ID + ":ENERGY").put(energy) print("Set energy to %s eV" % energy) def set_transmission(self, value, energy=None): self.updateE(energy) PV(self.ID + ":3RD_HARM_SP").put(0) PV(self.ID + ":TRANS_SP").put(value) def set_transmission_third_harmonic(self, value, energy=None): self.updateE(energy) PV(self.ID + ":3RD_HARM_SP").put(1) PV(self.ID + ":TRANS_SP").put(value) def setE(self): pass def get_transmission(self, verbose=True): tFun = PV(self.ID + ":TRANS_RB").value tTHG = PV(self.ID + ":TRANS3EDHARM_RB").value if verbose: print("Transmission Fundamental: %s THG: %s" % (tFun, tTHG)) return tFun, tTHG def get_current_value(self, *args, **kwargs): return self.get_transmission(*args, verbose=False, **kwargs)[0] def set_target_value(self, value, sleeptime=10, hold=False): def changer(): self.set_transmission(value) sleep(sleeptime) if self.pulse_picker: self.pulse_picker.open() return Task(changer, hold=hold) def get_status(self): s_str = self._pv_status_str.get(as_string=True) s_int = self._pv_status_int.get() return s_str, s_int def __repr__(self): t = self.get_transmission() s = "1st harm. transmission = %g\n" % t[0] s += "3rd harm. transmission = %g\n" % t[1] s += "Targets in beam:\n" s += "%s" % self.get_status()[0] return s def __call__(self, *args, **kwargs): self.set_transmission(*args, **kwargs)