scale Ks; removed fixed energy <-> K maps;
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
import numpy as np
|
import numpy as np
|
||||||
#from scipy.interpolate import Akima1DInterpolator as Akima
|
|
||||||
from epics import PV
|
from epics import PV
|
||||||
|
|
||||||
from slic.core.adjustable import Adjustable
|
from slic.core.adjustable import Adjustable
|
||||||
@ -8,119 +7,28 @@ from slic.core.adjustable import PVAdjustable
|
|||||||
from slic.core.scanner.scanbackend import wait_for_all #, stop_all
|
from slic.core.scanner.scanbackend import wait_for_all #, stop_all
|
||||||
|
|
||||||
|
|
||||||
|
# 14 is the CHIC
|
||||||
n_unds = [
|
n_unds = [
|
||||||
8, 9, 10, 11, 12, 13,
|
7, 8, 9, 10, 11, 12, 13,
|
||||||
15, 16, 17, 18, 19, 20, 21, 22
|
15, 16, 17, 18, 19, 20, 21, 22
|
||||||
]
|
]
|
||||||
|
|
||||||
und_names = [f"SATUN{n:02}-UIND030" for n in n_unds]
|
und_names = [f"SATUN{n:02}-UIND030" for n in n_unds]
|
||||||
|
|
||||||
und_name_cal = "SATUN12-UIND030"
|
und_name_cal = "SATUN12-UIND030"
|
||||||
|
|
||||||
|
|
||||||
#energies = [
|
|
||||||
# 0.5457977557372193,
|
|
||||||
# 0.5429495415906611,
|
|
||||||
# 0.5401552739843691,
|
|
||||||
# 0.537355500731781,
|
|
||||||
# 0.534605067464375,
|
|
||||||
# 0.5318574959825555,
|
|
||||||
# 0.5291128804749312,
|
|
||||||
# 0.5264167029579244,
|
|
||||||
# 0.5237231992520139,
|
|
||||||
# 0.5210645197823921,
|
|
||||||
#]
|
|
||||||
|
|
||||||
#k_values = [
|
|
||||||
# 2.673,
|
|
||||||
# 2.681888888888889,
|
|
||||||
# 2.690777777777778,
|
|
||||||
# 2.699666666666667,
|
|
||||||
# 2.708555555555556,
|
|
||||||
# 2.7174444444444443,
|
|
||||||
# 2.7263333333333333,
|
|
||||||
# 2.735222222222222,
|
|
||||||
# 2.744111111111111,
|
|
||||||
# 2.753,
|
|
||||||
#]
|
|
||||||
|
|
||||||
|
|
||||||
#energies = [
|
|
||||||
# 0.549610621973092,
|
|
||||||
# 0.5479937271701031,
|
|
||||||
# 0.546395126105196,
|
|
||||||
# 0.544814685256097,
|
|
||||||
# 0.543218728674525,
|
|
||||||
# 0.541660979262817,
|
|
||||||
# 0.540074069530098,
|
|
||||||
# 0.538501771379368,
|
|
||||||
# 0.536939177980873,
|
|
||||||
# 0.535392458877575,
|
|
||||||
# 0.533842152732307,
|
|
||||||
# 0.5323060597843,
|
|
||||||
# 0.530767931907046,
|
|
||||||
# 0.5292440325790481,
|
|
||||||
# 0.5277161991879861,
|
|
||||||
# 0.526199323076255,
|
|
||||||
# 0.524699672767738,
|
|
||||||
#]
|
|
||||||
|
|
||||||
#k_values = [
|
|
||||||
# 2.673,
|
|
||||||
# 2.678,
|
|
||||||
# 2.683,
|
|
||||||
# 2.688,
|
|
||||||
# 2.693,
|
|
||||||
# 2.698,
|
|
||||||
# 2.703,
|
|
||||||
# 2.708,
|
|
||||||
# 2.713,
|
|
||||||
# 2.718,
|
|
||||||
# 2.723,
|
|
||||||
# 2.728,
|
|
||||||
# 2.733,
|
|
||||||
# 2.738,
|
|
||||||
# 2.743,
|
|
||||||
# 2.748,
|
|
||||||
# 2.753,
|
|
||||||
#]
|
|
||||||
|
|
||||||
|
|
||||||
#energies = [
|
|
||||||
# 1.1743862662276334,
|
|
||||||
# 1.1561455825400897,
|
|
||||||
# 1.1381577488951293,
|
|
||||||
# 1.1204686653636284,
|
|
||||||
# 1.1031371551015796,
|
|
||||||
# 1.0860714511221887,
|
|
||||||
# 1.069262314526579,
|
|
||||||
# 1.05279814063446,
|
|
||||||
# 1.0366146962391598,
|
|
||||||
# 1.0206897775380315,
|
|
||||||
#]
|
|
||||||
|
|
||||||
#k_values = [
|
|
||||||
# 1.5,
|
|
||||||
# 1.52222222,
|
|
||||||
# 1.54444444,
|
|
||||||
# 1.56666667,
|
|
||||||
# 1.58888889,
|
|
||||||
# 1.61111111,
|
|
||||||
# 1.63333333,
|
|
||||||
# 1.65555556,
|
|
||||||
# 1.67777778,
|
|
||||||
# 1.7,
|
|
||||||
#]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Undulators(Adjustable):
|
class Undulators(Adjustable):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(name="Athos Undulators", units="eV")
|
super().__init__(name="Athos Undulators", units="eV")
|
||||||
self.adjs = {name: Undulator(name) for name in und_names}
|
self.adjs = {name: Undulator(name) for name in und_names}
|
||||||
|
|
||||||
self.convert = ConverterEK()
|
self.convert = ConverterEK()
|
||||||
|
|
||||||
|
a = self.adjs[und_name_cal]
|
||||||
|
self.scale = ScalerEK(a)
|
||||||
|
|
||||||
|
|
||||||
def set_target_value(self, value, hold=False):
|
def set_target_value(self, value, hold=False):
|
||||||
k = self.convert.K(value)
|
k = self.convert.K(value)
|
||||||
@ -129,12 +37,26 @@ class Undulators(Adjustable):
|
|||||||
return
|
return
|
||||||
print(f"{k} <- {value}")
|
print(f"{k} <- {value}")
|
||||||
|
|
||||||
|
ks_current = [a.get_current_value(readback=False) for a in self.adjs.values()]
|
||||||
|
|
||||||
|
ks_target = self.scale.K(value, ks_current)
|
||||||
|
print("scaled: ", ks_target)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# ks_target = k * np.ones_like(ks_current)
|
||||||
|
# print("all equal:", ks_target)
|
||||||
|
# print()
|
||||||
|
|
||||||
def change():
|
def change():
|
||||||
# replace by set_all_target_values_and_wait when print not needed anymore
|
#TODO: replace by set_all_target_values_and_wait when print not needed anymore
|
||||||
tasks = []
|
tasks = []
|
||||||
for name, a in self.adjs.items():
|
for (name, a), k_old, k_new in zip(self.adjs.items(), ks_current, ks_target):
|
||||||
print(f"{name} <- {k}")
|
delta = k_old - k_new
|
||||||
t = a.set_target_value(k, hold=False)
|
print(f"{name}: {k_old}\t->\t{k_new}\t({delta})")
|
||||||
|
if np.isnan(k_new):
|
||||||
|
print(f"{name} skipped since target K is nan")
|
||||||
|
continue
|
||||||
|
t = a.set_target_value(k_new, hold=False)
|
||||||
tasks.append(t)
|
tasks.append(t)
|
||||||
wait_for_all(tasks)
|
wait_for_all(tasks)
|
||||||
|
|
||||||
@ -149,7 +71,7 @@ class Undulators(Adjustable):
|
|||||||
all_ks = [a.get_current_value() for a in self.adjs.values()]
|
all_ks = [a.get_current_value() for a in self.adjs.values()]
|
||||||
checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
|
checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
|
||||||
if not all(checks):
|
if not all(checks):
|
||||||
print("Warning: Ks are not all close:")
|
print(f"Warning: Ks are not all close to {k}:")
|
||||||
for name, k, chk in zip(self.adjs.keys(), all_ks, checks):
|
for name, k, chk in zip(self.adjs.keys(), all_ks, checks):
|
||||||
if not chk:
|
if not chk:
|
||||||
print(name, k)
|
print(name, k)
|
||||||
@ -164,49 +86,15 @@ class Undulators(Adjustable):
|
|||||||
|
|
||||||
class Undulator(PVAdjustable):
|
class Undulator(PVAdjustable):
|
||||||
|
|
||||||
def __init__(self, name, accuracy=0.001):
|
def __init__(self, name, accuracy=0.00001):
|
||||||
pvname_setvalue = name + ":K_SET"
|
pvname_setvalue = name + ":K_SET"
|
||||||
pvname_readback = name + ":K_READ"
|
pvname_readback = name + ":K_READ"
|
||||||
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, name=name)
|
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, active_move=True, name=name)
|
||||||
self.energy = PVAdjustable(name + ":FELPHOTENE")
|
self.adj_energy = PVAdjustable(name + ":FELPHOTENE")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def energy(self):
|
||||||
#def make_calib(x, y):
|
return self.adj_energy.get_current_value() * 1000
|
||||||
# x, y = list(zip(*sorted(zip(x, y))))
|
|
||||||
# return Akima(x, y)
|
|
||||||
|
|
||||||
|
|
||||||
#def get_map(k_min=min(k_values), k_max=max(k_values)):
|
|
||||||
# und = Undulator(und_name_cal)
|
|
||||||
# start_k_value = und.get_current_value()
|
|
||||||
|
|
||||||
# k_values = np.linspace(k_min, k_max, 10)
|
|
||||||
# energies = []
|
|
||||||
# print()
|
|
||||||
# print("mapping = {")
|
|
||||||
# for k in k_values:
|
|
||||||
# und.set_target_value(k).wait()
|
|
||||||
# energy = und.energy.get_current_value()
|
|
||||||
# print(f" {energy}: {k},")
|
|
||||||
# energies.append(energy)
|
|
||||||
# print("}")
|
|
||||||
# energies = np.array(energies)
|
|
||||||
|
|
||||||
# print()
|
|
||||||
# print("energies = [")
|
|
||||||
# for energy in energies:
|
|
||||||
# print(f" {energy},")
|
|
||||||
# print("]")
|
|
||||||
|
|
||||||
# print()
|
|
||||||
# print("k_values = [")
|
|
||||||
# for k in k_values:
|
|
||||||
# print(f" {k},")
|
|
||||||
# print("]")
|
|
||||||
|
|
||||||
# und.set_target_value(start_k_value).wait()
|
|
||||||
# return energies, k_values
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -242,3 +130,19 @@ class ConverterEK:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ScalerEK:
|
||||||
|
|
||||||
|
def __init__(self, und_reference):
|
||||||
|
self.und = und_reference
|
||||||
|
|
||||||
|
def K(self, energy_target, K_current=None):
|
||||||
|
if K_current is None:
|
||||||
|
K_current = self.und.get_current_value()
|
||||||
|
K_current = np.asarray(K_current)
|
||||||
|
energy_current = self.und.energy
|
||||||
|
energy_ratio = energy_current / energy_target
|
||||||
|
K_target_squared = energy_ratio * (K_current**2 + 2) - 2
|
||||||
|
return np.sqrt(K_target_squared)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user