Source code for mxcubecore.HardwareObjects.EMBL.EMBLBeam

#
#  Project name: 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 <http://www.gnu.org/licenses/>.

"""
EMBLBeamInfo
Hardware object is used to define final beam size and shape.
It can include aperture, slits and/or beam focusing hwobj
"""

import ast
import logging
import sys

from mxcubecore.HardwareObjects.abstract.AbstractBeam import AbstractBeam

__credits__ = ["EMBL Hamburg"]
__license__ = "LGPLv3+"
__category__ = "General"


[docs]class EMBLBeam(AbstractBeam): """Hardware object is used to define final beam size and shape""" def __init__(self, *args): """Defines all variables""" AbstractBeam.__init__(self, *args) self.focus_mode = None self.aperture_pos_name = None self.default_beam_divergence = None self.chan_beam_position_hor = None self.chan_beam_position_ver = None self.chan_beam_size_microns = None self.chan_beam_shape_ellipse = None
[docs] def init(self): """Initialized all variables""" self._beam_info_dict["size_x"] = 9999 self._beam_info_dict["size_y"] = 9999 self._aperture = self.get_object_by_role("aperture") if self._aperture is not None: self.connect( self._aperture, "diameterIndexChanged", self.aperture_diameter_changed, ) else: self.log.debug("BeamInfo: Aperture hwobj not defined") self._slits = self.get_object_by_role("slits") if self._slits is not None: self.connect(self._slits, "valueChanged", self.slits_gap_changed) else: self.log.debug("BeamInfo: Slits hwobj not defined") self._definer = self.get_object_by_role("beam_focusing") if self._definer is not None: ( focus_mode_name, self._beam_size_dict["definer"], ) = self._definer.get_active_focus_mode() self.connect( self._definer, "focusingModeChanged", self.focusing_mode_changed, ) else: self.log.debug("BeamInfo: Beam focusing hwobj not defined") self.chan_beam_position_hor = self.get_channel_object("BeamPositionHorizontal") if self.chan_beam_position_hor: self.chan_beam_position_hor.connect_signal( "update", self.beam_pos_hor_changed ) self.beam_pos_hor_changed(self.chan_beam_position_hor.get_value()) self.chan_beam_position_ver = self.get_channel_object("BeamPositionVertical") if self.chan_beam_position_ver: self.chan_beam_position_ver.connect_signal( "update", self.beam_pos_ver_changed ) self.chan_beam_size_microns = self.get_channel_object("BeamSizeMicrons") self.chan_beam_shape_ellipse = self.get_channel_object("BeamShapeEllipse") self.default_beam_divergence = ast.literal_eval( self.get_property("defaultBeamDivergence") )
[docs] def get_beam_divergence_hor(self): """Returns beam horizontal beam divergence :return: float """ beam_divergence_hor = None if self._definer is not None: beam_divergence_hor = self._definer.get_divergence_hor() else: beam_divergence_hor = self.default_beam_divergence[0] return beam_divergence_hor
[docs] def get_beam_divergence_ver(self): """Returns vertical beam divergence :return: float """ beam_divergence_ver = None if self._definer is not None: beam_divergence_ver = self._definer.get_divergence_ver() else: beam_divergence_ver = self.default_beam_divergence[1] return beam_divergence_ver
[docs] def beam_pos_hor_changed(self, value): """Updates horizontal beam position :param value: horizontal beam position :type value: float :return: None """ self._beam_position_on_screen[0] = value self.emit("beamPosChanged", (self._beam_position_on_screen,))
[docs] def beam_pos_ver_changed(self, value): """Updates vertical beam position :param value: vertical beam position :type value: float :return: None """ self._beam_position_on_screen[1] = value self.emit("beamPosChanged", (self._beam_position_on_screen,))
[docs] def get_beam_position(self): """Returns beam mark position :return: [float, float] """ if self.chan_beam_position_hor and self.chan_beam_position_ver: self._beam_position_on_screen = [ self.chan_beam_position_hor.get_value(), self.chan_beam_position_ver.get_value(), ] return self._beam_position_on_screen
[docs] def set_beam_position(self, beam_x, beam_y): """Sets the beam mark position :param beam_x: horizontal beam mark position :type beam_x: int :param beam_y: vertical beam mark position :type beam_y: int :return: None """ self._beam_position_on_screen = [beam_x, beam_y] if self.chan_beam_position_hor and self.chan_beam_position_ver: self.chan_beam_position_hor.set_value(int(beam_x)) self.chan_beam_position_ver.set_value(int(beam_y)) else: self.emit("beamPosChanged", (self._beam_position_on_screen,))
[docs] def aperture_diameter_changed(self, name, size): """Method called when aperture changed. Evaluates beam mark position :param name: position name :type name: str :param size: diameter size :type size: float :return: None """ self._beam_size_dict["aperture"] = [size, size] self.aperture_pos_name = name self.update_beam_info() self.re_emit_values()
[docs] def get_aperture_pos_name(self): """Returns current aperture position :return: position name as str """ return self._aperture.get_current_pos_name()
[docs] def slits_gap_changed(self, size): """Method when slits gap changes. Evaluates beam mark position :param size: gap size :type size: list of two floats :return: None """ self._beam_size_dict["slits"] = size self.update_beam_info() self.re_emit_values()
[docs] def focusing_mode_changed(self, name, size): """Updates beam mark size when beam focusing changes :param name: focusing name :type name: str :param size: beam size :type size: float :return: None """ self.focus_mode = name self._beam_size_dict["definer"] = size self.update_beam_info() self.re_emit_values()
[docs] def get_beam_size(self): """Returns beam size in microns :return: Tuple(int, int) """ self.update_beam_info() return (self._beam_info_dict["size_x"], self._beam_info_dict["size_y"])
[docs] def get_beam_shape(self): """Returns beam shape :return: beam shape as str """ self.update_beam_info() return self._beam_info_dict["shape"]
[docs] def get_slits_gap(self): """Returns slits gap :return: list of two floats """ self.update_beam_info() slits_gap = [None, None] if self._beam_size_dict["slits"] != [sys.float_info.max, sys.float_info.max]: slits_gap = self._beam_size_dict["slits"] return slits_gap
[docs] def set_slits_gap(self, width_microns, height_microns): """Sets slits gaps :param width_microns: width in microns :type width_microns: float :param height_microns: height in microns :type height_microns: float :return: None """ if self.focus_mode == "Double": logging.getLogger("GUI").warning( "Slits are disabled in the Double focus mode" ) else: self._slits.set_horizontal_gap(width_microns / 1000.0) self._slits.set_vertical_gap(height_microns / 1000.0)
[docs] def update_beam_info(self): """Called if aperture, slits or focusing has been changed :return: dictionary,{size_x:0.1, size_y:0.1, shape:"rectangular"} """ size_x = min( self._beam_size_dict["aperture"][0], self._beam_size_dict["slits"][0], self._beam_size_dict["definer"][0], ) size_y = min( self._beam_size_dict["aperture"][1], self._beam_size_dict["slits"][1], self._beam_size_dict["definer"][1], ) if size_x == 9999 or size_y == 9999: return if ( abs(size_x - self._beam_info_dict.get("size_x", 0)) > 1e-3 or abs(size_y - self._beam_info_dict.get("size_y", 0)) > 1e-3 ): self._beam_info_dict["size_x"] = size_x self._beam_info_dict["size_y"] = size_y if self._beam_size_dict["aperture"] <= [size_x, size_y]: self._beam_info_dict["shape"] = "ellipse" else: self._beam_info_dict["shape"] = "rectangular" if ( self.chan_beam_size_microns is not None and self._beam_info_dict["size_x"] < 1.3 and self._beam_info_dict["size_y"] < 1.3 ): self.chan_beam_size_microns.set_value( ( self._beam_info_dict["size_x"] * 1000, self._beam_info_dict["size_y"] * 1000, ) ) if self.chan_beam_shape_ellipse: self.chan_beam_shape_ellipse.set_value( self._beam_info_dict["shape"] == "ellipse" )
def re_emit_values(self): """Emits signals :return: None """ if ( self._beam_info_dict["size_x"] != sys.float_info.max and self._beam_info_dict["size_y"] != sys.float_info.max ): self.emit( "beamSizeChanged", ( ( self._beam_info_dict["size_x"] * 1000, self._beam_info_dict["size_y"] * 1000, ), ), ) self.emit("beamInfoChanged", (self._beam_info_dict,))
[docs] def get_beam_info(self): """Returns beam info :return: dict """ self.update_beam_info() return self._beam_info_dict
[docs] def re_emit_values(self): """Reemits all signals :return: None """ self.emit("beamInfoChanged", (self._beam_info_dict,)) self.emit("beamPosChanged", (self._beam_position_on_screen,))
[docs] def move_beam(self, direction, step=1): """Moves beam mark :param direction: direction :type direction: str :param step: step in pixels :type step: int :return: None """ if direction == "left": self.chan_beam_position_hor.set_value( self._beam_position_on_screen[0] - step ) elif direction == "right": self.chan_beam_position_hor.set_value( self._beam_position_on_screen[0] + step ) elif direction == "up": self.chan_beam_position_ver.set_value( self._beam_position_on_screen[1] - step ) elif direction == "down": self.chan_beam_position_ver.set_value( self._beam_position_on_screen[1] + step )
[docs] def get_focus_mode(self): """Returns current focusing mode :return: str """ focus_mode = None if self._definer is not None: focus_mode = self._definer.get_focus_mode() return focus_mode