mxcubecore 1.440.0__py3-none-any.whl → 1.449.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. mxcubecore/Command/BlueskyHttpServer.py +84 -0
  2. mxcubecore/CommandContainer.py +14 -0
  3. mxcubecore/HardwareObjects/Gphl/GphlQueueEntry.py +2 -2
  4. mxcubecore/HardwareObjects/ICATLIMS.py +16 -2
  5. mxcubecore/HardwareObjects/LNLS/BlueskyHttpServer.py +23 -0
  6. mxcubecore/HardwareObjects/LNLS/EPICS/EPICSMotor.py +40 -0
  7. mxcubecore/HardwareObjects/LNLS/LNLSDiffractometer.py +44 -297
  8. mxcubecore/HardwareObjects/MicrodiffInOut.py +12 -5
  9. mxcubecore/HardwareObjects/QtGraphicsManager.py +28 -21
  10. mxcubecore/HardwareObjects/abstract/AbstractMultiCollect.py +57 -83
  11. mxcubecore/HardwareObjects/abstract/AbstractNState.py +3 -1
  12. mxcubecore/HardwareObjects/abstract/AbstractVideoDevice.py +9 -4
  13. mxcubecore/HardwareObjects/abstract/ISPyBAbstractLims.py +8 -4
  14. mxcubecore/HardwareObjects/autoprocessing.py +2 -2
  15. mxcubecore/HardwareObjects/mockup/CollectMockup.py +11 -8
  16. mxcubecore/HardwareObjects/mockup/ISPyBRestClientMockup.py +10 -6
  17. mxcubecore/HardwareRepository.py +1 -1
  18. mxcubecore/protocols_config.py +7 -0
  19. mxcubecore/queue_entry/base_queue_entry.py +6 -5
  20. mxcubecore/utils/qt_import.py +0 -10
  21. {mxcubecore-1.440.0.dist-info → mxcubecore-1.449.0.dist-info}/METADATA +1 -1
  22. {mxcubecore-1.440.0.dist-info → mxcubecore-1.449.0.dist-info}/RECORD +25 -23
  23. {mxcubecore-1.440.0.dist-info → mxcubecore-1.449.0.dist-info}/WHEEL +0 -0
  24. {mxcubecore-1.440.0.dist-info → mxcubecore-1.449.0.dist-info}/licenses/COPYING +0 -0
  25. {mxcubecore-1.440.0.dist-info → mxcubecore-1.449.0.dist-info}/licenses/COPYING.LESSER +0 -0
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Project name: MXCuBE
4
+ # https://github.com/mxcube
5
+ #
6
+ # This file is part of MXCuBE software.
7
+ #
8
+ # MXCuBE is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Lesser General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # MXCuBE is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public License
19
+ # along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ import json
22
+ import os
23
+ import time
24
+
25
+ import gevent
26
+ import requests
27
+
28
+ from mxcubecore.CommandContainer import CommandObject
29
+
30
+ __copyright__ = """ Copyright © 2010 - 2020 by MXCuBE Collaboration """
31
+ __license__ = "LGPLv3+"
32
+
33
+
34
+ class BlueskyHttpServerCommand(CommandObject):
35
+ """Interface for communicating with the Bluesky Http Server API."""
36
+
37
+ _default_timeout = 5
38
+ _status_path = "api/status"
39
+ _execute_path = "api/queue/item/execute"
40
+
41
+ def __init__(self, name, url, timeout=5, **kwargs):
42
+ CommandObject.__init__(self, name, **kwargs)
43
+ self.username = ""
44
+ self._default_timeout = timeout
45
+ self._url = f"{url}/" if url[-1] != "/" else url
46
+ self._headers = {"Authorization": f"ApiKey {os.environ['AUTH_KEY']}"}
47
+
48
+ def format_response(self, response):
49
+ if response:
50
+ response.raise_for_status()
51
+ return json.loads(response.text)
52
+ return response
53
+
54
+ def status(self):
55
+ response = requests.get(
56
+ self._url + self._status_path,
57
+ headers=self._headers,
58
+ timeout=self._default_timeout,
59
+ )
60
+ return self.format_response(response)
61
+
62
+ def monitor_manager_state(self, stop_state, timeout=86400):
63
+ with gevent.Timeout(timeout, exception=TimeoutError):
64
+ while self.status()["manager_state"] != stop_state:
65
+ time.sleep(0.1)
66
+
67
+ def execute_plan(self, plan_name, kwargs=None):
68
+ if not kwargs:
69
+ kwargs = {}
70
+ return requests.post(
71
+ self._url + self._execute_path,
72
+ headers=self._headers,
73
+ json={
74
+ "user": self.username,
75
+ "item": {"name": plan_name, "item_type": "plan", "kwargs": kwargs},
76
+ },
77
+ timeout=self._default_timeout,
78
+ )
79
+
80
+ def is_connected(self):
81
+ http_server_status = self.status()
82
+ re_environment_open = http_server_status["worker_environment_exists"]
83
+ re_running = http_server_status["re_state"] is not None
84
+ return re_environment_open and re_running
@@ -760,6 +760,20 @@ class CommandContainer:
760
760
  cmd_name,
