BioImager  4.9.0
A .NET microscopy imaging application based on Bio library. Supports various microscopes by using imported libraries & GUI automation. Supports XInput game controllers to move stage, take images, run ImageJ macros on images or Bio C# scripts.
Loading...
Searching...
No Matches
mirao52e.py
1#!/usr/bin/env python3
2
3
20
21"""Imagine Optic Mirao 52-e deformable mirror.
22
23The Mirao 52-e deformable mirror is not capable of receiving hardware
24triggers. It is only capable of sending hardware triggers. That
25sending of hardware triggers is not implemented on this module because
26it's pointless.
27
28The Mirao 52-e deformable mirror has a limitation on valid patterns.
29From the vendor documentation (the command is the pattern to be
30applied):
31
32 [...] the sum of the absolute values defining the command must be
33 lower than or equal to 24 and each value must be comprised between
34 -1.0 and 1.0.
35
36In microscope, a pattern must be specified in the [0 1] range.
37However, the limit of 24, after rescaling to [-1 1] range, still
38applies.
39
40"""
41
42import ctypes
43import typing
44
45import numpy
46
47import microscope
49import microscope.abc
50
51
52try:
54except Exception as e:
55 raise microscope.LibraryLoadError(e) from e
56
57
61):
62 """Imagine Optic Mirao 52e deformable mirror.
63
64 The Mirao 52e deformable mirrors only support software trigger.
65
66 """
67
68 def __init__(self, **kwargs) -> None:
69 super().__init__(**kwargs)
70 # Status is not the return code of the function calls.
71 # Status is where we can find the error code in case a
72 # function call returns false. This _status variable will be
73 # an argument in all function calls.
74 self._status = ctypes.pointer(ctypes.c_int(mro.OK))
75 if not mro.open(self._status):
77 "failed to open mirao mirror (error code %d)"
78 % self._status.contents.value
79 )
80
81 @property
82 def n_actuators(self) -> int:
83 return mro.NB_COMMAND_VALUES
84
85 @staticmethod
86 def _normalize_patterns(patterns: numpy.ndarray) -> numpy.ndarray:
87 """
88 mirao52e SDK expects values in the [-1 1] range, so we normalize
89 them from the [0 1] range we expect in our interface.
90 """
91 patterns = (patterns * 2) - 1
92 return patterns
93
94 def _do_apply_pattern(self, pattern: numpy.ndarray) -> None:
95 pattern = self._normalize_patterns(pattern)
96 command = pattern.ctypes.data_as(mro.Command)
97 if not mro.applyCommand(command, mro.FALSE, self._status):
98 self._raise_status(mro.applyCommand)
99
100 def _raise_status(self, func: typing.Callable) -> None:
101 error_code = self._status.contents.value
103 "mro_%s() failed (error code %d)" % (func.__name__, error_code)
104 )
105
106 def _do_shutdown(self) -> None:
107 if not mro.close(self._status):
108 self._raise_status(mro.close)
numpy.ndarray _normalize_patterns(numpy.ndarray patterns)
Definition mirao52e.py:86
None _raise_status(self, typing.Callable func)
Definition mirao52e.py:100