1212from experiments .base .stimulus_process import Timer
1313from experiments .utils .exp_setup import get_experiment_settings , setup_trigger , setup_process
1414from utils .plotter import plot_triggers_response
15+ import random
1516
1617
1718class BaseExperiment :
@@ -138,7 +139,6 @@ def check_skeleton(self, frame, skeleton):
138139 self ._trial_timers [trial ].start ()
139140
140141 self ._process .put (self ._current_trial )
141- return result , response
142142
143143 @property
144144 def _trials (self ):
@@ -184,6 +184,120 @@ def get_trial(self):
184184 return self ._current_trial
185185
186186
187+ class BaseTrialExperiment (BaseExperiment ):
188+ def __init__ (self ):
189+ super ().__init__ ()
190+ self ._name = 'BaseTrialExperiment'
191+ self .experiment_finished = False
192+ self ._event = None
193+ self ._print_check = False
194+ self ._current_trial = None
195+ self ._result_list = []
196+ self ._success_count = 0
197+
198+ self ._parameter_dict = dict (TRIGGER = 'str' ,
199+ PROCESS = 'str' ,
200+ INTERTRIAL_TIME = 'int' ,
201+ TRIAL_TRIGGER = 'str' ,
202+ TRIAL_TIME = 'int' ,
203+ STIMULUS_TIME = 'int' ,
204+ RESULT_FUNC = 'str' ,
205+ EXP_LENGTH = 'int' ,
206+ EXP_COMPLETION = 'int' ,
207+ EXP_TIME = 'int' )
208+
209+ self ._settings_dict = get_experiment_settings (self ._name , self ._parameter_dict )
210+ self ._process = setup_process (self ._settings_dict ['PROCESS' ])
211+ self ._init_trigger = setup_trigger (self ._settings_dict ['TRIGGER' ])
212+ self ._trials_list = self .generate_trials_list (self ._trials , self ._settings_dict ['EXP_LENGTH' ])
213+ self ._trial_timer = Timer (self ._settings_dict ['TRIAL_TIME' ])
214+ self ._exp_timer = Timer (self ._settings_dict ['EXP_TIME' ])
215+ self ._intertrial_timer = Timer (self ._settings_dict ['INTERTRIAL_TIME' ])
216+
217+
218+
219+ def check_skeleton (self , frame , skeleton ):
220+ status , trial = self ._process .get_status ()
221+ if status :
222+ current_trial = self ._trials [trial ]
223+ condition , response = current_trial ['trigger' ].check_skeleton (skeleton )
224+ self ._process .pass_condition (condition )
225+ result = self ._process .get_result ()
226+ if result is not None :
227+ self .process_result (result , trial )
228+ self ._current_trial = None
229+ # check if all trials were successful until completion
230+ if self ._success_count >= self ._settings_dict ['EXP_COMPLETION' ]:
231+ print ("Experiment is finished" )
232+ print ("Trial reached required amount of successes" )
233+ self .stop_experiment ()
234+
235+ # if not continue
236+ print (' Going into Intertrial time.' )
237+ self ._intertrial_timer .reset ()
238+ self ._intertrial_timer .start ()
239+ result = None
240+ plot_triggers_response (frame , response )
241+
242+ elif not self ._intertrial_timer .check_timer ():
243+ if self ._current_trial is None :
244+ self ._current_trial = next (self ._trials_list ,False )
245+ elif not self ._current_trial :
246+ print ("Experiment is finished due to max. trial repetition." )
247+ print (self ._result_list )
248+ self .stop_experiment ()
249+ else :
250+ init_result , response_body = self ._init_trigger .check_skeleton (skeleton )
251+ if init_result :
252+ # check trial start triggers
253+ self ._process .set_trial (self ._current_trial )
254+ self ._print_check = False
255+ elif not self ._print_check :
256+ print ('Next trial: #' + str (len (self ._result_list ) + 1 ) + ' ' + self ._current_trial )
257+ print ('Animal is not meeting trial start criteria, the start of trial is delayed.' )
258+ self ._print_check = True
259+ # if experimental time ran out, finish experiments
260+ super ().check_exp_timer ()
261+
262+ def process_result (self , result , trial ):
263+ """
264+ Will add result if TRUE or reset comp_counter if FALSE
265+ :param result: bool if trial was successful
266+ :param trial: str name of the trial
267+ :return:
268+ """
269+ self ._result_list .append ((trial , result ))
270+ if result is True :
271+ self ._success_count += 1
272+ print ('Trial successful!' )
273+ else :
274+ print ('Trial failed.' )
275+ #
276+
277+ @staticmethod
278+ def generate_trials_list (trials : dict , length : int ):
279+ trials_list = []
280+ for trial in range (length ):
281+ trials_list .append (random .choice (list (trials .keys ())))
282+ return iter (trials_list )
283+
284+ @property
285+ def _trials (self ):
286+
287+ trigger = setup_trigger (self ._settings_dict ['TRIAL_TRIGGER' ])
288+ if self ._settings_dict ['RESULT_FUNC' ] == 'all' :
289+ result_func = all
290+ elif self ._settings_dict ['RESULT_FUNC' ] == 'any' :
291+ result_func = any
292+ else :
293+ raise ValueError (f'Result function can only be "all" or "any", not { self ._settings_dict ["RESULT_FUNC" ]} .' )
294+ trials = {'Trial' : dict (stimulus_timer = Timer (self ._settings_dict ['STIMULUS_TIME' ]),
295+ success_timer = Timer (self ._settings_dict ['TRIAL_TIME' ]),
296+ trigger = trigger ,
297+ result_func = result_func )}
298+
299+ return trials
300+
187301
188302class BaseConditionalExperiment (BaseExperiment ):
189303 """
@@ -208,6 +322,7 @@ def __init__(self):
208322 self ._current_trial = None
209323
210324 self ._exp_timer = Timer (self ._settings_dict ['EXP_TIME' ])
325+ self ._intertrial_timer = Timer (self ._settings_dict ['INTERTRIAL_TIME' ])
211326
212327 self ._trigger = setup_trigger (self ._settings_dict ['TRIGGER' ])
213328
@@ -225,16 +340,17 @@ def check_skeleton(self, frame, skeleton):
225340 self .stop_experiment ()
226341
227342 elif not self .experiment_finished :
343+ if not self ._intertrial_timer .check_timer ():
344+ # check if condition is met
345+ result , response = self ._trigger .check_skeleton (skeleton = skeleton )
346+ if result :
347+ self ._event_count += 1
348+ print ('Stimulation #{self._event_count}' .format ())
349+ self ._intertrial_timer .reset ()
350+ self ._intertrial_timer .start ()
228351
229- # check if condition is met
230- result , response = self ._trigger .check_skeleton (skeleton = skeleton )
231- plot_triggers_response (frame , response )
232- if result :
233- self ._event_count += 1
234- print ('Stimulation #{self._event_count}' .format ())
235-
236- self ._process .put (result )
237- return result , response
352+ plot_triggers_response (frame , response )
353+ self ._process .put (result )
238354
239355 def check_exp_timer (self ):
240356 """
@@ -269,12 +385,9 @@ def get_trial(self):
269385 return self ._current_trial
270386
271387
272-
273-
274-
275-
276388"""Standardexperiments that can be setup by using the experiment config"""
277389
390+
278391class BaseOptogeneticExperiment (BaseExperiment ):
279392 """Standard implementation of an optogenetic experiment"""
280393
0 commit comments