From 3ce6bbc134c6fe69f38d34f0c37b40a6375a2b45 Mon Sep 17 00:00:00 2001 From: x12sa Date: Mon, 16 Mar 2026 12:10:29 +0100 Subject: [PATCH 01/10] check attr exist in gui remove all docs --- csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py index 9727056..35ab84b 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py @@ -101,7 +101,8 @@ class flomniGuiTools: # dev.cam_flomni_overview.stop_live_mode() # dev.cam_flomni_gripper.stop_live_mode() # dev.cam_xeye.live_mode = False - self.gui.flomni.delete_all() + if hasattr(self.gui, "flomni"): + self.gui.flomni.delete_all() self.progressbar = None self.text_box = None -- 2.52.0 From 2c31d79f1b8b9178d2d7582eaf5c6786bec9e3b1 Mon Sep 17 00:00:00 2001 From: x12sa Date: Mon, 16 Mar 2026 12:39:35 +0100 Subject: [PATCH 02/10] loading of fit params from gui and from files --- .../plugins/flomni/flomni.py | 75 ++++++++++--------- .../plugins/flomni/x_ray_eye_align.py | 9 +-- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 1128d87..9459865 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -983,56 +983,61 @@ class FlomniAlignmentMixin: def read_alignment_offset( self, - dir_path=os.path.expanduser("~/Data10/specES1/internal/"), + dir_path=os.path.expanduser("~/data/raw/logs/"), setup="flomni", use_vertical_default_values=True, + get_data_from_gui=False, ): - """ - Read the alignment parameters from xray eye fit. + if not get_data_from_gui: + """ + Read the alignment parameters from xray eye fit. - """ - tomo_alignment_fit = np.zeros((2, 5)) - # with open(os.path.join(dir_path, "ptychotomoalign_Ax.txt"), "r") as file: - # tomo_alignment_fit[0][0] = file.readline() + """ + tomo_alignment_fit = np.zeros((2, 5)) + with open(os.path.join(dir_path, "ptychotomoalign_Ax.txt"), "r") as file: + tomo_alignment_fit[0][0] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Bx.txt"), "r") as file: - # tomo_alignment_fit[0][1] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Bx.txt"), "r") as file: + tomo_alignment_fit[0][1] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Cx.txt"), "r") as file: - # tomo_alignment_fit[0][2] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Cx.txt"), "r") as file: + tomo_alignment_fit[0][2] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Ay.txt"), "r") as file: - # tomo_alignment_fit[1][0] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Ay.txt"), "r") as file: + tomo_alignment_fit[1][0] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_By.txt"), "r") as file: - # tomo_alignment_fit[1][1] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_By.txt"), "r") as file: + tomo_alignment_fit[1][1] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Cy.txt"), "r") as file: - # tomo_alignment_fit[1][2] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Cy.txt"), "r") as file: + tomo_alignment_fit[1][2] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Ay3.txt"), "r") as file: - # tomo_alignment_fit[1][3] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Ay3.txt"), "r") as file: + tomo_alignment_fit[1][3] = file.readline() - # with open(os.path.join(dir_path, "ptychotomoalign_Cy3.txt"), "r") as file: - # tomo_alignment_fit[1][4] = file.readline() + with open(os.path.join(dir_path, "ptychotomoalign_Cy3.txt"), "r") as file: + tomo_alignment_fit[1][4] = file.readline() - params = dev.omny_xray_gui.fit_params_x.get() + print("New alignment parameters loaded from filesystem, meaning Matlab fit:") - #amplitude - tomo_alignment_fit[0][0] = params['SineModel_0_amplitude'] - #phase - tomo_alignment_fit[0][1] = params['SineModel_0_shift'] - #offset - tomo_alignment_fit[0][2] = params['LinearModel_1_intercept'] - print("applying vertical default values from mirror calibration, not from fit!") - tomo_alignment_fit[1][0] = 0 - tomo_alignment_fit[1][1] = 0 - tomo_alignment_fit[1][2] = 0 - tomo_alignment_fit[1][3] = 0 - tomo_alignment_fit[1][4] = 0 + else: + params = dev.omny_xray_gui.fit_params_x.get() + + #amplitude + tomo_alignment_fit[0][0] = params['SineModel_0_amplitude'] + #phase + tomo_alignment_fit[0][1] = params['SineModel_0_shift'] + #offset + tomo_alignment_fit[0][2] = params['LinearModel_1_intercept'] + print("applying vertical default values from mirror calibration, not from fit!") + tomo_alignment_fit[1][0] = 0 + tomo_alignment_fit[1][1] = 0 + tomo_alignment_fit[1][2] = 0 + tomo_alignment_fit[1][3] = 0 + tomo_alignment_fit[1][4] = 0 + print("New alignment parameters loaded based on Xray eye alignment GUI:") - print("New alignment parameters loaded:") print( f"X Amplitude {tomo_alignment_fit[0][0]}, " f"X Phase {tomo_alignment_fit[0][1]}, " diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py b/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py index 1ec5465..0de7b6c 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py @@ -231,10 +231,6 @@ class XrayEyeAlign: 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) - if keep_shutter_open: if self.flomni.OMNYTools.yesno("Close the shutter now?", "y"): dev.omnyfsh.fshclose() @@ -251,8 +247,11 @@ class XrayEyeAlign: print("Automatically loading new alignment parameters from xray eye alignment.\n") - self.flomni.read_alignment_offset() + self.flomni.read_alignment_offset(get_data_from_gui=True) + self.tomo_rotate(0) + + umv(dev.rtx, 0) print("You are ready to remove the xray eye and start ptychography scans.") def write_output(self): -- 2.52.0 From 5ff32decc4ab2ec0ed8ad02a0ff22ec2088146cc Mon Sep 17 00:00:00 2001 From: x12sa Date: Mon, 16 Mar 2026 17:54:56 +0100 Subject: [PATCH 03/10] gui delay startup, flomni loading params fix --- csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py | 4 +++- csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 9459865..e6b1dfd 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -988,12 +988,14 @@ class FlomniAlignmentMixin: use_vertical_default_values=True, get_data_from_gui=False, ): + + tomo_alignment_fit = np.zeros((2, 5)) + if not get_data_from_gui: """ Read the alignment parameters from xray eye fit. """ - tomo_alignment_fit = np.zeros((2, 5)) with open(os.path.join(dir_path, "ptychotomoalign_Ax.txt"), "r") as file: tomo_alignment_fit[0][0] = file.readline() diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py index 35ab84b..7dd2fce 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py @@ -1,4 +1,5 @@ import builtins +import time # from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get, epics_put, fshopen, fshclose @@ -31,6 +32,7 @@ class flomniGuiTools: self.gui.flomni.raise_window() else: self.gui.new("flomni") + time.sleep(1) def flomnigui_stop_gui(self): self.gui.flomni.hide() -- 2.52.0 From 68320e1944f433cb24f0d53f6100c759b606989e Mon Sep 17 00:00:00 2001 From: x12sa Date: Mon, 16 Mar 2026 17:55:37 +0100 Subject: [PATCH 04/10] check tracker signal before rt move, which is otherwise stuck forever. --- csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py index ad2c638..36f8574 100644 --- a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py @@ -394,7 +394,7 @@ class RtFlomniController(Controller): val = float(self.socket_put_and_receive(f"j{axis_number}").strip()) return val - def laser_tracker_check_signalstrength(self): + def laser_tracker_check_signalstrength(self, verbose=True): if not self.laser_tracker_check_enabled(): returnval = "disabled" else: @@ -405,9 +405,10 @@ class RtFlomniController(Controller): rtx = self.device_manager.devices.rtx min_signal = rtx.user_parameter.get("min_signal") low_signal = rtx.user_parameter.get("low_signal") - print(f"low signal: {low_signal}") - print(f"min signal: {min_signal}") - print(f"signal: {signal}") + if verbose: + print(f"low signal: {low_signal}") + print(f"min signal: {min_signal}") + print(f"signal: {signal}") if signal < min_signal: time.sleep(1) if signal < min_signal: @@ -621,6 +622,18 @@ class RtFlomniSetpointSignal(RtSetpointSignal): "The interferometer feedback is not running. Either it is turned off or and" " interferometer error occured." ) + + tracker_status = self.parent.controller.laser_tracker_check_signalstrength() + + if tracker_status == "toolow": + print( + "The interferometer signal is too low for movements. Realignment required." + ) + raise RtError( + "The interferometer signal is too low for movements. Realignment required." + ) + + self.set_with_feedback_disabled(val) def set_with_feedback_disabled(self, val): -- 2.52.0 From 58cd6bdaf7f81293651c40f2b1a29c5adf673bce Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 14:14:14 +0100 Subject: [PATCH 05/10] fixes run 1 --- .../bec_ipython_client/plugins/LamNI/lamni.py | 2 +- .../plugins/flomni/flomni.py | 88 +++++++++++-------- .../plugins/flomni/flomni_optics_mixin.py | 12 ++- .../plugins/flomni/gui_tools.py | 2 +- csaxs_bec/device_configs/ptycho_flomni.yaml | 11 ++- docs/user/ptychography/flomni.md | 9 +- 6 files changed, 75 insertions(+), 49 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py index db7a21c..ae0e4a3 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py @@ -779,7 +779,7 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools): user_input = input("Are these parameters correctly set for your scan? ") if user_input == "y": - print("good then") + print("OK. continue.") return self.tomo_countingtime = self._get_val(" s", self.tomo_countingtime, float) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index e6b1dfd..5fa740e 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -120,7 +120,7 @@ class FlomniInitStagesMixin: if self.OMNYTools.yesno("Init of foptz. Can the stage move to the upstream limit without collision?"): - print("good then") + print("OK. continue.") else: return @@ -174,7 +174,7 @@ class FlomniInitStagesMixin: print("done") if self.OMNYTools.yesno("Init of tracking stages. Did you remove the outer laser flight tubes?"): - print("good then") + print("OK. continue.") else: print("Stopping.") return @@ -190,7 +190,7 @@ class FlomniInitStagesMixin: print("done") if self.OMNYTools.yesno("Init of sample stage. Is the piezo at about 0 deg?"): - print("good then") + print("OK. continue.") else: print("Stopping.") return @@ -207,7 +207,7 @@ class FlomniInitStagesMixin: print("Initializing UPR stage.") if self.OMNYTools.yesno("To ensure that the end switches work, please check that they are currently not pushed. Is everything okay?"): - print("good then") + print("OK. continue.") else: print("Stopping.") return @@ -228,7 +228,7 @@ class FlomniInitStagesMixin: continue break if self.OMNYTools.yesno("Shall I start the index search?"): - print("good then. Starting index search.") + print("OK. continue.. Starting index search.") else: print("Stopping.") return @@ -247,7 +247,7 @@ class FlomniInitStagesMixin: print("done") if self.OMNYTools.yesno("Init of foptx. Can the stage move to the positive limit without collision? Attention: tracker flight tube!"): - print("good then") + print("OK. continue.") else: print("Stopping.") return @@ -271,7 +271,7 @@ class FlomniInitStagesMixin: break if self.OMNYTools.yesno("Start limit switch search of fopty?"): - print("good then") + print("OK. continue.") else: print("Stopping.") return @@ -438,7 +438,19 @@ class FlomniSampleTransferMixin: umv(dev.fsamx, fsamx_in) dev.fsamx.limits = [fsamx_in - 0.4, fsamx_in + 0.4] - #self.flomnigui_idle() + print("Moving X-ray eye in.") + + if self.OMNYTools.yesno("Please confirm that this is ok with the flight tube. This check is to be removed after commissioning", "n"): + print("OK. continue.") + else: + print("Stopping.") + raise FlomniError("Manual abort of x-ray eye in.") + + self.feye_in() + print("Moving X-ray optics out.") + self.foptics_out() + self.xrayeye_update_frame() + def laser_tracker_show_all(self): dev.rtx.controller.laser_tracker_show_all() @@ -543,12 +555,6 @@ class FlomniSampleTransferMixin: self.flomnigui_show_cameras() - if self.OMNYTools.yesno("Please confirm that there is currently no sample in the gripper. It would be dropped!", "y"): - print("good then") - else: - print("Stopping.") - raise FlomniError("The sample transfer was manually aborted.") - self.ftransfer_gripper_move(position) self.ftransfer_controller_enable_mount_mode() @@ -751,7 +757,7 @@ class FlomniSampleTransferMixin: return if self.OMNYTools.yesno("All OK? Continue?", "y"): - print("good then") + print("OK. continue.") dev.ftransy.controller.socket_put_confirmed("confirm=1") else: print("Stopping.") @@ -785,7 +791,7 @@ class FlomniSampleTransferMixin: if position == 0 and fsamx_pos > -160: if self.OMNYTools.yesno("May the flomni stage be moved out for the sample change? Feedback will be disabled and alignment will be lost!", "y"): - print("good then") + print("OK. continue.") self.ftransfer_flomni_stage_out() else: print("Stopping.") @@ -1481,11 +1487,14 @@ class Flomni( return dev = builtins.__dict__.get("dev") bec = builtins.__dict__.get("bec") + + + self.feye_out() tags = ["BEC_alignment_tomo", self.sample_name] self.write_to_scilog( f"Starting alignment scan. First scan number: {bec.queue.next_scan_number}.", tags ) - + start_angle = 0 angle_end = start_angle + 180 @@ -1514,9 +1523,8 @@ class Flomni( for scan_nr in range(start_scan_number, end_scan_number): self._write_tomo_scan_number(scan_nr, angle, 0) - print("Alignment scan finished. Please run SPEC_ptycho_align and load the new fit.") - umv(dev.fsamroy, 0) + self.OMNYTools.printgreenbold("\n\nAlignment scan finished. Please run SPEC_ptycho_align and load the new fit.") def _write_subtomo_to_scilog(self, subtomo_number): dev = builtins.__dict__.get("dev") @@ -1550,6 +1558,9 @@ class Flomni( self._write_subtomo_to_scilog(subtomo_number) + if start_angle is not None: + print(f"Sub tomo scan with start angle {angle} requested.") + if start_angle is None: if subtomo_number == 1: start_angle = 0 @@ -1568,6 +1579,7 @@ class Flomni( elif subtomo_number == 8: start_angle = self.tomo_angle_stepsize / 8.0 * 7 + # _tomo_shift_angles (potential global variable) _tomo_shift_angles = 0 angle_end = start_angle + 180 @@ -1598,7 +1610,7 @@ class Flomni( print(f"Starting flOMNI scan for angle {angle} in subtomo {subtomo_number}") self._print_progress() while not successful: - self.bl_chk._bl_chk_start() + #self.bl_chk._bl_chk_start() if not self.special_angles: self._current_special_angles = [] if self._current_special_angles: @@ -1621,10 +1633,10 @@ class Flomni( else: raise exc - if self.bl_chk._bl_chk_stop() and not error_caught: - successful = True - else: - self.bl_chk._bl_chk_wait_until_recovered() + # if self.bl_chk._bl_chk_stop() and not error_caught: + successful = True + # else: + # self.bl_chk._bl_chk_wait_until_recovered() end_scan_number = bec.queue.next_scan_number for scan_nr in range(start_scan_number, end_scan_number): self._write_tomo_scan_number(scan_nr, angle, subtomo_number) @@ -1645,19 +1657,19 @@ class Flomni( ): # pylint: disable=undefined-variable - if bec.active_account != "": - self.tomo_id = self.add_sample_database( - self.sample_name, - str(datetime.date.today()), - bec.active_account.decode(), - bec.queue.next_scan_number, - "flomni", - "test additional info", - "BEC", - ) - self.write_pdf_report() - else: - self.tomo_id = 0 + # if bec.active_account != "": + # self.tomo_id = self.add_sample_database( + # self.sample_name, + # str(datetime.date.today()), + # bec.active_account, + # bec.queue.next_scan_number, + # "flomni", + # "test additional info", + # "BEC", + # ) + # self.write_pdf_report() + # else: + self.tomo_id = 0 with scans.dataset_id_on_hold: if self.tomo_type == 1: @@ -1843,7 +1855,7 @@ class Flomni( return angle, subtomo_number - def tomo_reconstruct(self, base_path="~/Data10/specES1"): + def tomo_reconstruct(self, base_path="~/data/raw/logs/reconstruction_queue"): """write the tomo reconstruct file for the reconstruction queue""" bec = builtins.__dict__.get("bec") self.reconstructor.write( diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py index 903e4c9..ac69033 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py @@ -4,7 +4,7 @@ from rich import box from rich.console import Console from rich.table import Table -from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_put, fshclose +from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_put class FlomniOpticsMixin: @@ -16,12 +16,18 @@ class FlomniOpticsMixin: return param.get(var) def feye_out(self): - fshclose() + dev.omnyfsh.fshclose() self.foptics_in() + self.flomnigui_show_xeyealign() + self.xrayeye_update_frame() + if self.OMNYTools.yesno("Did the direct beam on the xray eye disappear?"): + print("excellent.") + else: + print("Aborting. With visible parts of the direct beam on the xray eye, it cannot be removed.") + return feyex_out = self._get_user_param_safe("feyex", "out") umv(dev.feyex, feyex_out) - epics_put("XOMNYI-XEYE-ACQ:0", 2) # move rotation stage to zero to avoid problems with wires umv(dev.fsamroy, 0) # umv(dev.fttrx1, 9.2) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py index 7dd2fce..c002ede 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py @@ -210,7 +210,7 @@ class flomniGuiTools: main_progress_ring.set_value(progress) subtomo_progress_ring.set_value(subtomo_progress) - text = f"Progress report:\n Tomo type: ....................... {self.progress['tomo_type']}\n Projection: ...................... {self.progress['projection']:.0f}\n Total projections expected ....... {self.progress['total_projections']}\n Angle: ........................... {self.progress['angle']}\n Current subtomo: ................. {self.progress['subtomo']}\n Current projection within subtomo: {self.progress['subtomo_projection']}\n Total projections per subtomo: ... {self.progress['subtomo_total_projections']}" + text = f"Progress report:\n Tomo type: {self.progress['tomo_type']}\n Projection: {self.progress['projection']:.0f}\n Total projections expected {self.progress['total_projections']}\n Angle: {self.progress['angle']}\n Current subtomo: {self.progress['subtomo']}\n Current projection within subtomo: {self.progress['subtomo_projection']}\n Total projections per subtomo: {int(self.progress['subtomo_total_projections'])}" self.progressbar.set_center_label(text) diff --git a/csaxs_bec/device_configs/ptycho_flomni.yaml b/csaxs_bec/device_configs/ptycho_flomni.yaml index 351856c..ebc3a7d 100644 --- a/csaxs_bec/device_configs/ptycho_flomni.yaml +++ b/csaxs_bec/device_configs/ptycho_flomni.yaml @@ -227,7 +227,7 @@ ftransy: readoutPriority: baseline connectionTimeout: 20 userParameter: - sensor_voltage: -2.4 + sensor_voltage: -1.1 ftransz: description: Sample transer Z deviceClass: csaxs_bec.devices.omny.galil.fgalil_ophyd.FlomniGalilMotor @@ -344,6 +344,9 @@ rtx: description: flomni rt deviceClass: csaxs_bec.devices.omny.rt.rt_flomni_ophyd.RtFlomniMotor deviceConfig: + limits: + - -200 + - 200 axis_Id: A host: mpc2844.psi.ch port: 2222 @@ -361,6 +364,9 @@ rty: description: flomni rt deviceClass: csaxs_bec.devices.omny.rt.rt_flomni_ophyd.RtFlomniMotor deviceConfig: + limits: + - -100 + - 100 axis_Id: B host: mpc2844.psi.ch port: 2222 @@ -376,6 +382,9 @@ rtz: description: flomni rt deviceClass: csaxs_bec.devices.omny.rt.rt_flomni_ophyd.RtFlomniMotor deviceConfig: + limits: + - -100 + - 100 axis_Id: C host: mpc2844.psi.ch port: 2222 diff --git a/docs/user/ptychography/flomni.md b/docs/user/ptychography/flomni.md index 26e8946..9e9945f 100644 --- a/docs/user/ptychography/flomni.md +++ b/docs/user/ptychography/flomni.md @@ -50,16 +50,15 @@ Manually move the gripper to a transfer position After the sample transfer the sample stage moved to the measurement position with your new sample. The Xray eye will automatically move in and the shutter will open. You may already see the sample in the omny xeye interface running on the windows computer. If you see your sample already at the approximately correct height, you can skip steps 1 to 3. Otherwise adjust the height: -1. `flomni.rt_feedback_disable()` disable the closed loop operation to allow movement of coarse stages +1. `flomni.feedback_disable()` disable the closed loop operation to allow movement of coarse stages 1. `umvr(dev.fsamy, 0.01)`, attention: unit , move the sample stage relative up (positive) or down (negative) until the sample is approximately vertically centered in xray eye screen 1. `flomni.xrayeye_update_frame()` will update the current image on the xray eye screen -1. `flomni.xrayeye_alignment_start()` start the coarse alignment of the sample by measuring (clicking in the X-ray eye software) the sample position at 0, 45, 90, 135, 180 degrees. Then use the matlab routine `SPEC_ptycho_align.m` to fit this data. -1. `flomni.read_alignment_offset()` read the generated alignment data. +1. `flomni.xrayeye_alignment_start()` start the coarse alignment of the sample by measuring (clicking in the X-ray eye software) the sample position at 0, 45, 90, 135, 180 degrees. The GUI will present a fit of this data, which is automatically loaded to BEC for aligning the sample. #### Fine alignment After the xrayeyealign, a fine alignment needs to be performed using ptychography. -_To bypass the fine alignment: `feye_out`_ +_To bypass the fine alignment: `flomni.feye_out`_ 1. `flomni.tomo_parameters()` Adjust the ptychographic scan parameters for performing an alignment scan. Typically FOVX = FOVX(Xrayeye)+20 mu, shell step = beamsize/2.5, number of projections and tomo mode are ignored in the alignment scans. @@ -71,7 +70,7 @@ _To bypass the fine alignment: `feye_out`_ Now that the sample is aligned, the tomographic measurement can be performed. 1. `flomni.tomo_parameters()` adjust the scan parameters for the tomographic scan. This includes the parameters for ptychographic scans of projections plus the strategy for angular sampling. The vertical shift adjusts the field of view, up (positive) or down (negative). After adjusting the numbers, type again `flomni.tomo_parameters()` and verify that they are correct. 1. `flomni.tomo_scan_projection(angle)` perform a ptychographic scan at the rotation angle . Launch the tomographic measurement by `flomni.tomo_scan()`. -1. Before changing sample, verify that all subtomograms were completely acquired using the `tomo_recons matlab` script. +1. Before changing sample, verify that all subtomograms were completely acquired using the tomo_reconstruction matlab script. #### If something went wrong… -- 2.52.0 From dcde0e783eec11ad2c71a3ca36fdb343bfdde187 Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 14:42:52 +0100 Subject: [PATCH 06/10] fix angle reversal at start with start angle pecified --- .../plugins/flomni/flomni.py | 43 +++++++++++++------ .../plugins/flomni/gui_tools.py | 11 ++++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 5fa740e..bec40bf 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -1559,7 +1559,7 @@ class Flomni( self._write_subtomo_to_scilog(subtomo_number) if start_angle is not None: - print(f"Sub tomo scan with start angle {angle} requested.") + print(f"Sub tomo scan with start angle {start_angle} requested.") if start_angle is None: if subtomo_number == 1: @@ -1582,16 +1582,35 @@ class Flomni( # _tomo_shift_angles (potential global variable) _tomo_shift_angles = 0 - angle_end = start_angle + 180 - angles = np.linspace( - start_angle + _tomo_shift_angles, - angle_end, - num=int(180 / self.tomo_angle_stepsize) + 1, - endpoint=True, - ) - # reverse even sub-tomograms - if not (subtomo_number % 2): - angles = np.flip(angles) + # compute number of projections + N = int(180 / self.tomo_angle_stepsize) + 1 + start = start_angle + _tomo_shift_angles + + if subtomo_number % 2: # odd subtomos → forward direction + # clamp end angle to max allowed + max_allowed_angle = 180.05 + self.tomo_angle_stepsize + proposed_end = start + 180 + angle_end = min(proposed_end, max_allowed_angle) + + angles = np.linspace( + start, + angle_end, + num=N, + endpoint=True, + ) + + else: # even subtomos → reverse direction + # go FROM start_angle down toward 0 + min_allowed_angle = 0 + proposed_end = start - 180 + angle_end = max(proposed_end, min_allowed_angle) + + angles = np.linspace( + start, + angle_end, + num=N, + endpoint=True, + ) for angle in angles: self.progress["subtomo"] = subtomo_number self.progress["subtomo_projection"] = np.where(angles == angle)[0][0] @@ -1866,7 +1885,7 @@ class Flomni( def _write_tomo_scan_number(self, scan_number: int, angle: float, subtomo_number: int) -> None: tomo_scan_numbers_file = os.path.expanduser( - "~/tomography_scannumbers.txt" + "~/data/raw/logs/tomography_scannumbers.txt" ) with open(tomo_scan_numbers_file, "a+") as out_file: # pylint: disable=undefined-variable diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py index c002ede..ba93df9 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/gui_tools.py @@ -210,7 +210,16 @@ class flomniGuiTools: main_progress_ring.set_value(progress) subtomo_progress_ring.set_value(subtomo_progress) - text = f"Progress report:\n Tomo type: {self.progress['tomo_type']}\n Projection: {self.progress['projection']:.0f}\n Total projections expected {self.progress['total_projections']}\n Angle: {self.progress['angle']}\n Current subtomo: {self.progress['subtomo']}\n Current projection within subtomo: {self.progress['subtomo_projection']}\n Total projections per subtomo: {int(self.progress['subtomo_total_projections'])}" + text = ( + f"Progress report:\n" + f" Tomo type: {self.progress['tomo_type']}\n" + f" Projection: {self.progress['projection']:.0f}\n" + f" Total projections expected {self.progress['total_projections']:.1f}\n" + f" Angle: {self.progress['angle']:.1f}\n" + f" Current subtomo: {self.progress['subtomo']}\n" + f" Current projection within subtomo: {self.progress['subtomo_projection']}\n" + f" Total projections per subtomo: {int(self.progress['subtomo_total_projections'])}" + ) self.progressbar.set_center_label(text) -- 2.52.0 From 8d6a2b0f5ca38a8d2831c8c41b7a03ab5ac7d4c7 Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 14:46:09 +0100 Subject: [PATCH 07/10] writing to spec log file removed (was for old webpage) --- csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py | 13 ------------- .../bec_ipython_client/plugins/flomni/flomni.py | 13 ------------- csaxs_bec/bec_ipython_client/plugins/omny/omny.py | 13 ------------- 3 files changed, 39 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py index ae0e4a3..24ada7f 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni.py @@ -356,18 +356,6 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools): # Logging helpers # ------------------------------------------------------------------ - def write_to_spec_log(self, content): - try: - with open( - os.path.expanduser( - "~/Data10/specES1/log-files/specES1_started_2022_11_30_1313.log" - ), - "a", - ) as log_file: - log_file.write(content) - except Exception: - logger.warning("Failed to write to spec log file (omny web page).") - def write_to_scilog(self, content, tags: list = None): try: if tags is not None: @@ -439,7 +427,6 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools): f"{str(datetime.datetime.now())}: LamNI scan projection at angle {angle}," f" scan number {bec.queue.next_scan_number}.\n" ) - self.write_to_spec_log(log_message) corridor_size = self.corridor_size if self.corridor_size > 0 else None scans.lamni_fermat_scan( fov_size=[self.lamni_piezo_range_x, self.lamni_piezo_range_y], diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index bec40bf..398cdff 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -1454,18 +1454,6 @@ class Flomni( def sample_name(self): return self.sample_get_name(0) - def write_to_spec_log(self, content): - try: - with open( - os.path.expanduser( - "~/Data10/specES1/log-files/specES1_started_2022_11_30_1313.log" - ), - "a", - ) as log_file: - log_file.write(content) - except Exception: - logger.warning("Failed to write to spec log file (omny web page).") - def write_to_scilog(self, content, tags: list = None): try: if tags is not None: @@ -1931,7 +1919,6 @@ class Flomni( f"{str(datetime.datetime.now())}: flomni scan projection at angle {angle}, scan" f" number {bec.queue.next_scan_number}.\n" ) - self.write_to_spec_log(log_message) # self.write_to_scilog(log_message, ["BEC_scans", self.sample_name]) scans.flomni_fermat_scan( fovx=self.fovx, diff --git a/csaxs_bec/bec_ipython_client/plugins/omny/omny.py b/csaxs_bec/bec_ipython_client/plugins/omny/omny.py index b4f62e8..a6bcb36 100644 --- a/csaxs_bec/bec_ipython_client/plugins/omny/omny.py +++ b/csaxs_bec/bec_ipython_client/plugins/omny/omny.py @@ -852,18 +852,6 @@ class OMNY( def sample_name(self): return dev.omny_samples.get_sample_name_in_samplestage() - def write_to_spec_log(self, content): - try: - with open( - os.path.expanduser( - "~/Data10/specES1/log-files/specES1_started_2022_11_30_1313.log" - ), - "a", - ) as log_file: - log_file.write(content) - except Exception: - logger.warning("Failed to write to spec log file (omny web page).") - def write_to_scilog(self, content, tags: list = None): try: if tags is not None: @@ -1288,7 +1276,6 @@ class OMNY( f"{str(datetime.datetime.now())}: omny scan projection at angle {angle}, scan" f" number {bec.queue.next_scan_number}.\n" ) - self.write_to_spec_log(log_message) # self.write_to_scilog(log_message, ["BEC_scans", self.sample_name]) scans.omny_fermat_scan( fovx=self.fovx, -- 2.52.0 From 4967474271a973023a945d89202b912a5d59ff68 Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 14:48:05 +0100 Subject: [PATCH 08/10] removed fsh commands --- .../bec_ipython_client/plugins/LamNI/lamni_optics_mixin.py | 4 ++-- docs/user/ptychography/lamni.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni_optics_mixin.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni_optics_mixin.py index efb468a..2437bf9 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni_optics_mixin.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/lamni_optics_mixin.py @@ -5,7 +5,7 @@ from rich import box from rich.console import Console from rich.table import Table -from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_put, fshclose +from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_put from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import OMNYTools dev = builtins.__dict__.get("dev") @@ -172,7 +172,7 @@ class LamNIOpticsMixin: def leye_out(self): self.loptics_in() - fshclose() + dev.omnyfsh.fshopen() leyey_out = self._get_user_param_safe("leyey", "out") umv(dev.leyey, leyey_out) diff --git a/docs/user/ptychography/lamni.md b/docs/user/ptychography/lamni.md index c916b04..ed7dcc4 100644 --- a/docs/user/ptychography/lamni.md +++ b/docs/user/ptychography/lamni.md @@ -26,7 +26,7 @@ The effective position of the axis of rotation shifts with sample thickness or m 1. `dev.lsamx` and `dev.lsamy` will print current position and the center value. Update the center value by `dev.lsamx.update_user_parameter({'center':8.69})` `dev.lsamy.update_user_parameter({'center':8.69})` -1. close the shutter: `fshclose()` +1. close the shutter: `dev.omnyfsh.fshclose()` #### X-ray eye alignment -- 2.52.0 From 583b15b772f79417557d9a8a8bb1ef38bdcba29d Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 15:29:23 +0100 Subject: [PATCH 09/10] fix number projections when starting with start_angle, correction in progress reporting --- .../plugins/flomni/flomni.py | 66 ++++++++++++++++--- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 398cdff..8bcc8a4 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -1571,9 +1571,31 @@ class Flomni( # _tomo_shift_angles (potential global variable) _tomo_shift_angles = 0 # compute number of projections - N = int(180 / self.tomo_angle_stepsize) + 1 + start = start_angle + _tomo_shift_angles + if subtomo_number % 2: # odd = forward + max_allowed_angle = 180.05 + self.tomo_angle_stepsize + proposed_end = start + 180 + angle_end = min(proposed_end, max_allowed_angle) + span = angle_end - start + + else: # even = reverse + min_allowed_angle = 0 + proposed_end = start - 180 + angle_end = max(proposed_end, min_allowed_angle) + span = start - angle_end + + # number of projections needed to maintain step size + N = int(span / self.tomo_angle_stepsize) + 1 + + angles = np.linspace( + start, + angle_end, + num=N, + endpoint=True, + ) + if subtomo_number % 2: # odd subtomos → forward direction # clamp end angle to max allowed max_allowed_angle = 180.05 + self.tomo_angle_stepsize @@ -1599,17 +1621,40 @@ class Flomni( num=N, endpoint=True, ) - for angle in angles: + + for i, angle in enumerate(angles): + self.progress["subtomo"] = subtomo_number - self.progress["subtomo_projection"] = np.where(angles == angle)[0][0] - self.progress["subtomo_total_projections"] = 180 / self.tomo_angle_stepsize - self.progress["projection"] = (subtomo_number - 1) * self.progress[ - "subtomo_total_projections" - ] + self.progress["subtomo_projection"] + + # --- NEW LOGIC FOR OFFSET WHEN start_angle IS SPECIFIED --- + if i == 0: + step = self.tomo_angle_stepsize + sa = start_angle + + if start_angle is None: + # normal operation: always start at zero + self._subtomo_offset = 0 + + else: + if subtomo_number % 2: # odd = forward direction + self._subtomo_offset = round(sa / step) + else: # even = reverse direction + self._subtomo_offset = round((180 - sa) / step) + + # progress index must always increase + self.progress["subtomo_projection"] = self._subtomo_offset + i + # ------------------------------------------------------------ + + # existing progress fields + self.progress["subtomo_total_projections"] = int(180 / self.tomo_angle_stepsize) + self.progress["projection"] = (subtomo_number - 1) * self.progress["subtomo_total_projections"] + self.progress["subtomo_projection"] self.progress["total_projections"] = 180 / self.tomo_angle_stepsize * 8 self.progress["angle"] = angle + + # finally do the scan at this angle self._tomo_scan_at_angle(angle, subtomo_number) + def _tomo_scan_at_angle(self, angle, subtomo_number): successful = False error_caught = False @@ -1685,7 +1730,7 @@ class Flomni( for ii in range(subtomo_start, 9): self.sub_tomo_scan(ii, start_angle=start_angle) start_angle = None - + elif self.tomo_type == 2: # Golden ratio tomography previous_subtomo_number = -1 @@ -1781,6 +1826,11 @@ class Flomni( else: raise FlomniError("undefined tomo type") + self.progress['projection'] = self.progress['total_projections'] + self.progress["subtomo_projection"] = self.progress["subtomo_total_projections"] + self._print_progress() + self.OMNYTools.printgreenbold("Tomoscan finished") + def _print_progress(self): print("\x1b[95mProgress report:") print(f"Tomo type: ....................... {self.progress['tomo_type']}") -- 2.52.0 From 43ae732e34a3ffa6ac539089081b190f6a45b812 Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 17 Mar 2026 16:07:17 +0100 Subject: [PATCH 10/10] added check for optics in etc to only move if not already there --- .../plugins/flomni/flomni.py | 11 +- .../plugins/flomni/flomni_optics_mixin.py | 107 ++++++++++++++++-- .../plugins/omny/omny_optics_mixin.py | 2 +- csaxs_bec/devices/omny/shutter.py | 2 + docs/user/ptychography/flomni.md | 2 +- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 8bcc8a4..707f44d 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -1621,7 +1621,7 @@ class Flomni( num=N, endpoint=True, ) - + for i, angle in enumerate(angles): self.progress["subtomo"] = subtomo_number @@ -1696,6 +1696,14 @@ class Flomni( def tomo_scan(self, subtomo_start=1, start_angle=None, projection_number=None): """start a tomo scan""" + if not self._check_eye_out_and_optics_in(): + print("Attention: The setup is not in measurement condition.\nXray eye might be IN or the Xray optics OUT.") + if self.OMNYTools.yesno("Shall I continue?", "n"): + print("OK") + else: + print("Stopping.") + return + self.flomnigui_show_progress() bec = builtins.__dict__.get("bec") @@ -1935,6 +1943,7 @@ class Flomni( dev.rtx.controller.laser_tracker_check_signalstrength() + scans = builtins.__dict__.get("scans") # additional_correction = self.align.compute_additional_correction(angle) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py index ac69033..17716a9 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_optics_mixin.py @@ -1,5 +1,5 @@ import time - +import numpy as np from rich import box from rich.console import Console from rich.table import Table @@ -38,16 +38,39 @@ class FlomniOpticsMixin: feyex_in = self._get_user_param_safe("feyex", "in") feyey_in = self._get_user_param_safe("feyey", "in") - umv(dev.feyex, feyex_in, dev.feyey, feyey_in) - #self.align.update_frame() + + current_feyex = dev.feyex.readback.get() + current_feyey = dev.feyey.readback.get() + + # check if both are close enough (within 0.01) + if np.isclose(current_feyex, feyex_in, atol=0.01) and np.isclose(current_feyey, feyey_in, atol=0.01): + # both already in position → do nothing + pass + else: + # move both axes to the desired "in" positions + umv(dev.feyex, feyex_in, dev.feyey, feyey_in) + + self.xrayeye_update_frame() def _ffzp_in(self): foptx_in = self._get_user_param_safe("foptx", "in") fopty_in = self._get_user_param_safe("fopty", "in") - umv(dev.foptx, foptx_in) - umv( - dev.fopty, fopty_in - ) # for 7.2567 keV and 150 mu, 60 nm fzp, loptz 83.6000 for propagation 1.4 mm + + current_foptx = dev.foptx.readback.get() + current_fopty = dev.fopty.readback.get() + + tol = 0.003 + + # if either axis is outside the tolerance → move both + need_move_optics = ( + not np.isclose(current_foptx, foptx_in, atol=tol) or + not np.isclose(current_fopty, fopty_in, atol=tol) + ) + + if need_move_optics: + umv(dev.foptx, foptx_in, dev.fopty, fopty_in) # for 7.2567 keV and 150 mu, 60 nm fzp, loptz 83.6000 for propagation 1.4 mm + else: + print("FZP is already at the in position.") def ffzp_in(self): """ @@ -90,19 +113,85 @@ class FlomniOpticsMixin: # umv(dev.losax, -1.4850, dev.losay, -0.1930) # umv(dev.losaz, 1.0000) # 7.2, 150 + fosax_in = self._get_user_param_safe("fosax", "in") fosay_in = self._get_user_param_safe("fosay", "in") fosaz_in = self._get_user_param_safe("fosaz", "in") + + # tighten limits dev.fosax.limits = [fosax_in - 0.1, fosax_in + 0.1] dev.fosay.limits = [fosay_in - 0.1, fosay_in + 0.1] dev.fosaz.limits = [fosaz_in - 0.1, fosaz_in + 0.1] - umv(dev.fosax, fosax_in, dev.fosay, fosay_in) - umv(dev.fosaz, fosaz_in) + + current_fosax = dev.fosax.readback.get() + current_fosay = dev.fosay.readback.get() + current_fosaz = dev.fosaz.readback.get() + + # tolerance + tol = 0.003 + + need_move_osa = ( + not np.isclose(current_fosax, fosax_in, atol=tol) or + not np.isclose(current_fosay, fosay_in, atol=tol) or + not np.isclose(current_fosaz, fosaz_in, atol=tol) + ) + + if need_move_osa: + umv(dev.fosax, fosax_in, dev.fosay, fosay_in) + umv(dev.fosaz, fosaz_in) + else: + print("OSA is already at the IN position.") # 11 kev # umv(dev.losax, -1.161000, dev.losay, -0.196) # umv(dev.losaz, 1.0000) + def _check_eye_out_and_optics_in(self, tol=0.003): + # --- expected IN positions --- + foptx_in = self._get_user_param_safe("foptx", "in") + fopty_in = self._get_user_param_safe("fopty", "in") + foptz_in = self._get_user_param_safe("foptz", "in") + + # --- expected OUT condition for the X-ray eye --- + # eye is OUT when it is *not within tolerance* of its IN position + feyex_out = self._get_user_param_safe("feyex", "out") + + # --- current positions --- + cx_feyex = dev.feyex.readback.get() + + cx_foptx = dev.foptx.readback.get() + cx_fopty = dev.fopty.readback.get() + cx_foptz = dev.foptz.readback.get() + + # --- check eye OUT --- + eye_out = ( + np.isclose(cx_feyex, feyex_out, atol=tol) + ) + + # --- check optics IN --- + optics_in = ( + np.isclose(cx_foptx, foptx_in, atol=tol) and + np.isclose(cx_fopty, fopty_in, atol=tol) and + np.isclose(cx_foptz, foptz_in, atol=tol) + ) + + fosax_in = self._get_user_param_safe("fosax", "in") + fosay_in = self._get_user_param_safe("fosay", "in") + fosaz_in = self._get_user_param_safe("fosaz", "in") + + cx_fosax = dev.fosax.readback.get() + cx_fosay = dev.fosay.readback.get() + cx_fosaz = dev.fosaz.readback.get() + + osa_in = ( + np.isclose(cx_fosax, fosax_in, atol=tol) and + np.isclose(cx_fosay, fosay_in, atol=tol) and + np.isclose(cx_fosaz, fosaz_in, atol=tol) + ) + + return eye_out and optics_in and osa_in + + def fosa_out(self): self.ensure_fheater_up() curtain_is_triggered = dev.foptz.controller.fosaz_light_curtain_is_triggered() diff --git a/csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py b/csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py index fb16ae8..e9ff998 100644 --- a/csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py +++ b/csaxs_bec/bec_ipython_client/plugins/omny/omny_optics_mixin.py @@ -48,7 +48,7 @@ class OMNYOpticsMixin: dev.oeyez.controller.socket_put_confirmed("axspeed[7]=10000") def oeye_out(self): - fshclose() + dev.omnyfsh.fshclose() if self.OMNYTools.yesno("Did you move in the optics?"): umv(dev.oeyez, -2) self._oeyey_mv(-60.3) diff --git a/csaxs_bec/devices/omny/shutter.py b/csaxs_bec/devices/omny/shutter.py index c318ebf..a4b7312 100644 --- a/csaxs_bec/devices/omny/shutter.py +++ b/csaxs_bec/devices/omny/shutter.py @@ -48,6 +48,7 @@ class OMNYFastShutter(PSIDeviceBase, Device): def fshopen(self): """Open the fast shutter.""" if self._check_if_cSAXS_shutter_exists_in_config(): + self.shutter.put(1) return self.device_manager.devices["fsh"].fshopen() else: self.shutter.put(1) @@ -55,6 +56,7 @@ class OMNYFastShutter(PSIDeviceBase, Device): def fshclose(self): """Close the fast shutter.""" if self._check_if_cSAXS_shutter_exists_in_config(): + self.shutter.put(0) return self.device_manager.devices["fsh"].fshclose() else: self.shutter.put(0) diff --git a/docs/user/ptychography/flomni.md b/docs/user/ptychography/flomni.md index 9e9945f..a0ebe84 100644 --- a/docs/user/ptychography/flomni.md +++ b/docs/user/ptychography/flomni.md @@ -76,7 +76,7 @@ Now that the sample is aligned, the tomographic measurement can be performed. A __single projection__ is to be repeated use `flomni.tomo_scan_projection()`. The target angle of scans can be found in the second column of the file in -`~/Data10/specES1/dat-files/omni_scannumbers.txt` +`~/data/raw/logs/tomography_scannumbers.txt` To continue an __interrupted tomography scan__: -- 2.52.0