Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 32f33f9f9c |
+36
-46
@@ -1185,7 +1185,6 @@ namespace.append_obj(
|
||||
"RIXS",
|
||||
lazy=True,
|
||||
name="rixs",
|
||||
jf_id="JF14T01V01",
|
||||
config_jf_adj=config_JFs,
|
||||
pgroup_adj=config_bernina.pgroup,
|
||||
module_name="eco.endstations.bernina_rixs",
|
||||
@@ -1319,13 +1318,13 @@ namespace.append_obj(
|
||||
# module_name="eco.devices_general.cameras_swissfel",
|
||||
# )
|
||||
|
||||
namespace.append_obj(
|
||||
"OxygenSensor",
|
||||
"SARES20-CWAG-GPS01:ADC08",
|
||||
lazy=True,
|
||||
name="oxygen_sensor",
|
||||
module_name="eco.devices_general.sensors_ai",
|
||||
)
|
||||
# namespace.append_obj(
|
||||
# "OxygenSensor",
|
||||
# "SARES20-CWAG-GPS01:ADC08",
|
||||
# lazy=True,
|
||||
# name="oxygen_sensor",
|
||||
# module_name="eco.devices_general.sensors_ai",
|
||||
# )
|
||||
|
||||
# namespace.append_obj(
|
||||
# "CameraBasler",
|
||||
@@ -1401,12 +1400,12 @@ namespace.append_obj(
|
||||
)
|
||||
|
||||
|
||||
namespace.append_obj(
|
||||
"IncouplingCleanBernina",
|
||||
lazy=True,
|
||||
name="clic",
|
||||
module_name="eco.loptics.bernina_laser",
|
||||
)
|
||||
# namespace.append_obj(
|
||||
# "IncouplingCleanBernina",
|
||||
# lazy=True,
|
||||
# name="clic",
|
||||
# module_name="eco.loptics.bernina_laser",
|
||||
# )
|
||||
# namespace.append_obj(
|
||||
# "MidIR",
|
||||
# lazy=True,
|
||||
@@ -1573,39 +1572,30 @@ class Incoupling(Assembly):
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_15", name="thz_par2_rx", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_11", name="thz_par1_z", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_17", name="thz_par1_ry", is_setting=True
|
||||
# )
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_11", name="thz_par1_z", is_setting=True
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_17", name="thz_par1_ry", is_setting=True
|
||||
)
|
||||
|
||||
# try:
|
||||
# self.motor_configuration_thorlabs = {
|
||||
# "thz_filter": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL4",
|
||||
# },
|
||||
# "thz_crystal": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL3",
|
||||
# },
|
||||
# "thz_waveplate": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL5",
|
||||
# },
|
||||
# "nd_filter": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL2",
|
||||
# },
|
||||
# "polarizer": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL1",
|
||||
# },
|
||||
# }
|
||||
try:
|
||||
self.motor_configuration_thorlabs = {
|
||||
"hwp": {
|
||||
"thz_filter": {
|
||||
"pvname": "SLAAR21-LMOT-ELL4",
|
||||
},
|
||||
"thz_crystal": {
|
||||
"pvname": "SLAAR21-LMOT-ELL3",
|
||||
},
|
||||
"thz_waveplate": {
|
||||
"pvname": "SLAAR21-LMOT-ELL5",
|
||||
},
|
||||
"fw": {
|
||||
"nd_filter": {
|
||||
"pvname": "SLAAR21-LMOT-ELL2",
|
||||
},
|
||||
"polarizer": {
|
||||
"pvname": "SLAAR21-LMOT-ELL1",
|
||||
},
|
||||
}
|
||||
|
||||
### thorlabs piezo motors ###
|
||||
@@ -1623,9 +1613,9 @@ class Incoupling(Assembly):
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_18", name="opa_mirr2_ry", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_10", name="tt_nopa_target", is_setting=True
|
||||
# )
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_10", name="tt_nopa_target", is_setting=True
|
||||
)
|
||||
self._append(
|
||||
AnalogOutput,
|
||||
"SLAAR21-LDIO-LAS6991:DAC07_VOLTS",
|
||||
@@ -1639,9 +1629,9 @@ class Incoupling(Assembly):
|
||||
is_setting=True,
|
||||
)
|
||||
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_1", name="lens_z", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_2", name="lens_x", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_3", name="lens_y", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_X", name="lens_z", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_Y", name="lens_x", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_Z", name="lens_y", is_setting=True)
|
||||
# self._append(
|
||||
# MotorRecord, "SARES20-MF1:MOT_13", name="eos_mirr", is_setting=True
|
||||
# )
|
||||
|
||||
@@ -56,7 +56,7 @@ class CamserverConfig2(Assembly):
|
||||
precision=0,
|
||||
check_interval=None,
|
||||
name="_config",
|
||||
is_setting=True,
|
||||
is_setting=False,
|
||||
is_display=False,
|
||||
)
|
||||
|
||||
@@ -64,7 +64,7 @@ class CamserverConfig2(Assembly):
|
||||
AdjustableObject,
|
||||
self._config,
|
||||
name="config",
|
||||
is_setting=False,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
)
|
||||
self._append(
|
||||
|
||||
@@ -10,7 +10,6 @@ from ..aliases import Alias
|
||||
from ..elements.adjustable import (
|
||||
AdjustableError,
|
||||
AdjustableFS,
|
||||
AdjustableGetSet,
|
||||
AdjustableMemory,
|
||||
spec_convenience,
|
||||
ValueInRange,
|
||||
@@ -884,7 +883,7 @@ class SmarActOpenLoopRecord(Assembly):
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_position.json",
|
||||
name="_position",
|
||||
name="position",
|
||||
default_value=0,
|
||||
is_setting=True,
|
||||
is_display=True,
|
||||
@@ -908,7 +907,7 @@ class SmarActOpenLoopRecord(Assembly):
|
||||
|
||||
def move(self, value, check=True, wait=False):
|
||||
value = int(value) * self.direction()
|
||||
pos = int(self._position() * self.direction())
|
||||
pos = int(self.position() * self.direction())
|
||||
target_rel = value - pos
|
||||
if check:
|
||||
if self.limit_low:
|
||||
@@ -925,7 +924,7 @@ class SmarActOpenLoopRecord(Assembly):
|
||||
f":MST{self.channel-1},{target_rel},{int(self.voltage()*40.95)},{int(self.frequency())}"
|
||||
)
|
||||
if res[-1] == "0":
|
||||
self._position.mv(value)
|
||||
self.position.mv(value)
|
||||
else:
|
||||
raise Exception(
|
||||
f"Motion of SmarAct Motor {self.name} failed with error code {res}"
|
||||
@@ -939,197 +938,7 @@ class SmarActOpenLoopRecord(Assembly):
|
||||
self.limit_high.set_target_value(limit_high)
|
||||
|
||||
def get_current_value(self):
|
||||
return self._position.get_current_value()
|
||||
|
||||
def set_current_value(self, value):
|
||||
self._position(value)
|
||||
|
||||
def set_target_value(self, value, hold=False, check=True, **kwargs):
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=self.move,
|
||||
hold=hold,
|
||||
stopper=self.stop,
|
||||
)
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
# """ return short info for the current motor"""
|
||||
s = f"{self.name}"
|
||||
# s += f"\t@ {colorama.Style.BRIGHT}{self.get_current_value():1.6g}{colorama.Style.RESET_ALL} stat: {self.status_flag().name}"
|
||||
s += f"\t@ {colorama.Style.BRIGHT}{self.get_current_value():1.6g}{colorama.Style.RESET_ALL}"
|
||||
# # s += "\tuser limits (low,high) : {:1.6g},{:1.6g}\n".format(*self.get_limits())
|
||||
s += f"\n{colorama.Style.DIM}low limit {colorama.Style.RESET_ALL}"
|
||||
s += ValueInRange(*self.get_limits()).get_str(self.get_current_value())
|
||||
s += f" {colorama.Style.DIM}high limit{colorama.Style.RESET_ALL}"
|
||||
# # s += "\tuser limits (low,high) : {:1.6g},{1.6g}".format(self.get_limits())
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
print(str(self))
|
||||
return object.__repr__(self)
|
||||
|
||||
|
||||
@spec_convenience
|
||||
# @get_from_archive
|
||||
@value_property
|
||||
@tweak_option
|
||||
class SmarActOpenLoopRecordMCS2(Assembly):
|
||||
def __init__(self, pvname=None, channel=None, name=None):
|
||||
super().__init__(name=name)
|
||||
self.pvname = pvname
|
||||
self.channel = channel
|
||||
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
self.pvname.split(":")[0] + f":MOT_{self.channel}.DESC",
|
||||
name="description",
|
||||
is_setting=False,
|
||||
is_display=False,
|
||||
)
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
self.pvname + ".AOUT",
|
||||
name="_com_set",
|
||||
is_setting=False,
|
||||
is_display=False,
|
||||
)
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
self.pvname + ".TINP",
|
||||
name="_com_get",
|
||||
is_setting=False,
|
||||
is_display=False,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_limit_high.json",
|
||||
default_value=-1e6,
|
||||
name="limit_high",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_limit_low.json",
|
||||
default_value=1e6,
|
||||
name="limit_low",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_voltage.json",
|
||||
name="voltage",
|
||||
default_value=25,
|
||||
is_setting=True,
|
||||
is_display=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_frequency.json",
|
||||
name="frequency",
|
||||
default_value=250,
|
||||
is_setting=True,
|
||||
is_display=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_position.json",
|
||||
name="_position",
|
||||
default_value=0,
|
||||
is_setting=True,
|
||||
is_display=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustableFS,
|
||||
f"/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/smaract_openloop_{name}_direction.json",
|
||||
name="direction",
|
||||
default_value=1,
|
||||
is_setting=True,
|
||||
is_display=True,
|
||||
)
|
||||
|
||||
def get_motion_mode():
|
||||
return int(self.eval_command(f":CHAN{self.channel-1}:MMOD?"))
|
||||
|
||||
def set_motion_mode(value):
|
||||
self.eval_command(f":CHAN{self.channel-1}:MMOD {value}")
|
||||
|
||||
self._append(
|
||||
AdjustableGetSet,
|
||||
get_motion_mode,
|
||||
set_motion_mode,
|
||||
set_returns_changer=False,
|
||||
precision=0,
|
||||
check_interval=None,
|
||||
cache_get_seconds=None,
|
||||
unit=None,
|
||||
name="motion_mode",
|
||||
)
|
||||
|
||||
if not self.motion_mode() == 4:
|
||||
self.motion_mode.mv_elog(
|
||||
4,
|
||||
f"Setting SmarAct Channel {self.channel} on {self.pvname} to Open Loop (4). To go back to closed loop, set it to (0)",
|
||||
)
|
||||
|
||||
def eval_command(self, cmd):
|
||||
self._com_set(cmd)
|
||||
sleep(0.2)
|
||||
return self._com_get()
|
||||
|
||||
def stop(self):
|
||||
self._com_set(f":STOP{self.channel-1}")
|
||||
|
||||
def move(self, value, check=True, wait=True):
|
||||
value = int(value) * self.direction()
|
||||
pos = int(self._position() * self.direction())
|
||||
target_rel = value - pos
|
||||
if check:
|
||||
if self.limit_low:
|
||||
if value < self.limit_low():
|
||||
raise Exception(
|
||||
f"Target value of {self.name} is smaller than limit value!"
|
||||
)
|
||||
if self.limit_high:
|
||||
if self.limit_high() < value:
|
||||
raise Exception(
|
||||
f"Target value of {self.name} is higher than limit value!"
|
||||
)
|
||||
self.eval_command(f":MOVE{self.channel-1} {target_rel}")
|
||||
if wait:
|
||||
while not self.get_move_done():
|
||||
sleep(0.1)
|
||||
self._position.mv(value)
|
||||
|
||||
def get_limits(self):
|
||||
return (self.limit_low(), self.limit_high())
|
||||
|
||||
def get_move_done(self):
|
||||
stat = self.get_status()
|
||||
if int(stat[-1]) == 9:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_status(self):
|
||||
stat = self.eval_command(f":CHAN{self.channel-1}:STAT?")
|
||||
if len(stat) == 0:
|
||||
for n in range(10):
|
||||
stat = self.eval_command(f":CHAN{self.channel-1}:STAT?")
|
||||
if len(stat) > 0:
|
||||
break
|
||||
return stat
|
||||
|
||||
def set_limits(self, limit_low, limit_high):
|
||||
self.limit_low.set_target_value(limit_low)
|
||||
self.limit_high.set_target_value(limit_high)
|
||||
|
||||
def get_current_value(self):
|
||||
return self._position.get_current_value()
|
||||
|
||||
def set_current_value(self, value):
|
||||
self._position(value)
|
||||
return self.position.get_current_value()
|
||||
|
||||
def set_target_value(self, value, hold=False, check=True, **kwargs):
|
||||
return Changer(
|
||||
|
||||
@@ -7,26 +7,28 @@ class OxygenSensor(AnalogInput):
|
||||
super().__init__(pvname, name=name)
|
||||
self.unit.set_target_value("%")
|
||||
|
||||
def set_no_oxygen(self, raw_val=None):
|
||||
if not raw_val:
|
||||
raw_val = self.raw.get_current_value()
|
||||
def set_no_oxygen(self, val_curr=None):
|
||||
if not val_curr:
|
||||
val_curr = self.raw.get_current_value()
|
||||
slo = self.linear_calibration_slope.get_current_value()
|
||||
off = self.linear_calibration_offset.get_current_value()
|
||||
r0 = raw_val
|
||||
r100 = (100 - off) / slo
|
||||
slo_n = 100 / (r100 - r0)
|
||||
off_n = -slo_n * r0
|
||||
|
||||
off_n = -slo * val_curr
|
||||
af = (100 - off) / slo
|
||||
# slo_new = slo*((100-val_curr)/(100-off))
|
||||
slo_n = 100 / af
|
||||
self.linear_calibration_offset(off_n)
|
||||
self.linear_calibration_slope(slo_n)
|
||||
|
||||
def set_full_oxygen(self, raw_val=None):
|
||||
if not raw_val:
|
||||
raw_val = self.raw.get_current_value()
|
||||
def set_full_oxygen(self, val_curr=None):
|
||||
if not val_curr:
|
||||
val_curr = self.raw.get_current_value()
|
||||
af = val_curr
|
||||
slo = self.linear_calibration_slope.get_current_value()
|
||||
off = self.linear_calibration_offset.get_current_value()
|
||||
r0 = -(off / slo)
|
||||
r100 = raw_val
|
||||
slo_n = 100 / (r100 - r0)
|
||||
off_n = -slo_n * r0
|
||||
|
||||
az = -off / slo
|
||||
slo_n = 100 / (af - az)
|
||||
off_n = -slo_n * az
|
||||
self.linear_calibration_offset(off_n)
|
||||
self.linear_calibration_slope(slo_n)
|
||||
|
||||
@@ -22,43 +22,32 @@ class Incoupling(Assembly):
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_15", name="thz_par2_rx", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_11", name="thz_par1_z", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_17", name="thz_par1_ry", is_setting=True
|
||||
# )
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS3:MOT_17", name="power_check", is_setting=True
|
||||
SmaractRecord, "SARES20-MCS2:MOT_11", name="thz_par1_z", is_setting=True
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_17", name="thz_par1_ry", is_setting=True
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
self.motor_configuration_thorlabs = {
|
||||
# "thz_filter": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL4",
|
||||
# },
|
||||
# "thz_crystal": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL3",
|
||||
# },
|
||||
# "thz_waveplate": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL5",
|
||||
# },
|
||||
# "nd_filter": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL2",
|
||||
# },
|
||||
# "polarizer": {
|
||||
# "pvname": "SLAAR21-LMOT-ELL1",
|
||||
# },
|
||||
|
||||
"waveplate": {
|
||||
"thz_filter": {
|
||||
"pvname": "SLAAR21-LMOT-ELL4",
|
||||
},
|
||||
"thz_crystal": {
|
||||
"pvname": "SLAAR21-LMOT-ELL3",
|
||||
},
|
||||
"thz_waveplate": {
|
||||
"pvname": "SLAAR21-LMOT-ELL5",
|
||||
},
|
||||
"filter_wheel": {
|
||||
"nd_filter": {
|
||||
"pvname": "SLAAR21-LMOT-ELL2",
|
||||
},
|
||||
|
||||
"polarizer": {
|
||||
"pvname": "SLAAR21-LMOT-ELL1",
|
||||
},
|
||||
}
|
||||
|
||||
### thorlabs piezo motors ###
|
||||
for name, config in self.motor_configuration_thorlabs.items():
|
||||
self._append(
|
||||
@@ -71,24 +60,24 @@ class Incoupling(Assembly):
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# self._append(
|
||||
# AdjustableInterpolate,
|
||||
# self.nd_filter,
|
||||
# filename_calib="/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/nd_filter_wheel_thlabs.json",
|
||||
# deadband=None,
|
||||
# interp_method="next",
|
||||
# callbacks_before_change=[],
|
||||
# callbacks_after_change=[],
|
||||
# unit="OptDens",
|
||||
# name="nd_filter_optical_density",
|
||||
# )
|
||||
self._append(
|
||||
AdjustableInterpolate,
|
||||
self.nd_filter,
|
||||
filename_calib="/sf/bernina/code/gac-bernina/eco_cnf_bernina/reference_values/nd_filter_wheel_thlabs.json",
|
||||
deadband=None,
|
||||
interp_method="next",
|
||||
callbacks_before_change=[],
|
||||
callbacks_after_change=[],
|
||||
unit="OptDens",
|
||||
name="nd_filter_optical_density",
|
||||
)
|
||||
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_18", name="opa_mirr2_ry", is_setting=True
|
||||
# )
|
||||
# self._append(
|
||||
# SmaractRecord, "SARES20-MCS2:MOT_10", name="tt_nopa_target", is_setting=True
|
||||
# )
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_18", name="opa_mirr2_ry", is_setting=True
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord, "SARES20-MCS2:MOT_10", name="tt_nopa_target", is_setting=True
|
||||
)
|
||||
self._append(
|
||||
AnalogOutput,
|
||||
"SLAAR21-LDIO-LAS6991:DAC07_VOLTS",
|
||||
@@ -102,56 +91,56 @@ class Incoupling(Assembly):
|
||||
is_setting=True,
|
||||
)
|
||||
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_1", name="lens_z", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_2", name="lens_x", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_3", name="lens_y", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_5", name="lens_z", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_6", name="lens_x", is_setting=True)
|
||||
self._append(MotorRecord, "SARES20-XPS1:MOT_4", name="lens_y", is_setting=True)
|
||||
# self._append(
|
||||
# MotorRecord, "SARES20-MF1:MOT_13", name="eos_mirr", is_setting=True
|
||||
# )
|
||||
|
||||
# self._append(
|
||||
# AnalogOutput,
|
||||
# "SLAAR21-LDIO-LAS6991:DAC06_VOLTS",
|
||||
# name="eos_fb_rx",
|
||||
# is_setting=True,
|
||||
# )
|
||||
# self._append(
|
||||
# AnalogOutput,
|
||||
# "SLAAR21-LDIO-LAS6991:DAC05_VOLTS",
|
||||
# name="eos_fb_ry",
|
||||
# is_setting=True,
|
||||
# )
|
||||
self._append(
|
||||
AnalogOutput,
|
||||
"SLAAR21-LDIO-LAS6991:DAC06_VOLTS",
|
||||
name="eos_fb_rx",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
AnalogOutput,
|
||||
"SLAAR21-LDIO-LAS6991:DAC05_VOLTS",
|
||||
name="eos_fb_ry",
|
||||
is_setting=True,
|
||||
)
|
||||
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
pvsetname="SLAAR21-LCAM-C561:FIT2_REQUIRED.PROC",
|
||||
name="fb_setpoint_rq",
|
||||
name="eos_fb_setpoint_rq",
|
||||
accuracy=1,
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
pvsetname="SLAAR21-LCAM-C561:FIT2_DEFAULT.PROC",
|
||||
name="fb_setpoint_df",
|
||||
name="eos_fb_setpoint_df",
|
||||
accuracy=1,
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
AdjustablePv,
|
||||
pvsetname="SLAAR21-LTIM01-EVR0:CALCW.A",
|
||||
name="fd_enable",
|
||||
name="eos_fd_enable",
|
||||
accuracy=1,
|
||||
is_setting=True,
|
||||
)
|
||||
|
||||
# self._append(
|
||||
# AdjustableVirtual,
|
||||
# [self.thz_crystal, self.thz_waveplate],
|
||||
# lambda c, w: c,
|
||||
# lambda angle: [angle, angle / 2],
|
||||
# name="thz_polarization",
|
||||
# is_setting=False,
|
||||
# )
|
||||
self._append(
|
||||
AdjustableVirtual,
|
||||
[self.thz_crystal, self.thz_waveplate],
|
||||
lambda c, w: c,
|
||||
lambda angle: [angle, angle / 2],
|
||||
name="thz_polarization",
|
||||
is_setting=False,
|
||||
)
|
||||
|
||||
self._append(
|
||||
DetectorPvData,
|
||||
@@ -165,11 +154,11 @@ class Incoupling(Assembly):
|
||||
name="pump_intensity",
|
||||
)
|
||||
|
||||
# self._append(
|
||||
# DetectorPvData,
|
||||
# "SARES20-LSCP9-FNS:CH6:VAL_GET",
|
||||
# name="shg_intensity",
|
||||
# )
|
||||
self._append(
|
||||
DetectorPvData,
|
||||
"SARES20-LSCP9-FNS:CH6:VAL_GET",
|
||||
name="shg_intensity",
|
||||
)
|
||||
# IOXAS (SARES20_CH6)
|
||||
|
||||
# self._append(
|
||||
|
||||
@@ -303,12 +303,13 @@ class DetectorStages(Assembly):
|
||||
f"Initialization of epics motor {name}: {pvname}:{pvmot} failed, replaced by dummy!"
|
||||
)
|
||||
|
||||
|
||||
class RIXS(Assembly):
|
||||
def __init__(
|
||||
self,
|
||||
name=None,
|
||||
pvname="SARES22-RIXS",
|
||||
jf_id="JF14T01V01",
|
||||
jf_id="JF05T01V01",
|
||||
config_jf_adj=None,
|
||||
pgroup_adj=None,
|
||||
alias_namespace=None,
|
||||
@@ -378,10 +379,13 @@ class RIXS(Assembly):
|
||||
pvname=pvname,
|
||||
)
|
||||
|
||||
self.append_multi_analyzer_motion(
|
||||
analyzer_list=[self.ana_right, self.ana_center, self.ana_left],
|
||||
name="energy_all_analyzers"
|
||||
)
|
||||
# self.append_analyzer(
|
||||
# pos=2,
|
||||
# analyzer="Si844",
|
||||
# hkl=(8, 4, 4),
|
||||
# name="ana2_laser",
|
||||
# pvname=pvname,
|
||||
# )
|
||||
|
||||
self._append(
|
||||
Jungfrau,
|
||||
@@ -422,45 +426,20 @@ class RIXS(Assembly):
|
||||
is_display="recursive",
|
||||
)
|
||||
|
||||
def append_multi_analyzer_motion(self, analyzer_list = [], name=None):
|
||||
|
||||
detector_motors = [self.det.t_hor, self.det.t_ver, self.det.rot]
|
||||
analyzer_motors = [motor for ana in analyzer_list for motor in [ana.__dict__["om"], ana.__dict__["t_hor"]]]
|
||||
|
||||
def motor_pos_from_energy_multy_analyzers(energy):
|
||||
motor_positions = np.array([ana.motor_pos_from_energy(energy) for ana in analyzer_list])
|
||||
|
||||
detector_positions = motor_positions[:,2:]
|
||||
if np.sum(np.std(detector_positions, axis=0)) > 0.1:
|
||||
raise (f"Conflicting detector target positions in multi analyzer motion: {[[ana.name, det_pos] for ana, det_pos in zip(analyzer_list, detector_positions)]}, check analyzer configuration")
|
||||
else:
|
||||
detector_position = np.mean(detector_positions, axis=0)
|
||||
analyzer_positions = np.concat(motor_positions[:,0:2])
|
||||
return np.concat([detector_position, analyzer_positions])
|
||||
|
||||
def energy_from_motor_pos_multy_analyzers(*args, **kwargs):
|
||||
energies = np.array([[ana.energy()] for ana in analyzer_list])
|
||||
if None in energies:
|
||||
return None
|
||||
elif np.std(energies) > 0.1:
|
||||
return None
|
||||
else:
|
||||
return np.mean(energies)
|
||||
|
||||
self._append(
|
||||
AdjustableVirtual,
|
||||
detector_motors+analyzer_motors,
|
||||
energy_from_motor_pos_multy_analyzers,
|
||||
motor_pos_from_energy_multy_analyzers,
|
||||
is_setting=False,
|
||||
is_display=True,
|
||||
name=name,
|
||||
unit="eV",
|
||||
)
|
||||
|
||||
def gui(self, guiType="xdm"):
|
||||
"""Adjustable convention"""
|
||||
cmd = ["caqtdm", "-macro"]
|
||||
cmd += ["P=SARES22-RIXS", "ESB_RIXS_motors.ui"]
|
||||
return self._run_cmd(" ".join(cmd))
|
||||
|
||||
# def get_adjustable_positions_str(self):
|
||||
# ostr = "*****GPS motor positions******\n"
|
||||
|
||||
# for tkey, item in self.__dict__.items():
|
||||
# if hasattr(item, "get_current_value"):
|
||||
# pos = item.get_current_value()
|
||||
# ostr += " " + tkey.ljust(17) + " : % 14g\n" % pos
|
||||
# return ostr
|
||||
|
||||
# def __repr__(self):
|
||||
# return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -13,7 +13,7 @@ from ..devices_general.motors import (
|
||||
MotorRecord,
|
||||
SmaractRecord,
|
||||
ThorlabsPiezoRecord,
|
||||
SmarActOpenLoopRecordMCS2,
|
||||
SmarActOpenLoopRecord,
|
||||
)
|
||||
from ..epics.adjustable import AdjustablePv
|
||||
import numpy as np
|
||||
@@ -1609,21 +1609,6 @@ def get_array_frame(a):
|
||||
return np.concatenate([a[:, 0], a[-1, 1:], a[-2::-1, -1], a[0, -2::-1]])
|
||||
|
||||
|
||||
class GicCameras(Assembly):
|
||||
def __init__(self, name=None, camera_config={}):
|
||||
super().__init__(name=name)
|
||||
for name, cfg in camera_config.items():
|
||||
self._append(
|
||||
CameraBasler,
|
||||
cfg["pvname"],
|
||||
camserver_alias="GIC_" + name,
|
||||
name=name,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
)
|
||||
self.__dict__[name].serial_no.mv(cfg["serial_number"])
|
||||
|
||||
|
||||
class GrazingIncidenceLowTemperatureChamber(Assembly):
|
||||
def __init__(self, xp=None, helium_control_valve=None, name=None):
|
||||
super().__init__(name=name)
|
||||
@@ -1662,23 +1647,6 @@ class GrazingIncidenceLowTemperatureChamber(Assembly):
|
||||
"channel": 14,
|
||||
},
|
||||
}
|
||||
self.camera_configuration = {
|
||||
"inline": {
|
||||
"pvname": "SARES20-CAMS142-M1",
|
||||
"serial_number": 40298870,
|
||||
},
|
||||
"sideview": {
|
||||
"pvname": "SARES20-CAMS142-M2",
|
||||
"serial_number": 40298884,
|
||||
},
|
||||
}
|
||||
|
||||
self._append(
|
||||
GicCameras,
|
||||
name="samplecam",
|
||||
camera_config=self.camera_configuration,
|
||||
)
|
||||
|
||||
for name, config in self.motor_configuration.items():
|
||||
self._append(
|
||||
SmaractRecord,
|
||||
@@ -1689,7 +1657,7 @@ class GrazingIncidenceLowTemperatureChamber(Assembly):
|
||||
|
||||
for name, config in self.motor_configuration_openloop.items():
|
||||
self._append(
|
||||
SmarActOpenLoopRecordMCS2,
|
||||
SmarActOpenLoopRecord,
|
||||
pvname=config["id"],
|
||||
name=name,
|
||||
channel=config["channel"],
|
||||
|
||||
@@ -1350,30 +1350,6 @@ class LaserBernina(Assembly):
|
||||
name="delay_twin",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord,
|
||||
"SLAAR21-LMTS-SMAR1:MOT_5",
|
||||
name="delaystage_ftir",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord,
|
||||
"SLAAR21-LMTS-SMAR1:MOT_4",
|
||||
name="dfg_rot",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
SmaractRecord,
|
||||
"SLAAR21-LMTS-SMAR1:MOT_3",
|
||||
name="dfg_pos",
|
||||
is_setting=True,
|
||||
)
|
||||
self._append(
|
||||
DelayTime,
|
||||
self.delaystage_ftir,
|
||||
name="delay_ftir",
|
||||
is_setting=True,
|
||||
)
|
||||
|
||||
self._append(
|
||||
DelayTime,
|
||||
|
||||
@@ -292,9 +292,9 @@ class TimetoolBerninaUSD(Assembly):
|
||||
for pos in x:
|
||||
print(f"Moving to {pos*1e15} fs")
|
||||
self.delay.set_target_value(pos).wait()
|
||||
pids_start.append(int(pid.value))
|
||||
pids_start.append(pid.value)
|
||||
sleep(seconds)
|
||||
pids_stop.append(int(pid.value))
|
||||
pids_stop.append(pid.value)
|
||||
retrieving = True
|
||||
i = 1
|
||||
source = dh.Daqbuf()
|
||||
@@ -401,10 +401,10 @@ class TimetoolBerninaUSD(Assembly):
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
if to_elog:
|
||||
fpath = f"{Path.home()}/temp/tt_calib.jpg"
|
||||
fpath = "/photonics/home/gac-bernina/tt_calib.jpg"
|
||||
fig.savefig(fpath, dpi=200)
|
||||
fpath = Path(fpath)
|
||||
dpath = Path(f"{Path.home()}/temp/tt_calib.pkl")
|
||||
dpath = Path("/photonics/home/gac-bernina/tt_calib.pkl")
|
||||
df = DataFrame({"tt_kb.delay": x, "tt_kb.edge_position_px": y})
|
||||
df.to_pickle(dpath)
|
||||
if to_elog:
|
||||
@@ -767,10 +767,10 @@ class TimetoolBerninaDSD(Assembly):
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
if to_elog:
|
||||
fpath = f"{Path.home()}/temp/tt_calib.jpg"
|
||||
fpath = "/photonics/home/gac-bernina/tt_calib.jpg"
|
||||
fig.savefig(fpath, dpi=200)
|
||||
fpath = Path(fpath)
|
||||
dpath = Path(f"{Path.home()}/temp/tt_calib.pkl")
|
||||
dpath = Path("/photonics/home/gac-bernina/tt_calib.pkl")
|
||||
df = DataFrame({"tt_kb.delay": x, "tt_kb.edge_position_px": y})
|
||||
df.to_pickle(dpath)
|
||||
if to_elog:
|
||||
|
||||
+275
-156
@@ -19,7 +19,8 @@ from importlib import import_module
|
||||
from lazy_object_proxy import Proxy as Proxy_orig
|
||||
from tabulate import tabulate
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from threading import Thread
|
||||
from dataclasses import dataclass, field
|
||||
from threading import Event, Thread, local
|
||||
from tqdm import tqdm
|
||||
from rich import progress
|
||||
from inspect import signature
|
||||
@@ -113,7 +114,7 @@ def format_manual_instantiation(
|
||||
]
|
||||
call_text = f"{obj_name}({', '.join(call_parts)})"
|
||||
|
||||
return f"For manual instantiation copy/paste: {import_stmt}; {call_text}"
|
||||
return f"Manual instantiation attempt: {import_stmt}; {call_text}"
|
||||
|
||||
|
||||
def append_manual_context(exc, manual_context):
|
||||
@@ -176,7 +177,7 @@ def replaceComponent(inp, dict_all, config_all, lazy=False):
|
||||
ind = [ta.name == tca["name"] for tca in config_all].index(True)
|
||||
outp.append(
|
||||
initFromConfigList(
|
||||
config_list[ind : ind + 1], config_all, lazy=lazy
|
||||
config_all[ind : ind + 1], config_all, lazy=lazy
|
||||
)
|
||||
)
|
||||
elif isinstance(ta, dict) or isinstance(ta, list):
|
||||
@@ -190,9 +191,9 @@ def replaceComponent(inp, dict_all, config_all, lazy=False):
|
||||
if ta.name in dict_all.keys():
|
||||
outp[tk] = dict_all[ta.name]
|
||||
else:
|
||||
ind = [tk.name == tca["name"] for tca in config_all].index(True)
|
||||
ind = [ta.name == tca["name"] for tca in config_all].index(True)
|
||||
outp[tk] = initFromConfigList(
|
||||
config_list[ind : ind + 1], config_all, lazy=lazy
|
||||
config_all[ind : ind + 1], config_all, lazy=lazy
|
||||
)
|
||||
elif isinstance(ta, dict) or isinstance(ta, list):
|
||||
outp[tk] = replaceComponent(ta, dict_all, config_all, lazy=lazy)
|
||||
@@ -356,6 +357,21 @@ class IsInitialisingError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class LazyNode:
|
||||
name: str
|
||||
factory: object
|
||||
args: tuple
|
||||
kwargs: dict
|
||||
module_name: str = None
|
||||
dependencies: set = field(default_factory=set)
|
||||
state: str = "pending"
|
||||
result: object = None
|
||||
exception: Exception = None
|
||||
event: Event = field(default_factory=Event)
|
||||
start_time: float = 0.0
|
||||
|
||||
|
||||
class Namespace(Assembly):
|
||||
def __init__(
|
||||
self,
|
||||
@@ -368,6 +384,7 @@ class Namespace(Assembly):
|
||||
super().__init__(name)
|
||||
# self.name = name
|
||||
self.lazy_items = {}
|
||||
self.lazy_nodes = {}
|
||||
self.initialized_items = {}
|
||||
self.failed_items = {}
|
||||
self.failed_items_excpetion = {}
|
||||
@@ -378,6 +395,7 @@ class Namespace(Assembly):
|
||||
|
||||
self.names_without_alias = []
|
||||
self._initializing = []
|
||||
self._thread_local = local()
|
||||
self.root_module = root_module
|
||||
self.alias_namespace = alias_namespace
|
||||
if required_names_directory:
|
||||
@@ -430,6 +448,10 @@ class Namespace(Assembly):
|
||||
names = self.failed_names
|
||||
for name in names:
|
||||
self.lazy_items[name] = self.failed_items.pop(name)
|
||||
self.lazy_nodes[name].state = "pending"
|
||||
self.lazy_nodes[name].result = None
|
||||
self.lazy_nodes[name].exception = None
|
||||
self.lazy_nodes[name].event.clear()
|
||||
try:
|
||||
self.failed_items_excpetion.pop(name)
|
||||
except KeyError:
|
||||
@@ -821,6 +843,202 @@ class Namespace(Assembly):
|
||||
aliases_out = aliases
|
||||
return aliases, has_no_aliases
|
||||
|
||||
def _collect_dependencies_from_value(self, value):
|
||||
if isinstance(value, NamespaceComponent):
|
||||
return {value.obj_name}
|
||||
if isinstance(value, Component):
|
||||
return {value.name}
|
||||
if isinstance(value, list):
|
||||
deps = set()
|
||||
for item in value:
|
||||
deps |= self._collect_dependencies_from_value(item)
|
||||
return deps
|
||||
if isinstance(value, tuple):
|
||||
deps = set()
|
||||
for item in value:
|
||||
deps |= self._collect_dependencies_from_value(item)
|
||||
return deps
|
||||
if isinstance(value, dict):
|
||||
deps = set()
|
||||
for item in value.values():
|
||||
deps |= self._collect_dependencies_from_value(item)
|
||||
return deps
|
||||
return set()
|
||||
|
||||
def _collect_dependencies(self, *args, **kwargs):
|
||||
dependencies = set()
|
||||
for value in args:
|
||||
dependencies |= self._collect_dependencies_from_value(value)
|
||||
for value in kwargs.values():
|
||||
dependencies |= self._collect_dependencies_from_value(value)
|
||||
return dependencies
|
||||
|
||||
def _resolve_factory_inputs(self, *args, lazy=False, **kwargs):
|
||||
resolved_args = []
|
||||
for value in args:
|
||||
resolved_args.append(self._resolve_factory_input(value, lazy=lazy))
|
||||
|
||||
resolved_kwargs = {}
|
||||
for key, value in kwargs.items():
|
||||
resolved_kwargs[key] = self._resolve_factory_input(value, lazy=lazy)
|
||||
|
||||
return resolved_args, resolved_kwargs
|
||||
|
||||
def _resolve_factory_input(self, value, lazy=False):
|
||||
if isinstance(value, NamespaceComponent):
|
||||
if lazy:
|
||||
return Proxy(lambda value=value: value.get())
|
||||
return self._materialize_dependency(value.obj_name)
|
||||
|
||||
if isinstance(value, Component):
|
||||
if lazy:
|
||||
return Proxy(lambda name=value.name: self._get_ready_object(name))
|
||||
return self._materialize_dependency(value.name)
|
||||
|
||||
if isinstance(value, list):
|
||||
return [self._resolve_factory_input(item, lazy=lazy) for item in value]
|
||||
|
||||
if isinstance(value, tuple):
|
||||
return tuple(self._resolve_factory_input(item, lazy=lazy) for item in value)
|
||||
|
||||
if isinstance(value, dict):
|
||||
return {
|
||||
key: self._resolve_factory_input(item, lazy=lazy)
|
||||
for key, item in value.items()
|
||||
}
|
||||
|
||||
return value
|
||||
|
||||
def _get_ready_object(self, name):
|
||||
if name in self.initialized_names:
|
||||
return self.initialized_items[name]
|
||||
if name in self.lazy_names:
|
||||
return self._ensure_node(name)
|
||||
raise Exception(f"Name {name} is not initialized!")
|
||||
|
||||
def _materialize_dependency(self, name):
|
||||
if name in self.initialized_names:
|
||||
return self.initialized_items[name]
|
||||
|
||||
if name not in self.lazy_names:
|
||||
raise Exception(f"Name {name} is not initialized!")
|
||||
|
||||
proxy = self.lazy_items.get(name)
|
||||
obj = self._ensure_node(name)
|
||||
if proxy is not None:
|
||||
self.lazy_items[name] = proxy
|
||||
return obj
|
||||
|
||||
def _ensure_node(self, name):
|
||||
node = self.lazy_nodes[name]
|
||||
if node.state == "done":
|
||||
return node.result
|
||||
if node.state == "failed":
|
||||
raise node.exception
|
||||
|
||||
if node.state == "pending":
|
||||
node.state = "running"
|
||||
node.start_time = time()
|
||||
node.event.clear()
|
||||
worker = Thread(target=self._run_node, args=(name,), daemon=True)
|
||||
worker.start()
|
||||
|
||||
node.event.wait()
|
||||
|
||||
if node.state == "done":
|
||||
return node.result
|
||||
if node.state == "failed":
|
||||
raise node.exception
|
||||
|
||||
raise RuntimeError(f"Lazy node {name} did not complete cleanly")
|
||||
|
||||
def _run_node(self, name):
|
||||
node = self.lazy_nodes[name]
|
||||
stack = getattr(self._thread_local, "stack", [])
|
||||
try:
|
||||
if name in stack:
|
||||
raise RuntimeError(f"Cyclic lazy dependency detected for {name}")
|
||||
|
||||
stack.append(name)
|
||||
self._thread_local.stack = stack
|
||||
|
||||
for dep_name in node.dependencies:
|
||||
self._ensure_node(dep_name)
|
||||
|
||||
obj_maker = node.factory
|
||||
if node.module_name:
|
||||
obj_maker = getattr(import_module(node.module_name), node.factory)
|
||||
|
||||
args_resolved, kwargs_resolved = self._resolve_factory_inputs(
|
||||
*node.args, lazy=True, **node.kwargs
|
||||
)
|
||||
accepts_name = "name" in signature(obj_maker).parameters
|
||||
manual_context = format_manual_instantiation(
|
||||
obj_maker,
|
||||
args_resolved,
|
||||
kwargs_resolved,
|
||||
name=name,
|
||||
accepts_name=accepts_name,
|
||||
module_name=node.module_name,
|
||||
)
|
||||
try:
|
||||
if accepts_name:
|
||||
obj_initialized = obj_maker(
|
||||
*args_resolved,
|
||||
name=name,
|
||||
**kwargs_resolved,
|
||||
)
|
||||
else:
|
||||
obj_initialized = obj_maker(*args_resolved, **kwargs_resolved)
|
||||
except Exception as e:
|
||||
append_manual_context(e, manual_context)
|
||||
self.failed_items[name] = self.lazy_items.pop(name)
|
||||
self.failed_items_excpetion[name] = e
|
||||
node.state = "failed"
|
||||
node.exception = e
|
||||
node.result = None
|
||||
return
|
||||
|
||||
self.initialized_items[name] = obj_initialized
|
||||
self.initialisation_times_lazy[name] = time() - node.start_time
|
||||
try:
|
||||
self.lazy_items.pop(name)
|
||||
except KeyError:
|
||||
pass
|
||||
node.state = "done"
|
||||
node.result = obj_initialized
|
||||
node.exception = None
|
||||
|
||||
if hasattr(obj_initialized, "alias"):
|
||||
self._append(
|
||||
obj_initialized,
|
||||
name=name,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
call_obj=False,
|
||||
)
|
||||
if self.alias_namespace and hasattr(obj_initialized, "alias"):
|
||||
for ta in obj_initialized.alias.get_all():
|
||||
try:
|
||||
self.alias_namespace.update(
|
||||
ta["alias"], ta["channel"], ta["channeltype"]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f'could not init alias {ta["alias"]}')
|
||||
print("error message", e)
|
||||
else:
|
||||
self.names_without_alias.append(name)
|
||||
return obj_initialized
|
||||
except Exception as e:
|
||||
node.state = "failed"
|
||||
node.exception = e
|
||||
node.result = None
|
||||
return
|
||||
finally:
|
||||
node.event.set()
|
||||
stack.pop()
|
||||
self._thread_local.stack = stack
|
||||
|
||||
def append_obj(
|
||||
self,
|
||||
obj_factory,
|
||||
@@ -831,152 +1049,63 @@ class Namespace(Assembly):
|
||||
init_timeout=30,
|
||||
**kwargs,
|
||||
):
|
||||
self.failed_items.pop(name, None)
|
||||
self.failed_items_excpetion.pop(name, None)
|
||||
self.initialized_items.pop(name, None)
|
||||
self.lazy_items.pop(name, None)
|
||||
self.lazy_nodes.pop(name, None)
|
||||
|
||||
if lazy:
|
||||
|
||||
def init_local():
|
||||
|
||||
if name in self.failed_names:
|
||||
tmpexc = self.failed_items_excpetion
|
||||
if isinstance(tmpexc[name], BaseException):
|
||||
raise tmpexc[name]
|
||||
else:
|
||||
raise IsInitialisingError(
|
||||
f"{name} failed previously to initialize."
|
||||
)
|
||||
|
||||
if name in self._initializing:
|
||||
self._init_priority[name] += 1
|
||||
while name in self._initializing:
|
||||
if (
|
||||
time() - self._initialisation_start_time[name]
|
||||
) <= init_timeout:
|
||||
sleep(5)
|
||||
else:
|
||||
# print(f'{name} waiting init since {time()-self._initialisation_start_time[name]} s')
|
||||
# sleep(5)
|
||||
# # passfailed_items_excpetion
|
||||
self._initializing.pop(self._initializing.index(name))
|
||||
raise IsInitialisingError(
|
||||
f"NB: {name} initialization timed out!"
|
||||
)
|
||||
|
||||
else:
|
||||
self._initializing.append(name)
|
||||
self._init_priority[name] = 0
|
||||
self._initialisation_start_time[name] = time()
|
||||
|
||||
# args, kwargs = replace_NamespaceComponents(*args, **kwargs)
|
||||
|
||||
if module_name:
|
||||
obj_maker = getattr(import_module(module_name), obj_factory)
|
||||
else:
|
||||
obj_maker = obj_factory
|
||||
|
||||
args_resolved, kwargs_resolved = replace_NamespaceComponents(
|
||||
*args, **kwargs
|
||||
)
|
||||
accepts_name = "name" in signature(obj_maker).parameters
|
||||
manual_context = format_manual_instantiation(
|
||||
obj_maker,
|
||||
args_resolved,
|
||||
kwargs_resolved,
|
||||
name=name,
|
||||
accepts_name=accepts_name,
|
||||
module_name=module_name,
|
||||
)
|
||||
try:
|
||||
if accepts_name:
|
||||
obj_initialized = obj_maker(
|
||||
*args_resolved,
|
||||
name=name,
|
||||
**kwargs_resolved,
|
||||
)
|
||||
else:
|
||||
obj_initialized = obj_maker(
|
||||
*args_resolved,
|
||||
**kwargs_resolved,
|
||||
)
|
||||
except Exception as e:
|
||||
append_manual_context(e, manual_context)
|
||||
self.failed_items[name] = self.lazy_items.pop(name)
|
||||
self.failed_items_excpetion[name] = e
|
||||
self._initializing.pop(self._initializing.index(name))
|
||||
raise
|
||||
|
||||
try:
|
||||
self.initialized_items[name] = self.lazy_items.pop(name)
|
||||
except KeyError:
|
||||
self.initialized_items[name] = self.failed_items.pop(name)
|
||||
self._initializing.pop(self._initializing.index(name))
|
||||
# if name in self.initialisation_times_lazy.keys():
|
||||
# self.initialisation_times_lazy[name] += time() - starttime
|
||||
# else:
|
||||
self.initialisation_times_lazy[name] = (
|
||||
time() - self._initialisation_start_time[name]
|
||||
)
|
||||
if hasattr(obj_initialized, "alias"):
|
||||
self._append(
|
||||
obj_initialized,
|
||||
name=name,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
call_obj=False,
|
||||
)
|
||||
if self.alias_namespace and hasattr(obj_initialized, "alias"):
|
||||
for ta in obj_initialized.alias.get_all():
|
||||
try:
|
||||
self.alias_namespace.update(
|
||||
ta["alias"], ta["channel"], ta["channeltype"]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f'could not init alias {ta["alias"]}')
|
||||
print("error message", e)
|
||||
# traceback.print_tb(e)
|
||||
else:
|
||||
self.names_without_alias.append(name)
|
||||
return obj_initialized
|
||||
|
||||
obj_lazy = Proxy(init_local)
|
||||
self.lazy_nodes[name] = LazyNode(
|
||||
name=name,
|
||||
factory=obj_factory,
|
||||
args=args,
|
||||
kwargs=kwargs,
|
||||
module_name=module_name,
|
||||
dependencies=self._collect_dependencies(*args, **kwargs),
|
||||
)
|
||||
obj_lazy = Proxy(partial(self._ensure_node, name))
|
||||
self.lazy_items[name] = obj_lazy
|
||||
if self.root_module:
|
||||
sys.modules[self.root_module].__dict__[name] = obj_lazy
|
||||
return obj_lazy
|
||||
|
||||
starttime = time()
|
||||
args_resolved, kwargs_resolved = self._resolve_factory_inputs(
|
||||
*args, lazy=False, **kwargs
|
||||
)
|
||||
if module_name:
|
||||
obj_maker = getattr(import_module(module_name), obj_factory)
|
||||
else:
|
||||
starttime = time()
|
||||
args, kwargs = replace_NamespaceComponents(*args, **kwargs)
|
||||
if module_name:
|
||||
obj_maker = getattr(import_module(module_name), obj_factory)
|
||||
else:
|
||||
obj_maker = obj_factory
|
||||
try:
|
||||
obj = obj_maker(*args, name=name, **kwargs)
|
||||
except TypeError:
|
||||
obj = obj_maker(*args, **kwargs)
|
||||
self.initialized_items[name] = obj
|
||||
self.initialisation_times_lazy[name] = time() - starttime
|
||||
if self.root_module:
|
||||
sys.modules[self.root_module].__dict__[name] = obj
|
||||
if hasattr(obj, "alias"):
|
||||
self._append(
|
||||
obj,
|
||||
name=name,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
call_obj=False,
|
||||
)
|
||||
if self.alias_namespace and hasattr(obj, "alias"):
|
||||
for ta in obj.alias.get_all():
|
||||
try:
|
||||
self.alias_namespace.update(
|
||||
ta["alias"], ta["channel"], ta["channeltype"]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f'could not init alias {ta["alias"]}')
|
||||
print("error message", e)
|
||||
else:
|
||||
self.names_without_alias.append(name)
|
||||
return obj
|
||||
obj_maker = obj_factory
|
||||
try:
|
||||
obj = obj_maker(*args_resolved, name=name, **kwargs_resolved)
|
||||
except TypeError:
|
||||
obj = obj_maker(*args_resolved, **kwargs_resolved)
|
||||
self.initialized_items[name] = obj
|
||||
self.initialisation_times_lazy[name] = time() - starttime
|
||||
if self.root_module:
|
||||
sys.modules[self.root_module].__dict__[name] = obj
|
||||
if hasattr(obj, "alias"):
|
||||
self._append(
|
||||
obj,
|
||||
name=name,
|
||||
is_setting=True,
|
||||
is_display="recursive",
|
||||
call_obj=False,
|
||||
)
|
||||
if self.alias_namespace and hasattr(obj, "alias"):
|
||||
for ta in obj.alias.get_all():
|
||||
try:
|
||||
self.alias_namespace.update(
|
||||
ta["alias"], ta["channel"], ta["channeltype"]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f'could not init alias {ta["alias"]}')
|
||||
print("error message", e)
|
||||
else:
|
||||
self.names_without_alias.append(name)
|
||||
return obj
|
||||
|
||||
def get_obj(self, name):
|
||||
if name in self.lazy_names:
|
||||
@@ -988,18 +1117,8 @@ class Namespace(Assembly):
|
||||
|
||||
def append_obj_from_config(self, cnf, lazy=False):
|
||||
module_name, obj_factory = cnf["type"].split(":")
|
||||
args = []
|
||||
for targ in cnf["args"]:
|
||||
if isinstance(targ, Component):
|
||||
args.append(self.get_obj(targ.name))
|
||||
else:
|
||||
args.append(targ)
|
||||
kwargs = {}
|
||||
for tk, tv in cnf["kwargs"].items():
|
||||
if isinstance(tv, Component):
|
||||
kwargs[tk] = self.get_obj(tv.name)
|
||||
else:
|
||||
kwargs[tk] = tv
|
||||
args = list(cnf["args"])
|
||||
kwargs = dict(cnf["kwargs"])
|
||||
if "lazy" in cnf.keys():
|
||||
lazy = cnf["lazy"]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from eco.utilities.config import Namespace
|
||||
from eco.utilities.config import Component, Namespace
|
||||
|
||||
|
||||
class BadThing:
|
||||
@@ -8,6 +8,16 @@ class BadThing:
|
||||
raise ValueError("boom")
|
||||
|
||||
|
||||
class DependencyThing:
|
||||
def __init__(self, name=None):
|
||||
self.name = name
|
||||
|
||||
|
||||
class NeedsDependency:
|
||||
def __init__(self, dependency, name=None):
|
||||
self.dependency = dependency
|
||||
|
||||
|
||||
def test_lazy_init_failure_includes_manual_instantiation_string():
|
||||
ns = Namespace(name="test")
|
||||
ns.append_obj(BadThing, 1, lazy=True, name="bad")
|
||||
@@ -26,3 +36,23 @@ def test_lazy_init_failure_includes_manual_instantiation_string():
|
||||
"BadThing(1, name='bad')"
|
||||
)
|
||||
assert ns.failed_items_excpetion["bad"].args[-1] == manual
|
||||
|
||||
|
||||
def test_append_obj_from_config_resolves_component_dependencies_eagerly_for_non_lazy_nodes():
|
||||
ns = Namespace(name="test")
|
||||
ns.append_obj(DependencyThing, lazy=True, name="dependency")
|
||||
|
||||
ns.append_obj_from_config(
|
||||
{
|
||||
"type": f"{__name__}:NeedsDependency",
|
||||
"name": "needs_dependency",
|
||||
"args": [Component("dependency")],
|
||||
"kwargs": {},
|
||||
"lazy": False,
|
||||
}
|
||||
)
|
||||
|
||||
root = ns.initialized_items["needs_dependency"]
|
||||
assert isinstance(root.dependency, DependencyThing)
|
||||
assert root.dependency is not ns.get_obj("dependency")
|
||||
assert root.dependency.name == "dependency"
|
||||
|
||||
Reference in New Issue
Block a user