Browse Source

Updated a number of settings. Forgot to commit for a while. -MT

master
mike 6 years ago
parent
commit
fd6ae585df
  1. 106
      SaccadePursuit.py
  2. 430
      SaccadePursuitEyeTracking.py
  3. 0
      eyelinker.py
  4. 28
      template.py

106
SaccadePursuit.py

@ -71,12 +71,14 @@ class SPtask(template.BaseExperiment):
stim_color, pursuit_frequencies, stim_color, pursuit_frequencies,
saccade_distance, saccade_time, saccade_distance, saccade_time,
stimulus_size, saccade_fixation_color, stimulus_size, saccade_fixation_color,
number_of_saccade_lights,
fixation_size, pursuit_distance, fixation_size, pursuit_distance,
necker_time, necker_color, necker_time, necker_color,
necker_scale, necker_bg_color, necker_scale, necker_bg_color,
necker_file, rivalry_file1, rivalry_file2, necker_file, rivalry_file1, rivalry_file2,
fixation_trial_time, rivalry_time, fixation_trial_time, rivalry_time,
rivalry_scale,rivalry_border_color, rivalry_height, rivalry_width,
rivalry_border_color,
rivalry_border_width, rivalry_distance, rivalry_border_width, rivalry_distance,
new_trial_sound, new_trial_sound,
questionaire_dict=None, questionaire_dict=None,
@ -84,33 +86,35 @@ class SPtask(template.BaseExperiment):
**kwargs): **kwargs):
self.new_trial_sound = new_trial_sound self.new_trial_sound = new_trial_sound
# Pursuit # Pursuit
self.pursuit_time = pursuit_time self.pursuit_time = pursuit_time
self.pursuit_distance = pursuit_distance self.pursuit_distance = pursuit_distance
self.pursuit_frequencies = pursuit_frequencies self.pursuit_frequencies = pursuit_frequencies
# Saccade # Saccade
self.stim_color = stim_color self.stim_color = stim_color
self.saccade_time = saccade_time self.saccade_time = saccade_time
self.stimulus_size = stimulus_size self.stimulus_size = stimulus_size
self.saccade_distance = saccade_distance self.saccade_distance = saccade_distance
self.saccade_fixation_color = saccade_fixation_color self.saccade_fixation_color = saccade_fixation_color
self.number_of_saccade_lights = number_of_saccade_lights
# Fixation # Fixation
self.fixation_size = fixation_size self.fixation_size = fixation_size
self.fixation_trial_time = fixation_trial_time self.fixation_trial_time = fixation_trial_time
# Necker # Necker
self.necker_time = necker_time self.necker_time = necker_time
self.necker_color = necker_color self.necker_color = necker_color
self.necker_scale = necker_scale self.necker_scale = necker_scale
self.necker_bg_color = necker_bg_color self.necker_bg_color = necker_bg_color
self.necker_file = necker_file self.necker_file = necker_file
# Rivalry # Rivalry
self.rivalry_time = rivalry_time self.rivalry_time = rivalry_time
self.rivalry_scale = rivalry_scale self.rivalry_height = rivalry_height
self.rivalry_width = rivalry_width
self.rivalry_file1 = rivalry_file1 self.rivalry_file1 = rivalry_file1
self.rivalry_file2 = rivalry_file2 self.rivalry_file2 = rivalry_file2
self.rivalry_border_color = rivalry_border_color self.rivalry_border_color = rivalry_border_color
@ -118,7 +122,7 @@ class SPtask(template.BaseExperiment):
self.rivalry_distance = rivalry_distance self.rivalry_distance = rivalry_distance
self.questionaire_dict = questionaire_dict self.questionaire_dict = questionaire_dict
super(SPtask, self).__init__(**kwargs) super(SPtask, self).__init__(**kwargs)
def chdir(self): def chdir(self):
@ -140,12 +144,16 @@ class SPtask(template.BaseExperiment):
""" """
trial_list = [] trial_list = []
saccade_locations = list(range(-self.saccade_distance,0,1)) #saccade_locations = list(range(-self.saccade_distance,0,1))
for x in range(self.saccade_distance): #for x in range(self.saccade_distance):
saccade_locations.append(x+1) # saccade_locations.append(x+1)
random.shuffle(saccade_locations) #random.shuffle(saccade_locations)
temp1 = random.sample(range(1,self.saccade_distance+1),self.number_of_saccade_lights)
temp2 = random.sample(range(1,self.saccade_distance+1),self.number_of_saccade_lights)
saccade_locations = [x*-1 for x in temp1] + temp2
counter = 0 counter = 0
for num_trials in range(numTrials): for num_trials in range(numTrials):
if condition == 'Pursuit': if condition == 'Pursuit':
@ -184,7 +192,7 @@ class SPtask(template.BaseExperiment):
trial_type -- Whether this trial is same or different. trial_type -- Whether this trial is same or different.
""" """
locs = [pursuit_frequency,0] locs = [pursuit_frequency,0]
trial = { trial = {
'locations': locs, 'locations': locs,
'trial_time': trial_time, 'trial_time': trial_time,
@ -201,18 +209,21 @@ class SPtask(template.BaseExperiment):
break_text = 'Please take a short break. Press any key to continue.' break_text = 'Please take a short break. Press any key to continue.'
self.display_text_screen(text=break_text, bg_color=[0, 0, 0]) self.display_text_screen(text=break_text, bg_color=[0, 0, 0])
def display_fixation(self, wait_time, necker_bg_color=[-1,-1,-1]): def display_fixation(self, wait_time, tracker, necker_bg_color=[-1,-1,-1]):
"""Displays a fixation cross. A helper function for self.run_trial. """Displays a fixation cross. A helper function for self.run_trial.
Parameters: Parameters:
wait_time -- The amount of time the fixation should be displayed for. wait_time -- The amount of time the fixation should be displayed for.
""" """
self.experiment_window.color = necker_bg_color self.experiment_window.color = necker_bg_color
stim = psychopy.visual.TextStim( stim = psychopy.visual.TextStim(
self.experiment_window, text='+', color=self.stim_color, height=self.fixation_size, units='deg') self.experiment_window, text='+', color=self.stim_color, height=self.fixation_size, units='deg')
if tracker:
tracker.send_message('Start Fixation')
for frameN in range(int(round(wait_time*60))): for frameN in range(int(round(wait_time*60))):
stim.draw() stim.draw()
self.experiment_window.flip() self.experiment_window.flip()
@ -225,9 +236,9 @@ class SPtask(template.BaseExperiment):
should be displayed. should be displayed.
colors -- A list of colors describing what should be drawn at each coordinate. colors -- A list of colors describing what should be drawn at each coordinate.
""" """
color = self.stim_color color = self.stim_color
stim = psychopy.visual.Circle( stim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2, self.experiment_window, radius=self.stimulus_size/2,
pos=coordinates, fillColor=color, pos=coordinates, fillColor=color,
@ -235,7 +246,7 @@ class SPtask(template.BaseExperiment):
fixation = psychopy.visual.TextStim( fixation = psychopy.visual.TextStim(
self.experiment_window, text='+', color=self.saccade_fixation_color, self.experiment_window, text='+', color=self.saccade_fixation_color,
height=self.fixation_size, units='deg') height=self.fixation_size, units='deg')
stimList = [] stimList = []
temp = list(range(-self.saccade_distance,self.saccade_distance,1)) temp = list(range(-self.saccade_distance,self.saccade_distance,1))
for circleN in temp: for circleN in temp:
@ -243,14 +254,14 @@ class SPtask(template.BaseExperiment):
tempCoord = circleN tempCoord = circleN
else: else:
tempCoord = circleN+1 tempCoord = circleN+1
tempStim = psychopy.visual.Circle( tempStim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2, self.experiment_window, radius=self.stimulus_size/2,
pos=[tempCoord,0], fillColor=self.saccade_dot_color, pos=[tempCoord,0], fillColor=self.saccade_dot_color,
lineColor=self.saccade_dot_color, units='deg') lineColor=self.saccade_dot_color, units='deg')
stimList.append(tempStim) stimList.append(tempStim)
if tracker:
tracker.send_message('Start Stim') tracker.send_message('Start Stim')
for frameN in range(int(round(stim_time*60))): for frameN in range(int(round(stim_time*60))):
for s in stimList: for s in stimList:
s.draw() s.draw()
@ -258,7 +269,8 @@ class SPtask(template.BaseExperiment):
stim.draw() stim.draw()
self.experiment_window.flip() self.experiment_window.flip()
#print(psychopy.tools.monitorunittools.deg2pix(stim.pos, self.experiment_monitor)) #print(psychopy.tools.monitorunittools.deg2pix(stim.pos, self.experiment_monitor))
tracker.send_message('End Stim') if tracker:
tracker.send_message('End Stim')
def display_saccade_fixation(self, stim_time): def display_saccade_fixation(self, stim_time):
"""Displays the stimuli. A helper function for self.run_saccade_trial. """Displays the stimuli. A helper function for self.run_saccade_trial.
@ -268,11 +280,11 @@ class SPtask(template.BaseExperiment):
should be displayed. should be displayed.
colors -- A list of colors describing what should be drawn at each coordinate. colors -- A list of colors describing what should be drawn at each coordinate.
""" """
fixation = psychopy.visual.TextStim( fixation = psychopy.visual.TextStim(
self.experiment_window, text='+', color=self.stim_color, self.experiment_window, text='+', color=self.stim_color,
height=self.fixation_size, units='deg') height=self.fixation_size, units='deg')
stimList = [] stimList = []
temp = list(range(-self.saccade_distance,self.saccade_distance,1)) temp = list(range(-self.saccade_distance,self.saccade_distance,1))
for circleN in temp: for circleN in temp:
@ -285,14 +297,14 @@ class SPtask(template.BaseExperiment):
pos=[tempCoord,0], fillColor=self.saccade_dot_color, pos=[tempCoord,0], fillColor=self.saccade_dot_color,
lineColor=self.saccade_dot_color, units='deg') lineColor=self.saccade_dot_color, units='deg')
stimList.append(tempStim) stimList.append(tempStim)
for frameN in range(int(round(stim_time*60))): for frameN in range(int(round(stim_time*60))):
for s in stimList: for s in stimList:
s.draw() s.draw()
fixation.draw() fixation.draw()
self.experiment_window.flip() self.experiment_window.flip()
def display_pursuit(self, stim_frequency, stim_time): def display_pursuit(self, stim_frequency, stim_time, tracker):
"""Displays a pursuit stimululus. A helper function for self.run_pursuit_trial. """Displays a pursuit stimululus. A helper function for self.run_pursuit_trial.
Parameters: Parameters:
@ -300,9 +312,9 @@ class SPtask(template.BaseExperiment):
point of the stimulus. point of the stimulus.
color -- A color describing what should be drawn. color -- A color describing what should be drawn.
""" """
color = self.stim_color color = self.stim_color
Xposition = [0] Xposition = [0]
num_frames_per_second = 60 num_frames_per_second = 60
counter = 0 counter = 0
@ -315,7 +327,7 @@ class SPtask(template.BaseExperiment):
for time in range(stim_frames): for time in range(stim_frames):
Xposition.append(math.sin(freq*math.radians((time+1)*360/num_frames_per_second))*self.pursuit_distance) Xposition.append(math.sin(freq*math.radians((time+1)*360/num_frames_per_second))*self.pursuit_distance)
counter += 1 counter += 1
stim = psychopy.visual.Circle( stim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2, self.experiment_window, radius=self.stimulus_size/2,
pos=(0,0), fillColor=color, pos=(0,0), fillColor=color,
@ -325,6 +337,9 @@ class SPtask(template.BaseExperiment):
stim.draw() stim.draw()
self.experiment_window.flip() self.experiment_window.flip()
if tracker:
tracker.send_message('Start Stim')
for Xpos in Xposition: for Xpos in Xposition:
stim.pos = (Xpos,0) stim.pos = (Xpos,0)
stim.draw() stim.draw()
@ -344,6 +359,8 @@ class SPtask(template.BaseExperiment):
stim.size *= self.necker_scale stim.size *= self.necker_scale
stim.setColor(self.necker_color, 'rgb255') stim.setColor(self.necker_color, 'rgb255')
responses = [] responses = []
if tracker:
tracker.send_message('Start Stim')
for frameN in range(stim_time*60): for frameN in range(stim_time*60):
response = psychopy.event.getKeys() response = psychopy.event.getKeys()
if response: if response:
@ -365,16 +382,17 @@ class SPtask(template.BaseExperiment):
def display_rivalry(self, stim_time, tracker): def display_rivalry(self, stim_time, tracker):
color = self.rivalry_border_color color = self.rivalry_border_color
lineSize = self.rivalry_border_width lineSize = self.rivalry_border_width
imDist = self.rivalry_distance stimPos = self.experiment_window.size[0]/4
stimPos = psychopy.tools.monitorunittools.pix2deg(stimPos,self.experiment_monitor)
stim1 = psychopy.visual.ImageStim( stim1 = psychopy.visual.ImageStim(
self.experiment_window, self.experiment_window,
image=self.rivalry_file1, pos=(-imDist,0)) image=self.rivalry_file1, pos=(-stimPos,0))
stim1.size *= self.rivalry_scale stim1.size = (self.rivalry_width, self.rivalry_height)
stim2 = psychopy.visual.ImageStim( stim2 = psychopy.visual.ImageStim(
self.experiment_window, self.experiment_window,
image=self.rivalry_file2, pos=(imDist,0)) image=self.rivalry_file2, pos=(stimPos,0))
stim2.size *= self.rivalry_scale stim2.size = (self.rivalry_width, self.rivalry_height)
borderScale = stim1.size[0]*0.4 borderScale = stim1.size[0]*0.4
borderWidth1 = stim1.size[0]+borderScale borderWidth1 = stim1.size[0]+borderScale
borderHeight1 = stim1.size[1]+borderScale borderHeight1 = stim1.size[1]+borderScale
@ -408,6 +426,8 @@ class SPtask(template.BaseExperiment):
lineColor=color, lineWidth=lineSize) lineColor=color, lineWidth=lineSize)
responses = [] responses = []
if tracker:
tracker.send_message('Start Stim')
for frameN in range(stim_time*60): for frameN in range(stim_time*60):
response = psychopy.event.getKeys() response = psychopy.event.getKeys()
if response: if response:
@ -447,19 +467,19 @@ class SPtask(template.BaseExperiment):
if trial['trial_type']=='Necker': if trial['trial_type']=='Necker':
freq = self.display_necker(trial['trial_time'], tracker) freq = self.display_necker(trial['trial_time'], tracker)
elif trial['trial_type']=='Pursuit': elif trial['trial_type']=='Pursuit':
self.display_pursuit(trial['pursuit_frequency'],trial['trial_time']) self.display_pursuit(trial['pursuit_frequency'],trial['trial_time'],tracker)
psychopy.sound.Sound(self.new_trial_sound).play() psychopy.sound.Sound(self.new_trial_sound).play()
freq = trial['pursuit_frequency'] freq = trial['pursuit_frequency']
elif trial['trial_type']=='Fixation': elif trial['trial_type']=='Fixation':
self.display_fixation(trial['trial_time']) self.display_fixation(trial['trial_time'],tracker)
elif trial['trial_type']=='Rivalry': elif trial['trial_type']=='Rivalry':
freq = self.display_rivalry(trial['trial_time'], tracker) freq = self.display_rivalry(trial['trial_time'], tracker)
else: else:
self.display_saccade(trial['locations'], trial['trial_time'], tracker) self.display_saccade(trial['locations'], trial['trial_time'], tracker)
psychopy.sound.Sound(self.new_trial_sound).play() psychopy.sound.Sound(self.new_trial_sound).play()
data = { data = {
'Subject': self.experiment_info['Subject Identifier'], 'Subject': self.experiment_info['Subject ID'],
'Block': block_num, 'Block': block_num,
'Trial': trial_num, 'Trial': trial_num,
'Timestamp': psychopy.core.getAbsTime(), 'Timestamp': psychopy.core.getAbsTime(),
@ -475,6 +495,6 @@ class SPtask(template.BaseExperiment):
# If you call this script directly, directs you to correct file # If you call this script directly, directs you to correct file
if __name__ == '__main__': if __name__ == '__main__':
warnings.showwarning( warnings.showwarning(
'Please run SaccadePursuitEyeTracking.py', 'Please run SaccadePursuitEyeTracking.py',
Warning,'SaccadePursuit.py',414) Warning,'SaccadePursuit.py',414)
warnings.formatwarning = warning_on_one_line warnings.formatwarning = warning_on_one_line

430
SaccadePursuitEyeTracking.py

@ -16,6 +16,8 @@ import random
import sys import sys
import traceback import traceback
import subprocess import subprocess
import math
import numpy
# Necesssary to access psychopy paths # Necesssary to access psychopy paths
import psychopy # noqa:F401 import psychopy # noqa:F401
@ -26,22 +28,26 @@ import SaccadePursuit
# Experimental Parameters # Experimental Parameters
monitor_name = 'testMonitor' monitor_name = 'testMonitor'
monitor_width = 41 monitor_width = 41 #25.8 height
distance_to_monitor = 74 distance_to_monitor = 74
monitor_px = [1440,900] monitor_px = [1440,900]
window_screen = 1 window_screen = 1
disableTracker = True # For Debugging disableTracker = False # For Debugging
isi_time = 2 # Interstimulus Interval isi_time = 2 # Interstimulus Interval
data_directory = os.path.join( data_directory = os.path.join(
os.path.expanduser('~'), 'Desktop', 'ExperimentalData', 'SaccadePursuitEyeTracking') os.path.expanduser('~'), 'Desktop', 'ExperimentalData', 'SaccadePursuitEyeTracking')
image_directory = os.path.join(os.getcwd(),'Images') # image_directory = os.path.join(os.getcwd(),'Images')
image_directory = os.path.join(
os.path.expanduser('~'), 'Desktop','SaccadePursuitExperiment','Images')
new_trial_sound = 'A' new_trial_sound = 'A'
instHeight = 6
# Saccade / Antisaccade Parameters # Saccade / Antisaccade Parameters
number_of_saccade_trials = 1 number_of_saccade_trials = 1
number_of_saccade_blocks = 1 number_of_saccade_blocks = 1
saccade_distance = 15 # Degrees per direction saccade_distance = 15 # Degrees per direction
number_of_saccade_lights = 7 # Number of active lights per direction
saccade_time = 3 # Maximum Time saccade_time = 3 # Maximum Time
stimulus_size = 0.3 stimulus_size = 0.3
stim_color = [1,-1,-1] stim_color = [1,-1,-1]
@ -54,8 +60,8 @@ antisaccade_file_scale = 1
number_of_pursuit_trials = 1 number_of_pursuit_trials = 1
number_of_pursuit_blocks = 1 number_of_pursuit_blocks = 1
pursuit_distance = 15 pursuit_distance = 15
pursuit_frequencies = [0.1,0.2,0.4] pursuit_frequencies = [0.1,0.2,0.3]
pursuit_time = [40,20,15] pursuit_time = [40,20,13.33]
# Necker Cube Parameters # Necker Cube Parameters
number_of_necker_trials = 1 number_of_necker_trials = 1
@ -78,12 +84,14 @@ fixation_trial_time = 15
number_of_rivalry_trials = 1 number_of_rivalry_trials = 1
number_of_rivalry_blocks = 1 number_of_rivalry_blocks = 1
rivalry_time = 90 rivalry_time = 90
rivalry_scale = 2.5 #rivalry_scale = 2.5
rivalry_height = 1.5
rivalry_width = 1
rivalry_distance = 3
rivalry_file1 = os.path.join(image_directory,'house4n_11-160.tif') rivalry_file1 = os.path.join(image_directory,'house4n_11-160.tif')
rivalry_file2 = os.path.join(image_directory,'face2nS_11-160.tif') rivalry_file2 = os.path.join(image_directory,'face2nS_11-160.tif')
rivalry_border_color = [190,190,190] rivalry_border_color = [190,190,190]
rivalry_border_width = 5 rivalry_border_width = 5
rivalry_distance = 4
response_box_file = os.path.join(image_directory,'ResponseBox3.tif') response_box_file = os.path.join(image_directory,'ResponseBox3.tif')
response_box_scale = 0.22 response_box_scale = 0.22
@ -101,43 +109,42 @@ data_fields = [
# Add additional questions here # Add additional questions here
questionaire_dict = { questionaire_dict = {
'Run Fixation': True,
'Run Smooth Pursuit': True, 'Run Smooth Pursuit': True,
'Run Saccade': True, 'Run Saccade': True,
'Run Anti-Saccade': True, 'Run Anti-Saccade': True,
'Run Necker Cube': True, # 'Run Necker Cube': False,
'Run Binocular Rivalry': False, 'Run Binocular Rivalry': True,
} }
questionaire_order=[ questionaire_order=[
'Subject Identifier', 'Subject ID',
'Age', 'Session',
'Timepoint',
'Experimenter Initials', 'Experimenter Initials',
'Gender', 'Gender',
'Run Fixation',
'Run Smooth Pursuit', 'Run Smooth Pursuit',
'Run Saccade', 'Run Saccade',
'Run Anti-Saccade', 'Run Anti-Saccade',
'Run Necker Cube', # 'Run Necker Cube',
'Run Binocular Rivalry', 'Run Binocular Rivalry',
] ]
instruct_text = [ instruct_text = [
('Welcome to the experiment. Press any key to continue.'), ('Welcome to the experiment'),
('In this experiment you will be following targets.\n\n' (#'In this experiment you will be following targets.\n\n'
'Each trial will start with a fixation cross. ' # 'Each trial will start with a fixation cross. '
'Focus on the fixation cross until a stimulus appears.\n\n' # 'Focus on the fixation cross until a stimulus appears.\n\n'
'In the first three phases, you will follow the stimuli. ' # 'In the first three phases, you will follow the stimuli. '
'In the fourth phase, you will focus on the ' # 'In the fourth phase, you will focus on the '
'opposite side of center cross at an ' # 'opposite side of center cross at an '
'equal distance as the stimulus. In the fifth ' # 'equal distance as the stimulus. In the fifth '
'phase, you will see a cube, and are to respond as ' # 'phase, you will see a cube, and are to respond as '
'indicated.' # 'indicated.'
'\n\n' # '\n\n'
'Do not move your head during the trials of this ' 'Do not move your head during the trials of this '
'experiment. Move only your eyes to follow the targets.' 'experiment.\n\nMove only your eyes.\n'),
'You will be offered breaks in between sections.\n\n' # 'You will be offered rests between sections.\n\n'
'Press any key to continue.'), # 'Press any key to continue.'),
] ]
saccade_instruct_text = ( saccade_instruct_text = (
@ -150,7 +157,7 @@ saccade_instruct_text = (
'move your eyes back to the fixation cross.\n\n' 'move your eyes back to the fixation cross.\n\n'
'Try not to blink while a red dot is displayed.\n\n' 'Try not to blink while a red dot is displayed.\n\n'
'You can then blink or close your eyes to rest for a few seconds.\n\n' 'You can then blink or close your eyes to rest for a few seconds.\n\n'
'Press any key to continue.' # 'Press any key to continue.'
) )
antisaccade_instruct_text = ( antisaccade_instruct_text = (
@ -164,7 +171,7 @@ antisaccade_instruct_text = (
'to the fixation point after each target disappears.\n\n' 'to the fixation point after each target disappears.\n\n'
'Try not to blink while a red dot is displayed.\n\n' 'Try not to blink while a red dot is displayed.\n\n'
'You can then blink or close your eyes to rest for a few seconds.\n\n' 'You can then blink or close your eyes to rest for a few seconds.\n\n'
'Press any key to continue.' # 'Press any key to continue.'
) )
pursuit_instruct_text = ( pursuit_instruct_text = (
@ -176,17 +183,7 @@ pursuit_instruct_text = (
'two seconds.\n\n' 'two seconds.\n\n'
'Try not to blink while the dot is moving.\n\n' 'Try not to blink while the dot is moving.\n\n'
'You can then blink or close your eyes to rest for a few seconds.\n\n' 'You can then blink or close your eyes to rest for a few seconds.\n\n'
'Press any key to continue.' # 'Press any key to continue.'
)
fixation_instruct_text = (
'For this experiment, we want to know how well you can keep '
'your eyes fixed on a target without moving. When the cross '
'appears, please fixate on it.\n\n'
'Try not to move your eyes from the cross or blink until it '
'disappears.\n\n'
'You can then blink or close your eyes to rest for a few seconds.\n\n'
'Press any key to continue.'
) )
necker_instruct_text = ( necker_instruct_text = (
@ -199,7 +196,7 @@ necker_instruct_text = (
'Try not to blink after the cube appears.\n\n' 'Try not to blink after the cube appears.\n\n'
'You can blink or close your eyes to rest after the cube ' 'You can blink or close your eyes to rest after the cube '
'disappears.\n\n' 'disappears.\n\n'
'Press any key to continue.' # 'Press any key to continue.'
) )
rivalry_instruct_text = ( rivalry_instruct_text = (
@ -210,7 +207,7 @@ rivalry_instruct_text = (
'the face and house, press the center button.\n\n' 'the face and house, press the center button.\n\n'
'You can blink or close your eyes to rest for a few seconds ' 'You can blink or close your eyes to rest for a few seconds '
'after the pictures disappear.\n\n' 'after the pictures disappear.\n\n'
'Press any key to continue.' # 'Press any key to continue.'
) )
def convert_color_value(color): def convert_color_value(color):
@ -226,12 +223,13 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.quit = False # Needed because eyetracker must shut down self.quit = False # Needed because eyetracker must shut down
self.tracker = None self.tracker = None
self.disable_tracker = disableTracker self.disableTracker = disableTracker
self.window_screen = window_screen self.window_screen = window_screen
self.monitor_px = monitor_px self.monitor_px = monitor_px
self.number_of_saccade_trials = number_of_saccade_trials self.number_of_saccade_trials = number_of_saccade_trials
self.number_of_saccade_blocks = number_of_saccade_blocks self.number_of_saccade_blocks = number_of_saccade_blocks
self.number_of_saccade_lights = number_of_saccade_lights
self.number_of_pursuit_trials = number_of_pursuit_trials self.number_of_pursuit_trials = number_of_pursuit_trials
self.number_of_pursuit_blocks = number_of_pursuit_blocks self.number_of_pursuit_blocks = number_of_pursuit_blocks
self.number_of_necker_trials = number_of_necker_trials self.number_of_necker_trials = number_of_necker_trials
@ -246,6 +244,7 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
self.response_box_scale = response_box_scale self.response_box_scale = response_box_scale
self.antisaccade_instruct_file = antisaccade_instruct_file self.antisaccade_instruct_file = antisaccade_instruct_file
self.antisaccade_file_scale = antisaccade_file_scale self.antisaccade_file_scale = antisaccade_file_scale
self.instHeight = instHeight
super(EyeTrackingSaccadePursuit, self).__init__(**kwargs) super(EyeTrackingSaccadePursuit, self).__init__(**kwargs)
@ -255,12 +254,18 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
self.display_text_screen('Quiting...', wait_for_input=False) self.display_text_screen('Quiting...', wait_for_input=False)
if self.tracker: if self.tracker:
fName = os.path.join(self.data_directory, fName = os.path.join(self.data_directory,
'ETSP' + self.experiment_info['Subject Identifier'] + '.edf') self.experiment_info['Subject ID'] + self.experiment_info['Timepoint'] + '.edf')
fName2 = os.path.join(self.data_directory,
'ETSP_' + self.experiment_info['Subject ID'] + self.experiment_info['Session'] \
+ self.experiment_info['Timepoint'] + '.edf')
self.tracker.set_offline_mode() self.tracker.set_offline_mode()
self.tracker.close_edf() self.tracker.close_edf()
self.tracker.transfer_edf() self.tracker.transfer_edf()
self.tracker.close_connection() self.tracker.close_connection()
subprocess.call(['edf2asc',fName]) #subprocess.call(['rename',fName, fName2])
os.rename(fName, fName2)
subprocess.call(['edf2asc',fName2])
super(EyeTrackingSaccadePursuit, self).quit_experiment() super(EyeTrackingSaccadePursuit, self).quit_experiment()
def run(self): def run(self):
@ -268,7 +273,7 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
print('Note: EDF file will be overwritten if identical subject identifiers are used!') print('Note: EDF file will be overwritten if identical subject identifiers are used!')
ok = self.get_experiment_info_from_dialog( ok = self.get_experiment_info_from_dialog(
additional_fields_dict=questionaire_dict, additional_fields_dict=questionaire_dict,
field_order=questionaire_order) field_order=questionaire_order)
if not ok: if not ok:
@ -276,16 +281,14 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
sys.exit(1) sys.exit(1)
conditions = [] conditions = []
if self.experiment_info['Run Fixation']:
conditions.append('Fixation')
if self.experiment_info['Run Smooth Pursuit']: if self.experiment_info['Run Smooth Pursuit']:
conditions.append('Pursuit') conditions.append('Pursuit')
if self.experiment_info['Run Saccade']: if self.experiment_info['Run Saccade']:
conditions.append('Saccade') conditions.append('Saccade')
if self.experiment_info['Run Anti-Saccade']: if self.experiment_info['Run Anti-Saccade']:
conditions.append('AntiSaccade') conditions.append('AntiSaccade')
if self.experiment_info['Run Necker Cube']: # if self.experiment_info['Run Necker Cube']:
conditions.append('Necker') # conditions.append('Necker')
if self.experiment_info['Run Binocular Rivalry']: if self.experiment_info['Run Binocular Rivalry']:
conditions.append('Rivalry') conditions.append('Rivalry')
@ -297,7 +300,7 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
if not self.disableTracker: if not self.disableTracker:
self.tracker = eyelinker.EyeLinker( self.tracker = eyelinker.EyeLinker(
self.experiment_window, self.experiment_window,
'ETSP' + self.experiment_info['Subject Identifier'] + '.edf', self.experiment_info['Subject ID'] + self.experiment_info['Timepoint'] + '.edf',
'BOTH' 'BOTH'
) )
self.tracker.initialize_graphics() self.tracker.initialize_graphics()
@ -310,12 +313,12 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
for instruction in self.instruct_text: for instruction in self.instruct_text:
self.display_text_screen(text=instruction) self.display_text_screen(text=instruction)
if not self.disableTracker: if not self.disableTracker:
self.tracker.display_eyetracking_instructions() self.tracker.display_eyetracking_instructions()
self.tracker.setup_tracker() self.tracker.setup_tracker()
self.tracker.send_command("track_search_limits=NO") self.tracker.send_command("track_search_limits=NO")
#random.shuffle(conditions) #random.shuffle(conditions)
condition_counter = 0 condition_counter = 0
@ -324,33 +327,38 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
numBlocks = 1 numBlocks = 1
numTrials = 1 numTrials = 1
if condition == 'Saccade': if condition == 'Saccade':
self.display_text_screen(text=saccade_instruct_text) # self.display_text_screen(text=saccade_instruct_text)
self.display_saccade_instructions()
numBlocks = self.number_of_saccade_blocks numBlocks = self.number_of_saccade_blocks
numTrials = self.number_of_saccade_trials numTrials = self.number_of_saccade_trials
elif condition=='AntiSaccade': elif condition=='AntiSaccade':
self.display_text_screen(text=antisaccade_instruct_text, # self.display_text_screen(text=antisaccade_instruct_text,
image_file = antisaccade_instruct_file, # image_file = antisaccade_instruct_file,
image_scale = self.antisaccade_file_scale) # image_scale = self.antisaccade_file_scale)
self.display_saccade_instructions(anti=True)
numBlocks = self.number_of_saccade_blocks numBlocks = self.number_of_saccade_blocks
numTrials = self.number_of_saccade_trials numTrials = self.number_of_saccade_trials
elif condition=='Fixation': elif condition=='Fixation':
self.display_text_screen(text=fixation_instruct_text)
numBlocks = self.number_of_fixation_blocks numBlocks = self.number_of_fixation_blocks
numTrials = self.number_of_fixation_trials numTrials = self.number_of_fixation_trials
elif condition=='Pursuit': elif condition=='Pursuit':
self.display_text_screen(text=pursuit_instruct_text) # self.display_text_screen(text=pursuit_instruct_text)
self.display_pursuit_instructions()
numBlocks = self.number_of_pursuit_blocks numBlocks = self.number_of_pursuit_blocks
numTrials = self.number_of_pursuit_trials numTrials = self.number_of_pursuit_trials
elif condition=='Necker': elif condition=='Necker':
self.display_text_screen(text=necker_instruct_text, self.display_text_screen(text=necker_instruct_text,
image_file=self.necker_response_box_file, image_file=self.necker_response_box_file,
image_scale=self.necker_response_box_scale) image_scale=self.necker_response_box_scale)
numBlocks = self.number_of_necker_blocks numBlocks = self.number_of_necker_blocks
numTrials = self.number_of_necker_trials numTrials = self.number_of_necker_trials
elif condition=='Rivalry': elif condition=='Rivalry':
self.display_text_screen(text=rivalry_instruct_text, # self.display_text_screen(text=rivalry_instruct_text,
image_file=self.response_box_file, # image_file=self.response_box_file,
image_scale=self.response_box_scale) # image_scale=self.response_box_scale)
self.display_rivalry_instructions(
image_file=self.response_box_file,
image_scale=self.response_box_scale)
numBlocks = self.number_of_rivalry_blocks numBlocks = self.number_of_rivalry_blocks
numTrials = self.number_of_rivalry_trials numTrials = self.number_of_rivalry_trials
else: else:
@ -363,14 +371,18 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
if condition == 'Saccade' or condition == 'AntiSaccade': if condition == 'Saccade' or condition == 'AntiSaccade':
self.display_saccade_fixation(1) self.display_saccade_fixation(1)
else: else:
self.display_fixation(0.5) self.display_fixation(0.5,[])
for trial_num, trial in enumerate(block): for trial_num, trial in enumerate(block):
print( printString = ("Condition: %s (%d/%d) Block: %d/%d Trial %d/%d"
"Condition: ",condition,"(",condition_counter,"/",len(conditions),")", % (condition,condition_counter,len(conditions),
"Block ",block_num+1,"/",numBlocks, block_num+1,numBlocks,trial_num+1,len(block)))
" Trial ",trial_num+1,"/",len(block) if condition == 'Saccade' or condition == 'AntiSaccade':
) if trial['locations'][0]>0:
printString = printString + " (Right)"
else:
printString = printString + " (Left)"
print(printString)
if not self.disableTracker: if not self.disableTracker:
self.tracker.send_message('CONDITION %s' % condition) self.tracker.send_message('CONDITION %s' % condition)
self.tracker.send_message('BLOCK %d' % block_num) self.tracker.send_message('BLOCK %d' % block_num)
@ -380,22 +392,26 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
self.tracker.send_status(status) self.tracker.send_status(status)
#psychopy.sound.Sound('C').play() #psychopy.sound.Sound('C').play()
self.tracker.start_recording() self.tracker.start_recording()
if condition == 'Pursuit' and trial_num==0:
self.display_fixation(self.fixation_trial_time,self.tracker)
data = self.run_trial(trial, block_num, trial_num, self.tracker) data = self.run_trial(trial, block_num, trial_num, self.tracker)
self.tracker.stop_recording() self.tracker.stop_recording()
#psychopy.sound.Sound('C').play() #psychopy.sound.Sound('C').play()
else: else:
if condition == 'Pursuit' and trial_num==0:
self.display_fixation(self.fixation_trial_time,self.tracker)
data = self.run_trial(trial, block_num, trial_num) data = self.run_trial(trial, block_num, trial_num)
data.update({'Condition': condition}) data.update({'Condition': condition})
self.send_data(data) self.send_data(data)
if condition == 'Saccade' or condition=='AntiSaccade': if condition == 'Saccade' or condition=='AntiSaccade':
self.display_saccade_fixation(self.isi_time) self.display_saccade_fixation(self.isi_time)
else: else:
self.display_fixation(self.isi_time) self.display_fixation(self.isi_time,[])
if condition == 'Saccade' or condition == 'AntiSaccade': if condition == 'Saccade' or condition == 'AntiSaccade':
self.display_saccade_fixation(1) self.display_saccade_fixation(1)
else: else:
self.display_fixation(0.5) self.display_fixation(0.5,[])
self.save_data_to_csv() self.save_data_to_csv()
if block_num + 1 != numBlocks: if block_num + 1 != numBlocks:
@ -429,6 +445,264 @@ class EyeTrackingSaccadePursuit(SaccadePursuit.SPtask):
self.quit_experiment() self.quit_experiment()
def display_pursuit_instructions(
self, bg_color=[0,0,0], wait_for_input=True, **kwargs):
bg_color = convert_color_value(bg_color)
fg_color = convert_color_value([255,255,255])
backgroundRect = psychopy.visual.Rect(
self.experiment_window, fillColor=bg_color, units='norm', width=2,
height=2)
backgroundRect.draw()
borderFrame = psychopy.visual.Rect(
self.experiment_window, lineColor=fg_color, units='deg',
width=self.pursuit_distance*2.1, height=1.5, pos=(0,self.instHeight))
textObject = psychopy.visual.TextStim(
self.experiment_window, text='** Smooth Pursuit Example **', color=fg_color, units='deg',
height=1, pos=(0,self.instHeight+2), **kwargs)
color = self.stim_color
Xposition = [0]
num_frames_per_second = 60
counter = 0
stim_frequency = [0.1]
stim_time = [10]
for freq in stim_frequency:
stim_frames = int(round(stim_time[counter]*num_frames_per_second))
for time in range(stim_frames):
Xposition.append(math.sin(freq*math.radians((time+1)*360/num_frames_per_second))*self.pursuit_distance)
counter += 1
stim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2,
pos=(0,0), fillColor=color,
lineColor=color, units='deg')
keys = None
while keys != ['space']:
for Xpos in Xposition:
textObject.draw()
borderFrame.draw()
stim.pos = (Xpos,self.instHeight)
stim.draw()
self.experiment_window.flip()
keys = psychopy.event.getKeys()
if keys==['space']:
break
return keys
def display_saccade_instructions(
self, anti=False, bg_color=[0,0,0], wait_for_input=True, **kwargs):
bg_color = convert_color_value(bg_color)
fg_color = convert_color_value([255,255,255])
backgroundRect = psychopy.visual.Rect(
self.experiment_window, fillColor=bg_color, units='norm', width=2,
height=2)
backgroundRect.draw()
borderFrame = psychopy.visual.Rect(
self.experiment_window, lineColor=fg_color, units='deg',
width=self.pursuit_distance*2.1, height=3, pos=(0,self.instHeight ))
if anti:
dispText = '** Anti-Saccade Example **'
else:
dispText = '** Saccade Example **'
textObject = psychopy.visual.TextStim(
self.experiment_window, text=dispText, color=fg_color, units='deg',
height=1, pos=(0,self.instHeight+3), **kwargs)
color = self.stim_color
stim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2,
pos=(1,0), fillColor=color,
lineColor=color, units='deg')
#arrowVert = [(-0.8,0.1),(-0.8,-0.1),(-0.4,-0.1),(-0.4,-0.2),(0,0),(-0.4,0.2),(-0.4,0.1)]
arrowVert = numpy.array([(-.25,-2),(.25,-2),(.25,-.75),(.5,-.75),(0,0),(-.5,-.75),(-.25,-.75),(-.25,-2)])
arrowVert = arrowVert + (0,self.instHeight + 5.25)
arrowStim = psychopy.visual.ShapeStim(
self.experiment_window, vertices=arrowVert, fillColor=color, size=0.5, lineColor=color, units='deg')
fixation = psychopy.visual.TextStim(
self.experiment_window, text='+', color=self.saccade_fixation_color,
height=self.fixation_size, units='deg', pos=[0,self.instHeight])
stimList = []
temp = list(range(-self.saccade_distance,self.saccade_distance,1))
for circleN in temp:
if circleN < 0:
tempCoord = circleN
else:
tempCoord = circleN+1
tempStim = psychopy.visual.Circle(
self.experiment_window, radius=self.stimulus_size/2,
pos=[tempCoord,self.instHeight], fillColor=self.saccade_dot_color,
lineColor=self.saccade_dot_color, units='deg')
stimList.append(tempStim)
temp1 = random.sample(range(1,self.saccade_distance+1),self.number_of_saccade_lights)
temp2 = random.sample(range(1,self.saccade_distance+1),self.number_of_saccade_lights)
saccade_locations = [x*-1 for x in temp1] + temp2
keys = None
while keys != ['space']:
for ii in range(4):
if anti:
stim_time = 5;
else:
stim_time = round(random.uniform(1,self.saccade_time),3)
for frameN in range(90):
textObject.draw()
borderFrame.draw()
for s in stimList:
s.draw()
fixation.color = color
fixation.draw()
self.experiment_window.flip()
keys = psychopy.event.getKeys()
if keys==['space']:
break
if keys==['space']:
break
Xpos = random.randint(1,15)*random.choice([-1,1])
for frameN in range(int(round(stim_time*60))):
textObject.draw()
borderFrame.draw()
for s in stimList:
s.draw()
stim.pos = (Xpos,self.instHeight)
stim.draw()
fixation.color=self.saccade_fixation_color
fixation.draw()
if anti and frameN > stim_time*30:
arrowVert2 = arrowVert + (-Xpos*2,0)
arrowStim.vertices = arrowVert2
arrowStim.draw()
self.experiment_window.flip()
keys = psychopy.event.getKeys()
if keys==['space']:
break
if keys==['space']:
break
if keys==['space']:
break
if anti:
textObject.draw()
borderFrame.draw()
for s in stimList:
s.draw()
fixation.color = color
fixation.draw()
self.experiment_window.flip()
keys = psychopy.event.waitKeys();
return keys
def display_rivalry_instructions(
self, anti=False, bg_color=[0,0,0], wait_for_input=True,
image_file=[], image_scale=0.25, **kwargs):
fg_color = convert_color_value([255,255,255])
bg_color = convert_color_value(bg_color)
backgroundRect = psychopy.visual.Rect(
self.experiment_window, fillColor=bg_color, units='norm', width=2,
height=2)
backgroundRect.draw()
textObject = psychopy.visual.TextStim(
self.experiment_window, text='** Binocular Rivalry Example **', color=fg_color, units='deg',
height=1, pos=(0,self.instHeight+2), **kwargs)
color = self.rivalry_border_color
lineSize = self.rivalry_border_width
stimPos = self.experiment_window.size[0]/4
stimPos = psychopy.tools.monitorunittools.pix2deg(stimPos,self.experiment_monitor)
stim1 = psychopy.visual.ImageStim(
self.experiment_window,
image=self.rivalry_file1, pos=(-stimPos,0))
stim1.size = (self.rivalry_width, self.rivalry_height)
stim2 = psychopy.visual.ImageStim(
self.experiment_window,
image=self.rivalry_file2, pos=(stimPos,0))
stim2.size = (self.rivalry_width, self.rivalry_height)
borderScale = stim1.size[0]*0.4
borderWidth1 = stim1.size[0]+borderScale
borderHeight1 = stim1.size[1]+borderScale
borderWidth2 = stim2.size[0]+borderScale
borderHeight2 = stim2.size[1]+borderScale
stimBorder1 = psychopy.visual.Rect(
self.experiment_window, width=borderWidth1,
height=borderHeight1,
pos=stim1.pos, lineWidth=lineSize,
lineColor=color, units='deg')
stimBorder2 = psychopy.visual.Rect(
self.experiment_window, width=borderWidth2,
height=borderHeight2,
pos=stim2.pos, lineWidth=lineSize,
lineColor=color, units='deg')
stimFix1_top = psychopy.visual.Line(
self.experiment_window, start=(stim1.pos[0],stim1.pos[1]+borderHeight1/2),
end=(stim1.pos[0],stim1.pos[1]+stim1.size[1]/1.9), units='deg',
lineColor=color, lineWidth=lineSize)
stimFix1_left = psychopy.visual.Line(
self.experiment_window, start=(stim1.pos[0]-borderWidth1/2,stim1.pos[1]),
end=(stim1.pos[0]-stim1.size[0]/1.9,stim1.pos[1]), units='deg',
lineColor=color, lineWidth=lineSize)
stimFix2_bottom = psychopy.visual.Line(
self.experiment_window, start=(stim2.pos[0],stim2.pos[1]-borderHeight2/2),
end=(stim2.pos[0],stim2.pos[1]-stim2.size[1]/1.9), units='deg',
lineColor=color, lineWidth=lineSize)
stimFix2_right = psychopy.visual.Line(
self.experiment_window, start=(stim2.pos[0]+borderWidth2/2,stim2.pos[1]),
end=(stim2.pos[0]+stim2.size[0]/1.9,stim2.pos[1]), units='deg',
lineColor=color, lineWidth=lineSize)
textObject.draw()
stim1.draw()
stim2.draw()
stimBorder1.draw()
stimBorder2.draw()
stimFix1_top.draw()
stimFix1_left.draw()
stimFix2_bottom.draw()
stimFix2_right.draw()
imageObject = psychopy.visual.ImageStim(
self.experiment_window, units='pix',
image=image_file)
sizex = int(round(imageObject.size[0])*image_scale)
sizey = int(round(imageObject.size[1])*image_scale)
bottomOfScreen = int(math.floor(-self.experiment_window.size[1]/2+sizey/2))+5
imageObject.size = [sizex,sizey]
imageObject.pos = (0,bottomOfScreen)
imageObject.draw()
self.experiment_window.flip()
keys = None
if wait_for_input:
psychopy.core.wait(.2) # Prevents accidental key presses
keys = psychopy.event.waitKeys()
while keys != ['space']:
keys = psychopy.event.waitKeys()
self.experiment_window.flip()
experiment = EyeTrackingSaccadePursuit( experiment = EyeTrackingSaccadePursuit(
experiment_name='ETSP', experiment_name='ETSP',
@ -443,6 +717,7 @@ experiment = EyeTrackingSaccadePursuit(
pursuit_frequencies=pursuit_frequencies, pursuit_frequencies=pursuit_frequencies,
saccade_distance=saccade_distance, saccade_distance=saccade_distance,
saccade_time=saccade_time, saccade_time=saccade_time,
number_of_saccade_lights=number_of_saccade_lights,
saccade_fixation_color=convert_color_value(saccade_fixation_color), saccade_fixation_color=convert_color_value(saccade_fixation_color),
saccade_dot_color = convert_color_value(saccade_dot_color), saccade_dot_color = convert_color_value(saccade_dot_color),
isi_time=isi_time, stimulus_size=stimulus_size, isi_time=isi_time, stimulus_size=stimulus_size,
@ -453,7 +728,8 @@ experiment = EyeTrackingSaccadePursuit(
necker_bg_color=convert_color_value(necker_bg_color), necker_bg_color=convert_color_value(necker_bg_color),
fixation_trial_time=fixation_trial_time, fixation_trial_time=fixation_trial_time,
rivalry_time=rivalry_time, rivalry_time=rivalry_time,
rivalry_scale=rivalry_scale, rivalry_height=rivalry_height,
rivalry_width=rivalry_width,
necker_file=necker_file, necker_file=necker_file,
rivalry_file1=rivalry_file1, rivalry_file1=rivalry_file1,
rivalry_file2=rivalry_file2, rivalry_file2=rivalry_file2,

0
eyelinker.py

28
template.py

@ -13,6 +13,7 @@ convert_color_value -- Converts a list of 3 values from 0 to 255 to -1 to 1.
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
from datetime import date
import os import os
import pickle import pickle
@ -135,8 +136,9 @@ class BaseExperiment(object):
fields for the dialog box and output dictionary. fields for the dialog box and output dictionary.
""" """
self.experiment_info = {'Subject Identifier': 'XX00', self.experiment_info = {'Subject ID': '0000',
'Age': '0', 'Session': 'A',
'Timepoint': '0',
'Experimenter Initials': 'MT', 'Experimenter Initials': 'MT',
'Gender': self.gender_options, 'Gender': self.gender_options,
} }
@ -144,8 +146,9 @@ class BaseExperiment(object):
if additional_fields_dict is not None: if additional_fields_dict is not None:
self.experiment_info.update(additional_fields_dict) self.experiment_info.update(additional_fields_dict)
if field_order is None: if field_order is None:
field_order=['Subject Identifier', field_order=['Subject ID',
'Age', 'Session',
'Timepoint',
'Experimenter Initials', 'Experimenter Initials',
'Gender', 'Gender',
] ]
@ -167,9 +170,11 @@ class BaseExperiment(object):
""" """
if filename is None: if filename is None:
filename = (self.experiment_name + '_' + filename = ('ETSP_' + self.experiment_info['Subject ID']
self.experiment_info['Subject Identifier'] + + self.experiment_info['Session']
'_info') + self.experiment_info['Timepoint'] +
'_info')
elif filename[-4:] == '.txt': elif filename[-4:] == '.txt':
filename = filename[:-4] filename = filename[:-4]
@ -190,7 +195,7 @@ class BaseExperiment(object):
with open(filename, 'w') as info_file: with open(filename, 'w') as info_file:
for key, value in self.experiment_info.items(): for key, value in self.experiment_info.items():
info_file.write(key + ':' + str(value) + '\n') info_file.write(key + ':' + str(value) + '\n')
info_file.write('\n') info_file.write('Date: ' + date.today().strftime('%m/%d/%Y') + '\n\n')
def open_csv_data_file(self, data_filename=None): def open_csv_data_file(self, data_filename=None):
"""Opens the csv file and writes the header. """Opens the csv file and writes the header.
@ -201,8 +206,9 @@ class BaseExperiment(object):
""" """
if data_filename is None: if data_filename is None:
data_filename = (self.experiment_name + '_' + data_filename = ('ETSP_' + self.experiment_info['Subject ID']
self.experiment_info['Subject Identifier']) + self.experiment_info['Session']
+ self.experiment_info['Timepoint'])
elif data_filename[-4:] == '.csv': elif data_filename[-4:] == '.csv':
data_filename = data_filename[:-4] data_filename = data_filename[:-4]
@ -355,7 +361,7 @@ class BaseExperiment(object):
wrapWidth=round(.8*self.experiment_window.size[0]), **kwargs) wrapWidth=round(.8*self.experiment_window.size[0]), **kwargs)
#textObject.draw() #textObject.draw()
if image_file: # Display image immediately below text. if image_file: # Display image at bottom of screen.
textObject.pos = (0,self.experiment_window.size[1]/2-5) textObject.pos = (0,self.experiment_window.size[1]/2-5)
textObject.alignVert = 'top' textObject.alignVert = 'top'
textObject.draw() textObject.draw()

Loading…
Cancel
Save