From 9126b8d64df52893b99923535695a9b7ed44121a Mon Sep 17 00:00:00 2001 From: x12sa Date: Tue, 7 Jul 2026 13:11:37 +0200 Subject: [PATCH] feat(flomni): add remove-only sample change via ftransfer_sample_change(-1) Passing -1 stows the sample currently in the sample stage into a free tray slot without mounting a replacement, matching the old control system's sample_change(-1) behavior. Existing swap-path logic is unchanged. --- .../plugins/flomni/flomni.py | 48 +++++++++++++++++-- docs/user/ptychography/flomni.md | 4 ++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 051b993..28b6a3b 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -839,12 +839,45 @@ class FlomniSampleTransferMixin: if sample_in_gripper: raise FlomniError("There is already a sample in the gripper. Aborting.") - self.check_position_is_valid(new_sample_position) + if new_sample_position == -1: + # Remove-only: stow the sample currently in the sample stage into a + # free tray slot and stop there -- no new sample is mounted. + sample_in_sample_stage = dev.flomni_samples.is_sample_slot_used(0) + if not sample_in_sample_stage: + raise FlomniError("There is no sample in the sample stage to remove. Aborting.") - if new_sample_position == 0: - raise FlomniError( - "The new sample to place cannot be the sample in the sample stage. Aborting." - ) + empty_slots = [] + for j in range(1, 20): + if not dev.flomni_samples.is_sample_slot_used(j): + empty_slots.append(j) + if not empty_slots: + raise FlomniError("There are no empty slots available. Aborting.") + + print(f"The following slots are empty: {empty_slots}.") + + while True: + user_input = input(f"Where shall I put the sample? Default: [{empty_slots[0]}] ") + + if user_input.strip() == "": + user_input = empty_slots[0] + break + + try: + user_input = int(user_input) + if user_input not in empty_slots: + raise ValueError + break + except ValueError: + print("Please specify a valid number.") + continue + + self.check_position_is_valid(user_input) + + self.ftransfer_get_sample(0) + self.ftransfer_put_sample(user_input) + return + + self.check_position_is_valid(new_sample_position) # sample_placed = getattr( # dev.flomni_samples.sample_placed, f"sample{new_sample_position}" @@ -855,6 +888,11 @@ class FlomniSampleTransferMixin: f"There is currently no sample in position [{new_sample_position}]. Aborting." ) + if new_sample_position == 0: + raise FlomniError( + "The new sample to place cannot be the sample in the sample stage. Aborting." + ) + # sample_in_sample_stage = dev.flomni_samples.sample_placed.sample0.get() sample_in_sample_stage = dev.flomni_samples.is_sample_slot_used(0) if sample_in_sample_stage: diff --git a/docs/user/ptychography/flomni.md b/docs/user/ptychography/flomni.md index 7b365af..bec0bc8 100644 --- a/docs/user/ptychography/flomni.md +++ b/docs/user/ptychography/flomni.md @@ -24,6 +24,10 @@ You will be asked to enter a sample name. To load a new sample in the sample stage, in principle only one command is needed `flomni.ftransfer_sample_change()` You will be asked where the previous sample should go with a suggestion for an empty position in the tray. + +To remove the current sample from the sample stage __without__ mounting a new one, use +`flomni.ftransfer_sample_change(-1)` +You will be asked where to stow the removed sample, same as above. Other commands: `ftransfer_tray_in /_out (not yet implemented).`