From b3cfeebaaea2a2b19e316339152ac9e1a8ded074 Mon Sep 17 00:00:00 2001 From: Sven Augustin Date: Tue, 12 Jul 2022 14:27:52 +0200 Subject: [PATCH] unified intensitymonitors --- .../devices/xdiagnostics/intensitymonitor1.py | 127 +++++++++++++++--- .../devices/xdiagnostics/intensitymonitor2.py | 102 ++++++++++++-- .../devices/xdiagnostics/intensitymonitor3.py | 52 +++---- 3 files changed, 224 insertions(+), 57 deletions(-) diff --git a/slic/devices/xdiagnostics/intensitymonitor1.py b/slic/devices/xdiagnostics/intensitymonitor1.py index 099ea5bc..6d4eef9b 100644 --- a/slic/devices/xdiagnostics/intensitymonitor1.py +++ b/slic/devices/xdiagnostics/intensitymonitor1.py @@ -1,39 +1,124 @@ -from slic.devices.general.detectors import FeDigitizer +import numpy as np + +from slic.core.adjustable import PVEnumAdjustable +from slic.devices.general.detectors_new import FeDigitizer, PvDataStream from slic.devices.general.motor import Motor -from slic.utils.pyepics import EnumWrapper +from slic.utils.hastyepics import get_pv as PV class SolidTargetDetectorPBPS: - def __init__(self, ID, VME_crate=None, link=None, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, z_undulator=None, description=None): + def __init__(self, ID, VME_crate=None, link=None, channels={}, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None, calc=None): self.ID = ID - self.x_diode = Motor(ID + ":MOTOR_X1") - self.y_diode = Motor(ID + ":MOTOR_Y1") - self.y_target = Motor(ID + ":MOTOR_PROBE") - self.target = EnumWrapper(ID + ":PROBE_SP") + self.name = name + self.diode_x = Motor(ID + ":MOTOR_X1", name="diode_x") + self.diode_y = Motor(ID + ":MOTOR_Y1", name="diode_y") + self.target_pos = Motor(ID + ":MOTOR_PROBE", name="target_pos") + self.target = PVEnumAdjustable(ID + ":PROBE_SP", name="target") if VME_crate: self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up)) self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down)) self.diode_left = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_left)) self.diode_right = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_right)) + if channels: + self.signal_up = PvDataStream(channels["up"]) + self.signal_down = PvDataStream(channels["down"]) + self.signal_left = PvDataStream(channels["left"]) + self.signal_right = PvDataStream(channels["right"]) + + if calc: + self.intensity = PvDataStream(calc["itot"]) + self.xpos = PvDataStream(calc["xpos"]) + self.ypos = PvDataStream(calc["ypos"]) + + + def get_calibration_values(self, seconds=5): + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() + ds = [self.signal_up, self.signal_down, self.signal_left, self.signal_right] + aqs = [d.acquire(seconds=seconds) for d in ds] + data = [aq.wait() for aq in aqs] + mean = [np.mean(td) for td in data] + std = [np.std(td) for td in data] + norm_diodes = [1 / tm / 4 for tm in mean] + return norm_diodes + + def set_calibration_values(self, norm_diodes): + #this is now only for bernina when using the ioxos from sla + channels = ["SLAAR21-LTIM01-EVR0:CALCI.INPG", "SLAAR21-LTIM01-EVR0:CALCI.INPH", "SLAAR21-LTIM01-EVR0:CALCI.INPF", "SLAAR21-LTIM01-EVR0:CALCI.INPE"] + for tc, tv in zip(channels, norm_diodes): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPE", "SLAAR21-LTIM01-EVR0:CALCX.INPF"] + for tc, tv in zip(channels, norm_diodes[2:4]): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPE", "SLAAR21-LTIM01-EVR0:CALCY.INPF"] + for tc, tv in zip(channels, norm_diodes[0:2]): + PV(tc).put(bytes(str(tv), "utf8")) + + def get_calibration_values_position(self, calib_intensities, seconds=5, motion_range=0.2): + self.diode_x.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_y.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + self.diode_x.set_target_value(pos).wait() + aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_left, self.signal_right]] + vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[0:2])] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # xcalib = [np.diff(calib_intensities[0:2])[0]/np.sum(calib_intensities[0:2]), grad] + xcalib = [0, grad] + self.diode_x.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + self.diode_y.set_target_value(pos).wait() + aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_up, self.signal_down]] + vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[2:4])] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # ycalib = [np.diff(calib_intensities[2:4])[0]/np.sum(calib_intensities[2:4]), grad] + ycalib = [0, grad] + self.diode_y.set_target_value(0).wait() + return xcalib, ycalib + + def set_calibration_values_position(self, xcalib, ycalib): + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPJ", "SLAAR21-LTIM01-EVR0:CALCX.INPI"] + # txcalib = [-1*xcalib[0],-1*xcalib[1]] + for tc, tv in zip(channels, xcalib): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPJ", "SLAAR21-LTIM01-EVR0:CALCY.INPI"] + for tc, tv in zip(channels, ycalib): + PV(tc).put(bytes(str(tv), "utf8")) + + def calibrate(self, seconds=5): + c = self.get_calibration_values(seconds=seconds) + self.set_calibration_values(c) + xc, yc = self.get_calibration_values_position(c, seconds=seconds) + self.set_calibration_values_position(xc, yc) + + def __repr__(self): - s = "**Intensity monitor**\n\n" + s = f"**Intensity monitor {self.name}**\n\n" - s += "Target: " + (self.target.get_name()) + "\n\n" + s += f"Target in: {self.target.get_current_value().name}\n\n" + try: + sd = "**Bias voltage**\n" + sd += " - Diode up: %.4f\n" % (self.diode_up.get_bias()) + sd += " - Diode down: %.4f\n" % (self.diode_down.get_bias()) + sd += " - Diode left: %.4f\n" % (self.diode_left.get_bias()) + sd += " - Diode right: %.4f\n" % (self.diode_right.get_bias()) + sd += "\n" - s += "**Bias voltage**\n" - s += " - Diode up: %.4f\n" % (self.diode_up.get_bias()) - s += " - Diode down: %.4f\n" % (self.diode_down.get_bias()) - s += " - Diode left: %.4f\n" % (self.diode_left.get_bias()) - s += " - Diode right: %.4f\n" % (self.diode_right.get_bias()) - s += "\n" - - s += "**Gain**\n" - s += " - Diode up: %i\n" % (self.diode_up.gain.get()) - s += " - Diode down: %i\n" % (self.diode_down.gain.get()) - s += " - Diode left: %i\n" % (self.diode_left.gain.get()) - s += " - Diode right: %i\n" % (self.diode_right.gain.get()) + sd += "**Gain**\n" + sd += " - Diode up: %i\n" % (self.diode_up.gain.get()) + sd += " - Diode down: %i\n" % (self.diode_down.gain.get()) + sd += " - Diode left: %i\n" % (self.diode_left.gain.get()) + sd += " - Diode right: %i\n" % (self.diode_right.gain.get()) + s += sd + except: + pass return s def set_gains(self, value): diff --git a/slic/devices/xdiagnostics/intensitymonitor2.py b/slic/devices/xdiagnostics/intensitymonitor2.py index a39e4d31..6d4eef9b 100644 --- a/slic/devices/xdiagnostics/intensitymonitor2.py +++ b/slic/devices/xdiagnostics/intensitymonitor2.py @@ -1,11 +1,14 @@ +import numpy as np + from slic.core.adjustable import PVEnumAdjustable -from slic.devices.general.detectors_new import FeDigitizer +from slic.devices.general.detectors_new import FeDigitizer, PvDataStream from slic.devices.general.motor import Motor +from slic.utils.hastyepics import get_pv as PV class SolidTargetDetectorPBPS: - def __init__(self, ID, VME_crate=None, link=None, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None): + def __init__(self, ID, VME_crate=None, link=None, channels={}, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None, calc=None): self.ID = ID self.name = name self.diode_x = Motor(ID + ":MOTOR_X1", name="diode_x") @@ -18,24 +21,101 @@ class SolidTargetDetectorPBPS: self.diode_left = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_left)) self.diode_right = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_right)) + if channels: + self.signal_up = PvDataStream(channels["up"]) + self.signal_down = PvDataStream(channels["down"]) + self.signal_left = PvDataStream(channels["left"]) + self.signal_right = PvDataStream(channels["right"]) + + if calc: + self.intensity = PvDataStream(calc["itot"]) + self.xpos = PvDataStream(calc["xpos"]) + self.ypos = PvDataStream(calc["ypos"]) + + + def get_calibration_values(self, seconds=5): + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() + ds = [self.signal_up, self.signal_down, self.signal_left, self.signal_right] + aqs = [d.acquire(seconds=seconds) for d in ds] + data = [aq.wait() for aq in aqs] + mean = [np.mean(td) for td in data] + std = [np.std(td) for td in data] + norm_diodes = [1 / tm / 4 for tm in mean] + return norm_diodes + + def set_calibration_values(self, norm_diodes): + #this is now only for bernina when using the ioxos from sla + channels = ["SLAAR21-LTIM01-EVR0:CALCI.INPG", "SLAAR21-LTIM01-EVR0:CALCI.INPH", "SLAAR21-LTIM01-EVR0:CALCI.INPF", "SLAAR21-LTIM01-EVR0:CALCI.INPE"] + for tc, tv in zip(channels, norm_diodes): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPE", "SLAAR21-LTIM01-EVR0:CALCX.INPF"] + for tc, tv in zip(channels, norm_diodes[2:4]): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPE", "SLAAR21-LTIM01-EVR0:CALCY.INPF"] + for tc, tv in zip(channels, norm_diodes[0:2]): + PV(tc).put(bytes(str(tv), "utf8")) + + def get_calibration_values_position(self, calib_intensities, seconds=5, motion_range=0.2): + self.diode_x.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_y.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + self.diode_x.set_target_value(pos).wait() + aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_left, self.signal_right]] + vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[0:2])] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # xcalib = [np.diff(calib_intensities[0:2])[0]/np.sum(calib_intensities[0:2]), grad] + xcalib = [0, grad] + self.diode_x.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + self.diode_y.set_target_value(pos).wait() + aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_up, self.signal_down]] + vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[2:4])] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # ycalib = [np.diff(calib_intensities[2:4])[0]/np.sum(calib_intensities[2:4]), grad] + ycalib = [0, grad] + self.diode_y.set_target_value(0).wait() + return xcalib, ycalib + + def set_calibration_values_position(self, xcalib, ycalib): + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPJ", "SLAAR21-LTIM01-EVR0:CALCX.INPI"] + # txcalib = [-1*xcalib[0],-1*xcalib[1]] + for tc, tv in zip(channels, xcalib): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPJ", "SLAAR21-LTIM01-EVR0:CALCY.INPI"] + for tc, tv in zip(channels, ycalib): + PV(tc).put(bytes(str(tv), "utf8")) + + def calibrate(self, seconds=5): + c = self.get_calibration_values(seconds=seconds) + self.set_calibration_values(c) + xc, yc = self.get_calibration_values_position(c, seconds=seconds) + self.set_calibration_values_position(xc, yc) + def __repr__(self): s = f"**Intensity monitor {self.name}**\n\n" s += f"Target in: {self.target.get_current_value().name}\n\n" try: - sd = "**Biasd voltage**\n" - sd += " - Diode up: %.4f\n" % (sdelf.diode_up.get_biasd()) - sd += " - Diode down: %.4f\n" % (sdelf.diode_down.get_biasd()) - sd += " - Diode left: %.4f\n" % (sdelf.diode_left.get_biasd()) - sd += " - Diode right: %.4f\n" % (sdelf.diode_right.get_biasd()) + sd = "**Bias voltage**\n" + sd += " - Diode up: %.4f\n" % (self.diode_up.get_bias()) + sd += " - Diode down: %.4f\n" % (self.diode_down.get_bias()) + sd += " - Diode left: %.4f\n" % (self.diode_left.get_bias()) + sd += " - Diode right: %.4f\n" % (self.diode_right.get_bias()) sd += "\n" sd += "**Gain**\n" - sd += " - Diode up: %i\n" % (sdelf.diode_up.gain.get()) - sd += " - Diode down: %i\n" % (sdelf.diode_down.gain.get()) - sd += " - Diode left: %i\n" % (sdelf.diode_left.gain.get()) - sd += " - Diode right: %i\n" % (sdelf.diode_right.gain.get()) + sd += " - Diode up: %i\n" % (self.diode_up.gain.get()) + sd += " - Diode down: %i\n" % (self.diode_down.gain.get()) + sd += " - Diode left: %i\n" % (self.diode_left.gain.get()) + sd += " - Diode right: %i\n" % (self.diode_right.gain.get()) s += sd except: pass diff --git a/slic/devices/xdiagnostics/intensitymonitor3.py b/slic/devices/xdiagnostics/intensitymonitor3.py index da424935..6d4eef9b 100644 --- a/slic/devices/xdiagnostics/intensitymonitor3.py +++ b/slic/devices/xdiagnostics/intensitymonitor3.py @@ -8,13 +8,13 @@ from slic.utils.hastyepics import get_pv as PV class SolidTargetDetectorPBPS: - def __init__(self, pvname, VME_crate=None, link=None, channels={}, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None, calc=None, calc_calib={}): + def __init__(self, ID, VME_crate=None, link=None, channels={}, ch_up=12, ch_down=13, ch_left=15, ch_right=14, elog=None, name=None, calc=None): + self.ID = ID self.name = name - self.pvname = pvname - self.x_diodes = Motor(pvname + ":MOTOR_X1") - self.y_diodes = Motor(pvname + ":MOTOR_Y1") - self.target_y = Motor(pvname + ":MOTOR_PROBE") - self.target = PVEnumAdjustable(pvname + ":PROBE_SP") + self.diode_x = Motor(ID + ":MOTOR_X1", name="diode_x") + self.diode_y = Motor(ID + ":MOTOR_Y1", name="diode_y") + self.target_pos = Motor(ID + ":MOTOR_PROBE", name="target_pos") + self.target = PVEnumAdjustable(ID + ":PROBE_SP", name="target") if VME_crate: self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up)) self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down)) @@ -32,9 +32,10 @@ class SolidTargetDetectorPBPS: self.xpos = PvDataStream(calc["xpos"]) self.ypos = PvDataStream(calc["ypos"]) + def get_calibration_values(self, seconds=5): - self.x_diodes.set_target_value(0).wait() - self.y_diodes.set_target_value(0).wait() + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() ds = [self.signal_up, self.signal_down, self.signal_left, self.signal_right] aqs = [d.acquire(seconds=seconds) for d in ds] data = [aq.wait() for aq in aqs] @@ -56,30 +57,30 @@ class SolidTargetDetectorPBPS: PV(tc).put(bytes(str(tv), "utf8")) def get_calibration_values_position(self, calib_intensities, seconds=5, motion_range=0.2): - self.x_diodes.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) - self.y_diodes.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) - self.x_diodes.set_target_value(0).wait() - self.y_diodes.set_target_value(0).wait() + self.diode_x.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_y.set_epics_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.diode_x.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() raw = [] for pos in [motion_range / 2, -motion_range / 2]: - self.x_diodes.set_target_value(pos).wait() + self.diode_x.set_target_value(pos).wait() aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_left, self.signal_right]] vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[0:2])] raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) grad = motion_range / np.diff(raw)[0] # xcalib = [np.diff(calib_intensities[0:2])[0]/np.sum(calib_intensities[0:2]), grad] xcalib = [0, grad] - self.x_diodes.set_target_value(0).wait() + self.diode_x.set_target_value(0).wait() raw = [] for pos in [motion_range / 2, -motion_range / 2]: - self.y_diodes.set_target_value(pos).wait() + self.diode_y.set_target_value(pos).wait() aqs = [ts.acquire(seconds=seconds) for ts in [self.signal_up, self.signal_down]] vals = [np.mean(aq.wait()) * calib for aq, calib in zip(aqs, calib_intensities[2:4])] raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) grad = motion_range / np.diff(raw)[0] # ycalib = [np.diff(calib_intensities[2:4])[0]/np.sum(calib_intensities[2:4]), grad] ycalib = [0, grad] - self.y_diodes.set_target_value(0).wait() + self.diode_y.set_target_value(0).wait() return xcalib, ycalib def set_calibration_values_position(self, xcalib, ycalib): @@ -97,23 +98,24 @@ class SolidTargetDetectorPBPS: xc, yc = self.get_calibration_values_position(c, seconds=seconds) self.set_calibration_values_position(xc, yc) + def __repr__(self): s = f"**Intensity monitor {self.name}**\n\n" s += f"Target in: {self.target.get_current_value().name}\n\n" try: - sd = "**Biasd voltage**\n" - sd += " - Diode up: %.4f\n" % (sdelf.diode_up.get_biasd()) - sd += " - Diode down: %.4f\n" % (sdelf.diode_down.get_biasd()) - sd += " - Diode left: %.4f\n" % (sdelf.diode_left.get_biasd()) - sd += " - Diode right: %.4f\n" % (sdelf.diode_right.get_biasd()) + sd = "**Bias voltage**\n" + sd += " - Diode up: %.4f\n" % (self.diode_up.get_bias()) + sd += " - Diode down: %.4f\n" % (self.diode_down.get_bias()) + sd += " - Diode left: %.4f\n" % (self.diode_left.get_bias()) + sd += " - Diode right: %.4f\n" % (self.diode_right.get_bias()) sd += "\n" sd += "**Gain**\n" - sd += " - Diode up: %i\n" % (sdelf.diode_up.gain.get()) - sd += " - Diode down: %i\n" % (sdelf.diode_down.gain.get()) - sd += " - Diode left: %i\n" % (sdelf.diode_left.gain.get()) - sd += " - Diode right: %i\n" % (sdelf.diode_right.gain.get()) + sd += " - Diode up: %i\n" % (self.diode_up.gain.get()) + sd += " - Diode down: %i\n" % (self.diode_down.gain.get()) + sd += " - Diode left: %i\n" % (self.diode_left.gain.get()) + sd += " - Diode right: %i\n" % (self.diode_right.gain.get()) s += sd except: pass