BioImager  3.9.1
A .NET microscopy imaging library. Supports various microscopes by using imported libraries & GUI automation. Supported libraries include Prior® & Zeiss® & all devices supported by Micromanager 2.0 and python-microscope.
Loading...
Searching...
No Matches
microscope.lights.toptica._iBeamConnection Class Reference

Public Member Functions

def __init__ (self, str port)
 
bytes command (self, bytes command)
 
None laser_on (self)
 
None laser_off (self)
 
None set_normal_channel_power (self, float power)
 
float show_power_uW (self)
 
bytes status_laser (self)
 
float show_max_power (self)
 

Detailed Description

Connection to a specific Toptica iBeam smart laser.

This class wraps the serial connection to the device, and provides
access to some of its commands performing most of the parsing and
validation.

Args:
    port: port name (Windows) or path to port (everything else) to
        connect to.  For example, `/dev/ttyS1`, `COM1`, or
        `/dev/cuad1`.

Definition at line 51 of file toptica.py.

Constructor & Destructor Documentation

◆ __init__()

def microscope.lights.toptica._iBeamConnection.__init__ (   self,
str  port 
)

Definition at line 65 of file toptica.py.

65 def __init__(self, port: str):
66 # From the Toptica iBeam SMART manual:
67 # Direct connection via COMx with 115200,8,N,1 and serial
68 # interface handshake "none". That means that no hardware
69 # handshake (DTR, RTS) and no software handshake (XON,XOFF) of
70 # the underlying operating system is supported.
71 serial_conn = serial.Serial(
72 port=port,
73 baudrate=115200,
74 timeout=1.0,
75 bytesize=serial.EIGHTBITS,
76 stopbits=serial.STOPBITS_ONE,
77 parity=serial.PARITY_NONE,
78 xonxoff=False,
79 rtscts=False,
80 dsrdtr=False,
81 )
82 self._serial = microscope._utils.SharedSerial(serial_conn)
83
84 # We don't know what is the current verbosity state and so we
85 # don't know yet what we should be reading back. So blindly
86 # set to the level we want, flush all output, and then check
87 # if indeed this is a Toptica iBeam device.
88 with self._serial.lock:
89 self._serial.write(b"echo off\r\n")
90 self._serial.write(b"prompt off\r\n")
91 # The talk level we want is 'usual'. In theory we should
92 # be able to use 'quiet' which only answers queries but in
93 # practice 'quiet' does not answer some queries like 'show
94 # serial'.
95 self._serial.write(b"talk usual\r\n")
96 self._serial.readlines() # discard all pending lines
97
98 # Empty command does nothing and returns nothing extra so we
99 # use it to ensure this at least behaves like a Toptica iBeam.
100 try:
101 self.command(b"")
102 except microscope.DeviceError as e:
104 "Failed to confirm Toptica iBeam on %s" % (port)
105 ) from e
106
107 answer = self.command(b"show serial")
108 if not answer.startswith(b"SN: "):
110 "Failed to parse serial from %s" % answer
111 )
112 _logger.info("got connection to Toptica iBeam %s", answer.decode())
113

Member Function Documentation

◆ command()

bytes microscope.lights.toptica._iBeamConnection.command (   self,
bytes  command 
)
Run command and return answer after minimal validation.

The output of a command has the format::

    \r\nANSWER\r\n[OK]\r\n

The returned bytes only include `ANSWER` without its own final
`\r\n`.  This means that the return value might be an empty
array of bytes.

Definition at line 114 of file toptica.py.

114 def command(self, command: bytes) -> bytes:
115 """Run command and return answer after minimal validation.
116
117 The output of a command has the format::
118
119 \r\nANSWER\r\n[OK]\r\n
120
121 The returned bytes only include `ANSWER` without its own final
122 `\r\n`. This means that the return value might be an empty
123 array of bytes.
124 """
125 # We expect to be on 'talk usual' mode without prompt so each
126 # command will end with [OK] on its own line.
127 with self._serial.lock:
128 self._serial.write(command + b"\r\n")
129 # An answer always starts with \r\n so there will be one
130 # before [OK] even if this command is not a query.
131 answer = self._serial.read_until(b"\r\n[OK]\r\n")
132
133 if not answer.startswith(b"\r\n"):
135 "answer to command %s does not start with CRLF."
136 " This may be leftovers from a previous command:"
137 " %s" % (command, answer)
138 )
139 if not answer.endswith(b"\r\n[OK]\r\n"):
141 "Command %s failed or failed to read answer: %s"
142 % (command, answer)
143 )
144
145 # If an error occurred, the answer still ends in [OK]. We
146 # need to check if the second line (first line is \r\n) is an
147 # error code with the format "%SYS-L-XXX, error description"
148 # where L is the error level (I for Information, W for
149 # Warning, E for Error, and F for Fatal), and XXX is the error
150 # code number.
151 if answer[2:7] == b"%SYS-" and answer[7] != ord(b"I"):
152 # Errors of level I (information) should not raise an
153 # exception since they can be replies to normal commands.
155 "Command %s failed: %s" % (command, answer)
156 )
157
158 # Exclude the first \r\n, the \r\n from a possible answer, and
159 # the final [OK]\r\n
160 return answer[2:-8]
161

References microscope._utils.SharedSerial._serial, microscope.controllers.coolled._CoolLEDConnection._serial, microscope.controllers.lumencor._SpectraIIIConnection._serial, microscope.controllers.prior._ProScanIIIConnection._serial, microscope.controllers.toptica._iChromeConnection._serial, microscope.controllers.zaber._ZaberConnection._serial, microscope.lights.toptica._iBeamConnection._serial, and microscope.stages.ludl._LudlController._serial.

