def hold_check(exp, holding_time, background_stimulus=None, n_sensors=2): # FIXME not checked for sensor=1 if background_stimulus is None: background_stimulus = stimuli.BlankScreen() background_stimulus.present() background_stimulus.present() udp.send("hold:test") fine = stimuli.Circle(radius=20, colour=misc.constants.C_GREY, line_width=0) too_low = stimuli.Circle(radius=20, colour=misc.constants.C_GREEN, line_width=0) too_strong = stimuli.Circle(radius=20, colour=misc.constants.C_RED, line_width=0) bkg = [ stimuli.Circle(position=(-200, 0), radius=24, colour=misc.constants.C_BLACK, line_width=0), stimuli.Circle(position=(200, 0), radius=24, colour=misc.constants.C_BLACK, line_width=0) ] key = None stopwatch.reset_stopwatch() while key is None and stopwatch.stopwatch_time < holding_time: key = exp.keyboard.check() udp.clear_receive_buffer() lv = [ rc.get_data(rc.Command.GET_THRESHOLD_LEVEL), rc.get_data(rc.Command.GET_THRESHOLD_LEVEL2) ] for i in range(n_sensors): bkg[i].clear_surface() if lv[i] == WEAK: too_low.plot(bkg[i]) stopwatch.reset_stopwatch() elif lv[i] == STRONG: too_strong.plot(bkg[i]) stopwatch.reset_stopwatch() elif lv[i] == FINE: fine.plot(bkg[i]) bkg[i].present(clear=False, update=False) bkg[i].present(clear=False, update=False) exp.screen.update() background_stimulus.present()
def _clickable_numeric_input(title, start_at): # copied from the 0.7.0 release of expyriment # https://github.com/expyriment/expyriment/blob/81acb8be1a2abcecdbbfe501e9c4f662c9ba6620/expyriment/control/_experiment_control.py#L96 background_stimulus = stimuli.BlankScreen(colour=(0, 0, 0)) fields = [ stimuli.Circle(diameter=200, colour=(70, 70, 70), position=(0, 70)), stimuli.Circle(diameter=200, colour=(70, 70, 70), position=(0, -70)), stimuli.Rectangle(size=(50, 50), colour=(70, 70, 70), position=(120, 0)) ] fields[0].scale((0.25, 0.25)) fields[1].scale((0.25, 0.25)) # stimuli.TextLine(text="-", text_size=36, position=(0, -70), # text_font="FreeMono", # text_colour=(0, 0, 0)), plusminus = [ stimuli.TextLine(title, text_size=24, text_colour=misc.constants.C_EXPYRIMENT_PURPLE, position=(-182, 0)), stimuli.FixCross(size=(15, 15), position=(0, 70), colour=(0, 0, 0), line_width=2), stimuli.FixCross(size=(15, 2), position=(0, -70), colour=(0, 0, 0), line_width=2), stimuli.TextLine(text="Go", text_size=18, position=(120, 0), text_colour=(0, 0, 0)) ] number = int(start_at) while True: text = stimuli.TextLine(text="{0}".format(number), text_size=28, text_colour=misc.constants.C_EXPYRIMENT_ORANGE) btn = io.TouchScreenButtonBox(button_fields=fields, stimuli=plusminus + [text], background_stimulus=background_stimulus) btn.show() key, rt = btn.wait() if key == fields[0]: number += 1 elif key == fields[1]: number -= 1 if number <= 0: number = 0 elif key == fields[2]: break return (number)
def fixdot(self, x=None, y=None, color=None): """See openexp._canvas.legacy""" if color != None: color = self.color(color) else: color = self.fgcolor if x == None: x = self.xcenter() if y == None: y = self.ycenter() stim = stimuli.Circle(16, colour=color, position=c2p((x, y))) self.add_stim(stim, prepare=False) stim = stimuli.Circle(4, colour=self.bgcolor, position=c2p((x, y))) self.add_stim(stim)
def prepare_trial(self, block): trial = design.Trial() # TODO: practice = e['Practice'] if 'Practice' in e else False labels = self.labels[block.get_factor('target_titles')][:block.get_factor('num_targets')] positions = TrailMaking.make_random_positions( self.exp.screen.window_size, self.radius, block.get_factor('num_targets'), self.exp.config.getfloat('DESIGN', 'min_distance_of_targets') * self.radius, self.exp.config.getfloat('DESIGN', 'attempts_before_reducing_min_distance')) for lab, pos in zip(labels, positions): stim = stimuli.Circle(radius=self.radius, position=pos, colour=self.colour_target, anti_aliasing=self.antialiasing) label = stimuli.TextBox(lab, (self.radius*2, self.radius*2), text_size=int(self.stimulus_relative_text_size * self.radius), position=[pos[0], pos[1] - self.stimulus_text_correction_y * self.radius], text_justification=1, text_colour=self.colour_target_label, text_font=self.target_font) trial.add_stimulus(stim) trial.add_stimulus(label) return(trial)
def create_erase_list_for_dot_list(dot_list): erase_list = [] for dot in dot_list: erase_list.append( stimuli.Circle(radius=RADIUS_OF_DOTS, position=dot.position, colour=COLOR_OF_ARENA)) return (erase_list)
def generate_n_dots(n_dots): positions = generate_list_of_n_positions_in_inner_square_of_arena(n_dots) dot_list = [] for i in range(n_dots): dot_list.append( stimuli.Circle(radius=RADIUS_OF_DOTS, colour=COLOR_OF_DOTS, position=positions[i])) return (dot_list)
def execute_trial(motion_coherence, direction, number_dots, time_duration=MAX_RESPONSE_DELAY): dot_list = generate_n_dots(N_DOTS) stimuli.BlankScreen().present() arena = stimuli.Circle(radius=RADIUS_OF_ARENA + 2 * RADIUS_OF_DOTS, colour=COLOR_OF_ARENA) cue = stimuli.FixCross(size=(SIZE_FIXATION_CROSS, SIZE_FIXATION_CROSS), line_width=LINE_WIDTH_FIXATION_CROSS) cue.present() exp.clock.wait(1000) key = exp.keyboard.check() exp.clock.reset_stopwatch() while (exp.clock.stopwatch_time < time_duration) and (key is None): update_stimulus(dot_list, arena) key, time = check_keyboard_response_and_time() exp.clock.wait(1) return (key, time)
control.set_develop_mode(True) exp = design.Experiment(name="My Experiment") control.initialize(exp) fixcross = stimuli.FixCross() fixcross.preload() blankscreen = stimuli.BlankScreen() blankscreen.preload() b = design.Block(name="Only Block") for i in range(10): waiting_time = random.randint(200, 2000) t = design.Trial() t.set_factor("waiting_time", waiting_time) s = stimuli.Circle(50) t.add_stimulus(s) b.add_trial(t) exp.add_block(b) exp.data_variable_names = ["Waiting Time", "Response Time"] control.start() for block in exp.blocks: for trial in block.trials: fixcross.present() exp.clock.wait( trial.get_factor("waiting_time") - trial.stimuli[0].preload()) trial.stimuli[0].present() button, rt = exp.keyboard.wait(keys=[misc.constants.K_SPACE])
#!/usr/bin/env python # -*- coding: utf-8 -*- """Example: moving stimulus in Expyriment using none OpenGL mode""" from expyriment import control, stimuli, misc control.defaults.open_gl = False # switch off opengl to avoid screen refesh sync exp = control.initialize() control.start() radius = 20 movement = [4, 8] arena = (exp.screen.size[0] / 2 - radius, exp.screen.size[1] / 2 - radius) dot = stimuli.Circle(radius=radius, colour=misc.constants.C_YELLOW) stimuli.BlankScreen().present() exp.clock.reset_stopwatch() while exp.clock.stopwatch_time < 10000: erase = stimuli.Rectangle(size=dot.surface_size, position=dot.position, colour=exp.background_colour) dot.move(movement) if dot.position[0] > arena[0] or dot.position[0] < -1 * arena[0]: movement[0] = -1 * movement[0] if dot.position[1] > arena[1] or dot.position[1] < -1 * arena[1]: movement[1] = -1 * movement[1] erase.present(clear=False, update=False) # present but do not refesh screen
""" reward(r) returns the bonus, which is a (step-wise) linear function of the error r (in %). Bonus increase with performance. It is at most +2.5€, 0€ for r=7% clipped to -10€. The bonus changes with 0.5€ steps. """ return max(-10, round(2 * (-33.2 + (100 - r) * 2.5 / 7)) / 2) # import matplotlib.pyplot as plt # plt.plot(r, [reward(r_) for r_ in r]) # Set and preload stimuli # define fixcross fixcross = stimuli.Circle(r_large, colour=misc.constants.C_WHITE, line_width=width_large, position=None, anti_aliasing=10) fixcross2 = stimuli.Circle(r_small, colour=misc.constants.C_WHITE, line_width=0, position=None, anti_aliasing=10) fixcross2.plot(fixcross) # define memo memo_disque = stimuli.Circle(r_memo, position=[d_memo, -d_memo], colour=misc.constants.C_DARKGREY, anti_aliasing=10) memo_carre = stimuli.Rectangle([l_memo, l_memo],
""" from expyriment import design, control, stimuli exp = design.Experiment(name="Kanisza square", background_colour=(127, 127, 127)) control.set_develop_mode(on=True) # Comment out for full screen experiment control.initialize(exp) control.start(skip_ready_screen=True) width, height = 200, 200 left = -width // 2 right = width // 2 top = height // 2 bottom = -height // 2 stimuli.Circle(50, (0, 0, 0), 0, (left, top)).present(clear=True, update=False) stimuli.Circle(50, (0, 0, 0), 0, (right, top)).present(clear=False, update=False) stimuli.Circle(50, (0, 0, 0), 0, (left, bottom)).present(clear=False, update=False) stimuli.Circle(50, (0, 0, 0), 0, (right, bottom)).present(clear=False, update=False) stimuli.Rectangle((width, height), (127, 127, 127), 0, None, None, (0, 0)).present(clear=False, update=True) exp.screen.save('kanisza-squares2.png') exp.keyboard.wait() control.end()
def run_trial(self, block, trial): trial = block.trials[0] def display_labels(lbls): return ' - '.join(lbls[:6]) + (' - ...' if len(lbls) > 6 else '') target_order = display_labels(self.labels[block.get_factor('target_titles')]) self.exp._show_message('', 'instruction', format={'target_order': target_order}) idoffset = trial.stimuli[1].id - 1 def make_surface(trial): sf = stimuli.BlankScreen() boundary = self.exp.config.gettuple('APPEARANCE', 'colour_window_boundary') if boundary: stimuli.Rectangle(self.exp.screen.window_size, line_width=self.line_width, colour=boundary).plot(sf) [s.plot(sf) for s in trial.stimuli] return sf surface = make_surface(trial) surface.present() cumulated = 0 path = [] currentcircle = 0 score = 0 mouse = self.exp.mouse.position has_moved = False logs = {'lost_touch': [], 'touched_targets': []} def get_log(evt): return { '_block': block.id + 1, 'current_target': currentcircle, 'distance': cumulated, 'time': self.exp.clock.stopwatch_time, 'score': score, 'event': evt } in_circle = -1 mismatched_circles = [] misc.Clock.reset_stopwatch(self.exp.clock) while True: new_mouse = self.exp.mouse.wait_motion(duration=20)[0] if self.exp.clock.stopwatch_time / 1000 >= block.get_factor('timeout'): self.exp._log_trial(block, trial, get_log('timeout')) break if self.exp.mouse.pressed_buttons[0] != 1: lost = False if currentcircle > 0 or len(mismatched_circles) > 0: lost = True if self.on_pointer_release == 'reset': currentcircle = 0 mismatched_circles = [] score = 0 # TODO has_moved = False surface = make_surface(trial) surface.present() elif self.on_pointer_release == 'nothing': pass if lost: logs['lost_touch'].append(get_log('lost_touch')) self.exp._log_trial(block, trial, logs['lost_touch'][-1]) continue if mouse == new_mouse: continue if not has_moved: has_moved = True mouse = None continue if abs(new_mouse[0]) >= self.exp.screen.window_size[0]/2 or abs(new_mouse[1]) >= self.exp.screen.window_size[1]/2: continue if mouse is not None: stimuli.Line(mouse, new_mouse, self.line_width, self.colour_line).plot(surface) stimuli.Circle(radius=self.line_width/2, position=new_mouse, colour=self.colour_line, anti_aliasing=self.antialiasing ).plot(surface) cumulated += TrailMaking.point_distance(new_mouse, mouse) path.append([new_mouse[0], new_mouse[1], self.exp.clock.stopwatch_time]) def get_stimulus_position(sid): return [ x for x in trial.stimuli if x.id == sid][0].position for s in trial.stimuli: if 'Circle' in s.__class__.__name__: x, y = s.position if TrailMaking.point_distance((x, y), new_mouse) <= self.radius: if in_circle == -1: in_circle = s.id if (s.id - idoffset)/2+0 == currentcircle: # stimuli.Circle(radius=CIRCLE_SIZE, colour=COLOUR_CIRCLE_DONE, line_width=LINEWIDTH, position=(x, y)).plot(surface) # , anti_aliasing=ANTIALIASING currentcircle += 1 # score += SCORE_CORRECT_CIRCLE logs['touched_targets'].append(get_log('correct_touch')) self.exp._log_trial(block, trial, logs['touched_targets'][-1]) if len(mismatched_circles) > 0: for ss in mismatched_circles + [s.id]: trial.stimuli[ss - idoffset].plot(surface) trial.stimuli[ss - idoffset + 1].plot(surface) mismatched_circles = [] elif (s.id - idoffset)/2+0 < currentcircle - 1 or (s.id - idoffset)/2+0 > currentcircle: if self.on_mismatched_circle == 'repeat_last': if len(mismatched_circles) == 0 and currentcircle > 0: currentcircle -= 1 stimuli.Circle(radius=self.ring_radius, colour=self.colour_target_hint, line_width=self.line_width, position=get_stimulus_position( currentcircle*2 + idoffset)).plot(surface) if self.on_mismatched_circle in ['highlight_only', 'repeat_last']: mismatched_circles.append(s.id) stimuli.Circle(radius=self.ring_radius, colour=self.colour_target_error, line_width=self.line_width, position=(x, y), anti_aliasing=self.antialiasing).plot(surface) # score += SCORE_WRONG_CIRCLE logs['touched_targets'].append( get_log('wrong_touch:' + str(currentcircle))) self.exp._log_trial(block, trial, logs['touched_targets'][-1]) else: if in_circle == s.id and TrailMaking.point_distance((x, y), new_mouse) >= self.radius + 1: trial.stimuli[in_circle - idoffset + 1].plot(surface) in_circle = -1 surface.present() mouse = new_mouse if currentcircle >= len(trial.stimuli)/2: self.exp._log_trial(block, trial, get_log('finish')) break logs['time'] = self.exp.clock.stopwatch_time logs['distance'] = cumulated logs['score'] = score self.exp._show_message('', 'trial_done', format={ 'distance': logs['distance'], 'time': logs['time'], 'score': logs['score']}) self.exp._log_block(trial, block, logs, {'trail': trial.id}, TrailMaking.make_trail_summary(logs, block)) # TODO # self.log_trail(block, path) # self.log_targets(block, block.trials[0].stimuli) return()
def start(experiment=None, auto_create_subject_id=None, subject_id=None, skip_ready_screen=False): """Start an experiment. This starts an experiment defined by 'experiment' and asks for the subject number. When the subject number is entered and confirmed by ENTER, a data file is created. Eventually, "Ready" will be shown on the screen and the method waits for ENTER to be pressed. After experiment start the following additional properties are available: * experiment.subject -- the current subject id * experiment.data -- the main data file Parameters ---------- experiment : design.Experiment, optional (DEPRECATED) don't use this parameter, it only exists to keep backward compatibility auto_create_subject_id : bool, optional if True new subject id will be created automatically subject_id : integer, optional start with a specific subject_id; no subject id input mask will be presented; subject_id must be an integer; setting this paramter overrules auto_create_subject_id skip_ready_screen : bool, optional if True ready screen will be skipped (default=False) Returns ------- exp : design.Experiment The started experiment will be returned. """ if experiment is None: experiment = expyriment._active_exp if experiment != expyriment._active_exp: raise Exception("Experiment is not the currently initialized " + "experiment!") if experiment.is_started: raise Exception("Experiment is already started!") if subject_id is not None: if not isinstance(subject_id, int): raise Exception("Subject id must be an integer. " + "{0} is not allowed.".format(type(subject_id))) auto_create_subject_id = True elif auto_create_subject_id is None: auto_create_subject_id = defaults.auto_create_subject_id experiment._is_started = True # temporarily switch off log_level old_logging = experiment.log_level experiment.set_log_level(0) screen_colour = experiment.screen.colour experiment._screen.colour = [0, 0, 0] if subject_id is None: default_number = DataFile.get_next_subject_number() else: default_number = subject_id if not auto_create_subject_id: if android is not None: background_stimulus = stimuli.BlankScreen(colour=(0, 0, 0)) fields = [ stimuli.Circle(radius=100, colour=(70, 70, 70), position=(0, 70), anti_aliasing=10), stimuli.Circle(radius=100, colour=(70, 70, 70), position=(0, -70), anti_aliasing=10), stimuli.Rectangle(size=(50, 50), colour=(70, 70, 70), position=(120, 0)) ] fields[0].scale((0.25, 0.25)) fields[1].scale((0.25, 0.25)) plusminus = [ stimuli.TextLine("Subject Number:", text_size=24, text_colour=constants.C_EXPYRIMENT_PURPLE, position=(-182, 0)), stimuli.FixCross(size=(15, 15), position=(0, 70), colour=(0, 0, 0), line_width=2), stimuli.FixCross(size=(15, 2), position=(0, -70), colour=(0, 0, 0), line_width=2), stimuli.TextLine(text="Go", text_size=18, position=(120, 0), text_colour=(0, 0, 0)) ] subject_id = default_number while True: text = stimuli.TextLine( text="{0}".format(subject_id), text_size=28, text_colour=constants.C_EXPYRIMENT_ORANGE) btn = TouchScreenButtonBox( button_fields=fields, stimuli=plusminus + [text], background_stimulus=background_stimulus) btn.show() key, rt = btn.wait() if key == fields[0]: subject_id += 1 elif key == fields[1]: subject_id -= 1 if subject_id <= 0: subject_id = 0 elif key == fields[2]: break experiment._subject = int(subject_id) else: position = (0, 0) while True: ask_for_subject = TextInput( message="Subject Number:", position=position, message_colour=misc.constants.C_EXPYRIMENT_PURPLE, message_text_size=24, user_text_colour=misc.constants.C_EXPYRIMENT_ORANGE, user_text_size=20, background_colour=(0, 0, 0), frame_colour=(70, 70, 70), ascii_filter=misc.constants.K_ALL_DIGITS) subject_id = ask_for_subject.get(repr(default_number)) try: experiment._subject = int(subject_id) break except: pass else: experiment._subject = default_number experiment.screen.clear() experiment.screen.update() experiment._data = DataFile(additional_suffix=experiment.filename_suffix) experiment.data.add_variable_names(experiment.data_variable_names) for txt in experiment.experiment_info: experiment.data.add_experiment_info(txt) for line in experiment.__str__().splitlines(): experiment.data.add_experiment_info(line) for f in experiment.bws_factor_names: _permuted_bws_factor_condition = \ experiment.get_permuted_bws_factor_condition(f) if isinstance(_permuted_bws_factor_condition, unicode): _permuted_bws_factor_condition = \ unicode2str(_permuted_bws_factor_condition) experiment.data.add_subject_info("{0} = {1}".format( unicode2str(f), _permuted_bws_factor_condition)) if experiment.events is not None: experiment.events._time_stamp = experiment.data._time_stamp experiment.events.rename(experiment.events.standard_file_name) number = defaults.initialize_delay - int(experiment.clock.time / 1000) if number > 0: text = stimuli.TextLine("Initializing, please wait...", text_size=24, text_colour=(160, 70, 250), position=(0, 0)) stimuli._stimulus.Stimulus._id_counter -= 1 text.present() text.present() # for flipping with double buffer text.present() # for flipping with tripple buffer while number > 0: counter = stimuli.TextLine( "{num:02d}".format(num=number), text_font='FreeMono', text_size=18, text_bold=True, text_colour=misc.constants.C_EXPYRIMENT_ORANGE, position=(0, -50), background_colour=(0, 0, 0)) stimuli._stimulus.Stimulus._id_counter -= 1 counter.present(clear=False) number -= 1 key = experiment.keyboard.wait(pygame.K_ESCAPE, duration=1000, check_for_control_keys=False) if key[0] is not None: break position = (0, 0) if not skip_ready_screen: stimuli.TextLine( "Ready", position=position, text_size=24, text_colour=misc.constants.C_EXPYRIMENT_ORANGE).present() stimuli._stimulus.Stimulus._id_counter -= 1 if android is None: experiment.keyboard.wait() else: experiment.mouse.wait_press() experiment.set_log_level(old_logging) experiment._screen.colour = screen_colour experiment.log_design_to_event_file() experiment._event_file_log("Experiment,started") return experiment
from expyriment import control, stimuli, design, misc colors = {'red': (255, 0, 0), 'green': (0, 255, 0)} positions = {'left': (-200, 0), 'right': (200, 0)} trials = [('left', 'red'), ('left', 'green'), ('right', 'red'), ('right', 'green')] * 10 design.randomize.shuffle_list(trials) exp = control.initialize() exp.data_variable_names = ["side", "color", "btn", "rt", "error"] control.start(exp, skip_ready_screen=True) stimuli.TextScreen("Simon task", instructions).present() exp.keyboard.wait(misc.constants.K_SPACE) exp.clock.wait(1000) for trial in trials: target = stimuli.Circle(30, colour=colors[trial[1]], position=positions[trial[0]]) exp.clock.wait(500 - stimuli.FixCross().present() - target.preload()) target.present() button, rt = exp.keyboard.wait([misc.constants.K_f, misc.constants.K_j]) error = ((button == misc.constants.K_f) & (trial[1] == 'red')) | \ ((button == misc.constants.K_j) & (trial[1] == 'green')) if error: stimuli.Tone(duration=200, frequency=2000).play() exp.data.add([trial[0], trial[1], button, rt, int(error)]) exp.clock.wait(1000 - stimuli.BlankScreen().present() - target.unload()) control.end(goodbye_text="Thank you very much...", goodbye_delay=2000)
exp = design.Experiment(name="Cool Experiment") control.initialize(exp) block_one = design.Block(name="Our only block") tmp_trial = design.Trial() cross = stimuli.FixCross() cross.preload() # define stimulus positions positions = [-400, -200, 0, 200, 400] # go through all positions for xpos in positions: # create circle accordingly stim = stimuli.Circle(radius=25, colour=(0,0,0),position=[xpos,0]) stim.preload() tmp_trial.add_stimulus(stim) tmp_trial.add_stimulus(cross) block_one.add_trial(tmp_trial) tmp_trial = tmp_trial.copy() tmp_trial.clear_stimuli() exp.add_block(block_one) control.start() for b in exp.blocks: for t in b.trials: t.stimuli[0].present(clear=True, update=False) t.stimuli[1].present(clear=False, update=True) exp.keyboard.wait()
block.add_trial(trial) else: stim = right_circle stim.preload() trial = expyriment.design.Trial() trial.add_stimulus(stim) block.add_trial(trial) ## Stimulus n = 10 expected_block_one = np.zeros(n) expected_block_two = np.zeros(n) circle_dist = 200 circle_radius = 20 left_circle = stimuli.Circle(circle_radius, position=[-circle_dist, 0]) left_circle.preload() right_circle = stimuli.Circle(circle_radius, position=[circle_dist, 0]) right_circle.preload() circle_displaytime = 100 ## Fixcross fixcross = stimuli.FixCross(size=(15, 15), line_width=3) fixcross.preload() ## Instruction instruction1 = """ Block 1 \n\ Fixez la croix de fixation. \n\ Positionnez votre index droit sur la flèche droite du clavier et votre index gauche sur la flèche gauche du clavier. \n\ Appuyez avec la flèche droite quand le rond blanc apparait à droite et appuyez avec la flèche gauche quand il apparait à gauche. \n\ Appuyez sur une des flèches pour commencer."""
def _test1(): info = """This will test the visual stimulus presentation timing specifics of your system. During the test, you will see two squares on the screen. After the test, you will be asked to indicate which (if any) of those two squares were flickering. [Press RETURN to continue]""" # TODO test very slow quit text = stimuli.TextScreen("Visual stimulus presentation test", info) #y = [] #for x in [16, 32, 48, 64]: # y.extend([x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ]) #graph1 = _make_graph(range(60), y, [0, 255, 0]) #y = range(80) #graph2 = _make_graph(range(60), y, [255, 0, 0]) #graph1.position = (-200, -100) #graph2.position = (200, -100) text.present() #graph1.present(clear=False, update=False) #graph2.present(clear=False) exp.keyboard.wait([constants.K_RETURN]) message = stimuli.TextScreen("Running", "Please wait...") message.present() message.present() message.present() c1 = stimuli.Canvas((400, 400)) c2 = stimuli.Canvas((400, 400)) c3 = stimuli.Canvas((400, 400)) frame1 = stimuli.Rectangle((100, 100), position=(-100, 0)) frame2 = stimuli.Rectangle((100, 100), position=(100, 0)) bg = stimuli.Rectangle((90, 90), colour=exp.background_colour) bg.plot(frame1) bg.plot(frame2) frame1.plot(c1) frame2.plot(c2) frame1.plot(c3) frame2.plot(c3) c1.preload() c2.preload() c3.preload() c1.present(clear=False) c2.present(clear=False) c3.present(clear=False) s1 = stimuli.Circle(1, colour=exp.background_colour) s2 = stimuli.Circle(1, colour=exp.background_colour) s1.preload() s2.preload() todo_time = range(0, 60) * 3 randomize.shuffle_list(todo_time) actual_time = [] for x in todo_time: s1.present(clear=False) start = get_time() exp.clock.wait(x) s2.present(clear=False) actual_time.append((get_time() - start) * 1000) exp.clock.wait(expyriment.design.randomize.rand_int(30, 60)) # determine refresh_rate tmp = [] for _x in range(100): start = get_time() s1.present(clear=False) tmp.append(get_time() - start) start = get_time() s2.present(clear=False) tmp.append(get_time() - start) refresh_rate = 1000 / (statistics.mean(tmp) * 1000) #text = stimuli.TextScreen("Results", "[Press RETURN to continue]") #graph = _make_graph(todo_time, actual_time, [150, 150, 150]) #graph.position = (0, -100) #text.present(update=False) #graph.present(clear=False) #exp.keyboard.wait([constants.K_RETURN]) #text = stimuli.TextScreen( # "Which picture looks most similar to the results?", # "[Press LEFT or RIGHT arrow key]") #y = [] #for x in [16, 32, 48, 64]: # y.extend([x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ]) #graph1 = _make_graph(range(60), y, [0, 255, 0]) #y = range(80) #graph2 = _make_graph(range(60), y, [255, 0, 0]) #graph1.position = (-200, -100) #graph2.position = (200, -100) #text.present(update=False) #graph1.present(clear=False, update=False) #graph2.present(clear=False) #key, _rt = exp.keyboard.wait([constants.K_LEFT, # constants.K_RIGHT]) #if key == constants.K_LEFT: # response1 = "Steps" #elif key == constants.K_RIGHT: # response1 = "Line" #else: # response1 = None # show histogram of presentation delays def expected_delay(presentation_time, refresh_rate): refresh_time = 1000.0 / refresh_rate return refresh_time - (presentation_time % refresh_time) # delay = map(lambda x: x[1]- x[0], zip(todo_time, actual_time)) unexplained_delay = map( lambda x: x[1] - x[0] - expected_delay(x[0], refresh_rate), zip(todo_time, actual_time)) hist, hist_str = _histogram(unexplained_delay) inaccuracies = [] delayed_presentations = 0 for key in hist.keys(): inaccuracies.extend([key % (1000 / refresh_rate)] * hist[key]) if key != 0: delayed_presentations += hist[key] inaccuracy = int(round(sum(inaccuracies) / float(len(inaccuracies)))) delayed = round(100 * delayed_presentations / 180.0, 2) text = stimuli.TextScreen( "How many of the two squares were flickering?", "[Press 0, 1 or 2]") text.present() key, _rt = exp.keyboard.wait( [constants.K_0, constants.K_1, constants.K_2]) if key == constants.K_0: response = 0 elif key == constants.K_1: response = 1 elif key == constants.K_2: response = 2 info = stimuli.TextScreen("Results", "") results1 = stimuli.TextScreen( "", "Estimated Screen Refresh Rate: {0} Hz (~ every {1} ms)\n\n". format(int(round(refresh_rate)), int(1000.0 / refresh_rate)), text_font="freemono", text_size=16, text_bold=True, text_justification=0, position=(0, 40)) results2 = stimuli.TextScreen( "", "Detected Framebuffer Pages: {0}\n\n".format(response + 1), text_font="freemono", text_size=16, text_bold=True, text_justification=0, position=(0, 20)) if inaccuracy != 0: results3_colour = [255, 0, 0] else: results3_colour = [0, 255, 0] results3 = stimuli.TextScreen( "", "Average Reporting Inaccuracy: {0} ms\n\n".format(inaccuracy), text_font="freemono", text_size=16, text_bold=True, text_justification=0, text_colour=results3_colour, position=(0, -20)) if delayed > 10: results4_colour = [255, 0, 0] elif 10 > delayed > 1: results4_colour = [255, 255, 0] else: results4_colour = [0, 255, 0] results4 = stimuli.TextScreen( "", "Unexplained Presentation Delays: {0} %\n\n\n".format(delayed), text_font="freemono", text_size=16, text_bold=True, text_justification=0, text_colour=results4_colour, position=(0, -40)) results5 = stimuli.TextScreen("", hist_str, text_font="freemono", text_size=16, text_bold=True, text_justification=0, position=(0, -100)) results1.plot(info) results2.plot(info) results3.plot(info) results4.plot(info) results5.plot(info) info2 = stimuli.TextLine("[Press RETURN to continue]", position=(0, -160)) info2.plot(info) info.present() exp.keyboard.wait([constants.K_RETURN]) return todo_time, actual_time, refresh_rate, inaccuracy, delayed, response
MIN_WAIT_TIME = 1000 MAX_WAIT_TIME = 2000 MAX_RESPONSE_DELAY = 2000 RADIUS = 30 COLORS = ((20, 20, 20), (60, 60, 60), (120, 120, 120), (255, 255, 255)) NCOPIES = 10 exp = design.Experiment(name="Visual Detection", text_size=40) control.initialize(exp) block = design.Block() for ic, color in enumerate(COLORS): t = design.Trial() t.set_factor("grey-level", ic) t.add_stimulus(stimuli.Circle(RADIUS, color)) block.add_trial(t, copies=NCOPIES) block.shuffle_trials() blankscreen = stimuli.BlankScreen() instructions = stimuli.TextScreen( "Instructions", f"""From time to time, a cross will appear at the center of screen. Your task is to press a key as quickly as possible when you see it (We measure your reaction-time). There will be {NCOPIES * len(COLORS)} trials in total. Press the space bar to start.""")
# run=4#experimental run control.defaults.event_logging = 2 # initialize the experiment exp = design.Experiment(name="Recall") control.initialize(exp) StimList = pd.read_hdf(filename, key='StimLists/StimListRec_Set%d' % run, mode='r') # creating most elements on screen fix = stimuli.Circle(3, colour=None, line_width=None, position=None, anti_aliasing=None) pos = [(-300, 0), (300, 0), (0, 0)] rect_b = stimuli.Rectangle((80, 80), colour=(255, 255, 255), position=pos[2]) blank = stimuli.BlankScreen() c1 = stimuli.BlankScreen() blank.plot(c1) c1.preload() c2 = stimuli.BlankScreen() fix.plot(c2) c2.preload() c3 = stimuli.BlankScreen() fix.plot(c3) rect_b.plot(c3)
blankscreen = stimuli.BlankScreen() instructions = stimuli.TextScreen( "Instructions", f"""From time to time, a Circle will appear at the center of screen. Your task is to press the space bar key as quickly as possible when you see it (We measure your reaction-time). There will be {3*NTRIALS} trials in total. Press the space bar to start.""") ###### 1.A --> Definition of the only two possible trials made up of two stimuli "Blue/Red" #Stimulus red visual_trial_red = design.Trial() visual_trial_red.add_stimulus(stimuli.Circle(radius=100, colour=(255, 0, 0))) #Stimulus blue visual_trial_blue = design.Trial() visual_trial_blue.add_stimulus(stimuli.Circle(radius=100, colour=(0, 0, 255))) ###### 1.B --> Definition of Associated Blocks "Blue/Red" visual_block_red = design.Block("red") # Buidlding red block with 5 stimuli for i in range(NTRIALS): visual_block_red.add_trial(visual_trial_red)