761
761
  )
762
762
 
763
+ elif cmd_type.lower() == "bluesky_http_server":
764
+ try:
765
+ from mxcubecore.Command.BlueskyHttpServer import (
766
+ BlueskyHttpServerCommand,
767
+ )
768
+
769
+ new_command = BlueskyHttpServerCommand(cmd_name, cmd, **attributes_dict)
770
+ except Exception as exc:
771
+ logging.getLogger().exception(
772
+ "%s: cannot establish a connection with the Bluesky Http Server %s",
773
+ self.id,
774
+ cmd_name,
775
+ )
776
+
763
777
  elif cmd_type.lower() == "sardana":
764
778
  doorname = None
765
779
  taurusname = None
@@ -49,7 +49,7 @@ class GphlWorkflowQueueEntry(BaseQueueEntry):
49
49
  )
50
50
  HWR.beamline.gphl_workflow.post_execute()
51
51
  HWR.beamline.gphl_workflow.pre_execute(self)
52
- self.log.debug("Done GphlWorkflowQueueEntry.pre_execute")
52
+ logging.getLogger("HWR").debug("Done GphlWorkflowQueueEntry.pre_execute")
53
53
 
54
54
  def post_execute(self):
55
55
  BaseQueueEntry.post_execute(self)
@@ -60,5 +60,5 @@ class GphlWorkflowQueueEntry(BaseQueueEntry):
60
60
  def stop(self):
61
61
  HWR.beamline.gphl_workflow.workflow_aborted("Dummy", "Dummy")
62
62
  BaseQueueEntry.stop(self)
63
- self.log.info("MXCuBE aborting current GΦL workflow")
63
+ logging.getLogger("user_level_log").info("MXCuBE aborting current GΦL workflow")
64
64
  self.get_view().setText(1, "Stopped")
@@ -898,12 +898,22 @@ class ICATLIMS(AbstractLims):
898
898
  if session is not None:
899
899
  investigation_name = session.proposal_name
900
900
 
