Skip to content

Commit cfbcd2e

Browse files
committed
inital commit for classifications
1 parent 629e201 commit cfbcd2e

File tree

8 files changed

+1316
-12
lines changed

8 files changed

+1316
-12
lines changed

experiments/custom/classifier.py

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.

experiments/custom/experiments.py

Lines changed: 219 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,228 @@
1111
from functools import partial
1212
from collections import Counter
1313
from experiments.custom.stimulus_process import ClassicProtocolProcess, SimpleProtocolProcess,Timer, ExampleProtocolProcess
14-
from experiments.custom.triggers import ScreenTrigger, RegionTrigger, OutsideTrigger, DirectionTrigger, SpeedTrigger
14+
from experiments.custom.triggers import ScreenTrigger, RegionTrigger, OutsideTrigger, DirectionTrigger, SpeedTrigger,\
15+
SimbaThresholdBehaviorPoolTrigger, BsoidClassBehaviorTriggerPool
1516
from utils.plotter import plot_triggers_response
1617
from utils.analysis import angle_between_vectors
1718
from experiments.custom.stimulation import show_visual_stim_img,laser_switch
19+
from experiments.custom.classifier import SimbaClassifier_Process, SimbaProcessPool, BsoidProcessPool
20+
21+
22+
from utils.configloader import THRESHOLD, POOL_SIZE
23+
24+
""" experimental classification experiment using Simba trained classifiers in a pool"""
25+
class SimbaBehaviorExperimentPool:
26+
"""
27+
Test experiment for Simba classification
28+
Simple class to contain all of the experiment properties and includes classification
29+
Uses multiprocess to ensure the best possible performance and
30+
to showcase that it is possible to work with any type of equipment, even timer-dependant
31+
"""
32+
33+
def __init__(self):
34+
"""Classifier process and initiation of behavior trigger"""
35+
self.experiment_finished = False
36+
self._process_pool = SimbaProcessPool(POOL_SIZE)
37+
#pass classifier to trigger, so that check_skeleton is the only function that passes skeleton
38+
#initiate in experiment, so that process can be started with start_experiment
39+
self._behaviortrigger = SimbaThresholdBehaviorPoolTrigger(prob_threshold= THRESHOLD,
40+
class_process_pool = self._process_pool)
41+
self._event = None
42+
#is not fully utilized in this experiment but is usefull to keep for further adaptation
43+
self._current_trial = None
44+
self._trial_count = {trial: 0 for trial in self._trials}
45+
self._trial_timers = {trial: Timer(10) for trial in self._trials}
46+
self._exp_timer = Timer(600)
47+
48+
def check_skeleton(self, frame, skeleton):
49+
"""
50+
Checking each passed animal skeleton for a pre-defined set of conditions
51+
Outputting the visual representation, if exist
52+
Advancing trials according to inherent logic of an experiment
53+
:param frame: frame, on which animal skeleton was found
54+
:param skeleton: skeleton, consisting of multiple joints of an animal
55+
"""
56+
self.check_exp_timer() # checking if experiment is still on
57+
for trial in self._trial_count:
58+
# checking if any trial hit a predefined cap
59+
if self._trial_count[trial] >= 10:
60+
self.stop_experiment()
61+
62+
if not self.experiment_finished:
63+
for trial in self._trials:
64+
# check for all trials if condition is met
65+
#this passes the skeleton to the trigger, where the feature extraction is done and the extracted features
66+
#are passed to the classifier process
67+
result, response = self._trials[trial]['trigger'](skeleton, target_prob = self._trials[trial]['target_prob'])
68+
plot_triggers_response(frame, response)
69+
#if the trigger is reporting back that the behavior is found: do something
70+
#currently nothing is done, expect counting the occurances
71+
if result:
72+
if self._current_trial is None:
73+
if not self._trial_timers[trial].check_timer():
74+
self._current_trial = trial
75+
self._trial_timers[trial].reset()
76+
self._trial_count[trial] += 1
77+
print(trial, self._trial_count[trial])
78+
else:
79+
if self._current_trial == trial:
80+
self._current_trial = None
81+
self._trial_timers[trial].start()
82+
@property
83+
def _trials(self):
84+
"""
85+
Defining the trials
86+
"""
87+
trials = {'SimBA1': dict(trigger=self._behaviortrigger.check_skeleton,
88+
target_prob = None,
89+
count=0)}
90+
return trials
91+
92+
def check_exp_timer(self):
93+
"""
94+
Checking the experiment timer
95+
"""
96+
if not self._exp_timer.check_timer():
97+
print("Experiment is finished")
98+
print("Time ran out.")
99+
self.stop_experiment()
100+
101+
def start_experiment(self):
102+
"""
103+
Start the experiment
104+
"""
105+
self._process_pool.start()
106+
if not self.experiment_finished:
107+
self._exp_timer.start()
108+
109+
def stop_experiment(self):
110+
"""
111+
Stop the experiment and reset the timer
112+
"""
113+
self.experiment_finished = True
114+
self._process_pool.end()
115+
print('Experiment completed!')
116+
self._exp_timer.reset()
117+
118+
def get_trial(self):
119+
"""
120+
Check which trial is going on right now
121+
"""
122+
return self._event
123+
124+
def get_info(self):
125+
""" returns optional info"""
126+
info = self._behaviortrigger.get_last_prob()
127+
return info
128+
129+
130+
131+
""" experimental classification experiment using BSOID trained classifiers in a pool"""
132+
133+
class BsoidBehaviorExperimentPool:
134+
"""
135+
Test experiment for Simba classification
136+
Simple class to contain all of the experiment properties and includes classification
137+
Uses multiprocess to ensure the best possible performance and
138+
to showcase that it is possible to work with any type of equipment, even timer-dependant
139+
"""
140+
141+
def __init__(self):
142+
"""Classifier process and initiation of behavior trigger"""
143+
self.experiment_finished = False
144+
self._process_pool = BsoidProcessPool(POOL_SIZE)
145+
#pass classifier to trigger, so that check_skeleton is the only function that passes skeleton
146+
#initiate in experiment, so that process can be started with start_experiment
147+
self._behaviortrigger = BsoidClassBehaviorTriggerPool(target_class= THRESHOLD,
148+
class_process_pool = self._process_pool)
149+
self._event = None
150+
#is not fully utilized in this experiment but is usefull to keep for further adaptation
151+
self._current_trial = None
152+
self._trial_count = {trial: 0 for trial in self._trials}
153+
self._trial_timers = {trial: Timer(10) for trial in self._trials}
154+
self._exp_timer = Timer(600)
155+
156+
def check_skeleton(self, frame, skeleton):
157+
"""
158+
Checking each passed animal skeleton for a pre-defined set of conditions
159+
Outputting the visual representation, if exist
160+
Advancing trials according to inherent logic of an experiment
161+
:param frame: frame, on which animal skeleton was found
162+
:param skeleton: skeleton, consisting of multiple joints of an animal
163+
"""
164+
self.check_exp_timer() # checking if experiment is still on
165+
for trial in self._trial_count:
166+
# checking if any trial hit a predefined cap
167+
if self._trial_count[trial] >= 10:
168+
self.stop_experiment()
169+
170+
if not self.experiment_finished:
171+
for trial in self._trials:
172+
# check for all trials if condition is met
173+
#this passes the skeleton to the trigger, where the feature extraction is done and the extracted features
174+
#are passed to the classifier process
175+
result, response = self._trials[trial]['trigger'](skeleton, target_class = self._trials[trial]['target_class'])
176+
plot_triggers_response(frame, response)
177+
#if the trigger is reporting back that the behavior is found: do something
178+
#currently nothing is done, expect counting the occurances
179+
if result:
180+
if self._current_trial is None:
181+
if not self._trial_timers[trial].check_timer():
182+
self._current_trial = trial
183+
self._trial_timers[trial].reset()
184+
self._trial_count[trial] += 1
185+
print(trial, self._trial_count[trial])
186+
else:
187+
if self._current_trial == trial:
188+
self._current_trial = None
189+
self._trial_timers[trial].start()
190+
@property
191+
def _trials(self):
192+
"""
193+
Defining the trials
194+
"""
195+
trials = {'BSOID1': dict(trigger=self._behaviortrigger.check_skeleton,
196+
target_class = None,
197+
count=0)}
198+
return trials
199+
200+
def check_exp_timer(self):
201+
"""
202+
Checking the experiment timer
203+
"""
204+
if not self._exp_timer.check_timer():
205+
print("Experiment is finished")
206+
print("Time ran out.")
207+
self.stop_experiment()
208+
209+
def start_experiment(self):
210+
"""
211+
Start the experiment
212+
"""
213+
self._process_pool.start()
214+
if not self.experiment_finished:
215+
self._exp_timer.start()
216+
217+
def stop_experiment(self):
218+
"""
219+
Stop the experiment and reset the timer
220+
"""
221+
self.experiment_finished = True
222+
self._process_pool.end()
223+
print('Experiment completed!')
224+
self._exp_timer.reset()
225+
226+
def get_trial(self):
227+
"""
228+
Check which trial is going on right now
229+
"""
230+
return self._event
231+
232+
def get_info(self):
233+
""" returns optional info"""
234+
info = self._behaviortrigger.get_last_prob()
235+
return info
18236

19237

20238
class ExampleExperiment:

0 commit comments

Comments
 (0)