Skip to content

Commit b0a9378

Browse files
committed
rfvc documentation and comments
1 parent 7986977 commit b0a9378

File tree

2 files changed

+57
-50
lines changed

2 files changed

+57
-50
lines changed

docs/source/02_user_guide/01_supported_hardware/remote_focus.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,33 @@ Optotune Focus Tunable Lens
115115
116116
------------------
117117

118+
ASI
119+
---
120+
121+
The ASI Tiger Controller has a few limitations for the analog signals. First, the
122+
minimum voltage must be zero volts. There are two analog waveforms offered, triangle
123+
and ramp waves. The triangle waveform is a periodic analog waveform, with no delay
124+
periods. The sawtooth waveform is a periodic analog waveform with a delay period
125+
between each cycle.
126+
127+
.. collapse:: Configuration File
128+
129+
.. code-block:: yaml
130+
131+
microscopes:
132+
microscope_name:
133+
remote_focus_device:
134+
hardware:
135+
type: ASI
136+
channel: PXI6269/ao3
137+
min: 0
138+
max: 5
139+
port: COM2
140+
baudrate: 9600
141+
|
142+
143+
------------------
144+
118145
Synthetic Remote Focus Device
119146
-----------------------------
120147
If no remote focus device is present, one must configure the software to use a synthetic

src/navigate/model/devices/remote_focus/asi.py

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
# Standard Library Imports
3434
import logging
35-
import time
3635
from typing import Any, Dict
3736

3837
# Third Party Imports
@@ -50,7 +49,7 @@
5049

5150
@log_initialization
5251
class ASIRemoteFocus(RemoteFocusBase , SerialDevice):
53-
"""RemoteFocusNI Class - Analog control of the remote focus device."""
52+
"""ASIRemoteFocus Class - Analog control of the remote focus device."""
5453

