introduce 25 deg offset in osamroy to have 0 to 360

initial work on omny class
This commit is contained in:
Holler Mirko
2024-10-01 15:36:10 +02:00
committed by wakonig_k
parent af2a2df55f
commit d3c86b07a0
6 changed files with 277 additions and 20 deletions

View File

@@ -17,7 +17,7 @@ from csaxs_bec.bec_ipython_client.plugins.omny.omny_alignment_mixin import OMNYA
from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import OMNYTools
from csaxs_bec.bec_ipython_client.plugins.omny.omny_sample_transfer_mixin import OMNYSampleTransferMixin
from csaxs_bec.bec_ipython_client.plugins.omny.omny_rt import OMNY_rt_client
#from csaxs_bec.bec_ipython_client.plugins.flomni.x_ray_eye_align import XrayEyeAlign
from csaxs_bec.bec_ipython_client.plugins.omny.x_ray_eye_align import XrayEyeAlign
logger = bec_logger.logger
@@ -38,7 +38,7 @@ class OMNYError(Exception):
class OMNYInitStagesMixin:
def enable_all_devices():
def enable_all_devices(self):
dev.ofzpx.enabled = True
dev.ofzpy.enabled = True
dev.ofzpz.enabled = True
@@ -438,7 +438,7 @@ class OMNYInitStagesMixin:
# dev.rtz.limits = [-250, 250]
dev.osamx.limits = [-1, 1]
dev.osamy.limits = [2.3000, 3.0000]
dev.osamroy.limits = [-27.0000, 337.0000]
dev.osamroy.limits = [-2.0000, 362.0000]
dev.oeyex.limits = [-48.0000, 10.0000]
dev.oeyez.limits = [-85.0000, 10.0000]
dev.oeyey.limits = [-61.0000, 1.0000]
@@ -542,6 +542,7 @@ class OMNY(
self.progress = {}
self.OMNYTools = OMNYTools(self.client)
OMNY_rt_client.__init__(self)
self.align = XrayEyeAlign(self.client, self)
def start_x_ray_eye_alignment(self):
if self.OMNYTools.yesno(
@@ -1403,14 +1404,16 @@ class OMNY(
# header = ""
header = (
" \n" * 3
+ " .d888 888 .d88888b. 888b d888 888b 888 8888888 \n"
+ ' d88P" 888 d88P" "Y88b 8888b d8888 8888b 888 888 \n'
+ " 888 888 888 888 88888b.d88888 88888b 888 888 \n"
+ " 888888 888 888 888 888Y88888P888 888Y88b 888 888 \n"
+ " 888 888 888 888 888 Y888P 888 888 Y88b888 888 \n"
+ " 888 888 888 888 888 Y8P 888 888 Y88888 888 \n"
+ ' 888 888 Y88b. .d88P 888 " 888 888 Y8888 888 \n'
+ ' 888 888 "Y88888P" 888 888 888 Y888 8888888 \n'
+ " ,o888888o. ,8. ,8. b. 8 `8.`8888. ,8' \n"
+ " . 8888 `88. ,888. ,888. 888o. 8 `8.`8888. ,8' \n"
+ ",8 8888 `8b .`8888. .`8888. Y88888o. 8 `8.`8888. ,8' \n"
+ "88 8888 `8b ,8.`8888. ,8.`8888. .`Y888888o. 8 `8.`8888.,8' \n"
+ "88 8888 88 ,8'8.`8888,8^8.`8888. 8o. `Y888888o. 8 `8.`88888' \n"
+ "88 8888 88 ,8' `8.`8888' `8.`8888. 8`Y8o. `Y88888o8 `8. 8888 \n"
+ "88 8888 ,8P ,8' `8.`88' `8.`8888. 8 `Y8o. `Y8888 `8 8888 \n"
+ "`8 8888 ,8P ,8' `8.`' `8.`8888. 8 `Y8o. `Y8 8 8888 \n"
+ " ` 8888 ,88' ,8' `8 `8.`8888. 8 `Y8o.` 8 8888 \n"
+ " `8888888P' ,8' ` `8.`8888. 8 `Yo 8 8888 \n"
)
padding = 20
fovxy = f"{self.fovx:.2f}/{self.fovy:.2f}"

View File

@@ -398,6 +398,15 @@ class OMNY_rt_client:
def feedback_disable(self):
dev.rtx.controller.feedback_disable()
def laser_tracker_on(self):
dev.rtx.controller.laser_tracker_on()
def laser_tracker_off(self):
dev.rtx.controller.laser_tracker_off()
def laser_tracker_show_all(self):
dev.rtx.controller.laser_tracker_show_all
def omny_interferometer_align_tracking(self):
self.mirror_channel=6
signal = dev.rtx.controller._omny_interferometer_get_signalsample(self.mirror_parameters[self.mirror_channel]["opt_signalchannel"], self.mirror_parameters[self.mirror_channel]["opt_averaging_time"])

View File

@@ -825,7 +825,7 @@ class OMNYSampleTransferMixin:
#old gripper motor
#check ST position and move gripper to ST
#umv otransz -18
#umv osamroy -25 osamy 2.7 osamx 0 otransx -213
#umv osamroy 0 osamy 2.7 osamx 0 otransx -213
#umv otransz 0
#umv otransx -458.5000
@@ -867,13 +867,13 @@ class OMNYSampleTransferMixin:
if oosaz_current<0.1 and oosax_current < -1.5:
oeyey_current = dev.oeyey.get().readback
if oeyey_current < -40:
umv(dev.osamroy, -25, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -350, dev.oeyex, 0, dev.oeyey, -15)
umv(dev.osamroy, 0, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -350, dev.oeyex, 0, dev.oeyey, -15)
else:
umv(dev.osamroy, -25, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -350, dev.oeyex, 0)
umv(dev.osamroy, 0, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -350, dev.oeyex, 0)
umv(dev.oshield, 0, dev.otransx, -458.1545+0.05, dev.oeyey, -4.8)
umv(dev.oshield, -12, dev.otransz, -45.6494)
else:
umv(dev.osamroy, -25, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -458.1545+0.05, dev.oeyex, 0, dev.oeyey, -4.8)
umv(dev.osamroy, 0, dev.osamy, 2.7, dev.osamx, 0, dev.otransx, -458.1545+0.05, dev.oeyex, 0, dev.oeyey, -4.8)
self.oeye_cam_in()

View File

@@ -0,0 +1,237 @@
from __future__ import annotations
import builtins
import os
import time
from typing import TYPE_CHECKING
from bec_lib import bec_logger
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen
logger = bec_logger.logger
# import builtins to avoid linter errors
bec = builtins.__dict__.get("bec")
dev = builtins.__dict__.get("dev")
umv = builtins.__dict__.get("umv")
umvr = builtins.__dict__.get("umvr")
if TYPE_CHECKING:
from bec_ipython_client.plugins.omny import OMNY
class XrayEyeAlign:
# pixel calibration, multiply to get mm
PIXEL_CALIBRATION = 0.1 / 113 # .2 with binning
def __init__(self, client, omny: OMNY) -> None:
self.client = client
self.omny = omny
self.device_manager = client.device_manager
self.scans = client.scans
self.alignment_values = {}
self.omny.reset_correction()
self.omny.reset_tomo_alignment_fit()
def _reset_init_values(self):
self.shift_xy = [0, 0]
self._xray_fov_xy = [0, 0]
def save_frame(self):
epics_put("XOMNYI-XEYE-SAVFRAME:0", 1)
def update_frame(self):
epics_put("XOMNYI-XEYE-ACQDONE:0", 0)
# start live
epics_put("XOMNYI-XEYE-ACQ:0", 1)
# wait for start live
while epics_get("XOMNYI-XEYE-ACQDONE:0") == 0:
time.sleep(0.5)
print("waiting for live view to start...")
fshopen()
epics_put("XOMNYI-XEYE-ACQDONE:0", 0)
while epics_get("XOMNYI-XEYE-ACQDONE:0") == 0:
print("waiting for new frame...")
time.sleep(0.5)
time.sleep(0.5)
# stop live view
epics_put("XOMNYI-XEYE-ACQ:0", 0)
time.sleep(1)
# fshclose
print("got new frame")
def update_fov(self, k: int):
self._xray_fov_xy[0] = max(epics_get(f"XOMNYI-XEYE-XWIDTH_X:{k}"), self._xray_fov_xy[0])
self._xray_fov_xy[1] = max(0, self._xray_fov_xy[0])
@property
def movement_buttons_enabled(self):
return [epics_get("XOMNYI-XEYE-ENAMVX:0"), epics_get("XOMNYI-XEYE-ENAMVY:0")]
@movement_buttons_enabled.setter
def movement_buttons_enabled(self, enabled: bool):
enabled = int(enabled)
epics_put("XOMNYI-XEYE-ENAMVX:0", enabled)
epics_put("XOMNYI-XEYE-ENAMVY:0", enabled)
def send_message(self, msg: str):
epics_put("XOMNYI-XEYE-MESSAGE:0.DESC", msg)
def align(self):
# reset shift xy and fov params
self._reset_init_values()
self.flomni.lights_off()
self.tomo_rotate(0)
epics_put("XOMNYI-XEYE-ANGLE:0", 0)
self.flomni.feye_in()
self.flomni.laser_tracker_on()
self.flomni.rt_feedback_enable_with_reset()
# disable movement buttons
self.movement_buttons_enabled = False
sample_name = self.flomni.sample_get_name(0)
epics_put("XOMNYI-XEYE-SAMPLENAME:0.DESC", sample_name)
# this makes sure we are in a defined state
self.flomni.rt_feedback_disable()
epics_put("XOMNYI-XEYE-PIXELSIZE:0", self.PIXEL_CALIBRATION)
self.flomni.fosa_out()
fsamx_in = self.flomni._get_user_param_safe("fsamx", "in")
umv(dev.fsamx, fsamx_in - 0.25)
self.flomni.ffzp_in()
self.update_frame()
# enable submit buttons
self.movement_buttons_enabled = False
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
epics_put("XOMNYI-XEYE-STEP:0", 0)
self.send_message("Submit center value of FZP.")
k = 0
while True:
if epics_get("XOMNYI-XEYE-SUBMIT:0") == 1:
val_x = epics_get(f"XOMNYI-XEYE-XVAL_X:{k}") / 2 * self.PIXEL_CALIBRATION # in mm
self.alignment_values[k] = val_x
print(f"Clicked position {k}: x {self.alignment_values[k]}")
rtx_position = dev.rtx.readback.get() / 1000
print(f"Current rtx position {rtx_position}")
self.alignment_values[k] -= rtx_position
print(f"Corrected position {k}: x {self.alignment_values[k]}")
if k == 0: # received center value of FZP
self.send_message("please wait ...")
self.movement_buttons_enabled = False
epics_put("XOMNYI-XEYE-SUBMIT:0", -1) # disable submit button
self.flomni.rt_feedback_disable()
fsamx_in = self.flomni._get_user_param_safe("fsamx", "in")
umv(dev.fsamx, fsamx_in)
self.flomni.foptics_out()
self.flomni.rt_feedback_disable()
umv(dev.fsamx, fsamx_in - 0.25)
self.update_frame()
epics_put("XOMNYI-XEYE-RECBG:0", 1)
while epics_get("XOMNYI-XEYE-RECBG:0") == 1:
time.sleep(0.5)
print("waiting for background frame...")
umv(dev.fsamx, fsamx_in)
time.sleep(0.5)
self.flomni.rt_feedback_enable_with_reset()
self.update_frame()
self.send_message("Adjust sample height and submit center")
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
self.movement_buttons_enabled = True
elif 1 <= k < 5: # received sample center value at samroy 0 ... 315
self.send_message("please wait ...")
epics_put("XOMNYI-XEYE-SUBMIT:0", -1)
self.movement_buttons_enabled = False
umv(dev.rtx, 0)
self.tomo_rotate(k * 45)
epics_put("XOMNYI-XEYE-ANGLE:0", self.get_tomo_angle())
self.update_frame()
self.send_message("Submit sample center")
epics_put("XOMNYI-XEYE-SUBMIT:0", 0)
epics_put("XOMNYI-XEYE-ENAMVX:0", 1)
self.update_fov(k)
elif k == 5: # received sample center value at samroy 270 and done
self.send_message("done...")
epics_put("XOMNYI-XEYE-SUBMIT:0", -1) # disable submit button
self.movement_buttons_enabled = False
self.update_fov(k)
break
k += 1
epics_put("XOMNYI-XEYE-STEP:0", k)
_xrayeyalignmvx = epics_get("XOMNYI-XEYE-MVX:0")
if _xrayeyalignmvx != 0:
umvr(dev.rtx, _xrayeyalignmvx)
print(f"Current rtx position {dev.rtx.readback.get() / 1000}")
epics_put("XOMNYI-XEYE-MVX:0", 0)
if k > 0:
epics_put(f"XOMNYI-XEYE-STAGEPOSX:{k}", dev.rtx.readback.get() / 1000)
time.sleep(3)
self.update_frame()
if k < 2:
# allow movements, store movements to calculate center
_xrayeyalignmvy = epics_get("XOMNYI-XEYE-MVY:0")
if _xrayeyalignmvy != 0:
self.flomni.rt_feedback_disable()
umvr(dev.fsamy, _xrayeyalignmvy / 1000)
time.sleep(2)
epics_put("XOMNYI-XEYE-MVY:0", 0)
self.flomni.rt_feedback_enable_with_reset()
self.update_frame()
time.sleep(0.2)
self.write_output()
fovx = self._xray_fov_xy[0] * self.PIXEL_CALIBRATION * 1000 / 2
fovy = self._xray_fov_xy[1] * self.PIXEL_CALIBRATION * 1000 / 2
self.tomo_rotate(0)
umv(dev.rtx, 0)
# free camera
epics_put("XOMNYI-XEYE-ACQ:0", 2)
print(
f"The largest field of view from the xrayeyealign was \nfovx = {fovx:.0f} microns, fovy"
f" = {fovy:.0f} microns"
)
print("Use the matlab routine to FIT the current alignment...")
print("Then LOAD ALIGNMENT PARAMETERS by running flomni.read_alignment_offset()\n")
def write_output(self):
file = os.path.expanduser("~/Data10/specES1/internal/xrayeye_alignmentvalues")
if not os.path.exists(file):
os.makedirs(os.path.dirname(file), exist_ok=True)
with open(file, "w") as alignment_values_file:
alignment_values_file.write("angle\thorizontal\n")
for k in range(1, 6):
fovx_offset = self.alignment_values[0] - self.alignment_values[k]
print(f"Writing to file new alignment: number {k}, value x {fovx_offset}")
alignment_values_file.write(f"{(k-1)*45}\t{fovx_offset*1000}\n")

View File

@@ -65,19 +65,27 @@ class OMNYGalilReadbackSignal(GalilSignalRO):
current_pos = float(self.controller.socket_put_and_receive(f"TP{self.parent.axis_Id}"))
current_pos *= self.parent.sign
step_mm = self.parent.motor_resolution.get()
return current_pos / step_mm
#here we introduce an offset of 25 to the rotation axis
#when setting a position this is taken into account in the controller
#that way we just do tomography from 0 to 180 degrees
if self.parent.axis_Id_numeric == 2 and self.sock.port == 8083:
return (current_pos / step_mm)+25
else:
return current_pos / step_mm
def read(self):
self._metadata["timestamp"] = time.time()
val = super().read()
#if reading rotation stage angle
if self.parent.axis_Id_numeric == 2 and self.sock.port == 8083:
try:
rt = self.parent.device_manager.devices["rtx"]
if rt.enabled:
rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"])
except KeyError:
logger.warning("Failed to set RT value during ogalil readback.")
logger.warning("Failed to set RT value during ogalil readback.")
# val[self.parent.name]["value"] = val[self.parent.name]["value"]+25
return val

View File

@@ -182,9 +182,9 @@ class RtOMNYController(Controller):
osamroy = self.get_device_manager().devices.osamroy
# the following read will also upate the angle in rt during readout
readback = osamroy.obj.readback.get()
if (np.fabs(readback + 25) > 0.1):
if (np.fabs(readback) > 0.1):
self.get_device_manager().connector.send_client_info(f"Rotating to zero", scope="feedback enable", show_asap=True)
osamroy.obj.move(-25, wait=True)
osamroy.obj.move(0, wait=True)
osamx = self.get_device_manager().devices.osamx
@@ -245,7 +245,7 @@ class RtOMNYController(Controller):
def laser_tracker_off(self):
if self.feedback_is_running():
print(
"Interferometer feedback is running. Cannot disable the tracker. First disable the feedback using rt_feedback_disable()"
"Interferometer feedback is running. Cannot disable the tracker. First disable the feedback using omny.feedback_disable()"
)
else:
self.socket_put("T0")