added conversion E <-> K instead of calibration curve
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.interpolate import Akima1DInterpolator as Akima
|
#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
|
||||||
@ -18,31 +18,31 @@ und_names = [f"SATUN{n:02}-UIND030" for n in n_unds]
|
|||||||
und_name_cal = "SATUN12-UIND030"
|
und_name_cal = "SATUN12-UIND030"
|
||||||
|
|
||||||
|
|
||||||
energies = [
|
#energies = [
|
||||||
0.5457977557372193,
|
# 0.5457977557372193,
|
||||||
0.5429495415906611,
|
# 0.5429495415906611,
|
||||||
0.5401552739843691,
|
# 0.5401552739843691,
|
||||||
0.537355500731781,
|
# 0.537355500731781,
|
||||||
0.534605067464375,
|
# 0.534605067464375,
|
||||||
0.5318574959825555,
|
# 0.5318574959825555,
|
||||||
0.5291128804749312,
|
# 0.5291128804749312,
|
||||||
0.5264167029579244,
|
# 0.5264167029579244,
|
||||||
0.5237231992520139,
|
# 0.5237231992520139,
|
||||||
0.5210645197823921,
|
# 0.5210645197823921,
|
||||||
]
|
#]
|
||||||
|
|
||||||
k_values = [
|
#k_values = [
|
||||||
2.673,
|
# 2.673,
|
||||||
2.681888888888889,
|
# 2.681888888888889,
|
||||||
2.690777777777778,
|
# 2.690777777777778,
|
||||||
2.699666666666667,
|
# 2.699666666666667,
|
||||||
2.708555555555556,
|
# 2.708555555555556,
|
||||||
2.7174444444444443,
|
# 2.7174444444444443,
|
||||||
2.7263333333333333,
|
# 2.7263333333333333,
|
||||||
2.735222222222222,
|
# 2.735222222222222,
|
||||||
2.744111111111111,
|
# 2.744111111111111,
|
||||||
2.753,
|
# 2.753,
|
||||||
]
|
#]
|
||||||
|
|
||||||
|
|
||||||
#energies = [
|
#energies = [
|
||||||
@ -116,16 +116,14 @@ k_values = [
|
|||||||
|
|
||||||
class Undulators(Adjustable):
|
class Undulators(Adjustable):
|
||||||
|
|
||||||
def __init__(self, energies=energies, k_values=k_values):
|
def __init__(self):
|
||||||
super().__init__(name="Athos Undulators")
|
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.eV_to_K = make_calib(energies, k_values)
|
self.convert = ConverterEK()
|
||||||
self.K_to_eV = make_calib(k_values, energies)
|
|
||||||
|
|
||||||
|
|
||||||
def set_target_value(self, value, hold=False):
|
def set_target_value(self, value, hold=False):
|
||||||
value /= 1000 # eV -> keV
|
k = self.convert.K(value)
|
||||||
k = self.eV_to_K(value)
|
|
||||||
if np.isnan(k):
|
if np.isnan(k):
|
||||||
print("K is nan for", value)
|
print("K is nan for", value)
|
||||||
return
|
return
|
||||||
@ -146,7 +144,7 @@ class Undulators(Adjustable):
|
|||||||
def get_current_value(self):
|
def get_current_value(self):
|
||||||
a = self.adjs[und_name_cal]
|
a = self.adjs[und_name_cal]
|
||||||
k = a.get_current_value()
|
k = a.get_current_value()
|
||||||
energy = self.K_to_eV(k)
|
energy = self.convert.E(k)
|
||||||
|
|
||||||
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)
|
||||||
@ -156,7 +154,7 @@ class Undulators(Adjustable):
|
|||||||
if not chk:
|
if not chk:
|
||||||
print(name, k)
|
print(name, k)
|
||||||
|
|
||||||
return float(energy) * 1000 # keV -> eV
|
return energy
|
||||||
|
|
||||||
|
|
||||||
def is_moving(self):
|
def is_moving(self):
|
||||||
@ -174,41 +172,73 @@ class Undulator(PVAdjustable):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_calib(x, y):
|
#def make_calib(x, y):
|
||||||
x, y = list(zip(*sorted(zip(x, y))))
|
# x, y = list(zip(*sorted(zip(x, y))))
|
||||||
return Akima(x, y)
|
# return Akima(x, y)
|
||||||
|
|
||||||
|
|
||||||
def get_map(k_min=min(k_values), k_max=max(k_values)):
|
#def get_map(k_min=min(k_values), k_max=max(k_values)):
|
||||||
und = Undulator(und_name_cal)
|
# und = Undulator(und_name_cal)
|
||||||
start_k_value = und.get_current_value()
|
# start_k_value = und.get_current_value()
|
||||||
|
|
||||||
k_values = np.linspace(k_min, k_max, 10)
|
# k_values = np.linspace(k_min, k_max, 10)
|
||||||
energies = []
|
# energies = []
|
||||||
print()
|
# print()
|
||||||
print("mapping = {")
|
# print("mapping = {")
|
||||||
for k in k_values:
|
# for k in k_values:
|
||||||
und.set_target_value(k).wait()
|
# und.set_target_value(k).wait()
|
||||||
energy = und.energy.get_current_value()
|
# energy = und.energy.get_current_value()
|
||||||
print(f" {energy}: {k},")
|
# print(f" {energy}: {k},")
|
||||||
energies.append(energy)
|
# energies.append(energy)
|
||||||
print("}")
|
# print("}")
|
||||||
energies = np.array(energies)
|
# energies = np.array(energies)
|
||||||
|
|
||||||
print()
|
# print()
|
||||||
print("energies = [")
|
# print("energies = [")
|
||||||
for energy in energies:
|
# for energy in energies:
|
||||||
print(f" {energy},")
|
# print(f" {energy},")
|
||||||
print("]")
|
# print("]")
|
||||||
|
|
||||||
print()
|
# print()
|
||||||
print("k_values = [")
|
# print("k_values = [")
|
||||||
for k in k_values:
|
# for k in k_values:
|
||||||
print(f" {k},")
|
# print(f" {k},")
|
||||||
print("]")
|
# print("]")
|
||||||
|
|
||||||
und.set_target_value(start_k_value).wait()
|
# und.set_target_value(start_k_value).wait()
|
||||||
return energies, k_values
|
# return energies, k_values
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ConverterEK:
|
||||||
|
|
||||||
|
h = 4.135667696e-15 # eV * s
|
||||||
|
c = 299792458 # m / s
|
||||||
|
lambda_u = 38e-3 # m
|
||||||
|
const = 2 * h * c / lambda_u # eV
|
||||||
|
|
||||||
|
electron_rest_energy = 0.51099895 # MeV
|
||||||
|
|
||||||
|
def __init__(self, pvname_electron_energy="SATCL01-MBND100:P-READ"):
|
||||||
|
self.pv_electron_energy = PV(pvname_electron_energy)
|
||||||
|
|
||||||
|
def K(self, energy):
|
||||||
|
f = self.get_factor()
|
||||||
|
v = f / energy - 1
|
||||||
|
return np.sqrt(2 * v)
|
||||||
|
|
||||||
|
def E(self, k_value):
|
||||||
|
f = self.get_factor()
|
||||||
|
v = 1 + k_value**2 / 2
|
||||||
|
return f / v
|
||||||
|
|
||||||
|
def get_factor(self):
|
||||||
|
return self.const * self.get_gamma_squared()
|
||||||
|
|
||||||
|
def get_gamma_squared(self):
|
||||||
|
electron_energy = self.pv_electron_energy.get()
|
||||||
|
gamma = electron_energy / self.electron_rest_energy
|
||||||
|
return gamma**2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user