mirror of
https://github.com/bec-project/ophyd_devices.git
synced 2025-06-24 11:41:09 +02:00
fix: bugfix online fixes
This commit is contained in:
@ -53,7 +53,9 @@ class BecScaninfoMixin:
|
|||||||
self.scanID = scan_msg.content["scanID"]
|
self.scanID = scan_msg.content["scanID"]
|
||||||
self.scan_number = scan_msg.content["info"]["scan_number"]
|
self.scan_number = scan_msg.content["info"]["scan_number"]
|
||||||
self.exp_time = scan_msg.content["info"]["exp_time"]
|
self.exp_time = scan_msg.content["info"]["exp_time"]
|
||||||
self.num_frames = scan_msg.content["info"]["num_points"]
|
self.num_frames = (
|
||||||
|
scan_msg.content["info"]["num_points"] * scan_msg.content["info"]["frames_per_trigger"]
|
||||||
|
)
|
||||||
self.scan_type = scan_msg.content["info"].get("scan_type", "step")
|
self.scan_type = scan_msg.content["info"].get("scan_type", "step")
|
||||||
self.readout_time = scan_msg.content["info"]["readout_time"]
|
self.readout_time = scan_msg.content["info"]["readout_time"]
|
||||||
self.username = self._get_username()
|
self.username = self._get_username()
|
||||||
|
@ -126,9 +126,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
if device_manager is None and not sim_mode:
|
if device_manager is None and not sim_mode:
|
||||||
raise EigerError(
|
raise EigerError("Add DeviceManager to initialization or init with sim_mode=True")
|
||||||
"Add DeviceManager to initialization or init with sim_mode=True"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.wait_for_connection() # Make sure to be connected before talking to PVs
|
self.wait_for_connection() # Make sure to be connected before talking to PVs
|
||||||
@ -142,9 +140,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
# TODO
|
# TODO
|
||||||
self.filepath = ""
|
self.filepath = ""
|
||||||
self.scaninfo.username = "e21206"
|
self.scaninfo.username = "e21206"
|
||||||
self.service_cfg = {
|
self.service_cfg = {"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"}
|
||||||
"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"
|
|
||||||
}
|
|
||||||
self.filewriter = FileWriterMixin(self.service_cfg)
|
self.filewriter = FileWriterMixin(self.service_cfg)
|
||||||
self.reduce_readout = 1e-3 # 3 ms
|
self.reduce_readout = 1e-3 # 3 ms
|
||||||
self.triggermode = 0 # 0 : internal, scan must set this if hardware triggered
|
self.triggermode = 0 # 0 : internal, scan must set this if hardware triggered
|
||||||
@ -172,9 +168,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
f"Type of new value {type(value)}:{value} does not match old value {type(old_value)}:{old_value}"
|
f"Type of new value {type(value)}:{value} does not match old value {type(old_value)}:{old_value}"
|
||||||
)
|
)
|
||||||
cfg.update({cfg_key: value})
|
cfg.update({cfg_key: value})
|
||||||
logger.info(
|
logger.info(f"Updated std_daq config for key {cfg_key} from {old_value} to {value}")
|
||||||
f"Updated std_daq config for key {cfg_key} from {old_value} to {value}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _init_standard_daq(self) -> None:
|
def _init_standard_daq(self) -> None:
|
||||||
self.std_rest_server_url = "http://xbl-daq-29:5000"
|
self.std_rest_server_url = "http://xbl-daq-29:5000"
|
||||||
@ -204,9 +198,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
energy = self.cam.beam_energy.read()[self.cam.beam_energy.name]["value"]
|
energy = self.cam.beam_energy.read()[self.cam.beam_energy.name]["value"]
|
||||||
if setp_energy != energy:
|
if setp_energy != energy:
|
||||||
self.cam.beam_energy.set(setp_energy) # .wait()
|
self.cam.beam_energy.set(setp_energy) # .wait()
|
||||||
threshold = self.cam.threshold_energy.read()[self.cam.threshold_energy.name][
|
threshold = self.cam.threshold_energy.read()[self.cam.threshold_energy.name]["value"]
|
||||||
"value"
|
|
||||||
]
|
|
||||||
if not np.isclose(setp_energy / 2, threshold, rtol=0.05):
|
if not np.isclose(setp_energy / 2, threshold, rtol=0.05):
|
||||||
self.cam.threshold_energy.set(setp_energy / 2) # .wait()
|
self.cam.threshold_energy.set(setp_energy / 2) # .wait()
|
||||||
|
|
||||||
@ -267,9 +259,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
self.arm_acquisition()
|
self.arm_acquisition()
|
||||||
logger.info("Waiting for detector to be armed")
|
logger.info("Waiting for detector to be armed")
|
||||||
while True:
|
while True:
|
||||||
det_ctrl = self.cam.detector_state.read()[self.cam.detector_state.name][
|
det_ctrl = self.cam.detector_state.read()[self.cam.detector_state.name]["value"]
|
||||||
"value"
|
|
||||||
]
|
|
||||||
if det_ctrl == int(DetectorState.RUNNING):
|
if det_ctrl == int(DetectorState.RUNNING):
|
||||||
break
|
break
|
||||||
time.sleep(0.005)
|
time.sleep(0.005)
|
||||||
@ -296,9 +286,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
# Message to BEC
|
# Message to BEC
|
||||||
state = True
|
state = True
|
||||||
|
|
||||||
msg = BECMessage.FileMessage(
|
msg = BECMessage.FileMessage(file_path=self.filepath, done=True, successful=state)
|
||||||
file_path=self.filepath, done=True, successful=state
|
|
||||||
)
|
|
||||||
self._producer.set_and_publish(
|
self._producer.set_and_publish(
|
||||||
MessageEndpoints.public_file(self.scaninfo.scanID, self.name),
|
MessageEndpoints.public_file(self.scaninfo.scanID, self.name),
|
||||||
msg.dumps(),
|
msg.dumps(),
|
||||||
|
@ -145,15 +145,14 @@ class McsCsaxs(SIS38XX):
|
|||||||
parent=None,
|
parent=None,
|
||||||
device_manager=None,
|
device_manager=None,
|
||||||
sim_mode=False,
|
sim_mode=False,
|
||||||
mcs_config = None,
|
mcs_config=None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
|
|
||||||
self.mcs_config = {
|
self.mcs_config = {
|
||||||
f"{name}_num_lines": 1,
|
f"{name}_num_lines": 1,
|
||||||
}
|
}
|
||||||
if mcs_config is not None:
|
if mcs_config is not None:
|
||||||
[self.mcs_config.update({f'{name}_{key}' : value}) for key, value in mcs_config.items()]
|
[self.mcs_config.update({f"{name}_{key}": value}) for key, value in mcs_config.items()]
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
prefix=prefix,
|
prefix=prefix,
|
||||||
@ -166,9 +165,7 @@ class McsCsaxs(SIS38XX):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if device_manager is None and not sim_mode:
|
if device_manager is None and not sim_mode:
|
||||||
raise MCSError(
|
raise MCSError("Add DeviceManager to initialization or init with sim_mode=True")
|
||||||
"Add DeviceManager to initialization or init with sim_mode=True"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self._stream_ttl = 1800
|
self._stream_ttl = 1800
|
||||||
@ -185,9 +182,7 @@ class McsCsaxs(SIS38XX):
|
|||||||
self.scaninfo = BecScaninfoMixin(device_manager, sim_mode)
|
self.scaninfo = BecScaninfoMixin(device_manager, sim_mode)
|
||||||
# TODO
|
# TODO
|
||||||
self.scaninfo.username = "e21206"
|
self.scaninfo.username = "e21206"
|
||||||
self.service_cfg = {
|
self.service_cfg = {"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"}
|
||||||
"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"
|
|
||||||
}
|
|
||||||
self.filewriter = FileWriterMixin(self.service_cfg)
|
self.filewriter = FileWriterMixin(self.service_cfg)
|
||||||
self._stopped = False
|
self._stopped = False
|
||||||
self._acquisition_done = False
|
self._acquisition_done = False
|
||||||
@ -209,9 +204,7 @@ class McsCsaxs(SIS38XX):
|
|||||||
self._set_trigger(TriggerSource.MODE3)
|
self._set_trigger(TriggerSource.MODE3)
|
||||||
self.input_polarity.set(0)
|
self.input_polarity.set(0)
|
||||||
self.count_on_start.set(0)
|
self.count_on_start.set(0)
|
||||||
self.mca_names = [
|
self.mca_names = [signal for signal in self.component_names if signal.startswith("mca")]
|
||||||
signal for signal in self.component_names if signal.startswith("mca")
|
|
||||||
]
|
|
||||||
self.mca_data = defaultdict(lambda: [])
|
self.mca_data = defaultdict(lambda: [])
|
||||||
for mca in self.mca_names:
|
for mca in self.mca_names:
|
||||||
signal = getattr(self, mca)
|
signal = getattr(self, mca)
|
||||||
@ -270,9 +263,7 @@ class McsCsaxs(SIS38XX):
|
|||||||
def _set_acquisition_params(self) -> None:
|
def _set_acquisition_params(self) -> None:
|
||||||
n_points = self.scaninfo.num_frames / int(self.num_lines.get())
|
n_points = self.scaninfo.num_frames / int(self.num_lines.get())
|
||||||
if n_points > 10000:
|
if n_points > 10000:
|
||||||
raise MCSError(
|
raise MCSError(f"Requested number of points {n_points} exceeds hardware limit of 10000")
|
||||||
f"Requested number of points {n_points} exceeds hardware limit of 10000"
|
|
||||||
)
|
|
||||||
self.num_use_all.set(n_points)
|
self.num_use_all.set(n_points)
|
||||||
self.preset_real.set(0)
|
self.preset_real.set(0)
|
||||||
|
|
||||||
|
@ -285,9 +285,7 @@ class GalilController(Controller):
|
|||||||
start_y *= sign_y
|
start_y *= sign_y
|
||||||
end_y *= sign_y
|
end_y *= sign_y
|
||||||
|
|
||||||
speed = np.abs(end_y - start_y) / (
|
speed = np.abs(end_y - start_y) / ((interval_y) * exp_time + (interval_y - 1) * readtime)
|
||||||
(interval_y) * exp_time + (interval_y - 1) * readtime
|
|
||||||
)
|
|
||||||
if speed > 2.00 or speed < 0.02:
|
if speed > 2.00 or speed < 0.02:
|
||||||
raise LimitError(
|
raise LimitError(
|
||||||
f"Speed of {speed:.03f}mm/s is outside of acceptable range of 0.02 to 2 mm/s"
|
f"Speed of {speed:.03f}mm/s is outside of acceptable range of 0.02 to 2 mm/s"
|
||||||
@ -299,9 +297,7 @@ class GalilController(Controller):
|
|||||||
|
|
||||||
# Hard coded to maximum offset of 0.1mm to avoid long motions.
|
# Hard coded to maximum offset of 0.1mm to avoid long motions.
|
||||||
self.socket_put_and_receive(f"off={(0):f}")
|
self.socket_put_and_receive(f"off={(0):f}")
|
||||||
self.socket_put_and_receive(
|
self.socket_put_and_receive(f"a_start={start_y:.04f};a_end={end_y:.04f};speed={speed:.04f}")
|
||||||
f"a_start={start_y:.04f};a_end={end_y:.04f};speed={speed:.04f}"
|
|
||||||
)
|
|
||||||
self.socket_put_and_receive(
|
self.socket_put_and_receive(
|
||||||
f"b_start={start_x:.04f};gridmax={gridmax:d};b_step={step_grid:.04f}"
|
f"b_start={start_x:.04f};gridmax={gridmax:d};b_step={step_grid:.04f}"
|
||||||
)
|
)
|
||||||
@ -321,9 +317,7 @@ class GalilController(Controller):
|
|||||||
val_axis4 = [] # x axis
|
val_axis4 = [] # x axis
|
||||||
while self.is_thread_active(thread_id):
|
while self.is_thread_active(thread_id):
|
||||||
posct = int(self.socket_put_and_receive(f"MGposct").strip().split(".")[0])
|
posct = int(self.socket_put_and_receive(f"MGposct").strip().split(".")[0])
|
||||||
logger.info(
|
logger.info(f"SGalil is scanning - latest enconder position {posct+1} from {n_samples}")
|
||||||
f"SGalil is scanning - latest enconder position {posct+1} from {n_samples}"
|
|
||||||
)
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if posct > last_readout:
|
if posct > last_readout:
|
||||||
positions = self.read_encoder_position(last_readout, posct)
|
positions = self.read_encoder_position(last_readout, posct)
|
||||||
@ -334,9 +328,7 @@ class GalilController(Controller):
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
# Readout of last positions after scan finished
|
# Readout of last positions after scan finished
|
||||||
posct = int(self.socket_put_and_receive(f"MGposct").strip().split(".")[0])
|
posct = int(self.socket_put_and_receive(f"MGposct").strip().split(".")[0])
|
||||||
logger.info(
|
logger.info(f"SGalil is scanning - latest enconder position {posct} from {n_samples}")
|
||||||
f"SGalil is scanning - latest enconder position {posct} from {n_samples}"
|
|
||||||
)
|
|
||||||
if posct > last_readout:
|
if posct > last_readout:
|
||||||
positions = self.read_encoder_position(last_readout, posct)
|
positions = self.read_encoder_position(last_readout, posct)
|
||||||
val_axis4.extend(positions[0])
|
val_axis4.extend(positions[0])
|
||||||
@ -348,9 +340,7 @@ class GalilController(Controller):
|
|||||||
val_axis2 = [] # y axis
|
val_axis2 = [] # y axis
|
||||||
val_axis4 = [] # x axis
|
val_axis4 = [] # x axis
|
||||||
for ii in range(fromval, toval + 1):
|
for ii in range(fromval, toval + 1):
|
||||||
rts = self.socket_put_and_receive(
|
rts = self.socket_put_and_receive(f"MGaposavg[{ii%2000}]*10,cposavg[{ii%2000}]*10")
|
||||||
f"MGaposavg[{ii%2000}]*10,cposavg[{ii%2000}]*10"
|
|
||||||
)
|
|
||||||
if rts == ":":
|
if rts == ":":
|
||||||
val_axis4.append(rts)
|
val_axis4.append(rts)
|
||||||
val_axis2.append(rts)
|
val_axis2.append(rts)
|
||||||
@ -389,15 +379,11 @@ class GalilReadbackSignal(GalilSignalRO):
|
|||||||
"""
|
"""
|
||||||
if self.parent.axis_Id_numeric == 2:
|
if self.parent.axis_Id_numeric == 2:
|
||||||
current_pos = float(
|
current_pos = float(
|
||||||
self.controller.socket_put_and_receive(
|
self.controller.socket_put_and_receive(f"MG _TP{self.parent.axis_Id}/mm")
|
||||||
f"MG _TP{self.parent.axis_Id}/mm"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
elif self.parent.axis_Id_numeric == 4:
|
elif self.parent.axis_Id_numeric == 4:
|
||||||
# hardware controller readback from axis 4 is on axis 0, A instead of E
|
# hardware controller readback from axis 4 is on axis 0, A instead of E
|
||||||
current_pos = float(
|
current_pos = float(self.controller.socket_put_and_receive(f"MG _TP{'A'}/mm"))
|
||||||
self.controller.socket_put_and_receive(f"MG _TP{'A'}/mm")
|
|
||||||
)
|
|
||||||
current_pos *= self.parent.sign
|
current_pos *= self.parent.sign
|
||||||
return current_pos
|
return current_pos
|
||||||
|
|
||||||
@ -443,17 +429,11 @@ class GalilSetpointSignal(GalilSignalBase):
|
|||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
if self.parent.axis_Id_numeric == 2:
|
if self.parent.axis_Id_numeric == 2:
|
||||||
self.controller.socket_put_confirmed(
|
self.controller.socket_put_confirmed(f"PA{self.parent.axis_Id}={target_val:.4f}*mm")
|
||||||
f"PA{self.parent.axis_Id}={target_val:.4f}*mm"
|
|
||||||
)
|
|
||||||
self.controller.socket_put_and_receive(f"BG{self.parent.axis_Id}")
|
self.controller.socket_put_and_receive(f"BG{self.parent.axis_Id}")
|
||||||
elif self.parent.axis_Id_numeric == 4:
|
elif self.parent.axis_Id_numeric == 4:
|
||||||
self.controller.socket_put_confirmed(
|
self.controller.socket_put_confirmed(f"targ{self.parent.axis_Id}={target_val:.4f}")
|
||||||
f"targ{self.parent.axis_Id}={target_val:.4f}"
|
self.controller.socket_put_and_receive(f"XQ#POSE,{self.parent.axis_Id_numeric}")
|
||||||
)
|
|
||||||
self.controller.socket_put_and_receive(
|
|
||||||
f"XQ#POSE,{self.parent.axis_Id_numeric}"
|
|
||||||
)
|
|
||||||
while self.controller.is_thread_active(0):
|
while self.controller.is_thread_active(0):
|
||||||
time.sleep(0.005)
|
time.sleep(0.005)
|
||||||
|
|
||||||
@ -462,9 +442,7 @@ class GalilMotorIsMoving(GalilSignalRO):
|
|||||||
@threadlocked
|
@threadlocked
|
||||||
def _socket_get(self):
|
def _socket_get(self):
|
||||||
if self.parent.axis_Id_numeric == 2:
|
if self.parent.axis_Id_numeric == 2:
|
||||||
ret = self.controller.is_axis_moving(
|
ret = self.controller.is_axis_moving(self.parent.axis_Id, self.parent.axis_Id_numeric)
|
||||||
self.parent.axis_Id, self.parent.axis_Id_numeric
|
|
||||||
)
|
|
||||||
return ret
|
return ret
|
||||||
if self.parent.axis_Id_numeric == 4:
|
if self.parent.axis_Id_numeric == 4:
|
||||||
# Motion signal from axis 4 is mapped to axis 5
|
# Motion signal from axis 4 is mapped to axis 5
|
||||||
@ -502,12 +480,8 @@ class SGalilMotor(Device, PositionerBase):
|
|||||||
kind="hinted",
|
kind="hinted",
|
||||||
)
|
)
|
||||||
user_setpoint = Cpt(GalilSetpointSignal, signal_name="setpoint")
|
user_setpoint = Cpt(GalilSetpointSignal, signal_name="setpoint")
|
||||||
motor_is_moving = Cpt(
|
motor_is_moving = Cpt(GalilMotorIsMoving, signal_name="motor_is_moving", kind="normal")
|
||||||
GalilMotorIsMoving, signal_name="motor_is_moving", kind="normal"
|
all_axes_referenced = Cpt(GalilAxesReferenced, signal_name="all_axes_referenced", kind="config")
|
||||||
)
|
|
||||||
all_axes_referenced = Cpt(
|
|
||||||
GalilAxesReferenced, signal_name="all_axes_referenced", kind="config"
|
|
||||||
)
|
|
||||||
high_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
high_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
||||||
low_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
low_limit_travel = Cpt(Signal, value=0, kind="omitted")
|
||||||
|
|
||||||
@ -688,9 +662,7 @@ class SGalilMotor(Device, PositionerBase):
|
|||||||
def axis_Id_numeric(self, val):
|
def axis_Id_numeric(self, val):
|
||||||
if isinstance(val, int):
|
if isinstance(val, int):
|
||||||
if val not in [2, 4]:
|
if val not in [2, 4]:
|
||||||
raise ValueError(
|
raise ValueError(f"Numeric value {val} is not supported, it must be either 2 or 4.")
|
||||||
f"Numeric value {val} is not supported, it must be either 2 or 4."
|
|
||||||
)
|
|
||||||
self._axis_Id_alpha = val
|
self._axis_Id_alpha = val
|
||||||
self._axis_Id_numeric = (chr(val + 97)).capitalize()
|
self._axis_Id_numeric = (chr(val + 97)).capitalize()
|
||||||
else:
|
else:
|
||||||
@ -714,11 +686,7 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
from ophyd_devices.utils.socket import SocketMock
|
from ophyd_devices.utils.socket import SocketMock
|
||||||
|
|
||||||
samx = SGalilMotor(
|
samx = SGalilMotor("E", name="samx", host="129.129.122.26", port=23, socket_cls=SocketMock)
|
||||||
"E", name="samx", host="129.129.122.26", port=23, socket_cls=SocketMock
|
samy = SGalilMotor("C", name="samy", host="129.129.122.26", port=23, socket_cls=SocketMock)
|
||||||
)
|
|
||||||
samy = SGalilMotor(
|
|
||||||
"C", name="samy", host="129.129.122.26", port=23, socket_cls=SocketMock
|
|
||||||
)
|
|
||||||
|
|
||||||
samx.controller.galil_show_all()
|
samx.controller.galil_show_all()
|
||||||
|
Reference in New Issue
Block a user