psychopy.org | Reference | Downloads | Github

Counterbalancing loops

OS (e.g. Win10): Win10
PsychoPy version (e.g. 1.84.x): v3.0.4
Standard Standalone? (y/n) If not then what?: y
What are you trying to achieve?:
My design involves showing participants trials where an actor either kicks a ball or turns from it and types on a computer or turns from it whilst another actor does the reverse. I want to counterbalance across participants which is seen. So for participant 1 they see actor1 kicking the ball and turning from the computer and actor2 turning from the ball and typing at the computer but participant 2 would see actor2 kicking the ball and turning from the computer and actor1 turning from the ball and typing at the computer.

Unfortunately it is a little more complicated than that because I need to control the images seen and the ordering a little bit so I have a first loop which is a practice trial of 12 trials (pracFkicks), a second loop of 32 trials (block1Fkicks) and then a third loop of 40 trials (repeated 5 times; block2fkicks). It should all flow smoothly so that the participant in unaware that there are three loops.

So, what I have done is put all of that into one loop called FKicks.

I should note that within the loops, there are the routines:
fixation
blank screen
trial (shows the action picture)
Feedback - a piece of code that tells psychopy whether to select the correct or incorrect feedback fro participants

I have the same routines in each loop, but I alter the excel file that it selects the stimuli from.

I then did exactly the same for the other counterbalance:
A practice trial of 12 trials (pracMkicks), a second loop of 32 trials (block1Mkicks) and then a third loop of 40 trials (repeated 5 times; block2Mkicks). With an overriding loop called MKicks.

What I want is for participants to EITHER see the whole MKicks loop OR the whole FKicks loop depending on whether their participant number is odd or even.

What did you try to make it work?:
I’ve seen a variety of solutions involving conditions files but these seem to be referring to routines rather than loops. I’m assuming it will be some form of code but I am unfamiliar with python and am using builder.

I would really appreciate any help.

Your suspicion is correct that this is best handled outside of a conditions file. What you should do is add a new field to the Experiment Info dialog, let’s say called loop_type. On each run, enter a value there which is either M or F.

Then insert a code component on your routine within each loop, and put code like this in its “begin routine” tab to ensure a given loop doesn’t run:

if expInfo['loop_type'] != 'M':
    MKicks.finished = True  # end this loop before the next iteration check
    continueRoutine = False # but have to ensure the first iteration doesn't start at all.

and similarly for the other loop:

if expInfo['loop_type'] != 'F':
    FKicks.finished = True
    continueRoutine = False

You could also do this:

if expInfo['loop_type'].upper() != 'M':

which forces the value to be upper case, protecting you against accidentally typing m instead of M.

Thanks for the reply.

I tried to add in a new routine within the first part of the MKicks and FKicks loops with the code in but that didn’t work. So I re-read what you wrote and you said “Insert a code component on your routine within each loop” as though there was only one routine per loop but I haven’t coded it that way…perhaps there is a better way than I have done?

I was trying to keep my post simple but basically what happens in a trial:

fixation point (randomly for between 800 and 1000ms)
blank screen (for 500ms)
neutral image of actor stood with object (500ms)
action image of actor interacting or turning from object (2000ms or until button press)
correct feedback - blank screen shown for 200ms OR Error feedback - error message shown for 3000ms

When I started programming in Psychopy I originally tried to get them all in one routine but the way you have to do the timing made this not quite match up (because of the random presentation of the fixation point). I could put the fixation, blank, neutral image and action imagine in one routine and have the blank as starting at the same time as the fixation but then which would be in the front (i.e., seen)? Also, that would mean when the fixation was shorter, the blank screen would be longer which I don’t want - is there a better solution?

What I have done currently is separated it out into 6 routines per subloop:
fixation
blank screen
routine with action image and neutral image in
feedback code - says which of the next two to run (correct or error response)
correct response (in its own loop)
error response (in its own loop)

So where would I put your code for it to work in this instance?

The other question with the code suggested is that my routines are all within subloops (practice, Block1, Block2) - I’m guessing since the command refers to the whole M (or F) kicks loops that this shouldn’t be an issue?

Thanks,

Kim

OK, if you have multiple routines within a loop, then yes, you’ll need to insert that code on each one. You don’t need to end the loop again (that just needs to happen once), but you do need to stop this particular routine running on the very first iteration, so just put something like this on the second and subsequent routines:

if expInfo['loop_type'] != 'M':
    # prevent this routine running on the first iteration of the wrong sort of loop:
    continueRoutine = False 

and so on for the other loop too.

It is often more convenient to do things that way. This is why they are called “routines” rather than “trials”, as a trial will often need to consist of more than one. Just keep it as it currently is, but insert these little code snippets on each one.

The other question with the code suggested is that my routines are all within subloops (practice, Block1, Block2) - I’m guessing since the command refers to the whole M (or F) kicks loops that this shouldn’t be an issue?

I’m not sure I quite understand your layout without seeing a screen shot, but depending on the arrangement, you might need to end both the inner and outer loops for a given routine.