diff --git a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py index 80d27ed1c8..142f126d25 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py @@ -30,12 +30,9 @@ import logging import time -from typing import ( - Any, - List, -) +from typing import Any, List -import gevent +from gevent import Timeout, sleep, spawn from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.EMBLFlexHCD import EMBLFlexHCD @@ -48,11 +45,9 @@ class EMBLFlexHarvester(EMBLFlexHCD): - """EMBLFlexHarvester is the Hardware Object interface for the EMBL Flex Sample Changer - It inherits from EMBLFlexHCD and implements the Harvester interface. - """ + """Implement the MBL Harvester interface as Flex sample changer" """ - __TYPE__ = "Flex Sample Changer" + __TYPE__ = "EMBL Harvester Sample Changer" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -66,7 +61,7 @@ def init(self): self._loaded_sample = (-1, -1, -1) self._harvester_hwo = self.get_object_by_role("harvester") - EMBLFlexHCD.init(self) + super().init() def get_room_temperature_mode(self) -> bool: """Get the Harvester Room Temperature Mode""" @@ -96,9 +91,9 @@ def get_sample_list(self) -> List[Any]: ha_sample_lists = self._harvester_hwo.get_crystal_uuids() ha_sample_names = self._harvester_hwo.get_sample_names() ha_sample_states = self._harvester_hwo.get_samples_state() - except Exception as e: + except Exception as err: self.user_log.error( - "Failed retrieving sample metadata from Harvester: %s", e + f"Failed retrieving sample metadata from Harvester: {err}" ) return present_sample_list @@ -173,7 +168,7 @@ def load_a_pin_for_calibration(self): self.prepare_load() self.enable_power() - load_task = gevent.spawn( + load_task = spawn( self._execute_cmd_exporter, "loadSampleFromHarvester", self.pin_cleaning, @@ -182,12 +177,12 @@ def load_a_pin_for_calibration(self): self._wait_busy(30) err_msg = "Timeout while waiting to sample to be loaded" - with gevent.Timeout(600, RuntimeError(err_msg)): + with Timeout(600, RuntimeError(err_msg)): while not load_task.ready(): logging.getLogger("user_level_log").info("wait loading task") - gevent.sleep(2) + sleep(2) - with gevent.Timeout(600, RuntimeError(err_msg)): + with Timeout(600, RuntimeError(err_msg)): while True: logging.getLogger("user_level_log").info("Wait Robot Safe position") is_safe = self._execute_cmd_exporter( @@ -195,27 +190,20 @@ def load_a_pin_for_calibration(self): ) if is_safe: break - gevent.sleep(2) + sleep(2) return True except RuntimeError: return False def start_harvester_centring(self): + logging.getLogger("user_level_log").info("Start Auto Harvesting Centring") try: - dm = HWR.beamline.diffractometer - - logging.getLogger("user_level_log").info("Start Auto Harvesting Centring") - - computed_offset = HWR.beamline.harvester.get_offsets_for_sample_centring() - dm.start_harvester_centring(computed_offset) + HWR.beamline.sample_view.start_harvester_centring() except Exception as exc: - logging.getLogger("user_level_log").exception( - "Could not center sample, skipping" - ) - raise QueueExecutionException( - "Could not center sample, skipping", self - ) from exc + msg = "Could not center sample, skipping" + logging.getLogger("user_level_log").exception(msg) + raise QueueExecutionException(msg, self) from exc def _set_loaded_sample_and_prepare(self, loaded_sample_tup, previous_sample_tup): res = False @@ -232,7 +220,8 @@ def _set_loaded_sample_and_prepare(self, loaded_sample_tup, previous_sample_tup) self.queue_harvest_next_sample(loaded_sample.get_address()) # we expect CENTRING_METHOD to be None - # NB: move this call to base_queue_entry mount_sample and add Harvester Centring METHOD + # NB: move this call to base_queue_entry mount_sample and + # add Harvester Centring METHOD HWR.beamline.queue_manager.centring_method = CENTRING_METHOD.NONE self.start_harvester_centring() @@ -263,7 +252,8 @@ def _do_load(self, sample=None) -> bool: sample.get_basket_no(), sample.get_vial_no(), ) - # Flex/Exporter Does not know the loaded sample location we keep track of it ourselfs + # Flex/Exporter does not know the loaded sample location, + # keep track locally. self._loaded_sample = loaded_sample return self._set_loaded_sample_and_prepare(loaded_sample, previous_sample) @@ -272,7 +262,7 @@ def _perform_loading_sequence(self, sample_uuid) -> bool: logging.getLogger("user_level_log").info( "Start loading from harvester SAMPLE_UUID %s", sample_uuid ) - load_task = gevent.spawn( + load_task = spawn( self._execute_cmd_exporter, "loadSampleFromHarvester", sample_uuid, @@ -296,13 +286,13 @@ def _perform_loading_sequence(self, sample_uuid) -> bool: # Wait for sample to be loaded err_msg = "Timeout while waiting to sample to be loaded" try: - with gevent.Timeout(600, RuntimeError(err_msg)): + with Timeout(600, RuntimeError(err_msg)): while not load_task.ready(): logging.getLogger("user_level_log").info("Wait loading task") loaded_sample = self._hw_get_mounted_crystal_id() if loaded_sample == sample_uuid: break - gevent.sleep(2) + sleep(2) except RuntimeError: logging.getLogger("user_level_log").error(err_msg) return False @@ -314,14 +304,14 @@ def _finalize_loading_sequence(self) -> bool: # Wait for robot to be in safe state err_msg = "Timeout while waiting for robot to be in safe state" try: - with gevent.Timeout(600, RuntimeError(err_msg)): + with Timeout(600, RuntimeError(err_msg)): while True: is_safe = self._execute_cmd_exporter( "getRobotIsSafe", attribute=True ) if is_safe: break - gevent.sleep(2) + sleep(2) except RuntimeError: logging.getLogger("user_level_log").error(err_msg) return False diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index 2b1462117f..59944215bc 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -38,7 +38,6 @@ harvester wid30harvest:9001 ------------------------------------------------------------------ """ from __future__ import annotations @@ -46,7 +45,7 @@ import logging from typing import List, Optional, Union -import gevent +from gevent import Timeout, sleep from mxcubecore.BaseHardwareObjects import HardwareObject @@ -98,7 +97,6 @@ def __init__(self, name): super().__init__(name) self.timeout = 600 # default timeout - # Internal variables ----------- self.calibration_state = False def init(self): @@ -111,49 +109,48 @@ def set_calibration_state(self, state: bool): """Set Calibration state Args: - state (bool) : Whether a calibration procedure is on going + state: True if a calibration procedure is on going. """ self.calibration_state = state def _wait_ready(self, timeout: Union[float, None] = None): - """Wait Harvester to be ready + """Wait timeout seconds until status is ready. Args: - (timeout) : Whether to wait for a amount of time - timeout is None wait forever, timeout <=0 use default timeout + timeout: optional - timeout [s], + if timeout = 0: return at once and do not wait, + if timeout is None: wait forever (default). """ - if timeout is not None and timeout <= 0: - timeout = self.timeout + if timeout == 0: + return err_msg = "Timeout waiting for Harvester to be ready" - with gevent.Timeout(timeout, RuntimeError(err_msg)): + with Timeout(timeout, RuntimeError(err_msg)): while not self._ready(): logging.getLogger("user_level_log").info( "Waiting Harvester to be Ready" ) - gevent.sleep(3) + sleep(3) def _wait_sample_transfer_ready(self, timeout: Union[float, None] = None): - """Wait Harvester to be ready to transfer a sample + """Wait timeout seconds until ready to transfer a sample. Args: - timeout (second) : Whether to wait for a amount of time - timeout is None wait forever, timeout <=0 use default timeout + timeout: optional - timeout [s], + if timeout = 0: return at once and do not wait, + if timeout is None: wait forever (default). """ - if timeout is not None and timeout <= 0: - timeout = self.timeout + if timeout == 0: + return err_msg = "Timeout waiting for Harvester to be ready to transfer" try: - with gevent.Timeout(timeout, RuntimeError(err_msg)): - while not self._ready_to_transfer(): - logging.getLogger("user_level_log").info( - "Waiting Harvester to be ready to transfer for 10 minutes" - ) - gevent.sleep(3) + with Timeout(timeout, RuntimeError(err_msg)): + while not self._ready_to_transfer: + sleep(3) except RuntimeError as exc: # In case of timeout we as abort, park and trash self.abort() @@ -220,6 +217,7 @@ def get_status(self) -> str: """ return self._execute_cmd_exporter("getStatus", attribute=True) + @property def _ready(self) -> str: """check whether the Harvester is READY @@ -227,17 +225,12 @@ def _ready(self) -> str: """ return self._execute_cmd_exporter("getState", attribute=True) == "Ready" - def _busy(self) -> bool: - """check whether the Harvester is BUSY - - Return (bool): True if Harvester is not Ready otherwise False - """ - return self._execute_cmd_exporter("getState", attribute=True) != "Ready" - + @property def _ready_to_transfer(self) -> bool: - """check whether the Harvester is Waiting Sample Transfer + """check if the Harvester is Waiting Sample Transfer - Return (bool): True if Harvester is Waiting Sample Transfer otherwise False + Returns: + True if Harvester is Waiting Sample Transfer otherwise False """ return ( self._execute_cmd_exporter("getStatus", attribute=True) @@ -247,31 +240,31 @@ def _ready_to_transfer(self) -> bool: def get_samples_state(self) -> List[str]: """Get the Harvester Samples State - Return (List): list of crystal state "waiting_for_transfer, Running etc.." + Return: + List of states "Waiting Sample Transfer", "Running"... """ return self._execute_cmd_exporter("getSampleStates", attribute=True) def get_current_crystal(self) -> str: - """Get the Harvester current harvested crystal + """Get the current harvested crystal Return (str): the crystal uuid """ return self._execute_cmd_exporter("getCurrentSampleID", attribute=True) - def is_crystal_harvested(self, crystal_uuid: str) -> str: + def is_crystal_harvested(self, crystal_uuid: str) -> bool: """Check Whether if the current crystal is harvested - args: the crystal uuid - - Return (bool): True if the crystal is the current harvested crystal + Args: + crystal_uuid: the crystal uuid + Returns: + True if the crystal is the current harvested crystal. """ - res = False - in_list = crystal_uuid in self.get_crystal_uuids() - if in_list: - Current_SampleID = self.get_current_crystal() - if crystal_uuid == Current_SampleID: - res = True - return res + if crystal_uuid in self.get_crystal_uuids(): + current_sample_id = self.get_current_crystal() + if crystal_uuid == current_sample_id: + return True + return False def current_crystal_state(self, crystal_uuid: str) -> str: """get current crystal state @@ -352,8 +345,6 @@ def get_sample_acronyms(self) -> List[str]: ) return harvester_sample_acronyms - # ------------------------------------------------------------------------------------ - def abort(self) -> str: """Send Abort command Abort any current Harvester Actions @@ -388,8 +379,6 @@ def trash_sample(self): """Trash the current Harvested Crystal""" return self._execute_cmd_exporter("trashSample", command=True) - # ----------------------------------------------------------------------------- - def load_plate(self, plate_id: str) -> str: """Change Harvester current plate @@ -445,7 +434,7 @@ def set_room_temperature_mode(self, value: bool) -> bool: print("setting HA Room temperature to: %s" % value) return self.get_room_temperature_mode() - # -------------------- Calibrate Drift Shape offset ---------------------------- + # -------------------- Calibrate Drift Shape offset ---------------- def get_last_sample_drift_offset_x(self) -> float: """Sample Offset X position when drifted @@ -474,7 +463,7 @@ def get_last_sample_drift_offset_z(self) -> float: ) return pin_last_drift_offset_z - # ---------------------- Calibrate Cut Shape offset---------------------------- + # ---------------------- Calibrate Cut Shape offset--------------- def get_last_pin_cut_shape_offset_x(self) -> float: """Pin shape Offset x position @@ -542,7 +531,7 @@ def queue_harvest_sample( wait_before_load = not self.get_room_temperature_mode() if self.get_number_of_available_pin() > 0: - gevent.sleep(2) + sleep(2) if current_queue_index == 0: logging.getLogger("user_level_log").info("Harvesting First Sample") @@ -551,9 +540,10 @@ def queue_harvest_sample( sample_uuid, wait_before_load ) if harvest_res is False: - # if sample could not be Harvest, but no exception is raised, let's skip the sample + # if sample could not be harvested, but no exception is + # raised, the sample is skipped logging.getLogger("user_level_log").error( - "Harvester could not Harvest sample, Stopping queue" + "Harvester could not harvest sample, Stopping queue" ) else: logging.getLogger("user_level_log").info("checking last Harvesting") @@ -561,23 +551,21 @@ def queue_harvest_sample( sample_uuid, wait_before_load ) if harvest_res is False: - # if sample could not be Harvest, but no exception is raised, let's skip the sample + # if sample could not be harvested, but no exception is + # raised, the sample is skipped logging.getLogger("user_level_log").error( "There is no more Pins in the Harvester, Stopping queue" ) - elif self.get_number_of_available_pin() == 0 and self._ready_to_transfer(): + elif self.get_number_of_available_pin() == 0 and self._ready_to_transfer: logging.getLogger("user_level_log").warning( - "Warning: Harvester pins is approaching to ZERO" - ) - logging.getLogger("user_level_log").warning( - "Warning: Mounting last Sample, Queue will stop on next one" + "Mounting the last Sample, Queue will stop on next one" ) # in this case we just load the sample that is ready in the Harester harvest_res = True else: # raise Not enough pins available in the pin provider logging.getLogger("user_level_log").error( - "There is no more Pins in the Harvester, Stopping queue" + "No more Pins left in the Harvester, Stopping queue" ) return harvest_res @@ -601,11 +589,11 @@ def queue_harvest_next_sample(self, next_sample_loc_str: str, sample_uuid: str): def harvest_sample_before_mount( self, sample_uuid: str, wait_before_load: bool = False ) -> bool: - """send harvest sample command - Check and set the current state of the Harvester and the sample before Harvest - - Return (bool): whether the sample has been harvest then mount (True) - or had and exception (False) + """Check and set the current state of the Harvester and the sample + before harvesting. + Return: + True if the sample has been harvested and mounted. + False if exception has been received. """ res = None @@ -638,7 +626,6 @@ def harvest_sample_before_mount( self._wait_sample_transfer_ready(self.timeout) res = True else: - # logging.getLogger("user_level_log").info("ERROR: Sample Could not be Harvested (Harvester Ready, ) ") msg = self.get_status() logging.getLogger("user_level_log").exception( "ERROR: Sample Could not be Harvested" @@ -651,7 +638,7 @@ def harvest_sample_before_mount( except RuntimeError: return False - elif self._ready_to_transfer(): + elif self._ready_to_transfer: try: if ( self.current_crystal_state(sample_uuid) @@ -718,7 +705,7 @@ def harvest_sample_before_mount( # Try an abort and move to next sample return False - def get_offsets_for_sample_centring(self) -> tuple[float]: + def get_offsets_for_sample_centering(self) -> tuple[float]: """Calculate sample centring offsets based on Harvested pin shape pre-calculated offsets diff --git a/mxcubecore/HardwareObjects/HarvesterMaintenance.py b/mxcubecore/HardwareObjects/HarvesterMaintenance.py index 3b6300a24a..ceedeaf861 100644 --- a/mxcubecore/HardwareObjects/HarvesterMaintenance.py +++ b/mxcubecore/HardwareObjects/HarvesterMaintenance.py @@ -24,7 +24,7 @@ import logging -import gevent +from gevent import sleep from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject @@ -40,6 +40,7 @@ class HarvesterMaintenance(HardwareObject): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.saved_motor_positions = {} def init(self): self._harvester = self.get_object_by_role("harvester") @@ -150,7 +151,7 @@ def get_cmd_info(self): return cmd_list def send_command(self, cmd_name, args=None): - if cmd_name in ["park"]: + if "park" in cmd_name: self._do_park() if cmd_name == "trash": self._do_trash() @@ -176,17 +177,19 @@ def calibrate_pin(self) -> bool: self._harvester.load_calibrated_pin() self._harvester._wait_sample_transfer_ready(None) - print("waiting 40 seconds before mount") - # For some reason the Harvester return READY too soon + + # For some reason the Harvester returns READY too soon # approximately 40 Second sooner - gevent.sleep(40) + print("waiting 40 seconds before mount") + sleep(40) + sample_mount_device = HWR.beamline.sample_changer mount_current_sample = sample_mount_device.load_a_pin_for_calibration() if mount_current_sample: try: - md = HWR.beamline.diffractometer - md._wait_ready() + diffr = HWR.beamline.diffractometer + diffr.wait_status_ready() sample_drift_x = float(self._harvester.get_last_sample_drift_offset_x()) sample_drift_y = float(self._harvester.get_last_sample_drift_offset_y()) @@ -194,25 +197,16 @@ def calibrate_pin(self) -> bool: -self._harvester.get_last_sample_drift_offset_z() ) - motor_pos_dict = { - "kappa": float( - md["HacentringReferencePosition"].get_property("kappa_ref") - ), - "kappa_phi": float( - md["HacentringReferencePosition"].get_property("phi_ref") - ), - "phi": float( - md["HacentringReferencePosition"].get_property("omega_ref") - ), - "phiy": md.phiyMotor.get_value() + sample_drift_x, - } - - md.move_motors(motor_pos_dict) - md._wait_ready() - md.centringFocus.set_value_relative(sample_drift_z, None) - md.centringVertical.set_value_relative(sample_drift_y, None) - - md.save_current_motor_position() + motor_pos_dict = HWR.beamline.sample_view.harvester_reference.copy() + motor_pos_dict["phiy"] = diffr.phiy.get_value() + sample_drift_x + + diffr.set_value_motors(motor_pos_dict) + diffr.wait_status_ready() + diffr.sample_focus.set_value_relative(sample_drift_z, None) + diffr.sample_vertical.set_value_relative(sample_drift_y, None) + + self.saved_motor_positions = diffr.get_value_motors() + self._harvester.set_calibration_state(True) logging.getLogger("user_level_log").info( @@ -240,40 +234,25 @@ def validate_calibration(self) -> bool: goes to end (True) or had and exception (False) """ try: - md = HWR.beamline.diffractometer - - motor_pos_dict = { - "focus": md.focusMotor.get_value(), - "phiy": md.phiyMotor.get_value(), - "phiz": md.phizMotor.get_value(), - "centring_focus": md.centringFocus.get_value(), - "centring_vertical": md.centringVertical.get_value(), - } + diffr = HWR.beamline.diffractometer + + motor_pos_dict = diffr.get_value_motors() + new_motor_offset = {} + saved_position = self.saved_motor_positions - saved_position = md.saved_motor_position # find offset position based on old and new motor position - new_motor_offset = { - "focus": motor_pos_dict["focus"] - saved_position["focus"], - "phiy": motor_pos_dict["phiy"] - saved_position["phiy"], - "phiz": motor_pos_dict["phiz"] - saved_position["phiz"], - "centring_focus": ( - motor_pos_dict["centring_focus"] - saved_position["centring_focus"] - ), - "centring_vertical": ( - motor_pos_dict["centring_vertical"] - - saved_position["centring_vertical"] - ), - } + for nam in ("focus", "phiy", "phiz", "sample_focus", "sample_vertical"): + new_motor_offset[nam] = motor_pos_dict[nam] - saved_position[nam] calibrated_motor_offset = { - "focus": new_motor_offset["focus"] + new_motor_offset["centring_focus"], + "focus": new_motor_offset["focus"] + new_motor_offset["sample_focus"], "phiy": new_motor_offset["phiy"], "phiz": ( - new_motor_offset["phiz"] + new_motor_offset["centring_vertical"] + new_motor_offset["phiz"] + new_motor_offset["sample_vertical"] ), } - # we store the motor offset in the Harvester, to be used for sample centring + # store the offset in the Harvester, to be used for sample centring self._harvester.store_calibrated_pin( calibrated_motor_offset["focus"], calibrated_motor_offset["phiy"], diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index 68f6132fdb..3d1891e218 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -77,6 +77,7 @@ def __init__(self, name): self.centring_status = {} self.rotation_reference = {} self.chi_angle = None + self.harvester_reference = {} def init(self): super().init() @@ -110,6 +111,9 @@ def init(self): self.centring_motors[role].motor.connect( "stateChanged", self._update_shape_positions ) + + diffr.zoom.connect("valueChanged", self._update_shape_positions) + self._camera = self.get_object_by_role("camera") self._last_oav_image = None @@ -121,11 +125,17 @@ def init(self): self.rotation_reference.update( {"motor": self.centring_motors.get(self.rotation_reference.get("name"))} ) + harvester_reference = self.get_property("harvester_reference_position", {}) + if isinstance(harvester_reference, str): + self.harvester_reference = literal_eval(harvester_reference) def _update_shape_positions(self, *args, **kwargs): - for shape in self.get_shapes(): + _shapes = self._shapes.copy() + + for _key, shape in _shapes.items(): shape.update_position(self.motor_positions_to_screen) + self._shapes = _shapes self.emit("shapesChanged") def get_positions(self) -> dict[str, float]: @@ -186,7 +196,7 @@ def get_centred_point_from_coord(self, x, y, return_by_names=None): phiz = motors_dict.get("phiz") + dy return { - "omega": motors_dict.get("omega"), + "omega": -motors_dict.get("omega"), "phiy": float(-phiy), "phiz": phiz, "sampx": float(-sampx), @@ -212,10 +222,15 @@ def motor_positions_to_screen( diffr.wait_status_ready(50) motors_dict = self.get_positions() for key, val in positions_dict.items(): + if val is None: + continue new_pos_dict[key] = self.centring_motors[key].direction * ( val - motors_dict.get(key) ) - omega_angle = math.radians(motors_dict.get("omega", 0)) + omega_angle = ( + math.radians(motors_dict.get("omega", 0)) + * self.centring_motors["omega"].direction + ) rot_matrix = np.matrix( [ [math.cos(omega_angle), -math.sin(omega_angle)], @@ -304,6 +319,7 @@ def auto_centring_done(self, auto_centring_procedure): logging.exception("Could not complete automatic centring") logging.getLogger("user_level_log").info("Automatic loop centring failed") self.centring_failed() + self.reject_centring() else: if res is None: logging.error("Could not complete automatic centring") @@ -311,6 +327,7 @@ def auto_centring_done(self, auto_centring_procedure): "Automatic loop centring failed" ) self.centring_failed() + self.reject_centring() else: self.centring_done() self.accept_centring() @@ -373,7 +390,7 @@ def run_custom_auto_centring(self): self.current_centring_method = "Automatic" self.emit("centringStarted", ("Automatic")) diffr = HWR.beamline.diffractometer - self.wait_status_ready(60) + diffr.wait_status_ready(60) diffr.run_custom_script("sample_centering") diffr.wait_status_ready() @@ -424,6 +441,36 @@ def start_auto_centring(self): self.emit("centringStarted", ("Automatic")) self.current_centring_procedure.link(self.auto_centring_done) + def start_harvester_centring(self): + """Start harvester automatic centring procedure""" + + if self.current_centring_procedure is not None: + logging.getLogger("HWR").exception("Already centring") + + self.log.info("Harvester sample centring") + self.current_centring_method = "Automatic" + self.emit("centringStarted", ("Automatic")) + diffr = HWR.beamline.diffractometer + diffr.wait_status_ready(60) + # diffr.set_phase(diffr.get_phase_enum.CENTRE) + + motors_dict = self.get_positions() + for key, val in self.harvester_reference.items(): + motors_dict.update({key: val}) + _offsets = HWR.beamline.harvester.get_offsets_for_sample_centering() + motors_dict["phiy"] += _offsets[0] + diffr.set_value_motors(motors_dict) + + # next two motors are not part of the centring motors + # we move them separately + diffr.motors_hwobj_dict["sample_focus"].set_value_relative(_offsets[1]) + diffr.motors_hwobj_dict["sample_vertical"].set_value_relative(_offsets[2]) + + diffr.wait_status_ready(10) + + self.centring_done() + self.accept_centring() + def move_to_beam(self, x: float, y: float): """Move the sample to the x,y coordinates. Args: diff --git a/ruff.toml b/ruff.toml index dbb3093686..d8bffcf5d0 100644 --- a/ruff.toml +++ b/ruff.toml @@ -380,11 +380,6 @@ convention = "google" "B006", "S301", ] -"mxcubecore/HardwareObjects/EMBLFlexHarvester.py" = [ - "B904", - "E501", - "E712", -] "mxcubecore/HardwareObjects/ESRF/BlissHutchTrigger.py" = [ "B904", ] @@ -512,12 +507,6 @@ convention = "google" "B905", "F841", ] -"mxcubecore/HardwareObjects/Harvester.py" = [ - "E501", -] -"mxcubecore/HardwareObjects/HarvesterMaintenance.py" = [ - "E501", -] "mxcubecore/HardwareObjects/ICATLIMS.py" = [ "E501", ]