Stimulus Group Creation

Hi Chris,

Quick question - We’ve done yet more modifications on how we want our code to work for the white noise experiment. We’ll generate images ahead of time, and we want to load a random set of these into a stimulus group for each trial. I’m working on how to do this - I need to generate a random number within the range of images we have for each frame we need, then use those numbers to get the image files (they will have the numbers in the names) into a stimulus group. However, I want the order to be random with no duplicate images, so I’m thinking a range replicator isn’t the way to do this. Any help would be appreciated.

Thanks!
Yvonne

Hi Yvonne,

I need to generate a random number within the range of images we have for each frame we need, then use those numbers to get the image files (they will have the numbers in the names) into a stimulus group. However, I want the order to be random with no duplicate images, so I’m thinking a range replicator isn’t the way to do this.

There’s no getting around using a range replicator to define the set of image_file stimuli (well, unless you want to declare all 60-plus of them individually). However, there’s no need to use a range replicator to load images in to these stimuli. For example, in the update_dynamic_white_noise macro I wrote, I use a while action to unload and load image files:

frame_number = 0
while (frame_number < num_noise_frames) {
    unload_stimulus (dynamic_white_noise_frames[frame_number])
    dynamic_white_noise_frame_path = dynamic_white_noise_filenames[frame_number]
    load_stimulus (dynamic_white_noise_frames[frame_number])
    frame_number += 1
}

But you can load/unload the members of the stimulus group in any order you like. You don’t have to do it sequentially.

To prevent loading duplicate images, you’ll need some way to keep track of which ones you’ve already loaded. Within a single session, you might be able to use a selection variable for this task. However, if you need to keep track of already-loaded images across multiple loads/unloads of the experiment, you’ll need to record the list of used images externally (maybe in a text file, written via Python actions).

Out of curiosity, why do you need to randomize the order of random noise images? Shouldn’t the randomness of the noise be enough?

Chris

Hi Chris,

This is great, thank you. I’ll try this out.

The thought behind doing it randomly was so that we wouldn’t have to worry
about keeping track of where we stopped after a session/day/load/unload of
the experiment. Additionally, if we ran through all the images we
generated, if we were doing this sequentially, we would want to shuffle
them afterwards (or generate a new batch). But with picking them randomly
each time, we won’t ever need to shuffle them. It was more about the
stimulus/file management than the randomness in this case. Our other
thought was using a “pointer” method, but because it’s not easy to
save/retrieve variables from a text file with MWorks, we thought this might
be easier on that front as well.

Best,
Yvonne

Hi Chris,

I’m having quite a few issues with getting this code written and would be
thankful for some more help. Sorry about all the back and forth!

First, is there a way to use a variable for the file path to define a
stimulus group? It didn’t work for us, though I notice you do this in the
code that generates images in between each trial.

Second, for randomly pulling from a large bank of images, we thought
perhaps the way to do it would be to redefine the stimulus group each trial
using the image files that match the random numbers we generated. However,
we ran into the fact that we can’t have a stimulus group inside of a
protocol (even when within a macro). We also tried introducing the random
subset during the loading phase (after putting more images than necessary
in the stimulus group), which sort of worked, but because it’s a frame
list, it ended up only presenting the ones that were loaded, and leaving
gaps of gray background when images weren’t loaded.

I think I might need an example of how to do the following, because I’m
totally unsure what to try next: Out of a large set of images
(pre-generated, in a given folder and named sequentially such as
white_noise_1, white_noise_2, etc.), before each trial we need to choose
some number of images equal to the frames we want to present, define them
as frame list stimuli, and then present them during the trial. I think I
mentioned before that we don’t want repeated images, but we actually don’t
care if they’re repeated or not.

Thank you,
Yvonne

Hi Yvonne,

I think the attached example does what you want. Please read the comments in the experiment before trying to run it. If you have any questions, please let me know.

Chris

Attachment: randomized_batch_loading.zip (1.75 KB)

Hi Chris,

Thank you so much, this works great!! I’ll work on integrating it with the
task code I have and let you know if I have issues.

I have a couple of quick questions as well. First, is there any way to get
python files not to run at experiment load? This isn’t a huge issue, but I
was having a python bridge write some things to a text file and ended up
with an extra file that was produced at experiment runtime.
Second, we changed the random number generation so that it also saves the
numbers it generates as elements in an array (to write it to a text file
for later use), but I wanted to double check that the array does get
written in the order that the numbers are generated, so that we don’t
confuse the order of the images.

Thank you,
Yvonne

Hi Yvonne,

First, is there any way to get python files not to run at experiment load?

Sure. Replace

python_file ('create_symlink_to_noise_images.py')

with

resource ('create_symlink_to_noise_images.py')

Then, somewhere in your protocol, add

run_python_file ('create_symlink_to_noise_images.py')

Note that this will execute the file every time the protocol runs. If you still want it to run only once, you’ll need to handle that yourself (e.g. with a flag variable).

Second, we changed the random number generation so that it also saves the numbers it generates as elements in an array (to write it to a text file for later use), but I wanted to double check that the array does get written in the order that the numbers are generated, so that we don’t confuse the order of the images.

I’m not sure what your question is here.

Chris

Hi Chris,

Thanks! That’s perfect, I just wanted the python file in question to not
run at load time.

The question about the arrays is more of a double check than anything, it’s
a little bit of a silly question but is important to us. We’ve modified the
code you gave me so that it writes the random numbers it generates to
choose the images to an array:

random_num_noise_images[frame_number] = disc_rand(1, total_num_noise_images)

Which we then load with

noise_frame_path = format(

               'whitenoise_images/imgWhiteNoise_%d.tiff',

                random_num_noise_images[frame_number]

                )
            load_stimulus (white_noise_frames[frame_number])

I just wanted to make sure that the numbers in the array get stored in the
same order that we’ll load them in. That is, that the first number in the
array corresponds to frame 1, the second to frame 2, etc. I know this is
probably true, but I couldn’t figure out a way to verify it so I thought I
would ask just in case MWorks organizes arrays differently than I would
expect.

Thanks,
Yvonne

Hi Yvonne,

I just wanted to make sure that the numbers in the array get stored in the same order that we’ll load them in. That is, that the first number in the array corresponds to frame 1, the second to frame 2, etc.

If the code looks like this:

frame_number = 0
while (frame_number < num_noise_frames) {
    unload_stimulus (white_noise_frames[frame_number])
    random_num_noise_images[frame_number] = disc_rand(1, total_num_noise_images)
    noise_frame_path = format(
        'whitenoise_images/white_noise_%d.tiff',
        random_num_noise_images[frame_number]
        )
    load_stimulus (white_noise_frames[frame_number])
    frame_number += 1
}

then, yes, the numbers in random_num_noise_images will be in the same order as the corresponding images in white_noise_frames are loaded.

Chris