Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beam refactoring - definer and size (former Aperture as NState) #919

Merged
merged 14 commits into from
Aug 20, 2024
55 changes: 39 additions & 16 deletions mxcubecore/HardwareObjects/XMLRPCServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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):
"""
Expand All @@ -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"):
"""
Expand Down Expand Up @@ -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):
"""
Expand All @@ -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):
"""
Expand All @@ -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):
"""
Expand Down Expand Up @@ -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
Expand Down
96 changes: 65 additions & 31 deletions mxcubecore/HardwareObjects/abstract/AbstractBeam.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.

"""
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
Expand All @@ -43,7 +44,7 @@ class BeamShape(Enum):

UNKNOWN = "unknown"
RECTANGULAR = "rectangular"
ELIPTICAL = "ellipse"
ELLIPTICAL = "ellipse"


class AbstractBeam(HardwareObject):
Expand All @@ -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],
Expand All @@ -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,
Expand All @@ -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):
Expand Down Expand Up @@ -113,22 +116,31 @@ 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:
NotImplementedError
"""
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:
Expand All @@ -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
Expand All @@ -153,18 +175,23 @@ 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):
"""Get the beam position
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):
Expand All @@ -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

Expand Down
Loading
Loading