Source code for mxcubecore.HardwareObjects.EMBL.EMBLCRL

#
#  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/>.

"""EMBLCRL"""

import logging
import math

import gevent

from mxcubecore import HardwareRepository as HWR
from mxcubecore.BaseHardwareObjects import HardwareObject

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


[docs]class EMBLCRL(HardwareObject): """Controls CRLs""" def __init__(self, name): HardwareObject.__init__(self, name) self.focal_length = None self.lens_count = None self.modes = None self.current_mode = None self.energy_value = None self.energy_state = None self.current_focusing_mode = None self.crl_value = None self.chan_crl_value = None self.cmd_set_crl_value = None self.cmd_set_trans_value = None self.beam_focusing_hwobj = None self.at_startup = None
[docs] def init(self): """Inits all variables""" self.focal_length = self.get_property("focal_length") self.lens_count = 6 self.chan_crl_value = self.get_channel_object("chanCrlValue") if self.chan_crl_value: self.chan_crl_value.connect_signal("update", self.crl_value_changed) self.cmd_set_crl_value = self.get_command_object("cmdSetLenses") self.cmd_set_trans_value = self.get_command_object("cmdSetTrans") self.energy_value = HWR.beamline.energy.get_value() self.connect(HWR.beamline.energy, "stateChanged", self.energy_state_changed) self.beam_focusing_hwobj = self.get_object_by_role("beam_focusing") if self.beam_focusing_hwobj is not None: self.connect( self.beam_focusing_hwobj, "focusingModeRequested", self.focusing_mode_requested, ) lens_modes = self.beam_focusing_hwobj.get_available_lens_modes() if lens_modes: self.set_mode(lens_modes[0]) else: self.set_mode("Manual")
[docs] def convert_value(self, value): """Converts int to list of bits""" if isinstance(value, (list, tuple)): lens_combination = 0 for index in range(self.lens_count): lens_combination = lens_combination + value[index] * pow(2, index) else: lens_combination = [0, 0, 0, 0, 0, 0] for index in range(self.lens_count): lens_combination[index] = (value & pow(2, index)) / pow(2, index) return lens_combination
[docs] def get_modes(self): """Returns list with available CRL modes""" if self.beam_focusing_hwobj: return self.beam_focusing_hwobj.get_available_lens_modes() else: return ["Manual"]
[docs] def get_mode(self): """Returns current crl mode""" return self.current_mode
[docs] def set_mode(self, mode): """Sets crl mode :param mode: crl mode :type mode: str :return: None """ self.current_mode = mode # if self.current_mode == "Out": # self.set_crl_value([0, 0, 0, 0, 0, 0]) if self.current_mode == "Automatic": self.set_according_to_energy() self.emit("crlModeChanged", self.current_mode)
[docs] def energy_state_changed(self, state): """If CRL's in the automatic mode then change setting according to the current energy :param state: energy state :type state: str """ if ( state == "ready" and state != self.energy_state and self.current_mode == "Automatic" ): self.energy_value = HWR.beamline.energy.get_value() self.set_according_to_energy() self.energy_state = state
[docs] def set_according_to_energy(self): """Sets CRL combination according to the current energy""" min_abs = 20 selected_combination = None # crl_value = [0, 0, 0, 0, 0, 0] self.energy_value = HWR.beamline.energy.get_value() for combination_index in range(1, 65): current_abs = abs( self.energy_value - math.sqrt( (2 * 341.52 * combination_index) / (2000 * (1 / 42.6696 + 1 / self.focal_length)) ) ) if current_abs < min_abs: min_abs = current_abs selected_combination = combination_index # for index in range(6): # crl_value[index] = (selected_combination & pow(2,index))/pow(2,index) self.set_crl_value(self.convert_value(selected_combination))
[docs] def get_image_plane_distance(self, value): """Returns image plane distance""" if isinstance(value, list): lens_combination = self.convert_value(value) else: lens_combination = value return 1.0 / ( 2 * 341.52 * lens_combination / 2000 / (self.energy_value**2) - 1 / 42.6696 )
[docs] def focusing_mode_requested(self, focusing_mode): """Sets CRL combination based on the focusing mode""" if focusing_mode is not None: self.modes = self.beam_focusing_hwobj.get_available_lens_modes( focusing_mode ) self.set_mode(self.modes[0]) self.set_crl_value( self.beam_focusing_hwobj.get_lens_combination(focusing_mode) )
[docs] def crl_value_changed(self, value): """Emit signal when crl combination changed""" self.crl_value = value self.emit("crlValueChanged", self.crl_value)
[docs] def set_crl_value(self, value, timeout=None): """Sets CRL lens combination. If integer passed then converts value to the bit list """ if not isinstance(value, (list, tuple)): value = self.convert_value(value) if value is not None: self.cmd_set_crl_value(value) self.cmd_set_trans_value(1) logging.getLogger("GUI").info( "Setting CRL image plane " + "distance to %.2f" % self.get_image_plane_distance(value) ) if timeout: gevent.sleep(1) with gevent.Timeout(timeout, Exception("Timeout waiting for CRL")): while value != self.crl_value: gevent.sleep(0.1)
[docs] def get_crl_value(self): """Return crl combination""" return self.crl_value
[docs] def re_emit_values(self): """Reemits signals""" self.emit("crlModeChanged", self.current_mode) self.emit("crlValueChanged", self.crl_value)
[docs] def move_up(self): """Moves lense combination one value up""" new_value = self.convert_value(self.crl_value) + 1 self.set_crl_value(new_value)
[docs] def move_down(self): """Moves lense combination one value down""" new_value = self.convert_value(self.crl_value) - 1 self.set_crl_value(new_value)