File size: 2,385 Bytes
999c5c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
DeepLabCut Toolbox (deeplabcut.org)
© A. & M. Mathis Labs

Licensed under GNU Lesser General Public License v3.0
"""


from dlclive.processor.processor import Processor
import serial
import struct
import pickle
import time


class TeensyLaser(Processor):
    def __init__(
        self, com, baudrate=115200, pulse_freq=50, pulse_width=5, max_stim_dur=0
    ):

        super().__init__()
        self.ser = serial.Serial(com, baudrate)
        self.pulse_freq = pulse_freq
        self.pulse_width = pulse_width
        self.max_stim_dur = (
            max_stim_dur if (max_stim_dur >= 0) and (max_stim_dur < 65356) else 0
        )
        self.stim_on = False
        self.stim_on_time = []
        self.stim_off_time = []

    def close_serial(self):

        self.ser.close()

    def turn_stim_on(self):

        # command to activate PWM signal to laser is the letter 'O' followed by three 16 bit integers -- pulse frequency, pulse width, and max stim duration
        if not self.stim_on:
            self.ser.write(
                b"O"
                + struct.pack(
                    "HHH", self.pulse_freq, self.pulse_width, self.max_stim_dur
                )
            )
            self.stim_on = True
            self.stim_on_time.append(time.time())

    def turn_stim_off(self):

        # command to turn off PWM signal to laser is the letter 'X'
        if self.stim_on:
            self.ser.write(b"X")
            self.stim_on = False
            self.stim_off_time.append(time.time())

    def process(self, pose, **kwargs):

        # define criteria to stimulate (e.g. if first point is in a corner of the video)
        box = [[0, 100], [0, 100]]
        if (
            (pose[0][0] > box[0][0])
            and (pose[0][0] < box[0][1])
            and (pose[0][1] > box[1][0])
            and (pose[0][1] < box[1][1])
        ):
            self.turn_stim_on()
        else:
            self.turn_stim_off()

        return pose

    def save(self, file=None):

        ### save stim on and stim off times
        save_code = 0
        if file:
            try:
                pickle.dump(
                    {"stim_on": self.stim_on_time, "stim_off": self.stim_off_time},
                    open(file, "wb"),
                )
                save_code = 1
            except Exception:
                save_code = -1
        return save_code