auto-trainer-core 2.0.1.dev349__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- auto_trainer_core-2.0.1.dev349.dist-info/METADATA +19 -0
- auto_trainer_core-2.0.1.dev349.dist-info/RECORD +73 -0
- auto_trainer_core-2.0.1.dev349.dist-info/WHEEL +5 -0
- auto_trainer_core-2.0.1.dev349.dist-info/top_level.txt +1 -0
- autotrainer/core/__init__.py +319 -0
- autotrainer/core/analysis/__init__.py +6 -0
- autotrainer/core/analysis/alarm_monitor.py +484 -0
- autotrainer/core/analysis/audio_spectrum_data.py +27 -0
- autotrainer/core/analysis/audio_spectrum_monitor.py +134 -0
- autotrainer/core/analysis/auto_tunnel_fan_monitor.py +92 -0
- autotrainer/core/analysis/detector.py +179 -0
- autotrainer/core/analysis/external_doors_monitor.py +124 -0
- autotrainer/core/analysis/global_animal_presence_monitor.py +69 -0
- autotrainer/core/analysis/head_fix_measurement.py +15 -0
- autotrainer/core/analysis/headbar_pressure_monitor.py +158 -0
- autotrainer/core/analysis/load_cell_monitor.py +377 -0
- autotrainer/core/analysis/load_cell_tare_monitor.py +217 -0
- autotrainer/core/analysis/measurement_data.py +80 -0
- autotrainer/core/analysis/pellet_position_monitor.py +108 -0
- autotrainer/core/analysis/sensor_analysis.py +390 -0
- autotrainer/core/analysis/system_fault_monitor.py +81 -0
- autotrainer/core/analysis/system_maintenance_monitor.py +88 -0
- autotrainer/core/animal/__init__.py +1 -0
- autotrainer/core/animal/animal_subject.py +208 -0
- autotrainer/core/capture.py +25 -0
- autotrainer/core/configuration/__init__.py +88 -0
- autotrainer/core/configuration/alarm_configuration.py +55 -0
- autotrainer/core/configuration/animal_presence_configuration.py +17 -0
- autotrainer/core/configuration/behavior_configuration.py +323 -0
- autotrainer/core/configuration/camera_configuration.py +108 -0
- autotrainer/core/configuration/external_doors_monitor_configuration.py +9 -0
- autotrainer/core/configuration/hardware_configuration.py +30 -0
- autotrainer/core/configuration/inference_configuration.py +26 -0
- autotrainer/core/configuration/load_cell_config.py +61 -0
- autotrainer/core/configuration/persistence_configuration.py +29 -0
- autotrainer/core/configuration/presence_detection_configuration.py +9 -0
- autotrainer/core/configuration/system_configuration.py +211 -0
- autotrainer/core/configuration/system_fault_config.py +9 -0
- autotrainer/core/configuration/system_maintenance_config.py +17 -0
- autotrainer/core/diamond_triangle_config.py +150 -0
- autotrainer/core/event/__init__.py +54 -0
- autotrainer/core/event/api_event_kind.py +5 -0
- autotrainer/core/event/api_event_plugin.py +57 -0
- autotrainer/core/event/event_info.py +53 -0
- autotrainer/core/event/event_manager.py +296 -0
- autotrainer/core/event/event_manager_plugin.py +45 -0
- autotrainer/core/event/file_event_plugin.py +91 -0
- autotrainer/core/event/logger_event_plugin.py +43 -0
- autotrainer/core/fixed_array_multiqueue.py +263 -0
- autotrainer/core/fixed_array_queue.py +124 -0
- autotrainer/core/frame_index.py +34 -0
- autotrainer/core/interfaces.py +347 -0
- autotrainer/core/logging.py +714 -0
- autotrainer/core/message/__init__.py +26 -0
- autotrainer/core/message/audio_spectrum_message.py +21 -0
- autotrainer/core/message/measurement_message.py +61 -0
- autotrainer/core/message/message_handler.py +158 -0
- autotrainer/core/message/motor_configuration_message.py +128 -0
- autotrainer/core/message/system_command_kind.py +74 -0
- autotrainer/core/message/system_message_handler.py +122 -0
- autotrainer/core/message/system_status_message.py +112 -0
- autotrainer/core/multiproc.py +50 -0
- autotrainer/core/notification/__init__.py +2 -0
- autotrainer/core/notification/notification_center.py +80 -0
- autotrainer/core/notification/trigger_notification.py +27 -0
- autotrainer/core/observable_object.py +105 -0
- autotrainer/core/perf_monitor.py +77 -0
- autotrainer/core/pose_elements.py +196 -0
- autotrainer/core/project/__init__.py +19 -0
- autotrainer/core/project/project_info.py +486 -0
- autotrainer/core/queue_util.py +60 -0
- autotrainer/core/reach_event.py +38 -0
- autotrainer/core/video_detection.py +326 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
from typing import Callable, List, Protocol, Optional, TypeVar
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
|
|
5
|
+
from autotrainer.core import Offset3DTuple, ObservableObjectProtocol
|
|
6
|
+
from autotrainer.core.observable_object import EventHandler
|
|
7
|
+
from autotrainer.core.reach_event import ReachEvent
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CoverServoStatus(int, enum.Enum):
|
|
11
|
+
OK = 0
|
|
12
|
+
COVER_POSITION_ERROR = 1
|
|
13
|
+
RELEASE_POSITION_ERROR = 2
|
|
14
|
+
|
|
15
|
+
COVER_AND_RELEASE_POS_ERROR = COVER_POSITION_ERROR | RELEASE_POSITION_ERROR
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def is_error(self):
|
|
19
|
+
return self is not CoverServoStatus.OK
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RecordingEndingReason(str, enum.Enum):
|
|
23
|
+
|
|
24
|
+
NA = "NA"
|
|
25
|
+
ALGO_PAUSED = "AlgoPaused"
|
|
26
|
+
EXIT_TUNNEL = "ExitTunnel"
|
|
27
|
+
PELLET_LOADING = "PelletLoading"
|
|
28
|
+
MISSING_ANIMAL_ACTIVITY_TIMEOUT = "MissingAnimalActivityTimeout"
|
|
29
|
+
MOTOR_DRIFT_HOMING = "MotorDriftHoming"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class CaptureAnalysisResult(str, enum.Enum):
|
|
33
|
+
|
|
34
|
+
CAPTURE_ONLY = "capture_only"
|
|
35
|
+
ANALYSIS_SUCCEEDED = "analysis_succeeded"
|
|
36
|
+
ANALYSIS_FAILED = "analysis_failed"
|
|
37
|
+
ANALYSIS_DELAYED = "analysis_delayed"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class PelletHardwareProtocol(Protocol):
|
|
41
|
+
"""
|
|
42
|
+
Defines an expected/required set of commands from the pellet device that are used as part of the behavior algorithm
|
|
43
|
+
and state machine.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def delay(self, amount: float):
|
|
47
|
+
"""Request to delay that amount of seconds"""
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def last_set_position(self) -> Optional[Offset3DTuple]:
|
|
51
|
+
"""Give the last SET position (deliver position, used with SEND_PELLET command"""
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def last_position(self) -> Optional[Offset3DTuple]:
|
|
55
|
+
"""Given the last actual position"""
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def last_dcs_set_position(self) -> Optional[Offset3DTuple]:
|
|
59
|
+
"""Give the last SET position, in DCS, (deliver position), used with SEND_PELLET command"""
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def last_dcs_position(self) -> Optional[Offset3DTuple]:
|
|
63
|
+
"""Given the last actual, in DCS, triangle position"""
|
|
64
|
+
|
|
65
|
+
def set_x(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
66
|
+
"""
|
|
67
|
+
Change the X stepper location and set it as the X-axis pellet release location.
|
|
68
|
+
|
|
69
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def set_y(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
73
|
+
"""
|
|
74
|
+
Change the Y stepper location and set it as the Y-axis pellet release location.
|
|
75
|
+
|
|
76
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def set_z(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
80
|
+
"""
|
|
81
|
+
Change the Z stepper location and set it as the Z-axis pellet release location.
|
|
82
|
+
|
|
83
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def set_dcs_x(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
87
|
+
"""
|
|
88
|
+
Change the DCS-X stepper location and set it as the X-axis pellet release location.
|
|
89
|
+
|
|
90
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
def set_dcs_y(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
94
|
+
"""
|
|
95
|
+
Change the DCS-Y stepper location and set it as the Y-axis pellet release location.
|
|
96
|
+
|
|
97
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
def set_dcs_z(self, value: float, *, absolute: bool = True, sender: str = "NA") -> Optional[UUID]:
|
|
101
|
+
"""
|
|
102
|
+
Change the DCS-Z stepper location and set it as the Z-axis pellet release location.
|
|
103
|
+
|
|
104
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def move_x(self, value: float, *, absolute: bool = True) -> Optional[UUID]:
|
|
108
|
+
"""
|
|
109
|
+
Move the X stepper. This may not be supported on all device platforms.
|
|
110
|
+
|
|
111
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
def move_y(self, value: float, *, absolute: bool = True) -> Optional[UUID]:
|
|
115
|
+
"""
|
|
116
|
+
Move the Y stepper. This may not be supported on all device platforms.
|
|
117
|
+
|
|
118
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def move_z(self, value: float, *, absolute: bool = True) -> Optional[UUID]:
|
|
122
|
+
"""
|
|
123
|
+
Move the Z stepper. This may not be supported on all device platforms.
|
|
124
|
+
|
|
125
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def send_home(self) -> Optional[UUID]:
|
|
129
|
+
"""
|
|
130
|
+
Request a move to 0, 0, 0.
|
|
131
|
+
|
|
132
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
def send_retract(self) -> Optional[UUID]:
|
|
136
|
+
"""Request a move to y - 10 (relative)
|
|
137
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
def load_pellet(self) -> Optional[UUID]:
|
|
141
|
+
"""
|
|
142
|
+
Request a full load cycle to scoop the pellet from the bin.
|
|
143
|
+
|
|
144
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def send_pellet(self) -> Optional[UUID]:
|
|
148
|
+
"""
|
|
149
|
+
Request a move from the current position to the "send" location stored in the hardware.
|
|
150
|
+
|
|
151
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
def cover_pellet(self) -> Optional[UUID]:
|
|
155
|
+
"""
|
|
156
|
+
Request the barrier arm close and cover the pellet.
|
|
157
|
+
|
|
158
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
def release_pellet(self) -> Optional[UUID]:
|
|
162
|
+
"""
|
|
163
|
+
Request the barrier arm open and expose the pellet.
|
|
164
|
+
|
|
165
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def play_tone(self, frequency: int, duration: float) -> Optional[UUID]:
|
|
169
|
+
"""
|
|
170
|
+
Request the device play a tone.
|
|
171
|
+
|
|
172
|
+
:return: A token to expect from the device message handler when the request is complete.
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
def set_motors_drift(self, drift: Offset3DTuple):
|
|
176
|
+
"""Set the motor drift offset"""
|
|
177
|
+
|
|
178
|
+
def set_auto_correct_motor_drift(self, enabled: bool):
|
|
179
|
+
"""Set autocorrect motor drift"""
|
|
180
|
+
|
|
181
|
+
def set_tunnel_fan_on(self) -> Optional[UUID]:
|
|
182
|
+
"""Turn ON tunnel FAN"""
|
|
183
|
+
|
|
184
|
+
def set_tunnel_fan_off(self) -> Optional[UUID]:
|
|
185
|
+
"""Turn OFF tunnel FAN"""
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class TunnelHardwareProtocol(Protocol):
|
|
189
|
+
"""
|
|
190
|
+
Defines the expected set of commands and properties from the tunnel device that are used as part of the
|
|
191
|
+
behavior algorithm and state machine.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def head_magnet_intensity(self) -> Optional[float]:
|
|
196
|
+
"""
|
|
197
|
+
Return the current head magnet position.
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def update_head_magnet_intensity(self, position: float) -> Optional[UUID]:
|
|
201
|
+
"""
|
|
202
|
+
Request an update to the head magnet position.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
position: The % position [0, 100] to set the head magnet.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
A token to expect from the device message handler when the request is complete.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
def open_tunnel_gate(self) -> Optional[UUID]:
|
|
212
|
+
"""
|
|
213
|
+
Request the tunnel gate to open.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
A token to expect from the device message handler when the request is complete.
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
def close_tunnel_gate(self) -> Optional[UUID]:
|
|
220
|
+
"""
|
|
221
|
+
Request the tunnel gate to close.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
A token to expect from the device message handler when the request is complete.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
def tare_load_cell(self) -> Optional[UUID]:
|
|
228
|
+
"""
|
|
229
|
+
Request the load cell perform a tare operation.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
A token to expect from the device message handler when the request is complete.
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
#
|
|
236
|
+
|
|
237
|
+
class BatchAnalysisStartingEvent:
|
|
238
|
+
def __call__(self, *, batch_len: int):
|
|
239
|
+
"""When a session batch analysis starts"""
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class BatchAnalysisEndingEvent:
|
|
243
|
+
def __call__(self, *, failed_count: int):
|
|
244
|
+
"""When a session batch analysis is finished"""
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class BehaviorAlgoEvents:
|
|
248
|
+
"""Define the behavior algo events and their signature"""
|
|
249
|
+
# NB: *assigned/defined* here,
|
|
250
|
+
# but used as typehints in BehaviorAlgoProtocol below.
|
|
251
|
+
|
|
252
|
+
session_starting = EventHandler[Callable[[], None]]
|
|
253
|
+
session_capture_ending = EventHandler[Callable[[RecordingEndingReason], None]]
|
|
254
|
+
|
|
255
|
+
session_processing_starting = EventHandler[Callable[[], None]]
|
|
256
|
+
|
|
257
|
+
batch_analysis_starting = EventHandler[BatchAnalysisStartingEvent]
|
|
258
|
+
batch_analysis_ending = EventHandler[BatchAnalysisEndingEvent]
|
|
259
|
+
|
|
260
|
+
session_ending = EventHandler[Callable[[CaptureAnalysisResult], None]]
|
|
261
|
+
|
|
262
|
+
cover_servo_status_changed = EventHandler[Callable[[CoverServoStatus], None]]
|
|
263
|
+
|
|
264
|
+
# NB:
|
|
265
|
+
# these events receive as single param/arg the **increment** applied to the previous value (whatever it was):
|
|
266
|
+
pellets_presented_evt = EventHandler[Callable[[int], None]]
|
|
267
|
+
pellets_consumed_evt = EventHandler[Callable[[int], None]]
|
|
268
|
+
successful_reaches_evt = EventHandler[Callable[[int], None]]
|
|
269
|
+
total_reaches_evt = EventHandler[Callable[[int], None]]
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class BehaviorAlgorithmProtocol(ObservableObjectProtocol, Protocol):
|
|
273
|
+
|
|
274
|
+
# 1) attributes, or properties:
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def pellet_delivery_enabled(self) -> bool: ...
|
|
278
|
+
@pellet_delivery_enabled.setter
|
|
279
|
+
def pellet_delivery_enabled(self, value: bool): ...
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def pellet_cover_enabled(self) -> bool: ...
|
|
283
|
+
@pellet_cover_enabled.setter
|
|
284
|
+
def pellet_cover_enabled(self, value: bool): ...
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def intersession_pellet_shift_enabled(self) -> bool: ...
|
|
288
|
+
@intersession_pellet_shift_enabled.setter
|
|
289
|
+
def intersession_pellet_shift_enabled(self, value: bool): ...
|
|
290
|
+
|
|
291
|
+
@property
|
|
292
|
+
def pellet_hands_min_distance(self) -> float: ...
|
|
293
|
+
@pellet_hands_min_distance.setter
|
|
294
|
+
def pellet_hands_min_distance(self, value: float): ...
|
|
295
|
+
|
|
296
|
+
# autoclamp / headfix:
|
|
297
|
+
@property
|
|
298
|
+
def head_fixation_enabled(self) -> bool: ...
|
|
299
|
+
@head_fixation_enabled.setter
|
|
300
|
+
def head_fixation_enabled(self, value: bool): ...
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def auto_clamp_no_activity_release_delay(self) -> float: ...
|
|
304
|
+
@auto_clamp_no_activity_release_delay.setter
|
|
305
|
+
def auto_clamp_no_activity_release_delay(self, value: float): ...
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
def auto_clamp_release_load_count(self) -> int: ...
|
|
309
|
+
@auto_clamp_release_load_count.setter
|
|
310
|
+
def auto_clamp_release_load_count(self, value: int): ...
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def baseline_intensity(self) -> float: ...
|
|
314
|
+
@baseline_intensity.setter
|
|
315
|
+
def baseline_intensity(self, value: float): ...
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def trial_reaches(self) -> List[ReachEvent]:
|
|
319
|
+
"""The list of reaches of the previously analyzed trial"""
|
|
320
|
+
|
|
321
|
+
# 2) commands :
|
|
322
|
+
|
|
323
|
+
def reset_configuration(self) -> None:
|
|
324
|
+
"""Reset the configuration to what it was when it was first loaded"""
|
|
325
|
+
|
|
326
|
+
# 3) events:
|
|
327
|
+
|
|
328
|
+
session_starting: BehaviorAlgoEvents.session_starting
|
|
329
|
+
"""Emitted when a new trial recording starts"""
|
|
330
|
+
|
|
331
|
+
session_capture_ending: BehaviorAlgoEvents.session_capture_ending
|
|
332
|
+
"""Emitted when a new trial recording ends"""
|
|
333
|
+
|
|
334
|
+
session_ending: BehaviorAlgoEvents.session_ending
|
|
335
|
+
"""Emitted when a trial "full session" ended, this can have analysis processed or not"""
|
|
336
|
+
|
|
337
|
+
pellets_presented_evt: BehaviorAlgoEvents.pellets_presented_evt
|
|
338
|
+
"""When a pellet is "presented" ; i.e: when it's arrived at deliver/send position"""
|
|
339
|
+
|
|
340
|
+
pellets_consumed_evt: BehaviorAlgoEvents.pellets_consumed_evt
|
|
341
|
+
"""When a pellet is consumed"""
|
|
342
|
+
|
|
343
|
+
successful_reaches_evt: BehaviorAlgoEvents.successful_reaches_evt
|
|
344
|
+
"""Successful reaches"""
|
|
345
|
+
|
|
346
|
+
total_reaches_evt: BehaviorAlgoEvents.total_reaches_evt
|
|
347
|
+
"""Total reaches"""
|