Source code for pytemscript.modules.projection

from typing import Union, Dict, List, Tuple
from collections import OrderedDict
import logging

from ..utils.misc import RequestBody
from ..utils.enums import (ProjectionMode, ProjectionSubMode, ProjDetectorShiftMode,
                           ProjectionDetectorShift, LensProg)
from .extras import Vector


[docs] class Projection: """ Projection system functions. """ __slots__ = ("__client", "__id", "__err_msg", "__magnifications") def __init__(self, client): self.__client = client self.__id = "tem.Projection" self.__err_msg = "Microscope is not in %s mode" self.__magnifications = OrderedDict() def __find_magnifications(self) -> None: if not self.__magnifications: logging.info("Querying magnification table..") body = RequestBody(attr="tem.AutoNormalizeEnabled", value=False) self.__client.call(method="set", body=body) self.mode = ProjectionMode.IMAGING saved_index = self.magnification_index previous_index = None index = 1 while True: self.magnification_index = index index = self.magnification_index if index == previous_index: # failed to set new index break self.__magnifications[self.magnification] = (index, self.magnification_range) previous_index = index index += 1 # restore initial mag self.magnification_index = saved_index body = RequestBody(attr="tem.AutoNormalizeEnabled", value=True) self.__client.call(method="set", body=body) logging.info("Available magnifications: %s", self.__magnifications) @property def list_magnifications(self) -> Dict: """ List of available magnifications: mag -> (mag_index, submode). """ self.__find_magnifications() return self.__magnifications @property def focus(self) -> float: """ Absolute focus value. (read/write) """ body = RequestBody(attr=self.__id + ".Focus", validator=float) return self.__client.call(method="get", body=body) @focus.setter def focus(self, value: float) -> None: if not (-1.0 <= value <= 1.0): raise ValueError("%s is outside of range -1.0 to 1.0" % value) body = RequestBody(attr=self.__id + ".Focus", value=value) self.__client.call(method="set", body=body)
[docs] def eucentric_focus(self) -> None: """ Reset focus to eucentric value. """ body = RequestBody(attr=self.__id + ".Focus", value=0) self.__client.call(method="set", body=body)
@property def magnification(self) -> int: """ The reference magnification value (screen up setting). (read/write) """ body = RequestBody(attr=self.__id + ".Mode", validator=int) if self.__client.call(method="get", body=body) == ProjectionMode.IMAGING: body = RequestBody(attr=self.__id + ".Magnification", validator=float) return round(self.__client.call(method="get", body=body)) else: raise RuntimeError(self.__err_msg % "Imaging") @magnification.setter def magnification(self, value: int) -> None: body = RequestBody(attr=self.__id + ".Mode", validator=int) if self.__client.call(method="get", body=body) == ProjectionMode.IMAGING: self.__find_magnifications() if value not in self.__magnifications: raise ValueError("Magnification %s not found in the table" % value) index = self.__magnifications[value][0] self.magnification_index = index else: raise RuntimeError(self.__err_msg % "Imaging") @property def magnification_index(self) -> int: """ The magnification index. (read/write) """ body = RequestBody(attr=self.__id + ".MagnificationIndex", validator=int) return self.__client.call(method="get", body=body) @magnification_index.setter def magnification_index(self, value: int) -> None: body = RequestBody(attr=self.__id + ".MagnificationIndex", value=value) self.__client.call(method="set", body=body) @property def camera_length(self) -> float: """ The reference camera length in m (screen up setting). """ body = RequestBody(attr=self.__id + ".Mode", validator=int) if self.__client.call(method="get", body=body) == ProjectionMode.DIFFRACTION: body = RequestBody(attr=self.__id + ".CameraLength", validator=float) return self.__client.call(method="get", body=body) else: raise RuntimeError(self.__err_msg % "Diffraction") @property def camera_length_index(self) -> int: """ The camera length index. (read/write) """ body = RequestBody(attr=self.__id + ".CameraLengthIndex", validator=int) return self.__client.call(method="get", body=body) @camera_length_index.setter def camera_length_index(self, value: int) -> None: body = RequestBody(attr=self.__id + ".CameraLengthIndex", value=value) self.__client.call(method="set", body=body) @property def image_shift(self) -> Vector: """ Image shift in um. (read/write) """ shx = RequestBody(attr=self.__id + ".ImageShift.X", validator=float) shy = RequestBody(attr=self.__id + ".ImageShift.Y", validator=float) x = self.__client.call(method="get", body=shx) y = self.__client.call(method="get", body=shy) return Vector(x, y) * 1e6 @image_shift.setter def image_shift(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: value = Vector.convert_to(vector) * 1e-6 body = RequestBody(attr=self.__id + ".ImageShift", value=value) self.__client.call(method="set", body=body) @property def image_beam_shift(self) -> Vector: """ Image shift with beam shift compensation in um. (read/write) """ bsx = RequestBody(attr=self.__id + ".ImageBeamShift.X", validator=float) bsy = RequestBody(attr=self.__id + ".ImageBeamShift.Y", validator=float) x = self.__client.call(method="get", body=bsx) y = self.__client.call(method="get", body=bsy) return Vector(x, y) * 1e6 @image_beam_shift.setter def image_beam_shift(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: value = Vector.convert_to(vector) * 1e-6 body = RequestBody(attr=self.__id + ".ImageBeamShift", value=value) self.__client.call(method="set", body=body) @property def image_beam_tilt(self) -> Vector: """ Beam tilt with diffraction shift compensation in mrad. (read/write) """ btx = RequestBody(attr=self.__id + ".ImageBeamTilt.X", validator=float) bty = RequestBody(attr=self.__id + ".ImageBeamTilt.Y", validator=float) x = self.__client.call(method="get", body=btx) y = self.__client.call(method="get", body=bty) return Vector(x, y) * 1e3 @image_beam_tilt.setter def image_beam_tilt(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: value = Vector.convert_to(vector) * 1e-3 body = RequestBody(attr=self.__id + ".ImageBeamTilt", value=value) self.__client.call(method="set", body=body) @property def diffraction_shift(self) -> Vector: """ Diffraction shift in mrad. (read/write) """ #TODO: 180/pi*value = approx number in TUI stigx = RequestBody(attr=self.__id + ".DiffractionShift.X", validator=float) stigy = RequestBody(attr=self.__id + ".DiffractionShift.Y", validator=float) x = self.__client.call(method="get", body=stigx) y = self.__client.call(method="get", body=stigy) return Vector(x, y) * 1e3 @diffraction_shift.setter def diffraction_shift(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: value = Vector.convert_to(vector) * 1e-3 body = RequestBody(attr=self.__id + ".DiffractionShift", value=value) self.__client.call(method="set", body=body) @property def diffraction_stigmator(self) -> Vector: """ Diffraction stigmator. (read/write) """ body = RequestBody(attr=self.__id + ".Mode", validator=int) if self.__client.call(method="get", body=body) == ProjectionMode.DIFFRACTION: stigx = RequestBody(attr=self.__id + ".DiffractionStigmator.X", validator=float) stigy = RequestBody(attr=self.__id + ".DiffractionStigmator.Y", validator=float) x = self.__client.call(method="get", body=stigx) y = self.__client.call(method="get", body=stigy) return Vector(x, y) else: raise RuntimeError(self.__err_msg % "Diffraction") @diffraction_stigmator.setter def diffraction_stigmator(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: body = RequestBody(attr=self.__id + ".Mode", validator=int) if self.__client.call(method="get", body=body) == ProjectionMode.DIFFRACTION: value = Vector.convert_to(vector) value.set_limits(-1.0, 1.0) body = RequestBody(attr=self.__id + ".DiffractionStigmator", value=value) self.__client.call(method="set", body=body) else: raise RuntimeError(self.__err_msg % "Diffraction") @property def objective_stigmator(self) -> Vector: """ Objective stigmator. (read/write) """ stigx = RequestBody(attr=self.__id + ".ObjectiveStigmator.X", validator=float) stigy = RequestBody(attr=self.__id + ".ObjectiveStigmator.Y", validator=float) x = self.__client.call(method="get", body=stigx) y = self.__client.call(method="get", body=stigy) return Vector(x, y) @objective_stigmator.setter def objective_stigmator(self, vector: Union[Vector, List[float], Tuple[float, float]]) -> None: value = Vector.convert_to(vector) value.set_limits(-1.0, 1.0) body = RequestBody(attr=self.__id + ".ObjectiveStigmator", value=value) self.__client.call(method="set", body=body) @property def defocus(self) -> float: """ Defocus value in um. (read/write) Changing 'Defocus' will also change 'Focus' and vice versa. """ body = RequestBody(attr=self.__id + ".Defocus", validator=float) return self.__client.call(method="get", body=body) * 1e6 @defocus.setter def defocus(self, value: float) -> None: body = RequestBody(attr=self.__id + ".Defocus", value=float(value) * 1e-6) self.__client.call(method="set", body=body) @property def objective(self) -> float: """ The excitation of the objective lens in percent. """ body = RequestBody(attr=self.__id + ".ObjectiveExcitation", validator=float) return self.__client.call(method="get", body=body) @property def mode(self) -> str: """ Main mode of the projection system (either imaging or diffraction). ProjectionMode enum (read/write) """ body = RequestBody(attr=self.__id + ".Mode", validator=int) result = self.__client.call(method="get", body=body) return ProjectionMode(result).name @mode.setter def mode(self, mode: ProjectionMode) -> None: body = RequestBody(attr=self.__id + ".Mode", value=mode) self.__client.call(method="set", body=body) @property def detector_shift(self) -> str: """ Detector shift. ProjectionDetectorShift enum. (read/write) """ body = RequestBody(attr=self.__id + ".DetectorShift", validator=int) result = self.__client.call(method="get", body=body) return ProjectionDetectorShift(result).name @detector_shift.setter def detector_shift(self, value: ProjectionDetectorShift) -> None: body = RequestBody(attr=self.__id + ".DetectorShift", value=value) self.__client.call(method="set", body=body) @property def detector_shift_mode(self) -> str: """ Detector shift mode. ProjDetectorShiftMode enum. (read/write) """ body = RequestBody(attr=self.__id + ".DetectorShiftMode", validator=int) result = self.__client.call(method="get", body=body) return ProjDetectorShiftMode(result).name @detector_shift_mode.setter def detector_shift_mode(self, value: ProjDetectorShiftMode) -> None: body = RequestBody(attr=self.__id + ".DetectorShiftMode", value=value) self.__client.call(method="set", body=body) @property def magnification_range(self) -> str: """ Submode of the projection system (either LM, M, SA, MH, LAD or D). ProjectionSubMode enum. The imaging submode can change when the magnification is changed. """ body = RequestBody(attr=self.__id + ".SubMode", validator=int) result = self.__client.call(method="get", body=body) return ProjectionSubMode(result).name @property def image_rotation(self) -> float: """ The rotation of the image or diffraction pattern on the fluorescent screen with respect to the specimen. Units: mrad. """ body = RequestBody(attr=self.__id + ".ImageRotation", validator=float) return self.__client.call(method="get", body=body) * 1e3 @property def is_eftem_on(self) -> bool: """ Check if the EFTEM lens program setting is ON. """ body = RequestBody(attr=self.__id + ".LensProgram", validator=int) result = self.__client.call(method="get", body=body) return LensProg(result) == LensProg.EFTEM
[docs] def eftem_on(self) -> None: """ Switch on EFTEM. """ body = RequestBody(attr=self.__id + ".LensProgram", value=LensProg.EFTEM) self.__client.call(method="set", body=body)
[docs] def eftem_off(self) -> None: """ Switch off EFTEM. """ body = RequestBody(attr=self.__id + ".LensProgram", value=LensProg.REGULAR) self.__client.call(method="set", body=body)
[docs] def reset_defocus(self) -> None: """ Reset defocus value in the TEM user interface to zero. Does not change any lenses. """ body = RequestBody(attr=self.__id + ".ResetDefocus()") self.__client.call(method="exec", body=body)