added coupled mono+und

This commit is contained in:
gac-furka
2022-01-19 16:47:46 +01:00
parent 44290ea065
commit bc08e0f7c4
4 changed files with 487 additions and 33 deletions

View File

@ -2,29 +2,39 @@ from time import sleep
import numpy as np
from epics import PV
from logzero import logger as log
from slic.core.adjustable import Adjustable
from slic.core.adjustable import PVAdjustable
from slic.core.scanner.scanbackend import wait_for_all #, stop_all
# 14 is the CHIC
n_unds = [
6, 7, 8, 9, 10, 11, 12, 13,
15, 16, 17, 18
]
und_names = [f"SATUN{n:02}-UIND030" for n in n_unds]
und_name_cal = "SATUN13-UIND030"
UND_NAME_FMT = "SATUN{:02}-UIND030"
N_UND_CHIC = 14
class Undulators(Adjustable):
def __init__(self, scaled=True, name="Athos Undulators", units="eV"):
super().__init__("ATHOS_UNDULATORS", name=name, units=units)
self.adjs = {name: Undulator(name) for name in und_names}
self.chic = CHIC(name, units)
def __init__(self, n_unds, n_und_ref, chic_fudge_offset=0, adjust_chic=True, scaled=True, ID="ATHOS_UNDULATORS", name="Athos Undulators", units="eV"):
super().__init__(ID, name=name, units=units)
self.n_unds = n_unds = list(n_unds)
self.n_und_ref = n_und_ref
if n_und_ref not in n_unds:
raise ValueError(f"the reference undulator ({n_und_ref}) is not in the list of active undulators: {n_unds}")
if N_UND_CHIC in n_unds:
log.warning(f"the CHIC ({N_UND_CHIC}) is in the list of active undulators: {n_unds}, and will be ignored/removed")
n_unds.remove(N_UND_CHIC)
self.und_names = und_names = [UND_NAME_FMT.format(n) for n in n_unds]
self.und_name_cal = und_name_cal = UND_NAME_FMT.format(n_und_ref)
self.adjs = {name: Undulator(name) for name in und_names}
self.chic = CHIC(chic_fudge_offset, name, units)
self.adjust_chic = adjust_chic
self.scaled = scaled
self.convert = ConverterEK()
@ -64,21 +74,22 @@ class Undulators(Adjustable):
t = a.set_target_value(k_new, hold=False)
tasks.append(t)
wait_for_all(tasks)
print("CHIC adjustment follows")
self.chic.set_target_value(value, hold=False).wait() #TODO: test whether an additional sleep is needed
sleep(10)
print("CHIC adjustment done")
if self.adjust_chic:
print("CHIC adjustment follows")
self.chic.set_target_value(value, hold=False).wait() #TODO: test whether an additional sleep is needed
print("CHIC adjustment done")
return self._as_task(change, hold=hold)
def get_current_value(self):
a = self.adjs[und_name_cal]
n = self.und_name_cal
a = self.adjs[n]
k = a.get_current_value()
energy = self.convert.E(k)
all_ks = [a.get_current_value() for a in self.adjs.values()]
checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
# all_ks = [a.get_current_value() for a in self.adjs.values()]
# checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
# if not all(checks):
# print(f"Warning: Ks are not all close to {k}:")
# for name, k, chk in zip(self.adjs.keys(), all_ks, checks):
@ -98,8 +109,8 @@ class Undulator(PVAdjustable):
def __init__(self, name, accuracy=0.0005):
pvname_setvalue = name + ":K_SET"
pvname_readback = name + ":K_READ"
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, active_move=True, name=name)
self.adj_energy = PVAdjustable(name + ":FELPHOTENE")
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, active_move=True, name=name, internal=True)
self.adj_energy = PVAdjustable(name + ":FELPHOTENE", internal=True)
@property
def energy(self):
@ -157,7 +168,8 @@ class ScalerEK:
class CHIC(PVAdjustable):
def __init__(self, name, units):
def __init__(self, fudge_offset, name, units):
self.fudge_offset = fudge_offset
name += " CHIC Energy"
super().__init__("SATUN-CHIC:PHOTON-ENERGY", name=name)
self.pvs.start = PV("SATUN-CHIC:APPLY-DELAY-OFFSET-PHASE")
@ -165,7 +177,7 @@ class CHIC(PVAdjustable):
def set_target_value(self, value, hold=False):
fudge_offset = 0
fudge_offset = self.fudge_offset
print("CHIC fudge offset is", fudge_offset)
value -= fudge_offset
value /= 1000
@ -185,14 +197,35 @@ class CHIC(PVAdjustable):
def get_current_value(self):
return super().get_current_value() * 1000
class Mono(PVAdjustable):
def __init__(self, name, accuracy=0.01):
pvname_setvalue = name + ":SetEnergy"
pvname_readback = name + ":photonenergy"
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, active_move=True, name=name)
def __init__(self, pv_mono_name, mono_name):
self.pv_name=pv_mono_name
pvname_setvalue = pv_mono_name + ":SetEnergy"
#pvname_readback = name + ":photonenergy"
pvname_done_moving = pv_mono_name + ":MOVING"
super().__init__(pvname_setvalue, pvname_done_moving=pvname_done_moving, name=mono_name)
class Coupled_MonoUnd(Adjustable):
def __init__(self, n_unds, n_und_ref, chic_fudge_offset=0, adjust_chic=True, scaled=True, ID="ATHOS_Mon_Und", unds_name="Athos Undulators", units="eV", pv_mono_name="", mono_name="", delta=0, name="" ):
super().__init__(ID, name=name, units=units)
self.mono = Mono(pv_mono_name, mono_name)
self.und = Undulators(n_unds, n_und_ref, chic_fudge_offset, name=unds_name)
self.delta = delta
def set_target_value(self, value):
tm = self.mono.set_target_value(value)
tu = self.und.set_target_value(value + self.delta)
tm.wait()
tu.wait()
def get_current_value(self):
return self.mono.get_current_value()
def is_moving(self):
return any([self.mono.is_moving(),self.und.is_moving()])