introduce 25 deg offset in osamroy to have 0 to 360
initial work on omny class
This commit is contained in:
@@ -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}"
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
237
csaxs_bec/bec_ipython_client/plugins/omny/x_ray_eye_align.py
Normal file
237
csaxs_bec/bec_ipython_client/plugins/omny/x_ray_eye_align.py
Normal 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")
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user