Skip to content

Commit 7590ae5

Browse files
Merge pull request #1134 from TheDeanLab/fix-expansion-daq-issue
Fix expansion daq issue
2 parents c8fd6fa + 02cef38 commit 7590ae5

File tree

1 file changed

+61
-5
lines changed
  • src/navigate/model/devices/daq

1 file changed

+61
-5
lines changed

src/navigate/model/devices/daq/ni.py

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Copyright (c) 2021-2024 The University of Texas Southwestern Medical Center.
22
# All rights reserved.
3-
43
# Redistribution and use in source and binary forms, with or without
54
# modification, are permitted for academic and research use only (subject to the
65
# limitations in the disclaimer below) provided that the following conditions are met:
@@ -36,11 +35,13 @@
3635
import traceback
3736
import time
3837
from typing import Union, Dict, Any
38+
import gc
3939

4040
# Third Party Imports
4141
import nidaqmx
4242
import nidaqmx.constants
4343
import nidaqmx.task
44+
from nidaqmx.system import System
4445
import numpy as np
4546

4647
# Local Imports
@@ -104,13 +105,23 @@ def __init__(self, configuration: Dict[str, Any]) -> None:
104105
#: bool: Flag for waiting to run.
105106
self.wait_to_run_lock = Lock()
106107

108+
#: int: trigger count
109+
self.trigger_count = 0
110+
111+
#: int: trigger reset count
112+
self.trigger_reset_count = None
113+
107114
def __str__(self) -> str:
108115
"""String representation of the class."""
109116
return "NIDAQ"
110117

111118
def __del__(self) -> None:
112119
"""Destructor."""
113-
for task in [self.camera_trigger_task, self.master_trigger_task, self.laser_switching_task]:
120+
for task in [
121+
self.camera_trigger_task,
122+
self.master_trigger_task,
123+
self.laser_switching_task,
124+
]:
114125
if task:
115126
try:
116127
task.stop()
@@ -125,8 +136,9 @@ def __del__(self) -> None:
125136
task.stop()
126137
task.close()
127138
except Exception:
128-
logger.exception(f"Error stopping task: {traceback.format_exc()}")
129-
139+
logger.exception(
140+
f"Error stopping task: {traceback.format_exc()}"
141+
)
130142

131143
def set_external_trigger(self, external_trigger=None) -> None:
132144
"""Set trigger mode.
@@ -438,7 +450,7 @@ def prepare_acquisition(self, channel_key: str) -> None:
438450
# Specify ports, timing, and triggering
439451
self.set_external_trigger(self.external_trigger)
440452

441-
def run_acquisition(self, wait_until_done : bool = True) -> None:
453+
def run_acquisition(self, wait_until_done: bool = True) -> None:
442454
"""Run DAQ Acquisition.
443455
444456
Run the tasks for triggering, analog and counter outputs.
@@ -464,6 +476,8 @@ def run_acquisition(self, wait_until_done : bool = True) -> None:
464476
if wait_until_done:
465477
self.wait_acquisition_done()
466478

479+
self.trigger_count += 1
480+
467481
def wait_acquisition_done(self) -> None:
468482
"""Wait acquisition tasks done"""
469483

@@ -485,6 +499,13 @@ def wait_acquisition_done(self) -> None:
485499
except nidaqmx.DaqError:
486500
pass
487501

502+
if (
503+
self.trigger_reset_count is not None
504+
and self.trigger_count >= self.trigger_reset_count
505+
):
506+
self.stop_acquisition()
507+
self.prepare_acquisition(self.current_channel_key)
508+
488509
def stop_acquisition(self) -> None:
489510
"""Stop Acquisition.
490511
@@ -509,6 +530,12 @@ def stop_acquisition(self) -> None:
509530
self.wait_to_run_lock.release()
510531

511532
self.analog_output_tasks = {}
533+
if (
534+
self.trigger_reset_count is not None
535+
and self.trigger_count >= self.trigger_reset_count
536+
):
537+
self.reset()
538+
self.trigger_count = 0
512539

513540
def enable_microscope(self, microscope_name: str) -> None:
514541
"""Enable microscope.
@@ -522,6 +549,9 @@ def enable_microscope(self, microscope_name: str) -> None:
522549
self.microscope_name = microscope_name
523550
self.analog_outputs = {}
524551
self.analog_output_tasks = {}
552+
self.trigger_reset_count = self.configuration["configuration"][
553+
"microscopes"
554+
][microscope_name]["daq"].get("trigger_reset_count", None)
525555

526556
self.camera_delay = (
527557
float(self.waveform_constants["other_constants"].get("camera_delay", 5))
@@ -607,3 +637,29 @@ def update_analog_task(self, board_name: str) -> Union[bool, None]:
607637

608638
self.is_updating_analog_task = False
609639
self.wait_to_run_lock.release()
640+
641+
def reset(self, device_name: str = None) -> None:
642+
"""Reset the DAQ device.
643+
644+
Parameters
645+
----------
646+
device_name : str
647+
Name of the device to reset. If None, reset all devices.
648+
"""
649+
for k in list(self.analog_output_tasks.keys()):
650+
del self.analog_output_tasks[k]
651+
652+
if hasattr(self, "camera_trigger_task"):
653+
del self.camera_trigger_task
654+
if hasattr(self, "master_trigger_task"):
655+
del self.master_trigger_task
656+
gc.collect()
657+
658+
system = System.local()
659+
for device in system.devices:
660+
if device_name is None or device.name == device_name:
661+
try:
662+
device.reset_device()
663+
logger.info(f"Reset device: {device.name}")
664+
except Exception:
665+
logger.debug(f"Could not reset device: {traceback.format_exc()}")

0 commit comments

Comments
 (0)