[Bug]: Cannot start program: "Expected package name at the start of dependency specifier -illow"
MichaelWoodc opened this issue · 3 comments
PsychoPy Version
2023.2.3
What OS are your PsychoPy running on?
Windows 10
Bug Description
Can't run program! I get the following error at line 18 of my code, right after:
plugins.activatePlugins()
I get this:
Exception has occurred: InvalidRequirement
Expected package name at the start of dependency specifier
-illow
^
pkg_resources.extern.packaging._tokenizer.ParserSyntaxError: Expected package name at the start of dependency specifier
-illow
^
The above exception was the direct cause of the following exception:
File "C:\Users\micha\OneDrive - Georgia Southern University\emotionseeg\eegtest\debugme.py", line 18, in <module>
plugins.activatePlugins()
pkg_resources.extern.packaging.requirements.InvalidRequirement: Expected package name at the start of dependency specifier
-illow
^
Expected Behaviour
I just want it to run without problems
Steps to Reproduce
- Run the generated psychopy script in VScode
Additional context
Here is the entire code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This experiment was created using PsychoPy3 Experiment Builder (v2023.2.3),
on November 07, 2023, at 21:56
If you publish work using this script the most relevant publication is:
Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019)
PsychoPy2: Experiments in behavior made easy Behav Res 51: 195.
https://doi.org/10.3758/s13428-018-01193-y
"""
# --- Import packages ---
from psychopy import locale_setup
from psychopy import prefs
from psychopy import plugins
plugins.activatePlugins()
prefs.hardware['audioLib'] = 'ptb'
prefs.hardware['audioLatencyMode'] = '3'
from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, layout
from psychopy.tools import environmenttools
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
STOPPED, FINISHED, PRESSED, RELEASED, FOREVER, priority)
import numpy as np # whole numpy lib is available, prepend 'np.'
from numpy import (sin, cos, tan, log, log10, pi, average,
sqrt, std, deg2rad, rad2deg, linspace, asarray)
from numpy.random import random, randint, normal, shuffle, choice as randchoice
import os # handy system and path functions
import sys # to get file system encoding
import psychopy.iohub as io
from psychopy.hardware import keyboard
# --- Setup global variables (available in all functions) ---
# Ensure that relative paths start from the same directory as this script
_thisDir = os.path.dirname(os.path.abspath(__file__))
# Store info about the experiment session
psychopyVersion = '2023.2.3'
expName = 'EGG_experiment_template' # from the Builder filename that created this script
expInfo = {
'participant': f"{randint(0, 999999):06.0f}",
'session': '001',
'date': data.getDateStr(), # add a simple timestamp
'expName': expName,
'psychopyVersion': psychopyVersion,
}
def showExpInfoDlg(expInfo):
"""
Show participant info dialog.
Parameters
==========
expInfo : dict
Information about this experiment, created by the `setupExpInfo` function.
Returns
==========
dict
Information about this experiment.
"""
# temporarily remove keys which the dialog doesn't need to show
poppedKeys = {
'date': expInfo.pop('date', data.getDateStr()),
'expName': expInfo.pop('expName', expName),
'psychopyVersion': expInfo.pop('psychopyVersion', psychopyVersion),
}
# show participant info dialog
dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
if dlg.OK == False:
core.quit() # user pressed cancel
# restore hidden keys
expInfo.update(poppedKeys)
# return expInfo
return expInfo
def setupData(expInfo, dataDir=None):
"""
Make an ExperimentHandler to handle trials and saving.
Parameters
==========
expInfo : dict
Information about this experiment, created by the `setupExpInfo` function.
dataDir : Path, str or None
Folder to save the data to, leave as None to create a folder in the current directory.
Returns
==========
psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
"""
# data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
if dataDir is None:
dataDir = _thisDir
filename = u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
# make sure filename is relative to dataDir
if os.path.isabs(filename):
dataDir = os.path.commonprefix([dataDir, filename])
filename = os.path.relpath(filename, dataDir)
# an ExperimentHandler isn't essential but helps with data saving
thisExp = data.ExperimentHandler(
name=expName, version='',
extraInfo=expInfo, runtimeInfo=None,
originPath='C:\\Users\\micha\\OneDrive - Georgia Southern University\\emotionseeg\\eegtest\\EGG_experiment_template.py',
savePickle=True, saveWideText=True,
dataFileName=dataDir + os.sep + filename, sortColumns='time'
)
thisExp.setPriority('thisRow.t', priority.CRITICAL)
thisExp.setPriority('expName', priority.LOW)
# return experiment handler
return thisExp
def setupLogging(filename):
"""
Setup a log file and tell it what level to log at.
Parameters
==========
filename : str or pathlib.Path
Filename to save log file and data files as, doesn't need an extension.
Returns
==========
psychopy.logging.LogFile
Text stream to receive inputs from the logging system.
"""
# this outputs to the screen, not a file
logging.console.setLevel(logging.EXP)
# save a log file for detail verbose info
logFile = logging.LogFile(filename+'.log', level=logging.EXP)
return logFile
def setupWindow(expInfo=None, win=None):
"""
Setup the Window
Parameters
==========
expInfo : dict
Information about this experiment, created by the `setupExpInfo` function.
win : psychopy.visual.Window
Window to setup - leave as None to create a new window.
Returns
==========
psychopy.visual.Window
Window in which to run this experiment.
"""
if win is None:
# if not given a window to setup, make one
win = visual.Window(
size=[1440, 900], fullscr=True, screen=0,
winType='pyglet', allowStencil=False,
monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
backgroundImage='', backgroundFit='none',
blendMode='avg', useFBO=True,
units='height'
)
if expInfo is not None:
# store frame rate of monitor if we can measure it
expInfo['frameRate'] = win.getActualFrameRate()
else:
# if we have a window, just set the attributes which are safe to set
win.color = [0,0,0]
win.colorSpace = 'rgb'
win.backgroundImage = ''
win.backgroundFit = 'none'
win.units = 'height'
win.mouseVisible = False
win.hideMessage()
return win
def setupInputs(expInfo, thisExp, win):
"""
Setup whatever inputs are available (mouse, keyboard, eyetracker, etc.)
Parameters
==========
expInfo : dict
Information about this experiment, created by the `setupExpInfo` function.
thisExp : psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
win : psychopy.visual.Window
Window in which to run this experiment.
Returns
==========
dict
Dictionary of input devices by name.
"""
# --- Setup input devices ---
inputs = {}
ioConfig = {}
# Setup iohub keyboard
ioConfig['Keyboard'] = dict(use_keymap='psychopy')
ioSession = '1'
if 'session' in expInfo:
ioSession = str(expInfo['session'])
ioServer = io.launchHubServer(window=win, **ioConfig)
eyetracker = None
# create a default keyboard (e.g. to check for escape)
defaultKeyboard = keyboard.Keyboard(backend='iohub')
# return inputs dict
return {
'ioServer': ioServer,
'defaultKeyboard': defaultKeyboard,
'eyetracker': eyetracker,
}
def pauseExperiment(thisExp, inputs=None, win=None, timers=[], playbackComponents=[]):
"""
Pause this experiment, preventing the flow from advancing to the next routine until resumed.
Parameters
==========
thisExp : psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
inputs : dict
Dictionary of input devices by name.
win : psychopy.visual.Window
Window for this experiment.
timers : list, tuple
List of timers to reset once pausing is finished.
playbackComponents : list, tuple
List of any components with a `pause` method which need to be paused.
"""
# if we are not paused, do nothing
if thisExp.status != PAUSED:
return
# pause any playback components
for comp in playbackComponents:
comp.pause()
# prevent components from auto-drawing
win.stashAutoDraw()
# run a while loop while we wait to unpause
while thisExp.status == PAUSED:
# make sure we have a keyboard
if inputs is None:
inputs = {
'defaultKeyboard': keyboard.Keyboard(backend='ioHub')
}
# check for quit (typically the Esc key)
if inputs['defaultKeyboard'].getKeys(keyList=['escape']):
endExperiment(thisExp, win=win, inputs=inputs)
# flip the screen
win.flip()
# if stop was requested while paused, quit
if thisExp.status == FINISHED:
endExperiment(thisExp, inputs=inputs, win=win)
# resume any playback components
for comp in playbackComponents:
comp.play()
# restore auto-drawn components
win.retrieveAutoDraw()
# reset any timers
for timer in timers:
timer.reset()
def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
"""
Run the experiment flow.
Parameters
==========
expInfo : dict
Information about this experiment, created by the `setupExpInfo` function.
thisExp : psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
psychopy.visual.Window
Window in which to run this experiment.
inputs : dict
Dictionary of input devices by name.
globalClock : psychopy.core.clock.Clock or None
Clock to get global time from - supply None to make a new one.
thisSession : psychopy.session.Session or None
Handle of the Session object this experiment is being run from, if any.
"""
# mark experiment as started
thisExp.status = STARTED
# make sure variables created by exec are available globally
exec = environmenttools.setExecEnvironment(globals())
# get device handles from dict of input devices
ioServer = inputs['ioServer']
defaultKeyboard = inputs['defaultKeyboard']
eyetracker = inputs['eyetracker']
# make sure we're running in the directory for this experiment
os.chdir(_thisDir)
# get filename from ExperimentHandler for convenience
filename = thisExp.dataFileName
frameTolerance = 0.001 # how close to onset before 'same' frame
endExpNow = False # flag for 'escape' or other condition => quit the exp
# get frame duration from frame rate in expInfo
if 'frameRate' in expInfo and expInfo['frameRate'] is not None:
frameDur = 1.0 / round(expInfo['frameRate'])
else:
frameDur = 1.0 / 60.0 # could not measure, so guess
# Start Code - component code to be run after the window creation
# --- Initialize components for Routine "videos" ---
baseline1 = visual.TextStim(win=win, name='baseline1',
text='Baseline test\n\nRelax for one minute witih eyes open',
font='Open Sans',
pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
color='white', colorSpace='rgb', opacity=None,
languageStyle='LTR',
depth=0.0);
baseline2 = visual.TextStim(win=win, name='baseline2',
text='Baseline test\n\nRelax for one minute with eyes closed',
font='Open Sans',
pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
color='white', colorSpace='rgb', opacity=None,
languageStyle='LTR',
depth=-1.0);
# --- Initialize components for Routine "playclip" ---
stimclip = visual.MovieStim(
win, name='stimclip',
filename=None, movieLib='ffpyplayer',
loop=False, volume=1.0, noAudio=False,
pos=(0, 0), size=(0.5, 0.5), units=win.units,
ori=0.0, anchor='center',opacity=None, contrast=1.0,
depth=0
)
# --- Initialize components for Routine "positivenegative" ---
attractiveness = visual.Slider(win=win, name='attractiveness',
startValue=None, size=(1.0, 0.1), pos=(0, -0.3), units=win.units,
labels=["Positive", "Negative"],ticks=None, granularity=1,
style='radio', styleTweaks=(), opacity=None,
labelColor='LightGray', markerColor='Red', lineColor='White', colorSpace='rgb',
font='Open Sans', labelHeight=0.05,
flip=False, ori=0.0, depth=0, readOnly=False)
# --- Initialize components for Routine "rating2" ---
attractiveness_2 = visual.Slider(win=win, name='attractiveness_2',
startValue=None, size=(1.0, 0.1), pos=(0, -0.2), units=win.units,
labels=['Happy','Saf'], ticks=(1, 2, 3, 4, 5), granularity=0.1,
style='rating', styleTweaks=(), opacity=None,
labelColor='LightGray', markerColor='Red', lineColor='White', colorSpace='rgb',
font='Open Sans', labelHeight=0.05,
flip=False, ori=0.0, depth=0, readOnly=False)
# create some handy timers
if globalClock is None:
globalClock = core.Clock() # to track the time since experiment started
if ioServer is not None:
ioServer.syncClock(globalClock)
logging.setDefaultClock(globalClock)
routineTimer = core.Clock() # to track time remaining of each (possibly non-slip) routine
win.flip() # flip window to reset last flip timer
# store the exact time the global clock started
expInfo['expStart'] = data.getDateStr(format='%Y-%m-%d %Hh%M.%S.%f %z', fractionalSecondDigits=6)
# --- Prepare to start Routine "videos" ---
continueRoutine = True
# update component parameters for each repeat
thisExp.addData('videos.started', globalClock.getTime())
# keep track of which components have finished
videosComponents = [baseline1, baseline2]
for thisComponent in videosComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
frameN = -1
# --- Run Routine "videos" ---
routineForceEnded = not continueRoutine
while continueRoutine and routineTimer.getTime() < 4.0:
# get current time
t = routineTimer.getTime()
tThisFlip = win.getFutureFlipTime(clock=routineTimer)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *baseline1* updates
# if baseline1 is starting this frame...
if baseline1.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
baseline1.frameNStart = frameN # exact frame index
baseline1.tStart = t # local t and not account for scr refresh
baseline1.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(baseline1, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'baseline1.started')
# update status
baseline1.status = STARTED
baseline1.setAutoDraw(True)
# if baseline1 is active this frame...
if baseline1.status == STARTED:
# update params
pass
# if baseline1 is stopping this frame...
if baseline1.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > baseline1.tStartRefresh + 2-frameTolerance:
# keep track of stop time/frame for later
baseline1.tStop = t # not accounting for scr refresh
baseline1.frameNStop = frameN # exact frame index
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'baseline1.stopped')
# update status
baseline1.status = FINISHED
baseline1.setAutoDraw(False)
# *baseline2* updates
# if baseline2 is starting this frame...
if baseline2.status == NOT_STARTED and tThisFlip >= 2-frameTolerance:
# keep track of start time/frame for later
baseline2.frameNStart = frameN # exact frame index
baseline2.tStart = t # local t and not account for scr refresh
baseline2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(baseline2, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'baseline2.started')
# update status
baseline2.status = STARTED
baseline2.setAutoDraw(True)
# if baseline2 is active this frame...
if baseline2.status == STARTED:
# update params
pass
# if baseline2 is stopping this frame...
if baseline2.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > baseline2.tStartRefresh + 2-frameTolerance:
# keep track of stop time/frame for later
baseline2.tStop = t # not accounting for scr refresh
baseline2.frameNStop = frameN # exact frame index
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'baseline2.stopped')
# update status
baseline2.status = FINISHED
baseline2.setAutoDraw(False)
# check for quit (typically the Esc key)
if defaultKeyboard.getKeys(keyList=["escape"]):
thisExp.status = FINISHED
if thisExp.status == FINISHED or endExpNow:
endExperiment(thisExp, inputs=inputs, win=win)
return
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
routineForceEnded = True
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in videosComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# --- Ending Routine "videos" ---
for thisComponent in videosComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.addData('videos.stopped', globalClock.getTime())
# using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
if routineForceEnded:
routineTimer.reset()
else:
routineTimer.addTime(-4.000000)
# set up handler to look after randomisation of conditions etc
videoclips = data.TrialHandler(nReps=1.0, method='sequential',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions('conditions.xlsx'),
seed=None, name='videoclips')
thisExp.addLoop(videoclips) # add the loop to the experiment
thisVideoclip = videoclips.trialList[0] # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisVideoclip.rgb)
if thisVideoclip != None:
for paramName in thisVideoclip:
globals()[paramName] = thisVideoclip[paramName]
for thisVideoclip in videoclips:
currentLoop = videoclips
thisExp.timestampOnFlip(win, 'thisRow.t')
# pause experiment here if requested
if thisExp.status == PAUSED:
pauseExperiment(
thisExp=thisExp,
inputs=inputs,
win=win,
timers=[routineTimer],
playbackComponents=[]
)
# abbreviate parameter names if possible (e.g. rgb = thisVideoclip.rgb)
if thisVideoclip != None:
for paramName in thisVideoclip:
globals()[paramName] = thisVideoclip[paramName]
# --- Prepare to start Routine "playclip" ---
continueRoutine = True
# update component parameters for each repeat
thisExp.addData('playclip.started', globalClock.getTime())
stimclip.setMovie(stim)
# keep track of which components have finished
playclipComponents = [stimclip]
for thisComponent in playclipComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
frameN = -1
# --- Run Routine "playclip" ---
routineForceEnded = not continueRoutine
while continueRoutine and routineTimer.getTime() < 1.0:
# get current time
t = routineTimer.getTime()
tThisFlip = win.getFutureFlipTime(clock=routineTimer)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *stimclip* updates
# if stimclip is starting this frame...
if stimclip.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
stimclip.frameNStart = frameN # exact frame index
stimclip.tStart = t # local t and not account for scr refresh
stimclip.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(stimclip, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'stimclip.started')
# update status
stimclip.status = STARTED
stimclip.setAutoDraw(True)
stimclip.play()
# if stimclip is stopping this frame...
if stimclip.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > stimclip.tStartRefresh + 1-frameTolerance:
# keep track of stop time/frame for later
stimclip.tStop = t # not accounting for scr refresh
stimclip.frameNStop = frameN # exact frame index
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'stimclip.stopped')
# update status
stimclip.status = FINISHED
stimclip.setAutoDraw(False)
stimclip.stop()
if stimclip.isFinished: # force-end the Routine
continueRoutine = False
# check for quit (typically the Esc key)
if defaultKeyboard.getKeys(keyList=["escape"]):
thisExp.status = FINISHED
if thisExp.status == FINISHED or endExpNow:
endExperiment(thisExp, inputs=inputs, win=win)
return
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
routineForceEnded = True
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in playclipComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# --- Ending Routine "playclip" ---
for thisComponent in playclipComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.addData('playclip.stopped', globalClock.getTime())
stimclip.stop() # ensure movie has stopped at end of Routine
# using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
if routineForceEnded:
routineTimer.reset()
else:
routineTimer.addTime(-1.000000)
# --- Prepare to start Routine "positivenegative" ---
continueRoutine = True
# update component parameters for each repeat
thisExp.addData('positivenegative.started', globalClock.getTime())
attractiveness.reset()
# keep track of which components have finished
positivenegativeComponents = [attractiveness]
for thisComponent in positivenegativeComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
frameN = -1
# --- Run Routine "positivenegative" ---
routineForceEnded = not continueRoutine
while continueRoutine:
# get current time
t = routineTimer.getTime()
tThisFlip = win.getFutureFlipTime(clock=routineTimer)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *attractiveness* updates
# if attractiveness is starting this frame...
if attractiveness.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
attractiveness.frameNStart = frameN # exact frame index
attractiveness.tStart = t # local t and not account for scr refresh
attractiveness.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(attractiveness, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'attractiveness.started')
# update status
attractiveness.status = STARTED
attractiveness.setAutoDraw(True)
# if attractiveness is active this frame...
if attractiveness.status == STARTED:
# update params
pass
# Check attractiveness for response to end Routine
if attractiveness.getRating() is not None and attractiveness.status == STARTED:
continueRoutine = False
# check for quit (typically the Esc key)
if defaultKeyboard.getKeys(keyList=["escape"]):
thisExp.status = FINISHED
if thisExp.status == FINISHED or endExpNow:
endExperiment(thisExp, inputs=inputs, win=win)
return
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
routineForceEnded = True
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in positivenegativeComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# --- Ending Routine "positivenegative" ---
for thisComponent in positivenegativeComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.addData('positivenegative.stopped', globalClock.getTime())
videoclips.addData('attractiveness.response', attractiveness.getRating())
videoclips.addData('attractiveness.rt', attractiveness.getRT())
# the Routine "positivenegative" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
# --- Prepare to start Routine "rating2" ---
continueRoutine = True
# update component parameters for each repeat
thisExp.addData('rating2.started', globalClock.getTime())
attractiveness_2.reset()
# keep track of which components have finished
rating2Components = [attractiveness_2]
for thisComponent in rating2Components:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
frameN = -1
# --- Run Routine "rating2" ---
routineForceEnded = not continueRoutine
while continueRoutine:
# get current time
t = routineTimer.getTime()
tThisFlip = win.getFutureFlipTime(clock=routineTimer)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *attractiveness_2* updates
# if attractiveness_2 is starting this frame...
if attractiveness_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
attractiveness_2.frameNStart = frameN # exact frame index
attractiveness_2.tStart = t # local t and not account for scr refresh
attractiveness_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(attractiveness_2, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'attractiveness_2.started')
# update status
attractiveness_2.status = STARTED
attractiveness_2.setAutoDraw(True)
# if attractiveness_2 is active this frame...
if attractiveness_2.status == STARTED:
# update params
pass
# Check attractiveness_2 for response to end Routine
if attractiveness_2.getRating() is not None and attractiveness_2.status == STARTED:
continueRoutine = False
# check for quit (typically the Esc key)
if defaultKeyboard.getKeys(keyList=["escape"]):
thisExp.status = FINISHED
if thisExp.status == FINISHED or endExpNow:
endExperiment(thisExp, inputs=inputs, win=win)
return
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
routineForceEnded = True
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in rating2Components:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# --- Ending Routine "rating2" ---
for thisComponent in rating2Components:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.addData('rating2.stopped', globalClock.getTime())
videoclips.addData('attractiveness_2.response', attractiveness_2.getRating())
videoclips.addData('attractiveness_2.rt', attractiveness_2.getRT())
# the Routine "rating2" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
thisExp.nextEntry()
if thisSession is not None:
# if running in a Session with a Liaison client, send data up to now
thisSession.sendExperimentData()
# completed 1.0 repeats of 'videoclips'
# mark experiment as finished
endExperiment(thisExp, win=win, inputs=inputs)
def saveData(thisExp):
"""
Save data from this experiment
Parameters
==========
thisExp : psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
"""
filename = thisExp.dataFileName
# these shouldn't be strictly necessary (should auto-save)
thisExp.saveAsWideText(filename + '.csv', delim='auto')
thisExp.saveAsPickle(filename)
def endExperiment(thisExp, inputs=None, win=None):
"""
End this experiment, performing final shut down operations.
This function does NOT close the window or end the Python process - use `quit` for this.
Parameters
==========
thisExp : psychopy.data.ExperimentHandler
Handler object for this experiment, contains the data to save and information about
where to save it to.
inputs : dict
Dictionary of input devices by name.
win : psychopy.visual.Window
Window for this experiment.
"""
if win is not None:
# remove autodraw from all current components
win.clearAutoDraw()
# Flip one final time so any remaining win.callOnFlip()
# and win.timeOnFlip() tasks get executed
win.flip()
# mark experiment handler as finished
thisExp.status = FINISHED
# shut down eyetracker, if there is one
if inputs is not None:
if 'eyetracker' in inputs and inputs['eyetracker'] is not None:
inputs['eyetracker'].setConnectionState(False)
logging.flush()
def quit(thisExp, win=None, inputs=None, thisSession=None):
"""
Fully quit, closing the window and ending the Python process.
Parameters
==========
win : psychopy.visual.Window
Window to close.
inputs : dict
Dictionary of input devices by name.
thisSession : psychopy.session.Session or None
Handle of the Session object this experiment is being run from, if any.
"""
thisExp.abort() # or data files will save again on exit
# make sure everything is closed down
if win is not None:
# Flip one final time so any remaining win.callOnFlip()
# and win.timeOnFlip() tasks get executed before quitting
win.flip()
win.close()
if inputs is not None:
if 'eyetracker' in inputs and inputs['eyetracker'] is not None:
inputs['eyetracker'].setConnectionState(False)
logging.flush()
if thisSession is not None:
thisSession.stop()
# terminate Python process
core.quit()
# if running this experiment as a script...
if __name__ == '__main__':
# call all functions in order
thisExp = setupData(expInfo=expInfo)
logFile = setupLogging(filename=thisExp.dataFileName)
win = setupWindow(expInfo=expInfo)
inputs = setupInputs(expInfo=expInfo, thisExp=thisExp, win=win)
run(
expInfo=expInfo,
thisExp=thisExp,
win=win,
inputs=inputs
)
saveData(thisExp=thisExp)
quit(thisExp=thisExp, win=win, inputs=inputs)
Well, it's hard to know from this if this is a user error, or something else.
Do any experiments run (e.g. just a simple demo)? If so what distinguishes this experiment from the working ones?
What happens if you run the experiment from PsychoPy itself, rather than converting to code and running from VS Code?
I believe this is an issue with your dependencies, rather than a bug in PsychoPy. You should be able to add the psychopy-installed python to your VS Code options to get things going. As to why it's saying -illow, instead of pillow, I'm not sure, but maybe that's just a string getting wrapped across lines during the output. Anyway, feel free to re-open if you have further info that points to this being an actual bug in psychopy rather than your setup. Thanks