def prime(side="RIGHT", duration=1000, conflict=False, testmode=False): display_background() display_ship() display_cue(side=side, conflict=conflict) n.refresh() time = datetime.datetime.now() response = np.nan RT = np.nan if testmode is False: while (datetime.datetime.now() - time).total_seconds() * 1000 < duration: current_response = n.response( time_max=duration - (datetime.datetime.now() - time).total_seconds() * 1000, get_RT=False) if (current_response != "Time_Max_Exceeded"): response = str(current_response) RT = datetime.datetime.now() if isinstance(RT, datetime.datetime): return ({ "Cue_Response": response, "Cue_Response_RT": -1 * (datetime.datetime.now() - RT).total_seconds() * 1000 }) else: return ({"Cue_Response": response, "Cue_Response_RT": RT})
def ITI(duration=1000, testmode=False, display_trigger=False): display_background() display_ship() if display_trigger is True: trigger.stop() n.refresh() time = datetime.datetime.now() response = np.nan RT = np.nan if testmode is False: while (datetime.datetime.now() - time).total_seconds() * 1000 < duration: current_response = n.response( time_max=duration - (datetime.datetime.now() - time).total_seconds() * 1000, get_RT=False) if (current_response != "Time_Max_Exceeded"): response = str(current_response) RT = datetime.datetime.now() if isinstance(RT, datetime.datetime): return ({ "Previous_Response": response, "Previous_RT": -1 * (datetime.datetime.now() - RT).total_seconds() * 1000 }) else: return ({"Previous_Response": response, "Previous_RT": RT})
def display_instructions(text="text instructions", text_end="Shoot to start the mission.", background=(13, 71, 161), display_trigger=False): n.newpage(background, auto_refresh=False) n.write("\n\n\n" + text, color="white", long_text=True) n.write(text_end, color="white", y=-9) if display_trigger is True: trigger.stop() n.refresh() n.response(allow=["DOWN", "RIGHT", "LEFT", "SPACE"])
def attention_priming(n_trials=20, display_trigger=False): # Data creation data = { "Stimulus_Side": ["RIGHT"] * int(n_trials / 2) + ["LEFT"] * int(n_trials / 2), "ITI": list(generate_interval_frames(500, 1500, n_trials / 2)) * 2 } data["Priming_Interval"] = randomize_and_repeat( generate_interval_frames(50, 1000, n_trials / 2), 2) data = pd.DataFrame.from_dict(data) data = data.sample(len(data)).reset_index(drop=True) data = data.to_dict(orient="index") # Instructions n.newpage((24, 4, 64), auto_refresh=False) n.write("Well done! You're doing great!", color="white", y=5, size=1.5) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2000) display_instructions( """Our engineers have worked hard over the past months. We are now able to prevent the rebels' ships from gathering power. \n\nSo no more RED CROSS!""", text_end="Press SPACE to continue.", display_trigger=display_trigger) display_instructions( """For your next mission, our engineers have also improved your radar. We can now predict the position of the rebels' ships even before they emerge!\n\nThis new technology is going to help you improve your speed significantly.\n\nGive it a try, and show us again how FAST you are.""", display_trigger=display_trigger) for trial in range(n_trials): data[trial].update( ITI(data[trial]["ITI"], testmode=testmode, display_trigger=display_trigger)) data[trial].update( prime(side=data[trial]["Stimulus_Side"], duration=data[trial]["Priming_Interval"])) data[trial].update( display_stimulus(side=data[trial]["Stimulus_Side"], testmode=testmode, display_trigger=display_trigger)) data[trial]["Trial_Order"] = trial + 1 data = pd.DataFrame.from_dict(data, orient="index") return (data)
def procedure(): n.newpage("white") n.write("Veuillez patienter...", y=-9, color="blue") n.refresh() # Preload images in cache cache = {} for colour in ["white", "red", "yellow", "blue", "black"]: for focus in ["global", "local"]: for angle in [-90, 0, 90, 180]: cache = n.preload(colour + "_" + focus, size=8, extension = ".png", cache = cache, path = "./Stimuli/", rotate=angle) cache = n.preload(colour + "_circle", size=8, extension = ".png", cache = cache, path = "./Stimuli/", rotate=angle) dfs = [] dfs.append(sequence(cache, response_selection="None", inhibition=False, conflict=False)) dfs.append(sequence(cache, response_selection="Conditional", inhibition=False, conflict=False)) dfs.append(sequence(cache, response_selection="Conditional", inhibition=True, conflict=False)) dfs.append(sequence(cache, response_selection="Conditional", inhibition=True, conflict=True)) df = processing(dfs) return(df)
def run_trials(cache, trials): prestim_interval = list(np.random.uniform(33.333333, 2000, len(trials)-1)) prestim_interval.insert(0, 2000) for order, trial in enumerate(trials): n.refresh() trial["Order"] = order+1 trial["Time_Trial_Onset"] = datetime.datetime.now() # Wait trial["Prestimulus_Interval"] = int(prestim_interval[order]) if testmode is False: trial["Prestimulus_Interval"] = n.time.wait(int(prestim_interval[order])) # Diplay stuff n.image(trial["Global_Color"] + "_" + trial["Global_Shape"], size=8, extension = ".png", cache = cache, path = "./Stimuli/", rotate=trial["Global_Angle"]) n.image(trial["Local_Color"] + "_" + trial["Local_Shape"], size=8, extension = ".png", cache = cache, path = "./Stimuli/", rotate=trial["Local_Angle"]) n.refresh() trial["Time_Stimulus_Onset"] = datetime.datetime.now() if testmode is False: answer, RT = n.response(time_max = 1750, allow=["DOWN", "RIGHT", "LEFT"]) if answer == "Time_Max_Exceeded": answer = "NA" else: answer = np.random.choice(["DOWN", "RIGHT", "LEFT", "NA"]) RT = np.random.uniform(100, 1750) trial["Response"] = answer trial["RT"] = RT n.newpage('grey', auto_refresh=False) return(trials)
def PDM(signal=50, angle=0, n_points=1000, motion_slow=0, motion_size=75, box_size=8, point_size=0.05, point_speed=1, ITI=1000): """ Pattern Detection in Motion """ angle_rad = np.radians(angle) y_movement = np.sin(np.radians(angle)) * point_speed x_movement = np.cos(np.radians(angle)) * point_speed random_rad_angle = np.random.uniform(0, 360, int(n_points * (100 - signal) / 100)) random_y_movement = np.sin(np.radians(random_rad_angle)) * point_speed random_x_movement = np.cos(np.radians(random_rad_angle)) * point_speed # Generate points circle_r = n.Coordinates.to_pygame(distance_x=box_size / 2) circle_x = n.Coordinates.to_pygame(x=0) circle_y = n.Coordinates.to_pygame(y=0) signal_x = [] signal_y = [] random_x = [] random_y = [] for point in range(int(n_points * signal / 100)): alpha = 2 * np.pi * np.random.random() r = circle_r * np.random.random() x = r * np.cos(alpha) + circle_x y = r * np.sin(alpha) + circle_y signal_x.append(x) signal_y.append(y) for point in range(int(n_points * (100 - signal) / 100)): alpha = 2 * np.pi * np.random.random() r = circle_r * np.random.random() x = r * np.cos(alpha) + circle_x y = r * np.sin(alpha) + circle_y random_x.append(x) random_y.append(y) signal_x = np.array(signal_x) signal_y = np.array(signal_y) random_x = np.array(random_x) random_y = np.array(random_y) # Mask box_size = n.Coordinates.to_pygame(distance_y=box_size) x = n.screen_width / 2 - box_size / 2 y = (n.screen_height - box_size) / 2 # Preparation n.newpage("black", auto_refresh=False) # n.newpage("grey", auto_refresh=False) pygame.draw.circle(n.screen, n.color("grey"), (int(n.screen_width / 2), int(n.screen_height / 2)), int(abs(box_size) / 2), 0) n.write("+", color="white", size=1.5) n.refresh() n.time.wait(ITI) # Movement time_start = datetime.datetime.now() for i in range(motion_size): n.newpage("black", auto_refresh=False) # n.newpage("grey", auto_refresh=False) pygame.draw.circle(n.screen, n.color("grey"), (int(n.screen_width / 2), int(n.screen_height / 2)), int(abs(box_size) / 2), 0) for point in range(len(signal_x)): pygame.draw.circle(n.screen, n.color("black"), (int(signal_x[point]), int(signal_y[point])), 3, 0) # n.circle(x=half1_x[point], y=half1_y[point], size=point_size, fill_color="black") for point in range(len(random_x)): pygame.draw.circle(n.screen, n.color("black"), (int(random_x[point]), int(random_y[point])), 3, 0) # n.circle(x=half2_x[point], y=half2_y[point], size=point_size, fill_color="black") signal_x += x_movement signal_y -= y_movement random_x -= random_x_movement random_y += random_y_movement # TODO: ensure that points stay in the mask area (and transport them from one side to another if needed) n.refresh() if motion_slow > 0: n.time.wait(motion_slow) # Save duration = datetime.datetime.now() - time_start parameters = { "Angle": angle, "Angle_Radian": angle_rad, "Signal": signal, "n_Points": n_points, "Box_Size": box_size, "Motion_Size": motion_size, "Point_Size": point_size, "Point_Speed": point_speed, "Mask_Corrdinates": (int(n.screen_width / 2), int(n.screen_height / 2)), "Mask_Size": int(abs(box_size) / 2), "ITI": ITI, "Movement_Duration": duration } return (parameters)
def PDM_response(parameters): pygame.mouse.set_visible(True) n.newpage("grey") pygame.draw.circle(n.screen, n.color("black"), parameters["Mask_Corrdinates"], parameters["Mask_Size"], 0) angles = np.array([ parameters["Angle"], parameters["Angle"] + 90, parameters["Angle"] + 180, parameters["Angle"] + 270 ]) angles[angles > 360] = angles[angles > 360] - 360 angles = np.sort(angles) n.image(pyllusion_path + "arrow.png", x=1.5, y=-5, size=2, rotate=angles[0], scale_by="width") n.image(pyllusion_path + "arrow.png", x=-1.5, y=-5, size=2, rotate=angles[1], scale_by="width") n.image(pyllusion_path + "arrow.png", x=-1.5, y=-8, size=2, rotate=angles[2], scale_by="width") n.image(pyllusion_path + "arrow.png", x=1.5, y=-8, size=2, rotate=angles[3], scale_by="width") n.line(left_x=-10, left_y=-6.5, right_x=10, right_y=-6.5, line_color="black", thickness=2) n.line(left_x=0, left_y=-10, right_x=0, right_y=10, line_color="black", thickness=2) n.refresh() loop = True while loop == True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: quit() x, y = pygame.mouse.get_pos() if pygame.mouse.get_pressed() == (1, 0, 0): loop = False x, y = n.Coordinates.from_pygame(x=x, y=y) if x < 0: if y < -6.5: response = angles[2] n.rectangle(x=-1.5, y=-8, width=3, height=3, fill_color="green", thickness=2) else: response = angles[1] n.rectangle(x=-1.5, y=-5, width=3, height=3, fill_color="green", thickness=2) else: if y < -6.5: response = angles[3] n.rectangle(x=1.5, y=-8, width=3, height=3, fill_color="green", thickness=2) else: response = angles[0] n.rectangle(x=1.5, y=-5, width=3, height=3, fill_color="green", thickness=2) n.image(pyllusion_path + "arrow.png", x=1.5, y=-5, size=2, rotate=angles[0], scale_by="width") n.image(pyllusion_path + "arrow.png", x=-1.5, y=-5, size=2, rotate=angles[1], scale_by="width") n.image(pyllusion_path + "arrow.png", x=-1.5, y=-8, size=2, rotate=angles[2], scale_by="width") n.image(pyllusion_path + "arrow.png", x=1.5, y=-8, size=2, rotate=angles[3], scale_by="width") n.line(left_x=-10, left_y=-6.5, right_x=10, right_y=-6.5, line_color="black", thickness=2) n.line(left_x=0, left_y=-10, right_x=0, right_y=10, line_color="black", thickness=2) pygame.draw.circle(n.screen, n.color("black"), parameters["Mask_Corrdinates"], parameters["Mask_Size"], 0) # n.write(str(response), color="white") n.refresh() n.time.wait(50) pygame.mouse.set_visible(False) return (response)
def response_selection(n_trials=100, testmode=False, display_trigger=False): # Data creation data = { "Stimulus_Side": ["RIGHT"] * int(n_trials / 2) + ["LEFT"] * int(n_trials / 2), "ITI": list(generate_interval_frames(500, 1500, n_trials / 2)) * 2 } data = pd.DataFrame.from_dict(data) data = data.sample(len(data)).reset_index(drop=True) data = data.to_dict(orient="index") # Instructions if testmode is False: n.newpage((24, 4, 64), auto_refresh=False) n.write("When suddenly...", color="white", y=5, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2000) n.write("...your ship engine EXPLODES!", color="white", y=1.5, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2500) n.newpage("white") n.time.wait(1000) n.write("You wake up in a hospital.", color="black", y=5, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(1500) n.write("One year has passed since the accident.", color="black", y=1.5, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2000) display_instructions( """Things have changed, since. You find your dear old ship, and its famous auto-aiming cannons, damaged in a dump.\n\nYou have no choice but to start again, in this new can box they call a ship...\n\nNo more auto-aiming cannons.""", text_end="Press SPACE to continue.", background=(24, 4, 64), display_trigger=display_trigger) display_instructions( """But you're not going to give up! You're going to show everyone that you are the fastest pilot for a reason...\n\nEven if that means manually aiming at the targets!""", text_end="Press SPACE to continue.", background=(24, 4, 64), display_trigger=display_trigger) display_instructions( """Okay, rookie, get ready for action.\n\nPress LEFT or RIGHT depending on where the enemy appears, and be as fast as possible!""", display_trigger=display_trigger) for trial in range(n_trials): data[trial].update( ITI(data[trial]["ITI"], testmode=testmode, display_trigger=display_trigger)) data[trial].update( display_stimulus(side=data[trial]["Stimulus_Side"], testmode=testmode, display_trigger=display_trigger)) data[trial]["Trial_Order"] = trial + 1 data = pd.DataFrame.from_dict(data, orient="index") return (data)
def TFM_response(parameters): pygame.mouse.set_visible(True) n.newpage("grey") pygame.draw.circle( n.screen, n.color("black"), parameters["Mask_Corrdinates"], parameters["Mask_Size"], 0, ) n.image( pyllusion_path + "arrow_grey.png", x=-1.7, y=-6.2, size=2, rotate=parameters["Angle"] + 180, scale_by="width", ) n.image( pyllusion_path + "arrow_grey.png", x=-2.3, y=-5.8, size=2, rotate=parameters["Angle"] + 180, scale_by="width", ) n.image( pyllusion_path + "arrow.png", x=-2, y=-6, size=3, rotate=parameters["Angle"], scale_by="width", ) n.image( pyllusion_path + "arrow_grey.png", x=1.7, y=-6.2, size=2, rotate=parameters["Angle"], scale_by="width", ) n.image( pyllusion_path + "arrow_grey.png", x=2.3, y=-5.8, size=2, rotate=parameters["Angle"], scale_by="width", ) n.image( pyllusion_path + "arrow.png", x=2, y=-6, size=3, rotate=parameters["Angle"] + 180, scale_by="width", ) n.line(left_x=0, left_y=-10, right_x=0, right_y=10, line_color="black", thickness=1) n.refresh() loop = True while loop == True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: quit() x, y = pygame.mouse.get_pos() if pygame.mouse.get_pressed() == (1, 0, 0): loop = False x, y = n.Coordinates.from_pygame(x=x, y=y) if x < 0: response_side = "LEFT" response = parameters["Angle"] n.rectangle(x=-5, width=10, height=20, fill_color="green") else: response_side = "RIGHT" response = parameters["Angle"] + 180 n.rectangle(x=5, width=10, height=20, fill_color="green") if response >= 360: response -= 360 pygame.draw.circle( n.screen, n.color("black"), parameters["Mask_Corrdinates"], parameters["Mask_Size"], 0, ) # n.write(str(response), color="white") n.refresh() n.time.wait(50) pygame.mouse.set_visible(False) return (response, response_side)
def response_inhibition(n_trials=200, min_SSRT=0, max_SSRT=300, frame=16.66667, staircase=False, testmode=False, display_trigger=False): def generate_data(n_trials, min_SSRT=0, max_SSRT=300, frame=16.66667, adaptive=False): data = { "Stimulus_Side": ["RIGHT"] * int(n_trials / 2) + ["LEFT"] * int(n_trials / 2), "ITI": list(generate_interval_frames(500, 1500, n_trials / 2)) * 2 } # SSRT ss = np.array( randomize_and_repeat([False, False, True], int(n_trials / 3)) + [False] * int(n_trials - int(n_trials / 3) * 3)) data["Stop_Signal"] = ss data["Stop_Signal_RT"] = np.array([np.nan] * int(n_trials)) if adaptive is False: ssrt = generate_interval_frames(min_SSRT, max_SSRT, int(sum(ss))) data["Stop_Signal_RT"][ss == True] = randomize_without_repetition( list(ssrt)) else: data["Stop_Signal_RT"][ss == True] = np.array( [-1] * len(data["Stop_Signal_RT"][ss == True])) data = pd.DataFrame.from_dict(data) data = data.sample(len(data)).reset_index(drop=True) data = data.to_dict(orient="index") return (data) # First if testmode is False: ITI(2000, testmode=testmode, display_trigger=display_trigger) display_enemy() if display_trigger is True: trigger.stop() n.refresh() n.time.wait(150) display_enemy(stop=True) if display_trigger is True: trigger.stop() n.refresh() n.response(allow=["RIGHT", "LEFT"], time_max=1500) n.time.wait(1500) # Instructions n.newpage((24, 4, 64), auto_refresh=False) n.write("Wait! What's that?!", color="white", y=5, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2000) display_instructions( """Bad news, rookie, it seems like the rebels have upgraded some of their ships!\n\nIf we do not manage to shoot as SOON as the ennemy appears, they'll have time to activate counter-measures that will return our bullets and damage our ship.""", text_end="Press SPACE to continue.", display_trigger=display_trigger) display_instructions( """Shoot the incoming ships as FAST as possible, before a RED CROSS appears.\n\nDo not shoot at the RED CROSS, or it will harm us too!""", display_trigger=display_trigger) # Generate data if staircase is True: staircase = nk.staircase(signal=generate_interval_frames( 0, max_SSRT, int(max_SSRT / frame)), treshold=0.5, burn=0) data = generate_data(int(n_trials / 2), min_SSRT, max_SSRT, frame) else: data = generate_data(int(n_trials), min_SSRT, max_SSRT, frame) # Run trials if staircase is False: for trial in range(0, n_trials): data[trial].update( ITI(data[trial]["ITI"], testmode=testmode, display_trigger=display_trigger)) data[trial].update( display_stimulus(side=data[trial]["Stimulus_Side"], stop=data[trial]["Stop_Signal_RT"], testmode=testmode, display_trigger=display_trigger)) data[trial]["Trial_Order"] = trial + 1 # # With staircase # else: # for trial in range(0, int(n_trials/2)): # data[trial].update(ITI(data[trial]["ITI"], testmode = testmode, display_trigger = display_trigger)) # data[trial].update(display_stimulus(side=data[trial]["Stimulus_Side"], stop=data[trial]["Stop_Signal_RT"], testmode = testmode, display_trigger = display_trigger)) # if staircase is True: # if data[trial]["Stop_Signal"] is True: # if data[trial]['RT'] >= data[trial]["Stop_Signal_RT"]: # if data[trial]["Response"] == "Time_Max_Exceeded": # staircase.add_response(response=0, value=data[trial]["Stop_Signal_RT"]) # else: # staircase.add_response(response=1, value=data[trial]["Stop_Signal_RT"]) # data[trial]["Trial_Order"] = trial + 1 # # data_staircase = generate_data(int(n_trials/2), min_SSRT, max_SSRT, adaptive=True) # for i in list(data_staircase.keys()): # Replace keys # data_staircase[i + int(n_trials/2)] = data_staircase.pop(i) # data.update(data_staircase) # for trial in range(int(n_trials/2), n_trials): # data[trial].update(ITI(data[trial]["ITI"], testmode = testmode, display_trigger = display_trigger)) # if data[trial]["Stop_Signal_RT"] == -1: # data[trial]["Stop_Signal_RT"] = staircase.predict_next_value() # data[trial].update(display_stimulus(side=data[trial]["Stimulus_Side"], stop=data[trial]["Stop_Signal_RT"], testmode = testmode, display_trigger = display_trigger)) # if data[trial]["Stop_Signal"] is True: # if data[trial]['RT'] >= data[trial]["Stop_Signal_RT"]: # if data[trial]["Response"] == "Time_Max_Exceeded": # staircase.add_response(response=0, value=data[trial]["Stop_Signal_RT"]) # else: # staircase.add_response(response=1, value=data[trial]["Stop_Signal_RT"]) # data[trial]["Trial_Order"] = trial + 1 data = pd.DataFrame.from_dict(data, orient="index") return (data)
def display_stimulus(side="RIGHT", always_right=False, allies=False, stop=np.nan, time_max=1500, testmode=False, display_trigger=False): if stop == 0: if allies is False: display_enemy(side=side, stop=True) elif allies is True: display_enemy(side=side, stop=True, allies=True) else: if allies is False: display_enemy(side=side) elif allies is True: display_enemy(side=side, allies=True) if display_trigger is True: trigger.start() n.refresh() time = datetime.datetime.now() if always_right is True: if testmode is False: response, RT = n.response(allow="DOWN", time_max=time_max) else: response, RT = "DOWN", np.random.normal(750, 250) display_fire(side=side) display_explosion(side=side) else: if np.isnan(stop) or stop == 0: if testmode is False: response, RT = n.response(allow=["LEFT", "RIGHT"], time_max=time_max) else: response, RT = np.random.choice(["LEFT", "RIGHT"]), np.random.normal( 750, 250) else: if testmode is True: response = np.random.choice(["LEFT", "RIGHT", np.nan]) if pd.isna(response): RT = np.nan else: RT = np.random.normal(750, 250) else: RT = 0 response, RT = n.response(allow=["LEFT", "RIGHT"], time_max=stop) if response not in ["LEFT", "RIGHT"]: display_enemy(side=side, stop=True) n.refresh() response, RT = n.response(allow=["LEFT", "RIGHT"], time_max=time_max - stop) RT += stop if response in ["LEFT", "RIGHT", "DOWN"]: display_fire(side=response) display_explosion(side=response) if testmode is False: if response in ["LEFT", "RIGHT", "DOWN"]: if display_trigger is True: trigger.stop() n.refresh() n.time.wait(200) return ({ "Response": response, "RT": RT, "Trial_Time_Onset": time, "Trial_Time_End": datetime.datetime.now() })
# -*- coding: utf-8 -*- """ Test suite. Authors: Dominique Makowski Copyright: The Neuropsydia Development Team Site: https://github.com/neuropsychology/Neuropsydia.py """ import neuropsydia as n n.start() n.write("dupa") n.refresh() n.time.wait(100) n.newpage() n.image("img.jpg", fullscreen=True) n.refresh() n.time.wait(100) n.close() print("STATUS: PASSED.")
span = 2 # Initial span while number_of_fails < 3: # Do it while the number of errors is smaller than 3 sequence = np.random.randint( 10, size=span ) # Generate sequence of size span with ints ranging from 0 to 9 good_answer = "" # Initiate an empty good_answer for digit in sequence: # For every digit in the sequence... good_answer = good_answer + str( digit) # Add the current stimulus to the good answer n.newpage("grey") # Load a grey background n.time.wait(250) # Display an empty screen for 250 ms n.newpage("grey") # Load a grey background n.write(digit, size=3) # Load the stimulus n.refresh() # Display the stimulus on screen n.time.wait(1000) # Wait 1000 ms # Get answer n.newpage("white") answer = n.ask("Answer:") # Manage result if answer == good_answer: span = span + 1 # Increase span number_of_fails = 0 # Reset value else: number_of_fails = number_of_fails + 1 n.newpage() # Load a white background n.write("Max span: " + str(span - 1)) # Write task result
n.countdown() # Display countdown # Initialize the data storage with a dictionary containing empty lists data = {"Trial": [], "Stimulus": [], "ISI":[], "RT":[], "Response":[]} for trial in range(5): # Iterate over the number of trials stimulus = random.choice(["green", "red"]) # Select a stimulus type ISI = random.randrange(start=500, stop=2000, step=500) # Select the inter-stimuli interval (ISI) n.newpage("grey") # Fill the screen n.write("+") # Fixation cross n.refresh() # Diplay it on screen n.time.wait(ISI) # Wait n.circle(size=2, fill_color=stimulus) # Display the stimulus (filled with the color selected above) n.refresh() # Diplay it on screen response, RT = n.response(time_max=1500) # Wait until 1.5s and collect the response and its time # Categorize the response if response == "SPACE" and stimulus == "green": response_type = "HIT" # Hit if response != "SPACE" and stimulus == "green": response_type = "MISS" # Miss if response == "SPACE" and stimulus == "red": response_type = "FA" # False Alarm if response != "SPACE" and stimulus == "red": response_type = "CR" # Correct Rejection
# Initialize the data storage with a dictionary containing empty lists data = {"Trial": [], "Stimulus": [], "ISI":[], "RT":[], "Response":[]} n_trials = 10 # Number of trials for trial in range(n_trials): # Iterate over the number of trials stimulus = random.choice(["green", "green", "green", "red"]) # Select a stimulus type ISI = random.randrange(start=250, stop=1250, step=250) # Select the inter-stimuli interval (ISI) n.newpage("grey") # Fill the screen n.write("+") # Fixation cross n.refresh() # Diplay it on screen n.time.wait(ISI) # Wait n.circle(size=2, fill_color=stimulus) # Display the stimulus (filled with the color selected above) n.refresh() # Diplay it on screen response, RT = n.response(time_max=1000) # Wait until 1 s and collect the response and its time # Categorize the response if response == "SPACE" and stimulus == "green": response_type = "HIT" # Hit if response != "SPACE" and stimulus == "green": response_type = "MISS" # Miss if response == "SPACE" and stimulus == "red": response_type = "FA" # False Alarm if response != "SPACE" and stimulus == "red": response_type = "CR" # Correct Rejection
def sequence(cache, response_selection="None", inhibition=False, conflict=False): # Sequence Preparation if response_selection == "None": trials = [] for i in range(30): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Local_Angle":np.random.choice([-90, 0, 90, 180]), "Inhibition":False, "Conflict":"Neutral", "Response_Availability":True, "Response_Correct":0 } trials.append(trial) if response_selection == "Conditional": if conflict is False: if inhibition is False: trials = [] correct_responses = {-90:-90, 0:0, 90:90, 180:"NA"} for i in range(30): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":False, "Conflict":"Neutral", "Response_Availability":True } trial["Response_Correct"] = correct_responses[trial["Local_Angle"]] trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue", "white"]), "Local_Angle":180, "Inhibition":False, "Conflict":"Neutral", "Response_Availability":False, "Response_Correct":"NA" } trials.append(trial) np.random.shuffle(trials) else: trials = [] correct_responses = {-90:-90, 0:0, 90:90, 180:"NA"} for i in range(40): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":False, "Conflict":"Neutral", "Response_Availability":True } trial["Response_Correct"] = correct_responses[trial["Local_Angle"]] trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":False, "Conflict":"Neutral", "Response_Availability":False, "Response_Correct":"NA" } trials.append(trial) for i in range(6): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":"white", "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":True, "Conflict":"Neutral", "Response_Availability":True, "Response_Correct":"NA" } trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"circle", "Global_Color":"white", "Global_Angle":0, "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":True, "Conflict":"Neutral", "Response_Availability":False, "Response_Correct":"NA" } trials.append(trial) np.random.shuffle(trials) else: trials = [] correct_responses = {-90:-90, 0:0, 90:90, 180:"NA"} for i in range(40): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":False, "Conflict":"Incongruent", "Response_Availability":True } trial["Response_Correct"] = correct_responses[trial["Local_Angle"]] if trial["Local_Angle"] in [-90, 0]: trial["Global_Angle"] = trial["Local_Angle"] + 180 else: trial["Global_Angle"] = trial["Local_Angle"] - 180 trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":False, "Conflict":"Incongruent", "Response_Availability":False, "Response_Correct":"NA" } if trial["Local_Angle"] in [-90, 0]: trial["Global_Angle"] = trial["Local_Angle"] + 180 else: trial["Global_Angle"] = trial["Local_Angle"] - 180 trials.append(trial) for i in range(6): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":"white", "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":True, "Conflict":"Incongruent", "Response_Availability":True, "Response_Correct":"NA" } if trial["Local_Angle"] in [-90, 0]: trial["Global_Angle"] = trial["Local_Angle"] + 180 else: trial["Global_Angle"] = trial["Local_Angle"] - 180 trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":"white", "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":True, "Conflict":"Incongruent", "Response_Availability":False, "Response_Correct":"NA" } if trial["Local_Angle"] in [-90, 0]: trial["Global_Angle"] = trial["Local_Angle"] + 180 else: trial["Global_Angle"] = trial["Local_Angle"] - 180 trials.append(trial) np.random.shuffle(trials) for i in range(40): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":False, "Conflict":"Congruent", "Response_Availability":True } trial["Response_Correct"] = correct_responses[trial["Local_Angle"]] trial["Global_Angle"] = trial["Local_Angle"] trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":False, "Conflict":"Congruent", "Response_Availability":False, "Response_Correct":"NA" } trial["Global_Angle"] = trial["Local_Angle"] trials.append(trial) for i in range(6): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":"white", "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":np.random.choice([-90, 0, 90]), "Inhibition":True, "Conflict":"Congruent", "Response_Availability":True, "Response_Correct":"NA" } trial["Global_Angle"] = trial["Local_Angle"] trials.append(trial) for i in range(3): trial = { "Condition_Response_Selection":response_selection, "Condition_Inhibition":inhibition, "Condition_Conflict":conflict, "Global_Shape":"global", "Global_Color":"white", "Local_Shape":"local", "Local_Color":np.random.choice(["red", "yellow", "blue"]), "Local_Angle":180, "Inhibition":True, "Conflict":"Congruent", "Response_Availability":False, "Response_Correct":"NA" } trial["Global_Angle"] = trial["Local_Angle"] trials.append(trial) np.random.shuffle(trials) # Instructions n.newpage("white") n.write("Instructions", style="bold", y=8, size=1.5) if inhibition is False: instr_angles = [-90 , 0, 90, 180] instr_glob_angles = [-90 , 0, -90, 0] instr_glob_color = ["blue", "yellow", "white", "red"] instr_loc_color = ["red", "blue", "red", "yellow"] instr_responses = ["arrow", "arrow", "arrow", "cross"] else: instr_angles = [-90 , 0, 90, 180, -90] instr_glob_angles = [-90 , 0, -90, 0, -90] instr_glob_color = ["blue", "yellow", "red", "blue", "white"] instr_loc_color = ["red", "red", "blue", "yellow", "red"] instr_responses = ["arrow", "arrow", "arrow", "cross", "cross"] if conflict is True: instr_shapes = "_global" else: instr_shapes = "_circle" if response_selection == "None": intr_resp_angles = [0, 0, 0, 0, 0] instr_responses = ["arrow", "arrow", "arrow", "arrow"] if response_selection == "Conditional": intr_resp_angles = [-90 , 0, 90, 0, 0] x = -7.5 for pos, angle in enumerate(instr_angles): n.image(instr_glob_color[pos] + instr_shapes, size=6, y=1, x = x+pos*3.75, extension = ".png", path = "./Stimuli/", rotate=instr_glob_angles[pos]) n.image(instr_loc_color[pos] + "_local", size=6, y=1, x = x+pos*3.75, extension = ".png", path = "./Stimuli/", rotate=angle) n.image(instr_responses[pos], size=2.75, y=-5.5, x = x+pos*3.75, extension = ".png", path = "./Stimuli/", rotate=intr_resp_angles[pos]) n.refresh() n.write("Appuyez sur ENTRER pour commencer.", style="end") n.newpage('grey', auto_refresh=False) # Run trials data = run_trials(cache, trials) df = statistics(data) return(df)
"RT": [], "Condition": [], "Correct": [] } #============================================================================== # Part 1: Denomination #============================================================================== n.instructions("Press LEFT when RED, DOWN when GREEN and RIGHT when BLUE.") n_trials = 10 for trial in range(n_trials): n.newpage("grey") # Neutral grey background n.write("+") # Fixation cross n.refresh() # Display it n.time.wait(250) # Wait 250 ms stim_color = np.random.choice(["raw_red", "raw_green", "raw_blue"]) # Choose a color stim = "XXXX" n.newpage("grey") # Neutral grey background n.write(stim, style="bold", color=stim_color, size=3) # Load the stimulus n.refresh() # Display it answer, RT = n.response() # Record response and response time # Append trial info to data["Stimulus"].append(stim) data["Stimulus_Color"].append(stim_color) data["Answer"].append(answer) data["RT"].append(RT)
# Initialize values number_of_fails = 0 # Initial number of errors span = 2 # Initial span while number_of_fails < 3: sequence = np.random.randint(10, size=span) # Generate sequence good_answer = "" # Transform sequence of integers into string for digit in sequence: # For every element in the sequence... good_answer = good_answer + str( digit) # Add the current stimulus to sequence n.newpage("grey") n.time.wait(250) # Display an empty screen for 250 ms n.newpage("grey") # Load a grey background n.write(digit, size=3) # Load the stimulus n.refresh() # Render the stimulus on screen n.time.wait(1000) # Wait 1000 ms # Get answer n.newpage("white") answer = n.ask("Answer:") # Manage result if answer == good_answer: span = span + 1 # Increase span number_of_fails = 0 # Reset value else: number_of_fails = number_of_fails + 1 n.newpage() # Load a white background n.write("Max span: " + str(span - 1)) # Write task result
def statistics(data): n.newpage("white") n.write("Veuillez patienter...", y=-9, color="blue") n.refresh() df = pd.DataFrame.from_dict(data) # Scores df["Response_Correct_Orientation"] = [angle_to_orientation[angle] for angle in df["Response_Correct"]] df["Correct"] = np.where(df["Response"]==df["Response_Correct_Orientation"], 1, 0) df["Color_Congruence"] = np.where(df["Local_Color"]==df["Global_Color"], True, False) # Response Type - STD # df = df.reset_index() # response_type = [] # for row in range(len(df)): # if df["Correct"][row]==1 and df["Response_Correct_Orientation"][row]!="NA": # response_type.append("Hit") # if df["Correct"][row]==1 and df["Response_Correct_Orientation"][row]=="NA": # response_type.append("Correct_Rejection") # if df["Correct"][row]==0 and df["Response_Correct_Orientation"][row]!="NA": # response_type.append("Miss") # if df["Correct"][row]==0 and df["Response_Correct_Orientation"][row]=="NA": # response_type.append("False_Alarm") # df["Response_Type"] = response_type # Luminance and contrast luminance_global = [] luminance_local = [] contrast = [] for row in range(len(df)): luminance_global.append(n.color_luminance(colors_ref[df["Global_Color"][row]])) luminance_local.append(n.color_luminance(colors_ref[df["Local_Color"][row]])) contrast.append(n.color_contrast(colors_ref[df["Global_Color"][row]], colors_ref[df["Local_Color"][row]])) df["Luminance_Global"] = luminance_global df["Luminance_Local"] = luminance_local df["Contrast"] = contrast if df["Condition_Conflict"].values[0] == False: dfs = [df.reindex()] else: dfs = [df[df["Conflict"]=="Congruent"].sort_values("Order").reindex(), df[df["Conflict"]=="Incongruent"].sort_values("Order").reindex()] for data in dfs: cumulative_average = [] cumulative_sd = [] cumulative_se = [] for row in range(len(data)): global sliced sliced = data.loc[0:row] sliced = sliced[(sliced["Correct"]==1) & (sliced["Response_Correct"].map(str)!="NA")]["RT"] cumulative_average.append(sliced.mean()) cumulative_sd.append(sliced.std()) if len(sliced.dropna()) > 1: cumulative_se.append(scipy.stats.sem(sliced)) else: cumulative_se.append(np.nan) data["Cumulative_Average"] = cumulative_average data['Cumulative_SD'] = cumulative_sd data['Cumulative_SE'] = cumulative_se df = pd.concat(dfs) df.sort_values("Order") df = df.replace("NA", np.nan) return(df)
"Answer": [], "RT": [], "Condition": [], "Correct": []} #============================================================================== # Part 1: Denomination #============================================================================== n.instructions("Press LEFT when RED, DOWN when GREEN and RIGHT when BLUE.") n_trials = 10 for trial in range(n_trials): n.newpage("grey") # Neutral grey background n.write("+") # Fixation cross n.refresh() # Display it n.time.wait(250) # Wait 250 ms stim_color = np.random.choice(["raw_red", "raw_green", "raw_blue"]) # Choose a color stim = "XXXX" n.newpage("grey") # Neutral grey background n.write(stim, style="bold", color=stim_color, size=3) # Load the stimulus n.refresh() # Display it answer, RT = n.response() # Record response and response time # Append trial info to data["Stimulus"].append(stim) data["Stimulus_Color"].append(stim_color) data["Answer"].append(answer) data["RT"].append(RT) data["Condition"].append("Neutral")
def processing_speed(n_trials=60, testmode=False, display_trigger=False): # Data creation data = { "Stimulus_Side": ["RIGHT"] * int(n_trials / 2) + ["LEFT"] * int(n_trials / 2), "ITI": list(generate_interval_frames(500, 1500, n_trials / 2)) * 2 } data = pd.DataFrame.from_dict(data) data = data.sample(len(data)).reset_index(drop=True) data = data.to_dict(orient="index") # Instructions if testmode is False: n.newpage((24, 4, 64), auto_refresh=False) n.write("One year ago...", color="white", y=2, size=1.5) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(1500) n.write("...deep inside the REBEL territory...", color="white", y=0, size=1.2) if display_trigger is True: trigger.stop() n.refresh() n.time.wait(2500) display_instructions( """Okay, pilot, here's the mission briefing.\n\nThe commander requires you to destroy all the incoming enemies... Nothing too hard for our best pilot!""", text_end="Press SPACE to continue.", display_trigger=display_trigger) display_instructions( """Just destroy them as fast as your can with your famous auto-aiming cannons.\n\nPress DOWN to shoot whenever an enemy appears.""", display_trigger=display_trigger) for trial in range(n_trials): data[trial].update( ITI(data[trial]["ITI"], testmode=testmode, display_trigger=display_trigger)) data[trial].update( display_stimulus(side=data[trial]["Stimulus_Side"], always_right=True, testmode=testmode, display_trigger=display_trigger)) data[trial]["Trial_Order"] = trial + 1 # Explosion! if testmode is False: ITI(1000, testmode=testmode, display_trigger=display_trigger) display_explosion(side="CENTRE") if display_trigger is True: trigger.stop() n.refresh() n.time.wait(800) data = pd.DataFrame.from_dict(data, orient="index") return (data)
# Initialize values number_of_fails = 0 # Initial number of errors span = 2 # Initial span while number_of_fails < 3: # Do it while the number of errors is smaller than 3 sequence = np.random.randint(10, size=span) # Generate sequence of size span with ints ranging from 0 to 9 good_answer = "" # Initiate an empty good_answer for digit in sequence: # For every digit in the sequence... good_answer = good_answer + str(digit) # Add the current stimulus to the good answer n.newpage("grey") # Load a grey background n.time.wait(250) # Display an empty screen for 250 ms n.newpage("grey") # Load a grey background n.write(digit, size=3) # Load the stimulus n.refresh() # Display the stimulus on screen n.time.wait(1000) # Wait 1000 ms # Get answer n.newpage("white") answer = n.ask("Answer:") # Manage result if answer == good_answer: span = span + 1 # Increase span number_of_fails = 0 # Reset value else: number_of_fails = number_of_fails + 1 n.newpage() # Load a white background n.write("Max span: " + str(span-1)) # Write task result
def fixation_cross(time=3000): n.newpage("grey", auto_refresh=False) n.write("+", size=2) trigger.stop() n.refresh() n.time.wait(time)