Pass Experiment Info as command line arguments to PsychoPy Experiments

Hi,

I want to write a batch script which calls five PsychoPy experiments one after another but only type the information which usually is being written in the Experiment Settings as Experiment Info (such as randomization triallist, age, participant number, language, …) once to minimize errors and the number of tasks while executing the experiment.

I already managed to run the lastrun.py file using the python.exe which comes with PsychoPy2 (although I wonder what pyhtonw.exe and python27.exe are for) via the cmd.exe so I see no problem in writing a batch script to call one experiment after another. The problem I am struggling with right now is finding a way to enter the Experiment Info only once so that the information will be passed on from the execution batch file to each of the experiments as arguments.

Is there a way to pass the Experiment Info which is being asked in the Experiment Settings as command line argument to the experiment?

Although I am familiar with the Coder, the experiment has been created by somebody else using the Builder and as I am not the person who has to maintain the experiment I would like to have a Builder solution - anything else would not be maintainable for my study group if changes to the experiment need to be made.

OS: Win7
PsychoPy version: 1.90.2 (PsychoPy2 Builder)
Standard Standalone? yes

@Vathiala, I think there is only one way to do this, and that is by manually adding information to the beginning of the Python scripts that are output by Builder. You cannot insert this information from Builder using a code component, because you cannot access the built-in code that is written before the experiment starts. However, it is an easy solution to apply to your .py files - you just have to make sure that Builder does not overwrite these files when Builder runs e.g., your “lastrun” file is overwritten every time you run your experiment, so rename it and your custom code is safe.

To get cmd line args into your script, do the following.

# Immediately after the import statements:
cmdVar = None
if sys.argv[1]:
    cmdVar = sys.argv[1]  # get the first arg from command line

# Now add the following to your gui dict
expInfo = {'participant': '', 'session': '001', 'cmd': cmdVar}  # cmd entry holds cmdline variable

Now, from your batch file, you can run something like the following to insert information into your experiment from the command line:

python myExperiment.py myCmdVar

1 Like

@dvbridges

Thank you very much for your answer. I did solve it the way you suggested, although it means that I have to edit that part each time that changes are made using the Builder-Version of the experiment. Your code does not quite work, though; the if statement causes an IndexError.

IndexError: list index out of range

This is the solution I came up with, using the len() funktion. In this experiment, both the participant code as well as the age group are passed on to the experiment via the command line. Moreover, the dialogue window will only pop up if the information had not been passed to the experiment already, causing a shorter break between the experiments when executing them via the batch-script but also making it possible to execute the experiment outside of the batch-script.

# Get command line arguments passed if present
ParticipantCode = None
AgeGroup = None
if len(sys.argv) > 1:
    ParticipantCode = sys.argv[1]  # get the first argument from command line
    AgeGroup = sys.argv[2] # second argument from command line

# Store info about the experiment session
expName = 'Experiment'  # from the Builder filename that created this script
expInfo = {u'participant': u'' if ParticipantCode == None else ParticipantCode,
           u'age group': u'' if AgeGroup == None else AgeGroup}
if ParticipantCode == None: #checking if the ParticipantCode has been passed on from the command line
    dlg = gui.DlgFromDict(dictionary=expInfo, title=expName)
    if dlg.OK == False:
        core.quit()  # user pressed cancel
expInfo['date'] = data.getDateStr()  # add a simple timestamp
expInfo['expName'] = expName

I can then call it like this in the batch-script:

:: Set variables which are going to be needed for the experiment.
set /p ParticipantCode=Participant Code:
set /p AgeGroup=Age Group:
:: Call all experiments one after another, giving each the arguments they need for the experiments.
:: Note to pay attention to the order, as we call them in the experiment by the order in which they are put in here.
"C:\Program Files (x86)\PsychoPy2\python.exe" C:\Users\...\Experiment1.py %ParticipantCode% %AgeGroup%
"C:\Program Files (x86)\PsychoPy2\python.exe" C:\Users\...\Experiment2.py %ParticipantCode% %AgeGroup%

Of course, I olny call 2 of five experiments in this example, just for showing the idea :slight_smile:

2 Likes