Stimulus Group Creation

Yvonne Bowman's Avatar

Yvonne Bowman

02 Jul, 2018 07:32 PM

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

  1. Support Staff 1 Posted by Christopher Sta... on 03 Jul, 2018 02:04 PM

    Christopher Stawarz's Avatar

    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

  2. 2 Posted by Yvonne Bowman on 05 Jul, 2018 03:46 PM

    Yvonne Bowman's Avatar

    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

  3. 3 Posted by Yvonne Bowman on 06 Jul, 2018 07:24 PM

    Yvonne Bowman's Avatar

    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

  4. Support Staff 4 Posted by Christopher Sta... on 09 Jul, 2018 03:32 PM

    Christopher Stawarz's Avatar

    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

  5. 5 Posted by Yvonne Bowman on 09 Jul, 2018 09:15 PM

    Yvonne Bowman's Avatar

    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

  6. Support Staff 6 Posted by Christopher Sta... on 11 Jul, 2018 12:23 PM

    Christopher Stawarz's Avatar

    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

  7. 7 Posted by Yvonne Bowman on 11 Jul, 2018 02:35 PM

    Yvonne Bowman's Avatar

    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

  8. Support Staff 8 Posted by Christopher Sta... on 13 Jul, 2018 01:51 PM

    Christopher Stawarz's Avatar

    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

  9. Christopher Stawarz closed this discussion on 24 Jul, 2018 01:14 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac