How do I randomize 7 blocks in my study? Each routine is a specific level in my study (in this case, stimulus onset asynchrony/time interval) and it's not very feasible to have only one routine :(

Hello everyone! :slight_smile:

What are you trying to achieve?:

I am currently doing a reaction time and accuracy task that involves comparing visually presented numerical information and auditory numerical information. The visually presented numerical information will be presented in three forms - Arabic numerals (e.g 5), number words (e.g five), and non-symbolic magnitude (a picture of 5 dots). Both visual numerical information and auditory numerical information will be presented sequentially. After the presentation of the 2nd stimulus, participants are to respond if these two stimuli are conveying the same information or not. They are supposed to press “a” if the numerical information is the same and “l” if it’s different.

Apart from varying the format of the visual numerical stimuli I am presenting, I also intend to vary the stimulus onset asynchrony (SOA)/time interval between the two stimuli. I have 7 levels of time intervals/SOAs (plus minus 750, 250 and 500, and 0ms), resulting in me creating my experiment in such a manner (see attached picture).

One set of fixation_cross and VA_750ms (for example) constitutes a block. Hence, in total, there are 7 blocks here (only 4 are pictured though). I have already randomized the trials within each block. The next step for me is to randomize the presentation of these blocks, with one block denoting one level of SOA/time interval (e.g +750ms). To do this, I’ve placed a loop around all the blocks, with this loop titled “blocknames” in the picture. While the experiment still works fine, randomization still doesn’t occur.

I understand that there was a post addressing the randomization of blocks, but I felt that it was more specific to experiments that only have one routine. This is not very feasible for my case considering that I would have to vary the time interval between two numerical stimuli within a trial.

What did you try to make it work?:
Nevertheless, I’ve tried to create an excel file with the names of the excel files in each condition - across all routines, the excel files actually contain the same information, but they’re just named differently according to what the condition name is (e.g AV500ms, VA750ms). In this case, the experiment still works, but the blocks are still not being randomized.

What specifically went wrong when you tried that?:
With the same excel file, I also tried to label my conditions as $condsFile instead of using the exact document location, but this was what I got instead.
image

This might be some useful background info on my Psychopy software and laptop.
OS (e.g. Win10): Win 10
PsychoPy version (e.g. 1.84.x): 2020.1.3
Standard Standalone? (y/n) Yes,

I apologize if this might have been posted a few times. However, I’ve tried to apply these solutions according to what my experiment requires, but to no avail. I’m also quite a new user to Psychopy and am not very sure on how to proceed from here as well. Would really appreciate any advice on this!

Thank you and sorry for the inconvenience!

This question has been answered here:

In the future, don’t bother posting questions both here and at StackOverflow. The expertise you need is here on this forum. If you get an answer at SO, it will likely come from someone who would have answered it here anyway. But you might also get unfriendly attention at SO, as they can be quite doctrinaire about what sort of questions they accept there (and might not look kindly on non-programming questions like this one).

Hi Michael,

Thank you for your advice! Will take note of these.

Your solution does work! Thank you :slight_smile:

However, I do have another question - is there any way that I can vary the onset of the response keys in the experiment? As each block has a different duration, I would like to vary the onset of response keys, such that participants respond at different timings according to when the 2nd stimulus starts appearing.

Thank you!

You should just be able to apply the same onset time to the keyboard component as you do for your stimulus component.

Does that make sense? If not, I would need a fuller description of what you are wanting to do.

Hi Michael,

Here’s a description on what I want to do:

Example:
A stimulus will be presented for 500ms first, followed by a time interval of either 0ms or plus minus 250ms, 500ms, or 750ms. The participant will respond following the onset of the 2nd stimulus. I wish to vary the time the participant responds according to the time interval of each experimental block. I have negative time intervals because one stimulus is in visual form, and the other is in auditory form. So positive time intervals end up like this (visual stimulus --> auditory stimulus), whereas negative time intervals result in auditory stimulus --> visual stimulus.

Another thing i realized was that when i tried to apply the same onset time to the keyboard component, while the experiment does run, it’s quite strange that for some trials/blocks, the fixation cross appears before the 2nd stimulus appears, whereas for some, the cross only appears after I respond. I’m not sure about why this is happening?

Thank you and sorry for the inconvenience! Really appreciate your advice on this Michael :slight_smile:

OK, I think you need to provide screenshots of the timelines of your experimental routines, so that I can understand the sequence of events better and so that we can we can refer to things by common names. Also please provide examples of what variables and values your conditions files contain.

Hi Michael,

Attached is a screenshot of the timeline of my experiment:

I have a total of 7 condition files. Attached are 2 screenshots from 2 of my condition files:
In this condition, the visual number is presented first, followed by the auditory number (a number is being read out over an audio clip). In this case, the time interval between these two stimuli is 250ms, as denoted by the column “soa” in my excel sheet. Visual onset refers to the time where the visual number is presented, in this case, 0ms. It will be presented for 500ms. 250ms will then pass, before the auditory number is being read out. In this case, auditory onset refers to the timing that the auditory number is being read out, in this case, 750ms or 0.75seconds (this is labelled as audioonset in my excel sheet). I wish to measure reaction time from the onset of the 2nd stimulus to the participant’s response. Hence, the onset of the key responses (titled samedifferentonset in the excel sheet) is the same as the auditory onset in this case.

In this condition, the auditory number gets presented first, followed by the visual number (which is presented on the screen). Hence, the time interval between these two stimuli is recorded as -500ms instead. So an auditory number will be presented first for 500ms. A time interval of 500ms will then pass before the visual stimulus is presented for 500ms. 1s would have passed when the visual stimulus is being presented - hence, the key response onset is written as 1 second as well, under the column “samedifferentonset”.

For the most part, the experiment does work fine. However, for some trials, this is what happens:
What should happen in a single trial:
fixation cross → number → number → (after response) fixation cross

For some it’s like that:
fixation cross → number → fixation cross → number

It’s pretty strange that only a number of trials are affected, and I’m not sure how to remedy this?

Also, on a side note, I was wondering if there is any way to vary the number of times these routines “practicebreak” and “breaktime” appear? These routines are aimed at getting participants to take a short break before they resume the experiment. These routines appear 2 times and 7 times respectively. I only want “practicebreak” to appear once, in between the 2 blocks of my practice trials. I only want “breaktime” to appear 6 times, in between the 7 blocks of my practice trials.

Thank you Michael!! Really appreciate your help on this :slight_smile:

This bit is easy. Insert a code component on each of these routines (from the “custom” component panel). In its “begin routine” tab, put code like this to skip the last iteration:

if actualloop.thisN == actualloop.nTotal - 1:
    continueRoutine = False

And similarly for the practice loop. Remember, Python counts from zero, so we need to subtract 1 from the total number of iterations to compare it to the current loop iteration.

To understand the rest, I need to see screenshots of the actual timelines within each of the trial routines, and see how you are specifying the onset times of each of their components.

Lastly, it’s very likely we could condense this task even further, by just having a single set of loops and routines, nested three deep (one loop for trials, one for blocks, and one for the practice/actual condition). This would very likely make the analysis file easier for you to work with, as all of your key dependent variables would then be in the same columns. You might already be able to see how how that could be done, given what you did before. As before, the outer loop is connected to a small conditions file of just two rows, containing the names of the practice and actual conditions files for the current block loops. The middle, block loop, would then get that variable name rather than a hard-coded file name. The outer loop would be set to “sequential” rather than “random”, to ensure that practice trials always come first.

You can also condense down to just having one instructions routine. The content for the instructions text component can be set from a column in the conditions file for the outermost loop. The instructions routine would be encompassed only within the outermost loop, so it would only run twice during the experiment.

This might seem obsessive, but you will end up with a much more orderly data file, which you will be very glad of at the analysis stage.

Hi Michael,

Thank you for the code! It fixed the problem I mentioned earlier :slight_smile:

Regarding the screenshot of actual timelines, here they are:

This was how I specified the onset times of each of these components. What I’ve shown here is the practice trial. I did the same for the actual trials too.

Regarding your suggestions on how I can further condense my experiment, thank you so much Michael! Let me try them out first :slight_smile:

Also, on a side note, I actually tried to upload my experiment on Pavlovia earlier, but I’m not sure why it’s unable to detect my loops in the experiment, or that the routine “practice break” and “start experiment” does not appear. Is there any way I can remedy this? Regarding the loop problem, I’ve tried to change my code from the “Begin Routine” tab to “each frame” tab but to no avail.

Thank you!

Thanks. Now just to make things very easy for me, could you put some expected values in the “expected start” and “expected duration” fields? That will draw indicative timelines so I can understand the intended flow a bit better (it’s late at night here…)

Perhaps best to just edit the post above and replace the screenshot with an updated one.

Hi Michael! No worries! Here they are:

I will make use of the -500ms SOA conditions as an example.


“Headphones.png” appears together with the sound.

The visual stimulus:

So in this case, the auditory stimulus and image of headphones will appear for 500ms first. A time interval of 500ms will then pass before the visual stimulus appears. During the onset of the 2nd stimulus, the participant can start responding.

Thank you for your help Michael! Sorry for the inconvenience.

Sorry, no what I meant was leave your actual variable names in the start and duration fields as they were, but put some typical values in the “expected” fields. Those are the fields that are currently empty, immediately below your actual start and duration fields.

That will provide hints for PsychoPy to then draw timelines next to each of your component icons, showing when they are typically expected to start and stop.

Hi Michael,

Thank you for the suggestion, but what if the expected start for each condition is actually different?

For the condition that has 250ms, the auditory onset would be 750ms while the visual onset is 0ms.
For the condition that has -750ms, however, the auditory onset would be 0ms while the visual onset would be 1250ms instead.

Hence, I’m not exactly sure how to proceed with this, given that they’re different for each condition.

Regarding your suggestion about having 3 nested loops, one thing is that each practice block only has 12 trials, whereas the actual blocks have more. Is there any way to toggle this in code?

Thank you!

There is no issue here, as the trials are controlled by conditions files. In this case, your “practice” conditions file will have 12 rows, while the conditions files for the experimental blocks will be longer. PsychoPy will sort all of that out for you automatically. i.e. each loop will run for as many iterations as there are rows of data in the conditions file.

That’s fine, just choose one or the other condition to use as an illustration. It will be useful for you to have in your file, as a visual aid if you are showing someone else, or for you in six months time when everything may not be so obvious.

I’m only asking because the description you’ve given in the text is not so obvious for me to understand. Perhaps we could just reboot:

  1. Describe in a paragraph exactly when you want things to occur.
  2. Describe exactly how you are implementing this (e.g. what variables and formulae are going in what fields), and
  3. Describe exactly what is going wrong.

For (1), imagine the kind of detail someone would need in the methods section of a paper. i.e. could someone understand your procedure, knowing nothing other than what you tell them.