5554
def __init__(
5655
self,
@@ -60,7 +59,7 @@ def __init__(
6059
*args,
6160
**kwargs,
6261
) -> None:
63-
"""Initialize the RemoteFocusNI class.
62+
"""Initialize the ASIRemoteFocus class.
6463
6564
Parameters
6665
----------
@@ -142,7 +141,10 @@ def connect(cls, port, baudrate=115200, timeout=0.25):
142141
return tiger_controller
143142

144143
def adjust(self, exposure_times, sweep_times, offset=None):
145-
"""Adjusts the remote focus waveform based on the readout time.
144+
"""Adjust the waveform.
145+
146+
This method adjusts the waveform parameters.
147+
Based on the sensor mode and readout direction, either the triangle or ramp function will be called.
146148
147149
Parameters
148150
----------
@@ -152,11 +154,6 @@ def adjust(self, exposure_times, sweep_times, offset=None):
152154
Dictionary of sweep times for each selected channel
153155
offset : float, optional
154156
Offset value for the remote focus waveform, by default None
155-
156-
Returns
157-
-------
158-
waveform : numpy.ndarray
159-
Waveform for the remote focus device.
160157
"""
161158

162159
# to determine if the waveform has to be triangular
@@ -171,17 +168,6 @@ def adjust(self, exposure_times, sweep_times, offset=None):
171168
waveform_constants = self.configuration["waveform_constants"]
172169
imaging_mode = microscope_state["microscope_name"]
173170
zoom = microscope_state["zoom"]
174-
# ramp_type = self.configuration["configuration"]["microscopes"][
175-
# self.microscope_name]['remote focus device']['ramp_type']
176-
177-
remote_focus_delay = (
178-
float(waveform_constants["other_constants"]["remote_focus_delay"]) / 1000
179-
)
180-
181-
remote_focus_ramp_falling = (
182-
float(waveform_constants["other_constants"]["remote_focus_ramp_falling"])
183-
/ 1000
184-
)
185171

186172
for channel_key in microscope_state["channels"].keys():
187173
# channel includes 'is_selected', 'laser', 'filter', 'camera_exposure'...
@@ -197,6 +183,7 @@ def adjust(self, exposure_times, sweep_times, offset=None):
197183
self.sweep_time = sweep_times[channel_key]
198184

199185
# Remote Focus Parameters
186+
# Validation for when user puts a '-' or '.' in spinbox
200187
temp = waveform_constants["remote_focus_constants"][imaging_mode][zoom][
201188
laser
202189
]["amplitude"]
@@ -240,22 +227,20 @@ def adjust(self, exposure_times, sweep_times, offset=None):
240227
self.triangle(sweep_time, amplitude, offset)
241228

242229
else:
243-
self.ramp(exposure_time=exposure_time,
244-
sweep_time=self.sweep_time,
245-
remote_focus_delay=remote_focus_delay,
246-
camera_delay=self.camera_delay,
247-
fall=remote_focus_ramp_falling,
248-
amplitude=amplitude,
249-
offset=remote_focus_offset
250-
)
230+
self.ramp(exposure_time, amplitude, remote_focus_offset)
251231

252232
def triangle(
253233
self,
254234
sweep_time=0.24,
255235
amplitude=1,
256236
offset=0,
257237
):
258-
"""Sends the tiger controller commands to initiate the triangle wave
238+
"""Sends the tiger controller commands to initiate the triangle wave.
239+
240+
The waveform starts at the offset and immediately rises linearly to 2x amplitude
241+
(amplitude here refers to 1/2 peak-to-peak) and immediately falls linearly back
242+
to the offset. The waveform is a periodic waveform with no delay periods between
243+
cycles.
259244
260245
Parameters
261246
----------
@@ -267,24 +252,30 @@ def triangle(
267252
Unit - Volts
268253
"""
269254

270-
period = int(round(sweep_time * 1000))
255+
# Converts sweep_time to ms and amplitude and offset to mV
256+
period = int(round(sweep_time * 1000))
271257
amplitude *= 1000
272258
offset *= 1000
273259

260+
# Triangle waveform
274261
self.remote_focus.SA_waveform(self.axis, 1, amplitude, offset, period)
262+
# Waveform is free running after it is triggered
275263
self.remote_focus.SAM(self.axis, 4)
276264

277265
def ramp(
278266
self,
279267
exposure_time=0.2,
280-
sweep_time=0.24,
281-
remote_focus_delay=0.005,
282-
camera_delay=0.001,
283-
fall=0.05,
284268
amplitude=1,
285269
offset=0.5,
286270
):
287-
"""Sends the tiger controller commands to make the ramp wave
271+
"""Sends the tiger controller commands to initiate the ramp wave.
272+
273+
The waveform starts at offset and immediately rises linearly to 2x amplitude
274+
(amplitude here refers to 1/2 peak-to-peak) and then immediately drops back
275+
down to the offset voltage during the fall period.
276+
277+
There is a delay period after each cycle that comes from the PLC, which is
278+
not included in this function.
288279
289280
Parameters
290281
----------
@@ -304,25 +295,14 @@ def ramp(
304295
Unit - Volts
305296
"""
306297

307-
# rise period
308-
309-
# print(f"{exposure_time}, {camera_delay}, {remote_focus_delay}")
310-
# period = int(
311-
# (exposure_time + camera_delay - remote_focus_delay) * 1000
312-
# )
313-
314-
# delay period
315-
# extra_samples = int(int(sweep_time)- (remote_focus_delay + period + fall))
316-
# if extra_samples > 0:
317-
# _delay_time = remote_focus_delay + fall + extra_samples
318-
# else:
319-
# _delay_time = remote_focus_delay + fall
320-
298+
# Converts exposure_time to ms and amplitude and offset to mV
321299
amplitude *= 1000
322300
offset *= 1000
323301
exposure_time = int(round(exposure_time * 1000))
324-
#print(f"RFVC: {amplitude} {offset} {exposure_time}")
302+
303+
# Ramp waveform that is triggered on TTL inputs
325304
self.remote_focus.SA_waveform(self.axis, 128, amplitude, offset, exposure_time)
305+
# The waveform cycles once and waits for another TTL inputs
326306
self.remote_focus.SAM(self.axis, 2)
327307

328308
def move(self, exposure_times, sweep_times, offset=None):

0 commit comments

Comments
 (0)