merging all laser timing files

This commit is contained in:
2020-08-11 23:55:12 +02:00
parent a6af4af52c
commit f39ca1fbcd
2 changed files with 223 additions and 13 deletions
+183 -13
View File
@@ -4,8 +4,15 @@ import numpy as np
import time
from slic.core.task import Task
_basefolder = "/sf/bernina/config/com/data/src/lasertiming"
#TODO
#bernina
PS = "SLAAR02-TSPL-EPL"
_basefolder = "/sf/bernina/config/eco/offsets"
#alvra:
PS = "SLAAR01-TSPL-EPL"
_basefolder = "/sf/alvra/config/lasertiming"
_posTypes = ["user", "dial", "raw"]
@@ -22,7 +29,31 @@ def timeToStr(value, n=12):
return ret_str
def niceTimeToStr(delay, fmt="%+.0f"):
a_delay = abs(delay)
if a_delay >= 1:
ret = fmt % delay + "s"
elif 1e-3 <= a_delay < 1:
ret = fmt % (delay * 1e3) + "ms"
elif 1e-6 <= a_delay < 1e-3:
ret = fmt % (delay * 1e6) + "us"
elif 1e-9 <= a_delay < 1e-6:
ret = fmt % (delay * 1e9) + "ns"
elif 1e-12 <= a_delay < 1e-9:
ret = fmt % (delay * 1e12) + "ps"
elif 1e-15 <= a_delay < 1e-12:
ret = fmt % (delay * 1e12) + "fs"
elif 1e-18 <= a_delay < 1e-15:
ret = fmt % (delay * 1e12) + "as"
elif a_delay < 1e-18:
ret = "0s"
else:
ret = str(delay) + "s"
return ret
class Storage(object):
""" this class is needed to store the offset in files and read in s """
def __init__(self, pvname):
self._filename = os.path.join(_basefolder, pvname)
@@ -61,10 +92,11 @@ class Storage(object):
class Pockels_trigger(PV):
def __init__(self, pv_basename):
pvname = pv_basename + "-RB"
def __init__(self, pv_get, pv_set, pv_offset_get): #TODO make offset optional
pvname = pv_get
PV.__init__(self, pvname)
self._pv_setvalue = PV(pv_basename + "-SP")
self._pv_offset_get = PV(pv_offset_get)
self._pv_setvalue = PV(pv_set)
self._filename = os.path.join(_basefolder, pvname)
self._storage = Storage(pvname)
@@ -73,7 +105,7 @@ class Pockels_trigger(PV):
return self._storage.value
def get_dial(self):
return super().get() * 1e-6
return np.round(super().get() * 1e-6, 9) + self._pv_offset_get.get() * 1e-9 - 7.41e-9 #TODO what is the constant?
def get(self):
""" convert time to sec """
@@ -98,16 +130,20 @@ class Pockels_trigger(PV):
return "Pockel Trigger PV: %s user , dial = %s, %s" % (self.pvname, user, dial)
class Phase_shifter(PV):
""" this class is needed to store the offset in files and read in ps """
_OSCILLATOR_PERIOD = 1 / 71.368704e6
def __init__(self, pv_basename="SLAAR01-TSPL-EPL"):
class Phase_shifter(PV):
def __init__(self, pv_basename=PS, dial_max=14.0056e-9, precision=100e-15):
pvname = pv_basename + ":CURR_DELTA_T"
PV.__init__(self, pvname)
self._filename = os.path.join(_basefolder, pvname)
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
self._storage = Storage(pvname)
self.dial_max = dial_max
self.retry = precision
@property
def offset(self):
@@ -125,17 +161,25 @@ class Phase_shifter(PV):
value = self.get_dial()
self._storage.store(value)
def move(self, value):
def move(self, value, accuracy=None):
if accuracy is None:
accuracy = self.retry
dial = value + self.offset
dial = np.mod(dial, _OSCILLATOR_PERIOD)
if dial > self.dial_max:
dial = self.dial_max
dial_ps = dial * 1e12
self._pv_setvalue.put(dial_ps)
time.sleep(0.1)
self._pv_execute.put(1)
while np.abs(self.get() - value) > 100e-15:
#print(accuracy)
while np.abs(self.get_dial() - dial) > accuracy:
#print(np.abs(self.get_dial()-dial))
time.sleep(0.2)
def set(self, value):
newoffset = self.get_dial() - value
newoffset = np.mod(newoffset, _OSCILLATOR_PERIOD)
self.store(newoffset)
def __repr__(self):
@@ -144,9 +188,135 @@ class Phase_shifter(PV):
return "Phase Shifter: user,dial = %s , %s" % (user, dial)
#_pockels_in = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
#_pockels_out = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
#_phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
#TODO
#bernina
sg_get = "SLAAR-LTIM02-EVR0:Pul3-Delay-RB"
sg_set = "SLAAR-LTIM02-EVR0:Pul3_NEW_DELAY"
sg_off = "SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay1-RB"
sdg_get = "SLAAR-LTIM02-EVR0:Pul2-Delay-RB"
sdg_set = "SLAAR-LTIM02-EVR0:Pul2_NEW_DELAY"
sdg_off = "SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay0-RB"
#alvra:
sg = "SLAAR-LTIM01-EVR0:Pul2-Delay"
sg_get = sg + "-RB"
sg_set = sg + "-SP"
sg_offset = "SLAAR-LTIM01-EVR0:UnivDlyModule1-Delay1-RB"
sdg = "SLAAR-LTIM01-EVR0:Pul3-Delay"
sdg_get = sdg + "-RB"
sdg_set = sdg + "-SP"
_slicer_gate = Pockels_trigger(sg_get, sg_set, sg_off)
_sdg1 = Pockels_trigger(sdg_get, sdg_set, sdg_off)
_phase_shifter = Phase_shifter(PS)
_POCKELS_CELL_RESOLUTION = 7e-9
class Lxt(object):
def __init__(self, accuracy_poly=[100e-15, 1e-7]):
self.sdg1 = _sdg1
self.slicer_gate = _slicer_gate
self.phase_shifter = _phase_shifter
self.Id = PS
self.name = "lxt"
self.elog = None
self.accuracy_poly = accuracy_poly
def move_sdg(self, value):
self.sdg1.move(value)
def move(self, value, accuracy=None):
self.sdg1.move(-value)
self.slicer_gate.move(-value)
if not accuracy:
accuracy = np.abs(value) * self.accuracy_poly[1] + self.accuracy_poly[0]
self.phase_shifter.move(value, accuracy=accuracy)
def set(self, value):
self.phase_shifter.set(value)
self.slicer_gate.set(-value)
self.sdg1.set(-value)
def get(self):
# pulses are at SOME_IDX*OSCILLATOR_PERIOD-PHASESHITER
# the -PHASESHITER is due to the inverted sign
phase_shifter = self.phase_shifter.get()
sdg1_delay = self.sdg1.get()
idx_pulse = (sdg1_delay + phase_shifter) / _OSCILLATOR_PERIOD
delay = int(idx_pulse) * _OSCILLATOR_PERIOD - phase_shifter
return -delay
def set_target_value(self, value, hold=False):
""" Adjustable convention"""
changer = lambda: self.move(value)
return Task(changer, hold=hold)
def get_current_value(self):
return self.get()
def set_current_value(self, value):
self.set(value)
def __repr__(self):
delay = niceTimeToStr(lxt.get())
return "delay = %s" % (delay)
class eTiming:
def __init__(self, Id):
self.Id = Id
self.name = "Globi laser electronic timing (us)"
self._eTimeSet = PV("SLAAR01-LTIM-PDLY:DELAY") # current laser timing number from Edwin's timing PV
self._eTimeRBK = PV("SLAAR-LGEN:DLY_OFFS1") # readback on Edwin's timing PV
self._moving = PV("SLAAR01-LTIM-PDLY:WAITING")
def get_current_value(self):
return self._eTimeRBK.get() * 1e6 # convert from us to ps
def wait_for_valid_value(self):
tval = np.nan
while not np.isfinite(tval):
tval = self.get_current_value()
return tval
def move_and_wait(self, value, checktime=0.01):
self._eTimeSet.put(value)
time.sleep(0.2)
while self._moving.get() == 0.0:
time.sleep(checktime)
def set_current_value(self, value):
self._eTimeSet.put(value)
def __repr__(self):
return self.__str__()
def set_target_value(self, value, hold=False):
changer = lambda: self.move_and_wait(value)
return Task(changer, hold=hold)
def __str__(self):
eTimingRBKStr = str(self.get_current_value())
eTimingSetStr = self._eTimeSet.get(as_string=True)
s = "Globi laser electronic timing\n"
s += "- electronic timing readback (ps): {}\n".format(eTimingRBKStr)
s += "- electronic timing setpoint (ps): {}".format(eTimingSetStr)
return s
class PhaseShifterAramis:
+40
View File
@@ -13,6 +13,8 @@ _basefolder = "/sf/bernina/config/eco/offsets"
PS = "SLAAR01-TSPL-EPL"
_basefolder = "/sf/alvra/config/lasertiming"
_posTypes = ["user", "dial", "raw"]
def timeToStr(value, n=12):
fmt = "%%+.%df" % n
@@ -317,3 +319,41 @@ class eTiming:
class PhaseShifterAramis:
def __init__(self, Id, name=None, elog=None, z_undulator=None, description=None):
self.Id = Id
self._pshifter = Phase_shifter(Id)
self._elog = elog
self.name = name
def set_target_value(self, value, hold=False, check=True):
""" Adjustable convention"""
mover = lambda: self._pshifter.move(value)
return Task(mover, hold=hold)
def stop(self):
""" Adjustable convention"""
pass
def get_current_value(self, posType="user", readback=True):
""" Adjustable convention"""
_keywordChecker([("posType", posType, _posTypes)])
if posType == "user":
return self._pshifter.get()
if posType == "dial":
return self._pshifter.get_dial()
def set_current_value(self, value, posType="user"):
""" Adjustable convention"""
_keywordChecker([("posType", posType, _posTypes)])
if posType == "user":
return self._motor.set(value)
def _keywordChecker(kw_key_list_tups):
for tkw, tkey, tlist in kw_key_list_tups:
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)