added hysteresis protections and magnet cycling; renamed TwoColorChicane -> TwoColorChicaneCurrent; added TwoColorChicaneDelay

This commit is contained in:
2023-07-16 18:40:15 +02:00
parent 6fb509a746
commit fed899129b

View File

@ -7,6 +7,9 @@ from logzero import logger as log
from slic.core.adjustable import Adjustable, PVAdjustable, PVEnumAdjustable
from slic.core.scanner.scanbackend import wait_for_all #, stop_all
from slic.utils import cprint, tqdm_sleep
from .delay_current import DelayCurrentConverter
UND_NAME_FMT = "SATUN{:02}-UIND030"
@ -313,18 +316,81 @@ class CHIC(PVAdjustable):
class TwoColorChicane(PVAdjustable):
class TwoColorChicaneCurrent(PVAdjustable):
def __init__(self, name):#, t0=0):
# self.t0 = t0
# name += " Two Color Chicane"
super().__init__("SATUN14-MBND100:I-SET", "SATUN14-MBND100:I-READ", process_time=1, name=name)
def __init__(
self,
pvname_setvalue="SATUN14-MBND100:I-SET", pvname_readback="SATUN14-MBND100:I-READ", name="Two Color Chicane as current",
accuracy=0.1, process_time=1,
hysteresis_protection=True,
**kwargs
):
super().__init__(
pvname_setvalue, pvname_readback, name=name,
accuracy=accuracy, process_time=process_time,
**kwargs
)
self.hysteresis_protection = hysteresis_protection
# def set_target_value(self, value, hold=False):
# super().set_target_value(value)
self.cycle_time = 250
self.pv_cycle = PV("SATUN14-MBND100:CYCLE")
self.previous_target = None
# def get_current_value(self):
# return super().get_current_value()
def set_target_value(self, value, **kwargs):
current = self.get_current_value()
if value < current:
cprint(f"Hysteresis Warning: target value {value} is smaller than the current value {current}", color="red")
if self.hysteresis_protection and value == self.previous_target:
cprint(f"target value {value} is identical to previous target value, will not try to change", color="cyan")
return
self.previous_target = value
super().set_target_value(value, **kwargs)
def cycle_magnet(self):
self.pv_cycle.put(1, wait=True)
tqdm_sleep(self.cycle_time)
# set the current to 1 and 2 consecutively,
# since the results after the first step always looks strange
self.set_target_value(1).wait()
sleep(1)
self.set_target_value(2).wait()
sleep(1)
class TwoColorChicaneDelay(Adjustable):
def __init__(self, ID="TWO-COLOR-CHICANE-DELAY", name="Two Color Chicane as delay", pvname_electron_energy="SATCB01:ENE-FILT-OP", hysteresis_protection=True, units="fs", **kwargs):
self.adj_current = TwoColorChicaneCurrent(hysteresis_protection=hysteresis_protection, internal=True)
self.pv_electron_energy = PV(pvname_electron_energy)
self.converter = DelayCurrentConverter()
super().__init__(ID, name=name, units=units, **kwargs)
def get_current_value(self):
current = self.adj_current.get_current_value()
delay = self.calc_delay_fs(current)
return delay
def set_target_value(self, delay):
current = self.calc_current_A(delay)
print(f"{current} A <- {delay} fs")
self.adj_current.set_target_value(current).wait()
def is_moving(self):
return self.adj_current.is_moving()
def cycle_magnet(self):
self.adj_current.cycle_magnet()
def calc_current_A(self, delay_fs):
electron_energy = self.pv_electron_energy.get()
return self.converter.current_A(delay_fs, electron_energy)
def calc_delay_fs(self, current_A):
electron_energy = self.pv_electron_energy.get()
return self.converter.delay_fs(current_A, electron_energy)