From a81b9cea6d318ee90dde843a75f82a7084052602 Mon Sep 17 00:00:00 2001 From: fabcor Date: Fri, 16 Aug 2024 10:34:33 +0200 Subject: [PATCH 001/172] Allow `.yaml` extension for YAML config files The recommended file extension for YAML files is `.yaml`. Both `.yaml` and `.yml` are valid extensions for YAML files. --- mxcubecore/HardwareRepository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareRepository.py b/mxcubecore/HardwareRepository.py index 80c06a1240..55c518b34a 100644 --- a/mxcubecore/HardwareRepository.py +++ b/mxcubecore/HardwareRepository.py @@ -181,7 +181,7 @@ def load_from_yaml(configuration_file, role, _container=None, _table=None): msg0 = "Done loading contents" for role1, config_file in _objects.items(): fname, fext = os.path.splitext(config_file) - if fext == ".yml": + if fext in (".yaml", ".yml"): load_from_yaml( config_file, role=role1, _container=result, _table=_table ) From 248e7d4dc6e80f4e93a2fcad0cf2fb08884f4014 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 19 Aug 2024 07:39:16 +0000 Subject: [PATCH 002/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 79261e62a6..b8170e5df7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.135.0" +version = "1.136.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From e84cbd6d942534b75ed75bf0d4b5882aa7c5f8f7 Mon Sep 17 00:00:00 2001 From: meguiraun Date: Mon, 19 Aug 2024 19:08:14 +0200 Subject: [PATCH 003/172] XRF centred position (#988) * propagate xrf centred position retrive xrf cpos from shape typo xrf model knows about shape * propagate energy scan centred position --- .../HardwareObjects/abstract/AbstractEnergyScan.py | 12 ++++++++++-- .../HardwareObjects/abstract/AbstractXRFSpectrum.py | 5 ++++- mxcubecore/model/queue_model_objects.py | 2 ++ mxcubecore/queue_entry/energy_scan.py | 5 +++++ mxcubecore/queue_entry/xrf_spectrum.py | 6 ++++-- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py index 1b6153412c..8a1040f9f2 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py @@ -13,6 +13,7 @@ def __init__(self): self.data_collect_task = None self._egyscan_task = None self.scanning = False + self.cpos = None def open_safety_shutter(self, timeout): """ @@ -141,7 +142,14 @@ def do_energy_scan(self): # def start_energy_scan( def start_energy_scan( - self, element, edge, directory, prefix, session_id=None, blsample_id=None + self, + element, + edge, + directory, + prefix, + session_id=None, + blsample_id=None, + cpos=None, ): if self._egyscan_task and not self._egyscan_task.ready(): raise RuntimeError("Scan already started.") @@ -152,7 +160,7 @@ def start_energy_scan( STATICPARS_DICT = self.get_static_parameters( self.get_property("config_file"), element, edge ) - + self.cpos = cpos self.energy_scan_parameters = STATICPARS_DICT self.energy_scan_parameters["element"] = element self.energy_scan_parameters["edge"] = edge diff --git a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py index 7c2fa81a63..da0d986258 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py @@ -59,6 +59,7 @@ def __init__(self, name): self.lims = None self.spectrum_info_dict = {} self.default_integration_time = None + self.cpos = None def init(self): """Initialisation""" @@ -76,8 +77,9 @@ def start_spectrum( archive_dir=None, session_id=None, blsample_id=None, + cpos=None, ): - """Start the procedure. Called by the queu_model. + """Start the procedure. Called by the queue_model. Args: integration_time (float): Inregration time [s]. @@ -87,6 +89,7 @@ def start_spectrum( session_id (int): Session ID number (from ISpyB) blsample_id (int): Sample ID number (from ISpyB) """ + self.cpos = cpos self.spectrum_info_dict = {"sessionId": session_id, "blSampleId": blsample_id} integration_time = integration_time or self.default_integration_time self.spectrum_info_dict["exposureTime"] = integration_time diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index f0a1995e33..111542ccf5 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -1055,6 +1055,7 @@ def __init__(self, sample=None, path_template=None, cpos=None): self.comments = None self.set_requires_centring(True) self.centred_position = cpos + self.shape = None if not sample: self.sample = Sample() @@ -1160,6 +1161,7 @@ def __init__(self, sample=None, path_template=None, cpos=None): self.set_requires_centring(True) self.centred_position = cpos self.adjust_transmission = True + self.shape = None if not sample: self.sample = Sample() diff --git a/mxcubecore/queue_entry/energy_scan.py b/mxcubecore/queue_entry/energy_scan.py index 9cff316472..8ea2ed7144 100644 --- a/mxcubecore/queue_entry/energy_scan.py +++ b/mxcubecore/queue_entry/energy_scan.py @@ -55,6 +55,10 @@ def execute(self): energy_scan = self.get_data_model() self.get_view().setText(1, "Starting energy scan") + if energy_scan.shape is not None: + point = HWR.beamline.sample_view.get_shape(energy_scan.shape) + energy_scan.centred_position = point.get_centred_position() + sample_model = self.get_data_model().get_sample_node() sample_lims_id = sample_model.lims_id @@ -71,6 +75,7 @@ def execute(self): energy_scan.path_template.get_prefix(), HWR.beamline.session.session_id, sample_lims_id, + cpos=energy_scan.centred_position, ) HWR.beamline.energy_scan.ready_event.wait() diff --git a/mxcubecore/queue_entry/xrf_spectrum.py b/mxcubecore/queue_entry/xrf_spectrum.py index 8666b7561c..30588aa129 100644 --- a/mxcubecore/queue_entry/xrf_spectrum.py +++ b/mxcubecore/queue_entry/xrf_spectrum.py @@ -54,11 +54,12 @@ def __setstate__(self, d): def execute(self): """Execute""" super().execute() - if HWR.beamline.xrf_spectrum is not None: xrf_spectrum = self.get_data_model() + if xrf_spectrum.shape is not None: + point = HWR.beamline.sample_view.get_shape(xrf_spectrum.shape) + xrf_spectrum.centred_position = point.get_centred_position() self.get_view().setText(1, "Starting xrf spectrum") - path_template = xrf_spectrum.path_template HWR.beamline.xrf_spectrum.start_spectrum( integration_time=xrf_spectrum.count_time, @@ -67,6 +68,7 @@ def execute(self): prefix=f"{path_template.get_prefix()}_{path_template.run_number}", session_id=HWR.beamline.session.session_id, blsample_id=xrf_spectrum._node_id, + cpos=xrf_spectrum.centred_position, ) HWR.beamline.xrf_spectrum._ready_event.wait() HWR.beamline.xrf_spectrum._ready_event.clear() From 158dda076c0f588f3e5462362b9d8e6d639963da Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 19 Aug 2024 17:08:37 +0000 Subject: [PATCH 004/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b8170e5df7..7929e4890c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.136.0" +version = "1.137.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From c4e4d80c7244d917c8141762adaa482636f68bc4 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 14 Aug 2024 15:08:16 +0200 Subject: [PATCH 005/172] Fixed calls to super class for objects that used to use Device or Equipment --- deprecated/HardwareObjects/Mar225.py | 2 +- deprecated/HardwareObjects/NamedState.py | 2 +- deprecated/HardwareObjects/SpecMotor.py | 6 +++--- deprecated/HardwareObjects/SpecShell.py | 2 +- deprecated/HardwareObjects/mockup/MachInfoMockup.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBABackLight.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py | 2 +- mxcubecore/HardwareObjects/ALBA/ALBATransmission.py | 2 +- mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py | 2 +- mxcubecore/HardwareObjects/BeamInfo.py | 2 +- mxcubecore/HardwareObjects/CatsMaint.py | 2 +- mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py | 2 +- mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py | 2 +- mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py | 2 +- mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py | 2 +- mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py | 2 +- mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py | 2 +- mxcubecore/HardwareObjects/ESRF/BlissTurret.py | 2 +- mxcubecore/HardwareObjects/ESRF/BlissVolpi.py | 2 +- mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID30Cryo.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID30Light.py | 2 +- mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py | 2 +- mxcubecore/HardwareObjects/FlexHCDMaintenance.py | 2 +- mxcubecore/HardwareObjects/Grob.py | 2 +- mxcubecore/HardwareObjects/GrobMotor.py | 2 +- mxcubecore/HardwareObjects/GrobSampleChanger.py | 2 +- mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py | 2 +- mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py | 2 +- mxcubecore/HardwareObjects/Mar225.py | 2 +- mxcubecore/HardwareObjects/MicrodiffInOut.py | 2 +- mxcubecore/HardwareObjects/MiniDiff.py | 2 +- mxcubecore/HardwareObjects/MotorWPositions.py | 2 +- mxcubecore/HardwareObjects/Q315dist.py | 2 +- mxcubecore/HardwareObjects/RobodiffFShut.py | 2 +- mxcubecore/HardwareObjects/RobodiffLight.py | 2 +- mxcubecore/HardwareObjects/RobodiffMotor.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX1/PX1BeamInfo.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py | 2 +- mxcubecore/HardwareObjects/SpecMotor.py | 6 +++--- mxcubecore/HardwareObjects/SpecShell.py | 2 +- mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py | 2 +- mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py | 2 +- 60 files changed, 64 insertions(+), 64 deletions(-) diff --git a/deprecated/HardwareObjects/Mar225.py b/deprecated/HardwareObjects/Mar225.py index 5c308fd18f..67dc6bc5ec 100644 --- a/deprecated/HardwareObjects/Mar225.py +++ b/deprecated/HardwareObjects/Mar225.py @@ -3,7 +3,7 @@ class Mar225(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): pass diff --git a/deprecated/HardwareObjects/NamedState.py b/deprecated/HardwareObjects/NamedState.py index 27a23d88d8..b5360c0aff 100644 --- a/deprecated/HardwareObjects/NamedState.py +++ b/deprecated/HardwareObjects/NamedState.py @@ -25,7 +25,7 @@ class NamedState(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.stateList = [] def _init(self): diff --git a/deprecated/HardwareObjects/SpecMotor.py b/deprecated/HardwareObjects/SpecMotor.py index 163738c322..1717d5a937 100644 --- a/deprecated/HardwareObjects/SpecMotor.py +++ b/deprecated/HardwareObjects/SpecMotor.py @@ -2,11 +2,11 @@ from SpecClient_gevent.SpecMotor import SpecMotorA -class SpecMotor(Device, SpecMotorA): +class SpecMotor(HardwareObject, SpecMotorA): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) SpecMotorA.__init__(self) def _init(self): @@ -53,7 +53,7 @@ def get_motor_mnemonic(self): class SpecVersionMotor(SpecMotor): def __init__(self, specversion, specname, username): - Device.__init__(self, specname) + super().__init__(specname) self.specversion = specversion self.specname = specname self.username = username diff --git a/deprecated/HardwareObjects/SpecShell.py b/deprecated/HardwareObjects/SpecShell.py index 5cbf355162..0d73ebb1be 100644 --- a/deprecated/HardwareObjects/SpecShell.py +++ b/deprecated/HardwareObjects/SpecShell.py @@ -30,7 +30,7 @@ def update(self, value): class SpecShell(HardwareObject): def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.isSpecReady = False def init(self): diff --git a/deprecated/HardwareObjects/mockup/MachInfoMockup.py b/deprecated/HardwareObjects/mockup/MachInfoMockup.py index f228d636c5..95242bea29 100644 --- a/deprecated/HardwareObjects/mockup/MachInfoMockup.py +++ b/deprecated/HardwareObjects/mockup/MachInfoMockup.py @@ -46,7 +46,7 @@ class MachInfoMockup(HardwareObject): default_topup_remaining = 70 # seconds def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.current = self.default_current self.lifetime = self.default_lifetime diff --git a/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py b/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py index 4f0c812e2a..c426dfabc1 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py @@ -7,7 +7,7 @@ class ALBABackLight(HardwareObject): def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) self.limits = [None, None] self.state = None self.current_level = None diff --git a/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py b/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py index 6c462b69e0..25a047bdc2 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py @@ -32,7 +32,7 @@ def __init__(self, *args): """ Descrip. : """ - Equipment.__init__(self, *args) + super().__init__(*args) self.aperture_hwobj = None self.slits_hwobj = None diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py b/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py index 332de9e3d0..3445cc069e 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py @@ -6,7 +6,7 @@ class ALBAEnergy(HardwareObject): def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) self.energy_position = None self.wavelength_position = None diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py b/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py index 1c03f9ba64..e66d3489c3 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py @@ -5,7 +5,7 @@ class ALBAFrontLight(HardwareObject): def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) self.limits = [None, None] self.state = None diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py b/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py index e438c4223f..61be06f712 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py @@ -78,7 +78,7 @@ class ALBAMachineInfo(HardwareObject): """ def __init__(self, name): - Equipment.__init__(self, name) + super().__init__(name) self.logger = logging.getLogger("HWR MachineInfo") self.logger.info("__init__()") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py b/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py index 9f54f9df6c..9b8df1e766 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py @@ -5,7 +5,7 @@ class ALBASupervisor(HardwareObject): def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) def init(self): self.state_chan = self.get_channel_object("state") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBATransmission.py b/mxcubecore/HardwareObjects/ALBA/ALBATransmission.py index eb859f7716..37c86e1e55 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBATransmission.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBATransmission.py @@ -4,7 +4,7 @@ class ALBATransmission(HardwareObject): def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) self.transmission = None def init(self): diff --git a/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py b/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py index ff361a88bd..742aa44f67 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py @@ -78,7 +78,7 @@ class XalocMachineInfo(HardwareObject): """ def __init__(self, name): - Equipment.__init__(self, name) + super().__init__(name) """ Descript. : """ diff --git a/mxcubecore/HardwareObjects/BeamInfo.py b/mxcubecore/HardwareObjects/BeamInfo.py index 699419caf2..f4c1f3dbf1 100644 --- a/mxcubecore/HardwareObjects/BeamInfo.py +++ b/mxcubecore/HardwareObjects/BeamInfo.py @@ -33,7 +33,7 @@ def __init__(self, *args): """ Descrip. : """ - Equipment.__init__(self, *args) + super().__init__(*args) self.aperture_hwobj = None self.beam_definer = None diff --git a/mxcubecore/HardwareObjects/CatsMaint.py b/mxcubecore/HardwareObjects/CatsMaint.py index f7574715c2..9d1fdc3644 100644 --- a/mxcubecore/HardwareObjects/CatsMaint.py +++ b/mxcubecore/HardwareObjects/CatsMaint.py @@ -58,7 +58,7 @@ class CatsMaint(HardwareObject): """ def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) self._state = None self._running = None diff --git a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py index c04abea91c..4f7d00f8a8 100644 --- a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py +++ b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py @@ -43,7 +43,7 @@ class DigitalZoomMotor(AbstractMotor, Device): def __init__(self, name): AbstractMotor.__init__(self, name) - Device.__init__(self, name) + super().__init__(name) self.camera = None def init(self): diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py index f1e6eb4831..bf06c9213e 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py @@ -28,7 +28,7 @@ class EMBLBeamstop(Device, AbstractMotor): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.distance = None self.default_size = None diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py b/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py index c3073b8469..990c46b89b 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py @@ -40,7 +40,7 @@ class EMBLDoorInterlock(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.use_door_interlock = None self.door_interlock_state = None diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py b/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py index 853b31bf54..e1d3940c75 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py @@ -37,7 +37,7 @@ class EMBLImageTracking(HardwareObject): """ def __init__(self, *args): - Device.__init__(self, *args) + super().__init__(*args) self.state = None self.state_dict = {"image_tracking": False, "filter_frames": False} diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py b/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py index 117b5c41e4..cc8c27e286 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py @@ -97,7 +97,7 @@ class EMBLMotorsGroup(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.server_address = None self.group_address = None self.motors_list = None diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py b/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py index e6688ebf78..88807f2968 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py @@ -13,7 +13,7 @@ class EMBLPPUControl(HardwareObject): """ def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.all_status = None self.status_result = None diff --git a/mxcubecore/HardwareObjects/ESRF/BlissTurret.py b/mxcubecore/HardwareObjects/ESRF/BlissTurret.py index ec0f42d9d1..916a95f5e6 100644 --- a/mxcubecore/HardwareObjects/ESRF/BlissTurret.py +++ b/mxcubecore/HardwareObjects/ESRF/BlissTurret.py @@ -4,7 +4,7 @@ class BlissTurret(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): self.username = self.turret_name diff --git a/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py b/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py index e4f086fe63..808256b400 100644 --- a/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py +++ b/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py @@ -5,7 +5,7 @@ class BlissVolpi(HardwareObject): def __init__(self, name): # AbstractMotor.__init__(self, name) - Device.__init__(self, name) + super().__init__(name) def init(self): self.username = self.volpi_name diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py b/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py index 039b9e15c4..3a3b736e4c 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py @@ -8,7 +8,7 @@ class ESRFCryoMon(HardwareObject): def __init__(self, *args, **kwargs): - Device.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) self.n2level = None self.temp = None diff --git a/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py b/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py index 241d96f694..3dcb68264f 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py @@ -25,7 +25,7 @@ class BeamInfo(HardwareObject): def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.beam_size_slits = [9999, 9999] self.beam_size_aperture = [9999, 9999] diff --git a/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py index 3686e4cb71..d8d1e5a658 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py @@ -10,7 +10,7 @@ class ID23PhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) self.threshold = [] def init(self): diff --git a/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py index 4b5e44e019..b6ea643135 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py @@ -10,7 +10,7 @@ class ID29PhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): self.counter = self.get_object_by_role("counter") diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py index f6a481d5f3..b9e5883f33 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py @@ -6,7 +6,7 @@ class ID30A3PhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): controller = self.get_object_by_role("controller") diff --git a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py b/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py index 50e1dbf737..c4cd41bf0b 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py @@ -8,7 +8,7 @@ class ID30Cryo(HardwareObject): states = {0: "out", 1: "in"} def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): controller = self.get_object_by_role("controller") diff --git a/mxcubecore/HardwareObjects/ESRF/ID30Light.py b/mxcubecore/HardwareObjects/ESRF/ID30Light.py index eb94ddf7b0..121995fea9 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30Light.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30Light.py @@ -10,7 +10,7 @@ class ID30Light(Device, AbstractMotor): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): controller = self.get_object_by_role("controller") diff --git a/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py index 0cc169ee76..86302395f9 100644 --- a/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py @@ -8,7 +8,7 @@ class TangoKeithleyPhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): self.get_object_by_role("controller") diff --git a/mxcubecore/HardwareObjects/FlexHCDMaintenance.py b/mxcubecore/HardwareObjects/FlexHCDMaintenance.py index 3f75612d1d..2d2709dfcd 100644 --- a/mxcubecore/HardwareObjects/FlexHCDMaintenance.py +++ b/mxcubecore/HardwareObjects/FlexHCDMaintenance.py @@ -34,7 +34,7 @@ class FlexHCDMaintenance(HardwareObject): """ def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): self._sc = self.get_object_by_role("sample_changer") diff --git a/mxcubecore/HardwareObjects/Grob.py b/mxcubecore/HardwareObjects/Grob.py index 3f93385ded..db48bef7c4 100644 --- a/mxcubecore/HardwareObjects/Grob.py +++ b/mxcubecore/HardwareObjects/Grob.py @@ -4,7 +4,7 @@ class Grob(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.SampleTableMotor = grob_control.SampleTableMotor self.GonioMotor = grob_control.GonioMotor self.SampleMotor = grob_control.SampleMotor diff --git a/mxcubecore/HardwareObjects/GrobMotor.py b/mxcubecore/HardwareObjects/GrobMotor.py index f881a7106e..bbe2a904b1 100644 --- a/mxcubecore/HardwareObjects/GrobMotor.py +++ b/mxcubecore/HardwareObjects/GrobMotor.py @@ -8,7 +8,7 @@ class GrobMotor(Device, AbstractMotor): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): self.motorState = GrobMotor.NOTINITIALIZED diff --git a/mxcubecore/HardwareObjects/GrobSampleChanger.py b/mxcubecore/HardwareObjects/GrobSampleChanger.py index eb78176ade..d91df18876 100644 --- a/mxcubecore/HardwareObjects/GrobSampleChanger.py +++ b/mxcubecore/HardwareObjects/GrobSampleChanger.py @@ -18,7 +18,7 @@ class GrobSampleChanger(HardwareObject): ALWAYS_ALLOW_MOUNTING = True def __init__(self, *args, **kwargs): - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): self._procedure = "" diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py index 9c56abe386..1a3c0ee69a 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py @@ -39,7 +39,7 @@ def __init__(self, *args): """ Descrip. : """ - Equipment.__init__(self, *args) + super().__init__(*args) self.device = None self.file_suffix = None diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py index e20be55602..4ba7125066 100755 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py @@ -28,7 +28,7 @@ class BIOMAXMD3Camera(HardwareObject): } def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.set_is_ready(True) def init(self): diff --git a/mxcubecore/HardwareObjects/Mar225.py b/mxcubecore/HardwareObjects/Mar225.py index 5c308fd18f..67dc6bc5ec 100644 --- a/mxcubecore/HardwareObjects/Mar225.py +++ b/mxcubecore/HardwareObjects/Mar225.py @@ -3,7 +3,7 @@ class Mar225(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): pass diff --git a/mxcubecore/HardwareObjects/MicrodiffInOut.py b/mxcubecore/HardwareObjects/MicrodiffInOut.py index f89ba0719e..2c42ae4896 100644 --- a/mxcubecore/HardwareObjects/MicrodiffInOut.py +++ b/mxcubecore/HardwareObjects/MicrodiffInOut.py @@ -19,7 +19,7 @@ class MicrodiffInOut(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.actuatorState = "unknown" self.username = "unknown" # default timeout - 5 sec diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 437a6b06c1..3ae5e7fe92 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -108,7 +108,7 @@ class MiniDiff(HardwareObject): # MOVE_TO_BEAM_MODE = "Move to Beam" def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) qmo.CentredPosition.set_diffractometer_motor_names( "phi", diff --git a/mxcubecore/HardwareObjects/MotorWPositions.py b/mxcubecore/HardwareObjects/MotorWPositions.py index 75ec932c77..db5bf0ce28 100644 --- a/mxcubecore/HardwareObjects/MotorWPositions.py +++ b/mxcubecore/HardwareObjects/MotorWPositions.py @@ -52,7 +52,7 @@ class MotorWPositions(AbstractMotor, Device): def __init__(self, name): AbstractMotor.__init__(self, name) - Device.__init__(self, name) + super().__init__(name) self.predefined_positions = {} self.motor = None self.delta = 0.001 diff --git a/mxcubecore/HardwareObjects/Q315dist.py b/mxcubecore/HardwareObjects/Q315dist.py index 0c6f465446..26755a087e 100644 --- a/mxcubecore/HardwareObjects/Q315dist.py +++ b/mxcubecore/HardwareObjects/Q315dist.py @@ -7,7 +7,7 @@ def _init(self): self.connect("equipmentReady", self.equipmentReady) self.connect("equipmentNotReady", self.equipmentNotReady) - return BaseHardwareObjects.Equipment._init(self) + return BaseHardwareObjects.super()._init() def init(self): self.detm = self.get_deviceby_role("detm") diff --git a/mxcubecore/HardwareObjects/RobodiffFShut.py b/mxcubecore/HardwareObjects/RobodiffFShut.py index b307a374ac..c84bbf36e5 100644 --- a/mxcubecore/HardwareObjects/RobodiffFShut.py +++ b/mxcubecore/HardwareObjects/RobodiffFShut.py @@ -3,7 +3,7 @@ class RobodiffFShut(HardwareObject): def __init__(self, name): - Equipment.__init__(self, name) + super().__init__(name) def init(self): self.robodiff = self.get_object_by_role("robot") diff --git a/mxcubecore/HardwareObjects/RobodiffLight.py b/mxcubecore/HardwareObjects/RobodiffLight.py index 7bf30515f0..fe248b5e60 100644 --- a/mxcubecore/HardwareObjects/RobodiffLight.py +++ b/mxcubecore/HardwareObjects/RobodiffLight.py @@ -10,7 +10,7 @@ class RobodiffLight(Device, AbstractMotor): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): controller = self.get_object_by_role("controller") diff --git a/mxcubecore/HardwareObjects/RobodiffMotor.py b/mxcubecore/HardwareObjects/RobodiffMotor.py index e94089d4ce..38ac9b91b8 100644 --- a/mxcubecore/HardwareObjects/RobodiffMotor.py +++ b/mxcubecore/HardwareObjects/RobodiffMotor.py @@ -7,7 +7,7 @@ class RobodiffMotor(HardwareObject): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.__initialized = False def init(self): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1BeamInfo.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1BeamInfo.py index 44d24a7d18..369b3d4303 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1BeamInfo.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1BeamInfo.py @@ -25,7 +25,7 @@ class PX1BeamInfo(HardwareObject): def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.beam_position = [None, None] self.beam_size = [100, 100] diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py index 1e1aa48e45..1617bc6a43 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py @@ -46,7 +46,7 @@ class PX1EnergyScan(AbstractEnergyScan, Equipment): def __init__(self, name): AbstractEnergyScan.__init__(self) - Equipment.__init__(self, name) + super().__init__(name) self.scanning = False self.stopping = False diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py index d1bafb681b..e190ebac01 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py @@ -72,7 +72,7 @@ def tostring(state): class PX1Environment(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.auth = None self.device = None diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py index c5324702ba..3afb38f633 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py @@ -51,7 +51,7 @@ def _init(self): self.currentDistance = self.distance_chan.get_value() self._nominal_value = self.resolution_chan.get_value() - return Equipment._init(self) + return super()._init() def connect_notify(self, signal): if signal == "stateChanged": diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py index 47f507c0d7..7a0da6b2b4 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py @@ -8,7 +8,7 @@ class PX1TangoLight(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.currentState = "unknown" def init(self): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py index c1b6363b17..034d9a0f97 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py @@ -21,7 +21,7 @@ class PX2Attenuator(HardwareObject): } def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.labels = [] self.attno = 0 diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py index 5071fa89b8..3bf732fc66 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py @@ -36,7 +36,7 @@ class PX2BeamInfo(HardwareObject): def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.beam_position = [328, 220] # [None, None] self.beam_size = [0.010, 0.005] # [None, None] diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py index 411db3ba01..4ada5bb2cb 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py @@ -36,7 +36,7 @@ class SOLEILCatsMaint(HardwareObject): def __init__(self, *args, **kwargs): logging.info("CatsMaint: __init__") - Equipment.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) def init(self): logging.info("CatsMaint: init") diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py index 6c1e90508f..2a59362d20 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py @@ -5,7 +5,7 @@ class SOLEILFlux(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) def init(self): self.flux_channel = self.get_channel_object("flux") diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py index 49187d2da5..a7b3df9ff2 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py @@ -13,7 +13,7 @@ class SOLEILPss(HardwareObject): READ_CMD, READ_OUT = (0, 1) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.wagoState = "unknown" self.__oldValue = None diff --git a/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py b/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py index 446d3c94a1..c4c1ae3c8f 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py +++ b/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py @@ -38,7 +38,7 @@ def __init__(self, name): # State values as expected by Motor bricks - Device.__init__(self, name) + super().__init__(name) self.GUIstep = 0.1 self.motor_states = MotorStates() diff --git a/mxcubecore/HardwareObjects/SpecMotor.py b/mxcubecore/HardwareObjects/SpecMotor.py index 163738c322..1717d5a937 100644 --- a/mxcubecore/HardwareObjects/SpecMotor.py +++ b/mxcubecore/HardwareObjects/SpecMotor.py @@ -2,11 +2,11 @@ from SpecClient_gevent.SpecMotor import SpecMotorA -class SpecMotor(Device, SpecMotorA): +class SpecMotor(HardwareObject, SpecMotorA): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) SpecMotorA.__init__(self) def _init(self): @@ -53,7 +53,7 @@ def get_motor_mnemonic(self): class SpecVersionMotor(SpecMotor): def __init__(self, specversion, specname, username): - Device.__init__(self, specname) + super().__init__(specname) self.specversion = specversion self.specname = specname self.username = username diff --git a/mxcubecore/HardwareObjects/SpecShell.py b/mxcubecore/HardwareObjects/SpecShell.py index 5cdde91836..c4fe5c876f 100644 --- a/mxcubecore/HardwareObjects/SpecShell.py +++ b/mxcubecore/HardwareObjects/SpecShell.py @@ -30,7 +30,7 @@ def update(self, value): class SpecShell(HardwareObject): def __init__(self, *args): - Equipment.__init__(self, *args) + super().__init__(*args) self.isSpecReady = False def init(self): diff --git a/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py b/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py index 64c931e1a9..d4c4519024 100644 --- a/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py @@ -38,7 +38,7 @@ def __init__(self, *args): """ Descrip. : """ - Equipment.__init__(self, *args) + super().__init__(*args) self.device = None self.file_suffix = None diff --git a/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py b/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py index fff31deb3c..1f0ce4db13 100755 --- a/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py @@ -18,7 +18,7 @@ class MicrodiffInOutMockup(HardwareObject): def __init__(self, name): - Device.__init__(self, name) + super().__init__(name) self.actuatorState = "unknown" self.username = "unknown" # default timeout - 3 sec From ec6156d12996cbf9a71601897131aaf645827b69 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 20 Aug 2024 13:28:13 +0000 Subject: [PATCH 006/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7929e4890c..3bb79e0159 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.137.0" +version = "1.138.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From f0faff78ba9b126f8929ede4787db19c6b5ea898 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Tue, 20 Aug 2024 17:45:11 +0200 Subject: [PATCH 007/172] Beam refactoring - definer and size (former Aperture as NState) (#919) * Aperture from AbstractNState implementation. * Change BeamMockup accordingly. * Start using HO from beam_definer branch. * Fix bug. * Black * Add _definer_type property.Fix typo for elliptical.Documentation. * Add beam definer (as started in beam_definer branch). * Add beam size methods.Minor cleanup * beam_test change * black * black * Again? * Size is in mm * Black again. --------- Co-authored-by: Antonia Beteva --- mxcubecore/HardwareObjects/XMLRPCServer.py | 55 ++-- .../HardwareObjects/abstract/AbstractBeam.py | 96 ++++--- .../HardwareObjects/mockup/ApertureMockup.py | 133 +++++---- .../mockup/BeamDefinerMockup.py | 124 +++++++++ .../HardwareObjects/mockup/BeamMockup.py | 262 ++++++++++++++---- .../HardwareObjects/mockup/MotorMockupBis.py | 63 +++++ .../configuration/mockup/beam-mockup.xml | 3 +- .../configuration/mockup/beam_definer.xml | 7 + .../configuration/mockup/beam_size_hor.xml | 8 + .../configuration/mockup/beam_size_ver.xml | 8 + .../mockup/diffractometer-mockup.xml | 1 + test/pytest/TestAbstractNStateBase.py | 4 +- test/pytest/test_aperture.py | 64 +++++ test/pytest/test_beam.py | 211 ++++++++++---- test/pytest/test_beam_definer.py | 44 +++ 15 files changed, 881 insertions(+), 202 deletions(-) create mode 100644 mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py create mode 100644 mxcubecore/HardwareObjects/mockup/MotorMockupBis.py create mode 100644 mxcubecore/configuration/mockup/beam_definer.xml create mode 100644 mxcubecore/configuration/mockup/beam_size_hor.xml create mode 100644 mxcubecore/configuration/mockup/beam_size_ver.xml create mode 100644 test/pytest/test_aperture.py create mode 100644 test/pytest/test_beam_definer.py diff --git a/mxcubecore/HardwareObjects/XMLRPCServer.py b/mxcubecore/HardwareObjects/XMLRPCServer.py index fbbc32ead3..6da1b41d42 100644 --- a/mxcubecore/HardwareObjects/XMLRPCServer.py +++ b/mxcubecore/HardwareObjects/XMLRPCServer.py @@ -12,15 +12,15 @@ import inspect import pkgutil import types -import gevent import socket import time +import xml import json import atexit import jsonpickle -import xml from functools import reduce +import gevent from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR @@ -57,7 +57,7 @@ def __init__(self, name): self.xmlrpc_prefixes = set() self.current_entry_task = None self.host = None - self.use_token = True + self.use_token = None atexit.register(self.close) self.gphl_workflow_status = None @@ -77,7 +77,7 @@ def init(self): self.host = host self.port = self.get_property("port") - self.use_token = self.get_property("use_token", True) + self.use_token = self.get_property("use_token", False) try: self.open() @@ -141,6 +141,9 @@ def open(self): self._server.register_function(self.cryo_temperature) self._server.register_function(self.flux) self._server.register_function(self.check_for_beam) + self._server.register_function(self.set_beam_size) + self._server.register_function(self.get_beam_size) + self._server.register_function(self.get_available_beam_size) self._server.register_function(self.set_aperture) self._server.register_function(self.get_aperture) self._server.register_function(self.get_aperture_list) @@ -190,8 +193,7 @@ def anneal(self, time): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return True + return True def _add_to_queue(self, task, set_on=True): """ @@ -220,8 +222,7 @@ def _add_to_queue(self, task, set_on=True): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return True + return True def start_queue(self): """ @@ -235,8 +236,7 @@ def start_queue(self): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return True + return True def log_message(self, message, level="info"): """ @@ -285,8 +285,7 @@ def _model_add_child(self, parent_id, child): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return node_id + return node_id def _model_get_node(self, node_id): """ @@ -298,8 +297,7 @@ def _model_get_node(self, node_id): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return node + return node def queue_execute_entry_with_id(self, node_id, use_async=False): """ @@ -320,8 +318,7 @@ def queue_execute_entry_with_id(self, node_id, use_async=False): except Exception as ex: logging.getLogger("HWR").exception(str(ex)) raise - else: - return True + return True def queue_set_workflow_lims_id(self, node_id, lims_id): """ @@ -512,6 +509,32 @@ def flux(self): def check_for_beam(self): return HWR.beamline.flux.is_beam() + def set_beam_size(self, size): + """Set the beam size. + Args: + size (list): Width, heigth or + (str): Size label. + """ + HWR.beamline.beam.set_value(size) + return True + + def get_beam_size(self): + """Get the beam size [um], its shape and label. + Returns: + (tuple): (width, heigth, shape, label), with types + (float, float, str, str) + """ + return HWR.beamline.beam.get_value_xml() + + def get_available_beam_size(self): + """Get the available predefined beam sizes. + Returns: + (dict): Dictionary wiith list of avaiable beam size labels + and the corresponding size (width,height) tuples. + {"label": [str, str, ...], "size": [(w,h), (w,h), ...]} + """ + return HWR.beamline.beam.get_defined_beam_size() + def set_aperture(self, pos_name): HWR.beamline.beam.set_value(pos_name) return True diff --git a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py index 753693b2ef..917895b44a 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py @@ -19,19 +19,20 @@ # along with MXCuBE. If not, see . """ -AbstracBeam class - methods to define the size and shape of the beam, its presence. +AbstracBeam class - methods to define the size and shape of the beam. emits: - beamSizeChanged (self._beam_width, self._beam_height) - beamInfoChanged (self._beam_info_dict.copy()) """ -__copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ +__copyright__ = """ Copyright © by MXCuBE Collaboration """ __license__ = "LGPLv3+" import abc import sys +from warnings import warn from enum import Enum, unique from mxcubecore.BaseHardwareObjects import HardwareObject @@ -43,7 +44,7 @@ class BeamShape(Enum): UNKNOWN = "unknown" RECTANGULAR = "rectangular" - ELIPTICAL = "ellipse" + ELLIPTICAL = "ellipse" class AbstractBeam(HardwareObject): @@ -57,6 +58,7 @@ def __init__(self, name): self._aperture = None self._slits = None self._definer = None + self._definer_type = None self._beam_size_dict = { "aperture": [sys.float_info.max, sys.float_info.max], @@ -68,7 +70,7 @@ def __init__(self, name): self._beam_shape = BeamShape.UNKNOWN self._beam_label = None self._beam_divergence = (None, None) - self._beam_position_on_screen = [None, None] # TODO move to sample_view + self._beam_position_on_screen = [None, None] self._beam_info_dict = { "size_x": self._beam_width, @@ -85,7 +87,8 @@ def init(self): _divergence_vertical = self.get_property("beam_divergence_vertical") _divergence_horizontal = self.get_property("beam_divergence_horizontal") self._beam_divergence = (_divergence_horizontal, _divergence_vertical) - self._beam_position_on_screen = (0, 0) + self._beam_position_on_screen = [0, 0] + self._definer_type = self.get_property("definer_type") @property def aperture(self): @@ -113,15 +116,13 @@ def get_beam_divergence(self): Returns: (tuple): Beam divergence (horizontal, vertical) [μm] """ - if self._definer: - return self._definer.get_divergence() return self._beam_divergence def get_available_size(self): - """Get the available predefined beam definers configuration. + """Get the available beam definers configuration. Returns: (dict): Dictionary {"type": (list), "values": (list)}, where - "type": the definer type + "type": the definer type ("aperture", "slits","definer") "values": List of available beam size difinitions, according to the "type". Raises: @@ -129,6 +130,17 @@ def get_available_size(self): """ raise NotImplementedError + def get_defined_beam_size(self): + """Get the predefined beam labels and size. + Returns: + (dict): Dictionary wiith list of avaiable beam size labels + and the corresponding size (width,height) tuples. + {"label": [str, str, ...], "size": [(w,h), (w,h), ...]} + Raises: + NotImplementedError + """ + raise NotImplementedError + def get_beam_shape(self): """ Returns: @@ -145,6 +157,16 @@ def get_beam_size(self): self.evaluate_beam_info() return self._beam_width, self._beam_height + def set_value(self, size=None): + """Set the beam size. + Args: + size (list): Width, heigth [um] or + (str): Aperture or definer name. + Raises: + NotImplementedError + """ + raise NotImplementedError + def set_beam_size_shape(self, beam_width, beam_height, beam_shape): """ Sets beam size and shape @@ -153,10 +175,15 @@ def set_beam_size_shape(self, beam_width, beam_height, beam_shape): beam_height (float): requested beam height in microns beam_shape (BeamShape enum): requested beam shape """ + warn( + "set_beam_size_shape is deprecated. Use set_value() instead", + DeprecationWarning, + ) + if beam_shape == BeamShape.RECTANGULAR: self._slits.set_horizontal_gap(beam_width) self._slits.set_vertical_gap(beam_height) - elif beam_shape == BeamShape.ELIPTICAL: + elif beam_shape == BeamShape.ELLIPTICAL: self._aperture.set_diameter_size(beam_width) def get_beam_position_on_screen(self): @@ -164,7 +191,7 @@ def get_beam_position_on_screen(self): Returns: (tuple): Position (x, y) [pixel] """ - # TODO move this method to AbstractSampleView + # (TODO) move this method to AbstractSampleView return self._beam_position_on_screen def set_beam_position_on_screen(self, beam_x_y): @@ -183,30 +210,37 @@ def get_beam_info_dict(self): def evaluate_beam_info(self): """ - Method called if aperture, slits or focusing has been changed - Returns: dictionary, {size_x: 0.1, size_y: 0.1, shape: BeamShape enum} + Method called if aperture, slits or focusing has been changed. + Evaluates which of the beam size defining devices determins the size. + Returns: + (dict): Beam info dictionary (dict), type of the definer (str). + {size_x: float, size_y: float, + shape: BeamShape enum, label: str}, """ + _shape = BeamShape.UNKNOWN + _size = min(self._beam_size_dict.values()) + key = [k for k, v in self._beam_size_dict.items() if v == _size] - size_x = min( - self._beam_size_dict["aperture"][0], self._beam_size_dict["slits"][0] - ) - size_y = min( - self._beam_size_dict["aperture"][1], self._beam_size_dict["slits"][1] - ) - - self._beam_width = size_x - self._beam_height = size_y - - if tuple(self._beam_size_dict["aperture"]) < tuple( - self._beam_size_dict["slits"] - ): - self._beam_shape = BeamShape.ELIPTICAL + if len(key) == 1: + _label = key[0] else: - self._beam_shape = BeamShape.RECTANGULAR + if self._definer_type in key: + _label = self._definer_type + else: + _label = "UNKNOWN" - self._beam_info_dict["size_x"] = size_x - self._beam_info_dict["size_y"] = size_y - self._beam_info_dict["shape"] = self._beam_shape + if _label == "slits": + _shape = BeamShape.RECTANGULAR + else: + _shape = BeamShape.ELLIPTICAL + + self._beam_width = _size[0] + self._beam_height = _size[1] + self._beam_shape = _shape + self._beam_info_dict["size_x"] = _size[0] + self._beam_info_dict["size_y"] = _size[1] + self._beam_info_dict["shape"] = _shape + self._beam_info_dict["label"] = _label return self._beam_info_dict diff --git a/mxcubecore/HardwareObjects/mockup/ApertureMockup.py b/mxcubecore/HardwareObjects/mockup/ApertureMockup.py index 940f595177..ac21240fb0 100644 --- a/mxcubecore/HardwareObjects/mockup/ApertureMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ApertureMockup.py @@ -17,68 +17,105 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import logging -from mxcubecore.HardwareObjects.abstract.AbstractAperture import ( - AbstractAperture, -) - - -__credits__ = ["MXCuBE collaboration"] -__license__ = "LGPLv3" - - """ -xml example: +Example xml_ configuration: + +.. code-block:: xml - - ["BEAM", "OFF", "PARK"] - [5, 10, 20, 30, 50, 100] - + + aperture + {"A5": (5, 0.11), A10": (10, 0.15), "A20": (20, 0.3), "A30": (30, 0.63), "A50": (50, 0.9), "A100": (100, 1)} + ["BEAM", "OFF", "PARK"] + """ +from enum import Enum +from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState +from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup -DEFAULT_POSITION_LIST = ("BEAM", "OFF", "PARK") -DEFAULT_DIAMETER_SIZE_LIST = (5, 10, 20, 30, 50, 100) +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" -class ApertureMockup(AbstractAperture): - def __init__(self, name): - AbstractAperture.__init__(self, name) +class ApertureMockup(AbstractNState, ActuatorMockup): + """Mockup file for aperture as Nstate actuator""" def init(self): - try: - self._diameter_size_list = eval(self.get_property("diameter_size_list")) - except Exception: - self._diameter_size_list = DEFAULT_DIAMETER_SIZE_LIST - logging.getLogger("HWR").error( - "Aperture: no diameter size list defined, using default list" - ) + super().init() + # check if we have values other that UKNOWN (no values in config) + if len(self.VALUES) == 1: + self._initialise_values() + self._initialise_inout() + self._nominal_value = self.VALUES.A10 - try: - self._position_list = eval(self.get_property("position_list")) - except Exception: - self._position_list = DEFAULT_POSITION_LIST - logging.getLogger("HWR").error( - "Aperture: no position list defined, using default list" - ) + def get_value(self): + return self._nominal_value - self.set_position_index(0) - self.set_diameter_index(0) + def _initialise_values(self): + """Initialise the ValueEnum if not in the config""" + values = {} + predefined_postions = (5, 10, 20, 30, 50, 100) + factors = (0.11, 0.15, 0.3, 0.63, 0.9, 1) + for _pos, _fac in zip(predefined_postions, factors): + values[f"A{_pos}"] = (_pos, _fac) + self.VALUES = Enum( + "ValueEnum", + dict(values, **{item.name: item.value for item in self.VALUES}), + ) - def set_in(self): - """ - Sets aperture in the beam - """ - self.set_position("BEAM") + def _initialise_inout(self): + """Add IN and OUT to the values Enum""" + values_dict = {"IN": "BEAM", "OUT": "OFF"} + values_dict.update({item.name: item.value for item in self.VALUES}) + self.VALUES = Enum("ValueEnum", values_dict) - def set_out(self): - """ - Removes aperture from the beam + def get_factor(self, label): + """Get the factor associated to a label. + Args: + (enum, str): label enum or name + Returns: + (float) or (tuple): Factor value """ - self.set_position("OFF") + if isinstance(label, str): + try: + return self.VALUES[label].value[1] + except (KeyError, ValueError, IndexError): + return 1.0 + try: + return label.value[1] + except (ValueError, IndexError): + return 1.0 - def is_out(self): + def get_size(self, label): + """Get the aperture size associated to a label. + Args: + (enum, str): label enum or name + Returns: + (float): Factor value + Raises: + RuntimeError: Unknown aperture size. """ + if isinstance(label, str): + try: + return float(self.VALUES[label].value[0]) + except (KeyError, ValueError, IndexError) as err: + raise RuntimeError("Unknown aperture size") from err + try: + return float(label.value[0]) + except (ValueError, IndexError) as err: + if self.inout_obj: + return None + raise RuntimeError("Unknown aperture size") from err + + def get_diameter_size_list(self): + """Get the list of values to be visible. Hide IN, OUT and UNKNOWN. Returns: - bool: True if aperture is in the beam, otherwise returns false + (list): List of availble aperture values (string). """ - return self._current_position_name != "BEAM" + values = [] + for value in self.VALUES: + _nam = value.name + + if _nam not in ["IN", "OUT", "UNKNOWN"]: + values.append(_nam) + + return values diff --git a/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py b/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py new file mode 100644 index 0000000000..24764ccbac --- /dev/null +++ b/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py @@ -0,0 +1,124 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +""" +BeamDefinerMockup class. +Two mock motors change the width and the heigth of the beam. +Example xml configuration: + +.. code-block:: xml + + + Beam Definer + + + {"50x50": (0.05, 0.05), "100x100": (0.1, 0.1), "20x5": (0.02, 0.005)} + 50x50 + +""" + +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + +import time +import random +from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState +from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup + + +class BeamDefinerMockup(AbstractNState, ActuatorMockup): + """BeamDefinerMockup class""" + + def __init__(self, *args): + super().__init__(*args) + self.beam_size_hor = None + self.beam_size_ver = None + + def init(self): + super().init() + self.beam_size_hor = self.get_object_by_role("beam_size_hor") + self.beam_size_ver = self.get_object_by_role("beam_size_ver") + + # set default value [mm] + self.beam_size_hor.set_value(0.1) + self.beam_size_ver.set_value(0.1) + + _default_name = self.get_property("default_size_name") + if self.get_value() == self.VALUES.UNKNOWN and _default_name: + # set default beam value + self._set_value(self.VALUES[_default_name]) + self.update_value() + + self.connect(self.beam_size_hor, "valueChanged", self.motors_changed) + self.connect(self.beam_size_ver, "valueChanged", self.motors_changed) + + def motors_changed(self, value): + """Emit valueChanged for the definer when motor position changed""" + print(value) + name = self.get_current_position_name() + self.emit("valueChanged", name) + + def get_value(self): + """Get the beam value. + Returns: + (Enum): The current position Enum. + """ + try: + return self.VALUES[self.get_current_position_name()] + except (ValueError, KeyError, TypeError): + return self.VALUES.UNKNOWN + + def get_current_position_name(self): + """Get the current beam size name. + Returns: + (str): Current beam size name. + """ + hor = self.beam_size_hor.get_value() + ver = self.beam_size_ver.get_value() + for val in self.VALUES: + if val.value == (hor, ver): + return val.name + return "UNKNOWN" + + def _set_value(self, value): + """Set the beam size. + Args: + value(str): name of the beam size to set. + """ + if isinstance(value, str): + size_x, size_y = self.VALUES[value].value + else: + size_x, size_y = value.value + self.beam_size_hor.set_value(float(size_x)) + self.beam_size_ver.set_value(float(size_y)) + time.sleep(random.uniform(0.3, 1.0)) + self.update_value(value) + + def get_predefined_positions_list(self): + """Get the position labels list. + Returns: + (list): List of all the labels defined. + """ + values = [] + for value in self.VALUES: + nam = value.name + if value.name != "UNKNOWN": + values.append(nam) + return values diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index 1a44198adb..7cf8803ffd 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -19,68 +19,148 @@ # along with MXCuBE. If not, see . """ -BeamMockup class +BeamMockup class - methods to define the size and shape of he beam. + +Example xml configuration: + +.. code-block:: xml + + + + + definer + 0 + 0 + """ -__copyright__ = """ Copyright © 2016 - 2020 by MXCuBE Collaboration """ +__copyright__ = """ Copyright © by MXCuBE Collaboration """ __license__ = "LGPLv3+" +from ast import literal_eval -from mxcubecore.HardwareObjects.abstract.AbstractBeam import ( - BeamShape, - AbstractBeam, -) +from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam class BeamMockup(AbstractBeam): - def __init__(self, name): - AbstractBeam.__init__(self, name) + """Beam Mockup class""" - self._beam_size_dict["slits"] = [9999, 9999] - self._beam_size_dict["aperture"] = [9999, 9999] - self._beam_position_on_screen = [680, 512] - self._beam_divergence = (0, 0) + def __init__(self, name): + super().__init__(name) + self._definer_type = None def init(self): - AbstractBeam.init(self) - - self._beam_position_on_screen = eval( - self.get_property("beam_position", "[318, 238]") - ) + """Initialize hardware""" + super().init() self._aperture = self.get_object_by_role("aperture") - if self._aperture is not None: - self.connect( - self._aperture, - "diameterIndexChanged", - self.aperture_diameter_changed, - ) - - ad = self._aperture.get_diameter_size() / 1000.0 - self._beam_size_dict["aperture"] = [ad, ad] - self._beam_info_dict["label"] = self._aperture.get_diameter_size() + if self._aperture: + _definer_type = "aperture" + self._aperture.connect("valueChanged", self.aperture_diameter_changed) self._slits = self.get_object_by_role("slits") - if self._slits is not None: - self.connect(self._slits, "valueChanged", self.slits_gap_changed) + if self._slits: + _definer_type = "slits" + self._slits.connect("valueChanged", self.slits_gap_changed) - sx, sy = self._slits.get_gaps() - self._beam_size_dict["slits"] = [sx, sy] + self._definer = self.get_object_by_role("definer") + if self._definer: + _definer_type = "definer" + self._definer.connect("valueChanged", self._re_emit_values) + + self._definer_type = self.get_property("definer_type") or _definer_type + + self._beam_position_on_screen = literal_eval( + self.get_property("beam_position", "[318, 238]") + ) - self.evaluate_beam_info() self.re_emit_values() self.emit("beamPosChanged", (self._beam_position_on_screen,)) + def _re_emit_values(self, *args, **kwargs): + self.re_emit_values() + + def _get_aperture_value(self): + """Get the size and the label of the aperture in place. + Returns: + (list, str): Size [mm] (width, height), label. + """ + _size = self.aperture.get_value().value[0] + try: + _label = self.aperture.get_value().name + except AttributeError: + _label = str(_size) + _size /= 1000.0 + + return [_size, _size], _label + + def _get_definer_value(self): + """Get the size and the name of the definer in place. + Returns: + (list, str): Size [mm] (width, height), label. + """ + try: + value = self.definer.get_value() + if isinstance(value, tuple): + return [value[1], value[1]], value[0] + return list(value.value), value.name + except AttributeError: + return [-1, -1], "UNKNOWN" + + def _get_slits_value(self): + """Get the size of the slits in place. + Returns: + (list, str): Size [mm] (width, height), label. + """ + _size = self.slits.get_gaps() + return _size, "slits" + + def get_value(self): + """Get the size (width and heigth) of the beam, its shape and + its label. The size is in mm. + Retunrs: + (tuple): (width, heigth, shape, name), with types + (float, float, Enum, str) + """ + labels = {} + _label = "UNKNOWN" + if self.aperture: + _size, _name = self._get_aperture_value() + self._beam_size_dict.update({"aperture": _size}) + labels.update({"aperture": _name}) + + if self.slits: + _size, _name = self._get_slits_value() + self._beam_size_dict.update({"slits": _size}) + labels.update({"slits": _name}) + + if self.definer: + _size, _name = self._get_definer_value() + self._beam_size_dict.update({"definer": _size}) + labels.update({"definer": _name}) + + info_dict = self.evaluate_beam_info() + + try: + _label = labels[info_dict["label"]] + self._beam_info_dict["label"] = _label + except KeyError: + _label = info_dict["label"] + + return self._beam_width, self._beam_height, self._beam_shape, _label + def aperture_diameter_changed(self, name, size): """ Method called when the aperture diameter changes Args: - name (str): diameter name - not used. + name (str): diameter name. size (float): diameter size in microns """ + self.aperture.update_value(f"A{size}") self._beam_size_dict["aperture"] = [size, size] - self._beam_info_dict["label"] = int(size * 1000) + name = name or f"A{int(size * 1000)}" self.evaluate_beam_info() + self._beam_info_dict["label"] = name self.re_emit_values() def slits_gap_changed(self, size): @@ -90,23 +170,19 @@ def slits_gap_changed(self, size): size (tuple): two floats indicates beam size in microns """ self._beam_size_dict["slits"] = size + self._beam_info_dict["label"] = "slits" self.evaluate_beam_info() self.re_emit_values() - def set_beam_position_on_screen(self, beam_x, beam_y): - """ - Sets beam mark position on screen + def set_beam_position_on_screen(self, beam_x_y): + """Sets beam mark position on screen #TODO move method to sample_view Args: - beam_x (int): horizontal position in pixels - beam_y (int): vertical position in pixels + beam_x_y (list): Position [x, y] [pixel] """ - self._beam_position_on_screen = (beam_x, beam_y) + self._beam_position_on_screen = beam_x_y self.emit("beamPosChanged", (self._beam_position_on_screen,)) - def get_value(self): - return list(self.get_beam_info_dict().values()) - def get_slits_gap(self): """ Returns: tuple with beam size in microns @@ -121,20 +197,102 @@ def set_slits_gap(self, width_microns, height_microns): width_microns (int): height_microns (int): """ - if self._slits: - self._slits.set_horizontal_gap(width_microns / 1000.0) - self._slits.set_vertical_gap(height_microns / 1000.0) + if self.slits: + self.slits.set_horizontal_gap(width_microns / 1000.0) + self.slits.set_vertical_gap(height_microns / 1000.0) def get_aperture_pos_name(self): """ Returns (str): name of current aperture position """ - if self._aperture: - return self._aperture.get_current_pos_name() + return self.aperture.get_current_pos_name() + + def get_defined_beam_size(self): + """Get the predefined beam labels and size. + Returns: + (dict): Dictionary with lists of avaiable beam size labels + and the corresponding size (width,height) tuples. + {"label": [str, str, ...], "size": [(w,h), (w,h), ...]} + """ + labels = [] + values = [] + if self._definer_type == "slits": + return { + "label": ["low", "high"], + "size": [self.slits.get_min_limits(), self.slits.get_max_limits()], + } + + if self._definer_type == "aperture": + _enum = self.aperture.VALUES + elif self._definer_type == "definer": + _enum = self.definer.VALUES + + for value in _enum: + _nam = value.name + if _nam not in ["IN", "OUT", "UNKNOWN"]: + labels.append(_nam) + if self._definer_type == "aperture": + values.append((value.value[0] / 1000.0, value.value[0] / 1000.0)) + else: + values.append(value.value) + return {"label": labels, "size": values} def get_available_size(self): - aperture_list = self._aperture.get_diameter_size_list() - return {"type": "enum", "values": aperture_list} + """Get the available predefined beam definer configuration. + Returns: + (dict): {"type": ["apertures"], "values": [labels]} or + {"type": ["definer"], "values": [labels]} or + {"type": ["width", "height"], "values": + [low_lim_w, high_lim_w, low_lim_h, high_lim_h]} + + """ + if self._definer_type == "aperture": + # get list of the available apertures + return { + "type": ["aperture"], + "values": self.aperture.get_diameter_size_list(), + } + + if self._definer_type == "definer": + # get list of the available definer positions + return { + "type": ["definer"], + "values": self.definer.get_predefined_positions_list(), + } + + if self._definer_type == "slits": + # get the list of the slits motors range + _low_w, _low_h = self.slits.get_min_limits() + _high_w, _high_h = self.slits.get_max_limits() + return { + "type": ["width", "height"], + "values": [_low_w, _high_w, _low_h, _high_h], + } + + return {} + + def set_value(self, size=None): + """Set the beam size + Args: + size (list): Width, heigth or + (str): Aperture or definer definer name. + Raises: + RuntimeError: Beam definer not configured + Size out of the limits. + TypeError: Wrong size type. + """ + if self._definer_type in (self.slits, "slits"): + if not isinstance(size, list): + raise TypeError("Incorrect input value for slits") + self.slits.set_horizontal_gap(size[0]) + self.slits.set_vertical_gap(size[1]) + + if self._definer_type in (self.aperture, "aperture"): + if not isinstance(size, str): + raise TypeError("Incorrect input value for aperture") + self.aperture.set_value(size) - def set_value(self, value): - self._aperture.set_diameter_size(value) + if self._definer_type in (self.definer, "definer"): + if not isinstance(size, str): + raise TypeError("Incorrect input value for definer") + self.definer.set_value(size) diff --git a/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py b/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py new file mode 100644 index 0000000000..9ff61362de --- /dev/null +++ b/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py @@ -0,0 +1,63 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public License +# along with MXCuBE. If not, see . +""" +Example xml file: + + Detector Distance + dtox + 1e-2 + +""" + +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor +from mxcubecore.BaseHardwareObjects import HardwareObjectState + +__copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + + +class MotorMockupBis(AbstractMotor): + """Motor Motor implementation""" + + def init(self): + """Initialise the motor""" + super().init() + # init state to match motor's one + self.update_state(self.STATES.READY) + + def get_state_nu(self): + """Get the motor state. + Returns: + (enum HardwareObjectState): Motor state. + """ + return HardwareObjectState.READY + + def get_value(self): + return self._nominal_value + + def _set_value(self, value): + """Move motor to absolute value. + Args: + value (float): target value + """ + self.update_state(self.STATES.BUSY) + # self.update_value(value) + self._nominal_value = value + self.update_state(self.STATES.READY) diff --git a/mxcubecore/configuration/mockup/beam-mockup.xml b/mxcubecore/configuration/mockup/beam-mockup.xml index 05df3129fd..233a0f9721 100644 --- a/mxcubecore/configuration/mockup/beam-mockup.xml +++ b/mxcubecore/configuration/mockup/beam-mockup.xml @@ -1,7 +1,8 @@ + + 12.0 12.0 - diff --git a/mxcubecore/configuration/mockup/beam_definer.xml b/mxcubecore/configuration/mockup/beam_definer.xml new file mode 100644 index 0000000000..74adcb2fad --- /dev/null +++ b/mxcubecore/configuration/mockup/beam_definer.xml @@ -0,0 +1,7 @@ + + Beam Definer + + + {"50x50": (0.05, 0.05), "100x100": (0.1, 0.1), "20x5": (0.02, 0.005)} + 50x50 + diff --git a/mxcubecore/configuration/mockup/beam_size_hor.xml b/mxcubecore/configuration/mockup/beam_size_hor.xml new file mode 100644 index 0000000000..4c1889d9c6 --- /dev/null +++ b/mxcubecore/configuration/mockup/beam_size_hor.xml @@ -0,0 +1,8 @@ + + beam_size_hor + Beam Width + 0.1 + 100 + 0.01 + [-150, 150] + diff --git a/mxcubecore/configuration/mockup/beam_size_ver.xml b/mxcubecore/configuration/mockup/beam_size_ver.xml new file mode 100644 index 0000000000..6c6185e33f --- /dev/null +++ b/mxcubecore/configuration/mockup/beam_size_ver.xml @@ -0,0 +1,8 @@ + + beam_size_ver + Beam Height + 0.1 + 100 + 0.001 + [-150, 150] + diff --git a/mxcubecore/configuration/mockup/diffractometer-mockup.xml b/mxcubecore/configuration/mockup/diffractometer-mockup.xml index 3164adec94..f6fe44f80c 100644 --- a/mxcubecore/configuration/mockup/diffractometer-mockup.xml +++ b/mxcubecore/configuration/mockup/diffractometer-mockup.xml @@ -8,6 +8,7 @@ + ("phi", "kappa", "kappa_phi", "phiz", "phiy", "sampx", "sampy") {"x":340,"y":250} diff --git a/test/pytest/TestAbstractNStateBase.py b/test/pytest/TestAbstractNStateBase.py index 8dc317130e..c62d40aaf5 100644 --- a/test/pytest/TestAbstractNStateBase.py +++ b/test/pytest/TestAbstractNStateBase.py @@ -62,7 +62,7 @@ def test_setting_timeouts_1(self, test_object): if test_object.read_only: return - values = list(val for val in test_object.VALUES if val != "UNKNOWN") + values = list(val for val in test_object.VALUES if val.name != "UNKNOWN") val1, val2 = values[:2] # Must be set first so the next command causes a change @@ -77,7 +77,7 @@ def test_setting_timeouts_2(self, test_object): if test_object.read_only: return - values = list(val for val in test_object.VALUES if val != "UNKNOWN") + values = list(val for val in test_object.VALUES if val.name != "UNKNOWN") val1, val2 = values[:2] # Must be set first so the next command causes a change diff --git a/test/pytest/test_aperture.py b/test/pytest/test_aperture.py new file mode 100644 index 0000000000..dc9f2bfddc --- /dev/null +++ b/test/pytest/test_aperture.py @@ -0,0 +1,64 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public License +# along with MXCuBE. If not, see . + +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + +import pytest +from test.pytest.TestAbstractNStateBase import TestAbstractNStateBase + + +@pytest.fixture +def test_object(beamline): + result = beamline.diffractometer.aperture + yield result + + +class TestAperture(TestAbstractNStateBase): + def test_aperture_atributes(self, test_object): + assert ( + test_object is not None + ), "Aperture hardware objects is None (not initialized)" + current_value = test_object.get_value() + assert current_value in test_object.VALUES + + def test_initialise_values_from_default(self, test_object): + values = test_object.VALUES + test_object._initialise_values() + assert values != test_object.VALUES + test_object._initialise_inout() + assert hasattr(test_object.VALUES, "IN") + + def test_get_factor(self, test_object): + for value in test_object.VALUES: + _nam = value.name + if _nam not in ["IN", "OUT", "UNKNOWN"]: + assert value.value[1] == test_object.get_factor(_nam) + assert value.value[1] == test_object.get_factor(value) + + def test_size(self, test_object): + test_object._initialise_inout() + for label in test_object.get_diameter_size_list(): + test_object.set_value(test_object.VALUES[label]) + test_object.update_value(test_object.VALUES[label]) + assert float(test_object.VALUES[label].value[0]) == test_object.get_size( + label + ) + assert test_object.VALUES[label] == test_object.get_value() diff --git a/test/pytest/test_beam.py b/test/pytest/test_beam.py index 4910b02831..33a04ae793 100644 --- a/test/pytest/test_beam.py +++ b/test/pytest/test_beam.py @@ -22,12 +22,8 @@ """Test suite for Beam hardware object. """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals - from test.pytest import TestHardwareObjectBase -from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape, AbstractBeam - +from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape import pytest @@ -44,23 +40,6 @@ def test_object(beamline): # NBNB TODO -@pytest.fixture -def beam(): - """ """ - - beam = AbstractBeam(name="abstract_beam") - yield beam - - -class TestAbstractBeam: - """ """ - - def test_beam_setup(self, beam: AbstractBeam): - """ """ - - assert beam is not None - - class TestBeam(TestHardwareObjectBase.TestHardwareObjectBase): """TestBeam class""" @@ -92,59 +71,187 @@ def test_get(self, test_object): beam_height, (int, float) ), "Vertical beam size has to be int or float" - def test_set(self, test_object): + def test_get_defined_beam_size(self, test_object): + """Check the defined beam size values for each definer type""" + if test_object.definer: + test_object._definer_type = "definer" + _vals = test_object.get_defined_beam_size() + _list = test_object.definer.get_predefined_positions_list() + assert _vals["label"] == _list + + if test_object.aperture: + test_object._definer_type = "aperture" + _vals = test_object.get_defined_beam_size() + _list = test_object.aperture.get_diameter_size_list() + assert _vals["label"] == _list + for val in _vals["size"]: + assert isinstance(val, tuple) + assert val[0] == val[1] + + if test_object.slits: + test_object._definer_type = "slits" + _range = test_object.get_defined_beam_size() + assert _range["label"] == ["low", "high"] + _low_w, _low_h = test_object.slits.get_min_limits() + _high_w, _high_h = test_object.slits.get_max_limits() + assert _range["size"] == [[_low_w, _low_h], [_high_w, _high_h]] + + def test_get_available_size(self, test_object): + """Check the available beam size values for each definer type""" + if test_object.definer: + test_object._definer_type = "definer" + _vals = test_object.get_available_size() + _list = test_object.definer.get_predefined_positions_list() + assert _vals["type"][0] == "definer" + assert _vals["values"] == _list + + if test_object.aperture: + test_object._definer_type = "aperture" + _vals = test_object.get_available_size() + _list = test_object.aperture.get_diameter_size_list() + assert _vals["type"][0] == "aperture" + assert _vals["values"] == _list + + if test_object.slits: + test_object._definer_type = "slits" + _vals = test_object.get_available_size() + assert _vals["type"] == ["width", "height"] + _low_w, _low_h = test_object.slits.get_min_limits() + _high_w, _high_h = test_object.slits.get_max_limits() + assert _vals["values"] == [_low_w, _high_w, _low_h, _high_h] + + def test_evaluate_beam_size(self, test_object): """ - Test set methods + The apertutre and the slits have the same size, + slits are the beam definer type. + Slits are bigger than the aperture, slits are the beam definer type. """ - max_diameter = max(test_object.aperture.get_diameter_size_list()) - test_object.aperture.set_diameter_size(max_diameter) + if test_object.aperture: + _list = [] + for val in test_object.aperture.get_diameter_size_list(): + _list.append(int(test_object.aperture.VALUES[val].value[0])) + max_diameter = max(_list) + test_object.aperture.set_value( + test_object.aperture.VALUES[f"A{max_diameter}"], timeout=2 + ) + target_width = target_height = max_diameter / 1000.0 - target_width = 0.01 - target_height = 0.01 - test_object.set_beam_size_shape( - target_width, target_height, BeamShape.RECTANGULAR - ) + if test_object.slits is not None: + target_width = 0.1 + target_height = 0.1 + test_object.slits.set_horizontal_gap(target_width) + test_object.slits.set_vertical_gap(target_height) - beam_width, beam_height = test_object.get_beam_size() + beam_width, beam_height, beam_shape, beam_label = test_object.get_value() assert target_width == beam_width assert target_height == beam_height + if beam_label == "slits": + assert beam_shape == BeamShape.RECTANGULAR + else: + assert beam_shape == BeamShape.ELLIPTICAL + if test_object._definer_type == "aperture": + assert beam_label == f"A{max_diameter}" - beam_shape = test_object.get_beam_shape() - assert beam_shape == BeamShape.RECTANGULAR + if test_object.slits is not None: + test_object.slits.set_horizontal_gap(0.2) + test_object.slits.set_vertical_gap(0.2) + beam_width, beam_height, beam_shape, beam_label = test_object.get_value() + target_width = target_height = max_diameter / 1000.0 + assert target_width == beam_width + assert target_height == beam_height + if beam_label == "slits": + assert beam_shape == BeamShape.RECTANGULAR + else: + assert beam_shape == BeamShape.ELLIPTICAL + if test_object._definer_type == "aperture": + assert beam_label == f"A{max_diameter}" def test_set_aperture_diameters(self, test_object): """ Set large slit gaps and in the sequence select all aperture diameters. - Beam shape is eliptical and size defined by the selected aperture + Beam shape is elliptical and size defined by the selected aperture. """ - test_object.slits.set_horizontal_gap(1) - test_object.slits.set_vertical_gap(1) + if test_object.aperture is None: + return + + test_object._definer_type = "aperture" + if test_object.slits is not None: + test_object.slits.set_horizontal_gap(1) + test_object.slits.set_vertical_gap(1) + for aperture_diameter in test_object.aperture.get_diameter_size_list(): - test_object.aperture.set_diameter_size(aperture_diameter) - beam_width, beam_height = test_object.get_beam_size() - # TODO get_beam_size returns size in mm, but aperture diameters - # are in microns. Use microns in all beam related hwobj - assert beam_width == beam_height == aperture_diameter / 1000.0 + _val = test_object.aperture.VALUES[aperture_diameter] + test_object.aperture.set_value(_val, timeout=2) - beam_shape = test_object.get_beam_shape() - assert beam_shape == BeamShape.ELIPTICAL + beam_width, beam_height, beam_shape, beam_label = test_object.get_value() + # get_value returns size in mm, aperture diameters are in microns + assert beam_width == beam_height == _val.value[0] / 1000.0 + assert beam_shape == BeamShape.ELLIPTICAL + assert beam_label == aperture_diameter def test_set_slit_gaps(self, test_object): """ Set slits smaller as the largest aperture diameter. - In this case beam size and shape is defined by slits + In this case beam size and shape is defined by slits. + Test get_beam_size and get_beam_shape instead of get_value """ - max_diameter = max(test_object.aperture.get_diameter_size_list()) - test_object.aperture.set_diameter_size(max_diameter) + if test_object.slits is None: + return + + test_object._definer_type = "slits" - target_width = 0.01 - target_height = 0.01 - test_object.slits.set_horizontal_gap(target_width) - test_object.slits.set_vertical_gap(target_height) + if test_object.aperture: + _list = [] + for val in test_object.aperture.get_diameter_size_list(): + _list.append(int(test_object.aperture.VALUES[val].value[0])) + max_diameter = max(_list) + test_object.aperture.set_value( + test_object.aperture.VALUES[f"A{max_diameter}"], timeout=2 + ) + # slit size in mm, aperture diameters are in microns + target_width = target_height = max_diameter / 2000.0 + test_object.set_value([target_width, target_height]) + # beam_width, beam_height, beam_shape, _ = test_object.get_value() beam_width, beam_height = test_object.get_beam_size() assert target_width == beam_width assert target_height == beam_height - beam_shape = test_object.get_beam_shape() assert beam_shape == BeamShape.RECTANGULAR + + def test_set_definer_size(self, test_object): + """ + Set large slit gaps and max aperture size. + Beam shape is elliptical and size defined by the selected definer. + """ + if test_object.definer is None: + return + + test_object._definer_type = "definer" + if test_object.slits is not None: + test_object.slits.set_horizontal_gap(1) + test_object.slits.set_vertical_gap(1) + + if test_object.aperture: + _list = [] + for val in test_object.aperture.get_diameter_size_list(): + _list.append(int(test_object.aperture.VALUES[val].value[0])) + max_diameter = max(_list) + test_object.aperture.set_value( + test_object.aperture.VALUES[f"A{max_diameter}"], timeout=2 + ) + + for dsize in test_object.definer.VALUES: + if dsize.name != "UNKNOWN": + test_object.definer.set_value(dsize, timeout=2) + + ( + beam_width, + beam_height, + beam_shape, + beam_label, + ) = test_object.get_value() + assert beam_width == dsize.value[0] + assert beam_height == dsize.value[1] + assert beam_shape == BeamShape.ELLIPTICAL + assert beam_label == dsize.name diff --git a/test/pytest/test_beam_definer.py b/test/pytest/test_beam_definer.py new file mode 100644 index 0000000000..c4685ee878 --- /dev/null +++ b/test/pytest/test_beam_definer.py @@ -0,0 +1,44 @@ +#! /usr/bin/env python +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +"""Test suite for BeamDefiner hardware object. +""" + +import pytest +from test.pytest.TestAbstractNStateBase import TestAbstractNStateBase + +__copyright__ = """ Copyright © by MXCuBE Collaboration """ +__license__ = "LGPLv3+" + + +@pytest.fixture +def test_object(beamline): + """Use the beam object from beamline""" + result = beamline.beam.definer + yield result + + +class TestBeamDefiner(TestAbstractNStateBase): + """TestBeam class""" + + def test_beam_atributes(self, test_object): + """Test if object exists.""" + assert test_object is not None, "Beam hardware object is None (not initialized)" From 216bdd71407fefc617190daeac53cc909dd151be Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 20 Aug 2024 15:45:35 +0000 Subject: [PATCH 008/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3bb79e0159..e3a88d2a36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.138.0" +version = "1.139.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 63bab647e0d51d222971f849c11dbb497a605a75 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Mon, 19 Aug 2024 16:17:23 +0200 Subject: [PATCH 009/172] Rename Oxford700 to OxfordCryostream (handles all models). Add temperature monitoring feature. --- .../HardwareObjects/ESRF/OxfordCryostream.py | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py diff --git a/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py b/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py new file mode 100644 index 0000000000..f1f1c51c0b --- /dev/null +++ b/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py @@ -0,0 +1,225 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public License +# along with MXCuBE. If not, see . + +""" Oxford Cryostream, controlled by bliss. +Example xml_ configuration: + +.. code-block:: xml + + + Cryostream + + cryostream + 120 + + +""" + + +import sys +import logging +from gevent import Timeout, sleep, spawn + +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator + +CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] +PHASE_ACTION = { + "RAMP": "ramp", + "COOL": "cool", + "HOLD": "hold", + "PLAT": "plat", + "PURGE": "purge", + "END": "end", +} + + +class OxfordCryostream(AbstractActuator): + """Control of the Oxford Cryostream model 700, 800 and 1000""" + + def __init__(self, name): + super().__init__(name) + + self.temp = None + self.temp_threshold = None + self._monitor_obj = None + self._timeout = 5 # [s] + self._hw_ctrl = None + self.ctrl = None + self.interval = None + + def _do_polling(self): + """Do endless polling with predefined interval""" + while True: + try: + self.force_emit_signals() + except Exception: + sys.excepthook(*sys.exc_info()) + sleep(self.interval) + + def init(self): + """Initialisation""" + controller = self.get_object_by_role("controller") + cryostat = self.get_property("cryostat") + self.interval = self.get_property("interval", 10) + try: + self.ctrl = getattr(controller, cryostat) + spawn(self._do_polling) + self._hw_ctrl = self.ctrl.controller._hw_controller + except AttributeError as err: + raise RuntimeError("Cannot use cryostream") from err + + self._monitor_obj = self.get_object_by_role("monitor_temperature") + self.temp_threshold = self.get_property("temperature_threshold", 0.0) + + def force_emit_signals(self): + """Forces to emit all signals.""" + self.emit("valueChanged", (self.get_value(),)) + self.emit("stateChanged", (self.get_state(),)) + + def get_temperature(self): + """Read the temperature. + Returns: + (float): The temperature [deg K] + """ + try: + return self.ctrl.input.read() + except Exception: + # try to read again + temp = self.ctrl.input.read() + if temp is None: + return 9999.0 + return temp + + def get_value(self): + return self.get_temperature() + + def _set_value(self, value=None): + """Define the setpoint. + Args: + value(float): target temperature [deg K] + """ + if value is not None: + self.ctrl.setpoint = value + + def rampstate(self): + """Read the state of the ramping. + Returns: + (str): Ramping state. + """ + return self.ctrl.is_ramping() + + def start_action(self, phase="RAMP", target=None, rate=None): + """Run phase action action. + Args: + phase(str): The phase action. Default value - RAMP + target(float): Target temperature. + rate:(float): Ramp rate. + """ + if phase in PHASE_ACTION: + action = getattr(self._hw_ctrl, PHASE_ACTION[phase]) + if rate: + action(target, rate=rate) + elif target: + action(target) + else: + action() + + def stop_action(self, phase="HOLD"): + """Stop action. + Args: + phase(str): Phase action. + """ + if phase in PHASE_ACTION: + getattr(self._hw_ctrl, PHASE_ACTION[phase]) + + def pause(self, execute=True): + """Pause the ramping. + Args: + execute(bool): True to pause, False to resume. + """ + if execute: + self._hw_ctrl.pause() + else: + self._hw_ctrl.resume() + + def get_specific_state(self): + """Read the state of the controller. + Returns: + (str): The state. + """ + try: + return self._hw_ctrl.read_run_mode().upper() + except (AttributeError, TypeError): + return "UNKNOWN" + + def get_static_parameters(self): + """Get predefined parameters. + Returns: + {list): Predefimed parameters. + """ + return ["oxford", "K", "hour"] + + def get_params(self): + """Read from the controller. + Returns: + (list): [target_temperature, ramp_rate, phase, run_mode] + """ + target_temperature = self.ctrl.setpoint + ramp_rate = self.ctrl.ramprate + phase = self._hw_ctrl.read_phase().upper() + run_mode = self._hw_ctrl.read_run_mode() + self.temp = self.ctrl.input.read() + return [target_temperature, ramp_rate, phase, run_mode] + + def check_temperature(self, threshold=None): + """Check if the temperature is under the threshold. + Args: + threshold (float): Temperature threshold (optional) + Returns: + (bool): True if under the threshold, False otherwise. + """ + threshold = threshold or self.temp_threshold + logging.getLogger("user_level_log").info("Cryo temperature reading ...") + cryo_temp = self.get_value() + if cryo_temp > threshold: + logging.getLogger("user_level_log").info("Cryo temperature too high ...") + return False + return True + + def wait_temperature(self, threshold=None, timeout=None): + """Wait until the temperature is under the threshold. + Args: + threshold (float): Temperature threshold (optional) + timeout (float): optional - timeout [s], + If timeout == 0: return at once and do not wait + (default); + if timeout is None: wait forever. + """ + if self._monitor_obj: + try: + check = self._monitor_obj.get_value().value + except AttributeError: + check = False + if check is True: + threshold = threshold or self.temp_threshold + timeout = timeout or self._timeout + with Timeout(timeout, RuntimeError("Temperature timeout")): + while not self.check_temperature(threshold=threshold): + sleep(0.5) From cc6b6f6fb40ff407a1846e8a23e6a7f95a294f3a Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Mon, 19 Aug 2024 16:48:26 +0200 Subject: [PATCH 010/172] Remove the temperature polling - now handled in the cryostream HO --- .../abstract/AbstractMultiCollect.py | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index deb2aed803..ce2ac41c30 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -783,28 +783,12 @@ def do_collect(self, owner, data_collect_parameters): self.open_safety_shutter() flux_threshold = self.get_property("flux_threshold", 0) - cryo_threshold = self.get_property("cryo_threshold", 0) - check_cryo = self.get_property("check_cryo", False) - - HWR.beamline.flux.wait_for_beam() - - # Wait for cryo - # from time to time cryo does not answer - cryo_temp = 999 - while check_cryo and cryo_temp > cryo_threshold: - try: - logging.getLogger("user_level_log").info( - "Cryo temperature reading ..." - ) - cryo_temp = HWR.beamline.diffractometer.cryostream.get_value() - if cryo_temp > cryo_threshold: - logging.getLogger("user_level_log").info( - "Cryo temperature too high ..." - ) - gevent.sleep(0.5) - except: - break + try: + HWR.beamline.flux.wait_for_beam() + HWR.beamline.cryo.wait_temperature() + except AttributeError: + pass logging.getLogger("user_level_log").info("Preparing intensity monitors") self.prepare_intensity_monitors() From fd39f4b7d4110fcd72f3f082317d3a9d0ecafb3a Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 21 Aug 2024 08:13:55 +0000 Subject: [PATCH 011/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e3a88d2a36..78cc5bb7a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.139.0" +version = "1.140.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From d40f2a3441d04d66d31bad8326fd81471c8e4d52 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Tue, 20 Aug 2024 17:53:08 +0200 Subject: [PATCH 012/172] ESRF Implementation of new beam size and definer handling --- mxcubecore/HardwareObjects/ESRF/ESRFBeam.py | 274 ++++++++++-------- .../HardwareObjects/ESRF/ESRFBeamDefiner.py | 125 ++++++++ .../HardwareObjects/ESRF/ID232BeamDefiner.py | 213 +++++++------- .../HardwareObjects/ESRF/ID30A3BeamDefiner.py | 128 ++++++++ 4 files changed, 514 insertions(+), 226 deletions(-) create mode 100644 mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py create mode 100644 mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py index 9abba378fa..7401713217 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py @@ -23,51 +23,49 @@ the beam. """ -__copyright__ = """ Copyright © 2023 by the MXCuBE collaboration """ +__copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" import logging -from mxcubecore.HardwareObjects.abstract.AbstractBeam import ( - AbstractBeam, - BeamShape, -) +from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam from mxcubecore import HardwareRepository as HWR class ESRFBeam(AbstractBeam): """Beam ESRF implementation""" - def __init__(self, name): - super().__init__(name) - self._aperture = None - self._slits = {} - self._complex = None - self._definer_type = None - self.beam_height = None - self.beam_width = None + unit = "mm" def init(self): """Initialize hardware""" super().init() - # self._definer_type = self.get_property("definer") + _definer_type = [] self._aperture = self.get_object_by_role("aperture") if self._aperture: - self._definer_type = "aperture" + _definer_type.append("aperture") _slits = self.get_property("slits") if _slits: - self._definer_type = "slits" + self._slits = {} + _definer_type.append("slits") _bliss_obj = self.get_object_by_role("bliss") for name in _slits.split(): _key, _val = name.split(":") - self._slits.update({_key: _bliss_obj.__getattribute__(_val)}) + self._slits.update({_key: _bliss_obj.getattribute(_val)}) - self._complex = self.get_object_by_role("complex") - if self._complex: - self._definer_type = "complex" + self._definer = self.get_object_by_role("definer") + if self._definer: + _definer_type.append("definer") + + if len(_definer_type) == 1: + self._definer_type = _definer_type[0] + else: + self._definer_type = None + + self._definer_type = self.get_property("definer_type") or self._definer_type beam_position = self.get_property("beam_position") @@ -78,54 +76,42 @@ def init(self): self._aperture.connect("valueChanged", self._re_emit_values) self._aperture.connect("stateChanged", self._re_emit_values) - if self._complex: - self._complex.connect("valueChanged", self._re_emit_values) - self._complex.connect("stateChanged", self._re_emit_values) + if self._definer: + self._definer.connect("valueChanged", self._re_emit_values) + self._definer.connect("stateChanged", self._re_emit_values) - def _re_emit_values(self, *args, **kwargs): + def _re_emit_values(self, value): + # redefine as re_emit_values takes no arguments self.re_emit_values() - def _get_aperture_size(self): + def _get_aperture_value(self): """Get the size and the label of the aperture in place. Returns: - (float, str): Size [mm], label. + (list, str): Size [mm] [width, height], label. """ - _size = self._aperture.get_value().value[1] - + _size = self.aperture.get_value().value[1] try: - _label = self._aperture.get_value().value[1] + _label = self.aperture.get_value().name except AttributeError: _label = str(_size) + _size /= 1000.0 - return _size / 1000.0, _label + return [_size, _size], _label - def _get_complex_size(self): + def _get_definer_value(self): """Get the size and the name of the definer in place. Returns: - (float, str): Size [mm], label. + (list, str): Size [mm] [width, height], label. """ try: - value = self._complex.get_value() - return value.value[1], value.name + value = self.definer.get_value() + if isinstance(value, tuple): + return [value[1], value[1]], value[0] + if value.name != "UNKNOWN": + return list(value.value), value.name except AttributeError: logging.getLogger("HWR").info("Could not read beam size") - return (-1, -1), "UNKNOWN" - - def _get_complex_size_old(self): - """Get the size and the name of the definer in place. - Returns: - (float, str): Size [mm], label. - """ - try: - _size = self._complex.size_by_name[ - self._complex.get_current_position_name() - ] - _name = self._complex.get_current_position_name() - except KeyError: - logging.getLogger("HWR").info("Could not read beam size") - _size, _name = (-1, -1), "UNKNOWN" - - return _size, _name + return [-1, -1], "UNKNOWN" def _get_slits_size(self): """Get the size of the slits in place. @@ -133,87 +119,113 @@ def _get_slits_size(self): (dict): {"width": float, "heigth": float}. """ beam_size = {} - for _key, _val in self._slits: + for _key, _val in self.slits: beam_size.update({_key: abs(_val.position)}) return beam_size def get_value(self): - """Get the size (width and heigth) of the beam and its shape. - The size is in mm. + """Get the size (width and heigth) of the beam, its shape and + its label. The size is in mm. Retunrs: - (tuple): Dictionary (width, heigth, shape, name), with types - (float, float, Enum, str) + (tuple): (width, heigth, shape, name), with types + (float, float, Enum, str) """ - _shape = BeamShape.UNKNOWN - - _beamsize_dict = {} - if self._aperture: - _size, _name = self._get_aperture_size() - _beamsize_dict.update({_name: [_size]}) - _shape = BeamShape.ELIPTICAL + labels = {} + _label = "UNKNOWN" + if self.aperture: + _size, _name = self._get_aperture_value() + self._beam_size_dict.update({"aperture": _size}) + labels.update({"aperture": _name}) - if self._complex: - _size, _name = self._get_complex_size() - _beamsize_dict.update({_name: _size}) - _shape = BeamShape.ELIPTICAL + if self.slits: + _size, _name = self._get_slits_value() + self._beam_size_dict.update({"slits": _size}) + labels.update({"slits": _name}) - if self._slits: - _beamsize_dict.update({"slits": self._get_slits_size().values()}) + if self.definer: + _size, _name = self._get_definer_value() + self._beam_size_dict.update({"definer": _size}) + labels.update({"definer": _name}) - def _beam_size_compare(size): - return size[0] + info_dict = self.evaluate_beam_info() - # find which device has the minimum size try: - _val = min(_beamsize_dict.values(), key=_beam_size_compare) - - _key = [k for k, v in _beamsize_dict.items() if v == _val] - - _name = _key[0] - self.beam_width = _val[0] + _label = labels[info_dict["label"]] + self._beam_info_dict["label"] = _label + except KeyError: + _label = info_dict["label"] - if "slits" in _key: - self.beam_height = _val[1] - _shape = BeamShape.RECTANGULAR - elif len(_val) > 1: - self.beam_height = _val[1] - else: - self.beam_height = _val[0] - except (ValueError, TypeError): - return None, None, _shape, "none" + return self._beam_width, self._beam_height, self._beam_shape, _label - return self.beam_width, self.beam_height, _shape, _name + def get_value_xml(self): + """XMLRPC does not handle Enum, the shape is transformed to string""" + beamsize = self.get_value() + return beamsize[0], beamsize[1], beamsize[2].value, beamsize[3] def get_available_size(self): """Get the available predefined beam definer configuration. Returns: - (dict): apertures {name: dimension} or - slits {"width": motor object, "heigth", motor object} or - complex definer {name: dimension}. + (dict): {"type": ["apertures"], "values": [labels]} or + {"type": ["definer"], "values": [labels]} or + {"type": ["width", "height"], "values": + [low_lim_w, high_lim_w, low_lim_h, high_lim_h]} """ - _type = "enum" - if self._definer_type in (self._aperture, "aperture"): - # get list of the available apertures - aperture_list = self._aperture.get_diameter_size_list() - return {"type": [_type], "values": aperture_list} - - if self._definer_type in (self._complex, "complex"): - # return {"type": [_type], "values": self._complex.size_list} + if self._definer_type == "aperture": return { - "type": [_type], - "values": self._complex.get_predefined_positions_list(), + "type": ["aperture"], + "values": self.aperture.get_diameter_size_list(), } - if self._definer_type in (self._slits, "slits"): + if self._definer_type == "definer": + return { + "type": ["definer"], + "values": self.definer.get_predefined_positions_list(), + } + + if self._definer_type in (self.slits, "slits"): # get the list of the slits motors range - _low_w, _high_w = self._slits["width"].get_limits() - _low_h, _high_h = self._slits["height"].get_limits() + _low_w, _high_w = self.slits["width"].get_limits() + _low_h, _high_h = self.slits["height"].get_limits() return { - "type": ["range", "range"], + "type": ["width", "height"], "values": [_low_w, _high_w, _low_h, _high_h], } - return [] + return {} + + def get_defined_beam_size(self): + """Get the predefined beam labels and size. + Returns: + (dict): Dictionary wiith list of avaiable beam size labels + and the corresponding size (width,height) tuples. + {"label": [str, str, ...], "size": [(w,h), (w,h), ...]} + """ + labels = [] + values = [] + + if self._definer_type == "slits": + # get the list of the slits motors range + _low_w, _high_w = self.slits["width"].get_limits() + _low_h, _high_h = self.slits["height"].get_limits() + return { + "label": ["low", "high"], + "size": [(_low_w, _low_h), (_high_w, _high_h)], + } + + if self._definer_type == "aperture": + _enum = self.aperture.VALUES + elif self._definer_type == "definer": + _enum = self.definer.VALUES + + for value in _enum: + _nam = value.name + if _nam not in ["IN", "OUT", "UNKNOWN"]: + labels.append(_nam) + if isinstance(value.value, tuple): + values.append(value.value) + else: + values.append(value.value[0]) + return {"label": labels, "size": values} def _set_slits_size(self, size=None): """Move the slits to the desired position. @@ -223,57 +235,69 @@ def _set_slits_size(self, size=None): RuntimeError: Size out of the limits. TypeError: Invalid size """ - w_lim = self._slits["width"].get_limits() - h_lim = self._slits["heigth"].get_limits() + if not isinstance(size, list): + raise TypeError("Incorrect input value for slits") + w_lim = self.slits["width"].get_limits() + h_lim = self.slits["heigth"].get_limits() try: if min(w_lim) > size[0] > max(w_lim): raise RuntimeError("Size out of the limits") if min(h_lim) > size[1] > max(h_lim): raise RuntimeError("Size out of the limits") - self._slits["width"].set_value(size[0]) - self._slits["heigth"].set_value(size[1]) - except TypeError: - raise TypeError("Invalid size") + self.slits["width"].set_value(size[0]) + self.slits["heigth"].set_value(size[1]) + except TypeError as err: + raise TypeError("Invalid size") from err def _set_aperture_size(self, size=None): """Move the aperture to the desired size. Args: size (str): The position name. + Raises: + TypeError """ + if not isinstance(size, str): + raise TypeError("Incorrect input value for aperture") + try: - _enum = getattr(self._aperture.VALUES, "A" + size) - except AttributeError: - _enum = getattr(self._aperture.VALUES, size) + _ap = self.aperture.VALUES[size] + except KeyError: + _ap = self.aperture.VALUES[f"A{size}"] - self._aperture.set_value(_enum) + self.aperture.set_value(_ap) - def _set_complex_size(self, size=None): - """Move the complex definer to the desired size. + def _set_definer_size(self, size=None): + """Move the definer to the desired size. Args: size (str): The position name. + Raises: + TypeError: Invalid size. """ - self._complex.set_value(size) + if not isinstance(size, str): + raise TypeError("Incorrect input value for definer") + + self._definer.set_value(self.definer.VALUES[size]) def set_value(self, size=None): """Set the beam size Args: size (list): Width, heigth or - (str): Aperture or complex definer name. + (str): Aperture or definer name. Raises: RuntimeError: Beam definer not configured Size out of the limits. """ - if self._definer_type in (self._slits, "slits"): + if self._definer_type in (self.slits, "slits"): self._set_slits_size(size) - if self._definer_type in (self._aperture, "aperture"): + if self._definer_type in (self.aperture, "aperture"): self._set_aperture_size(size) - if self._definer_type in (self._complex, "complex"): - self._set_complex_size(size) + if self._definer_type in (self.definer, "definer"): + self._set_definer_size(size) def get_beam_position_on_screen(self): - if self._beam_position_on_screen == (0, 0): + if self._beam_position_on_screen == [0, 0]: try: _beam_position_on_screen = ( HWR.beamline.diffractometer.get_beam_position() diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py new file mode 100644 index 0000000000..213604cb3f --- /dev/null +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py @@ -0,0 +1,125 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . +""" +Generic ESRF Beam Definer. + +Example xml configuration: + +.. code-block:: xml + + Beam Definer + + 4x4 um + 0.004, 0.004 + + + 4x8 um + 0.004, 0.008 + + 4x4 um + +""" + +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + +from ast import literal_eval +from enum import Enum +from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState + + +class ESRFBeamDefiner(AbstractNState): + """Generic ESRF beam definer implementation""" + + def __init__(self, *args): + super().__init__(*args) + self.beam_config = {} + self.config = [] + + def init(self): + super().init() + self._default_name = self.get_property("default_size_name") + + # keep the config is needed by the inheriring classes + self.config = self.init_config() + + # check if we have values other that UKNOWN + if len(self.VALUES) == 1: + self._initialise_values() + + def init_config(self): + """Get the configutarion from the file""" + + cfg = self["beam_config"] + if not isinstance(cfg, list): + cfg = [cfg] + + for beam_cfg in cfg: + name = beam_cfg.get_property("name") + beam_size = beam_cfg.get_property("beam_size", (0.015, 0.015)) + if isinstance(beam_size, str): + beam_size = literal_eval(beam_size) + self.beam_config.update({name: beam_size}) + return cfg + + def get_limits(self): + return (1, len(self.beam_config)) + + def get_value(self): + """Get the device value + Returns: + (Enum): The current position Enum. + """ + try: + return self.VALUES[self.get_current_position_name()] + except (ValueError, KeyError): + return self.VALUES.UNKNOWN + + def get_size(self): + """Get the current beam size (horozontal and vertical). + Returns: + (tuple): Curren beam size (horizontal, vertical) [mm]. + """ + return self.get_value().value + + def get_current_position_name(self): + """Get the current beam size name. + Returns: + (str): Current beam size name. + """ + raise NotImplementedError + + def get_predefined_positions_list(self): + """Get the list of all the beam size names. + Returns: + (list): List of strings with the beam size names. + """ + return list(self.beam_config.keys()) + + def _initialise_values(self): + """Initialise the ValueEnum from the configuration. + Raises: + RuntimeError: No values defined. + """ + self.VALUES = Enum( + "ValueEnum", + dict(self.beam_config, **{item.name: item.value for item in self.VALUES}), + ) diff --git a/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py index e503205189..e9aeb9fab7 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py @@ -1,54 +1,89 @@ -import ast +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public License +# along with MXCuBE. If not, see . +""" +ID23-2 Beam Definer. + +Example xml configuration: + +.. code-block:: xml + + Beam Definer + + # bliss tranfocator object names + tf + tf2 + + 4x4 um + 0.004, 0.004 + 0 0 0 0 0 0 0 0 0 + 0 0 1 1 0 0 0 0 0 + + + 4x8 um + 0.004, 0.008 + 0 0 0 0 0 0 0 0 0 + 0 0 1 0 1 0 0 0 0 + + 4x4 um + +""" + +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + from enum import Enum from gevent import Timeout, sleep - -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState -from bliss.common import event +from mxcubecore.HardwareObjects.ESRF.ESRFBeamDefiner import ESRFBeamDefiner -class ID232BeamDefiner(AbstractNState): +class ID232BeamDefiner(ESRFBeamDefiner): + """ID23-2 beam definer implementattion""" def __init__(self, *args): super().__init__(*args) - self.tf_cfg_by_name = {} - self.coef_by_name = {} - self.size_by_name = {} - self.pos_names = [] + self.tf_cfg = {} self.controller = None + self.tf1 = None + self.tf2 = None def init(self): + """Initialisation""" super().init() self.controller = self.get_object_by_role("controller") - event.connect(self.controller.tf, "state", self._tf_state_updated) - event.connect(self.controller.tf2, "state", self._tf_state_updated) - - cfg = self["lenses_config"] - if not isinstance(cfg, list): - cfg = [cfg] - - for lens_cfg in cfg: - name = lens_cfg.get_property("name") - tf1 = lens_cfg.get_property("tf1").split() - tf2 = lens_cfg.get_property("tf2").split() - size = lens_cfg.get_property("size") - coef = lens_cfg.get_property("coef") - self.pos_names.append(lens_cfg.get_property("name")) - self.tf_cfg_by_name[name] = { - "tf1": ["IN" if x else "OUT" for x in map(int, tf1)], - "tf2": ["IN" if x else "OUT" for x in map(int, tf2)], - } - self.size_by_name[name] = tuple([float(x) for x in ast.literal_eval(size)]) - self.coef_by_name[name] = float(coef) - - # check if we have values other that UKNOWN - if len(self.VALUES) == 1: - self._initialise_values() - - def is_ready(self): - return self.controller is not None + self.tf1 = self.controller.config.get(self.get_property("tf1")) + self.tf2 = self.controller.config.get(self.get_property("tf2")) + for beam_cfg in self.config: + name = beam_cfg.get_property("name") + tf1 = [int(x) for x in beam_cfg.get_property("tf1").split()] + tf2 = [int(x) for x in beam_cfg.get_property("tf2").split()] + self.tf_cfg[name] = {"tf1": tf1, "tf2": tf2} + + self.connect(self.tf1, "state", self._tf_update_state) + self.connect(self.tf2, "state", self._tf_update_state) + + if self.get_value() == self.VALUES.UNKNOWN and self._default_name: + # set default beam value + self.set_value(self._default_name) def get_state(self): """Get the device state. @@ -57,89 +92,65 @@ def get_state(self): """ return self.STATES.READY - def get_limits(self): - return (1, len(self.pos_names)) - - def get_value(self): - """Get the device value - Returns: - (int): The position index. - """ - try: - return self.VALUES[self.get_current_position_name()] - except (ValueError, KeyError): - return self.VALUES.UNKNOWN - - def _tf_state_updated(self, new_state=None): + def _tf_update_state(self, state=None): + """Update the value""" name = self.get_current_position_name() self.emit("valueChanged", name) - self.emit( - "diameterIndexChanged", (name, (1e6, self.size_by_name.get(name, 1e6))) - ) - - def connect_notify(self, signal): - return self._tf_state_updated() - - def get_predefined_positions_list(self): - return self.pos_names def get_current_status(self): - tf1_status = self.controller.tf.wago.get("stat")[::2] - tf2_status = self.controller.tf2.wago.get("stat")[::2] + """Get the status of the transfocators. + Returns: + (tuple): Tuple of two lists, giving the state for each lense + """ + tf1_status = self.tf1.wago.get("stat")[::2] + tf2_status = self.tf2.wago.get("stat")[::2] return tf1_status, tf2_status - def get_current_position_name(self, *args): + def get_current_position_name(self): + """Get the current beam size name. + Returns: + (str): Current beam size name. + """ try: - tf1_state = self.controller.tf.status_read()[1].split() - tf2_state = self.controller.tf2.status_read()[1].split() - except: + tf1_state, tf2_state = self.get_current_status() + except ValueError: return "UNKNOWN" - for name in self.pos_names: - tf1_cfg = self.tf_cfg_by_name[name]["tf1"] - tf2_cfg = self.tf_cfg_by_name[name]["tf2"] - - for i, tf_pos in enumerate(zip(tf1_state, tf2_state)): - if tf_pos[0] in (tf1_cfg[i], "---") and tf_pos[1] in ( - tf2_cfg[i], - "---", - ): - continue - else: - break - else: + + for name in self.beam_config: + if ( + self.tf_cfg[name]["tf1"] == tf1_state + and self.tf_cfg[name]["tf2"] == tf2_state + ): return name + return "UNKNOWN" - def set_value(self, name, timeout=None): + def set_value(self, value, timeout=None): """Set the beam size. Args: - name (str): position name + value(str): name of the beam size to set. + timeout(float): Timeout to wait for the execution to finish [s]. + Raises: + RuntimeError: Cannot change beam size. """ - tf1_cfg = [1 if x == "IN" else 0 for x in self.tf_cfg_by_name[name]["tf1"]] - tf2_cfg = [1 if x == "IN" else 0 for x in self.tf_cfg_by_name[name]["tf2"]] + if isinstance(value, Enum): + value = value.name - self.controller.tf.set(*tf1_cfg) - self.controller.tf2.set(*tf2_cfg) - self.wait_ready((tf1_cfg,tf2_cfg), timeout) + tf1_cfg = self.tf_cfg[value]["tf1"] + tf2_cfg = self.tf_cfg[value]["tf2"] + self.tf1.set(*tf1_cfg) + self.tf2.set(*tf2_cfg) - def wait_ready(self, status, timeout=None): + try: + self.wait_status((tf1_cfg, tf2_cfg), timeout) + except RuntimeError as err: + raise RuntimeError("Cannot change beam size") from err + + def wait_status(self, status, timeout=None): """Wait timeout seconds until status reached Args: + status (tuple): Transfocator status to be reached. timeout (float): Timeout [s]. Defaults to None. """ with Timeout(timeout, RuntimeError("Execution timeout")): while status != self.get_current_status(): sleep(0.5) - - def _initialise_values(self): - """Initialise the ValueEnum from the hardware - Raises: - RuntimeError: No aperture diameters defined. - """ - values = {} - for val in self.pos_names: - values[val] = [self.pos_names.index(val), self.size_by_name[val]] - - self.VALUES = Enum( - "ValueEnum", - dict(values, **{item.name: item.value for item in self.VALUES}), - ) diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py new file mode 100644 index 0000000000..db40b2b215 --- /dev/null +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py @@ -0,0 +1,128 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public License +# along with MXCuBE. If not, see . +""" +ID30-A3 Beam Definer. + +Example xml configuration: + +.. code-block:: xml + + + + 15um, A15 um + 0.015, 0.015 + 15 + + + 15um, A15 um + 0.015, 0.015 + 30 + + + 7um, A7 um + 0.007, 0.007 + 7 + + +""" + +__copyright__ = """ Copyright © by the MXCuBE collaboration """ +__license__ = "LGPLv3+" + +from enum import Enum +from mxcubecore.HardwareObjects.ESRF.ESRFBeamDefiner import ESRFBeamDefiner + + +class ID30A3BeamDefiner(ESRFBeamDefiner): + """ID30-A3 beam definer implementattion""" + + def __init__(self, *args): + super().__init__(*args) + self.controller = None + + def init(self): + """Initialisation""" + super().init() + + self.controller = self.get_object_by_role("controller") + _dict = {} + for beam_cfg in self.config: + name = beam_cfg.get_property("name") + _ap_size = beam_cfg.get_property("aperture_size") + _aperture = self.controller.value_to_enum(_ap_size, idx=1) + _dict[name] = [self.beam_config[name], _aperture] + + self.beam_config = _dict + self._initialise_values() + self.connect(self.controller, "valueChanged", self._update_name) + + def get_state(self): + """Get the device state. + Returns: + (enum 'HardwareObjectState'): Device state. + """ + return self.controller.get_state() + + def _update_name(self, value=None): + """ + Emits: + valueChanged (str): Current beam size name. + """ + name = self.get_current_position_name() + self.emit("valueChanged", name) + + def get_current_position_name(self): + """Get the current beam size name. + Returns: + (str): Current beam size name. + """ + _aperture = self.controller.get_value() + for name in self.beam_config: + if self.beam_config[name][1] == _aperture: + return name + return "UNKNOWN" + + def get_value(self): + """Get the device value + Returns: + (Enum): The current position Enum. + """ + try: + value = self.VALUES[self.get_current_position_name()] + if isinstance(value.value, tuple): + return value + return Enum("Dummy", {value.name: value.value[0]})[value.name] + except (ValueError, KeyError): + return self.VALUES.UNKNOWN + + def set_value(self, value, timeout=None): + """Set the beam size. + Args: + value(str): name of the beam size to set. + timeout(float): Timeout to wait for the execution to finish [s]. + Raises: + RuntimeError: Cannot change beam size. + """ + if isinstance(value, Enum): + value = value.name + + #self.controller.set_value(self.ctrl_cfg[value], timeout=timeout) + self.controller.set_value(self.beam_config[value][1], timeout=timeout) From 425f1be1cbf11fb80f2673818512d8e35d9273ae Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Wed, 21 Aug 2024 09:54:15 +0200 Subject: [PATCH 013/172] Remove obsolete code. --- mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py index db40b2b215..077776b7b3 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py @@ -124,5 +124,4 @@ def set_value(self, value, timeout=None): if isinstance(value, Enum): value = value.name - #self.controller.set_value(self.ctrl_cfg[value], timeout=timeout) self.controller.set_value(self.beam_config[value][1], timeout=timeout) From fcca3b5e64e42c779897e5cd18af22900be16047 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 21 Aug 2024 08:50:07 +0000 Subject: [PATCH 014/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 78cc5bb7a9..34502172bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.140.0" +version = "1.141.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 6a2a864ec92b02842dd74e692fbef49db8fa5b1e Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 23 Aug 2024 14:40:40 +0200 Subject: [PATCH 015/172] Replaced the use of a few remaining Device with HardwareObject --- mxcubecore/HardwareObjects/ALBA/ALBACalibration.py | 4 ++-- mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py | 4 ++-- mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py | 4 ++-- mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py | 2 +- .../HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py | 4 ++-- mxcubecore/HardwareObjects/ALBA/XalocCalibration.py | 4 ++-- mxcubecore/HardwareObjects/Camera.py | 6 +++--- mxcubecore/HardwareObjects/LNLS/LNLSCamera.py | 2 +- mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py | 4 ++-- mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py | 4 ++-- mxcubecore/HardwareObjects/TangoLimaVideo.py | 4 ++-- mxcubecore/HardwareObjects/VaporyVideo.py | 4 ++-- mxcubecore/HardwareObjects/mockup/MDCameraMockup.py | 4 ++-- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py b/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py index 9d1f9648c7..e781b573a4 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py @@ -51,9 +51,9 @@ __status__ = "Draft" -class ALBACalibration(BaseHardwareObjects.Device): +class ALBACalibration(BaseHardwareObjects.HardwareObject): def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py b/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py index ea8c2bde8f..f008b7c8d8 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py @@ -56,7 +56,7 @@ ) -class ALBAEpsActuator(BaseHardwareObjects.Device): +class ALBAEpsActuator(BaseHardwareObjects.HardwareObject): states = { STATE_OUT: "out", @@ -70,7 +70,7 @@ class ALBAEpsActuator(BaseHardwareObjects.Device): default_state_strings = ["Out", "In"] def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): self.actuator_state = STATE_UNKNOWN diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py b/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py index 91183d79ad..b11b3a90ee 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py @@ -57,7 +57,7 @@ ) -class ALBAFastShutter(BaseHardwareObjects.Device): +class ALBAFastShutter(BaseHardwareObjects.HardwareObject): states = { STATE_OUT: "out", @@ -71,7 +71,7 @@ class ALBAFastShutter(BaseHardwareObjects.Device): default_state_strings = ["Out", "In"] def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py index a606d62901..d6fc2e1d9b 100755 --- a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py @@ -75,7 +75,7 @@ class ALBAZoomMotor(BaseHardwareObjects.Device, AbstractMotor): INIT, FAULT, READY, MOVING, ONLIMIT = range(5) def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): logging.getLogger("HWR").debug("Initializing zoom motor IOR") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py index cbc3b91202..d85b76008b 100755 --- a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py @@ -62,12 +62,12 @@ __status__ = "Draft" -class ALBAZoomMotorAutoBrightness(BaseHardwareObjects.Device, AbstractMotor): +class ALBAZoomMotorAutoBrightness(BaseHardwareObjects.HardwareObject, AbstractMotor): INIT, FAULT, READY, MOVING, ONLIMIT = range(5) def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): logging.getLogger("HWR").debug("Initializing zoom motor autobrightness IOR") diff --git a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py index d8d497ce2e..19bf3d143f 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py @@ -5,9 +5,9 @@ from mxcubecore import BaseHardwareObjects -class XalocCalibration(BaseHardwareObjects.Device): +class XalocCalibration(BaseHardwareObjects.HardwareObject): def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def init(self): diff --git a/mxcubecore/HardwareObjects/Camera.py b/mxcubecore/HardwareObjects/Camera.py index 0486474d25..075e965dde 100644 --- a/mxcubecore/HardwareObjects/Camera.py +++ b/mxcubecore/HardwareObjects/Camera.py @@ -75,15 +75,15 @@ def __init__(self, mmapFile): ImageType.__init__(self, "rgb") -class Camera(BaseHardwareObjects.Device): +class Camera(BaseHardwareObjects.HardwareObject): def _init(self): if self.get_property("tangoname"): # Tango device import PyTango - class TangoCamera(BaseHardwareObjects.Device): + class TangoCamera(BaseHardwareObjects.HardwareObject): def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def oprint(self, msg): print(("Camera.py--tango device-- %s" % msg)) diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py index 28d48bf4b5..2047ae71e4 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py @@ -28,7 +28,7 @@ CAMERA_IMG_WIDTH = "epicsCameraSample_img_width" CAMERA_IMG_HEIGHT = "epicsCameraSample_img_height" -class LNLSCamera(BaseHardwareObjects.Device): +class LNLSCamera(BaseHardwareObjects.HardwareObject): def __init__(self,name): BaseHardwareObjects.Device.__init__(self,name) diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py index 3bce7ed5a7..830e1993b0 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py @@ -16,7 +16,7 @@ from mxcubecore import HardwareRepository as HWR -class PX2Guillotine(BaseHardwareObjects.Device): +class PX2Guillotine(BaseHardwareObjects.HardwareObject): shutterState = { # 0: 'ON', # 1: 'OFF', @@ -88,7 +88,7 @@ class PX2Guillotine(BaseHardwareObjects.Device): } def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) logging.info("Guillotine init ") def init(self): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py index cf269e8ded..700ec7bb2e 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py @@ -16,7 +16,7 @@ from mxcubecore import HardwareRepository as HWR -class SOLEILGuillotine(BaseHardwareObjects.Device): +class SOLEILGuillotine(BaseHardwareObjects.HardwareObject): shutterState = { # 0: 'ON', # 1: 'OFF', @@ -88,7 +88,7 @@ class SOLEILGuillotine(BaseHardwareObjects.Device): } def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) logging.info("Guillotine init ") def init(self): diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 27f7c9f99f..15ee24c988 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -51,9 +51,9 @@ def poll_image(lima_tango_device, video_mode, FORMATS): return img, width, height -class TangoLimaVideo(BaseHardwareObjects.Device): +class TangoLimaVideo(BaseHardwareObjects.HardwareObject): def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) self.__brightnessExists = False self.__contrastExists = False self.__gainExists = False diff --git a/mxcubecore/HardwareObjects/VaporyVideo.py b/mxcubecore/HardwareObjects/VaporyVideo.py index f32bb4f070..f9787221bf 100755 --- a/mxcubecore/HardwareObjects/VaporyVideo.py +++ b/mxcubecore/HardwareObjects/VaporyVideo.py @@ -28,7 +28,7 @@ from mxcubecore.HardwareObjects.Camera import JpegType -class VaporyVideo(BaseHardwareObjects.Device): +class VaporyVideo(BaseHardwareObjects.HardwareObject): """ Descript. : """ @@ -37,7 +37,7 @@ def __init__(self, name): """ Descript. : """ - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) self.force_update = None self.image_dimensions = None self.image_polling = None diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index 3fc77906fd..94657418b7 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -13,9 +13,9 @@ SLOW_INTERVAL = 1000 -class MDCameraMockup(BaseHardwareObjects.Device): +class MDCameraMockup(BaseHardwareObjects.HardwareObject): def __init__(self, name): - BaseHardwareObjects.Device.__init__(self, name) + super().__init__(name) def _init(self): self._format = "MPEG1" From 61b7828cac708f17b4039ebd3a0632c477a1ace4 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 27 Aug 2024 06:25:06 +0000 Subject: [PATCH 016/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 34502172bd..ab8508eea7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.141.0" +version = "1.142.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 8e17c4beac5c680d92de47d51de8f6d0f0c25c2b Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 27 Aug 2024 11:38:21 +0200 Subject: [PATCH 017/172] Moved set_is_ready method from Device to HardwareObject and added deprecation warning --- mxcubecore/BaseHardwareObjects.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mxcubecore/BaseHardwareObjects.py b/mxcubecore/BaseHardwareObjects.py index 869d2755b3..468119984c 100644 --- a/mxcubecore/BaseHardwareObjects.py +++ b/mxcubecore/BaseHardwareObjects.py @@ -778,6 +778,16 @@ def is_ready(self) -> bool: """ return self._ready_event.is_set() + def set_is_ready(self, value: bool): + warnings.warn( + "set_is_ready method ported from Device is Deprecated and will be removed", + DeprecationWarning, + ) + if value: + self.update_state(HardwareObjectState.READY) + else: + self.update_state(HardwareObjectState.OFF) + def update_state(self, state: Optional[HardwareObjectState] = None) -> None: """Update self._state, and emit signal stateChanged if the state has changed. From bebbc2b87a5174520ebe9000043620e8eea447f0 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 27 Aug 2024 15:25:06 +0000 Subject: [PATCH 018/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ab8508eea7..d7090547ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.142.0" +version = "1.143.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 9ece3a110ab119a012ed2fd39d63655c573f5181 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Tue, 27 Aug 2024 15:33:51 +0100 Subject: [PATCH 019/172] Fixed bugs related to recent Beamdefiner changes --- mxcubecore/HardwareObjects/QtGraphicsLib.py | 5 +++-- mxcubecore/HardwareObjects/mockup/BeamMockup.py | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/QtGraphicsLib.py b/mxcubecore/HardwareObjects/QtGraphicsLib.py index 6b5b8e17e2..db7b8de967 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsLib.py +++ b/mxcubecore/HardwareObjects/QtGraphicsLib.py @@ -191,8 +191,9 @@ def set_beam_info(self, beam_info): :type beam_info: dict """ self.beam_is_rectangle = beam_info.get("shape") == "rectangular" - self.beam_size_mm[0] = beam_info.get("size_x", 0) - self.beam_size_mm[1] = beam_info.get("size_y", 0) + # NBNB TODO fix to match correct way of setting unkown values + self.beam_size_mm[0] = beam_info.get("size_x", 0) or 0 + self.beam_size_mm[1] = beam_info.get("size_y", 0) or 0 if not math.isnan(self.pixels_per_mm[0]): self.beam_size_pix[0] = int(self.beam_size_mm[0] * self.pixels_per_mm[0]) if not math.isnan(self.pixels_per_mm[1]): diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index 7cf8803ffd..e2d48c3236 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -149,18 +149,19 @@ def get_value(self): return self._beam_width, self._beam_height, self._beam_shape, _label - def aperture_diameter_changed(self, name, size): + def aperture_diameter_changed(self, aperture): """ Method called when the aperture diameter changes Args: name (str): diameter name. - size (float): diameter size in microns """ - self.aperture.update_value(f"A{size}") + + size = aperture.value[0] + self.aperture.update_value(aperture) self._beam_size_dict["aperture"] = [size, size] - name = name or f"A{int(size * 1000)}" + # name = name or f"A{int(size * 1000)}" self.evaluate_beam_info() - self._beam_info_dict["label"] = name + self._beam_info_dict["label"] = aperture.name self.re_emit_values() def slits_gap_changed(self, size): From 694dc56e2adb4bf79da83760d8c0290044d07099 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Tue, 27 Aug 2024 15:34:56 +0100 Subject: [PATCH 020/172] Removed commented-out line --- mxcubecore/HardwareObjects/mockup/BeamMockup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index e2d48c3236..2fcb137f7c 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -159,7 +159,6 @@ def aperture_diameter_changed(self, aperture): size = aperture.value[0] self.aperture.update_value(aperture) self._beam_size_dict["aperture"] = [size, size] - # name = name or f"A{int(size * 1000)}" self.evaluate_beam_info() self._beam_info_dict["label"] = aperture.name self.re_emit_values() From 793a9298319b599af0ecc8515423822f8ff809d7 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Wed, 28 Aug 2024 10:54:35 +0100 Subject: [PATCH 021/172] Updated doc strings to allow for latest change --- mxcubecore/HardwareObjects/mockup/BeamMockup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index 2fcb137f7c..e2bdf5dba9 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -153,7 +153,7 @@ def aperture_diameter_changed(self, aperture): """ Method called when the aperture diameter changes Args: - name (str): diameter name. + aperture (aperture(Enum)): Aperture enum. """ size = aperture.value[0] From fad5f965a7884b1d450b8e80bcb4cff82ad32aa6 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Wed, 28 Aug 2024 11:06:22 +0100 Subject: [PATCH 022/172] Removed commented-out line --- mxcubecore/HardwareObjects/QtGraphicsLib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/QtGraphicsLib.py b/mxcubecore/HardwareObjects/QtGraphicsLib.py index db7b8de967..791011e2ef 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsLib.py +++ b/mxcubecore/HardwareObjects/QtGraphicsLib.py @@ -191,7 +191,6 @@ def set_beam_info(self, beam_info): :type beam_info: dict """ self.beam_is_rectangle = beam_info.get("shape") == "rectangular" - # NBNB TODO fix to match correct way of setting unkown values self.beam_size_mm[0] = beam_info.get("size_x", 0) or 0 self.beam_size_mm[1] = beam_info.get("size_y", 0) or 0 if not math.isnan(self.pixels_per_mm[0]): From 8df43cd491809075b7e96bfe5399c76d53956716 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 28 Aug 2024 10:19:43 +0000 Subject: [PATCH 023/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d7090547ed..e8964124cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.143.0" +version = "1.144.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 87db3bce1568f2154ab8294303d80af3b00ea7ad Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Wed, 28 Aug 2024 18:29:10 +0200 Subject: [PATCH 024/172] Fix bug in BeamMockup and test_beam (#1006) Co-authored-by: Antonia Beteva --- mxcubecore/HardwareObjects/mockup/BeamMockup.py | 4 ++-- test/pytest/test_beam.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index e2bdf5dba9..f3c8b8a015 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -290,9 +290,9 @@ def set_value(self, size=None): if self._definer_type in (self.aperture, "aperture"): if not isinstance(size, str): raise TypeError("Incorrect input value for aperture") - self.aperture.set_value(size) + self.aperture.set_value(self.aperture.VALUES[size], timeout=2) if self._definer_type in (self.definer, "definer"): if not isinstance(size, str): raise TypeError("Incorrect input value for definer") - self.definer.set_value(size) + self.definer.set_value(self.definer.VALUES[size], timeout=2) diff --git a/test/pytest/test_beam.py b/test/pytest/test_beam.py index 33a04ae793..1458891e37 100644 --- a/test/pytest/test_beam.py +++ b/test/pytest/test_beam.py @@ -181,7 +181,7 @@ def test_set_aperture_diameters(self, test_object): for aperture_diameter in test_object.aperture.get_diameter_size_list(): _val = test_object.aperture.VALUES[aperture_diameter] - test_object.aperture.set_value(_val, timeout=2) + test_object.set_value(aperture_diameter) beam_width, beam_height, beam_shape, beam_label = test_object.get_value() # get_value returns size in mm, aperture diameters are in microns @@ -243,7 +243,7 @@ def test_set_definer_size(self, test_object): for dsize in test_object.definer.VALUES: if dsize.name != "UNKNOWN": - test_object.definer.set_value(dsize, timeout=2) + test_object.set_value(dsize.name) ( beam_width, From e4c7876a0a2a37266df6313875fb7c7a40627bfe Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 28 Aug 2024 16:29:41 +0000 Subject: [PATCH 025/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e8964124cf..53e7bebfb0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.144.0" +version = "1.145.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 1350c6665dcb336ebd8bb6df7f7318d00dfb117a Mon Sep 17 00:00:00 2001 From: meguiraun Date: Mon, 2 Sep 2024 11:28:55 +0200 Subject: [PATCH 026/172] hwobj-ify abstract energy scan (#1008) --- mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py index 8a1040f9f2..c66fcdccfa 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py @@ -4,12 +4,14 @@ import logging import gevent from mxcubecore.TaskUtils import error_cleanup +from mxcubecore.BaseHardwareObjects import HardwareObject -class AbstractEnergyScan(object): +class AbstractEnergyScan(HardwareObject): __metaclass__ = abc.ABCMeta - def __init__(self): + def __init__(self, name): + super().__init__(name) self.data_collect_task = None self._egyscan_task = None self.scanning = False From fff83786eadcb03851198ace3b8677b1e323854c Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 2 Sep 2024 09:29:18 +0000 Subject: [PATCH 027/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 53e7bebfb0..0d55f8aba5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.145.0" +version = "1.146.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 0f853b6986ada52b72e13a045a9873739752a346 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Mon, 2 Sep 2024 13:26:23 +0200 Subject: [PATCH 028/172] extra attrs for xrf spectrum dict revert (#1005) * Remove prefix, spectrum_directory and archive_directory from spectrum_info_dict * Camel to snake case. --------- Co-authored-by: Antonia Beteva --- mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py index da0d986258..0ceab69ad9 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py @@ -93,7 +93,6 @@ def start_spectrum( self.spectrum_info_dict = {"sessionId": session_id, "blSampleId": blsample_id} integration_time = integration_time or self.default_integration_time self.spectrum_info_dict["exposureTime"] = integration_time - self.spectrum_info_dict["prefix"] = prefix self.spectrum_info_dict["filename"] = "" # Create the data and the archive directory (if needed) and files if data_dir: @@ -102,7 +101,6 @@ def start_spectrum( return False filename = self.get_filename(data_dir, prefix) self.spectrum_info_dict["filename"] = filename + "." + self.file_suffix - self.spectrum_info_dict["spectrum_directory"] = os.path.dirname(filename) if archive_dir: if not self.create_directory(archive_dir): self.update_state(self.STATES.FAULT) @@ -114,7 +112,6 @@ def start_spectrum( self.spectrum_info_dict["jpegScanFileFullPath"] = filename + ".png" self.spectrum_info_dict["annotatedPymcaXfeSpectrum"] = filename + ".html" self.spectrum_info_dict["fittedDataFileFullPath"] = filename + "_peaks.csv" - self.spectrum_info_dict["archive_directory"] = archive_dir self.spectrum_info_dict["startTime"] = time.strftime("%Y-%m-%d %H:%M:%S") self.update_state(self.STATES.BUSY) @@ -242,4 +239,4 @@ def spectrum_command_failed(self): def spectrum_store_lims(self): """Store the data in lims, according to the existing data model.""" if self.spectrum_info_dict.get("sessionId"): - self.lims.storeXfeSpectrum(self.spectrum_info_dict) + self.lims.store_xfe_spectrum(self.spectrum_info_dict) From 084d3a614b1ec021b180359361d3b6e6c7e8feca Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 2 Sep 2024 11:26:46 +0000 Subject: [PATCH 029/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0d55f8aba5..7f4808ab20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.146.0" +version = "1.147.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 20d48c5e3cea14f5d5d3885bf258929b69d10ecb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:28:25 +0000 Subject: [PATCH 030/172] Bump opencv-python from 4.7.0.72 to 4.8.1.78 Bumps [opencv-python](https://github.com/opencv/opencv-python) from 4.7.0.72 to 4.8.1.78. - [Release notes](https://github.com/opencv/opencv-python/releases) - [Commits](https://github.com/opencv/opencv-python/commits) --- updated-dependencies: - dependency-name: opencv-python dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index bf3422ff60..b26f4bd056 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1388,28 +1388,28 @@ files = [ [[package]] name = "opencv-python" -version = "4.7.0.72" +version = "4.8.1.78" description = "Wrapper package for OpenCV python bindings." optional = false python-versions = ">=3.6" files = [ - {file = "opencv-python-4.7.0.72.tar.gz", hash = "sha256:3424794a711f33284581f3c1e4b071cfc827d02b99d6fd9a35391f517c453306"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:d4f8880440c433a0025d78804dda6901d1e8e541a561dda66892d90290aef881"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:7a297e7651e22eb17c265ddbbc80e2ba2a8ff4f4a1696a67c45e5f5798245842"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd08343654c6b88c5a8c25bf425f8025aed2e3189b4d7306b5861d32affaf737"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebfc0a3a2f57716e709028b992e4de7fd8752105d7a768531c4f434043c6f9ff"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-win32.whl", hash = "sha256:eda115797b114fc16ca6f182b91c5d984f0015c19bec3145e55d33d708e9bae1"}, - {file = "opencv_python-4.7.0.72-cp37-abi3-win_amd64.whl", hash = "sha256:812af57553ec1c6709060c63f6b7e9ad07ddc0f592f3ccc6d00c71e0fe0e6376"}, + {file = "opencv-python-4.8.1.78.tar.gz", hash = "sha256:cc7adbbcd1112877a39274106cb2752e04984bc01a031162952e97450d6117f6"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:91d5f6f5209dc2635d496f6b8ca6573ecdad051a09e6b5de4c399b8e673c60da"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31f47e05447da8b3089faa0a07ffe80e114c91ce0b171e6424f9badbd1c5cd"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9814beca408d3a0eca1bae7e3e5be68b07c17ecceb392b94170881216e09b319"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c406bdb41eb21ea51b4e90dfbc989c002786c3f601c236a99c59a54670a394"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-win32.whl", hash = "sha256:a7aac3900fbacf55b551e7b53626c3dad4c71ce85643645c43e91fcb19045e47"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-win_amd64.whl", hash = "sha256:b983197f97cfa6fcb74e1da1802c7497a6f94ed561aba6980f1f33123f904956"}, ] [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, - {version = ">=1.22.0", markers = "python_version >= \"3.11\""}, ] [[package]] From cfaf0ccbe7eb27fa0389b188f315f3d9b93da0f8 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 2 Sep 2024 13:13:59 +0000 Subject: [PATCH 031/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7f4808ab20..ed2976e293 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.147.0" +version = "1.148.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 2c57ddf6ac5869cce957660a5f4726aa72e1f74a Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Mon, 2 Sep 2024 14:45:24 +0200 Subject: [PATCH 032/172] fix initialization of EnergyScanMockup In 1350c6665dcb336ebd8bb6df7f7318d00dfb117a commit, the AbstractEnergyScan class has been changed to extend HardwareObject. It's AbstractEnergyScan.__init__() method now takes a string parameter. This change breaks current EnergyScanMockup.__init__() method, as it calls AbstractEnergyScan.__init__() without any arguments. Remove the EnergyScanMockup.__init__() method, as it's no longer needed. This fixes the issue with creating EnergyScanMockup objects. --- mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py index 88520a2e57..367dfd138a 100644 --- a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py @@ -164,11 +164,7 @@ ) -class EnergyScanMockup(AbstractEnergyScan, HardwareObject): - def __init__(self, name): - AbstractEnergyScan.__init__(self) - HardwareObject.__init__(self, name) - +class EnergyScanMockup(AbstractEnergyScan): def init(self): self.ready_event = gevent.event.Event() From 4bb8845eba9b45908839c545aa09145a16a82e42 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 2 Sep 2024 13:36:03 +0000 Subject: [PATCH 033/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ed2976e293..5dc9bf526d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.148.0" +version = "1.149.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 40b73f4ed74dde943ae2a95159ef2404dc6dc5ef Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 26 Jul 2024 11:22:29 +0200 Subject: [PATCH 034/172] fix wording in some doc strings Fix typos and spelling style in some python doc strings. --- mxcubecore/HardwareObjects/QueueModel.py | 2 +- mxcubecore/HardwareObjects/abstract/AbstractBeam.py | 2 +- mxcubecore/HardwareRepository.py | 2 +- mxcubecore/queue_entry/base_queue_entry.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mxcubecore/HardwareObjects/QueueModel.py b/mxcubecore/HardwareObjects/QueueModel.py index 63224c0a1d..fc0691fdce 100644 --- a/mxcubecore/HardwareObjects/QueueModel.py +++ b/mxcubecore/HardwareObjects/QueueModel.py @@ -150,7 +150,7 @@ def add_child(self, parent, child): Adds the child node . Raises the exception TypeError if child is not of type TaskNode. - Moves the child (reparents it) if it already has a parent. + Moves the child (re-parents it) if it already has a parent. :param child: TaskNode to add :type child: TaskNode diff --git a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py index 917895b44a..999bafb2e6 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py @@ -19,7 +19,7 @@ # along with MXCuBE. If not, see . """ -AbstracBeam class - methods to define the size and shape of the beam. +AbstractBeam class - methods to define the size and shape of the beam. emits: - beamSizeChanged (self._beam_width, self._beam_height) diff --git a/mxcubecore/HardwareRepository.py b/mxcubecore/HardwareRepository.py index 55c518b34a..e8f1ba9c55 100644 --- a/mxcubecore/HardwareRepository.py +++ b/mxcubecore/HardwareRepository.py @@ -269,7 +269,7 @@ def set_user_file_directory(user_file_directory): def init_hardware_repository(configuration_path): - """Initialise hardweare repository - must be run at program start + """Initialise hardware repository - must be run at program start Args: configuration_path (str): PATHSEP-separated string of directories diff --git a/mxcubecore/queue_entry/base_queue_entry.py b/mxcubecore/queue_entry/base_queue_entry.py index bb374a4740..cf57e98f62 100644 --- a/mxcubecore/queue_entry/base_queue_entry.py +++ b/mxcubecore/queue_entry/base_queue_entry.py @@ -242,8 +242,8 @@ def get_data_model(self): def set_view(self, view, view_set_queue_entry=True): """ Sets the view of this queue entry to . Makes the - correspodning bi-directional connection if view_set_queue_entry - is set to True. Which is normaly case, it can be usefull with + corresponding bidirectional connection if view_set_queue_entry + is set to True. Which is normally case, it can be useful with 'uni-directional' connection in some rare cases. :param view: The view to associate with this entry @@ -275,7 +275,7 @@ def is_enabled(self): def set_enabled(self, state): """ - Enables or disables this entry, controls wether this item + Enables or disables this entry, controls if this item should be executed (enabled) or not (disabled) :param state: Enabled if state is True otherwise disabled. From 2a2a38cbec55d2748229829c3efd8375444440cc Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 26 Jul 2024 11:23:04 +0200 Subject: [PATCH 035/172] add missing . in the documentation --- docs/source/dev/queue.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/dev/queue.md b/docs/source/dev/queue.md index 1c42d72e39..21ce2167e1 100644 --- a/docs/source/dev/queue.md +++ b/docs/source/dev/queue.md @@ -40,7 +40,7 @@ The model consists of an object called `QueueModel` that has a tree structure of The combination of a `QueueEntry` and its model (`QueueModel`) is often referred to as a *task*, and makes up the entity that will be executed when the queue is executed. The one-to-one mapping makes it possible to represent a queue and construct the queue entries from the queue model objects. In this way, the tree of queue model objects defines the queue. A task or collection protocol can be added to the queue by adding the *queue model object* to the `QueueModel`. For instance, a rotational data collection is added to the queue by adding a `DataCollectionTaskNode` to the `QueueModel`. This method of adding tasks to the queue is used by the Workflow engines, while the interfaces directly attach a `TaskNode` object to the corresponding `QueueEntry` which is then -*enqueued* +*enqueued*. ## Task creation - creation of QueueEntry and QueueModel A task is created by creating a `Tasknode` and attaching it to a corresponding `QueueEntry`. The `QueueEntry` is added or *enqueued* to the queue via the method `QueueManager.enqueue`. From 213319bcc3ece55b72dc8934877ea10c284d19f7 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 26 Jul 2024 11:25:48 +0200 Subject: [PATCH 036/172] remove confusing class doc string The doc string for DataCollection seems to be talking about something different then the DataCollection class. Probably some kind of refactoring accident. --- mxcubecore/model/queue_model_objects.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 111542ccf5..407dd70b20 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -579,28 +579,6 @@ def get_display_name(self): class DataCollection(TaskNode): - """ - Adds the child node . Raises the exception TypeError - if child is not of type TaskNode. - - Moves the child (reparents it) if it already has a parent. - - :param parent: Parent TaskNode object. - :type parent: TaskNode - - :param acquisition_list: List of Acquisition objects. - :type acquisition_list: list - - :crystal: Crystal object - :type crystal: Crystal - - :param processing_paremeters: Parameters used by autoproessing software. - :type processing_parameters: ProcessingParameters - - :returns: None - :rtype: None - """ - def __init__( self, acquisition_list=None, From 9ffedc5e337cfab0434a08a0f7b8510ef60daf07 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 26 Jul 2024 14:16:19 +0200 Subject: [PATCH 037/172] remove duplicate import --- mxcubecore/HardwareObjects/QueueManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/QueueManager.py b/mxcubecore/HardwareObjects/QueueManager.py index 2a2911d887..368b5384b4 100644 --- a/mxcubecore/HardwareObjects/QueueManager.py +++ b/mxcubecore/HardwareObjects/QueueManager.py @@ -8,7 +8,6 @@ documentation for the queue_entry module for more information. """ import logging -import traceback import gevent import traceback From 99b07a6700925a50cbad78c0075343eeefbd2ec2 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Tue, 13 Aug 2024 11:58:02 +0200 Subject: [PATCH 038/172] remove unused imports --- mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py | 4 ---- mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py | 1 - mxcubecore/model/common.py | 2 +- test/pytest/test_hwo_maxiv_mach_info.py | 2 +- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py index bb26f75eed..79e9c222d6 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py @@ -1,14 +1,10 @@ from typing_extensions import Literal from pydantic import BaseModel, Field -from mxcubecore.TaskUtils import task -from mxcubecore.CommandContainer import CommandObject from mxcubecore.HardwareObjects.BeamlineActions import ( BeamlineActions, - ControllerCommand, AnnotatedCommand, ) -from mxcubecore.utils.conversion import camel_to_snake import gevent import logging diff --git a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py index defc138113..5bb9490754 100644 --- a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py @@ -1,4 +1,3 @@ -import gevent import time import logging diff --git a/mxcubecore/model/common.py b/mxcubecore/model/common.py index f862b26e37..1cf6375979 100644 --- a/mxcubecore/model/common.py +++ b/mxcubecore/model/common.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Optional, Union +from typing import Optional from pydantic import BaseModel, Field diff --git a/test/pytest/test_hwo_maxiv_mach_info.py b/test/pytest/test_hwo_maxiv_mach_info.py index c7203e28e1..68324aa7f8 100644 --- a/test/pytest/test_hwo_maxiv_mach_info.py +++ b/test/pytest/test_hwo_maxiv_mach_info.py @@ -2,7 +2,7 @@ import pytest from gevent.event import Event from tango.server import Device, attribute, command -from tango.test_context import DeviceTestContext, MultiDeviceTestContext +from tango.test_context import MultiDeviceTestContext from mxcubecore.HardwareObjects.MAXIV.MachInfo import MachInfo From 24995e090b6fd2c2da423fd5babc485306ffb698 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Tue, 13 Aug 2024 18:08:11 +0200 Subject: [PATCH 039/172] remove commented out code It's been commented a long time ago. I don't think anyone is going to miss it now. --- mxcubecore/HardwareRepository.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/mxcubecore/HardwareRepository.py b/mxcubecore/HardwareRepository.py index e8f1ba9c55..6fc737e59c 100644 --- a/mxcubecore/HardwareRepository.py +++ b/mxcubecore/HardwareRepository.py @@ -683,19 +683,6 @@ def get_procedure(self, procedure_name): """Return a Procedure given its name (see get_hardware_object())""" return self.get_hardware_object(procedure_name) - # def get_connection(self, connection_name): - # """Return the Connection object for a Spec connection, given its name - # - # Parameters : - # connectionName -- a Spec version name ('host:port' string) - # - # Return : - # the corresponding SpecConnection object - # """ - # connections_manager = SpecConnectionsManager.SpecConnectionsManager() - # - # return connections_manager.get_connection(connection_name) - def is_device(self, name): """Check if a Hardware Object is a Device From cf3ba5ab072350a81b8724fa885dd2b1b582f4a1 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Tue, 13 Aug 2024 18:10:51 +0200 Subject: [PATCH 040/172] remove incorrect type hint This method returns 'None'. --- mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py b/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py index 3b44048093..1e12413529 100644 --- a/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py @@ -42,7 +42,7 @@ def __init__(self, *args): """ GenericDiffractometer.__init__(self, *args) - def init(self) -> bool: + def init(self): """ Descript. : """ From 3867c0e59124d95723558f92f491ab045f859bd7 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Mon, 19 Aug 2024 16:25:59 +0200 Subject: [PATCH 041/172] fix typos in comment and doc strings --- mxcubecore/HardwareObjects/BeamlineActions.py | 2 +- test/pytest/test_command_container.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mxcubecore/HardwareObjects/BeamlineActions.py b/mxcubecore/HardwareObjects/BeamlineActions.py index f180d8b13d..799e6e284d 100644 --- a/mxcubecore/HardwareObjects/BeamlineActions.py +++ b/mxcubecore/HardwareObjects/BeamlineActions.py @@ -180,7 +180,7 @@ def _get_command_object_class(self, path_str): _cls_name = parts[-1] self._annotated_commands.append(_cls_name) - # Assume import from current module if only class name givien (no module) + # assume import from current module if only class name given (no module) if len(parts) == 1: _cls = getattr(sys.modules[__name__], _cls_name) else: diff --git a/test/pytest/test_command_container.py b/test/pytest/test_command_container.py index c23bafb037..d58700c69a 100644 --- a/test/pytest/test_command_container.py +++ b/test/pytest/test_command_container.py @@ -20,7 +20,7 @@ @pytest.fixture(scope="function") def cmd_object() -> Generator[CommandObject, None, None]: - """Pytest fixture to instanciate a new "CommandObject" object. + """Pytest fixture to instantiate a new "CommandObject" object. Yields: Generator[CommandObject, None, None]: New object instance. @@ -32,7 +32,7 @@ def cmd_object() -> Generator[CommandObject, None, None]: @pytest.fixture(scope="function") def channel_object() -> Generator[ChannelObject, None, None]: - """Pytest fixture to instanciate a new "ChannelObject" object. + """Pytest fixture to instantiate a new "ChannelObject" object. Yields: Generator[ChannelObject, None, None]: New object instance. @@ -44,7 +44,7 @@ def channel_object() -> Generator[ChannelObject, None, None]: @pytest.fixture(scope="function") def cmd_container() -> Generator[CommandContainer, None, None]: - """Pytest fixture to instanciate a new "CommandContainer" object. + """Pytest fixture to instantiate a new "CommandContainer" object. Yields: Generator[CommandContainer, None, None]: New object instance. From fce3e98e27d6cffea88018b0137cdb1d91b3a2af Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 26 Jul 2024 14:25:52 +0200 Subject: [PATCH 042/172] trim linters exclude lists Remove files from autoflake and black exclude list, that does not need to be there. --- pyproject.toml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5dc9bf526d..0b17c745e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,8 +115,6 @@ mxcubecore/HardwareObjects/SOLEIL/SOLEILqueue_entry.py, mxcubecore/HardwareObjects/TangoLimaMpegVideo.py, mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py, mxcubecore/HardwareObjects/XSDataMXv1.py, -mxcubecore/model/common.py, -mxcubecore/model/queue_model_objects.py, """ [tool.black] @@ -133,8 +131,6 @@ force-exclude = ''' | buck-out | build | dist - # this file contains invalid python syntax - | mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py # # Exclude files below from black checks until we get around fixing them. # This way we can check that all other files are black clean in CI. @@ -153,8 +149,6 @@ force-exclude = ''' | mxcubecore/HardwareObjects/DESY/P11DetectorCover.py | mxcubecore/HardwareObjects/Beamline.py | mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py - | mxcubecore/HardwareObjects/DESY/P11Pinhole.py - | mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py | mxcubecore/HardwareObjects/DESY/P11Shutter.py | mxcubecore/HardwareObjects/EMBL/EMBLAperture.py | mxcubecore/HardwareObjects/EMBL/EMBLBSD.py @@ -185,6 +179,7 @@ force-exclude = ''' | mxcubecore/HardwareObjects/ESRF/ID231BeamCmds.py | mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py | mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py + | mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py | mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py | mxcubecore/HardwareObjects/ESRF/ID232MultiCollect.py | mxcubecore/HardwareObjects/ESRF/ID29MultiCollect.py @@ -216,7 +211,6 @@ force-exclude = ''' | mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | mxcubecore/HardwareObjects/ISPyBClient.py | mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py - | mxcubecore/HardwareObjects/MotorsNPosition.py | mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py | mxcubecore/HardwareObjects/PlateManipulatorMaintenance.py | mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py @@ -225,7 +219,6 @@ force-exclude = ''' | mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py | mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pilatus.py | mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Collect.py - | mxcubecore/HardwareObjects/SOLEIL/SOLEILLdapLogin.py | mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py | mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Collect.py | mxcubecore/HardwareObjects/SOLEIL/SOLEILMachineInfo.py @@ -234,9 +227,7 @@ force-exclude = ''' | mxcubecore/HardwareObjects/abstract/sample_changer/Crims.py | mxcubecore/HardwareObjects/abstract/AbstractCollect.py | mxcubecore/HardwareObjects/mockup/MotorMockup.py - | mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py | mxcubecore/HardwareObjects/mockup/ShutterMockup.py - | mxcubecore/HardwareObjects/mockup/XRFSpectrumMockup.py | mxcubecore/Poller.py | mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py | mxcubecore/model/crystal_symmetry.py From c65d887645cb5429d6573637f12ab3c9e0fec427 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 3 Sep 2024 06:32:51 +0000 Subject: [PATCH 043/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0b17c745e0..be22a2711f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.149.0" +version = "1.150.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From efff7c849febb57ec33b5046abac9cd0ebd4a25f Mon Sep 17 00:00:00 2001 From: Mikel Eguiraun Date: Tue, 3 Sep 2024 20:07:21 +0200 Subject: [PATCH 044/172] fix when static params are not defined --- mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py index c66fcdccfa..05743e4c2a 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py @@ -157,13 +157,15 @@ def start_energy_scan( raise RuntimeError("Scan already started.") self.emit("energyScanStarted", ()) - STATICPARS_DICT = {} # Set the energy from the element and edge parameters STATICPARS_DICT = self.get_static_parameters( self.get_property("config_file"), element, edge ) self.cpos = cpos - self.energy_scan_parameters = STATICPARS_DICT + if STATICPARS_DICT is not None: + self.energy_scan_parameters = STATICPARS_DICT + else: + self.energy_scan_parameters = {} self.energy_scan_parameters["element"] = element self.energy_scan_parameters["edge"] = edge self.energy_scan_parameters["directory"] = directory From ce2d196e3fadaff94411839560f3ad80b27882bd Mon Sep 17 00:00:00 2001 From: Mikel Eguiraun Date: Tue, 3 Sep 2024 20:26:06 +0200 Subject: [PATCH 045/172] remove unneeded argument --- mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py index 05743e4c2a..a7fde87c6e 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py @@ -103,7 +103,7 @@ def escan_prepare(self): """ pass - def choose_attenuation(self, energy_scan_parameters): + def choose_attenuation(self): """ Procedure to set the minimal attenuation in order no preserve the sample. Should be done at the energy after the edge. From 76b20d40ab59b4d092bbdc0764f4d9015877bc32 Mon Sep 17 00:00:00 2001 From: Mikel Eguiraun Date: Tue, 3 Sep 2024 20:26:37 +0200 Subject: [PATCH 046/172] a working escan mockup --- .../mockup/EnergyScanMockup.py | 103 ++++++++---------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py index 367dfd138a..2f57f60135 100644 --- a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py @@ -165,10 +165,13 @@ class EnergyScanMockup(AbstractEnergyScan): + def __init__(self, name): + AbstractEnergyScan.__init__(self, name) + def init(self): self.ready_event = gevent.event.Event() - self.scan_info = {} + self.energy_scan_parameters = {} self.result_value_emitter = None self.scan_data = [] self.thEdgeThreshold = 5 @@ -191,47 +194,28 @@ def emit_result_values(self): time.sleep(0.05) self.scanCommandFinished() - def start_energy_scan( - self, - element, - edge, - directory, - prefix, - session_id=None, - blsample_id=None, - exptime=3, - ): - - self._element = element - self._edge = edge - self.scan_info = { - "sessionId": session_id, - "blSampleId": blsample_id, - "element": element, - "edgeEnergy": edge, - } - self.scan_info["exposureTime"] = exptime - + def execute_energy_scan(self, energy_scan_parameters): + self.energy_scan_parameters["exposureTime"] = 0.01 + print(self.cpos) if HWR.beamline.transmission is not None: - self.scan_info["transmissionFactor"] = HWR.beamline.transmission.get_value() + self.energy_scan_parameters[ + "transmissionFactor" + ] = HWR.beamline.transmission.get_value() else: - self.scan_info["transmissionFactor"] = None + self.energy_scan_parameters["transmissionFactor"] = None size_hor = None size_ver = None if HWR.beamline.beam is not None: size_hor, size_ver = HWR.beamline.beam.get_beam_size() size_hor = size_hor * 1000 size_ver = size_ver * 1000 - self.scan_info["beamSizeHorizontal"] = size_hor - self.scan_info["beamSizeVertical"] = size_ver - self.scan_info["startEnergy"] = 0 - self.scan_info["endEnergy"] = 0 - self.scan_info["fluorescenceDetector"] = "Mockup detector" + self.energy_scan_parameters["beamSizeHorizontal"] = size_hor + self.energy_scan_parameters["beamSizeVertical"] = size_ver + self.energy_scan_parameters["startEnergy"] = 0 + self.energy_scan_parameters["endEnergy"] = 0 + self.energy_scan_parameters["fluorescenceDetector"] = "Mockup detector" self.scan_data = [] - self.scanCommandStarted() self.result_value_emitter = gevent.spawn(self.emit_result_values) - # self.emit('energyScanFinished', (self.scan_info,)) - # self.ready_event.set() def do_chooch(self, elt, edge, scan_directory, archive_directory, prefix): """ @@ -289,7 +273,9 @@ def do_chooch(self, elt, edge, scan_directory, archive_directory, prefix): archive_file_raw.write("%f,%f\r\n" % (x, y)) scan_file_raw.close() archive_file_raw.close() - self.scan_info["scanFileFullPath"] = str(scan_file_raw_filename) + self.energy_scan_parameters["scanFileFullPath"] = str( + scan_file_raw_filename + ) pk = 7.519 ip = 7.516 @@ -299,24 +285,24 @@ def do_chooch(self, elt, edge, scan_directory, archive_directory, prefix): fpInfl = -21.1 fppInfl = 11.9 comm = "Mockup results" - self.scan_info["edgeEnergy"] = 0.1 - self.thEdge = self.scan_info["edgeEnergy"] + self.energy_scan_parameters["edgeEnergy"] = 0.1 + self.thEdge = self.energy_scan_parameters["edgeEnergy"] logging.getLogger("HWR").info( "th. Edge %s ; chooch results are pk=%f, ip=%f, rm=%f" % (self.thEdge, pk, ip, rm) ) - self.scan_info["peakEnergy"] = pk - self.scan_info["inflectionEnergy"] = ip - self.scan_info["remoteEnergy"] = rm - self.scan_info["peakFPrime"] = fpPeak - self.scan_info["peakFDoublePrime"] = fppPeak - self.scan_info["inflectionFPrime"] = fpInfl - self.scan_info["inflectionFDoublePrime"] = fppInfl - self.scan_info["comments"] = comm - self.scan_info["choochFileFullPath"] = scan_file_efs_filename - self.scan_info["filename"] = archive_file_raw_filename - self.scan_info["workingDirectory"] = archive_directory + self.energy_scan_parameters["peakEnergy"] = pk + self.energy_scan_parameters["inflectionEnergy"] = ip + self.energy_scan_parameters["remoteEnergy"] = rm + self.energy_scan_parameters["peakFPrime"] = fpPeak + self.energy_scan_parameters["peakFDoublePrime"] = fppPeak + self.energy_scan_parameters["inflectionFPrime"] = fpInfl + self.energy_scan_parameters["inflectionFDoublePrime"] = fppInfl + self.energy_scan_parameters["comments"] = comm + self.energy_scan_parameters["choochFileFullPath"] = scan_file_efs_filename + self.energy_scan_parameters["filename"] = archive_file_raw_filename + self.energy_scan_parameters["workingDirectory"] = archive_directory chooch_graph_x, chooch_graph_y1, chooch_graph_y2 = zip(*chooch_graph_data) chooch_graph_x = list(chooch_graph_x) @@ -350,7 +336,9 @@ def do_chooch(self, elt, edge, scan_directory, archive_directory, prefix): handles.append(ax2.plot(chooch_graph_x, chooch_graph_y2, color="red")) canvas = FigureCanvasAgg(fig) - self.scan_info["jpegChoochFileFullPath"] = str(archive_file_png_filename) + self.energy_scan_parameters["jpegChoochFileFullPath"] = str( + archive_file_png_filename + ) try: logging.getLogger("HWR").info( "Rendering energy scan and Chooch " + "graphs to PNG file : %s", @@ -427,11 +415,12 @@ def scanCommandStarted(self, *args): """ Descript. : """ + print(self.energy_scan_parameters) title = "%s %s: %s %s" % ( - self.scan_info["sessionId"], - self.scan_info["blSampleId"], - self.scan_info["element"], - self.scan_info["edgeEnergy"], + self.energy_scan_parameters["sessionId"], + self.energy_scan_parameters["blSampleId"], + self.energy_scan_parameters["element"], + self.energy_scan_parameters["edgeEnergy"], ) dic = { "xlabel": "energy", @@ -441,7 +430,7 @@ def scanCommandStarted(self, *args): } self.emit("scanStart", dic) self.emit("energyScanStarted", dic) - self.scan_info["startTime"] = time.strftime("%Y-%m-%d %H:%M:%S") + self.energy_scan_parameters["startTime"] = time.strftime("%Y-%m-%d %H:%M:%S") self.scanning = True def scanCommandFinished(self, *args): @@ -449,12 +438,12 @@ def scanCommandFinished(self, *args): Descript. : """ with cleanup(self.ready_event.set): - self.scan_info["endTime"] = time.strftime("%Y-%m-%d %H:%M:%S") + self.energy_scan_parameters["endTime"] = time.strftime("%Y-%m-%d %H:%M:%S") logging.getLogger("HWR").debug("Energy Scan: finished") self.scanning = False - self.scan_info["startEnergy"] = self.scan_data[-1][0] / 1000.0 - self.scan_info["endEnergy"] = self.scan_data[-1][1] / 1000.0 - self.emit("energyScanFinished", self.scan_info) + self.energy_scan_parameters["startEnergy"] = self.scan_data[-1][0] / 1000.0 + self.energy_scan_parameters["endEnergy"] = self.scan_data[-1][1] / 1000.0 + self.emit("energyScanFinished", self.energy_scan_parameters) def get_scan_data(self): """ @@ -467,4 +456,4 @@ def store_energy_scan(self): Descript. : """ if HWR.beamline.lims: - db_status = HWR.beamline.lims.storeEnergyScan(self.scan_info) + db_status = HWR.beamline.lims.storeEnergyScan(self.energy_scan_parameters) From 236d5899a9c10e4dc01e4d959012fc161361c661 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 4 Sep 2024 13:55:37 +0000 Subject: [PATCH 047/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index be22a2711f..f6d6fae9a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.150.0" +version = "1.151.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From de650e84a69ae63103701eed68feca3fd74aeea1 Mon Sep 17 00:00:00 2001 From: meguiraun Date: Thu, 5 Sep 2024 10:41:54 +0200 Subject: [PATCH 048/172] allow update grid result data (#1004) * allow update grid result data * allow update grid result data * document grid result format --- mxcubecore/HardwareObjects/SampleView.py | 29 ++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index b502132277..d6ab601489 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -330,11 +330,31 @@ def get_grid(self): return grid def set_grid_data(self, sid, result_data, data_file_path): + """ + Sets grid rsult data for a shape with the specified id. + + Args: + sid (str): The id of the shape to set grid data for. + result_data: The result data to set for the shape. Either a base64 encoded string for PNG/image + or a dictionary for RGB (keys are cell number and value RGBa list). Data is only updated if result is RGB based + data_file_path (str): The path to the data file associated with the result data. + + Returns: + None + + Raises: + AttributeError: If no shape with the specified id exists. + """ + shape = self.get_shape(sid) if shape: - shape.set_result(result_data) - shape.result_data_path = data_file_path + if shape.result and type(shape.result) == dict: + # append data + shape.result.update(result_data) + else: + shape.set_result(result_data) + shape.result_data_path = data_file_path self.emit("newGridResult", shape) else: @@ -522,7 +542,9 @@ def __init__(self, mpos_list, screen_coord): self.num_cols = -1 self.num_rows = -1 self.selected = False - self.result = [] + # result is a base64 encoded string for PNG/image heatmap results + # or a dictionary (for RGB number based results) + self.result = None self.pixels_per_mm = [1, 1] self.beam_pos = [1, 1] self.beam_width = 0 @@ -564,7 +586,6 @@ def set_id(self, id_num): def set_result(self, result_data): self.result = result_data - self._result = result_data def get_result(self): return self.result From f1c302d8d3905c39426473c136fff22872cba00f Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 5 Sep 2024 08:42:19 +0000 Subject: [PATCH 049/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f6d6fae9a7..3cfb287205 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.151.0" +version = "1.152.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 0c70b2dc8e71565ada471f01cc2a40c8bb465ed2 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Mon, 9 Sep 2024 15:15:38 +0200 Subject: [PATCH 050/172] =?UTF-8?q?units:=20add=20micrometers=20(=CE=BCm)?= =?UTF-8?q?=20to=20millimeters=20conversion=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a function to convert micrometers (μm) to millimeters. --- mxcubecore/utils/units.py | 7 +++++++ test/pytest/test_utils_units.py | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/mxcubecore/utils/units.py b/mxcubecore/utils/units.py index 7c5bbfa38f..e425e7bf87 100644 --- a/mxcubecore/utils/units.py +++ b/mxcubecore/utils/units.py @@ -59,6 +59,13 @@ def mm_to_meter(millimeters: float) -> float: return millimeters / 1000.0 +def um_to_mm(micrometers: float) -> float: + """ + convert micrometers (μm) to millimeters + """ + return micrometers / 1000.0 + + # # current units # diff --git a/test/pytest/test_utils_units.py b/test/pytest/test_utils_units.py index 998f4e39cb..1afb62701f 100644 --- a/test/pytest/test_utils_units.py +++ b/test/pytest/test_utils_units.py @@ -6,6 +6,7 @@ ev_to_kev, meter_to_mm, mm_to_meter, + um_to_mm, A_to_mA, ) @@ -40,6 +41,11 @@ def test_mm_to_meter(): assert isclose(mm_to_meter(10.5), 0.0105) +def test_um_to_mm(): + assert isclose(um_to_mm(5), 0.005) + assert isclose(um_to_mm(42.2), 0.0422) + + def test_A_to_mA(): assert isclose(A_to_mA(2), 2000.0) assert isclose(A_to_mA(0.3921), 392.1) From b2dc2bd07334dc7c21888938cc6dbbfdfbf71135 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 9 Sep 2024 15:04:20 +0000 Subject: [PATCH 051/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3cfb287205..9a5cec111a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.152.0" +version = "1.153.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From b186403611797c90e54507590ab119767804b499 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 17 Sep 2024 13:54:52 +0200 Subject: [PATCH 052/172] Added comparability between pydantic 1 and 2 --- mxcubecore/BaseHardwareObjects.py | 12 ++++++------ .../ESRF/queue_entry/ssx_base_queue_entry.py | 2 +- .../ESRF/queue_entry/ssx_big_foil_collection.py | 2 +- .../ESRF/queue_entry/ssx_chip_collection.py | 2 +- .../ESRF/queue_entry/ssx_injector_collection.py | 2 +- .../ESRF/queue_entry/test_collection.py | 2 +- mxcubecore/HardwareObjects/GenericDiffractometer.py | 2 +- .../HardwareObjects/mockup/BeamlineActionsMockup.py | 2 +- mxcubecore/model/common.py | 2 +- mxcubecore/model/configmodel.py | 2 +- mxcubecore/model/procedure_model.py | 5 ++--- mxcubecore/queue_entry/test_collection.py | 2 +- 12 files changed, 18 insertions(+), 19 deletions(-) diff --git a/mxcubecore/BaseHardwareObjects.py b/mxcubecore/BaseHardwareObjects.py index 468119984c..f785b8db37 100644 --- a/mxcubecore/BaseHardwareObjects.py +++ b/mxcubecore/BaseHardwareObjects.py @@ -26,7 +26,7 @@ from collections import OrderedDict import logging from gevent import event, Timeout -import pydantic +from pydantic.v1 import create_model, Field import warnings from typing import ( @@ -50,7 +50,7 @@ if TYPE_CHECKING: from logging import Logger - from pydantic import BaseModel + from pydantic.v1 import BaseModel from .CommandContainer import CommandObject __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ @@ -658,11 +658,11 @@ def _get_type_annotations(self) -> None: # Skipp return typehint if _n != "return": self._exports[attr_name].append(_n) - fdict[_n] = (_t, pydantic.Field(alias=_n)) + fdict[_n] = (_t, Field(alias=_n)) _models[attr_name] = ( - pydantic.create_model(attr_name, **fdict), - pydantic.Field(alias=attr_name), + create_model(attr_name, **fdict), + Field(alias=attr_name), ) self._pydantic_models[attr_name] = _models[attr_name][0] @@ -672,7 +672,7 @@ def _get_type_annotations(self) -> None: attr_name ].schema_json() - model = pydantic.create_model(self.__class__.__name__, **_models) + model = create_model(self.__class__.__name__, **_models) self._pydantic_models["all"] = model def execute_exported_command(self, cmd_name: str, args: Dict[str, Any]) -> Any: diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py index 63572b4d4a..91d3a0a0e8 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py @@ -6,7 +6,7 @@ import gevent from typing_extensions import Literal -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from devtools import debug from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py index 350002fea1..2d78ef104e 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py @@ -2,7 +2,7 @@ from typing_extensions import Literal -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from devtools import debug from mxcubecore.model.common import ( diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py index 600d8214a8..36c459094d 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py @@ -3,7 +3,7 @@ import contextlib import enum import subprocess -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from devtools import debug from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py index 620c71ce4f..a43e777851 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py @@ -2,7 +2,7 @@ import time import enum -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from devtools import debug from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py index de378d9acb..8ae771c4d4 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py @@ -3,7 +3,7 @@ from typing_extensions import Literal -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from devtools import debug from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/GenericDiffractometer.py b/mxcubecore/HardwareObjects/GenericDiffractometer.py index 30ffe35d19..b139d7cc92 100755 --- a/mxcubecore/HardwareObjects/GenericDiffractometer.py +++ b/mxcubecore/HardwareObjects/GenericDiffractometer.py @@ -33,7 +33,7 @@ import enum from typing import List, Tuple, Union, Dict -from pydantic import BaseModel, Field, ValidationError +from pydantic.v1 import BaseModel, Field, ValidationError from mxcubecore.HardwareObjects import sample_centring from mxcubecore.model import queue_model_objects diff --git a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py index 79e9c222d6..4e19e8e9fc 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py @@ -1,6 +1,6 @@ from typing_extensions import Literal -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from mxcubecore.HardwareObjects.BeamlineActions import ( BeamlineActions, AnnotatedCommand, diff --git a/mxcubecore/model/common.py b/mxcubecore/model/common.py index 1cf6375979..3517fc290d 100644 --- a/mxcubecore/model/common.py +++ b/mxcubecore/model/common.py @@ -1,6 +1,6 @@ from datetime import datetime from typing import Optional -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field class CommonCollectionParamters(BaseModel): diff --git a/mxcubecore/model/configmodel.py b/mxcubecore/model/configmodel.py index f82fbc11c2..a014abbcb0 100644 --- a/mxcubecore/model/configmodel.py +++ b/mxcubecore/model/configmodel.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field class ExporterNStateConfigModel(BaseModel): diff --git a/mxcubecore/model/procedure_model.py b/mxcubecore/model/procedure_model.py index ea3717c0e2..796c3b9559 100644 --- a/mxcubecore/model/procedure_model.py +++ b/mxcubecore/model/procedure_model.py @@ -1,14 +1,13 @@ # -*- coding: utf-8 -*- -import pydantic -from pydantic import Field +from pydantic.v1 import BaseModel, Field class ValidationError(Exception): pass -class BaseModel(pydantic.BaseModel): +class BaseModel(BaseModel): def __init__(self, *args, **kwargs): try: super(BaseModel, self).__init__(*args, **kwargs) diff --git a/mxcubecore/queue_entry/test_collection.py b/mxcubecore/queue_entry/test_collection.py index ca23ffe981..63f6a9a280 100644 --- a/mxcubecore/queue_entry/test_collection.py +++ b/mxcubecore/queue_entry/test_collection.py @@ -1,6 +1,6 @@ import json -from pydantic import BaseModel, Field +from pydantic.v1 import BaseModel, Field from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry from mxcubecore.model.common import ( From efa4d9c48630c5fb7749c1e0abcc0994ba78a029 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 17 Sep 2024 14:01:49 +0200 Subject: [PATCH 053/172] Updated pydantic --- poetry.lock | 87 +++++++++++++++++++++++++++----------------------- pyproject.toml | 2 +- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/poetry.lock b/poetry.lock index b26f4bd056..772d55d5e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "alabaster" @@ -1405,11 +1405,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, ] [[package]] @@ -1636,47 +1636,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.13" +version = "1.10.18" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, + {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, + {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, + {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, + {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, + {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, + {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, + {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, + {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, + {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, + {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, + {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, + {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, + {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, + {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, + {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, + {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, + {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, + {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, + {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, + {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, + {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, + {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, + {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, + {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, + {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, + {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, + {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, + {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, + {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, + {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, + {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, + {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, + {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, + {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, + {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, + {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, + {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, + {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, + {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, + {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, + {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, + {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, ] [package.dependencies] @@ -2580,4 +2587,4 @@ tango = ["PyTango"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "3ae500c49ba9c9893d12bcdf6a3a14b7f0e06811f9fd509c07a41254d0f6dd26" +content-hash = "da2aa65f120456f20e6db67223867645be071600f59ea36e2f8bc65c5916e9e5" diff --git a/pyproject.toml b/pyproject.toml index 9a5cec111a..1c280d360f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ lxml = "^4.9.1" matplotlib = "^3.6.2" numpy = "^1.23.5" Pillow = "^9.3.0" -pydantic = "^1.10.2" +pydantic = "^1.10.18" PyDispatcher = "^2.0.6" "ruamel.yaml" = "^0.17.21" scipy = "^1.9.3" From 97e64584a1f321e5a6c3cd7b78e7b74b772b69bf Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 18 Sep 2024 09:19:49 +0000 Subject: [PATCH 054/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1c280d360f..5d14da8bf7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.153.0" +version = "1.154.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 65b1523970fe1dd4c2415510055e81be9b5c5eff Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 16 Sep 2024 14:06:21 +0200 Subject: [PATCH 055/172] actions: notify teams upon new discussion in category --- .github/workflows/discussions.yml | 90 +++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 .github/workflows/discussions.yml diff --git a/.github/workflows/discussions.yml b/.github/workflows/discussions.yml new file mode 100644 index 0000000000..9655b49d48 --- /dev/null +++ b/.github/workflows/discussions.yml @@ -0,0 +1,90 @@ +--- +# This workflow notifies working groups about new discussions in their corresponding +# categories, by mentioning the Team in a first comment. +# It is necessary since GitHub doesn't support subsriptions to discussion categories +# see related feature request: https://github.com/orgs/community/discussions/3951 +# If GitHub implements this feature, this workflow becomes obsolete. + +# To work, this workflow requires a GitHub App installed on the repository with the +# following permissions: +# - Write and Read of repository Discussions +# - Read of Organization members (needed for reading the teams) + +# !! You need to make sure that the app's id and a generated private key are saved +# as corresponding organization secrets !! + +name: Notify Team on New Discussion +"on": + discussion: + types: [created] + +jobs: + notify_team: + runs-on: ubuntu-latest + steps: + # First generate the app token for authentication + - name: Get GitHub App token + id: github-app-token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Notify Team + uses: actions/github-script@v7 + with: + github-token: ${{ steps.github-app-token.outputs.token }} + script: | + const discussion = context.payload.discussion; + const category = discussion.category.name; + + const query = ` + query($discussionNumber: Int!) { + repository( + owner: "${context.repo.owner}", + name: "${context.repo.repo}" + ) { + discussion(number: $discussionNumber) { + id + } + } + } + `; + + const mutation = ` + mutation($discussionId: ID!, $body: String!) { + addDiscussionComment( + input: {discussionId: $discussionId, body: $body} + ) { + comment { + id + body + } + } + } + `; + + const response = await github.graphql(query, { + discussionNumber: discussion.number + }); + + const discussionId = response.repository.discussion.id; + + const teams = await github.rest.teams.list({ + org: context.repo.owner, + }); + + const team = teams.data.find(t => t.name === category); + + if (team) { + const teamMention = `${context.repo.owner}/${team.slug}`; + const commentBody = `@${teamMention} A new discussion was created in the` + + ` "${category}" category: ${discussion.html_url}`; + + await github.graphql(mutation, { + discussionId: discussionId, + body: commentBody + }); + } else { + console.log(`No team found for category: ${category}`); + } From dfb3ce4154a0f7ddeb2d72f9474e0661261de948 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 18 Sep 2024 13:58:27 +0000 Subject: [PATCH 056/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5d14da8bf7..ce6fffc82d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.154.0" +version = "1.155.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 3c9a254a159a87a92679bc4d25c1b8327b635933 Mon Sep 17 00:00:00 2001 From: FLorial Jean Baptiste Date: Mon, 23 Sep 2024 19:27:02 +0200 Subject: [PATCH 057/172] [type hint] fix for Python 3.8 incompatible typehints --- mxcubecore/HardwareObjects/Harvester.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index 870d800e39..8b97d9ced1 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -40,6 +40,7 @@ ----------------------------------------------------------------- """ +from __future__ import annotations import gevent import logging from typing import Optional From 8e498c223e70267a7bc343f79ef95a598cb67c1d Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 26 Sep 2024 09:30:11 +0000 Subject: [PATCH 058/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ce6fffc82d..f9f6e8bcde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.155.0" +version = "1.156.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 9d89967cf8cb56ecebd290b7738ba4398b758338 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 19 Sep 2024 09:38:16 +0200 Subject: [PATCH 059/172] Bumped Pydantic to 2.x --- poetry.lock | 185 ++++++++++++++++++++++++++++++++++--------------- pyproject.toml | 2 +- 2 files changed, 131 insertions(+), 56 deletions(-) diff --git a/poetry.lock b/poetry.lock index 772d55d5e1..2750956434 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,6 +11,20 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "astroid" version = "2.15.5" @@ -1636,62 +1650,123 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" +version = "2.8.2" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydispatcher" @@ -2372,13 +2447,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.3.0" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, - {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -2587,4 +2662,4 @@ tango = ["PyTango"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "da2aa65f120456f20e6db67223867645be071600f59ea36e2f8bc65c5916e9e5" +content-hash = "5eb30152deba32472c5d3c847505077cd2596993f5518dd32f8911f2c983afc3" diff --git a/pyproject.toml b/pyproject.toml index f9f6e8bcde..73a986201a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ lxml = "^4.9.1" matplotlib = "^3.6.2" numpy = "^1.23.5" Pillow = "^9.3.0" -pydantic = "^1.10.18" +pydantic = ">=2.8.2,<2.9.0" PyDispatcher = "^2.0.6" "ruamel.yaml" = "^0.17.21" scipy = "^1.9.3" From 2c089b08d363d2ee51a1686fc3f15f7c85d2670d Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 27 Sep 2024 07:30:24 +0000 Subject: [PATCH 060/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 73a986201a..0c5cfafb7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.156.0" +version = "1.157.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 41b02baf56a3d1f5de7f35b122e753a832e8fc7f Mon Sep 17 00:00:00 2001 From: rhfogh Date: Tue, 17 Sep 2024 09:51:06 +0100 Subject: [PATCH 061/172] Added workflow parameter IDs for ESRF workflow automation --- .../HardwareObjects/Gphl/GphlWorkflow.py | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 96026d05fd..27300bf32d 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -33,6 +33,7 @@ import math import subprocess import socket +import uuid from collections import OrderedDict import gevent @@ -1689,6 +1690,10 @@ def setup_data_collection(self, payload, correlation_id): rotation_settings = dict( (role, current_pos_dict[role]) for role in sweepSetting.axisSettings ) + orientation_id = gphl_workflow_model.workflow_params.get("orientation_id") + if orientation_id: + # We have a pre-existing orientation ID. Use it + rotation_settings["id_"] = orientation_id newRotation = GphlMessages.GoniostatRotation(**rotation_settings) translation_settings = dict( (role, current_pos_dict.get(role)) @@ -1974,7 +1979,7 @@ def collect_data(self, payload, correlation_id): # Handle orientations and (re) centring goniostatRotation = sweep.goniostatSweepSetting - rotation_id = goniostatRotation.id_ + rotation_id = orientation_id = goniostatRotation.id_ initial_settings = sweep.get_initial_settings() orientation = ( initial_settings.get("kappa"), initial_settings.get( "kappa_phi") @@ -1994,12 +1999,13 @@ def collect_data(self, payload, correlation_id): rotation_id == gphl_workflow_model.current_rotation_id or (0 <= maxdev < angular_tolerance) ): - # Use same postion as previous sweep, set only omega start + # Use same position as previous sweep, set only omega start acq_parameters.centred_position = queue_model_objects.CentredPosition( {goniostatRotation.scanAxis: scan.start} ) + orientation_id = gphl_workflow_model.current_rotation_id else: - # New sweep, or recentriong_mode == scan + # New sweep, or recentring_mode == scan # # We need to recentre # Put centring on queue and collect using the resulting position # NB this means that the actual translational axis positions @@ -2035,6 +2041,28 @@ def collect_data(self, payload, correlation_id): - sweep_offset ) data_collection = queue_model_objects.DataCollection([acq], crystal) + # Workflow parameters for ICAT / external workflow + # The 'if' statement is to allow this to work in multiple versions + if hasattr(data_collection, "workflow_params"): + wfp = gphl_workflow_model.workflow_params + if not wfp.get("workflow_name"): + wfp["workflow_name"] = gphl_workflow_model.wfname + if not wfp.get("workflow_type"): + wfp["workflow_type"] = gphl_workflow_model.wftype + if not wfp.get("workflow_uid"): + wfp["workflow_uid"] = HWR.beamline.gphl_connection._enactment_id + if not wfp.get("position_id"): + # As of 20240911 all workflows use a single position, + wfp["position_id"] = str(uuid.uuid1()) + if ( + gphl_workflow_model.wftype == "acquisition" + and not gphl_workflow_model.characterisation_done + and not wfp.get("characterisation_id") + ): + wfp["characterisation_id"] = sweep.id_ + wfp["orientation_id"] = orientation_id + data_collection.workflow_params.update(wfp) + data_collections.append(data_collection) data_collection.set_enabled(True) From bd7ba7a4ddd9c437f0f887edd30f6e669435f564 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Tue, 17 Sep 2024 09:52:41 +0100 Subject: [PATCH 062/172] Added workflow parameter IDs for ESRF workflow automation, part 2 --- mxcubecore/model/queue_model_objects.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 407dd70b20..928668a812 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -2022,6 +2022,9 @@ def __init__(self): self.acquisition_dose = 0.0 self.strategy_length = 0.0 + # Workflow attributes - for passing to LIMS (conf Olof Svensson) + self.workflow_params = {} + # # Centring handling and MXCuBE-side flow self.set_requires_centring(False) @@ -2329,6 +2332,11 @@ def init_from_task_data(self, sample_model, params): if value: setattr(self, tag, value) + # For external workflow parameters (conf. Olof Svensson) + dd1 = params.get("workflow_params") + if dd1: + self.workflow_params.update(dd1) + settings = HWR.beamline.gphl_workflow.settings # NB settings is an internal attribute DO NOT MODIFY From 4547d28c87a2203dbab60d5e1095ecaec646a17d Mon Sep 17 00:00:00 2001 From: rhfogh Date: Mon, 23 Sep 2024 12:51:46 +0100 Subject: [PATCH 063/172] Now correct fix for recentring='none' bug --- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 27300bf32d..b1fc8ec07e 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -1615,6 +1615,7 @@ def setup_data_collection(self, payload, correlation_id): ) self._latest_translation_id = translation.id_ self._recentrings.append(translation) + goniostatTranslations.append(translation) # Update current position current_okp = tuple( current_pos_dict[role] for role in self.rotation_axis_roles @@ -1658,16 +1659,19 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = sweepSetting.id_ + goniostatTranslations.append(translation) else: if recentring_mode == "none": if has_recentring_file: - # NB if no recentring but MiniKappaCorrection this still OK + # If we have recentring use it + # If not, never mind, presumably we have MiniKappaCorrescion translation = GphlMessages.GoniostatTranslation( rotation=sweepSetting, **translation_settings ) - self._latest_translation_id = None + goniostatTranslations.append(translation) + self._latest_translation_id = None else: if has_recentring_file: settings.update(translation_settings) @@ -1676,6 +1680,7 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = sweepSetting.id_ + goniostatTranslations.append(translation) if recentring_mode == "start": # We want snapshots in this mode, # and the first sweepmis skipped in the loop below @@ -1707,7 +1712,7 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = newRotation.id_ - goniostatTranslations.append(translation) + goniostatTranslations.append(translation) # calculate or determine centring for remaining sweeps for sweepSetting in sweepSettings[1:]: From c3620f5844f8cd2a7e755d832e96a77646f6ac23 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 30 Sep 2024 08:35:05 +0000 Subject: [PATCH 064/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0c5cfafb7d..2c3448e877 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.157.0" +version = "1.158.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 7bb08e595754b212647e6337f8310d898a1cf0f2 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 27 Sep 2024 09:44:36 +0200 Subject: [PATCH 065/172] Bumped pillow --- poetry.lock | 158 +++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 89 insertions(+), 71 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2750956434..6d25f46cab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1439,82 +1439,100 @@ files = [ [[package]] name = "pillow" -version = "9.5.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] [[package]] name = "pkgutil-resolve-name" @@ -2662,4 +2680,4 @@ tango = ["PyTango"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "5eb30152deba32472c5d3c847505077cd2596993f5518dd32f8911f2c983afc3" +content-hash = "e8967226a541e8f1dfce6a91a64413149c1c410377b2b43aa5178802a40cdd47" diff --git a/pyproject.toml b/pyproject.toml index 2c3448e877..f60a3a7de3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ jsonschema = "^4.17.1" lxml = "^4.9.1" matplotlib = "^3.6.2" numpy = "^1.23.5" -Pillow = "^9.3.0" +Pillow = "^10.4.0" pydantic = ">=2.8.2,<2.9.0" PyDispatcher = "^2.0.6" "ruamel.yaml" = "^0.17.21" From 672e428dfca3d1111f952b669109f72ca02d3131 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 30 Sep 2024 12:52:11 +0000 Subject: [PATCH 066/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f60a3a7de3..ed00e41ba6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.158.0" +version = "1.159.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 645330c802161ecb38d67a1f9d8844008f8f1515 Mon Sep 17 00:00:00 2001 From: agruzinov <78498907+agruzinov@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:49:38 +0200 Subject: [PATCH 067/172] P11 char (#966) * Set energy within the tolerance * Added handling of progress bar during data collection * EDNA startup tests at P11 * Added waiting for resulting ENDA xml output for characterisation. * Black * Add more explicit omega_wait_on function in P11NanoDiff * Patched recursion error in MotorsNPositon used at P11. * Black * Refactor move motors in P11NanoDiff. Avoid as_dict none error. * Refactor move motors in P11NanoDiff. Avoid waiting before move is done. * Refactoring of characterisation. Move MOSFLM to P11EDNACharacterisation. Simplified edna_maxwell() * EDNA folders check - separate creation of char and rotational dirs (all based on xds_dir). * Revisit path conversion for EDNA xml * Updated latest local changes to the EDNA CHaracterisation * Put the xdsapp start in the separate function * Added maschine info class (WIP) * Added flux estimation using tabulated values (temporary plug for EDNA tests) * Added transmission to the log * Data processing is fixed by duplicationg h5 header info from the CC * Added info.txt prototype from CC * Added function returning string of beam focus for info.txt * Added writing info.txt similar to CC * Fixed failing Diffraction plan execution due to the path mismatch * Beam current simulation for EDNA * Added get current from mach_info to info.txt * Cleanup * Added the reading of machine parameters * Code cleanup. Adding the filter thickness into the info.txt in mm * Code cleanup * Black * Fix image_interval in info.txt * Removed debug print * Removed unused genxdsinp function. Moved to the start script. * Added additional check for the waiting untill NanoDiff is ready * Make sure that debug directory is created * Increased timeout for EDNA output waiting * Added additional robot actions * Debug of data collection * Added explicit wait for teh arm command * Added maxwell processing for autoproc * Test debugs * Increased a bit delay for a debuggingh data collection * Black * Black * Suppress multy wedge data collection (GB) in characterisation * Added explicit remeasure of the flux for raddose before starting characterisation * Add writing the info about autoproc for presenterd in datasets.txt * Addeed writing path to EDNA for presenterd * Rewverted back the delay to 0.003 * Added prototype for the angle calibration. To be checked with beam. * Adapted data collection from CC. Moved goniometer-related code to the P11NanoDiff including xml files changes. * Added additional status check for the detector distance * Removed function that is now in P11NanoDiff * Added the changes to make it work again after Device class deprecation (see PR#940 - attemt to solve issue 902) * Linting * Change init (PR966) * Change init in P11Session (PR966) * Removed Hardwareobject inheritance in MjpgStreamVideo (PR966) * Removed unnnessesary self.is_ready() after update (PR966) * Black * Update of the P11Beam after rebase and update of the AbstractBeam * Update * Changes according to the suggestions in PR966 * Removed typo AbstractCollect * P11Beam updates (PR#966) * Removed duplicatons (PR#966) * Moved energy chack logick to P11Energy (PR#966) * Removed return (PR#966) * Explicit int() conversion for the mouse click coordinates in teh centring after python 3.10 upgrade * Removed commented code * Removed commented code * Black * Adressing the function return issue (PR#966) * Black * Revovin evaluate_beam_info after properly writing beam sizes as list and not as tuple (PR#966) * Fixing NanoDiff centring issues * Reimplemented Maschine Info using TangoMaschineInfo (PR#966) * Removed the unused code (PR#966) * Removed the unnessesary line (PR#966) * Added update_state call after the state is ready * Added usage of default_values and docstrings update (PR#966) * Added properly formatted docstrings * Fixed display of proposal in case ISPyB is not available * Updated the file header according to the recent py_file_header without dates * Black and additional header update * Changed P11Pinhole to use Nstate * Add P11 beamstop, collimator and yag using NState. To be tested. * Update of the P11NanoDiff to use get_value instead of _get_positions (migrate MotorsNPosition to Nstate, PR#966) * Black * Refactor collimator to be an instance of AbstractNState class (PR#966) * Added implementation of P11Beamstop as AbstractNState instead of MotorNState PR#966 * Added Diode-Yag stage implementation as AbstractNState (PR#966) * Corrected P11NanoDiff initially to test reimplemetation of beamline componeneta as AbstractNState * Removed setting omega to 0 during the centring phase in P11NanoDiff * Refactoring to use AbstractNState for Pinholes,Yag and Collimator * Refactoring and corresponding updates in P11NanoDiff to work with new objects * Linting * Typo fix in TangoMotor * Fixed the waiting phase during components move after refactoring (PR#966) * Fixes of qt-related parts after refactoring PR#966 * Added initial handling of DoorInterlock * Moved url to the properties * fixing the write info for screening. Reverting back the line removed during the work on PR#966 * Quick fix for the manual centring for now (reverted). To be investigated. * Update the MultiNState for revisiting the recursion problem and value return (PR#966). * Added the py_header info into the files * Removed phiz from the centring tower movement in P11NanoDiff * Code cleanup * Added info comments for the GUI during phase changes * Cleanup * Cleanup * Added position return function to work with qt multi-state brick * Removed the moving yag down during initialization * Black * Added proper logging * Preliminary update of the MachineInfo to make it work with qt * Linting * Modify so it works with qt mach info brick * P11MachInfo cleanup * Change to 3s update * Changes to fix the detector misfires in P11Collect characterisation * Fixed the unable to start session if the beamtime file is not created - no beamtime. * P11Session code cleanup --------- Co-authored-by: Andrey Gruzinov --- mxcubecore/HardwareObjects/DESY/Centring.py | 3 +- .../HardwareObjects/DESY/DigitalZoomMotor.py | 10 +- .../HardwareObjects/DESY/MjpgStreamVideo.py | 9 +- .../HardwareObjects/DESY/P11AlbulaView.py | 10 +- .../HardwareObjects/DESY/P11BackLight.py | 4 +- mxcubecore/HardwareObjects/DESY/P11Beam.py | 86 +- .../HardwareObjects/DESY/P11BeamStop.py | 123 ++ mxcubecore/HardwareObjects/DESY/P11Collect.py | 1296 +++++++++-------- .../HardwareObjects/DESY/P11Collimator.py | 140 ++ .../HardwareObjects/DESY/P11DetectorCover.py | 4 +- .../DESY/P11DetectorDistance.py | 17 +- .../HardwareObjects/DESY/P11DoorInterlock.py | 87 ++ .../DESY/P11EDNACharacterisation.py | 473 +++++- .../HardwareObjects/DESY/P11EigerDetector.py | 9 +- mxcubecore/HardwareObjects/DESY/P11Energy.py | 20 +- .../HardwareObjects/DESY/P11FastShutter.py | 5 +- mxcubecore/HardwareObjects/DESY/P11Flux.py | 155 +- .../HardwareObjects/DESY/P11ISPyBClient.py | 60 + .../HardwareObjects/DESY/P11MachineInfo.py | 136 ++ .../HardwareObjects/DESY/P11NanoDiff.py | 604 ++++---- mxcubecore/HardwareObjects/DESY/P11Pinhole.py | 157 +- .../HardwareObjects/DESY/P11SampleChanger.py | 41 +- mxcubecore/HardwareObjects/DESY/P11Session.py | 66 +- mxcubecore/HardwareObjects/DESY/P11Shutter.py | 5 +- .../HardwareObjects/DESY/P11Transmission.py | 96 +- .../HardwareObjects/DESY/P11YagDiode.py | 122 ++ mxcubecore/HardwareObjects/DESY/P11Zoom.py | 12 +- .../HardwareObjects/DESY/ValueStateChannel.py | 8 +- mxcubecore/HardwareObjects/MotorsNPosition.py | 66 +- mxcubecore/HardwareObjects/QtGraphicsLib.py | 8 +- mxcubecore/HardwareObjects/TangoMotor.py | 4 +- mxcubecore/queue_entry/__init__.py | 4 +- mxcubecore/queue_entry/advanced_connector.py | 4 +- mxcubecore/queue_entry/characterisation.py | 11 +- mxcubecore/queue_entry/optical_centring.py | 4 +- mxcubecore/queue_entry/sample_centring.py | 4 +- mxcubecore/queue_entry/test_collection.py | 4 +- mxcubecore/queue_entry/xray_centering.py | 4 +- mxcubecore/queue_entry/xray_centering2.py | 4 +- 39 files changed, 2678 insertions(+), 1197 deletions(-) create mode 100644 mxcubecore/HardwareObjects/DESY/P11BeamStop.py create mode 100644 mxcubecore/HardwareObjects/DESY/P11Collimator.py create mode 100644 mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py create mode 100644 mxcubecore/HardwareObjects/DESY/P11MachineInfo.py create mode 100644 mxcubecore/HardwareObjects/DESY/P11YagDiode.py diff --git a/mxcubecore/HardwareObjects/DESY/Centring.py b/mxcubecore/HardwareObjects/DESY/Centring.py index 961b71c45b..bd03fdd2e5 100644 --- a/mxcubecore/HardwareObjects/DESY/Centring.py +++ b/mxcubecore/HardwareObjects/DESY/Centring.py @@ -18,7 +18,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" @@ -64,7 +64,6 @@ def init(self): print("-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+") def initCentringProcedure(self): - print("initCentringProcedure(self)") """ Descript. : call before starting rotate-click sequence diff --git a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py index 4f7d00f8a8..bdcbfddad1 100644 --- a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py +++ b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,11 +18,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . - +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" __author__ = "Jan Meyer" __email__ = "jan.meyer@desy.de" -__copyright__ = "(c)2016 DESY, FS-PE, P11" -__license__ = "GPL" import logging @@ -30,7 +30,7 @@ from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates -class DigitalZoomMotor(AbstractMotor, Device): +class DigitalZoomMotor(AbstractMotor, HardwareObject): """ Works with camera devices which provide zoom_exists, set_zoom, get_zoom and get_zoom_min_max @@ -72,8 +72,6 @@ def init(self): "DigitalZoomMotor: digital zoom is not supported " "by camera object" ) - self.set_is_ready(self.get_state() == MotorStates.READY) - def update_state(self): """ Descript. : forces position update diff --git a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py index dfa9d005d1..baec00edc4 100644 --- a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py +++ b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,10 +18,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" __author__ = "Jan Meyer" __email__ = "jan.meyer@desy.de" -__copyright__ = "(c)2015 DESY, FS-PE, P11" -__license__ = "GPL" import gevent @@ -46,7 +47,7 @@ from mxcubecore.BaseHardwareObjects import HardwareObject -class MjpgStreamVideo(AbstractVideoDevice, Device): +class MjpgStreamVideo(AbstractVideoDevice): """ Hardware object to capture images using mjpg-streamer and it's input_avt.so plugin for AVT Prosilica cameras. @@ -333,7 +334,7 @@ def init(self): sensor_height = int(sensor_info["value"]) self.sensor_dimensions = (sensor_width, sensor_height) - self.set_is_ready(True) + # self.is_ready() self.set_zoom(0) # overview camera def http_get(self, query, host=None, port=None, path=None): diff --git a/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py b/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py index 8d51ebb028..c3c28dc2ab 100644 --- a/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py +++ b/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py @@ -18,11 +18,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -from mxcubecore.BaseHardwareObjects import HardwareObject - -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" +from mxcubecore.BaseHardwareObjects import HardwareObject import sys import time @@ -38,12 +37,10 @@ class P11AlbulaView(HardwareObject): - default_interval = 0.5 # secs stoptimer = -1.0 def init(self): - self.alive = False self.stream = False self.viewer = None @@ -102,7 +99,6 @@ def start(self, path=None, filetype=None, interval=None, stream=False): super().start() def stop(self, interval=0.0): - if self.stoptimer < 0.0 and interval > 0.0: self.stoptimer = interval return @@ -133,7 +129,6 @@ def run(self): self.alive = True while self.alive: - # hdf5 wavelength = 12398.4 / energy @@ -225,7 +220,6 @@ def run(self): if __name__ == "__main__": - lv = LiveView() lv.start() time.sleep(200) diff --git a/mxcubecore/HardwareObjects/DESY/P11BackLight.py b/mxcubecore/HardwareObjects/DESY/P11BackLight.py index 2dc8117446..bc541bffcf 100644 --- a/mxcubecore/HardwareObjects/DESY/P11BackLight.py +++ b/mxcubecore/HardwareObjects/DESY/P11BackLight.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,7 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11Shutter""" +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" from enum import Enum, unique from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState diff --git a/mxcubecore/HardwareObjects/DESY/P11Beam.py b/mxcubecore/HardwareObjects/DESY/P11Beam.py index 318911d1fa..ab5560d065 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Beam.py +++ b/mxcubecore/HardwareObjects/DESY/P11Beam.py @@ -1,3 +1,5 @@ +# encoding: utf-8 +# # Project: MXCuBE # https://github.com/mxcube # @@ -16,36 +18,33 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11Beam""" +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" +__credits__ = ["DESY P11"] +__category__ = "General" from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam +from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape from mxcubecore.BaseHardwareObjects import HardwareObjectState - - -__credits__ = ["DESY P11"] -__license__ = "LGPLv3+" -__category__ = "General" +import numpy as np class P11Beam(AbstractBeam): - def __init__(self, *args): - super().__init__(*args) - - self._beam_size_dict = {"aperture": [9999, 9999], "slits": [9999, 9999]} + def init(self): + self.pinhole_hwobj = self.get_object_by_role("pinhole") self._beam_position_on_screen = [340, 256] self.focus_sizes = { - -1: {"label": "unknown", "size": (0.2, 0.2)}, - 0: {"label": "flat", "size": (0.2, 0.2)}, - 1: {"label": "200x200", "size": (0.2, 0.2)}, - 2: {"label": "100x100", "size": (0.1, 0.1)}, - 3: {"label": "50x50", "size": (0.05, 0.05)}, - 4: {"label": "20x20", "size": (0.02, 0.02)}, - 5: {"label": "4x9", "size": (0.009, 0.004)}, + -1: {"label": "unknown", "size": [0.2, 0.2]}, + 0: {"label": "flat", "size": [0.2, 0.2]}, + 1: {"label": "200x200", "size": [0.2, 0.2]}, + 2: {"label": "100x100", "size": [0.1, 0.1]}, + 3: {"label": "50x50", "size": [0.05, 0.05]}, + 4: {"label": "20x20", "size": [0.02, 0.02]}, + 5: {"label": "4x9", "size": [0.009, 0.004]}, } - def init(self): self.mirror_idx_ch = self.get_channel_object("beamsize") self.mirror_state_ch = self.get_channel_object("state") @@ -57,18 +56,45 @@ def init(self): self.mirror_idx_changed() self.mirror_state_changed() + def get_available_size(self): + """Returns available beam sizes based on the current configuration.""" + return {"type": ["focus"], "values": [self.focus_sizes]} + + def get_defined_beam_size(self): + """Implements the abstract method to return defined beam sizes.""" + return { + "label": [item["label"] for item in self.focus_sizes.values()], + "size": [item["size"] for item in self.focus_sizes.values()], + } + + def set_value(self, size=None): + """Implements the abstract method to set the beam size.""" + if isinstance(size, list): + self._beam_width, self._beam_height = size + elif isinstance(size, str): + matching_size = next( + (v for k, v in self.focus_sizes.items() if v["label"] == size), None + ) + if matching_size: + self._beam_width, self._beam_height = matching_size["size"] + self.evaluate_beam_info() + + def set_beam_position_on_screen(self, beam_x_y): + """Sets the beam position on the screen.""" + self._beam_position_on_screen = beam_x_y + self.re_emit_values() + def get_beam_info_state(self): if self.mirror_state_ch is not None: tango_state = self.mirror_state_ch.get_value() return self._convert_tango_state(tango_state) - return self.STATES_READY + return self.STATES.READY def get_slits_gap(self): return None, None def mirror_state_changed(self, state=None): - if state is None: state = self.get_beam_info_state() @@ -86,7 +112,6 @@ def _convert_tango_state(self, state): return _state def mirror_idx_changed(self, value=None): - if value is None: value = self.mirror_idx_ch.get_value() @@ -105,3 +130,22 @@ def mirror_idx_changed(self, value=None): self.evaluate_beam_info() self.re_emit_values() + + def get_pinhole_size(self): + # Keep it default as the pinhole and beamsize interaction is locked for now + return 200 + + def get_beam_focus_label(self): + + value = self.mirror_idx_ch.get_value() + + if value not in self.focus_sizes: + value = -1 + return "UNKNOWN mirror index" + else: + curr_size_item = self.focus_sizes[value] + self.log.debug( + f" current mirror focus is {curr_size_item['label']}: {curr_size_item['size']}" + ) + + return curr_size_item["label"] diff --git a/mxcubecore/HardwareObjects/DESY/P11BeamStop.py b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py new file mode 100644 index 0000000000..0e73c67084 --- /dev/null +++ b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py @@ -0,0 +1,123 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +from mxcubecore.HardwareObjects.NState import NState +from mxcubecore.BaseHardwareObjects import HardwareObjectState +import ast +import time + + +class P11BeamStop(NState): + default_delta = 0.1 + + def init(self): + """Initialize the BeamStop motors and load positions.""" + super().init() + + self.x_motor = self.get_object_by_role("bstopx") + + self.load_positions() + self.load_deltas() + + self.log.debug(f"Beamstop X Motor initialized: {self.x_motor}") + self.log.debug(f"Beamstop Y Motor not used") + self.log.debug(f"Beamstop Z Motor not used") + + def load_positions(self): + """Load predefined positions from the XML configuration.""" + self.log.info("Loading BeamStop positions from config") + positions_str = self.get_property("values") + + if not positions_str: + self.log.error( + "No values for BeamStop positions found in the configuration." + ) + raise ValueError("No BeamStop positions found in configuration") + + # Convert the string to a dictionary using ast.literal_eval + try: + self.positions = ast.literal_eval(positions_str) + if isinstance(self.positions, dict): + self.log.info(f"Available BeamStop positions: {self.positions}") + else: + raise ValueError("Positions data is not a dictionary") + except (SyntaxError, ValueError) as e: + self.log.error(f"Error parsing BeamStop positions: {e}") + raise ValueError("Invalid BeamStop positions format in the configuration.") + + def load_deltas(self): + """Load individual motor deltas from the XML configuration explicitly.""" + self.log.info("Loading deltas from config") + + # Fetch individual deltas for each motor + delta_bstopx = self.get_property("delta_bstopx") + + # If a delta is not specified, fallback to a default delta value + self.deltas = { + "bstopx": float(delta_bstopx) + if delta_bstopx is not None + else self.default_delta, + } + + # Log the deltas for each motor + for motorname, delta in self.deltas.items(): + self.log.info(f"Delta for {motorname}: {delta}") + + def set_value(self, value): + """Move the BeamStop motors to the given position.""" + if value not in self.positions: + raise ValueError(f"Invalid value {value}, not in available positions") + + position = self.positions[value] + + self.x_motor._set_value(position.get("bstopx")) + + def get_value(self): + """Get the current BeamStop position based on the motor positions.""" + current_x = self.x_motor.get_value() + + for position_name, position in self.positions.items(): + if self.is_within_deltas(position.get("bstopx"), current_x, "bstopx"): + return position_name # Return the matching position name + + def is_within_deltas(self, target_value, current_value, motor_name): + """Check if the current motor position is within the delta tolerance for that specific motor.""" + delta = self.deltas.get(motor_name) + if target_value is None or delta is None: + return False + return abs(current_value - target_value) <= delta + + def get_position_list(self): + """Return a list of available positions.""" + return list(self.positions.keys()) + + def wait_for_position(self): + """Wait for motors to reach their target positions.""" + while any(motor.get_state() != "ON" for motor in [self.x_motor]): + time.sleep(0.1) + + def is_moving(self): + """ + Descript. : True if the motor is currently moving + """ + return self.get_state() == HardwareObjectState.BUSY diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index f461489842..c675409161 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -18,10 +18,9 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" - import errno import socket import time @@ -33,8 +32,7 @@ import numpy as np import psutil import subprocess -import time - +import gevent from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect from mxcubecore import HardwareRepository as HWR @@ -49,50 +47,37 @@ def __init__(self, *args): super().__init__(*args) def init(self): - + """Initializes beamline collection parameters like default speed and server names.""" super().init() - - self.default_speed = self.get_property("omega_default_speed", 130) - self.turnback_time = self.get_property("turnback_time", 0.3) + self.default_speed = 120 #self.get_property("omega_default_speed", 130) + self.turnback_time = 0.5# self.get_property("turnback_time", 0.3) self.filter_server_name = self.get_property("filterserver") self.mono_server_name = self.get_property("monoserver") self.filter_server = DeviceProxy(self.filter_server_name) self.mono_server = DeviceProxy(self.mono_server_name) - self.lower_bound_ch = self.get_channel_object("acq_lower_bound") - self.upper_bound_ch = self.get_channel_object("acq_upper_bound") - - self.acq_arm_cmd = self.get_command_object("acq_arm") - self.acq_on_cmd = self.get_command_object("acq_on") - self.acq_off_cmd = self.get_command_object("acq_off") - self.acq_window_off_cmd = self.get_command_object("acq_window_off") - self.latest_frames = None self.acq_speed = None - - if None in [ - self.lower_bound_ch, - self.upper_bound_ch, - self.acq_arm_cmd, - self.acq_on_cmd, - self.acq_off_cmd, - self.acq_window_off_cmd, - ]: - self.init_ok = False - self.log.debug("lower_bound_ch: %s" % self.lower_bound_ch) - self.log.debug("upper_bound_ch: %s" % self.upper_bound_ch) - self.log.debug("acq_arm_cmd: %s" % self.acq_arm_cmd) - self.log.debug("acq_on_cmd: %s" % self.acq_on_cmd) - self.log.debug("acq_off_cmd: %s" % self.acq_off_cmd) - self.log.debug("acq_window_off_cmd: %s" % self.acq_window_off_cmd) - else: - self.init_ok = True + self.total_angle_range = None @task def move_motors(self, motor_position_dict): + """Moves motors to the specified positions. + + Args: + motor_position_dict (dict): Dictionary containing motor positions. + """ HWR.beamline.diffractometer.move_motors(motor_position_dict) def _take_crystal_snapshot(self, filename): + """Takes a snapshot of the crystal and saves it to the given filename. + + Args: + filename (str): Path to save the crystal snapshot. + + Raises: + RuntimeError: If unable to move to the centring phase. + """ self.log.debug("#COLLECT# taking crystal snapshot.") if not HWR.beamline.diffractometer.is_centring_phase(): @@ -109,27 +94,38 @@ def _take_crystal_snapshot(self, filename): HWR.beamline.sample_view.save_snapshot(filename) def set_transmission(self, value): - """ - Descript. : + """Sets the transmission value on the beamline. + + Args: + value (float): Transmission value to set. """ HWR.beamline.transmission.set_value(value) def set_energy(self, value): - """ - Descript. : + """Sets the energy value on the beamline. + + Args: + value (float): Energy value to set. """ HWR.beamline.energy.set_value(value) - + def set_resolution(self, value): - """ - Descript. : + """Sets the resolution of the beamline. + + Args: + value (float): Resolution value to set. """ if round(HWR.beamline.resolution.get_value(), 2) != round(value, 2): HWR.beamline.resolution.set_value(value) def do_collect(self, owner): - """ - Actual collect sequence + """Performs the data collection sequence. + + Args: + owner: Owner of the current data collection. + + Raises: + RuntimeError: If collection preparation or execution fails. """ log = logging.getLogger("user_level_log") log.info("Collection: Preparing to collect") @@ -142,16 +138,12 @@ def do_collect(self, owner): self.collection_id = None try: - # ---------------------------------------------------------------- # Prepare data collection - self.open_detector_cover() self.open_safety_shutter() self.open_fast_shutter() - # ---------------------------------------------------------------- # Store information in LIMS - self.current_dc_parameters["status"] = "Running" self.current_dc_parameters["collection_start_time"] = time.strftime( "%Y-%m-%d %H:%M:%S" @@ -164,11 +156,6 @@ def do_collect(self, owner): log.info("Collection: Storing data collection in LIMS") self.store_data_collection_in_lims() - log.info( - "Collection: Creating directories for raw images and processing files" - ) - self.create_file_directories() - log.info("Collection: Getting sample info from parameters") self.get_sample_info() @@ -178,8 +165,6 @@ def do_collect(self, owner): if all( item is None for item in self.current_dc_parameters["motors"].values() ): - # No centring point defined - # create point based on the current position current_diffractometer_position = ( HWR.beamline.diffractometer.get_positions() ) @@ -188,17 +173,14 @@ def do_collect(self, owner): motor ] = current_diffractometer_position.get(motor) - # ---------------------------------------------------------------- # Move to the centered position and take crystal snapshots - log.info("Collection: Moving to centred position") self.move_to_centered_position() self.take_crystal_snapshots() self.move_to_centered_position() - # ---------------------------------------------------------------- + self.emit("progressStep", 2) # Set data collection parameters - if "transmission" in self.current_dc_parameters: log.info( "Collection: Setting transmission to %.2f", @@ -233,18 +215,8 @@ def do_collect(self, owner): ) self.move_detector(self.current_dc_parameters["detector_distance"]) - # ---------------------------------------------------------------- - # Site specific implementation of a data collection - - # In order to call the hook with original parameters - # before update_data_collection_in_lims changes them - # TODO check why this happens - self.data_collection_hook() - # ---------------------------------------------------------------- - # Store information in LIMS - log.info("Collection: Updating data collection in LIMS") self.update_data_collection_in_lims() @@ -257,11 +229,7 @@ def do_collect(self, owner): self.data_collection_cleanup() def data_collection_hook(self): - if not self.init_ok: - raise RuntimeError( - "P11Collect. - object initialization failed. COLLECTION not possible" - ) - + """Handles site-specific data collection processes.""" dc_pars = self.current_dc_parameters collection_type = dc_pars["experiment_type"] @@ -286,9 +254,13 @@ def data_collection_hook(self): exp_time = osc_pars["exposure_time"] self.acq_speed = img_range / exp_time + self.total_angle_range = abs(stop_angle - start_angle) + if not self.diffractometer_prepare_collection(): raise RuntimeError("Cannot prepare diffractometer for collection") + self.emit("progressStep", 5) + try: self.log.debug("############# #COLLECT# Opening detector cover") HWR.beamline.diffractometer.detector_cover_open(wait=True) @@ -303,7 +275,14 @@ def data_collection_hook(self): self.log.debug("#COLLECT# Programming detector for data collection") if collection_type == "Characterization": - # Filepath for the presenterd to work + + # Prepares metadata taken from current osc parameters. + self.prepare_characterization() + self.log.info( + "Collection: Creating directories for raw images and processing files EDNA and MOSFLM" + ) + self.create_characterisation_directories() + # Filepath for the presented data to work filepath = os.path.join( basepath, prefix, @@ -313,13 +292,6 @@ def data_collection_hook(self): + "%s_%d" % (prefix, runno), ) - # Filepath to the EDNA processing - # filepath = os.path.join(basepath,"%s_%d" % (prefix, runno)) - - # setting up xds_dir for characterisation (used there internally to create dirs) - self.current_dc_parameters["xds_dir"] = os.path.join( - basepath, "%s_%d" % (prefix, runno) - ) self.log.debug( "======= CURRENT FILEPATH: " @@ -349,8 +321,15 @@ def data_collection_hook(self): HWR.beamline.detector.prepare_characterisation( exp_time, nframes, angle_inc, filepath ) + else: - # Filepath to work with presenterd + # Prepares metadata taken from current osc parameters. + self.prepare_std_collection(start_angle, img_range) + self.log.info( + "Collection: Creating directories for raw images and processing files" + ) + self.create_file_directories() + filepath = os.path.join( basepath, prefix, @@ -360,9 +339,6 @@ def data_collection_hook(self): + "%s_%d" % (prefix, runno), ) - # Filepath to work with EDNA - # filepath = os.path.join(basepath,"%s_%d" % (prefix, runno)) - self.log.debug( "======= CURRENT FILEPATH: " + str(filepath) @@ -380,7 +356,6 @@ def data_collection_hook(self): ) self.log.debug("#COLLECT# Starting detector") - HWR.beamline.detector.start_acquisition() # Check whether the live view monitoring is on. Restart if needed. process_name = os.getenv("MXCUBE_LIVEVIEW_NAME") @@ -399,74 +374,384 @@ def data_collection_hook(self): self.collect_characterisation( start_angle, img_range, nframes, angle_inc, exp_time ) + + # Move to 0 with default speed (fast) + HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) + time.sleep(0.1) + HWR.beamline.diffractometer.move_omega(0) + + # Adding H5 info for characterization + start_angles_collected = [] + for nf in range(nframes): + start_angles_collected.append(start_angle + nf * angle_inc) + self.add_h5_info_characterisation( + self.latest_h5_filename, start_angles_collected, img_range + ) + + latest_image = HWR.beamline.detector.get_eiger_name_pattern() + latest_local_path = os.path.dirname(f"/gpfs{latest_image}_master.h5") + latest_local_name = f"/gpfs{latest_image}_master.h5".split("/")[-1] + self.write_info_txt( + latest_local_path, + latest_local_name, + start_angle, + nframes, + img_range, + angle_inc, + exp_time, + "screening", + ) + else: self.log.debug("STARTING STANDARD COLLECTION") + duration = self.total_angle_range / self.acq_speed + start_time = time.time() + + latest_image = HWR.beamline.detector.get_eiger_name_pattern() + latest_local_path = os.path.dirname(f"/gpfs{latest_image}_master.h5") + latest_local_name = f"/gpfs{latest_image}_master.h5".split("/")[-1] + + # Start the progress emitter in a separate greenlet + gevent.spawn(self.progress_emitter, start_time, duration) + + HWR.beamline.diffractometer.wait_omega() + + # Arm the detector here. For characterization it is a bit different. + HWR.beamline.detector.start_acquisition() self.collect_std_collection(start_angle, stop_angle) + # Move to 0 with default speed (fast) + HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) + time.sleep(0.1) + HWR.beamline.diffractometer.move_omega(0) + + self.add_h5_info_standard_data_collection(self.latest_h5_filename) + + self.write_info_txt( + latest_local_path, + latest_local_name, + start_angle, + nframes, + img_range, + stop_angle - start_angle, + exp_time, + "regular", + ) + except RuntimeError: self.log.error(traceback.format_exc()) finally: - self.add_h5_info(self.latest_h5_filename) self.acquisition_cleanup() - # Show the latest image after collection latest_image = HWR.beamline.detector.get_eiger_name_pattern() latest_image = f"/gpfs{latest_image}_master.h5" self.adxv_notify(latest_image) - def collect_std_collection(self, start_angle, stop_angle): + def progress_emitter(self, start_time, duration): + """Emits progress steps during data collection. + + Args: + start_time (float): Start time of the data collection. + duration (float): Estimated duration of the data collection. """ - The function collects data from a standard acquisition by moving the omega motor from a start - angle to a stop angle. + while True: + elapsed_time = time.time() - start_time + progress = (elapsed_time / duration) * 100 - :param start_angle: The starting angle for the collection - :param stop_angle: The stop_angle parameter is the final angle at which the collection should - stop + if progress >= 100: + progress = 98 + self.emit("progressStep", progress) + break + self.emit("progressStep", progress) + gevent.sleep(1) # Non-blocking sleep + + def add_h5_info_standard_data_collection(self, imagepath): + """Adds metadata to the HDF5 file for a standard data collection. + + Args: + imagepath (str): Path to the HDF5 file. """ - HWR.beamline.diffractometer.wait_omega() + time.sleep(1) + self.log.debug("adding h5 info for standard data collection") + try: + f = h5py.File(imagepath, "r+") + # source and instrument + g = f.create_group("entry/source") + g.attrs["NX_class"] = np.array("NXsource", dtype="S") + g.create_dataset("name", data=np.array("PETRA III, DESY", dtype="S")) + g = f.get("entry/instrument") + g.create_dataset("name", data=np.array("P11", dtype="S")) + # attenuator + g = f.create_group("entry/instrument/attenuator") + g.attrs["NX_class"] = np.array("NXattenuator", dtype="S") + ds = g.create_dataset( + "thickness", dtype="f8", data=float(self.get_filter_thickness()) + ) + ds.attrs["units"] = np.array("m", dtype="S") + ds = g.create_dataset("type", data=np.array("Aluminum", dtype="S")) + ds = g.create_dataset( + "attenuator_transmission", + dtype="f8", + data=float(self.get_filter_transmission()), + ) - start_pos = start_angle - self.turnback_time * self.acq_speed - stop_pos = stop_angle + self.turnback_time * self.acq_speed + # Keep it here as it is not clear if it is needed. + # It was used in CC to fix the issue with the data processing + + # #fix rotation axis and detector orientation + # ds = f.get(u"entry/sample/transformations/omega") + # ds.attrs[u"vector"] = [1., 0., 0.] + # ds = f.get(u"entry/instrument/detector/module/fast_pixel_direction") + # ds.attrs[u"vector"] = [1., 0., 0.] + # ds = f.get(u"entry/instrument/detector/module/slow_pixel_direction") + # ds.attrs[u"vector"] = [0., 1., 0.] + # delete phi angle info to avoid confusion + nodes = [ + "entry/sample/goniometer/phi", + "entry/sample/goniometer/phi_end", + "entry/sample/goniometer/phi_range_average", + "entry/sample/goniometer/phi_range_total", + ] + for node in nodes: + if node in f: + del f[node] + f.close() + except RuntimeWarning: + self.log.debug("writing header to H5 FAILED!") + def add_h5_info_characterisation( + self, imagepath, start_angles_collected, degreesperframe + ): + """Adds metadata to the HDF5 file for characterization data collection. - self.log.debug("#COLLECT# Running OMEGA through the std acquisition") - if start_angle <= stop_angle: - self.lower_bound_ch.set_value(start_angle) - self.upper_bound_ch.set_value(stop_angle) + Args: + imagepath (str): Path to the HDF5 file. + start_angles_collected (list): List of angles at which images were collected. + degreesperframe (float): Number of degrees per frame collected. + """ + time.sleep(1) + self.log.debug("adding h5 info for characterization") + try: + f = h5py.File(imagepath, "r+") + # source and instrument + g = f.create_group("entry/source") + g.attrs["NX_class"] = np.array("NXsource", dtype="S") + g.create_dataset("name", data=np.array("PETRA III, DESY", dtype="S")) + g = f.get("entry/instrument") + g.create_dataset("name", data=np.array("P11", dtype="S")) + # attenuator + g = f.create_group("entry/instrument/attenuator") + g.attrs["NX_class"] = np.array("NXattenuator", dtype="S") + ds = g.create_dataset( + "thickness", dtype="f8", data=float(self.get_filter_thickness()) + ) + ds.attrs["units"] = np.array("m", dtype="S") + ds = g.create_dataset("type", data=np.array("Aluminum", dtype="S")) + ds = g.create_dataset( + "attenuator_transmission", + dtype="f8", + data=float(self.get_filter_transmission()), + ) + # delete existing angle info + nodes = [ + "entry/sample/goniometer/omega", + "entry/sample/goniometer/omega_end", + "entry/sample/goniometer/omega_range_average", + "entry/sample/goniometer/omega_range_total", + "entry/sample/goniometer/phi", + "entry/sample/goniometer/phi_end", + "entry/sample/goniometer/phi_range_average", + "entry/sample/goniometer/phi_range_total", + "entry/sample/transformations/omega", + "entry/sample/transformations/omega_end", + "entry/sample/transformations/omega_range_average", + "entry/sample/transformations/omega_range_total", + ] + for node in nodes: + if node in f: + del f[node] + + angles = [] + angles_end = [] + for angle in start_angles_collected: + angles.append(float(angle)) + angles_end.append(float(angle + degreesperframe)) + g = f.get("entry/sample/goniometer") + o = g.create_dataset("omega", dtype="f8", data=angles) + o.attrs["vector"] = [1.0, 0.0, 0.0] + g.create_dataset("omega_end", dtype="f8", data=angles_end) + g.create_dataset( + "omega_range_average", dtype="f8", data=float(degreesperframe) + ) + g = f.get("entry/sample/transformations") + o = g.create_dataset("omega", dtype="f8", data=angles) + o.attrs["vector"] = [1.0, 0.0, 0.0] + g.create_dataset("omega_end", dtype="f8", data=angles_end) + g.create_dataset( + "omega_range_average", dtype="f8", data=float(degreesperframe) + ) + f.close() + except RuntimeWarning: + self.log.debug("writing header to H5 characterization FAILED!") + + def write_info_txt( + self, + path, + name, + startangle, + frames, + degreesperframe, + imageinterval, + exposuretime, + run_type, + ): + """Writes info about the data collection into a text file. + + Args: + path (str): Directory path where the info file will be saved. + name (str): Name of the run. + startangle (float): Starting angle of the collection. + frames (int): Number of frames collected. + degreesperframe (float): Degrees per frame. + imageinterval (float): Interval between images. + exposuretime (float): Exposure time in milliseconds. + run_type (str): Type of run (e.g., 'regular' or 'screening'). + """ + if run_type == "regular": + + INFO_TXT = ( + "run type: {run_type:s}\n" + + "run name: {name:s}\n" + + "start angle: {startangle:.2f}deg\n" + + "frames: {frames:d}\n" + + "degrees/frame: {degreesperframe:.2f}deg\n" + + "exposure time: {exposuretime:.3f}ms\n" + + "energy: {energy:.3f}keV\n" + + "wavelength: {wavelength:.3f}A\n" + + "detector distance: {detectordistance:.2f}mm\n" + + "resolution: {resolution:.2f}A\n" + + "aperture: {pinholeDiameter:d}um\n" + + "focus: {focus:s}\n" + + "filter transmission: {filterTransmission:.3f}%\n" + + "filter thickness: {filterThickness:d}um\n" + + "ring current: {beamCurrent:.3f}mA\n" + + "\n" + + "For exact flux reading, please consult the staff." + ) - else: - self.lower_bound_ch.set_value(stop_angle) - self.upper_bound_ch.set_value(start_angle) + energy = HWR.beamline.energy.get_value() + wavelength = 12.3984 / (energy) # in Angstrom + resolution = HWR.beamline.resolution.get_value() + detectordistance = HWR.beamline.detector.get_eiger_detector_distance() + transmission = HWR.beamline.transmission.get_value() + filter_thickness = self.get_filter_thickness_in_mm() + pinhole_diameter = HWR.beamline.beam.get_pinhole_size() + focus = HWR.beamline.beam.get_beam_focus_label() + current = HWR.beamline.machine_info.get_current() + + output = INFO_TXT.format( + run_type=run_type, + name=name, + startangle=startangle, + frames=frames, + degreesperframe=degreesperframe, + exposuretime=exposuretime * 1000, + energy=energy, + wavelength=wavelength, + detectordistance=detectordistance, + resolution=resolution, + pinholeDiameter=int(pinhole_diameter), + focus=str(focus), + filterTransmission=int(transmission), + filterThickness=int(filter_thickness), + beamCurrent=float(current), + ) - self.omega_mv(start_pos, self.default_speed) - self.acq_arm_cmd() - self.omega_mv(stop_pos, self.acq_speed) - time.sleep(0.5) - self.acq_off_cmd() - self.acq_window_off_cmd() - self.omega_mv(stop_angle, self.acq_speed) + f = open(path + "/info.txt", "w") + f.write(output) + f.close() + + if run_type == "screening": + + INFO_TXT = ( + "run type: {run_type:s}\n" + + "run name: {name:s}\n" + + "start angle: {startangle:.2f}deg\n" + + "frames: {frames:d}\n" + + "degrees/frame: {degreesperframe:.2f}deg\n" + + "exposure time: {exposuretime:.3f}ms\n" + + "energy: {energy:.3f}keV\n" + + "wavelength: {wavelength:.3f}A\n" + + "detector distance: {detectordistance:.2f}mm\n" + + "resolution: {resolution:.2f}A\n" + + "aperture: {pinholeDiameter:d}um\n" + + "focus: {focus:s}\n" + + "filter transmission: {filterTransmission:.3f}%\n" + + "filter thickness: {filterThickness:d}um\n" + + "ring current: {beamCurrent:.3f}mA\n" + + "\n" + + "For exact flux reading, please consult the staff." + ) + + energy = HWR.beamline.energy.get_value() + wavelength = 12.3984 / (energy) # in Angstrom + resolution = HWR.beamline.resolution.get_value() + detectordistance = HWR.beamline.detector.get_eiger_detector_distance() + transmission = HWR.beamline.transmission.get_value() + filter_thickness = self.get_filter_thickness_in_mm() + pinhole_diameter = HWR.beamline.beam.get_pinhole_size() + focus = HWR.beamline.beam.get_beam_focus_label() + current = HWR.beamline.machine_info.get_current() + + output = INFO_TXT.format( + run_type=run_type, + name=name, + startangle=startangle, + frames=frames, + degreesperframe=degreesperframe, + exposuretime=exposuretime * 1000, + energy=energy, + wavelength=wavelength, + detectordistance=detectordistance, + resolution=resolution, + pinholeDiameter=int(pinhole_diameter), + focus=str(focus), + filterTransmission=int(transmission), + filterThickness=int(filter_thickness), + beamCurrent=float(current), + ) + + f = open(path + "/info.txt", "w") + f.write(output) + f.close() + + def prepare_characterization(self): + """Prepares for characterization data collection by setting the start angle and angle increment for the detector.""" + self.log.debug("Preparing for characterization data collection.") + + osc_pars = self.current_dc_parameters["oscillation_sequence"][0] + start_angle = osc_pars["start"] + HWR.beamline.detector.set_eiger_start_angle(start_angle) + + img_range = osc_pars["range"] + HWR.beamline.detector.set_eiger_angle_increment(img_range) def collect_characterisation( self, start_angle, img_range, nimages, angle_inc, exp_time ): + """Collects a series of images at different angles for characterization. + + Args: + start_angle (float): Starting angle for the characterization acquisition. + img_range (float): Range of angles over which a single image is collected. + nimages (int): Number of images to be collected during the characterization process. + angle_inc (float): Increment in angle between each image in the collection. + exp_time (float): Exposure time for each image. """ - The function `collect_characterisation` is used to collect a series of images at different - angles for characterisation. - - :param start_angle: The starting angle for the characterisation acquisition - :param img_range: The `img_range` parameter represents the range of angles over which the single image - will be collected - :param nimages: The parameter `nimages` represents the number of images to be collected during - the characterisation process (1, 2, 4). - :param angle_inc: The `angle_inc` parameter represents the increment in angle between each image - in the collection - :param exp_time: The `exp_time` parameter represents the exposure time for each image - """ - self.log.debug( - "#COLLECT# Running OMEGA through the characteristation acquisition" + "#COLLECT# Running OMEGA through the characterization acquisition" ) - self.omega_mv(start_angle, self.default_speed) + start_angle = int(start_angle) for img_no in range(nimages): self.log.debug("collecting image %s" % img_no) @@ -475,29 +760,88 @@ def collect_characterisation( self.log.debug("collecting image %s, angle %f" % (img_no, start_at)) - # Keep it here for now. It is not clear if it is needed. - # if start_at >= stop_angle: - # init_pos = start_at # - self.acq_speed * self.turnback_time - # # init_pos = start_at - 1.5 - # else: - # init_pos = start_at # + self.acq_speed * self.turnback_time - # # init_pos = start_at + 1.5 - # self.omega_mv(init_pos, self.default_speed) + #[WIP] + #NB! Another attemt to fix the misfires. + #Keep comments here until finished + #Here is the previous implementation: + #self.collect_std_collection(start_at, stop_angle) + + #Here is sligthly modified standard data collection routine + #Adjust the angle since each time we are starting with 90 degrees offset. + start_pos = start_at - self.turnback_time * self.acq_speed + stop_pos = stop_angle + self.turnback_time * self.acq_speed + + self.log.debug("#COLLECT# Running OMEGA through the std acquisition") + HWR.beamline.diffractometer.wait_omega_on() + HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) + time.sleep(1) + HWR.beamline.diffractometer.move_omega(start_pos) + time.sleep(1) + HWR.beamline.diffractometer.wait_omega_on() + time.sleep(1) + # NB! angles reversed could work??? + HWR.beamline.diffractometer.set_pso_control_arm(start_angle, stop_angle) + time.sleep(3) + HWR.beamline.diffractometer.set_omega_velocity(self.acq_speed) + time.sleep(1) + + #Arm the detector only once in the beginning. Set to wait 4 triggers. + if img_no == 0: + HWR.beamline.detector.start_acquisition() + time.sleep(3) + + HWR.beamline.diffractometer.move_omega(stop_pos) + + self.emit("progressStep", int(120 / (nimages) * (img_no + 1))) - self.collect_std_collection(start_at, stop_angle) - self.log.debug( - "======= collect_characterisation Waiting =======================================" - ) + def prepare_std_collection(self, start_angle, img_range): + """Prepares a standard collection by setting the start angle and angle increment in the detector's header. + + Args: + start_angle (float): Starting angle for the standard collection sequence. + img_range (float): Angle increment for each frame. + + Returns: + bool: True if successful, False otherwise. + """ + osc_pars = self.current_dc_parameters["oscillation_sequence"][0] + start_angle = osc_pars["start"] + HWR.beamline.detector.set_eiger_start_angle(start_angle) - def adxv_notify(self, image_filename, image_num=1): + img_range = osc_pars["range"] + HWR.beamline.detector.set_eiger_angle_increment(img_range) + + def collect_std_collection(self, start_angle, stop_angle): + """Performs the standard data collection by moving the omega motor from start to stop angle. + + Args: + start_angle (float): Starting angle for the collection. + stop_angle (float): Stop angle for the collection. """ - The `adxv_notify` function sends a notification to an ADXV to load an image file and - display a specific slab. + start_pos = start_angle - self.turnback_time * self.acq_speed + stop_pos = stop_angle + self.turnback_time * self.acq_speed - :param image_filename: The `image_filename` parameter is a string that represents the filename - of the image that needs to be loaded into ADXV - :param image_num: The `image_num` parameter is an optional parameter that specifies the image - number to be loaded in ADXV. If not provided, it defaults to 1, defaults to 1 (optional) + self.log.debug("#COLLECT# Running OMEGA through the std acquisition") + HWR.beamline.diffractometer.wait_omega_on() + HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) + time.sleep(1) + HWR.beamline.diffractometer.move_omega(start_pos) + time.sleep(1) + HWR.beamline.diffractometer.wait_omega_on() + time.sleep(1) + HWR.beamline.diffractometer.set_pso_control_arm(start_angle, stop_angle) + time.sleep(3) + HWR.beamline.diffractometer.set_omega_velocity(self.acq_speed) + time.sleep(1) + HWR.beamline.diffractometer.move_omega(stop_pos) + + + def adxv_notify(self, image_filename, image_num=1): + """Sends a notification to an ADXV to load an image file and display a specific slab. + + Args: + image_filename (str): Filename of the image to be loaded. + image_num (int, optional): Image number to load in ADXV. Defaults to 1. """ logging.getLogger("HWR").info(f"ADXV notify {image_filename}") logging.getLogger("HWR").info(f"ADXV notify {image_num}") @@ -517,12 +861,25 @@ def adxv_notify(self, image_filename, image_num=1): pass def is_process_running(self, process_name): + """Checks if a process is running by its name. + + Args: + process_name (str): Name of the process to check. + + Returns: + bool: True if the process is running, False otherwise. + """ for proc in psutil.process_iter(): if proc.name() == process_name: return True return False def start_process(self, command): + """Starts a process with the specified command. + + Args: + command (list): List of command arguments to start the process. + """ subprocess.Popen( command, stdout=subprocess.DEVNULL, @@ -532,119 +889,28 @@ def start_process(self, command): ) def acquisition_cleanup(self): - """ - The function `acquisition_cleanup` performs various cleanup tasks related to data acquisition, - such as setting the omega velocity, turning off acquisition and window commands, closing the - detector cover, and stopping the acquisition. - """ + """Performs cleanup after data acquisition, including stopping the detector and resetting motor velocities.""" try: HWR.beamline.detector.stop_acquisition() HWR.beamline.diffractometer.wait_omega() - # ================= - # It is probably already finished in a standard collection. - self.acq_off_cmd() - self.acq_window_off_cmd() - # ================== HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) self.log.debug("#COLLECT# Closing detector cover") HWR.beamline.diffractometer.detector_cover_close(wait=True) - # Move omega to 0 at the end - self.omega_mv(0, self.default_speed) + HWR.beamline.diffractometer.stop_motion() except RuntimeError: self.log.error(traceback.format_exc()) - def add_h5_info(self, h5file): - """ - Add information to an HDF5 file. - - :param h5file: The name or path of the HDF5 file. - """ - self.log.debug("========== Writing H5 info ==============") - - # Wait for the HDF5 file to appear with a timeout - start_time = time.time() - while not os.path.exists(h5file): - if time.time() - start_time > 5: - raise IOError( - "Cannot add info to HDF5 file. Timeout waiting for file on disk." - ) - time.sleep(0.5) - - try: - with h5py.File(h5file, "r+") as h5fd: - # Create or get the 'entry/source' group - source_group = self.get_or_create_group(h5fd, "entry/source") - source_group.attrs["NX_class"] = np.array("NXsource", dtype="S") - - # Create or get datasets within the 'entry/source' group - self.create_or_get_dataset( - source_group, "name", np.array("PETRA III, DESY", dtype="S") - ) - - # Create or get the 'entry/instrument' group - instrument_group = self.get_or_create_group(h5fd, "entry/instrument") - - # Create or get datasets within the 'entry/instrument' group - self.create_or_get_dataset( - instrument_group, "name", np.array("P11", dtype="S") - ) - - # Create or get the 'entry/instrument/attenuator' group - attenuator_group = self.get_or_create_group( - instrument_group, "attenuator" - ) - attenuator_group.attrs["NX_class"] = np.array("NXattenuator", dtype="S") - - # Create or get datasets within the 'entry/instrument/attenuator' group - self.create_or_get_dataset( - attenuator_group, "thickness", self.get_filter_thickness() - ) - self.create_or_get_dataset( - attenuator_group, "type", np.array("Aluminum", dtype="S") - ) - self.create_or_get_dataset( - attenuator_group, - "attenuator_transmission", - self.get_filter_transmission(), - ) - - # Keep it here as it is not clear if it is needed. - # It was used in CC to fix the issue with the data processing - # h5fd["entry/sample/transformations/omega"].attrs["vector"] = [ - # 1.0, - # 0.0, - # 0.0, - # ] - # h5fd["entry/instrument/detector/module/fast_pixel_direction"].attrs[ - # "vector" - # ] = [1.0, 0.0, 0.0] - # h5fd["entry/instrument/detector/module/slow_pixel_direction"].attrs[ - # "vector" - # ] = [0.0, 1.0, 0.0] - - # Delete unwanted nodes - unwanted_nodes = [ - "entry/sample/goniometer/phi", - "entry/sample/goniometer/phi_end", - "entry/sample/goniometer/phi_range_average", - "entry/sample/goniometer/phi_range_total", - ] - for node in unwanted_nodes: - if node in h5fd: - del h5fd[node] - except RuntimeWarning as err_msg: - self.log.debug(f"Error while adding info to HDF5 file: {str(err_msg)}") - self.log.debug(traceback.format_exc()) - def get_or_create_group(self, parent_group, group_name): - """ - Get or create a group within a parent group. + """Gets or creates a group within a parent group. + + Args: + parent_group (h5py.Group): The parent group where the new group will be created. + group_name (str): The name of the group to get or create. - :param parent_group: The parent group where the new group will be created. - :param group_name: The name of the group to get or create. - :return: The group object. + Returns: + h5py.Group: The group object. """ if group_name in parent_group: return parent_group[group_name] @@ -652,12 +918,12 @@ def get_or_create_group(self, parent_group, group_name): return parent_group.create_group(group_name) def create_or_get_dataset(self, group, dataset_name, dataset_data): - """ - Create or get a dataset within a group. + """Creates or retrieves a dataset within a group. - :param group: The group where the dataset will be created or retrieved. - :param dataset_name: The name of the dataset. - :param dataset_data: The data to be stored in the dataset. + Args: + group (h5py.Group): The group where the dataset will be created or retrieved. + dataset_name (str): The name of the dataset. + dataset_data: The data to be stored in the dataset. """ if dataset_name in group: dataset = group[dataset_name] @@ -665,10 +931,26 @@ def create_or_get_dataset(self, group, dataset_name, dataset_data): dataset = group.create_dataset(dataset_name, data=dataset_data) def get_filter_thickness(self): + """Calculates the total thickness of three filters. + + Returns: + float: The total thickness of the filters in meters. If the filter server is not available, it returns -1. """ - The function `get_filter_thickness` calculates the total thickness of three filters. - :return: the total thickness of the filters in meters. If the filter server is not available, it - returns -1. + if self.filter_server: + thick1 = self.filter_server.Filter1Thickness + thick2 = self.filter_server.Filter2Thickness + thick3 = self.filter_server.Filter3Thickness + + thickness = int(thick1) + int(thick2) + int(thick3) + return float(thickness) / 1_000_000 + else: + return -1 + + def get_filter_thickness_in_mm(self): + """Calculates the total thickness of three filters in millimeters. + + Returns: + int: The total thickness of the filters in millimeters. If the filter server is not available, it returns -1. """ if self.filter_server: thick1 = self.filter_server.Filter1Thickness @@ -677,259 +959,179 @@ def get_filter_thickness(self): thickness = int(thick1) + int(thick2) + int(thick3) - return float(thickness) / 1_000_000 + return int(thickness) else: return -1 def get_filter_transmission(self): - """ - The function returns the current transmission value from the filter server, or -1 if the filter - server is not available. - :return: The method is returning the current transmission value of the filter server. If the - filter server is not available, it returns -1. + """Gets the current transmission value from the filter server. + + Returns: + float: The current transmission value. If the filter server is not available, it returns -1. """ if self.filter_server: return self.filter_server.CurrentTransmission else: return -1 - def generate_xds_template(self): - """ - The function generates an XDS template by executing a command on a remote server. - """ - self.log.debug( - "============== Generating XDS template.============================" - ) + def xdsapp_maxwell(self): + """Starts XDSAPP auto-processing on the Maxwell cluster.""" + self.log.debug("==== XDSAPP AUTOPROCESSING IS STARTED ==========") - h5file = self.latest_h5_filename + resolution = self.get_resolution() - basedir, fname = os.path.split(h5file) + image_dir_local, filename = os.path.split(self.latest_h5_filename) + image_dir = image_dir_local.replace( + "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] + ) + process_dir = image_dir.replace("/raw/", "/processed/") + process_dir_local = image_dir_local.replace("/raw/", "/processed/") + xdsapp_path = os.path.join(process_dir, "xdsapp") + xdsapp_path_local = os.path.join(process_dir_local, "xdsapp") + self.log.debug('============XDSAPP======== xdsapp_path="%s"' % xdsapp_path) self.log.debug( - "============== BASEDIR for Generating XDS template " - + str(basedir) - + "============================" + '============XDSAPP======== xdsapp_path_local="%s"' % xdsapp_path_local ) - process_dir = basedir.replace("/raw/", "/processed/") + "/manual" - self.mkdir_with_mode(process_dir, mode=0o777) + try: + self.mkdir_with_mode(xdsapp_path_local, mode=0o777) + self.log.debug("=========== XDSAPP ============ XDSAPP directory created") - rel_image_dir = self.get_relative_path(process_dir, basedir) - rel_image_path = os.path.join(rel_image_dir, fname) + except OSError: + self.log.debug(sys.exc_info()) + self.log.debug("Cannot create XDSAPP directory") - cmd_tpl = ( - "\"sleep 20; module load xdsapp/3.1.9; cd '{processpath:s}'; " - + "generate_XDS.INP '{imagepath:s}'\" >/dev/null 2>&1\n" - ) + base_process_dir = self.base_dir(process_dir_local, "processed") + datasets_file = os.path.join(base_process_dir, "datasets.txt") - cmd = cmd_tpl.format(imagepath=h5file, processpath=process_dir) - os.system("ssh -n -f p11user@haspp11eval01 " + cmd) - self.log.debug( - "============== " - + "ssh -n -f p11user@haspp11eval01 " - + cmd - + "============================" + try: + open(datasets_file, "a", encoding="utf-8").write( + xdsapp_path_local.split("/gpfs/current/processed/")[1] + "\n" + ) + except RuntimeError as err_msg: + self.log.debug("Cannot write to datasets.txt") + self.log.debug(sys.exc_info()) + + ssh = HWR.beamline.session.get_ssh_command() + sbatch = HWR.beamline.session.get_sbatch_command( + jobname_prefix="xdsapp", + logfile_path=xdsapp_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ) + + "/xdsapp.log", ) - def trigger_auto_processing(self, process_event=None, frame_number=None): - """ - The function `trigger_auto_processing` triggers auto processing based on the experiment type and - performs different actions for characterization and OSC experiments. - - :param process_event: The `process_event` parameter is an optional argument that specifies the - type of event that triggered the auto processing. It can be used to provide additional - information or context for the processing - :param frame_number: The `frame_number` parameter is used to specify the number of frames in the - processing. It is an integer value that represents the number of frames to be processed - :return: The function does not return any value. - """ - - self.log.debug("Triggering auto processing") - - dc_pars = self.current_dc_parameters - collection_type = dc_pars["experiment_type"] - self.log.debug( - "=============== Supported experiment types: ===========\n" - + str(dc_pars["experiment_type"]) + cmd = ( + "/asap3/petra3/gpfs/common/p11/processing/xdsapp_sbatch.sh " + + "{imagepath:s} {processpath:s} {res:f}" + ).format( + imagepath=image_dir + "/" + filename, + processpath=xdsapp_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ), + res=resolution, ) - if collection_type == "Characterization": - self.log.debug( - "==== AUTOPROCESSING CHARACTERISATION IN PROGRESS ==========" + os.system( + '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( + ssh=ssh, sbatch=sbatch, cmd=cmd ) + ) - resolution = self.get_resolution() - frames = self.latest_frames + def autoproc_maxwell(self): + """Starts AutoProc auto-processing on the Maxwell cluster.""" + self.log.debug("==== AUTOPROC AUTOPROCESSING IS STARTED ==========") - image_dir_local, filename = os.path.split(self.latest_h5_filename) - # AG: Image dir at this point is located locally. This path is not seen on the MAXWELL. Path needs to be converted. - # /gpfs/current/ to get_beamline_metadata()[2] - image_dir = image_dir_local.replace( - "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] - ) - process_dir = image_dir.replace("/raw/", "/processed/") - process_dir_local = image_dir_local.replace("/raw/", "/processed/") - mosflm_path = os.path.join(process_dir, "mosflm") - mosflm_path_local = os.path.join(process_dir_local, "mosflm") - self.log.debug('============MOSFLM======== mosflm_path="%s"' % mosflm_path) - self.log.debug( - '============MOSFLM======== mosflm_path_local="%s"' % mosflm_path_local - ) + resolution = self.get_resolution() - ssh = HWR.beamline.session.get_ssh_command() + image_dir_local, filename = os.path.split(self.latest_h5_filename) - try: - self.mkdir_with_mode(mosflm_path_local, mode=0o777) - self.log.debug( - "=========== MOSFLM ============ Mosflm directory created" - ) + image_dir = image_dir_local.replace( + "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] + ) + process_dir = image_dir.replace("/raw/", "/processed/") + process_dir_local = image_dir_local.replace("/raw/", "/processed/") + autoproc_path = os.path.join(process_dir, "autoproc") + autoproc_path_local = os.path.join(process_dir_local, "autoproc") + self.log.debug( + '============AUTOPROC======== autoproc_path="%s"' % autoproc_path + ) + self.log.debug( + '============AUTOPROC======== autoproc_path_local="%s"' + % autoproc_path_local + ) - except OSError: - self.log.debug(sys.exc_info()) - self.log.debug("Cannot create mosflm directory") + try: + self.mkdir_with_mode(autoproc_path_local, mode=0o777) + self.log.debug( + "=========== AUTOPROC ============ autoproc directory created" + ) - base_process_dir = self.base_dir(process_dir_local, "processed") - datasets_file = os.path.join(base_process_dir, "datasets.txt") + except OSError: + self.log.debug(sys.exc_info()) + self.log.debug("Cannot create AUTOPROC directory") - # add to datasets.txt for presenterd - try: - open(datasets_file, "a").write( - mosflm_path_local.split("/gpfs/current/processed/")[1] + "\n" - ) - except RuntimeWarning as err_msg: - self.log.debug("Cannot write to datasets.txt") - self.log.debug(sys.exc_info(), err_msg) - - # create call - ssh = HWR.beamline.session.get_ssh_command() - sbatch = HWR.beamline.session.get_sbatch_command( - jobname_prefix="mosflm", - logfile_path=mosflm_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], - "/beamline/p11/current", - ) - + "/mosflm.log", - ) + base_process_dir = self.base_dir(process_dir_local, "processed") + datasets_file = os.path.join(base_process_dir, "datasets.txt") - cmd = ( - "/asap3/petra3/gpfs/common/p11/processing/mosflm_sbatch.sh " - + "{imagepath:s} {filename:s} {processpath:s} {frames:d} {res:f}" - ).format( - imagepath=image_dir, - filename=filename, - processpath=mosflm_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], - "/beamline/p11/current", - ), - frames=frames, - res=resolution, + try: + open(datasets_file, "a", encoding="utf-8").write( + autoproc_path_local.split("/gpfs/current/processed/")[1] + "\n" ) - self.log.debug('=======MOSFLM========== ssh="%s"' % ssh) - self.log.debug('=======MOSFLM========== sbatch="%s"' % sbatch) - self.log.debug('=======MOSFLM========== executing process cmd="%s"' % cmd) - self.log.debug( - '=======MOSFLM========== {ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) + except RuntimeError as err_msg: + self.log.debug("Cannot write to datasets.txt") + self.log.debug(sys.exc_info()) + + ssh = HWR.beamline.session.get_ssh_command() + sbatch = HWR.beamline.session.get_sbatch_command( + jobname_prefix="autoproc", + logfile_path=autoproc_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" ) + + "/autoproc.log", + ) - os.system( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}"\\"'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) + cmd = ( + "/asap3/petra3/gpfs/common/p11/processing/autoproc_sbatch.sh " + + "{imagepath:s} {processpath:s}" + ).format( + imagepath=image_dir + "/" + filename, + processpath=autoproc_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" ) - else: - if collection_type == "OSC": - self.log.debug( - "==== AUTOPROCESSING STANDARD PROCESSING IS IN PROGRESS ==========" - ) - - resolution = self.get_resolution() - frames = self.latest_frames - - image_dir_local, filename = os.path.split(self.latest_h5_filename) - - image_dir = image_dir_local.replace( - "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] - ) - process_dir = image_dir.replace("/raw/", "/processed/") - process_dir_local = image_dir_local.replace("/raw/", "/processed/") - xdsapp_path = os.path.join(process_dir, "xdsapp") - xdsapp_path_local = os.path.join(process_dir_local, "xdsapp") - self.log.debug( - '============XDSAPP======== xdsapp_path="%s"' % xdsapp_path - ) - self.log.debug( - '============XDSAPP======== xdsapp_path_local="%s"' - % xdsapp_path_local - ) - - try: - self.mkdir_with_mode(xdsapp_path_local, mode=0o777) - self.log.debug( - "=========== XDSAPP ============ XDSAPP directory created" - ) - - except OSError: - self.log.debug(sys.exc_info()) - self.log.debug("Cannot create XDSAPP directory") - - base_process_dir = self.base_dir(process_dir_local, "processed") - datasets_file = os.path.join(base_process_dir, "datasets.txt") + + "/processing", + ) - # add to datasets.txt for presenterd - try: - open(datasets_file, "a", encoding="utf-8").write( - xdsapp_path_local.split("/gpfs/current/processed/")[1] + "\n" - ) - except RuntimeError as err_msg: - self.log.debug("Cannot write to datasets.txt") - self.log.debug(sys.exc_info()) - - # create call - ssh = HWR.beamline.session.get_ssh_command() - sbatch = HWR.beamline.session.get_sbatch_command( - jobname_prefix="xdsapp", - logfile_path=xdsapp_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], - "/beamline/p11/current", - ) - + "/xdsapp.log", - ) + os.system( + '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( + ssh=ssh, sbatch=sbatch, cmd=cmd + ) + ) - self.log.debug( - "=============== XDSAPP ================" - + xdsapp_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], - "/beamline/p11/current", - ) - ) - cmd = ( - "/asap3/petra3/gpfs/common/p11/processing/xdsapp_sbatch.sh " - + "{imagepath:s} {processpath:s} {res:f}" - ).format( - imagepath=image_dir + "/" + filename, - processpath=xdsapp_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], - "/beamline/p11/current", - ), - res=resolution, - ) + def trigger_auto_processing(self, process_event=None, frame_number=None): + """Triggers auto processing based on the experiment type. - self.log.debug( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) - ) + Args: + process_event: Optional event that triggered the auto processing. + frame_number (int, optional): Number of frames to process. + """ + self.log.debug("Triggering auto processing") + collection_type = self.current_dc_parameters["experiment_type"] + self.log.debug( + "=============== Supported experiment types: ===========\n" + + str(self.current_dc_parameters["experiment_type"]) + ) - os.system( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) - ) + self.xdsapp_maxwell() + self.autoproc_maxwell() def diffractometer_prepare_collection(self): + """Prepares the diffractometer for data collection. + Returns: + bool: True if the diffractometer is in collect phase, False otherwise. + """ self.log.debug("#COLLECT# preparing collection ") if not HWR.beamline.diffractometer.is_collect_phase(): self.log.debug("#COLLECT# going to collect phase") @@ -942,68 +1144,15 @@ def diffractometer_prepare_collection(self): return HWR.beamline.diffractometer.is_collect_phase() - def prepare_std_collection(self, start_angle, img_range): - """ - The function prepares a standard collection by setting the start angle and angle increment in - the header of the Eiger detector. - - :param start_angle: The start_angle parameter represents the starting angle of the standard collection - sequence. It is used to also set the start angle in the header of the detector. - :param img_range: The `img_range` parameter represents the range of angles over which the - detector will collect single image. It is used to set the angle increment in the header of the Eiger - detector - :return: a boolean value of True. - """ - # Add start angle to the header - osc_pars = self.current_dc_parameters["oscillation_sequence"][0] - start_angle = osc_pars["start"] - HWR.beamline.detector.set_eiger_start_angle(start_angle) - - # Add angle increment to the header - osc_pars = self.current_dc_parameters["oscillation_sequence"][0] - img_range = osc_pars["range"] - HWR.beamline.detector.set_eiger_angle_increment(img_range) - - def omega_mv(self, target, speed): - """ - The function sets the velocity of the omega motor, moves the omega motor to a target position, - and waits for the movement to complete. - - :param target: The target parameter is the desired position or angle that you want the omega - motor to move to. - :param speed: The speed parameter is the desired velocity at which the omega motor should move - """ - HWR.beamline.diffractometer.set_omega_velocity(speed) - HWR.beamline.diffractometer.move_omega(target) - HWR.beamline.diffractometer.wait_omega() - - def prepare_characterization(self): - """ - The function prepares for characterization data collection by setting the start angle and angle - increment for the detector. - :return: a boolean value of True. - """ - self.log.debug("Preparing for characterization data collection.") - - # Add start angle to the header - osc_pars = self.current_dc_parameters["oscillation_sequence"][0] - start_angle = osc_pars["start"] - HWR.beamline.detector.set_eiger_start_angle(start_angle) - - # Add angle increment to the header - osc_pars = self.current_dc_parameters["oscillation_sequence"][0] - img_range = osc_pars["range"] - HWR.beamline.detector.set_eiger_angle_increment(img_range) - def get_relative_path(self, path1, path2): - """ - The function `get_relative_path` takes two paths as input and returns the relative path from the - first path to the second path. + """Returns the relative path from path1 to path2. - :param path1: The `path1` parameter is a string representing the first path. It can be an - absolute or relative path to a file or directory - :param path2: The `path2` parameter is a string representing a file or directory path - :return: the relative path between `path1` and `path2`. + Args: + path1 (str): First path. + path2 (str): Second path. + + Returns: + str: The relative path between path1 and path2. """ path_1 = path1.split(os.path.sep) path_2 = path2.split(os.path.sep) @@ -1018,13 +1167,14 @@ def get_relative_path(self, path1, path2): return os.path.join(*parts) def base_dir(self, path, what): - """ - The function `base_dir` returns the base directory path of a given file or directory. + """Returns the base directory path that contains the specified "what" directory or file. - :param path: The `path` parameter is a string representing a file path - :param what: The "what" parameter is a string that represents the directory or file name that - you are searching for within the given path - :return: the base directory path that contains the specified "what" directory or file. + Args: + path (str): The path to a file or directory. + what (str): The directory or file name to search for. + + Returns: + str: The base directory containing the "what". """ what = what.lstrip(os.path.sep) @@ -1041,27 +1191,21 @@ def base_dir(self, path, what): return start_sep + os.path.join(*path_[: i + 1]) def mkdir_with_mode(self, directory, mode): - """ - The function creates a directory with a specified mode if it does not already exist. + """Creates a directory with the specified mode. - :param directory: The "directory" parameter is the path of the directory that you want to - create. It can be an absolute path or a relative path - :param mode: The "mode" parameter in the above code refers to the permissions that will be set - for the newly created directory. It is an optional parameter and can be specified as an octal - value + Args: + directory (str): Path of the directory to create. + mode (int): Mode (permissions) to set for the directory. """ if not os.path.isdir(directory): oldmask = os.umask(000) os.makedirs(directory, mode=mode) os.umask(oldmask) - # self.checkPath(directory,force=True) self.log.debug("local directory created") def create_directories(self, *args): - """ - Descript. : - """ + """Creates directories for raw files and processing files.""" for directory in args: try: self.mkdir_with_mode(directory, mode=0o777) @@ -1070,21 +1214,14 @@ def create_directories(self, *args): raise def check_path(self, path=None, force=False): - """ - The function checks if a given path is valid and accessible, and creates the directories along - the path if they don't exist. - - :param path: The `path` parameter is the file path that needs to be checked. It is optional and - defaults to `None` - :param force: The "force" parameter is a boolean flag that determines whether the function - should create the directories in the given path if they do not exist. If "force" is set to True, - the function will create the directories. If "force" is set to False, the function will return - False if any, defaults to False (optional) - :return: the path if it exists and is writable. If the path does not exist and the force - parameter is set to True, the function will attempt to create the directory and return the path - if successful. If the path does not exist and the force parameter is set to False, the function - will print an error message and return False. If the path exists but is not writable, the - function + """Checks if a path is valid and accessible, and creates directories if needed. + + Args: + path (str, optional): The path to check. Defaults to None. + force (bool, optional): Whether to create the directories if they don't exist. Defaults to False. + + Returns: + str or bool: The path if valid and accessible, or False if not. """ path = str(path).replace("\\", "/") dirs = path.strip("/").split("/") @@ -1104,21 +1241,45 @@ def check_path(self, path=None, force=False): self.log.debug("dir not found:", str(sys.exc_info())) return False if not os.access(path, os.W_OK): - self.log.debug("dir not writeable:", str(sys.exc_info())) + self.log.debug("dir not writable:", str(sys.exc_info())) return False return path + def create_characterisation_directories(self): + """Creates directories for raw files and processing files for EDNA and MOSFLM.""" + self.create_directories( + self.current_dc_parameters["fileinfo"]["directory"], + self.current_dc_parameters["fileinfo"]["process_directory"], + ) + + collection_type = HWR.beamline.collect.current_dc_parameters["experiment_type"] + print("************** PREPARING FOLDERS FOR COLLECTION TYPE", collection_type) + + xds_directory, auto_directory = self.prepare_input_files() + xds_directory = xds_directory.replace("/rotational_", "/screening_").replace( + "/xdsapp", "/edna" + ) + auto_directory = auto_directory.replace("/rotational_", "/screening_").replace( + "/xdsapp", "/edna" + ) + try: + self.create_directories(xds_directory, auto_directory) + os.system("chmod -R 777 %s %s" % (xds_directory, auto_directory)) + except Exception: + logging.exception("Could not create processing file directory") + return + if xds_directory: + self.current_dc_parameters["xds_dir"] = xds_directory + if auto_directory: + self.current_dc_parameters["auto_dir"] = auto_directory + def create_file_directories(self): - """ - Method create directories for raw files and processing files. - Directories for xds.input and auto_processing are created - """ + """Creates directories for raw files and processing files.""" self.create_directories( self.current_dc_parameters["fileinfo"]["directory"], self.current_dc_parameters["fileinfo"]["process_directory"], ) - """create processing directories and img links""" xds_directory, auto_directory = self.prepare_input_files() try: self.create_directories(xds_directory, auto_directory) @@ -1132,10 +1293,11 @@ def create_file_directories(self): self.current_dc_parameters["auto_dir"] = auto_directory def prepare_input_files(self): + """Prepares directories for processing input files. + + Returns: + tuple: Paths for XDS and AutoProc directories. """ - Descript. : - """ - i = 1 logging.getLogger("user_level_log").info( "Creating XDS processing input file directories" ) @@ -1162,9 +1324,7 @@ def prepare_input_files(self): return xds_directory, auto_directory def take_crystal_snapshots(self): - """ - Descript. : - """ + """Takes sample snapshots and saves them to disk.""" if self.current_dc_parameters["take_snapshots"]: snapshot_directory = os.path.join( self.current_dc_parameters["fileinfo"]["directory"], "snapshot" @@ -1177,7 +1337,7 @@ def take_crystal_snapshots(self): "Collection: Error creating snapshot directory" ) - number_of_snapshots = 1 # 4 + number_of_snapshots = self.current_dc_parameters["take_snapshots"] logging.getLogger("user_level_log").info( "Collection: Taking %d sample snapshot(s)" % number_of_snapshots ) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collimator.py b/mxcubecore/HardwareObjects/DESY/P11Collimator.py new file mode 100644 index 0000000000..7bc0a676b3 --- /dev/null +++ b/mxcubecore/HardwareObjects/DESY/P11Collimator.py @@ -0,0 +1,140 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +import ast +from mxcubecore.HardwareObjects.NState import NState +from collections import OrderedDict +from mxcubecore.BaseHardwareObjects import HardwareObjectState + + +class P11Collimator(NState): + """Collimator hardware object class""" + + def init(self): + """Initialize the collimator with its motors and positions.""" + super().init() + + # Retrieve motors using their roles + self.y_motor = self.get_object_by_role("collimatory") # Y-axis motor + self.z_motor = self.get_object_by_role("collimatorz") # Z-axis motor + + self.log.info(f"Collimator Y Motor initialized: {self.y_motor}") + self.log.info(f"Collimator Z Motor initialized: {self.z_motor}") + + # Load positions from XML configuration + self.load_positions() + + # Load deltas for each motor + self.load_deltas() + + # Set _positions for UI access + self._positions = OrderedDict() + self._positions = self.positions + + def load_positions(self): + """Load predefined positions from the XML configuration.""" + self.log.info("Loading collimator positions from config") + positions_str = self.get_property("values") + + # Convert the string to a dictionary using ast.literal_eval + try: + self.positions = ast.literal_eval(positions_str) + if isinstance(self.positions, dict): + self.log.info(f"Available collimator positions: {self.positions}") + else: + raise ValueError("Positions data is not a dictionary") + except (SyntaxError, ValueError) as e: + self.log.error(f"Error parsing collimator positions: {e}") + raise ValueError( + "Invalid collimator positions format in the configuration." + ) + + def load_deltas(self): + """Load individual motor deltas from the XML configuration explicitly.""" + self.log.info("Loading deltas from config") + + # Fetch individual deltas for each motor + delta_y = self.get_property("delta_collimatory") + delta_z = self.get_property("delta_collimatorz") + + # If a delta is not specified, fallback to a default delta value + self.deltas = { + "collimatory": float(delta_y) + if delta_y is not None + else self.default_delta, + "collimatorz": float(delta_z) + if delta_z is not None + else self.default_delta, + } + + # Log the deltas for each motor + for motorname, delta in self.deltas.items(): + self.log.info(f"Delta for {motorname}: {delta}") + + def set_value(self, value): + """Set the collimator to the specified position.""" + if value not in self.positions: + raise ValueError(f"Invalid state value: {value}") + + y_position = self.positions[value]["collimatory"] + z_position = self.positions[value]["collimatorz"] + + # Move the motors + self.y_motor._set_value(y_position) + self.z_motor._set_value(z_position) + self.log.info(f"Setting collimator to position: {value}") + + def get_position_list(self): + """Return the list of available collimator positions.""" + return list(self.positions.keys()) + + def get_value(self): + """Get the current collimator position based on the motor positions.""" + current_y = self.y_motor.get_value() + current_z = self.z_motor.get_value() + + for position_name, position in self.positions.items(): + if self.is_within_deltas( + position.get("collimatory"), current_y, "collimatory" + ) and self.is_within_deltas( + position.get("collimatorz"), current_z, "collimatorz" + ): + return position_name # Return the matching position name + + def is_within_deltas(self, target_value, current_value, motor_name): + """Check if the current motor position is within the delta tolerance for that specific motor.""" + delta = self.deltas.get(motor_name) + if target_value is None or delta is None: + return False + return abs(current_value - target_value) <= delta + + def is_moving(self): + """Return True if any motor is moving.""" + return self.y_motor.is_moving() or self.z_motor.is_moving() + + def get_state(self): + """Determine the overall state of the collimator motor system.""" + if self.is_moving(): + return HardwareObjectState.BUSY + else: + return HardwareObjectState.READY diff --git a/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py b/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py index c37e569930..9a8fa5f92d 100644 --- a/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py +++ b/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,7 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11DetectorCover""" +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" import time import gevent diff --git a/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py b/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py index 0bf8741246..4ff0e65a4d 100644 --- a/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py +++ b/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py @@ -1,7 +1,7 @@ # encoding: utf-8 # # Project: MXCuBE -# https://github.com/mxcube. +# https://github.com/mxcube # # This file is part of MXCuBE software. # @@ -16,10 +16,11 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License -# along with MXCuBE. If not, see . +# along with MXCuBE. If not, see . -__credits__ = ["DESY P11"] +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" +__credits__ = ["DESY P11"] __category__ = "Motor" from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor @@ -149,6 +150,16 @@ def _set_value(self, value): # Wait until motor is reachiung the actual distance within tolerance. tolerance = 1.0 # mm Actual tolerance is within 0.3 range. while abs(self.get_value() - value) >= tolerance: + _state = self.chan_state.get_value() + if _state == "ON": + state = self.STATES.READY + self.update_state(state) + break + elif _state == "MOVING": + state = self.STATES.BUSY + else: + state = self.STATES.FAULT + self.update_state(state) time.sleep(0.5) def get_limits(self): diff --git a/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py b/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py new file mode 100644 index 0000000000..2189ee9d81 --- /dev/null +++ b/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py @@ -0,0 +1,87 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +from mxcubecore.BaseHardwareObjects import HardwareObject +import logging +import sys +import urllib.request + +__credits__ = ["MXCuBE collaboration"] + + +class P11DoorInterlock(HardwareObject): + def __init__(self, name): + HardwareObject.__init__(self, name) + + self.door_interlock_state = None + self.simulationMode = False + + def init(self): + self.door_interlock_state = self.STATES.READY + + def connected(self): + self.set_is_ready(True) + + def disconnected(self): + self.set_is_ready(False) + + def door_is_interlocked(self): + return self.door_interlock_state in [self.STATES.READY] + + def get_state(self): + return self.door_interlock_state + + def unlock(self): + self.breakInterlockEH() + + def unlock_door_interlock(self): + if self.door_interlock_state == "locked_active": + self.door_interlock_state = "unlocked" + self.emit("doorInterlockStateChanged", self.door_interlock_state, "") + + def breakInterlockEH(self): + """Command to break the interlock by sending a request to a URL.""" + if not self.simulationMode: + logging.info("Attempting to break interlock by opening EH") + url = self.get_property("unlockEH_url") + success = self.fetch_url(url) + if success: + logging.info("EH opened successfully") + # Update the state to reflect that the interlock was broken + self.emit("doorInterlockStateChanged", self.door_interlock_state, "") + else: + logging.error("Failed to open EH") + + def fetch_url(self, url, timeout=3, retries=10): + """Fetch URL with retry mechanism.""" + for attempt in range(retries): + try: + result = urllib.request.urlopen(url, None, timeout).readlines() + logging.info(f"Successfully fetched URL: {url}") + return True # Success + except Exception as e: + logging.error(f"Error fetching URL: {url} on attempt {attempt + 1}") + logging.error(f"Error details: {sys.exc_info()}") + if attempt + 1 == retries: + logging.error(f"All {retries} attempts failed.") + return False # Failed after retries diff --git a/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py b/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py index e54bbdce05..e015bc3326 100644 --- a/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py +++ b/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py @@ -1,7 +1,30 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + import os import logging -import binascii - +import time +import copy from mxcubecore.model import queue_model_objects as qmo from mxcubecore.model import queue_model_enumerables as qme @@ -46,6 +69,9 @@ def __init__(self, name): self.start_edna_command = None def _run_edna(self, input_file, results_file, process_directory): + # First submit MOSFLM job + self.mosflm_maxwell() + """Starts EDNA""" msg = "Starting EDNA characterisation using xml file %s" % input_file logging.getLogger("queue_exec").info(msg) @@ -62,24 +88,87 @@ def _run_edna(self, input_file, results_file, process_directory): return self.result - def edna_maxwell(self, process_directory, inputxml, outputxml): - """ - The function `edna_maxwell` is used to execute a command on a remote cluster using SSH and SBATCH. - - :param process_directory: The `process_directory` parameter is the directory where the processing - will take place. It is a string that represents the path to the directory - :param inputxml: The inputxml parameter is the path to the input XML file that will be used as - input for the EDNA process - :param outputxml: The `outputxml` parameter is the path to the output XML file that will be - generated by the EDNA process - """ - # TODO: Check if this function is still needed or adapt to use edna_command from XML config. + def mosflm_maxwell(self): + self.log.debug("==== MOSFLM CHARACTERISATION IN PROGRESS ==========") + + # Retrieve resolution value and number of frames + resolution = HWR.beamline.resolution.get_value() + frames = HWR.beamline.collect.current_dc_parameters["oscillation_sequence"][0][ + "number_of_images" + ] + + # Fetch the latest local master image filename + latest_h5_filename = HWR.beamline.detector.get_latest_local_master_image_name() + # Prepare local and remote image directory paths + image_dir_local, filename = os.path.split(latest_h5_filename) + remote_base_path = HWR.beamline.session.get_beamtime_metadata()[2] + image_dir = image_dir_local.replace("/gpfs/current", remote_base_path) + process_dir_local = image_dir_local.replace("/raw/", "/processed/") + process_dir = image_dir.replace("/raw/", "/processed/") + mosflm_path_local = os.path.join(process_dir_local, "mosflm") + mosflm_path = os.path.join(process_dir, "mosflm") + + self.log.debug(f'============MOSFLM======== mosflm_path="{mosflm_path}"') self.log.debug( - '=======EDNA========== PROCESS DIRECTORY="%s"' % process_directory + f'============MOSFLM======== mosflm_path_local="{mosflm_path_local}"' ) - self.log.debug('=======EDNA========== IN="%s"' % inputxml) - self.log.debug('=======EDNA========== OUT="%s"' % outputxml) + + # Create local MOSFLM directory + try: + self.mkdir_with_mode(mosflm_path_local, mode=0o777) + self.log.debug("=========== MOSFLM ============ Mosflm directory created") + except OSError as e: + self.log.debug(f"Cannot create mosflm directory: {e}") + + # Update datasets.txt file for presenterd + base_process_dir = HWR.beamline.collect.base_dir(process_dir_local, "processed") + datasets_file = os.path.join(base_process_dir, "datasets.txt") + try: + with open(datasets_file, "a") as file: + file.write( + f"{mosflm_path_local.split('/gpfs/current/processed/')[1]}\n" + ) + except (OSError, RuntimeWarning) as err: + self.log.debug(f"Cannot write to datasets.txt: {err}") + + # Create SBATCH command + ssh = HWR.beamline.session.get_ssh_command() + log_file_path = ( + mosflm_path.replace(remote_base_path, "/beamline/p11/current") + + "/mosflm.log" + ) + sbatch = HWR.beamline.session.get_sbatch_command( + jobname_prefix="mosflm", logfile_path=log_file_path + ) + + # Formulate processing command + cmd = ( + f"/asap3/petra3/gpfs/common/p11/processing/mosflm_sbatch.sh " + f"{image_dir} {filename} {mosflm_path.replace(remote_base_path, '/beamline/p11/current')} " + f"{frames} {resolution}" + ) + + # Log and execute the command + self.log.debug(f'=======MOSFLM========== ssh="{ssh}"') + self.log.debug(f'=======MOSFLM========== sbatch="{sbatch}"') + self.log.debug(f'=======MOSFLM========== executing process cmd="{cmd}"') + full_cmd = f'{ssh} "{sbatch} --wrap \\"{cmd}\\""' + self.log.debug(f"=======MOSFLM========== {full_cmd}") + + os.system(full_cmd) + + def edna_maxwell(self, process_directory, inputxml, outputxml): + """ + Executes a command on a remote cluster using SSH and SBATCH for EDNA processing. + + :param process_directory: Directory where the processing will take place. + :param inputxml: Path to the input XML file. + :param outputxml: Path to the output XML file that will be generated. + """ + self.log.debug(f'=======EDNA========== PROCESS DIRECTORY="{process_directory}"') + self.log.debug(f'=======EDNA========== IN (XML INPUT)="{inputxml}"') + self.log.debug(f'=======EDNA========== OUT (XML OUTPUT)="{outputxml}"') ssh = HWR.beamline.session.get_ssh_command() sbatch = HWR.beamline.session.get_sbatch_command( @@ -88,55 +177,64 @@ def edna_maxwell(self, process_directory, inputxml, outputxml): + "/edna.log", ) - # Check path conversion inxml = inputxml.replace("/gpfs", "/beamline/p11") outxml = outputxml.replace( - "/gpfs/current/raw", "/beamline/p11/current/processed" + "/gpfs/current/processed", "/beamline/p11/current/processed" ) - processpath = ( - process_directory.replace( - "/gpfs/current/raw", "/beamline/p11/current/processed" - ) - + "/edna" - ) - self.mkdir_with_mode( - process_directory.replace("/gpfs/current/raw", "/gpfs/current/processed/") - + "/edna", - mode=0o777, + + processpath = process_directory.replace( + "/gpfs/current/processed", "/beamline/p11/current/processed" ) self.log.debug( - '=======EDNA========== CLUSTER PROCESS DIRECTORY="%s"' % processpath + f'=======EDNA========== CLUSTER PROCESS DIRECTORY="{processpath}"' ) - self.log.debug('=======EDNA========== CLUSTER IN="%s"' % inxml) - self.log.debug('=======EDNA========== CLUSTER OUT="%s"' % outxml) + self.log.debug(f'=======EDNA========== CLUSTER IN="{inxml}"') + self.log.debug(f'=======EDNA========== CLUSTER OUT="{outxml}"') + self.log.debug(f'=======EDNA========== ssh="{ssh}"') + self.log.debug(f'=======EDNA========== sbatch="{sbatch}"') - self.log.debug('=======EDNA========== ssh="%s"' % ssh) - self.log.debug('=======EDNA========== sbatch="%s"' % sbatch) + cmd = f"/asap3/petra3/gpfs/common/p11/processing/edna_sbatch.sh {inxml} {outxml} {processpath}" - cmd = ( - "/asap3/petra3/gpfs/common/p11/processing/edna_sbatch.sh " - + "{inxml:s} {outxml:s} {processpath:s}" - ).format(inxml=inxml, outxml=outxml, processpath=processpath) + self.log.debug(f'=======EDNA========== executing process cmd="{cmd}"') + self.log.debug(f'=======EDNA========== {ssh} "{sbatch} --wrap \\"{cmd}\\""') + logging.info(f'{ssh} "{sbatch} --wrap \\"{cmd}\\""') - self.log.debug('=======EDNA========== executing process cmd="%s"' % cmd) - self.log.debug( - '=======EDNA========== {ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) - ) + waitforxml = outputxml.replace("/raw/", "/processed/") + self.log.debug(f"=======EDNA========== WAITING FOR OUTPUTXML IN {waitforxml}") - logging.info( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}"\\"'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd - ) - ) + self.log.debug(f'=======EDNA Script========== {ssh} "{cmd}"') + os.system(f'{ssh} "{cmd}"') + + self.wait_for_file(waitforxml, timeout=60) - os.system( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}"\\"'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd + # Update datasets.txt file for presenterd + base_process_dir = "/gpfs/current/processed" + datasets_file = os.path.join(base_process_dir, "datasets.txt") + try: + with open(datasets_file, "a") as file: + file.write( + f"{process_directory.split('/gpfs/current/processed/')[1]}\n" + ) + except (OSError, RuntimeWarning) as err: + self.log.debug(f"Cannot write to datasets.txt: {err}") + + def wait_for_file(self, file_path, timeout=60, check_interval=1): + start_time = time.time() + while not os.path.exists(file_path): + elapsed_time = time.time() - start_time + if elapsed_time >= timeout: + self.log.debug( + f"Timeout reached. File '{file_path}' not found within {timeout} seconds." + ) + raise RuntimeWarning( + f"Timeout reached. File '{file_path}' not found within {timeout} seconds." + ) + self.log.info( + f"Waiting for file '{file_path}'... ({elapsed_time:.1f}/{timeout} seconds elapsed)" ) - ) + time.sleep(check_interval) + self.log.info(f"File '{file_path}' found.") def input_from_params(self, data_collection, char_params): edna_input = XSDataInputMXCuBE.parseString(self.edna_default_input) @@ -165,6 +263,8 @@ def input_from_params(self, data_collection, char_params): pass try: + # Flux get_value() subsequently executing measure_flux() to fill in the dictionary + beam.setFlux(XSDataFlux(HWR.beamline.flux.get_value())) except AttributeError: pass @@ -263,38 +363,265 @@ def input_from_params(self, data_collection, char_params): acquisition_parameters = data_collection.acquisitions[0].acquisition_parameters path_template = data_collection.acquisitions[0].path_template - # Make sure there is a proper path conversion between different mount points + # NB!: path_template content is in queue_model_objects.py logging.info( - "======= Characterisation path template ====%s", path_template.directory + "======= Characterisation path template directory ====%s", + path_template.directory, ) - - image_dir = path_template.directory.replace( - "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] + logging.info( + "======= Characterisation path template process_directory ====%s", + path_template.process_directory, + ) + logging.info( + "======= Characterisation path template xds_dir ====%s", + path_template.xds_dir, + ) + logging.info( + "======= Characterisation path template base_prefix ====%s", + path_template.base_prefix, + ) + logging.info( + "======= Characterisation path template mad_prefix ====%s", + path_template.mad_prefix, + ) + logging.info( + "======= Characterisation path template reference_image_prefix ====%s", + path_template.reference_image_prefix, + ) + logging.info( + "======= Characterisation path template wedge_prefix ====%s", + path_template.wedge_prefix, + ) + logging.info( + "======= Characterisation path template run_number ====%s", + str(path_template.run_number), + ) + logging.info( + "======= Characterisation path template suffix ====%s", path_template.suffix + ) + logging.info( + "======= Characterisation path template precision ====%s", + str(path_template.precision), + ) + logging.info( + "======= Characterisation path template start_num ====%s", + str(path_template.start_num), + ) + logging.info( + "======= Characterisation path template num_files ====%s", + str(path_template.num_files), + ) + logging.info( + "======= Characterisation path template compression ====%s", + path_template.compression, ) - logging.info(image_dir) + # Make sure there is a proper path conversion between different mount points + + # This is where the folder with h5 files is located. + # It is straightforward to construct it from xds_dir + image_dir = path_template.xds_dir.replace( + "/gpfs/current/processed/", "/beamline/p11/current/raw/" + ).replace("/edna", "") + + # This is needed because EDNA needs to concert eiger2cbf in place + # The directory is created by local user, EDNA process is executed by another without + # access rights. + raw_char_directory = path_template.xds_dir.replace( + "/gpfs/current/processed/", "/gpfs/current/raw/" + ).replace("/edna", "") + os.system(f"chmod +777 {raw_char_directory}") + + # Here is actual path to the *.h5 data are defined: + # It is expected to be %5d (4 zeros), but files are generated %6d (5 leading zeros). + # It also requires _data_%6d.h5 + # TODO: Fix elsewhere. + path_template.precision = 6 path_str = os.path.join(image_dir, path_template.get_image_file_name()) - logging.info(path_template.xds_dir) - characterisation_dir = path_template.xds_dir.replace( - "/autoprocessing_", "/characterisation_" + logging.info( + "======= Characterisation path of what image filename is expected ====%s", + path_template.get_image_file_name(), + ) + logging.info( + "======= Characterisation path where to search for images ====%s", path_str ) - os.makedirs(characterisation_dir, mode=0o755, exist_ok=True) + # NB!: Directories at this point are created elswhere (data_collection_hook) + # xds_dir at this point already has all the needed substitutions. + characterisation_dir = path_template.xds_dir + + # pattern = r"(_\d{6}\.h5)$" for img_num in range(int(acquisition_parameters.num_images)): image_file = XSDataImage() path = XSDataString() path.value = path_str % (img_num + 1) image_file.path = path + image_file.path.value, image_file.number = XSDataInteger(img_num + 1) data_set.addImageFile(image_file) edna_input.addDataSet(data_set) edna_input.process_directory = characterisation_dir + return edna_input + def dc_from_output(self, edna_result, reference_image_collection): + data_collections = [] + + crystal = copy.deepcopy(reference_image_collection.crystal) + ref_proc_params = reference_image_collection.processing_parameters + processing_parameters = copy.deepcopy(ref_proc_params) + + try: + char_results = edna_result.getCharacterisationResult() + edna_strategy = char_results.getStrategyResult() + collection_plan = edna_strategy.getCollectionPlan()[0] + wedges = collection_plan.getCollectionStrategy().getSubWedge() + except Exception: + pass + else: + try: + resolution = ( + collection_plan.getStrategySummary().getResolution().getValue() + ) + resolution = round(resolution, 3) + except AttributeError: + resolution = None + + try: + transmission = ( + collection_plan.getStrategySummary().getAttenuation().getValue() + ) + transmission = round(transmission, 2) + except AttributeError: + transmission = None + + try: + screening_id = edna_result.getScreeningId().getValue() + except AttributeError: + screening_id = None + + # GB merging wedges wedges + osc_very_end = ( + wedges[-1] + .getExperimentalCondition() + .getGoniostat() + .getRotationAxisEnd() + .getValue() + ) + + for i in range(0, 1): # GB len(wedges)): + wedge = wedges[i] + exp_condition = wedge.getExperimentalCondition() + goniostat = exp_condition.getGoniostat() + beam = exp_condition.getBeam() + + acq = qmo.Acquisition() + acq.acquisition_parameters = ( + HWR.beamline.get_default_acquisition_parameters() + ) + acquisition_parameters = acq.acquisition_parameters + + acquisition_parameters.centred_position = ( + reference_image_collection.acquisitions[ + 0 + ].acquisition_parameters.centred_position + ) + + acq.path_template = HWR.beamline.get_default_path_template() + + # Use the same path template as the reference_collection + # and update the members the needs to be changed. Keeping + # the directories of the reference collection. + ref_pt = reference_image_collection.acquisitions[0].path_template + + acq.path_template = copy.deepcopy(ref_pt) + + # This part was removing the "raw" from final directory and failing to collect data from EDNA-generated diffraction plan. + # Keep it here until it is clear that it is not propagating further. + # acq.path_template.directory = "/".join( + # ref_pt.directory.split("/")[0:-2] + # ) + + # acq.path_template.wedge_prefix = "w" + str(i + 1) + acq.path_template.reference_image_prefix = str() + + if resolution: + acquisition_parameters.resolution = resolution + + if transmission: + acquisition_parameters.transmission = transmission + + if screening_id: + acquisition_parameters.screening_id = screening_id + + try: + acquisition_parameters.osc_start = ( + goniostat.getRotationAxisStart().getValue() + ) + except AttributeError: + pass + """ GB: + try: + acquisition_parameters.osc_end = ( + goniostat.getRotationAxisEnd().getValue() + ) + except AttributeError: + pass + """ + acquisition_parameters.osc_end = osc_very_end + + try: + acquisition_parameters.osc_range = ( + goniostat.getOscillationWidth().getValue() + ) + except AttributeError: + pass + + try: + num_images = int( + abs( + acquisition_parameters.osc_end + - acquisition_parameters.osc_start + ) + / acquisition_parameters.osc_range + ) + + acquisition_parameters.first_image = 1 + acquisition_parameters.num_images = num_images + acq.path_template.num_files = num_images + acq.path_template.start_num = 1 + + except AttributeError: + pass + + try: + acquisition_parameters.transmission = ( + beam.getTransmission().getValue() + ) + except AttributeError: + pass + + try: + acquisition_parameters.energy = round( + (123_984.0 / beam.getWavelength().getValue()) / 10000.0, 4 + ) + except AttributeError: + pass + + try: + acquisition_parameters.exp_time = beam.getExposureTime().getValue() + except AttributeError: + pass + + dc = qmo.DataCollection([acq], crystal, processing_parameters) + data_collections.append(dc) + + return data_collections + def mkdir_with_mode(self, directory, mode): """ The function creates a directory with a specified mode if it does not already exist. @@ -313,3 +640,23 @@ def mkdir_with_mode(self, directory, mode): # self.checkPath(directory,force=True) self.log.debug("local directory created") + + def get_html_report(self, edna_result): + """ + Args: + output (EDNAResult) EDNAResult object + + Returns: + (str) The path to the html result report generated by the characterisation + software + """ + html_report = None + + try: + html_report = str(edna_result.getHtmlPage().getPath().getValue()) + html_report = html_report.replace("/beamline/p11", "/gpfs") + + except AttributeError: + pass + + return html_report diff --git a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py index 73e01afe99..700707996e 100644 --- a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py +++ b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py @@ -18,11 +18,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" import gevent - from mxcubecore.Command.Tango import DeviceProxy from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector @@ -210,6 +209,7 @@ def set_metadata(self): def start_acquisition(self): self.eiger_dev.Arm() + self.wait_ready() def stop_acquisition(self): self.eiger_dev.Abort() @@ -264,3 +264,8 @@ def get_attr_enum(self, dev, attr): def get_eiger_name_pattern(self): return self.writer_dev.NamePattern + + def get_latest_local_master_image_name(self): + latest_image = self.get_eiger_name_pattern() + latest_image = f"/gpfs{latest_image}_master.h5" + return latest_image diff --git a/mxcubecore/HardwareObjects/DESY/P11Energy.py b/mxcubecore/HardwareObjects/DESY/P11Energy.py index cda97ccd68..891ea7b534 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Energy.py +++ b/mxcubecore/HardwareObjects/DESY/P11Energy.py @@ -18,11 +18,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy -from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup +from mxcubecore import HardwareRepository as HWR import logging @@ -30,7 +30,6 @@ class P11Energy(AbstractEnergy): - _default_energy = 12.0 def __init__(self, name): @@ -116,8 +115,16 @@ def _set_value(self, value): prog_value = value * 1000 self.chan_autobrake.set_value(True) if self.get_state() == self.STATES.READY: - self.log.debug("Programming ENERGY to %s" % prog_value) - self.chan_energy.set_value(prog_value) + + current_value = self.get_value() + if abs(current_value - value) < 0.01: + self.log.debug( + "The difference between the current and desired energy values is less than 0.01. No change made." + ) + else: + self.log.debug("Programming ENERGY to %s eV" % prog_value) + self.chan_energy.set_value(prog_value) + self.log.debug(f"Energy value set to {value} keV.") def get_value(self): """ @@ -137,9 +144,6 @@ def get_value(self): return None return value - # def get_limits(self): - # return my_limits - def test_hwo(hwo): print("Energy is: {0} keV".format(hwo.get_value())) diff --git a/mxcubecore/HardwareObjects/DESY/P11FastShutter.py b/mxcubecore/HardwareObjects/DESY/P11FastShutter.py index 8314dde9e4..ae81fc6a2e 100644 --- a/mxcubecore/HardwareObjects/DESY/P11FastShutter.py +++ b/mxcubecore/HardwareObjects/DESY/P11FastShutter.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,7 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11Shutter""" +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" from enum import Enum from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState @@ -41,7 +43,6 @@ class P11FastShutter(AbstractNState): default_close_time = 3 def __init__(self, name): - super().__init__(name) self.chan_value = None diff --git a/mxcubecore/HardwareObjects/DESY/P11Flux.py b/mxcubecore/HardwareObjects/DESY/P11Flux.py index d1475ab6f4..27673432c7 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Flux.py +++ b/mxcubecore/HardwareObjects/DESY/P11Flux.py @@ -1,3 +1,4 @@ +# encoding: utf-8 # # Project: MXCuBE # https://github.com/mxcube @@ -17,42 +18,71 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -from random import random +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +import numpy as np +from scipy.interpolate import Rbf, interp1d + from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux from mxcubecore import HardwareRepository as HWR + __credits__ = ["MXCuBE collaboration"] __category__ = "General" class P11Flux(AbstractFlux): - - # default_flux - for initialising mockup - default_flux = 5e12 - def __init__(self, name): - AbstractFlux.__init__(self, name) + super().__init__(name) self.measured_flux_list = [] self.measured_flux_dict = {} self.current_flux_dict = {} def init(self): - + # Here are reference flux values from the config file + # Those are values at which flux is measured + self.default_flux = self.get_property("defaultFlux") + + self.default_beamsize = self.get_property("defaultBeamsize") + self.default_pinhole = self.get_property("defaultPinhole") + self.default_energy = self.get_property("defaultEnergy") + self.default_current = self.get_property("defaultCurrent") self.measure_flux() def get_value(self): """Get flux at current transmission in units of photons/s""" - - """ FLUX IS CHEETED HERE - NOWERE ELSE!""" + # TODO: Once the motor movements are involved, check the logic. + self.measure_flux() return self.current_flux_dict["flux"] def measure_flux(self): """Measures intesity""" beam_size = HWR.beamline.beam.get_beam_size() transmission = HWR.beamline.transmission.get_value() - flux = self.default_flux * (1 + random()) + energy = HWR.beamline.energy.get_value() * 1000 + # TODO: Check pinhole from HWR.beamline.diffractometer + current_pinhole = HWR.beamline.beam.get_pinhole_size() + current = HWR.beamline.machine_info.get_current() + mess = HWR.beamline.machine_info.get_message() + + flux = ( + self.estimate_flux_with_reference( + max(beam_size[0] * 1000, beam_size[0] * 1000), + max(beam_size[0] * 1000, beam_size[0] * 1000), + energy, + current, + self.default_beamsize, + self.default_pinhole, + self.default_energy, + self.default_flux, + self.default_current, + ) + * transmission + / 100.0 + ) self.measured_flux_list = [ { @@ -70,3 +100,108 @@ def measure_flux(self): "fluxInfoChanged", {"measured": self.measured_flux_dict, "current": self.current_flux_dict}, ) + + self.log.debug( + f"Estimated flux for beam size {max(beam_size[0] * 1000, beam_size[0] * 1000)}, pinhole size {current_pinhole}, transmission {transmission}, energy {energy} eV and current {current} mA: {flux:.2e} ph/s" + ) + + def estimate_flux_with_reference( + self, + beam_size, + pinhole_size, + energy, + current, + ref_beam_size, + ref_pinhole_size, + ref_energy, + ref_flux, + ref_current, + ): + """ + Helper function to estimate the flux based on the input beam size, pinhole size, energy, and current, scaled by a reference flux and current. + Temporary plug to have realistic flux estimations. + + Parameters: + beam_size (int): Beam size in numerical format (e.g., 300, 200, 100, 50, 20, 9) + pinhole_size (int): Pinhole size in numerical format (e.g., 200, 100, 50, 20) + energy (int): Energy in eV + current (float): Current in mA + ref_beam_size (int): Reference beam size + ref_pinhole_size (int): Reference pinhole size + ref_energy (int): Reference energy in eV + ref_flux (float): Reference flux value + ref_current (float): Reference current in mA + + Returns: + float: Estimated flux + """ + # Measured table at different beam parameters + beam_sizes = np.array([300, 300, 300, 300, 200, 100, 50, 20, 9]) + pinhole_sizes = np.array([200, 100, 50, 20, 200, 200, 200, 200, 100]) + fluxes = np.array( + [2e12, 5e11, 1.25e11, 2e10, 4.4e12, 9.9e12, 9.9e12, 9.9e12, 8.7e12] + ) + energies = np.full(beam_sizes.shape, 12000) + + # Measured energy-flux dependance + energy_flux = np.array( + [ + [6000, 1.70e12], + [7000, 3.70e12], + [8000, 4.90e12], + [10000, 3.90e12], + [12000, 4.37e12], + [14000, 4.20e12], + [16000, 3.80e12], + [18000, 3.00e12], + [20000, 2.20e12], + [22000, 1.60e12], + [24000, 9.10e11], + [26000, 5.80e11], + ] + ) + + X = np.column_stack((beam_sizes, pinhole_sizes, energies)) + y = fluxes + rbf_interpolator = Rbf(X[:, 0], X[:, 1], X[:, 2], y, function="linear") + energy_flux_interpolator = interp1d( + energy_flux[:, 0], + energy_flux[:, 1], + kind="linear", + fill_value="extrapolate", + ) + estimated_ref_flux = rbf_interpolator( + ref_beam_size, ref_pinhole_size, ref_energy + ) + + if np.isnan(estimated_ref_flux): + raise RuntimaWarning( + "Reference flux cannot be estimated using the interpolator. Check reference points." + ) + + # Scale the flux based on the reference flux + scale_factor = ref_flux / estimated_ref_flux + + # Estimate the flux at the desired beam, pinhole size, and energy + estimated_flux = rbf_interpolator( + beam_size, pinhole_size, 12000 + ) # Always interpolate at 12000 eV + + if np.isnan(estimated_flux): + raise RuntimaWarning( + "Desired flux cannot be estimated using the interpolator. Check input points." + ) + + # Scale the estimated flux based on the energy-dependent flux variation + energy_scale_factor = energy_flux_interpolator( + energy + ) / energy_flux_interpolator( + 12000 + ) # Scaling relative to 12000 eV + + # Scale the flux based on the current + current_scale_factor = current / ref_current + + return ( + estimated_flux * scale_factor * energy_scale_factor * current_scale_factor + ) diff --git a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py index 18aaa89172..4afe4cb053 100644 --- a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py +++ b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py @@ -1,7 +1,34 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + import logging import ssl from mxcubecore.HardwareObjects.ISPyBClient import ISPyBClient from mxcubecore import HardwareRepository as HWR +from suds import WebFault +from urllib.error import URLError +from suds.transport import TransportError + ssl._create_default_https_context = ssl._create_unverified_context @@ -73,3 +100,36 @@ def prepare_image_for_lims(self, image_dict): image_dict[prop] = ispyb_path except RuntimeWarning("Can not prepare image path fir LIMS for %s" % prop): pass + + def get_proposal(self, proposal_code, proposal_number): + logging.getLogger("HWR").debug( + "ISPyB. Obtaining proposal for code=%s / prop_number=%s" + % (proposal_code, proposal_number) + ) + + try: + if self._shipping: + # Attempt to fetch the proposal from ISPyB + proposal = self._shipping.service.findProposal( + proposal_code, proposal_number + ) + else: + raise URLError("Shipping service unavailable") + + if proposal: + proposal["code"] = proposal_code + proposal["number"] = proposal_number + return {"Proposal": proposal, "status": {"code": "ok"}} + except (WebFault, URLError, TransportError) as e: + # Log the error and fallback + logging.getLogger("ispyb_client").exception( + "Error fetching proposal. Returning fallback values." + ) + return { + "Proposal": { + "code": proposal_code, + "number": proposal_number, + "title": "Unknown Proposal", + }, + "status": {"code": "error", "msg": "ISPyB is not connected."}, + } diff --git a/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py b/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py new file mode 100644 index 0000000000..049475123c --- /dev/null +++ b/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py @@ -0,0 +1,136 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +import logging +import gevent +from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo +from mxcubecore.HardwareObjects.TangoMachineInfo import TangoMachineInfo +from mxcubecore.HardwareObjects.TangoMachineInfo import TangoMachineInfo +from PyQt5.QtCore import QObject, pyqtSignal + + +class P11MachineInfo(TangoMachineInfo, QObject): + # Declare the signal + valuesChanged = pyqtSignal(dict) + + # Declare the signal + machineCurrentChanged = pyqtSignal(float, bool) + + def __init__(self, *args, **kwargs): + """Initializes the P11MachineInfo and QObject.""" + # Initialize both parent classes explicitly + TangoMachineInfo.__init__( + self, *args, **kwargs + ) # Initialize the TangoMachineInfo class + QObject.__init__(self) # Initialize the QObject class + + def init(self): + """Initialize Tango channels for machine info.""" + super().init() + + self.emit_values() # Emit initial values after init + gevent.spawn(self.periodic_update) + + def periodic_update(self): + while True: + self.emit_values() + gevent.sleep(3) + + def emit_values(self): + """Emit the current machine info values.""" + values_dict = { + "current": { + "title": "Current (mA)", + "value": self.get_current() or 0, # Ensure value is not None + }, + "lifetime": {"title": "Lifetime (h)", "value": self.get_lifetime() or 0}, + "energy": { + "title": "Energy (GeV)", + "value": self.get_maschine_energy() or 0, + }, + "message": { + "title": "Message", + "value": self.get_message() or "No message", + }, + } + + logging.info(f"Emitting machine info values: {values_dict}") + self.valuesChanged.emit(values_dict) # Emit the valuesChanged signal + + def get_value(self): + """Returns a dictionary of the current machine information.""" + try: + self._mach_info_dict = {} # Initialize dictionary + + # Fetch the current values from their respective methods + self._mach_info_dict["current"] = self.get_current() or 0 + self._mach_info_dict["lifetime"] = self.get_lifetime() or 0 + self._mach_info_dict["energy"] = self.get_maschine_energy() or 0 + self._mach_info_dict["message"] = self.get_message() or "No message" + + logging.info( + f"Machine Info Dictionary: {self._mach_info_dict}" + ) # Log the populated dictionary + return self._mach_info_dict # Return the dictionary with machine info + + except Exception as e: + logging.error(f"Error getting machine values: {e}") + return {} # Return empty dictionary if there's an error + + def get_current(self): + try: + current_value = ( + self.current.get_value() + ) # Fetch the value from the Tango hardware + return round(current_value, 2) + except AttributeError: + logging.error("Error reading 'current': Attribute 'current' not found.") + return 0 + + def get_lifetime(self): + try: + lifetime_value = self.lifetime.get_value() # Fetch lifetime value + return round(lifetime_value, 2) + except AttributeError: + logging.error("Error reading 'lifetime': Attribute 'lifetime' not found.") + return 0 + + def get_maschine_energy(self): + try: + energy_value = self.energy.get_value() # Fetch energy value + return round(energy_value, 2) + except AttributeError: + logging.error("Error reading 'energy': Attribute 'energy' not found.") + return 0 + + def get_message(self): + try: + message_value = self.message.get_value() # Fetch message from hardware + return message_value + except AttributeError: + logging.error("Error reading 'message': Attribute 'message' not found.") + return "Message unavailable" + + def update_current(self, current_value, in_range): + # Emit the signal with the current machine value and its range status + self.machineCurrentChanged.emit(current_value, in_range) diff --git a/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py b/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py index 29a294a452..7f09037448 100644 --- a/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py +++ b/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py @@ -18,16 +18,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" +from gevent.event import AsyncResult - -from tango import DeviceProxy +from tango import DeviceProxy, DevFailed from mxcubecore.TaskUtils import task from mxcubecore.HardwareObjects.GenericDiffractometer import ( DiffractometerState, GenericDiffractometer, ) + from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore import HardwareRepository as HWR from enum import Enum, unique @@ -43,7 +44,6 @@ import sys import logging - murko_path = os.getenv("MURKO_PATH") sys.path.insert(1, murko_path) from murko import get_predictions, plot_analysis @@ -168,6 +168,34 @@ def init(self): self.nclicks = 3 self.step = 120 + self.lower_bound_ch = self.get_channel_object("acq_lower_bound") + self.upper_bound_ch = self.get_channel_object("acq_upper_bound") + + self.acq_arm_cmd = self.get_command_object("acq_arm") + self.acq_abort = self.get_command_object("acq_abort") + self.acq_on_cmd = self.get_command_object("acq_on") + self.acq_off_cmd = self.get_command_object("acq_off") + self.acq_window_off_cmd = self.get_command_object("acq_window_off") + + if None in [ + self.lower_bound_ch, + self.upper_bound_ch, + self.acq_arm_cmd, + self.acq_on_cmd, + self.acq_off_cmd, + self.acq_window_off_cmd, + ]: + self.init_ok = False + self.log.debug("lower_bound_ch: %s" % self.lower_bound_ch) + self.log.debug("upper_bound_ch: %s" % self.upper_bound_ch) + self.log.debug("acq_arm_cmd: %s" % self.acq_arm_cmd) + self.log.debug("acq_on_cmd: %s" % self.acq_on_cmd) + self.log.debug("acq_off_cmd: %s" % self.acq_off_cmd) + self.log.debug("acq_window_off_cmd: %s" % self.acq_window_off_cmd) + else: + self.init_ok = True + + def update_beam_position(self): zoom_hwobj = self.motor_hwobj_dict["zoom"] image_dimensions = zoom_hwobj.camera_hwobj.get_image_dimensions() @@ -255,9 +283,9 @@ def predict_click_pix(self, frame): h = 0.5 # Save the debug results - name_pattern = "%s_%s.jpg" % (os.getuid(), time.asctime().replace(" ", "_")) - directory = "%s/murko" % os.getenv("HOME") - + name_pattern = f"{os.getuid()}_{time.asctime().replace(' ', '_')}.jpg" + directory = f"{os.getenv('HOME')}/murko" + os.makedirs(directory, exist_ok=True) template = os.path.join(directory, name_pattern) plot_analysis([image_jpeg], analysis, image_paths=[template]) @@ -402,7 +430,7 @@ def automatic_ai_centring( if k <= n_clicks: while str(dev_gonio.State()) != "ON": time.sleep(0.1) - self.centring_phi.set_value(omega + step) + self.centring_phi.set_value(omega + step, timeout=0) while str(dev_gonio.State()) != "ON": time.sleep(0.1) @@ -677,175 +705,94 @@ def shift(self, t, f, b, n, beta): s[mask == 1] = self.planparallel_shift(b, t_base[mask == 1], n, sense=-1) return s - def manual_centring( - self, - n_clicks=3, - alignmenty_direction=1.0, - alignmentz_direction=1.0, - centringx_direction=1.0, - centringy_direction=1.0, - ): + + def manual_centring(self, phi_range=120, n_points=3): """ Descript. : """ - logging.getLogger("user_level_log").info("Starting manual centring") - _start = time.time() - result_position = {} - - reference_position = self.get_positions() - - vertical_clicks = [] - horizontal_clicks = [] - vertical_discplacements = [] - horizontal_displacements = [] - omegas = [] - images = [] - calibrations = [] + X = [] + Y = [] + PHI = [] - if isinstance(self.nclicks, int) and self.nclicks >= 3: - n_clicks = self.nclicks - - logging.getLogger("user_level_log").info( - "Expected number of clicks %d" % (n_clicks) - ) + beam_xc, beam_yc = self.beam_position + self.log.debug("STARTING Manual Centring") - if self.step is not None: - step = self.step - else: - step = 360.0 / (n_clicks) + motor_positions = { + 'phiy': self.centring_phiy.motor.get_value(), + 'sampx': self.centring_sampx.motor.get_value(), + 'sampy': self.centring_sampy.motor.get_value(), + 'phi': self.centring_phi.motor.get_value(), + } - logging.getLogger("user_level_log").info("Default centring step %.2f" % (step)) + phi_mot = self.centring_phi.motor + phi_start_pos = phi_mot.get_value() - for k in range(n_clicks): - self.user_clicked_event = gevent.event.AsyncResult() + for click in range(n_points): + self.user_clicked_event = AsyncResult() x, y = self.user_clicked_event.get() - image = HWR.beamline.sample_view.camera.last_jpeg - calibration = np.array( - [1.0 / self.pixels_per_mm_y, 1.0 / self.pixels_per_mm_x] - ) - omega = self.centring_phi.motor.get_value() - - vertical_clicks.append(y) - horizontal_clicks.append(x) - omegas.append(omega) - images.append(image) - calibrations.append([calibration]) - - x -= self.beam_position[0] - x /= self.pixels_per_mm_x - y -= self.beam_position[1] - y /= self.pixels_per_mm_y - vertical_discplacements.append(y) - horizontal_displacements.append(x) - - logging.getLogger("HWR").info("click %d %f %f %f" % (k + 1, omega, x, y)) - - if k <= n_clicks: - self.centring_phi.set_value(omega + step) - - name_pattern = "%s_%s" % (os.getuid(), time.asctime().replace(" ", "_")) - directory = "%s/manual_optical_alignment" % os.getenv("HOME") - - vertical_discplacements = np.array(vertical_discplacements) * 1.0e3 - - angles = np.radians(omegas) - - initial_parameters = lmfit.Parameters() - initial_parameters.add_many( - ("c", 0.0, True, -5e3, +5e3, None, None), - ("r", 0.0, True, 0.0, 4e3, None, None), - ("alpha", -np.pi / 3, True, -2 * np.pi, 2 * np.pi, None, None), - ("front", 0.01, True, 0.0, 1.0, None, None), - ("back", 0.005, True, 0.0, 1.0, None, None), - ("n", 1.31, True, 1.29, 1.33, None, None), - ("beta", 0.0, True, -2 * np.pi, +2 * np.pi, None, None), - ) - - fit_y = lmfit.minimize( - self.refractive_model_residual, - initial_parameters, - method="nelder", - args=(angles, vertical_discplacements), - ) - - optimal_params = fit_y.params - v = optimal_params.valuesdict() - c = v["c"] - r = v["r"] - alpha = v["alpha"] - front = v["front"] - back = v["back"] - n = v["n"] - beta = v["beta"] - - c *= 1.0e-3 - r *= 1.0e-3 - front *= 1.0e-3 - back *= 1.0e-3 - - horizontal_center = np.mean(horizontal_displacements) - - d_sampx = centringx_direction * r * np.sin(alpha) - d_sampy = centringy_direction * r * np.cos(alpha) - d_y = alignmenty_direction * horizontal_center - d_z = alignmentz_direction * c - - move_vector_dictionary = { - "phiz": d_z, - "phiy": d_y, - "sampx": d_sampx, - "sampy": d_sampy, - } + if click < 2: + phi_mot.set_value_relative(phi_range) + + X.append(x) + Y.append(y) + PHI.append(phi_mot.get_value()) + + DX = [] + DY = [] + ANG = [] + + P = [] + Q = [] + + for i in range(n_points): + dx = X[i] - beam_xc + dy = Y[i] - beam_yc + ang = math.radians( PHI[i]) + + DX.append(dx) + DY.append(dy) + ANG.append(ang) + + for i in range(n_points): + y0 = DY[i] + ang0 = ANG[i] + if i < (n_points-1): + y1 = DY[i+1] + ang1 = ANG[i+1] + else: + y1 = DY[0] + ang1 = ANG[0] - for motor in reference_position: - result_position[motor] = reference_position[motor] - if motor in move_vector_dictionary: - result_position[motor] += move_vector_dictionary[motor] + p = ( y0*math.sin(ang1) - y1*math.sin(ang0) ) / math.sin(ang1-ang0) + q = ( y0*math.cos(ang1) - y1*math.cos(ang0) ) / math.sin(ang1-ang0) - _end = time.time() - duration = _end - _start - self.log.info( - "input and analysis in manual_centring took %.3f seconds" % duration - ) + P.append(p) + Q.append(q) - results = { - "vertical_clicks": vertical_clicks, - "horizontal_clicks": horizontal_clicks, - "vertical_discplacements": vertical_discplacements, - "horizontal_displacements": horizontal_displacements, - "omegas": omegas, - "angles": angles, - "calibrations": calibrations, - "reference_position": reference_position, - "result_position": result_position, - "duration": duration, - "vertical_optimal_parameters": v, - "move_vector_dictionary": move_vector_dictionary, - } + x_s = -sum(Q)/n_points + y_s = sum(P)/n_points + z_s = sum(DX)/n_points - template = os.path.join(directory, name_pattern) + x_d_mm = x_s / self.pixels_per_mm_y + y_d_mm = y_s / self.pixels_per_mm_y + z_d_mm = z_s / self.pixels_per_mm_x - if not os.path.isdir(directory): - os.makedirs(directory) + x_d = self.centring_sampx.mm_to_units(x_d_mm) + y_d = self.centring_sampy.mm_to_units(y_d_mm) + z_d = self.centring_phiy.mm_to_units(z_d_mm) - clicks_filename = "%s_clicks.pickle" % template - f = open(clicks_filename, "wb") - pickle.dump(results, f) - f.close() + sampx_mot = self.centring_sampx.motor + sampy_mot = self.centring_sampy.motor + phiy_mot = self.centring_phiy.motor - self.log.info( - "manual_centring finished in %.3f seconds" % (time.time() - _start) - ) - - result_position = {} - result_position["phi"] = reference_position["phi"] - for key in move_vector_dictionary: - result_position[key] = ( - reference_position[key] + 1e3 * move_vector_dictionary[key] - ) + x_pos = sampx_mot.get_value() + x_d + y_pos = sampy_mot.get_value() + y_d + z_pos = phiy_mot.get_value() + z_d - self.log.info("result_position %s" % str(result_position)) - return result_position + motor_positions['phiy'] = z_pos + motor_positions['sampx'] = x_pos + motor_positions['sampy'] = y_pos + return motor_positions def get_positions(self): sampx_pos = self.motor_hwobj_dict["sampx"].get_value() @@ -889,9 +836,9 @@ def move_to_beam(self, x, y, omega=None): samp_y_pos = self.centring_sampy.motor.get_value() + samp_y phiy = self.centring_phiy.motor.get_value() + x_dist - self.centring_sampx.motor.set_value(samp_x_pos) - self.centring_sampy.motor.set_value(samp_y_pos) - self.centring_phiy.motor.set_value(phiy) + self.centring_sampx.motor.set_value(samp_x_pos, timeout=0) + self.centring_sampy.motor.set_value(samp_y_pos, timeout=0) + self.centring_phiy.motor.set_value(phiy, timeout=0) def start_move_to_beam(self, coord_x=None, coord_y=None, omega=None): """ @@ -945,18 +892,79 @@ def get_osc_dynamic_limits(self): def get_scan_dynamic_limits(self, speed=None): return (-360, 360) + def stop_motion(self): + self.acq_abort() + self.acq_window_off_cmd() + self.acq_off_cmd() + def move_omega_relative(self, relative_angle): + self.wait_omega_on() self.motor_hwobj_dict["phi"].set_value_relative(relative_angle, 5) + def set_pso_control_arm(self, start_angle, stop_angle): + """This Method sets the Tango Device Server "proxyGoniometer" into the PSOcontrolArm mode. + For this mode, there is a contact(pin) on controller, which will be set to High(Low) + State, to trigger "start acquisition"("end acquisition") events of Detector-FastShutter. + """ + try: + if start_angle <= stop_angle: + self.lower_bound_ch.set_value(start_angle) + self.upper_bound_ch.set_value(stop_angle) + else: + self.lower_bound_ch.set_value(stop_angle) + self.upper_bound_ch.set_value(start_angle) + + self.acq_arm_cmd() + except: + print( + "++++++++++++++++++++++++++++++++++++++++++++++++ ERROR setting the PSO********************************************************" + ) + def move_omega(self, angle): - # self.wait_omega() + self.wait_omega_on() + self.wait_omega() + self.motor_hwobj_dict["phi"].set_value(angle, timeout=0) - # Explicit check here. Quick fix for now. - dev_gonio = DeviceProxy("p11/servomotor/eh.1.01") - while str(dev_gonio.State()) != "ON": - time.sleep(0.1) + def move_omega_with_calibration(self, angle): + self.wait_omega_on() + + # Code below is calibration so that angle is always stays within 360 degrees. + # TODO: check the behaviour + currentAngle = self.get_omega_position() + + if currentAngle < 0: + currentAngle = abs(currentAngle) + loadAngleNew = currentAngle % 360 + self.omega_calibrate(-loadAngleNew) + self.motor_hwobj_dict["phi"].set_value(angle, timeout=0) + else: + loadAngleNew = currentAngle % 360 + self.omega_calibrate(loadAngleNew) + self.motor_hwobj_dict["phi"].set_value(angle, timeout=0) + + def wait_omega_on(self, timeout=30): + """ + Wait until the omega device finishes its movement and reaches the "ON" state. + """ + dev_omega = DeviceProxy("p11/servomotor/eh.1.01") + start_time = time.time() + + while True: + try: + current_state = str(dev_omega.State()) + if current_state == "ON": + logging.info("Omega device has finished movement and is now ON.") + break + except DevFailed as e: + logging.error(f"Error communicating with the omega device: {e}") - self.motor_hwobj_dict["phi"].set_value(angle) + if time.time() - start_time > timeout: + logging.error( + "Timeout while waiting for omega device to finish movement and turn ON." + ) + break + + time.sleep(0.1) def get_omega_position(self): return self.motor_hwobj_dict["phi"].get_value() @@ -1065,24 +1073,24 @@ def wait_phase(self, timeout=140): self.motor_state_changed() # Extra waiting loop for the pinhole did not reached the top position because it is blocked. - pinhole_states = ["200", "100", "50", "20", "Down"] + pinhole_states = ["200", "100", "50", "20", "down"] timeout = 140 start_wait = time.time() self.log.debug( "================= Wait whiile pinholes are not blocked whille going up. Pinhole now in the position " - + str(self.pinhole_hwobj.get_position()) + + str(self.pinhole_hwobj.get_value()) ) while time.time() - start_wait < timeout: time.sleep(0.1) for st in pinhole_states: if ( - self.pinhole_hwobj.get_position() == st + self.pinhole_hwobj.get_value() == st and not self.pinhole_hwobj.is_moving() ): self.log.debug( "Pinhole has reached position " - + str(self.pinhole_hwobj.get_position()) + + str(self.pinhole_hwobj.get_value()) ) break else: @@ -1101,31 +1109,29 @@ def goto_centring_phase(self, wait=True): self.phase_goingto = GenericDiffractometer.PHASE_CENTRING - self.log.debug(" - close detector cover") + logging.getLogger("GUI").warning("Closing detector cover...") self.detcover_hwobj.close(timeout=0) - self.log.debug(" - setting backlight in") + logging.getLogger("GUI").warning("Setting backlight in...") self.backlight_hwobj.set_in() - self.log.debug(" - putting collimator down") - self.collimator_hwobj.set_position("Down") + logging.getLogger("GUI").warning("Putting collimator down...") + self.collimator_hwobj.set_value("down") - self.log.debug(" - setting beamstop out") - self.beamstop_hwobj.set_position("Out") + logging.getLogger("GUI").warning("Setting collimator out...") + self.beamstop_hwobj.set_value("out") - self.log.debug(" - moving yag down") - self.yag_hwobj.set_position("Out") + logging.getLogger("GUI").warning("Moving yag down...") + self.yag_hwobj.set_value("down") - self.log.debug(" - moving pinhole down") - if not self.ignore_pinhole: - self.pinhole_hwobj.set_position("Down") - - self.move_omega(0) - self.wait_omega() + logging.getLogger("GUI").warning("Moving pinhole down...") + self.pinhole_hwobj.set_value("down") if wait: self.wait_phase() + logging.getLogger("GUI").info("Phase set is finished") + def is_transfer_phase(self): return self.get_phase() == GenericDiffractometer.PHASE_TRANSFER @@ -1143,17 +1149,18 @@ def goto_transfer_phase(self, wait=True): self.backlight_hwobj.set_out() self.log.debug(" - putting collimator down") - self.collimator_hwobj.set_position("Down") + self.collimator_hwobj.set_value("down") self.log.debug(" - setting beamstop out") - self.beamstop_hwobj.set_position("Out") + self.beamstop_hwobj.set_value("out") self.log.debug(" - moving yag down") - self.yag_hwobj.set_position("Out") + self.yag_hwobj.set_value("down") self.log.debug(" - moving pinhole down") + if not self.ignore_pinhole: - self.pinhole_hwobj.set_position("Down") + self.pinhole_hwobj.set_value("down") self.log.debug(" - moving omega to 0") @@ -1192,57 +1199,55 @@ def wait_detcover(self, state, timeout=60): gevent.sleep(0.5) def is_collect_phase(self): + if self.get_phase() == GenericDiffractometer.PHASE_COLLECTION: + return True + else: + self.wait_phase() + return self.get_phase() == GenericDiffractometer.PHASE_COLLECTION def goto_collect_phase(self, wait=True): self.phase_goingto = GenericDiffractometer.PHASE_COLLECTION self.log.debug(" SETTING DATA COLLECTION PHASE ") - # self.log.debug(" - open detector cover") - self.log.debug(" - setting backlight out") - self.log.debug(" - putting collimator up") - self.log.debug(" - setting beamstop in") - self.log.debug(" - moving yag down") - # self.detcover_hwobj.open() + logging.getLogger("GUI").warning("Moving pinhole out...") self.backlight_hwobj.set_out() - self.collimator_hwobj.set_position("Up") - self.beamstop_hwobj.set_position("In") - self.yag_hwobj.set_position("Out") - self.log.debug("========= - checking pinhole ===============") + logging.getLogger("GUI").warning("Moving collimator up...") + self.collimator_hwobj.set_value("up") - # If the pinhole is Down set pinhole to 200 - if self.pinhole_hwobj.get_position() == "Down": - self.log.debug("Pinhole is down. Setting pinhole to 200.") - self.pinhole_hwobj.set_position("200") + logging.getLogger("GUI").warning("Moving beamstop in...") + self.beamstop_hwobj.set_value("in") - # restore pinhole position is the role of save / restore at mounting - # time. not of the collect phase - # self.pinhole_hwobj.set_position("In") + logging.getLogger("GUI").warning("Moving yag down...") + self.yag_hwobj.set_value("down") - self.log.debug(" - checking gonio tower position ") + self.log.debug("========= - checking pinhole ===============") + + # If the pinhole is Down set pinhole to 200 + if self.pinhole_hwobj.get_value() == "down": + logging.getLogger("GUI").warning("Pinhole is down. Setting pinhole to 200.") + self.pinhole_hwobj.set_value("200") if wait: self.wait_phase() - # sampx to 0 + logging.getLogger("GUI").info("Phase set is finished") def goto_beam_phase(self, wait=True): - self.phase_goingto = GenericDiffractometer.PHASE_BEAMLOCATION + self.phase_goingto = GenericDiffractometer.PHASE_BEAM self.log.debug(" SETTING BEAM LOCATION PHASE ") - self.log.debug(" - open detector cover") - self.detcover_hwobj.open(timeout=0) self.log.debug(" - setting backlight out") - self.backlight_hwobj.set_out() # out + self.backlight_hwobj.set_out() - self.log.debug(" - putting collimator up") self.log.debug(" - setting beamstop in") - self.log.debug(" - moving scintillator down") - self.log.debug(" - checking pinhole ") - self.log.debug(" - checking gonio tower position ") + self.beamstop_hwobj.set_value("in") + self.log.debug(" - moving scintillator up") + self.yag_hwobj.set_value("yag") + if wait: self.wait_phase() @@ -1254,10 +1259,11 @@ def update_phase(self, value=None): cover_closed = self.detcover_hwobj.is_closed blight_in = self.backlight_hwobj.is_in() blight_out = self.backlight_hwobj.is_out() - collim = self.collimator_hwobj.get_position() - bstop = self.beamstop_hwobj.get_position() - pinh = self.pinhole_hwobj.get_position() - yag = self.yag_hwobj.get_position() + collim = self.collimator_hwobj.get_value() + bstop = self.beamstop_hwobj.get_value() + pinh = self.pinhole_hwobj.get_value() + yag = self.yag_hwobj.get_value() + omega_moving = self.omega_hwobj.is_moving() cover_moving = self.detcover_hwobj.is_moving() @@ -1271,13 +1277,13 @@ def update_phase(self, value=None): missing.append("lightin") if not cover_closed: missing.append("cover_closed") - if not collim == "Down": + if not collim == "down": missing.append("collim_down") - if not yag == "Out": + if not yag == "down": missing.append("yag_out") - if not bstop == "Out": + if not bstop == "out": missing.append("bstop_out") - if not pinh == "Down" and not self.ignore_pinhole: + if not pinh == "down" and not self.ignore_pinhole: missing.append("pinh_down") if not missing: @@ -1288,13 +1294,13 @@ def update_phase(self, value=None): missing.append("lightout") if not cover_closed: missing.append("cover_closed") - if not collim == "Down": + if not collim == "down": missing.append("collim_down") - if not bstop == "Out": + if not bstop == "out": missing.append("bstop_out") - if not yag == "Out": + if not yag == "down": missing.append("yag_out") - if not pinh == "Down" and not self.ignore_pinhole: + if not pinh == "down" and not self.ignore_pinhole: missing.append("pinh_down") if abs(omega_pos) >= 0.01: missing.append("omega_zero") @@ -1313,11 +1319,11 @@ def update_phase(self, value=None): missing.append("lightout") # if not cover_open: # missing.append("cover_opened") - if not collim == "Up": + if not collim == "up": missing.append("collim_up") - if not bstop == "In": + if not bstop == "in": missing.append("bstop_in") - if not yag == "Out": + if not yag == "down": missing.append("yag_out") if not missing: @@ -1373,7 +1379,7 @@ def save_position(self, position_name): saved_position = {} for motname in self.save_motor_list: saved_position[motname] = self.motor_hwobj_dict[motname].get_value() - saved_position["pinhole"] = self.pinhole_hwobj.get_position() + saved_position["pinhole"] = self.pinhole_hwobj.get_value() saved_position["backlight"] = self.backlight_hwobj.get_value() self._saved_position[position_name] = saved_position self.log.debug("P11NanoDiff - saving positions for %s" % position_name) @@ -1402,7 +1408,7 @@ def wait_position_ready(self, timeout=70): while (time.time() - t0) < timeout: busy = False - if not self.pinhole_hwobj.is_ready(): + if self.pinhole_hwobj.is_moving(): busy = True self.log.debug(" - pinhole is not ready") if self.backlight_hwobj.is_moving(): @@ -1440,90 +1446,70 @@ def restore_position(self, position_name): self.update_phase() - def move_motors(self, motor_positions, timeout=15): + # Helper function to move individual motors + def move_motor(self, motor_name, position, motor_dict, timeout): + if motor_name in motor_dict: + self.log.debug(f"Moving motor '{motor_name}' to position {position}") + motor_hwobj = self.motor_hwobj_dict.get(motor_name) + if motor_hwobj and position is not None: + motor_hwobj.set_value(position, timeout=None) + gevent.sleep(0.1) + self.wait_device_ready(timeout) + self.log.debug(f"'{motor_name}' movement DONE") + + def move_motors(self, motor_positions, timeout=10): """ - Moves diffractometer motors to the requested positions + Moves diffractometer motors to the requested positions. - :param motors_dict: dictionary with motor names or hwobj - and target values. - :type motors_dict: dict """ - if not isinstance(motor_positions, dict): - motor_positions = motor_positions.as_dict() - self.wait_device_ready(timeout) + # Check if motor_positions is None + if motor_positions is None: + self.log.debug("motor_positions is None") - for motor in ["phiy", "phiz"]: - if motor not in motor_positions: - continue - position = motor_positions[motor] - self.log.debug( - f"first moving translation motor '{motor}' to position {position}" - ) + # Convert to dictionary if not already one + if not isinstance(motor_positions, dict): + try: + motor_positions = motor_positions.as_dict() + except RuntimeWarning: + self.log.rror( + "motor_positions is not a dict and cannot be converted using as_dict()" + ) + return - motor_hwobj = self.motor_hwobj_dict.get(motor) - if None in (motor_hwobj, position): - continue - motor_hwobj.set_value(position, timeout=None) - gevent.sleep(0.1) - self.wait_device_ready(timeout) - self.log.debug(f" translation movements DONE") + # Move translation motors + for motor in ["phiy", "phiz"]: + if motor in motor_positions: + self.move_motor(motor, motor_positions[motor], motor_positions, timeout) + # Move alignment motors for motor in ["sampx", "sampy"]: - if motor not in motor_positions: - continue - position = motor_positions[motor] - self.log.debug( - f"then moving alignment motor '{motor}' to position {position}" - ) - - motor_hwobj = self.motor_hwobj_dict.get(motor) - if None in (motor_hwobj, position): - continue - motor_hwobj.set_value(position, timeout=None) - gevent.sleep(0.1) - self.wait_device_ready(timeout) - self.log.debug(f" alignment movements DONE") + if motor in motor_positions: + self.move_motor(motor, motor_positions[motor], motor_positions, timeout) + # Move 'phi' motor separately if "phi" in motor_positions: - self.log.debug(f"finally moving motor 'phi' to position {position}") - position = motor_positions["phi"] + phi_position = motor_positions["phi"] + self.log.debug(f"Finally moving motor 'phi' to position {phi_position}") motor_hwobj = self.motor_hwobj_dict.get("phi") - if None not in (motor_hwobj, position): - if abs(motor_hwobj.get_value() - position) > 1.0e-4: - - motor_hwobj.set_value(position, timeout=None) - gevent.sleep(0.1) - - self.log.debug(" phi move DONE") - - # is there anything left? - for motor in motor_positions.keys(): - if motor in ["phiy", "phiz", "phi", "sampx", "sampy"]: - continue - position = motor_positions[motor] - self.log.debug(f"moving remaining motor {motor} to position {position}") - """ - if isinstance(motor, (str, unicode)): - logging.getLogger("HWR").debug(" Moving %s to %s" % (motor, position)) - else: - logging.getLogger("HWR").debug( - " Moving %s to %s" % (str(motor.name()), position) - ) - """ - if isinstance(motor, (str, unicode)): - motor_role = motor - motor = self.motor_hwobj_dict.get(motor_role) - # del motor_positions[motor_role] - if None in (motor, position): - continue - # motor_positions[motor] = position - motor.set_value(position) - self.wait_device_ready(timeout) - - if self.delay_state_polling is not None and self.delay_state_polling > 0: - # delay polling for state in the - # case of controller not reporting MOVING inmediately after cmd + if ( + motor_hwobj + and phi_position is not None + and abs(motor_hwobj.get_value() - phi_position) > 1.0e-4 + ): + motor_hwobj.set_value(phi_position, timeout=None) + gevent.sleep(0.1) + self.log.debug("Phi movement DONE") + + # Move any remaining motors + for motor, position in motor_positions.items(): + if motor not in ["phiy", "phiz", "phi", "sampx", "sampy"]: + self.move_motor(motor, motor_positions[motor], motor_positions, timeout) + + # Delay polling for state in the + # case of controller not reporting MOVING inmediately after cmd + if self.delay_state_polling and self.delay_state_polling > 0: gevent.sleep(self.delay_state_polling) + # Final check to ensure all devices are ready self.wait_device_ready(timeout) diff --git a/mxcubecore/HardwareObjects/DESY/P11Pinhole.py b/mxcubecore/HardwareObjects/DESY/P11Pinhole.py index 8710970efa..2d36b7a194 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Pinhole.py +++ b/mxcubecore/HardwareObjects/DESY/P11Pinhole.py @@ -1,3 +1,5 @@ +# encoding: utf-8 +# # Project: MXCuBE # https://github.com/mxcube # @@ -16,63 +18,122 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11Shutter""" - - -from mxcubecore.HardwareObjects.MotorsNPosition import MotorsNPosition -from configparser import ConfigParser - -import copy - - -__credits__ = ["DESY P11"] +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -__category__ = "General" - - -class P11Pinhole(MotorsNPosition): - def __init__(self, name): - super().__init__(name) +from mxcubecore.HardwareObjects.NState import NState +import ast +from mxcubecore.BaseHardwareObjects import HardwareObjectState - self._config_file = None +class P11Pinhole(NState): def init(self): - """Initilise the predefined values""" - - # if simulation is set - open and close will be mere software flags - - self._config_file = self.get_property("config_file") - + """Initialize the pinhole motors and load positions.""" super().init() - def load_positions(self): - - config = ConfigParser() - config.read(self._config_file) - - if not "Pinholes" in config: - return + # Load the predefined pinhole positions from the XML + self.load_positions() - names = config["Pinholes"]["pinholesizelist"].split(",") - names[0] = "Down" + # Load the motors + self.y_motor = self.get_object_by_role("pinholey") + self.z_motor = self.get_object_by_role("pinholez") - units = ["micron"] * len(names) - units[0] = "" + # Log motor initialization + self.log.info(f"Pinhole Y Motor initialized: {self.y_motor}") + self.log.info(f"Pinhole Z Motor initialized: {self.z_motor}") - posnames = copy.copy(names) - posnames[1:] = ["{}um".format(posname) for posname in posnames[1:]] + # Load deltas for each motor + self.load_deltas() - yposlist = map(int, config["Pinholes"]["pinholeyposlist"].split(",")) - zposlist = map(int, config["Pinholes"]["pinholezposlist"].split(",")) + # Set _positions for UI access + self._positions = self.positions - for name, posname, unit, ypos, zpos in zip( - names, posnames, units, yposlist, zposlist - ): - self._positions[name] = {} - self._properties[name] = {} - - self._positions[name]["pinholey"] = ypos - self._positions[name]["pinholez"] = zpos - self._positions[name]["unit"] = unit - self._positions[name]["posname"] = posname + def load_positions(self): + """Load predefined positions from the XML configuration.""" + self.log.info("Loading pinhole positions from config") + positions_str = self.get_property("values") + + # Log the retrieved positions string + self.log.info(f"Retrieved positions: {positions_str}") + + # Check if positions_str is None or empty + if positions_str is None: + self.log.error( + "No values for pinhole positions found in the configuration." + ) + raise ValueError("No pinhole positions found in configuration") + + # Convert the string to a dictionary using ast.literal_eval + try: + self.positions = ast.literal_eval(positions_str) + if isinstance(self.positions, dict): + self.log.info(f"Available pinhole positions: {self.positions}") + else: + raise ValueError("Positions data is not a dictionary") + except (SyntaxError, ValueError) as e: + self.log.error(f"Error parsing pinhole positions: {e}") + raise ValueError("Invalid pinhole positions format in the configuration.") + + def load_deltas(self): + """Load individual motor deltas from the XML configuration.""" + self.log.info("Loading deltas from config") + + # Fetch individual deltas for each motor + delta_y = self.get_property("delta_pinholey") + delta_z = self.get_property("delta_pinholez") + + # If a delta is not specified, fallback to a default delta value + self.deltas = { + "pinholey": float(delta_y) if delta_y is not None else self.default_delta, + "pinholez": float(delta_z) if delta_z is not None else self.default_delta, + } + + # Log the deltas for each motor + for motorname, delta in self.deltas.items(): + self.log.info(f"Delta for {motorname}: {delta}") + + def set_value(self, value): + """Move the pinhole motors to the given position.""" + if value not in self.positions: + raise ValueError(f"Invalid value {value}, not in available positions") + + position = self.positions[value] + + # Move each motor to the desired position + self.y_motor._set_value(position.get("pinholey")) + self.z_motor._set_value(position.get("pinholez")) + + def get_value(self): + """Get the current pinhole position based on the motor positions.""" + current_y = self.y_motor.get_value() + current_z = self.z_motor.get_value() + + for position_name, position in self.positions.items(): + if self.is_within_deltas( + position.get("pinholey"), current_y, "pinholey" + ) and self.is_within_deltas( + position.get("pinholez"), current_z, "pinholez" + ): + return position_name # Return the matching position name + + def is_within_deltas(self, target_value, current_value, motor_name): + """Check if the current motor position is within the delta tolerance for that specific motor.""" + delta = self.deltas.get(motor_name) + if target_value is None or delta is None: + return False + return abs(current_value - target_value) <= delta + + def get_position_list(self): + """Return the list of available pinhole positions.""" + return list(self.positions.keys()) + + def is_moving(self): + """Return True if any motor is moving.""" + return self.y_motor.is_moving() or self.z_motor.is_moving() + + def get_state(self): + """Determine the overall state of the pinhole motor system.""" + if self.is_moving(): + return HardwareObjectState.BUSY + else: + return HardwareObjectState.READY diff --git a/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py b/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py index ffd242cee5..f737e0e7d3 100644 --- a/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py +++ b/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py @@ -18,7 +18,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" @@ -35,7 +35,6 @@ class P11SampleChanger(SampleChanger): - __TYPE__ = "P11SC" NO_OF_BASKETS = 23 NO_OF_SAMPLES_IN_BASKET = 16 @@ -65,6 +64,9 @@ def init(self): self.load_cmd = self.get_command_object("mount") self.unload_cmd = self.get_command_object("unmount") self.wash_cmd = self.get_command_object("wash") + self.home_cmd = self.get_command_object("home") + self.cool_cmd = self.get_command_object("cool") + self.deice_cmd = self.get_command_object("deice") self.chan_current_sample = self.get_channel_object("current_sample") self.chan_current_sample.connect_signal("update", self.current_sample_changed) @@ -120,6 +122,30 @@ def is_powered(self): def load_sample(self, holder_length, sample_location=None, wait=False): self.load(sample_location, wait) + def home(self): + self.wait_sc_ready() + self.log.debug("OPERATING SC NOW (HOME) sample_changer") + self._set_state(SampleChangerState.Moving) + self.home_cmd() + self.wait_sc_ready() + self.emit("progressStop", ()) + + def cool(self): + self.wait_sc_move() + self.log.debug("OPERATING SC NOW (COOL) sample_changer") + self._set_state(SampleChangerState.Moving) + self.cool_cmd() + self.wait_sc_move() + self.emit("progressStop", ()) + + def deice(self): + self.wait_sc_move() + self.log.debug("OPERATING SC NOW (DE-ICING) sample_changer") + self._set_state(SampleChangerState.Moving) + self.deice_cmd() + self.wait_sc_move() + self.emit("progressStop", ()) + def wash(self, wait=False): if not self.has_loaded_sample(): self.user_log.debug("No sample is mounted. Wash command not possible") @@ -180,7 +206,6 @@ def load(self, sample=None, wait=True): # Do a chained load in this case if self.has_loaded_sample(): - # Do first an unload in this case if (sample is None) or (sample == self.get_loaded_sample()): raise Exception( @@ -211,7 +236,6 @@ def load(self, sample=None, wait=True): return self.get_loaded_sample() def _load(self, sample_no): - self.log.debug(" - checking if conditions (except cryo) are all fulfilled") if not self.check_pre_conditions(): raise Exception("conditions for loading not met") @@ -242,7 +266,6 @@ def unload(self, sample=None, wait=True): ) def _unload(self): - self.log.debug(" - checking if conditions (except cryo) are all fulfilled") if not self.check_pre_conditions(): raise Exception("conditions for loading not met") @@ -418,6 +441,14 @@ def _init_sc_contents(self): self._set_state(SampleChangerState.Ready) + def wait_sc_move(self): + while True: + state = str(self.chan_state.get_value()) + if state == "ON": + self._set_state(SampleChangerState.Ready) + break + time.sleep(0.05) + def wait_sc_ready(self): t0 = last_printed = time.time() diff --git a/mxcubecore/HardwareObjects/DESY/P11Session.py b/mxcubecore/HardwareObjects/DESY/P11Session.py index 6e9abdd3a3..e70dd32226 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Session.py +++ b/mxcubecore/HardwareObjects/DESY/P11Session.py @@ -18,7 +18,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" import os @@ -29,7 +29,6 @@ from datetime import date from select import EPOLL_CLOEXEC from mxcubecore.HardwareObjects.Session import Session - from configparser import ConfigParser PATH_BEAMTIME = "/gpfs/current" @@ -38,14 +37,9 @@ class P11Session(Session): - default_archive_folder = "raw" - def __init__(self, *args): - super().__init__(*args) - def init(self): - super().init() self.settings_file = self.get_property("p11_settings_file") @@ -63,13 +57,33 @@ def init(self): self.start_time = time.strftime("%Y%m%d") self.info_set_defaults() + + # Try to locate the metadata file and process it. + self.beamtime_metadata_file = self.locate_metadata_file() + + if self.beamtime_metadata_file: + ( + self.beamline, + self.beamtime, + self.remote_data_dir, + self.user_name, + self.user_sshkey, + self.slurm_reservation, + self.slurm_partition, + self.slurm_node, + ) = self.parse_metadata_file(self.beamtime_metadata_file) + else: + # Fall back to local paths if no metadata is found + self.log.debug("Falling back to local directory for saving data.") + self.select_base_directory( + "local" + ) # Use local paths instead of beamtime data + if self.is_beamtime_open(): self.read_beamtime_info() elif self.is_commissioning_open(): self.read_commissioning_info() - self.select_base_directory(self.operation_mode) - self.set_base_data_directories( self.base_directory, self.base_directory, @@ -79,18 +93,6 @@ def init(self): archive_folder=self.default_archive_folder, ) - self.beamtime_metadata_file = self.locate_metadata_file() - ( - self.beamline, - self.beamtime, - self.remote_data_dir, - self.user_name, - self.user_sshkey, - self.slurm_reservation, - self.slurm_partition, - self.slurm_node, - ) = self.parse_metadata_file(self.beamtime_metadata_file) - def info_set_defaults(self): self.beamtime_info["beamtimeId"] = None self.beamtime_info["proposalType"] = None @@ -222,7 +224,6 @@ def is_writable_dir(self, folder): return os.path.isdir(folder) and os.access(folder, os.F_OK | os.W_OK) def locate_metadata_file(self, root_dir="/gpfs"): - try: beamtime_dirs = [ path @@ -233,19 +234,28 @@ def locate_metadata_file(self, root_dir="/gpfs"): ] except OSError as e: print(e) - raise FileNotFoundError( - "Root directory does not exist: " + str(root_dir) - ) from e + self.log.debug("Root directory does not exist: " + str(root_dir)) + return None # Fall back if the root directory doesn't exist. + + self.log.debug(f"Scanning directories: {beamtime_dirs}") + metadata_files = [] for curr_dir in beamtime_dirs + [root_dir]: curr_dir_metadata_files = glob.glob("{0}/*metadata*.json".format(curr_dir)) metadata_files.extend(curr_dir_metadata_files) + self.log.debug( + f"Found metadata files in {curr_dir}: {curr_dir_metadata_files}" + ) + if len(metadata_files) != 1: - raise FileNotFoundError("Unique metadata JSON file not found") + self.log.debug( + "Unique metadata JSON file not found. Falling back to /gpfs/local." + ) + return None # Return None to indicate no metadata file was found. + return metadata_files[0] def parse_metadata_file(self, metadatafile_path): - beamline = "" beamtime = "" coredatadir = "" @@ -324,12 +334,10 @@ def parse_metadata_file(self, metadatafile_path): ) def get_beamtime_metadata(self, root_dir="/gpfs"): - metadata_file = self.locate_metadata_file(root_dir) return self.parse_metadata_file(metadata_file) def get_ssh_command(self): - ssh_command = "/usr/bin/ssh" ssh_opts_general = "-o BatchMode=yes -o CheckHostIP=no -o StrictHostKeyChecking=no -o GSSAPIAuthentication=no -o GSSAPIDelegateCredentials=no -o PasswordAuthentication=no -o PubkeyAuthentication=yes -o PreferredAuthentications=publickey -o ConnectTimeout=10" ssh_opts_user = "-l {0}".format(self.user_name) diff --git a/mxcubecore/HardwareObjects/DESY/P11Shutter.py b/mxcubecore/HardwareObjects/DESY/P11Shutter.py index a09382f891..bd490b7040 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Shutter.py +++ b/mxcubecore/HardwareObjects/DESY/P11Shutter.py @@ -1,3 +1,5 @@ +# encoding: utf-8 +# # Project: MXCuBE # https://github.com/mxcube # @@ -16,7 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -"""P11Shutter""" +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" import time import gevent diff --git a/mxcubecore/HardwareObjects/DESY/P11Transmission.py b/mxcubecore/HardwareObjects/DESY/P11Transmission.py index 9b929072b5..34f9d6bff4 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Transmission.py +++ b/mxcubecore/HardwareObjects/DESY/P11Transmission.py @@ -18,14 +18,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2024 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" - import gevent import logging import time - from mxcubecore.HardwareObjects.abstract.AbstractTransmission import ( AbstractTransmission, ) @@ -34,56 +32,90 @@ class P11Transmission(AbstractTransmission): + """ + P11Transmission class for controlling transmission settings. + + This class extends the AbstractTransmission class and provides + methods to interact with hardware for setting and reading the + transmission values, as well as handling state changes. + + Attributes: + chan_read_value (Channel): Channel object to read the current value. + chan_set_value (Channel): Channel object to set the transmission value. + chan_state (Channel): Channel object to track the state of the hardware. + """ + def __init__(self, name): - super().__init__(name) + """ + Initializes the P11Transmission object with the given name. + Args: + name (str): The name of the transmission component. + """ + super().__init__(name) self.chan_read_value = None self.chan_set_value = None self.chan_state = None def init(self): + """ + Initializes the hardware channels and connects signals. - limits = self.get_property("limits", None) - - try: - limits = list(map(float, limits.split(","))) - except Exception as e: - log.error("P11Transmission - cannot parse limits: {}".format(str(e))) - limits = None - - if limits is None: - log.error( - "P11Transmission - Cannot read LIMITS from configuration xml file. Check values" - ) - return - else: - self.set_limits(limits) - + This method sets up the communication channels for reading, + setting, and tracking the transmission state. It connects + signals to handle updates from the hardware. + """ self.chan_read_value = self.get_channel_object("chanRead") self.chan_set_value = self.get_channel_object("chanSet") self.chan_state = self.get_channel_object("chanState") if self.chan_read_value is not None: - self.chan_read_value.connect_signal("update", self.value_changed) + self.chan_read_value.connect_signal("update", self.re_emit_value) if self.chan_state is not None: self.chan_state.connect_signal("update", self.state_changed) self.re_emit_values() - def re_emit_value(self): + def re_emit_value(self, *args): + """ + Re-emits the current transmission value and state. + + This method triggers the state and value updates to ensure + the current hardware state and value are reflected in the software. + + Args: + *args: Optional argument to handle extra signal data. + """ self.state_changed() - self.value_changed() + # Value update is now handled in AbstractActuator, no need for value_changed method here def get_state(self): + """ + Gets the current state of the transmission. + + Returns: + str: The current state of the transmission ("READY", "BUSY", or "FAULT"). + """ self.state_changed() return self._state def get_value(self): + """ + Retrieves the current transmission value from the hardware. + + Returns: + float: The current transmission value, multiplied by 100. + """ return self.chan_read_value.get_value() * 100.0 def state_changed(self, state=None): + """ + Handles state changes from the hardware. + Args: + state (str, optional): The new state from the hardware. If None, the state is fetched from the channel. + """ if state is None: state = self.chan_state.get_value() @@ -98,22 +130,16 @@ def state_changed(self, state=None): self.update_state(_state) - def value_changed(self, value=None): - if value is None: - _value = self.get_value() - else: - _value = value * 100.0 - - # update only if needed - if self._nominal_value is None or abs(self._nominal_value - _value) > 10e-1: - self.update_value(_value) - def _set_value(self, value): + """ + Sets a new transmission value to the hardware. + + Args: + value (float): The new transmission value to set. + """ value = value / 100.0 self.chan_set_value.set_value(value) - print("============== Setting transmission ==================") - while self.get_state() == "MOVING": time.sleep(0.1) print("Changing transmission") diff --git a/mxcubecore/HardwareObjects/DESY/P11YagDiode.py b/mxcubecore/HardwareObjects/DESY/P11YagDiode.py new file mode 100644 index 0000000000..820346fcad --- /dev/null +++ b/mxcubecore/HardwareObjects/DESY/P11YagDiode.py @@ -0,0 +1,122 @@ +# encoding: utf-8 +# +# Project: MXCuBE +# https://github.com/mxcube +# +# This file is part of MXCuBE software. +# +# MXCuBE is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# MXCuBE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" + +import ast +from mxcubecore.HardwareObjects.NState import NState +from collections import OrderedDict +from mxcubecore.BaseHardwareObjects import HardwareObjectState + + +class P11YagDiode(NState): + def init(self): + """Initialize the YAG diode motors and load positions from configuration.""" + super().init() + + self.z_motor = self.get_object_by_role("yagz") + self.x_motor = self.get_object_by_role("yagx") + + self.load_positions() + self.load_deltas() + + # Set _positions for UI access + self._positions = OrderedDict() + self._positions = self.positions + + self.log.info(f"YAG/Diode Z Motor initialized: {self.z_motor}") + self.log.info(f"YAG/Diode X Motor initialized: {self.x_motor}") + + def load_positions(self): + """Load predefined positions from the XML configuration.""" + self.log.info("Loading YAG/Diode positions from config") + positions_str = self.get_property("values") + + # Convert the string to a dictionary using ast.literal_eval + try: + self.positions = ast.literal_eval(positions_str) + if isinstance(self.positions, dict): + self.log.info(f"Available YAG/Diode positions: {self.positions}") + else: + raise ValueError("Positions data is not a dictionary") + except (SyntaxError, ValueError) as e: + self.log.error(f"Error parsing YAG/Diode positions: {e}") + raise ValueError("Invalid YAG/Diode positions format in the configuration.") + + def load_deltas(self): + """Load individual motor deltas from the XML configuration explicitly.""" + self.log.info("Loading deltas from config") + + # Fetch individual deltas for each motor + delta_x = self.get_property("delta_yagmotorx") + delta_z = self.get_property("delta_yagmotorz") + + # If a delta is not specified, fallback to a default delta value + self.deltas = { + "yagx": float(delta_x) if delta_x is not None else self.default_delta, + "yagz": float(delta_z) if delta_z is not None else self.default_delta, + } + + # Log the deltas for each motor + for motorname, delta in self.deltas.items(): + self.log.info(f"Delta for {motorname}: {delta}") + + def set_value(self, value): + """Set the yag/diode to the specified position.""" + + if value not in self.positions: + raise ValueError(f"Invalid state value: {value}") + + x_position = self.positions[value]["yagx"] + z_position = self.positions[value]["yagz"] + + # Move the motors + self.x_motor._set_value(x_position) + self.z_motor._set_value(z_position) + self.log.info(f"Setting collimator to position: {value}") + + def get_value(self): + """Get the current pinhole position based on the motor positions.""" + current_x = self.x_motor.get_value() + current_z = self.z_motor.get_value() + + for position_name, position in self.positions.items(): + if self.is_within_deltas( + position.get("yagx"), current_x, "yagx" + ) and self.is_within_deltas(position.get("yagz"), current_z, "yagz"): + return position_name # Return the matching position name + + def is_within_deltas(self, target_value, current_value, motor_name): + """Check if the current motor position is within the delta tolerance for that specific motor.""" + delta = self.deltas.get(motor_name) + if target_value is None or delta is None: + return False + return abs(current_value - target_value) <= delta + + def get_position_list(self): + """Return the list of available pinhole positions.""" + return list(self.positions.keys()) + + def is_moving(self): + """ + Descript. : True if the motor is currently moving + """ + return self.z_motor.get_state() == HardwareObjectState.BUSY diff --git a/mxcubecore/HardwareObjects/DESY/P11Zoom.py b/mxcubecore/HardwareObjects/DESY/P11Zoom.py index d7b406ac05..b9a1deb9e0 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Zoom.py +++ b/mxcubecore/HardwareObjects/DESY/P11Zoom.py @@ -1,7 +1,7 @@ # encoding: utf-8 # # Project: MXCuBE -# https://github.com/mxcube. +# https://github.com/mxcube # # This file is part of MXCuBE software. # @@ -16,7 +16,10 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License -# along with MXCuBE. If not, see . +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" from enum import Enum import ast @@ -40,10 +43,9 @@ def __init__(self, name): self.closest_zoom = None self.redis = redis.StrictRedis() - AbstractNState.__init__(self, name) + super().__init__(name) def init(self): - self._pixels_per_mm = self.get_property("pixels_per_mm") self._overview_pixels_per_mm = self.get_property("overview_pixels_per_mm") self.camera_hwobj = self.get_object_by_role("camera") @@ -116,12 +118,10 @@ def zoom_value_changed(self, value): # self.get_pixels_per_mm() def update_zoom(self): - dist = None value = self.get_value() for zoom in self.VALUES: - if value == 0: self.closest_zoom = zoom break diff --git a/mxcubecore/HardwareObjects/DESY/ValueStateChannel.py b/mxcubecore/HardwareObjects/DESY/ValueStateChannel.py index fdab0a73e5..37c25b97b3 100644 --- a/mxcubecore/HardwareObjects/DESY/ValueStateChannel.py +++ b/mxcubecore/HardwareObjects/DESY/ValueStateChannel.py @@ -1,7 +1,7 @@ # encoding: utf-8 # # Project: MXCuBE -# https://github.com/mxcube. +# https://github.com/mxcube # # This file is part of MXCuBE software. # @@ -16,7 +16,10 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License -# along with MXCuBE. If not, see . +# along with MXCuBE. If not, see . + +__copyright__ = """Copyright The MXCuBE Collaboration""" +__license__ = "LGPLv3+" from mxcubecore.BaseHardwareObjects import HardwareObject @@ -26,7 +29,6 @@ def __init__(self, name): super().__init__(name) def init(self): - self.yellow_states = self.green_states = self.red_states = None self.yellow_limits = self.red_limits = None diff --git a/mxcubecore/HardwareObjects/MotorsNPosition.py b/mxcubecore/HardwareObjects/MotorsNPosition.py index eee90e3fe1..13257c5d73 100644 --- a/mxcubecore/HardwareObjects/MotorsNPosition.py +++ b/mxcubecore/HardwareObjects/MotorsNPosition.py @@ -18,10 +18,9 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -__copyright__ = """ Copyright © 2010 - 2023 by MXCuBE Collaboration """ +__copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" - from collections import OrderedDict from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator @@ -78,6 +77,7 @@ def __init__(self, name): self.current_index = None self._last_position_name = None + self._updating_multi_value = None def init(self): motorlist = self.get_property("motorlist").split(",") @@ -172,7 +172,7 @@ def _set_value(self, value): def get_position(self): current_idx = self.get_value() - if current_idx != -1: + if current_idx is not None and current_idx != -1: return list(self._positions.keys())[current_idx] def motor_state_changed(self, state): @@ -183,32 +183,42 @@ def motor_value_changed(self, position=None): def update_multi_value(self): current_idx = -1 - current_pos = { - motorname: self.motor_hwobjs[motorname].get_value() - for motorname in self.motorlist - } - - for idx, name in enumerate(self._positions): - for motorname in self.motorlist: - if motorname not in self._positions[name]: - continue - - position = self._positions[name][motorname] - cur_pos = current_pos[motorname] - delta = self.deltas[motorname] - - if abs(cur_pos - position) > delta: - break - else: - for motorname in self.motorlist: - position = self._positions[name][motorname] - self.log.debug(" - motor %s is at %s" % (motorname, position)) - current_idx = idx - break - if current_idx != self.current_index: - self.current_index = current_idx - self.update_value(current_idx) + if not self._updating_multi_value: + self._updating_multi_value = True + + try: + current_pos = { + motorname: self.motor_hwobjs[motorname].get_value() + for motorname in self.motorlist + } + + for idx, name in enumerate(self._positions): + for motorname in self.motorlist: + if motorname not in self._positions[name]: + continue + + position = self._positions[name][motorname] + cur_pos = current_pos[motorname] + delta = self.deltas[motorname] + + if abs(cur_pos - position) > delta: + break + else: + for motorname in self.motorlist: + position = self._positions[name][motorname] + self.log.debug( + " - motor %s is at %s" % (motorname, position) + ) + current_idx = idx + break + + if current_idx != self.current_index: + self.current_index = current_idx + self.update_value(current_idx) + + finally: + self._updating_multi_value = False return current_idx diff --git a/mxcubecore/HardwareObjects/QtGraphicsLib.py b/mxcubecore/HardwareObjects/QtGraphicsLib.py index 791011e2ef..a3269b6535 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsLib.py +++ b/mxcubecore/HardwareObjects/QtGraphicsLib.py @@ -2772,7 +2772,9 @@ def mousePressEvent(self, event): """ position = qt_import.QPointF(event.scenePos()) self.scene().mouseClickedSignal.emit( - position.x(), position.y(), event.button() == qt_import.Qt.LeftButton + int(position.x()), + int(position.y()), + event.button() == qt_import.Qt.LeftButton, ) self.update() @@ -2783,7 +2785,7 @@ def mouseDoubleClickEvent(self, event): :return: """ position = qt_import.QPointF(event.scenePos()) - self.scene().mouseDoubleClickedSignal.emit(position.x(), position.y()) + self.scene().mouseDoubleClickedSignal.emit(int(position.x()), int(position.y())) self.update() def mouseReleaseEvent(self, event): @@ -2793,5 +2795,5 @@ def mouseReleaseEvent(self, event): :return: """ position = qt_import.QPointF(event.scenePos()) - self.scene().mouseReleasedSignal.emit(position.x(), position.y()) + self.scene().mouseReleasedSignal.emit(int(position.x()), int(position.y())) self.update() diff --git a/mxcubecore/HardwareObjects/TangoMotor.py b/mxcubecore/HardwareObjects/TangoMotor.py index d28c600a02..97ddb3bf95 100644 --- a/mxcubecore/HardwareObjects/TangoMotor.py +++ b/mxcubecore/HardwareObjects/TangoMotor.py @@ -30,7 +30,7 @@ class TangoMotor(AbstractMotor): - """TINEMotor class defines motor in the TINE control system""" + """TangoMotor class defines motor in the Tango control system""" default_polling = 500 @@ -51,7 +51,7 @@ def __init__(self, name): self.step_limits = None def init(self): - """Connects to all Tine channels and commands""" + """Connects to all Tango channels and commands""" self.polling = self.get_property("polling", TangoMotor.default_polling) self.actuator_name = self.get_property("actuator_name", self.name()) self._tolerance = self.get_property("tolerance", 1e-3) diff --git a/mxcubecore/queue_entry/__init__.py b/mxcubecore/queue_entry/__init__.py index 81246cd360..bb39621516 100644 --- a/mxcubecore/queue_entry/__init__.py +++ b/mxcubecore/queue_entry/__init__.py @@ -31,9 +31,7 @@ # These two queue entries, for the moment violates the convention above and # should eventually be changed from mxcubecore.queue_entry.xrf_spectrum import XrfSpectrumQueueEntry -from mxcubecore.queue_entry.characterisation import ( - CharacterisationGroupQueueEntry, -) +from mxcubecore.queue_entry.characterisation import CharacterisationGroupQueueEntry __all__ = [] MODEL_QUEUE_ENTRY_MAPPINGS = {} diff --git a/mxcubecore/queue_entry/advanced_connector.py b/mxcubecore/queue_entry/advanced_connector.py index 36ea864b11..15255b7f58 100644 --- a/mxcubecore/queue_entry/advanced_connector.py +++ b/mxcubecore/queue_entry/advanced_connector.py @@ -21,9 +21,7 @@ from mxcubecore import HardwareRepository as HWR -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/characterisation.py b/mxcubecore/queue_entry/characterisation.py index abe4012bc1..0b3ac813db 100644 --- a/mxcubecore/queue_entry/characterisation.py +++ b/mxcubecore/queue_entry/characterisation.py @@ -22,14 +22,9 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, - QUEUE_ENTRY_STATUS, -) - -from mxcubecore.queue_entry.data_collection import ( - DataCollectionQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry, QUEUE_ENTRY_STATUS + +from mxcubecore.queue_entry.data_collection import DataCollectionQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/optical_centring.py b/mxcubecore/queue_entry/optical_centring.py index dde9793caf..1dca79d880 100644 --- a/mxcubecore/queue_entry/optical_centring.py +++ b/mxcubecore/queue_entry/optical_centring.py @@ -21,9 +21,7 @@ from mxcubecore import HardwareRepository as HWR -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/sample_centring.py b/mxcubecore/queue_entry/sample_centring.py index fa6a963aa7..99ead404fe 100644 --- a/mxcubecore/queue_entry/sample_centring.py +++ b/mxcubecore/queue_entry/sample_centring.py @@ -20,9 +20,7 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/test_collection.py b/mxcubecore/queue_entry/test_collection.py index 63f6a9a280..094f9dcf83 100644 --- a/mxcubecore/queue_entry/test_collection.py +++ b/mxcubecore/queue_entry/test_collection.py @@ -10,9 +10,7 @@ StandardCollectionParameters, ) -from mxcubecore.model.queue_model_objects import ( - DataCollection, -) +from mxcubecore.model.queue_model_objects import DataCollection __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/xray_centering.py b/mxcubecore/queue_entry/xray_centering.py index 5bba685ffa..c7a884e518 100644 --- a/mxcubecore/queue_entry/xray_centering.py +++ b/mxcubecore/queue_entry/xray_centering.py @@ -19,9 +19,7 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/xray_centering2.py b/mxcubecore/queue_entry/xray_centering2.py index 1cd1d255ba..9ced94ff6f 100644 --- a/mxcubecore/queue_entry/xray_centering2.py +++ b/mxcubecore/queue_entry/xray_centering2.py @@ -20,9 +20,7 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" From 03c89f2eef8af604b211f5788813df3ad4216138 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 1 Oct 2024 12:50:02 +0000 Subject: [PATCH 068/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ed00e41ba6..c2c3f92855 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.159.0" +version = "1.160.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 495fe39f31a85bf20e65c0eeb94cb1994f4509d6 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Mon, 30 Sep 2024 09:42:04 +0200 Subject: [PATCH 069/172] units: add milliseconds (ms) to seconds conversion function --- mxcubecore/utils/units.py | 7 +++++++ test/pytest/test_utils_units.py | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/mxcubecore/utils/units.py b/mxcubecore/utils/units.py index e425e7bf87..560ffb7ebb 100644 --- a/mxcubecore/utils/units.py +++ b/mxcubecore/utils/units.py @@ -14,6 +14,13 @@ def us_to_sec(us: float) -> float: return us / 1_000_000.0 +def ms_to_sec(ms: float) -> float: + """ + convert milliseconds (ms) to seconds + """ + return ms / 1000.0 + + def sec_to_us(sec: float) -> float: """ convert seconds to microseconds (μs) diff --git a/test/pytest/test_utils_units.py b/test/pytest/test_utils_units.py index 1afb62701f..5a3f490f67 100644 --- a/test/pytest/test_utils_units.py +++ b/test/pytest/test_utils_units.py @@ -1,6 +1,7 @@ from math import isclose from mxcubecore.utils.units import ( us_to_sec, + ms_to_sec, sec_to_us, sec_to_hour, ev_to_kev, @@ -16,6 +17,11 @@ def test_us_to_sec(): assert isclose(us_to_sec(123.4), 0.0001234) +def test_ms_to_sec(): + assert isclose(ms_to_sec(13), 0.013) + assert isclose(ms_to_sec(2148.5), 2.1485) + + def test_sec_to_us(): assert isclose(sec_to_us(2), 2_000_000.0) assert isclose(sec_to_us(0.42), 420_000.0) From 01e515e085ae8f99756a1e65048ce896b2addc53 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 4 Oct 2024 07:19:37 +0000 Subject: [PATCH 070/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c2c3f92855..1467bfd058 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.160.0" +version = "1.161.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From a5f748f5fa25a51f69e17056f15a22770b414884 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Thu, 3 Oct 2024 17:09:52 +0200 Subject: [PATCH 071/172] Prevent mockup value to be set to exception on abort --- mxcubecore/HardwareObjects/mockup/ActuatorMockup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py b/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py index 8a853bc34e..ac7badd63a 100644 --- a/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py @@ -108,7 +108,8 @@ def abort(self): def _callback(self, move_task): value = move_task.get() - self._set_value(value) + if not isinstance(value, gevent.GreenletExit): + self._set_value(value) def _set_value(self, value): """ From a1944784933bde41027801f535ad59ffff2c8226 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 4 Oct 2024 09:28:42 +0000 Subject: [PATCH 072/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1467bfd058..5a1675d1b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.161.0" +version = "1.162.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 024b94eb3f1aff52c2083137f6e767bb8feaa4d2 Mon Sep 17 00:00:00 2001 From: FLorial Jean Baptiste Date: Tue, 8 Oct 2024 10:21:07 +0200 Subject: [PATCH 073/172] [Harvester] FIx typo FIx EMBLFlexHCD inheritance Object is a module, not a class --- mxcubecore/HardwareObjects/EMBLFlexHarvester.py | 2 +- mxcubecore/HardwareObjects/Harvester.py | 1 - mxcubecore/HardwareObjects/HarvesterMaintenance.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py index f8b6d7ac3e..50422e2535 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py @@ -31,7 +31,7 @@ from mxcubecore.TaskUtils import task -from mxcubecore.HardwareObjects import EMBLFlexHCD +from mxcubecore.HardwareObjects.EMBLFlexHCD import EMBLFlexHCD class EMBLFlexHarvester(EMBLFlexHCD): diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index 8b97d9ced1..fa6e4ac6d1 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -192,7 +192,6 @@ def _execute_cmd_exporter(self, cmd, *args, **kwargs): if cmd.startswith("set"): ret = exp_attr.set_value(args_str) - self._wait_ready(timeout=timeout) return ret # ---------------------- State -------------------------------- diff --git a/mxcubecore/HardwareObjects/HarvesterMaintenance.py b/mxcubecore/HardwareObjects/HarvesterMaintenance.py index 44e845f836..7579b92b4d 100644 --- a/mxcubecore/HardwareObjects/HarvesterMaintenance.py +++ b/mxcubecore/HardwareObjects/HarvesterMaintenance.py @@ -210,7 +210,7 @@ def calibrate_pin(self) -> bool: md.centringVertical.set_value_relative(sample_drift_y, None) md.save_current_motor_position() - self._harvester.calibration_state(True) + self._harvester.set_calibration_state(True) logging.getLogger("user_level_log").info( "Pin Calibration Step 1 Succeed" From d2f176be239558a7fd3cb8452dc78b8dee8a8fd6 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 9 Oct 2024 06:52:58 +0000 Subject: [PATCH 074/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5a1675d1b2..eaeb30aead 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.162.0" +version = "1.163.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 327bbff2babf3db44b6d22303ed6aabc37877a47 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Mon, 30 Sep 2024 16:45:52 +0100 Subject: [PATCH 075/172] Fixed collect resolution-setting problem --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 138 ++---------------- .../HardwareObjects/MAXIV/BIOMAXCollect.py | 34 ----- .../abstract/AbstractCollect.py | 57 ++++---- .../HardwareObjects/mockup/CollectMockup.py | 6 - 4 files changed, 46 insertions(+), 189 deletions(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index c675409161..09c30e6ef2 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -63,7 +63,7 @@ def init(self): @task def move_motors(self, motor_position_dict): """Moves motors to the specified positions. - + Args: motor_position_dict (dict): Dictionary containing motor positions. """ @@ -71,10 +71,10 @@ def move_motors(self, motor_position_dict): def _take_crystal_snapshot(self, filename): """Takes a snapshot of the crystal and saves it to the given filename. - + Args: filename (str): Path to save the crystal snapshot. - + Raises: RuntimeError: If unable to move to the centring phase. """ @@ -95,7 +95,7 @@ def _take_crystal_snapshot(self, filename): def set_transmission(self, value): """Sets the transmission value on the beamline. - + Args: value (float): Transmission value to set. """ @@ -103,130 +103,20 @@ def set_transmission(self, value): def set_energy(self, value): """Sets the energy value on the beamline. - + Args: value (float): Energy value to set. """ HWR.beamline.energy.set_value(value) - + def set_resolution(self, value): """Sets the resolution of the beamline. - + Args: value (float): Resolution value to set. """ if round(HWR.beamline.resolution.get_value(), 2) != round(value, 2): - HWR.beamline.resolution.set_value(value) - - def do_collect(self, owner): - """Performs the data collection sequence. - - Args: - owner: Owner of the current data collection. - - Raises: - RuntimeError: If collection preparation or execution fails. - """ - log = logging.getLogger("user_level_log") - log.info("Collection: Preparing to collect") - self.emit("collectReady", (False,)) - self.emit( - "collectOscillationStarted", - (owner, None, None, None, self.current_dc_parameters, None), - ) - self.emit("progressInit", ("Collection", 100, False)) - self.collection_id = None - - try: - # Prepare data collection - self.open_detector_cover() - self.open_safety_shutter() - self.open_fast_shutter() - - # Store information in LIMS - self.current_dc_parameters["status"] = "Running" - self.current_dc_parameters["collection_start_time"] = time.strftime( - "%Y-%m-%d %H:%M:%S" - ) - - logging.getLogger("HWR").info( - "Collection parameters: %s", str(self.current_dc_parameters) - ) - - log.info("Collection: Storing data collection in LIMS") - self.store_data_collection_in_lims() - - log.info("Collection: Getting sample info from parameters") - self.get_sample_info() - - log.info("Collection: Storing sample info in LIMS") - self.store_sample_info_in_lims() - - if all( - item is None for item in self.current_dc_parameters["motors"].values() - ): - current_diffractometer_position = ( - HWR.beamline.diffractometer.get_positions() - ) - for motor in self.current_dc_parameters["motors"].keys(): - self.current_dc_parameters["motors"][ - motor - ] = current_diffractometer_position.get(motor) - - # Move to the centered position and take crystal snapshots - log.info("Collection: Moving to centred position") - self.move_to_centered_position() - self.take_crystal_snapshots() - self.move_to_centered_position() - - self.emit("progressStep", 2) - # Set data collection parameters - if "transmission" in self.current_dc_parameters: - log.info( - "Collection: Setting transmission to %.2f", - self.current_dc_parameters["transmission"], - ) - self.set_transmission(self.current_dc_parameters["transmission"]) - - if "wavelength" in self.current_dc_parameters: - log.info( - "Collection: Setting wavelength to %.4f", - self.current_dc_parameters["wavelength"], - ) - self.set_wavelength(self.current_dc_parameters["wavelength"]) - - elif "energy" in self.current_dc_parameters: - log.info( - "Collection: Setting energy to %.4f", - self.current_dc_parameters["energy"], - ) - self.set_energy(self.current_dc_parameters["energy"]) - - dd = self.current_dc_parameters.get("resolution") - if dd and dd.get("upper"): - resolution = dd["upper"] - log.info("Collection: Setting resolution to %.3f", resolution) - self.set_resolution(resolution) - - elif "detector_distance" in self.current_dc_parameters: - log.info( - "Collection: Moving detector to %.2f", - self.current_dc_parameters["detector_distance"], - ) - self.move_detector(self.current_dc_parameters["detector_distance"]) - - self.data_collection_hook() - - log.info("Collection: Updating data collection in LIMS") - self.update_data_collection_in_lims() - - except RuntimeError as e: - failed_msg = "Data collection failed!\n%s" % str(e) - self.collection_failed(failed_msg) - else: - self.collection_finished() - finally: - self.data_collection_cleanup() + super().set_resolution(value) def data_collection_hook(self): """Handles site-specific data collection processes.""" @@ -761,11 +651,11 @@ def collect_characterisation( self.log.debug("collecting image %s, angle %f" % (img_no, start_at)) #[WIP] - #NB! Another attemt to fix the misfires. + #NB! Another attemt to fix the misfires. #Keep comments here until finished #Here is the previous implementation: #self.collect_std_collection(start_at, stop_angle) - + #Here is sligthly modified standard data collection routine #Adjust the angle since each time we are starting with 90 degrees offset. start_pos = start_at - self.turnback_time * self.acq_speed @@ -785,11 +675,11 @@ def collect_characterisation( HWR.beamline.diffractometer.set_omega_velocity(self.acq_speed) time.sleep(1) - #Arm the detector only once in the beginning. Set to wait 4 triggers. + #Arm the detector only once in the beginning. Set to wait 4 triggers. if img_no == 0: HWR.beamline.detector.start_acquisition() time.sleep(3) - + HWR.beamline.diffractometer.move_omega(stop_pos) self.emit("progressStep", int(120 / (nimages) * (img_no + 1))) @@ -800,7 +690,7 @@ def prepare_std_collection(self, start_angle, img_range): Args: start_angle (float): Starting angle for the standard collection sequence. img_range (float): Angle increment for each frame. - + Returns: bool: True if successful, False otherwise. """ @@ -835,7 +725,7 @@ def collect_std_collection(self, start_angle, stop_angle): time.sleep(1) HWR.beamline.diffractometer.move_omega(stop_pos) - + def adxv_notify(self, image_filename, image_num=1): """Sends a notification to an ADXV to load an image file and display a specific slab. diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py index e592095869..18a4fa1fab 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py @@ -1179,40 +1179,6 @@ def prepare_input_files(self): ) return xds_directory, auto_directory - # def move_detector(self, value): - # """ - # Descript. : move detector to the set distance - # """ - # lower_limit, upper_limit = self.get_detector_distance_limits() - # logging.getLogger("HWR").info( - # "...................value %s, detector movement start..... %s" - # % (value, HWR.beamline.detector.distance.get_value()) - # ) - # if upper_limit is not None and lower_limit is not None: - # if value >= upper_limit or value <= lower_limit: - # logging.getLogger("HWR").exception( - # "Can't move detector, the value is out of limits" - # ) - # self.stop_collect() - # else: - # try: - # if HWR.beamline.detector.distance is not None: - # HWR.beamline.detector.distance.set_value(value, timeout=50) - # # 30s is not enough for the whole range - # except Exception: - # logging.getLogger("HWR").exception( - # "Problems when moving detector!!" - # ) - # self.stop_collect() - # else: - # logging.getLogger("HWR").exception( - # "Can't get distance limits, not moving detector!!" - # ) - # logging.getLogger("HWR").info( - # "....................value %s detector movement finished.....%s" - # % (value, HWR.beamline.detector.distance.get_value()) - # ) - def prepare_detector(self): oscillation_parameters = self.current_dc_parameters["oscillation_sequence"][0] diff --git a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py index 040040798d..17a5af3c1c 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py @@ -220,32 +220,45 @@ def do_collect(self, owner): ) self.set_transmission(self.current_dc_parameters["transmission"]) - if "wavelength" in self.current_dc_parameters: + wavelength = self.current_dc_parameters.get("wavelength") + energy = self.current_dc_parameters.get("energy") + detector_distance = self.current_dc_parameters.get("detector_distance") + dd0 = self.current_dc_parameters.get("resolution") + if dd0 and dd0.get('upper'): + resolution = dd0["upper"] + else: + resolution = None + + if wavelength: + # Wavelength (not having a default) overrides energy log.info( "Collection: Setting wavelength to %.4f", self.current_dc_parameters["wavelength"], ) - self.set_wavelength(self.current_dc_parameters["wavelength"]) - - elif "energy" in self.current_dc_parameters: + energy = HWR.beamline.energy.calculate_energy(wavelength) + elif energy: log.info( "Collection: Setting energy to %.4f", self.current_dc_parameters["energy"], ) - self.set_energy(self.current_dc_parameters["energy"]) - - dd = self.current_dc_parameters.get("resolution") - if dd and dd.get("upper"): - resolution = dd["upper"] - log.info("Collection: Setting resolution to %.3f", resolution) + wavelength = HWR.beamline.energy.calculate_wavelength(energy) + if energy: + self.set_energy(energy) + + if detector_distance: + # detector_distance (not having a default) overrides resolution + resolution = HWR.beamline.resolution.distance_to_resolution( + detector_distance, wavelength + ) + log.info( + "Collection: Setting detector distance to %.2f", detector_distance, + ) self.set_resolution(resolution) - - elif "detector_distance" in self.current_dc_parameters: + elif resolution: log.info( - "Collection: Moving detector to %.2f", - self.current_dc_parameters["detector_distance"], + "Collection: Setting resolution to %.2f", resolution, ) - self.move_detector(self.current_dc_parameters["detector_distance"]) + self.set_resolution(resolution) # ---------------------------------------------------------------- # Site specific implementation of a data collection @@ -262,9 +275,8 @@ def do_collect(self, owner): log.info("Collection: Updating data collection in LIMS") self.update_data_collection_in_lims() - except: - exc_type, exc_value, exc_tb = sys.exc_info() - failed_msg = "Data collection failed!\n%s" % exc_value + except RuntimeError as e: + failed_msg = "Data collection failed!\n%s" % str(e) self.collection_failed(failed_msg) else: self.collection_finished() @@ -425,13 +437,8 @@ def set_resolution(self, value): """ Descript. : """ - pass - - def move_detector(self, value): - """ - Descript. : - """ - pass + HWR.beamline.energy.wait_ready() + HWR.beamline.resolution.set_value(value) def get_total_absorbed_dose(self): return diff --git a/mxcubecore/HardwareObjects/mockup/CollectMockup.py b/mxcubecore/HardwareObjects/mockup/CollectMockup.py index 625ba06793..b0365f4b30 100644 --- a/mxcubecore/HardwareObjects/mockup/CollectMockup.py +++ b/mxcubecore/HardwareObjects/mockup/CollectMockup.py @@ -209,14 +209,8 @@ def set_wavelength(self, wavelength): def set_energy(self, energy): HWR.beamline.energy.set_value(energy) - def set_resolution(self, new_resolution): - HWR.beamline.resolution.set_value(new_resolution) - def set_transmission(self, transmission): HWR.beamline.transmission.set_value(transmission) - def move_detector(self, detector_distance): - HWR.beamline.detector.distance.set_value(detector_distance) - def get_undulators_gaps(self): return {"u29": 10} From 8df1736fc9e91bad2445b455b76664b719f4b1a1 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Thu, 3 Oct 2024 11:31:11 +0100 Subject: [PATCH 076/172] Code improvements for previous commit --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 3 ++- mxcubecore/HardwareObjects/abstract/AbstractCollect.py | 9 ++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 09c30e6ef2..2c95b2704f 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -26,6 +26,7 @@ import time import sys import os +import math import logging import traceback import h5py @@ -115,7 +116,7 @@ def set_resolution(self, value): Args: value (float): Resolution value to set. """ - if round(HWR.beamline.resolution.get_value(), 2) != round(value, 2): + if math.isclose(HWR.beamline.resolution.get_value(), value, abs_tol=0.01): super().set_resolution(value) def data_collection_hook(self): diff --git a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py index 17a5af3c1c..31fe8fe17c 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py @@ -223,11 +223,10 @@ def do_collect(self, owner): wavelength = self.current_dc_parameters.get("wavelength") energy = self.current_dc_parameters.get("energy") detector_distance = self.current_dc_parameters.get("detector_distance") - dd0 = self.current_dc_parameters.get("resolution") - if dd0 and dd0.get('upper'): - resolution = dd0["upper"] - else: - resolution = None + try: + resolution = self.current_dc_parameters.get("resolution").get("upper") + except AttributeError: + resolution = None if wavelength: # Wavelength (not having a default) overrides energy From 0fc2615cab70c033aa1b56fa8b31be35f2f55efc Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 4 Oct 2024 15:13:19 +0100 Subject: [PATCH 077/172] Put GPhL files under black formatting --- .../HardwareObjects/Gphl/GphlMessages.py | 2 +- .../HardwareObjects/Gphl/GphlWorkflow.py | 133 ++++++++++-------- .../Gphl/GphlWorkflowConnection.py | 23 +-- .../Gphl/Transcal2MiniKappa.py | 44 +++--- pyproject.toml | 6 - 5 files changed, 108 insertions(+), 100 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlMessages.py b/mxcubecore/HardwareObjects/Gphl/GphlMessages.py index 2a6c711621..1057447e73 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlMessages.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlMessages.py @@ -342,7 +342,7 @@ def __init__( self._indexingHeader = indexingHeader self._priorCrystalClasses = priorCrystalClasses or () self._priorSpaceGroup = priorSpaceGroup - self._priorSpaceGroupString= priorSpaceGroupString + self._priorSpaceGroupString = priorSpaceGroupString self._userProvidedCell = userProvidedCell @property diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index b1fc8ec07e..0d6186b82b 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -328,9 +328,9 @@ def query_pre_strategy_params(self, choose_lattice=None): point_group = point_groups[-1] lattice_tags = alternative_lattices[lattice] if space_group: - crystal_class = ( - crystal_symmetry.SPACEGROUP_MAP[space_group].crystal_class - ) + crystal_class = crystal_symmetry.SPACEGROUP_MAP[ + space_group + ].crystal_class info = crystal_symmetry.CRYSTAL_CLASS_MAP[crystal_class] if info.bravais_lattice == lattice: point_group = info.point_group @@ -478,7 +478,7 @@ def query_pre_strategy_params(self, choose_lattice=None): strategies = list( strategy_settings["options"].get("strategy", "") + variant for variant in strategies - ) + ) fields["strategy"]["default"] = strategies[0] fields["strategy"]["title"] = "Acquisition strategy" fields["strategy"]["enum"] = strategies @@ -521,11 +521,15 @@ def query_pre_strategy_params(self, choose_lattice=None): fields[tag]["default"] = val else: for tag in ( - "cell_a", "cell_b", "cell_c", "cell_alpha", "cell_beta", "cell_gamma" + "cell_a", + "cell_b", + "cell_c", + "cell_alpha", + "cell_beta", + "cell_gamma", ): fields[tag]["default"] = 0 - # NB update_on_change supports None, "always", and "selected" # It controls whether an update signal is sent when a parameter changes ui_schema = { @@ -758,12 +762,9 @@ def pre_execute(self, queue_entry): if os.path.isfile(os.path.join(spotdir, "SPOT.XDS")): params["init_spot_dir"] = spotdir else: - raise ValueError( - "no file SPOT.XDS in %s" % spotdir) + raise ValueError("no file SPOT.XDS in %s" % spotdir) else: - raise ValueError( - "use_preset_spotdir was set for non-emulation sample" - ) + raise ValueError("use_preset_spotdir was set for non-emulation sample") cell_tags = ( "cell_a", @@ -809,7 +810,6 @@ def execute(self): HWR.beamline.gphl_connection.software_paths["GPHL_WDIR"], "recen.nml" ) - dispatcher.connect( self.handle_collection_start, "collectOscillationStarted", @@ -842,7 +842,9 @@ def execute(self): ) break elif message_type != "String": - logging.getLogger("HWR").info("GΦL queue processing %s", message_type) + logging.getLogger("HWR").info( + "GΦL queue processing %s", message_type + ) response = func(payload, correlation_id) if result_list is not None: result_list.append((response, correlation_id)) @@ -858,7 +860,6 @@ def execute(self): HWR.beamline.collect, ) - def post_execute(self): """ The workflow has finished, sets the state to 'READY' @@ -978,7 +979,8 @@ def query_collection_strategy(self, geometric_strategy): ) info_title = "--- %s ---" % title_string lines = [ - "Strategy '%s', for symmetry '%s'\n" % ( + "Strategy '%s', for symmetry '%s'\n" + % ( # title_string, data_model.strategy_variant or data_model.strategy_name, ptgrp, @@ -1111,7 +1113,7 @@ def query_collection_strategy(self, geometric_strategy): "title": "Oscillation range", "type": "string", "default": str(default_image_width), - "enum": list(str(val) for val in allowed_widths) + "enum": list(str(val) for val in allowed_widths), } fields["exposure_time"] = { "title": "Exposure Time (s)", @@ -1191,7 +1193,7 @@ def query_collection_strategy(self, geometric_strategy): "title": "Number of snapshots", "type": "string", "default": str(data_model.snapshot_count), - "enum": ["0", "1", "2", "4"] + "enum": ["0", "1", "2", "4"], } # recentring mode: @@ -1413,9 +1415,7 @@ def setup_data_collection(self, payload, correlation_id): allowed_widths[geometric_strategy.defaultWidthIdx or 0] ) else: - default_image_width = list( - self.settings.get("default_image_widths") - )[0] + default_image_width = list(self.settings.get("default_image_widths"))[0] # get parameters and initial transmission/use_dose if gphl_workflow_model.automation_mode: @@ -1433,7 +1433,7 @@ def setup_data_collection(self, payload, correlation_id): transmission = HWR.beamline.transmission.get_value() if not parameters.get("transmission"): parameters["transmission"] = transmission - if not( + if not ( parameters.get("exposure_time") and parameters.get("image_width") ): raise ValueError( @@ -1443,9 +1443,12 @@ def setup_data_collection(self, payload, correlation_id): else: image_width = parameters.setdefault("image_width", default_image_width) transmission = parameters.get("transmission") - maximum_dose = gphl_workflow_model.calc_maximum_dose( - image_width=image_width, - ) or 0 + maximum_dose = ( + gphl_workflow_model.calc_maximum_dose( + image_width=image_width, + ) + or 0 + ) if transmission: new_dose = maximum_dose * transmission / 100 elif maximum_dose: @@ -1467,9 +1470,7 @@ def setup_data_collection(self, payload, correlation_id): else: # We should not be here, but if we cannot calculate flux, ... new_dose = 0 - parameters["transmission"] = ( - HWR.beamline.transmission.get_value() - ) + parameters["transmission"] = HWR.beamline.transmission.get_value() else: # set gphl_workflow_model.transmission (initial value for interactive mode) use_dose = gphl_workflow_model.recommended_dose_budget() @@ -1526,7 +1527,7 @@ def setup_data_collection(self, payload, correlation_id): new_resolution = parameters.pop("resolution", initial_resolution) if ( new_resolution != initial_resolution - and not parameters.get("init_spot_dir") + and not parameters.get("init_spot_dir") and not gphl_workflow_model.characterisation_done ): logging.getLogger("GUI").info( @@ -1729,8 +1730,8 @@ def setup_data_collection(self, payload, correlation_id): if recentring_mode == "start": q_e = self.enqueue_sample_centring(motor_settings=settings) logging.getLogger("HWR").debug( - "GPHL recenter at : " + - ", ".join("%s:%s" % item for item in sorted(settings.items())) + "GPHL recenter at : " + + ", ".join("%s:%s" % item for item in sorted(settings.items())) ) translation, dummy = self.execute_sample_centring(q_e, sweepSetting) goniostatTranslations.append(translation) @@ -1744,8 +1745,8 @@ def setup_data_collection(self, payload, correlation_id): rotation=sweepSetting, **settings ) logging.getLogger("HWR").debug( - "GPHL calculate recentring: " + - ", ".join("%s:%s" % item for item in sorted(settings.items())) + "GPHL calculate recentring: " + + ", ".join("%s:%s" % item for item in sorted(settings.items())) ) goniostatTranslations.append(translation) # @@ -1978,7 +1979,7 @@ def collect_data(self, payload, correlation_id): key = ( path_template.base_prefix, path_template.run_number, - path_template.start_num + path_template.start_num, ) self._key_to_scan[key] = scan @@ -1987,7 +1988,8 @@ def collect_data(self, payload, correlation_id): rotation_id = orientation_id = goniostatRotation.id_ initial_settings = sweep.get_initial_settings() orientation = ( - initial_settings.get("kappa"), initial_settings.get( "kappa_phi") + initial_settings.get("kappa"), + initial_settings.get("kappa_phi"), ) if last_orientation: maxdev = max( @@ -2033,7 +2035,6 @@ def collect_data(self, payload, correlation_id): acq_parameters.take_snapshots = snapshot_count gphl_workflow_model.current_rotation_id = rotation_id - if repeat_count and sweep_offset and self.settings.get("use_multitrigger"): # Multitrigger sweep - add in parameters. # NB if we are here ther can be only one scan @@ -2152,10 +2153,8 @@ def select_lattice(self, payload, correlation_id): crystal_classes = () space_group = "" if not crystal_classes: - crystal_classes = ( - crystal_symmetry.crystal_classes_from_params( - lattices=(bravais_lattice) - ) + crystal_classes = crystal_symmetry.crystal_classes_from_params( + lattices=(bravais_lattice) ) params["space_group"] = space_group params["crystal_classes"] = crystal_classes @@ -2402,7 +2401,8 @@ def process_centring_request(self, payload, correlation_id): if not responses: self._return_parameters.set_exception( RuntimeError( - "Signal %s is not connected" % self.PARAMETERS_NEEDED) + "Signal %s is not connected" % self.PARAMETERS_NEEDED + ) ) result = self._return_parameters.get() @@ -2558,16 +2558,15 @@ def obtain_prior_information(self, payload, correlation_id): # return priorInformation - def handle_collection_end( self, dummy1, dummy2, dummy3, dummy4, dummy5, collect_dict ): - """ Read and process collectOscillationFinished signal + """Read and process collectOscillationFinished signal which means scan finished successfully""" key = ( collect_dict["fileinfo"].get("prefix"), collect_dict["fileinfo"].get("run_number"), - collect_dict["oscillation_sequence"][0].get("start_image_number") + collect_dict["oscillation_sequence"][0].get("start_image_number"), ) scan = self._key_to_scan.pop(key, None) if scan is None: @@ -2575,17 +2574,18 @@ def handle_collection_end( "No scan matching prefix: %s, run_number: %s, start_image_number: %s at end" % key ) + def handle_collection_start( self, owner, blsampleid, barcode, location, collect_dict, osc_id ): - """ Read and process collectOscillationStarted signal + """Read and process collectOscillationStarted signal Used to set actual centring positions NB only collect_dict is reliably non-null""" key = ( collect_dict["fileinfo"].get("prefix"), collect_dict["fileinfo"].get("run_number"), - collect_dict["oscillation_sequence"][0].get("start_image_number") + collect_dict["oscillation_sequence"][0].get("start_image_number"), ) scan = self._key_to_scan.get(key) if scan is None: @@ -2622,8 +2622,6 @@ def handle_collection_start( self._scan_id_to_translation_id[scan.id_] = translation.id_ self._recentrings.append(translation) - - # Utility functions def resolution2dose_budget( @@ -2679,7 +2677,6 @@ def maximum_dose_rate(energy=None): ) return 0 - def get_emulation_samples(self): """Get list of lims_sample information dictionaries for mock/emulation @@ -2759,7 +2756,6 @@ def get_emulation_samples(self): # return result - def get_emulation_sample_dir(self, sample_name=None): """If sample is a test data set for emulation, get test data directory Args: @@ -2775,7 +2771,7 @@ def get_emulation_sample_dir(self, sample_name=None): ) if sample_name: if sample_name.startswith(self.TEST_SAMPLE_PREFIX): - sample_name = sample_name[len(self.TEST_SAMPLE_PREFIX)+1:] + sample_name = sample_name[len(self.TEST_SAMPLE_PREFIX) + 1 :] sample_dir = HWR.beamline.gphl_connection.software_paths.get( "gphl_test_samples" ) @@ -2865,8 +2861,7 @@ def receive_ok_cancel(self, instruction, parameters): else: self._return_parameters.set_exception( ValueError( - "Illegal return instruction %s for Ok/Cancel query" - % instruction + "Illegal return instruction %s for Ok/Cancel query" % instruction ) ) @@ -2924,8 +2919,14 @@ def update_lattice(self, values): sgoptions = [""] + crystal_symmetry.space_groups_from_params() sgvalue = space_group result = { - "point_groups": {"value": pgvalue, "enum": pglist,}, - "space_group": {"value": sgvalue, "enum": sgoptions,}, + "point_groups": { + "value": pgvalue, + "enum": pglist, + }, + "space_group": { + "value": sgvalue, + "enum": sgoptions, + }, } # return result @@ -2980,7 +2981,7 @@ def update_indexing_solution(self, values): result = self.update_lattice(values1) result["lattice"] = { "value": lattice, - "enum":alternative_lattices[lattice], + "enum": alternative_lattices[lattice], } break else: @@ -3062,10 +3063,18 @@ def adjust_transmission(self, values): exposure_time=new_exposure_time, image_width=image_width ) result = { - "exposure_time": {"value": new_exposure_time,}, - "transmission": {"value": new_transmission,}, - "use_dose": {"value": use_dose,}, - "experiment_time": {"value": new_experiment_time,}, + "exposure_time": { + "value": new_exposure_time, + }, + "transmission": { + "value": new_transmission, + }, + "use_dose": { + "value": use_dose, + }, + "experiment_time": { + "value": new_experiment_time, + }, } elif new_transmission < transmission: # Try reducing exposure_time time instead @@ -3080,11 +3089,11 @@ def adjust_transmission(self, values): ) new_exposure_time = min_exposure result = { - "transmission": {"value":new_transmission}, - "exposure_time": {"value":new_exposure_time}, + "transmission": {"value": new_transmission}, + "exposure_time": {"value": new_exposure_time}, } else: - result = {"transmission": {"value":new_transmission}} + result = {"transmission": {"value": new_transmission}} if ( use_dose and dose_budget diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py index c5bc67fe77..fc12ec4e57 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py @@ -46,6 +46,7 @@ # Hacky, but the best solution to making py4j and gevent compatible import socket + origsocket = sys.modules.pop("socket") _origsocket = sys.modules.pop("_socket") import socket @@ -332,7 +333,7 @@ def start_workflow(self, workflow_queue, workflow_model_obj): ) for ss0 in command_list: - ss0 = ss0.rsplit('=', maxsplit=1)[-1] + ss0 = ss0.rsplit("=", maxsplit=1)[-1] if ss0.startswith("/") and "*" not in ss0 and not os.path.exists(ss0): logging.getLogger("HWR").warning("File does not exist : %s", ss0) @@ -496,15 +497,19 @@ def processMessage(self, py4j_message): if not self.msg_class_imported: try: - msg_class = self._gateway.jvm.py4j.reflection.ReflectionUtil.classForName( - "co.gphl.sdcp.astra.service.py4j.Py4jMessage" + msg_class = ( + self._gateway.jvm.py4j.reflection.ReflectionUtil.classForName( + "co.gphl.sdcp.astra.service.py4j.Py4jMessage" + ) ) java_gateway.java_import( self._gateway.jvm, "co.gphl.sdcp.astra.service.py4j.Py4jMessage" ) except Py4JJavaError: - msg_class = self._gateway.jvm.py4j.reflection.ReflectionUtil.classForName( - "co.gphl.sdcp.py4j.Py4jMessage" + msg_class = ( + self._gateway.jvm.py4j.reflection.ReflectionUtil.classForName( + "co.gphl.sdcp.py4j.Py4jMessage" + ) ) java_gateway.java_import( self._gateway.jvm, "co.gphl.sdcp.py4j.Py4jMessage" @@ -1061,12 +1066,8 @@ def _CollectionDone_to_java(self, collectionDone): scanIdMap = {} for item in collectionDone.scanIdMap.items(): scanIdMap[ - jvm.java.util.UUID.fromString( - conversion.text_type(item[0]) - ) - ] = jvm.java.util.UUID.fromString( - conversion.text_type(item[1]) - ) + jvm.java.util.UUID.fromString(conversion.text_type(item[0])) + ] = jvm.java.util.UUID.fromString(conversion.text_type(item[1])) return jvm.astra.messagebus.messages.information.CollectionDoneImpl( proposalId, collectionDone.status, diff --git a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py index 701af405fa..6047b3a755 100644 --- a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py +++ b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py @@ -48,6 +48,7 @@ TRANS_CROSS_SEC_OF_SOC=%s, %s, %s /""" + def get_recen_data(transcal_file, instrumentation_file, diffractcal_file=None, **kwds): """Read recentring data from GPhL files @@ -57,8 +58,7 @@ def get_recen_data(transcal_file, instrumentation_file, diffractcal_file=None, * diffractcal_file: diffrqctcal,.nl ioptional input file Returns: dict - -""" + """ result = {} if not (os.path.isfile(transcal_file) and os.path.isfile(instrumentation_file)): @@ -88,6 +88,7 @@ def get_recen_data(transcal_file, instrumentation_file, diffractcal_file=None, * # return result + def make_minikappa_data( home, cross_sec_of_soc, @@ -116,7 +117,7 @@ def make_minikappa_data( # In recen and transcal files, they are with motor axes in *columns* # The distinction is a transpose, equivalent to changing multiplication order transform = np.matrix(gonio_centring_axes) - transform.shape = (3,3) + transform.shape = (3, 3) omega = np.array(omega_axis) trans_1 = np.array(gonio_centring_axes[:3]) if abs(omega.dot(trans_1)) < 0.99: @@ -132,11 +133,9 @@ def make_minikappa_data( kappa_axis = np.dot(transform, np.array(kappa_axis)).tolist()[0] phi_axis = np.dot(transform, np.array(phi_axis)).tolist()[0] - # Shuffle axes to sampx, sampy, phiy order indices = list( - gonio_centring_axis_names.index(tag) - for tag in ("sampx", "sampy", "phiy") + gonio_centring_axis_names.index(tag) for tag in ("sampx", "sampy", "phiy") ) kappa_axis = list(kappa_axis[idx] for idx in indices) phi_axis = list(phi_axis[idx] for idx in indices) @@ -153,9 +152,8 @@ def make_minikappa_data( "phi_position": phi_position, } -def make_home_data( - centring_axes, axis_names, kappadir, kappapos, phidir, phipos -): + +def make_home_data(centring_axes, axis_names, kappadir, kappapos, phidir, phipos): """Convert in the oppoosite direction *from* minikappa configuration *to* transcal Args: @@ -176,13 +174,11 @@ def make_home_data( phipos = np.array(phipos) aval = kappadir.dot(phidir) bvec = phipos - kappapos - kappahome = ( - kappapos + (aval * bvec.dot(phidir) - bvec.dot(kappadir)) * kappadir - / (aval * aval - 1) + kappahome = kappapos + (aval * bvec.dot(phidir) - bvec.dot(kappadir)) * kappadir / ( + aval * aval - 1 ) - phihome = ( - phipos - (aval * bvec.dot(kappadir) - bvec.dot(phidir)) * phidir - / (aval * aval - 1) + phihome = phipos - (aval * bvec.dot(kappadir) - bvec.dot(phidir)) * phidir / ( + aval * aval - 1 ) home_position = 0.5 * (kappahome + phihome) # # (http://confluence.globalphasing.com/display/SDCP/EMBL+MiniKappaCorrection) @@ -196,10 +192,11 @@ def make_home_data( # Transform cross_sec_of_soc to lab coordinate system transform = np.matrix(centring_axes) - transform.shape = (3,3) + transform.shape = (3, 3) cross_sec_of_soc = np.dot(np.array(cross_sec_of_soc), transform).tolist()[0] return home_position, cross_sec_of_soc + def convert_to_gphl(instrumentation_file, minikappa_config, **kwds): if not os.path.isfile(instrumentation_file): @@ -217,6 +214,7 @@ def convert_to_gphl(instrumentation_file, minikappa_config, **kwds): ) return home_position, cross_sec_of_soc + def get_minikappa_data(configfile): root = ET.fromstring(open(configfile).read()) result = [] @@ -226,6 +224,7 @@ def get_minikappa_data(configfile): result.append(ast.literal_eval(elem.findtext(field))) return result + if __name__ == "__main__": from argparse import ArgumentParser, RawTextHelpFormatter @@ -245,13 +244,16 @@ def get_minikappa_data(configfile): Starting from the minikappa correction you need an instrumentation.nml file and a minikappa-correction-xml file - """ + """, ) default = "minikappa" parser.add_argument( "--source", - choices=["minikappa", "gphl", ], + choices=[ + "minikappa", + "gphl", + ], default=default, help="Type of input data to convert.\n", ) @@ -272,7 +274,9 @@ def get_minikappa_data(configfile): ) parser.add_argument( - "--minikappa_config", metavar="minikappa_config", help="minikappa-correction.xmll file\n" + "--minikappa_config", + metavar="minikappa_config", + help="minikappa-correction.xmll file\n", ) argsobj = parser.parse_args() @@ -284,4 +288,4 @@ def get_minikappa_data(configfile): print(minikappa_xml_template % minikappa_data) else: home, csoc = convert_to_gphl(**options_dict) - print (transcal_nml_template % tuple(home + csoc)) + print(transcal_nml_template % tuple(home + csoc)) diff --git a/pyproject.toml b/pyproject.toml index eaeb30aead..4319ed41c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,7 +91,6 @@ mxcubecore/HardwareObjects/EMBL/TINEMotor.py, mxcubecore/HardwareObjects/ESRF/ID30A1MultiCollect.py, mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py, mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py, -mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py, mxcubecore/HardwareObjects/LNLS/EPICSActuator.py, mxcubecore/HardwareObjects/LNLS/LNLSCollect.py, mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py, @@ -189,11 +188,8 @@ force-exclude = ''' | mxcubecore/HardwareObjects/ESRF/ID30A3MultiCollect.py | mxcubecore/HardwareObjects/ESRF/Oxford700.py | mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum.py - | mxcubecore/HardwareObjects/Gphl/GphlMessages.py | mxcubecore/HardwareObjects/GenericDiffractometer.py - | mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py | mxcubecore/HardwareObjects/LNLS/EPICSActuator.py - | mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py | mxcubecore/HardwareObjects/LNLS/EPICSMotor.py | mxcubecore/HardwareObjects/LNLS/LNLSAperture.py | mxcubecore/HardwareObjects/LNLS/EPICSNState.py @@ -208,7 +204,6 @@ force-exclude = ''' | mxcubecore/HardwareObjects/LNLS/read_transmission_mnc.py | mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py | mxcubecore/HardwareObjects/Lima2Detector.py - | mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | mxcubecore/HardwareObjects/ISPyBClient.py | mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py | mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py @@ -230,7 +225,6 @@ force-exclude = ''' | mxcubecore/HardwareObjects/mockup/ShutterMockup.py | mxcubecore/Poller.py | mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py - | mxcubecore/model/crystal_symmetry.py | mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py | mxcubecore/HardwareObjects/XSDataMXv1.py ) From c61ff61d4e2b1fb484e88258df2e7219d473f754 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 4 Oct 2024 15:43:27 +0100 Subject: [PATCH 078/172] Improve black formatting --- .../HardwareObjects/Gphl/GphlWorkflow.py | 26 +++++-------------- .../Gphl/Transcal2MiniKappa.py | 5 +--- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 0d6186b82b..84a66b62b2 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -2919,14 +2919,8 @@ def update_lattice(self, values): sgoptions = [""] + crystal_symmetry.space_groups_from_params() sgvalue = space_group result = { - "point_groups": { - "value": pgvalue, - "enum": pglist, - }, - "space_group": { - "value": sgvalue, - "enum": sgoptions, - }, + "point_groups": {"value": pgvalue, "enum": pglist}, + "space_group": {"value": sgvalue, "enum": sgoptions}, } # return result @@ -3063,18 +3057,10 @@ def adjust_transmission(self, values): exposure_time=new_exposure_time, image_width=image_width ) result = { - "exposure_time": { - "value": new_exposure_time, - }, - "transmission": { - "value": new_transmission, - }, - "use_dose": { - "value": use_dose, - }, - "experiment_time": { - "value": new_experiment_time, - }, + "exposure_time": {"value": new_exposure_time}, + "transmission": {"value": new_transmission}, + "use_dose": {"value": use_dose}, + "experiment_time": {"value": new_experiment_time}, } elif new_transmission < transmission: # Try reducing exposure_time time instead diff --git a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py index 6047b3a755..331c408baa 100644 --- a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py +++ b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py @@ -250,10 +250,7 @@ def get_minikappa_data(configfile): default = "minikappa" parser.add_argument( "--source", - choices=[ - "minikappa", - "gphl", - ], + choices=["minikappa", "gphl"], default=default, help="Type of input data to convert.\n", ) From 121ff9bdeebe32c4bf59a04803cc412421607aa3 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 11 Oct 2024 14:41:39 +0100 Subject: [PATCH 079/172] Removed space for black --- mxcubecore/model/crystal_symmetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/model/crystal_symmetry.py b/mxcubecore/model/crystal_symmetry.py index b2a6c44ed7..718c240fde 100644 --- a/mxcubecore/model/crystal_symmetry.py +++ b/mxcubecore/model/crystal_symmetry.py @@ -50,7 +50,7 @@ "o": "amo", "t": "amot", "h": "amh", - "c": "amotc" + "c": "amotc", } # Data from https://onlinelibrary.wiley.com/iucr/itc/Cb/ch1o4v0001/ From cf52ce391b770c8ecb8eccfb4ac1ce3160c0ee16 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 11 Oct 2024 15:24:30 +0100 Subject: [PATCH 080/172] Cleaned up for linting --- .../HardwareObjects/Gphl/GphlWorkflow.py | 141 +++++++++--------- 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 84a66b62b2..4c24af9920 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -49,7 +49,6 @@ from mxcubecore.queue_entry import QueueAbortedException from mxcubecore.HardwareObjects.Gphl import GphlMessages -from mxcubecore.HardwareObjects.Gphl.Transcal2MiniKappa import make_home_data from mxcubecore import HardwareRepository as HWR @@ -132,7 +131,7 @@ class GphlWorkflowStates(enum.Enum): ) all_point_group_tags = [] -for tag in ( +for atag in ( "Triclinic", "Monoclinic", "Orthorhombic", @@ -140,11 +139,11 @@ class GphlWorkflowStates(enum.Enum): "Hexagonal", "Cubic", ): - all_point_group_tags += lattice2point_group_tags[tag] + all_point_group_tags += lattice2point_group_tags[atag] # Allowed altervative lattices for a given lattice alternative_lattices = {} -for ll0 in ( +for list0 in ( ["aP", "Triclinic"], ["mP", "mC", "mI", "Monoclinic"], ["oP", "oC", "oF", "oI", "Orthorhombic"], @@ -152,8 +151,8 @@ class GphlWorkflowStates(enum.Enum): ["hP", "hR", "Hexagonal"], ["cP", "cF", "cI", "Cubic"], ): - for tag in ll0: - alternative_lattices[tag] = ll0 + for atag in list0: + alternative_lattices[atag] = list0 class GphlWorkflow(HardwareObjectYaml): @@ -321,6 +320,7 @@ def query_pre_strategy_params(self, choose_lattice=None): data_model = self._queue_entry.get_data_model() strategy_settings = data_model.strategy_settings space_group = data_model.space_group or "" + header = soldict = select_row = None if choose_lattice: header, soldict, select_row = self.parse_indexing_solution(choose_lattice) lattice = list(soldict.values())[select_row].bravaisLattice @@ -1592,7 +1592,6 @@ def setup_data_collection(self, payload, correlation_id): sweepSettings.reverse() # Handle centring of first orientation - pos_dict = HWR.beamline.diffractometer.get_positions() sweepSetting = sweepSettings[0] # Get current position @@ -2093,7 +2092,7 @@ def collect_data(self, payload, correlation_id): try: queue_manager.execute_entry(data_collection_entry) - except: + except Exception: HWR.beamline.queue_manager.emit("queue_execution_failed", (None,)) self._data_collection_group = None @@ -2103,7 +2102,7 @@ def collect_data(self, payload, correlation_id): else: status = 0 - failedScanIds = set(scan.id_ for scan in self._key_to_scan.values()) + # failedScanIds = set(scan.id_ for scan in self._key_to_scan.values()) return GphlMessages.CollectionDone( status=status, @@ -2352,69 +2351,69 @@ def process_centring_request(self, payload, correlation_id): logging.getLogger("HWR").warning( "No predefined positions for zoom motor." ) - elif True: + else: logging.getLogger("user_level_log").info( "Sample re-centering now active - Zoom in before continuing." ) - else: - # TODO The UI popup does not work in mxcubeweb - # NB Temporarily inactivated pending a fix - - # Ask user to zoom - info_text = """Automatic sample re-centering is now active - Switch to maximum zoom before continuing""" - - schema = { - "title": "GΦL Translational calibration", - "type": "object", - "properties": {}, - } - fields = schema["properties"] - fields["_info"] = { - "type": "textdisplay", - "default": info_text, - "readOnly": True, - } - ui_schema = { - "ui:order": ["_info"], - "ui:widget": "vertical_box", - "ui:options": { - "return_signal": self.PARAMETER_RETURN_SIGNAL, - # "update_signal": self.PARAMETER_UPDATE_SIGNAL, - # "update_on_change": "selected", - }, - } - self._return_parameters = gevent.event.AsyncResult() - try: - dispatcher.connect( - self.receive_ok_cancel, - self.PARAMETER_RETURN_SIGNAL, - dispatcher.Any, - ) - responses = dispatcher.send( - self.PARAMETERS_NEEDED, - self, - schema, - ui_schema, - ) - if not responses: - self._return_parameters.set_exception( - RuntimeError( - "Signal %s is not connected" % self.PARAMETERS_NEEDED - ) - ) - - result = self._return_parameters.get() - if result is StopIteration: - return StopIteration - finally: - dispatcher.disconnect( - self.receive_ok_cancel, - self.PARAMETER_RETURN_SIGNAL, - dispatcher.Any, - ) - self._return_parameters = None + # else: + # # TODO The UI popup does not work in mxcubeweb + # # NB Temporarily inactivated pending a fix + # + # # Ask user to zoom + # info_text = """Automatic sample re-centering is now active + # Switch to maximum zoom before continuing""" + # + # schema = { + # "title": "GΦL Translational calibration", + # "type": "object", + # "properties": {}, + # } + # fields = schema["properties"] + # fields["_info"] = { + # "type": "textdisplay", + # "default": info_text, + # "readOnly": True, + # } + # ui_schema = { + # "ui:order": ["_info"], + # "ui:widget": "vertical_box", + # "ui:options": { + # "return_signal": self.PARAMETER_RETURN_SIGNAL, + # # "update_signal": self.PARAMETER_UPDATE_SIGNAL, + # # "update_on_change": "selected", + # }, + # } + # self._return_parameters = gevent.event.AsyncResult() + # try: + # dispatcher.connect( + # self.receive_ok_cancel, + # self.PARAMETER_RETURN_SIGNAL, + # dispatcher.Any, + # ) + # responses = dispatcher.send( + # self.PARAMETERS_NEEDED, + # self, + # schema, + # ui_schema, + # ) + # if not responses: + # self._return_parameters.set_exception( + # RuntimeError( + # "Signal %s is not connected" % self.PARAMETERS_NEEDED + # ) + # ) + # + # result = self._return_parameters.get() + # if result is StopIteration: + # return StopIteration + # finally: + # dispatcher.disconnect( + # self.receive_ok_cancel, + # self.PARAMETER_RETURN_SIGNAL, + # dispatcher.Any, + # ) + # self._return_parameters = None settings = goniostatRotation.axisSettings.copy() if goniostatTranslation is not None: @@ -2513,7 +2512,7 @@ def execute_sample_centring( queue_manager = self._queue_entry.get_queue_controller() try: queue_manager.execute_entry(centring_entry) - except: + except Exception: HWR.beamline.queue_manager.emit("queue_execution_failed", (None,)) centring_result = centring_entry.get_data_model().get_centring_result() @@ -2764,7 +2763,7 @@ def get_emulation_sample_dir(self, sample_name=None): Returns: """ - sample_dir = None + sample_dir = "" if sample_name is None: sample_name = ( self._queue_entry.get_data_model().get_sample_node().get_name() @@ -2791,8 +2790,6 @@ def get_emulation_crystal_data(self, sample_name=None): Returns: Optional[str] """ - crystal_data = None - hklfile = None sample_dir = self.get_emulation_sample_dir(sample_name=sample_name) if os.path.isdir(sample_dir): crystal_file = os.path.join(sample_dir, "crystal.nml") From e8b25ba9912d9534639de589425f75935dde4d30 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 11 Oct 2024 14:53:53 +0000 Subject: [PATCH 081/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4319ed41c4..8b411e6b6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.163.0" +version = "1.164.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 6d7b7c8507f750526afc8fd9a036fa9234ebbce5 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 4 Oct 2024 17:53:32 +0100 Subject: [PATCH 082/172] First attempt to add space group synonyms --- mxcubecore/model/crystal_symmetry.py | 1100 ++++++++++++++++++----- mxcubecore/model/queue_model_objects.py | 8 +- 2 files changed, 864 insertions(+), 244 deletions(-) diff --git a/mxcubecore/model/crystal_symmetry.py b/mxcubecore/model/crystal_symmetry.py index 718c240fde..680d6faa9a 100644 --- a/mxcubecore/model/crystal_symmetry.py +++ b/mxcubecore/model/crystal_symmetry.py @@ -136,241 +136,857 @@ ] CRYSTAL_CLASS_MAP = OrderedDict((info.name, info) for info in CRYSTAL_CLASS_DATA) -SpaceGroupInfo = namedtuple("SpaceGroupInfo", ("number", "name", "crystal_class")) -# Data from https://onlinelibrary.wiley.com/iucr/itc/Cb/ch1o4v0001/ +SpaceGroupInfo = namedtuple( + "SpaceGroupInfo", ("number", "name", "crystal_class", "synonyms") +) +# Names and synonyms derived from CCP4 (v9.) symop.lib +# Additional synonyms added for SG3-15 (e.g. 'P 21') +# Alternative axis orders added as synonyms for SG17,18 +# SG 146,148,155,160,161,166,167 are given names starting with 'R', +# with 'H' names as synonyms +# Crystal class names from https://onlinelibrary.wiley.com/iucr/itc/Cb/ch1o4v0001/ SPACEGROUP_DATA = [ - SpaceGroupInfo(1, "P1", "1P"), - SpaceGroupInfo(2, "P-1", "-1P"), - SpaceGroupInfo(3, "P2", "2P"), - SpaceGroupInfo(4, "P21", "2P"), - SpaceGroupInfo(5, "C2", "2C"), - SpaceGroupInfo(6, "Pm", "mP"), - SpaceGroupInfo(7, "Pc", "mP"), - SpaceGroupInfo(8, "Cm", "mC"), - SpaceGroupInfo(9, "Cc", "mC"), - SpaceGroupInfo(10, "P2/m", "2/mP"), - SpaceGroupInfo(11, "P21/m", "2/mP"), - SpaceGroupInfo(12, "C2/m", "2/mC"), - SpaceGroupInfo(13, "P2/c", "2/mP"), - SpaceGroupInfo(14, "P21/c", "2/mP"), - SpaceGroupInfo(15, "C2/c", "2/mC"), - SpaceGroupInfo(16, "P222", "222P"), - SpaceGroupInfo(17, "P2221", "222P"), - SpaceGroupInfo(18, "P21212", "222P"), - SpaceGroupInfo(19, "P212121", "222P"), - SpaceGroupInfo(20, "C2221", "222C"), - SpaceGroupInfo(21, "C222", "222C"), - SpaceGroupInfo(22, "F222", "222F"), - SpaceGroupInfo(23, "I222", "222I"), - SpaceGroupInfo(24, "I212121", "222I"), - SpaceGroupInfo(25, "Pmm2", "mm2P"), - SpaceGroupInfo(26, "Pmc21", "mm2P"), - SpaceGroupInfo(27, "Pcc2", "mm2P"), - SpaceGroupInfo(28, "Pma2", "mm2P"), - SpaceGroupInfo(29, "Pca21", "mm2P"), - SpaceGroupInfo(30, "Pnc2", "mm2P"), - SpaceGroupInfo(31, "Pmn21", "mm2P"), - SpaceGroupInfo(32, "Pba2", "mm2P"), - SpaceGroupInfo(33, "Pna21", "mm2P"), - SpaceGroupInfo(34, "Pnn2", "mm2P"), - SpaceGroupInfo(35, "Cmm2", "mm2C"), - SpaceGroupInfo(36, "Cmc21", "mm2C"), - SpaceGroupInfo(37, "Ccc2", "mm2C"), - SpaceGroupInfo(38, "C2mm", "2mmC"), # NB Standard setting is in A, not C - SpaceGroupInfo(39, "C2me", "2mmC"), # NB Standard setting is in A, not C - SpaceGroupInfo(40, "C2cm", "2mmC"), # NB Standard setting is in A, not C - SpaceGroupInfo(41, "C2ce", "2mmC"), # NB Standard setting is in A, not C - SpaceGroupInfo(42, "Fmm2", "mm2F"), - SpaceGroupInfo(43, "Fdd2", "mm2F"), - SpaceGroupInfo(44, "Imm2", "mm2I"), - SpaceGroupInfo(45, "Iba2", "mm2I"), - SpaceGroupInfo(46, "Ima2", "mm2I"), - SpaceGroupInfo(47, "Pmmm", "mmmP"), - SpaceGroupInfo(48, "Pnnn", "mmmP"), - SpaceGroupInfo(49, "Pccm", "mmmP"), - SpaceGroupInfo(50, "Pban", "mmmP"), - SpaceGroupInfo(51, "Pmma", "mmmP"), - SpaceGroupInfo(52, "Pnna", "mmmP"), - SpaceGroupInfo(53, "Pmna", "mmmP"), - SpaceGroupInfo(54, "Pcca", "mmmP"), - SpaceGroupInfo(55, "Pbam", "mmmP"), - SpaceGroupInfo(56, "Pccn", "mmmP"), - SpaceGroupInfo(57, "Pbcm", "mmmP"), - SpaceGroupInfo(58, "Pnnm", "mmmP"), - SpaceGroupInfo(59, "Pmmn", "mmmP"), - SpaceGroupInfo(60, "Pbcn", "mmmP"), - SpaceGroupInfo(61, "Pbca", "mmmP"), - SpaceGroupInfo(62, "Pnma", "mmmP"), - SpaceGroupInfo(63, "Cmcm", "mmmC"), - SpaceGroupInfo(64, "Cmce", "mmmC"), - SpaceGroupInfo(65, "Cmmm", "mmmC"), - SpaceGroupInfo(66, "Cccm", "mmmC"), - SpaceGroupInfo(67, "Cmme", "mmmC"), - SpaceGroupInfo(68, "Ccce", "mmmC"), - SpaceGroupInfo(69, "Fmmm", "mmmF"), - SpaceGroupInfo(70, "Fddd", "mmmF"), - SpaceGroupInfo(71, "Immm", "mmmI"), - SpaceGroupInfo(72, "Ibam", "mmmI"), - SpaceGroupInfo(73, "Ibca", "mmmI"), - SpaceGroupInfo(74, "Imma", "mmmI"), - SpaceGroupInfo(75, "P4", "4P"), - SpaceGroupInfo(76, "P41", "4P"), - SpaceGroupInfo(77, "P42", "4P"), - SpaceGroupInfo(78, "P43", "4P"), - SpaceGroupInfo(79, "I4", "4I"), - SpaceGroupInfo(80, "I41", "4I"), - SpaceGroupInfo(81, "P-4", "-4P"), - SpaceGroupInfo(82, "I-4", "-4I"), - SpaceGroupInfo(83, "P4/m", "4/mP"), - SpaceGroupInfo(84, "P42/m", "4/mP"), - SpaceGroupInfo(85, "P4/n", "4/mP"), - SpaceGroupInfo(86, "P42/n", "4/mP"), - SpaceGroupInfo(87, "I4/m", "4/mI"), - SpaceGroupInfo(88, "I41/a", "4/mI"), - SpaceGroupInfo(89, "P422", "422P"), - SpaceGroupInfo(90, "P4212", "422P"), - SpaceGroupInfo(91, "P4122", "422P"), - SpaceGroupInfo(92, "P41212", "422P"), - SpaceGroupInfo(93, "P4222", "422P"), - SpaceGroupInfo(94, "P42212", "422P"), - SpaceGroupInfo(95, "P4322", "422P"), - SpaceGroupInfo(96, "P43212", "422P"), - SpaceGroupInfo(97, "I422", "422I"), - SpaceGroupInfo(98, "I4122", "422I"), - SpaceGroupInfo(99, "P4mm", "4mmP"), - SpaceGroupInfo(100, "P4bm", "4mmP"), - SpaceGroupInfo(101, "P42cm", "4mmP"), - SpaceGroupInfo(102, "P42nm", "4mmP"), - SpaceGroupInfo(103, "P4cc", "4mmP"), - SpaceGroupInfo(104, "P4nc", "4mmP"), - SpaceGroupInfo(105, "P42mc", "4mmP"), - SpaceGroupInfo(106, "P42bc", "4mmP"), - SpaceGroupInfo(107, "I4mm", "4mmI"), - SpaceGroupInfo(108, "I4cm", "4mmI"), - SpaceGroupInfo(109, "I41md", "4mmI"), - SpaceGroupInfo(110, "I41cd", "4mmI"), - SpaceGroupInfo(111, "P-42m", "-42mP"), - SpaceGroupInfo(112, "P-42c", "-42mP"), - SpaceGroupInfo(113, "P-421m", "-42mP"), - SpaceGroupInfo(114, "P-421c", "-42mP"), - SpaceGroupInfo(115, "P-4m2", "-4m2P"), - SpaceGroupInfo(116, "P-4c2", "-4m2P"), - SpaceGroupInfo(117, "P-4b2", "-4m2P"), - SpaceGroupInfo(118, "P-4n2", "-4m2P"), - SpaceGroupInfo(119, "I-4m2", "-4m2I"), - SpaceGroupInfo(120, "I-4c2", "-4m2I"), - SpaceGroupInfo(121, "I-42m", "-42mI"), - SpaceGroupInfo(122, "I-42d", "-42mI"), - SpaceGroupInfo(123, "P4/mmm", "4/mmmP"), - SpaceGroupInfo(124, "P4/mcc", "4/mmmP"), - SpaceGroupInfo(125, "P4/nbm", "4/mmmP"), - SpaceGroupInfo(126, "P4/nnc", "4/mmmP"), - SpaceGroupInfo(127, "P4/mbm", "4/mmmP"), - SpaceGroupInfo(128, "P4/mnc", "4/mmmP"), - SpaceGroupInfo(129, "P4/nmm", "4/mmmP"), - SpaceGroupInfo(130, "P4/ncc", "4/mmmP"), - SpaceGroupInfo(131, "P42/mmc", "4/mmmP"), - SpaceGroupInfo(132, "P42/mcm", "4/mmmP"), - SpaceGroupInfo(133, "P42/nbc", "4/mmmP"), - SpaceGroupInfo(134, "P42/nnm", "4/mmmP"), - SpaceGroupInfo(135, "P42/mbc", "4/mmmP"), - SpaceGroupInfo(136, "P42/mnm", "4/mmmP"), - SpaceGroupInfo(137, "P42/nmc", "4/mmmP"), - SpaceGroupInfo(138, "P42/ncm", "4/mmmP"), - SpaceGroupInfo(139, "I4/mmm", "4/mmmI"), - SpaceGroupInfo(140, "I4/mcm", "4/mmmI"), - SpaceGroupInfo(141, "I41/amd", "4/mmmI"), - SpaceGroupInfo(142, "I41/acd", "4/mmmI"), - SpaceGroupInfo(143, "P3", "3P"), - SpaceGroupInfo(144, "P31", "3P"), - SpaceGroupInfo(145, "P32", "3P"), - SpaceGroupInfo(146, "H3", "3R"), - SpaceGroupInfo(147, "P-3", "-3P"), - SpaceGroupInfo(148, "H-3", "-3R"), - SpaceGroupInfo(149, "P312", "312P"), - SpaceGroupInfo(150, "P321", "321P"), - SpaceGroupInfo(151, "P3112", "312P"), - SpaceGroupInfo(152, "P3121", "321P"), - SpaceGroupInfo(153, "P3212", "312P"), - SpaceGroupInfo(154, "P3221", "321P"), - SpaceGroupInfo(155, "H32", "32R"), - SpaceGroupInfo(156, "P3m1", "3m1P"), - SpaceGroupInfo(157, "P31m", "31mP"), - SpaceGroupInfo(158, "P3c1", "3m1P"), - SpaceGroupInfo(159, "P31c", "31mP"), - SpaceGroupInfo(160, "H3m", "3mR"), - SpaceGroupInfo(161, "H3c", "3mR"), - SpaceGroupInfo(162, "P-31m", "-31mP"), - SpaceGroupInfo(163, "P-31c", "-31mP"), - SpaceGroupInfo(164, "P-3m1", "-3m1P"), - SpaceGroupInfo(165, "P-3c1", "-3m1P"), - SpaceGroupInfo(166, "H-3m", "-3mR"), - SpaceGroupInfo(167, "H-3c", "-3mR"), - SpaceGroupInfo(168, "P6", "6P"), - SpaceGroupInfo(169, "P61", "6P"), - SpaceGroupInfo(170, "P65", "6P"), - SpaceGroupInfo(171, "P62", "6P"), - SpaceGroupInfo(172, "P64", "6P"), - SpaceGroupInfo(173, "P63", "6P"), - SpaceGroupInfo(174, "P-6", "-6P"), - SpaceGroupInfo(175, "P6/m", "6/mP"), - SpaceGroupInfo(176, "P63/m", "6/mP"), - SpaceGroupInfo(177, "P622", "622P"), - SpaceGroupInfo(178, "P6122", "622P"), - SpaceGroupInfo(179, "P6522", "622P"), - SpaceGroupInfo(180, "P6222", "622P"), - SpaceGroupInfo(181, "P6422", "622P"), - SpaceGroupInfo(182, "P6322", "622P"), - SpaceGroupInfo(183, "P6mm", "6mmP"), - SpaceGroupInfo(184, "P6cc", "6mmP"), - SpaceGroupInfo(185, "P63cm", "6mmP"), - SpaceGroupInfo(186, "P63mc", "6mmP"), - SpaceGroupInfo(187, "P-6m2", "-6m2P"), - SpaceGroupInfo(188, "P-6c2", "-6m2P"), - SpaceGroupInfo(189, "P-62m", "-62mP"), - SpaceGroupInfo(190, "P-62c", "-62mP"), - SpaceGroupInfo(191, "P6/mmm", "6/mmmP"), - SpaceGroupInfo(192, "P6/mmc", "6/mmmP"), - SpaceGroupInfo(193, "P63/mcm", "6/mmmP"), - SpaceGroupInfo(194, "P63/mmc", "6/mmmP"), - SpaceGroupInfo(195, "P23", "23P"), - SpaceGroupInfo(196, "F23", "23F"), - SpaceGroupInfo(197, "I23", "23I"), - SpaceGroupInfo(198, "P213", "23P"), - SpaceGroupInfo(199, "I213", "23I"), - SpaceGroupInfo(200, "Pm-3", "m-3P"), - SpaceGroupInfo(201, "Pn-3", "m-3P"), - SpaceGroupInfo(202, "Fm-3", "m-3F"), - SpaceGroupInfo(203, "Fd-3", "m-3F"), - SpaceGroupInfo(204, "Im-3", "m-3I"), - SpaceGroupInfo(205, "Pa-3", "m-3P"), - SpaceGroupInfo(206, "Ia-3", "m-3I"), - SpaceGroupInfo(207, "P432", "432P"), - SpaceGroupInfo(208, "P4232", "432P"), - SpaceGroupInfo(209, "F432", "432F"), - SpaceGroupInfo(210, "F4132", "432F"), - SpaceGroupInfo(211, "I432", "432I"), - SpaceGroupInfo(212, "P4332", "432P"), - SpaceGroupInfo(213, "P4132", "432P"), - SpaceGroupInfo(214, "I4132", "432I"), - SpaceGroupInfo(215, "P-43m", "-43mP"), - SpaceGroupInfo(216, "F-43m", "-43mF"), - SpaceGroupInfo(217, "I-43m", "-43mI"), - SpaceGroupInfo(218, "P-43n", "-43mP"), - SpaceGroupInfo(219, "F-43c", "-43mF"), - SpaceGroupInfo(220, "I-43d", "-43mI"), - SpaceGroupInfo(221, "Pm-3m", "m-3mP"), - SpaceGroupInfo(222, "Pn-3n", "m-3mP"), - SpaceGroupInfo(223, "Pm-3n", "m-3mP"), - SpaceGroupInfo(224, "Pn-3m", "m-3mP"), - SpaceGroupInfo(225, "Fm-3m", "m-3mF"), - SpaceGroupInfo(226, "Fm-3c", "m-3mF"), - SpaceGroupInfo(227, "Fd-3m", "m-3mF"), - SpaceGroupInfo(228, "Fd-3c", "m-3mF"), - SpaceGroupInfo(229, "Im-3m", "m-3mI"), - SpaceGroupInfo(230, "Ia-3d", "m-3mI"), + SpaceGroupInfo(number=1, name="P1", crystal_class="1P", synonyms=("P 1",)), + SpaceGroupInfo(number=2, name="P-1", crystal_class="-1P", synonyms=("P -1",)), + SpaceGroupInfo( + number=3, name="P2", crystal_class="2P", synonyms=("P 1 2 1", "P121", "P 2") + ), + SpaceGroupInfo( + number=4, name="P21", crystal_class="2P", synonyms=("P 1 21 1", "P1211", "P 21") + ), + SpaceGroupInfo( + number=5, name="C2", crystal_class="2C", synonyms=("C 1 2 1", "C121", "C 2") + ), + SpaceGroupInfo( + number=6, name="Pm", crystal_class="mP", synonyms=("P 1 m 1", "P1m1", "P m") + ), + SpaceGroupInfo( + number=7, name="Pc", crystal_class="mP", synonyms=("P 1 c 1", "P1c1", "P c") + ), + SpaceGroupInfo( + number=8, name="Cm", crystal_class="mC", synonyms=("C 1 m 1", "C1m1", "C m") + ), + SpaceGroupInfo( + number=9, name="Cc", crystal_class="mC", synonyms=("C 1 c 1", "C1c1", "C c") + ), + SpaceGroupInfo( + number=10, + name="P2/m", + crystal_class="2/mP", + synonyms=("P 1 2/m 1", "P12/m1", "P 2/m"), + ), + SpaceGroupInfo( + number=11, + name="P21/m", + crystal_class="2/mP", + synonyms=("P 1 21/m 1", "P121/m1", "P 21/m"), + ), + SpaceGroupInfo( + number=12, + name="C2/m", + crystal_class="2/mC", + synonyms=("C 1 2/m 1", "C12/m1", "C 2/m"), + ), + SpaceGroupInfo( + number=13, + name="P2/c", + crystal_class="2/mP", + synonyms=("P 1 2/c 1", "P12/c1", "P 2/c"), + ), + SpaceGroupInfo( + number=14, + name="P21/c", + crystal_class="2/mP", + synonyms=("P 1 21/c 1", "P121/c1", "P 21/c"), + ), + SpaceGroupInfo( + number=15, + name="C2/c", + crystal_class="2/mC", + synonyms=("C 1 2/c 1", "C12/c1", "C 2/c"), + ), + SpaceGroupInfo(number=16, name="P222", crystal_class="222P", synonyms=("P 2 2 2",)), + SpaceGroupInfo( + number=17, name="P2221", crystal_class="222P", synonyms=("P 2 2 21",) + ), + SpaceGroupInfo( + number=18, name="P21212", crystal_class="222P", synonyms=("P 21 21 2",) + ), + SpaceGroupInfo( + number=19, name="P212121", crystal_class="222P", synonyms=("P 21 21 21",) + ), + SpaceGroupInfo( + number=20, name="C2221", crystal_class="222C", synonyms=("C 2 2 21",) + ), + SpaceGroupInfo(number=21, name="C222", crystal_class="222C", synonyms=("C 2 2 2",)), + SpaceGroupInfo(number=22, name="F222", crystal_class="222F", synonyms=("F 2 2 2",)), + SpaceGroupInfo(number=23, name="I222", crystal_class="222I", synonyms=("I 2 2 2",)), + SpaceGroupInfo( + number=24, name="I212121", crystal_class="222I", synonyms=("I 21 21 21",) + ), + SpaceGroupInfo(number=25, name="Pmm2", crystal_class="mm2P", synonyms=("P m m 2",)), + SpaceGroupInfo( + number=26, name="Pmc21", crystal_class="mm2P", synonyms=("P m c 21",) + ), + SpaceGroupInfo(number=27, name="Pcc2", crystal_class="mm2P", synonyms=("P c c 2",)), + SpaceGroupInfo(number=28, name="Pma2", crystal_class="mm2P", synonyms=("P m a 2",)), + SpaceGroupInfo( + number=29, name="Pca21", crystal_class="mm2P", synonyms=("P c a 21",) + ), + SpaceGroupInfo(number=30, name="Pnc2", crystal_class="mm2P", synonyms=("P n c 2",)), + SpaceGroupInfo( + number=31, name="Pmn21", crystal_class="mm2P", synonyms=("P m n 21",) + ), + SpaceGroupInfo(number=32, name="Pba2", crystal_class="mm2P", synonyms=("P b a 2",)), + SpaceGroupInfo( + number=33, name="Pna21", crystal_class="mm2P", synonyms=("P n a 21",) + ), + SpaceGroupInfo(number=34, name="Pnn2", crystal_class="mm2P", synonyms=("P n n 2",)), + SpaceGroupInfo(number=35, name="Cmm2", crystal_class="mm2C", synonyms=("C m m 2",)), + SpaceGroupInfo( + number=36, name="Cmc21", crystal_class="mm2C", synonyms=("C m c 21",) + ), + SpaceGroupInfo(number=37, name="Ccc2", crystal_class="mm2C", synonyms=("C c c 2",)), + SpaceGroupInfo(number=38, name="Amm2", crystal_class="2mmC", synonyms=("A m m 2",)), + SpaceGroupInfo(number=39, name="Abm2", crystal_class="2mmC", synonyms=("A b m 2",)), + SpaceGroupInfo(number=40, name="Ama2", crystal_class="2mmC", synonyms=("A m a 2",)), + SpaceGroupInfo(number=41, name="Aba2", crystal_class="2mmC", synonyms=("A b a 2",)), + SpaceGroupInfo(number=42, name="Fmm2", crystal_class="mm2F", synonyms=("F m m 2",)), + SpaceGroupInfo(number=43, name="Fdd2", crystal_class="mm2F", synonyms=("F d d 2",)), + SpaceGroupInfo(number=44, name="Imm2", crystal_class="mm2I", synonyms=("I m m 2",)), + SpaceGroupInfo(number=45, name="Iba2", crystal_class="mm2I", synonyms=("I b a 2",)), + SpaceGroupInfo(number=46, name="Ima2", crystal_class="mm2I", synonyms=("I m a 2",)), + SpaceGroupInfo( + number=47, + name="Pmmm", + crystal_class="mmmP", + synonyms=("P 2/m 2/m 2/m", "P2/m2/m2/m", "P m m m"), + ), + SpaceGroupInfo( + number=48, + name="Pnnn", + crystal_class="mmmP", + synonyms=("P 2/n 2/n 2/n", "P2/n2/n2/n", "P n n n"), + ), + SpaceGroupInfo( + number=49, + name="Pccm", + crystal_class="mmmP", + synonyms=("P 2/c 2/c 2/m", "P2/c2/c2/m", "P c c m"), + ), + SpaceGroupInfo( + number=50, + name="Pban", + crystal_class="mmmP", + synonyms=("P 2/b 2/a 2/n", "P2/b2/a2/n", "P b a n"), + ), + SpaceGroupInfo( + number=51, + name="Pmma", + crystal_class="mmmP", + synonyms=("P 21/m 2/m 2/a", "P21/m2/m2/a", "P m m a"), + ), + SpaceGroupInfo( + number=52, + name="Pnna", + crystal_class="mmmP", + synonyms=("P 2/n 21/n 2/a", "P2/n21/n2/a", "P n n a"), + ), + SpaceGroupInfo( + number=53, + name="Pmna", + crystal_class="mmmP", + synonyms=("P 2/m 2/n 21/a", "P2/m2/n21/a", "P m n a"), + ), + SpaceGroupInfo( + number=54, + name="Pcca", + crystal_class="mmmP", + synonyms=("P 21/c 2/c 2/a", "P21/c2/c2/a", "P c c a"), + ), + SpaceGroupInfo( + number=55, + name="Pbam", + crystal_class="mmmP", + synonyms=("P 21/b 21/a 2/m", "P21/b21/a2/m", "P b a m"), + ), + SpaceGroupInfo( + number=56, + name="Pccn", + crystal_class="mmmP", + synonyms=("P 21/c 21/c 2/n", "P21/c21/c2/n", "P c c n"), + ), + SpaceGroupInfo( + number=57, + name="Pbcm", + crystal_class="mmmP", + synonyms=("P 2/b 21/c 21/m", "P2/b21/c21/m", "P b c m"), + ), + SpaceGroupInfo( + number=58, + name="Pnnm", + crystal_class="mmmP", + synonyms=("P 21/n 21/n 2/m", "P21/n21/n2/m", "P n n m"), + ), + SpaceGroupInfo( + number=59, + name="Pmmn", + crystal_class="mmmP", + synonyms=("P 21/m 21/m 2/n", "P21/m21/m2/n", "P m m n"), + ), + SpaceGroupInfo( + number=60, + name="Pbcn", + crystal_class="mmmP", + synonyms=("P 21/b 2/c 21/n", "P21/b2/c21/n", "P b c n"), + ), + SpaceGroupInfo( + number=61, + name="Pbca", + crystal_class="mmmP", + synonyms=("P 21/b 21/c 21/a", "P21/b21/c21/a", "P b c a"), + ), + SpaceGroupInfo( + number=62, + name="Pnma", + crystal_class="mmmP", + synonyms=("P 21/n 21/m 21/a", "P21/n21/m21/a", "P n m a"), + ), + SpaceGroupInfo( + number=63, + name="Cmcm", + crystal_class="mmmC", + synonyms=("C 2/m 2/c 21/m", "C2/m2/c21/m", "C m c m"), + ), + SpaceGroupInfo( + number=64, + name="Cmca", + crystal_class="mmmC", + synonyms=("C 2/m 2/c 21/a", "C2/m2/c21/a", "C m c a"), + ), + SpaceGroupInfo( + number=65, + name="Cmmm", + crystal_class="mmmC", + synonyms=("C 2/m 2/m 2/m", "C2/m2/m2/m", "C m m m"), + ), + SpaceGroupInfo( + number=66, + name="Cccm", + crystal_class="mmmC", + synonyms=("C 2/c 2/c 2/m", "C2/c2/c2/m", "C c c m"), + ), + SpaceGroupInfo( + number=67, + name="Cmma", + crystal_class="mmmC", + synonyms=("C 2/m 2/m 2/a", "C2/m2/m2/a", "C m m a"), + ), + SpaceGroupInfo( + number=68, + name="Ccca", + crystal_class="mmmC", + synonyms=("C 2/c 2/c 2/a", "C2/c2/c2/a", "C c c a"), + ), + SpaceGroupInfo( + number=69, + name="Fmmm", + crystal_class="mmmF", + synonyms=("F 2/m 2/m 2/m", "F2/m2/m2/m", "F m m m"), + ), + SpaceGroupInfo( + number=70, + name="Fddd", + crystal_class="mmmF", + synonyms=("F 2/d 2/d 2/d", "F2/d2/d2/d", "F d d d"), + ), + SpaceGroupInfo( + number=71, + name="Immm", + crystal_class="mmmI", + synonyms=("I 2/m 2/m 2/m", "I2/m2/m2/m", "I m m m"), + ), + SpaceGroupInfo( + number=72, + name="Ibam", + crystal_class="mmmI", + synonyms=("I 2/b 2/a 2/m", "I2/b2/a2/m", "I b a m"), + ), + SpaceGroupInfo( + number=73, + name="Ibca", + crystal_class="mmmI", + synonyms=("I 21/b 21/c 21/a", "I21/b21/c21/a", "I b c a"), + ), + SpaceGroupInfo( + number=74, + name="Imma", + crystal_class="mmmI", + synonyms=("I 21/m 21/m 21/a", "I21/m21/m21/a", "I m m a"), + ), + SpaceGroupInfo(number=75, name="P4", crystal_class="4P", synonyms=("P 4",)), + SpaceGroupInfo(number=76, name="P41", crystal_class="4P", synonyms=("P 41",)), + SpaceGroupInfo(number=77, name="P42", crystal_class="4P", synonyms=("P 42",)), + SpaceGroupInfo(number=78, name="P43", crystal_class="4P", synonyms=("P 43",)), + SpaceGroupInfo(number=79, name="I4", crystal_class="4I", synonyms=("I 4",)), + SpaceGroupInfo(number=80, name="I41", crystal_class="4I", synonyms=("I 41",)), + SpaceGroupInfo(number=81, name="P-4", crystal_class="-4P", synonyms=("P -4",)), + SpaceGroupInfo(number=82, name="I-4", crystal_class="-4I", synonyms=("I -4",)), + SpaceGroupInfo(number=83, name="P4/m", crystal_class="4/mP", synonyms=("P 4/m",)), + SpaceGroupInfo(number=84, name="P42/m", crystal_class="4/mP", synonyms=("P 42/m",)), + SpaceGroupInfo(number=85, name="P4/n", crystal_class="4/mP", synonyms=("P 4/n",)), + SpaceGroupInfo(number=86, name="P42/n", crystal_class="4/mP", synonyms=("P 42/n",)), + SpaceGroupInfo(number=87, name="I4/m", crystal_class="4/mI", synonyms=("I 4/m",)), + SpaceGroupInfo(number=88, name="I41/a", crystal_class="4/mI", synonyms=("I 41/a",)), + SpaceGroupInfo(number=89, name="P422", crystal_class="422P", synonyms=("P 4 2 2",)), + SpaceGroupInfo( + number=90, name="P4212", crystal_class="422P", synonyms=("P 4 21 2",) + ), + SpaceGroupInfo( + number=91, name="P4122", crystal_class="422P", synonyms=("P 41 2 2",) + ), + SpaceGroupInfo( + number=92, name="P41212", crystal_class="422P", synonyms=("P 41 21 2",) + ), + SpaceGroupInfo( + number=93, name="P4222", crystal_class="422P", synonyms=("P 42 2 2",) + ), + SpaceGroupInfo( + number=94, name="P42212", crystal_class="422P", synonyms=("P 42 21 2",) + ), + SpaceGroupInfo( + number=95, name="P4322", crystal_class="422P", synonyms=("P 43 2 2",) + ), + SpaceGroupInfo( + number=96, name="P43212", crystal_class="422P", synonyms=("P 43 21 2",) + ), + SpaceGroupInfo(number=97, name="I422", crystal_class="422I", synonyms=("I 4 2 2",)), + SpaceGroupInfo( + number=98, name="I4122", crystal_class="422I", synonyms=("I 41 2 2",) + ), + SpaceGroupInfo(number=99, name="P4mm", crystal_class="4mmP", synonyms=("P 4 m m",)), + SpaceGroupInfo( + number=100, name="P4bm", crystal_class="4mmP", synonyms=("P 4 b m",) + ), + SpaceGroupInfo( + number=101, name="P42cm", crystal_class="4mmP", synonyms=("P 42 c m",) + ), + SpaceGroupInfo( + number=102, name="P42nm", crystal_class="4mmP", synonyms=("P 42 n m",) + ), + SpaceGroupInfo( + number=103, name="P4cc", crystal_class="4mmP", synonyms=("P 4 c c",) + ), + SpaceGroupInfo( + number=104, name="P4nc", crystal_class="4mmP", synonyms=("P 4 n c",) + ), + SpaceGroupInfo( + number=105, name="P42mc", crystal_class="4mmP", synonyms=("P 42 m c",) + ), + SpaceGroupInfo( + number=106, name="P42bc", crystal_class="4mmP", synonyms=("P 42 b c",) + ), + SpaceGroupInfo( + number=107, name="I4mm", crystal_class="4mmI", synonyms=("I 4 m m",) + ), + SpaceGroupInfo( + number=108, name="I4cm", crystal_class="4mmI", synonyms=("I 4 c m",) + ), + SpaceGroupInfo( + number=109, name="I41md", crystal_class="4mmI", synonyms=("I 41 m d",) + ), + SpaceGroupInfo( + number=110, name="I41cd", crystal_class="4mmI", synonyms=("I 41 c d",) + ), + SpaceGroupInfo( + number=111, name="P-42m", crystal_class="-42mP", synonyms=("P -4 2 m",) + ), + SpaceGroupInfo( + number=112, name="P-42c", crystal_class="-42mP", synonyms=("P -4 2 c",) + ), + SpaceGroupInfo( + number=113, name="P-421m", crystal_class="-42mP", synonyms=("P -4 21 m",) + ), + SpaceGroupInfo( + number=114, name="P-421c", crystal_class="-42mP", synonyms=("P -4 21 c",) + ), + SpaceGroupInfo( + number=115, name="P-4m2", crystal_class="-4m2P", synonyms=("P -4 m 2",) + ), + SpaceGroupInfo( + number=116, name="P-4c2", crystal_class="-4m2P", synonyms=("P -4 c 2",) + ), + SpaceGroupInfo( + number=117, name="P-4b2", crystal_class="-4m2P", synonyms=("P -4 b 2",) + ), + SpaceGroupInfo( + number=118, name="P-4n2", crystal_class="-4m2P", synonyms=("P -4 n 2",) + ), + SpaceGroupInfo( + number=119, name="I-4m2", crystal_class="-4m2I", synonyms=("I -4 m 2",) + ), + SpaceGroupInfo( + number=120, name="I-4c2", crystal_class="-4m2I", synonyms=("I -4 c 2",) + ), + SpaceGroupInfo( + number=121, name="I-42m", crystal_class="-42mI", synonyms=("I -4 2 m",) + ), + SpaceGroupInfo( + number=122, name="I-42d", crystal_class="-42mI", synonyms=("I -4 2 d",) + ), + SpaceGroupInfo( + number=123, + name="P4/mmm", + crystal_class="4/mmmP", + synonyms=("P 4/m 2/m 2/m", "P4/m2/m2/m", "P4/m m m"), + ), + SpaceGroupInfo( + number=124, + name="P4/mcc", + crystal_class="4/mmmP", + synonyms=("P 4/m 2/c 2/c", "P4/m2/c2/c", "P4/m c c"), + ), + SpaceGroupInfo( + number=125, + name="P4/nbm", + crystal_class="4/mmmP", + synonyms=("P 4/n 2/b 2/m", "P4/n2/b2/m", "P4/n b m"), + ), + SpaceGroupInfo( + number=126, + name="P4/nnc", + crystal_class="4/mmmP", + synonyms=("P 4/n 2/n 2/c", "P4/n2/n2/c", "P4/n n c"), + ), + SpaceGroupInfo( + number=127, + name="P4/mbm", + crystal_class="4/mmmP", + synonyms=("P 4/m 21/b 2/m", "P4/m21/b2/m", "P4/m b m"), + ), + SpaceGroupInfo( + number=128, + name="P4/mnc", + crystal_class="4/mmmP", + synonyms=("P 4/m 21/n 2/c", "P4/m21/n2/c", "P4/m n c"), + ), + SpaceGroupInfo( + number=129, + name="P4/nmm", + crystal_class="4/mmmP", + synonyms=("P 4/n 21/m 2/m", "P4/n21/m2/m", "P4/n m m"), + ), + SpaceGroupInfo( + number=130, + name="P4/ncc", + crystal_class="4/mmmP", + synonyms=("P 4/n 2/c 2/c", "P4/n2/c2/c", "P4/n c c"), + ), + SpaceGroupInfo( + number=131, + name="P42/mmc", + crystal_class="4/mmmP", + synonyms=("P 42/m 2/m 2/c", "P42/m2/m2/c", "P42/m m c"), + ), + SpaceGroupInfo( + number=132, + name="P42/mcm", + crystal_class="4/mmmP", + synonyms=("P 42/m 2/c 2/m", "P42/m2/c2/m", "P42/m c m"), + ), + SpaceGroupInfo( + number=133, + name="P42/nbc", + crystal_class="4/mmmP", + synonyms=("P 42/n 2/b 2/c", "P42/n2/b2/c", "P42/n b c"), + ), + SpaceGroupInfo( + number=134, + name="P42/nnm", + crystal_class="4/mmmP", + synonyms=("P 42/n 2/n 2/m", "P42/n2/n2/m", "P42/n n m"), + ), + SpaceGroupInfo( + number=135, + name="P42/mbc", + crystal_class="4/mmmP", + synonyms=("P 42/m 21/b 2/c", "P42/m21/b2/c", "P42/m b c"), + ), + SpaceGroupInfo( + number=136, + name="P42/mnm", + crystal_class="4/mmmP", + synonyms=("P 42/m 21/n 2/m", "P42/m21/n2/m", "P42/m n m"), + ), + SpaceGroupInfo( + number=137, + name="P42/nmc", + crystal_class="4/mmmP", + synonyms=("P 42/n 21/m 2/c", "P42/n21/m2/c", "P42/n m c"), + ), + SpaceGroupInfo( + number=138, + name="P42/ncm", + crystal_class="4/mmmP", + synonyms=("P 42/n 21/c 2/m", "P42/n21/c2/m", "P42/n c m"), + ), + SpaceGroupInfo( + number=139, + name="I4/mmm", + crystal_class="4/mmmI", + synonyms=("I 4/m 2/m 2/m", "I4/m2/m2/m", "I4/m m m"), + ), + SpaceGroupInfo( + number=140, + name="I4/mcm", + crystal_class="4/mmmI", + synonyms=("I 4/m 2/c 2/m", "I4/m2/c2/m", "I4/m c m"), + ), + SpaceGroupInfo( + number=141, + name="I41/amd", + crystal_class="4/mmmI", + synonyms=("I 41/a 2/m 2/d", "I41/a2/m2/d", "I41/a m d"), + ), + SpaceGroupInfo( + number=142, + name="I41/acd", + crystal_class="4/mmmI", + synonyms=("I 41/a 2/c 2/d", "I41/a2/c2/d", "I41/a c d"), + ), + SpaceGroupInfo(number=143, name="P3", crystal_class="3P", synonyms=("P 3",)), + SpaceGroupInfo(number=144, name="P31", crystal_class="3P", synonyms=("P 31",)), + SpaceGroupInfo(number=145, name="P32", crystal_class="3P", synonyms=("P 32",)), + SpaceGroupInfo( + number=146, name="R3", crystal_class="3R", synonyms=("H 3", "H3", " R 3") + ), + SpaceGroupInfo(number=147, name="P-3", crystal_class="-3P", synonyms=("P -3",)), + SpaceGroupInfo( + number=148, name="R-3", crystal_class="-3R", synonyms=("H -3", "H-3", "R -3") + ), + SpaceGroupInfo( + number=149, name="P312", crystal_class="312P", synonyms=("P 3 1 2",) + ), + SpaceGroupInfo( + number=150, name="P321", crystal_class="321P", synonyms=("P 3 2 1",) + ), + SpaceGroupInfo( + number=151, name="P3112", crystal_class="312P", synonyms=("P 31 1 2",) + ), + SpaceGroupInfo( + number=152, name="P3121", crystal_class="321P", synonyms=("P 31 2 1",) + ), + SpaceGroupInfo( + number=153, name="P3212", crystal_class="312P", synonyms=("P 32 1 2",) + ), + SpaceGroupInfo( + number=154, name="P3221", crystal_class="321P", synonyms=("P 32 2 1",) + ), + SpaceGroupInfo( + number=155, name="R32", crystal_class="32R", synonyms=("H 3 2", "H32", "R 3 2") + ), + SpaceGroupInfo( + number=156, name="P3m1", crystal_class="3m1P", synonyms=("P 3 m 1",) + ), + SpaceGroupInfo( + number=157, name="P31m", crystal_class="31mP", synonyms=("P 3 1 m",) + ), + SpaceGroupInfo( + number=158, name="P3c1", crystal_class="3m1P", synonyms=("P 3 c 1",) + ), + SpaceGroupInfo( + number=159, name="P31c", crystal_class="31mP", synonyms=("P 3 1 c",) + ), + SpaceGroupInfo( + number=160, name="R3m", crystal_class="3mR", synonyms=("H 3 m", "H3m", "R 3 m") + ), + SpaceGroupInfo( + number=161, name="R3c", crystal_class="3mR", synonyms=("H 3 c", "H3c", "R 3 c") + ), + SpaceGroupInfo( + number=162, + name="P-31m", + crystal_class="-31mP", + synonyms=("P -3 1 2/m", "P-312/m", "P -3 1 m"), + ), + SpaceGroupInfo( + number=163, + name="P-31c", + crystal_class="-31mP", + synonyms=("P -3 1 2/c", "P-312/c", "P -3 1 c"), + ), + SpaceGroupInfo( + number=164, + name="P-3m1", + crystal_class="-3m1P", + synonyms=("P -3 2/m 1", "P-32/m1", "P -3 m 1"), + ), + SpaceGroupInfo( + number=165, + name="P-3c1", + crystal_class="-3m1P", + synonyms=("P -3 2/c 1", "P-32/c1", "P -3 c 1"), + ), + SpaceGroupInfo( + number=166, + name="R-3m", + crystal_class="-3mR", + synonyms=( + "H-3m", + "H -3 2/m", + "H-32/m", + "H -3 m", + "R -3 2/m", + "R-32/m", + "R -3 m", + ), + ), + SpaceGroupInfo( + number=167, + name="R-3c", + crystal_class="-3mR", + synonyms=( + "H-3c", + "H -3 2/c", + "H-32/c", + "H -3 c", + "R -3 2/c", + "R-32/c", + "R -3 c", + ), + ), + SpaceGroupInfo(number=168, name="P6", crystal_class="6P", synonyms=("P 6",)), + SpaceGroupInfo(number=169, name="P61", crystal_class="6P", synonyms=("P 61",)), + SpaceGroupInfo(number=170, name="P65", crystal_class="6P", synonyms=("P 65",)), + SpaceGroupInfo(number=171, name="P62", crystal_class="6P", synonyms=("P 62",)), + SpaceGroupInfo(number=172, name="P64", crystal_class="6P", synonyms=("P 64",)), + SpaceGroupInfo(number=173, name="P63", crystal_class="6P", synonyms=("P 63",)), + SpaceGroupInfo(number=174, name="P-6", crystal_class="-6P", synonyms=("P -6",)), + SpaceGroupInfo(number=175, name="P6/m", crystal_class="6/mP", synonyms=("P 6/m",)), + SpaceGroupInfo( + number=176, name="P63/m", crystal_class="6/mP", synonyms=("P 63/m",) + ), + SpaceGroupInfo( + number=177, name="P622", crystal_class="622P", synonyms=("P 6 2 2",) + ), + SpaceGroupInfo( + number=178, name="P6122", crystal_class="622P", synonyms=("P 61 2 2",) + ), + SpaceGroupInfo( + number=179, name="P6522", crystal_class="622P", synonyms=("P 65 2 2",) + ), + SpaceGroupInfo( + number=180, name="P6222", crystal_class="622P", synonyms=("P 62 2 2",) + ), + SpaceGroupInfo( + number=181, name="P6422", crystal_class="622P", synonyms=("P 64 2 2",) + ), + SpaceGroupInfo( + number=182, name="P6322", crystal_class="622P", synonyms=("P 63 2 2",) + ), + SpaceGroupInfo( + number=183, name="P6mm", crystal_class="6mmP", synonyms=("P 6 m m",) + ), + SpaceGroupInfo( + number=184, name="P6cc", crystal_class="6mmP", synonyms=("P 6 c c",) + ), + SpaceGroupInfo( + number=185, name="P63cm", crystal_class="6mmP", synonyms=("P 63 c m",) + ), + SpaceGroupInfo( + number=186, name="P63mc", crystal_class="6mmP", synonyms=("P 63 m c",) + ), + SpaceGroupInfo( + number=187, name="P-6m2", crystal_class="-6m2P", synonyms=("P -6 m 2",) + ), + SpaceGroupInfo( + number=188, name="P-6c2", crystal_class="-6m2P", synonyms=("P -6 c 2",) + ), + SpaceGroupInfo( + number=189, name="P-62m", crystal_class="-62mP", synonyms=("P -6 2 m",) + ), + SpaceGroupInfo( + number=190, name="P-62c", crystal_class="-62mP", synonyms=("P -6 2 c",) + ), + SpaceGroupInfo( + number=191, + name="P6/mmm", + crystal_class="6/mmmP", + synonyms=("P 6/m 2/m 2/m", "P6/m2/m2/m", "P 6/m m m"), + ), + SpaceGroupInfo( + number=192, + name="P6/mcc", + crystal_class="6/mmmP", + synonyms=("P 6/m 2/c 2/c", "P6/m2/c2/c", "P 6/m c c"), + ), + SpaceGroupInfo( + number=193, + name="P63/mcm", + crystal_class="6/mmmP", + synonyms=("P 63/m 2/c 2/m", "P63/m2/c2/m", "P 63/m c m"), + ), + SpaceGroupInfo( + number=194, + name="P63/mmc", + crystal_class="6/mmmP", + synonyms=("P 63/m 2/m 2/c", "P63/m2/m2/c", "P 63/m m c"), + ), + SpaceGroupInfo(number=195, name="P23", crystal_class="23P", synonyms=("P 2 3",)), + SpaceGroupInfo(number=196, name="F23", crystal_class="23F", synonyms=("F 2 3",)), + SpaceGroupInfo(number=197, name="I23", crystal_class="23I", synonyms=("I 2 3",)), + SpaceGroupInfo(number=198, name="P213", crystal_class="23P", synonyms=("P 21 3",)), + SpaceGroupInfo(number=199, name="I213", crystal_class="23I", synonyms=("I 21 3",)), + SpaceGroupInfo( + number=200, + name="Pm-3", + crystal_class="m-3P", + synonyms=("P 2/m -3", "P2/m-3", "P m -3"), + ), + SpaceGroupInfo( + number=201, + name="Pn-3", + crystal_class="m-3P", + synonyms=("P 2/n -3", "P2/n-3", "P n -3"), + ), + SpaceGroupInfo( + number=202, + name="Fm-3", + crystal_class="m-3F", + synonyms=("F 2/m -3", "F2/m-3", "F m -3"), + ), + SpaceGroupInfo( + number=203, + name="Fd-3", + crystal_class="m-3F", + synonyms=("F 2/d -3", "F2/d-3", "F d -3"), + ), + SpaceGroupInfo( + number=204, + name="Im-3", + crystal_class="m-3I", + synonyms=("I 2/m -3", "I2/m-3", "I m -3"), + ), + SpaceGroupInfo( + number=205, + name="Pa-3", + crystal_class="m-3P", + synonyms=("P 21/a -3", "P21/a-3", "P a -3"), + ), + SpaceGroupInfo( + number=206, + name="Ia-3", + crystal_class="m-3I", + synonyms=("I 21/a -3", "I21/a-3", "I a -3"), + ), + SpaceGroupInfo( + number=207, name="P432", crystal_class="432P", synonyms=("P 4 3 2",) + ), + SpaceGroupInfo( + number=208, name="P4232", crystal_class="432P", synonyms=("P 42 3 2",) + ), + SpaceGroupInfo( + number=209, name="F432", crystal_class="432F", synonyms=("F 4 3 2",) + ), + SpaceGroupInfo( + number=210, name="F4132", crystal_class="432F", synonyms=("F 41 3 2",) + ), + SpaceGroupInfo( + number=211, name="I432", crystal_class="432I", synonyms=("I 4 3 2",) + ), + SpaceGroupInfo( + number=212, name="P4332", crystal_class="432P", synonyms=("P 43 3 2",) + ), + SpaceGroupInfo( + number=213, name="P4132", crystal_class="432P", synonyms=("P 41 3 2",) + ), + SpaceGroupInfo( + number=214, name="I4132", crystal_class="432I", synonyms=("I 41 3 2",) + ), + SpaceGroupInfo( + number=215, name="P-43m", crystal_class="-43mP", synonyms=("P -4 3 m",) + ), + SpaceGroupInfo( + number=216, name="F-43m", crystal_class="-43mF", synonyms=("F -4 3 m",) + ), + SpaceGroupInfo( + number=217, name="I-43m", crystal_class="-43mI", synonyms=("I -4 3 m",) + ), + SpaceGroupInfo( + number=218, name="P-43n", crystal_class="-43mP", synonyms=("P -4 3 n",) + ), + SpaceGroupInfo( + number=219, name="F-43c", crystal_class="-43mF", synonyms=("F -4 3 c",) + ), + SpaceGroupInfo( + number=220, name="I-43d", crystal_class="-43mI", synonyms=("I -4 3 d",) + ), + SpaceGroupInfo( + number=221, + name="Pm-3m", + crystal_class="m-3mP", + synonyms=("P 4/m -3 2/m", "P4/m-32/m", "P m -3 m"), + ), + SpaceGroupInfo( + number=222, + name="Pn-3n", + crystal_class="m-3mP", + synonyms=("P 4/n -3 2/n", "P4/n-32/n", "P n -3 n"), + ), + SpaceGroupInfo( + number=223, + name="Pm-3n", + crystal_class="m-3mP", + synonyms=("P 42/m -3 2/n", "P42/m-32/n", "P m -3 n"), + ), + SpaceGroupInfo( + number=224, + name="Pn-3m", + crystal_class="m-3mP", + synonyms=("P 42/n -3 2/m", "P42/n-32/m", "P n -3 m"), + ), + SpaceGroupInfo( + number=225, + name="Fm-3m", + crystal_class="m-3mF", + synonyms=("F 4/m -3 2/m", "F4/m-32/m", "F m -3 m"), + ), + SpaceGroupInfo( + number=226, + name="Fm-3c", + crystal_class="m-3mF", + synonyms=("F 4/m -3 2/c", "F4/m-32/c", "F m -3 c"), + ), + SpaceGroupInfo( + number=227, + name="Fd-3m", + crystal_class="m-3mF", + synonyms=("F 41/d -3 2/m", "F41/d-32/m", "F d -3 m"), + ), + SpaceGroupInfo( + number=228, + name="Fd-3c", + crystal_class="m-3mF", + synonyms=("F 41/d -3 2/c", "F41/d-32/c", "F d -3 c"), + ), + SpaceGroupInfo( + number=229, + name="Im-3m", + crystal_class="m-3mI", + synonyms=("I 4/m -3 2/m", "I4/m-32/m", "I m -3 m"), + ), + SpaceGroupInfo( + number=230, + name="Ia-3d", + crystal_class="m-3mI", + synonyms=("I 41/a -3 2/d", "I41/a-32/d", "I a -3 d"), + ), ] SPACEGROUP_MAP = OrderedDict((info.name, info) for info in SPACEGROUP_DATA) +for tpl in SPACEGROUP_DATA: + # Done this way so that first elemets in map are on item per spacegroup + for tag in tpl.synonyms: + SPACEGROUP_MAP[tag] = tpl # Space group names for space groups compatible with chiral molecules, # i.e. that do not contain mirror planes or centres of symmetry, @@ -399,8 +1015,9 @@ ) UI_LATTICES = BRAVAIS_LATTICES + ("mI",) + def filter_crystal_classes(bravais_lattice, crystal_classes=()): - """ Filter crystal classes to select those compatible with selected Bravais lattice + """Filter crystal classes to select those compatible with selected Bravais lattice including sublattices @@ -414,7 +1031,8 @@ def filter_crystal_classes(bravais_lattice, crystal_classes=()): """ compatibles = SUB_LATTICE_MAP[bravais_lattice[0]] result = tuple( - xcls for xcls in crystal_classes + xcls + for xcls in crystal_classes if CRYSTAL_CLASS_MAP[xcls].bravais_lattice[0] in compatibles ) # @@ -436,7 +1054,7 @@ def space_groups_from_params(lattices=(), point_groups=(), chiral_only=True): if chiral_only: space_groups = XTAL_SPACEGROUPS[1:] else: - space_groups = list(SPACEGROUP_MAP) + space_groups = list(info.name for info in SPACEGROUP_DATA) if lattices or point_groups: sgs1 = [] if lattices: @@ -574,10 +1192,10 @@ def strategy_laue_group(crystal_classes: tuple, phasing=False): return result -def regularise_space_group(sgname:str): - """Convert finput (ISPyB) space gorup name to official space group name""" +def regularise_space_group(sgname: str): + """Convert input (ISPyB) space group name to official space group name""" - if sgname in SPACEGROUP_MAP: - return sgname - else: - return None + sginfo = SPACEGROUP_MAP.get(sgname) + if sginfo: + return sginfo.name + return None diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 928668a812..359c6e283a 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -2112,13 +2112,15 @@ def set_pre_strategy_params( # noqa: C901 from mxcubecore.HardwareObjects.Gphl import GphlMessages if space_group: - if space_group in crystal_symmetry.SPACEGROUP_MAP: - self.space_group = space_group - else: + sginfo = crystal_symmetry.SPACEGROUP_MAP.get(space_group) + if sginfo is None: raise ValueError( "Invalid space group %s, not in crystal_symmetry.SPACEGROUP_MAP" % space_group ) + else: + space_group = sginfo.name + self.space_group = space_group else: space_group = self.space_group if crystal_classes: From 91df1dde68106055144d40d5bf5d43994d04beca Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 11 Oct 2024 15:39:06 +0100 Subject: [PATCH 083/172] Cleaned up further for linting --- .../HardwareObjects/Gphl/GphlWorkflow.py | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 4c24af9920..13d97d70f5 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -2356,64 +2356,64 @@ def process_centring_request(self, payload, correlation_id): "Sample re-centering now active - Zoom in before continuing." ) - # else: - # # TODO The UI popup does not work in mxcubeweb - # # NB Temporarily inactivated pending a fix - # - # # Ask user to zoom - # info_text = """Automatic sample re-centering is now active - # Switch to maximum zoom before continuing""" - # - # schema = { - # "title": "GΦL Translational calibration", - # "type": "object", - # "properties": {}, - # } - # fields = schema["properties"] - # fields["_info"] = { - # "type": "textdisplay", - # "default": info_text, - # "readOnly": True, - # } - # ui_schema = { - # "ui:order": ["_info"], - # "ui:widget": "vertical_box", - # "ui:options": { - # "return_signal": self.PARAMETER_RETURN_SIGNAL, - # # "update_signal": self.PARAMETER_UPDATE_SIGNAL, - # # "update_on_change": "selected", - # }, - # } - # self._return_parameters = gevent.event.AsyncResult() - # try: - # dispatcher.connect( - # self.receive_ok_cancel, - # self.PARAMETER_RETURN_SIGNAL, - # dispatcher.Any, - # ) - # responses = dispatcher.send( - # self.PARAMETERS_NEEDED, - # self, - # schema, - # ui_schema, - # ) - # if not responses: - # self._return_parameters.set_exception( - # RuntimeError( - # "Signal %s is not connected" % self.PARAMETERS_NEEDED - # ) - # ) - # - # result = self._return_parameters.get() - # if result is StopIteration: - # return StopIteration - # finally: - # dispatcher.disconnect( - # self.receive_ok_cancel, - # self.PARAMETER_RETURN_SIGNAL, - # dispatcher.Any, - # ) - # self._return_parameters = None + # else: + # # TODO The UI popup does not work in mxcubeweb + # # NB Temporarily inactivated pending a fix + # + # # Ask user to zoom + # info_text = """Automatic sample re-centering is now active + # Switch to maximum zoom before continuing""" + # + # schema = { + # "title": "GΦL Translational calibration", + # "type": "object", + # "properties": {}, + # } + # fields = schema["properties"] + # fields["_info"] = { + # "type": "textdisplay", + # "default": info_text, + # "readOnly": True, + # } + # ui_schema = { + # "ui:order": ["_info"], + # "ui:widget": "vertical_box", + # "ui:options": { + # "return_signal": self.PARAMETER_RETURN_SIGNAL, + # # "update_signal": self.PARAMETER_UPDATE_SIGNAL, + # # "update_on_change": "selected", + # }, + # } + # self._return_parameters = gevent.event.AsyncResult() + # try: + # dispatcher.connect( + # self.receive_ok_cancel, + # self.PARAMETER_RETURN_SIGNAL, + # dispatcher.Any, + # ) + # responses = dispatcher.send( + # self.PARAMETERS_NEEDED, + # self, + # schema, + # ui_schema, + # ) + # if not responses: + # self._return_parameters.set_exception( + # RuntimeError( + # "Signal %s is not connected" % self.PARAMETERS_NEEDED + # ) + # ) + # + # result = self._return_parameters.get() + # if result is StopIteration: + # return StopIteration + # finally: + # dispatcher.disconnect( + # self.receive_ok_cancel, + # self.PARAMETER_RETURN_SIGNAL, + # dispatcher.Any, + # ) + # self._return_parameters = None settings = goniostatRotation.axisSettings.copy() if goniostatTranslation is not None: From bd74d06666eefd39485d643aada04a994b4a095a Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 11 Oct 2024 16:34:35 +0100 Subject: [PATCH 084/172] Added extra Space Group synonyms for P2221 and P21212 non-std settings --- mxcubecore/model/crystal_symmetry.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mxcubecore/model/crystal_symmetry.py b/mxcubecore/model/crystal_symmetry.py index 680d6faa9a..d4275ecea3 100644 --- a/mxcubecore/model/crystal_symmetry.py +++ b/mxcubecore/model/crystal_symmetry.py @@ -207,10 +207,16 @@ ), SpaceGroupInfo(number=16, name="P222", crystal_class="222P", synonyms=("P 2 2 2",)), SpaceGroupInfo( - number=17, name="P2221", crystal_class="222P", synonyms=("P 2 2 21",) + number=17, + name="P2221", + crystal_class="222P", + synonyms=("P 2 2 21", 'P2212', 'P 2 21 2', 'P2122', 'P 21 2 2') ), SpaceGroupInfo( - number=18, name="P21212", crystal_class="222P", synonyms=("P 21 21 2",) + number=18, + name="P21212", + crystal_class="222P", + synonyms=("P 21 21 2",'P21221', 'P 21 2 21', 'P22121', 'P 2 21 21') ), SpaceGroupInfo( number=19, name="P212121", crystal_class="222P", synonyms=("P 21 21 21",) From 808182173dee6b5fb107d850815d34c734f65451 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 11 Oct 2024 16:35:54 +0100 Subject: [PATCH 085/172] Run black --- mxcubecore/model/crystal_symmetry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mxcubecore/model/crystal_symmetry.py b/mxcubecore/model/crystal_symmetry.py index d4275ecea3..c2234141b2 100644 --- a/mxcubecore/model/crystal_symmetry.py +++ b/mxcubecore/model/crystal_symmetry.py @@ -210,13 +210,13 @@ number=17, name="P2221", crystal_class="222P", - synonyms=("P 2 2 21", 'P2212', 'P 2 21 2', 'P2122', 'P 21 2 2') + synonyms=("P 2 2 21", "P2212", "P 2 21 2", "P2122", "P 21 2 2"), ), SpaceGroupInfo( number=18, name="P21212", crystal_class="222P", - synonyms=("P 21 21 2",'P21221', 'P 21 2 21', 'P22121', 'P 2 21 21') + synonyms=("P 21 21 2", "P21221", "P 21 2 21", "P22121", "P 2 21 21"), ), SpaceGroupInfo( number=19, name="P212121", crystal_class="222P", synonyms=("P 21 21 21",) From b4c50e15532dba133d783760f5073eae786c9385 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Wed, 16 Oct 2024 14:48:26 +0100 Subject: [PATCH 086/172] Run pre-commit, and removed default_language_version --- .pre-commit-config.yaml | 4 ---- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 5 ++--- mxcubecore/HardwareObjects/abstract/AbstractCollect.py | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 79fb655644..322a8429fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,8 +1,5 @@ --- -default_language_version: - python: python3.8 - repos: - repo: https://github.com/adrienverge/yamllint @@ -53,7 +50,6 @@ repos: mxcubecore/HardwareObjects/EMBL/EMBL(Energy|DoorInterlock|OnlineProcessing)\.py| mxcubecore/HardwareObjects/mockup/(ISPyBClient|Motor|PlateManipulator)Mockup\.py| mxcubecore/HardwareObjects/abstract/(AbstractXRFSpectrum|sample_changer/Crims)\.py| - mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa\.py| mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution\.py| mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum\.py )$ diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 13d97d70f5..1a0cf8f40b 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -453,11 +453,11 @@ def query_pre_strategy_params(self, choose_lattice=None): reslimits = (0.5, 5.0) if resolution < reslimits[0]: resolution = ( - round(reslimits[0], resolution_decimals) + 0.1 ** resolution_decimals + round(reslimits[0], resolution_decimals) + 0.1**resolution_decimals ) if resolution > reslimits[1]: resolution = ( - round(reslimits[1], resolution_decimals) - 0.1 ** resolution_decimals + round(reslimits[1], resolution_decimals) - 0.1**resolution_decimals ) fields["resolution"] = { @@ -625,7 +625,6 @@ def query_pre_strategy_params(self, choose_lattice=None): elif not choose_lattice: # Characterisation ui_schema["parameters"]["column1"]["ui:order"].remove("point_groups") - pass else: # Acquisition diff --git a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py index 31fe8fe17c..2dc2b90c9e 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py @@ -24,7 +24,6 @@ """ import os -import sys import logging import time import errno From 1d31677d7715a6f796a7e450cf2438e2d7700c1e Mon Sep 17 00:00:00 2001 From: rhfogh Date: Thu, 17 Oct 2024 16:29:04 +0100 Subject: [PATCH 087/172] Removed commented-out section --- .../HardwareObjects/Gphl/GphlWorkflow.py | 63 +------------------ 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 1a0cf8f40b..218b89098d 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -453,11 +453,11 @@ def query_pre_strategy_params(self, choose_lattice=None): reslimits = (0.5, 5.0) if resolution < reslimits[0]: resolution = ( - round(reslimits[0], resolution_decimals) + 0.1**resolution_decimals + round(reslimits[0], resolution_decimals) + 0.1 ** resolution_decimals ) if resolution > reslimits[1]: resolution = ( - round(reslimits[1], resolution_decimals) - 0.1**resolution_decimals + round(reslimits[1], resolution_decimals) - 0.1 ** resolution_decimals ) fields["resolution"] = { @@ -2355,65 +2355,6 @@ def process_centring_request(self, payload, correlation_id): "Sample re-centering now active - Zoom in before continuing." ) - # else: - # # TODO The UI popup does not work in mxcubeweb - # # NB Temporarily inactivated pending a fix - # - # # Ask user to zoom - # info_text = """Automatic sample re-centering is now active - # Switch to maximum zoom before continuing""" - # - # schema = { - # "title": "GΦL Translational calibration", - # "type": "object", - # "properties": {}, - # } - # fields = schema["properties"] - # fields["_info"] = { - # "type": "textdisplay", - # "default": info_text, - # "readOnly": True, - # } - # ui_schema = { - # "ui:order": ["_info"], - # "ui:widget": "vertical_box", - # "ui:options": { - # "return_signal": self.PARAMETER_RETURN_SIGNAL, - # # "update_signal": self.PARAMETER_UPDATE_SIGNAL, - # # "update_on_change": "selected", - # }, - # } - # self._return_parameters = gevent.event.AsyncResult() - # try: - # dispatcher.connect( - # self.receive_ok_cancel, - # self.PARAMETER_RETURN_SIGNAL, - # dispatcher.Any, - # ) - # responses = dispatcher.send( - # self.PARAMETERS_NEEDED, - # self, - # schema, - # ui_schema, - # ) - # if not responses: - # self._return_parameters.set_exception( - # RuntimeError( - # "Signal %s is not connected" % self.PARAMETERS_NEEDED - # ) - # ) - # - # result = self._return_parameters.get() - # if result is StopIteration: - # return StopIteration - # finally: - # dispatcher.disconnect( - # self.receive_ok_cancel, - # self.PARAMETER_RETURN_SIGNAL, - # dispatcher.Any, - # ) - # self._return_parameters = None - settings = goniostatRotation.axisSettings.copy() if goniostatTranslation is not None: settings.update(goniostatTranslation.axisSettings) From ac74e5a54f8a001da50ca82e71403f1dfd8a893e Mon Sep 17 00:00:00 2001 From: rhfogh Date: Thu, 17 Oct 2024 16:41:40 +0100 Subject: [PATCH 088/172] Yet another black change --- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 218b89098d..5b63c2b98a 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -453,11 +453,11 @@ def query_pre_strategy_params(self, choose_lattice=None): reslimits = (0.5, 5.0) if resolution < reslimits[0]: resolution = ( - round(reslimits[0], resolution_decimals) + 0.1 ** resolution_decimals + round(reslimits[0], resolution_decimals) + 0.1**resolution_decimals ) if resolution > reslimits[1]: resolution = ( - round(reslimits[1], resolution_decimals) - 0.1 ** resolution_decimals + round(reslimits[1], resolution_decimals) - 0.1**resolution_decimals ) fields["resolution"] = { From d9668efbc0ea7c2d66536d9e6224beba212a4c40 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 17 Oct 2024 15:50:53 +0000 Subject: [PATCH 089/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8b411e6b6d..4131f944b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.164.0" +version = "1.165.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 965fa783cd5ad927f57e2190619806ae40a836eb Mon Sep 17 00:00:00 2001 From: fabcor Date: Fri, 18 Oct 2024 09:13:51 +0200 Subject: [PATCH 090/172] Update pre-commit hooks --- .pre-commit-config.yaml | 10 ++- deprecated/HardwareObjects/Camera.py | 1 + .../SpecMotorWSpecPositions.py | 1 + .../HardwareObjects/mockup/CameraMockup.py | 1 + .../HardwareObjects/mockup/VideoMockup.py | 1 + .../HardwareObjects/ALBA/XalocCalibration.py | 1 + mxcubecore/HardwareObjects/BlissActuator.py | 1 + mxcubecore/HardwareObjects/Camera.py | 1 + mxcubecore/HardwareObjects/CatsMaint.py | 1 + .../HardwareObjects/DESY/P11BeamStop.py | 6 +- .../HardwareObjects/DESY/P11Collimator.py | 12 +-- .../HardwareObjects/ESRF/BM14EnergyScan.py | 6 +- mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py | 1 + mxcubecore/HardwareObjects/ESRF/ESRFSC3.py | 1 + .../HardwareObjects/ESRF/ID231EnergyScan.py | 6 +- .../HardwareObjects/ESRF/ID30BEnergyScan.py | 6 +- .../HardwareObjects/ESRF/ID30BXRFSpectrum.py | 6 +- mxcubecore/HardwareObjects/ESRF/ID30SC3.py | 1 + .../HardwareObjects/Gphl/CollectEmulator.py | 2 +- .../Gphl/GphlWorkflowConnection.py | 12 +-- .../HardwareObjects/GrobSampleChanger.py | 1 + mxcubecore/HardwareObjects/ISPyBRestClient.py | 1 + .../HardwareObjects/LimaEigerDetector.py | 1 + .../HardwareObjects/MAXIV/BIOMAXKafka.py | 1 + .../HardwareObjects/MAXIV/MaxIVSession.py | 1 + mxcubecore/HardwareObjects/MiniDiff.py | 6 +- mxcubecore/HardwareObjects/MotorWPositions.py | 2 +- mxcubecore/HardwareObjects/PyISPyBClient.py | 1 + .../HardwareObjects/QtGraphicsManager.py | 6 +- mxcubecore/HardwareObjects/QueueManager.py | 1 + .../SOLEIL/PX1/PX1EnergyScan.py | 1 + .../HardwareObjects/SOLEIL/SOLEILCatsMaint.py | 1 + mxcubecore/HardwareObjects/Session.py | 1 + .../SpecMotorWSpecPositions.py | 1 + mxcubecore/HardwareObjects/TangoLimaVideo.py | 1 + .../HardwareObjects/TangoLimaVideoLoopback.py | 1 + mxcubecore/HardwareObjects/VaporyVideo.py | 1 - mxcubecore/HardwareObjects/XRFSpectrum.py | 12 +-- .../abstract/AbstractMultiCollect.py | 78 +++++++++---------- .../abstract/AbstractOnlineProcessing.py | 20 ++--- .../abstract/AbstractXRFSpectrum.py | 6 +- .../HardwareObjects/mockup/CatsMaintMockup.py | 1 + .../mockup/EnergyScanMockup.py | 6 +- .../mockup/ISPyBRestClientMockup.py | 1 + .../mockup/MachineInfoMockup.py | 1 + .../mockup/MicrodiffZoomMockup.py | 1 + mxcubecore/HardwareObjects/sample_centring.py | 32 +++++--- mxcubecore/model/queue_model_objects.py | 6 +- mxcubecore/queue_entry/advanced_connector.py | 6 +- mxcubecore/queue_entry/base_queue_entry.py | 6 +- 50 files changed, 159 insertions(+), 122 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 322a8429fd..8a360004dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,12 +10,12 @@ repos: - --strict - repo: https://github.com/python-poetry/poetry - rev: 1.5.0 + rev: 1.8.0 hooks: - id: poetry-check - repo: https://github.com/myint/autoflake - rev: v1.6.0 + rev: v2.3.1 hooks: - id: autoflake name: Autoflake @@ -27,13 +27,15 @@ repos: - --ignore-pass-after-docstring - repo: https://github.com/psf/black - rev: 22.8.0 + rev: 24.8.0 # The following version (`24.10.0`) dropped support for Python 3.8. hooks: - id: black name: Black - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.6.0 + # The following version (pre-commit-hooks 5.0.0) requires pre-commit 3.2.0 + # which does not support Python 3.8 (dropped in pre-commit 3.0.0). hooks: - id: trailing-whitespace # Exclude files from trailing-whitespace checks until we get around fixing them. diff --git a/deprecated/HardwareObjects/Camera.py b/deprecated/HardwareObjects/Camera.py index d062b6e277..25f1a9c4dc 100644 --- a/deprecated/HardwareObjects/Camera.py +++ b/deprecated/HardwareObjects/Camera.py @@ -15,6 +15,7 @@ --> """ + from mxcubecore import BaseHardwareObjects from mxcubecore import CommandContainer import gevent diff --git a/deprecated/HardwareObjects/SpecMotorWSpecPositions.py b/deprecated/HardwareObjects/SpecMotorWSpecPositions.py index 3614fbc868..763f510634 100644 --- a/deprecated/HardwareObjects/SpecMotorWSpecPositions.py +++ b/deprecated/HardwareObjects/SpecMotorWSpecPositions.py @@ -11,6 +11,7 @@ tolerance allowed between real motor position and defined position --> """ + import logging from mxcubecore.HardwareObjects import SpecMotor diff --git a/deprecated/HardwareObjects/mockup/CameraMockup.py b/deprecated/HardwareObjects/mockup/CameraMockup.py index fbeb17ae57..8ca6852157 100644 --- a/deprecated/HardwareObjects/mockup/CameraMockup.py +++ b/deprecated/HardwareObjects/mockup/CameraMockup.py @@ -1,5 +1,6 @@ """Class for cameras connected to framegrabbers run by Taco Device Servers """ + from mxcubecore import BaseHardwareObjects import logging import os diff --git a/deprecated/HardwareObjects/mockup/VideoMockup.py b/deprecated/HardwareObjects/mockup/VideoMockup.py index b1a3e57230..54fdb399cc 100755 --- a/deprecated/HardwareObjects/mockup/VideoMockup.py +++ b/deprecated/HardwareObjects/mockup/VideoMockup.py @@ -1,6 +1,7 @@ """ Descript. : """ + import os import time import gevent diff --git a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py index 19bf3d143f..10aef0434e 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py @@ -1,6 +1,7 @@ """ Class for reading images from Falcon camera OAV """ + from mxcubecore import HardwareRepository as HWR from mxcubecore import BaseHardwareObjects diff --git a/mxcubecore/HardwareObjects/BlissActuator.py b/mxcubecore/HardwareObjects/BlissActuator.py index 0110abb54b..fcaf3a2d5d 100644 --- a/mxcubecore/HardwareObjects/BlissActuator.py +++ b/mxcubecore/HardwareObjects/BlissActuator.py @@ -7,6 +7,7 @@ """ + import logging from warnings import warn diff --git a/mxcubecore/HardwareObjects/Camera.py b/mxcubecore/HardwareObjects/Camera.py index 075e965dde..34e9ce03ef 100644 --- a/mxcubecore/HardwareObjects/Camera.py +++ b/mxcubecore/HardwareObjects/Camera.py @@ -15,6 +15,7 @@ --> """ + from mxcubecore import BaseHardwareObjects from mxcubecore import CommandContainer import gevent diff --git a/mxcubecore/HardwareObjects/CatsMaint.py b/mxcubecore/HardwareObjects/CatsMaint.py index 9d1fdc3644..fe5c19d8a3 100644 --- a/mxcubecore/HardwareObjects/CatsMaint.py +++ b/mxcubecore/HardwareObjects/CatsMaint.py @@ -11,6 +11,7 @@ Vicente Rey - add support for ISARA Model """ + import logging from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/DESY/P11BeamStop.py b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py index 0e73c67084..24e4c9ee13 100644 --- a/mxcubecore/HardwareObjects/DESY/P11BeamStop.py +++ b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py @@ -74,9 +74,9 @@ def load_deltas(self): # If a delta is not specified, fallback to a default delta value self.deltas = { - "bstopx": float(delta_bstopx) - if delta_bstopx is not None - else self.default_delta, + "bstopx": ( + float(delta_bstopx) if delta_bstopx is not None else self.default_delta + ), } # Log the deltas for each motor diff --git a/mxcubecore/HardwareObjects/DESY/P11Collimator.py b/mxcubecore/HardwareObjects/DESY/P11Collimator.py index 7bc0a676b3..7a7bcf4460 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collimator.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collimator.py @@ -79,12 +79,12 @@ def load_deltas(self): # If a delta is not specified, fallback to a default delta value self.deltas = { - "collimatory": float(delta_y) - if delta_y is not None - else self.default_delta, - "collimatorz": float(delta_z) - if delta_z is not None - else self.default_delta, + "collimatory": ( + float(delta_y) if delta_y is not None else self.default_delta + ), + "collimatorz": ( + float(delta_z) if delta_z is not None else self.default_delta + ), } # Log the deltas for each motor diff --git a/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py b/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py index af9c0a1f83..f4320964d5 100644 --- a/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py @@ -28,9 +28,9 @@ def choose_attenuation(self): "Cannot find appropriate attenuation" ) raise RuntimeError("Cannot find appropriate attenuation") - self.energy_scan_parameters[ - "transmissionFactor" - ] = self.transmission.get_value() + self.energy_scan_parameters["transmissionFactor"] = ( + self.transmission.get_value() + ) @task def execute_energy_scan(self, energy_scan_parameters): diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py b/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py index 12d388bd93..6c687f7e6b 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py @@ -1,5 +1,6 @@ """ESRF SC3 Sample Changer Hardware Object """ + from mxcubecore.TaskUtils import task import SC3 import ESRF.ESRFSC3 as ESRFSC3 diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py b/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py index fc2bd37f52..424639fc65 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py @@ -1,5 +1,6 @@ """ESRF SC3 Sample Changer Hardware Object """ + import functools import logging from mxcubecore.TaskUtils import task, cleanup, error_cleanup diff --git a/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py index b31ec1036a..26218e13bb 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py @@ -27,9 +27,9 @@ def set_mca_roi(self, eroi_min, eroi_max): @task def choose_attenuation(self): self.execute_command("chooseAttenuation") - self.energy_scan_parameters[ - "transmissionFactor" - ] = self.transmission.get_value() + self.energy_scan_parameters["transmissionFactor"] = ( + self.transmission.get_value() + ) @task def execute_energy_scan(self, energy_scan_parameters): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py index c04d788a7a..9ee711a236 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py @@ -45,9 +45,9 @@ def choose_attenuation(self): eroi_max = self.energy_scan_parameters["eroi_max"] self.ctrl.detcover.set_in() self.ctrl.find_max_attenuation(ctime=2, roi=[eroi_min, eroi_max]) - self.energy_scan_parameters[ - "transmissionFactor" - ] = self.transmission.get_value() + self.energy_scan_parameters["transmissionFactor"] = ( + self.transmission.get_value() + ) @task def execute_energy_scan(self, energy_scan_parameters): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py b/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py index b4725cd016..b956624aba 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py @@ -409,9 +409,9 @@ def _findAttenuation(self, ct): print(ic) if ic > min_cnt: self.ctrl_hwobj.diffractometer.msclose() - self.spectrumInfo[ - "beamTransmission" - ] = HWR.beamline.transmission.get_value() + self.spectrumInfo["beamTransmission"] = ( + HWR.beamline.transmission.get_value() + ) logging.getLogger("user_level_log").info( "Transmission used for spectra: %g" % self.spectrumInfo["beamTransmission"] diff --git a/mxcubecore/HardwareObjects/ESRF/ID30SC3.py b/mxcubecore/HardwareObjects/ESRF/ID30SC3.py index 96abc49d43..c88ccd7110 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30SC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30SC3.py @@ -1,5 +1,6 @@ """ESRF SC3 Sample Changer Hardware Object """ + from mxcubecore.TaskUtils import task import SC3 import ESRFSC3 diff --git a/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py b/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py index 6e1ce9a2f8..3626b0ec00 100644 --- a/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py +++ b/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py @@ -229,7 +229,7 @@ def _get_simcal_input(self, data_collect_parameters, crystal_data): template = template.replace(ss0, "?" * int(ss0[1:-1])) name_template = os.path.join( text_type(data_collect_parameters["fileinfo"]["directory"]), - template + template, # data_collect_parameters['fileinfo']['template'] ) # We still use the normal name template for compressed data diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py index fc12ec4e57..793568a005 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py @@ -289,9 +289,9 @@ def start_workflow(self, workflow_queue, workflow_model_obj): # Set the workflow root subdirectory parameter from the base image directory image_root = os.path.abspath(HWR.beamline.session.get_base_image_directory()) if strategy_settings["wftype"] != "transcal": - workflow_options[ - "appdir" - ] = HWR.beamline.session.get_base_process_directory() + workflow_options["appdir"] = ( + HWR.beamline.session.get_base_process_directory() + ) rootsubdir = path_template.directory[len(image_root) :] if rootsubdir.startswith(os.path.sep): rootsubdir = rootsubdir[1:] @@ -1065,9 +1065,9 @@ def _CollectionDone_to_java(self, collectionDone): ) scanIdMap = {} for item in collectionDone.scanIdMap.items(): - scanIdMap[ - jvm.java.util.UUID.fromString(conversion.text_type(item[0])) - ] = jvm.java.util.UUID.fromString(conversion.text_type(item[1])) + scanIdMap[jvm.java.util.UUID.fromString(conversion.text_type(item[0]))] = ( + jvm.java.util.UUID.fromString(conversion.text_type(item[1])) + ) return jvm.astra.messagebus.messages.information.CollectionDoneImpl( proposalId, collectionDone.status, diff --git a/mxcubecore/HardwareObjects/GrobSampleChanger.py b/mxcubecore/HardwareObjects/GrobSampleChanger.py index d91df18876..6938468f84 100644 --- a/mxcubecore/HardwareObjects/GrobSampleChanger.py +++ b/mxcubecore/HardwareObjects/GrobSampleChanger.py @@ -1,5 +1,6 @@ """Sample Changer Hardware Object """ + import logging from mxcubecore.BaseHardwareObjects import HardwareObject import gevent diff --git a/mxcubecore/HardwareObjects/ISPyBRestClient.py b/mxcubecore/HardwareObjects/ISPyBRestClient.py index 1ea47ecb29..7b2bb43075 100644 --- a/mxcubecore/HardwareObjects/ISPyBRestClient.py +++ b/mxcubecore/HardwareObjects/ISPyBRestClient.py @@ -1,6 +1,7 @@ """ A client for ISPyB Webservices. """ + import logging import json import cgi diff --git a/mxcubecore/HardwareObjects/LimaEigerDetector.py b/mxcubecore/HardwareObjects/LimaEigerDetector.py index 189e0d53f8..442e175255 100644 --- a/mxcubecore/HardwareObjects/LimaEigerDetector.py +++ b/mxcubecore/HardwareObjects/LimaEigerDetector.py @@ -1,6 +1,7 @@ """LimaEigerDetector Class Lima Tango Device Server implementation of the Dectris Eiger2 Detector. """ + import gevent import time import os diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py index e65d9ff30e..4c410fbada 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py @@ -1,6 +1,7 @@ """ A client for Biomax Kafka services. """ + import logging import time import json diff --git a/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py b/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py index 2f8b9ea7eb..c6cdbed28a 100644 --- a/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py +++ b/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py @@ -3,6 +3,7 @@ Adapting from original Session.py to adapt the names of data directories """ + import os import time import socket diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 3ae5e7fe92..1b8a553802 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -993,9 +993,9 @@ def get_positions(self): "sampx": float(self.sampleXMotor.get_value()), "sampy": float(self.sampleYMotor.get_value()), "kappa": float(self.kappaMotor.get_value()) if self.kappaMotor else None, - "kappa_phi": float(self.kappaPhiMotor.get_value()) - if self.kappaPhiMotor - else None, + "kappa_phi": ( + float(self.kappaPhiMotor.get_value()) if self.kappaPhiMotor else None + ), "zoom": float(self.zoomMotor.get_value()), } diff --git a/mxcubecore/HardwareObjects/MotorWPositions.py b/mxcubecore/HardwareObjects/MotorWPositions.py index db5bf0ce28..6a0bc3f010 100644 --- a/mxcubecore/HardwareObjects/MotorWPositions.py +++ b/mxcubecore/HardwareObjects/MotorWPositions.py @@ -97,7 +97,7 @@ def get_predefined_positions_list(self): def get_current_position_name(self, pos=None): if pos is None: pos = self.motor.get_value() - for (position_name, position) in self.predefined_positions.items(): + for position_name, position in self.predefined_positions.items(): if self.delta >= abs(pos - position): return position_name return "" diff --git a/mxcubecore/HardwareObjects/PyISPyBClient.py b/mxcubecore/HardwareObjects/PyISPyBClient.py index 954f231d11..648e71730b 100644 --- a/mxcubecore/HardwareObjects/PyISPyBClient.py +++ b/mxcubecore/HardwareObjects/PyISPyBClient.py @@ -1,6 +1,7 @@ """ A client for PyISPyB Webservices. """ + import os import json import logging diff --git a/mxcubecore/HardwareObjects/QtGraphicsManager.py b/mxcubecore/HardwareObjects/QtGraphicsManager.py index 3737fe312a..7c71c06779 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsManager.py +++ b/mxcubecore/HardwareObjects/QtGraphicsManager.py @@ -976,9 +976,9 @@ def mouse_released(self, pos_x, pos_y): # self._shapes.add_shape(self.graphics_grid_draw_item.get_display_name(), # self.graphics_grid_draw_item # ) - self.shape_dict[ - self.graphics_grid_draw_item.get_display_name() - ] = self.graphics_grid_draw_item + self.shape_dict[self.graphics_grid_draw_item.get_display_name()] = ( + self.graphics_grid_draw_item + ) elif self.in_beam_define_state: self.stop_beam_define() elif self.in_select_items_state: diff --git a/mxcubecore/HardwareObjects/QueueManager.py b/mxcubecore/HardwareObjects/QueueManager.py index 368b5384b4..bf4dc51dcc 100644 --- a/mxcubecore/HardwareObjects/QueueManager.py +++ b/mxcubecore/HardwareObjects/QueueManager.py @@ -7,6 +7,7 @@ container of the queue, note the inheritance from QueueEntryContainer. See the documentation for the queue_entry module for more information. """ + import logging import gevent import traceback diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py index 1617bc6a43..e1165a6770 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py @@ -10,6 +10,7 @@ This has been modified to follow the AbstractEnergyScan method """ + import logging import os import time diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py index 4ada5bb2cb..39e9749cce 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py @@ -4,6 +4,7 @@ Functionality in addition to sample-transfer functionality: power control, lid control, error-recovery commands, ... """ + import logging from mxcubecore.TaskUtils import task from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/Session.py b/mxcubecore/HardwareObjects/Session.py index dd80bc2d6f..4dec423be4 100644 --- a/mxcubecore/HardwareObjects/Session.py +++ b/mxcubecore/HardwareObjects/Session.py @@ -4,6 +4,7 @@ Contains information regarding the current session and methods to access and manipulate this information. """ + import os import time import socket diff --git a/mxcubecore/HardwareObjects/SpecMotorWSpecPositions.py b/mxcubecore/HardwareObjects/SpecMotorWSpecPositions.py index 3614fbc868..763f510634 100644 --- a/mxcubecore/HardwareObjects/SpecMotorWSpecPositions.py +++ b/mxcubecore/HardwareObjects/SpecMotorWSpecPositions.py @@ -11,6 +11,7 @@ tolerance allowed between real motor position and defined position --> """ + import logging from mxcubecore.HardwareObjects import SpecMotor diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 15ee24c988..439212cf68 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -12,6 +12,7 @@ If video mode is not specified, BAYER_RG16 is used by default. """ + import logging import time import struct diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py index 9aafc29084..583c88196c 100644 --- a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py @@ -12,6 +12,7 @@ If video mode is not specified, BAYER_RG16 is used by default. """ + import logging import v4l2 import gipc diff --git a/mxcubecore/HardwareObjects/VaporyVideo.py b/mxcubecore/HardwareObjects/VaporyVideo.py index f9787221bf..d09445d4ff 100755 --- a/mxcubecore/HardwareObjects/VaporyVideo.py +++ b/mxcubecore/HardwareObjects/VaporyVideo.py @@ -19,7 +19,6 @@ [Included Hardware Objects] """ - import time import gevent import vapory diff --git a/mxcubecore/HardwareObjects/XRFSpectrum.py b/mxcubecore/HardwareObjects/XRFSpectrum.py index de862b8fb5..046a126afb 100644 --- a/mxcubecore/HardwareObjects/XRFSpectrum.py +++ b/mxcubecore/HardwareObjects/XRFSpectrum.py @@ -226,9 +226,9 @@ def spectrumCommandFinished(self, result): mcaData = self.mca_hwobj.read_data(save_data=True) mcaCalib = self.mca_hwobj.get_calibration() mcaConfig = {} - self.spectrumInfo[ - "beamTransmission" - ] = HWR.beamline.transmission.get_value() + self.spectrumInfo["beamTransmission"] = ( + HWR.beamline.transmission.get_value() + ) self.spectrumInfo["energy"] = HWR.beamline.energy.get_value() if HWR.beamline.flux: self.spectrumInfo["flux"] = HWR.beamline.flux.get_value() @@ -404,9 +404,9 @@ def _findAttenuation(self, ct): print(ic) if ic > min_cnt: self.ctrl_hwobj.diffractometer.msclose() - self.spectrumInfo[ - "beamTransmission" - ] = HWR.beamline.transmission.get_value() + self.spectrumInfo["beamTransmission"] = ( + HWR.beamline.transmission.get_value() + ) logging.getLogger("user_level_log").info( "Transmission used for spectra: %g" % self.spectrumInfo["beamTransmission"] diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index ce2ac41c30..378fd12970 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -445,9 +445,9 @@ def do_collect(self, owner, data_collect_parameters): logging.getLogger("user_level_log").info( "Getting synchrotron filling mode" ) - data_collect_parameters[ - "synchrotronMode" - ] = self.get_machine_fill_mode() + data_collect_parameters["synchrotronMode"] = ( + self.get_machine_fill_mode() + ) data_collect_parameters["status"] = "failed" logging.getLogger("user_level_log").info("Storing data collection in LIMS") @@ -487,9 +487,9 @@ def do_collect(self, owner, data_collect_parameters): if HWR.beamline.sample_changer is not None: try: - data_collect_parameters[ - "actualSampleBarcode" - ] = HWR.beamline.sample_changer.get_loaded_sample().get_id() + data_collect_parameters["actualSampleBarcode"] = ( + HWR.beamline.sample_changer.get_loaded_sample().get_id() + ) data_collect_parameters["actualContainerBarcode"] = ( HWR.beamline.sample_changer.get_loaded_sample() .get_container() @@ -573,9 +573,9 @@ def do_collect(self, owner, data_collect_parameters): if HWR.beamline.lims: try: if self.current_lims_sample: - self.current_lims_sample[ - "lastKnownCentringPosition" - ] = positions_str + self.current_lims_sample["lastKnownCentringPosition"] = ( + positions_str + ) logging.getLogger("user_level_log").info( "Updating sample information in LIMS" ) @@ -624,9 +624,9 @@ def do_collect(self, owner, data_collect_parameters): except Exception: pass - data_collect_parameters[ - "xtalSnapshotFullPath%i" % snapshot_i - ] = full_snapshot + data_collect_parameters["xtalSnapshotFullPath%i" % snapshot_i] = ( + full_snapshot + ) snapshots.append(full_snapshot) snapshot_i += 1 @@ -642,12 +642,12 @@ def do_collect(self, owner, data_collect_parameters): "Updating data collection in LIMS" ) if "kappa" in data_collect_parameters["actualCenteringPosition"]: - data_collect_parameters["oscillation_sequence"][0][ - "kappaStart" - ] = current_diffractometer_position["kappa"] - data_collect_parameters["oscillation_sequence"][0][ - "phiStart" - ] = current_diffractometer_position["kappa_phi"] + data_collect_parameters["oscillation_sequence"][0]["kappaStart"] = ( + current_diffractometer_position["kappa"] + ) + data_collect_parameters["oscillation_sequence"][0]["phiStart"] = ( + current_diffractometer_position["kappa_phi"] + ) HWR.beamline.lims.update_data_collection(data_collect_parameters) except Exception: logging.getLogger("HWR").exception( @@ -808,18 +808,18 @@ def do_collect(self, owner, data_collect_parameters): data_collect_parameters["flux_end"] = data_collect_parameters[ "flux" ] - data_collect_parameters[ - "wavelength" - ] = HWR.beamline.energy.get_wavelength() - data_collect_parameters[ - "detectorDistance" - ] = HWR.beamline.detector.distance.get_value() - data_collect_parameters[ - "resolution" - ] = HWR.beamline.resolution.get_value() - data_collect_parameters[ - "transmission" - ] = HWR.beamline.transmission.get_value() + data_collect_parameters["wavelength"] = ( + HWR.beamline.energy.get_wavelength() + ) + data_collect_parameters["detectorDistance"] = ( + HWR.beamline.detector.distance.get_value() + ) + data_collect_parameters["resolution"] = ( + HWR.beamline.resolution.get_value() + ) + data_collect_parameters["transmission"] = ( + HWR.beamline.transmission.get_value() + ) beam_centre_x, beam_centre_y = self.get_beam_centre() data_collect_parameters["xBeam"] = beam_centre_x data_collect_parameters["yBeam"] = beam_centre_y @@ -831,9 +831,9 @@ def do_collect(self, owner, data_collect_parameters): if key in und: data_collect_parameters["undulatorGap%d" % (i)] = und[key] i += 1 - data_collect_parameters[ - "resolutionAtCorner" - ] = self.get_resolution_at_corner() + data_collect_parameters["resolutionAtCorner"] = ( + self.get_resolution_at_corner() + ) beam_size_x, beam_size_y = self.get_beam_size() data_collect_parameters["beamSizeAtSampleX"] = beam_size_x data_collect_parameters["beamSizeAtSampleY"] = beam_size_y @@ -971,9 +971,9 @@ def do_collect(self, owner, data_collect_parameters): if archive_directory: lims_image["jpegFileFullPath"] = jpeg_full_path - lims_image[ - "jpegThumbnailFileFullPath" - ] = jpeg_thumbnail_full_path + lims_image["jpegThumbnailFileFullPath"] = ( + jpeg_thumbnail_full_path + ) try: HWR.beamline.lims.store_image(lims_image) @@ -1103,9 +1103,9 @@ def loop(self, owner, data_collect_parameters_list): logging.getLogger("user_level_log").info( "Data collection failed %s" % exc_value ) - data_collect_parameters[ - "status" - ] = "Data collection failed!" # Message to be stored in LIMS + data_collect_parameters["status"] = ( + "Data collection failed!" # Message to be stored in LIMS + ) failed_msg = "Data collection failed!\n%s" % exc_value self.emit( "collectOscillationFailed", diff --git a/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py b/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py index 595368a034..ce061784c1 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py @@ -224,9 +224,9 @@ def prepare_processing(self): if not acq_params.num_images_per_trigger: self.params_dict["num_images_per_trigger"] = 1 else: - self.params_dict[ - "num_images_per_trigger" - ] = acq_params.num_images_per_trigger + self.params_dict["num_images_per_trigger"] = ( + acq_params.num_images_per_trigger + ) self.params_dict["status"] = "Started" self.params_dict["title"] = "%s_%d_#####.cbf (%d - %d)" % ( @@ -770,13 +770,13 @@ def align_processing_results(self, start_index, end_index): center_x = ndimage.measurements.center_of_mass( self.results_aligned["score"] )[0] - self.results_aligned[ - "center_mass" - ] = HWR.beamline.diffractometer.get_point_from_line( - centred_positions[0], - centred_positions[1], - center_x, - self.params_dict["images_num"], + self.results_aligned["center_mass"] = ( + HWR.beamline.diffractometer.get_point_from_line( + centred_positions[0], + centred_positions[1], + center_x, + self.params_dict["images_num"], + ) ) else: self.results_aligned["center_mass"] = centred_positions[0] diff --git a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py index 0ceab69ad9..b8c8d99304 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py @@ -204,9 +204,9 @@ def spectrum_command_finished(self): """Actions to do if spectrum acquired.""" self.spectrum_info_dict["endTime"] = time.strftime("%Y-%m-%d %H:%M:%S") if HWR.beamline.transmission: - self.spectrum_info_dict[ - "beamTransmission" - ] = HWR.beamline.transmission.get_value() + self.spectrum_info_dict["beamTransmission"] = ( + HWR.beamline.transmission.get_value() + ) if HWR.beamline.energy: self.spectrum_info_dict["energy"] = HWR.beamline.energy.get_value() if HWR.beamline.flux: diff --git a/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py b/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py index df613409c2..f85b50439b 100644 --- a/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py +++ b/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py @@ -1,6 +1,7 @@ """ CATS maintenance mockup. """ + import logging from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py index 2f57f60135..fadbbd6e87 100644 --- a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py @@ -198,9 +198,9 @@ def execute_energy_scan(self, energy_scan_parameters): self.energy_scan_parameters["exposureTime"] = 0.01 print(self.cpos) if HWR.beamline.transmission is not None: - self.energy_scan_parameters[ - "transmissionFactor" - ] = HWR.beamline.transmission.get_value() + self.energy_scan_parameters["transmissionFactor"] = ( + HWR.beamline.transmission.get_value() + ) else: self.energy_scan_parameters["transmissionFactor"] = None size_hor = None diff --git a/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py b/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py index 16d93649ce..72bb047533 100644 --- a/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py @@ -1,6 +1,7 @@ """ A client for ISPyB Webservices. """ + from __future__ import print_function import logging from datetime import datetime diff --git a/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py b/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py index 3f019fc053..152dd89afa 100644 --- a/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py @@ -31,6 +31,7 @@ values['lifetime'] values['topup_remaining'] """ + import time import gevent diff --git a/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py b/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py index 5e6c27274c..2333d6bdcf 100644 --- a/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py @@ -8,6 +8,7 @@ EL6": 6} """ + from enum import Enum import gevent diff --git a/mxcubecore/HardwareObjects/sample_centring.py b/mxcubecore/HardwareObjects/sample_centring.py index 9610814deb..e900367170 100644 --- a/mxcubecore/HardwareObjects/sample_centring.py +++ b/mxcubecore/HardwareObjects/sample_centring.py @@ -356,12 +356,16 @@ def centre_plate( { sampx.motor: float(sampx.get_value() + sampx.direction * dx), sampy.motor: float(sampy.get_value() + sampy.direction * dy), - phiz.motor: float(phiz.get_value() + phiz.direction * d_vertical[0, 0]) - if phiz.__dict__.get("reference_position") is None - else phiz.reference_position, - phiy.motor: float(phiy.get_value() + phiy.direction * d_horizontal[0, 0]) - if phiy.__dict__.get("reference_position") is None - else phiy.reference_position, + phiz.motor: ( + float(phiz.get_value() + phiz.direction * d_vertical[0, 0]) + if phiz.__dict__.get("reference_position") is None + else phiz.reference_position + ), + phiy.motor: ( + float(phiy.get_value() + phiy.direction * d_horizontal[0, 0]) + if phiy.__dict__.get("reference_position") is None + else phiy.reference_position + ), } ) @@ -477,12 +481,16 @@ def center( { sampx.motor: float(sampx.get_value() + sampx.direction * dx), sampy.motor: float(sampy.get_value() + sampy.direction * dy), - phiz.motor: float(phiz.get_value() + phiz.direction * d_vertical[0, 0]) - if phiz.__dict__.get("reference_position") is None - else phiz.reference_position, - phiy.motor: float(phiy.get_value() + phiy.direction * d_horizontal[0, 0]) - if phiy.__dict__.get("reference_position") is None - else phiy.reference_position, + phiz.motor: ( + float(phiz.get_value() + phiz.direction * d_vertical[0, 0]) + if phiz.__dict__.get("reference_position") is None + else phiz.reference_position + ), + phiy.motor: ( + float(phiy.get_value() + phiy.direction * d_horizontal[0, 0]) + if phiy.__dict__.get("reference_position") is None + else phiy.reference_position + ), } ) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 359c6e283a..fac0562481 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -793,9 +793,9 @@ def get_online_processing_results(self): return self.online_processing_results def set_snapshot(self, snapshot): - self.acquisitions[ - 0 - ].acquisition_parameters.centred_position.snapshot_image = snapshot + self.acquisitions[0].acquisition_parameters.centred_position.snapshot_image = ( + snapshot + ) def add_processing_msg(self, time, method, status, msg): self.processing_msg_list.append((time, method, status, msg)) diff --git a/mxcubecore/queue_entry/advanced_connector.py b/mxcubecore/queue_entry/advanced_connector.py index 15255b7f58..6c8bdeb7bf 100644 --- a/mxcubecore/queue_entry/advanced_connector.py +++ b/mxcubecore/queue_entry/advanced_connector.py @@ -68,9 +68,9 @@ def execute(self): cpos_one, cpos_two, ) = HWR.beamline.sample_view.create_auto_line() - helical_model.acquisitions[ - 0 - ].acquisition_parameters.osc_start = cpos_one.phi + helical_model.acquisitions[0].acquisition_parameters.osc_start = ( + cpos_one.phi + ) helical_model.acquisitions[ 0 ].acquisition_parameters.centred_position = cpos_one diff --git a/mxcubecore/queue_entry/base_queue_entry.py b/mxcubecore/queue_entry/base_queue_entry.py index cf57e98f62..e2d2e1f720 100644 --- a/mxcubecore/queue_entry/base_queue_entry.py +++ b/mxcubecore/queue_entry/base_queue_entry.py @@ -565,9 +565,9 @@ def execute_interleaved(self, ref_num_images, interleave_num_images): acq_first_image, acq_first_image + item["collect_num_images"] - 1, ) - self.interleave_items[item["collect_index"]][ - "queue_entry" - ].in_queue = item_index < (len(self.interleave_sw_list) - 1) + self.interleave_items[item["collect_index"]]["queue_entry"].in_queue = ( + item_index < (len(self.interleave_sw_list) - 1) + ) msg = "Executing %s collection (subwedge %d:%d, " % ( method_type, From 4ee04294f92a6abdf892765d4aff3eeab6671f15 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 18 Oct 2024 14:31:02 +0000 Subject: [PATCH 091/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4131f944b9..b451ae9f61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.165.0" +version = "1.166.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From bf7a155bb97aad9f16b54e0ab1416e1922fb3db5 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Fri, 18 Oct 2024 17:19:39 +0200 Subject: [PATCH 092/172] remove old unused multicollect files --- .../HardwareObjects/ESRF/ESRFMultiCollect.py | 3 - .../HardwareObjects/ESRF/ID231MultiCollect.py | 78 ------ .../HardwareObjects/ESRF/ID232MultiCollect.py | 201 --------------- .../HardwareObjects/ESRF/ID29MultiCollect.py | 191 -------------- .../ESRF/ID30A1MultiCollect.py | 145 ----------- .../ESRF/ID30A3MultiCollect.py | 240 ------------------ 6 files changed, 858 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID231MultiCollect.py delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID232MultiCollect.py delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID29MultiCollect.py delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID30A1MultiCollect.py delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID30A3MultiCollect.py diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py index 990210d619..382e2740e1 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py @@ -8,9 +8,6 @@ from mxcubecore.utils.conversion import string_types from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects.ESRF.ESRFMetadataManagerClient import ( - MXCuBEMetadataClient, -) try: from httplib import HTTPConnection diff --git a/mxcubecore/HardwareObjects/ESRF/ID231MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ID231MultiCollect.py deleted file mode 100644 index 71a98a9746..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID231MultiCollect.py +++ /dev/null @@ -1,78 +0,0 @@ -from .ESRFMultiCollect import ESRFMultiCollect, task, time -import shutil -import logging -import os - - -class ID231MultiCollect(ESRFMultiCollect): - def __init__(self, name): - ESRFMultiCollect.__init__(self, name) - - @task - def data_collection_hook(self, data_collect_parameters): - ESRFMultiCollect.data_collection_hook(self, data_collect_parameters) - - oscillation_parameters = data_collect_parameters["oscillation_sequence"][0] - if data_collect_parameters.get("nb_sum_images"): - if ( - oscillation_parameters["number_of_images"] - % data_collect_parameters.get("nb_sum_images", 1) - != 0 - ): - raise RuntimeError("invalid number of images to sum") - - data_collect_parameters["dark"] = 0 - # are we doing shutterless ? - shutterless = data_collect_parameters.get("shutterless") - self._detector.shutterless = True if shutterless else False - - self.get_channel_object("parameters").set_value(data_collect_parameters) - self.execute_command("build_collect_seq") - # self.execute_command("local_set_experiment_type") - self.execute_command("prepare_beamline") - self.execute_command("musstPX_loadprog") - - def get_beam_size(self): - # should be moved to ESRFMultiCollect - # (at the moment, ESRFMultiCollect is still using spec) - return self.bl_control.beam_info.get_beam_size() - - def get_beam_shape(self): - # should be moved to ESRFMultiCollect - # (at the moment, ESRFMultiCollect is still using spec) - return self.bl_control.beam_info.get_beam_shape() - - def get_resolution_at_corner(self): - # should be moved to ESRFMultiCollect - # (at the moment, ESRFMultiCollect is still using spec) - return self.bl_control.resolution.get_value_at_corner() - - def get_beam_centre(self): - # should be moved to ESRFMultiCollect - # (at the moment, ESRFMultiCollect is still using spec) - return self.bl_control.resolution.get_beam_centre() - - def trigger_auto_processing(self, process_event, *args, **kwargs): - if process_event in ("before", "after"): - return ESRFMultiCollect.trigger_auto_processing( - self, process_event, *args, **kwargs - ) - - @task - def write_input_files(self, datacollection_id): - # copy *geo_corr.cbf* files to process directory - try: - process_dir = os.path.join(self.xds_directory, "..") - raw_process_dir = os.path.join(self.raw_data_input_file_dir, "..") - for dir in (process_dir, raw_process_dir): - for filename in ("x_geo_corr.cbf.bz2", "y_geo_corr.cbf.bz2"): - dest = os.path.join(dir, filename) - if os.path.exists(dest): - continue - shutil.copyfile( - os.path.join("/data/id23eh1/inhouse/opid231", filename), dest - ) - except Exception: - logging.exception("Exception happened while copying geo_corr files") - - return ESRFMultiCollect.write_input_files(self, datacollection_id) diff --git a/mxcubecore/HardwareObjects/ESRF/ID232MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ID232MultiCollect.py deleted file mode 100644 index f79e59fa6e..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID232MultiCollect.py +++ /dev/null @@ -1,201 +0,0 @@ -import gevent -import shutil -import logging -import os - -from mxcubecore.TaskUtils import task -from .ESRFMultiCollect import ESRFMultiCollect, PixelDetector, TunableEnergy -from mxcubecore.HardwareObjects.LimaPilatusDetector import LimaPilatusDetector - - -class ID232MultiCollect(ESRFMultiCollect): - def __init__(self, name): - ESRFMultiCollect.__init__(self, name, TunableEnergy()) - - @task - def data_collection_hook(self, data_collect_parameters): - ESRFMultiCollect.data_collection_hook(self, data_collect_parameters) - self._detector.shutterless = data_collect_parameters["shutterless"] - - def stop_oscillation(self): - self.get_object_by_role("diffractometer").abort() - self.get_object_by_role("diffractometer")._wait_ready(20) - - def close_fast_shutter(self): - state = self.get_object_by_role("fastshut").get_actuator_state(read=True) - if state != "out": - self.close_fast_shutter() - - @task - def get_beam_size(self): - return self.bl_control.beam_info.get_beam_size() - - @task - def get_slit_gaps(self): - return (None, None) - - @task - def get_beam_shape(self): - return self.bl_control.beam_info.get_beam_shape() - - def get_resolution_at_corner(self): - return self.bl_control.resolution.get_value_at_corner() - - def ready(*motors): - return not any([m.motorIsMoving() for m in motors]) - - @task - def move_motors(self, motors_to_move_dict): - # We do not wnta to modify the input dict - motor_positions_copy = motors_to_move_dict.copy() - diffr = self.bl_control.diffractometer - try: - self.get_object_by_role("controller").detcover.set_out() - except Exception: - pass - for tag in ("kappa", "kappa_phi"): - if tag in motor_positions_copy: - del motor_positions_copy[tag] - diffr.move_sync_motors(motor_positions_copy, wait=True, timeout=200) - - @task - def take_crystal_snapshots(self, number_of_snapshots): - diffr = self.get_object_by_role("diffractometer") - if self.bl_control.diffractometer.in_plate_mode(): - if number_of_snapshots > 0: - number_of_snapshots = 1 - # diffr.moveToPhase("Centring", wait=True, timeout=200) - if number_of_snapshots: - # put the back light in - diffr.get_deviceby_role("BackLightSwitch").actuatorIn() - self.bl_control.diffractometer.take_snapshots( - number_of_snapshots, wait=True - ) - diffr._wait_ready(20) - - @task - def do_prepare_oscillation(self, *args, **kwargs): - diffr = self.get_object_by_role("diffractometer") - # send again the command as MD2 software only handles one - # centered position!! - # has to be where the motors are and before changing the phase - diffr.get_command_object("save_centring_positions")() - # move to DataCollection phase - if diffr.getPhase() != "DataCollection": - logging.getLogger("user_level_log").info("Moving MD2 to Data Collection") - diffr.moveToPhase("DataCollection", wait=True, timeout=200) - # switch on the front light - diffr.get_object_by_role("FrontLight").set_value(2) - # take the back light out - diffr.get_object_by_role("BackLightSwitch").actuatorOut() - - @task - def oscil(self, start, end, exptime, npass): - diffr = self.get_object_by_role("diffractometer") - if self.helical: - diffr.oscilScan4d(start, end, exptime, self.helical_pos, wait=True) - elif self.mesh: - diffr.oscilScanMesh( - start, - end, - exptime, - self._detector.get_deadtime(), - self.mesh_num_lines, - self.mesh_total_nb_frames, - self.mesh_center, - self.mesh_range, - wait=True, - ) - else: - diffr.oscilScan(start, end, exptime, wait=True) - - def prepare_acquisition( - self, take_dark, start, osc_range, exptime, npass, number_of_images, comment="" - ): - energy = self._tunable_bl.get_value() - diffr = self.get_object_by_role("diffractometer") - diffr.setNbImages(number_of_images) - if self.mesh: - return self._detector.prepare_acquisition( - take_dark, - start, - osc_range, - exptime, - npass, - number_of_images, - comment, - energy, - trigger_mode="EXTERNAL_GATE", - ) - else: - return self._detector.prepare_acquisition( - take_dark, - start, - osc_range, - exptime, - npass, - number_of_images, - comment, - energy, - trigger_mode="EXTERNAL_TRIGGER", - ) - - def open_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorIn() - - def close_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorOut() - - def set_helical(self, helical_on): - self.helical = helical_on - - def set_helical_pos(self, helical_oscil_pos): - self.helical_pos = helical_oscil_pos - - # specifies the next scan will be a mesh scan - def set_mesh(self, mesh_on): - self.mesh = mesh_on - - def set_mesh_scan_parameters( - self, num_lines, total_nb_frames, mesh_center_param, mesh_range_param - ): - """ - sets the mesh scan parameters : - - vertcal range - - horizontal range - - nb lines - - nb frames per line - - invert direction (boolean) # NOT YET DONE - """ - self.mesh_num_lines = num_lines - self.mesh_total_nb_frames = total_nb_frames - self.mesh_range = mesh_range_param - self.mesh_center = mesh_center_param - - def get_cryo_temperature(self): - return 0 - - @task - def prepare_intensity_monitors(self): - return - - def get_beam_centre(self): - return self.bl_control.resolution.get_beam_centre() - - @task - def write_input_files(self, datacollection_id): - try: - process_dir = os.path.join(self.xds_directory, "..") - raw_process_dir = os.path.join(self.raw_data_input_file_dir, "..") - for dir in (process_dir, raw_process_dir): - for filename in ("x_geo_corr.cbf.bz2", "y_geo_corr.cbf.bz2"): - dest = os.path.join(dir, filename) - if os.path.exists(dest): - continue - shutil.copyfile( - os.path.join("/data/id29/inhouse/opid291", filename), dest - ) - except Exception: - logging.exception("Exception happened while copying geo_corr files") - - return ESRFMultiCollect.write_input_files(self, datacollection_id) diff --git a/mxcubecore/HardwareObjects/ESRF/ID29MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ID29MultiCollect.py deleted file mode 100644 index a3218bf911..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID29MultiCollect.py +++ /dev/null @@ -1,191 +0,0 @@ -import gevent -import shutil -import logging -import os - -from mxcubecore.TaskUtils import task -from .ESRFMultiCollect import ESRFMultiCollect, PixelDetector, TunableEnergy -from mxcubecore.HardwareObjects.LimaPilatusDetector import LimaPilatusDetector - - -class ID29MultiCollect(ESRFMultiCollect): - def __init__(self, name): - ESRFMultiCollect.__init__(self, name, TunableEnergy()) - - @task - def data_collection_hook(self, data_collect_parameters): - ESRFMultiCollect.data_collection_hook(self, data_collect_parameters) - - self._detector.shutterless = data_collect_parameters["shutterless"] - - def stop_oscillation(self): - self.get_object_by_role("diffractometer").abort() - self.get_object_by_role("diffractometer")._wait_ready(20) - - def close_fast_shutter(self): - state = self.get_object_by_role("fastshut").get_actuator_state(read=True) - if state != "out": - self.close_fast_shutter() - - @task - def get_beam_size(self): - return self.bl_control.beam_info.get_beam_size() - - @task - def get_slit_gaps(self): - self.get_object_by_role("controller") - - return (None, None) - - @task - def get_beam_shape(self): - return self.bl_control.beam_info.get_beam_shape() - - def get_resolution_at_corner(self): - return self.bl_control.resolution.get_value_at_corner() - - def ready(*motors): - return not any([m.motorIsMoving() for m in motors]) - - @task - def move_motors(self, motors_to_move_dict): - # We do not wnta to modify the input dict - motor_positions_copy = motors_to_move_dict.copy() - diffr = self.bl_control.diffractometer - for tag in ("kappa", "kappa_phi"): - if tag in motor_positions_copy: - del motor_positions_copy[tag] - diffr.move_sync_motors(motors_to_move_dict, wait=True, timeout=200) - - @task - def take_crystal_snapshots(self, number_of_snapshots): - diffr = self.get_object_by_role("diffractometer") - if self.bl_control.diffractometer.in_plate_mode(): - if number_of_snapshots > 0: - number_of_snapshots = 1 - # diffr.moveToPhase("Centring", wait=True, timeout=200) - if number_of_snapshots: - # put the back light in - diffr.get_deviceby_role("BackLightSwitch").actuatorIn() - self.bl_control.diffractometer.take_snapshots( - number_of_snapshots, wait=True - ) - diffr._wait_ready(20) - - @task - def do_prepare_oscillation(self, *args, **kwargs): - self.get_object_by_role("controller").detcover.set_out() - diffr = self.get_object_by_role("diffractometer") - # send again the command as MD2 software only handles one - # centered position!! - # has to be where the motors are and before changing the phase - diffr.get_command_object("save_centring_positions")() - # move to DataCollection phase - if diffr.getPhase() != "DataCollection": - logging.getLogger("user_level_log").info("Moving MD2 to Data Collection") - diffr.moveToPhase("DataCollection", wait=True, timeout=200) - # switch on the front light - diffr.get_object_by_role("FrontLight").set_value(2) - - @task - def oscil(self, start, end, exptime, npass): - diffr = self.get_object_by_role("diffractometer") - if self.helical: - diffr.oscilScan4d(start, end, exptime, self.helical_pos, wait=True) - elif self.mesh: - det = self._detector._detector - latency_time = ( - det.config.get_property("latecy_time_mesh") or det.get_deadtime() - ) - diffr.oscilScanMesh( - start, - end, - exptime, - latency_time, - self.mesh_num_lines, - self.mesh_total_nb_frames, - self.mesh_center, - self.mesh_range, - wait=True, - ) - else: - diffr.oscilScan(start, end, exptime, wait=True) - - def prepare_acquisition( - self, take_dark, start, osc_range, exptime, npass, number_of_images, comment="" - ): - if self.mesh: - trigger_mode = "EXTERNAL_GATE" - else: - trigger_mode = None # will be determined by ESRFMultiCollect - return ESRFMultiCollect.prepare_acquisition( - self, - take_dark, - start, - osc_range, - exptime, - npass, - number_of_images, - comment, - trigger_mode, - ) - - def open_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorIn() - - def close_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorOut() - - def set_helical(self, helical_on): - self.helical = helical_on - - def set_helical_pos(self, helical_oscil_pos): - self.helical_pos = helical_oscil_pos - - # specifies the next scan will be a mesh scan - def set_mesh(self, mesh_on): - self.mesh = mesh_on - - def set_mesh_scan_parameters( - self, num_lines, total_nb_frames, mesh_center_param, mesh_range_param - ): - """ - sets the mesh scan parameters : - - vertcal range - - horizontal range - - nb lines - - nb frames per line - - invert direction (boolean) # NOT YET DONE - """ - self.mesh_num_lines = num_lines - self.mesh_total_nb_frames = total_nb_frames - self.mesh_range = mesh_range_param - self.mesh_center = mesh_center_param - - def get_cryo_temperature(self): - return 0 - - @task - def prepare_intensity_monitors(self): - return - - def get_beam_centre(self): - return self.bl_control.resolution.get_beam_centre() - - @task - def write_input_files(self, datacollection_id): - try: - process_dir = os.path.join(self.xds_directory, "..") - raw_process_dir = os.path.join(self.raw_data_input_file_dir, "..") - for dir in (process_dir, raw_process_dir): - for filename in ("x_geo_corr.cbf.bz2", "y_geo_corr.cbf.bz2"): - dest = os.path.join(dir, filename) - if os.path.exists(dest): - continue - shutil.copyfile( - os.path.join("/data/id29/inhouse/opid291", filename), dest - ) - except Exception: - logging.exception("Exception happened while copying geo_corr files") - - return ESRFMultiCollect.write_input_files(self, datacollection_id) diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A1MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ID30A1MultiCollect.py deleted file mode 100644 index 3aec0bf66e..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID30A1MultiCollect.py +++ /dev/null @@ -1,145 +0,0 @@ -import shutil -import logging -import os -import decimal -import time - - -from mxcubecore.TaskUtils import task -from .ESRFMultiCollect import ESRFMultiCollect, FixedEnergy, PixelDetector -from mxcubecore.HardwareObjects.LimaPilatusDetector import LimaPilatusDetector - - -class ID30A1MultiCollect(ESRFMultiCollect): - def __init__(self, name): - ESRFMultiCollect.__init__(self, name, FixedEnergy(0.966, 12.8353)) - - self.helical = False - - @task - def data_collection_hook(self, data_collect_parameters): - oscillation_parameters = data_collect_parameters["oscillation_sequence"][0] - # are we doing shutterless ? - shutterless = data_collect_parameters.get("shutterless") - if oscillation_parameters["overlap"] != 0: - shutterless = False - self._detector.shutterless = True if shutterless else False - file_info = data_collect_parameters["fileinfo"] - diagfile = ( - os.path.join(file_info["directory"], file_info["prefix"]) - + "_%d_diag.dat" % file_info["run_number"] - ) - self.get_object_by_role("diffractometer").controller.set_diagfile(diagfile) - - # Metadata management - ESRFMultiCollect.data_collection_hook(self, data_collect_parameters) - - @task - def get_beam_size(self): - return self.bl_control.beam_info.get_beam_size() - - @task - def get_slit_gaps(self): - return ( - self.bl_control.diffractometer.controller.hgap.position(), - self.bl_control.diffractometer.controller.vgap.position(), - ) - - @task - def get_beam_shape(self): - return self.bl_control.beam_info.get_beam_shape() - - def get_resolution_at_corner(self): - return self.bl_control.resolution.get_value_at_corner() - - @task - def move_motors(self, motors_to_move_dict): - motion = ESRFMultiCollect.move_motors(self, motors_to_move_dict, wait=False) - - cover_task = self.get_object_by_role("eh_controller").detcover.set_out( - wait=False, timeout=15 - ) - - self.get_object_by_role("beamstop").moveToPosition("in") - self.get_object_by_role("light").wagoOut() - - motion.get() - cover_task.get() - - @task - def do_prepare_oscillation(self, *args, **kwargs): - return - - @task - def oscil(self, start, end, exptime, npass): - save_diagnostic = True - operate_shutter = True - if self.helical: - self.get_object_by_role("diffractometer").helical_oscil( - start, - end, - self.helical_pos, - exptime, - npass, - save_diagnostic, - operate_shutter, - ) - else: - self.get_object_by_role("diffractometer").oscil( - start, end, exptime, npass, save_diagnostic, operate_shutter - ) - - def open_fast_shutter(self): - self.get_object_by_role("diffractometer").controller.fshut.open() - - def close_fast_shutter(self): - self.get_object_by_role("diffractometer").controller.fshut.close() - - def set_helical(self, helical_on): - self.helical = helical_on - - def set_helical_pos(self, helical_oscil_pos): - self.helical_pos = helical_oscil_pos - - @task - def prepare_intensity_monitors(self): - self.get_object_by_role("diffractometer").controller.set_diode_autorange( - "i0", True, "i1", False - ) - self.get_object_by_role("diffractometer").controller.diode(True, False) - i0_range = decimal.Decimal( - str( - self.get_object_by_role("diffractometer").controller.get_diode_range()[ - 0 - ] - ) - ) - i1_range = float( - str(i0_range.as_tuple().digits[0]) - + "e" - + str(len(i0_range.as_tuple().digits[1:]) + i0_range.as_tuple().exponent) - ) - self.get_object_by_role("diffractometer").controller.set_i1_range(i1_range) - return - - def get_beam_centre(self): - return self.bl_control.resolution.get_beam_centre() - - @task - def write_input_files(self, datacollection_id): - # copy *geo_corr.cbf* files to process directory - try: - process_dir = os.path.join(self.xds_directory, "..") - raw_process_dir = os.path.join(self.raw_data_input_file_dir, "..") - for dir in (process_dir, raw_process_dir): - for filename in ("x_geo_corr.cbf.bz2", "y_geo_corr.cbf.bz2"): - dest = os.path.join(dir, filename) - if os.path.exists(dest): - continue - shutil.copyfile( - os.path.join("/data/id30a1/inhouse/opid30a1/", filename), dest - ) - except Exception: - logging.exception("Exception happened while copying geo_corr files") - - return ESRFMultiCollect.write_input_files(self, datacollection_id) diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ID30A3MultiCollect.py deleted file mode 100644 index 5f861029fc..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3MultiCollect.py +++ /dev/null @@ -1,240 +0,0 @@ -import gevent -import socket -import logging -import pickle as pickle - -from mxcubecore.TaskUtils import task - -from .ESRFMultiCollect import ESRFMultiCollect, FixedEnergy, PixelDetector -from mxcubecore.HardwareObjects.LimaEigerDetector import Eiger -from PyTango.gevent import DeviceProxy - - -class ID30A3MultiCollect(ESRFMultiCollect): - def __init__(self, name): - ESRFMultiCollect.__init__(self, name, FixedEnergy(0.9677, 12.812)) - - self._notify_greenlet = None - - @task - def data_collection_hook(self, data_collect_parameters): - ESRFMultiCollect.data_collection_hook(self, data_collect_parameters) - - oscillation_parameters = data_collect_parameters["oscillation_sequence"][0] - exp_time = oscillation_parameters["exposure_time"] - if oscillation_parameters["range"] / exp_time > 90: - raise RuntimeError( - "Cannot move omega axis too fast (limit set to 90 degrees per second)." - ) - - self.first_image_timeout = 30 + exp_time * min( - 100, oscillation_parameters["number_of_images"] - ) - - data_collect_parameters["fileinfo"] - - self._detector.shutterless = data_collect_parameters["shutterless"] - - @task - def get_beam_size(self): - return self.bl_control.beam_info.get_beam_size() - - @task - def get_slit_gaps(self): - ctrl = self.get_object_by_role("controller") - return (ctrl.s1h.position(), ctrl.s1v.position()) - - @task - def get_beam_shape(self): - return self.bl_control.beam_info.get_beam_shape() - - def get_resolution_at_corner(self): - return self.bl_control.resolution.get_value_at_corner() - - @task - def move_motors(self, motors_to_move_dict): - # We do not want to modify the input dict - motor_positions_copy = motors_to_move_dict.copy() - diffr = self.bl_control.diffractometer - for tag in ("kappa", "kappa_phi"): - if tag in motor_positions_copy: - del motor_positions_copy[tag] - diffr.move_sync_motors(motors_to_move_dict, wait=True, timeout=200) - - """ - motion = ESRFMultiCollect.move_motors(self,motors_to_move_dict,wait=False) - - # DvS: - cover_task = gevent.spawn(self.get_object_by_role("eh_controller").detcover.set_out, timeout=15) - self.get_object_by_role("beamstop").moveToPosition("in", wait=True) - self.get_object_by_role("light").wagoOut() - motion.get() - # DvS: - cover_task.get() - """ - - @task - def take_crystal_snapshots(self, number_of_snapshots): - if self.bl_control.diffractometer.in_plate_mode(): - if number_of_snapshots > 0: - number_of_snapshots = 1 - - # this has to be done before each chage of phase - self.bl_control.diffractometer.get_command_object("save_centring_positions")() - # not going to centring phase if in plate mode (too long) - if not self.bl_control.diffractometer.in_plate_mode(): - self.bl_control.diffractometer.moveToPhase( - "Centring", wait=True, timeout=200 - ) - self.bl_control.diffractometer.take_snapshots(number_of_snapshots, wait=True) - - @task - def do_prepare_oscillation(self, *args, **kwargs): - # set the detector cover out - self.get_object_by_role("controller").detcover.set_out() - diffr = self.get_object_by_role("diffractometer") - # send again the command as MD2 software only handles one - # centered position!! - # has to be where the motors are and before changing the phase - diffr.get_command_object("save_centring_positions")() - # move to DataCollection phase - if diffr.getPhase() != "DataCollection": - logging.getLogger("user_level_log").info("Moving MD2 to Data Collection") - diffr.moveToPhase("DataCollection", wait=True, timeout=200) - # switch on the front light - diffr.get_object_by_role("FrontLight").set_value(0.8) - # take the back light out - diffr.get_object_by_role("BackLightSwitch").actuatorOut() - - @task - def oscil(self, start, end, exptime, npass, wait=True): - diffr = self.get_object_by_role("diffractometer") - if self.helical: - diffr.oscilScan4d(start, end, exptime, self.helical_pos, wait=True) - elif self.mesh: - diffr.oscilScanMesh( - start, - end, - exptime, - self._detector.get_deadtime(), - self.mesh_num_lines, - self.mesh_total_nb_frames, - self.mesh_center, - self.mesh_range, - wait=True, - ) - else: - diffr.oscilScan(start, end, exptime, wait=True) - - def prepare_acquisition( - self, take_dark, start, osc_range, exptime, npass, number_of_images, comment="" - ): - energy = self._tunable_bl.get_value() - return self._detector.prepare_acquisition( - take_dark, - start, - osc_range, - exptime, - npass, - number_of_images, - comment, - energy, - self.mesh, - ) - - def open_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorIn() - - def close_fast_shutter(self): - self.get_object_by_role("fastshut").actuatorOut() - - def stop_oscillation(self): - pass - - @task - def data_collection_cleanup(self): - self.get_object_by_role("diffractometer")._wait_ready(10) - state = self.get_object_by_role("fastshut").get_actuator_state(read=True) - if state != "out": - self.close_fast_shutter() - - def set_helical(self, helical_on): - self.helical = helical_on - - def set_helical_pos(self, helical_oscil_pos): - self.helical_pos = helical_oscil_pos - - def get_cryo_temperature(self): - return 0 - - @task - def set_detector_filenames( - self, frame_number, start, filename, jpeg_full_path, jpeg_thumbnail_full_path - ): - self.last_image_filename = filename - return ESRFMultiCollect.set_detector_filenames( - self, - frame_number, - start, - filename, - jpeg_full_path, - jpeg_thumbnail_full_path, - ) - - def adxv_notify(self, image_filename): - logging.info("adxv_notify %r", image_filename) - try: - adxv_notify_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - adxv_notify_socket.connect(("aelita.esrf.fr", 8100)) - adxv_notify_socket.sendall("load_image %s\n" % image_filename) - adxv_notify_socket.close() - except Exception: - pass - else: - gevent.sleep(3) - - def albula_notify(self, image_filename): - try: - albula_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - albula_socket.connect(("localhost", 31337)) - except Exception: - pass - else: - albula_socket.sendall( - pickle.dumps({"type": "newimage", "path": image_filename}) - ) - - # def trigger_auto_processing(self, *args, **kw): - # return - - @task - def prepare_intensity_monitors(self): - i1 = DeviceProxy("id30/keithley_massif3/i1") - i0 = DeviceProxy("id30/keithley_massif3/i0") - i1.autorange = False - i1.range = i0.range - - def get_beam_centre(self): - return self.bl_control.resolution.get_beam_centre() - - @task - def write_input_files(self, datacollection_id): - """ - # copy *geo_corr.cbf* files to process directory - - # DvS 23rd Feb. 2016: For the moment, we don't have these correction files for the Eiger, - # thus skipping the copying for now: - # - # try: - # process_dir = os.path.join(self.xds_directory, "..") - # raw_process_dir = os.path.join(self.raw_data_input_file_dir, "..") - # for dir in (process_dir, raw_process_dir): - # for filename in ("x_geo_corr.cbf.bz2", "y_geo_corr.cbf.bz2"): - # dest = os.path.join(dir,filename) - # if os.path.exists(dest): - # continue - # shutil.copyfile(os.path.join("/data/pyarch/id30a3", filename), dest) - # except: - # logging.exception("Exception happened while copying geo_corr files") - """ - return ESRFMultiCollect.write_input_files(self, datacollection_id) From e646fb2f03c7b3d31eb8439a0dca714ae47ca158 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 21 Oct 2024 06:07:46 +0000 Subject: [PATCH 093/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b451ae9f61..53dc054f25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.166.0" +version = "1.167.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 5d932ed674ccfcbeb52239ee422505f7827eb31c Mon Sep 17 00:00:00 2001 From: fabcor Date: Tue, 22 Oct 2024 10:48:49 +0200 Subject: [PATCH 094/172] Enforce usage of isort Update the configuration for isort. Enforce usage of isort via a pre-commit hook. --- .isort.cfg | 13 +-- .pre-commit-config.yaml | 5 + deprecated/Command/Exporter/MDClient.py | 5 +- deprecated/HardwareObjects/Camera.py | 12 ++- deprecated/HardwareObjects/EnhancedPopen.py | 6 +- deprecated/HardwareObjects/NamedState.py | 4 +- .../HardwareObjects/Server/Daemonize.py | 2 +- .../Server/SimpleXMLReadWriteSupport.py | 10 +- deprecated/HardwareObjects/Server/__init__.py | 6 +- deprecated/HardwareObjects/SpecMotor.py | 3 +- .../HardwareObjects/SpecMotorWPositions.py | 3 +- deprecated/HardwareObjects/SpecScan.py | 6 +- deprecated/HardwareObjects/SpecShell.py | 1 + deprecated/HardwareObjects/SpecState.py | 1 + .../HardwareObjects/TacoDevice_MTSafe.py | 7 +- .../HardwareObjects/mockup/CameraMockup.py | 6 +- .../HardwareObjects/mockup/MachInfoMockup.py | 3 +- .../mockup/MultiCollectMockup.py | 10 +- .../HardwareObjects/mockup/Oxford700Mockup.py | 10 +- .../HardwareObjects/mockup/VideoMockup.py | 2 + mxcubecore/BaseHardwareObjects.py | 39 +++++--- mxcubecore/Command/Epics.py | 8 +- mxcubecore/Command/Exporter.py | 8 +- mxcubecore/Command/Mockup.py | 6 +- mxcubecore/Command/Pool.py | 4 +- mxcubecore/Command/Sardana.py | 20 ++-- mxcubecore/Command/Spec.py | 8 +- mxcubecore/Command/Taco.py | 9 +- mxcubecore/Command/Tango.py | 7 +- mxcubecore/Command/Tine.py | 13 ++- mxcubecore/Command/exporter/ExporterClient.py | 6 +- mxcubecore/Command/exporter/ExporterStates.py | 1 + mxcubecore/Command/exporter/MDEvents.py | 4 +- mxcubecore/Command/exporter/StandardClient.py | 3 +- mxcubecore/CommandContainer.py | 19 +++- mxcubecore/HardwareObjectFileParser.py | 1 - .../ALBA/ALBAAutoProcessing.py | 18 ++-- .../HardwareObjects/ALBA/ALBABackLight.py | 8 +- .../HardwareObjects/ALBA/ALBABeamInfo.py | 1 + .../HardwareObjects/ALBA/ALBACalibration.py | 5 +- mxcubecore/HardwareObjects/ALBA/ALBACats.py | 11 ++- .../HardwareObjects/ALBA/ALBACatsMaint.py | 4 +- .../HardwareObjects/ALBA/ALBAClusterJob.py | 8 +- .../HardwareObjects/ALBA/ALBACollect.py | 11 ++- .../HardwareObjects/ALBA/ALBADataAnalysis.py | 18 ++-- mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py | 2 +- .../HardwareObjects/ALBA/ALBAEpsActuator.py | 5 +- .../HardwareObjects/ALBA/ALBAFastShutter.py | 5 +- mxcubecore/HardwareObjects/ALBA/ALBAFlux.py | 8 +- .../HardwareObjects/ALBA/ALBAFrontEnd.py | 5 +- .../HardwareObjects/ALBA/ALBAFrontLight.py | 3 +- .../HardwareObjects/ALBA/ALBAISPyBClient.py | 3 +- .../HardwareObjects/ALBA/ALBAMachineInfo.py | 8 +- .../HardwareObjects/ALBA/ALBAMiniDiff.py | 8 +- .../HardwareObjects/ALBA/ALBAPilatus.py | 9 +- .../HardwareObjects/ALBA/ALBASession.py | 2 +- .../HardwareObjects/ALBA/ALBASupervisor.py | 3 +- .../HardwareObjects/ALBA/ALBAZoomMotor.py | 6 +- .../ALBA/ALBAZoomMotorAutoBrightness.py | 3 +- .../HardwareObjects/ALBA/XalocCalibration.py | 2 +- .../HardwareObjects/ALBA/XalocMachineInfo.py | 8 +- .../HardwareObjects/ALBA/XalocMiniDiff.py | 8 +- mxcubecore/HardwareObjects/Attenuators.py | 1 + mxcubecore/HardwareObjects/BeamInfo.py | 3 +- mxcubecore/HardwareObjects/Beamline.py | 19 +++- mxcubecore/HardwareObjects/BeamlineActions.py | 20 ++-- mxcubecore/HardwareObjects/Bliss.py | 9 +- mxcubecore/HardwareObjects/BlissActuator.py | 4 +- mxcubecore/HardwareObjects/BlissEnergy.py | 4 +- .../HardwareObjects/BlissHutchTrigger.py | 4 +- mxcubecore/HardwareObjects/BlissMotor.py | 4 +- .../HardwareObjects/BlissMotorWPositions.py | 3 +- mxcubecore/HardwareObjects/BlissNState.py | 1 + mxcubecore/HardwareObjects/BlissShutter.py | 8 +- mxcubecore/HardwareObjects/Camera.py | 12 ++- mxcubecore/HardwareObjects/Cats90.py | 4 +- mxcubecore/HardwareObjects/CatsBessy.py | 5 +- mxcubecore/HardwareObjects/CatsMaint.py | 9 +- mxcubecore/HardwareObjects/CentringMath.py | 8 +- mxcubecore/HardwareObjects/DESY/Centring.py | 14 +-- .../HardwareObjects/DESY/DigitalZoomMotor.py | 7 +- .../HardwareObjects/DESY/MjpgStreamVideo.py | 13 ++- .../HardwareObjects/DESY/P11AlbulaView.py | 5 +- .../HardwareObjects/DESY/P11BackLight.py | 15 ++- mxcubecore/HardwareObjects/DESY/P11Beam.py | 9 +- .../HardwareObjects/DESY/P11BeamStop.py | 5 +- mxcubecore/HardwareObjects/DESY/P11Collect.py | 17 ++-- .../HardwareObjects/DESY/P11Collimator.py | 3 +- .../HardwareObjects/DESY/P11DetectorCover.py | 6 +- .../DESY/P11DetectorDistance.py | 3 +- .../HardwareObjects/DESY/P11DoorInterlock.py | 3 +- .../DESY/P11EDNACharacterisation.py | 50 +++++----- .../HardwareObjects/DESY/P11EigerDetector.py | 1 + mxcubecore/HardwareObjects/DESY/P11Energy.py | 6 +- .../HardwareObjects/DESY/P11FastShutter.py | 5 +- mxcubecore/HardwareObjects/DESY/P11Flux.py | 9 +- .../HardwareObjects/DESY/P11ISPyBClient.py | 7 +- .../HardwareObjects/DESY/P11MachineInfo.py | 8 +- .../HardwareObjects/DESY/P11NanoDiff.py | 46 +++++---- mxcubecore/HardwareObjects/DESY/P11Pinhole.py | 3 +- .../HardwareObjects/DESY/P11SampleChanger.py | 4 +- mxcubecore/HardwareObjects/DESY/P11Session.py | 10 +- mxcubecore/HardwareObjects/DESY/P11Shutter.py | 12 ++- .../HardwareObjects/DESY/P11Transmission.py | 4 +- .../HardwareObjects/DESY/P11YagDiode.py | 3 +- mxcubecore/HardwareObjects/DESY/P11Zoom.py | 8 +- mxcubecore/HardwareObjects/DataPublisher.py | 9 +- .../HardwareObjects/DozorOnlineProcessing.py | 13 +-- .../HardwareObjects/EDNACharacterisation.py | 50 +++++----- .../HardwareObjects/EMBL/EMBLAperture.py | 4 +- mxcubecore/HardwareObjects/EMBL/EMBLBSD.py | 8 +- mxcubecore/HardwareObjects/EMBL/EMBLBeam.py | 3 +- .../HardwareObjects/EMBL/EMBLBeamCentering.py | 6 +- .../HardwareObjects/EMBL/EMBLBeamFocusing.py | 3 +- .../HardwareObjects/EMBL/EMBLBeamline.py | 9 +- .../HardwareObjects/EMBL/EMBLBeamlineTest.py | 25 +++-- .../HardwareObjects/EMBL/EMBLBeamstop.py | 1 - mxcubecore/HardwareObjects/EMBL/EMBLCRL.py | 6 +- .../HardwareObjects/EMBL/EMBLCollect.py | 6 +- .../HardwareObjects/EMBL/EMBLDetector.py | 5 +- .../HardwareObjects/EMBL/EMBLDoorInterlock.py | 5 +- mxcubecore/HardwareObjects/EMBL/EMBLEnergy.py | 2 +- .../HardwareObjects/EMBL/EMBLEnergyScan.py | 13 +-- .../EMBL/EMBLExporterClient.py | 1 - mxcubecore/HardwareObjects/EMBL/EMBLFlux.py | 12 +-- .../HardwareObjects/EMBL/EMBLImageTracking.py | 1 - .../HardwareObjects/EMBL/EMBLMachineInfo.py | 12 ++- .../HardwareObjects/EMBL/EMBLMiniDiff.py | 13 +-- .../HardwareObjects/EMBL/EMBLMotorsGroup.py | 5 +- .../EMBL/EMBLOfflineProcessing.py | 7 +- .../EMBL/EMBLOnlineProcessing.py | 11 +-- .../HardwareObjects/EMBL/EMBLPPUControl.py | 1 - .../HardwareObjects/EMBL/EMBLQueueEntry.py | 5 +- .../HardwareObjects/EMBL/EMBLSSXChip.py | 2 +- .../HardwareObjects/EMBL/EMBLSafetyShutter.py | 9 +- .../HardwareObjects/EMBL/EMBLSession.py | 1 - .../HardwareObjects/EMBL/EMBLSlitBox.py | 1 - .../HardwareObjects/EMBL/EMBLTableMotor.py | 2 +- .../HardwareObjects/EMBL/EMBLTransfocator.py | 2 +- .../HardwareObjects/EMBL/EMBLXRFSpectrum.py | 9 +- .../HardwareObjects/EMBL/EMBLXrayImaging.py | 31 +++--- .../HardwareObjects/EMBL/MDFastShutter.py | 7 +- mxcubecore/HardwareObjects/EMBL/TINEMotor.py | 2 +- mxcubecore/HardwareObjects/EMBLFlexHCD.py | 10 +- .../HardwareObjects/EMBLFlexHarvester.py | 6 +- .../HardwareObjects/ESRF/BM14EnergyScan.py | 7 +- .../HardwareObjects/ESRF/BlissHutchTrigger.py | 9 +- .../HardwareObjects/ESRF/BlissTurret.py | 3 +- mxcubecore/HardwareObjects/ESRF/BlissVolpi.py | 3 +- mxcubecore/HardwareObjects/ESRF/ESRFBeam.py | 2 +- .../HardwareObjects/ESRF/ESRFBeamDefiner.py | 1 + .../HardwareObjects/ESRF/ESRFBeamInfo.py | 3 +- .../ESRF/ESRFBeamlineActions.py | 3 +- .../HardwareObjects/ESRF/ESRFCryoMon.py | 6 +- .../HardwareObjects/ESRF/ESRFEnergyScan.py | 18 ++-- mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py | 5 +- .../ESRF/ESRFMetadataManagerClient.py | 12 ++- .../HardwareObjects/ESRF/ESRFMultiCollect.py | 12 +-- .../HardwareObjects/ESRF/ESRFPhotonFlux.py | 1 + mxcubecore/HardwareObjects/ESRF/ESRFSC3.py | 8 +- .../HardwareObjects/ESRF/ESRFSession.py | 9 +- .../ESRF/ESRFSmallXrayCentring.py | 16 +-- .../HardwareObjects/ESRF/ESRFXRFSpectrum.py | 12 ++- .../HardwareObjects/ESRF/ID231BeamCmds.py | 6 +- .../HardwareObjects/ESRF/ID231BeamInfo.py | 3 +- .../HardwareObjects/ESRF/ID231EnergyScan.py | 6 +- .../HardwareObjects/ESRF/ID232BeamCmds.py | 6 +- .../HardwareObjects/ESRF/ID232BeamDefiner.py | 7 +- .../HardwareObjects/ESRF/ID232BeamInfo.py | 2 +- .../HardwareObjects/ESRF/ID232HutchTrigger.py | 8 +- .../HardwareObjects/ESRF/ID232PhotonFlux.py | 2 +- .../HardwareObjects/ESRF/ID23PhotonFlux.py | 6 +- .../HardwareObjects/ESRF/ID29BeamCmds.py | 6 +- .../HardwareObjects/ESRF/ID29EnergyScan.py | 7 +- .../HardwareObjects/ESRF/ID29HutchTrigger.py | 8 +- .../HardwareObjects/ESRF/ID29PhotonFlux.py | 8 +- .../HardwareObjects/ESRF/ID29XRFSpectrum.py | 18 ++-- .../HardwareObjects/ESRF/ID30A3BeamCmds.py | 1 + .../HardwareObjects/ESRF/ID30A3BeamDefiner.py | 1 + .../HardwareObjects/ESRF/ID30A3PhotonFlux.py | 6 +- .../HardwareObjects/ESRF/ID30BBeamCmds.py | 7 +- .../HardwareObjects/ESRF/ID30BEnergyScan.py | 9 +- .../HardwareObjects/ESRF/ID30BPhotonFlux.py | 1 + .../HardwareObjects/ESRF/ID30BXRFSpectrum.py | 8 +- .../HardwareObjects/ESRF/ID30BeamCmds.py | 8 +- .../HardwareObjects/ESRF/ID30BeamInfo.py | 2 +- mxcubecore/HardwareObjects/ESRF/ID30Cryo.py | 6 +- .../HardwareObjects/ESRF/ID30HutchTrigger.py | 10 +- mxcubecore/HardwareObjects/ESRF/ID30Light.py | 6 +- mxcubecore/HardwareObjects/ESRF/ID30SC3.py | 5 +- .../HardwareObjects/ESRF/MD2MultiCollect.py | 11 ++- mxcubecore/HardwareObjects/ESRF/Oxford700.py | 10 +- .../HardwareObjects/ESRF/OxfordCryostream.py | 9 +- .../ESRF/TangoKeithleyPhotonFlux.py | 5 +- .../ESRF/queue_entry/ssx_base_queue_entry.py | 19 ++-- .../queue_entry/ssx_big_foil_collection.py | 26 +++-- .../ESRF/queue_entry/ssx_chip_collection.py | 25 ++--- .../ESRF/queue_entry/ssx_foil_collection.py | 23 ++--- .../queue_entry/ssx_injector_collection.py | 26 +++-- .../ESRF/queue_entry/test_collection.py | 21 ++-- mxcubecore/HardwareObjects/EdnaWorkflow.py | 13 +-- mxcubecore/HardwareObjects/Energy.py | 2 + mxcubecore/HardwareObjects/ExporterMotor.py | 12 ++- mxcubecore/HardwareObjects/ExporterNState.py | 9 +- mxcubecore/HardwareObjects/FlexHCD.py | 7 +- .../HardwareObjects/FlexHCDMaintenance.py | 2 +- .../HardwareObjects/GenericDiffractometer.py | 29 ++++-- .../HardwareObjects/Gphl/CollectEmulator.py | 11 ++- .../HardwareObjects/Gphl/GphlMessages.py | 16 ++- .../HardwareObjects/Gphl/GphlQueueEntry.py | 4 +- .../HardwareObjects/Gphl/GphlWorkflow.py | 37 ++++--- .../Gphl/GphlWorkflowConnection.py | 36 ++++--- .../Gphl/Transcal2MiniKappa.py | 10 +- mxcubecore/HardwareObjects/Grob.py | 3 +- mxcubecore/HardwareObjects/GrobMotor.py | 6 +- .../HardwareObjects/GrobSampleChanger.py | 4 +- mxcubecore/HardwareObjects/Harvester.py | 4 +- .../HardwareObjects/HarvesterMaintenance.py | 6 +- mxcubecore/HardwareObjects/ISARAMaint.py | 7 +- mxcubecore/HardwareObjects/ISPyBClient.py | 18 ++-- mxcubecore/HardwareObjects/ISPyBRestClient.py | 14 ++- .../HardwareObjects/LNLS/EPICSActuator.py | 4 +- mxcubecore/HardwareObjects/LNLS/EPICSMotor.py | 1 + .../HardwareObjects/LNLS/EPICSNState.py | 2 +- .../HardwareObjects/LNLS/LNLSAperture.py | 4 +- mxcubecore/HardwareObjects/LNLS/LNLSBeam.py | 5 +- mxcubecore/HardwareObjects/LNLS/LNLSCamera.py | 6 +- .../HardwareObjects/LNLS/LNLSCollect.py | 15 +-- .../HardwareObjects/LNLS/LNLSDetDistMotor.py | 2 +- .../LNLS/LNLSDiffractometer.py | 9 +- mxcubecore/HardwareObjects/LNLS/LNLSEnergy.py | 3 +- .../HardwareObjects/LNLS/LNLSPilatusDet.py | 7 +- mxcubecore/HardwareObjects/LNLS/LNLSSlits.py | 1 - .../HardwareObjects/LNLS/LNLSTransmission.py | 8 +- mxcubecore/HardwareObjects/LNLS/LNLSZoom.py | 9 +- .../LNLS/read_transmission_mnc.py | 4 +- .../LNLS/set_transmission_mnc.py | 3 +- .../HardwareObjects/LdapAuthenticator.py | 1 + mxcubecore/HardwareObjects/Lima2Detector.py | 16 ++- .../HardwareObjects/LimaEigerDetector.py | 13 +-- .../HardwareObjects/LimaJungfrauDetector.py | 9 +- .../HardwareObjects/LimaPilatusDetector.py | 15 ++- .../HardwareObjects/MAXIV/BIOMAXAperture.py | 1 + .../HardwareObjects/MAXIV/BIOMAXBeamInfo.py | 2 +- .../MAXIV/BIOMAXBeamlineActions.py | 5 +- .../HardwareObjects/MAXIV/BIOMAXCollect.py | 18 ++-- .../HardwareObjects/MAXIV/BIOMAXEiger.py | 12 ++- .../HardwareObjects/MAXIV/BIOMAXEnergy.py | 4 +- .../HardwareObjects/MAXIV/BIOMAXKafka.py | 8 +- mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py | 13 ++- .../HardwareObjects/MAXIV/BIOMAXMD3Camera.py | 15 ++- .../HardwareObjects/MAXIV/BIOMAXPatches.py | 8 +- .../HardwareObjects/MAXIV/BIOMAXResolution.py | 2 +- .../MAXIV/BIOMAXTransmission.py | 3 +- .../MAXIV/MAXIVAutoProcessing.py | 17 ++-- mxcubecore/HardwareObjects/MAXIV/MachInfo.py | 11 ++- .../HardwareObjects/MAXIV/MaxIVSession.py | 9 +- .../HardwareObjects/MAXIV/autoProcLauncher.py | 12 +-- .../HardwareObjects/MAXIV/ednaProcLauncher.py | 10 +- mxcubecore/HardwareObjects/MD2Motor.py | 7 +- mxcubecore/HardwareObjects/MD3UP.py | 7 +- mxcubecore/HardwareObjects/MachCurrent.py | 5 +- mxcubecore/HardwareObjects/Marvin.py | 11 +-- mxcubecore/HardwareObjects/Microdiff.py | 12 ++- .../HardwareObjects/MicrodiffActuator.py | 5 +- .../HardwareObjects/MicrodiffAperture.py | 1 + .../HardwareObjects/MicrodiffFocusMotor.py | 2 +- mxcubecore/HardwareObjects/MicrodiffInOut.py | 3 +- .../HardwareObjects/MicrodiffKappaMotor.py | 4 +- mxcubecore/HardwareObjects/MicrodiffLight.py | 2 +- mxcubecore/HardwareObjects/MicrodiffMotor.py | 2 + .../HardwareObjects/MicrodiffSamplePseudo.py | 5 +- mxcubecore/HardwareObjects/MicrodiffZoom.py | 1 + mxcubecore/HardwareObjects/MiniDiff.py | 21 ++-- .../HardwareObjects/MiniKappaCorrection.py | 4 +- mxcubecore/HardwareObjects/MotorWPositions.py | 1 + mxcubecore/HardwareObjects/MotorsNPosition.py | 2 +- .../HardwareObjects/MultiplePositions.py | 3 +- mxcubecore/HardwareObjects/Native/__init__.py | 10 +- .../HardwareObjects/ObjectsController.py | 3 +- .../HardwareObjects/PlateManipulator.py | 9 +- mxcubecore/HardwareObjects/PyISPyBClient.py | 47 ++++----- mxcubecore/HardwareObjects/QtAxisCamera.py | 11 +-- mxcubecore/HardwareObjects/QtGraphicsLib.py | 6 +- .../HardwareObjects/QtGraphicsManager.py | 28 +++--- .../HardwareObjects/QtInstanceServer.py | 11 ++- mxcubecore/HardwareObjects/QtLimaVideo.py | 4 +- .../HardwareObjects/QtTangoLimaVideo.py | 6 +- mxcubecore/HardwareObjects/QueueManager.py | 5 +- mxcubecore/HardwareObjects/QueueModel.py | 7 +- mxcubecore/HardwareObjects/RedisClient.py | 8 +- mxcubecore/HardwareObjects/Resolution.py | 4 +- mxcubecore/HardwareObjects/Robodiff.py | 3 +- mxcubecore/HardwareObjects/RobodiffLight.py | 6 +- mxcubecore/HardwareObjects/RobodiffMotor.py | 5 +- .../RobodiffMotorWPositions.py | 3 +- mxcubecore/HardwareObjects/SC3.py | 6 +- .../SOLEIL/PX1/PX1Attenuator.py | 1 + .../SOLEIL/PX1/PX1CatsMaint.py | 6 +- .../HardwareObjects/SOLEIL/PX1/PX1Collect.py | 18 ++-- .../HardwareObjects/SOLEIL/PX1/PX1Cryotong.py | 11 +-- .../SOLEIL/PX1/PX1DetectorDistance.py | 1 + .../HardwareObjects/SOLEIL/PX1/PX1Energy.py | 9 +- .../SOLEIL/PX1/PX1EnergyScan.py | 23 ++--- .../SOLEIL/PX1/PX1Environment.py | 6 +- .../HardwareObjects/SOLEIL/PX1/PX1MiniDiff.py | 11 +-- .../HardwareObjects/SOLEIL/PX1/PX1Pilatus.py | 4 +- .../HardwareObjects/SOLEIL/PX1/PX1Pss.py | 1 + .../SOLEIL/PX1/PX1Resolution.py | 5 +- .../SOLEIL/PX1/PX1TangoLight.py | 1 + .../SOLEIL/PX2/PX2Attenuator.py | 3 +- .../HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py | 1 + .../HardwareObjects/SOLEIL/PX2/PX2Collect.py | 28 +++--- .../SOLEIL/PX2/PX2Diffractometer.py | 36 +++---- .../HardwareObjects/SOLEIL/PX2/PX2Energy.py | 14 ++- .../SOLEIL/PX2/PX2Guillotine.py | 1 + .../SOLEIL/PX2/PX2Qt4_LimaVideo.py | 6 +- .../SOLEIL/PX2/PX2Resolution.py | 8 +- .../HardwareObjects/SOLEIL/PX2/PX2Video.py | 13 ++- .../HardwareObjects/SOLEIL/SOLEILCatsMaint.py | 8 +- .../SOLEIL/SOLEILEnergyScan.py | 10 +- .../HardwareObjects/SOLEIL/SOLEILFlux.py | 3 +- .../SOLEIL/SOLEILGuillotine.py | 3 +- .../SOLEIL/SOLEILISPyBClient.py | 15 +-- .../SOLEIL/SOLEILMachineInfo.py | 10 +- .../HardwareObjects/SOLEIL/SOLEILPss.py | 4 +- .../HardwareObjects/SOLEIL/SOLEILRuche.py | 5 +- .../SOLEIL/SOLEILSafetyShutter.py | 4 +- .../HardwareObjects/SOLEIL/SOLEILSession.py | 3 +- .../SOLEIL/SOLEILqueue_entry.py | 2 +- .../HardwareObjects/SOLEIL/TangoDCMotor.py | 13 +-- mxcubecore/HardwareObjects/SampleView.py | 8 +- mxcubecore/HardwareObjects/SardanaMotor.py | 11 ++- mxcubecore/HardwareObjects/Session.py | 5 +- mxcubecore/HardwareObjects/SimpleHTML.py | 3 +- mxcubecore/HardwareObjects/SpecMotor.py | 3 +- .../HardwareObjects/SpecMotorWPositions.py | 3 +- mxcubecore/HardwareObjects/SpecScan.py | 6 +- mxcubecore/HardwareObjects/SpecShell.py | 6 +- mxcubecore/HardwareObjects/SpecState.py | 1 + mxcubecore/HardwareObjects/StateMachine.py | 7 +- .../HardwareObjects/TangoLimaMpegVideo.py | 1 + mxcubecore/HardwareObjects/TangoLimaVideo.py | 10 +- .../HardwareObjects/TangoLimaVideoDevice.py | 3 +- .../HardwareObjects/TangoLimaVideoLoopback.py | 12 ++- .../HardwareObjects/TangoMachineInfo.py | 5 +- mxcubecore/HardwareObjects/TangoMotor.py | 4 +- mxcubecore/HardwareObjects/TangoShutter.py | 8 +- mxcubecore/HardwareObjects/Transmission.py | 3 +- mxcubecore/HardwareObjects/UnitTest.py | 3 +- mxcubecore/HardwareObjects/VaporyVideo.py | 4 +- mxcubecore/HardwareObjects/VimbaVideo.py | 14 +-- mxcubecore/HardwareObjects/XMLRPCServer.py | 18 ++-- mxcubecore/HardwareObjects/XRFSpectrum.py | 4 +- .../HardwareObjects/XSDataAutoprocv1_0.py | 44 +++++---- mxcubecore/HardwareObjects/XSDataCommon.py | 7 +- .../HardwareObjects/XSDataControlDozorv1_1.py | 40 ++++---- .../HardwareObjects/XSDataMXCuBEv1_3.py | 68 +++++++------ .../HardwareObjects/XSDataMXCuBEv1_4.py | 81 +++++++++------- mxcubecore/HardwareObjects/XSDataMXv1.py | 97 ++++++++++--------- .../abstract/AbstractActuator.py | 1 - .../abstract/AbstractAperture.py | 1 - .../abstract/AbstractAuthenticator.py | 1 + .../HardwareObjects/abstract/AbstractBeam.py | 5 +- .../abstract/AbstractCharacterisation.py | 1 + .../abstract/AbstractCollect.py | 15 +-- .../abstract/AbstractDetector.py | 2 +- .../abstract/AbstractEnergy.py | 3 +- .../abstract/AbstractEnergyScan.py | 8 +- .../HardwareObjects/abstract/AbstractFlux.py | 3 +- .../HardwareObjects/abstract/AbstractMCA.py | 1 + .../abstract/AbstractMachineInfo.py | 1 + .../HardwareObjects/abstract/AbstractMotor.py | 9 +- .../abstract/AbstractMultiCollect.py | 19 ++-- .../abstract/AbstractNState.py | 7 +- .../abstract/AbstractOnlineProcessing.py | 22 ++--- .../abstract/AbstractProcedure.py | 19 ++-- .../abstract/AbstractResolution.py | 8 +- .../abstract/AbstractSampleChanger.py | 7 +- .../abstract/AbstractShutter.py | 6 +- .../HardwareObjects/abstract/AbstractSlits.py | 2 +- .../abstract/AbstractTransmission.py | 2 +- .../abstract/AbstractVideoDevice.py | 12 ++- .../abstract/AbstractXRFSpectrum.py | 4 +- .../abstract/AbstractXrayCentring.py | 10 +- .../abstract/sample_changer/Crims.py | 5 +- .../abstract/sample_changer/Sample.py | 1 + mxcubecore/HardwareObjects/autoprocessing.py | 2 +- .../HardwareObjects/mockup/ActuatorMockup.py | 4 +- .../HardwareObjects/mockup/ApertureMockup.py | 1 + .../mockup/BIOMAXEigerMockup.py | 11 ++- .../mockup/BeamDefinerMockup.py | 3 +- .../mockup/BeamlineActionsMockup.py | 13 ++- .../mockup/BeamlineTestMockup.py | 7 +- .../HardwareObjects/mockup/BeamstopMockup.py | 1 - .../HardwareObjects/mockup/CatsMaintMockup.py | 7 +- .../HardwareObjects/mockup/CollectMockup.py | 6 +- .../HardwareObjects/mockup/DetectorMockup.py | 4 +- .../mockup/DiffractometerMockup.py | 8 +- .../mockup/EDNACharacterisationMockup.py | 2 - .../mockup/EnergyScanMockup.py | 14 ++- .../mockup/ExporterNStateMockup.py | 4 +- .../HardwareObjects/mockup/FluxMockup.py | 9 +- .../HardwareObjects/mockup/HarvesterMockup.py | 3 +- .../mockup/ISPyBClientMockup.py | 2 +- .../mockup/ISPyBRestClientMockup.py | 4 +- .../mockup/LimaDetectorMockup.py | 6 +- .../HardwareObjects/mockup/MDCameraMockup.py | 5 +- .../mockup/MachineInfoMockup.py | 4 +- .../mockup/MicrodiffApertureMockup.py | 3 +- .../mockup/MicrodiffInOutMockup.py | 3 +- .../mockup/MicrodiffZoomMockup.py | 7 +- .../HardwareObjects/mockup/MotorMockup.py | 8 +- .../HardwareObjects/mockup/MotorMockupBis.py | 2 +- .../mockup/MultiCollectMockup.py | 14 +-- .../mockup/OfflineProcessingMockup.py | 7 +- .../mockup/OnlineProcessingMockup.py | 2 +- .../mockup/PlateManipulatorMockup.py | 1 + .../HardwareObjects/mockup/PlottingMockup.py | 3 +- .../HardwareObjects/mockup/ProcedureMockup.py | 5 +- .../HardwareObjects/mockup/QtVideoMockup.py | 12 ++- .../mockup/SOLEILCharacterisationMockup.py | 2 +- .../mockup/SampleChangerMockup.py | 2 +- .../HardwareObjects/mockup/ScanMockup.py | 11 ++- .../mockup/ShapeHistoryMockup.py | 2 +- .../HardwareObjects/mockup/ShutterMockup.py | 8 +- .../HardwareObjects/mockup/SlitsMockup.py | 1 - .../mockup/TransmissionMockup.py | 1 - .../HardwareObjects/mockup/XRFMockup.py | 3 +- .../mockup/XRFSpectrumMockup.py | 5 +- .../mockup/XrayCentringMockup.py | 10 +- mxcubecore/HardwareObjects/sample_centring.py | 11 ++- mxcubecore/HardwareRepository.py | 27 ++++-- mxcubecore/Poller.py | 6 +- mxcubecore/TaskUtils.py | 3 +- mxcubecore/__init__.py | 9 +- mxcubecore/configuration/checkxml.py | 11 ++- .../generate_md2_config_files.py | 2 +- mxcubecore/model/common.py | 6 +- mxcubecore/model/configmodel.py | 5 +- mxcubecore/model/crystal_symmetry.py | 5 +- mxcubecore/model/procedure_model.py | 5 +- mxcubecore/model/queue_model_objects.py | 5 +- mxcubecore/queue_entry/__init__.py | 11 +-- mxcubecore/queue_entry/advanced_connector.py | 2 +- mxcubecore/queue_entry/base_queue_entry.py | 16 +-- mxcubecore/queue_entry/characterisation.py | 8 +- mxcubecore/queue_entry/data_collection.py | 7 +- mxcubecore/queue_entry/energy_scan.py | 6 +- mxcubecore/queue_entry/generic_workflow.py | 2 +- mxcubecore/queue_entry/import_helper.py | 4 +- mxcubecore/queue_entry/optical_centring.py | 1 - mxcubecore/queue_entry/test_collection.py | 10 +- mxcubecore/queue_entry/xray_centering.py | 1 - mxcubecore/queue_entry/xray_centering2.py | 1 - mxcubecore/queue_entry/xrf_spectrum.py | 6 +- mxcubecore/saferef.py | 4 +- mxcubecore/utils/conversion.py | 14 ++- mxcubecore/utils/dataobject.py | 3 +- mxcubecore/utils/qt_import.py | 89 +++++++++-------- test/pytest/TestAbstractActuatorBase.py | 3 +- test/pytest/TestAbstractMotorBase.py | 6 +- test/pytest/TestAbstractNStateBase.py | 3 +- test/pytest/TestHardwareObjectBase.py | 12 ++- test/pytest/conftest.py | 8 +- test/pytest/test_aperture.py | 3 +- test/pytest/test_base_hardware_objects.py | 28 +++--- test/pytest/test_beam.py | 3 +- test/pytest/test_beam_definer.py | 3 +- test/pytest/test_beamline_ho_id.py | 8 +- test/pytest/test_command_container.py | 21 +++- test/pytest/test_detector.py | 9 +- test/pytest/test_detector_distance.py | 11 ++- test/pytest/test_energy.py | 4 +- test/pytest/test_flux.py | 1 + test/pytest/test_hwo_isara_maint.py | 14 ++- test/pytest/test_hwo_maxiv_mach_info.py | 8 +- test/pytest/test_mach_info.py | 3 +- test/pytest/test_procedure.py | 3 +- test/pytest/test_resolution.py | 2 +- test/pytest/test_sample_view.py | 8 +- test/pytest/test_shutter.py | 3 +- test/pytest/test_transmission.py | 1 + test/pytest/test_utils_units.py | 11 ++- test/pytest/test_xrf.py | 4 +- 485 files changed, 2357 insertions(+), 1716 deletions(-) diff --git a/.isort.cfg b/.isort.cfg index bbd41af7ab..4923de2c83 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,11 +1,4 @@ [settings] -; see https://github.com/psf/black -multi_line_output=3 -include_trailing_comma=True -force_grid_wrap=0 -combine_as_imports=True -use_parentheses=True -line_length=88 -sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER -default_section=THIRDPARTY -ensure_newline_before_comments = True +profile=black +py_version=38 +force_grid_wrap=2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8a360004dd..75873ce5b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,6 +26,11 @@ repos: - --remove-duplicate-keys - --ignore-pass-after-docstring + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + - repo: https://github.com/psf/black rev: 24.8.0 # The following version (`24.10.0`) dropped support for Python 3.8. hooks: diff --git a/deprecated/Command/Exporter/MDClient.py b/deprecated/Command/Exporter/MDClient.py index 419eee9689..037a1e666e 100644 --- a/deprecated/Command/Exporter/MDClient.py +++ b/deprecated/Command/Exporter/MDClient.py @@ -1,7 +1,8 @@ -import sys -import time import string +import sys import threading +import time + from Command.exporter.ExporterClient import * SERVER_ADDRESS = "localhost" diff --git a/deprecated/HardwareObjects/Camera.py b/deprecated/HardwareObjects/Camera.py index 25f1a9c4dc..b6dc01b3b7 100644 --- a/deprecated/HardwareObjects/Camera.py +++ b/deprecated/HardwareObjects/Camera.py @@ -16,13 +16,17 @@ """ -from mxcubecore import BaseHardwareObjects -from mxcubecore import CommandContainer -import gevent import logging import os -import time import sys +import time + +import gevent + +from mxcubecore import ( + BaseHardwareObjects, + CommandContainer, +) try: from Qub.CTools.qttools import BgrImageMmap diff --git a/deprecated/HardwareObjects/EnhancedPopen.py b/deprecated/HardwareObjects/EnhancedPopen.py index e5b2c96f92..d0a63be10e 100644 --- a/deprecated/HardwareObjects/EnhancedPopen.py +++ b/deprecated/HardwareObjects/EnhancedPopen.py @@ -1,9 +1,9 @@ +import errno +import fcntl import os +import select import subprocess -import errno import time -import select -import fcntl PIPE = subprocess.PIPE diff --git a/deprecated/HardwareObjects/NamedState.py b/deprecated/HardwareObjects/NamedState.py index b5360c0aff..f442a766a2 100644 --- a/deprecated/HardwareObjects/NamedState.py +++ b/deprecated/HardwareObjects/NamedState.py @@ -17,11 +17,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . +import logging + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -import logging - class NamedState(HardwareObject): def __init__(self, name): diff --git a/deprecated/HardwareObjects/Server/Daemonize.py b/deprecated/HardwareObjects/Server/Daemonize.py index bc89775a69..4887f0e2de 100644 --- a/deprecated/HardwareObjects/Server/Daemonize.py +++ b/deprecated/HardwareObjects/Server/Daemonize.py @@ -1,5 +1,5 @@ -import sys import os +import sys """This module is used to fork the current process into a daemon. Almost none of this is necessary (or advisable) if your daemon diff --git a/deprecated/HardwareObjects/Server/SimpleXMLReadWriteSupport.py b/deprecated/HardwareObjects/Server/SimpleXMLReadWriteSupport.py index 725a5de63c..dcf1aaf8ba 100644 --- a/deprecated/HardwareObjects/Server/SimpleXMLReadWriteSupport.py +++ b/deprecated/HardwareObjects/Server/SimpleXMLReadWriteSupport.py @@ -1,10 +1,12 @@ -import sys import io +import sys +from xml.sax import ( + SAXParseException, + make_parser, +) +from xml.sax.handler import ContentHandler from xml.sax.saxutils import XMLGenerator -from xml.sax import make_parser -from xml.sax import SAXParseException from xml.sax.xmlreader import AttributesImpl -from xml.sax.handler import ContentHandler _parser = make_parser() diff --git a/deprecated/HardwareObjects/Server/__init__.py b/deprecated/HardwareObjects/Server/__init__.py index faaaa19009..3cf6b651e1 100644 --- a/deprecated/HardwareObjects/Server/__init__.py +++ b/deprecated/HardwareObjects/Server/__init__.py @@ -4,10 +4,12 @@ from xml.sax import SAXParseException from xml.sax.handler import ContentHandler -from SpecClient_gevent import SpecServer -from SpecClient_gevent import SpecMessage import Daemonize import SimpleXMLReadWriteSupport +from SpecClient_gevent import ( + SpecMessage, + SpecServer, +) class XMLNodesWithRolesReadingHandler(ContentHandler): diff --git a/deprecated/HardwareObjects/SpecMotor.py b/deprecated/HardwareObjects/SpecMotor.py index 1717d5a937..412ee2c904 100644 --- a/deprecated/HardwareObjects/SpecMotor.py +++ b/deprecated/HardwareObjects/SpecMotor.py @@ -1,6 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject from SpecClient_gevent.SpecMotor import SpecMotorA +from mxcubecore.BaseHardwareObjects import HardwareObject + class SpecMotor(HardwareObject, SpecMotorA): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) diff --git a/deprecated/HardwareObjects/SpecMotorWPositions.py b/deprecated/HardwareObjects/SpecMotorWPositions.py index 03b864f166..770c9f9f9d 100644 --- a/deprecated/HardwareObjects/SpecMotorWPositions.py +++ b/deprecated/HardwareObjects/SpecMotorWPositions.py @@ -1,6 +1,7 @@ -from mxcubecore.HardwareObjects import SpecMotor import logging +from mxcubecore.HardwareObjects import SpecMotor + class SpecMotorWPositions(SpecMotor.SpecMotor): def init(self): diff --git a/deprecated/HardwareObjects/SpecScan.py b/deprecated/HardwareObjects/SpecScan.py index f0e4f16cc5..8064e23187 100644 --- a/deprecated/HardwareObjects/SpecScan.py +++ b/deprecated/HardwareObjects/SpecScan.py @@ -1,6 +1,8 @@ try: - from SpecClient_gevent import SpecEventsDispatcher - from SpecClient_gevent import SpecConnectionsManager + from SpecClient_gevent import ( + SpecConnectionsManager, + SpecEventsDispatcher, + ) except ImportError: from SpecClient import SpecEventsDispatcher from SpecClient import SpecConnectionsManager diff --git a/deprecated/HardwareObjects/SpecShell.py b/deprecated/HardwareObjects/SpecShell.py index 0d73ebb1be..280ff51e8a 100644 --- a/deprecated/HardwareObjects/SpecShell.py +++ b/deprecated/HardwareObjects/SpecShell.py @@ -7,6 +7,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject try: diff --git a/deprecated/HardwareObjects/SpecState.py b/deprecated/HardwareObjects/SpecState.py index 2fa6935a22..ac615cf824 100644 --- a/deprecated/HardwareObjects/SpecState.py +++ b/deprecated/HardwareObjects/SpecState.py @@ -7,6 +7,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import Procedure try: diff --git a/deprecated/HardwareObjects/TacoDevice_MTSafe.py b/deprecated/HardwareObjects/TacoDevice_MTSafe.py index 722b81b20c..adc4141f84 100644 --- a/deprecated/HardwareObjects/TacoDevice_MTSafe.py +++ b/deprecated/HardwareObjects/TacoDevice_MTSafe.py @@ -1,8 +1,9 @@ # $Id: TacoDevice_MTSafe.py,v 1.5 2004/11/15 12:39:19 guijarro Exp $ -from Taco import * -from threading import RLock -import weakref import types +import weakref +from threading import RLock + +from Taco import * _global_lock = RLock() diff --git a/deprecated/HardwareObjects/mockup/CameraMockup.py b/deprecated/HardwareObjects/mockup/CameraMockup.py index 8ca6852157..2517f8f44e 100644 --- a/deprecated/HardwareObjects/mockup/CameraMockup.py +++ b/deprecated/HardwareObjects/mockup/CameraMockup.py @@ -1,14 +1,16 @@ """Class for cameras connected to framegrabbers run by Taco Device Servers """ -from mxcubecore import BaseHardwareObjects import logging import os -import gevent import time + +import gevent import numpy from PIL import Image +from mxcubecore import BaseHardwareObjects + try: from cStringIO import StringIO except ImportError: diff --git a/deprecated/HardwareObjects/mockup/MachInfoMockup.py b/deprecated/HardwareObjects/mockup/MachInfoMockup.py index 95242bea29..147554dda1 100644 --- a/deprecated/HardwareObjects/mockup/MachInfoMockup.py +++ b/deprecated/HardwareObjects/mockup/MachInfoMockup.py @@ -32,9 +32,10 @@ values['topup_remaining'] """ -import gevent import time +import gevent + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/deprecated/HardwareObjects/mockup/MultiCollectMockup.py b/deprecated/HardwareObjects/mockup/MultiCollectMockup.py index b84185c768..9fe76b8cdb 100644 --- a/deprecated/HardwareObjects/mockup/MultiCollectMockup.py +++ b/deprecated/HardwareObjects/mockup/MultiCollectMockup.py @@ -1,12 +1,14 @@ +import logging +import os +import time + +import gevent + from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMultiCollect import ( AbstractMultiCollect, ) from mxcubecore.TaskUtils import task -import logging -import time -import os -import gevent class MultiCollectMockup(AbstractMultiCollect, HardwareObject): diff --git a/deprecated/HardwareObjects/mockup/Oxford700Mockup.py b/deprecated/HardwareObjects/mockup/Oxford700Mockup.py index 8131c52677..32ca4a01c2 100644 --- a/deprecated/HardwareObjects/mockup/Oxford700Mockup.py +++ b/deprecated/HardwareObjects/mockup/Oxford700Mockup.py @@ -1,10 +1,12 @@ # pylint: skip-file -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR -import gevent -import sys import random +import sys + +import gevent + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] PHASE_ACTION = { diff --git a/deprecated/HardwareObjects/mockup/VideoMockup.py b/deprecated/HardwareObjects/mockup/VideoMockup.py index 54fdb399cc..e7d5da0bdf 100755 --- a/deprecated/HardwareObjects/mockup/VideoMockup.py +++ b/deprecated/HardwareObjects/mockup/VideoMockup.py @@ -4,8 +4,10 @@ import os import time + import gevent from gui.utils.qt_import import QImage + from mxcubecore import BaseHardwareObjects from mxcubecore.HardwareObjects.Camera import JpegType diff --git a/mxcubecore/BaseHardwareObjects.py b/mxcubecore/BaseHardwareObjects.py index f785b8db37..ee979a1649 100644 --- a/mxcubecore/BaseHardwareObjects.py +++ b/mxcubecore/BaseHardwareObjects.py @@ -20,37 +20,50 @@ from __future__ import absolute_import -import typing import ast import enum -from collections import OrderedDict import logging -from gevent import event, Timeout -from pydantic.v1 import create_model, Field +import typing import warnings - +from collections import OrderedDict from typing import ( TYPE_CHECKING, - Callable, - Iterator, - Union, Any, + Callable, + Dict, Generator, + Iterator, List, - Dict, + Optional, +) +from typing import OrderedDict as TOrderedDict +from typing import ( Tuple, Type, - Optional, - OrderedDict as TOrderedDict, + Union, +) + +from gevent import ( + Timeout, + event, +) +from pydantic.v1 import ( + Field, + create_model, +) +from typing_extensions import ( + Literal, + Self, ) -from typing_extensions import Self, Literal -from mxcubecore.dispatcher import dispatcher from mxcubecore.CommandContainer import CommandContainer +from mxcubecore.dispatcher import dispatcher if TYPE_CHECKING: from logging import Logger + from pydantic.v1 import BaseModel + from .CommandContainer import CommandObject __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/Command/Epics.py b/mxcubecore/Command/Epics.py index a5c465b5d0..b747352965 100644 --- a/mxcubecore/Command/Epics.py +++ b/mxcubecore/Command/Epics.py @@ -18,8 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import logging import copy +import logging import time try: @@ -28,9 +28,11 @@ logging.getLogger("HWR").warning("EPICS support not available.") from mxcubecore import Poller +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) from mxcubecore.dispatcher import saferef -from mxcubecore.CommandContainer import CommandObject, ChannelObject - __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/Command/Exporter.py b/mxcubecore/Command/Exporter.py index 7152c8e2a5..5f4ab2a8a1 100644 --- a/mxcubecore/Command/Exporter.py +++ b/mxcubecore/Command/Exporter.py @@ -22,9 +22,15 @@ # from warnings import warn import logging + import gevent from gevent.queue import Queue -from mxcubecore.CommandContainer import CommandObject, ChannelObject + +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) + from .exporter import ExporterClient from .exporter.StandardClient import PROTOCOL diff --git a/mxcubecore/Command/Mockup.py b/mxcubecore/Command/Mockup.py index 0e41f49665..0fe57900a9 100755 --- a/mxcubecore/Command/Mockup.py +++ b/mxcubecore/Command/Mockup.py @@ -28,8 +28,10 @@ # import queue -from mxcubecore.CommandContainer import CommandObject, ChannelObject - +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/Command/Pool.py b/mxcubecore/Command/Pool.py index 74cc81b1d0..bad95004e8 100755 --- a/mxcubecore/Command/Pool.py +++ b/mxcubecore/Command/Pool.py @@ -20,6 +20,7 @@ import logging import weakref + import qt try: @@ -27,10 +28,9 @@ except ImportError: import queue - from mxcubecore.CommandContainer import ( - CommandObject, ChannelObject, + CommandObject, ConnectionError, ) diff --git a/mxcubecore/Command/Sardana.py b/mxcubecore/Command/Sardana.py index 3c0a59aa10..7fbe7bcb3b 100644 --- a/mxcubecore/Command/Sardana.py +++ b/mxcubecore/Command/Sardana.py @@ -26,13 +26,13 @@ import logging import os +import gevent +from gevent.event import Event + # import time # import types from mxcubecore.dispatcher import saferef -import gevent -from gevent.event import Event - try: import Queue as queue except ImportError: @@ -42,25 +42,31 @@ from mxcubecore.CommandContainer import ( - CommandObject, ChannelObject, + CommandObject, ConnectionError, ) # This is a site specific module where some of the dependencies might not be capture by the ``pyproject.toml`` during installation try: - from PyTango import DevFailed, ConnectionFailed import PyTango + from PyTango import ( + ConnectionFailed, + DevFailed, + ) except Exception: logging.getLogger("HWR").warning("Pytango is not available in this computer.") # try: - from sardana.taurus.core.tango.sardana import registerExtensions - from taurus import Device, Attribute import taurus + from sardana.taurus.core.tango.sardana import registerExtensions + from taurus import ( + Attribute, + Device, + ) except Exception: logging.getLogger("HWR").warning("Sardana is not available in this computer.") diff --git a/mxcubecore/Command/Spec.py b/mxcubecore/Command/Spec.py index 7eb1d761ba..72a38fc744 100644 --- a/mxcubecore/Command/Spec.py +++ b/mxcubecore/Command/Spec.py @@ -19,16 +19,18 @@ # along with MXCuBE. If not, see . try: + from SpecClient_gevent import SpecVariable from SpecClient_gevent.SpecCommand import SpecCommandA from SpecClient_gevent.SpecVariable import SpecVariableA - from SpecClient_gevent import SpecVariable except ImportError: from SpecClient.SpecCommand import SpecCommandA from SpecClient.SpecVariable import SpecVariableA from SpecClient import SpecVariable -from mxcubecore.CommandContainer import CommandObject, ChannelObject - +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/Command/Taco.py b/mxcubecore/Command/Taco.py index 496a520a85..370aa2a26a 100644 --- a/mxcubecore/Command/Taco.py +++ b/mxcubecore/Command/Taco.py @@ -18,15 +18,18 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import logging import copy +import logging +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) from mxcubecore.dispatcher import saferef + from .. import Poller -from mxcubecore.CommandContainer import CommandObject, ChannelObject from .. import TacoDevice_MTSafe as TacoDevice - __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/Command/Tango.py b/mxcubecore/Command/Tango.py index e656a62090..46be4814af 100644 --- a/mxcubecore/Command/Tango.py +++ b/mxcubecore/Command/Tango.py @@ -19,6 +19,7 @@ # along with MXCuBE. If not, see . import logging + import gevent import gevent.event @@ -27,15 +28,15 @@ except ImportError: import queue +import numpy +from mxcubecore import Poller from mxcubecore.CommandContainer import ( - CommandObject, ChannelObject, + CommandObject, ConnectionError, ) -from mxcubecore import Poller from mxcubecore.dispatcher import saferef -import numpy gevent_version = list(map(int, gevent.__version__.split("."))) diff --git a/mxcubecore/Command/Tine.py b/mxcubecore/Command/Tine.py index b666a64708..7ba3218b16 100755 --- a/mxcubecore/Command/Tine.py +++ b/mxcubecore/Command/Tine.py @@ -18,23 +18,26 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . +import logging import sys import time -import logging if sys.version_info[0] == 2: import Queue as queue else: import queue -import weakref -import gevent - -from mxcubecore.CommandContainer import CommandObject, ChannelObject import atexit +import weakref +import gevent import tine +from mxcubecore.CommandContainer import ( + ChannelObject, + CommandObject, +) + class TineCommand(CommandObject): def __init__( diff --git a/mxcubecore/Command/exporter/ExporterClient.py b/mxcubecore/Command/exporter/ExporterClient.py index f251a0ffbd..f608bdb884 100644 --- a/mxcubecore/Command/exporter/ExporterClient.py +++ b/mxcubecore/Command/exporter/ExporterClient.py @@ -21,7 +21,11 @@ """Exporter Client implementation""" import logging -from .StandardClient import StandardClient, ProtocolError + +from .StandardClient import ( + ProtocolError, + StandardClient, +) __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/Command/exporter/ExporterStates.py b/mxcubecore/Command/exporter/ExporterStates.py index 236a90f952..4b90725362 100644 --- a/mxcubecore/Command/exporter/ExporterStates.py +++ b/mxcubecore/Command/exporter/ExporterStates.py @@ -22,6 +22,7 @@ """ from enum import Enum + from mxcubecore.BaseHardwareObjects import HardwareObjectState __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/Command/exporter/MDEvents.py b/mxcubecore/Command/exporter/MDEvents.py index 0fd40accc2..ac8c4b754d 100644 --- a/mxcubecore/Command/exporter/MDEvents.py +++ b/mxcubecore/Command/exporter/MDEvents.py @@ -1,7 +1,9 @@ import sys -import time import threading +import time + from ExporterClient import ExporterClient + from mxcubecore.Command.exporter.StandardClient import PROTOCOL SERVER_ADDRESS = "localhost" diff --git a/mxcubecore/Command/exporter/StandardClient.py b/mxcubecore/Command/exporter/StandardClient.py index 2f53b2180a..a13e6da3a9 100644 --- a/mxcubecore/Command/exporter/StandardClient.py +++ b/mxcubecore/Command/exporter/StandardClient.py @@ -19,8 +19,9 @@ # along with MXCuBE. If not, see . """ ProtocolError and StandardClient implementation""" -import sys import socket +import sys + import gevent import gevent.lock diff --git a/mxcubecore/CommandContainer.py b/mxcubecore/CommandContainer.py index 99226f2b36..874e83409d 100644 --- a/mxcubecore/CommandContainer.py +++ b/mxcubecore/CommandContainer.py @@ -28,14 +28,22 @@ """ from __future__ import absolute_import -from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Union -import weakref import logging +import weakref +from typing import ( + Any, + Callable, + Dict, + Generator, + List, + Optional, + Tuple, + Union, +) from mxcubecore.dispatcher import dispatcher - __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" @@ -803,7 +811,10 @@ def add_command( self.name(), ) - from mxcubecore.Command.Sardana import SardanaCommand, SardanaMacro + from mxcubecore.Command.Sardana import ( + SardanaCommand, + SardanaMacro, + ) if cmd_type == "macro" and doorname is not None: try: diff --git a/mxcubecore/HardwareObjectFileParser.py b/mxcubecore/HardwareObjectFileParser.py index 36d1d3816a..870801d1f8 100644 --- a/mxcubecore/HardwareObjectFileParser.py +++ b/mxcubecore/HardwareObjectFileParser.py @@ -28,7 +28,6 @@ from mxcubecore import BaseHardwareObjects - CURRENT_XML = None new_objects_classes = { diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAAutoProcessing.py b/mxcubecore/HardwareObjects/ALBA/ALBAAutoProcessing.py index 8990d358d9..2e50a29ea6 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAAutoProcessing.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAAutoProcessing.py @@ -1,16 +1,20 @@ -from xaloc import XalocJob -from XSDataCommon import XSDataFile, XSDataString, XSDataInteger -from XSDataAutoprocv1_0 import XSDataAutoprocInput -from mxcubecore.BaseHardwareObjects import HardwareObject -from PyTango import DeviceProxy -import os import logging import math +import os +import sys from datetime import datetime from ALBAClusterJob import ALBAEdnaProcJob +from PyTango import DeviceProxy +from xaloc import XalocJob +from XSDataAutoprocv1_0 import XSDataAutoprocInput +from XSDataCommon import ( + XSDataFile, + XSDataInteger, + XSDataString, +) -import sys +from mxcubecore.BaseHardwareObjects import HardwareObject sys.path.append("/beamlines/bl13/controls/devel/pycharm/ALBAClusterClient") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py b/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py index c426dfabc1..48afa53615 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBABackLight.py @@ -1,9 +1,11 @@ -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject import logging -import gevent import time +import gevent + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject + class ALBABackLight(HardwareObject): def __init__(self, *args): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py b/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py index 25a047bdc2..87e0a4064a 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBABeamInfo.py @@ -20,6 +20,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py b/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py index e781b573a4..c08a534e61 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBACalibration.py @@ -38,10 +38,11 @@ """ -from mxcubecore import HardwareRepository as HWR -from mxcubecore import BaseHardwareObjects import logging +from mxcubecore import BaseHardwareObjects +from mxcubecore import HardwareRepository as HWR + __author__ = "Jordi Andreu" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/ALBACats.py b/mxcubecore/HardwareObjects/ALBA/ALBACats.py index b292f2deff..ebf2ba465b 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBACats.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBACats.py @@ -1,15 +1,16 @@ from __future__ import print_function +import logging +import time + +import gevent + from mxcubecore.HardwareObjects.Cats90 import ( + TOOL_SPINE, Cats90, SampleChangerState, - TOOL_SPINE, ) -import logging -import time -import gevent - TIMEOUT = 3 diff --git a/mxcubecore/HardwareObjects/ALBA/ALBACatsMaint.py b/mxcubecore/HardwareObjects/ALBA/ALBACatsMaint.py index bcff58c5fc..ce2afa8a3f 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBACatsMaint.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBACatsMaint.py @@ -1,6 +1,4 @@ -from mxcubecore.HardwareObjects.abstract.sample_changer.CatsMaint import ( - CatsMaint, -) +from mxcubecore.HardwareObjects.abstract.sample_changer.CatsMaint import CatsMaint class ALBACatsMaint(CatsMaint): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAClusterJob.py b/mxcubecore/HardwareObjects/ALBA/ALBAClusterJob.py index 644eb39522..b450b8c28c 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAClusterJob.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAClusterJob.py @@ -1,10 +1,10 @@ -from XSDataMXCuBEv1_3 import XSDataResultMXCuBE -from xaloc import XalocJob +import logging import os +import sys import time -import logging -import sys +from xaloc import XalocJob +from XSDataMXCuBEv1_3 import XSDataResultMXCuBE sys.path.append("/beamlines/bl13/controls/devel/pycharm/ALBAClusterClient") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBACollect.py b/mxcubecore/HardwareObjects/ALBA/ALBACollect.py index ecfa04b286..06b2ea4ea1 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBACollect.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBACollect.py @@ -19,15 +19,16 @@ """ ALBACollect """ -import os -import time import logging +import os import sys +import time + import gevent -from mxcubecore.TaskUtils import task -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect -from mxcubecore import HardwareRepository as HWR +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task __author__ = "Vicente Rey Bakaikoa" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/ALBADataAnalysis.py b/mxcubecore/HardwareObjects/ALBA/ALBADataAnalysis.py index 143c775033..9483f3f3ab 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBADataAnalysis.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBADataAnalysis.py @@ -1,13 +1,17 @@ -from xaloc import XalocJob -from XSDataCommon import XSDataFile, XSDataString -from XSDataMXCuBEv1_3 import XSDataResultMXCuBE -from mxcubecore.HardwareObjects.EDNACharacterisation import EDNACharacterisation -from PyTango import DeviceProxy +import logging import os +import sys import time -import logging -import sys +from PyTango import DeviceProxy +from xaloc import XalocJob +from XSDataCommon import ( + XSDataFile, + XSDataString, +) +from XSDataMXCuBEv1_3 import XSDataResultMXCuBE + +from mxcubecore.HardwareObjects.EDNACharacterisation import EDNACharacterisation sys.path.append("/beamlines/bl13/controls/devel/pycharm/ALBAClusterClient") diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py b/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py index 3445cc069e..b70ca26b59 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAEnergy.py @@ -1,7 +1,7 @@ import logging -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class ALBAEnergy(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py b/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py index f008b7c8d8..1b821476cd 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAEpsActuator.py @@ -42,10 +42,11 @@ """ -from mxcubecore import HardwareRepository as HWR -from mxcubecore import BaseHardwareObjects import logging +from mxcubecore import BaseHardwareObjects +from mxcubecore import HardwareRepository as HWR + STATE_OUT, STATE_IN, STATE_MOVING, STATE_FAULT, STATE_ALARM, STATE_UNKNOWN = ( 0, 1, diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py b/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py index b11b3a90ee..4f54408c99 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFastShutter.py @@ -42,11 +42,12 @@ """ -from mxcubecore import HardwareRepository as HWR -from mxcubecore import BaseHardwareObjects import logging import time +from mxcubecore import BaseHardwareObjects +from mxcubecore import HardwareRepository as HWR + STATE_OUT, STATE_IN, STATE_MOVING, STATE_FAULT, STATE_ALARM, STATE_UNKNOWN = ( 0, 1, diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFlux.py b/mxcubecore/HardwareObjects/ALBA/ALBAFlux.py index f8e0db95cc..0245a98c2d 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFlux.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFlux.py @@ -1,8 +1,10 @@ -from mxcubecore.HardwareObjects.abstract import AbstractFlux -from mxcubecore.BaseHardwareObjects import HardwareObject -import taurus import logging +import taurus + +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract import AbstractFlux + class ALBAFlux(Device, AbstractFlux.AbstractFlux): def init(self): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFrontEnd.py b/mxcubecore/HardwareObjects/ALBA/ALBAFrontEnd.py index a004079f4e..e27d3f4d12 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFrontEnd.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFrontEnd.py @@ -18,12 +18,13 @@ """ -from mxcubecore import HardwareRepository as HWR -from mxcubecore import BaseHardwareObjects import logging from ALBAEpsActuator import ALBAEpsActuator +from mxcubecore import BaseHardwareObjects +from mxcubecore import HardwareRepository as HWR + class ALBAFrontEnd(ALBAEpsActuator): def init(self): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py b/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py index e66d3489c3..740c2c9868 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAFrontLight.py @@ -1,6 +1,7 @@ +import logging + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -import logging class ALBAFrontLight(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAISPyBClient.py b/mxcubecore/HardwareObjects/ALBA/ALBAISPyBClient.py index a9259d0df6..7e3a242447 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAISPyBClient.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAISPyBClient.py @@ -1,8 +1,9 @@ import logging -from mxcubecore import HardwareRepository as HWR from ISPyBClient import ISPyBClient +from mxcubecore import HardwareRepository as HWR + class ALBAISPyBClient(ISPyBClient): def ldap_login(self, login_name, psd, ldap_connection): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py b/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py index 61be06f712..4f5da536f5 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAMachineInfo.py @@ -56,13 +56,17 @@ import logging import time +from datetime import ( + datetime, + timedelta, +) + from gevent import spawn from urllib2 import urlopen -from datetime import datetime, timedelta + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject - __author__ = "Jordi Andreu" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAMiniDiff.py b/mxcubecore/HardwareObjects/ALBA/ALBAMiniDiff.py index d10b1206e4..1da77d07b5 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAMiniDiff.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAMiniDiff.py @@ -46,15 +46,15 @@ import logging import time + +import gevent + from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, DiffractometerState, + GenericDiffractometer, ) -import gevent - from mxcubecore.model import queue_model_objects - __author__ = "Jordi Andreu" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAPilatus.py b/mxcubecore/HardwareObjects/ALBA/ALBAPilatus.py index 268d009270..78c11f05ce 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBAPilatus.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAPilatus.py @@ -18,16 +18,15 @@ # along with MXCuBE. If not, see . from __future__ import print_function + import logging import time -from mxcubecore.HardwareObjects.abstract.AbstractDetector import ( - AbstractDetector, -) -from mxcubecore.BaseHardwareObjects import HardwareObject - from PyTango.gevent import DeviceProxy +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector + __author__ = "Vicente Rey" __credits__ = ["ALBA"] __version__ = "2.3." diff --git a/mxcubecore/HardwareObjects/ALBA/ALBASession.py b/mxcubecore/HardwareObjects/ALBA/ALBASession.py index b77a640920..34ff01cbe8 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBASession.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBASession.py @@ -1,6 +1,6 @@ +import logging import os import time -import logging from mxcubecore.HardwareObjects import Session from mxcubecore.model import queue_model_objects diff --git a/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py b/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py index 9b8df1e766..3e3924497e 100644 --- a/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBASupervisor.py @@ -1,6 +1,7 @@ +import logging + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -import logging class ALBASupervisor(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py index d6fc2e1d9b..25fe6c9a89 100755 --- a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotor.py @@ -56,11 +56,13 @@ """ -from mxcubecore import BaseHardwareObjects -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor import logging + import PyTango +from mxcubecore import BaseHardwareObjects +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + __author__ = "Bixente Rey" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py index d85b76008b..b78e453bdb 100755 --- a/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py +++ b/mxcubecore/HardwareObjects/ALBA/ALBAZoomMotorAutoBrightness.py @@ -49,9 +49,10 @@ """ +import logging + from mxcubecore import BaseHardwareObjects from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor -import logging __author__ = "Jordi Andreu" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py index 10aef0434e..fb72762acf 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocCalibration.py @@ -2,8 +2,8 @@ Class for reading images from Falcon camera OAV """ -from mxcubecore import HardwareRepository as HWR from mxcubecore import BaseHardwareObjects +from mxcubecore import HardwareRepository as HWR class XalocCalibration(BaseHardwareObjects.HardwareObject): diff --git a/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py b/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py index 742aa44f67..7e28ef504e 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocMachineInfo.py @@ -56,13 +56,17 @@ import logging import time +from datetime import ( + datetime, + timedelta, +) + from gevent import spawn from urllib2 import urlopen -from datetime import datetime, timedelta + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject - __author__ = "Jordi Andreu" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/ALBA/XalocMiniDiff.py b/mxcubecore/HardwareObjects/ALBA/XalocMiniDiff.py index 650a11e8cf..638a20b83f 100644 --- a/mxcubecore/HardwareObjects/ALBA/XalocMiniDiff.py +++ b/mxcubecore/HardwareObjects/ALBA/XalocMiniDiff.py @@ -1,10 +1,10 @@ import logging import time -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, -) -from gevent.event import AsyncResult + import gevent +from gevent.event import AsyncResult + +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer class XalocMiniDiff(GenericDiffractometer): diff --git a/mxcubecore/HardwareObjects/Attenuators.py b/mxcubecore/HardwareObjects/Attenuators.py index 2bdb78789d..6663a91962 100644 --- a/mxcubecore/HardwareObjects/Attenuators.py +++ b/mxcubecore/HardwareObjects/Attenuators.py @@ -19,6 +19,7 @@ import gevent + from mxcubecore.HardwareObjects.abstract.AbstractTransmission import ( AbstractTransmission, ) diff --git a/mxcubecore/HardwareObjects/BeamInfo.py b/mxcubecore/HardwareObjects/BeamInfo.py index f4c1f3dbf1..28966080c2 100644 --- a/mxcubecore/HardwareObjects/BeamInfo.py +++ b/mxcubecore/HardwareObjects/BeamInfo.py @@ -20,8 +20,9 @@ """ import logging -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class BeamInfo(HardwareObject): diff --git a/mxcubecore/HardwareObjects/Beamline.py b/mxcubecore/HardwareObjects/Beamline.py index dd9ab41804..686a1f3f09 100644 --- a/mxcubecore/HardwareObjects/Beamline.py +++ b/mxcubecore/HardwareObjects/Beamline.py @@ -24,10 +24,18 @@ All HardwareObjects """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) + +from typing import ( + Any, + Union, +) -from typing import Union, Any from mxcubecore.dispatcher import dispatcher __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ @@ -36,7 +44,10 @@ import logging -from mxcubecore.BaseHardwareObjects import ConfiguredObject, HardwareObject +from mxcubecore.BaseHardwareObjects import ( + ConfiguredObject, + HardwareObject, +) # NBNB The acq parameter names match the attributes of AcquisitionParameters # Whereas the limit parameter values use more understandable names diff --git a/mxcubecore/HardwareObjects/BeamlineActions.py b/mxcubecore/HardwareObjects/BeamlineActions.py index 799e6e284d..c7243bbca8 100644 --- a/mxcubecore/HardwareObjects/BeamlineActions.py +++ b/mxcubecore/HardwareObjects/BeamlineActions.py @@ -1,22 +1,20 @@ -import sys import ast import importlib +import logging import operator +import sys -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task -from mxcubecore.CommandContainer import CommandObject -from mxcubecore.utils.conversion import camel_to_snake -from mxcubecore import HardwareRepository as HWR +import gevent +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.CommandContainer import ( - CommandObject, - TWO_STATE_COMMAND_T, ARGUMENT_TYPE_LIST, + TWO_STATE_COMMAND_T, + CommandObject, ) - -import gevent -import logging +from mxcubecore.TaskUtils import task +from mxcubecore.utils.conversion import camel_to_snake class ControllerCommand(CommandObject): diff --git a/mxcubecore/HardwareObjects/Bliss.py b/mxcubecore/HardwareObjects/Bliss.py index 4e046796b2..a326da037a 100644 --- a/mxcubecore/HardwareObjects/Bliss.py +++ b/mxcubecore/HardwareObjects/Bliss.py @@ -3,11 +3,16 @@ """ import itertools + import gevent import numpy -from mxcubecore.BaseHardwareObjects import HardwareObject from bliss.config import static -from bliss.data.node import DataNode, get_or_create_node +from bliss.data.node import ( + DataNode, + get_or_create_node, +) + +from mxcubecore.BaseHardwareObjects import HardwareObject __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/BlissActuator.py b/mxcubecore/HardwareObjects/BlissActuator.py index fcaf3a2d5d..f41a1cc4d0 100644 --- a/mxcubecore/HardwareObjects/BlissActuator.py +++ b/mxcubecore/HardwareObjects/BlissActuator.py @@ -11,9 +11,7 @@ import logging from warnings import warn -from mxcubecore.HardwareObjects.abstract.AbstractActuator import ( - AbstractActuator, -) +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/BlissEnergy.py b/mxcubecore/HardwareObjects/BlissEnergy.py index 72398bd820..30ac2e609d 100644 --- a/mxcubecore/HardwareObjects/BlissEnergy.py +++ b/mxcubecore/HardwareObjects/BlissEnergy.py @@ -37,9 +37,11 @@ """ import logging import math + from gevent import spawn -from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/BlissHutchTrigger.py b/mxcubecore/HardwareObjects/BlissHutchTrigger.py index f3c0630b93..c6934316f7 100644 --- a/mxcubecore/HardwareObjects/BlissHutchTrigger.py +++ b/mxcubecore/HardwareObjects/BlissHutchTrigger.py @@ -1,7 +1,9 @@ +import logging import sys + import gevent -import logging import PyTango.gevent + from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/BlissMotor.py b/mxcubecore/HardwareObjects/BlissMotor.py index 4f4b2b41e8..18aa10f781 100644 --- a/mxcubecore/HardwareObjects/BlissMotor.py +++ b/mxcubecore/HardwareObjects/BlissMotor.py @@ -27,9 +27,11 @@ """ import enum + from bliss.config import static -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/BlissMotorWPositions.py b/mxcubecore/HardwareObjects/BlissMotorWPositions.py index 1c275ad79e..27706824c3 100644 --- a/mxcubecore/HardwareObjects/BlissMotorWPositions.py +++ b/mxcubecore/HardwareObjects/BlissMotorWPositions.py @@ -1,6 +1,7 @@ +import logging from warnings import warn + from BlissMotor import BlissMotor -import logging class BlissMotorWPositions(BlissMotor): diff --git a/mxcubecore/HardwareObjects/BlissNState.py b/mxcubecore/HardwareObjects/BlissNState.py index 1eb9ce45b0..5b31fc1f26 100644 --- a/mxcubecore/HardwareObjects/BlissNState.py +++ b/mxcubecore/HardwareObjects/BlissNState.py @@ -29,6 +29,7 @@ """ from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates from mxcubecore.HardwareObjects.abstract.AbstractNState import ( AbstractNState, diff --git a/mxcubecore/HardwareObjects/BlissShutter.py b/mxcubecore/HardwareObjects/BlissShutter.py index 2b294b7462..0b8d8c31e6 100644 --- a/mxcubecore/HardwareObjects/BlissShutter.py +++ b/mxcubecore/HardwareObjects/BlissShutter.py @@ -30,11 +30,15 @@ """ -from enum import Enum, unique +from enum import ( + Enum, + unique, +) + import gevent -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Camera.py b/mxcubecore/HardwareObjects/Camera.py index 34e9ce03ef..c58d48dc48 100644 --- a/mxcubecore/HardwareObjects/Camera.py +++ b/mxcubecore/HardwareObjects/Camera.py @@ -16,13 +16,17 @@ """ -from mxcubecore import BaseHardwareObjects -from mxcubecore import CommandContainer -import gevent import logging import os -import time import sys +import time + +import gevent + +from mxcubecore import ( + BaseHardwareObjects, + CommandContainer, +) try: from Qub.CTools.qttools import BgrImageMmap diff --git a/mxcubecore/HardwareObjects/Cats90.py b/mxcubecore/HardwareObjects/Cats90.py index 329f1ee82e..d4623894dd 100644 --- a/mxcubecore/HardwareObjects/Cats90.py +++ b/mxcubecore/HardwareObjects/Cats90.py @@ -20,9 +20,11 @@ """ from __future__ import print_function + +import logging import time + import PyTango -import logging from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( Container, diff --git a/mxcubecore/HardwareObjects/CatsBessy.py b/mxcubecore/HardwareObjects/CatsBessy.py index cbc5e4ce03..10eebc7b93 100644 --- a/mxcubecore/HardwareObjects/CatsBessy.py +++ b/mxcubecore/HardwareObjects/CatsBessy.py @@ -1,12 +1,13 @@ +import time + from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( - Container, SC3, + Container, Sample, SampleChanger, SampleChangerState, gevent, ) -import time class Pin(Sample): diff --git a/mxcubecore/HardwareObjects/CatsMaint.py b/mxcubecore/HardwareObjects/CatsMaint.py index fe5c19d8a3..42841a38ec 100644 --- a/mxcubecore/HardwareObjects/CatsMaint.py +++ b/mxcubecore/HardwareObjects/CatsMaint.py @@ -13,15 +13,14 @@ """ import logging - -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject - -import gevent import time +import gevent from PyTango import DeviceProxy +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task + __author__ = "Jie Nan" __credits__ = ["The MxCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/CentringMath.py b/mxcubecore/HardwareObjects/CentringMath.py index d65ea5b3ff..5f6b825392 100644 --- a/mxcubecore/HardwareObjects/CentringMath.py +++ b/mxcubecore/HardwareObjects/CentringMath.py @@ -1,8 +1,10 @@ -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import Procedure +import logging import math + import numpy -import logging + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import Procedure class CentringMath(Procedure): diff --git a/mxcubecore/HardwareObjects/DESY/Centring.py b/mxcubecore/HardwareObjects/DESY/Centring.py index bd03fdd2e5..384e0f3d5a 100644 --- a/mxcubecore/HardwareObjects/DESY/Centring.py +++ b/mxcubecore/HardwareObjects/DESY/Centring.py @@ -23,16 +23,16 @@ import gevent - -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.BaseHardwareObjects import HardwareObject -from gevent import Timeout import numpy - +from gevent import Timeout # import DeviceProxy function and DevState: -from PyTango import DevState -from PyTango import DeviceProxy +from PyTango import ( + DeviceProxy, + DevState, +) + +from mxcubecore.BaseHardwareObjects import HardwareObject last_centred_position = [200, 200] diff --git a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py index bdcbfddad1..b236441d39 100644 --- a/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py +++ b/mxcubecore/HardwareObjects/DESY/DigitalZoomMotor.py @@ -25,9 +25,12 @@ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor -from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates +from mxcubecore.HardwareObjects.abstract.AbstractMotor import ( + AbstractMotor, + MotorStates, +) class DigitalZoomMotor(AbstractMotor, HardwareObject): diff --git a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py index baec00edc4..7e953c6607 100644 --- a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py +++ b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py @@ -24,10 +24,11 @@ __email__ = "jan.meyer@desy.de" -import gevent import json import traceback +import gevent + try: from httplib import HTTPConnection except ImportError: @@ -41,10 +42,14 @@ traceback.print_exc() redis_flag = False -from mxcubecore.utils.qt_import import QImage, QPixmap, QPoint -from mxcubecore.utils.conversion import string_types -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice +from mxcubecore.utils.conversion import string_types +from mxcubecore.utils.qt_import import ( + QImage, + QPixmap, + QPoint, +) class MjpgStreamVideo(AbstractVideoDevice): diff --git a/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py b/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py index c3c28dc2ab..88c8195b90 100644 --- a/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py +++ b/mxcubecore/HardwareObjects/DESY/P11AlbulaView.py @@ -21,12 +21,13 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from mxcubecore.BaseHardwareObjects import HardwareObject - import sys import time + from PIL import Image +from mxcubecore.BaseHardwareObjects import HardwareObject + sys.path.append("/opt/dectris/albula/4.0/python/") diff --git a/mxcubecore/HardwareObjects/DESY/P11BackLight.py b/mxcubecore/HardwareObjects/DESY/P11BackLight.py index bc541bffcf..4bc7f5c0ea 100644 --- a/mxcubecore/HardwareObjects/DESY/P11BackLight.py +++ b/mxcubecore/HardwareObjects/DESY/P11BackLight.py @@ -21,17 +21,24 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from enum import Enum, unique -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState -from mxcubecore.BaseHardwareObjects import HardwareObjectState +from enum import ( + Enum, + unique, +) +from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState __credits__ = ["DESY P11"] __license__ = "LGPLv3+" __category__ = "General" import time -from enum import Enum, unique +from enum import ( + Enum, + unique, +) + from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter diff --git a/mxcubecore/HardwareObjects/DESY/P11Beam.py b/mxcubecore/HardwareObjects/DESY/P11Beam.py index ab5560d065..ab808ca219 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Beam.py +++ b/mxcubecore/HardwareObjects/DESY/P11Beam.py @@ -23,11 +23,14 @@ __credits__ = ["DESY P11"] __category__ = "General" -from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam -from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape -from mxcubecore.BaseHardwareObjects import HardwareObjectState import numpy as np +from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractBeam import ( + AbstractBeam, + BeamShape, +) + class P11Beam(AbstractBeam): def init(self): diff --git a/mxcubecore/HardwareObjects/DESY/P11BeamStop.py b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py index 24e4c9ee13..715158e560 100644 --- a/mxcubecore/HardwareObjects/DESY/P11BeamStop.py +++ b/mxcubecore/HardwareObjects/DESY/P11BeamStop.py @@ -21,11 +21,12 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from mxcubecore.HardwareObjects.NState import NState -from mxcubecore.BaseHardwareObjects import HardwareObjectState import ast import time +from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.NState import NState + class P11BeamStop(NState): default_delta = 0.1 diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 2c95b2704f..4f59a005fb 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -22,23 +22,24 @@ __license__ = "LGPLv3+" import errno +import logging +import math +import os import socket -import time +import subprocess import sys -import os -import math -import logging +import time import traceback + +import gevent import h5py import numpy as np import psutil -import subprocess -import gevent -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect from mxcubecore import HardwareRepository as HWR -from mxcubecore.TaskUtils import task from mxcubecore.Command.Tango import DeviceProxy +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task FILE_TIMEOUT = 5 diff --git a/mxcubecore/HardwareObjects/DESY/P11Collimator.py b/mxcubecore/HardwareObjects/DESY/P11Collimator.py index 7a7bcf4460..646788db2a 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collimator.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collimator.py @@ -22,9 +22,10 @@ __license__ = "LGPLv3+" import ast -from mxcubecore.HardwareObjects.NState import NState from collections import OrderedDict + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.NState import NState class P11Collimator(NState): diff --git a/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py b/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py index 9a8fa5f92d..04a3e4900a 100644 --- a/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py +++ b/mxcubecore/HardwareObjects/DESY/P11DetectorCover.py @@ -22,12 +22,12 @@ __license__ = "LGPLv3+" import time +from enum import Enum + import gevent -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter from mxcubecore.BaseHardwareObjects import HardwareObjectState -from enum import Enum - +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __credits__ = ["DESY P11"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py b/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py index 4ff0e65a4d..bf861c352b 100644 --- a/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py +++ b/mxcubecore/HardwareObjects/DESY/P11DetectorDistance.py @@ -23,9 +23,10 @@ __credits__ = ["DESY P11"] __category__ = "Motor" -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor import time +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + class P11DetectorDistance(AbstractMotor): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py b/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py index 2189ee9d81..32c31b8f08 100644 --- a/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py +++ b/mxcubecore/HardwareObjects/DESY/P11DoorInterlock.py @@ -21,11 +21,12 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from mxcubecore.BaseHardwareObjects import HardwareObject import logging import sys import urllib.request +from mxcubecore.BaseHardwareObjects import HardwareObject + __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py b/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py index e015bc3326..bd304f138a 100644 --- a/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py +++ b/mxcubecore/HardwareObjects/DESY/P11EDNACharacterisation.py @@ -21,39 +21,41 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -import os +import copy import logging +import os import time -import copy -from mxcubecore.model import queue_model_objects as qmo -from mxcubecore.model import queue_model_enumerables as qme -from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( - SecureXMLRpcRequestHandler, +from XSDataCommon import ( + XSDataAngle, + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataFlux, + XSDataImage, + XSDataInteger, + XSDataLength, + XSDataSize, + XSDataString, + XSDataTime, + XSDataWavelength, +) +from XSDataMXCuBEv1_4 import ( + XSDataInputMXCuBE, + XSDataMXCuBEDataSet, + XSDataResultMXCuBE, ) + from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractCharacterisation import ( AbstractCharacterisation, ) - from mxcubecore.HardwareObjects.EDNACharacterisation import EDNACharacterisation - -from XSDataMXCuBEv1_4 import XSDataInputMXCuBE -from XSDataMXCuBEv1_4 import XSDataMXCuBEDataSet -from XSDataMXCuBEv1_4 import XSDataResultMXCuBE - -from XSDataCommon import XSDataAngle -from XSDataCommon import XSDataBoolean -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataImage -from XSDataCommon import XSDataFlux -from XSDataCommon import XSDataLength -from XSDataCommon import XSDataTime -from XSDataCommon import XSDataWavelength -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataSize -from XSDataCommon import XSDataString +from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( + SecureXMLRpcRequestHandler, +) +from mxcubecore.model import queue_model_enumerables as qme +from mxcubecore.model import queue_model_objects as qmo # from edna_test_data import EDNA_DEFAULT_INPUT # from edna_test_data import EDNA_TEST_DATA diff --git a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py index 700707996e..577c384cee 100644 --- a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py +++ b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py @@ -22,6 +22,7 @@ __license__ = "LGPLv3+" import gevent + from mxcubecore.Command.Tango import DeviceProxy from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector diff --git a/mxcubecore/HardwareObjects/DESY/P11Energy.py b/mxcubecore/HardwareObjects/DESY/P11Energy.py index 891ea7b534..e8d7e24852 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Energy.py +++ b/mxcubecore/HardwareObjects/DESY/P11Energy.py @@ -21,11 +21,11 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy -from mxcubecore import HardwareRepository as HWR - import logging +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy + log = logging.getLogger("HWR") diff --git a/mxcubecore/HardwareObjects/DESY/P11FastShutter.py b/mxcubecore/HardwareObjects/DESY/P11FastShutter.py index ae81fc6a2e..7ef713bdb4 100644 --- a/mxcubecore/HardwareObjects/DESY/P11FastShutter.py +++ b/mxcubecore/HardwareObjects/DESY/P11FastShutter.py @@ -22,15 +22,16 @@ __license__ = "LGPLv3+" from enum import Enum -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState -from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractNState __credits__ = ["DESY P11"] __license__ = "LGPLv3+" __category__ = "General" from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter diff --git a/mxcubecore/HardwareObjects/DESY/P11Flux.py b/mxcubecore/HardwareObjects/DESY/P11Flux.py index 27673432c7..d9b040dfe6 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Flux.py +++ b/mxcubecore/HardwareObjects/DESY/P11Flux.py @@ -22,12 +22,13 @@ __license__ = "LGPLv3+" import numpy as np -from scipy.interpolate import Rbf, interp1d - -from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux +from scipy.interpolate import ( + Rbf, + interp1d, +) from mxcubecore import HardwareRepository as HWR - +from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux __credits__ = ["MXCuBE collaboration"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py index 4afe4cb053..53a01bfd36 100644 --- a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py +++ b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py @@ -23,12 +23,13 @@ import logging import ssl -from mxcubecore.HardwareObjects.ISPyBClient import ISPyBClient -from mxcubecore import HardwareRepository as HWR -from suds import WebFault from urllib.error import URLError + +from suds import WebFault from suds.transport import TransportError +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.ISPyBClient import ISPyBClient ssl._create_default_https_context = ssl._create_unverified_context diff --git a/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py b/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py index 049475123c..b24e898d27 100644 --- a/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py +++ b/mxcubecore/HardwareObjects/DESY/P11MachineInfo.py @@ -22,11 +22,15 @@ __license__ = "LGPLv3+" import logging + import gevent +from PyQt5.QtCore import ( + QObject, + pyqtSignal, +) + from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo from mxcubecore.HardwareObjects.TangoMachineInfo import TangoMachineInfo -from mxcubecore.HardwareObjects.TangoMachineInfo import TangoMachineInfo -from PyQt5.QtCore import QObject, pyqtSignal class P11MachineInfo(TangoMachineInfo, QObject): diff --git a/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py b/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py index 7f09037448..eebca5e9bd 100644 --- a/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py +++ b/mxcubecore/HardwareObjects/DESY/P11NanoDiff.py @@ -20,34 +20,42 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" +import logging +import math +import os +import pickle +import sys +import time +from enum import ( + Enum, + unique, +) + +import gevent +import lmfit +import numpy as np +import sample_centring +import simplejpeg from gevent.event import AsyncResult +from tango import ( + DevFailed, + DeviceProxy, +) -from tango import DeviceProxy, DevFailed -from mxcubecore.TaskUtils import task +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.HardwareObjects.GenericDiffractometer import ( DiffractometerState, GenericDiffractometer, ) - -from mxcubecore.BaseHardwareObjects import HardwareObjectState -from mxcubecore import HardwareRepository as HWR -from enum import Enum, unique -import pickle -import lmfit -import simplejpeg -import numpy as np -import sample_centring -import gevent -import time -import math -import os -import sys -import logging +from mxcubecore.TaskUtils import task murko_path = os.getenv("MURKO_PATH") sys.path.insert(1, murko_path) -from murko import get_predictions, plot_analysis - +from murko import ( + get_predictions, + plot_analysis, +) if sys.version_info[0] >= 3: unicode = str diff --git a/mxcubecore/HardwareObjects/DESY/P11Pinhole.py b/mxcubecore/HardwareObjects/DESY/P11Pinhole.py index 2d36b7a194..2cb8944337 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Pinhole.py +++ b/mxcubecore/HardwareObjects/DESY/P11Pinhole.py @@ -21,9 +21,10 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from mxcubecore.HardwareObjects.NState import NState import ast + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.NState import NState class P11Pinhole(NState): diff --git a/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py b/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py index f737e0e7d3..75a9e95f3e 100644 --- a/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py +++ b/mxcubecore/HardwareObjects/DESY/P11SampleChanger.py @@ -22,16 +22,16 @@ __license__ = "LGPLv3+" -import time import logging +import time +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( SampleChanger, SampleChangerState, ) from mxcubecore.HardwareObjects.abstract.sample_changer import Container from mxcubecore.TaskUtils import task -from mxcubecore import HardwareRepository as HWR class P11SampleChanger(SampleChanger): diff --git a/mxcubecore/HardwareObjects/DESY/P11Session.py b/mxcubecore/HardwareObjects/DESY/P11Session.py index e70dd32226..76d64dd8e3 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Session.py +++ b/mxcubecore/HardwareObjects/DESY/P11Session.py @@ -21,15 +21,17 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" +import glob +import json import os import time -import json -import glob -import yaml +from configparser import ConfigParser from datetime import date from select import EPOLL_CLOEXEC + +import yaml + from mxcubecore.HardwareObjects.Session import Session -from configparser import ConfigParser PATH_BEAMTIME = "/gpfs/current" PATH_COMMISSIONING = "/gpfs/commissioning" diff --git a/mxcubecore/HardwareObjects/DESY/P11Shutter.py b/mxcubecore/HardwareObjects/DESY/P11Shutter.py index bd490b7040..40e88ac917 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Shutter.py +++ b/mxcubecore/HardwareObjects/DESY/P11Shutter.py @@ -22,13 +22,17 @@ __license__ = "LGPLv3+" import time -import gevent import urllib -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter +from enum import ( + Enum, + unique, +) + +import gevent + import mxcubecore.HardwareObjects.abstract.AbstractShutter as absshut from mxcubecore.BaseHardwareObjects import HardwareObjectState -from enum import Enum, unique - +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __credits__ = ["DESY P11"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/DESY/P11Transmission.py b/mxcubecore/HardwareObjects/DESY/P11Transmission.py index 34f9d6bff4..be14499117 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Transmission.py +++ b/mxcubecore/HardwareObjects/DESY/P11Transmission.py @@ -21,9 +21,11 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -import gevent import logging import time + +import gevent + from mxcubecore.HardwareObjects.abstract.AbstractTransmission import ( AbstractTransmission, ) diff --git a/mxcubecore/HardwareObjects/DESY/P11YagDiode.py b/mxcubecore/HardwareObjects/DESY/P11YagDiode.py index 820346fcad..dfae32a780 100644 --- a/mxcubecore/HardwareObjects/DESY/P11YagDiode.py +++ b/mxcubecore/HardwareObjects/DESY/P11YagDiode.py @@ -22,9 +22,10 @@ __license__ = "LGPLv3+" import ast -from mxcubecore.HardwareObjects.NState import NState from collections import OrderedDict + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.NState import NState class P11YagDiode(NState): diff --git a/mxcubecore/HardwareObjects/DESY/P11Zoom.py b/mxcubecore/HardwareObjects/DESY/P11Zoom.py index b9a1deb9e0..ce63e530c3 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Zoom.py +++ b/mxcubecore/HardwareObjects/DESY/P11Zoom.py @@ -21,11 +21,13 @@ __copyright__ = """Copyright The MXCuBE Collaboration""" __license__ = "LGPLv3+" -from enum import Enum import ast +from enum import Enum -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState -from mxcubecore.HardwareObjects.abstract.AbstractNState import BaseValueEnum +from mxcubecore.HardwareObjects.abstract.AbstractNState import ( + AbstractNState, + BaseValueEnum, +) redis_flag = False try: diff --git a/mxcubecore/HardwareObjects/DataPublisher.py b/mxcubecore/HardwareObjects/DataPublisher.py index 1ab7551634..6906464e60 100644 --- a/mxcubecore/HardwareObjects/DataPublisher.py +++ b/mxcubecore/HardwareObjects/DataPublisher.py @@ -16,12 +16,15 @@ # # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import redis import json -import gevent import logging +from enum import ( + Enum, + unique, +) -from enum import Enum, unique +import gevent +import redis from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/DozorOnlineProcessing.py b/mxcubecore/HardwareObjects/DozorOnlineProcessing.py index b830c22a16..dea6a38cc2 100644 --- a/mxcubecore/HardwareObjects/DozorOnlineProcessing.py +++ b/mxcubecore/HardwareObjects/DozorOnlineProcessing.py @@ -18,17 +18,18 @@ # along with MXCuBE. If not, see . -from XSDataCommon import XSDataBoolean -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataString +from XSDataCommon import ( + XSDataBoolean, + XSDataDouble, + XSDataInteger, + XSDataString, +) from XSDataControlDozorv1_1 import XSDataInputControlDozor +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractOnlineProcessing import ( AbstractOnlineProcessing, ) -from mxcubecore import HardwareRepository as HWR - __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EDNACharacterisation.py b/mxcubecore/HardwareObjects/EDNACharacterisation.py index c419fcc7e2..37661239f4 100644 --- a/mxcubecore/HardwareObjects/EDNACharacterisation.py +++ b/mxcubecore/HardwareObjects/EDNACharacterisation.py @@ -1,37 +1,39 @@ -import os +import binascii import copy import logging -import binascii +import os import subprocess import time -from mxcubecore.model import queue_model_objects as qmo -from mxcubecore.model import queue_model_enumerables as qme - -from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( - SecureXMLRpcRequestHandler, +from XSDataCommon import ( + XSDataAngle, + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataFlux, + XSDataImage, + XSDataInteger, + XSDataLength, + XSDataSize, + XSDataString, + XSDataTime, + XSDataWavelength, ) +from XSDataMXCuBEv1_4 import ( + XSDataInputMXCuBE, + XSDataMXCuBEDataSet, + XSDataResultMXCuBE, +) + from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractCharacterisation import ( AbstractCharacterisation, ) - -from XSDataMXCuBEv1_4 import XSDataInputMXCuBE -from XSDataMXCuBEv1_4 import XSDataMXCuBEDataSet -from XSDataMXCuBEv1_4 import XSDataResultMXCuBE - -from XSDataCommon import XSDataAngle -from XSDataCommon import XSDataBoolean -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataImage -from XSDataCommon import XSDataFlux -from XSDataCommon import XSDataLength -from XSDataCommon import XSDataTime -from XSDataCommon import XSDataWavelength -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataSize -from XSDataCommon import XSDataString +from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( + SecureXMLRpcRequestHandler, +) +from mxcubecore.model import queue_model_enumerables as qme +from mxcubecore.model import queue_model_objects as qmo # from edna_test_data import EDNA_DEFAULT_INPUT # from edna_test_data import EDNA_TEST_DATA diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLAperture.py b/mxcubecore/HardwareObjects/EMBL/EMBLAperture.py index e1f29c2427..e750231432 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLAperture.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLAperture.py @@ -19,9 +19,7 @@ """Inherited from AbstracAperture""" -from mxcubecore.HardwareObjects.abstract.AbstractAperture import ( - AbstractAperture, -) +from mxcubecore.HardwareObjects.abstract.AbstractAperture import AbstractAperture __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBSD.py b/mxcubecore/HardwareObjects/EMBL/EMBLBSD.py index 1ad3689e03..eca40ba42b 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBSD.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBSD.py @@ -19,14 +19,12 @@ """EMBLBSD (Beam shaping device) represents a diffractometer without a gonio""" -import time import logging -import gevent +import time -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, -) +import gevent +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeam.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeam.py index 0f5729adaa..76fd5ceee8 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeam.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeam.py @@ -23,12 +23,11 @@ It can include aperture, slits and/or beam focusing hwobj """ import ast -import sys import logging +import sys from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamCentering.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamCentering.py index 35ce6e36bc..96ab0315fd 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamCentering.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamCentering.py @@ -19,13 +19,13 @@ import logging from time import sleep + import gevent -from scipy.interpolate import interp1d import tine +from scipy.interpolate import interp1d -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamFocusing.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamFocusing.py index f25bca65ca..ad55979160 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamFocusing.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamFocusing.py @@ -20,10 +20,9 @@ import logging import gevent - from tine import query as tinequery -from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamline.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamline.py index f8c392b7b5..5ae39a0c51 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamline.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamline.py @@ -24,14 +24,19 @@ All HardwareObjects """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" __author__ = "Rasmus H Fogh" from collections import OrderedDict + from mxcubecore.HardwareObjects.Beamline import Beamline diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamlineTest.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamlineTest.py index edee56f9e2..10142a1dfa 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamlineTest.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamlineTest.py @@ -17,31 +17,30 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import tine -import numpy -import gevent import logging +import os import tempfile - -import numpy as np - - from csv import reader -from time import sleep from datetime import datetime from random import random -from scipy.interpolate import interp1d -from matplotlib.figure import Figure +from time import sleep + +import gevent +import numpy +import numpy as np +import tine from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure +from scipy.interpolate import interp1d + +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects import SimpleHTML # try: # import pdfkit # except Exception: # logging.getLogger("HWR").warning("pdfkit not available") -from mxcubecore.HardwareObjects import SimpleHTML -from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py b/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py index bf06c9213e..969506e741 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLBeamstop.py @@ -20,7 +20,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor - __credits__ = ["EMBL Hamburg"] __version__ = "2.3." __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLCRL.py b/mxcubecore/HardwareObjects/EMBL/EMBLCRL.py index 8b39685e43..0f8269b21a 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLCRL.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLCRL.py @@ -19,13 +19,13 @@ """EMBLCRL""" -import math import logging +import math + import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLCollect.py b/mxcubecore/HardwareObjects/EMBL/EMBLCollect.py index 1ad690323c..a5d753eee9 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLCollect.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLCollect.py @@ -21,11 +21,9 @@ import os -from mxcubecore.TaskUtils import task -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect - from mxcubecore import HardwareRepository as HWR - +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLDetector.py b/mxcubecore/HardwareObjects/EMBL/EMBLDetector.py index e5985eeac6..c8bc0e73e9 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLDetector.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLDetector.py @@ -24,10 +24,7 @@ import gevent -from mxcubecore.HardwareObjects.abstract.AbstractDetector import ( - AbstractDetector, -) - +from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py b/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py index 990c46b89b..0ceab99bb3 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLDoorInterlock.py @@ -18,10 +18,11 @@ # along with MXCuBE. If not, see . import logging + import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLEnergy.py b/mxcubecore/HardwareObjects/EMBL/EMBLEnergy.py index be87c5b821..e9190d10a7 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLEnergy.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLEnergy.py @@ -20,11 +20,11 @@ """EMBLEnergy""" import logging + import gevent from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLEnergyScan.py b/mxcubecore/HardwareObjects/EMBL/EMBLEnergyScan.py index 959b6f476a..114cdaab6e 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLEnergyScan.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLEnergyScan.py @@ -17,23 +17,20 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import time import logging +import os import subprocess +import time import gevent import numpy as np -from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure +from mxcubecore import HardwareRepository as HWR from mxcubecore import TaskUtils -from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import ( - AbstractEnergyScan, -) from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR - +from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import AbstractEnergyScan __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLExporterClient.py b/mxcubecore/HardwareObjects/EMBL/EMBLExporterClient.py index dd1faf95bc..624419ca4c 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLExporterClient.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLExporterClient.py @@ -23,7 +23,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.Command import Exporter - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLFlux.py b/mxcubecore/HardwareObjects/EMBL/EMBLFlux.py index bc0f5ddc12..2aa5a3c043 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLFlux.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLFlux.py @@ -17,19 +17,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import tine -import numpy -import gevent import logging - from copy import deepcopy from datetime import datetime -from scipy.interpolate import interp1d -from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux +import gevent +import numpy +import tine +from scipy.interpolate import interp1d from mxcubecore import HardwareRepository as HWR - +from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py b/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py index e1d3940c75..4ec8e28a7b 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLImageTracking.py @@ -25,7 +25,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLMachineInfo.py b/mxcubecore/HardwareObjects/EMBL/EMBLMachineInfo.py index 81620c0092..83b43710e1 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLMachineInfo.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLMachineInfo.py @@ -23,9 +23,9 @@ information). Value limits are included """ +import logging import os import time -import logging try: from urllib2 import urlopen @@ -33,13 +33,15 @@ from urllib.request import urlopen from collections import OrderedDict -from datetime import datetime, timedelta -from gevent import spawn +from datetime import ( + datetime, + timedelta, +) -from mxcubecore.BaseHardwareObjects import HardwareObject +from gevent import spawn from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLMiniDiff.py b/mxcubecore/HardwareObjects/EMBL/EMBLMiniDiff.py index bc9f96eded..64c7c3b981 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLMiniDiff.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLMiniDiff.py @@ -17,12 +17,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import time -import gevent import logging - +import time from math import sqrt +import gevent + try: import lucid3 as lucid except ImportError: @@ -33,12 +33,9 @@ "Could not find autocentring library, automatic centring is disabled" ) -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, -) -from mxcubecore.TaskUtils import task from mxcubecore import HardwareRepository as HWR - +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer +from mxcubecore.TaskUtils import task __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py b/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py index cc8c27e286..e5608a9aa5 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLMotorsGroup.py @@ -76,14 +76,13 @@ """ -import time import logging +import time import gevent - import tine -from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLOfflineProcessing.py b/mxcubecore/HardwareObjects/EMBL/EMBLOfflineProcessing.py index 7f5a9f4e68..eb56f189e4 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLOfflineProcessing.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLOfflineProcessing.py @@ -16,22 +16,21 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import time import logging +import os import subprocess +import time import gevent from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.XSDataAutoprocv1_0 import XSDataAutoprocInput from mxcubecore.HardwareObjects.XSDataCommon import ( XSDataDouble, XSDataFile, XSDataInteger, XSDataString, ) -from mxcubecore.HardwareObjects.XSDataAutoprocv1_0 import XSDataAutoprocInput - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLOnlineProcessing.py b/mxcubecore/HardwareObjects/EMBL/EMBLOnlineProcessing.py index 98f909b4c0..41aedd912b 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLOnlineProcessing.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLOnlineProcessing.py @@ -22,18 +22,18 @@ EMBLOnlineProcessing """ -import os import ast import logging +import os import subprocess -import numpy as np import gevent +import numpy as np +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractOnlineProcessing import ( AbstractOnlineProcessing, ) - from mxcubecore.HardwareObjects.XSDataCommon import ( XSDataBoolean, XSDataDouble, @@ -41,14 +41,11 @@ XSDataString, ) from mxcubecore.HardwareObjects.XSDataControlDozorv1_1 import ( + XSDataControlImageDozor, XSDataInputControlDozor, XSDataResultControlDozor, - XSDataControlImageDozor, ) - -from mxcubecore import HardwareRepository as HWR - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py b/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py index 88807f2968..82ba777c7c 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLPPUControl.py @@ -2,7 +2,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLQueueEntry.py b/mxcubecore/HardwareObjects/EMBL/EMBLQueueEntry.py index 86bb909e29..ea8ae195fa 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLQueueEntry.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLQueueEntry.py @@ -23,14 +23,13 @@ import logging +from mxcubecore import HardwareRepository as HWR from mxcubecore.dispatcher import dispatcher from mxcubecore.queue_entry.base_queue_entry import ( + QUEUE_ENTRY_STATUS, BaseQueueEntry, QueueExecutionException, - QUEUE_ENTRY_STATUS, ) -from mxcubecore import HardwareRepository as HWR - __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLSSXChip.py b/mxcubecore/HardwareObjects/EMBL/EMBLSSXChip.py index 2b0bdc55ba..73a583a498 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLSSXChip.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLSSXChip.py @@ -19,9 +19,9 @@ import logging -from mxcubecore.utils import qt_import from mxcubecore.HardwareObjects import QtGraphicsLib as GraphicsLib from mxcubecore.HardwareObjects.QtGraphicsManager import QtGraphicsManager +from mxcubecore.utils import qt_import SEQ_ITEM_COLORS = ( qt_import.QColor(204, 255, 204), diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLSafetyShutter.py b/mxcubecore/HardwareObjects/EMBL/EMBLSafetyShutter.py index b98a788f21..000dd16d6c 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLSafetyShutter.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLSafetyShutter.py @@ -20,10 +20,13 @@ """EMBLSafetyShutter""" import logging -from enum import Enum, unique -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter -from mxcubecore.BaseHardwareObjects import HardwareObjectState +from enum import ( + Enum, + unique, +) +from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLSession.py b/mxcubecore/HardwareObjects/EMBL/EMBLSession.py index 9c71375f7a..ca398e6b18 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLSession.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLSession.py @@ -28,7 +28,6 @@ from mxcubecore.HardwareObjects.Session import Session - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLSlitBox.py b/mxcubecore/HardwareObjects/EMBL/EMBLSlitBox.py index bfb9b0c069..91f6a8adfa 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLSlitBox.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLSlitBox.py @@ -72,7 +72,6 @@ from mxcubecore.HardwareObjects.abstract.AbstractSlits import AbstractSlits - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "Motor" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLTableMotor.py b/mxcubecore/HardwareObjects/EMBL/EMBLTableMotor.py index b06151a3a8..2883706eb5 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLTableMotor.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLTableMotor.py @@ -19,10 +19,10 @@ """EMBLTableMotor""" -import time import atexit import logging import socket +import time from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLTransfocator.py b/mxcubecore/HardwareObjects/EMBL/EMBLTransfocator.py index ef1fde6926..b4bf816e82 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLTransfocator.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLTransfocator.py @@ -20,11 +20,11 @@ """EMBLTransfocator""" import logging + import gevent from mxcubecore.BaseHardwareObjects import HardwareObject - __credits__ = ["EMBL Hamburg"] __category__ = "General" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLXRFSpectrum.py b/mxcubecore/HardwareObjects/EMBL/EMBLXRFSpectrum.py index 5d62fc57b1..d951769ada 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLXRFSpectrum.py @@ -18,15 +18,12 @@ # along with MXCuBE. If not, see . import logging -import gevent -from mxcubecore.HardwareObjects.abstract.AbstractXRFSpectrum import ( - AbstractXRFSpectrum, -) -from mxcubecore.BaseHardwareObjects import HardwareObject +import gevent from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractXRFSpectrum import AbstractXRFSpectrum __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EMBL/EMBLXrayImaging.py b/mxcubecore/HardwareObjects/EMBL/EMBLXrayImaging.py index 513a8c21d7..76e35783ff 100644 --- a/mxcubecore/HardwareObjects/EMBL/EMBLXrayImaging.py +++ b/mxcubecore/HardwareObjects/EMBL/EMBLXrayImaging.py @@ -18,33 +18,36 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import tine +import collections import json -import time -import Image import logging +import os import threading -import collections -from queue import Queue +import time from copy import deepcopy - -import gevent +from queue import Queue import cv2 as cv +import gevent +import Image import numpy as np -from scipy import ndimage, misc - +import tine from cStringIO import StringIO from PIL.ImageQt import ImageQt +from scipy import ( + misc, + ndimage, +) -from mxcubecore.utils import qt_import, Colors -from mxcubecore.TaskUtils import task +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect from mxcubecore.HardwareObjects.QtGraphicsManager import QtGraphicsManager from mxcubecore.model import queue_model_objects as qmo -from mxcubecore import HardwareRepository as HWR - +from mxcubecore.TaskUtils import task +from mxcubecore.utils import ( + Colors, + qt_import, +) __credits__ = ["EMBL Hamburg"] __category__ = "Task" diff --git a/mxcubecore/HardwareObjects/EMBL/MDFastShutter.py b/mxcubecore/HardwareObjects/EMBL/MDFastShutter.py index 2a298304f4..619fc3b6bc 100644 --- a/mxcubecore/HardwareObjects/EMBL/MDFastShutter.py +++ b/mxcubecore/HardwareObjects/EMBL/MDFastShutter.py @@ -17,8 +17,13 @@ # along with MXCuBE. If not, see . +from enum import ( + Enum, + unique, +) + import gevent -from enum import Enum, unique + from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __credits__ = ["EMBL Hamburg"] diff --git a/mxcubecore/HardwareObjects/EMBL/TINEMotor.py b/mxcubecore/HardwareObjects/EMBL/TINEMotor.py index b60c74e2e2..d7aa7ab6fa 100644 --- a/mxcubecore/HardwareObjects/EMBL/TINEMotor.py +++ b/mxcubecore/HardwareObjects/EMBL/TINEMotor.py @@ -21,12 +21,12 @@ """ import logging + import gevent from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" __category__ = "Motor" diff --git a/mxcubecore/HardwareObjects/EMBLFlexHCD.py b/mxcubecore/HardwareObjects/EMBLFlexHCD.py index af5c7ac40f..8c0ec13933 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHCD.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHCD.py @@ -28,16 +28,16 @@ /puck_configuration> """ -import time import ast import base64 -import pickle import logging +import pickle +import time + import gevent +from PyTango.gevent import DeviceProxy from mxcubecore import HardwareRepository as HWR - -from mxcubecore.TaskUtils import task from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( SampleChanger, SampleChangerState, @@ -46,7 +46,7 @@ Container, Sample, ) -from PyTango.gevent import DeviceProxy +from mxcubecore.TaskUtils import task class Pin(Sample): diff --git a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py index 50422e2535..6bb6cd8262 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py @@ -25,13 +25,13 @@ lid231flex1:9001 """ -import time import logging -import gevent +import time -from mxcubecore.TaskUtils import task +import gevent from mxcubecore.HardwareObjects.EMBLFlexHCD import EMBLFlexHCD +from mxcubecore.TaskUtils import task class EMBLFlexHarvester(EMBLFlexHCD): diff --git a/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py b/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py index f4320964d5..0c801825dd 100644 --- a/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/BM14EnergyScan.py @@ -1,6 +1,11 @@ import logging + +from ESRFEnergyScan import ( + ESRFEnergyScan, + TunableEnergy, +) + from mxcubecore.TaskUtils import task -from ESRFEnergyScan import ESRFEnergyScan, TunableEnergy class BM14EnergyScan(ESRFEnergyScan): diff --git a/mxcubecore/HardwareObjects/ESRF/BlissHutchTrigger.py b/mxcubecore/HardwareObjects/ESRF/BlissHutchTrigger.py index d7a06d0ad3..a7009d06aa 100644 --- a/mxcubecore/HardwareObjects/ESRF/BlissHutchTrigger.py +++ b/mxcubecore/HardwareObjects/ESRF/BlissHutchTrigger.py @@ -37,9 +37,14 @@ """ import logging -from gevent import sleep, spawn -from PyTango.gevent import DeviceProxy + +from gevent import ( + sleep, + spawn, +) from PyTango import DevFailed +from PyTango.gevent import DeviceProxy + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/ESRF/BlissTurret.py b/mxcubecore/HardwareObjects/ESRF/BlissTurret.py index 916a95f5e6..1cc116637b 100644 --- a/mxcubecore/HardwareObjects/ESRF/BlissTurret.py +++ b/mxcubecore/HardwareObjects/ESRF/BlissTurret.py @@ -1,6 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject from bliss.config import static +from mxcubecore.BaseHardwareObjects import HardwareObject + class BlissTurret(HardwareObject): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py b/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py index 808256b400..e5210b2fb0 100644 --- a/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py +++ b/mxcubecore/HardwareObjects/ESRF/BlissVolpi.py @@ -1,6 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject from bliss.config import static +from mxcubecore.BaseHardwareObjects import HardwareObject + class BlissVolpi(HardwareObject): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py index 7401713217..279b8c8caf 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py @@ -29,8 +29,8 @@ import logging -from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam class ESRFBeam(AbstractBeam): diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py index 213604cb3f..37d8b873ca 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeamDefiner.py @@ -43,6 +43,7 @@ from ast import literal_eval from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeamInfo.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeamInfo.py index 6b0adfb620..d8b7a9e3be 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeamInfo.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeamInfo.py @@ -1,6 +1,7 @@ import logging -from mxcubecore.HardwareObjects import BeamInfo + from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import BeamInfo """ XML example file diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeamlineActions.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeamlineActions.py index ef4d154eca..390dec46ce 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeamlineActions.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeamlineActions.py @@ -35,14 +35,15 @@ """ import ast + import gevent -from mxcubecore.TaskUtils import task from mxcubecore.HardwareObjects.BeamlineActions import ( BeamlineActions, ControllerCommand, HWObjActuatorCommand, ) +from mxcubecore.TaskUtils import task __copyright__ = """ Copyright © 2010-2023 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py b/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py index 3a3b736e4c..5bb7505ab4 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py @@ -1,7 +1,9 @@ +import time + +import gevent from PyTango.gevent import DeviceProxy + from mxcubecore.BaseHardwareObjects import HardwareObject -import gevent -import time CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py index 17277567be..32f8aa2803 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py @@ -1,25 +1,23 @@ import logging -import time +import math import os import os.path import shutil -import math -import gevent # import PyChooch # to run chooch in shell import subprocess -import numpy +import time -from matplotlib.figure import Figure +import gevent +import numpy from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import ( - AbstractEnergyScan, -) from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import AbstractEnergyScan +from mxcubecore.TaskUtils import task class FixedEnergy: diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py b/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py index 6c687f7e6b..49b954fee8 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMD2SC3.py @@ -1,9 +1,10 @@ """ESRF SC3 Sample Changer Hardware Object """ -from mxcubecore.TaskUtils import task -import SC3 import ESRF.ESRFSC3 as ESRFSC3 +import SC3 + +from mxcubecore.TaskUtils import task class Command: diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMetadataManagerClient.py b/mxcubecore/HardwareObjects/ESRF/ESRFMetadataManagerClient.py index 2b31f2f30e..d7fc9c6abb 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMetadataManagerClient.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMetadataManagerClient.py @@ -3,18 +3,20 @@ """A simple client for MetadataManager and MetaExperiment """ from __future__ import print_function + +import logging +import math import os +import smtplib import sys -import math import time -import logging -import PyTango.client import traceback from email.mime.text import MIMEText -import smtplib -from mxcubecore.utils.conversion import string_types +import PyTango.client + from mxcubecore import HardwareRepository as HWR +from mxcubecore.utils.conversion import string_types class MetadataManagerClient(object): diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py index 382e2740e1..e2b9aec541 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py @@ -1,13 +1,13 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractMultiCollect import * import logging -import time -import os import math +import os +import time + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractMultiCollect import * from mxcubecore.model.queue_model_objects import PathTemplate from mxcubecore.utils.conversion import string_types -from mxcubecore import HardwareRepository as HWR - try: from httplib import HTTPConnection diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFPhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ESRFPhotonFlux.py index 54c4e4804a..8d87c9159b 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFPhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFPhotonFlux.py @@ -33,6 +33,7 @@ """ import logging + import gevent from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py b/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py index 424639fc65..6993b21154 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSC3.py @@ -3,9 +3,15 @@ import functools import logging -from mxcubecore.TaskUtils import task, cleanup, error_cleanup + import SC3 +from mxcubecore.TaskUtils import ( + cleanup, + error_cleanup, + task, +) + class ESRFSC3(SC3.SC3): (FLAG_SC_IN_USE, FLAG_MINIDIFF_CAN_MOVE, FLAG_SC_CAN_LOAD, FLAG_SC_NEVER) = ( diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSession.py b/mxcubecore/HardwareObjects/ESRF/ESRFSession.py index 0211108144..d0fedaae7a 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSession.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSession.py @@ -1,11 +1,12 @@ -from mxcubecore.HardwareObjects import Session +import glob import os import time -import glob -from mxcubecore.model import queue_model_objects -from mxcubecore import HardwareRepository as HWR from typing import Tuple +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import Session +from mxcubecore.model import queue_model_objects + class ESRFSession(Session.Session): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py index 042de2438a..942b45aa41 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py @@ -18,21 +18,25 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) -import os import json -import time import logging +import os +import time + import requests +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractXrayCentring import ( AbstractXrayCentring, ) -from mxcubecore import HardwareRepository as HWR - __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" __author__ = "rhfogh" diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFXRFSpectrum.py b/mxcubecore/HardwareObjects/ESRF/ESRFXRFSpectrum.py index 32cb1d250c..f1f77c1e61 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFXRFSpectrum.py @@ -37,16 +37,18 @@ __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" -from unittest.mock import MagicMock import logging import os.path from ast import literal_eval +from unittest.mock import MagicMock from warnings import warn -import numpy -from PyMca5.PyMca import ConfigDict -from PyMca5.PyMca import ClassMcaTheory -from PyMca5.PyMca import QtMcaAdvancedFitReport +import numpy +from PyMca5.PyMca import ( + ClassMcaTheory, + ConfigDict, + QtMcaAdvancedFitReport, +) from mxcubecore.HardwareObjects.abstract.AbstractXRFSpectrum import AbstractXRFSpectrum diff --git a/mxcubecore/HardwareObjects/ESRF/ID231BeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID231BeamCmds.py index 5952e32407..9d788b7421 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID231BeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID231BeamCmds.py @@ -1,5 +1,9 @@ from mxcubecore.BaseHardwareObjects import HardwareObject -from .BeamCmds import ControllerCommand, HWObjActuatorCommand + +from .BeamCmds import ( + ControllerCommand, + HWObjActuatorCommand, +) class ID231BeamCmds(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py b/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py index 3dcb68264f..cf44caecc0 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID231BeamInfo.py @@ -19,8 +19,9 @@ """ import logging -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class BeamInfo(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py index 26218e13bb..febd3eb068 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ID231EnergyScan.py @@ -1,5 +1,9 @@ from mxcubecore.TaskUtils import task -from .ESRFEnergyScan import ESRFEnergyScan, TunableEnergy + +from .ESRFEnergyScan import ( + ESRFEnergyScan, + TunableEnergy, +) class ID231EnergyScan(ESRFEnergyScan): diff --git a/mxcubecore/HardwareObjects/ESRF/ID232BeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID232BeamCmds.py index 2b726bf228..a5015b05e5 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232BeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232BeamCmds.py @@ -1,5 +1,9 @@ from mxcubecore.BaseHardwareObjects import HardwareObject -from .BeamCmds import ControllerCommand, HWObjActuatorCommand + +from .BeamCmds import ( + ControllerCommand, + HWObjActuatorCommand, +) class ID232BeamCmds(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py index e9aeb9fab7..e98708c174 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232BeamDefiner.py @@ -51,7 +51,12 @@ from enum import Enum -from gevent import Timeout, sleep + +from gevent import ( + Timeout, + sleep, +) + from mxcubecore.HardwareObjects.ESRF.ESRFBeamDefiner import ESRFBeamDefiner diff --git a/mxcubecore/HardwareObjects/ESRF/ID232BeamInfo.py b/mxcubecore/HardwareObjects/ESRF/ID232BeamInfo.py index 422d537a6e..2415f1aa38 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232BeamInfo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232BeamInfo.py @@ -1,5 +1,5 @@ -from mxcubecore.HardwareObjects import BeamInfo from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import BeamInfo class ID232BeamInfo(BeamInfo.BeamInfo): diff --git a/mxcubecore/HardwareObjects/ESRF/ID232HutchTrigger.py b/mxcubecore/HardwareObjects/ESRF/ID232HutchTrigger.py index 0c0cfd50ed..4400b2720f 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232HutchTrigger.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232HutchTrigger.py @@ -1,8 +1,10 @@ import logging -import PyTango.gevent -import gevent -import time import sys +import time + +import gevent +import PyTango.gevent + from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/ID232PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID232PhotonFlux.py index bcc1cba99e..e3b9f663de 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID232PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID232PhotonFlux.py @@ -1,5 +1,5 @@ -from TangoKeithleyPhotonFlux import TangoKeithleyPhotonFlux from bliss.config import channels +from TangoKeithleyPhotonFlux import TangoKeithleyPhotonFlux class ID232PhotonFlux(TangoKeithleyPhotonFlux): diff --git a/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py index d8d1e5a658..d998f53841 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID23PhotonFlux.py @@ -1,11 +1,13 @@ -import time import logging import math +import time + from calc_flux import CalculateFlux from PyTango.gevent import DeviceProxy + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.TaskUtils import task -from mxcubecore import HardwareRepository as HWR class ID23PhotonFlux(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID29BeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID29BeamCmds.py index 4a220b09c3..6a7fae1a93 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29BeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29BeamCmds.py @@ -1,5 +1,9 @@ from mxcubecore.BaseHardwareObjects import HardwareObject -from .BeamCmds import ControllerCommand, HWObjActuatorCommand + +from .BeamCmds import ( + ControllerCommand, + HWObjActuatorCommand, +) class ID29BeamCmds(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py index 59c067242c..df425f13d1 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29EnergyScan.py @@ -1,6 +1,11 @@ -from .ESRFEnergyScan import ESRFEnergyScan, TunableEnergy, task from datetime import datetime +from .ESRFEnergyScan import ( + ESRFEnergyScan, + TunableEnergy, + task, +) + class ID29EnergyScan(ESRFEnergyScan): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/ESRF/ID29HutchTrigger.py b/mxcubecore/HardwareObjects/ESRF/ID29HutchTrigger.py index 96a6f1f124..893161bd4d 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29HutchTrigger.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29HutchTrigger.py @@ -1,8 +1,10 @@ import logging -import PyTango.gevent -import gevent -import time import sys +import time + +import gevent +import PyTango.gevent + from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py index b6ea643135..bf8845c4d7 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29PhotonFlux.py @@ -1,11 +1,13 @@ -import time import logging import math -from calc_flux import CalculateFlux import sys +import time + +from calc_flux import CalculateFlux + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.TaskUtils import task -from mxcubecore import HardwareRepository as HWR class ID29PhotonFlux(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum.py b/mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum.py index be2e624bc8..4585b69a6c 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum.py +++ b/mxcubecore/HardwareObjects/ESRF/ID29XRFSpectrum.py @@ -1,22 +1,28 @@ import logging import os.path + import numpy from mxcubecore.HardwareObjects.XRFSpectrum import XRFSpectrum try: - from PyMca import ConfigDict - from PyMca import ClassMcaTheory - from PyMca import QtMcaAdvancedFitReport + from PyMca import ( + ClassMcaTheory, + ConfigDict, + QtMcaAdvancedFitReport, + ) except ImportError: - from PyMca5.PyMca import ConfigDict - from PyMca5.PyMca import ClassMcaTheory - from PyMca5.PyMca import QtMcaAdvancedFitReport + from PyMca5.PyMca import ( + ClassMcaTheory, + ConfigDict, + QtMcaAdvancedFitReport, + ) """ Next two lines is a trick to avoid core dump in QtMcaAdvancedFitReport """ from unittest.mock import MagicMock + QtMcaAdvancedFitReport.qt = MagicMock() diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamCmds.py index 6b403289f5..4487091b37 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamCmds.py @@ -1,4 +1,5 @@ from mxcubecore.BaseHardwareObjects import HardwareObject + from .BeamCmds import ControllerCommand diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py index 077776b7b3..defcc15869 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3BeamDefiner.py @@ -48,6 +48,7 @@ __license__ = "LGPLv3+" from enum import Enum + from mxcubecore.HardwareObjects.ESRF.ESRFBeamDefiner import ESRFBeamDefiner diff --git a/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py index b9e5883f33..4a55b2ad59 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30A3PhotonFlux.py @@ -1,8 +1,10 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task import time + from PyTango.gevent import DeviceProxy +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task + class ID30A3PhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BBeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID30BBeamCmds.py index c47ccf3101..d562ca9a87 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BBeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BBeamCmds.py @@ -1,5 +1,10 @@ from mxcubecore.BaseHardwareObjects import HardwareObject -from .BeamCmds import ControllerCommand, TestCommand, HWObjActuatorCommand + +from .BeamCmds import ( + ControllerCommand, + HWObjActuatorCommand, + TestCommand, +) class ID30BBeamCmds(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py index 9ee711a236..379dd23fc7 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BEnergyScan.py @@ -1,7 +1,12 @@ -from mxcubecore.TaskUtils import task -from .ESRFEnergyScan import ESRFEnergyScan, TunableEnergy from datetime import datetime +from mxcubecore.TaskUtils import task + +from .ESRFEnergyScan import ( + ESRFEnergyScan, + TunableEnergy, +) + class ID30BEnergyScan(ESRFEnergyScan): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BPhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/ID30BPhotonFlux.py index 1be0814923..d1c4cd8901 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BPhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BPhotonFlux.py @@ -28,6 +28,7 @@ """ import logging + from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py b/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py index b956624aba..850f666d64 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BXRFSpectrum.py @@ -1,11 +1,13 @@ -from qt import copy import logging import os import time -import gevent.event + import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject +import gevent.event +from qt import copy + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class XrfSpectrum(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BeamCmds.py b/mxcubecore/HardwareObjects/ESRF/ID30BeamCmds.py index b0cb795aa0..3dc2e0a8fb 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BeamCmds.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BeamCmds.py @@ -1,8 +1,10 @@ +import logging + +import gevent + from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task from mxcubecore.CommandContainer import CommandObject -import gevent -import logging +from mxcubecore.TaskUtils import task class ControllerCommand(CommandObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30BeamInfo.py b/mxcubecore/HardwareObjects/ESRF/ID30BeamInfo.py index ec263c0516..21554c10d7 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30BeamInfo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30BeamInfo.py @@ -1,5 +1,5 @@ -from mxcubecore.HardwareObjects import BeamInfo from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import BeamInfo class ID30BeamInfo(BeamInfo.BeamInfo): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py b/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py index c4cd41bf0b..7f50468dbd 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py @@ -1,8 +1,10 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task import time + import gevent +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task + class ID30Cryo(HardwareObject): states = {0: "out", 1: "in"} diff --git a/mxcubecore/HardwareObjects/ESRF/ID30HutchTrigger.py b/mxcubecore/HardwareObjects/ESRF/ID30HutchTrigger.py index 1c80ee25af..0cc60455cb 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30HutchTrigger.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30HutchTrigger.py @@ -1,9 +1,11 @@ -from mxcubecore import BaseHardwareObjects import logging -import PyTango.gevent -import gevent -import time import sys +import time + +import gevent +import PyTango.gevent + +from mxcubecore import BaseHardwareObjects class ID30HutchTrigger(BaseHardwareObjects.HardwareObject): diff --git a/mxcubecore/HardwareObjects/ESRF/ID30Light.py b/mxcubecore/HardwareObjects/ESRF/ID30Light.py index 121995fea9..d53c2a9f1a 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30Light.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30Light.py @@ -1,8 +1,10 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor import time + import gevent +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + class ID30Light(Device, AbstractMotor): states = {0: "out", 1: "in"} diff --git a/mxcubecore/HardwareObjects/ESRF/ID30SC3.py b/mxcubecore/HardwareObjects/ESRF/ID30SC3.py index c88ccd7110..827145f68f 100644 --- a/mxcubecore/HardwareObjects/ESRF/ID30SC3.py +++ b/mxcubecore/HardwareObjects/ESRF/ID30SC3.py @@ -1,9 +1,10 @@ """ESRF SC3 Sample Changer Hardware Object """ -from mxcubecore.TaskUtils import task -import SC3 import ESRFSC3 +import SC3 + +from mxcubecore.TaskUtils import task class Command: diff --git a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py index d040d60497..1c613f8f0f 100644 --- a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py @@ -1,13 +1,14 @@ -import gevent -import shutil import logging import os +import shutil -from mxcubecore.TaskUtils import task -from .ESRFMultiCollect import ESRFMultiCollect -from mxcubecore.HardwareObjects.LimaPilatusDetector import LimaPilatusDetector +import gevent from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.LimaPilatusDetector import LimaPilatusDetector +from mxcubecore.TaskUtils import task + +from .ESRFMultiCollect import ESRFMultiCollect class MD2MultiCollect(ESRFMultiCollect): diff --git a/mxcubecore/HardwareObjects/ESRF/Oxford700.py b/mxcubecore/HardwareObjects/ESRF/Oxford700.py index 804c07f9c8..0729b6aaeb 100644 --- a/mxcubecore/HardwareObjects/ESRF/Oxford700.py +++ b/mxcubecore/HardwareObjects/ESRF/Oxford700.py @@ -1,12 +1,10 @@ -import gevent import sys -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR +import gevent -from mxcubecore.HardwareObjects.abstract.AbstractActuator import ( - AbstractActuator, -) +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] PHASE_ACTION = { diff --git a/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py b/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py index f1f1c51c0b..7c7a684771 100644 --- a/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py +++ b/mxcubecore/HardwareObjects/ESRF/OxfordCryostream.py @@ -33,9 +33,14 @@ """ -import sys import logging -from gevent import Timeout, sleep, spawn +import sys + +from gevent import ( + Timeout, + sleep, + spawn, +) from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator diff --git a/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py b/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py index 86302395f9..cd24af3f1e 100644 --- a/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py +++ b/mxcubecore/HardwareObjects/ESRF/TangoKeithleyPhotonFlux.py @@ -1,10 +1,11 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task import time # from PyTango.gevent import DeviceProxy from PyTango import DeviceProxy +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task + class TangoKeithleyPhotonFlux(HardwareObject): def __init__(self, *args, **kwargs): diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py index 91d3a0a0e8..21406849fc 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_base_queue_entry.py @@ -1,20 +1,21 @@ -import os -import logging -import subprocess import datetime import json -import gevent +import logging +import os +import subprocess +import xmlrpc.client -from typing_extensions import Literal -from pydantic.v1 import BaseModel, Field +import gevent from devtools import debug +from pydantic.v1 import ( + BaseModel, + Field, +) +from typing_extensions import Literal from mxcubecore import HardwareRepository as HWR from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry -import logging -import xmlrpc.client - class BaseUserCollectionParameters(BaseModel): num_images: int = Field(0, description="") diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py index 2d78ef104e..6f954f344b 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_big_foil_collection.py @@ -1,29 +1,25 @@ import logging -from typing_extensions import Literal - -from pydantic.v1 import BaseModel, Field from devtools import debug - -from mxcubecore.model.common import ( - CommonCollectionParamters, - PathParameters, - LegacyParameters, - StandardCollectionParameters, +from pydantic.v1 import ( + BaseModel, + Field, ) +from typing_extensions import Literal from mxcubecore import HardwareRepository as HWR - from mxcubecore.HardwareObjects.ESRF.queue_entry.ssx_base_queue_entry import ( + BaseUserCollectionParameters, SsxBaseQueueEntry, SsxBaseQueueTaskParameters, - BaseUserCollectionParameters, ) - -from mxcubecore.model.queue_model_objects import ( - DataCollection, +from mxcubecore.model.common import ( + CommonCollectionParamters, + LegacyParameters, + PathParameters, + StandardCollectionParameters, ) - +from mxcubecore.model.queue_model_objects import DataCollection __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py index 36c459094d..f09a16ffd3 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_chip_collection.py @@ -1,29 +1,24 @@ -import os -import logging import contextlib import enum +import logging +import os import subprocess -from pydantic.v1 import BaseModel, Field -from devtools import debug - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, -) - -from mxcubecore.model.queue_model_objects import ( - DataCollection, +from devtools import debug +from pydantic.v1 import ( + BaseModel, + Field, ) - +from mxcubecore import HardwareRepository as HWR from mxcubecore.model.common import ( CommonCollectionParamters, - PathParameters, LegacyParameters, + PathParameters, StandardCollectionParameters, ) - +from mxcubecore.model.queue_model_objects import DataCollection +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_foil_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_foil_collection.py index bdc938eab2..f016cf1ac6 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_foil_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_foil_collection.py @@ -2,29 +2,24 @@ import logging import math -from typing_extensions import Literal - -from pydantic import Field from devtools import debug - -from mxcubecore.model.common import ( - CommonCollectionParamters, - PathParameters, - LegacyParameters, - StandardCollectionParameters, -) +from pydantic import Field +from typing_extensions import Literal from mxcubecore import HardwareRepository as HWR - from mxcubecore.HardwareObjects.ESRF.queue_entry.ssx_base_queue_entry import ( + BaseUserCollectionParameters, SsxBaseQueueEntry, SsxBaseQueueTaskParameters, - BaseUserCollectionParameters, ) - +from mxcubecore.model.common import ( + CommonCollectionParamters, + LegacyParameters, + PathParameters, + StandardCollectionParameters, +) from mxcubecore.model.queue_model_objects import DataCollection - __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" __category__ = "General" diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py index a43e777851..9384375ea3 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/ssx_injector_collection.py @@ -1,28 +1,26 @@ +import enum import logging import time -import enum -from pydantic.v1 import BaseModel, Field from devtools import debug - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.model.common import ( - CommonCollectionParamters, - PathParameters, - LegacyParameters, - StandardCollectionParameters, +from pydantic.v1 import ( + BaseModel, + Field, ) +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.ESRF.queue_entry.ssx_base_queue_entry import ( + BaseUserCollectionParameters, SsxBaseQueueEntry, SsxBaseQueueTaskParameters, - BaseUserCollectionParameters, ) - -from mxcubecore.model.queue_model_objects import ( - DataCollection, +from mxcubecore.model.common import ( + CommonCollectionParamters, + LegacyParameters, + PathParameters, + StandardCollectionParameters, ) - +from mxcubecore.model.queue_model_objects import DataCollection __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py b/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py index 8ae771c4d4..c3263b1f4c 100644 --- a/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py +++ b/mxcubecore/HardwareObjects/ESRF/queue_entry/test_collection.py @@ -1,31 +1,26 @@ import os import subprocess -from typing_extensions import Literal - -from pydantic.v1 import BaseModel, Field from devtools import debug +from pydantic.v1 import ( + BaseModel, + Field, +) +from typing_extensions import Literal from mxcubecore import HardwareRepository as HWR - from mxcubecore.HardwareObjects.ESRF.queue_entry.ssx_base_queue_entry import ( + BaseUserCollectionParameters, SsxBaseQueueEntry, SsxBaseQueueTaskParameters, - BaseUserCollectionParameters, ) - - from mxcubecore.model.common import ( CommonCollectionParamters, - PathParameters, LegacyParameters, + PathParameters, StandardCollectionParameters, ) - -from mxcubecore.model.queue_model_objects import ( - DataCollection, -) - +from mxcubecore.model.queue_model_objects import DataCollection __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/EdnaWorkflow.py b/mxcubecore/HardwareObjects/EdnaWorkflow.py index cba088a169..ea2291d6da 100644 --- a/mxcubecore/HardwareObjects/EdnaWorkflow.py +++ b/mxcubecore/HardwareObjects/EdnaWorkflow.py @@ -1,18 +1,19 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject - +import binascii +import logging import os +import pprint import time + import gevent -import pprint -import logging import requests -import binascii + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject # import threading from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( SecureXMLRpcRequestHandler, ) -from mxcubecore import HardwareRepository as HWR try: from httplib import HTTPConnection diff --git a/mxcubecore/HardwareObjects/Energy.py b/mxcubecore/HardwareObjects/Energy.py index 2c07c24d6d..575ffbf97f 100644 --- a/mxcubecore/HardwareObjects/Energy.py +++ b/mxcubecore/HardwareObjects/Energy.py @@ -1,6 +1,8 @@ import logging import math + import gevent + from mxcubecore.BaseHardwareObjects import HardwareObject """ diff --git a/mxcubecore/HardwareObjects/ExporterMotor.py b/mxcubecore/HardwareObjects/ExporterMotor.py index 8da20eaebe..1a00ebc789 100644 --- a/mxcubecore/HardwareObjects/ExporterMotor.py +++ b/mxcubecore/HardwareObjects/ExporterMotor.py @@ -35,14 +35,18 @@ False """ -import sys -import math import logging +import math +import sys + +from gevent import ( + Timeout, + sleep, +) -from gevent import Timeout, sleep -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor from mxcubecore.Command.Exporter import Exporter from mxcubecore.Command.exporter.ExporterStates import ExporterStates +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/ExporterNState.py b/mxcubecore/HardwareObjects/ExporterNState.py index 61d0c857bd..64394362ec 100644 --- a/mxcubecore/HardwareObjects/ExporterNState.py +++ b/mxcubecore/HardwareObjects/ExporterNState.py @@ -30,10 +30,15 @@ """ from enum import Enum -from gevent import Timeout, sleep -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState + +from gevent import ( + Timeout, + sleep, +) + from mxcubecore.Command.Exporter import Exporter from mxcubecore.Command.exporter.ExporterStates import ExporterStates +from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/FlexHCD.py b/mxcubecore/HardwareObjects/FlexHCD.py index 8bdecf5086..02bd018030 100644 --- a/mxcubecore/HardwareObjects/FlexHCD.py +++ b/mxcubecore/HardwareObjects/FlexHCD.py @@ -1,9 +1,10 @@ import base64 +import logging import pickle + import gevent -import logging +from PyTango.gevent import DeviceProxy -from mxcubecore.TaskUtils import task from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( SampleChanger, SampleChangerState, @@ -12,7 +13,7 @@ Container, Sample, ) -from PyTango.gevent import DeviceProxy +from mxcubecore.TaskUtils import task class Pin(Sample): diff --git a/mxcubecore/HardwareObjects/FlexHCDMaintenance.py b/mxcubecore/HardwareObjects/FlexHCDMaintenance.py index 2d2709dfcd..685e9c1b6a 100644 --- a/mxcubecore/HardwareObjects/FlexHCDMaintenance.py +++ b/mxcubecore/HardwareObjects/FlexHCDMaintenance.py @@ -2,9 +2,9 @@ FLEX HCD maintenance mockup. """ -from mxcubecore.BaseHardwareObjects import HardwareObject import ast +from mxcubecore.BaseHardwareObjects import HardwareObject TOOL_FLANGE, TOOL_UNIPUCK, TOOL_SPINE, TOOL_PLATE, TOOL_LASER, TOOL_DOUBLE_GRIPPER = ( 0, diff --git a/mxcubecore/HardwareObjects/GenericDiffractometer.py b/mxcubecore/HardwareObjects/GenericDiffractometer.py index b139d7cc92..0105894175 100755 --- a/mxcubecore/HardwareObjects/GenericDiffractometer.py +++ b/mxcubecore/HardwareObjects/GenericDiffractometer.py @@ -21,24 +21,33 @@ GenericDiffractometer """ -import os -import json import copy +import enum +import json +import logging +import math +import os import time +from typing import ( + Dict, + List, + Tuple, + Union, +) + import gevent import gevent.event -import logging -import math import numpy -import enum - -from typing import List, Tuple, Union, Dict -from pydantic.v1 import BaseModel, Field, ValidationError +from pydantic.v1 import ( + BaseModel, + Field, + ValidationError, +) +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects import sample_centring from mxcubecore.model import queue_model_objects -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR try: unicode diff --git a/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py b/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py index 3626b0ec00..8f7287721a 100644 --- a/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py +++ b/mxcubecore/HardwareObjects/Gphl/CollectEmulator.py @@ -22,17 +22,18 @@ along with MXCuBE. If not, see . """ -import os -import subprocess import logging +import os import re +import subprocess from collections import OrderedDict + import f90nml -from mxcubecore.utils import conversion -from mxcubecore.HardwareObjects.mockup.CollectMockup import CollectMockup -from mxcubecore.TaskUtils import task from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.mockup.CollectMockup import CollectMockup +from mxcubecore.TaskUtils import task +from mxcubecore.utils import conversion __copyright__ = """ Copyright © 2017 - 2019 by Global Phasing Ltd. """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Gphl/GphlMessages.py b/mxcubecore/HardwareObjects/Gphl/GphlMessages.py index 1057447e73..bcc1849daa 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlMessages.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlMessages.py @@ -19,13 +19,19 @@ You should have received a copy of the GNU Lesser General Public License along with MXCuBE. If not, see . """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) -import uuid import json -from collections import OrderedDict -from collections import namedtuple +import uuid +from collections import ( + OrderedDict, + namedtuple, +) from mxcubecore.model import crystal_symmetry diff --git a/mxcubecore/HardwareObjects/Gphl/GphlQueueEntry.py b/mxcubecore/HardwareObjects/Gphl/GphlQueueEntry.py index 700e47173a..3e168e082e 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlQueueEntry.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlQueueEntry.py @@ -23,9 +23,9 @@ import logging -from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry -from mxcubecore import HardwareRepository as HWR +from mxcubecore import HardwareRepository as HWR +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 5b63c2b98a..9a5d91f301 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -21,35 +21,42 @@ You should have received a copy of the GNU Lesser General Public License along with MXCuBE. If not, see . """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import copy -import logging -import enum -import time import datetime -import os +import enum +import logging import math -import subprocess +import os import socket +import subprocess +import time import uuid from collections import OrderedDict +import f90nml import gevent import gevent.event import gevent.queue -import f90nml -from mxcubecore.dispatcher import dispatcher +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObjectYaml -from mxcubecore.model import queue_model_objects -from mxcubecore.model import crystal_symmetry -from mxcubecore.queue_entry import QUEUE_ENTRY_STATUS -from mxcubecore.queue_entry import QueueAbortedException - +from mxcubecore.dispatcher import dispatcher from mxcubecore.HardwareObjects.Gphl import GphlMessages -from mxcubecore import HardwareRepository as HWR +from mxcubecore.model import ( + crystal_symmetry, + queue_model_objects, +) +from mxcubecore.queue_entry import ( + QUEUE_ENTRY_STATUS, + QueueAbortedException, +) @enum.unique diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py index 793568a005..f6fdb77a4b 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py @@ -20,32 +20,38 @@ You should have received a copy of the GNU Lesser General Public License along with MXCuBE. If not, see . """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import logging import os -import subprocess -import uuid import signal -import time +import socket +import subprocess import sys +import time +import uuid -from py4j import clientserver, java_gateway +from py4j import ( + clientserver, + java_gateway, +) from py4j.protocol import Py4JJavaError -from mxcubecore.utils import conversion -from mxcubecore.HardwareObjects.Gphl import GphlMessages - -from mxcubecore.BaseHardwareObjects import HardwareObjectYaml from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectYaml +from mxcubecore.HardwareObjects.Gphl import GphlMessages +from mxcubecore.utils import conversion # NB this is patching the original socket module in to avoid the # monkeypatched version we get from gevent - that causes errors. # It depends on knowing where in py4j socket is imported # Hacky, but the best solution to making py4j and gevent compatible -import socket origsocket = sys.modules.pop("socket") _origsocket = sys.modules.pop("_socket") @@ -67,9 +73,11 @@ try: from louie import dispatcher except ImportError: - from pydispatch import dispatcher - from pydispatch import robustapply - from pydispatch import saferef + from pydispatch import ( + dispatcher, + robustapply, + saferef, + ) saferef.safe_ref = saferef.safeRef robustapply.robust_apply = robustapply.robustApply diff --git a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py index 331c408baa..1a08882363 100644 --- a/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py +++ b/mxcubecore/HardwareObjects/Gphl/Transcal2MiniKappa.py @@ -20,11 +20,12 @@ along with MXCuBE. If not, see . """ -import os import ast +import os from xml.etree import ElementTree as ET -import numpy as np + import f90nml +import numpy as np __copyright__ = """ Copyright © 2016 - 2023 MXCuBE Collaboration.""" __license__ = "LGPLv3+" @@ -227,7 +228,10 @@ def get_minikappa_data(configfile): if __name__ == "__main__": - from argparse import ArgumentParser, RawTextHelpFormatter + from argparse import ( + ArgumentParser, + RawTextHelpFormatter, + ) parser = ArgumentParser( prog="Transcal2MiniKappa.py", diff --git a/mxcubecore/HardwareObjects/Grob.py b/mxcubecore/HardwareObjects/Grob.py index db48bef7c4..59315160bf 100644 --- a/mxcubecore/HardwareObjects/Grob.py +++ b/mxcubecore/HardwareObjects/Grob.py @@ -1,6 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject from grob import grob_control +from mxcubecore.BaseHardwareObjects import HardwareObject + class Grob(HardwareObject): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/GrobMotor.py b/mxcubecore/HardwareObjects/GrobMotor.py index bbe2a904b1..a44820f965 100644 --- a/mxcubecore/HardwareObjects/GrobMotor.py +++ b/mxcubecore/HardwareObjects/GrobMotor.py @@ -1,8 +1,10 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor import math + import gevent +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + class GrobMotor(Device, AbstractMotor): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) diff --git a/mxcubecore/HardwareObjects/GrobSampleChanger.py b/mxcubecore/HardwareObjects/GrobSampleChanger.py index 6938468f84..3f2cee4a97 100644 --- a/mxcubecore/HardwareObjects/GrobSampleChanger.py +++ b/mxcubecore/HardwareObjects/GrobSampleChanger.py @@ -2,9 +2,11 @@ """ import logging -from mxcubecore.BaseHardwareObjects import HardwareObject + import gevent +from mxcubecore.BaseHardwareObjects import HardwareObject + class GrobSampleChanger(HardwareObject): (FLAG_SC_IN_USE, FLAG_MINIDIFF_CAN_MOVE, FLAG_SC_CAN_LOAD, FLAG_SC_NEVER) = ( diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index fa6e4ac6d1..a16e4204ac 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -41,10 +41,12 @@ ----------------------------------------------------------------- """ from __future__ import annotations -import gevent + import logging from typing import Optional +import gevent + from mxcubecore import queue_entry from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/HarvesterMaintenance.py b/mxcubecore/HardwareObjects/HarvesterMaintenance.py index 7579b92b4d..a1ebd97efa 100644 --- a/mxcubecore/HardwareObjects/HarvesterMaintenance.py +++ b/mxcubecore/HardwareObjects/HarvesterMaintenance.py @@ -21,10 +21,12 @@ """ Harvester Maintenance. """ -import gevent import logging -from mxcubecore.BaseHardwareObjects import HardwareObject + +import gevent + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class HarvesterMaintenance(HardwareObject): diff --git a/mxcubecore/HardwareObjects/ISARAMaint.py b/mxcubecore/HardwareObjects/ISARAMaint.py index 43af08c4f2..40491f4060 100644 --- a/mxcubecore/HardwareObjects/ISARAMaint.py +++ b/mxcubecore/HardwareObjects/ISARAMaint.py @@ -1,5 +1,10 @@ from typing import Optional -from tango import DeviceProxy, DevFailed + +from tango import ( + DevFailed, + DeviceProxy, +) + from mxcubecore.BaseHardwareObjects import HardwareObject """ diff --git a/mxcubecore/HardwareObjects/ISPyBClient.py b/mxcubecore/HardwareObjects/ISPyBClient.py index eb0749bff4..c05768266e 100644 --- a/mxcubecore/HardwareObjects/ISPyBClient.py +++ b/mxcubecore/HardwareObjects/ISPyBClient.py @@ -1,37 +1,39 @@ from __future__ import print_function -import sys -import json -import time + import itertools +import json import os +import sys +import time import traceback import warnings -from pprint import pformat from collections import namedtuple from datetime import datetime +from pprint import pformat try: - from urlparse import urljoin from urllib2 import URLError + from urlparse import urljoin except Exception: # Python3 from urllib.parse import urljoin from urllib.error import URLError -from suds.sudsobject import asdict from suds import WebFault from suds.client import Client +from suds.sudsobject import asdict + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.utils.conversion import string_types -from mxcubecore import HardwareRepository as HWR """ A client for ISPyB Webservices. """ import logging -import gevent +import gevent suds_encode = str.encode diff --git a/mxcubecore/HardwareObjects/ISPyBRestClient.py b/mxcubecore/HardwareObjects/ISPyBRestClient.py index 7b2bb43075..ac365e9603 100644 --- a/mxcubecore/HardwareObjects/ISPyBRestClient.py +++ b/mxcubecore/HardwareObjects/ISPyBRestClient.py @@ -2,15 +2,19 @@ A client for ISPyB Webservices. """ -import logging -import json import cgi - +import json +import logging from datetime import datetime -from requests import post, get from urllib.parse import urljoin -from mxcubecore.BaseHardwareObjects import HardwareObject + +from requests import ( + get, + post, +) + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject _CONNECTION_ERROR_MSG = ( "Could not connect to ISPyB, please verify that " diff --git a/mxcubecore/HardwareObjects/LNLS/EPICSActuator.py b/mxcubecore/HardwareObjects/LNLS/EPICSActuator.py index 200fcd2477..78528b90da 100644 --- a/mxcubecore/HardwareObjects/LNLS/EPICSActuator.py +++ b/mxcubecore/HardwareObjects/LNLS/EPICSActuator.py @@ -15,9 +15,11 @@ """ -import time import random +import time + import gevent + from mxcubecore.HardwareObjects.abstract import AbstractActuator diff --git a/mxcubecore/HardwareObjects/LNLS/EPICSMotor.py b/mxcubecore/HardwareObjects/LNLS/EPICSMotor.py index 7a5e786a1b..c6b33aeb4d 100644 --- a/mxcubecore/HardwareObjects/LNLS/EPICSMotor.py +++ b/mxcubecore/HardwareObjects/LNLS/EPICSMotor.py @@ -21,6 +21,7 @@ """ import logging import time + import gevent from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor diff --git a/mxcubecore/HardwareObjects/LNLS/EPICSNState.py b/mxcubecore/HardwareObjects/LNLS/EPICSNState.py index b5f1edb485..df75f0d63d 100644 --- a/mxcubecore/HardwareObjects/LNLS/EPICSNState.py +++ b/mxcubecore/HardwareObjects/LNLS/EPICSNState.py @@ -10,8 +10,8 @@ """ import logging - from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState from mxcubecore.HardwareObjects.LNLS.EPICSActuator import EPICSActuator diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSAperture.py b/mxcubecore/HardwareObjects/LNLS/LNLSAperture.py index 8af0417fcf..d9bcab496c 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSAperture.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSAperture.py @@ -18,10 +18,8 @@ # along with MXCuBE. If not, see . import logging -from mxcubecore.HardwareObjects.abstract.AbstractAperture import ( - AbstractAperture, -) +from mxcubecore.HardwareObjects.abstract.AbstractAperture import AbstractAperture __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3" diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSBeam.py b/mxcubecore/HardwareObjects/LNLS/LNLSBeam.py index e1d8a66554..1bcb754bf5 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSBeam.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSBeam.py @@ -27,7 +27,10 @@ import ast -from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape, AbstractBeam +from mxcubecore.HardwareObjects.abstract.AbstractBeam import ( + AbstractBeam, + BeamShape, +) class LNLSBeam(AbstractBeam): diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py index 2047ae71e4..e19c0b7963 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py @@ -1,14 +1,14 @@ """ Class for cameras connected by EPICS Area Detector """ -import os import logging -import gevent +import os from io import BytesIO from threading import Thread -from PIL import Image +import gevent import numpy as np +from PIL import Image from mxcubecore import BaseHardwareObjects diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py b/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py index b91ce0df32..5ced97b7c4 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py @@ -1,13 +1,15 @@ +import logging +import os +import time + +import gevent + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMultiCollect import ( AbstractMultiCollect, ) from mxcubecore.TaskUtils import task -from mxcubecore import HardwareRepository as HWR -import logging -import time -import os -import gevent class LNLSCollect(AbstractMultiCollect, HardwareObject): @@ -184,7 +186,8 @@ def loop(self, owner, data_collect_parameters_list): ) return - import sys, subprocess + import subprocess + import sys try: process = subprocess.Popen( diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py b/mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py index 2744b12d14..4c5ec2564c 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py @@ -1,5 +1,5 @@ -import time import logging +import time from mxcubecore.HardwareObjects.LNLS.LNLSMotor import LNLSMotor diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSDiffractometer.py b/mxcubecore/HardwareObjects/LNLS/LNLSDiffractometer.py index b75f7a5905..184836301c 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSDiffractometer.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSDiffractometer.py @@ -18,17 +18,16 @@ # along with MXCuBE. If not, see . import ast -import time import logging import random +import time import warnings -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer -) -from mxcubecore import HardwareRepository as HWR from gevent.event import AsyncResult +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer + class LNLSDiffractometer(GenericDiffractometer): """ diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSEnergy.py b/mxcubecore/HardwareObjects/LNLS/LNLSEnergy.py index f1fddce4c9..604e1490e4 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSEnergy.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSEnergy.py @@ -21,8 +21,7 @@ import logging -from mxcubecore.HardwareObjects.abstract.AbstractEnergy import ( - AbstractEnergy) +from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy from mxcubecore.HardwareObjects.LNLS.EPICSActuator import EPICSActuator diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSPilatusDet.py b/mxcubecore/HardwareObjects/LNLS/LNLSPilatusDet.py index 38c85820d9..6b0f6ad14e 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSPilatusDet.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSPilatusDet.py @@ -1,11 +1,10 @@ -import time import logging +import time -from mxcubecore.HardwareObjects.abstract.AbstractDetector import ( - AbstractDetector, -) import epics +from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector + class LNLSPilatusDet(AbstractDetector): diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSSlits.py b/mxcubecore/HardwareObjects/LNLS/LNLSSlits.py index db1e13bad4..f8b1d8ed4c 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSSlits.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSSlits.py @@ -20,7 +20,6 @@ from mxcubecore.HardwareObjects.abstract.AbstractSlits import AbstractSlits - __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSTransmission.py b/mxcubecore/HardwareObjects/LNLS/LNLSTransmission.py index 5efb4ea509..aadc255379 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSTransmission.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSTransmission.py @@ -25,12 +25,10 @@ AbstractTransmission, ) from mxcubecore.HardwareObjects.LNLS.EPICSActuator import EPICSActuator - -from mxcubecore.HardwareObjects.LNLS.read_transmission_mnc import ( - read_transmission -) +from mxcubecore.HardwareObjects.LNLS.read_transmission_mnc import read_transmission from mxcubecore.HardwareObjects.LNLS.set_transmission_mnc import ( - get_transmission, set_foils + get_transmission, + set_foils, ) __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSZoom.py b/mxcubecore/HardwareObjects/LNLS/LNLSZoom.py index bc71bfa61c..5b86af8c62 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSZoom.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSZoom.py @@ -8,12 +8,15 @@ EL6": 6} """ +import time from enum import Enum + import gevent -import time -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState -from mxcubecore.HardwareObjects.abstract.AbstractNState import BaseValueEnum +from mxcubecore.HardwareObjects.abstract.AbstractNState import ( + AbstractNState, + BaseValueEnum, +) from mxcubecore.HardwareObjects.LNLS.EPICSActuator import EPICSActuator diff --git a/mxcubecore/HardwareObjects/LNLS/read_transmission_mnc.py b/mxcubecore/HardwareObjects/LNLS/read_transmission_mnc.py index a6d85a58fb..0e092c3f0f 100644 --- a/mxcubecore/HardwareObjects/LNLS/read_transmission_mnc.py +++ b/mxcubecore/HardwareObjects/LNLS/read_transmission_mnc.py @@ -20,9 +20,11 @@ MU is the linear attenuation coeficient (cm^-1) and d is the thickness of the foil (cm). """ import argparse -from epics import PV import math +from epics import PV + + def read_input(): # Read inputs from terminal ap = argparse.ArgumentParser() diff --git a/mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py b/mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py index 2981d55ba8..21eb4a0a87 100755 --- a/mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py +++ b/mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py @@ -20,11 +20,12 @@ MU is the linear attenuation coeficient (cm^-1) and d is the thickness of the foil (cm). """ import argparse -from epics import PV import itertools import math import time +from epics import PV + def read_input(): # Read inputs from terminal diff --git a/mxcubecore/HardwareObjects/LdapAuthenticator.py b/mxcubecore/HardwareObjects/LdapAuthenticator.py index 574b011987..971cc658d5 100644 --- a/mxcubecore/HardwareObjects/LdapAuthenticator.py +++ b/mxcubecore/HardwareObjects/LdapAuthenticator.py @@ -5,6 +5,7 @@ """ import logging + import ldap from mxcubecore.HardwareObjects.abstract.AbstractAuthenticator import ( diff --git a/mxcubecore/HardwareObjects/Lima2Detector.py b/mxcubecore/HardwareObjects/Lima2Detector.py index 3c4cb7390c..c71a5d7121 100644 --- a/mxcubecore/HardwareObjects/Lima2Detector.py +++ b/mxcubecore/HardwareObjects/Lima2Detector.py @@ -1,23 +1,19 @@ -import gevent -import time import logging -from gevent import subprocess import os - -from uuid import uuid1 +import time from contextlib import ExitStack +from uuid import uuid1 -from lima2.client import Detector +import gevent +from gevent import subprocess from lima2.client import Detector from lima2.client.smx.aggregation import create_virtual_dataset -from mxcubecore.TaskUtils import task from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.CommandContainer import ConnectionError - from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector - -from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.TaskUtils import task _logger = logging.getLogger("HWR") diff --git a/mxcubecore/HardwareObjects/LimaEigerDetector.py b/mxcubecore/HardwareObjects/LimaEigerDetector.py index 442e175255..a8ab08f124 100644 --- a/mxcubecore/HardwareObjects/LimaEigerDetector.py +++ b/mxcubecore/HardwareObjects/LimaEigerDetector.py @@ -2,16 +2,17 @@ Lima Tango Device Server implementation of the Dectris Eiger2 Detector. """ -import gevent -import time -import os -import math import logging +import math +import os +import time + +import gevent -from mxcubecore.model.queue_model_objects import PathTemplate -from mxcubecore.TaskUtils import task from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector +from mxcubecore.model.queue_model_objects import PathTemplate +from mxcubecore.TaskUtils import task class LimaEigerDetector(AbstractDetector): diff --git a/mxcubecore/HardwareObjects/LimaJungfrauDetector.py b/mxcubecore/HardwareObjects/LimaJungfrauDetector.py index 615a2a1cff..881ecf1f2d 100644 --- a/mxcubecore/HardwareObjects/LimaJungfrauDetector.py +++ b/mxcubecore/HardwareObjects/LimaJungfrauDetector.py @@ -1,12 +1,13 @@ -import gevent -import time -import subprocess import logging import os +import subprocess +import time +import gevent + +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.CommandContainer import ConnectionError from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector -from mxcubecore.BaseHardwareObjects import HardwareObjectState class LimaJungfrauDetector(AbstractDetector): diff --git a/mxcubecore/HardwareObjects/LimaPilatusDetector.py b/mxcubecore/HardwareObjects/LimaPilatusDetector.py index fab9785645..545317457a 100644 --- a/mxcubecore/HardwareObjects/LimaPilatusDetector.py +++ b/mxcubecore/HardwareObjects/LimaPilatusDetector.py @@ -1,17 +1,16 @@ -import gevent -import time -import subprocess -import os import logging +import os +import subprocess +import time +import gevent from PyTango import DeviceProxy -from mxcubecore.TaskUtils import task + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.CommandContainer import ConnectionError - from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector - -from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.TaskUtils import task class LimaPilatusDetector(AbstractDetector): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py index 3ecaba3410..35ccf654bc 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py @@ -1,4 +1,5 @@ import logging + from mxcubecore.HardwareObjects.MicrodiffAperture import MicrodiffAperture diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py index 06a71f3d85..e210407820 100755 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py @@ -1,5 +1,5 @@ -from mxcubecore.HardwareObjects import BeamInfo from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import BeamInfo class BIOMAXBeamInfo(BeamInfo.BeamInfo): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py index 39ed91f22f..88235354fa 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py @@ -1,11 +1,12 @@ import logging import time + import gevent +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task from mxcubecore.CommandContainer import CommandObject -from mxcubecore import HardwareRepository as HWR +from mxcubecore.TaskUtils import task class ControllerCommand(CommandObject): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py index 18a4fa1fab..390c4bc560 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py @@ -11,22 +11,22 @@ """ -import os +import json import logging -import gevent -import time import math -import requests -import uuid -import json +import os import sys +import time +import uuid +import gevent +import requests from EigerDataSet import EigerDataSet -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task class BIOMAXCollect(AbstractCollect, HardwareObject): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py index 1a3c0ee69a..95f15334f6 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py @@ -20,14 +20,16 @@ """ from __future__ import print_function -import gevent -import time + import copy import logging +import time + +import gevent -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task class BIOMAXEiger(HardwareObject): @@ -700,8 +702,8 @@ def abort(self): def test(): - import sys import os + import sys if len(sys.argv) != 5: print( diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py index b7348023bc..c523768d69 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py @@ -1,7 +1,9 @@ import logging + import gevent -from mxcubecore.HardwareObjects import Energy + from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import Energy class BIOMAXEnergy(Energy.Energy): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py index 4c410fbada..955bd9306d 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py @@ -2,14 +2,16 @@ A client for Biomax Kafka services. """ +import json import logging +import re import time -import json import uuid -import re + import requests -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class BIOMAXKafka(HardwareObject): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py index b151c7163b..47c04bfa59 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py @@ -4,22 +4,21 @@ """ -import time +import io import logging +import math +import time + import gevent import lucid2 as lucid import numpy as np from PIL import Image -# import lucid -import io -import math - +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, DiffractometerState, + GenericDiffractometer, ) -from mxcubecore import HardwareRepository as HWR class BIOMAXMD3(GenericDiffractometer): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py index 4ba7125066..90f3ada66a 100755 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py @@ -1,13 +1,18 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -import math +import array +import base64 import logging +import math import time +from threading import ( + Event, + Thread, +) + import gevent -from threading import Event, Thread -import base64 -import array import numpy as np +from mxcubecore.BaseHardwareObjects import HardwareObject + class MD2TimeoutError(Exception): pass diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py index 0803b6a154..cae1a2bcdf 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py @@ -1,9 +1,11 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -import types import logging -import gevent import time +import types + +import gevent + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class BIOMAXPatches(HardwareObject): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py index 1c9bafb088..7ccf4f5ccc 100755 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py @@ -1,8 +1,8 @@ import logging -from mxcubecore.HardwareObjects import Resolution import math from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import Resolution class BIOMAXResolution(Resolution.Resolution): diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py index 26ebbfc4c4..00e927c14c 100644 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py +++ b/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py @@ -1,6 +1,7 @@ import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class BIOMAXTransmission(HardwareObject): diff --git a/mxcubecore/HardwareObjects/MAXIV/MAXIVAutoProcessing.py b/mxcubecore/HardwareObjects/MAXIV/MAXIVAutoProcessing.py index d85cd59b77..9a51f95623 100755 --- a/mxcubecore/HardwareObjects/MAXIV/MAXIVAutoProcessing.py +++ b/mxcubecore/HardwareObjects/MAXIV/MAXIVAutoProcessing.py @@ -21,18 +21,19 @@ MAXIVAutoProcessing """ -import os -import time import logging -import gevent +import os import subprocess +import time +import gevent from XSDataAutoprocv1_0 import XSDataAutoprocInput - -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataString +from XSDataCommon import ( + XSDataDouble, + XSDataFile, + XSDataInteger, + XSDataString, +) from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/MAXIV/MachInfo.py b/mxcubecore/HardwareObjects/MAXIV/MachInfo.py index ad603aecf7..40c5326672 100755 --- a/mxcubecore/HardwareObjects/MAXIV/MachInfo.py +++ b/mxcubecore/HardwareObjects/MAXIV/MachInfo.py @@ -1,10 +1,15 @@ -import re -import math import logging +import math +import re + import gevent from tango import DeviceProxy -from mxcubecore.utils.units import sec_to_hour, A_to_mA + from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo +from mxcubecore.utils.units import ( + A_to_mA, + sec_to_hour, +) # how often we refresh machine info REFRESH_PERIOD_SEC = 30 diff --git a/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py b/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py index c6cdbed28a..0a1625b1d1 100644 --- a/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py +++ b/mxcubecore/HardwareObjects/MAXIV/MaxIVSession.py @@ -4,13 +4,16 @@ Adapting from original Session.py to adapt the names of data directories """ +import logging import os -import time import socket -import logging +import time try: - from sdm import storage, Visitor + from sdm import ( + Visitor, + storage, + ) except Exception: raise Exception("Cannot import SDM library.") diff --git a/mxcubecore/HardwareObjects/MAXIV/autoProcLauncher.py b/mxcubecore/HardwareObjects/MAXIV/autoProcLauncher.py index 6060ee68dd..b95275ed56 100755 --- a/mxcubecore/HardwareObjects/MAXIV/autoProcLauncher.py +++ b/mxcubecore/HardwareObjects/MAXIV/autoProcLauncher.py @@ -4,17 +4,17 @@ # /data/staff/biomax/staff/jie/2015_11_10/processed -mode after # -datacollectionID 13 -residues 200 -anomalous False -cell "0,0,0,0,0,0" +import logging import os +import shlex +import string +import subprocess import sys +import tempfile import time -import string import urllib -import logging + import httplib -import logging -import tempfile -import subprocess -import shlex inputTemplate = """ diff --git a/mxcubecore/HardwareObjects/MAXIV/ednaProcLauncher.py b/mxcubecore/HardwareObjects/MAXIV/ednaProcLauncher.py index cc48655577..d14baec17f 100755 --- a/mxcubecore/HardwareObjects/MAXIV/ednaProcLauncher.py +++ b/mxcubecore/HardwareObjects/MAXIV/ednaProcLauncher.py @@ -3,16 +3,16 @@ # /data/staff/biomax/staff/jie/20161212_thau_2/processed4 -mode after # -datacollectionID 14 -residues 200 -anomalous False -cell "0,0,0,0,0,0" +import logging import os +import string +import subprocess import sys +import tempfile import time -import string import urllib -import logging + import httplib -import logging -import tempfile -import subprocess # XDS.INP creation is now asynchronous in mxcube, so it may not be here yet # when we're started diff --git a/mxcubecore/HardwareObjects/MD2Motor.py b/mxcubecore/HardwareObjects/MD2Motor.py index 50adfbd30e..efc1e428fd 100644 --- a/mxcubecore/HardwareObjects/MD2Motor.py +++ b/mxcubecore/HardwareObjects/MD2Motor.py @@ -1,6 +1,11 @@ import logging -from gevent import Timeout, sleep from warnings import warn + +from gevent import ( + Timeout, + sleep, +) + from mxcubecore.HardwareObjects.abstract.AbstractMotor import ( AbstractMotor, MotorStates, diff --git a/mxcubecore/HardwareObjects/MD3UP.py b/mxcubecore/HardwareObjects/MD3UP.py index e1dc6745ad..fd955b771d 100644 --- a/mxcubecore/HardwareObjects/MD3UP.py +++ b/mxcubecore/HardwareObjects/MD3UP.py @@ -1,11 +1,12 @@ -import math -import numpy import logging +import math import time +import numpy + +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects import Microdiff from mxcubecore.HardwareObjects.sample_centring import CentringMotor -from mxcubecore import HardwareRepository as HWR class MD3UP(Microdiff.Microdiff): diff --git a/mxcubecore/HardwareObjects/MachCurrent.py b/mxcubecore/HardwareObjects/MachCurrent.py index bf7b2f4dd2..853fdef8f4 100644 --- a/mxcubecore/HardwareObjects/MachCurrent.py +++ b/mxcubecore/HardwareObjects/MachCurrent.py @@ -31,9 +31,8 @@ """ import logging -from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import ( - AbstractMachineInfo, -) + +from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo __copyright__ = """ Copyright © 2010-2023 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Marvin.py b/mxcubecore/HardwareObjects/Marvin.py index 4a244c67a8..6ba8399a17 100644 --- a/mxcubecore/HardwareObjects/Marvin.py +++ b/mxcubecore/HardwareObjects/Marvin.py @@ -17,13 +17,15 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import time -import gevent import logging +import os import tempfile +import time from datetime import datetime +import gevent + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.HardwareObjects.abstract import AbstractSampleChanger from mxcubecore.HardwareObjects.abstract.sample_changer import ( @@ -32,9 +34,6 @@ Sample, ) -from mxcubecore import HardwareRepository as HWR - - POSITION_DESC = { "Park": "Parked", "PickDew": "Pick from dewar", diff --git a/mxcubecore/HardwareObjects/Microdiff.py b/mxcubecore/HardwareObjects/Microdiff.py index 0a6d542d44..2d5e3d1f4c 100644 --- a/mxcubecore/HardwareObjects/Microdiff.py +++ b/mxcubecore/HardwareObjects/Microdiff.py @@ -1,12 +1,18 @@ import logging import math import time + import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject, HardwareObjectState -from mxcubecore.HardwareObjects import MiniDiff -from mxcubecore.HardwareObjects import sample_centring from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import ( + HardwareObject, + HardwareObjectState, +) +from mxcubecore.HardwareObjects import ( + MiniDiff, + sample_centring, +) MICRODIFF = None diff --git a/mxcubecore/HardwareObjects/MicrodiffActuator.py b/mxcubecore/HardwareObjects/MicrodiffActuator.py index 96d5fc5231..f7314293fc 100644 --- a/mxcubecore/HardwareObjects/MicrodiffActuator.py +++ b/mxcubecore/HardwareObjects/MicrodiffActuator.py @@ -13,9 +13,8 @@ import logging import time -from mxcubecore.HardwareObjects.abstract.AbstractActuator import ( - AbstractActuator, -) + +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/MicrodiffAperture.py b/mxcubecore/HardwareObjects/MicrodiffAperture.py index 756cf9ea2d..03ddcda36e 100644 --- a/mxcubecore/HardwareObjects/MicrodiffAperture.py +++ b/mxcubecore/HardwareObjects/MicrodiffAperture.py @@ -38,6 +38,7 @@ """ from ast import literal_eval from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractNState import BaseValueEnum from mxcubecore.HardwareObjects.ExporterNState import ExporterNState diff --git a/mxcubecore/HardwareObjects/MicrodiffFocusMotor.py b/mxcubecore/HardwareObjects/MicrodiffFocusMotor.py index f1e1725371..5f613bb63d 100644 --- a/mxcubecore/HardwareObjects/MicrodiffFocusMotor.py +++ b/mxcubecore/HardwareObjects/MicrodiffFocusMotor.py @@ -1,5 +1,5 @@ -from mxcubecore.HardwareObjects.ExpMotor import ExpMotor from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.ExpMotor import ExpMotor class MicrodiffFocusMotor(ExpMotor): diff --git a/mxcubecore/HardwareObjects/MicrodiffInOut.py b/mxcubecore/HardwareObjects/MicrodiffInOut.py index 2c42ae4896..6dbff06c96 100644 --- a/mxcubecore/HardwareObjects/MicrodiffInOut.py +++ b/mxcubecore/HardwareObjects/MicrodiffInOut.py @@ -1,7 +1,8 @@ import logging +import time + from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates -import time """ Use the exporter to set different MD2 actuators in/out. diff --git a/mxcubecore/HardwareObjects/MicrodiffKappaMotor.py b/mxcubecore/HardwareObjects/MicrodiffKappaMotor.py index 32b4345738..71391f31fe 100644 --- a/mxcubecore/HardwareObjects/MicrodiffKappaMotor.py +++ b/mxcubecore/HardwareObjects/MicrodiffKappaMotor.py @@ -1,11 +1,11 @@ import logging import time + import gevent import numpy as np -import logging -from mxcubecore.HardwareObjects.ExporterMotor import ExporterMotor from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates +from mxcubecore.HardwareObjects.ExporterMotor import ExporterMotor class MicrodiffKappaMotor(ExporterMotor): diff --git a/mxcubecore/HardwareObjects/MicrodiffLight.py b/mxcubecore/HardwareObjects/MicrodiffLight.py index 42c5555225..257c75f1cd 100644 --- a/mxcubecore/HardwareObjects/MicrodiffLight.py +++ b/mxcubecore/HardwareObjects/MicrodiffLight.py @@ -1,5 +1,5 @@ -from mxcubecore.HardwareObjects.ExporterMotor import ExporterMotor from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.ExporterMotor import ExporterMotor class MicrodiffLight(ExporterMotor): diff --git a/mxcubecore/HardwareObjects/MicrodiffMotor.py b/mxcubecore/HardwareObjects/MicrodiffMotor.py index d9982cca47..cdb0480048 100644 --- a/mxcubecore/HardwareObjects/MicrodiffMotor.py +++ b/mxcubecore/HardwareObjects/MicrodiffMotor.py @@ -1,5 +1,7 @@ import time + from gevent import Timeout + from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor diff --git a/mxcubecore/HardwareObjects/MicrodiffSamplePseudo.py b/mxcubecore/HardwareObjects/MicrodiffSamplePseudo.py index b0266b495f..c3c2a5d25e 100644 --- a/mxcubecore/HardwareObjects/MicrodiffSamplePseudo.py +++ b/mxcubecore/HardwareObjects/MicrodiffSamplePseudo.py @@ -1,8 +1,9 @@ -from mxcubecore.HardwareObjects.MD2Motor import MD2Motor -from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates import logging import math +from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates +from mxcubecore.HardwareObjects.MD2Motor import MD2Motor + class MicrodiffSamplePseudo(MD2Motor): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/MicrodiffZoom.py b/mxcubecore/HardwareObjects/MicrodiffZoom.py index 2afc6ab53b..fbb638ec6a 100644 --- a/mxcubecore/HardwareObjects/MicrodiffZoom.py +++ b/mxcubecore/HardwareObjects/MicrodiffZoom.py @@ -33,6 +33,7 @@ """ from enum import Enum + from mxcubecore.HardwareObjects.ExporterNState import ExporterNState __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 1b8a553802..2bee7b4bc8 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -1,25 +1,22 @@ -import gevent -import tempfile +import copy +import json import logging import math import os +import tempfile import time -import copy -import numpy -import json - from typing import Union + +import gevent +import numpy from pydantic import ValidationError +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task from mxcubecore.HardwareObjects import sample_centring +from mxcubecore.HardwareObjects.GenericDiffractometer import GonioHeadConfiguration from mxcubecore.model import queue_model_objects as qmo -from mxcubecore import HardwareRepository as HWR - -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GonioHeadConfiguration, -) +from mxcubecore.TaskUtils import task try: from Qub.Tools import QubImageSave diff --git a/mxcubecore/HardwareObjects/MiniKappaCorrection.py b/mxcubecore/HardwareObjects/MiniKappaCorrection.py index a56c2efb82..9524b6b0b7 100644 --- a/mxcubecore/HardwareObjects/MiniKappaCorrection.py +++ b/mxcubecore/HardwareObjects/MiniKappaCorrection.py @@ -1,7 +1,9 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject import math + import numpy as np +from mxcubecore.BaseHardwareObjects import HardwareObject + class MiniKappaCorrection(HardwareObject): """ diff --git a/mxcubecore/HardwareObjects/MotorWPositions.py b/mxcubecore/HardwareObjects/MotorWPositions.py index 6a0bc3f010..bceebef658 100644 --- a/mxcubecore/HardwareObjects/MotorWPositions.py +++ b/mxcubecore/HardwareObjects/MotorWPositions.py @@ -18,6 +18,7 @@ # along with MXCuBE. If not, see . import logging + from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor diff --git a/mxcubecore/HardwareObjects/MotorsNPosition.py b/mxcubecore/HardwareObjects/MotorsNPosition.py index 13257c5d73..5dcdd2effb 100644 --- a/mxcubecore/HardwareObjects/MotorsNPosition.py +++ b/mxcubecore/HardwareObjects/MotorsNPosition.py @@ -23,9 +23,9 @@ from collections import OrderedDict +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates -from mxcubecore.BaseHardwareObjects import HardwareObjectState class MotorsNPosition(AbstractActuator): diff --git a/mxcubecore/HardwareObjects/MultiplePositions.py b/mxcubecore/HardwareObjects/MultiplePositions.py index 1e49961c89..c79eeb511f 100644 --- a/mxcubecore/HardwareObjects/MultiplePositions.py +++ b/mxcubecore/HardwareObjects/MultiplePositions.py @@ -144,9 +144,10 @@ except ImportError: import cElementTree -from mxcubecore.BaseHardwareObjects import HardwareObject import logging +from mxcubecore.BaseHardwareObjects import HardwareObject + class MultiplePositions(HardwareObject): def init(self): diff --git a/mxcubecore/HardwareObjects/Native/__init__.py b/mxcubecore/HardwareObjects/Native/__init__.py index 652e6abb4c..a9ee3d31af 100644 --- a/mxcubecore/HardwareObjects/Native/__init__.py +++ b/mxcubecore/HardwareObjects/Native/__init__.py @@ -1,11 +1,15 @@ # -*- coding: utf-8 -*- -import jsonpickle import inspect import logging -from mxcubecore.model import queue_model_objects -from mxcubecore.model import queue_model_enumerables + +import jsonpickle + from mxcubecore import HardwareRepository as HWR +from mxcubecore.model import ( + queue_model_enumerables, + queue_model_objects, +) xmlrpc_prefix = "" diff --git a/mxcubecore/HardwareObjects/ObjectsController.py b/mxcubecore/HardwareObjects/ObjectsController.py index 8019cfd82f..364674fd59 100644 --- a/mxcubecore/HardwareObjects/ObjectsController.py +++ b/mxcubecore/HardwareObjects/ObjectsController.py @@ -1,7 +1,8 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject import os import sys +from mxcubecore.BaseHardwareObjects import HardwareObject + class ObjectsController(HardwareObject): def __init__(self, *args): diff --git a/mxcubecore/HardwareObjects/PlateManipulator.py b/mxcubecore/HardwareObjects/PlateManipulator.py index 2d0b60dacb..8637d9a54e 100644 --- a/mxcubecore/HardwareObjects/PlateManipulator.py +++ b/mxcubecore/HardwareObjects/PlateManipulator.py @@ -32,20 +32,21 @@ ----------------------------------------------------------------------- """ +import logging import time + import gevent -import logging -from mxcubecore.HardwareObjects.abstract.sample_changer import Crims from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( SampleChanger, + SampleChangerMode, SampleChangerState, - SampleChangerMode ) +from mxcubecore.HardwareObjects.abstract.sample_changer import Crims from mxcubecore.HardwareObjects.abstract.sample_changer.Container import ( + Basket, Container, Sample, - Basket, ) diff --git a/mxcubecore/HardwareObjects/PyISPyBClient.py b/mxcubecore/HardwareObjects/PyISPyBClient.py index 648e71730b..966adc9cd2 100644 --- a/mxcubecore/HardwareObjects/PyISPyBClient.py +++ b/mxcubecore/HardwareObjects/PyISPyBClient.py @@ -2,42 +2,37 @@ A client for PyISPyB Webservices. """ -import os +import datetime import json import logging -import datetime - -from typing_extensions import Literal - -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR -from mxcubecore.model.common import BeamlineParameters, ISPYBCollectionPrameters +import os import pyispyb_client - -from pyispyb_client.apis.tags import authentication_api -from pyispyb_client.model.login import Login - -from pyispyb_client.apis.tags import webservices_serial_crystallography_api -from pyispyb_client.apis.tags import serial_crystallography_api -from pyispyb_client.model.ssx_data_collection_create import ( - SSXDataCollectionCreate, +from pyispyb_client import Configuration +from pyispyb_client.apis.tags import ( + authentication_api, + serial_crystallography_api, + webservices_serial_crystallography_api, ) +from pyispyb_client.model.event_chain_create import EventChainCreate +from pyispyb_client.model.event_create import EventCreate +from pyispyb_client.model.login import Login +from pyispyb_client.model.ssx_crystal_create import SSXCrystalCreate +from pyispyb_client.model.ssx_data_collection_create import SSXDataCollectionCreate from pyispyb_client.model.ssx_data_collection_group_create import ( SSXDataCollectionGroupCreate, ) -from pyispyb_client.model.ssx_sample_create import SSXSampleCreate -from pyispyb_client.model.ssx_crystal_create import SSXCrystalCreate from pyispyb_client.model.ssx_protein_create import SSXProteinCreate -from pyispyb_client.model.ssx_sample_component_create import ( - SSXSampleComponentCreate, -) -from pyispyb_client.model.event_chain_create import EventChainCreate -from pyispyb_client.model.event_create import ( - EventCreate, -) +from pyispyb_client.model.ssx_sample_component_create import SSXSampleComponentCreate +from pyispyb_client.model.ssx_sample_create import SSXSampleCreate +from typing_extensions import Literal -from pyispyb_client import Configuration +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.model.common import ( + BeamlineParameters, + ISPYBCollectionPrameters, +) class PyISPyBClient(HardwareObject): diff --git a/mxcubecore/HardwareObjects/QtAxisCamera.py b/mxcubecore/HardwareObjects/QtAxisCamera.py index 84867fd23d..b0baea0d9a 100755 --- a/mxcubecore/HardwareObjects/QtAxisCamera.py +++ b/mxcubecore/HardwareObjects/QtAxisCamera.py @@ -17,20 +17,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import time -import Image import base64 -import urllib2 +import time +import Image import numpy as np - +import urllib2 from cStringIO import StringIO from PIL.ImageQt import ImageQt +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice from mxcubecore.utils import qt_import -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import ( - AbstractVideoDevice, -) """ Hardare objects allows to access Axis camera jpg frames via direct http requests. diff --git a/mxcubecore/HardwareObjects/QtGraphicsLib.py b/mxcubecore/HardwareObjects/QtGraphicsLib.py index a3269b6535..313c271f71 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsLib.py +++ b/mxcubecore/HardwareObjects/QtGraphicsLib.py @@ -43,16 +43,14 @@ """ import copy -import math import logging +import math from datetime import datetime -from mxcubecore.utils import qt_import - from mxcubecore.model import queue_model_objects +from mxcubecore.utils import qt_import from mxcubecore.utils.conversion import string_types - SELECTED_COLOR = qt_import.Qt.green NORMAL_COLOR = qt_import.Qt.yellow SOLID_LINE_STYLE = qt_import.Qt.SolidLine diff --git a/mxcubecore/HardwareObjects/QtGraphicsManager.py b/mxcubecore/HardwareObjects/QtGraphicsManager.py index 7c71c06779..01463a05de 100644 --- a/mxcubecore/HardwareObjects/QtGraphicsManager.py +++ b/mxcubecore/HardwareObjects/QtGraphicsManager.py @@ -37,24 +37,28 @@ """ from __future__ import print_function -import os -import math + import logging +import math +import os try: import cPickle as pickle except Exception: import _pickle as pickle -from datetime import datetime from copy import deepcopy +from datetime import datetime import gevent +import matplotlib.pyplot as plt import numpy as np -from scipy import ndimage, interpolate, signal - from matplotlib import cm -import matplotlib.pyplot as plt +from scipy import ( + interpolate, + ndimage, + signal, +) try: import lucid2 as lucid @@ -64,15 +68,11 @@ except ImportError: pass -from mxcubecore.utils import qt_import - -from mxcubecore.model import queue_model_objects -from mxcubecore.HardwareObjects import QtGraphicsLib as GraphicsLib -from mxcubecore.HardwareObjects.abstract.AbstractSampleView import ( - AbstractSampleView, -) - from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects import QtGraphicsLib as GraphicsLib +from mxcubecore.HardwareObjects.abstract.AbstractSampleView import AbstractSampleView +from mxcubecore.model import queue_model_objects +from mxcubecore.utils import qt_import __credits__ = ["MXCuBE collaboration"] __category__ = "Graphics" diff --git a/mxcubecore/HardwareObjects/QtInstanceServer.py b/mxcubecore/HardwareObjects/QtInstanceServer.py index aecff95be6..0b4510db8b 100644 --- a/mxcubecore/HardwareObjects/QtInstanceServer.py +++ b/mxcubecore/HardwareObjects/QtInstanceServer.py @@ -1,13 +1,14 @@ -from mxcubecore.BaseHardwareObjects import Procedure import logging -import time -import pickle import os +import pickle +import pwd +import socket +import time + import gevent import gevent.server -import socket -import pwd +from mxcubecore.BaseHardwareObjects import Procedure from mxcubecore.utils import qt_import """ diff --git a/mxcubecore/HardwareObjects/QtLimaVideo.py b/mxcubecore/HardwareObjects/QtLimaVideo.py index defee8e57f..6db19b27f8 100644 --- a/mxcubecore/HardwareObjects/QtLimaVideo.py +++ b/mxcubecore/HardwareObjects/QtLimaVideo.py @@ -45,9 +45,7 @@ """ import logging -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import ( - AbstractVideoDevice, -) +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice try: from Lima import Core diff --git a/mxcubecore/HardwareObjects/QtTangoLimaVideo.py b/mxcubecore/HardwareObjects/QtTangoLimaVideo.py index 9a2a59f12e..92ae80a778 100644 --- a/mxcubecore/HardwareObjects/QtTangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/QtTangoLimaVideo.py @@ -41,13 +41,11 @@ """ import struct -import numpy as np +import numpy as np import PyTango -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import ( - AbstractVideoDevice, -) +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice class QtTangoLimaVideo(AbstractVideoDevice): diff --git a/mxcubecore/HardwareObjects/QueueManager.py b/mxcubecore/HardwareObjects/QueueManager.py index bf4dc51dcc..c7a4481602 100644 --- a/mxcubecore/HardwareObjects/QueueManager.py +++ b/mxcubecore/HardwareObjects/QueueManager.py @@ -9,13 +9,14 @@ """ import logging -import gevent import traceback +import gevent + from mxcubecore import queue_entry from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.queue_entry.base_queue_entry import QUEUE_ENTRY_STATUS from mxcubecore.queue_entry import base_queue_entry +from mxcubecore.queue_entry.base_queue_entry import QUEUE_ENTRY_STATUS QueueEntryContainer = base_queue_entry.QueueEntryContainer diff --git a/mxcubecore/HardwareObjects/QueueModel.py b/mxcubecore/HardwareObjects/QueueModel.py index fc0691fdce..ccba096c45 100644 --- a/mxcubecore/HardwareObjects/QueueModel.py +++ b/mxcubecore/HardwareObjects/QueueModel.py @@ -26,15 +26,16 @@ handle several models by using register_model and select_model. """ -import os import json import logging +import os + import jsonpickle -from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore import HardwareRepository as HWR from mxcubecore import queue_entry +from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.model import queue_model_objects -from mxcubecore import HardwareRepository as HWR class Serializer(object): diff --git a/mxcubecore/HardwareObjects/RedisClient.py b/mxcubecore/HardwareObjects/RedisClient.py index e94b93cde5..584dd873c0 100644 --- a/mxcubecore/HardwareObjects/RedisClient.py +++ b/mxcubecore/HardwareObjects/RedisClient.py @@ -33,14 +33,14 @@ """ -import redis -import gevent import logging + +import gevent import jsonpickle +import redis -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject __version__ = "2.3." __category__ = "General" diff --git a/mxcubecore/HardwareObjects/Resolution.py b/mxcubecore/HardwareObjects/Resolution.py index a3e77b18f3..aa929a0742 100644 --- a/mxcubecore/HardwareObjects/Resolution.py +++ b/mxcubecore/HardwareObjects/Resolution.py @@ -29,9 +29,7 @@ """ -from mxcubecore.HardwareObjects.abstract.AbstractResolution import ( - AbstractResolution, -) +from mxcubecore.HardwareObjects.abstract.AbstractResolution import AbstractResolution __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Robodiff.py b/mxcubecore/HardwareObjects/Robodiff.py index 878790f22b..034ceb11a8 100644 --- a/mxcubecore/HardwareObjects/Robodiff.py +++ b/mxcubecore/HardwareObjects/Robodiff.py @@ -1,3 +1,5 @@ +import gevent + from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( Container, Sample, @@ -7,7 +9,6 @@ task, time, ) -import gevent class Pin(Sample): diff --git a/mxcubecore/HardwareObjects/RobodiffLight.py b/mxcubecore/HardwareObjects/RobodiffLight.py index fe248b5e60..e97570529d 100644 --- a/mxcubecore/HardwareObjects/RobodiffLight.py +++ b/mxcubecore/HardwareObjects/RobodiffLight.py @@ -1,8 +1,10 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor import time + import gevent +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + class RobodiffLight(Device, AbstractMotor): states = {0: "out", 1: "in"} diff --git a/mxcubecore/HardwareObjects/RobodiffMotor.py b/mxcubecore/HardwareObjects/RobodiffMotor.py index 38ac9b91b8..25d2bcb9be 100644 --- a/mxcubecore/HardwareObjects/RobodiffMotor.py +++ b/mxcubecore/HardwareObjects/RobodiffMotor.py @@ -1,7 +1,8 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR import gevent +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject + class RobodiffMotor(HardwareObject): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) diff --git a/mxcubecore/HardwareObjects/RobodiffMotorWPositions.py b/mxcubecore/HardwareObjects/RobodiffMotorWPositions.py index 6faf380d70..e869d81b68 100644 --- a/mxcubecore/HardwareObjects/RobodiffMotorWPositions.py +++ b/mxcubecore/HardwareObjects/RobodiffMotorWPositions.py @@ -1,6 +1,7 @@ -from mxcubecore.HardwareObjects.RobodiffMotor import RobodiffMotor import logging +from mxcubecore.HardwareObjects.RobodiffMotor import RobodiffMotor + class RobodiffMotorWPositions(RobodiffMotor): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/SC3.py b/mxcubecore/HardwareObjects/SC3.py index 723c2d003f..0ab9248348 100644 --- a/mxcubecore/HardwareObjects/SC3.py +++ b/mxcubecore/HardwareObjects/SC3.py @@ -1,3 +1,6 @@ +import xml.sax +from xml.sax.handler import ContentHandler + from mxcubecore.HardwareObjects.abstract.AbstractSampleChanger import ( Container, Sample, @@ -8,9 +11,6 @@ sys, ) -import xml.sax -from xml.sax.handler import ContentHandler - class Pin(Sample): def __init__(self, basket, basket_no, sample_no): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Attenuator.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Attenuator.py index c59a436952..b9001b697e 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Attenuator.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Attenuator.py @@ -1,4 +1,5 @@ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1CatsMaint.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1CatsMaint.py index 32bfde811f..f03c9b353d 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1CatsMaint.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1CatsMaint.py @@ -1,10 +1,10 @@ # -from mxcubecore.HardwareObjects.CatsMaint import CatsMaint -from mxcubecore import HardwareRepository as HWR - import logging import time +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.CatsMaint import CatsMaint + class PX1CatsMaint(CatsMaint): def __init__(self, *args): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Collect.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Collect.py index 5117a8160a..aee801cc40 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Collect.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Collect.py @@ -3,23 +3,21 @@ """ +import logging import os +import socket +import subprocess import sys import time -import logging -import gevent -import subprocess -import socket - -from mxcubecore.Command.Tango import DeviceProxy - -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +import gevent from SOLEILMergeImage import merge as merge_images from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.Command.Tango import DeviceProxy +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task __author__ = "Vicente Rey Bakaikoa" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Cryotong.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Cryotong.py index 4ca94295e5..da707cda9e 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Cryotong.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Cryotong.py @@ -1,19 +1,18 @@ from __future__ import print_function + import logging -import gevent import time -from mxcubecore.Command.Tango import DeviceProxy - +import gevent +from PX1Environment import EnvironmentPhase +from mxcubecore.Command.Tango import DeviceProxy from mxcubecore.HardwareObjects.Cats90 import ( + BASKET_UNIPUCK, Cats90, SampleChangerState, - BASKET_UNIPUCK, ) -from PX1Environment import EnvironmentPhase - class PX1Cryotong(Cats90): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1DetectorDistance.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1DetectorDistance.py index 4aecfef96d..8650a78be4 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1DetectorDistance.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1DetectorDistance.py @@ -1,4 +1,5 @@ import time + import gevent from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Energy.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Energy.py index 316f67682a..1f359f0b1e 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Energy.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Energy.py @@ -1,14 +1,13 @@ # from qt import * -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy - -from mxcubecore.Command.Tango import DeviceProxy - import logging import os import time +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.Command.Tango import DeviceProxy +from mxcubecore.HardwareObjects.abstract.AbstractEnergy import AbstractEnergy + class PX1Energy(Device, AbstractEnergy): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py index e1165a6770..69fc97d6bc 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1EnergyScan.py @@ -12,24 +12,25 @@ """ import logging -import os -import time import math -import numpy -import gevent +import os import subprocess +import time -from matplotlib.figure import Figure -from matplotlib.backends.backend_agg import FigureCanvasAgg - +import gevent +import numpy from AbstractEnergyScan import AbstractEnergyScan -from mxcubecore.TaskUtils import task, cleanup - +from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure from xabs_lib import McMaster -from mxcubecore.Command.Tango import DeviceProxy -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.Command.Tango import DeviceProxy +from mxcubecore.TaskUtils import ( + cleanup, + task, +) class PX1EnergyScan(AbstractEnergyScan, Equipment): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py index e190ebac01..9396d5245d 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Environment.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -import time import logging -import gevent +import time -from mxcubecore.Command.Tango import DeviceProxy +import gevent from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.Command.Tango import DeviceProxy from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1MiniDiff.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1MiniDiff.py index e300630547..e8a405b5b2 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1MiniDiff.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1MiniDiff.py @@ -1,11 +1,10 @@ import logging -import gevent import time -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, -) +import gevent + from mxcubecore.HardwareObjects import sample_centring +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer class PX1MiniDiff(GenericDiffractometer): @@ -207,9 +206,7 @@ def move_motors(self, motor_positions, timeout=15): and target values. :type motors_dict: dict """ - from mxcubecore.model.queue_model_objects import ( - CentredPosition, - ) + from mxcubecore.model.queue_model_objects import CentredPosition if isinstance(motor_positions, CentredPosition): motor_positions_copy = motor_positions.as_dict() diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pilatus.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pilatus.py index e6a48deab1..c336843551 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pilatus.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pilatus.py @@ -20,10 +20,8 @@ import logging import time -from mxcubecore.HardwareObjects.abstract.AbstractDetector import ( - AbstractDetector, -) from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector __author__ = "Vicente Rey" __credits__ = ["SOLEIL"] diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pss.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pss.py index 0e8759482c..deab63cb8a 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pss.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Pss.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import logging + from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py index 3afb38f633..db12fbede5 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Resolution.py @@ -1,10 +1,9 @@ -import math import logging +import math import time -from mxcubecore.Command.Tango import DeviceProxy - from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.Command.Tango import DeviceProxy DETECTOR_DIAMETER = 424.0 diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py index 7a0da6b2b4..4a2ff7a9a8 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX1/PX1TangoLight.py @@ -1,5 +1,6 @@ import logging import time + import gevent from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py index 034d9a0f97..bb893cf4d6 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Attenuator.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- # from SimpleDevice2c import SimpleDevice -from PyTango.gevent import DeviceProxy import logging import math +from PyTango.gevent import DeviceProxy + from mxcubecore.BaseHardwareObjects import HardwareObject # from Command.Tango import TangoChannel diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py index 3bf732fc66..afae0df357 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2BeamInfo.py @@ -31,6 +31,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Collect.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Collect.py index ca1d0da4fd..ceb5890655 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Collect.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Collect.py @@ -16,28 +16,28 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os import logging -import gevent -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +import os -from omega_scan import omega_scan -from inverse_scan import inverse_scan -from reference_images import reference_images -from helical_scan import helical_scan -from fluorescence_spectrum import fluorescence_spectrum +import gevent from energy_scan import energy_scan +from film import film +from fluorescence_spectrum import fluorescence_spectrum +from helical_scan import helical_scan +from inverse_scan import inverse_scan +from nested_helical_acquisition import nested_helical_acquisition +from omega_scan import omega_scan # from xray_centring import xray_centring from raster_scan import raster_scan -from nested_helical_acquisition import nested_helical_acquisition +from reference_images import reference_images +from slits import slits1 from tomography import tomography -from film import film -from mxcubecore import HardwareRepository as HWR -from slits import slits1 +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task __credits__ = ["Synchrotron SOLEIL"] __version__ = "2.3." diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Diffractometer.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Diffractometer.py index 7e2f0ee6ef..0d926361dd 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Diffractometer.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Diffractometer.py @@ -17,30 +17,27 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . +import copy +import datetime +import logging import os +import pickle import time -import logging import traceback -import pickle -import copy -import datetime -import h5py - -import numpy as np -from scipy.optimize import minimize from math import sqrt -import gevent - -from goniometer import goniometer -from detector import detector -from camera import camera - import beam_align -import scan_and_align +import gevent +import h5py +import numpy as np import optical_alignment - +import scan_and_align from anneal import anneal as anneal_procedure +from camera import camera +from detector import detector +from goniometer import goniometer +from scipy.optimize import minimize + from mxcubecore.model.queue_model_enumerables import CENTRING_METHOD try: @@ -62,12 +59,9 @@ "Could not find autocentring library, automatic centring is disabled" ) -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - GenericDiffractometer, -) - -from mxcubecore.TaskUtils import task from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractometer +from mxcubecore.TaskUtils import task __credits__ = ["SOLEIL"] __version__ = "2.3." diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Energy.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Energy.py index d04ea889f3..7bf332f134 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Energy.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Energy.py @@ -1,8 +1,16 @@ -from mxcubecore.HardwareObjects.mockup.EnergyMockup import EnergyMockup -from energy import energy -from scipy.constants import kilo, h, c, eV, angstrom import logging +from energy import energy +from scipy.constants import ( + angstrom, + c, + eV, + h, + kilo, +) + +from mxcubecore.HardwareObjects.mockup.EnergyMockup import EnergyMockup + class PX2Energy(EnergyMockup): def init(self): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py index 830e1993b0..d411825287 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Guillotine.py @@ -12,6 +12,7 @@ import logging import time + from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Qt4_LimaVideo.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Qt4_LimaVideo.py index 7a617547a8..2f31a215e6 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Qt4_LimaVideo.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Qt4_LimaVideo.py @@ -43,10 +43,10 @@ 30 """ -import os -import time import logging +import os import struct +import time from mxcubecore.HardwareObjects.QtLimaVideo import QtLimaVideo @@ -110,10 +110,10 @@ def set_exposure_time(self, exposure_time): def test_hwo(): - from mxcubecore.utils.qt_import import * import time from mxcubecore import HardwareRepository as HWR + from mxcubecore.utils.qt_import import * hwr = HWR.get_hardware_repository() hwr.connect() diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py index c387c2e975..252a17280c 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py @@ -1,8 +1,10 @@ import logging -from mxcubecore.HardwareObjects.abstract.AbstractResolution import AbstractResolution -from mxcubecore import HardwareRepository as HWR -from resolution import resolution + from beam_center import beam_center +from resolution import resolution + +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractResolution import AbstractResolution class PX2Resolution(AbstractResolution): diff --git a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Video.py b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Video.py index 768e2168cc..7b7bcaeab3 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Video.py +++ b/mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Video.py @@ -40,17 +40,20 @@ """ +import logging import os +import struct import time + import gevent -import logging -import struct import numpy as np - -from GenericVideoDevice import GenericVideoDevice from camera import camera +from GenericVideoDevice import GenericVideoDevice -from mxcubecore.utils.qt_import import QImage, QPixmap +from mxcubecore.utils.qt_import import ( + QImage, + QPixmap, +) class PX2Video(GenericVideoDevice, camera): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py index 39e9749cce..728e324edc 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILCatsMaint.py @@ -6,11 +6,13 @@ """ import logging -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -import gevent import time +import gevent + +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task + __author__ = "Michael Hellmig" __credits__ = ["The MxCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILEnergyScan.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILEnergyScan.py index b0f0ed0d98..a59e0097ae 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILEnergyScan.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILEnergyScan.py @@ -1,17 +1,17 @@ import logging -import PyChooch +import math import os import time -import math + import gevent +import PyChooch import Xane - -from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.TaskUtils import cleanup -from mxcubecore import HardwareRepository as HWR class SOLEILEnergyScan(HardwareObject): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py index 2a59362d20..59102dd5cf 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILFlux.py @@ -1,6 +1,7 @@ +import PyTango + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject -import PyTango class SOLEILFlux(HardwareObject): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py index 700ec7bb2e..c8a5a36191 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILGuillotine.py @@ -10,9 +10,10 @@ """ -from mxcubecore import BaseHardwareObjects import logging import time + +from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILISPyBClient.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILISPyBClient.py index a701c4a579..945fa551c3 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILISPyBClient.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILISPyBClient.py @@ -1,14 +1,17 @@ import logging -import urllib2 import os -from cookielib import CookieJar +import traceback +from collections import namedtuple -from suds.transport.http import HttpAuthenticated +import urllib2 +from cookielib import CookieJar +from ISPyBClient import ( + _CONNECTION_ERROR_MSG, + ISPyBClient, +) from suds.client import Client +from suds.transport.http import HttpAuthenticated -from ISPyBClient import ISPyBClient, _CONNECTION_ERROR_MSG -import traceback -from collections import namedtuple from mxcubecore import HardwareRepository as HWR # The WSDL root is configured in the hardware object XML file. diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILMachineInfo.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILMachineInfo.py index f4948556b2..d25021292d 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILMachineInfo.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILMachineInfo.py @@ -59,14 +59,18 @@ 'discSizeGB': 20} """ +import logging import os import time -import logging +from datetime import ( + datetime, + timedelta, +) + from gevent import spawn from urllib2 import urlopen -from datetime import datetime, timedelta -from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["SOLEIL", "EMBL Hamburg"] __version__ = "2.3." diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py index a7b3df9ff2..998fbad8c3 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILPss.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- import logging import time -from mxcubecore.BaseHardwareObjects import HardwareObject + from PyTango import DeviceProxy +from mxcubecore.BaseHardwareObjects import HardwareObject + """Complex means we are not using SimpleDevice""" diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILRuche.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILRuche.py index 830164ecf8..2a0847eb57 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILRuche.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILRuche.py @@ -1,8 +1,9 @@ +import logging import os import time -import logging -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class SOLEILRuche(HardwareObject): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILSafetyShutter.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILSafetyShutter.py index 7a60eca910..4abbed7f25 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILSafetyShutter.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILSafetyShutter.py @@ -1,7 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject - import logging +from mxcubecore.BaseHardwareObjects import HardwareObject + class SOLEILSafetyShutter(HardwareObject): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILSession.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILSession.py index 3d3345b0e7..2bd4b19c5e 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILSession.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILSession.py @@ -1,8 +1,9 @@ +import logging import os import time -import logging import Session + from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/SOLEIL/SOLEILqueue_entry.py b/mxcubecore/HardwareObjects/SOLEIL/SOLEILqueue_entry.py index ebfc90dff3..42fdbebc3a 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/SOLEILqueue_entry.py +++ b/mxcubecore/HardwareObjects/SOLEIL/SOLEILqueue_entry.py @@ -1,5 +1,5 @@ -from mxcubecore.queue_entry import * from mxcubecore.model import queue_model_objects +from mxcubecore.queue_entry import * class PX2DataCollectionQueueEntry(DataCollectionQueueEntry): diff --git a/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py b/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py index c4c1ae3c8f..079059b558 100644 --- a/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py +++ b/mxcubecore/HardwareObjects/SOLEIL/TangoDCMotor.py @@ -1,16 +1,13 @@ -from mxcubecore import HardwareRepository as HWR - import logging + import gevent +import numpy +from PyQt4.QtGui import QApplication +from PyTango import DeviceProxy +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.Command.Tango import TangoCommand - -from PyTango import DeviceProxy - -from PyQt4.QtGui import QApplication - -import numpy from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index d6ab601489..5bd31fe56b 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -23,13 +23,9 @@ import copy from functools import reduce -from mxcubecore.model import queue_model_objects - -from mxcubecore.HardwareObjects.abstract.AbstractSampleView import ( - AbstractSampleView, -) - from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractSampleView import AbstractSampleView +from mxcubecore.model import queue_model_objects class SampleView(AbstractSampleView): diff --git a/mxcubecore/HardwareObjects/SardanaMotor.py b/mxcubecore/HardwareObjects/SardanaMotor.py index 2b8c44bf15..efbb5fbcb3 100644 --- a/mxcubecore/HardwareObjects/SardanaMotor.py +++ b/mxcubecore/HardwareObjects/SardanaMotor.py @@ -1,10 +1,15 @@ +import enum import logging import time -import enum -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor -from mxcubecore.BaseHardwareObjects import HardwareObject, HardwareObjectState + from gevent import Timeout +from mxcubecore.BaseHardwareObjects import ( + HardwareObject, + HardwareObjectState, +) +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + """ Interfaces Sardana Motor objects. taurusname is the only obligatory property. diff --git a/mxcubecore/HardwareObjects/Session.py b/mxcubecore/HardwareObjects/Session.py index 4dec423be4..b9d6676ac1 100644 --- a/mxcubecore/HardwareObjects/Session.py +++ b/mxcubecore/HardwareObjects/Session.py @@ -6,13 +6,12 @@ """ import os -import time import socket +import time +from typing import Tuple from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.model.queue_model_objects import PathTemplate -from typing import Tuple - default_raw_data_folder = "RAW_DATA" default_processed_data_folder = "PROCESSED_DATA" diff --git a/mxcubecore/HardwareObjects/SimpleHTML.py b/mxcubecore/HardwareObjects/SimpleHTML.py index 22dcab81f1..12abd68dc0 100644 --- a/mxcubecore/HardwareObjects/SimpleHTML.py +++ b/mxcubecore/HardwareObjects/SimpleHTML.py @@ -1,5 +1,6 @@ -import json import base64 +import json + from PIL import Image HTML_START = """ diff --git a/mxcubecore/HardwareObjects/SpecMotor.py b/mxcubecore/HardwareObjects/SpecMotor.py index 1717d5a937..412ee2c904 100644 --- a/mxcubecore/HardwareObjects/SpecMotor.py +++ b/mxcubecore/HardwareObjects/SpecMotor.py @@ -1,6 +1,7 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject from SpecClient_gevent.SpecMotor import SpecMotorA +from mxcubecore.BaseHardwareObjects import HardwareObject + class SpecMotor(HardwareObject, SpecMotorA): (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) diff --git a/mxcubecore/HardwareObjects/SpecMotorWPositions.py b/mxcubecore/HardwareObjects/SpecMotorWPositions.py index 03b864f166..770c9f9f9d 100644 --- a/mxcubecore/HardwareObjects/SpecMotorWPositions.py +++ b/mxcubecore/HardwareObjects/SpecMotorWPositions.py @@ -1,6 +1,7 @@ -from mxcubecore.HardwareObjects import SpecMotor import logging +from mxcubecore.HardwareObjects import SpecMotor + class SpecMotorWPositions(SpecMotor.SpecMotor): def init(self): diff --git a/mxcubecore/HardwareObjects/SpecScan.py b/mxcubecore/HardwareObjects/SpecScan.py index a11be727b2..050ffc813e 100644 --- a/mxcubecore/HardwareObjects/SpecScan.py +++ b/mxcubecore/HardwareObjects/SpecScan.py @@ -1,6 +1,8 @@ try: - from SpecClient_gevent import SpecEventsDispatcher - from SpecClient_gevent import SpecConnectionsManager + from SpecClient_gevent import ( + SpecConnectionsManager, + SpecEventsDispatcher, + ) except ImportError: from SpecClient import SpecEventsDispatcher from SpecClient import SpecConnectionsManager diff --git a/mxcubecore/HardwareObjects/SpecShell.py b/mxcubecore/HardwareObjects/SpecShell.py index c4fe5c876f..01aa6ca1f9 100644 --- a/mxcubecore/HardwareObjects/SpecShell.py +++ b/mxcubecore/HardwareObjects/SpecShell.py @@ -7,6 +7,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import HardwareObject try: @@ -14,7 +15,10 @@ except ImportError: import SpecClient -from qt import PYSIGNAL, QObject +from qt import ( + PYSIGNAL, + QObject, +) class SpecOutputVar(QObject, SpecClient.SpecVariable.SpecVariableA): diff --git a/mxcubecore/HardwareObjects/SpecState.py b/mxcubecore/HardwareObjects/SpecState.py index bf1d1128e9..cf848feef0 100644 --- a/mxcubecore/HardwareObjects/SpecState.py +++ b/mxcubecore/HardwareObjects/SpecState.py @@ -7,6 +7,7 @@ """ import logging + from mxcubecore.BaseHardwareObjects import Procedure try: diff --git a/mxcubecore/HardwareObjects/StateMachine.py b/mxcubecore/HardwareObjects/StateMachine.py index b81bdbfbc5..7d45dbe6d2 100644 --- a/mxcubecore/HardwareObjects/StateMachine.py +++ b/mxcubecore/HardwareObjects/StateMachine.py @@ -17,14 +17,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import time -import yaml import logging - +import time from datetime import datetime -from mxcubecore.BaseHardwareObjects import HardwareObject +import yaml +from mxcubecore.BaseHardwareObjects import HardwareObject __author__ = "EMBL Hamburg" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py index 2c47d5da16..1f8191f340 100644 --- a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py @@ -16,6 +16,7 @@ import os import subprocess import uuid + import psutil from mxcubecore.HardwareObjects.TangoLimaVideo import TangoLimaVideo diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 439212cf68..9be8283c1d 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -13,16 +13,16 @@ If video mode is not specified, BAYER_RG16 is used by default. """ +import io import logging -import time import struct -import numpy +import time + import gevent +import gipc +import numpy import PyTango from PIL import Image -import io -import gipc - from PyTango.gevent import DeviceProxy from mxcubecore import BaseHardwareObjects diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py b/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py index cb03a6d9b7..dd6092cda8 100644 --- a/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py @@ -63,9 +63,10 @@ """ from __future__ import print_function + import struct -import numpy as np +import numpy as np import PyTango from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py index 583c88196c..6dd85319ec 100644 --- a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py @@ -13,17 +13,21 @@ If video mode is not specified, BAYER_RG16 is used by default. """ +import fcntl import logging -import v4l2 -import gipc import os -import fcntl import subprocess import time import uuid + import gevent +import gipc +import v4l2 -from mxcubecore.HardwareObjects.TangoLimaVideo import TangoLimaVideo, poll_image +from mxcubecore.HardwareObjects.TangoLimaVideo import ( + TangoLimaVideo, + poll_image, +) def _poll_image(sleep_time, video_device, device_uri, video_mode, formats): diff --git a/mxcubecore/HardwareObjects/TangoMachineInfo.py b/mxcubecore/HardwareObjects/TangoMachineInfo.py index 6c1a74490d..e62021ffa9 100644 --- a/mxcubecore/HardwareObjects/TangoMachineInfo.py +++ b/mxcubecore/HardwareObjects/TangoMachineInfo.py @@ -30,9 +30,8 @@ """ import logging -from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import ( - AbstractMachineInfo, -) + +from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/TangoMotor.py b/mxcubecore/HardwareObjects/TangoMotor.py index 97ddb3bf95..73ea920bfc 100644 --- a/mxcubecore/HardwareObjects/TangoMotor.py +++ b/mxcubecore/HardwareObjects/TangoMotor.py @@ -20,10 +20,10 @@ TangoMotor class defines motor in the Tango control system (used and tested in DESY/P11 """ -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor - import gevent +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor + __credits__ = ["DESY P11"] __license__ = "LGPLv3+" __category__ = "Motor" diff --git a/mxcubecore/HardwareObjects/TangoShutter.py b/mxcubecore/HardwareObjects/TangoShutter.py index 5f85abe05a..1fc378d1da 100644 --- a/mxcubecore/HardwareObjects/TangoShutter.py +++ b/mxcubecore/HardwareObjects/TangoShutter.py @@ -39,9 +39,13 @@ are all covered by the TangoShuter class conventional states. """ import json -from enum import Enum, unique -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter +from enum import ( + Enum, + unique, +) + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter __copyright__ = """ Copyright © 2023 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/Transmission.py b/mxcubecore/HardwareObjects/Transmission.py index 51bd50a027..62c4183ee0 100644 --- a/mxcubecore/HardwareObjects/Transmission.py +++ b/mxcubecore/HardwareObjects/Transmission.py @@ -1,6 +1,7 @@ from PyTransmission import matt_control -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject class Transmission(HardwareObject): diff --git a/mxcubecore/HardwareObjects/UnitTest.py b/mxcubecore/HardwareObjects/UnitTest.py index f1e8744e5f..8c20abd91c 100644 --- a/mxcubecore/HardwareObjects/UnitTest.py +++ b/mxcubecore/HardwareObjects/UnitTest.py @@ -18,8 +18,9 @@ # along with MXCuBE. If not, see . -import unittest import logging +import unittest + from mxcubecore.BaseHardwareObjects import HardwareObject BEAMLINE = None diff --git a/mxcubecore/HardwareObjects/VaporyVideo.py b/mxcubecore/HardwareObjects/VaporyVideo.py index d09445d4ff..f4ea8a98ea 100755 --- a/mxcubecore/HardwareObjects/VaporyVideo.py +++ b/mxcubecore/HardwareObjects/VaporyVideo.py @@ -20,11 +20,13 @@ """ import time + import gevent import vapory -from mxcubecore.utils.qt_import import QImage + from mxcubecore import BaseHardwareObjects from mxcubecore.HardwareObjects.Camera import JpegType +from mxcubecore.utils.qt_import import QImage class VaporyVideo(BaseHardwareObjects.HardwareObject): diff --git a/mxcubecore/HardwareObjects/VimbaVideo.py b/mxcubecore/HardwareObjects/VimbaVideo.py index 08baa5d882..d49161dc3d 100644 --- a/mxcubecore/HardwareObjects/VimbaVideo.py +++ b/mxcubecore/HardwareObjects/VimbaVideo.py @@ -1,5 +1,6 @@ -import time import atexit +import time + import numpy as np from pymba import Vimba @@ -8,13 +9,14 @@ except ImportError: pass -from mxcubecore.utils.qt_import import QImage, QPixmap -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import ( - AbstractVideoDevice, -) - from abstract.AbstractVideoDevice import AbstractVideoDevice +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice +from mxcubecore.utils.qt_import import ( + QImage, + QPixmap, +) + class VimbaVideo(AbstractVideoDevice): def __init__(self, name): diff --git a/mxcubecore/HardwareObjects/XMLRPCServer.py b/mxcubecore/HardwareObjects/XMLRPCServer.py index 6da1b41d42..6f3ef7d295 100644 --- a/mxcubecore/HardwareObjects/XMLRPCServer.py +++ b/mxcubecore/HardwareObjects/XMLRPCServer.py @@ -5,25 +5,25 @@ configuration XML for more information. """ +import atexit +import inspect +import json import logging -import sys import os -import shutil -import inspect import pkgutil -import types +import shutil import socket +import sys import time +import types import xml -import json -import atexit -import jsonpickle - from functools import reduce + import gevent +import jsonpickle -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( SecureXMLRpcRequestHandler, ) diff --git a/mxcubecore/HardwareObjects/XRFSpectrum.py b/mxcubecore/HardwareObjects/XRFSpectrum.py index 046a126afb..fc53f3beea 100644 --- a/mxcubecore/HardwareObjects/XRFSpectrum.py +++ b/mxcubecore/HardwareObjects/XRFSpectrum.py @@ -2,8 +2,10 @@ import os import shutil import time -import gevent.event + import gevent +import gevent.event + from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/XSDataAutoprocv1_0.py b/mxcubecore/HardwareObjects/XSDataAutoprocv1_0.py index 45b9a891f4..88a5dedc84 100644 --- a/mxcubecore/HardwareObjects/XSDataAutoprocv1_0.py +++ b/mxcubecore/HardwareObjects/XSDataAutoprocv1_0.py @@ -4,19 +4,23 @@ # Generated Tue Oct 14 03:54::11 2014 by EDGenerateDS. # -from XSDataCommon import XSDataVectorDouble -from XSDataCommon import XSDataString -from XSDataCommon import XSDataResult -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataInput -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataBoolean import os import sys -from xml.dom import minidom -from xml.dom import Node - +from xml.dom import ( + Node, + minidom, +) + +from XSDataCommon import ( + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, + XSDataVectorDouble, +) strEdnaHome = os.environ.get("EDNA_HOME", None) @@ -32,14 +36,16 @@ } try: - from XSDataCommon import XSDataBoolean - from XSDataCommon import XSDataDouble - from XSDataCommon import XSDataFile - from XSDataCommon import XSDataInput - from XSDataCommon import XSDataInteger - from XSDataCommon import XSDataResult - from XSDataCommon import XSDataString - from XSDataCommon import XSDataVectorDouble + from XSDataCommon import ( + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, + XSDataVectorDouble, + ) except ImportError as error: if strEdnaHome is not None: for strXsdName in dictLocation: diff --git a/mxcubecore/HardwareObjects/XSDataCommon.py b/mxcubecore/HardwareObjects/XSDataCommon.py index 22c4e0681e..0852e5bffd 100644 --- a/mxcubecore/HardwareObjects/XSDataCommon.py +++ b/mxcubecore/HardwareObjects/XSDataCommon.py @@ -5,9 +5,10 @@ # import sys -from xml.dom import minidom -from xml.dom import Node - +from xml.dom import ( + Node, + minidom, +) # # Support/utility functions. diff --git a/mxcubecore/HardwareObjects/XSDataControlDozorv1_1.py b/mxcubecore/HardwareObjects/XSDataControlDozorv1_1.py index f1a7a993ba..0faf100fd7 100644 --- a/mxcubecore/HardwareObjects/XSDataControlDozorv1_1.py +++ b/mxcubecore/HardwareObjects/XSDataControlDozorv1_1.py @@ -4,18 +4,22 @@ # Generated Fri Feb 20 04:42::27 2015 by EDGenerateDS. # -from XSDataCommon import XSDataString -from XSDataCommon import XSDataResult -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataInput -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataBoolean import os import sys -from xml.dom import minidom -from xml.dom import Node - +from xml.dom import ( + Node, + minidom, +) + +from XSDataCommon import ( + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, +) strEdnaHome = os.environ.get("EDNA_HOME", None) @@ -30,13 +34,15 @@ } try: - from XSDataCommon import XSDataBoolean - from XSDataCommon import XSDataDouble - from XSDataCommon import XSDataFile - from XSDataCommon import XSDataInput - from XSDataCommon import XSDataInteger - from XSDataCommon import XSDataResult - from XSDataCommon import XSDataString + from XSDataCommon import ( + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, + ) except ImportError as error: if strEdnaHome is not None: for strXsdName in dictLocation: diff --git a/mxcubecore/HardwareObjects/XSDataMXCuBEv1_3.py b/mxcubecore/HardwareObjects/XSDataMXCuBEv1_3.py index fa5b75a921..5d12e827f3 100644 --- a/mxcubecore/HardwareObjects/XSDataMXCuBEv1_3.py +++ b/mxcubecore/HardwareObjects/XSDataMXCuBEv1_3.py @@ -4,24 +4,30 @@ # Generated Mon May 14 10:32::39 2012 by EDGenerateDS. # -from XSDataMXv1 import XSDataSampleCrystalMM -from XSDataMXv1 import XSDataResultCharacterisation -from XSDataMXv1 import XSDataInputCharacterisation -from XSDataMXv1 import XSDataExperimentalCondition -from XSDataMXv1 import XSDataDiffractionPlan -from XSDataMXv1 import XSDataCollectionPlan -from XSDataCommon import XSDataString -from XSDataCommon import XSDataResult -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataInput -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataDictionary -from XSDataCommon import XSData import os import sys -from xml.dom import minidom -from xml.dom import Node - +from xml.dom import ( + Node, + minidom, +) + +from XSDataCommon import ( + XSData, + XSDataDictionary, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, +) +from XSDataMXv1 import ( + XSDataCollectionPlan, + XSDataDiffractionPlan, + XSDataExperimentalCondition, + XSDataInputCharacterisation, + XSDataResultCharacterisation, + XSDataSampleCrystalMM, +) strEdnaHome = os.environ.get("EDNA_HOME", None) @@ -42,19 +48,23 @@ } try: - from XSDataCommon import XSData - from XSDataCommon import XSDataDictionary - from XSDataCommon import XSDataFile - from XSDataCommon import XSDataInput - from XSDataCommon import XSDataInteger - from XSDataCommon import XSDataResult - from XSDataCommon import XSDataString - from XSDataMXv1 import XSDataCollectionPlan - from XSDataMXv1 import XSDataDiffractionPlan - from XSDataMXv1 import XSDataExperimentalCondition - from XSDataMXv1 import XSDataInputCharacterisation - from XSDataMXv1 import XSDataResultCharacterisation - from XSDataMXv1 import XSDataSampleCrystalMM + from XSDataCommon import ( + XSData, + XSDataDictionary, + XSDataFile, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, + ) + from XSDataMXv1 import ( + XSDataCollectionPlan, + XSDataDiffractionPlan, + XSDataExperimentalCondition, + XSDataInputCharacterisation, + XSDataResultCharacterisation, + XSDataSampleCrystalMM, + ) except ImportError as error: if strEdnaHome is not None: for strXsdName in dictLocation: diff --git a/mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py b/mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py index 350ad4d9f1..8ddcffbbff 100644 --- a/mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py +++ b/mxcubecore/HardwareObjects/XSDataMXCuBEv1_4.py @@ -4,10 +4,12 @@ # Generated Thu Feb 9 10:58::29 2023 by EDGenerateDS. # -import os, sys -from xml.dom import minidom -from xml.dom import Node - +import os +import sys +from xml.dom import ( + Node, + minidom, +) strEdnaHome = os.environ.get("EDNA_HOME", None) @@ -30,21 +32,25 @@ } try: - from XSDataCommon import XSData - from XSDataCommon import XSDataDictionary - from XSDataCommon import XSDataDouble - from XSDataCommon import XSDataFile - from XSDataCommon import XSDataInput - from XSDataCommon import XSDataInteger - from XSDataCommon import XSDataResult - from XSDataCommon import XSDataString - from XSDataMXv1 import XSDataCollectionPlan - from XSDataMXv1 import XSDataDiffractionPlan - from XSDataMXv1 import XSDataExperimentalCondition - from XSDataCommon import XSDataImage - from XSDataMXv1 import XSDataInputCharacterisation - from XSDataMXv1 import XSDataResultCharacterisation - from XSDataMXv1 import XSDataSampleCrystalMM + from XSDataCommon import ( + XSData, + XSDataDictionary, + XSDataDouble, + XSDataFile, + XSDataImage, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, + ) + from XSDataMXv1 import ( + XSDataCollectionPlan, + XSDataDiffractionPlan, + XSDataExperimentalCondition, + XSDataInputCharacterisation, + XSDataResultCharacterisation, + XSDataSampleCrystalMM, + ) except ImportError as error: if strEdnaHome is not None: for strXsdName in dictLocation: @@ -57,24 +63,25 @@ sys.path.append(strRoot) else: raise error -from XSDataCommon import XSData -from XSDataCommon import XSDataDictionary -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataInput -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataResult -from XSDataCommon import XSDataString -from XSDataMXv1 import XSDataCollectionPlan -from XSDataMXv1 import XSDataDiffractionPlan -from XSDataMXv1 import XSDataExperimentalCondition -from XSDataCommon import XSDataImage -from XSDataMXv1 import XSDataInputCharacterisation -from XSDataMXv1 import XSDataResultCharacterisation -from XSDataMXv1 import XSDataSampleCrystalMM - - - +from XSDataCommon import ( + XSData, + XSDataDictionary, + XSDataDouble, + XSDataFile, + XSDataImage, + XSDataInput, + XSDataInteger, + XSDataResult, + XSDataString, +) +from XSDataMXv1 import ( + XSDataCollectionPlan, + XSDataDiffractionPlan, + XSDataExperimentalCondition, + XSDataInputCharacterisation, + XSDataResultCharacterisation, + XSDataSampleCrystalMM, +) # # Support/utility functions. diff --git a/mxcubecore/HardwareObjects/XSDataMXv1.py b/mxcubecore/HardwareObjects/XSDataMXv1.py index 22bd6f2794..4aecddeef9 100644 --- a/mxcubecore/HardwareObjects/XSDataMXv1.py +++ b/mxcubecore/HardwareObjects/XSDataMXv1.py @@ -4,10 +4,12 @@ # Generated Tue Mar 28 09:42::39 2023 by EDGenerateDS. # -import os, sys -from xml.dom import minidom -from xml.dom import Node - +import os +import sys +from xml.dom import ( + Node, + minidom, +) strEdnaHome = os.environ.get("EDNA_HOME", None) @@ -35,26 +37,28 @@ } try: - from XSDataCommon import XSData - from XSDataCommon import XSDataBoolean - from XSDataCommon import XSDataDouble - from XSDataCommon import XSDataFile - from XSDataCommon import XSDataFloat - from XSDataCommon import XSDataInput - from XSDataCommon import XSDataInteger - from XSDataCommon import XSDataMatrixDouble - from XSDataCommon import XSDataResult - from XSDataCommon import XSDataSize - from XSDataCommon import XSDataString - from XSDataCommon import XSDataVectorDouble - from XSDataCommon import XSDataImage - from XSDataCommon import XSDataAbsorbedDoseRate - from XSDataCommon import XSDataAngularSpeed - from XSDataCommon import XSDataFlux - from XSDataCommon import XSDataLength - from XSDataCommon import XSDataTime - from XSDataCommon import XSDataWavelength - from XSDataCommon import XSDataAngle + from XSDataCommon import ( + XSData, + XSDataAbsorbedDoseRate, + XSDataAngle, + XSDataAngularSpeed, + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataFloat, + XSDataFlux, + XSDataImage, + XSDataInput, + XSDataInteger, + XSDataLength, + XSDataMatrixDouble, + XSDataResult, + XSDataSize, + XSDataString, + XSDataTime, + XSDataVectorDouble, + XSDataWavelength, + ) except ImportError as error: if strEdnaHome is not None: for strXsdName in dictLocation: @@ -67,29 +71,28 @@ sys.path.append(strRoot) else: raise error -from XSDataCommon import XSData -from XSDataCommon import XSDataBoolean -from XSDataCommon import XSDataDouble -from XSDataCommon import XSDataFile -from XSDataCommon import XSDataFloat -from XSDataCommon import XSDataInput -from XSDataCommon import XSDataInteger -from XSDataCommon import XSDataMatrixDouble -from XSDataCommon import XSDataResult -from XSDataCommon import XSDataSize -from XSDataCommon import XSDataString -from XSDataCommon import XSDataVectorDouble -from XSDataCommon import XSDataImage -from XSDataCommon import XSDataAbsorbedDoseRate -from XSDataCommon import XSDataAngularSpeed -from XSDataCommon import XSDataFlux -from XSDataCommon import XSDataLength -from XSDataCommon import XSDataTime -from XSDataCommon import XSDataWavelength -from XSDataCommon import XSDataAngle - - - +from XSDataCommon import ( + XSData, + XSDataAbsorbedDoseRate, + XSDataAngle, + XSDataAngularSpeed, + XSDataBoolean, + XSDataDouble, + XSDataFile, + XSDataFloat, + XSDataFlux, + XSDataImage, + XSDataInput, + XSDataInteger, + XSDataLength, + XSDataMatrixDouble, + XSDataResult, + XSDataSize, + XSDataString, + XSDataTime, + XSDataVectorDouble, + XSDataWavelength, +) # # Support/utility functions. diff --git a/mxcubecore/HardwareObjects/abstract/AbstractActuator.py b/mxcubecore/HardwareObjects/abstract/AbstractActuator.py index 56cdbb7054..81657ac3ab 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractActuator.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractActuator.py @@ -31,7 +31,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractAperture.py b/mxcubecore/HardwareObjects/abstract/AbstractAperture.py index 52f0feb436..5193ecc4a6 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractAperture.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractAperture.py @@ -23,7 +23,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractAuthenticator.py b/mxcubecore/HardwareObjects/abstract/AbstractAuthenticator.py index 5f4a438e3a..9b4ef52766 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractAuthenticator.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractAuthenticator.py @@ -20,6 +20,7 @@ import abc + from mxcubecore.BaseHardwareObjects import HardwareObject __copyright__ = """ Copyright © 2010- 2022 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py index 999bafb2e6..5d7c0ed2c2 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py @@ -32,8 +32,11 @@ import abc import sys +from enum import ( + Enum, + unique, +) from warnings import warn -from enum import Enum, unique from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/abstract/AbstractCharacterisation.py b/mxcubecore/HardwareObjects/abstract/AbstractCharacterisation.py index 319356723d..08f31d4168 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractCharacterisation.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractCharacterisation.py @@ -26,6 +26,7 @@ """ import abc + import gevent.event from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py index 2dc2b90c9e..cc92eae71e 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractCollect.py @@ -23,18 +23,19 @@ Defines a sequence how data collection is executed. """ -import os -import logging -import time -import errno import abc import collections +import errno +import logging +import os +import time + import gevent import gevent.event -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/abstract/AbstractDetector.py b/mxcubecore/HardwareObjects/abstract/AbstractDetector.py index 11dc3bafce..fe87069355 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractDetector.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractDetector.py @@ -49,8 +49,8 @@ """ import abc -import math import ast +import math from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergy.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergy.py index 8630f3f977..37ce9fb3e3 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergy.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergy.py @@ -25,8 +25,9 @@ """ import abc -from mxcubecore.utils.conversion import HC_OVER_E + from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator +from mxcubecore.utils.conversion import HC_OVER_E __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py index a7fde87c6e..5f419cc686 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractEnergyScan.py @@ -1,10 +1,12 @@ -import os -import time import abc import logging +import os +import time + import gevent -from mxcubecore.TaskUtils import error_cleanup + from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import error_cleanup class AbstractEnergyScan(HardwareObject): diff --git a/mxcubecore/HardwareObjects/abstract/AbstractFlux.py b/mxcubecore/HardwareObjects/abstract/AbstractFlux.py index 7ef5473740..6cb0ee6322 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractFlux.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractFlux.py @@ -22,9 +22,8 @@ """ from scipy.interpolate import interp1d -from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator - from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMCA.py b/mxcubecore/HardwareObjects/abstract/AbstractMCA.py index 08ed911d18..ab49b773cb 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMCA.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMCA.py @@ -1,5 +1,6 @@ import abc from warnings import warn + from mxcubecore.TaskUtils import task diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMachineInfo.py b/mxcubecore/HardwareObjects/abstract/AbstractMachineInfo.py index c49c35e44e..eb65db741f 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMachineInfo.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMachineInfo.py @@ -21,6 +21,7 @@ import abc from ast import literal_eval + from mxcubecore.BaseHardwareObjects import HardwareObject __copyright__ = """ Copyright © by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMotor.py b/mxcubecore/HardwareObjects/abstract/AbstractMotor.py index 443fce394c..2a6cad88ce 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMotor.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMotor.py @@ -25,12 +25,13 @@ """ import abc -from enum import Enum, unique +from enum import ( + Enum, + unique, +) from mxcubecore.BaseHardwareObjects import HardwareObjectState -from mxcubecore.HardwareObjects.abstract.AbstractActuator import ( - AbstractActuator, -) +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index 378fd12970..4c09206911 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -1,18 +1,23 @@ -import os -import sys +import abc +import collections +import errno # import types import logging +import os +import socket +import sys import time -import errno -import abc -import collections + import autoprocessing import gevent -import socket -from mxcubecore.TaskUtils import task, cleanup, error_cleanup from mxcubecore import HardwareRepository as HWR +from mxcubecore.TaskUtils import ( + cleanup, + error_cleanup, + task, +) BeamlineControl = collections.namedtuple( "BeamlineControl", diff --git a/mxcubecore/HardwareObjects/abstract/AbstractNState.py b/mxcubecore/HardwareObjects/abstract/AbstractNState.py index 2cf3d4c550..a43078fb80 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractNState.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractNState.py @@ -24,9 +24,12 @@ import abc import ast -from enum import Enum, unique -from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator +from enum import ( + Enum, + unique, +) +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py b/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py index ce061784c1..44be947348 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractOnlineProcessing.py @@ -17,25 +17,23 @@ # along with MXCuBE. If not, see . """Abstract Online Processing class """ -import os -import time -import logging import json +import logging +import os import subprocess - +import time from copy import copy -from scipy import ndimage -from scipy.interpolate import UnivariateSpline -import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid1 import make_axes_locatable -import numpy as np import gevent - +import matplotlib.pyplot as plt +import numpy as np import SimpleHTML -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore import HardwareRepository as HWR +from mpl_toolkits.axes_grid1 import make_axes_locatable +from scipy import ndimage +from scipy.interpolate import UnivariateSpline +from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractProcedure.py b/mxcubecore/HardwareObjects/abstract/AbstractProcedure.py index 6e6f00081c..6db71712ef 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractProcedure.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractProcedure.py @@ -17,20 +17,25 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . import logging -from enum import IntEnum, unique +from enum import ( + IntEnum, + unique, +) import gevent.event -from mxcubecore.BaseHardwareObjects import ConfiguredObject -from mxcubecore.dispatcher import dispatcher - -# import mxcubecore.model.procedure_model - # Using jsonschma for validating the JSCONSchemas # https://json-schema.org/ # https://github.com/Julian/jsonschema +from jsonschema import ( + ValidationError, + validate, +) -from jsonschema import validate, ValidationError +from mxcubecore.BaseHardwareObjects import ConfiguredObject +from mxcubecore.dispatcher import dispatcher + +# import mxcubecore.model.procedure_model __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/abstract/AbstractResolution.py b/mxcubecore/HardwareObjects/abstract/AbstractResolution.py index 40bdbfc0e2..8c9cdd1c2c 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractResolution.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractResolution.py @@ -29,7 +29,13 @@ import abc import logging -from math import asin, atan, sin, tan +from math import ( + asin, + atan, + sin, + tan, +) + from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py index ed2655393e..7a7a66bf64 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py @@ -127,11 +127,14 @@ import abc import logging -from gevent import sleep, Timeout +from gevent import ( + Timeout, + sleep, +) -from mxcubecore.TaskUtils import task as dtask from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.sample_changer.Container import Container +from mxcubecore.TaskUtils import task as dtask class SampleChangerState: diff --git a/mxcubecore/HardwareObjects/abstract/AbstractShutter.py b/mxcubecore/HardwareObjects/abstract/AbstractShutter.py index 973b0b459f..5c1de55974 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractShutter.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractShutter.py @@ -23,7 +23,11 @@ """ import abc -from enum import Enum, unique +from enum import ( + Enum, + unique, +) + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState __copyright__ = """ Copyright 2016-2023 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSlits.py b/mxcubecore/HardwareObjects/abstract/AbstractSlits.py index ae357aa344..52eed56aa6 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSlits.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSlits.py @@ -21,8 +21,8 @@ """ import abc from warnings import warn -from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.BaseHardwareObjects import HardwareObject __credits__ = ["MXCuBE collaboration"] __version__ = "2.3" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractTransmission.py b/mxcubecore/HardwareObjects/abstract/AbstractTransmission.py index 29c714905d..a1bab489f7 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractTransmission.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractTransmission.py @@ -23,8 +23,8 @@ """ import abc -from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator +from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator __copyright__ = """ Copyright © 2010- 2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py b/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py index c1af323b5f..df32f1264a 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py @@ -29,14 +29,15 @@ """ import abc +import logging import os import sys import time -import logging +import warnings from io import BytesIO + import gevent import numpy as np -import warnings try: import cv2 @@ -45,12 +46,15 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - module_names = ["qt", "PyQt5", "PyQt4"] if any(mod in sys.modules for mod in module_names): USEQT = True - from mxcubecore.utils.qt_import import QPixmap, QImage, QSize + from mxcubecore.utils.qt_import import ( + QImage, + QPixmap, + QSize, + ) else: USEQT = False from PIL import Image diff --git a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py index b8c8d99304..ce36e0cb31 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractXRFSpectrum.py @@ -24,9 +24,11 @@ import logging import os import time + import gevent -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/abstract/AbstractXrayCentring.py b/mxcubecore/HardwareObjects/abstract/AbstractXrayCentring.py index 967ae9a97c..ac484c5652 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractXrayCentring.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractXrayCentring.py @@ -18,8 +18,12 @@ """Xray Centring Abstract Class with yaml configuration file. """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" @@ -28,8 +32,8 @@ import abc -from mxcubecore.BaseHardwareObjects import HardwareObjectYaml from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectYaml from mxcubecore.model import queue_model_objects diff --git a/mxcubecore/HardwareObjects/abstract/sample_changer/Crims.py b/mxcubecore/HardwareObjects/abstract/sample_changer/Crims.py index e2d82c9747..9ae97a35cf 100644 --- a/mxcubecore/HardwareObjects/abstract/sample_changer/Crims.py +++ b/mxcubecore/HardwareObjects/abstract/sample_changer/Crims.py @@ -1,10 +1,9 @@ +import urllib import xml.etree.cElementTree as et +from io import BytesIO import requests from PIL import Image -from io import BytesIO - -import urllib def get_image(url): diff --git a/mxcubecore/HardwareObjects/abstract/sample_changer/Sample.py b/mxcubecore/HardwareObjects/abstract/sample_changer/Sample.py index 99babb0a10..5f84d61af2 100644 --- a/mxcubecore/HardwareObjects/abstract/sample_changer/Sample.py +++ b/mxcubecore/HardwareObjects/abstract/sample_changer/Sample.py @@ -1,4 +1,5 @@ import sys + from .Component import Component try: diff --git a/mxcubecore/HardwareObjects/autoprocessing.py b/mxcubecore/HardwareObjects/autoprocessing.py index fc08024552..9f4de19bcc 100755 --- a/mxcubecore/HardwareObjects/autoprocessing.py +++ b/mxcubecore/HardwareObjects/autoprocessing.py @@ -1,5 +1,5 @@ -import os import logging +import os import subprocess diff --git a/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py b/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py index ac7badd63a..61c99ee2a5 100644 --- a/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ActuatorMockup.py @@ -26,9 +26,11 @@ e.g. class MotorMockup(ActuatorMockup, AbstractMotor): """ -import time import random +import time + import gevent + from mxcubecore.HardwareObjects.abstract import AbstractActuator __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ diff --git a/mxcubecore/HardwareObjects/mockup/ApertureMockup.py b/mxcubecore/HardwareObjects/mockup/ApertureMockup.py index ac21240fb0..f297c4b58f 100644 --- a/mxcubecore/HardwareObjects/mockup/ApertureMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ApertureMockup.py @@ -29,6 +29,7 @@ """ from enum import Enum + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup diff --git a/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py b/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py index d4c4519024..bec548d493 100644 --- a/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BIOMAXEigerMockup.py @@ -20,13 +20,18 @@ """ -import gevent -import time import logging +import time + +import gevent from mxcubecore import HardwareRepository as HWR -from mxcubecore.TaskUtils import task, cleanup, error_cleanup from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import ( + cleanup, + error_cleanup, + task, +) class BIOMAXEigerMockup(HardwareObject): diff --git a/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py b/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py index 24764ccbac..11a931c290 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamDefinerMockup.py @@ -37,8 +37,9 @@ __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" -import time import random +import time + from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup diff --git a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py index 4e19e8e9fc..c3211a9668 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamlineActionsMockup.py @@ -1,14 +1,17 @@ +import logging + +import gevent +from pydantic.v1 import ( + BaseModel, + Field, +) from typing_extensions import Literal -from pydantic.v1 import BaseModel, Field from mxcubecore.HardwareObjects.BeamlineActions import ( - BeamlineActions, AnnotatedCommand, + BeamlineActions, ) -import gevent -import logging - class SimpleFloat(BaseModel): exp_time: float = Field(100e-6, gt=0, lt=10, description="(s)") diff --git a/mxcubecore/HardwareObjects/mockup/BeamlineTestMockup.py b/mxcubecore/HardwareObjects/mockup/BeamlineTestMockup.py index 853c69426f..3ff3265a7f 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamlineTestMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamlineTestMockup.py @@ -22,17 +22,16 @@ """ -import os import logging +import os import tempfile from datetime import datetime import gevent -from mxcubecore.HardwareObjects import SimpleHTML -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR - +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects import SimpleHTML __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/mockup/BeamstopMockup.py b/mxcubecore/HardwareObjects/mockup/BeamstopMockup.py index 065a7e9714..a628b88717 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamstopMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamstopMockup.py @@ -21,7 +21,6 @@ from mxcubecore.BaseHardwareObjects import HardwareObject - __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py b/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py index f85b50439b..930ef537a1 100644 --- a/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py +++ b/mxcubecore/HardwareObjects/mockup/CatsMaintMockup.py @@ -3,13 +3,12 @@ """ import logging - -from mxcubecore.TaskUtils import task -from mxcubecore.BaseHardwareObjects import HardwareObject +import time import gevent -import time +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.TaskUtils import task __author__ = "Mikel Eguiraun" __credits__ = ["The MxCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/mockup/CollectMockup.py b/mxcubecore/HardwareObjects/mockup/CollectMockup.py index b0365f4b30..e9415d4751 100644 --- a/mxcubecore/HardwareObjects/mockup/CollectMockup.py +++ b/mxcubecore/HardwareObjects/mockup/CollectMockup.py @@ -21,10 +21,10 @@ import os import time -from mxcubecore.TaskUtils import task -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect -from mxcubecore import HardwareRepository as HWR +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect +from mxcubecore.TaskUtils import task __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/mockup/DetectorMockup.py b/mxcubecore/HardwareObjects/mockup/DetectorMockup.py index 1d1ff95070..03008545d7 100644 --- a/mxcubecore/HardwareObjects/mockup/DetectorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/DetectorMockup.py @@ -1,9 +1,7 @@ import time -from mxcubecore.HardwareObjects.abstract.AbstractDetector import ( - AbstractDetector, -) from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractDetector import AbstractDetector class DetectorMockup(AbstractDetector): diff --git a/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py b/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py index 1e12413529..30e0e15849 100644 --- a/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/DiffractometerMockup.py @@ -17,19 +17,19 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import time import logging import random +import time import warnings +from gevent.event import AsyncResult + +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.GenericDiffractometer import ( GenericDiffractometer, PhaseEnum, ) -from mxcubecore import HardwareRepository as HWR -from gevent.event import AsyncResult - class DiffractometerMockup(GenericDiffractometer): """ diff --git a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py index a75cbec468..a6a64c6b6e 100644 --- a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py @@ -19,10 +19,8 @@ from mxcubecore.HardwareObjects import edna_test_data from mxcubecore.HardwareObjects.EDNACharacterisation import EDNACharacterisation - from mxcubecore.HardwareObjects.XSDataMXCuBEv1_3 import XSDataResultMXCuBE - __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3" diff --git a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py index fadbbd6e87..477c3080ac 100644 --- a/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EnergyScanMockup.py @@ -1,18 +1,16 @@ +import logging import os import time + import gevent import gevent.event -import logging - -from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.figure import Figure -from mxcubecore.TaskUtils import cleanup -from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import ( - AbstractEnergyScan, -) -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.abstract.AbstractEnergyScan import AbstractEnergyScan +from mxcubecore.TaskUtils import cleanup scan_test_data = [ (10841.0, 20.0), diff --git a/mxcubecore/HardwareObjects/mockup/ExporterNStateMockup.py b/mxcubecore/HardwareObjects/mockup/ExporterNStateMockup.py index 4382ec7cec..9b16f03ec7 100644 --- a/mxcubecore/HardwareObjects/mockup/ExporterNStateMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ExporterNStateMockup.py @@ -29,10 +29,12 @@ """ from enum import Enum + from gevent import sleep -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState + from mxcubecore.Command.Exporter import Exporter from mxcubecore.Command.exporter.ExporterStates import ExporterStates +from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState __copyright__ = """ Copyright © 2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/FluxMockup.py b/mxcubecore/HardwareObjects/mockup/FluxMockup.py index fb7b943654..528723c295 100644 --- a/mxcubecore/HardwareObjects/mockup/FluxMockup.py +++ b/mxcubecore/HardwareObjects/mockup/FluxMockup.py @@ -22,11 +22,14 @@ """ from random import random -from gevent import sleep, Timeout -from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux -from mxcubecore import HardwareRepository as HWR +from gevent import ( + Timeout, + sleep, +) +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractFlux import AbstractFlux __copyright__ = """ Copyright © 2010-2022 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/HarvesterMockup.py b/mxcubecore/HardwareObjects/mockup/HarvesterMockup.py index 1a7a9ad8a0..e5c3f63d7b 100644 --- a/mxcubecore/HardwareObjects/mockup/HarvesterMockup.py +++ b/mxcubecore/HardwareObjects/mockup/HarvesterMockup.py @@ -34,9 +34,10 @@ ----------------------------------------------------------------------- """ -import gevent import logging +import gevent + from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py b/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py index 3cd11607a5..6ba8f22b3c 100644 --- a/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py @@ -6,8 +6,8 @@ import time import warnings -from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject try: from urlparse import urljoin diff --git a/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py b/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py index 72bb047533..135bb2f215 100644 --- a/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py @@ -3,10 +3,12 @@ """ from __future__ import print_function + import logging from datetime import datetime -from mxcubecore.BaseHardwareObjects import HardwareObject + from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObject try: from urlparse import urljoin diff --git a/mxcubecore/HardwareObjects/mockup/LimaDetectorMockup.py b/mxcubecore/HardwareObjects/mockup/LimaDetectorMockup.py index 0b113f6317..52c79515f9 100644 --- a/mxcubecore/HardwareObjects/mockup/LimaDetectorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/LimaDetectorMockup.py @@ -1,10 +1,12 @@ # pylint: skip-file -import time -from mxcubecore.TaskUtils import task import logging +import time + from PyTango import DeviceProxy + from mxcubecore import HardwareRepository as HWR +from mxcubecore.TaskUtils import task class LimaDetectorMockup: diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index 94657418b7..e8b2e42df4 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -1,10 +1,11 @@ """Class for cameras connected to framegrabbers run by Taco Device Servers""" -import psutil -import subprocess import logging +import subprocess import time + import gevent +import psutil from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR diff --git a/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py b/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py index 152dd89afa..dc43fa28e5 100644 --- a/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MachineInfoMockup.py @@ -37,9 +37,7 @@ import gevent from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import ( - AbstractMachineInfo, -) +from mxcubecore.HardwareObjects.abstract.AbstractMachineInfo import AbstractMachineInfo class MachineInfoMockup(AbstractMachineInfo): diff --git a/mxcubecore/HardwareObjects/mockup/MicrodiffApertureMockup.py b/mxcubecore/HardwareObjects/mockup/MicrodiffApertureMockup.py index d5e95db688..1b4199aa2f 100644 --- a/mxcubecore/HardwareObjects/mockup/MicrodiffApertureMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MicrodiffApertureMockup.py @@ -1,7 +1,8 @@ # from MD2Motor import MD2Motor -from mxcubecore.BaseHardwareObjects import HardwareObject import math +from mxcubecore.BaseHardwareObjects import HardwareObject + class MicrodiffApertureMockup(HardwareObject): def init(self): diff --git a/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py b/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py index 1f0ce4db13..014b5d358e 100755 --- a/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MicrodiffInOutMockup.py @@ -1,7 +1,8 @@ import logging -from mxcubecore.BaseHardwareObjects import HardwareObject import time +from mxcubecore.BaseHardwareObjects import HardwareObject + """ Use the exporter to set different MD2 actuators in/out. If private_state not specified, True will be send to set in and False for out. diff --git a/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py b/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py index 2333d6bdcf..1ea04d5fa1 100644 --- a/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MicrodiffZoomMockup.py @@ -10,10 +10,13 @@ """ from enum import Enum + import gevent -from mxcubecore.HardwareObjects.abstract.AbstractNState import AbstractNState -from mxcubecore.HardwareObjects.abstract.AbstractNState import BaseValueEnum +from mxcubecore.HardwareObjects.abstract.AbstractNState import ( + AbstractNState, + BaseValueEnum, +) class MicrodiffZoomMockup(AbstractNState): diff --git a/mxcubecore/HardwareObjects/mockup/MotorMockup.py b/mxcubecore/HardwareObjects/mockup/MotorMockup.py index 0a428fac80..3cd1c510ac 100644 --- a/mxcubecore/HardwareObjects/mockup/MotorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MotorMockup.py @@ -33,12 +33,14 @@ """ -import time import ast +import time -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor +from mxcubecore.HardwareObjects.abstract.AbstractMotor import ( + AbstractMotor, + MotorStates, +) from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup -from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates __copyright__ = """ Copyright © 2010-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py b/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py index 9ff61362de..59d788966b 100644 --- a/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py +++ b/mxcubecore/HardwareObjects/mockup/MotorMockupBis.py @@ -26,8 +26,8 @@ """ -from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractMotor import AbstractMotor __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py b/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py index 743258f707..feb1a52302 100644 --- a/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py @@ -1,15 +1,15 @@ +import logging +import os +import time + +import gevent + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.abstract.AbstractMultiCollect import ( AbstractMultiCollect, ) - -from mxcubecore import HardwareRepository as HWR - from mxcubecore.TaskUtils import task -import logging -import time -import os -import gevent class MultiCollectMockup(AbstractMultiCollect, HardwareObject): diff --git a/mxcubecore/HardwareObjects/mockup/OfflineProcessingMockup.py b/mxcubecore/HardwareObjects/mockup/OfflineProcessingMockup.py index f50e18e797..def656335a 100644 --- a/mxcubecore/HardwareObjects/mockup/OfflineProcessingMockup.py +++ b/mxcubecore/HardwareObjects/mockup/OfflineProcessingMockup.py @@ -16,22 +16,21 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import os -import time import logging +import os import subprocess +import time import gevent from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.HardwareObjects.XSDataAutoprocv1_0 import XSDataAutoprocInput from mxcubecore.HardwareObjects.XSDataCommon import ( XSDataDouble, XSDataFile, XSDataInteger, XSDataString, ) -from mxcubecore.HardwareObjects.XSDataAutoprocv1_0 import XSDataAutoprocInput - __credits__ = ["EMBL Hamburg"] __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/OnlineProcessingMockup.py b/mxcubecore/HardwareObjects/mockup/OnlineProcessingMockup.py index 8df0bad546..0e0d579da9 100644 --- a/mxcubecore/HardwareObjects/mockup/OnlineProcessingMockup.py +++ b/mxcubecore/HardwareObjects/mockup/OnlineProcessingMockup.py @@ -19,13 +19,13 @@ import time + import numpy from mxcubecore.HardwareObjects.abstract.AbstractOnlineProcessing import ( AbstractOnlineProcessing, ) - __license__ = "LGPLv3" diff --git a/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py b/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py index 1bc91a427f..7ad392450b 100644 --- a/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py @@ -45,6 +45,7 @@ import logging import time + import gevent from mxcubecore.HardwareObjects.abstract import AbstractSampleChanger diff --git a/mxcubecore/HardwareObjects/mockup/PlottingMockup.py b/mxcubecore/HardwareObjects/mockup/PlottingMockup.py index 2ad340993a..50ad603ae8 100644 --- a/mxcubecore/HardwareObjects/mockup/PlottingMockup.py +++ b/mxcubecore/HardwareObjects/mockup/PlottingMockup.py @@ -1,7 +1,8 @@ -from mxcubecore.BaseHardwareObjects import HardwareObject import gevent import numpy +from mxcubecore.BaseHardwareObjects import HardwareObject + def plot_emitter(new_plot, plot_data, plot_end): scan_nb = 0 diff --git a/mxcubecore/HardwareObjects/mockup/ProcedureMockup.py b/mxcubecore/HardwareObjects/mockup/ProcedureMockup.py index aaf6904f20..517bdfc8ac 100644 --- a/mxcubecore/HardwareObjects/mockup/ProcedureMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ProcedureMockup.py @@ -1,9 +1,6 @@ import gevent -from mxcubecore.HardwareObjects.abstract.AbstractProcedure import ( - AbstractProcedure, -) - +from mxcubecore.HardwareObjects.abstract.AbstractProcedure import AbstractProcedure from mxcubecore.model import procedure_model as datamodel diff --git a/mxcubecore/HardwareObjects/mockup/QtVideoMockup.py b/mxcubecore/HardwareObjects/mockup/QtVideoMockup.py index 6e82a85fd2..5bb39bafc3 100755 --- a/mxcubecore/HardwareObjects/mockup/QtVideoMockup.py +++ b/mxcubecore/HardwareObjects/mockup/QtVideoMockup.py @@ -18,12 +18,18 @@ # along with MXCuBE. If not, see . import time + import numpy as np from pkg_resources import resource_filename -from mxcubecore.utils.qt_import import QPainter, QPixmap, QPen, QBrush, QImage, Qt -from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import ( - AbstractVideoDevice, +from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice +from mxcubecore.utils.qt_import import ( + QBrush, + QImage, + QPainter, + QPen, + QPixmap, + Qt, ) diff --git a/mxcubecore/HardwareObjects/mockup/SOLEILCharacterisationMockup.py b/mxcubecore/HardwareObjects/mockup/SOLEILCharacterisationMockup.py index 86eaefe8b8..f351c339ab 100644 --- a/mxcubecore/HardwareObjects/mockup/SOLEILCharacterisationMockup.py +++ b/mxcubecore/HardwareObjects/mockup/SOLEILCharacterisationMockup.py @@ -1,11 +1,11 @@ import logging + import gevent.event from mxcubecore.HardwareObjects import edna_test_data from mxcubecore.HardwareObjects.abstract.AbstractCharacterisation import ( AbstractCharacterisation, ) - from mxcubecore.HardwareObjects.XSDataMXCuBEv1_3 import XSDataResultMXCuBE diff --git a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py index 5bb9490754..4a2dab91b3 100644 --- a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py @@ -1,5 +1,5 @@ -import time import logging +import time from mxcubecore.HardwareObjects.abstract import AbstractSampleChanger from mxcubecore.HardwareObjects.abstract.sample_changer import Container diff --git a/mxcubecore/HardwareObjects/mockup/ScanMockup.py b/mxcubecore/HardwareObjects/mockup/ScanMockup.py index 8b14a24b96..9a42b037e5 100644 --- a/mxcubecore/HardwareObjects/mockup/ScanMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ScanMockup.py @@ -17,18 +17,19 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import gevent -import random import ast +import random +import gevent + +from mxcubecore import HardwareRepository as HWR from mxcubecore.BaseHardwareObjects import HardwareObject from mxcubecore.HardwareObjects.DataPublisher import ( - PlotType, - PlotDim, DataType, + PlotDim, + PlotType, one_d_data, ) -from mxcubecore import HardwareRepository as HWR class ScanMockup(HardwareObject): diff --git a/mxcubecore/HardwareObjects/mockup/ShapeHistoryMockup.py b/mxcubecore/HardwareObjects/mockup/ShapeHistoryMockup.py index 453c1d889e..cb5b5bd47b 100644 --- a/mxcubecore/HardwareObjects/mockup/ShapeHistoryMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ShapeHistoryMockup.py @@ -19,9 +19,9 @@ import logging import os -from mxcubecore.model import queue_model_objects from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.model import queue_model_objects SELECTED_COLOR = "green" NORMAL_COLOR = "yellow" diff --git a/mxcubecore/HardwareObjects/mockup/ShutterMockup.py b/mxcubecore/HardwareObjects/mockup/ShutterMockup.py index 2902b5290c..c92bd508cb 100644 --- a/mxcubecore/HardwareObjects/mockup/ShutterMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ShutterMockup.py @@ -19,9 +19,13 @@ """ Mockup shutter implementation""" -from enum import Enum, unique -from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter +from enum import ( + Enum, + unique, +) + from mxcubecore.BaseHardwareObjects import HardwareObjectState +from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup diff --git a/mxcubecore/HardwareObjects/mockup/SlitsMockup.py b/mxcubecore/HardwareObjects/mockup/SlitsMockup.py index d1ea2431f2..b050fa10f0 100644 --- a/mxcubecore/HardwareObjects/mockup/SlitsMockup.py +++ b/mxcubecore/HardwareObjects/mockup/SlitsMockup.py @@ -20,7 +20,6 @@ from mxcubecore.HardwareObjects.abstract.AbstractSlits import AbstractSlits - __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/HardwareObjects/mockup/TransmissionMockup.py b/mxcubecore/HardwareObjects/mockup/TransmissionMockup.py index 44ac3d30df..505d4ef1a3 100644 --- a/mxcubecore/HardwareObjects/mockup/TransmissionMockup.py +++ b/mxcubecore/HardwareObjects/mockup/TransmissionMockup.py @@ -23,7 +23,6 @@ ) from mxcubecore.HardwareObjects.mockup.ActuatorMockup import ActuatorMockup - __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/XRFMockup.py b/mxcubecore/HardwareObjects/mockup/XRFMockup.py index b614486027..aa998368a3 100644 --- a/mxcubecore/HardwareObjects/mockup/XRFMockup.py +++ b/mxcubecore/HardwareObjects/mockup/XRFMockup.py @@ -1,6 +1,7 @@ import logging -import gevent import time + +import gevent import numpy from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/HardwareObjects/mockup/XRFSpectrumMockup.py b/mxcubecore/HardwareObjects/mockup/XRFSpectrumMockup.py index de13511377..40d6aeb775 100644 --- a/mxcubecore/HardwareObjects/mockup/XRFSpectrumMockup.py +++ b/mxcubecore/HardwareObjects/mockup/XRFSpectrumMockup.py @@ -24,10 +24,7 @@ from time import sleep -from mxcubecore.HardwareObjects.abstract.AbstractXRFSpectrum import ( - AbstractXRFSpectrum, -) - +from mxcubecore.HardwareObjects.abstract.AbstractXRFSpectrum import AbstractXRFSpectrum __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/mockup/XrayCentringMockup.py b/mxcubecore/HardwareObjects/mockup/XrayCentringMockup.py index 66d12de265..f0aef268f6 100644 --- a/mxcubecore/HardwareObjects/mockup/XrayCentringMockup.py +++ b/mxcubecore/HardwareObjects/mockup/XrayCentringMockup.py @@ -18,15 +18,19 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import logging -from mxcubecore.model import queue_model_objects from mxcubecore.HardwareObjects.abstract.AbstractXrayCentring import ( AbstractXrayCentring, ) +from mxcubecore.model import queue_model_objects __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/HardwareObjects/sample_centring.py b/mxcubecore/HardwareObjects/sample_centring.py index e900367170..a69d608400 100644 --- a/mxcubecore/HardwareObjects/sample_centring.py +++ b/mxcubecore/HardwareObjects/sample_centring.py @@ -1,11 +1,12 @@ -from scipy import optimize -import numpy -import gevent.event -import math -import time import logging +import math import os import tempfile +import time + +import gevent.event +import numpy +from scipy import optimize try: import lucid3 as lucid diff --git a/mxcubecore/HardwareRepository.py b/mxcubecore/HardwareRepository.py index 6fc737e59c..e89a9ba088 100644 --- a/mxcubecore/HardwareRepository.py +++ b/mxcubecore/HardwareRepository.py @@ -26,24 +26,35 @@ connections to the Control Software (Spec or Taco Device Servers). """ -from __future__ import print_function, absolute_import +from __future__ import ( + absolute_import, + print_function, +) +import importlib import logging -import weakref -import sys import os +import sys import time -import importlib import traceback -from typing import Union, TYPE_CHECKING +import weakref from datetime import datetime +from typing import ( + TYPE_CHECKING, + Union, +) from ruamel.yaml import YAML -from mxcubecore.utils.conversion import string_types, make_table +from mxcubecore import ( + BaseHardwareObjects, + HardwareObjectFileParser, +) from mxcubecore.dispatcher import dispatcher -from mxcubecore import BaseHardwareObjects -from mxcubecore import HardwareObjectFileParser +from mxcubecore.utils.conversion import ( + make_table, + string_types, +) if TYPE_CHECKING: from mxcubecore.BaseHardwareObjects import HardwareObject diff --git a/mxcubecore/Poller.py b/mxcubecore/Poller.py index cc76b0e384..19ba6e69fb 100644 --- a/mxcubecore/Poller.py +++ b/mxcubecore/Poller.py @@ -1,13 +1,11 @@ import logging -from dispatcher import saferef import gevent import gevent.monkey +import numpy +from dispatcher import saferef from gevent import _threading - from gevent.event import Event -import numpy - try: import Queue as queue diff --git a/mxcubecore/TaskUtils.py b/mxcubecore/TaskUtils.py index cff16c3a2e..a3137794b0 100644 --- a/mxcubecore/TaskUtils.py +++ b/mxcubecore/TaskUtils.py @@ -6,9 +6,10 @@ from types import InstanceType except ImportError: InstanceType = object +import collections import logging + import gevent -import collections class cleanup: diff --git a/mxcubecore/__init__.py b/mxcubecore/__init__.py index 961be785d5..dee41c00b1 100644 --- a/mxcubecore/__init__.py +++ b/mxcubecore/__init__.py @@ -1,10 +1,15 @@ from __future__ import absolute_import import logging -from logging.handlers import RotatingFileHandler import os import sys -from colorama import Fore, Back, Style +from logging.handlers import RotatingFileHandler + +from colorama import ( + Back, + Fore, + Style, +) from mxcubecore import HardwareRepository as HWR from mxcubecore import __version__ diff --git a/mxcubecore/configuration/checkxml.py b/mxcubecore/configuration/checkxml.py index 1e29245efe..9f99080b66 100644 --- a/mxcubecore/configuration/checkxml.py +++ b/mxcubecore/configuration/checkxml.py @@ -1,10 +1,15 @@ -import os -import xmltodict import argparse +import os import pprint + import pydantic +import xmltodict +from colorama import ( + Back, + Fore, + Style, +) -from colorama import Fore, Back, Style from mxcubecore.model import configmodel diff --git a/mxcubecore/configuration/soleil_px2/diffractometer/generate_md2_config_files.py b/mxcubecore/configuration/soleil_px2/diffractometer/generate_md2_config_files.py index d092a64c2e..ae6df7b7fe 100755 --- a/mxcubecore/configuration/soleil_px2/diffractometer/generate_md2_config_files.py +++ b/mxcubecore/configuration/soleil_px2/diffractometer/generate_md2_config_files.py @@ -1,8 +1,8 @@ #!/usr/bin/env python2 """Generate configuration files for MD2 motors. Available options are "exporter", "tango_events", "tango_polling" """ -from string import Template import os +from string import Template continuous_motors = { "AlignmentX": {"direction": "1", "GUIstep": "0.1"}, diff --git a/mxcubecore/model/common.py b/mxcubecore/model/common.py index 3517fc290d..ded8b87cb0 100644 --- a/mxcubecore/model/common.py +++ b/mxcubecore/model/common.py @@ -1,6 +1,10 @@ from datetime import datetime from typing import Optional -from pydantic.v1 import BaseModel, Field + +from pydantic.v1 import ( + BaseModel, + Field, +) class CommonCollectionParamters(BaseModel): diff --git a/mxcubecore/model/configmodel.py b/mxcubecore/model/configmodel.py index a014abbcb0..7a7ca074bd 100644 --- a/mxcubecore/model/configmodel.py +++ b/mxcubecore/model/configmodel.py @@ -1,4 +1,7 @@ -from pydantic.v1 import BaseModel, Field +from pydantic.v1 import ( + BaseModel, + Field, +) class ExporterNStateConfigModel(BaseModel): diff --git a/mxcubecore/model/crystal_symmetry.py b/mxcubecore/model/crystal_symmetry.py index c2234141b2..8272376378 100644 --- a/mxcubecore/model/crystal_symmetry.py +++ b/mxcubecore/model/crystal_symmetry.py @@ -26,7 +26,10 @@ __date__ = "30/04/2023" import operator -from collections import namedtuple, OrderedDict +from collections import ( + OrderedDict, + namedtuple, +) CrystalClassInfo = namedtuple( "CrystalClassInfo", diff --git a/mxcubecore/model/procedure_model.py b/mxcubecore/model/procedure_model.py index 796c3b9559..97b2de1b3d 100644 --- a/mxcubecore/model/procedure_model.py +++ b/mxcubecore/model/procedure_model.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- -from pydantic.v1 import BaseModel, Field +from pydantic.v1 import ( + BaseModel, + Field, +) class ValidationError(Exception): diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index fac0562481..8ec6cf721f 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -24,15 +24,16 @@ the QueueModel. """ import copy -import os import logging +import os from mxcubecore.model import queue_model_enumerables try: - from mxcubecore.model import crystal_symmetry from ruamel.yaml import YAML + from mxcubecore.model import crystal_symmetry + # If you want to write out copies of the file, use typ="rt" instead # pure=True uses yaml version 1.2, with fewere gotchas for strange type conversions yaml = YAML(typ="safe", pure=True) diff --git a/mxcubecore/queue_entry/__init__.py b/mxcubecore/queue_entry/__init__.py index bb39621516..3c81d8ee25 100644 --- a/mxcubecore/queue_entry/__init__.py +++ b/mxcubecore/queue_entry/__init__.py @@ -18,20 +18,19 @@ import sys -from mxcubecore.queue_entry.import_helper import ImportHelper +from mxcubecore.HardwareObjects.EMBL import EMBLQueueEntry +from mxcubecore.HardwareObjects.Gphl import GphlQueueEntry +from mxcubecore.model import queue_model_objects # Import all constants and BaseQueueEntry from base_queue_entry so that # queue _entry can be imported and used as before. from mxcubecore.queue_entry.base_queue_entry import * - -from mxcubecore.model import queue_model_objects -from mxcubecore.HardwareObjects.Gphl import GphlQueueEntry -from mxcubecore.HardwareObjects.EMBL import EMBLQueueEntry +from mxcubecore.queue_entry.characterisation import CharacterisationGroupQueueEntry +from mxcubecore.queue_entry.import_helper import ImportHelper # These two queue entries, for the moment violates the convention above and # should eventually be changed from mxcubecore.queue_entry.xrf_spectrum import XrfSpectrumQueueEntry -from mxcubecore.queue_entry.characterisation import CharacterisationGroupQueueEntry __all__ = [] MODEL_QUEUE_ENTRY_MAPPINGS = {} diff --git a/mxcubecore/queue_entry/advanced_connector.py b/mxcubecore/queue_entry/advanced_connector.py index 6c8bdeb7bf..2be14275d2 100644 --- a/mxcubecore/queue_entry/advanced_connector.py +++ b/mxcubecore/queue_entry/advanced_connector.py @@ -17,10 +17,10 @@ # along with MXCuBE. If not, see . import logging + import gevent from mxcubecore import HardwareRepository as HWR - from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/base_queue_entry.py b/mxcubecore/queue_entry/base_queue_entry.py index e2d2e1f720..c6ecf25330 100644 --- a/mxcubecore/queue_entry/base_queue_entry.py +++ b/mxcubecore/queue_entry/base_queue_entry.py @@ -22,20 +22,22 @@ execute queue entries in a hierarchical manner. """ +import copy import logging import sys -import traceback import time -import gevent -import copy - +import traceback from collections import namedtuple -from mxcubecore import HardwareRepository as HWR -from mxcubecore.model import queue_model_objects -from mxcubecore.model.queue_model_enumerables import CENTRING_METHOD, EXPERIMENT_TYPE +import gevent +from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects import autoprocessing +from mxcubecore.model import queue_model_objects +from mxcubecore.model.queue_model_enumerables import ( + CENTRING_METHOD, + EXPERIMENT_TYPE, +) __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/characterisation.py b/mxcubecore/queue_entry/characterisation.py index 0b3ac813db..eaaa662086 100644 --- a/mxcubecore/queue_entry/characterisation.py +++ b/mxcubecore/queue_entry/characterisation.py @@ -17,13 +17,15 @@ # along with MXCuBE. If not, see . import logging + import gevent from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects - -from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry, QUEUE_ENTRY_STATUS - +from mxcubecore.queue_entry.base_queue_entry import ( + QUEUE_ENTRY_STATUS, + BaseQueueEntry, +) from mxcubecore.queue_entry.data_collection import DataCollectionQueueEntry __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/data_collection.py b/mxcubecore/queue_entry/data_collection.py index 5626755e67..29183fd423 100644 --- a/mxcubecore/queue_entry/data_collection.py +++ b/mxcubecore/queue_entry/data_collection.py @@ -17,20 +17,21 @@ # along with MXCuBE. If not, see . import logging + import gevent from mxcubecore import HardwareRepository as HWR from mxcubecore.dispatcher import dispatcher from mxcubecore.model import queue_model_objects from mxcubecore.model.queue_model_enumerables import ( - EXPERIMENT_TYPE, COLLECTION_ORIGIN_STR, + EXPERIMENT_TYPE, ) from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, QUEUE_ENTRY_STATUS, - QueueExecutionException, + BaseQueueEntry, QueueAbortedException, + QueueExecutionException, center_before_collect, ) diff --git a/mxcubecore/queue_entry/energy_scan.py b/mxcubecore/queue_entry/energy_scan.py index 8ea2ed7144..c20b3eadb5 100644 --- a/mxcubecore/queue_entry/energy_scan.py +++ b/mxcubecore/queue_entry/energy_scan.py @@ -17,16 +17,16 @@ # along with MXCuBE. If not, see . import logging + import gevent from mxcubecore import HardwareRepository as HWR from mxcubecore.dispatcher import dispatcher - from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, QUEUE_ENTRY_STATUS, - QueueExecutionException, + BaseQueueEntry, QueueAbortedException, + QueueExecutionException, ) __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/generic_workflow.py b/mxcubecore/queue_entry/generic_workflow.py index a80b8b1b52..35512c72c9 100644 --- a/mxcubecore/queue_entry/generic_workflow.py +++ b/mxcubecore/queue_entry/generic_workflow.py @@ -16,8 +16,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import time import logging +import time import gevent diff --git a/mxcubecore/queue_entry/import_helper.py b/mxcubecore/queue_entry/import_helper.py index 99ecafce2b..0666f556a7 100644 --- a/mxcubecore/queue_entry/import_helper.py +++ b/mxcubecore/queue_entry/import_helper.py @@ -21,9 +21,9 @@ Utility class for importing queue entries """ -import sys -import os import logging +import os +import sys from importlib import import_module from pathlib import Path diff --git a/mxcubecore/queue_entry/optical_centring.py b/mxcubecore/queue_entry/optical_centring.py index 1dca79d880..766daf9727 100644 --- a/mxcubecore/queue_entry/optical_centring.py +++ b/mxcubecore/queue_entry/optical_centring.py @@ -20,7 +20,6 @@ import gevent from mxcubecore import HardwareRepository as HWR - from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/test_collection.py b/mxcubecore/queue_entry/test_collection.py index 094f9dcf83..abfc4f4cfa 100644 --- a/mxcubecore/queue_entry/test_collection.py +++ b/mxcubecore/queue_entry/test_collection.py @@ -1,16 +1,18 @@ import json -from pydantic.v1 import BaseModel, Field -from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry +from pydantic.v1 import ( + BaseModel, + Field, +) from mxcubecore.model.common import ( CommonCollectionParamters, - PathParameters, LegacyParameters, + PathParameters, StandardCollectionParameters, ) - from mxcubecore.model.queue_model_objects import DataCollection +from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3+" diff --git a/mxcubecore/queue_entry/xray_centering.py b/mxcubecore/queue_entry/xray_centering.py index c7a884e518..f5a4ccdac5 100644 --- a/mxcubecore/queue_entry/xray_centering.py +++ b/mxcubecore/queue_entry/xray_centering.py @@ -18,7 +18,6 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects - from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/xray_centering2.py b/mxcubecore/queue_entry/xray_centering2.py index 9ced94ff6f..2776346728 100644 --- a/mxcubecore/queue_entry/xray_centering2.py +++ b/mxcubecore/queue_entry/xray_centering2.py @@ -19,7 +19,6 @@ from mxcubecore import HardwareRepository as HWR from mxcubecore.model import queue_model_objects - from mxcubecore.queue_entry.base_queue_entry import BaseQueueEntry __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/queue_entry/xrf_spectrum.py b/mxcubecore/queue_entry/xrf_spectrum.py index 30588aa129..4f1023a635 100644 --- a/mxcubecore/queue_entry/xrf_spectrum.py +++ b/mxcubecore/queue_entry/xrf_spectrum.py @@ -22,13 +22,13 @@ import logging -from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore import HardwareRepository as HWR +from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.queue_entry.base_queue_entry import ( - BaseQueueEntry, QUEUE_ENTRY_STATUS, - QueueExecutionException, + BaseQueueEntry, QueueAbortedException, + QueueExecutionException, ) __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/saferef.py b/mxcubecore/saferef.py index f0aeb665cc..df5840856e 100644 --- a/mxcubecore/saferef.py +++ b/mxcubecore/saferef.py @@ -1,8 +1,8 @@ """Refactored 'safe reference from dispatcher.py""" -import weakref -import traceback import collections +import traceback +import weakref def safe_ref(target, on_delete=None): diff --git a/mxcubecore/utils/conversion.py b/mxcubecore/utils/conversion.py index d9ad114d68..e350552b55 100644 --- a/mxcubecore/utils/conversion.py +++ b/mxcubecore/utils/conversion.py @@ -20,12 +20,20 @@ """General data and functions, that can be shared between different HardwareObjects """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import re -from scipy.constants import h, c, e +from scipy.constants import ( + c, + e, + h, +) __date__ = "19/06/17" __credits__ = ["MXCuBE collaboration"] diff --git a/mxcubecore/utils/dataobject.py b/mxcubecore/utils/dataobject.py index 81aaec0113..77e198da62 100644 --- a/mxcubecore/utils/dataobject.py +++ b/mxcubecore/utils/dataobject.py @@ -18,9 +18,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with MXCuBE. If not, see . -import jsonschema import copy +import jsonschema + __copyright__ = """ Copyright © 2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" diff --git a/mxcubecore/utils/qt_import.py b/mxcubecore/utils/qt_import.py index 3e6798cf06..0f2e14dbb6 100644 --- a/mxcubecore/utils/qt_import.py +++ b/mxcubecore/utils/qt_import.py @@ -115,10 +115,8 @@ if (qt_variant == "PyQt5") or (qt_variant is None and not qt_imported): try: from PyQt5.QtCore import ( - pyqtSignal, - pyqtSlot, PYQT_VERSION_STR, - Qt, + QT_VERSION_STR, QCoreApplication, QDir, QEvent, @@ -130,8 +128,34 @@ QRectF, QRegExp, QSize, - QT_VERSION_STR, + Qt, QTimer, + pyqtSignal, + pyqtSlot, + ) + from PyQt5.QtGui import ( + QBrush, + QColor, + QContextMenuEvent, + QCursor, + QDoubleValidator, + QFocusEvent, + QFont, + QIcon, + QImage, + QIntValidator, + QKeyEvent, + QKeySequence, + QLinearGradient, + QMouseEvent, + QPainter, + QPainterPath, + QPalette, + QPen, + QPixmap, + QPolygon, + QRegExpValidator, + QValidator, ) from PyQt5.QtWidgets import ( QAbstractItemView, @@ -181,10 +205,10 @@ QSplitter, QStackedWidget, QStatusBar, - QTabWidget, QTableView, QTableWidget, QTableWidgetItem, + QTabWidget, QTextBrowser, QTextEdit, QToolBar, @@ -199,30 +223,6 @@ QWhatsThis, QWidget, ) - from PyQt5.QtGui import ( - QBrush, - QColor, - QContextMenuEvent, - QCursor, - QDoubleValidator, - QFocusEvent, - QFont, - QKeyEvent, - QKeySequence, - QIcon, - QImage, - QIntValidator, - QLinearGradient, - QMouseEvent, - QPainter, - QPainterPath, - QPalette, - QPen, - QPixmap, - QPolygon, - QRegExpValidator, - QValidator, - ) from PyQt5.uic import loadUi QStringList = list @@ -256,14 +256,12 @@ # but code is guaranteed to be compatible try: from PyQt4.QtCore import ( - pyqtSignal, - pyqtSlot, PYQT_VERSION_STR, - Qt, + QT_VERSION_STR, + SIGNAL, QDir, QEvent, QEventLoop, - QUrl, QObject, QPoint, QPointF, @@ -272,12 +270,13 @@ QRegExp, QSize, QStringList, - QT_VERSION_STR, + Qt, QTimer, - SIGNAL, + QUrl, + pyqtSignal, + pyqtSlot, ) from PyQt4.QtGui import ( - qApp, QAbstractItemView, QAction, QActionGroup, @@ -287,19 +286,18 @@ QCheckBox, QColor, QColorDialog, - QContextMenuEvent, QComboBox, + QContextMenuEvent, QCursor, QDesktopWidget, QDial, QDialog, - QInputDialog, QDoubleSpinBox, QDoubleValidator, QFileDialog, + QFocusEvent, QFont, QFrame, - QFocusEvent, QGraphicsItem, QGraphicsPixmapItem, QGraphicsScene, @@ -308,16 +306,16 @@ QGroupBox, QHBoxLayout, QHeaderView, - QKeyEvent, - QKeySequence, QIcon, QImage, QInputDialog, QIntValidator, + QKeyEvent, + QKeySequence, QLabel, QLayout, - QLineEdit, QLinearGradient, + QLineEdit, QListView, QListWidget, QListWidgetItem, @@ -347,10 +345,10 @@ QSplitter, QStackedWidget, QStatusBar, - QTabWidget, QTableView, QTableWidget, QTableWidgetItem, + QTabWidget, QTextBrowser, QTextEdit, QToolBar, @@ -363,8 +361,9 @@ QTreeWidgetItemIterator, QValidator, QVBoxLayout, - QWidget, QWhatsThis, + QWidget, + qApp, ) from PyQt4.uic import loadUi @@ -402,8 +401,8 @@ def getQApp(): from PySide.QtCore import * from PySide.QtGui import * - from PySide.QtUiTools import * from PySide.QtSvg import * + from PySide.QtUiTools import * from PySide.QtWebKit import * pyqtSignal = Signal diff --git a/test/pytest/TestAbstractActuatorBase.py b/test/pytest/TestAbstractActuatorBase.py index 7366482999..4ef0000555 100644 --- a/test/pytest/TestAbstractActuatorBase.py +++ b/test/pytest/TestAbstractActuatorBase.py @@ -21,13 +21,12 @@ __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" +import abc from test.pytest import TestHardwareObjectBase -import abc import gevent import pytest - test_object = TestHardwareObjectBase.test_object diff --git a/test/pytest/TestAbstractMotorBase.py b/test/pytest/TestAbstractMotorBase.py index e4dd1ef6f0..f3244c6088 100644 --- a/test/pytest/TestAbstractMotorBase.py +++ b/test/pytest/TestAbstractMotorBase.py @@ -22,9 +22,13 @@ __license__ = "LGPLv3+" import abc +from test.pytest import ( + TestAbstractActuatorBase, + TestHardwareObjectBase, +) + import gevent import pytest -from test.pytest import TestHardwareObjectBase, TestAbstractActuatorBase test_object = TestAbstractActuatorBase.test_object diff --git a/test/pytest/TestAbstractNStateBase.py b/test/pytest/TestAbstractNStateBase.py index c62d40aaf5..22189bbecf 100644 --- a/test/pytest/TestAbstractNStateBase.py +++ b/test/pytest/TestAbstractNStateBase.py @@ -23,8 +23,9 @@ __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" -from test.pytest import TestAbstractActuatorBase import abc +from test.pytest import TestAbstractActuatorBase + import pytest test_object = TestAbstractActuatorBase.test_object diff --git a/test/pytest/TestHardwareObjectBase.py b/test/pytest/TestHardwareObjectBase.py index 9a99c00bbc..27f3c231a2 100644 --- a/test/pytest/TestHardwareObjectBase.py +++ b/test/pytest/TestHardwareObjectBase.py @@ -19,19 +19,23 @@ Test suite to be used as base for testing when inheriting from HardwareObject. """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) __copyright__ = """ Copyright © 2020 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" import abc + import gevent.event +import pytest from mxcubecore.BaseHardwareObjects import HardwareObjectState -import pytest - @pytest.fixture def test_object(beamline): diff --git a/test/pytest/conftest.py b/test/pytest/conftest.py index 2399691756..8585738aae 100644 --- a/test/pytest/conftest.py +++ b/test/pytest/conftest.py @@ -19,13 +19,13 @@ # along with MXCuBE. If not, see . """Tests configuration""" -import sys import os +import sys -from mxcubecore import HardwareRepository as HWR - -from gevent import monkey import pytest +from gevent import monkey + +from mxcubecore import HardwareRepository as HWR monkey.patch_all(thread=False) diff --git a/test/pytest/test_aperture.py b/test/pytest/test_aperture.py index dc9f2bfddc..e79c5528fe 100644 --- a/test/pytest/test_aperture.py +++ b/test/pytest/test_aperture.py @@ -21,9 +21,10 @@ __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" -import pytest from test.pytest.TestAbstractNStateBase import TestAbstractNStateBase +import pytest + @pytest.fixture def test_object(beamline): diff --git a/test/pytest/test_base_hardware_objects.py b/test/pytest/test_base_hardware_objects.py index 3fe87abed3..87e0dc8c6d 100644 --- a/test/pytest/test_base_hardware_objects.py +++ b/test/pytest/test_base_hardware_objects.py @@ -1,26 +1,30 @@ import copy -import pytest +from collections import OrderedDict +from logging import Logger from typing import ( - Any, - Union, TYPE_CHECKING, - Iterator, - Generator, + Any, Dict, - Tuple, + Generator, + Iterator, List, - OrderedDict as TOrderedDict, ) -from logging import Logger +from typing import OrderedDict as TOrderedDict +from typing import ( + Tuple, + Union, +) from unittest.mock import MagicMock -from collections import OrderedDict + +import pytest + from mxcubecore.BaseHardwareObjects import ( ConfiguredObject, - PropertySet, - HardwareObjectNode, - HardwareObjectMixin, HardwareObject, + HardwareObjectMixin, + HardwareObjectNode, HardwareObjectYaml, + PropertySet, ) if TYPE_CHECKING: diff --git a/test/pytest/test_beam.py b/test/pytest/test_beam.py index 1458891e37..2dbcc19be0 100644 --- a/test/pytest/test_beam.py +++ b/test/pytest/test_beam.py @@ -23,10 +23,11 @@ """ from test.pytest import TestHardwareObjectBase -from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape import pytest +from mxcubecore.HardwareObjects.abstract.AbstractBeam import BeamShape + __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/test/pytest/test_beam_definer.py b/test/pytest/test_beam_definer.py index c4685ee878..31aa8ee997 100644 --- a/test/pytest/test_beam_definer.py +++ b/test/pytest/test_beam_definer.py @@ -22,9 +22,10 @@ """Test suite for BeamDefiner hardware object. """ -import pytest from test.pytest.TestAbstractNStateBase import TestAbstractNStateBase +import pytest + __copyright__ = """ Copyright © by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/test/pytest/test_beamline_ho_id.py b/test/pytest/test_beamline_ho_id.py index 2ac18a67ec..8e9ae29921 100644 --- a/test/pytest/test_beamline_ho_id.py +++ b/test/pytest/test_beamline_ho_id.py @@ -18,8 +18,12 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import pytest diff --git a/test/pytest/test_command_container.py b/test/pytest/test_command_container.py index d58700c69a..a543d5ea88 100644 --- a/test/pytest/test_command_container.py +++ b/test/pytest/test_command_container.py @@ -1,17 +1,28 @@ import copy import json import weakref -import pytest -from typing import Generator, TYPE_CHECKING, Any, Dict, Union, List, Tuple, Optional -from typing_extensions import Annotated from logging import Logger +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Generator, + List, + Optional, + Tuple, + Union, +) from unittest.mock import MagicMock + +import pytest +from typing_extensions import Annotated + from mxcubecore.CommandContainer import ( - ARGUMENT_TYPE_LIST, ARGUMENT_TYPE_JSON_SCHEMA, - CommandObject, + ARGUMENT_TYPE_LIST, ChannelObject, CommandContainer, + CommandObject, ) if TYPE_CHECKING: diff --git a/test/pytest/test_detector.py b/test/pytest/test_detector.py index be75e576b9..e5bc81f788 100644 --- a/test/pytest/test_detector.py +++ b/test/pytest/test_detector.py @@ -18,11 +18,16 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import math from test.pytest import TestHardwareObjectBase + import pytest __copyright__ = """ Copyright © 2016 - 2020 by MXCuBE Collaboration """ diff --git a/test/pytest/test_detector_distance.py b/test/pytest/test_detector_distance.py index c489c12388..a9d41f51c4 100644 --- a/test/pytest/test_detector_distance.py +++ b/test/pytest/test_detector_distance.py @@ -18,12 +18,17 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) -import pytest from test.pytest import TestAbstractMotorBase +import pytest + __copyright__ = """ Copyright © 2016 - 2020 by MXCuBE Collaboration """ __license__ = "LGPLv3+" __author__ = "rhfogh" diff --git a/test/pytest/test_energy.py b/test/pytest/test_energy.py index a49d10c02f..a7a7b1dc82 100644 --- a/test/pytest/test_energy.py +++ b/test/pytest/test_energy.py @@ -21,10 +21,10 @@ __copyright__ = """ Copyright © 2019-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" -import pytest - from test.pytest import TestAbstractActuatorBase +import pytest + @pytest.fixture def test_object(beamline): diff --git a/test/pytest/test_flux.py b/test/pytest/test_flux.py index e223e0b085..36f21dff08 100644 --- a/test/pytest/test_flux.py +++ b/test/pytest/test_flux.py @@ -24,6 +24,7 @@ __license__ = "LGPLv3+" from test.pytest import TestAbstractActuatorBase + import pytest diff --git a/test/pytest/test_hwo_isara_maint.py b/test/pytest/test_hwo_isara_maint.py index 3bacbe68bd..8c61c0c1f6 100644 --- a/test/pytest/test_hwo_isara_maint.py +++ b/test/pytest/test_hwo_isara_maint.py @@ -1,9 +1,17 @@ import pytest -from tango import DeviceProxy, Except -from tango.server import Device, attribute, command +from gevent.event import Event +from tango import ( + DeviceProxy, + Except, +) +from tango.server import ( + Device, + attribute, + command, +) from tango.test_context import DeviceTestContext + from mxcubecore.HardwareObjects.ISARAMaint import ISARAMaint -from gevent.event import Event """ Test the HardwareObjects.ISARAMaint sample changer maintenance hardware object. diff --git a/test/pytest/test_hwo_maxiv_mach_info.py b/test/pytest/test_hwo_maxiv_mach_info.py index 68324aa7f8..28de2c8d56 100644 --- a/test/pytest/test_hwo_maxiv_mach_info.py +++ b/test/pytest/test_hwo_maxiv_mach_info.py @@ -1,8 +1,14 @@ import math + import pytest from gevent.event import Event -from tango.server import Device, attribute, command +from tango.server import ( + Device, + attribute, + command, +) from tango.test_context import MultiDeviceTestContext + from mxcubecore.HardwareObjects.MAXIV.MachInfo import MachInfo diff --git a/test/pytest/test_mach_info.py b/test/pytest/test_mach_info.py index 0702db5b5d..226aa5786b 100644 --- a/test/pytest/test_mach_info.py +++ b/test/pytest/test_mach_info.py @@ -18,9 +18,10 @@ """Test suite for MachineInfo hardware object """ -import pytest from test.pytest import TestHardwareObjectBase +import pytest + __copyright__ = """ Copyright © by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/test/pytest/test_procedure.py b/test/pytest/test_procedure.py index 2e4d5e681c..da076299eb 100644 --- a/test/pytest/test_procedure.py +++ b/test/pytest/test_procedure.py @@ -1,6 +1,7 @@ import gevent -from mxcubecore.model import procedure_model + from mxcubecore.HardwareObjects.abstract.AbstractProcedure import ProcedureState +from mxcubecore.model import procedure_model def test_procedure_init(beamline): diff --git a/test/pytest/test_resolution.py b/test/pytest/test_resolution.py index 67c6fd6a9e..1ed8155eee 100755 --- a/test/pytest/test_resolution.py +++ b/test/pytest/test_resolution.py @@ -20,8 +20,8 @@ hardware objects """ from test.pytest import TestAbstractMotorBase -import pytest +import pytest __copyright__ = """ Copyright © 2016 - 2022 by MXCuBE Collaboration """ __license__ = "LGPLv3+" diff --git a/test/pytest/test_sample_view.py b/test/pytest/test_sample_view.py index 16ef59baab..82c2cf3115 100644 --- a/test/pytest/test_sample_view.py +++ b/test/pytest/test_sample_view.py @@ -18,8 +18,12 @@ """ """ -from __future__ import division, absolute_import -from __future__ import print_function, unicode_literals +from __future__ import ( + absolute_import, + division, + print_function, + unicode_literals, +) import pytest diff --git a/test/pytest/test_shutter.py b/test/pytest/test_shutter.py index 95bc054018..ca19b45084 100644 --- a/test/pytest/test_shutter.py +++ b/test/pytest/test_shutter.py @@ -21,10 +21,11 @@ __copyright__ = """ Copyright © 2019-2020 by the MXCuBE collaboration """ __license__ = "LGPLv3+" +from test.pytest import TestAbstractNStateBase + import pytest from mxcubecore.BaseHardwareObjects import HardwareObjectState -from test.pytest import TestAbstractNStateBase @pytest.fixture diff --git a/test/pytest/test_transmission.py b/test/pytest/test_transmission.py index ce38ccaf6d..f799b89199 100644 --- a/test/pytest/test_transmission.py +++ b/test/pytest/test_transmission.py @@ -24,6 +24,7 @@ __license__ = "LGPLv3+" from test.pytest import TestAbstractActuatorBase + import pytest diff --git a/test/pytest/test_utils_units.py b/test/pytest/test_utils_units.py index 5a3f490f67..9c668f695f 100644 --- a/test/pytest/test_utils_units.py +++ b/test/pytest/test_utils_units.py @@ -1,14 +1,15 @@ from math import isclose + from mxcubecore.utils.units import ( - us_to_sec, - ms_to_sec, - sec_to_us, - sec_to_hour, + A_to_mA, ev_to_kev, meter_to_mm, mm_to_meter, + ms_to_sec, + sec_to_hour, + sec_to_us, um_to_mm, - A_to_mA, + us_to_sec, ) diff --git a/test/pytest/test_xrf.py b/test/pytest/test_xrf.py index 81b4ccb9e7..50358b4760 100644 --- a/test/pytest/test_xrf.py +++ b/test/pytest/test_xrf.py @@ -29,8 +29,10 @@ __copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" -import pytest from test.pytest import TestHardwareObjectBase + +import pytest + from mxcubecore.BaseHardwareObjects import HardwareObjectState From 9ee66104dabf983b4c24a75f939d54bde721dc55 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 22 Oct 2024 14:41:48 +0000 Subject: [PATCH 095/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 53dc054f25..7f24fd67c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.167.0" +version = "1.168.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From bf1d50469cd91d01b4cce28fd1c12dab078e88eb Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Wed, 28 Aug 2024 11:00:03 +0200 Subject: [PATCH 096/172] New Snapshot routine Co-authored-by: marcus-oscarsson --- .../HardwareObjects/ESRF/ESRFMultiCollect.py | 1 + .../HardwareObjects/ESRF/MD2MultiCollect.py | 13 +-- .../HardwareObjects/GenericDiffractometer.py | 7 +- mxcubecore/HardwareObjects/MiniDiff.py | 13 +++ mxcubecore/HardwareObjects/SampleView.py | 93 ++++++++++++++++--- mxcubecore/HardwareObjects/TangoLimaVideo.py | 19 +--- .../abstract/AbstractMultiCollect.py | 48 +++++++++- .../abstract/AbstractSampleView.py | 11 ++- .../HardwareObjects/mockup/MDCameraMockup.py | 8 +- 9 files changed, 159 insertions(+), 54 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py index e2b9aec541..9bd98f36e8 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py @@ -47,6 +47,7 @@ def execute_command(self, command_name, *args, **kwargs): def init(self): self._detector = HWR.beamline.detector + self.number_of_snapshots = self.get_property("num_snapshots", 4) self.setControlObjects( diffractometer=self.get_object_by_role("diffractometer"), diff --git a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py index 1c613f8f0f..973ffeefc5 100644 --- a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py @@ -59,17 +59,8 @@ def move_motors(self, motors_to_move_dict): diffr.move_sync_motors(motor_positions_copy, wait=True, timeout=200) @task - def take_crystal_snapshots(self, number_of_snapshots): - if HWR.beamline.diffractometer.in_plate_mode(): - if number_of_snapshots > 0: - number_of_snapshots = 1 - else: - # this has to be done before each chage of phase - HWR.beamline.diffractometer.save_centring_positions() - # not going to centring phase if in plate mode (too long) - HWR.beamline.diffractometer.set_phase("Centring", wait=True, timeout=600) - - HWR.beamline.diffractometer.take_snapshots(number_of_snapshots, wait=True) + def take_crystal_snapshots(self, number_of_snapshots, image_path_list=[]): + HWR.beamline.diffractometer.new_take_snapshot(image_path_list) def do_prepare_oscillation(self, *args, **kwargs): # set the detector cover out diff --git a/mxcubecore/HardwareObjects/GenericDiffractometer.py b/mxcubecore/HardwareObjects/GenericDiffractometer.py index 0105894175..1de9aa0f4b 100755 --- a/mxcubecore/HardwareObjects/GenericDiffractometer.py +++ b/mxcubecore/HardwareObjects/GenericDiffractometer.py @@ -792,8 +792,13 @@ def get_motors(self): # return self.current_positions_dict.get("phi") def get_snapshot(self): + """ + Get sample_view snapshot + + :returns: bytes object of current camera image + """ if HWR.beamline.sample_view: - return HWR.beamline.sample_view.take_snapshot() + return HWR.beamline.sample_view.get_snapshot() def save_snapshot(self, filename): """ """ diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 2bee7b4bc8..950709b41f 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -1024,6 +1024,19 @@ def move_motors(self, roles_positions_dict): ): time.sleep(0.1) + def new_take_snapshot(self, image_path_list: list) -> None: + if self.get_current_phase() != "Centring": + use_custom_snapshot_routine = self.get_property( + "custom_snapshot_script_dir", False + ) + + if not use_custom_snapshot_routine: + self.set_phase("Centring", wait=True, timeout=200) + + for image_path in image_path_list: + HWR.beamline.sample_view.save_snapshot(path=image_path) + self.phiMotor.set_value_relative(90, timeout=5) + def take_snapshots(self, image_count, wait=False): HWR.beamline.sample_view.camera.forceUpdate = True diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index 5bd31fe56b..27343efd2e 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -22,12 +22,40 @@ import copy from functools import reduce +from PIL import Image +from io import BytesIO +import base64 +import numpy as np from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractSampleView import AbstractSampleView from mxcubecore.model import queue_model_objects +def combine_images(img1, img2): + if img1.size != img2.size: + raise ValueError("Images must be the same size") + + combined_img = Image.new("RGB", img1.size) + + pixels1 = img1.load() + pixels2 = img2.load() + combined_pixels = combined_img.load() + + width, height = img1.size + for x in range(width): + for y in range(height): + pixel1 = pixels1[x, y] + pixel2 = pixels2[x, y] + + if pixel2[0] <= 200 and pixel2[1] <= 60 and pixel2[2] <= 140: + combined_pixels[x, y] = pixel1 + else: + combined_pixels[x, y] = pixel2 + + return combined_img + + class SampleView(AbstractSampleView): def __init__(self, name): AbstractSampleView.__init__(self, name) @@ -36,7 +64,6 @@ def __init__(self, name): def init(self): super(SampleView, self).init() self._camera = self.get_object_by_role("camera") - self._ui_snapshot_cb = None self._last_oav_image = None self.hide_grid_threshold = self.get_property("hide_grid_threshold", 5) @@ -73,32 +100,70 @@ def start_auto_centring(self): """ pass - def set_ui_snapshot_cb(self, fun): - self._ui_snapshot_cb = fun + def get_snapshot(self, overlay=None, bw=False, return_as_array=False): + """ + Get snapshot(s) - def get_snapshot(self, overlay=True, bw=False, return_as_array=False): - """Get snapshot(s) Args: - overlay(bool): Display shapes and other items on the snapshot + overlay(str): Image data with shapes and other items to display on the snapshot bw(bool): return grayscale image return_as_array(bool): return as np array + + Returns: + (BytesIO) snapshot as bytes image """ - pass + img = self.take_snapshot(overlay_data=overlay, bw=bw) + + if return_as_array: + return np.array(img) + + buffered = BytesIO() + img.save(buffered, format="JPEG") + + return buffered + + def save_snapshot(self, path, overlay=None, bw=False): + """ + Save a snapshot to file. - def save_snapshot(self, path, overlay=True, bw=False): - """Save a snapshot to file. Args: path (str): The filename. - overlay(bool): Display shapes and other items on the snapshot + overlay(str): Image data with shapes and other items to display on the snapshot bw(bool): return grayscale image """ - if overlay: - self._ui_snapshot_cb(path, bw) - else: - self.camera.take_snapshot(path, bw) + img = self.take_snapshot(overlay_data=overlay, bw=bw) + img.save(path) self._last_oav_image = path + def take_snapshot(self, overlay_data=None, bw=False): + """ + Get snapshot with overlayed data. + + Args: + overlay_data (str): base64 encoded image to lay over camera image + bw (bool): return grayscale image + + Returns: + (Image) rgb or grayscale image + """ + data, width, height = self.camera.get_last_image() + + img = Image.frombytes("RGB", (width, height), data) + + if overlay_data: + overlay_data = base64.b64decode(overlay_data) + overlay_image = Image.open(BytesIO(overlay_data)) + overlay_image = overlay_image.resize( + (width, height), Image.Resampling.LANCZOS + ) + img = combine_images(img, overlay_image.convert("RGB")) + + if bw: + img.convert("1") + + return img + def get_last_image_path(self): return self._last_oav_image diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 9be8283c1d..0cac1648f8 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -19,10 +19,10 @@ import time import gevent -import gipc -import numpy import PyTango from PIL import Image +import io + from PyTango.gevent import DeviceProxy from mxcubecore import BaseHardwareObjects @@ -111,7 +111,7 @@ def init(self): self.set_is_ready(True) def get_last_image(self): - return self._last_image + return poll_image(self.device, self.video_mode, self._FORMATS) def _do_polling(self, sleep_time): lima_tango_device = self.device @@ -138,19 +138,6 @@ def get_width(self): def get_height(self): return self.device.image_height - def take_snapshot(self, path=None, bw=False): - data, width, height = poll_image(self.device, self.video_mode, self._FORMATS) - - img = Image.frombytes("RGB", (width, height), data) - - if bw: - img.convert("1") - - if path: - img.save(path) - - return img - def set_live(self, mode): curr_state = self.device.video_live diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index 4c09206911..e64ecefbc8 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -88,6 +88,8 @@ def __init__(self): self.mesh_range = None self.mesh_center = None + self.number_of_snapshots = 4 + def setControlObjects(self, **control_objects): self.bl_control = BeamlineControl(**control_objects) @@ -316,6 +318,41 @@ def adxv_notify(self, image_filename: str, image_num: int = 1): else: pass + def new_take_snapshots(self, dc_params): + # number_of_snapshots = dc_params.get("take_snapshots", 0) + snapshot_directory = dc_params["fileinfo"]["archive_directory"] + + if HWR.beamline.diffractometer.in_plate_mode(): + if number_of_snapshots > 0: + number_of_snapshots = 1 + + if not os.path.exists(snapshot_directory): + self.create_directories(snapshot_directory) + + image_path_list = [] + + for snapshot_index in range(self.number_of_snapshots): + snapshot_filename = os.path.join( + snapshot_directory, + "%s_%s_%s.snapshot.jpeg" + % ( + dc_params["fileinfo"]["prefix"], + dc_params["fileinfo"]["run_number"], + (snapshot_index + 1), + ), + ) + + image_path_list.append(snapshot_filename) + dc_params["xtalSnapshotFullPath%i" % (snapshot_index + 1)] = ( + snapshot_filename + ) + + logging.getLogger("user_level_log").info( + f"Taking {snapshot_index + 1} sample snapshot(s)" + ) + + HWR.beamline.diffractometer.new_take_snapshot(image_path_list) + def _take_crystal_snapshots(self, number_of_snapshots): try: if isinstance(number_of_snapshots, bool): @@ -563,11 +600,14 @@ def do_collect(self, owner, data_collect_parameters): # take snapshots, then assign centring status (which contains images) to # centring_info variable - take_snapshots = data_collect_parameters.get("take_snapshots", False) + # take_snapshots = data_collect_parameters.get("take_snapshots", False) - if take_snapshots: - logging.getLogger("user_level_log").info("Taking sample snapshosts") - self._take_crystal_snapshots(take_snapshots) + if self.number_of_snapshots: + logging.getLogger("user_level_log").info( + f"Taking sample ({self.number_of_snapshots}) snapshosts" + ) + # self._take_crystal_snapshots(take_snapshots) + self.new_take_snapshots(data_collect_parameters) centring_info = HWR.beamline.diffractometer.get_centring_status() # move *again* motors, since taking snapshots may change positions logging.getLogger("user_level_log").info( diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py index 8994512fea..b42d5d9b81 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py @@ -26,6 +26,7 @@ import abc from mxcubecore.BaseHardwareObjects import HardwareObject +from typing import Union class AbstractSampleView(HardwareObject): @@ -43,20 +44,22 @@ def __init__(self, name): self._shapes = None @abc.abstractmethod - def get_snapshot(self, overlay=True, bw=False, return_as_array=False): + def get_snapshot( + self, overlay: Union[bool, str] = True, bw=False, return_as_array=False + ): """Get snappshot(s) Args: - overlay(bool): Display shapes and other items on the snapshot + overlay(bool | str): Display shapes and other items on the snapshot bw(bool): return grayscale image return_as_array(bool): return as np array """ @abc.abstractmethod - def save_snapshot(self, filename, overlay=True, bw=False): + def save_snapshot(self, filename, overlay: Union[bool, str] = True, bw=False): """Save a snapshot to file. Args: filename (str): The filename. - overlay(bool): Display shapes and other items on the snapshot. + overlay(bool | str): Display shapes and other items on the snapshot. bw(bool): Return grayscale image. """ diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index e8b2e42df4..7f6fa90d0e 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -6,6 +6,7 @@ import gevent import psutil +from PIL import Image from mxcubecore import BaseHardwareObjects from mxcubecore import HardwareRepository as HWR @@ -92,10 +93,9 @@ def set_live(self, state): def imageType(self): return None - def takeSnapshot(self, snapshot_filename, bw=True): - return True - - take_snapshot = takeSnapshot + def get_last_image(self): + image = Image.open(self.image) + return image.tobytes(), image.size[0], image.size[1] def get_available_stream_sizes(self): try: From 4ff385c585275c75ae9543bd4daaae510e01aca3 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 23 Sep 2024 09:06:30 +0200 Subject: [PATCH 097/172] Logging --- mxcubecore/HardwareObjects/MiniDiff.py | 4 ++++ mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 950709b41f..07a26d9f6f 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -1034,6 +1034,10 @@ def new_take_snapshot(self, image_path_list: list) -> None: self.set_phase("Centring", wait=True, timeout=200) for image_path in image_path_list: + snapshot_index = image_path_list.index(image_path) + logging.getLogger("user_level_log").info( + f"Taking {snapshot_index + 1} sample snapshot(s)" + ) HWR.beamline.sample_view.save_snapshot(path=image_path) self.phiMotor.set_value_relative(90, timeout=5) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index e64ecefbc8..2c7b22e4be 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -347,10 +347,6 @@ def new_take_snapshots(self, dc_params): snapshot_filename ) - logging.getLogger("user_level_log").info( - f"Taking {snapshot_index + 1} sample snapshot(s)" - ) - HWR.beamline.diffractometer.new_take_snapshot(image_path_list) def _take_crystal_snapshots(self, number_of_snapshots): From 1c8f202a2f4cbe66b0dee4e1d557fb0fd6a0a3e7 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 30 Sep 2024 11:09:45 +0200 Subject: [PATCH 098/172] Taking snapshots depending on whats set on data collection --- .../HardwareObjects/abstract/AbstractMultiCollect.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index 2c7b22e4be..5403402380 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -319,7 +319,6 @@ def adxv_notify(self, image_filename: str, image_num: int = 1): pass def new_take_snapshots(self, dc_params): - # number_of_snapshots = dc_params.get("take_snapshots", 0) snapshot_directory = dc_params["fileinfo"]["archive_directory"] if HWR.beamline.diffractometer.in_plate_mode(): @@ -594,11 +593,7 @@ def do_collect(self, owner, data_collect_parameters): self.move_motors(motors_to_move_before_collect) HWR.beamline.diffractometer.save_centring_positions() - # take snapshots, then assign centring status (which contains images) to - # centring_info variable - # take_snapshots = data_collect_parameters.get("take_snapshots", False) - - if self.number_of_snapshots: + if data_collect_parameters.get("take_snapshots", False): logging.getLogger("user_level_log").info( f"Taking sample ({self.number_of_snapshots}) snapshosts" ) From 4edc6e5336e089736d829e1d64ed3074641bdea7 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Fri, 18 Oct 2024 16:54:15 +0200 Subject: [PATCH 099/172] cleanup of old snapshot routine Co-authored-by: marcus-oscarsson --- .../mockup/MultiCollectMockup.py | 4 - .../HardwareObjects/ESRF/MD2MultiCollect.py | 2 +- .../HardwareObjects/LNLS/LNLSCollect.py | 4 - mxcubecore/HardwareObjects/MiniDiff.py | 111 +----------------- .../abstract/AbstractMultiCollect.py | 24 +--- .../mockup/MultiCollectMockup.py | 4 - 6 files changed, 5 insertions(+), 144 deletions(-) diff --git a/deprecated/HardwareObjects/mockup/MultiCollectMockup.py b/deprecated/HardwareObjects/mockup/MultiCollectMockup.py index 9fe76b8cdb..4a4f92559d 100644 --- a/deprecated/HardwareObjects/mockup/MultiCollectMockup.py +++ b/deprecated/HardwareObjects/mockup/MultiCollectMockup.py @@ -103,10 +103,6 @@ def loop(self, owner, data_collect_parameters_list): logging.getLogger("HWR").info("data collection successful in loop") self.emit("collectReady", (True,)) - @task - def take_crystal_snapshots(self, number_of_snapshots): - self.bl_control.diffractometer.take_snapshots(number_of_snapshots, wait=True) - @task def data_collection_hook(self, data_collect_parameters): return diff --git a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py index 973ffeefc5..2c2cb419b6 100644 --- a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py @@ -60,7 +60,7 @@ def move_motors(self, motors_to_move_dict): @task def take_crystal_snapshots(self, number_of_snapshots, image_path_list=[]): - HWR.beamline.diffractometer.new_take_snapshot(image_path_list) + HWR.beamline.diffractometer.take_snapshot(image_path_list) def do_prepare_oscillation(self, *args, **kwargs): # set the detector cover out diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py b/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py index 5ced97b7c4..9ddc2688c7 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSCollect.py @@ -280,10 +280,6 @@ def set_pilatus_det_header(self, start_angle, step_size): wl_ok and dd_ok and bx_ok and by_ok and te_ok and ft_ok and sa_ok and ss_ok ) - @task - def take_crystal_snapshots(self, number_of_snapshots): - self.bl_control.diffractometer.take_snapshots(number_of_snapshots, wait=True) - @task def data_collection_hook(self, data_collect_parameters): return diff --git a/mxcubecore/HardwareObjects/MiniDiff.py b/mxcubecore/HardwareObjects/MiniDiff.py index 07a26d9f6f..676b1679de 100644 --- a/mxcubecore/HardwareObjects/MiniDiff.py +++ b/mxcubecore/HardwareObjects/MiniDiff.py @@ -3,7 +3,6 @@ import logging import math import os -import tempfile import time from typing import Union @@ -18,86 +17,6 @@ from mxcubecore.model import queue_model_objects as qmo from mxcubecore.TaskUtils import task -try: - from Qub.Tools import QubImageSave -except ImportError: - pass - - -class myimage: - def __init__(self, drawing): - self.drawing = drawing - matrix = self.drawing.matrix() - self.zoom = 1 - if matrix is not None: - self.zoom = matrix.m11() - - def save(self, filename=None): - self.img = self.drawing.getPPP() - - if filename is None: - fd, name = tempfile.mkstemp() - os.close(fd) - else: - name = filename - - QubImageSave.save(name, self.img, self.drawing.canvas(), self.zoom, "JPEG") - - if filename is None: - f = open(name, "r") - self.imgcopy = f.read() - f.close() - os.unlink(name) - - def __str__(self): - self.save() - return self.imgcopy - - -def set_light_in(light, light_motor, zoom): - with gevent.Timeout(5, RuntimeError("Could not set light in")): - light_level = None - - if light is not None: - light.wagoIn() - - # No light level, choose default - if light_motor.get_value() == 0: - zoom_level = int(zoom.get_value()) - light_level = None - - try: - light_level = zoom["positions"][0][zoom_level].get_property( - "lightLevel" - ) - except IndexError: - logging.getLogger("HWR").info("Could not get default light level") - light_level = 1 - - if light_level: - light_motor.set_value(light_level) - - while light.getWagoState() != "in": - time.sleep(0.5) - - -def take_snapshots(number_of_snapshots, light, light_motor, phi, zoom, drawing): - if number_of_snapshots <= 0: - return - - centredImages = [] - - set_light_in(light, light_motor, zoom) - - for i, angle in enumerate([0] + [-90] * (number_of_snapshots - 1)): - phi.set_value_relative(angle) - logging.getLogger("HWR").info("MiniDiff: taking snapshot #%d", i + 1) - centredImages.append((phi.get_value(), str(myimage(drawing)))) - - centredImages.reverse() # snapshot order must be according to positive rotation direction - - return centredImages - class MiniDiff(HardwareObject): MANUAL3CLICK_MODE = "Manual 3-click" @@ -410,14 +329,6 @@ def zoom(self): """ return self.zoomMotor - def save_snapshot(self, filename): - set_light_in(self.lightWago, self.lightMotor, self.zoomMotor) - img = myimage(self._drawing) - img.save(filename) - - def set_light_in(self): - set_light_in(self.lightWago, self.lightMotor, self.zoomMotor) - def set_sample_info(self, sample_info): self.currentSampleInfo = sample_info @@ -1024,7 +935,7 @@ def move_motors(self, roles_positions_dict): ): time.sleep(0.1) - def new_take_snapshot(self, image_path_list: list) -> None: + def take_snapshot(self, image_path_list: list) -> None: if self.get_current_phase() != "Centring": use_custom_snapshot_routine = self.get_property( "custom_snapshot_script_dir", False @@ -1041,26 +952,6 @@ def new_take_snapshot(self, image_path_list: list) -> None: HWR.beamline.sample_view.save_snapshot(path=image_path) self.phiMotor.set_value_relative(90, timeout=5) - def take_snapshots(self, image_count, wait=False): - HWR.beamline.sample_view.camera.forceUpdate = True - - snapshotsProcedure = gevent.spawn( - take_snapshots, - image_count, - self.lightWago, - self.lightMotor, - self.phiMotor, - self.zoomMotor, - self._drawing, - ) - self.emit("centringSnapshots", (None,)) - self.emitProgressMessage("Taking snapshots") - self.centringStatus["images"] = [] - snapshotsProcedure.link(self.snapshotsDone) - - if wait: - self.centringStatus["images"] = snapshotsProcedure.get() - def snapshotsDone(self, snapshotsProcedure): HWR.beamline.sample_view.camera.forceUpdate = False diff --git a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py index 5403402380..7ed49d7de8 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py @@ -252,10 +252,6 @@ def set_fast_characterisation(self, value: bool): def generate_image_jpeg(self, filename, jpeg_path, jpeg_thumbnail_path): pass - @task - def take_crystal_snapshots(self, number_of_snapshots): - HWR.beamline.diffractometer.take_snapshots(number_of_snapshots, wait=True) - def get_sample_info_from_parameters(self, parameters): """Returns sample_id, sample_location and sample_code from data collection parameters""" sample_info = parameters.get("sample_reference") @@ -318,7 +314,7 @@ def adxv_notify(self, image_filename: str, image_num: int = 1): else: pass - def new_take_snapshots(self, dc_params): + def take_snapshots(self, dc_params): snapshot_directory = dc_params["fileinfo"]["archive_directory"] if HWR.beamline.diffractometer.in_plate_mode(): @@ -346,20 +342,7 @@ def new_take_snapshots(self, dc_params): snapshot_filename ) - HWR.beamline.diffractometer.new_take_snapshot(image_path_list) - - def _take_crystal_snapshots(self, number_of_snapshots): - try: - if isinstance(number_of_snapshots, bool): - # backward compatibility, if number_of_snapshots is True|False - if number_of_snapshots: - return self.take_crystal_snapshots(4) - else: - return - if number_of_snapshots: - return self.take_crystal_snapshots(number_of_snapshots) - except Exception: - logging.getLogger("HWR").exception("Could not take crystal snapshots") + HWR.beamline.diffractometer.take_snapshot(image_path_list) @abc.abstractmethod def set_helical(self, helical_on): @@ -597,8 +580,7 @@ def do_collect(self, owner, data_collect_parameters): logging.getLogger("user_level_log").info( f"Taking sample ({self.number_of_snapshots}) snapshosts" ) - # self._take_crystal_snapshots(take_snapshots) - self.new_take_snapshots(data_collect_parameters) + self.take_snapshots(data_collect_parameters) centring_info = HWR.beamline.diffractometer.get_centring_status() # move *again* motors, since taking snapshots may change positions logging.getLogger("user_level_log").info( diff --git a/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py b/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py index feb1a52302..09a79be803 100644 --- a/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MultiCollectMockup.py @@ -104,10 +104,6 @@ def loop(self, owner, data_collect_parameters_list): logging.getLogger("HWR").info("data collection successful in loop") self.emit("collectReady", (True,)) - @task - def take_crystal_snapshots(self, number_of_snapshots): - self.bl_control.diffractometer.take_snapshots(number_of_snapshots, wait=True) - @task def data_collection_hook(self, data_collect_parameters): return From 3315598fa163faf989223399196285533fc8eb4d Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Tue, 22 Oct 2024 17:25:56 +0200 Subject: [PATCH 100/172] fix isort and docstring style --- mxcubecore/HardwareObjects/GenericDiffractometer.py | 5 +++-- mxcubecore/HardwareObjects/SampleView.py | 5 +++-- mxcubecore/HardwareObjects/TangoLimaVideo.py | 2 -- mxcubecore/HardwareObjects/abstract/AbstractSampleView.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/GenericDiffractometer.py b/mxcubecore/HardwareObjects/GenericDiffractometer.py index 1de9aa0f4b..4b88d1891b 100755 --- a/mxcubecore/HardwareObjects/GenericDiffractometer.py +++ b/mxcubecore/HardwareObjects/GenericDiffractometer.py @@ -793,9 +793,10 @@ def get_motors(self): def get_snapshot(self): """ - Get sample_view snapshot + Get snapshot from sample view - :returns: bytes object of current camera image + Returns: + bytes: A bytes object of the current camera image. """ if HWR.beamline.sample_view: return HWR.beamline.sample_view.get_snapshot() diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index 27343efd2e..b6202dd1fc 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -20,12 +20,13 @@ __copyright__ = """2019 by the MXCuBE collaboration """ __license__ = "LGPLv3+" +import base64 import copy from functools import reduce -from PIL import Image from io import BytesIO -import base64 + import numpy as np +from PIL import Image from mxcubecore import HardwareRepository as HWR from mxcubecore.HardwareObjects.abstract.AbstractSampleView import AbstractSampleView diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 0cac1648f8..10bc45fd90 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -21,8 +21,6 @@ import gevent import PyTango from PIL import Image -import io - from PyTango.gevent import DeviceProxy from mxcubecore import BaseHardwareObjects diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py index b42d5d9b81..69d972740a 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py @@ -24,9 +24,9 @@ __license__ = "LGPLv3+" import abc +from typing import Union from mxcubecore.BaseHardwareObjects import HardwareObject -from typing import Union class AbstractSampleView(HardwareObject): From 3ca58e802f436c03eedc34d760cddef60895dd3f Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 23 Oct 2024 10:02:16 +0000 Subject: [PATCH 101/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7f24fd67c8..fbea392c8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.168.0" +version = "1.169.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From d519336729c6596207a03036beb145cc1fe5160d Mon Sep 17 00:00:00 2001 From: Olof Svensson Date: Mon, 27 May 2024 16:06:27 +0200 Subject: [PATCH 102/172] [WF] - Fix for issue #689 : decrease length of autprocessing directory name --- .../HardwareObjects/ESRF/ESRFMultiCollect.py | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py index 9bd98f36e8..e1fa0da575 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFMultiCollect.py @@ -320,28 +320,26 @@ def reset_detector(self): def prepare_input_files( self, files_directory, prefix, run_number, process_directory ): - i = 1 - while True: - xds_input_file_dirname = "xds_%s_run%s_%d" % (prefix, run_number, i) - autoprocessing_input_file_dirname = "autoprocessing_%s_run%s_%d" % ( - prefix, - run_number, - i, - ) + autoprocessing_input_file_dirname = "autoprocessing" + autoprocessing_directory = os.path.join( + process_directory, autoprocessing_input_file_dirname + ) + xds_input_file_dirname = "xds_%s_run%s" % (prefix, run_number,) + mosflm_input_file_dirname = "mosflm_%s_run%s" % (prefix, run_number) + hkl2000_dirname = "hkl2000_%s_run%s" % (prefix, run_number) + + i = 1 + while os.path.exists(autoprocessing_directory): + autoprocessing_input_file_dirname = "autoprocessing_%d" % i autoprocessing_directory = os.path.join( process_directory, autoprocessing_input_file_dirname ) - - if not os.path.exists(autoprocessing_directory): - break - + xds_input_file_dirname = "xds_%s_run%s_%d" % (prefix, run_number, i) + mosflm_input_file_dirname = "mosflm_%s_run%s_%d" % (prefix, run_number, i) + hkl2000_dirname = "hkl2000_%s_run%s_%d" % (prefix, run_number, i) i += 1 - mosflm_input_file_dirname = "mosflm_%s_run%s_%d" % (prefix, run_number, i) - - hkl2000_dirname = "hkl2000_%s_run%s_%d" % (prefix, run_number, i) - self.raw_data_input_file_dir = os.path.join( files_directory, "process", xds_input_file_dirname ) From 3834cac344469d599eb8d7f8fe4a743662b9bf7c Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 25 Oct 2024 09:25:13 +0200 Subject: [PATCH 103/172] [WF] - Issue #687: Fix of typo --- mxcubecore/model/queue_model_objects.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 8ec6cf721f..b111c2ae42 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -488,6 +488,7 @@ def set_from_dict(self, p): self.free_pin_mode = p.get("freePinMode", False) self.loc_str = p.get("locStr", "") self.diffraction_plan = p.get("diffractionPlan") + self.name = p.get("sampleName", self.name) self.crystals[0].space_group = p.get("spaceGroup") or p.get( "crystalSpaceGroup", "" @@ -2688,6 +2689,7 @@ def to_collect_dict(data_collection, session, sample, centred_pos=None): data_collection.experiment_type ], "skip_images": acq_params.skip_existing_images, + "position_name": centred_pos.get_index(), "motors": centred_pos.as_dict() if centred_pos is not None else {}, "ispyb_group_data_collections": data_collection.ispyb_group_data_collections, } From ad25c1fa6be9d3f874aeb4b57fd8a1b845dba15a Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 21 Aug 2024 09:56:10 +0200 Subject: [PATCH 104/172] [WF] - Changed hardcoded host --- mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py index 942b45aa41..eb988b226c 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py @@ -50,7 +50,7 @@ def execute(self): logging.getLogger("HWR").debug("Executes SmallXrayCentring workflow") workflow_name = "SmallXrayCentring" - bes_host = "mxbes2-1707" + bes_host = "mxbes3-2204" bes_port = 38180 task_group_node_id = self._data_collection_group._node_id dict_parameters = json.loads(json.dumps(HWR.beamline.workflow.dict_parameters)) From 41d1330123ca03599e1094bea9018a54919976dc Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 25 Oct 2024 09:32:08 +0200 Subject: [PATCH 105/172] [WF] - Issue #697 : Refactoring of paramaters passed by workflows used by ICAT LIMS --- mxcubecore/model/queue_model_objects.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index b111c2ae42..536bbd9d7c 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -619,6 +619,7 @@ def __init__( self.workflow_id = None self.center_before_collect = False self.ispyb_group_data_collections = False + self.workflow_params = {} @staticmethod def set_processing_methods(processing_methods): @@ -2692,6 +2693,7 @@ def to_collect_dict(data_collection, session, sample, centred_pos=None): "position_name": centred_pos.get_index(), "motors": centred_pos.as_dict() if centred_pos is not None else {}, "ispyb_group_data_collections": data_collection.ispyb_group_data_collections, + "workflow_params": data_collection.workflow_params } ] From b7ff84d61e73db0ce7ca2d59e2fbcadf9b3cde49 Mon Sep 17 00:00:00 2001 From: Olof Svensson Date: Fri, 13 Sep 2024 15:42:43 +0200 Subject: [PATCH 106/172] [WF] - Issue #697: Added some documentation of workflow_params --- mxcubecore/model/queue_model_objects.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 536bbd9d7c..1eabe82b54 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -619,6 +619,8 @@ def __init__( self.workflow_id = None self.center_before_collect = False self.ispyb_group_data_collections = False + # The 'workflow_params' attribute is used for passing parameters + # from the automation workflows (BES) to ispyb-DRAC (see ICATLIMS.py) self.workflow_params = {} @staticmethod From 7e962df3e7a7d59624f2e2a9160861674cbfcd83 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 25 Oct 2024 09:36:55 +0200 Subject: [PATCH 107/172] [WF] - Changes from tests on MASSIF 1 on 2024/09/27 - tests of GPhL workflows --- .../ESRF/ESRFSmallXrayCentring.py | 3 + .../HardwareObjects/Gphl/GphlWorkflow.py | 75 +++++++++++-------- mxcubecore/model/queue_model_objects.py | 24 ++++-- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py index eb988b226c..99d71cfeea 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSmallXrayCentring.py @@ -57,6 +57,9 @@ def execute(self): dict_parameters["sample_node_id"] = task_group_node_id dict_parameters["end_workflow_in_mxcube"] = False dict_parameters["workflow_id"] = HWR.beamline.xml_rpc_server.workflow_id + dict_parameters["workflow_parameters"] = ( + self._queue_entry.get_data_model().get_workflow_parameters() + ) logging.getLogger("HWR").info("Starting workflow {0}".format(workflow_name)) logging.getLogger("HWR").info( "Starting a workflow on http://%s:%d/BES" % (bes_host, bes_port) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 9a5d91f301..2e4aa599f7 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -1621,7 +1621,6 @@ def setup_data_collection(self, payload, correlation_id): ) self._latest_translation_id = translation.id_ self._recentrings.append(translation) - goniostatTranslations.append(translation) # Update current position current_okp = tuple( current_pos_dict[role] for role in self.rotation_axis_roles @@ -1665,19 +1664,16 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = sweepSetting.id_ - goniostatTranslations.append(translation) else: if recentring_mode == "none": if has_recentring_file: - # If we have recentring use it - # If not, never mind, presumably we have MiniKappaCorrescion + # NB if no recentring but MiniKappaCorrection this still OK translation = GphlMessages.GoniostatTranslation( rotation=sweepSetting, **translation_settings ) - goniostatTranslations.append(translation) - self._latest_translation_id = None + self._latest_translation_id = None else: if has_recentring_file: settings.update(translation_settings) @@ -1701,7 +1697,9 @@ def setup_data_collection(self, payload, correlation_id): rotation_settings = dict( (role, current_pos_dict[role]) for role in sweepSetting.axisSettings ) - orientation_id = gphl_workflow_model.workflow_params.get("orientation_id") + orientation_id = gphl_workflow_model.workflow_parameters.get( + "orientation_id" + ) if orientation_id: # We have a pre-existing orientation ID. Use it rotation_settings["id_"] = orientation_id @@ -1718,7 +1716,7 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = newRotation.id_ - goniostatTranslations.append(translation) + goniostatTranslations.append(translation) # calculate or determine centring for remaining sweeps for sweepSetting in sweepSettings[1:]: @@ -1963,7 +1961,13 @@ def collect_data(self, payload, correlation_id): ) acq.path_template = path_template filename_params = scan.filenameParams - subdir = filename_params.get("subdir") + subdir = filename_params.get("subdir") or "" + prefix = filename_params.get("prefix", "") + head, prefix = os.path.split(prefix) + if head and subdir: + subdir = os.path.join(subdir, head) + else: + subdir = subdir or head if subdir: path_template.directory = os.path.join(path_template.directory, subdir) path_template.process_directory = os.path.join( @@ -1973,7 +1977,6 @@ def collect_data(self, payload, correlation_id): path_template.run_number = int(ss0) if ss0 else 1 path_template.start_num = acq_parameters.first_image path_template.num_files = acq_parameters.num_images - prefix = filename_params.get("prefix", "") if path_template.suffix.endswith("h5"): # Add scan number to prefix for interleaved hdf5 files (only) # NBNB Tempoary fix, pending solution to hdf5 interleaving problem @@ -1991,6 +1994,31 @@ def collect_data(self, payload, correlation_id): # Handle orientations and (re) centring goniostatRotation = sweep.goniostatSweepSetting rotation_id = orientation_id = goniostatRotation.id_ + + model_workflow_parameters = gphl_workflow_model.workflow_parameters + if not model_workflow_parameters.get("workflow_name"): + model_workflow_parameters["workflow_name"] = gphl_workflow_model.wfname + if not model_workflow_parameters.get("workflow_type"): + model_workflow_parameters["workflow_type"] = gphl_workflow_model.wftype + if not model_workflow_parameters.get("workflow_uid"): + model_workflow_parameters["workflow_uid"] = str( + HWR.beamline.gphl_connection._enactment_id + ) + if not model_workflow_parameters.get("workflow_position_id"): + # As of 20240911 all workflows use a single position, + model_workflow_parameters["workflow_position_id"] = str(uuid.uuid1()) + if ( + gphl_workflow_model.wftype == "acquisition" + and not gphl_workflow_model.characterisation_done + and not model_workflow_parameters.get("workflow_characterisation_id") + ): + model_workflow_parameters["workflow_characterisation_id"] = str( + sweep.id_ + ) + model_workflow_parameters["workflow_kappa_settings_id"] = str( + orientation_id + ) + initial_settings = sweep.get_initial_settings() orientation = ( initial_settings.get("kappa"), @@ -2054,28 +2082,9 @@ def collect_data(self, payload, correlation_id): data_collection = queue_model_objects.DataCollection([acq], crystal) # Workflow parameters for ICAT / external workflow # The 'if' statement is to allow this to work in multiple versions - if hasattr(data_collection, "workflow_params"): - wfp = gphl_workflow_model.workflow_params - if not wfp.get("workflow_name"): - wfp["workflow_name"] = gphl_workflow_model.wfname - if not wfp.get("workflow_type"): - wfp["workflow_type"] = gphl_workflow_model.wftype - if not wfp.get("workflow_uid"): - wfp["workflow_uid"] = HWR.beamline.gphl_connection._enactment_id - if not wfp.get("position_id"): - # As of 20240911 all workflows use a single position, - wfp["position_id"] = str(uuid.uuid1()) - if ( - gphl_workflow_model.wftype == "acquisition" - and not gphl_workflow_model.characterisation_done - and not wfp.get("characterisation_id") - ): - wfp["characterisation_id"] = sweep.id_ - wfp["orientation_id"] = orientation_id - data_collection.workflow_params.update(wfp) - + if hasattr(data_collection, "workflow_parameters"): + data_collection.workflow_parameters.update(model_workflow_parameters) data_collections.append(data_collection) - data_collection.set_enabled(True) data_collection.ispyb_group_data_collections = True data_collection.set_name(path_template.get_prefix()) @@ -2147,6 +2156,10 @@ def select_lattice(self, payload, correlation_id): bravais_lattice, choose_lattice.priorCrystalClasses ) + if space_group == "None": + space_group = None + # Should not happen + # 20240926 Rasmus and Olof if space_group: xtlc = crystal_symmetry.SPACEGROUP_MAP[space_group].crystal_class if ( diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 1eabe82b54..952c68fbd3 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -619,9 +619,9 @@ def __init__( self.workflow_id = None self.center_before_collect = False self.ispyb_group_data_collections = False - # The 'workflow_params' attribute is used for passing parameters + # The 'workflow_parameters' attribute is used for passing parameters # from the automation workflows (BES) to ispyb-DRAC (see ICATLIMS.py) - self.workflow_params = {} + self.workflow_parameters = {} @staticmethod def set_processing_methods(processing_methods): @@ -1274,7 +1274,9 @@ class XrayCentring2(TaskNode): (transmission, grid step, ...) """ - def __init__(self, name=None, motor_positions=None, grid_size=None): + def __init__( + self, name=None, motor_positions=None, grid_size=None, workflow_parameters=None + ): """ :param name: (str) Task name - for queue display. Default to std. name @@ -1285,6 +1287,7 @@ def __init__(self, name=None, motor_positions=None, grid_size=None): self._centring_result = None self._motor_positions = motor_positions.copy() if motor_positions else {} self._grid_size = tuple(grid_size) if grid_size else None + self._workflow_parameters = workflow_parameters if workflow_parameters else {} # I do nto now if you need a path template; if not remove this # and the access to it in init_from_task_data @@ -1320,6 +1323,9 @@ def set_centring_result(self, value): " or None, was a %s" % value.__class__.__name__ ) + def get_workflow_parameters(self): + return self._workflow_parameters + def init_from_task_data(self, sample_model, params): """Set parameters from task input dictionary. @@ -2028,7 +2034,7 @@ def __init__(self): self.strategy_length = 0.0 # Workflow attributes - for passing to LIMS (conf Olof Svensson) - self.workflow_params = {} + self.workflow_parameters = {} # # Centring handling and MXCuBE-side flow self.set_requires_centring(False) @@ -2128,6 +2134,10 @@ def set_pre_strategy_params( # noqa: C901 self.space_group = space_group else: space_group = self.space_group + if space_group == "None": + # Temporray fix - this should not happen + # 20240926 Rasmus Fogh and Olof Svensson + space_group = None if crystal_classes: self.crystal_classes = tuple(crystal_classes) elif space_group: @@ -2340,9 +2350,9 @@ def init_from_task_data(self, sample_model, params): setattr(self, tag, value) # For external workflow parameters (conf. Olof Svensson) - dd1 = params.get("workflow_params") + dd1 = params.get("workflow_parameters") if dd1: - self.workflow_params.update(dd1) + self.workflow_parameters.update(dd1) settings = HWR.beamline.gphl_workflow.settings # NB settings is an internal attribute DO NOT MODIFY @@ -2695,7 +2705,7 @@ def to_collect_dict(data_collection, session, sample, centred_pos=None): "position_name": centred_pos.get_index(), "motors": centred_pos.as_dict() if centred_pos is not None else {}, "ispyb_group_data_collections": data_collection.ispyb_group_data_collections, - "workflow_params": data_collection.workflow_params + "workflow_parameters": data_collection.workflow_parameters, } ] From f27f4cc268db9d040ab16ec2b20459ad49a5c1de Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 25 Oct 2024 12:05:55 +0000 Subject: [PATCH 108/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fbea392c8c..74794c21e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.169.0" +version = "1.170.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From f07af1ff7fb22404a3868d2fccf70c0c2fcaf90d Mon Sep 17 00:00:00 2001 From: rhfogh Date: Fri, 25 Oct 2024 13:14:48 +0100 Subject: [PATCH 109/172] Aded final fix for bu gin centring-mode 'none' --- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 2e4aa599f7..636e08ddfa 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -1621,6 +1621,7 @@ def setup_data_collection(self, payload, correlation_id): ) self._latest_translation_id = translation.id_ self._recentrings.append(translation) + goniostatTranslations.append(translation) # Update current position current_okp = tuple( current_pos_dict[role] for role in self.rotation_axis_roles @@ -1664,6 +1665,7 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = sweepSetting.id_ + goniostatTranslations.append(translation) else: @@ -1673,7 +1675,8 @@ def setup_data_collection(self, payload, correlation_id): translation = GphlMessages.GoniostatTranslation( rotation=sweepSetting, **translation_settings ) - self._latest_translation_id = None + goniostatTranslations.append(translation) + self._latest_translation_id = None else: if has_recentring_file: settings.update(translation_settings) @@ -1716,7 +1719,7 @@ def setup_data_collection(self, payload, correlation_id): self._latest_translation_id = translation.id_ self._recentrings.append(translation) gphl_workflow_model.current_rotation_id = newRotation.id_ - goniostatTranslations.append(translation) + goniostatTranslations.append(translation) # calculate or determine centring for remaining sweeps for sweepSetting in sweepSettings[1:]: From aee14c38a92a392573339050c390a9cb7ecf49a1 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 25 Oct 2024 13:18:18 +0000 Subject: [PATCH 110/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 74794c21e9..ceb19dfe91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.170.0" +version = "1.171.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 6282315d02be5ca2f27b46285f32214510bf45ce Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Fri, 25 Oct 2024 13:31:09 +0200 Subject: [PATCH 111/172] set correct return type --- mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py index a6a64c6b6e..a7d1b02004 100644 --- a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py @@ -39,7 +39,7 @@ def is_running(self): return def dc_from_output(self, edna_result, reference_image_collection): - return + return [] def get_default_characterisation_parameters(self): return super( From c891f184b8eec89a130aa8266c7d585bbaa93228 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Fri, 25 Oct 2024 16:07:46 +0200 Subject: [PATCH 112/172] Use type hints --- .../HardwareObjects/EDNACharacterisation.py | 60 +++++++++---------- .../mockup/EDNACharacterisationMockup.py | 26 +++++--- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/mxcubecore/HardwareObjects/EDNACharacterisation.py b/mxcubecore/HardwareObjects/EDNACharacterisation.py index 37661239f4..1f91f57c3c 100644 --- a/mxcubecore/HardwareObjects/EDNACharacterisation.py +++ b/mxcubecore/HardwareObjects/EDNACharacterisation.py @@ -4,12 +4,19 @@ import os import subprocess import time +from typing import List -from XSDataCommon import ( +from mxcubecore import HardwareRepository as HWR +from mxcubecore.HardwareObjects.abstract.AbstractCharacterisation import ( + AbstractCharacterisation, +) +from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( + SecureXMLRpcRequestHandler, +) +from mxcubecore.HardwareObjects.XSDataCommon import ( XSDataAngle, XSDataBoolean, XSDataDouble, - XSDataFile, XSDataFlux, XSDataImage, XSDataInteger, @@ -19,19 +26,11 @@ XSDataTime, XSDataWavelength, ) -from XSDataMXCuBEv1_4 import ( +from mxcubecore.HardwareObjects.XSDataMXCuBEv1_4 import ( XSDataInputMXCuBE, XSDataMXCuBEDataSet, XSDataResultMXCuBE, ) - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects.abstract.AbstractCharacterisation import ( - AbstractCharacterisation, -) -from mxcubecore.HardwareObjects.SecureXMLRpcRequestHandler import ( - SecureXMLRpcRequestHandler, -) from mxcubecore.model import queue_model_enumerables as qme from mxcubecore.model import queue_model_objects as qmo @@ -40,7 +39,7 @@ class EDNACharacterisation(AbstractCharacterisation): - def __init__(self, name): + def __init__(self, name) -> None: super(EDNACharacterisation, self).__init__(name) self.collect_obj = None @@ -48,7 +47,7 @@ def __init__(self, name): self.edna_default_file = None self.start_edna_command = None - def init(self): + def init(self) -> None: self.collect_obj = self.get_object_by_role("collect") self.start_edna_command = self.get_property("edna_command") self.edna_default_file = self.get_property("edna_default_file") @@ -64,7 +63,7 @@ def init(self): with open(fp, "r") as f: self.edna_default_input = "".join(f.readlines()) - def _modify_strategy_option(self, diff_plan, strategy_option): + def _modify_strategy_option(self, diff_plan, strategy_option) -> None: """Method for modifying the diffraction plan 'strategyOption' entry""" if diff_plan.getStrategyOption() is None: new_strategy_option = strategy_option @@ -75,7 +74,9 @@ def _modify_strategy_option(self, diff_plan, strategy_option): diff_plan.setStrategyOption(XSDataString(new_strategy_option)) - def _run_edna(self, input_file, results_file, process_directory): + def _run_edna( + self, input_file, results_file, process_directory + ) -> XSDataResultMXCuBE: """Starts EDNA""" msg = "Starting EDNA characterisation using xml file %s" % input_file logging.getLogger("queue_exec").info(msg) @@ -112,14 +113,12 @@ def _run_edna(self, input_file, results_file, process_directory): return self.result - def get_html_report(self, edna_result): + def get_html_report(self, edna_result) -> str: """ + Returns the path to the html result report generated by the characterisation software. + Args: output (EDNAResult) EDNAResult object - - Returns: - (str) The path to the html result report generated by the characterisation - software """ html_report = None @@ -130,7 +129,7 @@ def get_html_report(self, edna_result): return html_report - def input_from_params(self, data_collection, char_params): + def input_from_params(self, data_collection, char_params) -> XSDataInputMXCuBE: edna_input = XSDataInputMXCuBE.parseString(self.edna_default_input) if data_collection.id: @@ -273,13 +272,12 @@ def input_from_params(self, data_collection, char_params): edna_input.process_directory = characterisation_dir return edna_input - def characterise(self, edna_input): + def characterise(self, edna_input) -> str: """ + Runs Characterisation and returns the results. + Args: input (EDNAInput) EDNA input object - - Returns: - (str) The Characterisation result """ self.processing_done_event.set() self.prepare_input(edna_input) @@ -312,7 +310,9 @@ def characterise(self, edna_input): self.processing_done_event.clear() return self.result - def dc_from_output(self, edna_result, reference_image_collection): + def dc_from_output( + self, edna_result, reference_image_collection + ) -> List[qmo.DataCollection]: data_collections = [] crystal = copy.deepcopy(reference_image_collection.crystal) @@ -451,11 +451,9 @@ def dc_from_output(self, edna_result, reference_image_collection): return data_collections - def get_default_characterisation_parameters(self): + def get_default_characterisation_parameters(self) -> qmo.CharacterisationParameters: """ - Returns: - (queue_model_objects.CharacterisationsParameters) object with default - parameters. + Returns the default parameters """ edna_input = XSDataInputMXCuBE.parseString(self.edna_default_input) diff_plan = edna_input.getDiffractionPlan() @@ -515,7 +513,7 @@ def get_default_characterisation_parameters(self): return char_params - def generate_new_token(self): + def generate_new_token(self) -> str: # See: https://wyattbaldwin.com/2014/01/09/generating-random-tokens-in-python/ token = binascii.hexlify(os.urandom(5)).decode("utf-8") SecureXMLRpcRequestHandler.setReferenceToken(token) diff --git a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py index a7d1b02004..9c44b50a9e 100644 --- a/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py +++ b/mxcubecore/HardwareObjects/mockup/EDNACharacterisationMockup.py @@ -17,31 +17,39 @@ # You should have received a copy of the GNU General Lesser Public License # along with MXCuBE. If not, see . +from typing import List + from mxcubecore.HardwareObjects import edna_test_data from mxcubecore.HardwareObjects.EDNACharacterisation import EDNACharacterisation -from mxcubecore.HardwareObjects.XSDataMXCuBEv1_3 import XSDataResultMXCuBE +from mxcubecore.HardwareObjects.XSDataMXCuBEv1_4 import ( + XSDataInputMXCuBE, + XSDataResultMXCuBE, +) +from mxcubecore.model import queue_model_objects as qmo __credits__ = ["MXCuBE collaboration"] __license__ = "LGPLv3" class EDNACharacterisationMockup(EDNACharacterisation): - def __init__(self, name): + def __init__(self, name) -> None: super(EDNACharacterisationMockup, self).__init__(name) - def input_from_params(self, data_collection, char_params): - return + def input_from_params(self, data_collection, char_params) -> XSDataInputMXCuBE: + return XSDataInputMXCuBE.parseString(self.edna_default_input) - def characterise(self, edna_input): + def characterise(self, edna_input) -> XSDataResultMXCuBE: return XSDataResultMXCuBE.parseString(edna_test_data.EDNA_RESULT_DATA) - def is_running(self): - return + def is_running(self) -> bool: + return False - def dc_from_output(self, edna_result, reference_image_collection): + def dc_from_output( + self, edna_result, reference_image_collection + ) -> List[qmo.DataCollection]: return [] - def get_default_characterisation_parameters(self): + def get_default_characterisation_parameters(self) -> qmo.CharacterisationParameters: return super( EDNACharacterisationMockup, self ).get_default_characterisation_parameters() From e8e1ba17fccad92503827a8e20bf125f4459e413 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 28 Oct 2024 08:00:38 +0000 Subject: [PATCH 113/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ceb19dfe91..80e823b269 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.171.0" +version = "1.172.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From cb742731c8669149bc5741681f006bf1d0d58823 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 24 Oct 2024 16:18:35 +0200 Subject: [PATCH 114/172] [Queue] - Simplified mount_sample and related logic --- mxcubecore/HardwareObjects/EMBLFlexHCD.py | 17 ----- mxcubecore/HardwareObjects/FlexHCD.py | 17 ----- .../HardwareObjects/GrobSampleChanger.py | 9 ++- .../HardwareObjects/PlateManipulator.py | 22 +++--- mxcubecore/HardwareObjects/QueueManager.py | 2 + mxcubecore/HardwareObjects/Robodiff.py | 16 ---- .../abstract/AbstractSampleChanger.py | 24 ++++++ .../mockup/PlateManipulatorMockup.py | 20 +++-- .../mockup/SampleChangerMockup.py | 3 - mxcubecore/model/queue_model_enumerables.py | 4 +- mxcubecore/queue_entry/base_queue_entry.py | 76 ++++++------------- 11 files changed, 82 insertions(+), 128 deletions(-) diff --git a/mxcubecore/HardwareObjects/EMBLFlexHCD.py b/mxcubecore/HardwareObjects/EMBLFlexHCD.py index 8c0ec13933..88c227038d 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHCD.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHCD.py @@ -355,23 +355,6 @@ def _do_select(self, component): self._update_selection() - @task - def load_sample( - self, - holderLength, - sample_id=None, - sample_location=None, - sampleIsLoadedCallback=None, - failureCallback=None, - prepareCentring=True, - ): - # self._assert_ready() - cell, basket, sample = sample_location - sample = self.get_component_by_address( - Pin.get_sample_address(cell, basket, sample) - ) - return self.load(sample) - def chained_load(self, old_sample, sample): return self._do_load(sample) diff --git a/mxcubecore/HardwareObjects/FlexHCD.py b/mxcubecore/HardwareObjects/FlexHCD.py index 02bd018030..d9292d7583 100644 --- a/mxcubecore/HardwareObjects/FlexHCD.py +++ b/mxcubecore/HardwareObjects/FlexHCD.py @@ -286,23 +286,6 @@ def _do_select(self, component): self._update_selection() - @task - def load_sample( - self, - holderLength, - sample_id=None, - sample_location=None, - sampleIsLoadedCallback=None, - failureCallback=None, - prepareCentring=True, - ): - self._assert_ready() - cell, basket, sample = sample_location - sample = self.get_component_by_address( - Pin.get_sample_address(cell, basket, sample) - ) - return self.load(sample) - def chained_load(self, old_sample, sample): self._assert_ready() if self.exporter_addr: diff --git a/mxcubecore/HardwareObjects/GrobSampleChanger.py b/mxcubecore/HardwareObjects/GrobSampleChanger.py index 3f2cee4a97..2d38028106 100644 --- a/mxcubecore/HardwareObjects/GrobSampleChanger.py +++ b/mxcubecore/HardwareObjects/GrobSampleChanger.py @@ -153,23 +153,24 @@ def unload_mounted_sample( self._sample_transfer_done ) - def load_sample( + def load( self, - holderLength, + sample=None, sample_id=None, - sample_location=None, + holderLength=None, successCallback=None, failureCallback=None, prepareCentring=None, prepareCentringMotors={}, prepare_centring=None, prepare_centring_motors=None, + wait=True, ): self._successCallback = successCallback self._failureCallback = failureCallback self._holderlength = holderLength self._sample_id = sample_id - self._sample_location = sample_location + self._sample_location = sample if self._get_loaded_sampleNum(): self._procedure = "UNLOAD_LOAD" diff --git a/mxcubecore/HardwareObjects/PlateManipulator.py b/mxcubecore/HardwareObjects/PlateManipulator.py index 8637d9a54e..ca8d930ab5 100644 --- a/mxcubecore/HardwareObjects/PlateManipulator.py +++ b/mxcubecore/HardwareObjects/PlateManipulator.py @@ -86,13 +86,13 @@ def get_drop(self): def get_cell(self): return self.get_drop().get_cell() - + def get_basket_no(self): """ In this cas we assume a drop is a basket or puck """ return self.get_drop().get_index() + 1 - + def get_cell_no(self): """ In this cas we assume wells in the row is a cell @@ -249,7 +249,7 @@ def init(self): self.num_rows = self.get_property("numRows") self.num_drops = self.get_property("numDrops") - self.reference_pos_x = self.get_property("referencePosX") + self.reference_pos_x = self.get_property("referencePosX") if not self.reference_pos_x: self.reference_pos_x = 0.5 @@ -295,13 +295,13 @@ def change_plate_barcode(self, barcode): return True else: raise Exception("barcode unknown") - + def hw_get_loaded_sample_location(self): loaded_sample = None if(self.chan_drop_location): loaded_sample = self.chan_drop_location.get_value() - + return ( chr(65 + loaded_sample[0]) + str(loaded_sample[1] +1) @@ -398,13 +398,13 @@ def _do_load(self, sample=None): def load(self, sample=None, wait=True): comp = self._resolve_component(sample) coords = comp.get_coords() - res = self.load_sample(coords) + res = self._load_sample(coords) if res: self._set_loaded_sample(comp) comp._set_loaded(True, True) return res - def load_sample(self, sample_location=None, pos_x=None, pos_y=None, wait=True): + def _load_sample(self, sample_location=None, pos_x=None, pos_y=None, wait=True): """ Location is estimated by sample location and reference positions. """ @@ -448,7 +448,7 @@ def load_sample(self, sample_location=None, pos_x=None, pos_y=None, wait=True): return True except: - return False + return False def _do_unload(self, sample_slot=None): """ @@ -474,7 +474,7 @@ def _do_scan(self, component, recursive): if self.get_token() is None: raise Exception("No plate barcode defined") self._load_data(self.get_token()) - + def sync_with_crims(self): """ Descript. : @@ -677,7 +677,7 @@ def get_plate_location(self): def move_to_crystal_position(self, crystal_uuid): """ Descript. : Move Diff to crystal position - Get crystal_uuid from processing plan for loaded sample/drop + Get crystal_uuid from processing plan for loaded sample/drop """ ret = None if crystal_uuid in ["undefined", None]: @@ -691,7 +691,7 @@ def move_to_crystal_position(self, crystal_uuid): if (row == ord(x.row) - 65 and col == x.column -1 and drop == x.shelf -1): crystal_uuid = x.crystal_uuid else : raise Exception("No processing_plan OR Crystal Found in this well") - + if self.cmd_move_to_crystal_position and crystal_uuid: try: diff --git a/mxcubecore/HardwareObjects/QueueManager.py b/mxcubecore/HardwareObjects/QueueManager.py index c7a4481602..b5818d142d 100644 --- a/mxcubecore/HardwareObjects/QueueManager.py +++ b/mxcubecore/HardwareObjects/QueueManager.py @@ -15,6 +15,7 @@ from mxcubecore import queue_entry from mxcubecore.BaseHardwareObjects import HardwareObject +from mxcubecore.model.queue_model_enumerables import CENTRING_METHOD from mxcubecore.queue_entry import base_queue_entry from mxcubecore.queue_entry.base_queue_entry import QUEUE_ENTRY_STATUS @@ -25,6 +26,7 @@ class QueueManager(HardwareObject, QueueEntryContainer): def __init__(self, name): HardwareObject.__init__(self, name) QueueEntryContainer.__init__(self) + self.centring_method = CENTRING_METHOD.NONE self._root_task = None self._paused_event = gevent.event.Event() self._paused_event.set() diff --git a/mxcubecore/HardwareObjects/Robodiff.py b/mxcubecore/HardwareObjects/Robodiff.py index 034ceb11a8..59e8deda91 100644 --- a/mxcubecore/HardwareObjects/Robodiff.py +++ b/mxcubecore/HardwareObjects/Robodiff.py @@ -195,22 +195,6 @@ def _do_select(self, component): self.dw.waitEndOfMove() self._update_selection() - @task - def load_sample( - self, - holderLength, - sample_id=None, - sample_location=None, - sampleIsLoadedCallback=None, - failureCallback=None, - prepareCentring=True, - ): - cell, basket, sample = sample_location - sample = self.get_component_by_address( - Pin.get_sample_address(cell, basket, sample) - ) - return self.load(sample) - @task def unload_sample( self, diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py index 7a7a66bf64..6dae0ea524 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleChanger.py @@ -102,6 +102,7 @@ SampleChanger.LOADED_SAMPLE_CHANGED_EVENT SampleChanger.SELECTION_CHANGED_EVENT SampleChanger.TASK_FINISHED_EVENT +SampleChanger.PROGRESS_MESSAGE Tools for SC Classes ---------------------- @@ -211,6 +212,7 @@ class SampleChanger(Container, HardwareObject): SELECTION_CHANGED_EVENT = "selectionChanged" TASK_FINISHED_EVENT = "taskFinished" CONTENTS_UPDATED_EVENT = "contentsUpdated" + PROGRESS_MESSAGE = "progress_message" def __init__(self, type_, scannable, *args, **kwargs): super().__init__(type_, None, type_, scannable) @@ -219,6 +221,7 @@ def __init__(self, type_, scannable, *args, **kwargs): HardwareObject.__init__(self, *args, **kwargs) self.state = -1 self.status = "" + self._progress_message = "" self._set_state(SampleChangerState.Unknown) self.task = None self.task_proc = None @@ -311,6 +314,24 @@ def get_status(self): """ return self.status + @property + def progress_message(self) -> str: + """ + Returns: + Current progress message + """ + self._progress_message + + def set_progress_message(self, message: str) -> None: + """ + Set progress message describing the current sample changer activity. + + Args: + message: string describing current sample changer activity. + """ + self._progress_message = message + self._trigger_progress_message(message) + def get_task_error(self): """ Returns: @@ -826,6 +847,9 @@ def _set_selected_component(self, component): Container._set_selected_component(self, component) self._trigger_selection_changed_event() + def trigger_progress_message(self, message: str): + self.emit(self.PROGRESS_MESSAGE, (message,)) + # ######################## PRIVATE ######################### def _trigger_state_changed_event(self, former): diff --git a/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py b/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py index 7ad392450b..f018dd5ab0 100644 --- a/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py +++ b/mxcubecore/HardwareObjects/mockup/PlateManipulatorMockup.py @@ -95,7 +95,7 @@ def get_basket_no(self): In this cas we assume a drop is a basket or puck """ return self.get_drop().get_index() + 1 - + def get_cell_no(self): """ In this cas we assume a well in the row is a cell @@ -247,10 +247,10 @@ def init(self): AbstractSampleChanger.SampleChanger.init(self) self.update_state(self.STATES.READY) - + def _read_state(self): return 'ready' - + def _ready(self): return True @@ -328,12 +328,20 @@ def _do_load(self, sample=None): self._do_select(sample) self._set_loaded_sample(sample) - def load_sample(self, sample_location=None): + def load(self, sample=None, wait=True): + comp = self._resolve_component(sample) + coords = comp.get_coords() + res = self._load_sample(coords) + if res: + self._set_loaded_sample(comp) + comp._set_loaded(True, True) + return res + + def _load_sample(self, sample_location=None): """ Descript. : function to move to plate location. Location is estimated by sample location and reference positions. """ - row = sample_location[0] - 1 col = (sample_location[1] - 1) / self.num_drops drop = sample_location[1] - self.num_drops * col @@ -549,7 +557,7 @@ def get_plate_info(self): plate_info_dict["num_drops"] = self.num_drops plate_info_dict["plate_label"] = self.plate_label or "Demo plate label" plate_info_dict["plate_barcode"] = self.plate_barcode or "" - + return plate_info_dict def get_plate_location(self): diff --git a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py index 4a2dab91b3..032ce07b38 100644 --- a/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py +++ b/mxcubecore/HardwareObjects/mockup/SampleChangerMockup.py @@ -42,9 +42,6 @@ def init(self): def get_log_filename(self): return self.log_filename - def load_sample(self, holder_length, sample_location=None, wait=False): - self.load(sample_location, wait) - def load(self, sample, wait=False): self.emit("fsmConditionChanged", "sample_mounting_sample_changer", True) previous_sample = self.get_loaded_sample() diff --git a/mxcubecore/model/queue_model_enumerables.py b/mxcubecore/model/queue_model_enumerables.py index ee8c2e8204..262b4d803a 100644 --- a/mxcubecore/model/queue_model_enumerables.py +++ b/mxcubecore/model/queue_model_enumerables.py @@ -70,9 +70,9 @@ EDNA_NUM_REF_IMAGES = EDNARefImages(0, 1, 2, 3) CentringMethod = namedtuple( - "CentringMethod", ["MANUAL", "LOOP", "FULLY_AUTOMATIC", "XRAY"] + "CentringMethod", ["MANUAL", "LOOP", "FULLY_AUTOMATIC", "XRAY", "NONE"] ) -CENTRING_METHOD = CentringMethod(0, 1, 2, 3) +CENTRING_METHOD = CentringMethod(0, 1, 2, 3, 4) WorkflowType = namedtuple( "WorkflowType", ["BURN", "WF1", "WF2", "LineScan", "MeshScan", "XrayCentring"] diff --git a/mxcubecore/queue_entry/base_queue_entry.py b/mxcubecore/queue_entry/base_queue_entry.py index c6ecf25330..ed74328190 100644 --- a/mxcubecore/queue_entry/base_queue_entry.py +++ b/mxcubecore/queue_entry/base_queue_entry.py @@ -675,7 +675,6 @@ def execute(self): self.sample_centring_result = gevent.event.AsyncResult() try: mount_sample( - self._view, self._data_model, self.centring_done, self.sample_centring_result, @@ -766,16 +765,12 @@ def __init__(self, view=None, data_model=None): BaseQueueEntry.__init__(self, view, data_model) -def mount_sample(view, data_model, centring_done_cb, async_result): - view.setText(1, "Loading sample") +def mount_sample(data_model, centring_done_cb, async_result): + HWR.beamline.sample_changer.trigger_progress_message("Loading sample") HWR.beamline.sample_view.clear_all() - log = logging.getLogger("queue_exec") + log = logging.getLogger("user_level_log") loc = data_model.location - holder_length = data_model.holder_length - - snapshot_before_filename = "/tmp/test_before.png" - snapshot_after_filename = "/tmp/test_after.png" robot_action_dict = { "actionType": "LOAD", @@ -786,34 +781,13 @@ def mount_sample(view, data_model, centring_done_cb, async_result): "sessionId": HWR.beamline.session.session_id, "startTime": time.strftime("%Y-%m-%d %H:%M:%S"), } - # "xtalSnapshotBefore": data_model.get_snapshot_filename(prefix="before"), - # "xtalSnapshotAfter": data_model.get_snapshot_filename(prefix="after")} - sample_mount_device = HWR.beamline.sample_changer - - if hasattr(sample_mount_device, "__TYPE__"): - if sample_mount_device.__TYPE__ in ["Marvin", "CATS"]: - element = "%d:%02d" % tuple(loc) - sample_mount_device.load(sample=element, wait=True) - elif sample_mount_device.__TYPE__ == "PlateManipulator": - sample_mount_device.load_sample(sample_location=loc) - else: - if ( - sample_mount_device.load_sample( - holder_length, sample_location=loc, wait=True - ) - is False - ): - # WARNING: explicit test of False return value. - # This is to preserve backward compatibility (load_sample was supposed to return None); - # if sample could not be loaded, but no exception is raised, let's skip - # the sample - raise QueueSkipEntryException( - "Sample changer could not load sample", "" - ) + if not HWR.beamline.sample_changer.load(sample=data_model.loc_str, wait=True): + raise QueueSkipEntryException("Sample changer could not load sample", "") robot_action_dict["endTime"] = time.strftime("%Y-%m-%d %H:%M:%S") - if sample_mount_device.has_loaded_sample(): + + if HWR.beamline.sample_changer.has_loaded_sample(): robot_action_dict["status"] = "SUCCESS" else: robot_action_dict["message"] = "Sample was not loaded" @@ -821,25 +795,18 @@ def mount_sample(view, data_model, centring_done_cb, async_result): HWR.beamline.lims.store_robot_action(robot_action_dict) - if not sample_mount_device.has_loaded_sample(): - # Disables all related collections - view.setOn(False) - view.setText(1, "Sample not loaded") + if not HWR.beamline.sample_changer.has_loaded_sample(): + HWR.beamline.sample_changer.trigger_progress_message("Sample not loaded") raise QueueSkipEntryException("Sample not loaded", "") else: - view.setText(1, "Sample loaded") + HWR.beamline.sample_changer.trigger_progress_message("Sample loaded") dm = HWR.beamline.diffractometer - if dm is not None: - if hasattr(sample_mount_device, "__TYPE__"): - if sample_mount_device.__TYPE__ in ( - "Marvin", - "PlateManipulator", - "Mockup", - ): - return + centring_method = HWR.beamline.queue_manager.centring_method + + if centring_method != CENTRING_METHOD.NONE: try: dm.connect("centringAccepted", centring_done_cb) - centring_method = view.listView().parent().parent().centring_method + if centring_method == CENTRING_METHOD.MANUAL: log.warning( "Manual centring used, waiting for" + " user to center sample" @@ -857,21 +824,26 @@ def mount_sample(view, data_model, centring_done_cb, async_result): else: dm.start_centring_method(dm.MANUAL3CLICK_MODE) - view.setText(1, "Centring !") + HWR.beamline.sample_changer.trigger_progress_message("Centring !") centring_result = async_result.get() + if centring_result["valid"]: - view.setText(1, "Centring done !") + HWR.beamline.sample_changer.trigger_progress_message( + "Centring done !" + ) log.info("Centring saved") else: - view.setText(1, "Centring failed !") + HWR.beamline.sample_changer.trigger_progress_message( + "Centring failed !" + ) if centring_method == CENTRING_METHOD.FULLY_AUTOMATIC: raise QueueSkipEntryException( "Could not center sample, skipping", "" ) else: raise RuntimeError("Could not center sample") - except Exception as ex: - log.exception("Could not center sample: " + str(ex)) + except Exception: + logging.getLogger("HWR").exception("") finally: dm.disconnect("centringAccepted", centring_done_cb) From 33610e810ffdebbe743a9e91597dc2cecb5d6d30 Mon Sep 17 00:00:00 2001 From: FLorial Jean Baptiste Date: Mon, 28 Oct 2024 16:47:35 +0100 Subject: [PATCH 115/172] [Harvester] Added logic that were removed from mxcubeweb queue_harvest_sample , queue_harvest_next_sample , start_harvester_centring --- .../HardwareObjects/EMBLFlexHarvester.py | 102 ++++++++++++++++++ mxcubecore/HardwareObjects/Harvester.py | 32 ++---- 2 files changed, 108 insertions(+), 26 deletions(-) diff --git a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py index 6bb6cd8262..aaa24a8ca9 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py @@ -25,12 +25,17 @@ lid231flex1:9001 """ +from __future__ import annotations + import logging import time import gevent +from mxcubecore import HardwareRepository as HWR +from mxcubecore import queue_entry from mxcubecore.HardwareObjects.EMBLFlexHCD import EMBLFlexHCD +from mxcubecore.model import queue_model_objects as qmo from mxcubecore.TaskUtils import task @@ -138,10 +143,47 @@ def load_a_pin_for_calibration(self): except Exception: return False + def start_harvester_centring(self): + try: + dm = HWR.beamline.diffractometer + + logging.getLogger("user_level_log").info("Start Auto Harvesting Centring") + + computed_offset = HWR.beamline.harvester.get_offsets_for_sample_centering() + dm.start_harvester_centring(computed_offset) + + except Exception: + logging.getLogger("user_level_log").exception( + "Could not center sample, skipping" + ) + raise queue_entry.QueueSkipEntryException( + "Could not center sample, skipping", "" + ) + + def _set_loaded_sample_and_prepare(self, loaded_sample_tup, previous_sample_tup): + res = False + + loaded_sample = self.get_sample_with_address(loaded_sample_tup) + + if -1 not in loaded_sample_tup and loaded_sample_tup != previous_sample_tup: + self._set_loaded_sample(loaded_sample) + self._prepare_centring_task() + res = True + + if res: + if self._harvester_hwo.get_room_temperature_mode(): + self.queue_harvest_next_sample(loaded_sample.get_address()) + + # in this case we expect CENTRING_METHOD=None + self.start_harvester_centring() + + return res + def _do_load(self, sample=None): """ Load a Sample from Harvester """ + self.queue_harvest_sample(sample.get_address()) self._update_state() # We wait for the sample changer if its already doing something, like defreezing @@ -219,3 +261,63 @@ def harvest_and_mount_sample(self, xtal_uuid: str, sampleID: str) -> bool: except Exception: logging.getLogger("user_level_log").exception("Could not Harvest Crystal") return "Could not Harvest Crystal" + + def queue_list(self) -> list[str]: + """ + builds a List representation of the queue based. + """ + + node = HWR.beamline.queue_model.get_model_root() + + result = [] + + if isinstance(node, list): + node_list = node + else: + node_list = node.get_children() + + for node in node_list: + if isinstance(node, qmo.Sample): + result.append(node.loc_str) + + return result + + def get_sample_uuid(self, sampleID: str) -> str: + samples_list = self.get_sample_list() + sample_uuid = None + for s in samples_list: + if s.get_address() == sampleID or s.get_id() == sampleID: + sample_uuid = s.get_id() + return sample_uuid + + def queue_harvest_sample(self, sample_loc_str) -> None: + """ + While queue execution send harvest request + """ + current_queue = self.queue_list() + + sample_uuid = self.get_sample_uuid(sample_loc_str) + + self._harvester_hwo.queue_harvest_sample( + sample_loc_str, sample_uuid, current_queue + ) + + def queue_harvest_next_sample(self, sample_loc_str) -> None: + """ + While queue execution send harvest request + on next sample of the queue list + """ + + current_queue_list = self.queue_list() + + next_sample = None + try: + next_sample = current_queue_list[ + current_queue_list.index(sample_loc_str) + 1 + ] + except (ValueError, IndexError): + next_sample = None + + sample_uuid = self.get_sample_uuid(next_sample) + + self._harvester_hwo.queue_harvest_next_sample(next_sample, sample_uuid) diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index a16e4204ac..34d29a4d4d 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -164,7 +164,6 @@ def _execute_cmd_exporter(self, cmd, *args, **kwargs): return : respond """ ret = None - timeout = kwargs.pop("timeout", 0) if args: args_str = "%s" % "\t".join(map(str, args)) if kwargs.pop("command", None): @@ -512,29 +511,25 @@ def get_number_of_available_pin(self) -> int: return self._execute_cmd_exporter("getNbRemainingPins", command=True) def queue_harvest_sample( - self, data_model, sample_uuid: str, current_queue: dict + self, sample_loc_str, sample_uuid: str, current_queue_list: list[str] ) -> None: """ While queue execution send harvest request - current_queue : a build representation of the queue based on - python dictionaries + current_queue_list : a build representation of the queue based """ - current_queue_list = list(current_queue) current_queue_index = None try: - current_queue_index = current_queue_list.index(data_model.loc_str) + current_queue_index = current_queue_list.index(sample_loc_str) except (ValueError, IndexError): current_queue_index = None wait_before_load = not self.get_room_temperature_mode() - if sample_uuid in ["undefined", "", None]: - sample_uuid = current_queue[data_model.loc_str]["code"] if self.get_number_of_available_pin() > 0: gevent.sleep(2) - if current_queue_index == 1: + if current_queue_index == 0: logging.getLogger("user_level_log").info("Harvesting First Sample") harvest_res = self.harvest_sample_before_mount( @@ -577,28 +572,13 @@ def queue_harvest_sample( "There is no more Pins in the Harvester, Stopping queue", "" ) - def queue_harvest_next_sample( - self, data_model, sample_uuid: str, current_queue: dict - ): + def queue_harvest_next_sample(self, next_sample_loc_str: str, sample_uuid: str): """ While queue execution send harvest request on next sample of the queue list - current_queue : a build representation of the queue based on - python dictionaries """ - current_queue_list = list(current_queue) - next_sample = None - try: - next_sample = current_queue_list[ - current_queue_list.index(data_model.loc_str) + 1 - ] - except (ValueError, IndexError): - next_sample = None - - if sample_uuid in ["undefined", "", None]: - sample_uuid = current_queue[data_model.loc_str]["code"] - if next_sample is not None and self.get_number_of_available_pin() > 0: + if next_sample_loc_str is not None and self.get_number_of_available_pin() > 0: logging.getLogger("user_level_log").info("Harvesting Next Sample") self._wait_ready(None) From ec9d14e5acfbdeb420fbaeb2984f42d46218d22d Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 29 Oct 2024 13:29:50 +0000 Subject: [PATCH 116/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 80e823b269..c87fb74755 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.172.0" +version = "1.173.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 14c6763cf974208d84c67e35cd01b9a941ca8e18 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Tue, 29 Oct 2024 16:50:00 +0100 Subject: [PATCH 117/172] set stream size to tuple of ints --- .../HardwareObjects/TangoLimaMpegVideo.py | 36 ++++++------- .../HardwareObjects/TangoLimaVideoLoopback.py | 10 ++-- .../HardwareObjects/mockup/MDCameraMockup.py | 53 ++++++++++--------- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py index 1f8191f340..8ec4eea20e 100644 --- a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py @@ -13,9 +13,9 @@ """ -import os import subprocess import uuid +from typing import List import psutil @@ -27,7 +27,7 @@ def __init__(self, name): super(TangoLimaMpegVideo, self).__init__(name) self._format = "MPEG1" self._video_stream_process = None - self._current_stream_size = "0, 0" + self._current_stream_size = (0, 0) self.stream_hash = str(uuid.uuid1()) self._quality_str = "High" self._QUALITY_STR_TO_INT = {"High": 4, "Medium": 10, "Low": 20, "Adaptive": -1} @@ -40,26 +40,26 @@ def init(self): self._mpeg_scale = self.get_property("mpeg_scale", 1) self._image_size = (self.get_width(), self.get_height()) - def get_quality(self): + def get_quality(self) -> str: return self._quality_str - def set_quality(self, q): + def set_quality(self, q) -> None: self._quality_str = q self._quality = self._QUALITY_STR_TO_INT[q] self.restart_streaming() - def set_stream_size(self, w, h): - self._current_stream_size = "%s,%s" % (int(w), int(h)) + def set_stream_size(self, w, h) -> None: + self._current_stream_size = (int(w), int(h)) - def get_stream_size(self): - current_size = self._current_stream_size.split(",") - scale = float(current_size[0]) / self.get_width() - return current_size + list((scale,)) + def get_stream_size(self) -> tuple[int, int, float]: + width, height = self._current_stream_size + scale = float(width) / self.get_width() + return (width, height, scale) - def get_quality_options(self): + def get_quality_options(self) -> List[str]: return list(self._QUALITY_STR_TO_INT.keys()) - def get_available_stream_sizes(self): + def get_available_stream_sizes(self) -> List[tuple[int, int]]: try: w, h = self.get_width(), self.get_height() video_sizes = [(w, h), (int(w / 2), int(h / 2)), (int(w / 4), int(h / 4))] @@ -68,7 +68,7 @@ def get_available_stream_sizes(self): return video_sizes - def start_video_stream_process(self, port): + def start_video_stream_process(self) -> None: if ( not self._video_stream_process or self._video_stream_process.poll() is not None @@ -85,7 +85,7 @@ def start_video_stream_process(self, port): "-q", str(self._quality), "-s", - self._current_stream_size, + ", ".join(map(str, self._current_stream_size)), "-of", self._format, "-id", @@ -97,7 +97,7 @@ def start_video_stream_process(self, port): with open("/tmp/mxcube.pid", "a") as f: f.write("%s " % self._video_stream_process.pid) - def stop_streaming(self): + def stop_streaming(self) -> None: if self._video_stream_process: try: ps = [self._video_stream_process] + psutil.Process( @@ -110,7 +110,7 @@ def stop_streaming(self): self._video_stream_process = None - def start_streaming(self, _format=None, size=(0, 0), port=None): + def start_streaming(self, _format=None, size=(0, 0), port=None) -> None: if _format: self._format = _format @@ -123,8 +123,8 @@ def start_streaming(self, _format=None, size=(0, 0), port=None): _s = size self.set_stream_size(_s[0], _s[1]) - self.start_video_stream_process(self._port) + self.start_video_stream_process() - def restart_streaming(self, size): + def restart_streaming(self, size) -> None: self.stop_streaming() self.start_streaming(self._format, size=size) diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py index 6dd85319ec..c856723403 100644 --- a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py @@ -117,7 +117,7 @@ def __init__(self, name): super(TangoLimaVideoLoopback, self).__init__(name) self._video_stream_process = None - self._current_stream_size = "-1, -1" + self._current_stream_size = -1, -1 self._original_stream_size = -1, -1 self._stream_script_path = "" self.stream_hash = str(uuid.uuid1()) @@ -191,16 +191,16 @@ def _encoder_friendly_size(self, w, h): def set_stream_size(self, w, h): w, h = self._encoder_friendly_size(w, h) - self._current_stream_size = "%s,%s" % (w, h) + self._current_stream_size = (int(w), int(h)) def _set_stream_original_size(self, w, h): w, h = self._encoder_friendly_size(w, h) self._original_stream_size = w, h def get_stream_size(self): - current_size = self._current_stream_size.split(",") - scale = float(current_size[0]) / self._original_stream_size[0] - return current_size + list((scale,)) + width, height = self._current_stream_size + scale = float(width) / self._original_stream_size[0] + return (width, height, scale) def get_available_stream_sizes(self): try: diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index 7f6fa90d0e..d46d47b972 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -3,6 +3,7 @@ import logging import subprocess import time +from typing import List import gevent import psutil @@ -30,7 +31,7 @@ def _init(self): self.image = HWR.get_hardware_repository().find_in_repository(self.image_name) self.set_is_ready(True) self._video_stream_process = None - self._current_stream_size = "0, 0" + self._current_stream_size = (0, 0) def init(self): logging.getLogger("HWR").info("initializing camera object") @@ -39,7 +40,7 @@ def init(self): self.stopper = False # self.polling_timer(self.pollInterval, self.poll) gevent.spawn(self.poll) - def udiffVersionChanged(self, value): + def udiffVersionChanged(self, value) -> None: if value == "MD2_2": print(("start polling MD camera with poll interval=", self.pollInterval)) else: @@ -48,11 +49,11 @@ def udiffVersionChanged(self, value): ) self.stopper = True - def connectToDevice(self): + def connectToDevice(self) -> bool: self.connected = True return self.connected - def poll(self): + def poll(self) -> None: logging.getLogger("HWR").info("going to poll images") while not self.stopper: time.sleep(1) @@ -62,42 +63,42 @@ def poll(self): except Exception: logging.getLogger("HWR").exception("Could not read image") - def imageUpdated(self, value): + def imageUpdated(self, value) -> None: print(" got new image") print(value) - def gammaExists(self): + def gammaExists(self) -> bool: return False - def contrastExists(self): + def contrastExists(self) -> bool: return False - def brightnessExists(self): + def brightnessExists(self) -> bool: return False - def gainExists(self): + def gainExists(self) -> bool: return False - def get_width(self): + def get_width(self) -> int: # return 768 #JN ,20140807,adapt the MD2 screen to mxCuBE2 return 659 - def get_height(self): + def get_height(self) -> int: # return 576 # JN ,20140807,adapt the MD2 screen to mxCuBE2 return 493 - def set_live(self, state): + def set_live(self, state) -> bool: self.liveState = state return True def imageType(self): return None - def get_last_image(self): + def get_last_image(self) -> tuple[bytes, int, int]: image = Image.open(self.image) return image.tobytes(), image.size[0], image.size[1] - def get_available_stream_sizes(self): + def get_available_stream_sizes(self) -> List[tuple[int, int]]: try: w, h = self.get_width(), self.get_height() video_sizes = [(w, h), (int(w / 2), int(h / 2)), (int(w / 4), int(h / 4))] @@ -106,15 +107,15 @@ def get_available_stream_sizes(self): return video_sizes - def set_stream_size(self, w, h): - self._current_stream_size = "%s,%s" % (int(w), int(h)) + def set_stream_size(self, w, h) -> None: + self._current_stream_size = (int(w), int(h)) - def get_stream_size(self): - current_size = self._current_stream_size.split(",") - scale = float(current_size[0]) / self.get_width() - return current_size + list((scale,)) + def get_stream_size(self) -> tuple[int, int, float]: + width, height = self._current_stream_size + scale = float(width) / self.get_width() + return (width, height, scale) - def start_video_stream_process(self, port): + def start_video_stream_process(self) -> None: if ( not self._video_stream_process or self._video_stream_process.poll() is not None @@ -133,14 +134,14 @@ def start_video_stream_process(self, port): "-q", "4", "-s", - self._current_stream_size, + ", ".join(map(str, self._current_stream_size)), "-id", self.stream_hash, ], close_fds=True, ) - def stop_streaming(self): + def stop_streaming(self) -> None: if self._video_stream_process: try: ps = [self._video_stream_process] + psutil.Process( @@ -153,7 +154,7 @@ def stop_streaming(self): self._video_stream_process = None - def start_streaming(self, _format="MPEG1", size=(0, 0), port="8000"): + def start_streaming(self, _format="MPEG1", size=(0, 0), port="8000") -> None: self._format = _format self._port = port @@ -163,8 +164,8 @@ def start_streaming(self, _format="MPEG1", size=(0, 0), port="8000"): _s = int(size[0]), int(size[1]) self.set_stream_size(_s[0], _s[1]) - self.start_video_stream_process(port) + self.start_video_stream_process() - def restart_streaming(self, size): + def restart_streaming(self, size) -> None: self.stop_streaming() self.start_streaming(self._format, size=size) From a8932cf699b549290e039ef7d4faa9e26136d9d6 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 29 Oct 2024 18:06:13 +0000 Subject: [PATCH 118/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c87fb74755..1363673f28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.173.0" +version = "1.174.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 46a21ebf156a3381a41bf8f573bbfc6c2a40fd5b Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 1 Jul 2024 15:28:47 +0200 Subject: [PATCH 119/172] [BlissNState] - added missing argument to _update_state --- mxcubecore/HardwareObjects/BlissNState.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/BlissNState.py b/mxcubecore/HardwareObjects/BlissNState.py index 5b31fc1f26..d3bd09af6d 100644 --- a/mxcubecore/HardwareObjects/BlissNState.py +++ b/mxcubecore/HardwareObjects/BlissNState.py @@ -76,7 +76,9 @@ def init(self): self.update_state() - def _update_state(self): + # NB: Bliss calls the update handler with the state so its needed in the + # method definition + def _update_state(self, state=None): self.update_state(self.STATES.READY) def get_value(self): From 13c521fb8a7978d997148aaae27cc6591bb74541 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 5 Jul 2024 09:47:51 +0200 Subject: [PATCH 120/172] [BLISS] - Removed depricated bliss code --- mxcubecore/HardwareObjects/Bliss.py | 71 ----------------------------- 1 file changed, 71 deletions(-) diff --git a/mxcubecore/HardwareObjects/Bliss.py b/mxcubecore/HardwareObjects/Bliss.py index a326da037a..143217abcf 100644 --- a/mxcubecore/HardwareObjects/Bliss.py +++ b/mxcubecore/HardwareObjects/Bliss.py @@ -24,70 +24,6 @@ def all_equal(iterable): return next(grp, True) and not next(grp, False) -def watch_data(scan_node, scan_new_callback, scan_data_callback, scan_end_callback): - """Watch for data coming from the bliss scans. Exclude the simple count""" - # hack to not execute it - if scan_node: - return - scan_info = scan_node._info.get_all() - if scan_info["type"] == "ct": - return - - timescan = scan_info["type"] == "timescan" - if not timescan: - del scan_info["motors"][0] - scan_info["labels"] = scan_info["motors"] + scan_info["counters"] - ndata = len(scan_info["labels"]) - del scan_info["motors"] - del scan_info["counters"] - scan_data = dict() - data_indexes = dict() - - scan_new_callback(scan_info) - - scan_data_iterator = DataNode(scan_node) - for event_type, event_data in scan_data_iterator.walk_events(filter="zerod"): - if event_type is scan_data_iterator.NEW_DATA_IN_CHANNEL_EVENT: - zerod, channel_name = event_data - if not timescan and channel_name == "timestamp": - continue - data_channel = zerod.get_channel(channel_name) - data = data_channel.get(data_indexes.setdefault(channel_name, 0), -1) - data_indexes[channel_name] += len(data) - scan_data.setdefault(channel_name, []).extend(data) - if len(scan_data) == ndata and all_equal(data_indexes.values()): - scan_data_callback(scan_info, scan_data) - if data_indexes[channel_name] == scan_info["npoints"]: - scan_end_callback(scan_info) - scan_data = dict() - - -def watch_session( - session_name, scan_new_callback, scan_data_callback, scan_end_callback -): - """Watch the bliss session for new data""" - session_node = get_or_create_node(session_name, node_type="session") - if session_node is not None: - data_iterator = DataNode("session", session_name) - - watch_data_task = None - last = True - for scan_node in data_iterator.walk_from_last(filter="scan"): - if last: - # skip the last one, we are interested in new ones only - last = False - continue - if watch_data_task: - watch_data_task.kill() - watch_data_task = gevent.spawn( - watch_data, - scan_node, - scan_new_callback, - scan_data_callback, - scan_end_callback, - ) - - class Bliss(HardwareObject): """Bliss class""" @@ -102,13 +38,6 @@ def init(self, *args): session.setup(self.__dict__, verbose=True) - # self.__session_watcher = gevent.spawn( - # watch_session, - # self.get_property("session"), - # self.__on_scan_new, - # self.__on_scan_data, - # self.__on_scan_end, - # ) self.__scan_data = dict() def __on_scan_new(self, scan_info): From 289dbfe50f3ce297d08213849158facbef05ecfc Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 29 Oct 2024 18:25:51 +0000 Subject: [PATCH 121/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1363673f28..e5dfac1fdc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.174.0" +version = "1.175.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 6471595fddec881e11eb3eaee19e4f80739d6fb7 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Tue, 2 Apr 2024 08:18:02 +0200 Subject: [PATCH 122/172] [XRF] - Path to chooch changed --- mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py | 2 +- mxcubecore/HardwareObjects/XRFSpectrum.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py index 32f8aa2803..5527145b5a 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py @@ -268,7 +268,7 @@ def do_chooch(self, elt, edge, directory, archive_directory, prefix): # while waiting fro chooch to work... subprocess.call( [ - "/opt/pxsoft/bin/chooch", + "/cvmfs/sb.esrf.fr/bin/chooch", "-e", elt, "-a", diff --git a/mxcubecore/HardwareObjects/XRFSpectrum.py b/mxcubecore/HardwareObjects/XRFSpectrum.py index fc53f3beea..6df9d614ea 100644 --- a/mxcubecore/HardwareObjects/XRFSpectrum.py +++ b/mxcubecore/HardwareObjects/XRFSpectrum.py @@ -105,7 +105,7 @@ def startXrfSpectrum( try: os.makedirs(directory) except OSError as diag: - logging.getLogger().error( + logging.getLogger("user_level_log").error( "XRFSpectrum: error creating directory %s (%s)" % (directory, str(diag)) ) From 56b7b1f8940aec884c20c537804ce0fffd787ef9 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 7 Jun 2024 13:44:28 +0200 Subject: [PATCH 123/172] [ESRF Cryo] Making sure that cryostat is initialized --- mxcubecore/HardwareObjects/ESRF/Oxford700.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/ESRF/Oxford700.py b/mxcubecore/HardwareObjects/ESRF/Oxford700.py index 0729b6aaeb..9d00536b9c 100644 --- a/mxcubecore/HardwareObjects/ESRF/Oxford700.py +++ b/mxcubecore/HardwareObjects/ESRF/Oxford700.py @@ -36,7 +36,7 @@ def init(self): controller = self.get_object_by_role("controller") cryostat = self.get_property("cryostat") self.interval = self.get_property("interval") or 10 - self.ctrl = getattr(controller, cryostat) + self.ctrl = controller.config.get(cryostat) if self.ctrl: gevent.spawn(self._do_polling) self._hw_ctrl = self.ctrl.controller._hw_controller From 19254bdb13c83b4773182122df20334779116f5e Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Thu, 18 Jul 2024 08:01:00 +0200 Subject: [PATCH 124/172] [BEAM] - beam_size handling --- mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py index 2c2cb419b6..0d912f9e07 100644 --- a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py @@ -29,7 +29,8 @@ def data_collection_hook(self, data_collect_parameters): @task def get_beam_size(self): - return HWR.beamline.beam.beam_width, HWR.beamline.beam.beam_height + _width, _height, _, _ = HWR.beamline.beam.get_value() + return _width, _height @task def get_slit_gaps(self): From 59ee4d0f3c7c3a79243cb454b2d9648881a25a72 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Tue, 27 Aug 2024 17:14:03 +0200 Subject: [PATCH 125/172] [COLLECT] Open detector cover via diffractometer --- mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py | 12 +++++++++--- mxcubecore/HardwareObjects/Microdiff.py | 8 ++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py index 0d912f9e07..67d6053a1f 100644 --- a/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py +++ b/mxcubecore/HardwareObjects/ESRF/MD2MultiCollect.py @@ -64,16 +64,22 @@ def take_crystal_snapshots(self, number_of_snapshots, image_path_list=[]): HWR.beamline.diffractometer.take_snapshot(image_path_list) def do_prepare_oscillation(self, *args, **kwargs): + diffr = HWR.beamline.diffractometer + # set the detector cover out + try: + diffr.open_detector_cover() + except Exception: + logging.getLogger("HWR").exception("Could not open detector cover") + """ try: detcover = self.get_object_by_role("controller").detcover if detcover.state == "IN": detcover.set_out(10) except: - logging.getLogger("HWR").exception("Could close detector cover") - - diffr = HWR.beamline.diffractometer + logging.getLogger("HWR").exception("Could not open detector cover") + """ # send again the command as MD2 software only handles one # centered position!! diff --git a/mxcubecore/HardwareObjects/Microdiff.py b/mxcubecore/HardwareObjects/Microdiff.py index 2d5e3d1f4c..dc030fa77b 100644 --- a/mxcubecore/HardwareObjects/Microdiff.py +++ b/mxcubecore/HardwareObjects/Microdiff.py @@ -371,21 +371,21 @@ def _wait_ready(self, timeout=None): while not self._ready(): time.sleep(0.5) - def open_detector_cover(self): + def open_detector_cover(self, timeout=10): try: detcover = self.get_object_by_role("controller").detcover if detcover.state == "IN": - detcover.set_out(10) + detcover.set_out(timeout) except AttributeError: logging.getLogger("HWR").exception("No detector cover configured") - def close_detector_cover(self): + def close_detector_cover(self, timeout=10): try: detcover = self.get_object_by_role("controller").detcover if detcover.state == "OUT": - detcover.set_in(10) + detcover.set_in(timeout) except AttributeError: logging.getLogger("HWR").exception("No detector cover configured") From 24cabbfad9e4402e861489b76dfc4f2f14e7977a Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Mon, 9 Sep 2024 14:12:54 +0200 Subject: [PATCH 126/172] [EnergyScan] - Fix call to super classes --- mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py index 5527145b5a..5c18a21556 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFEnergyScan.py @@ -84,8 +84,7 @@ def _readParamsFromFile(self, config_file): class ESRFEnergyScan(AbstractEnergyScan, HardwareObject): def __init__(self, name, tunable_bl): - AbstractEnergyScan.__init__(self) - HardwareObject.__init__(self, name) + super().__init__(name) self._tunable_bl = tunable_bl def execute_command(self, command_name, *args, **kwargs): From c66270dc45a5837eafd937a0627cbbf72b4f9267 Mon Sep 17 00:00:00 2001 From: Antonia Beteva Date: Fri, 25 Oct 2024 10:00:33 +0200 Subject: [PATCH 127/172] Remove obsolete file - replaced by OxfordCryostream.py --- mxcubecore/HardwareObjects/ESRF/Oxford700.py | 100 ------------------- 1 file changed, 100 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/ESRF/Oxford700.py diff --git a/mxcubecore/HardwareObjects/ESRF/Oxford700.py b/mxcubecore/HardwareObjects/ESRF/Oxford700.py deleted file mode 100644 index 9d00536b9c..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/Oxford700.py +++ /dev/null @@ -1,100 +0,0 @@ -import sys - -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractActuator import AbstractActuator - -CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] -PHASE_ACTION = { - "RAMP": "ramp", - "COOL": "cool", - "HOLD": "hold", - "PLAT": "plat", - "PURGE": "purge", - "END": "end", -} - - -class Oxford700(AbstractActuator): - def __init__(self, name): - super().__init__(name) - - self.temp = None - self.temp_error = None - - def _do_polling(self): - while True: - try: - self.value_changed() - except Exception: - sys.excepthook(*sys.exc_info()) - gevent.sleep(self.interval) - - def init(self): - controller = self.get_object_by_role("controller") - cryostat = self.get_property("cryostat") - self.interval = self.get_property("interval") or 10 - self.ctrl = controller.config.get(cryostat) - if self.ctrl: - gevent.spawn(self._do_polling) - self._hw_ctrl = self.ctrl.controller._hw_controller - - def value_changed(self): - self.emit("temperatureChanged", (self.get_value(),)) - self.emit("valueChanged", (self.get_value(),)) - self.emit("stateChanged", (self.get_state(),)) - - def get_temperature(self): - try: - return self.ctrl.input.read() - except: - # try to read again - temp = self.ctrl.input.read() - if temp is None: - return 9999. - return temp - - def get_value(self): - return self.get_temperature() - - def rampstate(self): - return self.ctrl.is_ramping() - - def start_action(self, phase="RAMP", target=None, rate=None): - if phase in PHASE_ACTION: - action = getattr(self._hw_ctrl, PHASE_ACTION[phase]) - if rate: - action(target, rate=rate) - elif target: - action(target) - else: - action() - - def stop_action(self, phase="HOLD"): - if phase in PHASE_ACTION: - getattr(self._hw_ctrl, PHASE_ACTION[phase]) - - def pause(self, execute=True): - if execute: - self._hw_ctrl.pause() - else: - self._hw_ctrl.resume() - - def get_specific_state(self): - try: - return self._hw_ctrl.read_run_mode().upper() - except (AttributeError, TypeError): - return "UNKNOWN" - - def get_static_parameters(self): - return ["oxford", "K", "hour"] - - def get_params(self): - run_mode = self._hw_ctrl.read_run_mode() - target = self.ctrl.setpoint - rate = self.ctrl.ramprate - phase = self._hw_ctrl.read_phase() - self.temp = self.ctrl.input.read() - return [target, rate, phase.upper(), run_mode] From 502456e1c5e4e4a2291719454c0ae3b1c02cf3ea Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 9 Feb 2024 15:58:43 +0100 Subject: [PATCH 128/172] [ESRF HO] - Starting run number counting at 1 --- mxcubecore/HardwareObjects/ESRF/ESRFSession.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFSession.py b/mxcubecore/HardwareObjects/ESRF/ESRFSession.py index d0fedaae7a..75416e0a98 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFSession.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFSession.py @@ -54,7 +54,7 @@ def get_full_path(self, subdir: str, tag: str) -> Tuple[str, str]: # Use the same sequnce numbering for all tags/types, (We are not # creating individual run number per tag) full_path = os.path.join( - self.get_base_image_directory(), subdir, f"run_{run_num:02d}/" + self.get_base_image_directory(), subdir, f"run_{run_num:02d}_{tag}/" ) # Check collects in queue not yet collected From 7db7eb461473cf218f466a861c2e1687643f8f2a Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Fri, 9 Feb 2024 15:58:44 +0100 Subject: [PATCH 129/172] [MCA] - MCA API change --- mxcubecore/HardwareObjects/XRFSpectrum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/XRFSpectrum.py b/mxcubecore/HardwareObjects/XRFSpectrum.py index 6df9d614ea..9a1e5dd825 100644 --- a/mxcubecore/HardwareObjects/XRFSpectrum.py +++ b/mxcubecore/HardwareObjects/XRFSpectrum.py @@ -224,9 +224,9 @@ def spectrumCommandFinished(self, result): self.scanning = False if result is not False: fname = self.spectrumInfo["filename"].replace(".dat", ".raw") - self.mca_hwobj.set_presets(fname=str(fname)) - mcaData = self.mca_hwobj.read_data(save_data=True) - mcaCalib = self.mca_hwobj.get_calibration() + self.mca_hwobj.datafile = str(fname) + mcaData = self.mca_hwobj.read_roi_data(save_data=True) + mcaCalib = self.mca_hwobj.calibration mcaConfig = {} self.spectrumInfo["beamTransmission"] = ( HWR.beamline.transmission.get_value() From 66381f00572554514c2557c1d770e4ec57f77702 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 29 Oct 2024 18:40:23 +0000 Subject: [PATCH 130/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e5dfac1fdc..a8fd6c4cd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.175.0" +version = "1.176.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 53921b0f6d5d112e5b7f88c01c397fbb0f03db82 Mon Sep 17 00:00:00 2001 From: fabcor Date: Tue, 29 Oct 2024 11:33:28 +0100 Subject: [PATCH 131/172] Clarify contribution guidelines for units --- CONTRIBUTING.md | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 93768f44fd..6e52eebbae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -111,22 +111,33 @@ The exact routine is described more preceisly in [MEP01](https://github.com/mxcu ### Coding convention and style guidelines #### Units -Functions returning a value representing a physical quantity should in general be assoicated with -a unit. It has been agreed that the following units should, where applicable, be used across the -code base - - * mm (millimeter) for translative motors and sizes - * degrees for rotative motors - * perecent (%) for ratios like attenuation - * keV for energy - * K (Kelvin) for temperature - * Å (Ångström) for resolution - * Pixels are to be used for beam location (center) - * Datetime YYYY-MM-DD HH:MM:SS(.ff) ,possibly with hundreds of seconds (ff), and with 24 hour clock. +Units must be documented via docstrings +for the parameters and return values of functions and methods, +for variables, +and for attributes of classes and objects. + +The units of variables within a function or method must be documented as well. +For example, with simple comments or by including the unit in the variable name itself. When writing code that converts between different units, -it is recommended to use utility functions from {py:mod}`mxcubecore.utils.units` module. -This will to aid in the readability of the code. +it is possible to use utility functions from {py:mod}`mxcubecore.utils.units` module, +which will make the unit conversion explicit. + +Furthermore, it has been agreed that, whenever possible, +the following units must be used across the code base: + +* mm (millimetre) for translational motors and sizes +* degree for rotational motors +* percentage (%) for ratios like attenuation +* keV for energy +* K (Kelvin) for temperature +* Å (Ångström) for resolution +* pixel for beam location (centre) +* YYYY-MM-DD HH:MM:SS(.ff) for date and time, + possibly with hundreds of seconds (ff), and with 24-hour clock. + +Even if the code uses those units, they must be documented. + #### Value update signals/callbacks The "valueChanged" and "stateChanged" signals should be used when a HardwareObjects value or state From 529f9ef15f2aa52be9b85d5d3299c14da8e6f3fd Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 30 Oct 2024 09:20:27 +0000 Subject: [PATCH 132/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a8fd6c4cd6..32f982f9c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.176.0" +version = "1.177.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From d549face4e6008dfc98cc2b1599fb6b2bb3dca35 Mon Sep 17 00:00:00 2001 From: dominikatrojanowska <154609837+dominikatrojanowska@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:21:10 +0100 Subject: [PATCH 133/172] Refactoring ISPyBClientMockup for authnentication tests (#1066) Refactor ISPyBClientMockup for authentication tests --- mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py b/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py index 6ba8f22b3c..8724a1b428 100644 --- a/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py +++ b/mxcubecore/HardwareObjects/mockup/ISPyBClientMockup.py @@ -95,9 +95,12 @@ def get_login_type(self): def login(self, login_id, psd, ldap_connection=None, create_session=True): # to simulate wrong loginID - if login_id != "idtest0": + if login_id not in ("idtest0", "idtest1"): return { - "status": {"code": "error", "msg": "loginID 'wrong' does not exist!"}, + "status": { + "code": "error", + "msg": f"loginID '{login_id}' does not exist!", + }, "Proposal": None, "Session": None, } @@ -108,7 +111,7 @@ def login(self, login_id, psd, ldap_connection=None, create_session=True): "Proposal": None, "Session": None, } - # to simulate ispybDown, but login succeed + # to simulate ispybDown, but login succeed if psd == "ispybDown": return { "status": {"code": "ispybDown", "msg": "ispyb is down"}, From 705091281e9acf6f3fb552c56e8da9d83d0906cb Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Thu, 31 Oct 2024 13:21:39 +0000 Subject: [PATCH 134/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 32f982f9c6..6d722f12b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.177.0" +version = "1.178.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From d084dd0e53dc30845df2fa9262d35312d40eae3f Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 14 May 2024 13:26:31 +0200 Subject: [PATCH 135/172] [CenteredPoint] - Using position name instead of id for index --- mxcubecore/HardwareObjects/SampleView.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index b6202dd1fc..696acba559 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -547,7 +547,7 @@ def mpos(self): def set_id(self, id_num): Shape.set_id(self, id_num) - self.cp_list[0].index = self.id + self.cp_list[0].index = self.name def as_dict(self): d = Shape.as_dict(self) @@ -576,6 +576,9 @@ def __init__(self, mpos_list, screen_coord): self.label = "Line" self.set_id(Line.SHAPE_COUNT) + def set_id(self, id_num): + Shape.set_id(self, id_num) + def get_centred_positions(self): return [self.start_cpos, self.end_cpos] @@ -644,7 +647,6 @@ def get_num_lines(self): def set_id(self, id_num): Shape.set_id(self, id_num) - self.cp_list[0].index = self.id def set_result(self, result_data): self.result = result_data @@ -661,7 +663,6 @@ def as_dict(self): beam_pos = HWR.beamline.beam.get_beam_position_on_screen() size_x, size_y, shape, _label = HWR.beamline.beam.get_value() - # MXCuBE - 2 WF compatability d["x1"] = -float((beam_pos[0] - d["screen_coord"][0]) / pixels_per_mm[0]) d["y1"] = -float((beam_pos[1] - d["screen_coord"][1]) / pixels_per_mm[1]) d["steps_x"] = d["num_cols"] From 21a99e1a4b157bf864506c4aa31d4bd56f7b294c Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 4 Nov 2024 08:15:47 +0000 Subject: [PATCH 136/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6d722f12b2..46652e8f4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.178.0" +version = "1.179.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From d0776d77456dddb49d7fb645467daebf7c98ae06 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 17 Jun 2024 07:56:31 +0200 Subject: [PATCH 137/172] [SampleView] - Use complete name with the "A" --- mxcubecore/HardwareObjects/MicrodiffAperture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/MicrodiffAperture.py b/mxcubecore/HardwareObjects/MicrodiffAperture.py index 03ddcda36e..e7d97d105d 100644 --- a/mxcubecore/HardwareObjects/MicrodiffAperture.py +++ b/mxcubecore/HardwareObjects/MicrodiffAperture.py @@ -168,6 +168,6 @@ def get_diameter_size_list(self): _nam = value.name if _nam not in ["IN", "OUT", "UNKNOWN"]: - values.append(_nam[1:]) + values.append(_nam) return values From 162817a11bc4f08315b59acabdd8fd4d1c427fc2 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 4 Nov 2024 08:51:59 +0000 Subject: [PATCH 138/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 46652e8f4a..7a93ec3208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.179.0" +version = "1.180.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From ae4459aaad0d35de5e48fc06f1bab13afd3530ae Mon Sep 17 00:00:00 2001 From: rhfogh Date: Thu, 31 Oct 2024 18:24:13 +0000 Subject: [PATCH 139/172] Added configurable log output for external programs from GPhL WF --- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 5 ++++- mxcubecore/configuration/esrf_id30a2/gphl-workflow.yml | 4 ++++ mxcubecore/configuration/mockup/gphl/gphl-workflow.yml | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index 636e08ddfa..e15cae8b5b 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -847,7 +847,10 @@ def execute(self): message_type, ) break - elif message_type != "String": + elif message_type == "String": + if not self.settings.get("suppress_external_log_output"): + func(payload, correlation_id) + else: logging.getLogger("HWR").info( "GΦL queue processing %s", message_type ) diff --git a/mxcubecore/configuration/esrf_id30a2/gphl-workflow.yml b/mxcubecore/configuration/esrf_id30a2/gphl-workflow.yml index 465b973fe0..016443874b 100644 --- a/mxcubecore/configuration/esrf_id30a2/gphl-workflow.yml +++ b/mxcubecore/configuration/esrf_id30a2/gphl-workflow.yml @@ -46,6 +46,10 @@ settings: starting_beamline_energy: current default_beam_energy_tag: Main + # Suppress log output of programs called from GPhL workflow + # Default to False + suppress_external_log_output: false + defaults: # Default values for queue_model_objects.GphlWorkflow attributes diff --git a/mxcubecore/configuration/mockup/gphl/gphl-workflow.yml b/mxcubecore/configuration/mockup/gphl/gphl-workflow.yml index 435219b757..31f085ce9f 100644 --- a/mxcubecore/configuration/mockup/gphl/gphl-workflow.yml +++ b/mxcubecore/configuration/mockup/gphl/gphl-workflow.yml @@ -44,6 +44,10 @@ settings: # NB Temporary developer option. Defaults to 1 allow_duplicate_orientations: 0 + # Suppress log output of programs called from GPhL workflow + # Default to False + suppress_external_log_output: false + # TEST ONLY developer option. Use preset SPOT.XDS file and skip characterisation. # Only works for GPhL test samples with SPOT.XDS file # NB to get sensible results you should use the default values for resolution and From 3748ef5c2d3f9a58dfcaac84c7ae0917fc2e65e5 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 4 Nov 2024 09:02:02 +0000 Subject: [PATCH 140/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a93ec3208..46036fc4b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.180.0" +version = "1.181.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 3ced46b96bf36f076dd5d518978d93229d0bd9e9 Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Fri, 1 Nov 2024 14:01:30 +0100 Subject: [PATCH 141/172] queue models: handle omitted 'centred_pos' argument In the utility function to_collect_dict(), take into the account that 'centred_pos' argument can be omitted. Don't call centred_pos.get_index() if 'centred_pos' is omitted or is None. --- mxcubecore/model/queue_model_objects.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mxcubecore/model/queue_model_objects.py b/mxcubecore/model/queue_model_objects.py index 952c68fbd3..5368701233 100644 --- a/mxcubecore/model/queue_model_objects.py +++ b/mxcubecore/model/queue_model_objects.py @@ -2702,7 +2702,9 @@ def to_collect_dict(data_collection, session, sample, centred_pos=None): data_collection.experiment_type ], "skip_images": acq_params.skip_existing_images, - "position_name": centred_pos.get_index(), + "position_name": ( + centred_pos.get_index() if centred_pos is not None else None + ), "motors": centred_pos.as_dict() if centred_pos is not None else {}, "ispyb_group_data_collections": data_collection.ispyb_group_data_collections, "workflow_parameters": data_collection.workflow_parameters, From e83cb5cc9e9c030bf54333aed5e8f8a7591482b5 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 4 Nov 2024 10:34:54 +0000 Subject: [PATCH 142/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 46036fc4b0..70416269b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.181.0" +version = "1.182.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 136d1bf3f7a102d29c43227215344a1646d39c68 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 11:37:00 +0100 Subject: [PATCH 143/172] Use types from typing for Type Hints --- mxcubecore/HardwareObjects/EMBLFlexHarvester.py | 10 +++++++--- mxcubecore/HardwareObjects/Harvester.py | 13 ++++++++----- mxcubecore/HardwareObjects/TangoLimaMpegVideo.py | 9 ++++++--- mxcubecore/HardwareObjects/mockup/MDCameraMockup.py | 11 +++++++---- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py index aaa24a8ca9..c15784e4ab 100644 --- a/mxcubecore/HardwareObjects/EMBLFlexHarvester.py +++ b/mxcubecore/HardwareObjects/EMBLFlexHarvester.py @@ -29,6 +29,10 @@ import logging import time +from typing import ( + Any, + List, +) import gevent @@ -69,7 +73,7 @@ def set_room_temperature_mode(self, value): def mount_from_harvester(self): return True - def get_sample_list(self) -> list: + def get_sample_list(self) -> List[Any]: """ Get Sample List related to the Harvester content/processing Plan """ @@ -262,7 +266,7 @@ def harvest_and_mount_sample(self, xtal_uuid: str, sampleID: str) -> bool: logging.getLogger("user_level_log").exception("Could not Harvest Crystal") return "Could not Harvest Crystal" - def queue_list(self) -> list[str]: + def queue_list(self) -> List[str]: """ builds a List representation of the queue based. """ @@ -271,7 +275,7 @@ def queue_list(self) -> list[str]: result = [] - if isinstance(node, list): + if isinstance(node, List): node_list = node else: node_list = node.get_children() diff --git a/mxcubecore/HardwareObjects/Harvester.py b/mxcubecore/HardwareObjects/Harvester.py index 34d29a4d4d..52786bc774 100644 --- a/mxcubecore/HardwareObjects/Harvester.py +++ b/mxcubecore/HardwareObjects/Harvester.py @@ -43,7 +43,10 @@ from __future__ import annotations import logging -from typing import Optional +from typing import ( + List, + Optional, +) import gevent @@ -235,7 +238,7 @@ def _ready_to_transfer(self) -> bool: == "Waiting Sample Transfer" ) - def get_samples_state(self) -> list[str]: + def get_samples_state(self) -> List[str]: """Get the Harvester Samples State Return (List): list of crystal state "waiting_for_transfer, Running etc.." @@ -301,7 +304,7 @@ def check_crystal_state(self, crystal_uuid: str) -> Optional[str]: else: return None - def get_crystal_uuids(self) -> list[str]: + def get_crystal_uuids(self) -> List[str]: """Get the Harvester Sample List uuid Return (List): list of crystal by uuid from the current processing plan" @@ -311,7 +314,7 @@ def get_crystal_uuids(self) -> list[str]: ) return harvester_crystal_list - def get_sample_names(self) -> list[str]: + def get_sample_names(self) -> List[str]: """Get the Harvester Sample List Name Return (List): list of crystal by names from the current processing plan" @@ -333,7 +336,7 @@ def get_crystal_images_urls(self, crystal_uuid: str) -> str: ) return crystal_images_url - def get_sample_acronyms(self) -> list[str]: + def get_sample_acronyms(self) -> List[str]: """Get the Harvester Sample List by Acronyms Return (List): list of crystal by Acronyms from the current processing plan" diff --git a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py index 8ec4eea20e..a430269b63 100644 --- a/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaMpegVideo.py @@ -15,7 +15,10 @@ import subprocess import uuid -from typing import List +from typing import ( + List, + Tuple, +) import psutil @@ -51,7 +54,7 @@ def set_quality(self, q) -> None: def set_stream_size(self, w, h) -> None: self._current_stream_size = (int(w), int(h)) - def get_stream_size(self) -> tuple[int, int, float]: + def get_stream_size(self) -> Tuple[int, int, float]: width, height = self._current_stream_size scale = float(width) / self.get_width() return (width, height, scale) @@ -59,7 +62,7 @@ def get_stream_size(self) -> tuple[int, int, float]: def get_quality_options(self) -> List[str]: return list(self._QUALITY_STR_TO_INT.keys()) - def get_available_stream_sizes(self) -> List[tuple[int, int]]: + def get_available_stream_sizes(self) -> List[Tuple[int, int]]: try: w, h = self.get_width(), self.get_height() video_sizes = [(w, h), (int(w / 2), int(h / 2)), (int(w / 4), int(h / 4))] diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index d46d47b972..938be393fa 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -3,7 +3,10 @@ import logging import subprocess import time -from typing import List +from typing import ( + List, + Tuple, +) import gevent import psutil @@ -94,11 +97,11 @@ def set_live(self, state) -> bool: def imageType(self): return None - def get_last_image(self) -> tuple[bytes, int, int]: + def get_last_image(self) -> Tuple[bytes, int, int]: image = Image.open(self.image) return image.tobytes(), image.size[0], image.size[1] - def get_available_stream_sizes(self) -> List[tuple[int, int]]: + def get_available_stream_sizes(self) -> List[Tuple[int, int]]: try: w, h = self.get_width(), self.get_height() video_sizes = [(w, h), (int(w / 2), int(h / 2)), (int(w / 4), int(h / 4))] @@ -110,7 +113,7 @@ def get_available_stream_sizes(self) -> List[tuple[int, int]]: def set_stream_size(self, w, h) -> None: self._current_stream_size = (int(w), int(h)) - def get_stream_size(self) -> tuple[int, int, float]: + def get_stream_size(self) -> Tuple[int, int, float]: width, height = self._current_stream_size scale = float(width) / self.get_width() return (width, height, scale) From bf56e14a58b31672f3532e0858e0fb31b1652aa8 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Mon, 4 Nov 2024 12:26:54 +0000 Subject: [PATCH 144/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 70416269b3..445bf77dfa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.182.0" +version = "1.183.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 814805f183d7728a0c020dd9ae156e7adc495d7d Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Tue, 5 Nov 2024 08:05:15 +0100 Subject: [PATCH 145/172] MAXIV: remove obsolete hardware objects Remove MAXIV hardware objects that are no longer in use. --- .../HardwareObjects/MAXIV/BIOMAXAperture.py | 51 - .../HardwareObjects/MAXIV/BIOMAXBeamInfo.py | 81 - .../MAXIV/BIOMAXBeamlineActions.py | 153 -- .../HardwareObjects/MAXIV/BIOMAXCollect.py | 1513 ----------------- .../HardwareObjects/MAXIV/BIOMAXEiger.py | 797 --------- .../HardwareObjects/MAXIV/BIOMAXEnergy.py | 68 - .../HardwareObjects/MAXIV/BIOMAXKafka.py | 86 - mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py | 650 ------- .../HardwareObjects/MAXIV/BIOMAXMD3Camera.py | 214 --- .../HardwareObjects/MAXIV/BIOMAXPatches.py | 160 -- .../HardwareObjects/MAXIV/BIOMAXResolution.py | 56 - .../MAXIV/BIOMAXTransmission.py | 54 - pyproject.toml | 6 - 13 files changed, 3889 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py delete mode 100755 mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py delete mode 100755 mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py delete mode 100755 mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py delete mode 100644 mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py deleted file mode 100644 index 35ccf654bc..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXAperture.py +++ /dev/null @@ -1,51 +0,0 @@ -import logging - -from mxcubecore.HardwareObjects.MicrodiffAperture import MicrodiffAperture - - -class BIOMAXAperture(MicrodiffAperture): - - POSITIONS = ("BEAM", "OFF", "PARK") - - def __init__(self, *args): - MicrodiffAperture.__init__(self, *args) - self.aperture_position = None - - def init(self): - MicrodiffAperture.init(self) - self.aperture_position = self.add_channel( - {"type": "exporter", "name": "AperturePosition"}, "AperturePosition" - ) - if self.aperture_position is not None: - self.connect(self.aperture_position, "update", self.position_changed) - - self.get_diameter_size_list = self.get_predefined_positions_list - self.set_position = self.moveToPosition - - def moveToPosition(self, positionName): - logging.getLogger().debug( - "%s: trying to move %s to %s:%f", - self.name(), - self.motor_name, - positionName, - self.predefinedPositions[positionName], - ) - if positionName == "Outbeam": - self.aperture_position.set_value("OFF") - else: - try: - self.set_value( - self.predefinedPositions[positionName], wait=True, timeout=10 - ) - except Exception: - logging.getLogger("HWR").exception( - "Cannot move motor %s: invalid position name.", str(self.username) - ) - if self.aperture_position.get_value() != "BEAM": - self.aperture_position.set_value("BEAM") - - def get_position_list(self): - return BIOMAXAperture.POSITIONS - - def position_changed(self, position): - self.emit("valueChanged", position) # self.aperture_position.get_value()) diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py deleted file mode 100755 index e210407820..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamInfo.py +++ /dev/null @@ -1,81 +0,0 @@ -from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects import BeamInfo - - -class BIOMAXBeamInfo(BeamInfo.BeamInfo): - def __init__(self, *args): - BeamInfo.BeamInfo.__init__(self, *args) - - def init(self): - self.chan_beam_size_microns = None - self.chan_beam_shape_ellipse = None - BeamInfo.BeamInfo.init(self) - - self.chan_beam_pos_x = self.get_channel_object("BeamPositionHorizontal") - self.chan_beam_pos_y = self.get_channel_object("BeamPositionVertical") - self.chan_beam_size_x = self.get_channel_object("BeamSizeHorizontal") - self.chan_beam_size_y = self.get_channel_object("BeamSizeVertical") - self.chan_beam_shape_ellipse = self.get_channel_object("BeamShapeEllipse") - self.chan_ImageZoom = self.get_channel_object("ImageZoom") - self.chan_CoaxialCameraZoomValue = self.get_channel_object( - "CoaxialCameraZoomValue" - ) - - self.connect(self.chan_beam_pos_x, "update", self.beam_position_changed) - self.connect(self.chan_beam_pos_y, "update", self.beam_position_changed) - self.connect(self.chan_ImageZoom, "update", self.beam_position_changed) - self.connect(self.chan_beam_size_x, "update", self.beam_info_changed) - self.connect(self.chan_beam_size_y, "update", self.beam_info_changed) - self.connect(self.chan_beam_shape_ellipse, "update", self.beam_info_changed) - self.connect(self.chan_CoaxialCameraZoomValue, "update", self.beam_info_changed) - - self.aperture_pos_changed(self.aperture_hwobj.getApertureSize()) - - def connect_notify(self, *args): - self.evaluate_beam_info() - self.re_emit_values() - - def beam_position_changed(self, value): - self.get_beam_position() - self.emit("beamPosChanged", (self.beam_position,)) - - def beam_info_changed(self, value): - self.evaluate_beam_info() - self.emit("beamInfoChanged", (self.beam_info_dict,)) - - def get_beam_position(self): - """ - Descript. : - Arguments : - Return : - """ - - return self.beam_position - if self.chan_ImageZoom.get_value() is not None: - zoom = self.chan_ImageZoom.get_value() - self.beam_position[0] = self.chan_beam_pos_x.get_value() * zoom - self.beam_position[1] = self.chan_beam_pos_y.get_value() * zoom - else: - self.beam_position[0] = HWR.beamline.sample_view.camera.get_width() / 2 - self.beam_position[1] = HWR.beamline.sample_view.camera.get_height() / 2 - - return self.beam_position - - def set_beam_position(self, beam_x, beam_y): - return - - def evaluate_beam_info(self, *args): - BeamInfo.BeamInfo.evaluate_beam_info(self, *args) - try: - if self.chan_beam_shape_ellipse.get_value(): - self.beam_info_dict["shape"] = "ellipse" - else: - self.beam_info_dict["shape"] = "rectangle" - except Exception: - self.beam_info_dict["shape"] = "ellipse" - curpos = self.aperture_hwobj.get_current_position_name() - size_x = size_y = eval(str(curpos)) / 1000.0 - self.beam_info_dict["size_x"] = size_x - self.beam_info_dict["size_y"] = size_y - self.beam_info_dict["pos"] = self.beam_position - return self.beam_info_dict diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py deleted file mode 100644 index 88235354fa..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXBeamlineActions.py +++ /dev/null @@ -1,153 +0,0 @@ -import logging -import time - -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.CommandContainer import CommandObject -from mxcubecore.TaskUtils import task - - -class ControllerCommand(CommandObject): - def __init__(self, name, cmd): - CommandObject.__init__(self, name) - self._cmd = cmd - self._cmd_execution = None - self.type = "CONTROLLER" - - def is_connected(self): - return True - - def get_arguments(self): - if self.name() == "Anneal": - self.add_argument("Time [s]", "float") - - return CommandObject.get_arguments(self) - - @task - def __call__(self, *args, **kwargs): - self.emit("commandBeginWaitReply", (str(self.name()),)) - self._cmd_execution = gevent.spawn(self._cmd, *args, **kwargs) - self._cmd_execution.link(self._cmd_done) - - def _cmd_done(self, cmd_execution): - try: - try: - res = cmd_execution.get() - except Exception: - self.emit("commandFailed", (str(self.name()),)) - else: - if isinstance(res, gevent.GreenletExit): - self.emit("commandFailed", (str(self.name()),)) - else: - self.emit("commandReplyArrived", (str(self.name()), res)) - finally: - self.emit("commandReady") - - def abort(self): - if self._cmd_execution and not self._cmd_execution.ready(): - self._cmd_execution.kill() - - def value(self): - return None - - -class BIOMAXBeamlineActions(HardwareObject): - def __init__(self, *args): - HardwareObject.__init__(self, *args) - - def _prepare_open_hutch_task(self): - """ - Descript.: prepare beamline for openning the hutch door, - """ - logging.getLogger("HWR").info("Preparing experimental hutch for door openning.") - time.sleep(1) - if ( - HWR.beamline.safety_shutter is not None - and HWR.beamline.safety_shutter.getShutterState() == "opened" - ): - logging.getLogger("HWR").info("Closing safety shutter...") - HWR.beamline.safety_shutter.closeShutter() - while HWR.beamline.safety_shutter.getShutterState() == "opened": - gevent.sleep(0.1) - - if self.detector_cover_hwobj is not None: - logging.getLogger("HWR").info("Closing detector cover...") - self.detector_cover_hwobj.closeShutter() - - if HWR.beamline.detector.distance is not None: - logging.getLogger("HWR").info("Moving detector to safe area...") - HWR.beamline.detector.distance.set_value(800, timeout=50) - - if HWR.beamline.sample_changer.is_powered(): - if HWR.beamline.sample_changer.get_loaded_sample() is not None: - logging.getLogger("HWR").info("Unloading mounted sample.") - HWR.beamline.sample_changer.unload(None, wait=True) - HWR.beamline.sample_changer._wait_device_ready(30) - if HWR.beamline.sample_changer._chnInSoak.get_value(): - logging.getLogger("HWR").info( - "Sample Changer was in SOAK, going to DRY" - ) - self.sample_changer_maint_hwobj.send_command("dry") - gevent.sleep(1) - HWR.beamline.sample_changer._wait_device_ready(300) - if HWR.beamline.sample_changer.is_powered(): - logging.getLogger("HWR").info("Sample Changer to HOME") - self.sample_changer_maint_hwobj.send_command("home") - gevent.sleep(1) - HWR.beamline.sample_changer._wait_device_ready(30) - - logging.getLogger("HWR").info("Sample Changer CLOSING LID") - self.sample_changer_maint_hwobj.send_command("closelid1") - gevent.sleep(1) - HWR.beamline.sample_changer._wait_device_ready(10) - - logging.getLogger("HWR").info("Sample Changer POWER OFF") - self.sample_changer_maint_hwobj.send_command("powerOff") - else: - logging.getLogger("HWR").warning( - "Cannot prepare Hutch openning, Isara is powered off" - ) - - def _prepare_for_new_sample_task(self, manual_mode=True): - """ - Descript.: prepare beamline for a new sample, - """ - logging.getLogger("HWR").info("Preparing beamline for a new sample.") - time.sleep(1) - if manual_mode: - if self.detector_cover_hwobj is not None: - logging.getLogger("HWR").info("Closing detector shutter...") - self.detector_cover_hwobj.closeShutter() - logging.getLogger("HWR").info("Setting diffractometer in Transfer phase...") - HWR.beamline.diffractometer.set_phase("Transfer", wait=False) - - if ( - HWR.beamline.safety_shutter is not None - and HWR.beamline.safety_shutter.getShutterState() == "opened" - ): - logging.getLogger("HWR").info("Closing safety shutter...") - HWR.beamline.safety_shutter.closeShutter() - while HWR.beamline.safety_shutter.getShutterState() == "opened": - gevent.sleep(0.1) - - if HWR.beamline.detector.distance is not None: - logging.getLogger("HWR").info("Moving detector to safe area...") - HWR.beamline.detector.distance.set_value(800, timeout=50) - - def init(self): - self.sample_changer_maint_hwobj = self.get_object_by_role( - "sample_changer_maintenance" - ) - self.detector_cover_hwobj = self.get_object_by_role("detector_cover") - - self.prepare_open_hutch = ControllerCommand( - "prepare_open_hutch", self._prepare_open_hutch_task - ) - self.prepare_new_sample = ControllerCommand( - "prepare_new_sample", self._prepare_for_new_sample_task - ) - - def get_commands(self): - return [self.prepare_open_hutch, self.prepare_new_sample] diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py deleted file mode 100644 index 390c4bc560..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py +++ /dev/null @@ -1,1513 +0,0 @@ -""" - File: BIOMAXCollect.py - - Description: This module implements the hardware object for the Biomax data collection - -todo list: -cancellation -exception -stopCollect -abort - -""" - -import json -import logging -import math -import os -import sys -import time -import uuid - -import gevent -import requests -from EigerDataSet import EigerDataSet - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.HardwareObjects.abstract.AbstractCollect import AbstractCollect -from mxcubecore.TaskUtils import task - - -class BIOMAXCollect(AbstractCollect, HardwareObject): - """ - Descript: Data collection class, inherited from AbstractCollect - """ - - # min images to trigger auto processing - NIMAGES_TRIGGER_AUTO_PROC = 50 - - def __init__(self, name): - """ - Descript. : - """ - AbstractCollect.__init__(self) - HardwareObject.__init__(self, name) - - self._centring_status = None - - self.osc_id = None - self.owner = None - self._collecting = False - self._error_msg = "" - self._error_or_aborting = False - self.collect_frame = None - self.helical = False - self.helical_pos = None - self.ready_event = None - self.stopCollect = self.stop_collect - self.triggers_to_collect = None - - self.exp_type_dict = None - self.display = {} - self.stop_display = False - - self.datacatalog_enabled = True - self.datacatalog_url = None - self.collection_uuid = "" - - def init(self): - """ - Descript. : - """ - self.ready_event = gevent.event.Event() - self.sample_changer_maint_hwobj = self.get_object_by_role( - "sample_changer_maintenance" - ) - self.detector_cover_hwobj = self.get_object_by_role("detector_cover") - self.datacatalog_url = self.get_property("datacatalog_url", None) - self.datacatalog_enabled = self.get_property("datacatalog_enabled", True) - - if self.datacatalog_enabled: - logging.getLogger("HWR").info( - "[COLLECT] Datacatalog enabled, url: %s" % self.datacatalog_url - ) - else: - logging.getLogger("HWR").warning("[COLLECT] Datacatalog not enabled") - - # todo - # self.cryo_stream_hwobj = self.get_object_by_role("cryo_stream") - - undulators = [] - # todo - try: - for undulator in self["undulators"]: - undulators.append(undulator) - except Exception: - pass - - self.exp_type_dict = {"Mesh": "Mesh", "Helical": "Helical"} - try: - min_exp = HWR.beamline.detector.get_minimum_exposure_time() - except Exception: - logging.getLogger("HWR").error( - "[HWR] *** Detector min exposure not available, set to 0.1" - ) - min_exp = 0.1 - try: - pix_x = HWR.beamline.detector.get_pixel_size_x() - except Exception: - logging.getLogger("HWR").error( - "[HWR] *** Detector X pixel size not available, set to 7-5e5" - ) - pix_x = 7.5e-5 - try: - pix_y = HWR.beamline.detector.get_pixel_size_y() - except Exception: - logging.getLogger("HWR").error( - "[HWR] *** Detector Y pixel size not available, set to 7-5e5" - ) - pix_y = 7.5e-5 - - beam_div_hor, beam_div_ver = HWR.beamline.beam.get_beam_divergence() - - self.set_beamline_configuration( - synchrotron_name="MAXIV", - directory_prefix=self.get_property("directory_prefix"), - default_exposure_time=self.get_property("default_exposure_time"), - minimum_exposure_time=min_exp, - detector_fileext=HWR.beamline.detector.get_property("file_suffix"), - detector_type=HWR.beamline.detector.get_property("type"), - detector_manufacturer=HWR.beamline.detector.get_property( - "manufacturer" - ), - detector_model=HWR.beamline.detector.get_property("model"), - detector_px=pix_x, - detector_py=pix_y, - undulators=undulators, - focusing_optic=self.get_property("focusing_optic"), - monochromator_type=self.get_property("monochromator"), - beam_divergence_vertical=beam_div_ver, - beam_divergence_horizontal=beam_div_hor, - polarisation=self.get_property("polarisation"), - input_files_server=self.get_property("input_files_server"), - ) - - """ to add """ - # self.chan_undulator_gap = self.get_channel_object('UndulatorGap') - # self.chan_machine_current = self.get_channel_object("MachineCurrent") - - self.emit("collectReady", (True,)) - - def move_to_center_position(self): - """ - Descript. : - """ - logging.getLogger("HWR").info("[COLLECT] Moving to center position") - shape_id = self.get_current_shape_id() - shape = HWR.beamline.sample_view.get_shape(shape_id).as_dict() - - x = shape.get("screen_coord")[0] - y = shape.get("screen_coord")[1] - x_ppmm = shape.get("pixels_per_mm")[0] / 1000 - y_ppmm = shape.get("pixels_per_mm")[1] / 1000 - - cell_width = shape.get("cell_width") - cell_height = shape.get("cell_height") - - num_cols = shape.get("num_cols") / 2 - num_rows = shape.get("num_rows") / 2 - - x_cor = x + cell_width * x_ppmm * (num_cols - 1) + cell_width * x_ppmm / 2 - y_cor = y + cell_height * y_ppmm * (num_rows - 1) + cell_height * y_ppmm / 2 - center_positions = HWR.beamline.diffractometer.get_centred_point_from_coord( - x_cor, y_cor, return_by_names=True - ) - center_positions.pop("zoom") - center_positions.pop("beam_x") - center_positions.pop("beam_y") - self.move_motors(center_positions) - - # --------------------------------------------------------- - # refactor do_collect - def do_collect(self, owner): - """ - Actual collect sequence - """ - log = logging.getLogger("user_level_log") - log.info("Collection: Preparing to collect") - # todo, add more exceptions and abort - try: - self.emit("collectReady", (False,)) - self.emit("collectStarted", (owner, 1)) - - # ---------------------------------------------------------------- - """ should all go data collection hook - self.open_detector_cover() - self.open_safety_shutter() - self.open_fast_shutter() - """ - # ---------------------------------------------------------------- - - self.current_dc_parameters["status"] = "Running" - self.current_dc_parameters["collection_start_time"] = time.strftime( - "%Y-%m-%d %H:%M:%S" - ) - self.current_dc_parameters["synchrotronMode"] = self.get_machine_fill_mode() - - log.info("Collection: Storing data collection in LIMS") - self.store_data_collection_in_lims() - - log.info( - "Collection: Creating directories for raw images and processing files" - ) - self.create_file_directories() - - log.info("Collection: Getting sample info from parameters") - self.get_sample_info() - - # log.info("Collect: Storing sample info in LIMS") - # self.store_sample_info_in_lims() - - if all( - item is None for item in self.current_dc_parameters["motors"].values() - ): - # No centring point defined - # create point based on the current position - current_diffractometer_position = ( - HWR.beamline.diffractometer.get_positions() - ) - for motor in self.current_dc_parameters["motors"].keys(): - self.current_dc_parameters["motors"][ - motor - ] = current_diffractometer_position[motor] - - # todo, self.move_to_centered_position() should go inside take_crystal_snapshots, - # which makes sure it move motors to the correct positions and move back - # if there is a phase change - log.debug("Collection: going to take snapshots...") - self.take_crystal_snapshots() - log.debug("Collection: snapshots taken") - # to fix permission issues - snapshots_files = [] - - for key, value in self.current_dc_parameters.items(): - if key.startswith("xtalSnapshotFullPath"): - snapshots_files.append(value) - try: - archive_directory = self.current_dc_parameters["fileinfo"][ - "archive_directory" - ] - os.chmod(archive_directory, 0o777) - for file in snapshots_files: - os.chmod(file, 0o777) - except Exception as ex: - print(ex) - # prepare beamline for data acquisiion - self.prepare_acquisition() - self.emit( - "collectOscillationStarted", - (owner, None, None, None, self.current_dc_parameters, None), - ) - - self.data_collection_hook() - self.emit_collection_finished() - except Exception as ex: - logging.getLogger("HWR").error("[COLLECT] Data collection failed: %s", ex) - self.emit_collection_failed() - self.close_fast_shutter() - self.close_detector_cover() - - def prepare_acquisition(self): - """ todo - 1. check the currrent value is the same as the tobeset value - 2. check how to add detroi in the mode - """ - logging.getLogger("HWR").info( - "[COLLECT] Preparing data collection with parameters: %s" - % self.current_dc_parameters - ) - - self.stop_display = False - log = logging.getLogger("user_level_log") - - if "transmission" in self.current_dc_parameters: - log.info( - "Collection: Setting transmission to %.3f", - self.current_dc_parameters["transmission"], - ) - try: - HWR.beamline.transmission.set_value( - self.current_dc_parameters["transmission"] - ) - except Exception as ex: - log.error("Collection: cannot set beamline transmission.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting transmission: %s" % ex - ) - raise Exception("[COLLECT] Error setting transmission: %s" % ex) - - if "wavelength" in self.current_dc_parameters: - log.info( - "Collection: Setting wavelength to %.3f", - self.current_dc_parameters["wavelength"], - ) - try: - self.set_wavelength(self.current_dc_parameters["wavelength"]) - except Exception as ex: - log.error("Collection: cannot set beamline wavelength.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting wavelength: %s" % ex - ) - raise Exception("[COLLECT] Error setting wavelength: %s" % ex) - - elif "energy" in self.current_dc_parameters: - log.info( - "Collection: Setting energy to %.3f", - self.current_dc_parameters["energy"], - ) - try: - self.set_energy(self.current_dc_parameters["energy"]) - except Exception as ex: - log.error("Collection: cannot set beamline energy.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting energy: %s" % ex - ) - raise Exception("[COLLECT] Error setting energy: %s" % ex) - - if "detroi" in self.current_dc_parameters: - try: - log.info( - "Collection: Setting detector to %s", - self.current_dc_parameters["detroi"], - ) - HWR.beamline.detector.set_roi_mode(self.current_dc_parameters["detroi"]) - except Exception as ex: - log.error("Collection: cannot set detector roi.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting detector roi: %s" % ex - ) - raise Exception("[COLLECT] Error setting detector roi: %s" % ex) - - if "resolution" in self.current_dc_parameters: - try: - resolution = self.current_dc_parameters["resolution"]["upper"] - log.info("Collection: Setting resolution to %.3f", resolution) - HWR.beamline.resolution.set_value(resolution) - except Exception as ex: - log.error("Collection: cannot set resolution.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting resolution: %s" % ex - ) - raise Exception("[COLLECT] Error setting resolution: %s" % ex) - - elif "detector_distance" in self.current_dc_parameters: - try: - log.info( - "Collection: Moving detector to %f", - self.current_dc_parameters["detector_distance"], - ) - HWR.beamline.detector.distance.set_value( - self.current_dc_parameters["detector_distance"] - ) - except Exception as ex: - log.error("Collection: cannot set detector distance.") - logging.getLogger("HWR").error( - "[COLLECT] Error setting detector distance: %s" % ex - ) - raise Exception("[COLLECT] Error setting detector distance: %s" % ex) - - self.triggers_to_collect = self.prepare_triggers_to_collect() - - log.info("Collection: Updating data collection in LIMS") - self._update_data_collection_in_lims() - - # Generate and set a unique id, used in the data catalog and the detector - # must know it - self.collection_uuid = str(uuid.uuid4()) - logging.getLogger("HWR").info( - "[COLLECT] Generating UUID: %s" % self.collection_uuid - ) - - try: - HWR.beamline.detector.set_collection_uuid(self.collection_uuid) - except Exception as ex: - logging.getLogger("HWR").warning( - "[COLLECT] Error setting UUID in the detector: %s" % ex - ) - if self.datacatalog_enabled: - try: - self.store_datacollection_uuid_datacatalog() - except Exception as ex: - logging.getLogger("HWR").warning( - "[COLLECT] Error sending uuid to data catalog: %s", ex - ) - - try: - self.prepare_detector() - except Exception as ex: - log.error("Collection: cannot set prepare detector.") - logging.getLogger("HWR").error( - "[COLLECT] Error preparing detector: %s" % ex - ) - raise Exception("[COLLECT] Error preparing detector: %s" % ex) - - # move MD3 to DataCollection phase if it's not - if HWR.beamline.diffractometer.get_current_phase() != "DataCollection": - log.info("Moving Diffractometer to Data Collection") - HWR.beamline.diffractometer.set_phase( - "DataCollection", wait=True, timeout=200 - ) - if ( - self.current_dc_parameters.get("experiment_type", "Unknown").lower() - == "mesh" - ): - self.move_to_center_position() - else: - self.move_to_centered_position() - - # ------------------------------------------------------------------------------- - - def prepare_triggers_to_collect(self): - - oscillation_parameters = self.current_dc_parameters["oscillation_sequence"][0] - osc_start = oscillation_parameters["start"] - osc_range = oscillation_parameters["range"] - nframes = oscillation_parameters["number_of_images"] - overlap = oscillation_parameters["overlap"] - triggers_to_collect = [] - - if overlap > 0 or overlap < 0: - # currently for characterization, only collect one image at each omega - # position - ntriggers = nframes - nframes_per_trigger = 1 - for trigger_num in range(1, ntriggers + 1): - triggers_to_collect.append( - (osc_start, trigger_num, nframes_per_trigger, osc_range) - ) - osc_start += osc_range * nframes_per_trigger - overlap - elif self.current_dc_parameters["experiment_type"] == "Mesh": - logging.getLogger("HWR").info( - "osc_start %s, nframes %s, osc_range %s num_lines %s" - % (osc_start, nframes, osc_range, self.get_mesh_num_lines()) - ) - triggers_to_collect.append( - (osc_start, self.get_mesh_num_lines(), nframes, osc_range) - ) - else: - triggers_to_collect.append((osc_start, 1, nframes, osc_range)) - - return triggers_to_collect - - def data_collection_hook(self): - """ - Descript. : main collection command - """ - - try: - self._collecting = True - oscillation_parameters = self.current_dc_parameters["oscillation_sequence"][ - 0 - ] - self.open_detector_cover() - self.open_safety_shutter() - - # TODO: investigate gevent.timeout exception handing, this wait is to ensure - # that conf is done before arming - time.sleep(2) - try: - HWR.beamline.detector.wait_config_done() - HWR.beamline.detector.start_acquisition() - HWR.beamline.detector.wait_ready() - except Exception as ex: - logging.getLogger("HWR").error("[COLLECT] Detector Error: %s", ex) - raise RuntimeError("[COLLECT] Detector error while arming.") - - # call after start_acquisition (detector is armed), when all the config parameters are definitely - # implemented - try: - shutterless_exptime = HWR.beamline.detector.get_acquisition_time() - except Exception as ex: - logging.getLogger("HWR").error( - "[COLLECT] Detector error getting acquisition time: %s" % ex - ) - shutterless_exptime = 0.01 - - # wait until detector is ready (will raise timeout RuntimeError), sometimes arm command - # is accepted by the detector but without any effect at all... sad... - # HWR.beamline.detector.wait_ready() - for ( - osc_start, - trigger_num, - nframes_per_trigger, - osc_range, - ) in self.triggers_to_collect: - osc_end = osc_start + osc_range * nframes_per_trigger - self.display_task = gevent.spawn(self._update_image_to_display) - self.progress_task = gevent.spawn(self._update_task_progress) - self.oscillation_task = self.oscil( - osc_start, osc_end, shutterless_exptime, 1, wait=True - ) - try: - HWR.beamline.detector.stop_acquisition() - except Exception as ex: - logging.getLogger("HWR").error( - "[COLLECT] Detector error stopping acquisition: %s" % ex - ) - - # not closing the safety shutter here, but in prepare_beamline - # to avoid extra open/closes - # self.close_safety_shutter() - self.close_detector_cover() - self.emit( - "collectImageTaken", oscillation_parameters["number_of_images"] - ) - except RuntimeError as ex: - self.data_collection_cleanup() - logging.getLogger("HWR").error("[COLLECT] Runtime Error: %s" % ex) - raise Exception("data collection hook failed... ", str(ex)) - except Exception: - self.data_collection_cleanup() - logging.getLogger("HWR").error("Unexpected error:", sys.exc_info()[0]) - raise Exception("data collection hook failed... ", sys.exc_info()[0]) - - def get_mesh_num_lines(self): - return self.mesh_num_lines - - def get_mesh_total_nb_frames(self): - return self.mesh_total_nb_frames - - def get_current_shape_id(self): - return self.current_dc_parameters["shape"] - - def oscil(self, start, end, exptime, npass, wait=True): - oscillation_parameters = self.current_dc_parameters["oscillation_sequence"][0] - msg = ( - "[BIOMAXCOLLECT] Oscillation requested oscillation_parameters: %s" - % oscillation_parameters - ) - # msg += " || dc parameters: %s" % self.current_dc_parameters - logging.getLogger("HWR").info(msg) - - if self.helical: - HWR.beamline.diffractometer.osc_scan_4d( - start, end, exptime, self.helical_pos, wait=True - ) - elif self.current_dc_parameters["experiment_type"] == "Mesh": - mesh_range = oscillation_parameters["mesh_range"] - # HWR.beamline.diffractometer.raster_scan(20, 22, 10, 0.2, 0.2, 10, 10) - logging.getLogger("HWR").info( - "Mesh oscillation requested: number of lines %s" - % self.get_mesh_num_lines() - ) - logging.getLogger("HWR").info( - "Mesh oscillation requested: total number of frames %s" - % self.get_mesh_total_nb_frames() - ) - shape_id = self.get_current_shape_id() - shape = HWR.beamline.sample_view.get_shape(shape_id).as_dict() - range_x = shape.get("num_cols") * shape.get("cell_width") / 1000.0 - range_y = shape.get("num_rows") * shape.get("cell_height") / 1000.0 - HWR.beamline.diffractometer.raster_scan( - start, - end, - exptime * self.get_mesh_num_lines(), - range_y, # vertical_range in mm, - range_x, # horizontal_range in mm, - self.get_mesh_num_lines(), - self.get_mesh_total_nb_frames(), # is in fact nframes per line - invert_direction=1, - wait=True, - ) - else: - HWR.beamline.diffractometer.osc_scan(start, end, exptime, wait=True) - - def _update_task_progress(self): - logging.getLogger("HWR").info("[BIOMAXCOLLECT] update task progress launched") - num_images = self.current_dc_parameters["oscillation_sequence"][0][ - "number_of_images" - ] - if self.current_dc_parameters.get("experiment_type") == "Mesh": - shape_id = self.get_current_shape_id() - shape = HWR.beamline.sample_view.get_shape(shape_id).as_dict() - num_cols = shape.get("num_cols") - num_rows = shape.get("num_rows") - num_images = num_cols * num_rows - num_steps = 10.0 - if num_images < num_steps: - step_size = 1 - num_steps = num_images - else: - step_size = float( - num_images / num_steps - ) # arbitrary, 10 progress steps or messages - exp_time = self.current_dc_parameters["oscillation_sequence"][0][ - "exposure_time" - ] - step_count = 0 - current_frame = 0 - time.sleep(exp_time * step_size) - while step_count < num_steps: - time.sleep(exp_time * step_size) - current_frame += step_size - logging.getLogger("HWR").info( - "[BIOMAXCOLLECT] collectImageTaken %s (%s, %s, %s)" - % (current_frame, num_images, step_size, step_count) - ) - self.emit( - "collectImageTaken", - current_frame - / self.current_dc_parameters["oscillation_sequence"][0][ - "number_of_images" - ], - ) - step_count += 1 - - def emit_collection_failed(self): - """ - Descrip. : - """ - failed_msg = "Data collection failed!" - self.current_dc_parameters["status"] = failed_msg - self.current_dc_parameters["comments"] = "%s\n%s" % ( - failed_msg, - self._error_msg, - ) - self.emit( - "collectOscillationFailed", - ( - self.owner, - False, - failed_msg, - self.current_dc_parameters.get("collection_id"), - self.osc_id, - ), - ) - self.emit("collectEnded", self.owner, False, failed_msg) - self.emit("collectReady", (True,)) - self._collecting = None - self.ready_event.set() - - logging.getLogger("HWR").error( - "[COLLECT] COLLECTION FAILED, self.current_dc_parameters: %s" - % self.current_dc_parameters - ) - self._update_data_collection_in_lims() - - def emit_collection_finished(self): - """ - Descript. : - """ - if self.current_dc_parameters["experiment_type"] == "Mesh": - # disable stream interface - # stop spot finding - HWR.beamline.detector.disable_stream() - self.stop_spot_finder() - success_msg = "Data collection successful" - self.current_dc_parameters["status"] = success_msg - self.emit( - "collectOscillationFinished", - ( - self.owner, - True, - success_msg, - self.current_dc_parameters.get("collection_id"), - self.osc_id, - self.current_dc_parameters, - ), - ) - self.emit("collectEnded", self.owner, True, success_msg) - self.emit("collectReady", (True,)) - self.emit("progressStop", ()) - self._collecting = None - self.ready_event.set() - self._update_data_collection_in_lims() - - logging.getLogger("HWR").debug( - "[COLLECT] COLLECTION FINISHED, self.current_dc_parameters: %s" - % self.current_dc_parameters - ) - - if self.current_dc_parameters.get("experiment_type") != "Mesh": - try: - logging.getLogger("HWR").info( - "[BIOMAXCOLLECT] Going to generate XDS input files" - ) - # generate XDS.INP only in raw/process - data_path = self.current_dc_parameters["fileinfo"]["filename"] - logging.getLogger("HWR").info( - "[BIOMAXCOLLECT] DATA file: %s" % data_path - ) - logging.getLogger("HWR").info( - "[BIOMAXCOLLECT] XDS file: %s" - % self.current_dc_parameters["xds_dir"] - ) - # Wait for the master file - self.wait_for_file_copied(data_path) - os.system( - "cd %s;/mxn/groups/biomax/wmxsoft/scripts_mxcube/generate_xds_inp.sh %s &" - % (self.current_dc_parameters["xds_dir"], data_path) - ) - logging.getLogger("HWR").info( - "[BIOMAXCOLLECT] AUTO file: %s" - % self.current_dc_parameters["auto_dir"] - ) - os.system( - "cd %s;/mxn/groups/biomax/wmxsoft/scripts_mxcube/generate_xds_inp_auto.sh %s &" - % (self.current_dc_parameters["auto_dir"], data_path) - ) - if ( - self.current_dc_parameters["experiment_type"] in ("OSC", "Helical") - and self.current_dc_parameters["oscillation_sequence"][0]["overlap"] - == 0 - and self.current_dc_parameters["oscillation_sequence"][0][ - "number_of_images" - ] - >= self.NIMAGES_TRIGGER_AUTO_PROC - ): - self.trigger_auto_processing("after", self.current_dc_parameters, 0) - except Exception as ex: - logging.getLogger("HWR").error( - "[COLLECT] Error creating XDS files, %s" % ex - ) - - # we store the first and the last images, TODO: every 45 degree - logging.getLogger("HWR").info("Storing images in lims, frame number: 1") - try: - self._store_image_in_lims(1) - self.generate_and_copy_thumbnails( - self.current_dc_parameters["fileinfo"]["filename"], 1 - ) - except Exception as ex: - print(ex) - - last_frame = self.current_dc_parameters["oscillation_sequence"][0][ - "number_of_images" - ] - if last_frame > 1: - logging.getLogger("HWR").info( - "Storing images in lims, frame number: %d" % last_frame - ) - try: - self._store_image_in_lims(last_frame) - self.generate_and_copy_thumbnails( - self.current_dc_parameters["fileinfo"]["filename"], last_frame - ) - except Exception as ex: - print(ex) - - if self.datacatalog_enabled: - self.store_datacollection_datacatalog() - - def _store_image_in_lims_by_frame_num(self, frame, motor_position_id=None): - """ - Descript. : - """ - # Dont save mesh first and last images - # Mesh images (best positions) are stored after data analysis - logging.getLogger("HWR").info( - "TODO: fix store_image_in_lims_by_frame_num method for nimages>1" - ) - return - - def generate_and_copy_thumbnails(self, data_path, frame_number): - # generare diffraction thumbnails - image_file_template = self.current_dc_parameters["fileinfo"]["template"] - archive_directory = self.current_dc_parameters["fileinfo"]["archive_directory"] - thumb_filename = "%s.thumb.jpeg" % os.path.splitext(image_file_template)[0] - jpeg_thumbnail_file_template = os.path.join(archive_directory, thumb_filename) - jpeg_thumbnail_full_path = jpeg_thumbnail_file_template % frame_number - - logging.getLogger("HWR").info( - "[COLLECT] Generating thumbnails, output filename: %s" - % jpeg_thumbnail_full_path - ) - logging.getLogger("HWR").info( - "[COLLECT] Generating thumbnails, data path: %s" % data_path - ) - input_file = data_path - binfactor = 1 - nimages = 1 - first_image = 0 - rootname, ext = os.path.splitext(input_file) - rings = [0.25, 0.50, 0.75, 1.00, 1.25] - # master file is need but also data files - # 100 frames per data file, so adapt accordingly for the file name in case not the first frame - # TODO: get num_images_per_file as variable - time.sleep(2) - if frame_number > 1: - frame_number = frame_number / 100 - - self.wait_for_file_copied(data_path) # master file - - data_file = data_path.replace("master", "data_{:06d}".format(frame_number)) - - self.wait_for_file_copied(data_path) # data file - - if not os.path.exists(os.path.dirname(jpeg_thumbnail_full_path)): - os.makedirs(os.path.dirname(jpeg_thumbnail_full_path)) - try: - dataset = EigerDataSet(data_path) - dataset.save_thumbnail( - binfactor, - output_file=jpeg_thumbnail_full_path, - start_image=first_image, - nb_images=nimages, - rings=rings, - ) - except Exception as ex: - print(ex) - - try: - os.chmod(os.path.dirname(jpeg_thumbnail_full_path), 0o777) - os.chmod(jpeg_thumbnail_full_path, 0o777) - except Exception as ex: - print(ex) - - def wait_for_file_copied(self, full_file_path): - # first wait for the file being created - with gevent.Timeout( - 30, Exception("Timeout waiting for the data file available.") - ): - while not os.path.exists(full_file_path): - gevent.sleep(0.1) - - # then wait to finish the copy - size1 = -1 - with gevent.Timeout( - 300, Exception("Timeout waiting for the data to be copied available.") - ): - while size1 != os.path.getsize(full_file_path): - size1 = os.path.getsize(full_file_path) - gevent.sleep(1) - - def _store_image_in_lims(self, frame_number, motor_position_id=None): - """ - Descript. : - """ - if HWR.beamline.lims: - file_location = self.current_dc_parameters["fileinfo"]["directory"] - image_file_template = self.current_dc_parameters["fileinfo"]["template"] - filename = image_file_template % frame_number - lims_image = { - "dataCollectionId": self.current_dc_parameters["collection_id"], - "fileName": filename, - "fileLocation": file_location, - "imageNumber": frame_number, - "measuredIntensity": HWR.beamline.flux.get_value(), - "synchrotronCurrent": self.get_machine_current(), - "machineMessage": self.get_machine_message(), - "temperature": self.get_cryo_temperature(), - } - archive_directory = self.current_dc_parameters["fileinfo"][ - "archive_directory" - ] - - if archive_directory: - jpeg_filename = ( - "%s.thumb.jpeg" % os.path.splitext(image_file_template)[0] - ) - thumb_filename = ( - "%s.thumb.jpeg" % os.path.splitext(image_file_template)[0] - ) - jpeg_file_template = os.path.join(archive_directory, jpeg_filename) - jpeg_thumbnail_file_template = os.path.join( - archive_directory, thumb_filename - ) - jpeg_full_path = jpeg_file_template % frame_number - jpeg_thumbnail_full_path = jpeg_thumbnail_file_template % frame_number - lims_image["jpegFileFullPath"] = jpeg_full_path - lims_image["jpegThumbnailFileFullPath"] = jpeg_thumbnail_full_path - lims_image["fileLocation"] = os.path.dirname(jpeg_thumbnail_full_path) - if motor_position_id: - lims_image["motorPositionId"] = motor_position_id - logging.getLogger("HWR").info( - "LIMS IMAGE: %s, %s, %s, %s" - % ( - jpeg_filename, - thumb_filename, - jpeg_full_path, - jpeg_thumbnail_full_path, - ) - ) - try: - image_id = HWR.beamline.lims.store_image(lims_image) - except Exception as ex: - print(ex) - # temp fix for ispyb permission issues - try: - session_dir = os.path.join(archive_directory, "../../../") - os.system("chmod -R 777 %s" % (session_dir)) - except Exception as ex: - print(ex) - - return image_id - - def take_crystal_snapshots(self): - """ - Descript. : - """ - if self.current_dc_parameters["take_snapshots"]: - # snapshot_directory = self.current_dc_parameters["fileinfo"]["archive_directory"] - # save the image to the data collection directory for the moment - snapshot_directory = os.path.join( - self.current_dc_parameters["fileinfo"]["directory"], "snapshot" - ) - if not os.path.exists(snapshot_directory): - try: - self.create_directories(snapshot_directory) - except Exception: - logging.getLogger("HWR").exception( - "Collection: Error creating snapshot directory" - ) - - # for plate head, takes only one image - if ( - HWR.beamline.diffractometer.head_type - == HWR.beamline.diffractometer.HEAD_TYPE_PLATE - ): - number_of_snapshots = 1 - else: - number_of_snapshots = 4 # 4 take only one image for the moment - logging.getLogger("user_level_log").info( - "Collection: Taking %d sample snapshot(s)" % number_of_snapshots - ) - if HWR.beamline.diffractometer.get_current_phase() != "Centring": - logging.getLogger("user_level_log").info( - "Moving Diffractometer to CentringPhase" - ) - HWR.beamline.diffractometer.set_phase( - "Centring", wait=True, timeout=200 - ) - self.move_to_centered_position() - - for snapshot_index in range(number_of_snapshots): - snapshot_filename = os.path.join( - snapshot_directory, - "%s_%s_%s.snapshot.jpeg" - % ( - self.current_dc_parameters["fileinfo"]["prefix"], - self.current_dc_parameters["fileinfo"]["run_number"], - (snapshot_index + 1), - ), - ) - self.current_dc_parameters[ - "xtalSnapshotFullPath%i" % (snapshot_index + 1) - ] = snapshot_filename - # self._do_take_snapshot(snapshot_filename) - self._take_crystal_snapshot(snapshot_filename) - time.sleep(1) # needed, otherwise will get the same images - if number_of_snapshots > 1: - HWR.beamline.diffractometer.move_omega_relative(90) - time.sleep(1) # needed, otherwise will get the same images - - def trigger_auto_processing(self, process_event, params_dict, frame_number): - """ - Descript. : - """ - # todo - fast_dp_dir = os.path.join(params_dict["auto_dir"], "fast_dp") - biomax_pipeline_dir = os.path.join(params_dict["auto_dir"], "biomax_pipeline") - # autoPROC_dir = os.path.join(params_dict["auto_dir"],"autoPROC") - - self.create_directories(fast_dp_dir) # , biomax_pipeline_dir)#, autoPROC_dir) - - logging.getLogger("HWR").info( - "[COLLECT] triggering auto processing, parameters: %s" % params_dict - ) - logging.getLogger("HWR").info( - "[COLLECT] triggering auto processing, self.current_dc_parameters: %s" - % self.current_dc_parameters - ) - - logging.getLogger("HWR").info("[COLLECT] Launching fast_dp") - os.system( - "cd %s;/mxn/groups/biomax/wmxsoft/scripts_mxcube/fast_dp.sh %s &" - % (fast_dp_dir, params_dict["fileinfo"]["filename"]) - ) - - # logging.getLogger("HWR").info("[COLLECT] Launching biomax_pipeline") - # os.system("cd %s;/mxn/groups/biomax/wmxsoft/scripts_mxcube/biomax_pipeline.sh %s &" \ - # % (biomax_pipeline_dir, params_dict['fileinfo']['filename'])) - # os.system("cd %s;/mxn/groups/biomax/wmxsoft/scripts_mxcube/autoPROC.sh %s &" \ - # % (autoPROC_dir, params_dict['fileinfo']['filename'])) - # return - - logging.getLogger("HWR").info("[COLLECT] Launching MAXIV Autoprocessing") - if HWR.beamline.offline_processing is not None: - HWR.beamline.offline_processing.execute_autoprocessing( - process_event, self.current_dc_parameters, frame_number - ) - - def get_beam_centre(self): - """ - Descript. : - """ - if HWR.beamline.resolution is not None: - return HWR.beamline.resolution.get_beam_centre() - else: - return None, None - - def get_beam_shape(self): - """ - Descript. : - """ - if HWR.beamline.beam is not None: - return HWR.beamline.beam.get_beam_shape() - - def open_detector_cover(self): - """ - Descript. : - """ - try: - logging.getLogger("HWR").info("Openning the detector cover.") - self.detector_cover_hwobj.openShutter() - time.sleep(1) # make sure the cover is up before the data collection stars - except Exception: - logging.getLogger("HWR").exception("Could not open the detector cover") - pass - - def close_detector_cover(self): - """ - Descript. : - """ - try: - logging.getLogger("HWR").info("Closing the detector cover") - self.detector_cover_hwobj.closeShutter() - except Exception: - logging.getLogger("HWR").exception("Could not close the detector cover") - pass - - def open_safety_shutter(self): - """ - Descript. : - """ - # todo add time out? if over certain time, then stop acquisiion and - # popup an error message - if HWR.beamline.safety_shutter.getShutterState() == "opened": - return - timeout = 5 - count_time = 0 - logging.getLogger("HWR").info("Opening the safety shutter.") - HWR.beamline.safety_shutter.openShutter() - while ( - HWR.beamline.safety_shutter.getShutterState() == "closed" - and count_time < timeout - ): - time.sleep(0.1) - count_time += 0.1 - if HWR.beamline.safety_shutter.getShutterState() == "closed": - logging.getLogger("HWR").exception("Could not open the safety shutter") - raise Exception("Could not open the safety shutter") - - def close_safety_shutter(self): - """ - Descript. : - """ - # todo, add timeout, same as open - logging.getLogger("HWR").info("Closing the safety shutter.") - HWR.beamline.safety_shutter.closeShutter() - while HWR.beamline.safety_shutter.getShutterState() == "opened": - time.sleep(0.1) - - def open_fast_shutter(self): - """ - Descript. : important to make sure it's passed, as we - don't open the fast shutter in MXCuBE - """ - pass - - def close_fast_shutter(self): - """ - Descript. : - """ - # to do, close the fast shutter as early as possible in case - # MD3 fails to do so - pass - - @task - def _take_crystal_snapshot(self, filename): - """ - Descript. : - """ - # take image from server - HWR.beamline.sample_view.take_snapshot(filename) - - def set_helical(self, helical_on): - """ - Descript. : - """ - self.helical = helical_on - - def set_helical_pos(self, helical_oscil_pos): - """ - Descript. : - """ - self.helical_pos = helical_oscil_pos - - def set_energy(self, value): - logging.getLogger("HWR").info("[COLLECT] Setting beamline energy") - HWR.beamline.energy.set_value(value) # keV - logging.getLogger("HWR").info("[COLLECT] Setting detector energy") - HWR.beamline.detector.set_photon_energy(value * 1000) # ev - - def set_wavelength(self, value): - HWR.beamline.energy.set_wavelength(value) - current_energy = HWR.beamline.energy.get_energy() - HWR.beamline.detector.set_photon_energy(current_energy * 1000) - - @task - def move_motors(self, motor_position_dict): - """ - Descript. : - """ - HWR.beamline.diffractometer.move_sync_motors(motor_position_dict) - - def create_file_directories(self): - """ - Method create directories for raw files and processing files. - Directories for xds.input and auto_processing are created - """ - self.create_directories( - self.current_dc_parameters["fileinfo"]["directory"], - self.current_dc_parameters["fileinfo"]["process_directory"], - ) - - """create processing directories and img links""" - xds_directory, auto_directory = self.prepare_input_files() - try: - self.create_directories(xds_directory, auto_directory) - # temporary, to improve - os.system("chmod -R 777 %s %s" % (xds_directory, auto_directory)) - """todo, create link of imgs for auto_processing - try: - os.symlink(files_directory, os.path.join(process_directory, "img")) - except os.error, e: - if e.errno != errno.EEXIST: - raise - """ - # os.symlink(files_directory, os.path.join(process_directory, "img")) - except Exception: - logging.exception("Could not create processing file directory") - return - if xds_directory: - self.current_dc_parameters["xds_dir"] = xds_directory - if auto_directory: - self.current_dc_parameters["auto_dir"] = auto_directory - - def prepare_input_files(self): - """ - Descript. : - """ - i = 1 - logging.getLogger("user_level_log").info( - "Creating XDS (MAXIV-BioMAX) processing input file directories" - ) - - while True: - xds_input_file_dirname = "xds_%s_%s_%d" % ( - self.current_dc_parameters["fileinfo"]["prefix"], - self.current_dc_parameters["fileinfo"]["run_number"], - i, - ) - xds_directory = os.path.join( - self.current_dc_parameters["fileinfo"]["directory"], - "process", - xds_input_file_dirname, - ) - if not os.path.exists(xds_directory): - break - i += 1 - auto_directory = os.path.join( - self.current_dc_parameters["fileinfo"]["process_directory"], - xds_input_file_dirname, - ) - logging.getLogger("HWR").info( - "[COLLECT] Processing input file directories: XDS: %s, AUTO: %s" - % (xds_directory, auto_directory) - ) - return xds_directory, auto_directory - - def prepare_detector(self): - - oscillation_parameters = self.current_dc_parameters["oscillation_sequence"][0] - ( - osc_start, - trigger_num, - nframes_per_trigger, - osc_range, - ) = self.triggers_to_collect[0] - if self.current_dc_parameters["experiment_type"] == "Mesh": - ntrigger = self.get_mesh_num_lines() - else: - ntrigger = len(self.triggers_to_collect) - config = HWR.beamline.detector.col_config - """ move after setting energy - if roi == "4M": - config['RoiMode'] = "4M" - else: - config['RoiMode'] = "disabled" #disabled means 16M - - config['PhotonEnergy'] = self._tunable_bl.get_current_energy() - """ - config["OmegaStart"] = osc_start # oscillation_parameters['start'] - config["OmegaIncrement"] = osc_range # oscillation_parameters["range"] - ( - beam_centre_x, - beam_centre_y, - ) = self.get_beam_centre() # self.get_beam_centre_pixel() # returns pixel - config["BeamCenterX"] = beam_centre_x # unit, should be pixel for master file - config["BeamCenterY"] = beam_centre_y - config["DetectorDistance"] = HWR.beamline.detector.distance.get_value() / 1000.0 - - config["CountTime"] = oscillation_parameters["exposure_time"] - - config["NbImages"] = nframes_per_trigger - config["NbTriggers"] = ntrigger - - try: - config["ImagesPerFile"] = oscillation_parameters["images_per_file"] - except Exception: - config["ImagesPerFile"] = 100 - - if nframes_per_trigger * ntrigger < config["ImagesPerFile"]: - self.display["delay"] = ( - nframes_per_trigger * ntrigger * oscillation_parameters["exposure_time"] - ) - else: - self.display["delay"] = ( - config["ImagesPerFile"] * oscillation_parameters["exposure_time"] - ) - self.display["exp"] = oscillation_parameters["exposure_time"] - self.display["nimages"] = nframes_per_trigger * ntrigger - - import re - - file_parameters = self.current_dc_parameters["fileinfo"] - file_parameters["suffix"] = self.bl_config.detector_fileext - image_file_template = "%(prefix)s_%(run_number)s" % file_parameters - name_pattern = os.path.join(file_parameters["directory"], image_file_template) - # file_parameters["template"] = image_file_template - file_parameters["filename"] = "%s_master.h5" % name_pattern - self.display["file_name1"] = file_parameters["filename"] - self.display["file_name2"] = re.sub( - "^/mxn/biomax-eiger-dc-1", "/localdata", file_parameters["filename"] - ) - - # os.path.join(file_parameters["directory"], image_file_template) - config["FilenamePattern"] = re.sub( - "^/data", "", name_pattern - ) # remove "/data in the beginning" - - if self.current_dc_parameters["experiment_type"] == "Mesh": - # enable stream interface - # appendix with grid name, collection id - HWR.beamline.detector.enable_stream() - img_appendix = { - "exp_type": "mesh", - "col_id": self.current_dc_parameters["collection_id"], - "shape_id": self.get_current_shape_id(), - } - HWR.beamline.detector.set_image_appendix(json.dumps(img_appendix)) - - if self.current_dc_parameters["experiment_type"] == "Mesh": - self.start_spot_finder( - oscillation_parameters["exposure_time"], - file_parameters["directory"], - image_file_template, - ) - - return HWR.beamline.detector.prepare_acquisition(config) - - def start_spot_finder(self, exp_time, path, prefix="mesh"): - """ - Launch ZMQ client and spot finding on the HPC - """ - self.stop_spot_finder() - os.system( - "python /mxn/groups/biomax/wmxsoft/scripts_mxcube/spot_finder/start_spot_finder.py \ - -t %s -d %s -p %s -H clu0-fe-0 &" - % (exp_time, path, prefix) - ) - logging.getLogger("HWR").info( - "starting spot finder on the HPC...... python /mxn/groups/biomax/wmxsoft/scripts_mxcube/spot_finder/start_spot_finder.py \ - -t %s -d %s -p %s -H clu0-fe-0 &" - % (exp_time, path, prefix) - ) - - return - - def stop_spot_finder(self): - """ - Stop ZMQ client and spot finding server on the HPC - """ - os.system( - "/mxn/groups/biomax/wmxsoft/scripts_mxcube/spot_finder/cancel_spot_finder.sh" - ) - return - - def stop_collect(self, owner): - """ - Stops data collection - """ - logging.getLogger("HWR").error("Stopping collection ....") - HWR.beamline.diffractometer.abort() - HWR.beamline.detector.cancel() - HWR.beamline.detector.disarm() - if self.current_dc_parameters["experiment_type"] == "Mesh": - # disable stream interface - # stop spot finding - HWR.beamline.detector.disable_stream() - self.stop_spot_finder() - if self.data_collect_task is not None: - self.data_collect_task.kill(block=False) - logging.getLogger("HWR").error("Collection stopped") - self.stop_display = True - - def get_undulators_gaps(self): - """ - Descript. : - """ - # todo - return None - - def get_slit_gaps(self): - """ - Descript. : - """ - try: - return HWR.beamline.beam.get_beam_size() - except Exception: - return None - - def get_machine_current(self): - """ - Descript. : - """ - try: - return HWR.beamline.machine_info.get_current() - except Exception: - return None - - def get_machine_message(self): - """ - Descript. : - """ - # todo - return "" - - def get_machine_fill_mode(self): - """ - Descript. : - """ - try: - return HWR.beamline.machine_info.getFillingMode() - except Exception: - return "" - - def prepare_for_new_sample(self, manual_mode=True): - """ - Descript.: prepare beamline for a new sample, - """ - logging.getLogger("HWR").info("[HWR] Preparing beamline for a new sample.") - if manual_mode: - if self.detector_cover_hwobj is not None: - self.close_detector_cover() - HWR.beamline.diffractometer.set_phase("Transfer", wait=False) - if ( - HWR.beamline.safety_shutter is not None - and HWR.beamline.safety_shutter.getShutterState() == "opened" - ): - self.close_safety_shutter() - HWR.beamline.detector.distance.set_value(800) - - def _update_image_to_display(self): - fname1 = "/mxn/groups/biomax/wmxsoft/auto_load_img_cc/to_display" - fname2 = "/mxn/groups/biomax/ctrl_soft/auto_load_img_cc/to_display" - time.sleep(self.display["delay"] + 3) - frequency = 5 - step = int(math.ceil(frequency / self.display["exp"])) - if step == 1: - frequency = self.display["exp"] - for i in range(1, self.display["nimages"] + 1, step): - # if self.stop_display: - # break - # time.sleep(frequency) - try: - os.system("echo %s, %s > %s" % (self.display["file_name1"], i, fname1)) - os.system("echo %s, %s > %s" % (self.display["file_name2"], i, fname2)) - except Exception as ex: - print(ex) - if self.stop_display: - break - time.sleep(frequency) - - def enable_datacatalog(self, enable): - self.datacatalog_enabled = enable - - def store_datacollection_uuid_datacatalog(self): - msg = {} - collection = self.current_dc_parameters - proposal_code = HWR.beamline.session.proposal_code - proposal_number = HWR.beamline.session.proposal_number - - proposal_info = HWR.beamline.lims.get_proposal(proposal_code, proposal_number) - msg["time"] = time.time() - msg["proposal"] = proposal_number - msg["uuid"] = self.collection_uuid - msg["beamline"] = "BioMAX" - msg["event"] = "biomax-experiment-began" - msg["directory"] = collection.get("fileinfo").get("directory") - - logging.getLogger("HWR").info( - "[HWR] Sending collection started info to the data catalog: %s" % msg - ) - proxies = {"http": None, "https": None} - - if self.datacatalog_url: - try: - requests.post( - self.datacatalog_url, data=json.dumps(msg), proxies=proxies - ) - except Exception as ex: - logging.getLogger("HWR").error( - "[HWR] Error sending collection started info to the data catalog: %s %s" - % (self.datacatalog_url, ex) - ) - else: - logging.getLogger("HWR").error( - "[HWR] Error sending collection started info to the data catalog: No datacatalog URL specified" - ) - - def store_datacollection_datacatalog(self): - """ - Send the data collection parameters to the data catalog. In the form: - """ - msg = {} - # files = [] - collection = self.current_dc_parameters - proposal_code = HWR.beamline.session.proposal_code - proposal_number = HWR.beamline.session.proposal_number - - proposal_info = HWR.beamline.lims.get_proposal(proposal_code, proposal_number) - # session info is missing! - sessionId = collection.get("sessionId", None) - if sessionId: - session_info = HWR.beamline.lims.get_session(sessionId) - proposal_info["Session"] = session_info - else: - # We do not send this info when the commissioning is the fake proposal - return - - collection["proposalInfo"] = proposal_info - - # the following lines are fot helping with serialization - try: - collection["proposalInfo"]["Session"]["lastUpdate"] = collection[ - "proposalInfo" - ]["Session"]["lastUpdate"].isoformat() - collection["proposalInfo"]["Session"]["timeStamp"] = collection[ - "proposalInfo" - ]["Session"]["timeStamp"].isoformat() - except Exception: - if "Session" in collection["proposalInfo"].keys(): - collection["proposalInfo"]["Session"]["lastUpdate"] = "" - collection["proposalInfo"]["Session"]["timeStamp"] = "" - try: - # Default of 100 images per h5 file. TODO: move to xml config - num_files = int( - math.ceil( - collection["oscillation_sequence"][0]["number_of_images"] / 100.0 - ) - ) - except Exception as ex: - logging.getLogger("HWR").error("[HWR] Error during data catalog: %s" % ex) - num_files = -1 - - collection["fileinfo"]["num_files"] = num_files # num_images per files - proxies = {"http": None, "https": None} - - # files.append(collection.get('fileinfo').get('filename')) # this is the - # master file - template = collection.get("fileinfo").get("template") - directory = collection.get("fileinfo").get("directory") - # for num in range(1, num_files + 1): - # files.append(os.path.join(directory, template % num)) - # now we build the dict as hannes requested - msg["event"] = "biomax-experiment-ended" - msg["proposal"] = proposal_number - msg["uuid"] = self.collection_uuid - msg["beamline"] = proposal_info.get("Session", {}).get("beamlineName", "") - msg["directory"] = directory - # msg['files'] = files - msg["scientific"] = collection - - logging.getLogger("HWR").info( - "[HWR] Sending collection info to the data catalog: %s" % msg - ) - - if self.datacatalog_url: - try: - requests.post( - self.datacatalog_url, data=json.dumps(msg), proxies=proxies - ) - except Exception as ex: - logging.getLogger("HWR").error( - "[HWR] Error sending collection info to the data catalog: %s %s" - % (self.datacatalog_url, ex) - ) - else: - logging.getLogger("HWR").error( - "[HWR] Error sending collection info to the data catalog: No datacatalog URL specified" - ) diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py deleted file mode 100644 index 95f15334f6..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py +++ /dev/null @@ -1,797 +0,0 @@ -""" - - File: BIOMAXEiger.py - - Description: This module implements the hardware object for the Eiger detector - based on a Tango device server - - -Detector Status: ------------------ - -hardware status: - ready: ready for trigger (this is the state after an "Arm" command) - idle: ready for config (this should be the state after a "Disarm" command) - -hardware object status: - - configuring: a configuration task is ongoing - - -""" -from __future__ import print_function - -import copy -import logging -import time - -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task - - -class BIOMAXEiger(HardwareObject): - """ - Description: Eiger hwobj based on tango - """ - - def __init__(self, *args): - """ - Descrip. : - """ - super().__init__(*args) - - self.device = None - self.file_suffix = None - self.default_exposure_time = None - self.default_compression = None - self.buffer_limit = None - self.dcu = None - self.config_state = None - self.initialized = False - self.status_chan = None - - # defaults - self.energy_change_threshold_default = 20 - - def init(self): - tango_device = self.get_property("detector_device") - filewriter_device = self.get_property("filewriter_device") - - self.file_suffix = self.get_property("file_suffix") - self.default_exposure_time = self.get_property("default_exposure_time") - self.default_compression = self.get_property("default_compression") - self.buffer_limit = self.get_property("buffer_limit") - self.dcu = self.get_property("dcu") - - # not all of the following attr are needed, for now all of them here for - # convenience - attr_list = ( - "NbImages", - "Temperature", - "Humidity", - "CountTime", - "FrameTime", - "PhotonEnergy", - "Wavelength", - "EnergyThreshold", - "FlatfieldEnabled", - "AutoSummationEnabled", - "TriggerMode", - "RateCorrectionEnabled", - "BitDepth", - "ReadoutTime", - "Description", - "NbImagesMax", - "NbImagesMin", - "CountTimeMax", - "CountTimeMin", - "FrameTimeMax", - "FrameTimeMin", - "PhotonEnergyMax", - "PhotonEnergyMin", - "EnergyThresholdMax", - "EnergyThresholdMin", - "Time", - "NbTriggers", - "NbTriggersMax", - "XPixelSize", - "YPixelSize", - "NbTriggersMin", - "CountTimeInte", - "DownloadDirectory", - "FilesInBuffer", - "Error", - "BeamCenterX", - "BeamCenterY", - "DetectorDistance", - "OmegaIncrement", - "OmegaStart", - "Compression", - "RoiMode", - "State", - "Status", - "XPixelsDetector", - "YPixelsDetector", - "CollectionUUID", - "RoiMode", - "HeaderDetail", - "HeaderAppendix", - "ImageAppendix", - "StreamState", - ) - - fw_list = ( - "FilenamePattern", - "ImagesPerFile", - "BufferFree", - "FileWriterState", - "ImageNbStart", - "Mode", - ) - - # config needed to be set up for data collection - # if values are None, use the one from the system - self.col_config = { - "OmegaStart": 0, - "OmegaIncrement": 0.1, - "BeamCenterX": None, # length not pixel - "BeamCenterY": None, - "DetectorDistance": None, - "CountTime": None, - "NbImages": None, - "NbTriggers": None, - "ImagesPerFile": None, - "RoiMode": None, - "FilenamePattern": None, - "PhotonEnergy": None, - "TriggerMode": "exts", - } - - # not all of the following commands are needed, for now all of them here - # for convenience - cmd_list = ( - "Arm", - "Trigger", - "Abort", - "Cancel", - "ClearBuffer", - "DeleteFileFromBuffer", - "Disarm", - "DownloadFilesFromBuffer", - "EnableStream", - "DisableStream", - ) - - for channel_name in attr_list: - self.add_channel( - { - "type": "tango", - "name": channel_name, - "tangoname": tango_device, - "timeout": 10000, - }, - channel_name, - ) - - # we need to program timeout once in the device - # get any of the channels for that. - - for channel_name in fw_list: - self.add_channel( - {"type": "tango", "name": channel_name, "tangoname": filewriter_device}, - channel_name, - ) - - for cmd_name in cmd_list: - self.add_command( - { - "type": "tango", - "name": cmd_name, - "timeout": 8000, - "tangoname": tango_device, - }, - cmd_name, - ) - # init the detector settings in case of detector restart - # use bslz4 for compression () - - # we need to call the init device before accessing the channels here - # otherwise the initialization is triggered by the HardwareRepository Poller - # that is delayed after the application starts - - try: - self.energy_change_threshold = float( - self.get_property("min_trigger_energy_change") - ) - except Exception: - self.energy_change_threshold = self.energy_change_threshold_default - - self.get_channel_object("Compression").init_device() - self.get_channel_object("Compression").set_value("bslz4") - - # self.get_channel_object('TriggerMode').init_device() - # self.get_channel_object('TriggerMode').set_value("exts") - - # STATUS , status can be "idle", "ready", "UNKNOWN" - def get_status(self): - if self.status_chan is None: - self.status_chan = self.get_channel_object("Status") - - if self.status_chan is not None: - self.initialized = True - else: - return "not_init" - - return self.status_chan.get_value().split("\n")[0] - - def is_idle(self): - return self.get_status()[:4] == "idle" - - def is_ready(self): - return self.get_status()[:5] == "ready" - - def is_acquire(self): - return self.get_status() == "acquire" - - def is_preparing(self): - return self.config_state == "config" - - def prepare_error(self): - if self.config_state == "error": - return True - else: - return False - - def wait_ready(self, timeout=20): - with gevent.Timeout(timeout, RuntimeError("Detector not ready")): - while not self.is_ready(): - gevent.sleep(0.1) - - def wait_ready_or_idle(self): - with gevent.Timeout(20, RuntimeError("Detector neither ready or idle")): - while not (self.is_ready() or self.is_idle()): - logging.getLogger("HWR").debug( - "Waiting for the detector to be ready, current state: " - + self.get_status() - ) - gevent.sleep(0.25) - - def wait_idle(self): - with gevent.Timeout(20, RuntimeError("Detector not ready")): - while not self.is_idle(): - gevent.sleep(0.25) - - def wait_acquire(self): - with gevent.Timeout(20, RuntimeError("Detector not ready")): - while not self.is_acquire(): - gevent.sleep(0.25) - - def wait_buffer_ready(self): - with gevent.Timeout( - 20, RuntimeError("Detector free buffer size is lower than limit") - ): - while self.get_buffer_free() < self.buffer_limit: - gevent.sleep(0.25) - - def wait_config_done(self): - logging.getLogger("HWR").info("Waiting to configure the detector.") - with gevent.Timeout(30, RuntimeError("Detector configuration error")): - while self.is_preparing(): - gevent.sleep(0.1) - logging.getLogger("HWR").info("Detector configuration finished.") - - def wait_attribute_applied(self, att, new_val): - with gevent.Timeout( - 10, - RuntimeError( - "Timeout setting attr: %s to value %s, type: %s" - % (att, new_val, type(new_val)) - ), - ): - # format numbers to remove the precission comparison, 3 decimal enough? - # if type(new_val)== 'str' or type(new_val) == 'unicode': - # while self.get_channel_value(att) != new_val: - # gevent.sleep(0.1) - if att in [ - "FilenamePattern", - "HeaderDetail", - "HeaderAppendix", - "ImageAppendix", - ]: - while self.get_channel_value(att) != new_val: - gevent.sleep(0.1) - elif "BeamCenter" in att: - while format(self.get_channel_value(att), ".2f") != format( - new_val, ".2f" - ): - gevent.sleep(0.1) - else: - while format(self.get_channel_value(att), ".4f") != format( - new_val, ".4f" - ): - gevent.sleep(0.1) - - # STATUS END - - # GET INFORMATION - - def set_channel_value(self, name, value): - try: - logging.getLogger("HWR").debug( - "[DETECTOR] Setting value: %s for attribute %s" % (value, name) - ) - self.get_channel_object(name).set_value(value) - self.wait_attribute_applied(name, value) - except Exception as ex: - logging.getLogger("HWR").error(ex) - logging.getLogger("HWR").info( - "Cannot set value: %s for attribute %s" % (value, name) - ) - - def get_readout_time(self): - return self.get_channel_value("ReadoutTime") - - def get_acquisition_time(self): - frame_time = self.get_channel_value("FrameTime") - readout_time = self.get_channel_value("ReadoutTime") - nb_images = self.get_channel_value("NbImages") - time = nb_images * frame_time - readout_time - _count_time = self._config_vals.get("CountTime") - _nb_images = self._config_vals.get("NbImages") - logging.getLogger("HWR").debug( - "[DETECTOR] Configuration params: CounTime: %s, NbImages: %s" - % (_count_time, _nb_images) - ) - logging.getLogger("HWR").debug( - "[DETECTOR] Params applied IN the detector: FrameTime: %s, NbImages: %s" - % (frame_time, nb_images) - ) - if format(time, ".4f") != format( - _nb_images * _count_time - readout_time, ".4f" - ): - logging.getLogger("HWR").error( - "[DETECTOR] Acquisition time configuration wrong." - ) - logging.getLogger("HWR").info("Detector acquisition time: " + str(time)) - return time - - def get_buffer_free(self): - return self.get_channel_value("BufferFree") - - def get_roi_mode(self): - return self.get_channel_value("RoiMode") - - def get_pixel_size_x(self): - """ - return sizes of a single pixel along x-axis respectively - unit, mm - """ - # x_pixel_size = self.get_channel_object("XPixelSize") # unit, m - x_pixel_size = 0.000075 - return x_pixel_size * 1000 - - def get_pixel_size_y(self): - """ - return sizes of a single pixel along y-axis respectively - unit, mm - """ - # y_pixel_size = self.get_channel_object("YPixelSize") # unit, m - y_pixel_size = 0.000075 - return y_pixel_size * 1000 - - def get_x_pixels_in_detector(self): - """ - number of pixels along x-axis - numbers vary depending on the RoiMode - """ - return self.get_channel_value("XPixelsDetector") - - def get_y_pixels_in_detector(self): - """ - number of pixels along y-axis, - numbers vary depending on the RoiMode - """ - return self.get_channel_value("YPixelsDetector") - - def get_minimum_exposure_time(self): - return self.get_channel_value("FrameTimeMin") - self.get_readout_time() - - def get_sensor_thickness(self): - return # not available, self.get_channel_object("").get_value() - - def has_shutterless(self): - return True - - def get_collection_uuid(self): - return self.get_channel_value("CollectionUUID") - - def get_header_detail(self): - """ - Detail of header data to be sent. - """ - return self.get_channel_value("HeaderDetail") - - def get_header_appendix(self): - """ - Data that is appended to the header data - """ - return self.get_channel_value("HeaderAppendix") - - def get_image_appendix(self): - """ - Data that is appended to the image data - """ - return self.get_channel_value("ImageAppendix") - - def get_stream_state(self): - """ - "disabled", "ready", "acquire" or "error". - """ - return self.get_channel_value("StreamState") - - # GET INFORMATION END - - # SET VALUES - def set_photon_energy(self, energy): - """ - set photon_energy - Note, the readout_time will be changed - engery, in eV - """ - valid = self._validate_energy_value(energy) - - if valid == -1: - return False - elif valid == 0: - return True # is valid, but no need to change energy. continue - else: - self.set_channel_value("PhotonEnergy", energy) - return True - - def _validate_energy_value(self, energy): - try: - target_energy = float(energy) - except Exception: - # not a valid value - logging.getLogger("user_level_log").info("Wrong Energy value: %s" % energy) - return -1 - - max_energy = self.get_channel_value("PhotonEnergyMax") - min_energy = self.get_channel_value("PhotonEnergyMin") - current_energy = self.get_channel_value("PhotonEnergy") - - print(" - currently configured energy is: %s" % current_energy) - print(" - min val: %s / max val: %s " % (min_energy, max_energy)) - - if target_energy < min_energy or target_energy > max_energy: - print("Energy value out of limits: %s" % energy) - logging.getLogger("user_level_log").info( - "Energy value out of limits: %s" % energy - ) - return -1 - - if abs(energy - current_energy) > self.energy_change_threshold: - print("Energy difference over threshold. program energy necessary") - return 1 - else: - print("Energy difference below threshold. Do not need to program") - return 0 - - def set_energy_threshold(self, threshold): - """ - set energy_threshold - Note, the readout_time will be changed - By deafult, the value is 50% of the photon_energy and will be - updated upon setting PhotonEnergy. If other values are needed, - this should be set after changing PhotonEnergy. - Eengery, in eV - """ - self.set_channel_value("EnergyThreshold", threshold) - - def set_collection_uuid(self, col_uuid): - self.set_channel_value("CollectionUUID", col_uuid) - - def set_header_detail(self, value): - """ - Detail of header data to be sent. - """ - if value not in ["all", "basic", "none"]: - logging.getLogger("HWR").error("Cannot set stream header detail") - return - self.set_channel_value("HeaderDetail", value) - - def set_header_appendix(self, value): - """ - Data that is appended to the header data - """ - self.set_channel_value("HeaderAppendix", value) - - def set_image_appendix(self, value): - """ - Data that is appended to the image data - """ - self.set_channel_value("ImageAppendix", value) - - def set_roi_mode(self, value): - if value not in ["4M", "disabled"]: - logging.getLogger("HWR").error("Cannot set stream header detail") - return - return self.get_channel_value("RoiMode") - - # SET VALUES END - - def prepare_acquisition(self, config): - """ - config is a dictionary - OmegaStart,OmegaIncrement, - BeamCenterX - BeamCenterY - OmegaStart - OmegaIncrement - start, osc_range, exptime, ntrigger, number_of_images, images_per_file, - compression,ROI,wavelength): - """ - - logging.getLogger("user_level_log").info("Preparing acquisition") - - self.config_state = "config" - - self._config_vals = copy.copy(config) - # self._config_task = gevent.spawn(self._prepare_acquisition_sequence) - # self._config_task.link(self._configuration_done) - # self._config_task.link_exception(self._configuration_failed) - try: - self._prepare_acquisition_sequence() - except Exception as ex: - print(ex) - self._configuration_failed() - else: - self._configuration_done() - - def _configuration_done(self): # (self, gl) - logging.getLogger("HWR").info("Detector configuration done") - self.config_state = None - - def _configuration_failed(self): # (self, gl) - self.config_state = "error" - logging.getLogger("HWR").error("Could not configure detector") - RuntimeError("Could not configure detector") - - def _prepare_acquisition_sequence(self): - if not self.is_idle(): - self.stop_acquisition() - - self.wait_idle() - - logging.getLogger("HWR").info( - "Ok. detector is idle. Continuing with configuration" - ) - logging.getLogger("HWR").info(self._config_vals) - if "PhotonEnergy" in self._config_vals.keys(): - new_egy = self._config_vals["PhotonEnergy"] - if new_egy is not None: - if self.set_photon_energy(new_egy) is False: - raise Exception("Could not program energy in detector") - if "CountTime" in self._config_vals.keys(): - self.set_channel_value("CountTime", self._config_vals["CountTime"]) - print( - "readout time and count time is ", - self.get_readout_time(), - self.get_channel_value("CountTime"), - ) - self.set_channel_value( - "FrameTime", self._config_vals["CountTime"] + self.get_readout_time() - ) - print("new frame time is ", self.get_channel_value("FrameTime")) - for cfg_name, cfg_value in self._config_vals.items(): - t0 = time.time() - if cfg_name == "PhotonEnergy" or cfg_name == "CountTime": - continue # already handled above - - logging.getLogger("HWR").info( - "Detector: configuring %s: %s" % (cfg_name, cfg_value) - ) - if cfg_value is None or cfg_value == "": - continue - - if cfg_value is not None: - if self.get_channel_value(cfg_name) != cfg_value: - self.set_channel_value(cfg_name, cfg_value) - if cfg_name == "RoiMode": - self.emit("roiChanged") - else: - print(" - value does need to change") - else: - logging.getLogger("HWR").error( - "Could not config value %s for detector. Not such channel" - % cfg_name - ) - logging.getLogger("HWR").info( - "Detector parameter configuration took %s seconds" % (time.time() - t0) - ) - - @task - def start_acquisition(self): - """ - Before starting the acquisition a prepare_acquisition should be issued - After prepare_acquisition the detector should be in "idle" state - - Otherwise you will have to send a "disarm" command by hand to be able to - start an acquisition - """ - - self.wait_buffer_ready() - - if not self.is_idle(): - RuntimeError("Detector should be idle before starting a new acquisition") - - self.config_state = None - - logging.getLogger("user_level_log").info("Detector going to arm") - - return self.arm() - - def stop_acquisition(self): - """ - when use external trigger, Disarm is required, otherwise the last h5 will - not be released and not available in WebDAV. - """ - - logging.getLogger("HWR").info("[DETECTOR] Stop acquisition, waiting...") - self.wait_ready_or_idle() - - try: - self.cancel() - # this is needed as disarm in tango device server does not seem to work - # as expected. the disarm command in the simpleinterface is always working - # when called from Tango it does not. Once bug is solved in tango server, the - # call to "cancel()" is not necessary here - self.disarm() - logging.getLogger("HWR").info( - "[DETECTOR] Stop acquisition, detector canceled and disarmed." - ) - except Exception: - pass - - def cancel_acquisition(self): - """Cancel acquisition""" - logging.getLogger("HWR").info("[DETECTOR] Cancelling acquisition") - try: - self.cancel() - except Exception: - pass - - time.sleep(1) - self.disarm() - - def arm(self): - logging.getLogger("HWR").info("[DETECTOR] Arm command requested") - cmd = self.get_command_object("Arm") - cmd.set_device_timeout(10000) - cmd() - self.wait_ready() - logging.getLogger("HWR").info( - "[DETECTOR] Arm command executed, new state of the dectector: " - + self.get_status() - ) - logging.getLogger("user_level_log").info("Detector armed") - - def trigger(self): - self.get_command_object("Trigger")() - - def disarm(self): - self.get_command_object("Disarm")() - - def enable_stream(self): - self.get_command_object("EnableStream")() - - def disable_stream(self): - self.get_command_object("DisableStream")() - - def cancel(self): - self.get_command_object("Cancel")() - - def abort(self): - try: - self.get_command_object("Abort")() - except Exception: - pass - - -def test(): - import os - import sys - - if len(sys.argv) != 5: - print( - "Usage: %s triggermode (exts/ints) nb_images exp_time energy" % sys.argv[0] - ) - sys.exit(0) - else: - try: - trigmode = sys.argv[1] - nimages = float(sys.argv[2]) - exptime = float(sys.argv[3]) - egy = float(sys.argv[4]) - except ValueError: - print("Cannot decode parameters. Aborting") - sys.exit(0) - - if trigmode not in ["exts", "ints"]: - print('Bad trigger mode. It should be "exts" or "ints"') - sys.exit(0) - - hwr = HWR.get_hardware_repository() - hwr.connect() - detector = HWR.beamline.detector - - config = { - "OmegaStart": 0, - "OmegaIncrement": 0.1, - "BeamCenterX": None, # length not pixel - "BeamCenterY": None, - "DetectorDistance": None, - "FrameTime": exptime, - "NbImages": nimages, - "NbTriggers": None, - "ImagesPerFile": None, - "RoiMode": "4M", - "FilenamePattern": None, - "PhotonEnergy": egy, - "TriggerMode": trigmode, - } - - if detector.get_status() == "not_init": - print("Cannot initialize hardware object") - sys.exit(0) - - if not detector.is_idle(): - detector.stop_acquisition() - detector.wait_idle() - - detector.prepare_acquisition(config) - - print("Waiting for configuration finished") - - while detector.is_preparing(): - gevent.wait(timeout=0.1) - gevent.sleep(0.1) - print(".") - - if detector.prepare_error(): - print("Prepare went wrong. Aborting") - sys.exit(0) - - readout_time = detector.get_readout_time() - print("EIGER configuration done") - - print("Starting acquisition (trigmode = %s)" % trigmode) - if trigmode == "exts": - total_time = nimages * (exptime + readout_time) - print("Total exposure time (estimated) will be: %s", total_time) - - try: - detector.start_acquisition() - - if trigmode == "exts": - print(" - waiting for trigger.") - sys.stdout.flush() - detector.wait_acquire() - print(" - trigger received. Acquiring") - detector.wait_ready_or_idle() - else: - detector.trigger() - detector.wait_ready_or_idle() - - detector.stop_acquisition() - print("Acquisition done") - except KeyboardInterrupt: - detector.abort() - detector.wait_idle() - - -if __name__ == "__main__": - test() diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py deleted file mode 100644 index c523768d69..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXEnergy.py +++ /dev/null @@ -1,68 +0,0 @@ -import logging - -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects import Energy - - -class BIOMAXEnergy(Energy.Energy): - def __init__(self, *args, **kwargs): - Energy.Energy.__init__(self, *args, **kwargs) - - def init(self): - self.ready_event = gevent.event.Event() - self.tunable = False - self.moving = None - self.default_en = None - self.ctrl = None - self.en_lims = [] - - try: - self.default_en = self.get_property("default_energy") - except KeyError: - logging.getLogger("HWR").warning("Energy: no default energy") - - try: - self.tunable = self.get_property("tunable_energy") - except KeyError: - logging.getLogger("HWR").warning("Energy: will set to fixed energy") - - try: - self.ctrl = self.get_object_by_role("controller") - except KeyError: - logging.getLogger("HWR").info("No controller used") - - if HWR.beamline.energy is not None: - HWR.beamline.energy.connect("valueChanged", self.energyPositionChanged) - HWR.beamline.energy.connect("stateChanged", self.energyStateChanged) - - # def get_current_energy(self): - # if HWR.beamline.energy is not None: - # try: - # return HWR.beamline.energy.get_value() / 1000 - # except Exception: - # logging.getLogger("HWR").exception( - # "EnergyHO: could not read current energy" - # ) - # return None - # return self.default_en - - def get_limits(self): - if not self.tunable: - return None - - if HWR.beamline.energy is not None: - try: - self.en_lims = HWR.beamline.energy.get_limits() - self.en_lims = ( - float(self.en_lims[0]) / 1000, - float(self.en_lims[1]) / 1000, - ) - return self.en_lims - except Exception: - logging.getLogger("HWR").exception( - "EnergyHO: could not read energy motor limits" - ) - return None - return None diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py deleted file mode 100644 index 955bd9306d..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXKafka.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -A client for Biomax Kafka services. -""" - -import json -import logging -import re -import time -import uuid - -import requests - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject - - -class BIOMAXKafka(HardwareObject): - """ - Web-service client for Kafka services. - Example xml file: - - my_host.maxiv.lu.se - biomax - - - """ - - def __init__(self, name): - HardwareObject.__init__(self, name) - self.kafka_server = None - self.topic = "" - - def init(self): - """ - Init method declared by HardwareObject. - """ - self.kafka_server = self.get_property("kafka_server") - self.topic = self.get_property("topic") - self.beamline_name = HWR.beamline.session.beamline_name - self.file = open("/tmp/kafka_errors.txt", "a") - self.url = self.kafka_server + "/kafka" - - logging.getLogger("HWR").info("KAFKA link initialized.") - - def key_is_snake_case(sel, k): - return "_" in k - - def snake_to_camel(self, text): - return re.sub("_([a-zA-Z0-9])", lambda m: m.group(1).upper(), text) - - def send_data_collection(self, collection_data): - d = dict() - - d.update( - { - "uuid": str(uuid.uuid4()), - "beamline": self.beamline_name, - "proposal": HWR.beamline.session.get_proposal(), # e.g. MX20170251 - "session": HWR.beamline.session.get_session_start_date(), # 20171206 - "userCategory": "visitors", # HWR.beamline.session.get_user_category() #staff or visitors - "_v": "0", - } - ) - - collection_data.update(d) - - for k in collection_data.keys(): - if self.key_is_snake_case(k): - collection_data[self.snake_to_camel(k)] = collection_data.pop(k) - - data = json.dumps(collection_data) - - try: - requests.post(self.url, data=data) - logging.getLogger("HWR").info( - "Pushed data collection info to KAFKA, UUID: %s" - % collection_data["uuid"] - ) - except Exception as ex: - self.file.write(time.strftime("%d %b %Y %H:%M:%S", time.gmtime()) + "\n") - self.file.write(data + "\n") - self.file.write(50 * "#" + "\n") - self.file.flush() - logging.getLogger("HWR").error( - "KAFKA link error. %s; data saved to /tmp/kafka_errors.txt" % str(ex) - ) diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py deleted file mode 100644 index 47c04bfa59..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py +++ /dev/null @@ -1,650 +0,0 @@ -""" - -BIOMAXMinidiff (MD3) - -""" - -import io -import logging -import math -import time - -import gevent -import lucid2 as lucid -import numpy as np -from PIL import Image - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects.GenericDiffractometer import ( - DiffractometerState, - GenericDiffractometer, -) - - -class BIOMAXMD3(GenericDiffractometer): - - MOTOR_TO_EXPORTER_NAME = { - "focus": "AlignmentX", - "kappa": "Kappa", - "kappa_phi": "Phi", - "phi": "Omega", - "phiy": "AlignmentY", - "phiz": "AlignmentZ", - "sampx": "CentringX", - "sampy": "CentringY", - "zoom": "Zoom", - } - - AUTOMATIC_CENTRING_IMAGES = 6 - - def __init__(self, *args): - """ - Description: - """ - GenericDiffractometer.__init__(self, *args) - # Compatibility line - self.C3D_MODE = GenericDiffractometer.CENTRING_METHOD_AUTO - self.MANUAL3CLICK_MODE = "Manual 3-click" - - def init(self): - - GenericDiffractometer.init(self) - - self.front_light = self.get_object_by_role("frontlight") - self.back_light = self.get_object_by_role("backlight") - self.back_light_switch = self.get_object_by_role("backlightswitch") - self.front_light_switch = self.get_object_by_role("frontlightswitch") - - self.centring_hwobj = self.get_object_by_role("centring") - if self.centring_hwobj is None: - logging.getLogger("HWR").debug("EMBLMinidiff: Centring math is not defined") - - self.phi_motor_hwobj = self.motor_hwobj_dict["phi"] - self.phiz_motor_hwobj = self.motor_hwobj_dict["phiz"] - self.phiy_motor_hwobj = self.motor_hwobj_dict["phiy"] - self.zoom_motor_hwobj = self.motor_hwobj_dict["zoom"] - self.focus_motor_hwobj = self.motor_hwobj_dict["focus"] - self.sample_x_motor_hwobj = self.motor_hwobj_dict["sampx"] - self.sample_y_motor_hwobj = self.motor_hwobj_dict["sampy"] - try: - self.kappa_motor_hwobj = self.motor_hwobj_dict["kappa"] - except Exception: - self.kappa_motor_hwobj = None - try: - self.kappa_phi_motor_hwobj = self.motor_hwobj_dict["kappa_phi"] - except Exception: - self.kappa_phi_motor_hwobj = None - - self.cent_vertical_pseudo_motor = None - try: - self.cent_vertical_pseudo_motor = self.add_channel( - {"type": "exporter", "name": "CentringTableVerticalPositionPosition"}, - "CentringTableVerticalPosition", - ) - if self.cent_vertical_pseudo_motor is not None: - self.connect( - self.cent_vertcial_pseudo_motor, "update", self.centring_motor_moved - ) - except Exception: - logging.getLogger("HWR").warning( - "Cannot initialize CentringTableVerticalPosition" - ) - - try: - use_sc = self.get_property("use_sc") - self.set_use_sc(use_sc) - except Exception: - logging.getLogger("HWR").debug("Cannot set sc mode, use_sc: ", str(use_sc)) - - try: - self.zoom_centre = eval(self.get_property("zoom_centre")) - zoom = HWR.beamline.sample_view.camera.get_image_zoom() - if zoom is not None: - self.zoom_centre["x"] = self.zoom_centre["x"] * zoom - self.zoom_centre["y"] = self.zoom_centre["y"] * zoom - self.beam_position = [self.zoom_centre["x"], self.zoom_centre["y"]] - HWR.beamline.beam.set_beam_position(self.beam_position) - except Exception: - self.zoom_centre = {"x": 0, "y": 0} - logging.getLogger("HWR").warning( - "BIOMAXMD3: " + "zoom centre not configured" - ) - - def current_phase_changed(self, current_phase): - """ - Descript. : - """ - self.current_phase = current_phase - logging.getLogger("HWR").info("MD3 phase changed to %s" % current_phase) - self.emit("phaseChanged", (current_phase,)) - - def start3ClickCentring(self): - self.start_centring_method(self.CENTRING_METHOD_MANUAL) - - def startAutoCentring(self): - self.start_centring_method(self.CENTRING_METHOD_AUTO) - - def get_pixels_per_mm(self): - """ - Get the values from coaxCamScaleX and coaxCamScaleY channels diretly - - :returns: list with two floats - """ - zoom = HWR.beamline.sample_view.camera.get_image_zoom() - # return (0.5/self.channel_dict["CoaxCamScaleX"].get_value(), - # 0.5/self.channel_dict["CoaxCamScaleY"].get_value()) - return ( - zoom / self.channel_dict["CoaxCamScaleX"].get_value(), - 1 / self.channel_dict["CoaxCamScaleY"].get_value(), - ) - - def update_zoom_calibration(self): - """ - """ - # self.pixels_per_mm_x = 0.5/self.channel_dict["CoaxCamScaleX"].get_value() - # self.pixels_per_mm_y = 0.5/self.channel_dict["CoaxCamScaleY"].get_value() - zoom = HWR.beamline.sample_view.camera.get_image_zoom() - self.pixels_per_mm_x = zoom / self.channel_dict["CoaxCamScaleX"].get_value() - self.pixels_per_mm_y = zoom / self.channel_dict["CoaxCamScaleY"].get_value() - - def manual_centring(self): - """ - Descript. : - """ - self.centring_hwobj.initCentringProcedure() - for click in range(3): - self.user_clicked_event = gevent.event.AsyncResult() - x, y = self.user_clicked_event.get() - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) / self.pixels_per_mm_y, - } - ) - if self.in_plate_mode(): - dynamic_limits = self.phi_motor_hwobj.get_dynamic_limits() - if click == 0: - self.phi_motor_hwobj.set_value(dynamic_limits[0]) - elif click == 1: - self.phi_motor_hwobj.set_value(dynamic_limits[1]) - else: - if click < 2: - self.phi_motor_hwobj.set_value_relative(90) - self.omega_reference_add_constraint() - return self.centring_hwobj.centeredPosition(return_by_name=False) - - def automatic_centring_old(self): - """Automatic centring procedure. Rotates n times and executes - centring algorithm. Optimal scan position is detected. - """ - - surface_score_list = [] - self.zoom_motor_hwobj.moveToPosition("Zoom 1") - self.wait_device_ready(3) - self.centring_hwobj.initCentringProcedure() - for image in range(BIOMAXMD3.AUTOMATIC_CENTRING_IMAGES): - x, y, score = self.find_loop() - if x > -1 and y > -1: - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) / self.pixels_per_mm_y, - } - ) - surface_score_list.append(score) - self.phi_motor_hwobj.set_value_relative( - 360.0 / BIOMAXMD3.AUTOMATIC_CENTRING_IMAGES, timeout=5 - ) - self.omega_reference_add_constraint() - return self.centring_hwobj.centeredPosition(return_by_name=False) - - def automatic_centring(self): - """Automatic centring procedure. Rotates n times and executes - centring algorithm. Optimal scan position is detected. - """ - - # check if loop is there at the beginning - i = 0 - while -1 in self.find_loop(): - self.phi_motor_hwobj.set_value_relative(90, timeout=5) - i += 1 - if i > 4: - self.emit_progress_message("No loop detected, aborting") - return - - for k in range(3): - self.emit_progress_message("Doing automatic centring") - surface_score_list = [] - self.centring_hwobj.initCentringProcedure() - for a in range(3): - x, y, score = self.find_loop() - logging.info("in autocentre, x=%f, y=%f", x, y) - if x < 0 or y < 0: - for i in range(1, 9): - # logging.info("loop not found - moving back %d" % i) - self.phi_motor_hwobj.set_value_relative(10, timeout=5) - x, y, score = self.find_loop() - surface_score_list.append(score) - if -1 in (x, y): - continue - if y >= 0: - if x < HWR.beamline.sample_view.camera.get_width() / 2: - x = 0 - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) - / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) - / self.pixels_per_mm_y, - } - ) - break - else: - x = HWR.beamline.sample_view.camera.get_width() - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) - / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) - / self.pixels_per_mm_y, - } - ) - break - if -1 in (x, y): - raise RuntimeError("Could not centre sample automatically.") - self.phi_motor_hwobj.set_value_relative(-i * 10, timeout=5) - else: - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) / self.pixels_per_mm_y, - } - ) - self.phi_motor_hwobj.set_value_relative(90) - self.wait_device_ready(5) - - self.omega_reference_add_constraint() - centred_pos = self.centring_hwobj.centeredPosition(return_by_name=False) - if k < 2: - self.move_to_centred_position(centred_pos) - self.wait_device_ready(5) - return centred_pos - - def find_loop(self): - """ - Description: - """ - imgStr = HWR.beamline.sample_view.camera.get_snapshot_img_str() - image = Image.open(io.BytesIO(imgStr)) - try: - img = np.array(image) - img_rot = np.rot90(img, 1) - info, y, x = lucid.find_loop( - np.array(img_rot, order="C"), IterationClosing=6 - ) - x = HWR.beamline.sample_view.camera.get_width() - x - except Exception: - return -1, -1, 0 - if info == "Coord": - surface_score = 10 - return x, y, surface_score - else: - return -1, -1, 0 - - def omega_reference_add_constraint(self): - """ - Descript. : - """ - if self.omega_reference_par is None or self.beam_position is None: - return - if self.omega_reference_par["camera_axis"].lower() == "x": - on_beam = ( - (self.beam_position[0] - self.zoom_centre["x"]) - * self.omega_reference_par["direction"] - / self.pixels_per_mm_x - + self.omega_reference_par["position"] - ) - else: - on_beam = ( - (self.beam_position[1] - self.zoom_centre["y"]) - * self.omega_reference_par["direction"] - / self.pixels_per_mm_y - + self.omega_reference_par["position"] - ) - self.centring_hwobj.appendMotorConstraint(self.omega_reference_motor, on_beam) - - def omega_reference_motor_moved(self, pos): - """ - Descript. : - """ - if self.omega_reference_par["camera_axis"].lower() == "x": - pos = ( - self.omega_reference_par["direction"] - * (pos - self.omega_reference_par["position"]) - * self.pixels_per_mm_x - + self.zoom_centre["x"] - ) - self.reference_pos = (pos, -10) - else: - pos = ( - self.omega_reference_par["direction"] - * (pos - self.omega_reference_par["position"]) - * self.pixels_per_mm_y - + self.zoom_centre["y"] - ) - self.reference_pos = (-10, pos) - self.emit("omegaReferenceChanged", (self.reference_pos,)) - - def motor_positions_to_screen(self, centred_positions_dict): - """ - Descript. : - """ - c = centred_positions_dict - - if self.head_type == GenericDiffractometer.HEAD_TYPE_MINIKAPPA: - kappa = self.motor_hwobj_dict["kappa"] - phi = self.motor_hwobj_dict["kappa_phi"] - - # if (c['kappa'], c['kappa_phi']) != (kappa, phi) \ - # and self.minikappa_correction_hwobj is not None: - # c['sampx'], c['sampy'], c['phiy'] = self.minikappa_correction_hwobj.shift( - # c['kappa'], c['kappa_phi'], [c['sampx'], c['sampy'], c['phiy']], kappa, - # phi) - xy = self.centring_hwobj.centringToScreen(c) - # x = (xy['X'] + c['beam_x']) * self.pixels_per_mm_x + \ - x = xy["X"] * self.pixels_per_mm_x + self.zoom_centre["x"] - # y = (xy['Y'] + c['beam_y']) * self.pixels_per_mm_y + \ - y = xy["Y"] * self.pixels_per_mm_y + self.zoom_centre["y"] - return x, y - - def osc_scan(self, start, end, exptime, wait=False): - if self.in_plate_mode(): - scan_speed = math.fabs(end - start) / exptime - # todo, JN, get scan_speed limit - """ - low_lim, hi_lim = map(float, self.scanLimits(scan_speed)) - if start < low_lim: - raise ValueError("Scan start below the allowed value %f" % low_lim) - elif end > hi_lim: - raise ValueError("Scan end abobe the allowed value %f" % hi_lim) - """ - scan_params = "1\t%0.3f\t%0.3f\t%0.4f\t1" % (start, (end - start), exptime) - scan = self.command_dict["startScanEx"] - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 oscillation requested, waiting device ready..., params " - + str(scan_params) - ) - self.wait_device_ready(200) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 oscillation requested, device ready." - ) - scan(scan_params) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 oscillation launched, waiting for device ready." - ) - # if wait: - time.sleep(0.1) - self.wait_device_ready(exptime + 30) # timeout of 5 min - logging.getLogger("HWR").info("[BIOMAXMD3] MD3 oscillation, device ready.") - - def osc_scan_4d(self, start, end, exptime, helical_pos, wait=False): - if self.in_plate_mode(): - scan_speed = math.fabs(end - start) / exptime - # todo, JN, get scan_speed limit - """ - low_lim, hi_lim = map(float, self.scanLimits(scan_speed)) - if start < low_lim: - raise ValueError("Scan start below the allowed value %f" % low_lim) - elif end > hi_lim: - raise ValueError("Scan end abobe the allowed value %f" % hi_lim) - """ - scan_params = "%0.3f\t%0.3f\t%0.4f\t" % (start, (end - start), exptime) - scan_params += "%0.3f\t" % helical_pos["1"]["phiy"] - scan_params += "%0.3f\t" % helical_pos["1"]["phiz"] - scan_params += "%0.3f\t" % helical_pos["1"]["sampx"] - scan_params += "%0.3f\t" % helical_pos["1"]["sampy"] - scan_params += "%0.3f\t" % helical_pos["2"]["phiy"] - scan_params += "%0.3f\t" % helical_pos["2"]["phiz"] - scan_params += "%0.3f\t" % helical_pos["2"]["sampx"] - scan_params += "%0.3f\t" % helical_pos["2"]["sampy"] - - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 helical oscillation requested, waiting device ready..., params " - + str(scan_params) - ) - scan = self.command_dict["startScan4DEx"] - time.sleep(0.1) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 helical oscillation requested, device ready." - ) - scan(scan_params) - self.wait_device_ready(exptime + 30) - if wait: - self.wait_device_ready(900) # timeout of 5 min - - def raster_scan( - self, - start, - end, - exptime, - vertical_range, - horizontal_range, - nlines, - nframes, - invert_direction=1, - wait=False, - ): - """ - raster_scan: snake scan by default - start, end, exptime are the parameters per line - Note: vertical_range and horizontal_range unit is mm, a test value could be 0.1,0.1 - example, raster_scan(20, 22, 5, 0.1, 0.1, 10, 10) - """ - if self.in_plate_mode(): - scan_speed = math.fabs(end - start) / exptime - # todo, JN, get scan_speed limit - """ - low_lim, hi_lim = map(float, self.scanLimits(scan_speed)) - if start < low_lim: - raise ValueError("Scan start below the allowed value %f" % low_lim) - elif end > hi_lim: - raise ValueError("Scan end abobe the allowed value %f" % hi_lim) - """ - - logging.getLogger("HWR").info("[BIOMAXMD3] MD3 raster oscillation requested") - msg = "[BIOMAXMD3] MD3 raster scan params:" - msg += " start: %s, end: %s, exptime: %s, range: %s, nframes: %s" % ( - start, - end, - exptime, - end - start, - nframes, - ) - logging.getLogger("HWR").info(msg) - - self.channel_dict["ScanStartAngle"].set_value(start) - self.channel_dict["ScanExposureTime"].set_value(exptime) - self.channel_dict["ScanRange"].set_value(end - start) - self.channel_dict["ScanNumberOfFrames"].set_value(nframes) - - raster_params = "%0.5f\t%0.5f\t%i\t%i\t%i" % ( - vertical_range, - horizontal_range, - nlines, - nframes, - invert_direction, - ) - - raster = self.command_dict["startRasterScan"] - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 raster oscillation requested, params: %s" % (raster_params) - ) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 raster oscillation requested, waiting device ready" - ) - - self.wait_device_ready(200) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 raster oscillation requested, device ready." - ) - raster(raster_params) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 raster oscillation launched, waiting for device ready." - ) - time.sleep(0.1) - self.wait_device_ready(exptime * nlines + 30) - logging.getLogger("HWR").info( - "[BIOMAXMD3] MD3 finish raster scan, device ready." - ) - - def keep_position_after_phase_change(self, new_phase): - """ - Check if MD3 should keep the current position after changing phase - """ - current_phase = self.get_current_phase() - if current_phase == "DataCollection" and new_phase == "Centring": - return True - - # Probably not needed - # if current_phase == "Centring" and new_phase == "DataCollection": - # return True - - return False - - def set_phase(self, phase, wait=False, timeout=None): - keep_position = self.keep_position_after_phase_change(phase) - current_positions = {} - motors = [ - "phi", - "focus", - "phiz", - "phiy", - "sampx", - "sampy", - "kappa", - "kappa_phi", - ] - motors_dict = {} - if keep_position: - for motor in motors: - try: - current_positions[motor] = self.motor_hwobj_dict[motor].get_value() - except Exception: - pass - try: - self.wait_device_ready(10) - except Exception as ex: - logging.getLogger("HWR").error( - "[BIOMAXMD3] Cannot change phase to %s, timeout waiting for MD3 ready, %s" - % (phase, ex) - ) - logging.getLogger("user_log").error( - "[MD3] Cannot change phase to %s, timeout waiting for MD3 ready" % phase - ) - else: - self.command_dict["startSetPhase"](phase) - if keep_position: - self.move_sync_motors(current_positions) - if wait: - if not timeout: - timeout = 40 - self.wait_device_ready(timeout) - - # def move_sync_motors(self, motors_dict, wait=False, timeout=None): - def move_sync_motors(self, motors_dict, wait=True, timeout=30): - argin = "" - logging.getLogger("HWR").debug( - "BIOMAXMD3: in move_sync_motors, wait: %s, motors: %s, tims: %s " - % (wait, motors_dict, time.time()) - ) - for motor, position in motors_dict.items(): - if motor in ("kappa", "kappa_phi"): - logging.getLogger("HWR").info("[BIOMAXMD3] Removing %s motor.", motor) - continue - if position is None: - continue - name = self.MOTOR_TO_EXPORTER_NAME[motor] - argin += "%s=%0.3f;" % (name, position) - if not argin: - return - self.wait_device_ready(2000) - self.command_dict["startSimultaneousMoveMotors"](argin) - if wait: - self.wait_device_ready(timeout) - - def moveToBeam(self, x, y): - try: - self.emit_progress_message("Move to beam...") - pos_x, pos_y = HWR.beamline.beam.get_beam_position_on_screen() - self.beam_position = (pos_x, pos_y) - beam_xc = self.beam_position[0] - beam_yc = self.beam_position[1] - cent_vertical_to_move = self.cent_vertical_pseudo_motor.get_value() - ( - x - beam_xc - ) / float(self.pixelsPerMmY) - self.emit_progress_message("") - - self.phiy_motor_hwobj.set_value_relative( - -1 * (y - beam_yc) / float(self.pixelsPerMmZ) - ) - self.cent_vertical_pseudo_motor.set_value(cent_vertical_to_move) - self.wait_device_ready(5) - except Exception: - logging.getLogger("HWR").exception("MD3: could not move to beam.") - - def get_centred_point_from_coord(self, x, y, return_by_names=None): - """ - Descript. : - """ - self.centring_hwobj.initCentringProcedure() - self.centring_hwobj.appendCentringDataPoint( - { - "X": (x - self.beam_position[0]) / self.pixels_per_mm_x, - "Y": (y - self.beam_position[1]) / self.pixels_per_mm_y, - } - ) - self.omega_reference_add_constraint() - pos = self.centring_hwobj.centeredPosition() - if return_by_names: - pos = self.convert_from_obj_to_name(pos) - return pos - - def abort(self): - """ - Stops all the pending tasks, stops all the motors and closes all theirs control loop. - """ - logging.getLogger("HWR").exception("MiniDiff: going to abort") - self.command_dict["abort"]() - logging.getLogger("HWR").exception("MiniDiff: all movements aborted") - - def move_omega_relative(self, relative_angle): - """ - Descript. : - """ - self.phi_motor_hwobj.set_value_relative(relative_angle, 10) - - def is_ready(self): - """ - Detects if device is ready - """ - return self.channel_dict["State"].get_value() == DiffractometerState.tostring( - # return self.current_state == DiffractometerState.tostring(\ - DiffractometerState.Ready - ) - - def get_positions(self): - return { - "phi": float(self.phi_motor_hwobj.get_value()), - "focus": float(self.focus_motor_hwobj.get_value()), - "phiy": float(self.phiy_motor_hwobj.get_value()), - "phiz": float(self.phiz_motor_hwobj.get_value()), - "sampx": float(self.sample_x_motor_hwobj.get_value()), - "sampy": float(self.sample_y_motor_hwobj.get_value()), - "kappa": float(self.kappa_motor_hwobj.get_value()) - if self.kappa_motor_hwobj - else None, - "kappa_phi": float(self.kappa_phi_motor_hwobj.get_value()) - if self.kappa_phi_motor_hwobj - else None, - "zoom": float(self.zoom_motor_hwobj.get_value()), - } diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py deleted file mode 100755 index 90f3ada66a..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py +++ /dev/null @@ -1,214 +0,0 @@ -import array -import base64 -import logging -import math -import time -from threading import ( - Event, - Thread, -) - -import gevent -import numpy as np - -from mxcubecore.BaseHardwareObjects import HardwareObject - - -class MD2TimeoutError(Exception): - pass - - -class BIOMAXMD3Camera(HardwareObject): - (NOTINITIALIZED, UNUSABLE, READY, MOVESTARTED, MOVING, ONLIMIT) = (0, 1, 2, 3, 4, 5) - EXPORTER_TO_MOTOR_STATE = { - "Invalid": NOTINITIALIZED, - "Fault": UNUSABLE, - "Ready": READY, - "Moving": MOVING, - "Created": NOTINITIALIZED, - "Initializing": NOTINITIALIZED, - "Unknown": UNUSABLE, - "LowLim": ONLIMIT, - "HighLim": ONLIMIT, - } - - def __init__(self, name): - super().__init__(name) - self.set_is_ready(True) - - def init(self): - logging.getLogger("HWR").info("initializing camera object") - self.specName = self.motor_name - self.pollInterval = 80 - - self.image_attr = self.add_channel( - {"type": "exporter", "name": "image"}, "ImageJPG" - ) - - # new attrs for the MD3 with extra camera options - self.width = 680 - self.height = 512 - self.chan_zoom = self.add_channel( - {"type": "exporter", "name": "ImageZoom"}, "ImageZoom" - ) - self.roi_x = self.add_channel({"type": "exporter", "name": "RoiX"}, "RoiX") - self.roi_y = self.add_channel({"type": "exporter", "name": "RoiY"}, "RoiY") - self.roi_width = self.add_channel( - {"type": "exporter", "name": "RoiWidth"}, "RoiWidth" - ) - self.roi_height = self.add_channel( - {"type": "exporter", "name": "RoiHeight"}, "RoiHeight" - ) - self.set_camera_roi = self.add_command( - {"type": "exporter", "name": "setCameraROI"}, "setCameraROI" - ) - - self.width = self.roi_width.get_value() - self.height = self.roi_height.get_value() - - if self.get_property("interval"): - self.pollInterval = self.get_property("interval") - self.stopper = False # self.polling_timer(self.pollInterval, self.poll) - # if self.get_property("image_zoom"): - try: - self.zoom = float(self.get_property("image_zoom")) - self.chan_zoom.set_value(self.zoom) - self.width = self.roi_width.get_value() * self.zoom - self.height = self.roi_height.get_value() * self.zoom - except Exception: - logging.getLogger("HWR").info("cannot set image zoom level") - thread = Thread(target=self.poll) - thread.daemon = True - thread.start() - - def getImage(self): - return self.image_attr.get_value() - - def poll(self): - logging.getLogger("HWR").info("going to poll images") - self.image_attr = self.add_channel( - {"type": "exporter", "name": "image"}, "ImageJPG" - ) - while not self.stopper: - time.sleep(float(self.pollInterval) / 1000) - # time.sleep(1) - # print "polling", datetime.datetime.now().strftime("%H:%M:%S.%f") - try: - img = self.image_attr.get_value() - imgArray = array.array("b", img) - imgStr = imgArray.tostring() - # self.emit("imageReceived", self.imageaux,1360,1024) - self.emit("imageReceived", imgStr, 1360, 1024) - except KeyboardInterrupt: - self.connected = False - self.stopper = True - logging.getLogger("HWR").info("poll images stopped") - return - except Exception: - logging.getLogger("HWR").exception("Could not read image") - self.image_attr = self.add_channel( - {"type": "exporter", "name": "image"}, "ImageJPG" - ) - - def stopPolling(self): - self.stopper = True - - def startPolling(self): - # assuming that it is already stop, more advances features with - # threading.Event, Event.is_set... - self.stopper = False - thread.stop() - thread = Thread(target=self.poll) - thread.daemon = True - thread.start() - - def setCameraRoi(self, x1, y1, x2, y2): - """ - Configure the camera Region Of Interest. - X1 (int): abscissa of top left corner - Y1 (int): ordinate of top left corner - X2 (int): abscissa of bottom right corner - Y2 (int): ordinate of bottom right corner - """ - try: - self.set_camera_roi(x1, y1, x1, y2) - self.width = x2 - x1 - self.height = y1 - y2 - return True - except Exception: - logging.getLogger("HWR").exception("Could not set image roi") - return False - - def getCameraRoi(self): - """ - Retrieve camera roi settings - """ - try: - return [ - self.roi_x.get_value(), - self.roi_y.get_value(), - self.roi_width.get_value(), - self.roi_height.get_value(), - ] - except Exception: - logging.getLogger("HWR").exception("Could not retrieve image roi settings") - return False - - def getImageZoom(self): - try: - return self.zoom.get_value() - except Exception as e: - logging.getLogger("HWR").exception("Could not retrieve image zoom settings") - return False - - def setImageZoom(self, new_zoom): - try: - return self.zoom.set_value(new_zoom) - except Exception as e: - logging.getLogger("HWR").exception("Could not retrieve image zoom settings") - return False - - def imageUpdated(self, value): - print(" got new image") - print(value) - - def gammaExists(self): - return False - - def contrastExists(self): - return False - - def brightnessExists(self): - return False - - def gainExists(self): - return False - - def get_width(self): - # return self.roi_width.get_value() - return self.width - - def get_height(self): - # return self.roi_height.get_value() - return self.height - - def set_live(self, state): - self.liveState = state - return True - - def imageType(self): - return None - - def takeSnapshot(self, snapshot_filename, bw=True): - img = self.image_attr.get_value() - imgArray = array.array("b", img) - imgStr = imgArray.tostring() - f = open(snapshot_filename, "wb") - f.write(imgStr) - f.close() - return True - - def get_snapshot_img_str(self): - img = self.image_attr.get_value() - imgArray = array.array("b", img) - return imgArray.tostring() diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py deleted file mode 100644 index cae1a2bcdf..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXPatches.py +++ /dev/null @@ -1,160 +0,0 @@ -import logging -import time -import types - -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject - - -class BIOMAXPatches(HardwareObject): - """ - Hwobj for patching hwobj methods without inheriting classes. - """ - - def before_load_sample(self): - """ - Ensure that the detector is in safe position and sample changer in SOAK - """ - if not HWR.beamline.sample_changer._chnPowered.get_value(): - raise RuntimeError("Cannot load sample, sample changer not powered") - if not self.sc_in_soak(): - logging.getLogger("HWR").info( - "Sample changer not in SOAK position, moving there..." - ) - try: - self.sample_changer_maintenance.send_command("soak") - time.sleep(0.25) - HWR.beamline.sample_changer._wait_device_ready(45) - except Exception as ex: - raise RuntimeError( - "Cannot load sample, sample changer cannot go to SOAK position: %s" - % str(ex) - ) - self.curr_dtox_pos = HWR.beamline.detector.distance.get_value() - if ( - HWR.beamline.detector.distance is not None - and HWR.beamline.detector.distance.get_value() < self.safe_position - ): - logging.getLogger("HWR").info( - "Moving detector to safe position before loading a sample." - ) - logging.getLogger("user_level_log").info( - "Moving detector to safe position before loading a sample." - ) - - self.wait_motor_ready(HWR.beamline.detector.distance) - try: - HWR.beamline.detector.distance.set_value(self.safe_position, timeout=30) - except Exception: - logging.getLogger("HWR").warning("Cannot move detector") - else: - logging.getLogger("HWR").info("Detector already in safe position.") - logging.getLogger("user_level_log").info( - "Detector already in safe position." - ) - try: - logging.getLogger("HWR").info( - "Waiting for Diffractometer to be ready before proceeding with the sample loading." - ) - HWR.beamline.diffractometer.wait_device_ready(15) - except Exception as ex: - logging.getLogger("HWR").warning( - "Diffractometer not ready. Proceeding with the sample loading, good luck..." - ) - else: - logging.getLogger("HWR").info( - "Diffractometer ready, proceeding with the sample loading." - ) - time.sleep(1) - - def after_load_sample(self): - """ - Move to centring after loading the sample - """ - if not HWR.beamline.sample_changer._chnPowered.get_value(): - raise RuntimeError( - "Not proceeding with the steps after sample loading, sample changer not powered" - ) - if ( - HWR.beamline.diffractometer is not None - and HWR.beamline.diffractometer.get_current_phase() != "Centring" - ): - logging.getLogger("HWR").info("Changing diffractometer phase to Centring") - logging.getLogger("user_level_log").info( - "Changing diffractometer phase to Centring" - ) - try: - HWR.beamline.diffractometer.wait_device_ready(15) - except Exception: - pass - HWR.beamline.diffractometer.set_phase("Centring") - logging.getLogger("HWR").info( - "Diffractometer phase changed, current phase: %s" - % HWR.beamline.diffractometer.get_current_phase() - ) - else: - logging.getLogger("HWR").info("Diffractometer already in Centring") - logging.getLogger("user_level_log").info( - "Diffractometer already in Centring" - ) - logging.getLogger("HWR").info( - "Moving detector to pre-mount position %s" % self.curr_dtox_pos - ) - try: - if not HWR.beamline.sample_changer._chnPowered.get_value(): - raise RuntimeError( - "Not moving detector to pre-mount position, sample changer not powered" - ) - HWR.beamline.detector.distance.set_value(self.curr_dtox_pos, timeout=30) - except Exception: - logging.getLogger("HWR").warning("Cannot move detector") - - def new_load(self, *args, **kwargs): - logging.getLogger("HWR").debug("Patched sample load version.") - try: - sample = kwargs.get("sample", None) - except Exception: - pass - if sample is None: - sample = args[1] - - logging.getLogger("HWR").debug( - "Patched sample load version. Sample to load: %s" % sample - ) - - self.before_load_sample() - self.__load(sample) - self.after_load_sample() - - def new_unload(self, *args, **kwargs): - logging.getLogger("HWR").info( - "Sample changer in SOAK position: %s" % self.sc_in_soak() - ) - self.before_load_sample() - self.__unload(args[1]) - # self.after_load_sample() - - def wait_motor_ready(self, mot_hwobj, timeout=30): - with gevent.Timeout(timeout, RuntimeError("Motor not ready")): - while mot_hwobj.is_moving(): - gevent.sleep(0.5) - - def sc_in_soak(self): - return HWR.beamline.sample_changer._chnInSoak.get_value() - - def init(self, *args): - self.sample_changer_maintenance = self.get_object_by_role( - "sample_changer_maintenance" - ) - self.__load = HWR.beamline.sample_changer.load - self.__unload = HWR.beamline.sample_changer.unload - self.curr_dtox_pos = None - - HWR.beamline.sample_changer.load = types.MethodType( - self.new_load, HWR.beamline.sample_changer - ) - HWR.beamline.sample_changer.unload = types.MethodType( - self.new_unload, HWR.beamline.sample_changer - ) diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py deleted file mode 100755 index 7ccf4f5ccc..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXResolution.py +++ /dev/null @@ -1,56 +0,0 @@ -import logging -import math - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects import Resolution - - -class BIOMAXResolution(Resolution.Resolution): - def __init__(self, *args, **kwargs): - Resolution.Resolution.__init__(self, *args, **kwargs) - - def init(self): - - detector = HWR.beamline.detector - - if detector: - try: - self.det_width = detector.get_x_pixels_in_detector() - self.det_height = detector.get_y_pixels_in_detector() - except Exception: - self.det_width = 4150 - self.det_height = 4371 - - else: - self.valid = False - logging.getLogger().exception("Cannot get detector size") - - self.connect(detector.distance, "stateChanged", self.dtoxStateChanged) - self.connect(detector.distance, "valueChanged", self.dtoxPositionChanged) - self.connect(HWR.beamline.energy, "valueChanged", self.energyChanged) - self.connect(detector, "roiChanged", self.det_roi_changed) - - def res2dist(self, res=None): - current_wavelength = HWR.beamline.energy.get_wavelength() - - if res is None: - res = self._nominal_value - - try: - ttheta = 2 * math.asin(current_wavelength / (2 * res)) - return HWR.beamline.detector.get_radius() / math.tan(ttheta) - except Exception as ex: - print(ex) - return None - - def dist2res(self, dist=None): - detector_HO = HWR.beamline.detector - if dist is None: - dist = detector_HO.distance.get_value() - - return "%.3f" % self._calc_res(detector_HO.get_radius, dist) - - def det_roi_changed(self): - self.det_width = HWR.beamline.detector.get_x_pixels_in_detector() - self.det_height = HWR.beamline.detector.get_y_pixels_in_detector() - self.recalculateResolution() diff --git a/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py b/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py deleted file mode 100644 index 00e927c14c..0000000000 --- a/mxcubecore/HardwareObjects/MAXIV/BIOMAXTransmission.py +++ /dev/null @@ -1,54 +0,0 @@ -import gevent - -from mxcubecore import HardwareRepository as HWR -from mxcubecore.BaseHardwareObjects import HardwareObject - - -class BIOMAXTransmission(HardwareObject): - def init(self): - self.ready_event = gevent.event.Event() - self.moving = None - self.limits = [0, 100] - self.threhold = 5 - - if HWR.beamline.transmission is not None: - HWR.beamline.transmission.connect( - "valueChanged", self.transmissionPositionChanged - ) - - def is_ready(self): - return True - - def get_value(self): - return "%.3f" % HWR.beamline.transmission.get_value() - - def getAttState(self): - return 1 - - def get_limits(self): - return (0, 100) - - def setpoint_reached(self, setpoint): - curr_pos = float(self.get_value()) - return abs(curr_pos - setpoint) < 5 - - def set_value(self, value, wait=False): - if value < self.limits[0] or value > self.limits[1]: - raise Exception("Transmssion out of limits.") - HWR.beamline.transmission.set_value(value) - if wait: - with gevent.Timeout(30, Exception("Timeout waiting for device ready")): - while not self.setpoint_reached(value): - gevent.sleep(0.1) - - self._update() - - def _update(self): - self.emit("attStateChanged", self.getAttState()) - - def transmissionPositionChanged(self, *args): - pos = self.get_value() - self.emit("valueChanged", (pos,)) - - def stop(self): - HWR.beamline.transmission.stop() diff --git a/pyproject.toml b/pyproject.toml index 445bf77dfa..b1f8374904 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,9 +95,6 @@ mxcubecore/HardwareObjects/LNLS/EPICSActuator.py, mxcubecore/HardwareObjects/LNLS/LNLSCollect.py, mxcubecore/HardwareObjects/LNLS/LNLSDetDistMotor.py, mxcubecore/HardwareObjects/Lima2Detector.py, -mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py, -mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py, -mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3Camera.py, mxcubecore/HardwareObjects/MAXIV/MAXIVAutoProcessing.py, mxcubecore/HardwareObjects/MAXIV/autoProcLauncher.py, mxcubecore/HardwareObjects/MAXIV/ednaProcLauncher.py, @@ -205,10 +202,7 @@ force-exclude = ''' | mxcubecore/HardwareObjects/LNLS/set_transmission_mnc.py | mxcubecore/HardwareObjects/Lima2Detector.py | mxcubecore/HardwareObjects/ISPyBClient.py - | mxcubecore/HardwareObjects/MAXIV/BIOMAXEiger.py - | mxcubecore/HardwareObjects/MAXIV/BIOMAXMD3.py | mxcubecore/HardwareObjects/PlateManipulatorMaintenance.py - | mxcubecore/HardwareObjects/MAXIV/BIOMAXCollect.py | mxcubecore/HardwareObjects/SOLEIL/PX1/PX1Cryotong.py | mxcubecore/HardwareObjects/PlateManipulator.py | mxcubecore/HardwareObjects/SOLEIL/PX2/PX2Resolution.py From 877387708740752c701e42ccd5cd2ae7e4c8f155 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 6 Nov 2024 09:49:54 +0000 Subject: [PATCH 146/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b1f8374904..5def19d8d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.183.0" +version = "1.184.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From e10ee1359c3d61d7b6e7d01b5e0dc8f39c94f3f6 Mon Sep 17 00:00:00 2001 From: pmockoocy Date: Wed, 23 Oct 2024 12:18:26 +0200 Subject: [PATCH 147/172] Now persists hidden state when moving motors --- mxcubecore/HardwareObjects/SampleView.py | 26 +++++++++++++++---- .../abstract/AbstractSampleView.py | 12 +++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index 696acba559..b04f13bfa0 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -29,7 +29,10 @@ from PIL import Image from mxcubecore import HardwareRepository as HWR -from mxcubecore.HardwareObjects.abstract.AbstractSampleView import AbstractSampleView +from mxcubecore.HardwareObjects.abstract.AbstractSampleView import ( + AbstractSampleView, + ShapeState, +) from mxcubecore.model import queue_model_objects @@ -179,7 +182,9 @@ def add_shape(self, shape): self.shapes[shape.id] = shape shape.shapes_hw_object = self - def add_shape_from_mpos(self, mpos_list, screen_coord, t): + def add_shape_from_mpos( + self, mpos_list, screen_coord, t, user_state: ShapeState = "SAVED" + ): """ Adds a shape of type , with motor positions from mpos_list and screen position screen_coord. @@ -198,11 +203,15 @@ def add_shape_from_mpos(self, mpos_list, screen_coord, t): if _cls: shape = _cls(mpos_list, screen_coord) + # In case the shape is being recreated, we need to restore it. + shape.state = user_state + shape.user_state = user_state + self.add_shape(shape) return shape - def add_shape_from_refs(self, refs, t): + def add_shape_from_refs(self, refs, t, user_state: ShapeState = "SAVED"): """ Adds a shape of type , taking motor positions and screen positions from reference points in refs. @@ -217,7 +226,7 @@ def add_shape_from_refs(self, refs, t): mpos = [self.get_shape(refid).mpos() for refid in refs] spos_list = [self.get_shape(refid).screen_coord for refid in refs] spos = reduce((lambda x, y: tuple(x) + tuple(y)), spos_list, ()) - shape = self.add_shape_from_mpos(mpos, spos, t) + shape = self.add_shape_from_mpos(mpos, spos, t, user_state) shape.refs = refs return shape @@ -457,7 +466,10 @@ def __init__(self, mpos_list=[], screen_coord=(-1, -1)): self.id = "" self.cp_list = [] self.name = "" - self.state = "SAVED" + self.state: ShapeState = "SAVED" + self.user_state: ShapeState = ( + "SAVED" # used to persist user preferences in regards wether to show or hide particular shape. + ) self.label = "" self.screen_coord = screen_coord self.selected = False @@ -622,6 +634,10 @@ def update_position(self, transform): phi_pos = HWR.beamline.diffractometer.omega.get_value() % 360 _d = abs((self.get_centred_position().phi % 360) - phi_pos) + if self.user_state == "HIDDEN": + self.state = "HIDDEN" + return + if min(_d, 360 - _d) > self.shapes_hw_object.hide_grid_threshold: self.state = "HIDDEN" else: diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py index 69d972740a..64c9f85079 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py @@ -24,10 +24,15 @@ __license__ = "LGPLv3+" import abc -from typing import Union +from typing import ( + Literal, + Union, +) from mxcubecore.BaseHardwareObjects import HardwareObject +ShapeState = Literal["HIDDEN", "SAVED", "TMP"] + class AbstractSampleView(HardwareObject): """AbstractSampleView Class""" @@ -153,13 +158,16 @@ def add_shape(self, shape): return @abc.abstractmethod - def add_shape_from_mpos(self, mpos_list, screen_cord, _type): + def add_shape_from_mpos( + self, mpos_list, screen_cord, _type, user_state: ShapeState = "SAVED" + ): """Add a shape of type , with motor positions from mpos_list and screen position screen_coord. Args: mpos_list (list[mpos_list]): List of motor positions screen_coord (tuple(x, y): Screen cordinate for shape _type (str): Type str for shape, P (Point), L (Line), G (Grid) + user_state (ShapeState): State of the shape set by the user Returns: (Shape): Shape of type _type """ From 57cef47bd67cbc95007c1a1c04144abf268d1c1f Mon Sep 17 00:00:00 2001 From: pmockoocy Date: Mon, 4 Nov 2024 10:08:32 +0100 Subject: [PATCH 148/172] added way to preserve state when recreating shapes --- mxcubecore/HardwareObjects/SampleView.py | 17 ++++++++++++----- .../abstract/AbstractSampleView.py | 7 ++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/mxcubecore/HardwareObjects/SampleView.py b/mxcubecore/HardwareObjects/SampleView.py index b04f13bfa0..b114f631ca 100644 --- a/mxcubecore/HardwareObjects/SampleView.py +++ b/mxcubecore/HardwareObjects/SampleView.py @@ -183,7 +183,12 @@ def add_shape(self, shape): shape.shapes_hw_object = self def add_shape_from_mpos( - self, mpos_list, screen_coord, t, user_state: ShapeState = "SAVED" + self, + mpos_list, + screen_coord, + t, + state: ShapeState = "SAVED", + user_state: ShapeState = "SAVED", ): """ Adds a shape of type , with motor positions from mpos_list and @@ -203,15 +208,17 @@ def add_shape_from_mpos( if _cls: shape = _cls(mpos_list, screen_coord) - # In case the shape is being recreated, we need to restore it. - shape.state = user_state + # In case the shape is being recreated, we need to restore it's state. + shape.state = state shape.user_state = user_state self.add_shape(shape) return shape - def add_shape_from_refs(self, refs, t, user_state: ShapeState = "SAVED"): + def add_shape_from_refs( + self, refs, t, state: ShapeState = "SAVED", user_state: ShapeState = "SAVED" + ): """ Adds a shape of type , taking motor positions and screen positions from reference points in refs. @@ -226,7 +233,7 @@ def add_shape_from_refs(self, refs, t, user_state: ShapeState = "SAVED"): mpos = [self.get_shape(refid).mpos() for refid in refs] spos_list = [self.get_shape(refid).screen_coord for refid in refs] spos = reduce((lambda x, y: tuple(x) + tuple(y)), spos_list, ()) - shape = self.add_shape_from_mpos(mpos, spos, t, user_state) + shape = self.add_shape_from_mpos(mpos, spos, t, state, user_state) shape.refs = refs return shape diff --git a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py index 64c9f85079..7e5f9a1e23 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractSampleView.py @@ -159,7 +159,12 @@ def add_shape(self, shape): @abc.abstractmethod def add_shape_from_mpos( - self, mpos_list, screen_cord, _type, user_state: ShapeState = "SAVED" + self, + mpos_list, + screen_cord, + _type, + state: ShapeState = "SAVED", + user_state: ShapeState = "SAVED", ): """Add a shape of type , with motor positions from mpos_list and screen position screen_coord. From a70756e5ac9cf0c7b26dacf407ba30477d06ec96 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 6 Nov 2024 10:11:32 +0000 Subject: [PATCH 149/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5def19d8d6..c8af392ec9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.184.0" +version = "1.185.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 2ce7d79eed5758728aa63b1034702ef2fdd9c9bd Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Tue, 5 Nov 2024 16:43:02 +0100 Subject: [PATCH 150/172] Remove obsolete ESRF files --- .../HardwareObjects/ESRF/ESRFCryoMon.py | 60 ----------------- mxcubecore/HardwareObjects/ESRF/ID30Cryo.py | 66 ------------------- 2 files changed, 126 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py delete mode 100644 mxcubecore/HardwareObjects/ESRF/ID30Cryo.py diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py b/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py deleted file mode 100644 index 5bb7505ab4..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ESRFCryoMon.py +++ /dev/null @@ -1,60 +0,0 @@ -import time - -import gevent -from PyTango.gevent import DeviceProxy - -from mxcubecore.BaseHardwareObjects import HardwareObject - -CRYO_STATUS = ["OFF", "SATURATED", "READY", "WARNING", "FROZEN", "UNKNOWN"] - - -class ESRFCryoMon(HardwareObject): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.n2level = None - self.temp = None - self.temp_error = None - self.cryo_status = None - self.dry_status = None - self.sdry_status = None - - def init(self): - self.tg_device = None - self.set_is_ready(True) - self._monitoring_greenlet = gevent.spawn(self._monitor) - - def _monitor(self): - self.tg_device = None - while True: - if self.tg_device is None: - self.tg_device = DeviceProxy(self.get_property("tangoname")) - try: - temp = self.tg_device.Gas_temp - except Exception: - self.tg_device = None - else: - # if n2level != self.n2level: - # self.n2level = n2level - # self.emit("levelChanged", (n2level, )) - if temp != self.temp: - self.temp = temp - self.emit("temperatureChanged", (temp, 0)) - # if cryo_status != self.cryo_status: - # self.cryo_status = cryo_status - # self.emit("cryoStatusChanged", (CRYO_STATUS[cryo_status], )) - # if dry_status != self.dry_status: - # self.dry_status = dry_status - # if dry_status != 9999: - # self.emit("dryStatusChanged", (CRYO_STATUS[dry_status], )) - # if sdry_status != self.sdry_status: - # self.sdry_status = sdry_status - # if sdry_status != 9999: - # self.emit("sdryStatusChanged", (CRYO_STATUS[sdry_status], )) - time.sleep(3) - - def setN2Level(self, newLevel): - raise NotImplementedError - - def getTemperature(self): - return self.tg_device.Gas_temp diff --git a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py b/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py deleted file mode 100644 index 7f50468dbd..0000000000 --- a/mxcubecore/HardwareObjects/ESRF/ID30Cryo.py +++ /dev/null @@ -1,66 +0,0 @@ -import time - -import gevent - -from mxcubecore.BaseHardwareObjects import HardwareObject -from mxcubecore.TaskUtils import task - - -class ID30Cryo(HardwareObject): - states = {0: "out", 1: "in"} - - def __init__(self, name): - super().__init__(name) - - def init(self): - controller = self.get_object_by_role("controller") - - self._state = None - self.username = self.name() - self.wago_controller = getattr(controller, self.wago) - self.command_key = self.get_property("cmd") - self.in_key = self.get_property("is_in") - self.out_key = self.get_property("is_out") - self.wago_polling = self._wago_polling(self.command_key, wait=False) - self.set_is_ready(True) - - @task - def _wago_polling(self, key): - while True: - try: - reading = int(self.wago_controller.get(key)) - except Exception: - time.sleep(1) - continue - if self._state != reading: - self._state = reading - self.emit("wagoStateChanged", (self.getWagoState(),)) - self.emit("actuatorStateChanged", (self.getWagoState(),)) - time.sleep(1) - - def getWagoState(self): - return ID30Cryo.states.get(self._state, "unknown") - - def wagoIn(self): - with gevent.Timeout(5): - self.wago_controller.set(self.command_key, 1) - while self.wago_controller.get(self.in_key) == 0: - time.sleep(0.5) - - def wagoOut(self): - with gevent.Timeout(5): - self.wago_controller.set(self.command_key, 0) - while self.wago_controller.get(self.out_key) == 0: - time.sleep(0.5) - - def get_actuator_state(self): - return self.getWagoState() - - def actuatorIn(self): - return self.wagoIn() - - def actuatorOut(self): - return self.wagoOut() - - def get_state(self): - return ID30Cryo.READY From 4a7bda39b004df508cacccab378ac32e2db2c982 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 6 Nov 2024 10:38:19 +0000 Subject: [PATCH 151/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c8af392ec9..1b91604a74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.185.0" +version = "1.186.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 36ee2b340959df8c267c0424cec200edce6231bf Mon Sep 17 00:00:00 2001 From: Andrey Gruzinov Date: Wed, 2 Oct 2024 12:32:35 +0200 Subject: [PATCH 152/172] Fix for the broken data collections when no beamtime ID is open. Fallback to the local dir. No online data processing. Rebasing --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 224 +++++++++--------- .../HardwareObjects/DESY/P11EigerDetector.py | 2 +- .../HardwareObjects/DESY/P11ISPyBClient.py | 13 + mxcubecore/HardwareObjects/DESY/P11Session.py | 16 +- 4 files changed, 143 insertions(+), 112 deletions(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 4f59a005fb..9c9756173d 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -255,10 +255,10 @@ def data_collection_hook(self): if self.is_process_running(process_name) and self.is_process_running( "adxv" ): - print(f"{process_name} is already running.") + self.log.debug(f"{process_name} is already running.") else: os.system(f"killall -9 {process_name}") - print(f"{process_name} is not running. Starting...") + self.log.debug(f"{process_name} is not running. Starting...") self.start_process(command) if collection_type == "Characterization": @@ -868,138 +868,148 @@ def get_filter_transmission(self): def xdsapp_maxwell(self): """Starts XDSAPP auto-processing on the Maxwell cluster.""" - self.log.debug("==== XDSAPP AUTOPROCESSING IS STARTED ==========") + + if HWR.beamline.session.get_beamtime_metadata() != None: - resolution = self.get_resolution() + self.log.debug("==== XDSAPP AUTOPROCESSING IS STARTED ==========") - image_dir_local, filename = os.path.split(self.latest_h5_filename) + resolution = self.get_resolution() - image_dir = image_dir_local.replace( - "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] - ) - process_dir = image_dir.replace("/raw/", "/processed/") - process_dir_local = image_dir_local.replace("/raw/", "/processed/") - xdsapp_path = os.path.join(process_dir, "xdsapp") - xdsapp_path_local = os.path.join(process_dir_local, "xdsapp") - self.log.debug('============XDSAPP======== xdsapp_path="%s"' % xdsapp_path) - self.log.debug( - '============XDSAPP======== xdsapp_path_local="%s"' % xdsapp_path_local - ) + image_dir_local, filename = os.path.split(self.latest_h5_filename) - try: - self.mkdir_with_mode(xdsapp_path_local, mode=0o777) - self.log.debug("=========== XDSAPP ============ XDSAPP directory created") + image_dir = image_dir_local.replace( + "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] + ) + process_dir = image_dir.replace("/raw/", "/processed/") + process_dir_local = image_dir_local.replace("/raw/", "/processed/") + xdsapp_path = os.path.join(process_dir, "xdsapp") + xdsapp_path_local = os.path.join(process_dir_local, "xdsapp") + self.log.debug('============XDSAPP======== xdsapp_path="%s"' % xdsapp_path) + self.log.debug( + '============XDSAPP======== xdsapp_path_local="%s"' % xdsapp_path_local + ) - except OSError: - self.log.debug(sys.exc_info()) - self.log.debug("Cannot create XDSAPP directory") + try: + self.mkdir_with_mode(xdsapp_path_local, mode=0o777) + self.log.debug("=========== XDSAPP ============ XDSAPP directory created") - base_process_dir = self.base_dir(process_dir_local, "processed") - datasets_file = os.path.join(base_process_dir, "datasets.txt") + except OSError: + self.log.debug(sys.exc_info()) + self.log.debug("Cannot create XDSAPP directory") - try: - open(datasets_file, "a", encoding="utf-8").write( - xdsapp_path_local.split("/gpfs/current/processed/")[1] + "\n" - ) - except RuntimeError as err_msg: - self.log.debug("Cannot write to datasets.txt") - self.log.debug(sys.exc_info()) - - ssh = HWR.beamline.session.get_ssh_command() - sbatch = HWR.beamline.session.get_sbatch_command( - jobname_prefix="xdsapp", - logfile_path=xdsapp_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + base_process_dir = self.base_dir(process_dir_local, "processed") + datasets_file = os.path.join(base_process_dir, "datasets.txt") + + try: + open(datasets_file, "a", encoding="utf-8").write( + xdsapp_path_local.split("/gpfs/current/processed/")[1] + "\n" + ) + except RuntimeError as err_msg: + self.log.debug("Cannot write to datasets.txt") + self.log.debug(sys.exc_info()) + + ssh = HWR.beamline.session.get_ssh_command() + sbatch = HWR.beamline.session.get_sbatch_command( + jobname_prefix="xdsapp", + logfile_path=xdsapp_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ) + + "/xdsapp.log", ) - + "/xdsapp.log", - ) - cmd = ( - "/asap3/petra3/gpfs/common/p11/processing/xdsapp_sbatch.sh " - + "{imagepath:s} {processpath:s} {res:f}" - ).format( - imagepath=image_dir + "/" + filename, - processpath=xdsapp_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" - ), - res=resolution, - ) + cmd = ( + "/asap3/petra3/gpfs/common/p11/processing/xdsapp_sbatch.sh " + + "{imagepath:s} {processpath:s} {res:f}" + ).format( + imagepath=image_dir + "/" + filename, + processpath=xdsapp_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ), + res=resolution, + ) - os.system( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd + os.system( + '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( + ssh=ssh, sbatch=sbatch, cmd=cmd + ) ) - ) + else: + self.log.debug("Beamtime metadata is not found. No online resouces available. Autoprocessing on the cluster is not available.") def autoproc_maxwell(self): """Starts AutoProc auto-processing on the Maxwell cluster.""" - self.log.debug("==== AUTOPROC AUTOPROCESSING IS STARTED ==========") + + if HWR.beamline.session.get_beamtime_metadata() != None: - resolution = self.get_resolution() + self.log.debug("==== AUTOPROC AUTOPROCESSING IS STARTED ==========") - image_dir_local, filename = os.path.split(self.latest_h5_filename) + resolution = self.get_resolution() - image_dir = image_dir_local.replace( - "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] - ) - process_dir = image_dir.replace("/raw/", "/processed/") - process_dir_local = image_dir_local.replace("/raw/", "/processed/") - autoproc_path = os.path.join(process_dir, "autoproc") - autoproc_path_local = os.path.join(process_dir_local, "autoproc") - self.log.debug( - '============AUTOPROC======== autoproc_path="%s"' % autoproc_path - ) - self.log.debug( - '============AUTOPROC======== autoproc_path_local="%s"' - % autoproc_path_local - ) + image_dir_local, filename = os.path.split(self.latest_h5_filename) - try: - self.mkdir_with_mode(autoproc_path_local, mode=0o777) + image_dir = image_dir_local.replace( + "/gpfs/current", HWR.beamline.session.get_beamtime_metadata()[2] + ) + process_dir = image_dir.replace("/raw/", "/processed/") + process_dir_local = image_dir_local.replace("/raw/", "/processed/") + autoproc_path = os.path.join(process_dir, "autoproc") + autoproc_path_local = os.path.join(process_dir_local, "autoproc") self.log.debug( - "=========== AUTOPROC ============ autoproc directory created" + '============AUTOPROC======== autoproc_path="%s"' % autoproc_path + ) + self.log.debug( + '============AUTOPROC======== autoproc_path_local="%s"' + % autoproc_path_local ) - except OSError: - self.log.debug(sys.exc_info()) - self.log.debug("Cannot create AUTOPROC directory") + try: + self.mkdir_with_mode(autoproc_path_local, mode=0o777) + self.log.debug( + "=========== AUTOPROC ============ autoproc directory created" + ) - base_process_dir = self.base_dir(process_dir_local, "processed") - datasets_file = os.path.join(base_process_dir, "datasets.txt") + except OSError: + self.log.debug(sys.exc_info()) + self.log.debug("Cannot create AUTOPROC directory") - try: - open(datasets_file, "a", encoding="utf-8").write( - autoproc_path_local.split("/gpfs/current/processed/")[1] + "\n" - ) - except RuntimeError as err_msg: - self.log.debug("Cannot write to datasets.txt") - self.log.debug(sys.exc_info()) - - ssh = HWR.beamline.session.get_ssh_command() - sbatch = HWR.beamline.session.get_sbatch_command( - jobname_prefix="autoproc", - logfile_path=autoproc_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + base_process_dir = self.base_dir(process_dir_local, "processed") + datasets_file = os.path.join(base_process_dir, "datasets.txt") + + try: + open(datasets_file, "a", encoding="utf-8").write( + autoproc_path_local.split("/gpfs/current/processed/")[1] + "\n" + ) + except RuntimeError as err_msg: + self.log.debug("Cannot write to datasets.txt") + self.log.debug(sys.exc_info()) + + ssh = HWR.beamline.session.get_ssh_command() + sbatch = HWR.beamline.session.get_sbatch_command( + jobname_prefix="autoproc", + logfile_path=autoproc_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ) + + "/autoproc.log", ) - + "/autoproc.log", - ) - cmd = ( - "/asap3/petra3/gpfs/common/p11/processing/autoproc_sbatch.sh " - + "{imagepath:s} {processpath:s}" - ).format( - imagepath=image_dir + "/" + filename, - processpath=autoproc_path.replace( - HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + cmd = ( + "/asap3/petra3/gpfs/common/p11/processing/autoproc_sbatch.sh " + + "{imagepath:s} {processpath:s}" + ).format( + imagepath=image_dir + "/" + filename, + processpath=autoproc_path.replace( + HWR.beamline.session.get_beamtime_metadata()[2], "/beamline/p11/current" + ) + + "/processing", ) - + "/processing", - ) - os.system( - '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( - ssh=ssh, sbatch=sbatch, cmd=cmd + os.system( + '{ssh:s} "{sbatch:s} --wrap \\"{cmd:s}\\""'.format( + ssh=ssh, sbatch=sbatch, cmd=cmd + ) ) - ) + else: + self.log.debug("Beamtime metadata is not found. No online resouces available. Autoprocessing on the cluster is not available.") def trigger_auto_processing(self, process_event=None, frame_number=None): """Triggers auto processing based on the experiment type. @@ -1145,7 +1155,7 @@ def create_characterisation_directories(self): ) collection_type = HWR.beamline.collect.current_dc_parameters["experiment_type"] - print("************** PREPARING FOLDERS FOR COLLECTION TYPE", collection_type) + self.log.debug("PREPARING FOLDERS FOR COLLECTION TYPE", collection_type) xds_directory, auto_directory = self.prepare_input_files() xds_directory = xds_directory.replace("/rotational_", "/screening_").replace( diff --git a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py index 577c384cee..f762e84c76 100644 --- a/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py +++ b/mxcubecore/HardwareObjects/DESY/P11EigerDetector.py @@ -221,7 +221,7 @@ def stop_acquisition(self): def wait_ready(self, timeout=30): with gevent.Timeout(timeout, RuntimeError("timeout waiting detector ready")): while self.chan_status.get_value().lower() not in ["ready", "idle"]: - gevent.sleep(1) + gevent.sleep(2) def status_changed(self, status): self.log.debug("P11EigerDetector - status changed. now is %s" % status) diff --git a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py index 53a01bfd36..59433876c7 100644 --- a/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py +++ b/mxcubecore/HardwareObjects/DESY/P11ISPyBClient.py @@ -70,6 +70,19 @@ def store_robot_action(self, robot_action_dict): # TODO ISPyB is not ready for now. This prevents from error 500 from the server. pass + def _store_data_collection_group(self, group_data): + """ """ + + # Workaround to make the data collection work even if ISPyB is not available due to the beamtime is not opened. + try: + group_id = self._collection.service.storeOrUpdateDataCollectionGroup( + group_data + ) + except: + group_id = -9999 + + return group_id + def prepare_collect_for_lims(self, mx_collect_dict): # Attention! directory passed by reference. modified in place diff --git a/mxcubecore/HardwareObjects/DESY/P11Session.py b/mxcubecore/HardwareObjects/DESY/P11Session.py index 76d64dd8e3..d757321e96 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Session.py +++ b/mxcubecore/HardwareObjects/DESY/P11Session.py @@ -33,6 +33,7 @@ from mxcubecore.HardwareObjects.Session import Session + PATH_BEAMTIME = "/gpfs/current" PATH_COMMISSIONING = "/gpfs/commissioning" PATH_FALLBACK = "/gpfs/local" @@ -108,8 +109,8 @@ def is_beamtime_open(self): "=========== BEAMTIME IS OPEN (/gpfs/current exists) ============" ) else: - self.log.debug( - "=========== NO BEMTIME ID IS OPEN (check /gpfs/current) ============" + logging.getLogger("GUI").error( + "No beamtime ID is open (check /gpfs/current)" ) return self.is_writable_dir( @@ -336,8 +337,15 @@ def parse_metadata_file(self, metadatafile_path): ) def get_beamtime_metadata(self, root_dir="/gpfs"): - metadata_file = self.locate_metadata_file(root_dir) - return self.parse_metadata_file(metadata_file) + + try: + metadata_file = self.locate_metadata_file(root_dir) + return self.parse_metadata_file(metadata_file) + except: + self.log.debug( + "Metadata file can not be parsed. Check if beamtime is open." + ) + return None def get_ssh_command(self): ssh_command = "/usr/bin/ssh" From 75b0f1d2fd677fa80bcafb1cf6e85f331df21216 Mon Sep 17 00:00:00 2001 From: Andrey Gruzinov Date: Wed, 2 Oct 2024 13:50:28 +0200 Subject: [PATCH 153/172] Fix log debug in P11Collect --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 9c9756173d..0aa76bd9e6 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -1155,7 +1155,7 @@ def create_characterisation_directories(self): ) collection_type = HWR.beamline.collect.current_dc_parameters["experiment_type"] - self.log.debug("PREPARING FOLDERS FOR COLLECTION TYPE", collection_type) + self.log.debug("PREPARING FOLDERS FOR COLLECTION TYPE %s", str(collection_type)) xds_directory, auto_directory = self.prepare_input_files() xds_directory = xds_directory.replace("/rotational_", "/screening_").replace( From 146617c51fa24a30ca006eb14793621c7894f10f Mon Sep 17 00:00:00 2001 From: Andrey Gruzinov Date: Wed, 2 Oct 2024 14:22:53 +0200 Subject: [PATCH 154/172] Characterisation sequence fix in P11Collect --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 0aa76bd9e6..3740e5b605 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -666,16 +666,16 @@ def collect_characterisation( self.log.debug("#COLLECT# Running OMEGA through the std acquisition") HWR.beamline.diffractometer.wait_omega_on() HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) - time.sleep(1) + gevent.sleep(1) HWR.beamline.diffractometer.move_omega(start_pos) - time.sleep(1) + gevent.sleep(1) HWR.beamline.diffractometer.wait_omega_on() - time.sleep(1) + gevent.sleep(1) # NB! angles reversed could work??? HWR.beamline.diffractometer.set_pso_control_arm(start_angle, stop_angle) - time.sleep(3) + gevent.sleep(3) HWR.beamline.diffractometer.set_omega_velocity(self.acq_speed) - time.sleep(1) + gevent.sleep(1) #Arm the detector only once in the beginning. Set to wait 4 triggers. if img_no == 0: @@ -683,6 +683,8 @@ def collect_characterisation( time.sleep(3) HWR.beamline.diffractometer.move_omega(stop_pos) + HWR.beamline.diffractometer.wait_omega_on() + HWR.beamline.diffractometer.stop_motion() self.emit("progressStep", int(120 / (nimages) * (img_no + 1))) From ac351619b40326fdbeb9349cd214c45d9f1b9376 Mon Sep 17 00:00:00 2001 From: Andrey Gruzinov Date: Wed, 2 Oct 2024 14:58:32 +0200 Subject: [PATCH 155/172] Rebasing Removed extensive debug delays in characterisation P11Collect --- mxcubecore/HardwareObjects/DESY/P11Collect.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Collect.py b/mxcubecore/HardwareObjects/DESY/P11Collect.py index 3740e5b605..fd4af8784b 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Collect.py +++ b/mxcubecore/HardwareObjects/DESY/P11Collect.py @@ -666,22 +666,15 @@ def collect_characterisation( self.log.debug("#COLLECT# Running OMEGA through the std acquisition") HWR.beamline.diffractometer.wait_omega_on() HWR.beamline.diffractometer.set_omega_velocity(self.default_speed) - gevent.sleep(1) HWR.beamline.diffractometer.move_omega(start_pos) - gevent.sleep(1) HWR.beamline.diffractometer.wait_omega_on() - gevent.sleep(1) - # NB! angles reversed could work??? HWR.beamline.diffractometer.set_pso_control_arm(start_angle, stop_angle) - gevent.sleep(3) HWR.beamline.diffractometer.set_omega_velocity(self.acq_speed) - gevent.sleep(1) #Arm the detector only once in the beginning. Set to wait 4 triggers. if img_no == 0: HWR.beamline.detector.start_acquisition() time.sleep(3) - HWR.beamline.diffractometer.move_omega(stop_pos) HWR.beamline.diffractometer.wait_omega_on() HWR.beamline.diffractometer.stop_motion() From ccf3c60070b0a755404115735a117e704b6a1e99 Mon Sep 17 00:00:00 2001 From: Andrey Gruzinov Date: Tue, 5 Nov 2024 16:58:39 +0100 Subject: [PATCH 156/172] Linting --- mxcubecore/HardwareObjects/DESY/P11Session.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/DESY/P11Session.py b/mxcubecore/HardwareObjects/DESY/P11Session.py index d757321e96..087de814a3 100644 --- a/mxcubecore/HardwareObjects/DESY/P11Session.py +++ b/mxcubecore/HardwareObjects/DESY/P11Session.py @@ -33,7 +33,6 @@ from mxcubecore.HardwareObjects.Session import Session - PATH_BEAMTIME = "/gpfs/current" PATH_COMMISSIONING = "/gpfs/commissioning" PATH_FALLBACK = "/gpfs/local" From 7e6c0b9f2fdb66c624eedb0932f62ebf599c9746 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 6 Nov 2024 11:24:30 +0000 Subject: [PATCH 157/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1b91604a74..50b3eb4100 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.186.0" +version = "1.187.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From 2b1ec4e5070dd39651f257deb5574e0f6fb15961 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Tue, 5 Nov 2024 17:22:25 +0100 Subject: [PATCH 158/172] Fix deprecated code for redis client --- mxcubecore/HardwareObjects/DataPublisher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/DataPublisher.py b/mxcubecore/HardwareObjects/DataPublisher.py index 6906464e60..5d5f69582e 100644 --- a/mxcubecore/HardwareObjects/DataPublisher.py +++ b/mxcubecore/HardwareObjects/DataPublisher.py @@ -100,7 +100,7 @@ def init(self): rdb = self.get_property("db", 11) self._r = redis.Redis( - host=rhost, port=rport, db=rdb, charset="utf-8", decode_responses=True + host=rhost, port=rport, db=rdb, encoding="utf-8", decode_responses=True ) if not self._subsribe_task: From 62082d85c2749350f9e5dbd66770079ab9c227fd Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Wed, 6 Nov 2024 11:27:59 +0000 Subject: [PATCH 159/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 50b3eb4100..9fb70d0009 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.187.0" +version = "1.188.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From b9d23257b1fe47d9ea06e796c3eb66fff9104fb7 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Sat, 9 Nov 2024 16:16:15 +0100 Subject: [PATCH 160/172] [ESRF] EdnaWorkflow: send XML-RPC host and port to BES --- mxcubecore/HardwareObjects/EdnaWorkflow.py | 52 ++++++++++++---------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/mxcubecore/HardwareObjects/EdnaWorkflow.py b/mxcubecore/HardwareObjects/EdnaWorkflow.py index ea2291d6da..acc415cb72 100644 --- a/mxcubecore/HardwareObjects/EdnaWorkflow.py +++ b/mxcubecore/HardwareObjects/EdnaWorkflow.py @@ -2,6 +2,7 @@ import logging import os import pprint +import socket import time import gevent @@ -102,7 +103,7 @@ def command_failure(self): return self.command_failed def set_command_failed(self, *args): - logging.getLogger("HWR").error("Workflow '%s' Tango command failed!" % args[1]) + logging.getLogger("HWR").error("Workflow '%s' Tango command failed!", args[1]) self.command_failed = True def state_changed(self, new_value): @@ -174,19 +175,15 @@ def abort(self): self.gevent_event.set() self.command_failed = False if self.bes_workflow_id is not None: - abort_URL = os.path.join( - "http://{0}:{1}".format(self.bes_host, self.bes_port), - "ABORT", - self.bes_workflow_id, + abort_URL = ( + f"http://{self.bes_host}:{self.bes_port}/ABORT/{self.bes_workflow_id}" ) - logging.getLogger("HWR").info("BES abort web service URL: %r" % abort_URL) + logging.getLogger("HWR").info("BES abort web service URL: %r", abort_URL) response = requests.get(abort_URL) if response.status_code == 200: workflow_status = response.text logging.getLogger("HWR").info( - "BES workflow id {0}: {1}".format( - self.bes_workflow_id, workflow_status - ) + "BES workflow id %s: %s", self.bes_workflow_id, workflow_status ) self.state.value = "ON" @@ -231,35 +228,42 @@ def start(self, list_arguments): time0 = time.time() self.startBESWorkflow() time1 = time.time() - logging.info("Time to start workflow: {0}".format(time1 - time0)) + logging.info("Time to start workflow: %f sec", time1 - time0) def startBESWorkflow(self): - logging.info("Starting workflow {0}".format(self.workflow_name)) + logging.info("Starting workflow %s", self.workflow_name) + + xml_rpc_server = HWR.beamline.xml_rpc_server + if xml_rpc_server is None: + logging.getLogger("HWR").warning("No XMLRPCServer configured") + return + logging.info( - "Starting a workflow on http://%s:%d/BES" % (self.bes_host, self.bes_port) - ) - start_URL = os.path.join( - "/BES", "bridge", "rest", "processes", self.workflow_name, "RUN" + "Starting a workflow on http://%s:%d/BES", self.bes_host, self.bes_port ) + self.dict_parameters["initiator"] = HWR.beamline.session.endstation_name self.dict_parameters["sessionId"] = HWR.beamline.session.session_id self.dict_parameters["externalRef"] = HWR.beamline.session.get_proposal() - self.dict_parameters["token"] = self.token - start_URL = os.path.join( - "http://{0}:{1}".format(self.bes_host, self.bes_port), - "RUN", - self.workflow_name, - ) - logging.getLogger("HWR").info("BES start URL: %r" % start_URL) + self.dict_parameters["token"] = ( + self.token + ) # Deprecated in favor of mxcubeParameters + self.dict_parameters["mxcubeParameters"] = { + "host": socket.getfqdn(), + "port": xml_rpc_server.port, + "token": self.token, + } + + start_URL = f"http://{self.bes_host}:{self.bes_port}/RUN/{self.workflow_name}" + logging.getLogger("HWR").info("BES start URL: %r", start_URL) response = requests.post(start_URL, json=self.dict_parameters) if response.status_code == 200: self.state.value = "RUNNING" request_id = response.text logging.getLogger("HWR").info( - "Workflow started, request id: %r" % request_id + "Workflow started, BES request id: %r", request_id ) self.bes_workflow_id = request_id else: logging.getLogger("HWR").error("Workflow didn't start!") - request_id = None self.state.value = "ON" From 540e19b2f899f0d8eb0ee8b5f8630d416f38212a Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 12 Nov 2024 13:20:21 +0000 Subject: [PATCH 161/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9fb70d0009..32df3af552 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.188.0" +version = "1.189.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From a5fbd56ec165f802d63581dd29b224cbf492ba88 Mon Sep 17 00:00:00 2001 From: rhfogh Date: Wed, 6 Nov 2024 14:00:32 +0000 Subject: [PATCH 162/172] Removed obsolete temporary fix for hdf5 file names --- mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py index e15cae8b5b..de50ae5817 100644 --- a/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py +++ b/mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py @@ -360,7 +360,7 @@ def query_pre_strategy_params(self, choose_lattice=None): point_group = point_groups[-1] lattice_tags = [""] + list(lattice2point_group_tags) if space_group not in crystal_symmetry.XTAL_SPACEGROUPS: - # Non-enantiomeric sace groups not supported in user interface + # Non-enantiomeric space groups not supported in user interface space_group = "" else: lattice = "" @@ -1909,7 +1909,6 @@ def collect_data(self, payload, correlation_id): last_orientation = () maxdev = -1 snapshotted_rotation_ids = set() - scan_numbers = {} for scan in scans: sweep = scan.sweep acq = queue_model_objects.Acquisition() @@ -1983,11 +1982,6 @@ def collect_data(self, payload, correlation_id): path_template.run_number = int(ss0) if ss0 else 1 path_template.start_num = acq_parameters.first_image path_template.num_files = acq_parameters.num_images - if path_template.suffix.endswith("h5"): - # Add scan number to prefix for interleaved hdf5 files (only) - # NBNB Tempoary fix, pending solution to hdf5 interleaving problem - scan_numbers[prefix] = scan_no = scan_numbers.get(prefix, 0) + 1 - prefix += "_s%s" % scan_no path_template.base_prefix = prefix key = ( From f4e7766c4453451c89ec82145a2b79a4d91fd2ca Mon Sep 17 00:00:00 2001 From: rhfogh Date: Thu, 7 Nov 2024 16:32:59 +0000 Subject: [PATCH 163/172] Bug fix - changed save_scene_snapshot call to save_snapshot --- mxcubecore/HardwareObjects/mockup/CollectMockup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxcubecore/HardwareObjects/mockup/CollectMockup.py b/mxcubecore/HardwareObjects/mockup/CollectMockup.py index e9415d4751..f4f3c36261 100644 --- a/mxcubecore/HardwareObjects/mockup/CollectMockup.py +++ b/mxcubecore/HardwareObjects/mockup/CollectMockup.py @@ -149,7 +149,7 @@ def stop_collect(self): @task def _take_crystal_snapshot(self, filename): - HWR.beamline.sample_view.save_scene_snapshot(filename) + HWR.beamline.sample_view.save_snapshot(filename) @task def _take_crystal_animation(self, animation_filename, duration_sec=1): From 1dd8f9124f8428cf04c16814c14c3c3e885ab440 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 12 Nov 2024 13:58:48 +0000 Subject: [PATCH 164/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 32df3af552..e0bc109464 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.189.0" +version = "1.190.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "] From bbe3e30f533959e6f59945a81d90a4ee4b4c250e Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 14:47:37 +0100 Subject: [PATCH 165/172] Remove TangoLimaVideoLoopback --- .../HardwareObjects/TangoLimaVideoLoopback.py | 270 ------------------ 1 file changed, 270 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py b/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py deleted file mode 100644 index c856723403..0000000000 --- a/mxcubecore/HardwareObjects/TangoLimaVideoLoopback.py +++ /dev/null @@ -1,270 +0,0 @@ -"""Class for cameras connected to Lima Tango Device Servers - -Example configuration: ----------------------- - - Prosilica 1350C - id23/limaccd/minidiff2 - id23/limabeamviewer/minidiff2 - 15 - RGB24 - - -If video mode is not specified, BAYER_RG16 is used by default. -""" - -import fcntl -import logging -import os -import subprocess -import time -import uuid - -import gevent -import gipc -import v4l2 - -from mxcubecore.HardwareObjects.TangoLimaVideo import ( - TangoLimaVideo, - poll_image, -) - - -def _poll_image(sleep_time, video_device, device_uri, video_mode, formats): - from PyTango import DeviceProxy - - connected = False - while not connected: - try: - logging.getLogger("HWR").info("Connecting to %s", device_uri) - lima_tango_device = DeviceProxy(device_uri) - lima_tango_device.ping() - - except Exception as ex: - logging.getLogger("HWR").exception("") - logging.getLogger("HWR").info( - "Could not connect to %s, retrying ...", device_uri - ) - connected = False - time.sleep(0.2) - else: - connected = True - - while True: - try: - data = poll_image(lima_tango_device, video_mode, formats)[0] - video_device.write(data) - except Exception as ex: - print(ex) - finally: - time.sleep(sleep_time / 2) - - -def start_video_stream(scale, _hash, fpath): - """ - Start encoding and streaming from device video_device. - - :param str device: The path to the device to stream from - :returns: Tupple with the two processes performing streaming and encoding - :rtype: tuple - """ - websocket_relay_js = os.path.join(os.path.dirname(fpath), "websocket-relay.js") - - FNULL = open(os.devnull, "w") - - relay = subprocess.Popen( - ["node", websocket_relay_js, _hash, "4041", "4042"], close_fds=True - ) - - # Make sure that the relay is running (socket is open) - time.sleep(2) - - scale = "%sx%s" % scale # tuple(scale.split(",")) - - ffmpeg = subprocess.Popen( - [ - "ffmpeg", - "-f", - "rawvideo", - "-pixel_format", - "rgb24", - "-s", - scale, - "-i", - "-", - "-f", - "mpegts", - "-b:v", - "6000k", - "-q:v", - "4", - "-an", - "-vcodec", - "mpeg1video", - "http://localhost:4041/" + _hash, - ], - stderr=FNULL, - stdin=subprocess.PIPE, - shell=False, - close_fds=True, - ) - - return relay, ffmpeg - - -class TangoLimaVideoLoopback(TangoLimaVideo): - def __init__(self, name): - super(TangoLimaVideoLoopback, self).__init__(name) - - self._video_stream_process = None - self._current_stream_size = -1, -1 - self._original_stream_size = -1, -1 - self._stream_script_path = "" - self.stream_hash = str(uuid.uuid1()) - self.video_device = None - self._polling_mode = "gevent" - self._p = None - - def init(self): - super(TangoLimaVideoLoopback, self).init() - self._polling_mode = self.get_property("polling_mode", "gevent") - - def _do_polling(self, sleep_time): - if self._polling_mode == "process": - self._p = gipc.start_process( - target=_poll_image, - args=( - sleep_time, - self.video_device, - self.get_property("tangoname"), - self.video_mode, - self._FORMATS, - ), - ) - else: - self._p = gevent.spawn( - _poll_image, - sleep_time, - self.video_device, - self.get_property("tangoname"), - self.video_mode, - self._FORMATS, - ) - - def _open_video_device(self, path="/dev/video0"): - if os.path.exists(path): - device = open(path, "wb", 0) - self.video_device = device - else: - msg = "Cannot open video device %s, path do not exist. " % path - msg += "Make sure that the v4l2loopback kernel module is loaded (modprobe v4l2loopback). " - msg += "Falling back to MJPEG." - raise RuntimeError(msg) - - return self.video_device - - def _initialize_video_device(self, pixel_format, width, height, channels): - f = v4l2.v4l2_format() - f.type = v4l2.V4L2_BUF_TYPE_VIDEO_OUTPUT - f.fmt.pix.pixelformat = pixel_format - f.fmt.pix.width = width - f.fmt.pix.height = height - f.fmt.pix.field = v4l2.V4L2_FIELD_NONE - f.fmt.pix.bytesperline = width * channels - f.fmt.pix.sizeimage = width * height * channels - f.fmt.pix.colorspace = v4l2.V4L2_COLORSPACE_SRGB - - res = fcntl.ioctl(self.video_device, v4l2.VIDIOC_S_FMT, f) - - if res != 0: - raise RuntimeError("Could not initialize video device: %d" % res) - - return True - - def _encoder_friendly_size(self, w, h): - # Some video decoders have difficulties to decode videos with odd image dimensions - # (JSMPEG beeing one of them) so we make sure that the size is even - w = w if w % 2 == 0 else w + 1 - h = h if h % 2 == 0 else h + 1 - - return w, h - - def set_stream_size(self, w, h): - w, h = self._encoder_friendly_size(w, h) - self._current_stream_size = (int(w), int(h)) - - def _set_stream_original_size(self, w, h): - w, h = self._encoder_friendly_size(w, h) - self._original_stream_size = w, h - - def get_stream_size(self): - width, height = self._current_stream_size - scale = float(width) / self._original_stream_size[0] - return (width, height, scale) - - def get_available_stream_sizes(self): - try: - w, h = self._encoder_friendly_size(self.get_width(), self.get_height()) - # Calculate half the size and quarter of the size if MPEG streaming is used - # otherwise just return the orignal size. - if self._video_stream_process: - video_sizes = [(w, h), (w / 2, h / 2), (w / 4, h / 4)] - else: - video_sizes = [(w, h)] - - except (ValueError, AttributeError): - video_sizes = [] - - return video_sizes - - def start_video_stream_process(self): - if self._video_stream_process: - self.stop_video_stream_process() - - if ( - not self._video_stream_process - or self._video_stream_process.poll() is not None - ): - python_executable = os.sep.join( - os.path.dirname(os.__file__).split(os.sep)[:-2] + ["bin", "python"] - ) - - # self._video_stream_process = subprocess.Popen( - # [ - # python_executable, - # self._stream_script_path, - # self.video_device.name, - # self._current_stream_size, - # self.stream_hash, - # ], - # close_fds=True, - # ) - - size = self.get_width(), self.get_height() - self._video_stream_process = start_video_stream( - size, self.stream_hash, self._stream_script_path - )[1] - self.video_device = self._video_stream_process.stdin - - def stop_video_stream_process(self): - if self._video_stream_process: - os.system("pkill -TERM -P {pid}".format(pid=self._video_stream_process.pid)) - self._video_stream_process = None - - def restart(self): - self.start_video_stream_process() - - def start(self, loopback_device_path, stream_script_path): - self._stream_script_path = stream_script_path - w, h = self.get_width(), self.get_height() - - self._open_video_device(loopback_device_path) - # self._initialize_video_device(v4l2.V4L2_PIX_FMT_RGB24, w, h, 3) - - self.set_stream_size(w, h) - self._set_stream_original_size(w, h) - self.start_video_stream_process() - - self._do_polling(self.device.video_exposure) - - return self.video_device From 9ec58ee392b1a9993738a7c261459bbc32545f4e Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 14:48:40 +0100 Subject: [PATCH 166/172] remove imageType --- mxcubecore/HardwareObjects/Camera.py | 8 -------- mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py | 6 ------ mxcubecore/HardwareObjects/LNLS/LNLSCamera.py | 3 --- mxcubecore/HardwareObjects/VaporyVideo.py | 6 ------ .../HardwareObjects/abstract/AbstractVideoDevice.py | 6 ------ mxcubecore/HardwareObjects/mockup/MDCameraMockup.py | 3 --- 6 files changed, 32 deletions(-) diff --git a/mxcubecore/HardwareObjects/Camera.py b/mxcubecore/HardwareObjects/Camera.py index c58d48dc48..8abe23f70d 100644 --- a/mxcubecore/HardwareObjects/Camera.py +++ b/mxcubecore/HardwareObjects/Camera.py @@ -236,10 +236,6 @@ def setImageTypeFromXml(self, property_name): elif image_type.lower().startswith("mmap:"): self.imgtype = MmapType(image_type.split(":")[1]) - def imageType(self): - """Returns a 'jpeg' or 'bayer' type object depending on the image type""" - return self.imgtype - def newImage(self, img_cnt): streamChan = self.get_channel_object("stream") self.emit( @@ -761,10 +757,6 @@ def init(self): def oprint(self, msg): print(("Camera.py--taco device--%s" % msg)) - def imageType(self): - """Returns a 'jpeg' or 'bayer' type object depending on the image type""" - return self.imgtype - def value_changed(self, deviceName, value): self.emit( "imageReceived", diff --git a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py index 7e953c6607..40a860aca8 100644 --- a/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py +++ b/mxcubecore/HardwareObjects/DESY/MjpgStreamVideo.py @@ -581,12 +581,6 @@ def get_image_dimensions(self): def get_scale(self): return self.scale - def imageType(self): - """ - Descript. : - """ - return - def contrast_exists(self): """ Descript. : diff --git a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py index e19c0b7963..ff7619583e 100644 --- a/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py +++ b/mxcubecore/HardwareObjects/LNLS/LNLSCamera.py @@ -348,9 +348,6 @@ def setLive(self, live): except: return False - def imageType(self): - return None - def takeSnapshot(self, *args): pass #imgFile = QtCore.QFile(args[0]) diff --git a/mxcubecore/HardwareObjects/VaporyVideo.py b/mxcubecore/HardwareObjects/VaporyVideo.py index f4ea8a98ea..8a737d63e7 100755 --- a/mxcubecore/HardwareObjects/VaporyVideo.py +++ b/mxcubecore/HardwareObjects/VaporyVideo.py @@ -89,12 +89,6 @@ def generate_image(self): self.force_update, ) - def imageType(self): - """ - Descript. : - """ - return self.image_type - def contrastExists(self): """ Descript. : diff --git a/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py b/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py index df32f1264a..a479e9d4e6 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py @@ -338,12 +338,6 @@ def get_scaling_factor(self): get_image_zoom = get_scaling_factor - def imageType(self): - """ - Descript. : returns image type (not used) - """ - return self.image_format - def start_camera(self): """Start""" return diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index 938be393fa..66d219b9fc 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -94,9 +94,6 @@ def set_live(self, state) -> bool: self.liveState = state return True - def imageType(self): - return None - def get_last_image(self) -> Tuple[bytes, int, int]: image = Image.open(self.image) return image.tobytes(), image.size[0], image.size[1] From f373532c2ceb1cf5029a35b764bc92d31d05e27a Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 14:56:29 +0100 Subject: [PATCH 167/172] Remove VaporyVideo --- mxcubecore/HardwareObjects/VaporyVideo.py | 233 ---------------------- 1 file changed, 233 deletions(-) delete mode 100755 mxcubecore/HardwareObjects/VaporyVideo.py diff --git a/mxcubecore/HardwareObjects/VaporyVideo.py b/mxcubecore/HardwareObjects/VaporyVideo.py deleted file mode 100755 index 8a737d63e7..0000000000 --- a/mxcubecore/HardwareObjects/VaporyVideo.py +++ /dev/null @@ -1,233 +0,0 @@ -""" -[Name] VaporyVideo - -[Description] -Hardware object to simulate video with loop object. Hardware object is based -on a LimaVideo hardware object. It contains SimulatedLoop class that could -be used to display and navigate loop. -At this version vapory generates image each second and stores in /tmp. -At first look there is no direct conversion from vapory scene to qimage. - -[Channels] - -[Commands] - -[Emited signals] - - - imageReceived : emits qimage to bricks - -[Included Hardware Objects] -""" - -import time - -import gevent -import vapory - -from mxcubecore import BaseHardwareObjects -from mxcubecore.HardwareObjects.Camera import JpegType -from mxcubecore.utils.qt_import import QImage - - -class VaporyVideo(BaseHardwareObjects.HardwareObject): - """ - Descript. : - """ - - def __init__(self, name): - """ - Descript. : - """ - super().__init__(name) - self.force_update = None - self.image_dimensions = None - self.image_polling = None - self.image_type = None - self.qimage = None - - def init(self): - """ - Descript. : - """ - self.vapory_camera = vapory.Camera("location", [0, 2, -3], "look_at", [0, 1, 2]) - self.vapory_light = vapory.LightSource([2, 4, -3], "color", [1, 1, 1]) - - self.simulated_loop = SimulatedLoop() - self.simulated_loop.set_position(0, 0, 0) - - self.force_update = False - self.image_dimensions = [600, 400] - self.image_type = JpegType() - self.set_is_ready(True) - self.generate_image() - - self.image_polling = gevent.spawn(self._do_imagePolling, 1) - - def rotate_scene_absolute(self, angle): - self.simulated_loop.set_position(angle, 0, 0) - self.generate_image() - - def rotate_scene_relative(self, angle): - return - - def generate_image(self): - self.vapory_sene = vapory.Scene( - self.vapory_camera, - objects=[self.vapory_light, self.simulated_loop.loop_object], - ) - image_array = self.vapory_sene.render( - "/tmp/vapory_tmp_image.png", - width=self.image_dimensions[0], - height=self.image_dimensions[1], - ) - self.qimage = QImage("/tmp/vapory_tmp_image.png") - self.emit( - "imageReceived", - self.qimage, - self.qimage.width(), - self.qimage.height(), - self.force_update, - ) - - def contrastExists(self): - """ - Descript. : - """ - return - - def setContrast(self, contrast): - """ - Descript. : - """ - return - - def getContrast(self): - """ - Descript. : - """ - return - - def getContrastMinMax(self): - """ - Descript. : - """ - return - - def brightnessExists(self): - """ - Descript. : - """ - return - - def setBrightness(self, brightness): - """ - Descript. : - """ - return - - def getBrightness(self): - """ - Descript. : - """ - return - - def getBrightnessMinMax(self): - """ - Descript. : - """ - return - - def gainExists(self): - """ - Descript. : - """ - return - - def setGain(self, gain): - """ - Descript. : - """ - return - - def getGain(self): - """ - Descript. : - """ - return - - def getGainMinMax(self): - """ - Descript. : - """ - return - - def gammaExists(self): - """ - Descript. : - """ - return - - def setGamma(self, gamma): - """ - Descript. : - """ - return - - def getGamma(self): - """ - Descript. : - """ - return - - def getGammaMinMax(self): - """ - Descript. : - """ - return (0, 1) - - def set_live(self, mode): - """ - Descript. : - """ - return - - def get_width(self): - """ - Descript. : - """ - return self.image_dimensions[0] - - def get_height(self): - """ - Descript. : - """ - return self.image_dimensions[1] - - def _do_imagePolling(self, sleep_time): - """ - Descript. : - """ - while True: - image_array = self.vapory_sene.render( - "/tmp/vapory_tmp_image.png", - width=self.image_dimensions[0], - height=self.image_dimensions[1], - ) - self.qimage = QImage("/tmp/vapory_tmp_image.png") - self.emit( - "imageReceived", - self.qimage, - self.qimage.width(), - self.qimage.height(), - self.force_update, - ) - time.sleep(sleep_time) - - -class SimulatedLoop: - def __init__(self): - self.texture = vapory.Texture(vapory.Pigment("color", [1, 0, 1])) - self.loop_object = vapory.Box([0, 0, 0], 2, self.texture) - - def set_position(self, x, y, z): - self.loop_object.args = [[x, y, z], 2, self.texture] From 0fe3750653e9a786e7376ee6b9b0b997b4e760ff Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 15:00:55 +0100 Subject: [PATCH 168/172] fix import in VimbaVideo.py --- mxcubecore/HardwareObjects/VimbaVideo.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/mxcubecore/HardwareObjects/VimbaVideo.py b/mxcubecore/HardwareObjects/VimbaVideo.py index d49161dc3d..fc0920968b 100644 --- a/mxcubecore/HardwareObjects/VimbaVideo.py +++ b/mxcubecore/HardwareObjects/VimbaVideo.py @@ -1,7 +1,6 @@ import atexit import time -import numpy as np from pymba import Vimba try: @@ -9,8 +8,6 @@ except ImportError: pass -from abstract.AbstractVideoDevice import AbstractVideoDevice - from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice from mxcubecore.utils.qt_import import ( QImage, From 7d73a676fbfcd64d96a654a3aea602e67f917d7b Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 17:08:11 +0100 Subject: [PATCH 169/172] Remove Camera.py --- mxcubecore/HardwareObjects/Camera.py | 980 ------------------ .../configuration/esrf_id231/ccd/ge1350c.xml | 14 - .../esrf_id231/ccd/ge1350c_hutch.xml | 11 - .../configuration/esrf_id231/ccd/meteor1.xml | 5 - .../configuration/esrf_id231/ccd/meteor2.xml | 5 - .../configuration/esrf_id231/ccd/meteor3.xml | 5 - .../configuration/esrf_id231/ccd/meteor4.xml | 5 - .../esrf_id29/ccd/prosilica_md2.xml | 12 - 8 files changed, 1037 deletions(-) delete mode 100644 mxcubecore/HardwareObjects/Camera.py delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/ge1350c.xml delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/ge1350c_hutch.xml delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/meteor1.xml delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/meteor2.xml delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/meteor3.xml delete mode 100755 mxcubecore/configuration/esrf_id231/ccd/meteor4.xml delete mode 100644 mxcubecore/configuration/esrf_id29/ccd/prosilica_md2.xml diff --git a/mxcubecore/HardwareObjects/Camera.py b/mxcubecore/HardwareObjects/Camera.py deleted file mode 100644 index 8abe23f70d..0000000000 --- a/mxcubecore/HardwareObjects/Camera.py +++ /dev/null @@ -1,980 +0,0 @@ -"""Class for cameras connected to framegrabbers run by Taco Device Servers - -template: - - user label - - polling interval (in ms.) - - -""" - -import logging -import os -import sys -import time - -import gevent - -from mxcubecore import ( - BaseHardwareObjects, - CommandContainer, -) - -try: - from Qub.CTools.qttools import BgrImageMmap -except ImportError: - logging.getLogger("HWR").warning( - "Qub memory map not available: cannot use mmap image type" - ) - BgrImageMmap = None - -try: - import Image -except ImportError: - logging.getLogger("HWR").warning("PIL not available: cannot take snapshots") - canTakeSnapshots = False -else: - canTakeSnapshots = True - - -class ImageType: - def __init__(self, type=None): - self.image_type = type - - def type(self): - return self.image_type - - -class JpegType(ImageType): - def __init__(self): - ImageType.__init__(self, "jpeg") - - -class BayerType(ImageType): - def __init__(self, bayer_matrix): - ImageType.__init__(self, "bayer") - self.bayer_matrix = bayer_matrix.upper() - - -class RawType(ImageType): - def __init__(self): - ImageType.__init__(self, "raw") - - -class MmapType(ImageType): - def __init__(self, mmapFile): - ImageType.__init__(self, "mmap") - self.mmapFile = mmapFile - - -class RGBType(ImageType): - def __init__(self, mmapFile): - ImageType.__init__(self, "rgb") - - -class Camera(BaseHardwareObjects.HardwareObject): - def _init(self): - if self.get_property("tangoname"): - # Tango device - import PyTango - - class TangoCamera(BaseHardwareObjects.HardwareObject): - def __init__(self, name): - super().__init__(name) - - def oprint(self, msg): - print(("Camera.py--tango device-- %s" % msg)) - - def _init(self): - self.forceUpdate = False - self.device = None - self.imgtype = None - try: - self.device = PyTango.DeviceProxy(self.tangoname) - # try a first call to get an exception if the device - # is not exported - self.device.ping() - except PyTango.DevFailed as traceback: - last_error = traceback[-1] - logging.getLogger("HWR").error( - "%s: %s", str(self.name()), last_error.desc - ) - - self.device = BaseHardwareObjects.Null() - self.bpmDevice = None - else: - self.setImageTypeFromXml("imagetype") - - self.__brightnessExists = False - self.__contrastExists = False - self.__gainExists = False - self.__gammaExists = False - - _attribute_list = self.device.get_attribute_list() - # self.oprint ("attribute list:") - # self.oprint (_attribute_list) - - imgChan = self.add_channel( - {"type": "tango", "name": "image", "read_as_str": 1}, - "RgbImage", - ) - imgWidth = self.add_channel( - {"type": "tango", "name": "width"}, "Width" - ) - imgHeight = self.add_channel( - {"type": "tango", "name": "height"}, "Height" - ) - fullWidth = self.add_channel( - {"type": "tango", "name": "fullwidth"}, "FullWidth" - ) - fullHeight = self.add_channel( - {"type": "tango", "name": "fullheight"}, "FullHeight" - ) - roi = self.add_channel({"type": "tango", "name": "roi"}, "Roi") - exposure = self.add_channel( - {"type": "tango", "name": "exposure"}, "Exposure" - ) - - if "Brightness" in _attribute_list: - print("add brightness") - brightness = self.add_channel( - {"type": "tango", "name": "brightness"}, "Brightness" - ) - self.__brightnessExists = True - - if "Contrast" in _attribute_list: - contrast = self.add_channel( - {"type": "tango", "name": "contrast"}, "Contrast" - ) - self.__contrastExists = True - - if "Gain" in _attribute_list: - gain = self.add_channel( - {"type": "tango", "name": "gain"}, "Gain" - ) - self.__gainExists = True - - if "Gamma" in _attribute_list: - gamma = self.add_channel( - {"type": "tango", "name": "gamma"}, "Gamma" - ) - self.__gammaExists = True - - self.set_is_ready(True) - - """ - Check wether there is a BPM device defined or not - """ - if self.get_property("bpmname"): - self.bpmDevice = CommandContainer.CommandContainer() - self.bpmDevice.tangoname = self.bpmname - threshold = self.bpmDevice.add_channel( - {"type": "tango", "name": "threshold"}, "Threshold" - ) - centerx = self.bpmDevice.add_channel( - {"type": "tango", "name": "centerx"}, "X" - ) - centery = self.bpmDevice.add_channel( - {"type": "tango", "name": "centery"}, "Y" - ) - fwhmx = self.bpmDevice.add_channel( - {"type": "tango", "name": "fwhmx"}, "XFwhm" - ) - fwhmy = self.bpmDevice.add_channel( - {"type": "tango", "name": "fwhmy"}, "YFwhm" - ) - maxpix = self.bpmDevice.add_channel( - {"type": "tango", "name": "maxpix"}, "MaxPixelValue" - ) - intensity = self.bpmDevice.add_channel( - {"type": "tango", "name": "intensity"}, "Intensity" - ) - onCmd = self.bpmDevice.add_command( - {"type": "tango", "name": "on"}, "On" - ) - offCmd = self.bpmDevice.add_command( - {"type": "tango", "name": "off"}, "Off" - ) - stateCmd = self.bpmDevice.add_command( - {"type": "tango", "name": "state"}, "State" - ) - else: - self.bpmDevice = None - logging.getLogger("HWR").warning( - "%s: No BPM defined", str(self.name()) - ) - - def setImageTypeFromXml(self, property_name): - image_type = self.get_property(property_name) or "Jpeg" - - if image_type.lower() == "jpeg": - streamChan = self.add_channel( - {"type": "tango", "name": "stream", "read_as_str": 1}, - "JpegImage", - ) - self.imgtype = JpegType() - elif image_type.lower().startswith("bayer:"): - streamChan = self.add_channel( - {"type": "tango", "name": "stream", "read_as_str": 1}, - "BayerImage", - ) - self.imgtype = BayerType(image_type.split(":")[1]) - elif image_type.lower().startswith("raw"): - streamChan = self.add_channel( - {"type": "tango", "name": "stream", "read_as_str": 1}, - "Image", - ) - self.imgtype = RawType() - elif image_type.lower().startswith("mmap:"): - self.imgtype = MmapType(image_type.split(":")[1]) - - def newImage(self, img_cnt): - streamChan = self.get_channel_object("stream") - self.emit( - "imageReceived", - streamChan.get_value(), - self.get_width(), - self.get_height(), - self.forceUpdate, - ) - - def __checkImageCounter(self, lastImageNumber=[0]): - lastNumber = lastImageNumber[0] - currentNumber = self.__mmapBgr.getImageCount() - if currentNumber != lastNumber: - lastImageNumber[0] = currentNumber - newImage = self.__mmapBgr.getNewImage() - self.emit( - "imageReceived", - ( - newImage, - newImage.width(), - newImage.height(), - self.forceUpdate, - ), - ) - - def _do_mmapBrgPolling(self, sleep_time): - while True: - self.__checkImageCounter() - time.sleep(sleep_time) - - def connect_notify(self, signal): - if signal == "imageReceived": - try: - display_num = os.environ["DISPLAY"].split(":")[1] - except Exception: - remote_client = False - else: - remote_client = display_num != "0.0" - - if remote_client and self.get_property("remote_imagetype"): - self.setImageTypeFromXml("remote_imagetype") - - if isinstance(self.imgtype, MmapType): - self.__mmapBgr = BgrImageMmap(self.imgtype.mmapFile) - self.__mmapBrgPolling = gevent.spawn( - self._do_mmapBrgPolling, - self.get_property("interval") / 1000.0, - ) - else: - try: - imgCnt = self.add_channel( - { - "type": "tango", - "name": "img_cnt", - "polling": self.get_property("interval"), - }, - "ImageCounter", - ) - imgCnt.connect_signal("update", self.newImage) - except Exception: - pass - - # ############ CONTRAST ################# - - def contrastExists(self): - return self.__contrastExists - - def setContrast(self, contrast): - """tango""" - try: - contrastChan = self.get_channel_object("contrast") - contrastChan.set_value(str(contrast)) - except Exception: - self.oprint("setContrast failed") - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - - def getContrast(self): - """tango""" - try: - contrastChan = self.get_channel_object("contrast") - contrast = contrastChan.get_value() - return contrast - except Exception: - self.oprint("getContrast failed") - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - return -1 - - def getContrastMinMax(self): - _config = self.device.get_attribute_config("contrast") - return (_config.min_value, _config.max_value) - - # ############ BRIGHTNESS ################# - - def brightnessExists(self): - return self.__brightnessExists - - def setBrightness(self, brightness): - """tango""" - try: - brightnessChan = self.get_channel_object("brightness") - brightnessChan.set_value(brightness) - except Exception: - self.oprint("setBrightness failed") - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - - def getBrightness(self): - """tango""" - try: - brightnessChan = self.get_channel_object("brightness") - brightness = brightnessChan.get_value() - return brightness - except Exception: - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - return -1 - - def getBrightnessMinMax(self): - _config = self.device.get_attribute_config("brightness") - return (_config.min_value, _config.max_value) - - # ############ GAIN ################# - - def gainExists(self): - return self.__gainExists - - def setGain(self, gain): - """tango""" - try: - gainChan = self.get_channel_object("gain") - # ???? gainChan.set_value(str(gain)) - gainChan.set_value(gain) - except Exception: - self.oprint("setGain failed") - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - - def getGain(self): - """tango""" - try: - gainChan = self.get_channel_object("gain") - gain = gainChan.get_value() - return gain - except Exception: - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - self.oprint("getGain failed") - return -1 - - def getGainMinMax(self): - _config = self.device.get_attribute_config("gain") - return (_config.min_value, _config.max_value) - - # ############ GAMMA ################# - - def gammaExists(self): - return self.__gammaExists - - def setGamma(self, gamma): - """tango""" - try: - gammaChan = self.get_channel_object("gamma") - gammaChan.set_value(gamma) - except Exception: - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - - def getGamma(self): - """tango""" - try: - gammaChan = self.get_channel_object("gamma") - gamma = gammaChan.get_value() - return gamma - except Exception: - sys.excepthook( - sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] - ) - return -1 - - def getGammaMinMax(self): - _config = self.device.get_attribute_config("gamma") - return (_config.min_value, _config.max_value) - - # ############ WIDTH ################# - - def get_width(self): - """tango""" - width = self.get_channel_object("width") - return width.get_value() - - def get_height(self): - """tango""" - height = self.get_channel_object("height") - - return height.get_value() - - def setSize(self, width, height): - """Set new image size - - Only takes width into account, because anyway - we can only set a scale factor - """ - return - - def takeSnapshot(self, *args, **kwargs): - """tango""" - if canTakeSnapshots: - imgChan = self.get_channel_object("image") - rawimg = imgChan.get_value() - w = self.get_width() - h = self.get_height() - if len(rawimg) == w * h * 3: - img_type = "RGB" - else: - img_type = "L" - try: - if kwargs.get("bw", False) and img_type == "RGB": - img = Image.frombuffer( - img_type, - (self.get_width(), self.get_height()), - rawimg, - ).convert("L") - else: - img = Image.frombuffer( - img_type, - (self.get_width(), self.get_height()), - rawimg, - ) - img = img.transpose(Image.FLIP_TOP_BOTTOM) - # img.save(*args) - except Exception: - logging.getLogger("HWR").exception( - "%s: could not save snapshot", self.name() - ) - else: - if len(args): - try: - img.save(*args) - except Exception: - logging.getLogger("HWR").exception( - "%s: could not save snapshot", self.name() - ) - else: - return True - else: - return img - else: - logging.getLogger("HWR").error( - "%s: could not take snapshot: sorry PIL is not available :-(", - self.name(), - ) - return False - - take_snapshot = takeSnapshot - - """ - BPM method - """ - - def setBpm(self, bpmOn): - """tango""" - if self.bpmDevice is not None: - if bpmOn: - self.bpmDevice.execute_command("on") - else: - self.bpmDevice.execute_command("off") - - def getBpmState(self): - """tango""" - if self.bpmDevice is not None: - return self.bpmDevice.execute_command("state") - else: - return PyTango.DevState.UNKNOWN - - def getBpmValues(self): - """Tango""" - if self.bpmDevice is not None: - # self.oprint("bpmDevice name =%s"%self.bpmDevice.tangoname) - try: - threshold = self.bpmDevice.get_channel_object( - "threshold" - ).get_value() - except Exception: - threshold = -1 - try: - centerx = self.bpmDevice.get_channel_object( - "centerx" - ).get_value() - except Exception: - centerx = -1 - try: - centery = self.bpmDevice.get_channel_object( - "centery" - ).get_value() - except Exception: - centery = -1 - try: - fwhmx = self.bpmDevice.get_channel_object( - "fwhmx" - ).get_value() - except Exception: - fwhmx = -1 - try: - fwhmy = self.bpmDevice.get_channel_object( - "fwhmy" - ).get_value() - except Exception: - fwhmy = -1 - try: - maxpix = self.bpmDevice.get_channel_object( - "maxpix" - ).get_value() - except Exception: - maxpix = -1 - try: - intensity = self.bpmDevice.get_channel_object( - "intensity" - ).get_value() - except Exception: - intensity = -1 - # self.oprint("Device name =%s"%self.device.name()) - try: - exposure = self.get_channel_object("exposure").get_value() - except Exception: - exposure = -1 - - # SIZES - try: - width = self.get_channel_object("fullwidth").get_value() - except Exception: - width = -1 - try: - height = self.get_channel_object("fullheight").get_value() - except Exception: - height = -1 - - # FLIPS - try: - fliphorizontal = self.get_channel_object( - "fliphorizontal" - ).get_value() - except Exception: - fliphorizontal = 0 - - try: - flipvertical = self.get_channel_object( - "flipvertical" - ).get_value() - except Exception: - flipvertical = 0 - - # GAIN - try: - gain = self.get_channel_object("gain").get_value() - except Exception: - gain = 0 - - # GAMMA - try: - gamma = self.get_channel_object("gamma").get_value() - except Exception: - gamma = 0 - - try: - if self.device.State() == PyTango.DevState.ON: - live = True - else: - live = False - except Exception: - live = False - try: - if self.getBpmState() == PyTango.DevState.ON: - bpm = True - else: - bpm = False - except Exception: - bpm = False - try: - # ?????????? # (startx, starty, endx, endy, d1, d2, d3, d4) = self.get_channel_object("roi").get_value() - ( - startx, - endx, - starty, - endy, - d1, - d2, - d3, - d4, - ) = self.get_channel_object("roi").get_value() - # print "Camera.py -- startx=", startx - # print self.get_channel_object("roi").get_value() - except Exception: - (startx, starty, endx, endy, d1, d2, d3, d4) = ( - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ) - - else: - self.oprint("bpmDevice is None") - - ( - threshold, - centerx, - centery, - fwhmx, - fwhmy, - maxpix, - intensity, - exposure, - width, - height, - gain, - ) = (-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2) - (startx, starty, endx, endy, d1, d2, d3, d4) = ( - -2, - -2, - -2, - -2, - -2, - -2, - -2, - -2, - ) - (live, bpm) = (False, False) - self.res = {} - self.res["time"] = exposure - self.res["threshold"] = threshold - self.res["width"] = width - self.res["height"] = height - self.res["fliph"] = fliphorizontal - self.res["flipv"] = flipvertical - self.res["startx"] = startx - self.res["starty"] = starty - self.res["endx"] = endx - self.res["endy"] = endy - self.res["centerx"] = centerx - self.res["centery"] = centery - self.res["fwhmx"] = fwhmx - self.res["fwhmy"] = fwhmy - self.res["maxpix"] = maxpix - self.res["intensity"] = intensity - self.res["gain"] = gain - self.res["gamma"] = gamma - self.res["live"] = live - self.res["bpmon"] = bpm - - return self.res - - def set_live(self, mode): - """tango""" - if mode: - self.device.Live() - else: - self.device.Stop() - - def setBpm(self, bpmOn): - """tango""" - if self.bpmDevice is not None: - if bpmOn: - self.bpmDevice.execute_command("on") - else: - self.bpmDevice.execute_command("off") - - def resetROI(self): - """tango""" - self.device.resetROI() - - def setROI(self, startx, endx, starty, endy): - """tango""" - # ?????# self.get_channel_object("roi").set_value([startx, starty, endx, endy]) - self.get_channel_object("roi").set_value( - [startx, endx, starty, endy] - ) - - def setExposure(self, exposure): - self.get_channel_object("exposure").set_value(exposure) - - def setThreshold(self, threshold): - if self.bpmDevice is not None: - self.bpmDevice.get_channel_object("threshold").set_value( - threshold - ) - - self.__class__ = TangoCamera - self._init() - elif self.get_property("taconame"): - # this is a Taco device - import TacoDevice - - class TacoCamera(TacoDevice.TacoDevice): - def init(self): - self.imgtype = JpegType() - self.forceUpdate = False - - if self.device.imported: - # device is already in tcp mode (done in _init) - self.device.DevCcdLive(1) # start acquisition - self.setPollCommand( - "DevCcdReadJpeg", 75, direct=True, compare=False - ) # 75: quality - self.set_is_ready(True) - - def oprint(self, msg): - print(("Camera.py--taco device--%s" % msg)) - - def value_changed(self, deviceName, value): - self.emit( - "imageReceived", - (value, self.get_width(), self.get_height(), self.forceUpdate), - ) - - def setContrast(self, contrast): - """taco""" - brightness = self.getBrightness() - - if brightness != -1: - str_val = "%d %d" % (int(brightness), int(contrast)) - self.device.DevCcdSetHwPar(str_val) - - def getContrast(self): - """taco""" - str_val = self.device.DevCcdGetHwPar() - - if isinstance(str_val, type("")): - [brightness, contrast] = str_val.split() - return int(contrast) - else: - return -1 - - def setBrightness(self, brightness): - """taco""" - contrast = self.getContrast() - - if contrast != -1: - str_val = "%d %d" % (int(brightness), int(contrast)) - self.device.DevCcdSetHwPar(str_val) - - def getBrightness(self): - """taco""" - str_val = self.device.DevCcdGetHwPar() - - if isinstance(str_val, type("")): - [brightness, contrast] = str_val.split() - return int(brightness) - else: - return -1 - - def get_width(self): - """taco""" - if self.is_ready(): - return self.device.DevCcdXSize() - - def get_height(self): - """taco""" - if self.is_ready(): - return self.device.DevCcdYSize() - - def setSize(self, width, height): - """taco""" - if self.is_ready(): - return self.device.DevCcdOutputSize(width, height) - - def takeSnapshot(self, *args): - """taco""" - if canTakeSnapshots: - rawimg = self.device.DevCcdRead(1) - try: - img = Image.frombuffer( - "RGB", (self.get_width(), self.get_height()), rawimg - ) - pixmap = img.tostring("raw", "BGR") - img = Image.frombuffer("RGB", img.size, pixmap) - # img.save(*args) - except Exception: - logging.getLogger("HWR").exception( - "%s: could not save snapshot", self.name() - ) - else: - if len(args): - try: - img.save(*args) - except Exception: - logging.getLogger("HWR").exception( - "%s: could not save snapshot", self.name() - ) - else: - return True - else: - return img - else: - logging.getLogger("HWR").error( - "%s: could not take snapshot: sorry PIL is not available :-(", - self.name(), - ) - return False - - take_snapshot = takeSnapshot - - def getBpmValues(self): - """Taco""" - if self.is_ready(): - values = self.device.DevReadSigValues() - gain = self.device.DevCcdGetGain() - - self.res = {} - if values[9] == 0: - self.res["live"] = False - else: - self.res["live"] = True - self.res["time"] = values[0] - self.res["threshold"] = values[1] - self.res["width"] = values[3] - self.res["height"] = values[4] - self.res["startx"] = values[5] - self.res["starty"] = values[6] - self.res["endx"] = values[7] - self.res["endy"] = values[8] - self.res["centerx"] = values[12] - self.res["centery"] = values[13] - self.res["fwhmx"] = values[14] - self.res["fwhmy"] = values[15] - self.res["maxpix"] = values[18] - self.res["gain"] = gain - self.res["intensity"] = values[11] - # bpm is always on - self.res["bpmon"] = True - return self.res - else: - self.res = {} - self.res["live"] = False - self.res["time"] = -2 - self.res["threshold"] = -2 - self.res["width"] = -2 - self.res["height"] = -2 - self.res["startx"] = -2 - self.res["starty"] = -2 - self.res["endx"] = -2 - self.res["endy"] = -2 - self.res["centerx"] = -2 - self.res["centery"] = -2 - self.res["fwhmx"] = -2 - self.res["fwhmy"] = -2 - self.res["maxpix"] = -2 - self.res["gain"] = -2 - self.res["intensity"] = -2 - # bpm is always on - self.res["bpmon"] = False - return self.res - - def set_live(self, mode): - """taco""" - if mode: - self.device.DevCcdLive(1) - else: - self.device.DevCcdLive(0) - - def setBpm(self, bpmOn): - """taco""" - - def getBpmState(self): - """taco""" - return "ON" - - def setROI(self, startx, endx, starty, endy): - """taco""" - if self.is_ready(): - - self.getBpmValues() - if self.res["live"]: - self.set_live(False) - time.sleep(0.1) - - self.device.DevCcdSetRoI(startx, starty, endx, endy) - - if self.res["live"]: - time.sleep(0.1) - self.set_live(True) - - def setExposure(self, exposure): - """taco""" - if self.is_ready(): - - self.getBpmValues() - if self.res["live"]: - self.set_live(False) - time.sleep(0.1) - - self.device.DevCcdSetExposure(exposure) - - if self.res["live"]: - time.sleep(0.1) - self.set_live(True) - - def setGain(self, gain): - """taco""" - if self.is_ready(): - - self.getBpmValues() - if self.res["live"]: - self.set_live(False) - time.sleep(0.1) - - self.device.DevCcdSetGain(gain) - - if self.res["live"]: - time.sleep(0.1) - self.set_live(True) - - def setThreshold(self, threshold): - """taco""" - if self.is_ready(): - - self.getBpmValues() - if self.res["live"]: - self.set_live(False) - time.sleep(0.1) - - self.device.DevCcdSetThreshold(threshold) - - if self.res["live"]: - time.sleep(0.1) - self.set_live(True) - - self.__class__ = TacoCamera - self._TacoDevice__dc = False - self._init() diff --git a/mxcubecore/configuration/esrf_id231/ccd/ge1350c.xml b/mxcubecore/configuration/esrf_id231/ccd/ge1350c.xml deleted file mode 100755 index ddba9ab096..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/ge1350c.xml +++ /dev/null @@ -1,14 +0,0 @@ - - Prosilica GE1350C - id23/ge1350c/1 - - - mmap:/tmp/prosilicaBuffer - 40 - 40 - id23/ge1350c-bpm/1 - - - diff --git a/mxcubecore/configuration/esrf_id231/ccd/ge1350c_hutch.xml b/mxcubecore/configuration/esrf_id231/ccd/ge1350c_hutch.xml deleted file mode 100755 index 498eb99956..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/ge1350c_hutch.xml +++ /dev/null @@ -1,11 +0,0 @@ - - Prosilica GE1350C - id23/ge1350c/1 - tango:id23/ge1350c-taco/1 - bayer:rg - 40 - - - diff --git a/mxcubecore/configuration/esrf_id231/ccd/meteor1.xml b/mxcubecore/configuration/esrf_id231/ccd/meteor1.xml deleted file mode 100755 index 758e5c786e..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/meteor1.xml +++ /dev/null @@ -1,5 +0,0 @@ - - Matrox Meteor, 1st camera - id23/meteor2/0 - 200 - diff --git a/mxcubecore/configuration/esrf_id231/ccd/meteor2.xml b/mxcubecore/configuration/esrf_id231/ccd/meteor2.xml deleted file mode 100755 index 9e91ec38d3..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/meteor2.xml +++ /dev/null @@ -1,5 +0,0 @@ - - Matrox Meteor, 2d camera - id23/meteor2/1 - 200 - diff --git a/mxcubecore/configuration/esrf_id231/ccd/meteor3.xml b/mxcubecore/configuration/esrf_id231/ccd/meteor3.xml deleted file mode 100755 index c709d1f9a5..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/meteor3.xml +++ /dev/null @@ -1,5 +0,0 @@ - - Matrox Meteor, 3rd camera - id23/meteor2/2 - 200 - diff --git a/mxcubecore/configuration/esrf_id231/ccd/meteor4.xml b/mxcubecore/configuration/esrf_id231/ccd/meteor4.xml deleted file mode 100755 index 1d62c87e07..0000000000 --- a/mxcubecore/configuration/esrf_id231/ccd/meteor4.xml +++ /dev/null @@ -1,5 +0,0 @@ - - Matrox Meteor, 4th camera - id23/meteor2/3 - 200 - diff --git a/mxcubecore/configuration/esrf_id29/ccd/prosilica_md2.xml b/mxcubecore/configuration/esrf_id29/ccd/prosilica_md2.xml deleted file mode 100644 index 3f823f1468..0000000000 --- a/mxcubecore/configuration/esrf_id29/ccd/prosilica_md2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - Prosilica MD2 - id29/md2/1 - mmap:/tmp/prosilicaBuffer - - 40 - 60 - - id29/md2-bpm/1 - cb - - From f40d077e8ce5095bc366178f70f179a6e58385ef Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Mon, 4 Nov 2024 17:13:23 +0100 Subject: [PATCH 170/172] Remove unused allocations --- mxcubecore/HardwareObjects/TangoLimaVideo.py | 8 +------- mxcubecore/HardwareObjects/TangoLimaVideoDevice.py | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index 10bc45fd90..b8903e67fc 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -31,9 +31,7 @@ def poll_image(lima_tango_device, video_mode, FORMATS): hfmt = ">IHHqiiHHHH" hsize = struct.calcsize(hfmt) - _, _, img_mode, frame_number, width, height, _, _, _, _ = struct.unpack( - hfmt, img_data[1][:hsize] - ) + _, _, _, _, width, height, _, _, _, _ = struct.unpack(hfmt, img_data[1][:hsize]) raw_data = img_data[1][hsize:] _from, _to = FORMATS.get(video_mode, (None, None)) @@ -53,10 +51,6 @@ def poll_image(lima_tango_device, video_mode, FORMATS): class TangoLimaVideo(BaseHardwareObjects.HardwareObject): def __init__(self, name): super().__init__(name) - self.__brightnessExists = False - self.__contrastExists = False - self.__gainExists = False - self.__gammaExists = False self.__polling = None self._video_mode = None self._last_image = (0, 0, 0) diff --git a/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py b/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py index dd6092cda8..5e59daf6f7 100644 --- a/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideoDevice.py @@ -133,9 +133,9 @@ def get_image(self): img_data = self.device.video_last_image if img_data[0] == "VIDEO_IMAGE": - raw_fmt = img_data[1][: self.header_size] + _ = img_data[1][: self.header_size] raw_buffer = np.fromstring(img_data[1][self.header_size :], np.uint16) - _, ver, img_mode, frame_number, width, height, _, _, _, _ = struct.unpack( + _, _, _, _, width, height, _, _, _, _ = struct.unpack( self.header_fmt, img_data[1][: self.header_size] ) return raw_buffer, width, height From a543ec1b2ab7bdc17f314283de29e11594d2fb35 Mon Sep 17 00:00:00 2001 From: walesch-yan Date: Tue, 5 Nov 2024 17:55:32 +0100 Subject: [PATCH 171/172] Prevent using deprecated set_is_ready function --- mxcubecore/HardwareObjects/TangoLimaVideo.py | 2 +- mxcubecore/HardwareObjects/mockup/MDCameraMockup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mxcubecore/HardwareObjects/TangoLimaVideo.py b/mxcubecore/HardwareObjects/TangoLimaVideo.py index b8903e67fc..79ef4826cc 100755 --- a/mxcubecore/HardwareObjects/TangoLimaVideo.py +++ b/mxcubecore/HardwareObjects/TangoLimaVideo.py @@ -100,7 +100,7 @@ def init(self): else: logging.getLogger("HWR").info("MXCuBE NOT controlling video") - self.set_is_ready(True) + self.update_state(BaseHardwareObjects.HardwareObjectState.READY) def get_last_image(self): return poll_image(self.device, self.video_mode, self._FORMATS) diff --git a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py index 66d219b9fc..7de0cd4ef8 100644 --- a/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py +++ b/mxcubecore/HardwareObjects/mockup/MDCameraMockup.py @@ -32,7 +32,7 @@ def _init(self): self.connected = False self.image_name = self.get_property("image_name") self.image = HWR.get_hardware_repository().find_in_repository(self.image_name) - self.set_is_ready(True) + self.update_state(BaseHardwareObjects.HardwareObjectState.READY) self._video_stream_process = None self._current_stream_size = (0, 0) From 849fa57805ca944844d6bcf69d17585ae491e839 Mon Sep 17 00:00:00 2001 From: Marcus Oskarsson Date: Tue, 12 Nov 2024 15:56:18 +0000 Subject: [PATCH 172/172] [skip ci] Bumped minor version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e0bc109464..a5fb2b8e38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mxcubecore" -version = "1.190.0" +version = "1.191.0" license = "LGPL-3.0-or-later" description = "Core libraries for the MXCuBE application" authors = ["The MXCuBE collaboration "]