"""
[Name] BeamInfo
[Description]
BeamInfo hardware object is used to define final beam size and shape.
It can include aperture, slits and/or other beam definer (lenses or other eq.)
[Emitted signals]
beamInfoChanged
beamPosChanged
[Included Hardware Objects]
-----------------------------------------------------------------------
| name | signals | functions
-----------------------------------------------------------------------
aperture_hwobj apertureChanged
slits_hwobj
beam_definer_hwobj
-----------------------------------------------------------------------
"""
from mxcubecore.BaseHardwareObjects import HardwareObject
[docs]class BeamInfo(HardwareObject):
def __init__(self, *args):
super().__init__(*args)
self.aperture_hwobj = None
self.beam_definer = None
self.slits_hwobj = None
self.beam_size_slits = None
self.beam_size_aperture = None
self.beam_size_definer = None
self.beam_position = None
self.beam_info_dict = None
self.default_beam_divergence = None
self.chan_beam_size_microns = None
self.chan_beam_shape_ellipse = None
[docs] def init(self):
self.beam_size_slits = [9999, 9999]
self.beam_size_aperture = [9999, 9999]
self.beam_size_definer = [9999, 9999]
self.beam_position = (0, 0)
self.beam_info_dict = {}
self.polarisation = self.get_property("polarisation", 0.99)
self.aperture_hwobj = self.get_object_by_role("aperture")
if self.aperture_hwobj is not None:
self.connect(
self.aperture_hwobj, "apertureChanged", self.aperture_pos_changed
)
else:
self.log.debug("BeamInfo: Aperture hwobj not defined")
self.slits_hwobj = self.get_object_by_role("slits")
if self.slits_hwobj is not None:
self.connect(self.slits_hwobj, "gapSizeChanged", self.slits_gap_changed)
else:
self.log.debug("BeamInfo: Slits hwobj not defined")
if self.beam_definer is not None:
self.connect(
self.beam_definer, "definerPosChanged", self.definer_pos_changed
)
else:
self.log.debug("BeamInfo: Beam definer hwobj not defined")
default_beam_divergence_vertical = None
default_beam_divergence_horizontal = None
try:
default_beam_divergence_vertical = int(
self.get_property("beam_divergence_vertical")
)
default_beam_divergence_horizontal = int(
self.get_property("beam_divergence_horizontal")
)
except Exception:
self.log.exception("")
self.default_beam_divergence = [
default_beam_divergence_horizontal,
default_beam_divergence_vertical,
]
def connect_notify(self, *args):
self.evaluate_beam_info()
self.re_emit_values()
def get_beam_divergence_hor(self):
if self.beam_definer is not None:
return self.beam_definer.get_divergence_hor()
else:
return self.default_beam_divergence[0]
def get_beam_divergence_ver(self):
if self.beam_definer is not None:
return self.beam_definer.get_divergence_ver()
else:
return self.default_beam_divergence[1]
def get_beam_position(self):
return (0, 0)
def set_beam_position(self, beam_x, beam_y):
raise NotImplementedError
def aperture_pos_changed(self, size):
self.beam_size_aperture = size
self.evaluate_beam_info()
self.re_emit_values()
def slits_gap_changed(self, size):
self.beam_size_slits = size
self.evaluate_beam_info()
self.re_emit_values()
def definer_pos_changed(self, name, size):
self.beam_size_definer = size
self.evaluate_beam_info()
self.re_emit_values()
def get_beam_info(self):
return self.evaluate_beam_info()
[docs] def get_beam_size(self):
"""
Descript. : returns beam size in millimeters
Return : list with two integers
"""
self.evaluate_beam_info()
return self.beam_info_dict["size_x"], self.beam_info_dict["size_y"]
def get_beam_shape(self):
self.evaluate_beam_info()
return self.beam_info_dict["shape"]
def get_slits_gap(self):
self.evaluate_beam_info()
return self.beam_size_slits
[docs] def evaluate_beam_info(self):
"""
Descript. : 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_aperture[0],
self.beam_size_slits[0],
self.beam_size_definer[0],
)
size_y = min(
self.beam_size_aperture[1],
self.beam_size_slits[1],
self.beam_size_definer[1],
)
self.beam_info_dict["size_x"] = size_x
self.beam_info_dict["size_y"] = size_y
# be careful with comparisons!!! both have to be the same type (=tuple)
if tuple(self.beam_size_aperture) < tuple(self.beam_size_slits):
self.beam_info_dict["shape"] = "ellipse"
else:
self.beam_info_dict["shape"] = "rectangular"
return self.beam_info_dict
[docs] def re_emit_values(self):
if (
self.beam_info_dict["size_x"] != 9999
and self.beam_info_dict["size_y"] != 9999
):
self.emit(
"beamSizeChanged",
((self.beam_info_dict["size_x"], self.beam_info_dict["size_y"]),),
)
self.emit("beamInfoChanged", (self.beam_info_dict,))
if self.chan_beam_size_microns:
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"
)