Building better experiments§


Using Builder§

All the base knowledge we assume at the start of this workshop can be learnt from this 15 minute video

This shows you how to make the ‘posnerHand’ demo available from previous examples


What makes a PsychoPy experiment?§

Open the posnerHand.psyexp file. An experiment in Builder has:


The conditions file§

Open the conditions.xlsx file…

If you are going to change something on every repeat of a routine (e.g. stimulus location changes on each trial) you can use a Conditions file. This is fed into the loop surrounding the routine.

Each header is a parameter, each row corresponds to the value of that parameter on each repeat/trial.


Let’s practice making minor edits§


Warm up exercises (5-10 mins)§

When you are finished, come back to the main session and collect one run of your task so that we can talk through the data file.


Block designs and counterbalancing§


Randomised block designs§

A block design is where we have sets of similar trials organised into blocks rather than having trials interleaved.

  • a block of faces to recognise or a block of houses
  • a faces oriented correctly and faces inverted
  • a block of Stroop task in English and a block in French

Note: these are all cases where the components would be identical between blocks.


The natural error§

The biggest error that people make with this is to create a Routine (and a loop) for each block of trials:


Then they ask on the forum, “How do I shuffle the blocks on my Flow?”

That is the wrong way to think about it (for blocks with identical components).


The right way§

Instead of a Routine for each block, create a Routine for all your trials and make it behave differently across the blocks:


Then you can set the conditions files in your blocks loop to control the block-level changes.

The outer “blocks” loop then takes a (meta) “conditions” file that specifies which of the conditions files will be loaded in each block.


The right way§

Imagine we want to extend our Posner task to include a block where invalid trials occur on a higher proportion of trials.

We need to create a total of 3 conditions files:


The right way§



The label variable isn’t technically needed but it could be used to tell people what block they are about to enter. The point is that you can still use other variables here, defined at the block level of the program.


The right way§

Now we need to set up the variables inside our experiment:


The right way§


The right way§

We could also tell the participants what kind of block they are about to enter, we can add a text object that takes:


Randomised block design complete!§

You’ve sorted out block designs in a relatively neat fashion.

Just keep clear what differs from one block to the next (for a conditions file) and what stays the same (for the Routine definition).



Counterbalancing your blocks is really just an extension of the blocking scenario, except that you set the blocks to operate in a particular order rather than leaving PsychoPy to randomise them.


Setting the order§

At the moment, PsychoPy doesn’t handle the ordering for you - you need to decide how to create the orders and how to assign participants.

So, you need a file per conditions order (e.g. A -> B and B-> A) and then set the blocks loop to be sequential rather than random to preserve the order you set.


How to assign participants to a group§

Easiest way is by hand at the start of the run for the participant. The steps are:

Note: This second kind of formatting is termed an ‘fstring’ in python - we will talk about that more later.



Let’s practice counterbalancing in different ways using the counterbalancing exercises in the demo folder. In “excercise 1” you will find a non efficient counterbalanced design. We want to improve this in 2 phases.

  1. Turn this inefficient design into a randomised block design. (the cat and dog images are presented in blocks, but in a random order)
  2. Then turn this into a counterbalanced design. So that group A see cats first and group B see dogs first. (You should be able to input group in the GUI at the start)

When you are finished, come back to the main session, if you run into any error messages please share them (on slack) and we can discuss them.


Counterbalancing subtasks§

Sometimes we might have to counterbalance subtasks (i.e. routines that contain very different sets of components)

You can wrap a loop around any set of routines and control if it presents using nReps.


Counterbalancing subtasks§

In the below we could control create the order C->B->A by using a conditions file where the nReps of each subloop are set per iteration of the outerloop.


Counterbalancing subtasks§

e.g. using a conditions file like this…

nRepsA nRepsB nRepsC
0 0 1
0 1 0
1 0 1

Where the nReps argument of each subloop is set using something like ‘$nRepsA’ ect.



Open exercise 2 in the counterbalanceExercises folder. This is very similar to our last task, but this time our two routines present different kinds of components, so we need to use a different method of counterbalancing.

We want a design where groupA sees cat images first and group B sees cat words first. Counterbalance this flow using the nReps arguments in the loops.


All done§

You can now create trials and blocks in any order, fixed or random and counterbalance subtasks!

You’re in complete control (but you need to understand what orders you want!)

Up next

Extending Builder with code

Making the most of mouse inputs