901
- return {
901
+ actual_instrument = None
902
+ try:
903
+ if (
904
+ self.active_session is None
905
+ or not self.active_session.is_scheduled_beamline
906
+ ):
907
+ actual_instrument = HWR.beamline.session.beamline_name
908
+ except RuntimeError as e:
909
+ logger.warning("Failed to set __actualInstrument. %s", e)
910
+
911
+ result = {
902
912
  "sampleId": sample_id,
903
913
  "Sample_name": sample_name,
904
914
  "startDate": start_time,
905
915
  "endDate": end_time,
906
- "investigation_id": investigation_id,
916
+ "investigationId": investigation_id,
907
917
  "beamline_name": beamline_name,
908
918
  "proposal": investigation_name,
909
919
  "scheduled_beamline_name": scheduled_beamline_name,
@@ -920,6 +930,10 @@ class ICATLIMS(AbstractLims):
920
930
  "InstrumentSource_current": machine_info.get("current"),
921
931
  "InstrumentSource_mode": machine_info.get("fill_mode"),
922
932
  }
933
+ if actual_instrument is not None:
934
+ result["__actualInstrument"] = actual_instrument
935
+
936
+ return result
923
937
 
924
938
  def store_energy_scan(self, energyscan_dict: dict):
925
939
  try:
@@ -0,0 +1,23 @@
1
+ from mxcubecore.BaseHardwareObjects import HardwareObject
2
+
3
+
4
+ class BlueskyHttpServer(HardwareObject):
5
+ def __init__(self, name):
6
+ HardwareObject.__init__(self, name)
7
+
8
+ def init(self):
9
+ super().init()
10
+ self.api = self.get_command_object("bluesky_http_server")
11
+ self.api.username = "mnc-data"
12
+
13
+ def execute_plan(self, plan_name, kwargs=None):
14
+ response = self.api.execute_plan(plan_name=plan_name, kwargs=kwargs)
15
+ response_content = response.json()
16
+ if response_content["success"]:
17
+ try:
18
+ self.api.monitor_manager_state("running")
19
+ self.api.monitor_manager_state("idle")
20
+ except TimeoutError:
21
+ self.log.exception("The Bluesky plan has timed out!")
22
+ else:
23
+ self.log.exception(response_content["msg"])
@@ -97,3 +97,43 @@ class EPICSMotor(EPICSActuator, AbstractMotor):
97
97
  def done_movement(self):
98
98
  dmov = self.get_channel_value(self.MOTOR_DMOV)
99
99
  return bool(dmov)
100
+
101
+
102
+ class EPICSMotorDetachable(EPICSMotor):
103
+ """
104
+ Class that implements an interface of motor record IOC and accepts
105
+ a presence PV, that indicated if the motor is or is not present on the
106
+ facility. If it is present, it actuates as an EpicsMotor, if it is not,
107
+ then the widget receives the state OFF and remains disabled.
108
+
109
+ YAML Example
110
+ ------------
111
+
112
+ %YAML 1.2
113
+ ---
114
+ class: LNLS.EPICS.EPICSMotor.EPICSMotorDetachable
115
+ epics:
116
+ "MOTOR_PV":
117
+ channels:
118
+ '':
119
+ 'PRESENCE_PREFIX':
120
+ channels:
121
+ 'presence':
122
+ suffix: "PRESENCE_SUFFIX"
123
+ configuration:
124
+ is_absent_value: 0
125
+
126
+ """
127
+
128
+ MOTOR_PRESENCE_RBV = "presence"
129
+
130
+ def init(self):
131
+ super().init()
132
+ self.get_value()
133
+
134
+ def get_value(self):
135
+ value = self.get_property("is_absent_value")
136
+ current_value = int(self.get_channel_value(self.MOTOR_PRESENCE_RBV))
137
+ if current_value == value:
138
+ self.update_state(self.STATES.OFF)
139
+ return super().get_value()
@@ -1,24 +1,3 @@
1
- #
2
- # Project name: MXCuBE
3
- # https://github.com/mxcube
4
- #
5
- # This file is part of MXCuBE software.
6
- #
7
- # MXCuBE is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Lesser General Public License as published by
9
- # the Free Software Foundation, either version 3 of the License, or
10
- # (at your option) any later version.
11
- #
12
- # MXCuBE is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Lesser General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Lesser General Public License
18
- # along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
19
-
20
- import logging
21
- import random
22
1
  import time
23
2
 
24
3
  from gevent.event import AsyncResult
@@ -28,71 +7,33 @@ from mxcubecore.HardwareObjects.GenericDiffractometer import GenericDiffractomet
28
7
 
29
8
 
30
9
  class LNLSDiffractometer(GenericDiffractometer):
31
- """
32
- Descript. :
33
- """
34
-
35
10
  def __init__(self, name):
36
- """
37
- Descript. :
38
- """
39
11
  GenericDiffractometer.__init__(self, name)
40
12
 
41
- # child object slots
42
- self.backlight = None
43
- self.backlightswitch = None
44
- self.beamstop_distance = None
45
- self.focus = None
46
- self.frontlight = None
47
- self.frontlightswitch = None
48
- self.phi = None
49
- self.phiy = None
50
- self.phiz = None
51
- self.sampx = None
52
- self.sampy = None
53
-
54
13
  def init(self):
55
- """
56
- Descript. :
57
- """
58
- # self.image_width = 100
59
- # self.image_height = 100
60
-
61
14
  GenericDiffractometer.init(self)
62
- # Bzoom: 1.86 um/pixel (or 0.00186 mm/pixel) at minimum zoom
63
- self.x_calib = self.get_property("x_calib", "")
64
- self.y_calib = self.get_property("y_calib", "")
65
- self.last_centred_position = self.get_property("last_centred_position", "")
66
-
67
- self.pixels_per_mm_x = 1.0 / self.x_calib
68
- self.pixels_per_mm_y = 1.0 / self.y_calib
69
- self.beam_position = self.get_property("beam_position", "")
70
-
71
- self.current_phase = GenericDiffractometer.PHASE_CENTRING
72
-
73
- self.cancel_centring_methods = {}
15
+ self._bluesky_api = HWR.beamline.get_object_by_role("bluesky")
16
+ self.pixels_per_mm_x = 10**-4
17
+ self.pixels_per_mm_y = 10**-4
18
+ self.beam_position = [318, 238]
19
+ self.last_centred_position = self.beam_position
74
20
  self.current_motor_positions = {
75
- "phiy": self.get_property("current_motor_positions_phiy", ""),
76
- "sampx": self.get_property("current_motor_positions_sampx", ""),
77
- "sampy": self.get_property("current_motor_positions_sampy", ""),
78
- "zoom": self.get_property("current_motor_positions_zoom", ""),
79
- "focus": self.get_property("current_motor_positions_focus", ""),
80
- "phiz": self.get_property("current_motor_positions_phiz", ""),
81
- "phi": self.get_property("current_motor_positions_phi", ""),
82
- "kappa": self.get_property("current_motor_positions_kappa", ""),
83
- "kappa_phi": self.get_property("current_motor_positions_kappa_phi", ""),
21
+ "phiy": 0,
22
+ "sampx": 0,
23
+ "sampy": 0,
24
+ "zoom": 0,
25
+ "focus": 0,
26
+ "phiz": 0,
27
+ "phi": 0,
28
+ "kappa": 0,
29
+ "kappa_phi": 0,
84
30
  }
85
31
 
86
- self.current_state_dict = {}
87
- self.centring_status = {"valid": False}
88
- self.centring_time = self.get_property("centring_time", "")
89
-
32
+ self.centring_time = 0
90
33
  self.mount_mode = self.get_property("sample_mount_mode")
91
34
  if self.mount_mode is None:
92
35
  self.mount_mode = "manual"
93
36
 
94
- self.equipment_ready()
95
-
96
37
  self.connect(self.motor_hwobj_dict["phi"], "valueChanged", self.phi_motor_moved)
97
38
  self.connect(
98
39
  self.motor_hwobj_dict["phiy"], "valueChanged", self.phiy_motor_moved
@@ -115,108 +56,10 @@ class LNLSDiffractometer(GenericDiffractometer):
115
56
  self.motor_hwobj_dict["sampy"], "valueChanged", self.sampy_motor_moved
116
57
  )
117
58
 
118
- def manual_centring(self):
119
- """
120
- Descript. :
121
- """
122
- self.print_log(level="debug", msg="Iniciando centragem manual...")
123
- for click in range(3):
124
- self.print_log(
125
- level="debug", msg=f"Aguardando clique do usuário ({click + 1}/3)..."
126
- )
127
- self.user_clicked_event = AsyncResult()
128
- x, y = self.user_clicked_event.get()
129
- self.print_log(
130
- level="debug", msg=f"Usuário clicou nas coordenadas: x={x}, y={y}"
131
- )
132
-
133
- # go to beam
134
- self.print_log(
135
- level="debug", msg="Movendo para o feixe com as coordenadas clicadas."
136
- )
137
- res = self.move_to_beam(x, y) # wait before continue
138
- self.print_log(
139
- level="debug", msg=f"Resultado do movimento para o feixe: {res}"
140
- )
141
-
142
- if click < 2:
143
- self.print_log(
144
- level="debug",
145
- msg=f"Executando rotação relativa do motor phi em 90 graus (click={click})...",
146
- )
147
- self.motor_hwobj_dict["phi"].set_value_relative(90)
148
-
149
- self.print_log(
150
- level="debug", msg=f"Salvando última posição centrada: x={x}, y={y}"
151
- )
152
- self.last_centred_position[0] = x
153
- self.last_centred_position[1] = y
154
-
155
- self.print_log(level="debug", msg="Centragem manual finalizada.")
156
- return {}
157
-
158
- def automatic_centring(self):
159
- """Automatic centring procedure"""
160
- self.print_log(level="debug", msg="Iniciando centragem automática...")
161
-
162
- centred_pos_dir = self._get_random_centring_position()
163
- self.print_log(
164
- level="debug",
165
- msg=f"Posição centrada gerada automaticamente: {centred_pos_dir}",
166
- )
167
-
168
- self.emit("newAutomaticCentringPoint", centred_pos_dir)
169
- self.print_log(level="debug", msg="Sinal 'newAutomaticCentringPoint' emitido.")
170
-
171
- return centred_pos_dir
172
-
173
- def _get_random_centring_position(self):
174
- """Get random centring result for current positions"""
175
-
176
- # Names of motors to vary during centring
177
- vary_actuator_names = ("sampx", "sampy", "phiy")
178
-
179
- # Range of random variation
180
- var_range = 0.08
181
-
182
- # absolute value limit for varied motors
183
- var_limit = 2.0
184
-
185
- result = self.current_motor_positions.copy()
186
- for tag in vary_actuator_names:
187
- val = result.get(tag)
188
- if val is not None:
189
- random_num = random.random()
190
- var = (random_num - 0.5) * var_range
191
- val += var
192
- if abs(val) > var_limit:
193
- val *= 1 - var_range / var_limit
194
- result[tag] = val
195
- return result
196
-
197
59
  def is_ready(self) -> bool:
198
- """
199
- Descript. :
200
- """
201
60
  return True
202
61
 
203
- def get_centred_point_from_coord(self, x, y, return_by_names=None):
204
- """
205
- Descript. :
206
- """
207
- centred_pos_dir = self._get_random_centring_position()
208
- return centred_pos_dir
209
-
210
- def motor_positions_to_screen(self, centred_positions_dict):
211
- """
212
- Descript. :
213
- """
214
- return self.last_centred_position[0], self.last_centred_position[1]
215
-
216
62
  def phi_motor_moved(self, pos):
217
- """
218
- Descript. :
219
- """
220
63
  self.current_motor_positions["phi"] = pos
221
64
  self.emit("phiMotorMoved", pos)
222
65
 
@@ -233,9 +76,6 @@ class LNLSDiffractometer(GenericDiffractometer):
233
76
  self.current_motor_positions["sampy"] = pos
234
77
 
235
78
  def kappa_motor_moved(self, pos):
236
- """
237
- Descript. :
238
- """
239
79
  self.current_motor_positions["kappa"] = pos
240
80
  if time.time() - self.centring_time > 1.0:
241
81
  self.invalidate_centring()
@@ -243,136 +83,43 @@ class LNLSDiffractometer(GenericDiffractometer):
243
83
  self.emit("kappaMotorMoved", pos)
244
84
 
245
85
  def kappa_phi_motor_moved(self, pos):
246
- """
247
- Descript. :
248
- """
249
86
  self.current_motor_positions["kappa_phi"] = pos
250
87
  if time.time() - self.centring_time > 1.0:
251
88
  self.invalidate_centring()
252
89
  self.emit_diffractometer_moved()
253
90
  self.emit("kappaPhiMotorMoved", pos)
254
91
 
255
- def calculate_move_to_beam_pos(self, x, y):
256
- """
257
- Descript. : calculate motor positions to put sample on the beam.
258
- Returns: dict of motor positions
259
- """
260
-
261
- # Atualiza posição atual do feixe
262
- self.beam_position[0], self.beam_position[1] = (
263
- HWR.beamline.beam.get_beam_position_on_screen()
264
- )
265
- self.print_log(
266
- level="debug", msg=f"Posição atual do feixe na tela: {self.beam_position}"
267
- )
268
-
269
- # Armazena clique do usuário
270
- self.last_centred_position[0] = x
271
- self.last_centred_position[1] = y
272
- self.print_log(
273
- level="debug", msg=f"Última posição clicada pelo usuário: x={x}, y={y}"
274
- )
275
-
276
- # Obtém posições atuais dos motores
277
- omega_pos = self.motor_hwobj_dict["phi"].get_value()
278
- goniox_pos = self.motor_hwobj_dict["phiz"].get_value()
279
- sampx_pos = self.motor_hwobj_dict["sampx"].get_value()
280
- sampy_pos = self.motor_hwobj_dict["sampy"].get_value()
281
- self.print_log(
282
- level="debug",
283
- msg=f"Posições atuais dos motores: omega={omega_pos}, phiz={goniox_pos}, sampx={sampx_pos}, sampy={sampy_pos}",
284
- )
285
-
286
- # Cálculo da movimentação de goniox
287
- import math
288
-
289
- drx_goniox = abs(-x - y + 1152) / math.sqrt(2)
290
- dir_goniox = 1 if y <= (-x + 1152) else -1
291
- move_goniox = dir_goniox * drx_goniox / self.pixels_per_mm_x + goniox_pos
292
- self.print_log(
293
- level="debug",
294
- msg=f"Movimento calculado para phiz (goniox): {move_goniox:.4f}",
295
- )
296
-
297
- # Cálculo da movimentação em Y
298
- dry_samp = abs(x - y - 128) / math.sqrt(2)
299
- dir_samp = 1 if y >= x - 128 else -1
300
- move_samp = dir_samp * dry_samp
301
- self.print_log(
302
- level="debug",
303
- msg=f"Movimento intermediário para centragem vertical (samp): {move_samp:.4f}",
304
- )
305
-
306
- move_sampy = move_samp / self.pixels_per_mm_y
307
- self.print_log(
308
- level="debug", msg=f"Conversão para mm em Y: move_sampy = {move_sampy:.4f}"
309
- )
310
-
311
- move_sampy += sampy_pos
312
- self.print_log(
313
- level="debug", msg=f"Posição absoluta destino para sampy: {move_sampy:.4f}"
314
- )
315
-
316
- # Criação do dicionário de destino
317
- centred_pos_dir = {"phiz": move_goniox, "sampy": move_sampy}
318
- self.print_log(
319
- level="debug",
320
- msg=f"Posições alvo calculadas para centragem: {centred_pos_dir}",
321
- )
92
+ def manual_centring(self):
93
+ self.log.info("Initializing manual sample alignment...")
94
+ for step in range(3):
95
+ self.log.info(f"Step {step + 1} of 3...")
96
+ self.user_clicked_event = AsyncResult()
97
+ self.waiting_for_click = True
98
+ x, y = self.user_clicked_event.get()
99
+ self.log.info(f"{x}, {y}")
100
+ self._bluesky_api.execute_plan(
101
+ plan_name="manual_alignment",
102
+ kwargs={"x_px": x, "y_px": y, "step": step},
103
+ )
104
+ self.log.info("Manual sample alignment has finished...")
105
+ return {}
322
106
 
323
- return centred_pos_dir
107
+ def automatic_centring(self):
108
+ self.log.info("Initializing automatic sample alignment...")
109
+ self._bluesky_api.execute_plan(plan_name="automatic_alignment")
110
+ self.log.info("Automatic sample alignment has finished...")
324
111
 
325
112
  def move_to_beam(self, x, y, omega=None):
326
- """
327
- Descript. : function to create a centring point based on all motors
328
- positions.
329
- """
330
- logging.getLogger("HWR").info("Moving to beam...")
331
- self.print_log(
332
- level="debug",
333
- msg=f"Initializing beam centering with beam at x={x}, y={y}...",
334
- )
335
-
336
- centred_pos_dir = self.calculate_move_to_beam_pos(x, y)
337
-
338
- self.print_log(level="debug", msg="Moving to beam...")
339
- self.move_to_motors_positions(centred_pos_dir, wait=True)
340
-
341
- logging.getLogger("HWR").info("Move to beam has finished...")
342
- return centred_pos_dir
113
+ self.log.info("Moving to beam...")
343
114
 
344
- def start_move_to_beam(self, coord_x=None, coord_y=None, omega=None):
345
- """
346
- Descript. :
347
- """
348
- self.last_centred_position[0] = coord_x
349
- self.last_centred_position[1] = coord_y
350
- self.centring_time = time.time()
351
- curr_time = time.strftime("%Y-%m-%d %H:%M:%S")
352
- self.centring_status = {
353
- "valid": True,
354
- "startTime": curr_time,
355
- "endTime": curr_time,
356
- }
357
- motors = self.get_positions()
358
- self.last_centred_position[0] = coord_x
359
- self.last_centred_position[1] = coord_y
360
- self.centring_status["motors"] = motors
361
- self.centring_status["valid"] = True
362
- self.centring_status["angleLimit"] = False
363
- self.emit_progress_message("")
364
- self.accept_centring()
365
- self.current_centring_method = None
366
- self.current_centring_procedure = None
367
-
368
- def re_emit_values(self):
369
- self.emit("zoomMotorPredefinedPositionChanged", None, None)
370
- omega_ref = [0, 238]
371
- self.emit("omegaReferenceChanged", omega_ref)
372
-
373
- def move_omega_relative(self, relative_angle):
374
- self.motor_hwobj_dict["phi"].set_value_relative(relative_angle, 5)
115
+ self._bluesky_api.execute_plan(
116
+ plan_name="move_to_beam",
117
+ kwargs={
118
+ "x_px": x - self.beam_position[0],
119
+ "y_px": y - self.beam_position[1],
120
+ },
121
+ )
122
+ self.log.info("Move to beam has finished...")
375
123
 
376
- def set_phase(self, phase, timeout=None):
377
- self.current_phase = str(phase)
378
- self.emit("minidiffPhaseChanged", (self.current_phase,))
124
+ def motor_positions_to_screen(self, motor_positions):
125
+ return self.beam_position
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  import time
3
+ import warnings
3
4
 
4
5
  from mxcubecore.BaseHardwareObjects import HardwareObject
5
6
 
@@ -53,11 +54,17 @@ class MicrodiffInOut(HardwareObject):
53
54
  import ast
54
55
 
55
56
  self.states = ast.literal_eval(states)
56
- try:
57
- tt = float(self.get_property("timeout"))
58
- self.timeout = tt
59
- except Exception:
60
- self.log.exception("")
57
+ tt = self.get_property("timeout")
58
+ if tt is None:
59
+ warnings.warn(
60
+ "%s: %s is not configured" % (self.__class__.__name__, "timeout")
61
+ )
62
+ else:
63
+ try:
64
+ tt = float(tt)
65
+ except TypeError:
66
+ self.log.exception("")
67
+ self.timeout = tt
61
68
 
62
69
  if self.get_property("use_hwstate"):
63
70
  self.hwstate_attr = self.add_channel(