def present_temporal_stream(self, temporal_stream): duration_cd = CountDown(ITEM_DURATION, start=False) mask_cd = CountDown(MASK_DURATION, start=False) response_window = CountDown(2, start=False) last_item = True if len(temporal_stream) == 1 else False item = temporal_stream.pop() if item[1]: self.target_onset = self.target_sw.elapsed() duration_cd.start() while duration_cd.counting(): self.blit_img(item[0], reg=5, loc=P.screen_c) mask_cd.start() while mask_cd.counting(): self.blit_img(self.mask, reg=5, loc=P.screen_c) if last_item: clear() response_window.start() while response_window.counting(): fill() flip()
def feedback(self, response): if self.winning_bandit == HIGH: winning_bandit_loc = self.high_value_location else: winning_bandit_loc = self.low_value_location if response == winning_bandit_loc: points = self.bandit_payout(value=self.winning_bandit) msg = message("You won {0} points!".format(points), "score up", blit_txt=False) else: points = self.penalty # -5 msg = message("You lost 5 points!", "score down", blit_txt=False) self.total_score += points feedback = [points, msg] feedback_exposure = CountDown(self.feedback_exposure_period) while feedback_exposure.counting(): ui_request() fill() blit(feedback[1], location=P.screen_c, registration=5) flip() return feedback[0]
def trial(self): # Clear screen and wait for target onset fill() flip() while self.evm.before('target_on'): ui_request() # Start timer and collect response self.rc.collect() response = self.rc.keypress_listener.response() # Stop timer and show for 1sec after response is made elapsed_msg = message(str(int(response.rt)).zfill(4), style='PVT', blit_txt=False) feedback_timer = CountDown(1) while feedback_timer.counting(): fill() blit(elapsed_msg, 5, P.screen_c) flip() # Log trial data to database return { "block_num": P.block_number, "trial_num": P.trial_number, "isi": self.interstim_interval, "rt": response.rt }
def feedback(self, response): correct_response = True if response == self.tilt_line_location else False # Every 5 trials of a particular payoff, ask anticipated earnings if self.potential_payoff == HIGH: self.high_value_trial_count += 1 if self.high_value_trial_count in [5, 10, 15]: self.query_learning(HIGH) else: self.low_value_trial_count += 1 if self.low_value_trial_count in [5, 10, 15]: self.query_learning(LOW) # Determine payout for trial if correct_response & (self.winning_trial == YES): points = self.payout() msg = message("You won {0} points!".format(points), 'myText', blit_txt=False) else: points = self.penalty msg = message("You lost 5 points!", 'myText', blit_txt=False) # Keep tally of score self.total_score += points feedback = [points, msg] # Present score feedback_exposure = CountDown(self.feedback_exposure_period) fill() blit(feedback[1], location=P.screen_c, registration=5) flip() while feedback_exposure.counting(): ui_request() return feedback[0]
def block(self): # Show block message at start of every block header = "Block {0} of {1}".format(P.block_number, P.blocks_per_experiment) if P.practicing: header = "This is a practice block. ({0})".format(header) practice_msg = "During this block you will be given feedback for your responses." msg = message(header + "\n" + practice_msg, align="center", blit_txt=False) else: msg = message(header, blit_txt=False) message_interval = CountDown(1) while message_interval.counting(): ui_request() # Allow quitting during loop fill() blit(msg, 8, (P.screen_c[0], P.screen_y * 0.4)) flip() flush() start_msg = message("Press any key to start.", blit_txt=False) fill() blit(msg, 8, (P.screen_c[0], P.screen_y * 0.4)) blit(start_msg, 5, [P.screen_c[0], P.screen_y * 0.6]) flip() any_key()
def present_feedback(self): msg = "Incorrect!" self.blit_msg(msg, 'left') feedback_cd = CountDown(0.5) while feedback_cd.counting(): ui_request()
def present_stream(self): duration_cd = CountDown(self.item_duration) isi_cd = CountDown(self.isi) item = self.rsvp_stream.pop() fill() blit(item[0], registration=5, location=P.screen_c) flip() duration_cd.reset() while duration_cd.counting(): pass fill() if item[1]: self.temporal_presentation_times.append([self.evm.trial_time_ms, item[2]]) isi_cd.reset() while isi_cd.counting(): pass
def present_feedback(self): fill() message("Incorrect!", location=P.screen_c, registration=5, blit_txt=True) flip() feedback_period_cd = CountDown(0.5) # seconds while feedback_period_cd.counting(): ui_request()
def present_stream(self): duration_cd = CountDown(self.item_duration, start=False) isi_cd = CountDown(self.isi, start=False) item = self.rsvp_stream.pop() fill() blit(item[0], registration=5, location=P.screen_c) flip() duration_cd.start() while duration_cd.counting(): pass fill() if item[1]: self.target_onset = self.target_sw.elapsed() isi_cd.start() while isi_cd.counting(): pass
def get_ambient_level(self, period=1): """Determines the average ambient noise level from the input stream over a given period. Gives a 3-second countdown before starting to help the user ensure they are quiet. Args: period (numeric, optional): The number of seconds to record input for. Defaults to one second. Returns: int: The average of the peaks of all samples recorded during the period. """ warn_msg = ( "Please remain quiet while the ambient noise level is sampled. " "Sampling will begin in {0} second{1}.") peaks = [] wait_period = CountDown(3) while wait_period.counting(): ui_request() fill() remaining = int(math.ceil(wait_period.remaining())) s = "" if remaining == 1 else "s" # to avoid "1 seconds" message(warn_msg.format(remaining, s), location=P.screen_c, registration=5) flip() self.stream.start() fill() flip() sample_period = CountDown(period) while sample_period.counting(): ui_request() peaks.append(self.stream.sample().peak) self.stream.stop() return sum(peaks) / float(len(peaks))
def get_peak_during(self, period, msg=None): """Determines the peak loudness value recorded over a given period. Displays a visual callback that shows the current input volume and the loudest peak encounteredduring the interval so far. Args: period (numeric): the number of seconds to record input for. msg (:obj:`~klibs.KLGraphics.KLNumpySurface.NumpySurface`, optional): a rendered message to display in the top-right corner of the screen during the sampling loop. Returns: int: the loudest peak of all samples recorded during the period. """ local_peak = 0 last_sample = 0 if msg: msg = message(msg, blit_txt=False) flush() self.stream.start() sample_period = CountDown(period + 0.05) while sample_period.counting(): ui_request() sample = self.stream.sample().peak if sample_period.elapsed() < 0.05: # Sometimes 1st or 2nd peaks are extremely high for no reason, so ignore first 50ms continue if sample > local_peak: local_peak = sample sample_avg = (sample + last_sample) / 2 peak_circle = peak(5, int( (local_peak / 32767.0) * P.screen_y * 0.8)) sample_circle = peak( 5, int((sample_avg / 32767.0) * P.screen_y * 0.8)) last_sample = sample fill() blit(Ellipse(peak_circle, fill=[255, 145, 0]), location=P.screen_c, registration=5) blit(Ellipse(sample_circle, fill=[84, 60, 182]), location=P.screen_c, registration=5) if msg: blit(msg, location=[25, 25], registration=7) flip() self.stream.stop() return local_peak
def block(self): # Determine probe bias for block and generate list of probe locs accordingly if P.block_number > 3: self.probe_bias = "left" nonbiased_loc = "right" else: self.probe_bias = "right" nonbiased_loc = "left" loc_list = [self.probe_bias]*4 + [nonbiased_loc] self.probe_locs = loc_list * int(P.trials_per_block/float(len(loc_list))+1) random.shuffle(self.probe_locs) # At the start of each block, display a start message (block progress if experimental block, # practice message if practice block). After 3000ms, keypress will start first trial. probe_msg = ( "During this block, the colour target will appear more often on the " "{0} and less often on the {1}.".format(self.probe_bias, nonbiased_loc) ) header = "Block {0} of {1}".format(P.block_number, P.blocks_per_experiment) if P.practicing: header = "This is a practice block. ({0})".format(header) if P.block_number > 1: msg = message(header+"\n"+probe_msg, align="center", blit_txt=False) else: msg = message(header, blit_txt=False) message_interval = CountDown(1) while message_interval.counting(): ui_request() # Allow quitting during loop fill() blit(msg, 8, (P.screen_c[0], P.screen_y*0.4)) flip() flush() fill() blit(msg, 8, (P.screen_c[0], P.screen_y*0.4)) message("Press any key to start.", registration=5, location=[P.screen_c[0], P.screen_y*0.6]) flip() any_key() # When running participants, send halfway point and last-block notifications to researcher via Slack if not P.development_mode: if P.block_number == 3: # If participant is halfway done slack_message("Halfway done ({0}/{1})".format(P.block_number, P.blocks_per_experiment))
def present_stream(self): # Each stream item presented for a pre-specified duration cd = CountDown(self.item_duration) sw = Stopwatch() for item in self.rsvp_stream: cd.reset() sw.reset() fill() blit(item, registration=5, location=P.screen_c) flip() #print(cd.elapsed) while cd.counting(): ui_request() print(sw.elapsed()) sw.reset()
def block(self): # Generate font sizes to use for numbers during the block self.num_sizes = [] while len(self.num_sizes) <= P.trials_per_block: self.num_sizes = self.num_sizes + self.sizes random.shuffle(self.num_sizes) self.num_sizes = self.num_sizes[0:P.trials_per_block] # Generate block message header = "" #"Block {0} of {1}".format(P.block_number, P.blocks_per_experiment) instructions = ( "Please press the space key quickly when a digit other than {0} \nappears on screen, " "and withhold your response when the digit is {0}.".format( P.target)) if P.practicing: header = "This is a practice block." instructions = instructions + "\nYou will be given feedback on your accuracy." msg = message(header + "\n\n" + instructions, 'normal', align="center", blit_txt=False) start_msg = message("Press the [space] key to start.", 'normal', blit_txt=False) # Show block message, and wait for input before staring block if P.block_number in [1, self.first_nonpractice]: message_interval = CountDown(2) while message_interval.counting(): ui_request() # Allow quitting during loop fill() blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15))) flip() while True: if key_pressed(' '): break fill() blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15))) blit(start_msg, 5, (P.screen_c[0], int(P.screen_y * 0.75))) flip()
def trial(self): """ trial_factors: 1 = mask_type, 2 = target_level, 3 = mask_size, 4 = target_shape] """ if P.development_mode: print(self.mask_type, self.target_level, self.mask_size, self.target_shape) self.rc.collect() resp = self.rc.keypress_listener.response() if P.development_mode: print(resp) # handle timeouts if resp.rt == TIMEOUT: feedback = CountDown(1) msg = message("Too slow!", "alert", blit_txt=False) while feedback.counting(): ui_request() fill() blit(msg, 5, P.screen_c) flip() clear() # create readable data as fixation is currrently in (x,y) coordinates if self.fixation == self.fixation_top: initial_fixation = "TOP" elif self.fixation == self.fixation_central: initial_fixation = "CENTRAL" else: initial_fixation = "BOTTOM" return {"practicing": P.practicing, "response": resp.value, "rt": float(resp.rt), "mask_type": self.mask_type, "mask_size": self.mask_size, "local": self.target_shape if self.target_level == LOCAL else "D", "global": self.target_shape if self.target_level == GLOBAL else "D", "d_orientation": self.orientation, "trial_num": P.trial_number, "block_num": P.block_number, "initial_fixation": initial_fixation}
def feedback(self, response): # Keep count of bandit choices if response == self.high_value_location: self.bandit_selected = HIGH self.times_selected_high = self.times_selected_high + 1 # Occasionally probe participant learning if self.times_selected_high in [5, 10, 15]: self.query_learning(HIGH) else: self.bandit_selected = LOW self.time_selected_low = self.time_selected_low + 1 if self.time_selected_low in [5, 10, 15]: self.query_learning(LOW) # Determine payout if self.winning_trial == YES: points = self.bandit_payout(value=self.bandit_selected) msg = message("You won {0} points!".format(points), "payout", blit_txt=False) else: points = self.penalty # -5 msg = message("You lost 5 points!", "payout", blit_txt=False) # Running point total self.total_score += points feedback = [points, msg] # Present payout feedback_exposure = CountDown(self.feedback_exposure_period) while feedback_exposure.counting(): ui_request() fill() blit(feedback[1], location=P.screen_c, registration=5) flip() return feedback[0]
def warm_up(self): warmup_timer = CountDown(600, start=True) self.first_signal_played = False self.second_signal_played = False self.third_signal_played = False self.fourth_signal_played = False while warmup_timer.counting(): if key_pressed(sdl2.SDLK_DELETE): break t = warmup_timer.elapsed() if t < 60: tool = 'pencil' elif 60 <= t < 120: if not self.first_signal_played: self.warning_signal.play() self.first_signal_played = True tool = 'charcoal' elif 120 <= t < 180: if not self.second_signal_played: self.warning_signal.play() self.second_signal_played = True tool = 'smudger' elif 180 <= t < 240: if not self.third_signal_played: self.warning_signal.play() self.third_signal_played = True tool = 'eraser' else: if not self.fourth_signal_played: self.warning_signal.play() self.fourth_signal_played = True tool = 'any' fill() blit(self.images['warmup.png'], 5, P.screen_c) blit(self.warmup_txt[tool], 1, (30, P.screen_y-30)) flip()
def __validate(self): instruction = ( "Okay, threshold set! " "To ensure its validity, please provide one (and only one) more response." ) fill() message(instruction, location=P.screen_c, registration=5) flip() self.stream.start() validate_counter = CountDown(5) while validate_counter.counting(): ui_request() if self.stream.sample().peak >= self.threshold: validate_counter.finish() self.threshold_valid = True self.stream.stop() if self.threshold_valid: validation_msg = "Great, validation was successful! Press any key to continue." else: validation_msg = ( "Validation wasn't successful. " "Type C to re-calibrate or V to try validation again.") fill() message(validation_msg, location=P.screen_c, registration=5) flip() selection_made = False while not selection_made: q = pump(True) if self.threshold_valid: if key_pressed(queue=q): return else: if key_pressed(SDLK_c, queue=q): self.calibrate() elif key_pressed(SDLK_v, queue=q): self.__validate()
def instructions(self): p1 = ( "During this task, you will presented with a sequence of numbers in the middle of " "the screen.\n\nPress any key to see an example.") p2 = ( "Your task will be to press the [space] key as quickly as possible whenever a " "number other than {0} appears, and to withhold your response whenever the number " "is {0}.\n\nPress any key to continue.".format(P.target)) p3 = ( "Occasionally, the task will be interrupted by screens asking you about your " "focus just prior.\nWhen this happens, please select the most accurate " "response using the mouse cursor.\n\nPress any key to see an example." ) p4 = ( "After responding, you will be asked how much effort you " "were putting into staying focused on the task before the interruption.\n\n" "When this happens, please answer using the scale from 0% to 100% that will appear " "on screen. Your responses will be anonymous so please answer honestly.\n\n" "Press any key to see an example.") msg1 = message(p1, 'normal', blit_txt=False, align='center') msg2 = message(p2, 'normal', blit_txt=False, align='center', wrap_width=int(P.screen_x * 0.8)) msg3 = message(p3, 'normal', blit_txt=False, align='center', wrap_width=int(P.screen_x * 0.8)) msg4 = message(p4, 'normal', blit_txt=False, align='center', wrap_width=int(P.screen_x * 0.8)) # First page of instructions flush() fill() blit(msg1, 5, P.screen_c) flip() any_key(allow_mouse_click=False) # Example stimuli numlist = [1, 2, 3, 4, 5, 6, 7, 8, 9] random.shuffle(numlist) for n in numlist[1:5]: trialtime = CountDown(1.125) numsize = random.choice(self.sizes) while trialtime.counting(): ui_request() fill() mask_on = trialtime.elapsed() > 0.25 if mask_on: blit(self.mask_x, 5, P.screen_c) blit(self.mask_ring, 5, P.screen_c) else: blit(self.digits[n][numsize], 5, P.screen_c) flip() # Task explanation/illustration flush() fill() blit(msg2, 5, P.screen_c) flip() any_key(allow_mouse_click=False) # Probe explanation + example probe fill() blit(msg3, 5, P.screen_c) flip() any_key(allow_mouse_click=False) self.probe.collect() # Slider explanation + example slider fill() blit(msg4, 5, P.screen_c) flip() any_key(allow_mouse_click=False) self.get_effort()
def trial(self): fill() blit(self.digits[self.number][self.num_size], 5, P.screen_c) flip() self.rc.collect() response = self.rc.keypress_listener.response() if response.rt == klibs.TIMEOUT: resp, rt = ['nogo', 'NA'] else: resp, rt = response correct_resp = 'nogo' if self.number == P.target else 'go' accuracy = resp == correct_resp while self.evm.before('trial_end'): ui_request() fill() blit(self.mask_x, 5, P.screen_c) blit(self.mask_ring, 5, P.screen_c) flip() if P.practicing: if accuracy == False: feedback = "Incorrect! " if correct_resp == 'nogo': feedback += "Please withhold responses to the digit {0}.".format( P.target) else: feedback += "Please respond quickly to digits other than {0}.".format( P.target) else: feedback = "Correct response!" feedback_msg = message(feedback, 'normal', blit_txt=False) feedback_timer = CountDown(1.5) while feedback_timer.counting(): ui_request() fill() blit(feedback_msg, 5, P.screen_c) flip() # If probe trial, present MW probe and wait for response + keypress before ending trial if self.probe_trial: probe_resp, probe_rt = self.probe.collect() eff_level, eff_rt = self.get_effort() probe_rt = probe_rt * 1000 # convert seconds to ms eff_rt = eff_rt * 1000 # convert seconds to ms eff_level = eff_level * 100 # scale range to 0% - 100% resume_msg = message("Press the [space] key to resume the task.", 'title', blit_txt=False) while True: if key_pressed(' '): break fill() blit(resume_msg, 5, P.screen_c) flip() else: probe_resp, probe_rt, eff_level, eff_rt = ('NA', 'NA', 'NA', 'NA') return { "practicing": P.practicing, "block_num": P.block_number, "trial_num": P.trial_number, "digit": self.number, "digit_size": self.num_size, "target_digit": P.target, "response": resp, "rt": rt, "accuracy": accuracy, "probe_resp": probe_resp, "probe_rt": probe_rt, "effort_level": eff_level, "effort_rt": eff_rt }
def block(self): halfway_block = (P.blocks_per_experiment / 2) + 1 if P.run_practice_blocks and P.session_number == 1: halfway_block += 3 if P.run_practice_blocks and P.session_number == 1 and P.block_number <= 3: txt = "This is a practice block ({0} of 3)\n\n".format( P.block_number) if P.block_number == 1: txt += ( "During this task, arrows will appear either above or below the '+' symbol.\n" "Your job will be to indicate the direction of the middle arrow as quickly\n" "and accurately as possible using the keyboard.\n\n" "( c = left, m = right )") elif P.block_number == 2: txt += ( "On some trials, the central arrow will be displaced upwards or downwards " "by a large amount.\n" "When this occurs, please press the space bar instead of the 'c' or 'm' keys." ) self.trial_type = 'EV' self.ev_offset = 'below' demo_arrows = self.generate_arrows() else: txt += ( "On some trials, a large red countdown timer will appear instead of the arrows." "\nWhen this occurs, please press the space bar as quickly as you can." ) instructions = message(txt, align='center', blit_txt=False) continue_msg = message('Press any key to begin.', align='center', blit_txt=False) instruction_time = CountDown(3) while True: keydown = key_pressed() fill() blit(instructions, 8, (P.screen_c[0], int(P.screen_y * 0.1))) if P.block_number == 2: blit(self.fixation, 5, P.screen_c) for shape, loc in demo_arrows: blit(shape, 5, loc) elif P.block_number == 3: elapsed = min( [int(instruction_time.elapsed() * 1000), 367]) demo_counter = message(str(elapsed).zfill(4), "PVT", blit_txt=False) blit(demo_counter, 5, P.screen_c) if P.development_mode or instruction_time.counting() == False: blit(continue_msg, 2, (P.screen_c[0], int(P.screen_y * 0.9))) if keydown == True: break flip() elif P.run_practice_blocks and P.session_number == 1 and P.block_number == 4: self.block_msg( "Practice complete! Press any key to begin the task.") elif P.block_number == 1: self.block_msg("Press any key to begin the task.") elif P.block_number == halfway_block: self.block_msg( "Phew, you're halfway done! Press any key to continue.")
def instructions(self): p1 = ( "During this task, you will presented with a sequence of letters in the middle of " "the screen.\n\nPress any key to see an example.") p2a = ( "For some blocks, your task will be to indicate whether each letter matches " "the letter just before it:") p2b = ( "For others, your task will be to indicate whether each letter matches " "the letter two before it:") p2c = "(matches for each block type are highlighted)" p3 = ( "Occasionally, the task will be interrupted by screens asking you about your " "focus just prior.\nWhen this happens, please select the most accurate " "response using the mouse cursor.\n\nPress any key to see an example." ) msg1 = message(p1, 'normal', blit_txt=False, align='center') msg2a = message(p2a, 'normal', blit_txt=False, wrap_width=int(P.screen_x * 0.8)) msg2b = message(p2b, 'normal', blit_txt=False, wrap_width=int(P.screen_x * 0.8)) msg2c = message(p2c, 'normal', blit_txt=False) msg3 = message(p3, 'normal', blit_txt=False, align='center', wrap_width=int(P.screen_x * 0.8)) # First page of instructions flush() fill() blit(msg1, 5, P.screen_c) flip() any_key(allow_mouse_click=False) # Example stimuli for letter in (1, 2, 1): trialtime = CountDown(2.5) while trialtime.counting(): mask_on = trialtime.elapsed() > 0.5 stim = self.mask if mask_on else self.letters[ self.letter_set[letter]] ui_request() fill() blit(self.accuracy_rect, 5, P.screen_c) blit(self.accuracy_mask, 5, P.screen_c) blit(stim, 5, P.screen_c) flip() # Task explanation/illustration fill() blit(msg2a, 8, (P.screen_c[0], int(P.screen_y * 0.15))) blit(msg2b, 8, (P.screen_c[0], int(P.screen_y * 0.45))) blit(msg2c, 2, (P.screen_c[0], int(P.screen_y * 0.8))) self.draw_nback_illustration(int(P.screen_y * 0.3), target=5) self.draw_nback_illustration(int(P.screen_y * 0.6), target=4) flip() any_key(allow_mouse_click=False) # Probe explanation + example probe fill() blit(msg3, 5, P.screen_c) flip() any_key() self.probe.collect()
def block(self): # Initialize/reset list of previous letters presented self.past_letters = [] # Determine nback difficulty for the block even_block = P.block_number % 2 == 0 if self.first_nback == 1: self.nback = 2 if even_block else 1 else: self.nback = 1 if even_block else 2 # Determine positions of thought probes in trial sequence # Probes are pseudo-randomly distributed throughout blocks, with one probe in every set of # 30 trials. Probes cannot appear in the first 8 trials of a set, ensuring that probes are # at minimum 20 seconds apart. self.probe_trials = [] noprobe_span = [False] * P.noprobe_span probe_span = [True] + [False] * P.probe_span while len(self.probe_trials) < P.trials_per_block: random.shuffle(probe_span) self.probe_trials += noprobe_span + probe_span # Generate block message header = "Block {0} of {1}".format(P.block_number, P.blocks_per_experiment) nback_txts = [' ', 'just before it', 'two before it'] instructions = ( "During this block, please press the [m] key when a letter matches\nthe letter " "{0}, and the [n] key when it does not.".format( nback_txts[self.nback])) if P.practicing: header = "This is a practice block. ({0})".format(header) instructions = instructions + "\nYou will be given feedback on your accuracy." msg = message(header + "\n\n" + instructions, 'normal', align="center", blit_txt=False) start_msg = message("Press the [n] key to start.", 'normal', blit_txt=False) # Show block message, and wait for input before staring block message_interval = CountDown(2) while message_interval.counting(): ui_request() # Allow quitting during loop fill() blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15))) self.draw_nback_illustration(P.screen_c[1], target=5 if self.nback == 1 else 4) flip() while True: if key_pressed('n'): break fill() blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15))) self.draw_nback_illustration(P.screen_c[1], target=5 if self.nback == 1 else 4) blit(start_msg, 5, (P.screen_c[0], int(P.screen_y * 0.75))) flip()
def trial(self): start_delay = CountDown(P.origin_wait_time) while start_delay.counting(): ui_request() fill() blit(self.tracker_dot, 5, self.origin_pos) flip() animate_start = self.evm.trial_time self.figure.animate() animate_time = self.evm.trial_time - animate_start avg_velocity = self.figure.path_length / animate_time if self.response_type == PHYS: self.physical_trial() elif self.response_type == MOTR: self.imagery_trial() else: self.control_trial() fill() flip() if self.__practicing__: return return { "session_num": self.session_number, "block_num": P.block_number, "trial_num": P.trial_number, "response_type": self.response_type, "feedback_type": self.feedback_type, "figure_type": self.figure_name, "figure_file": self.file_name + ".tlf", "stimulus_gt": self.animate_time, # intended animation time "stimulus_mt": animate_time, # actual animation time "avg_velocity": avg_velocity, # in pixels per second "path_length": self.figure.path_length, "trace_file": (self.file_name + ".tlt") if self.response_type == PHYS else 'NA', "rt": self.rt, "it": self.it, "control_question": self.control_question if self.response_type == CTRL else 'NA', "control_response": self.control_response, "mt": self.mt }