Referenced by microscope.controllers.zaber._ZaberDeviceConnection.been_homed(), microscope.controllers.zaber._ZaberDeviceConnection.command(), microscope.controllers.zaber._ZaberDeviceConnection.get_absolute_position(), microscope.controllers.prior._ProScanIIIConnection.get_command(), microscope.stages.ludl._LudlController.get_command(), microscope.controllers.zaber._ZaberDeviceConnection.get_current_index(), microscope.controllers.prior._ProScanIIIConnection.get_description(), microscope.stages.ludl._LudlController.get_description(), microscope.controllers.zaber._ZaberDeviceConnection.get_index_distance(), microscope.controllers.zaber._ZaberDeviceConnection.get_limit_max(), microscope.controllers.zaber._ZaberDeviceConnection.get_limit_min(), microscope.controllers.zaber._ZaberDeviceConnection.get_number_axes(), microscope.controllers.zaber._ZaberDeviceConnection.get_rotation_length(), microscope.controllers.zaber._ZaberDeviceConnection.home(), microscope.lights.toptica._iBeamConnection.laser_off(), microscope.lights.toptica._iBeamConnection.laser_on(), microscope.lights.toptica._iBeamConnection.set_normal_channel_power(), microscope.lights.toptica._iBeamConnection.show_power_uW(), and microscope.lights.toptica._iBeamConnection.status_laser().

◆ laser_off()

None microscope.lights.toptica._iBeamConnection.laser_off (   self)
Deactivate LD driver.

Definition at line 166 of file toptica.py.

166 def laser_off(self) -> None:
167 """Deactivate LD driver."""
168 self.command(b"laser off")
169

References microscope.controllers.prior._ProScanIIIConnection.command(), microscope.lights.toptica._iBeamConnection.command(), microscope.stages.ludl._LudlController.command(), and microscope.controllers.zaber._ZaberDeviceConnection.command().

◆ laser_on()

None microscope.lights.toptica._iBeamConnection.laser_on (   self)
Activate LD driver.

Definition at line 162 of file toptica.py.

162 def laser_on(self) -> None:
163 """Activate LD driver."""
164 self.command(b"laser on")
165

References microscope.controllers.prior._ProScanIIIConnection.command(), microscope.lights.toptica._iBeamConnection.command(), microscope.stages.ludl._LudlController.command(), and microscope.controllers.zaber._ZaberDeviceConnection.command().

◆ set_normal_channel_power()

None microscope.lights.toptica._iBeamConnection.set_normal_channel_power (   self,
float  power 
)
Set power in mW for channel 2 (normal operating level channel).

We don't have channel number as an argument because we only
want to be setting the power via channel 2 (channel 1 is the
bias and we haven't seen a laser with a channel 3 yet).

Definition at line 170 of file toptica.py.

170 def set_normal_channel_power(self, power: float) -> None:
171 """Set power in mW for channel 2 (normal operating level channel).
172
173 We don't have channel number as an argument because we only
174 want to be setting the power via channel 2 (channel 1 is the
175 bias and we haven't seen a laser with a channel 3 yet).
176 """
177 self.command(b"channel 2 power %f" % power)
178

References microscope.controllers.prior._ProScanIIIConnection.command(), microscope.lights.toptica._iBeamConnection.command(), microscope.stages.ludl._LudlController.command(), and microscope.controllers.zaber._ZaberDeviceConnection.command().

◆ show_max_power()

float microscope.lights.toptica._iBeamConnection.show_max_power (   self)

Definition at line 192 of file toptica.py.

192 def show_max_power(self) -> float:
193 # There should be a cleaner way to get these, right? We can
194 # query the current limits (mA) but how do we go from there to
195 # the power limits (mW)?
196 table = self.command(b"show satellite")
197 value = _get_table_value(table, key=b"Pmax")
198 if not value.endswith(b" mW"):
200 "failed to parse power from %s" % value
201 )
202 return float(value[:-3])
203
204

◆ show_power_uW()

float microscope.lights.toptica._iBeamConnection.show_power_uW (   self)
Returns actual laser power in µW.

Definition at line 179 of file toptica.py.

179 def show_power_uW(self) -> float:
180 """Returns actual laser power in µW."""
181 answer = self.command(b"show power")
182 if not answer.startswith(b"PIC = ") and not answer.endswith(b" uW "):
184 "failed to parse power from answer: %s" % answer
185 )
186 return float(answer[7:-5])
187

References microscope.controllers.prior._ProScanIIIConnection.command(), microscope.lights.toptica._iBeamConnection.command(), microscope.stages.ludl._LudlController.command(), and microscope.controllers.zaber._ZaberDeviceConnection.command().

◆ status_laser()

bytes microscope.lights.toptica._iBeamConnection.status_laser (   self)
Returns actual status of the LD driver (ON or OFF).

Definition at line 188 of file toptica.py.

188 def status_laser(self) -> bytes:
189 """Returns actual status of the LD driver (ON or OFF)."""
190 return self.command(b"status laser")
191

References microscope.controllers.prior._ProScanIIIConnection.command(), microscope.lights.toptica._iBeamConnection.command(), microscope.stages.ludl._LudlController.command(), and microscope.controllers.zaber._ZaberDeviceConnection.command().


The documentation for this class was generated from the following file: