psychopy.org | Reference | Downloads | Github

Memory task block design

Windows 10, PsychoPy 3.0.7

Hi, I’m looking for some advice on how to make an experiment. I’d like to make a memory task, so it will have an encoding and retrieval phase, with an interval phase inbetween. The encoding phase is a simple event-related design so that’s easy enough, but my issue is with the retrieval phase which I need to be in mini-blocks of 3 to 5 trials. This is problematic because if it would be impractical to have tons of individual csv files (one for each block).

I did see the page on making a block-designed experiment and that was helpful. In this blocked phase, there will be 2 conditions: “attention” (A) and “memory” (M), so I set up an attention.csv and a memory.csv, which will store the trial text stimuli. The problem is that I can’t seem to figure out how to just present 3 to 5 trials of each condition at a time, and then to never present those specific trials again. As it is, condition A or M is randomly selected, then ALL trials from within that file are presented, and if I want to have more than 1 block then it just goes back and re-presents those trials again. I also need to consider randomisation of this - which is fine for the blocks, but I also need to randomise the trials…

One way around this that I can think of is to insert a code component somewhere that keeps track of a trial index stored inside the respective .csv file, and then to only present a trial with an index that is not yet been logged. But that seems incredibly hacky and I’m sure there is a more straightforward way around it. Any ideas?

Just to make this clearer, I’m trying to implement something like this:

And I anticipate there will be somewhere around 24 to 30 blocks in total (half for each condition of A or M). I was attempting this all day yesterday, seems like the main issue is that no two stimuli should be the same, as you can see in the third block of the example it is the same condition but different stimuli.

I attempted to use counters for both conditions, and then to index into a csv file using the ‘Selected rows’ box but this just gave me errors whenever I didn’t hardcode the selected rows. Can anybody help? Am I overlooking something painfully obvious here?

This probably the approach to use: set the loop to be “sequential” but feed it a randomised selection of row indices each time the loop runs. e.g. say you have 50 rows to select from and want to show a subset of 5 on each run of the loop. Then insert a Code Component and put something like this in its “begin experiment” tab:

indices = list(range(50)) # list from 0 to 49
shuffle(indices) # randomise the order

So presumably you have a nested loop situation, so in the inner loop, you could get a random selection of five rows, without any repetition, using something like this in the “selected rows” field:

indices[outer_looop_name.thisN * 5, outer_looop_name.thisN * 5 + 5]

e.g. on the first iteration of the outer loop, this would yield [0, 5], the second [5, 10], etc. Although these are deterministic values, you are sampling from a shuffled list, so the result will be randomised but non-repeating coverage of all of the indices.

Please show us what you attempted to specify and the full text of the error message.

I can never remember the precise syntax needed for this field, so the suggestion above might or might not work in that precise expression either.

Thank you! So this is giving me the same error that I had, which is seen below. I tried changing it to [blocks.thisN*3:blocks.thisN*3+3] to be a slice but it’s the same.

Sorry, I specified the index start and finish but not what list they are supposed to come from. Could,d you try:

indices[outer_looop_name.thisN * 5, outer_looop_name.thisN * 5 + 5]

I still don’t know if this expression will work: under the hood, this field has to be interpreted by Builder and it is not always able to deal with aribitrary code.

I see. I tried it and it is giving the same TypeError.

Since this selection argument is taking a string, maybe we need to somehow convert our input? Could the eval() function help here?

It needed a $ sign - I had tried this before but it would not let me make the change (builder gave me some red error text). It must be some sort of bug as it worked when I pressed enter (rather than click ok).

The problem I’m now facing is that the conditions are split into 2 separate .csv files, so I have one called attention.csv and another called memory.csv. The way it is at the moment, the indices list is created and the first 3 rows of the first condition are presented, then it moves to the next condition and presents the final 3 rows for that, and then ends. Instead, I’d like to present the first 3 trials of condition 1, then of condition 2, then the next 3 of condition 1 and so on. Then scale it up for more stimuli.

For setting this up, I’ve created template stimuli and files until the structure runs properly. Here are what the files look like, and I’ve printed the indices list, followed by the slice that gets presented in each block, for each stimulus: