diff --git a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py index 279b8c8c..91f1b828 100644 --- a/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py +++ b/mxcubecore/HardwareObjects/ESRF/ESRFBeam.py @@ -38,6 +38,11 @@ class ESRFBeam(AbstractBeam): unit = "mm" + def __init__(self, name): + super().__init__(name) + self._beam_check_obj = None + self._monitorbeam_obj = None + def init(self): """Initialize hardware""" super().init() @@ -48,10 +53,10 @@ def init(self): _definer_type.append("aperture") _slits = self.get_property("slits") + _bliss_obj = self.get_object_by_role("bliss") if _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)}) @@ -80,6 +85,12 @@ def init(self): self._definer.connect("valueChanged", self._re_emit_values) self._definer.connect("stateChanged", self._re_emit_values) + self._monitorbeam_obj = self.get_object_by_role("monitor_beam") + + beam_check = self.get_property("beam_check_name") + if beam_check and _bliss_obj: + self._beam_check_obj = getattr(_bliss_obj, beam_check) + def _re_emit_values(self, value): # redefine as re_emit_values takes no arguments self.re_emit_values() @@ -313,3 +324,27 @@ def get_beam_position_on_screen(self): def get_beam_size(self): beam_value = self.get_value() return (beam_value[0], beam_value[1]) + + def _is_beam(self): + """Check if there is beam + Returns: + (bool): True if beam present, False otherwise + """ + return self._beam_check_obj.is_beam() + + def wait_for_beam(self, timeout=None): + """Wait until beam present + Args: + timeout (float): optional - timeout [s], + If timeout == 0: return at once and do not wait + (default); + if timeout is None: wait forever. + """ + if self._monitorbeam_obj: + try: + timeout = timeout or self._beam_check_obj.timeout + if self._monitorbeam_obj.get_value().value: + return self._beam_check_obj.wait_for_beam(timeout) + except AttributeError: + return True + return True diff --git a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py index 5d7c0ed2..8eb7dfc8 100644 --- a/mxcubecore/HardwareObjects/abstract/AbstractBeam.py +++ b/mxcubecore/HardwareObjects/abstract/AbstractBeam.py @@ -256,3 +256,30 @@ def re_emit_values(self): self.emit("beamSizeChanged", (self._beam_width, self._beam_height)) self.emit("beamInfoChanged", (self._beam_info_dict)) self.emit("beamPosChanged", (self._beam_position_on_screen,)) + + @property + def is_beam(self): + """Check if there is beam. + Returns: + (bool): True if beam present, False otherwise + """ + return self._is_beam() + + def _is_beam(self): + """Specific implementation to check the presence of the beam. + Raises: + NotImplementedError. + """ + return True + + def wait_for_beam(self, timeout=None): + """Wait until beam present + Args: + timeout (float): optional - timeout [s], + If timeout == 0: return at once and do not wait + (default); + if timeout is None: wait forever. + Returns: + (bool): True if beam present, False otherwise + """ + return True diff --git a/mxcubecore/HardwareObjects/mockup/BeamMockup.py b/mxcubecore/HardwareObjects/mockup/BeamMockup.py index f3c8b8a0..5576d447 100644 --- a/mxcubecore/HardwareObjects/mockup/BeamMockup.py +++ b/mxcubecore/HardwareObjects/mockup/BeamMockup.py @@ -31,6 +31,7 @@ definer 0 0 + (10,10) """ @@ -48,6 +49,7 @@ class BeamMockup(AbstractBeam): def __init__(self, name): super().__init__(name) self._definer_type = None + self._check_beam = () def init(self): """Initialize hardware""" @@ -74,6 +76,10 @@ def init(self): self.get_property("beam_position", "[318, 238]") ) + _check_beam = self.get_property("check_beam") + if _check_beam: + self._check_beam = literal_eval(_check_beam) + self.re_emit_values() self.emit("beamPosChanged", (self._beam_position_on_screen,)) @@ -296,3 +302,13 @@ def set_value(self, size=None): if not isinstance(size, str): raise TypeError("Incorrect input value for definer") self.definer.set_value(self.definer.VALUES[size], timeout=2) + + def _is_beam(self): + """Check if there is beam + Returns: + (bool): True if beam present, False otherwise + """ + if not self._check_beam: + return True + beam = self.get_value() + return all([x1 <= x2 for (x1, x2) in zip(self._check_beam, (beam[0], beam[1]))]) diff --git a/mxcubecore/configuration/mockup/beam-mockup.xml b/mxcubecore/configuration/mockup/beam-mockup.xml index 233a0f97..85a2e3a3 100644 --- a/mxcubecore/configuration/mockup/beam-mockup.xml +++ b/mxcubecore/configuration/mockup/beam-mockup.xml @@ -5,4 +5,6 @@ 12.0 12.0 + + (0.030,0.030) diff --git a/test/pytest/test_beam.py b/test/pytest/test_beam.py index 2dbcc19b..3d98d4e5 100644 --- a/test/pytest/test_beam.py +++ b/test/pytest/test_beam.py @@ -256,3 +256,21 @@ def test_set_definer_size(self, test_object): assert beam_height == dsize.value[1] assert beam_shape == BeamShape.ELLIPTICAL assert beam_label == dsize.name + + def test_is_beam(self, test_object): + """Check if there is beam""" + check_beam = test_object._check_beam + if not check_beam: + assert test_object.is_beam == True + else: + test_object._definer_type = "aperture" + for val in test_object.aperture.get_diameter_size_list(): + app_size = int(test_object.aperture.VALUES[val].value[0]) / 1000 + test_object.aperture.set_value( + test_object.aperture.VALUES[val], timeout=2 + ) + _beam = test_object.is_beam + if check_beam[0] > app_size: + assert _beam == False + else: + assert _beam == True