Layering stimuli

Hi Chris,

I’ve been using MWorks 0.8 (I think it’s from a nightly around Nov 2017) to present plaid stimuli by sequentially queuing two orthogonal gratings (“stimOne” and “maskOne”) and then updating the stimulus display:







The stimuli look fine to me but I’ve noticed some asymmetries in the data. At first I thought they were biological, but now I’m starting to wonder if they’re due to the stimuli. Is it possible that the final contrast of each stimulus depends on the order that the stimuli are queued? If so, do more recent versions of MWorks handle this more symmetrically?

Here is the code defining the stimulus properties if that’s useful (the one for the “mask” is comparable):

Thanks,
Lindsey.

Hi Lindsey,

I’ve been using MWorks 0.8 (I think it’s from a nightly around Nov 2017) to present plaid stimuli

I’m a little confused by this. The option to use gratings as masks was part of the 0.9 release and didn’t enter the nightly build until July 2018. Are you sure you aren’t using a more recent MWorks version? Or are you using some other method to generate a plaid?

It’d probably be helpful to see the complete definitions of both gratings, including their parameter values. That said, I do have one recommendation: I would remove the play_dynamic_stimulus actions and instead add autoplay="YES" to the stimulus definitions. By using separate “play_dynamic_stimulus” actions, you introduce some (potential) variability in the start time for each stimulus. (For example, the top grating may end up getting a start time that’s one frame after the bottom grating.) By using autoplay, you can ensure that the start time for both gratings is always the same (as long as they’re queued as part of the same display update).

I don’t know if this is the source of the inconsistencies you’re seeing, but it at least seems possible.

Cheers,
Chris

Hi Chris,

I’m a little confused by this. The option to use gratings as masks

https://mworks.github.io/documentation/latest/components/drifting_grating_stimulus.html#mask
was part of the 0.9 release and didn’t enter the nightly build until July
2018. Are you sure you aren’t using a more recent MWorks version? Or are
you using some other method to generate a plaid?

I’ve attached a screenshot of the version of MWorks that I’m using. I’m
not sure whether I’m designating the grating as a mask as you mean it (for
mask, I call gaussian, but I think this has been an option since before
0.8). My approach was just to queue two different drifting_grating stimuli
in the same x_position and y_position.

It’d probably be helpful to see the complete definitions of both gratings,
including their parameter values.

Here is the definition of the “mask” grating:

The starting_phase of stimOne and maskOne is typically 0, but I do have a
condition where I randomize maskOne [0 90 180 270].
rotation of both stimOne and maskOne can vary- though often stimOne and
maskOne are constrained to be 90 deg apart.
alpha_multplier is typically randomized for both stimOne and maskOne (such
that they are independent)- I most often use [0 0.0625 0.125 0.25 0.5]
though I sometimes use [0 0.32 0.48].
spatial_frequency, speed, x_size, y_size, and x_position and y_position
are always shared with stimOne and maskOne.

That said, I do have one recommendation: I would remove the

play_dynamic_stimulus actions and instead add autoplay=“YES” to the
stimulus definitions. By using separate “play_dynamic_stimulus” actions,
you introduce some (potential) variability in the start time for each
stimulus. (For example, the top grating may end up getting a start time
that’s one frame after the bottom grating.) By using autoplay
https://mworks.github.io/documentation/latest/components/drifting_grating_stimulus.html#autoplay,
you can ensure that the start time for both gratings is always the same (as
long as they’re queued as part of the same display update).

I will change this and see if it makes any difference. Let me know if you
have any insight from the stimulus definitions and parameters or the MWorks
version.

Thanks,
Lindsey

Attachment: mworksversion.tiff (30.1 KB)

Hi Lindsey,

Thanks for the additional details. I understand what you’re doing now.

Apart from the possible issue with play_dynamic_stimulus, I don’t see any reason why the stimulus’ appearance would be inconsistent.

Is it possible that the final contrast of each stimulus depends on the order that the stimuli are queued?

Do you mean that you sometimes queue maskOne before stimOne, and sometimes after? I think that could indeed change the final stimulus, depending on the alpha_multplier values being used.

Chris

Hi Chris,

Do you mean that you sometimes queue maskOne before stimOne, and sometimes

after? I think that could indeed change the final stimulus, depending on
the alpha_multplier values being used.

No- in this code, I always queue stimuli in the same order.

But I vary the alpha_multiplier (as a proxy for changing the relative
contrast) of stimOne and maskOne in a matrix such that sometimes
stimOne>maskOne, sometimes stimOne<maskOne, and sometimes stimOne=maskOne.
I’m concerned that depending on the order the stimuli are presented,
stimOne might not actually be equal to maskOne, despite having the same
alpha_multiplier (and have a bias towards one for the other combos).
Ideally it shouldn’t matter which grating gets queued first such that if I
swap the grating_direction for stimOne and maskOne, I would get the same
result. It was the lack of symmetry when I did this swap that suggested
that there might be some asymmetry in the stimulus (rather than in the
biology). I can show some data if this would be helpful to make this more
concrete- but unfortunately, my only current assay of the stimulus is
through the data, rather than a direct measure of the stimulus, which is
why I approached you.

Lindsey.

Ideally it shouldn’t matter which grating gets queued first such that if I swap the grating_direction for stimOne and maskOne, I would get the same result.

You definitely don’t get the same result if you do that. See the attached example, which performs such a swap once per second while the gratings are playing. Or am I misunderstanding the scenario you’re describing?

In any case, the stimulus you’ve constructed is tricky to reason about. When the bottom grating is drawn, it’s blended with the background. If the background is 50% gray, then the grating’s alpha_multiplier parameter functions as a contrast. When the top grating is drawn, it’s blended with the result of blending the bottom grating with the background. In this case, alpha_multiplier is not equivalent to contrast, as the grating is being blended with something other than a 50% gray background. I find it difficult to predict a priori what the resulting stimulus will look like.

Chris

Attachment: direction_swap.xml (2.53 KB)

Chris,
That’s really helpful to know.
How would I go about creating a stimulus where the two gratings are
interchangeable? Is that a function that currently exists?
Thanks,
Lindsey.

Hi Lindsey,

How would I go about creating a stimulus where the two gratings are interchangeable? Is that a function that currently exists?

That took a bit of thought, but I think I’ve got it.

The attached example demonstrates the sort of stimulus that (I think) you’re trying to create. It requires MWorks 0.9 or later, because you need a layer in order to have a Gaussian mask on top. I’ve included both XML and MWEL versions. The latter includes some explanatory comments.

If you have any questions, please let me know.

Chris

Attachment: plaid_stimulus.zip (2.69 KB)

Thanks so much- I’ll give it a try.
Lindsey.

Hi Chris,
Actually, I have a few questions:

  1. Can I now just independently change the alpha of the top and bottom
    gratings to change their relative contrast? Or do I need to change the
    alpha of the plaid_contrast_rectangle? What does this plaid_contrast value
    reflect?
  2. You have set the plaid_mask_type as ‘raised cosine’- is this something
    specific to creating the plaid? Or can it still be a gaussian if I want to
    keep this consistent?
  3. Does the order of the queuing of the two non-grating stimuli (the
    plaid_contrast_rectangle and plaid_mask) matter? For instance, can I queue
    both of these at the beginning of the experiment and just leave them there?
    Thanks,
    Lindsey.

Hi Lindsey,

The comments in the MWEL file answer several of your questions. I recommend taking a look at it (in the text editor of your choice).

Can I now just independently change the alpha of the top and bottom gratings to change their relative contrast?

As explained in the MWEL file, the bottom grating’s alpha is always one. You control the blending of the top and bottom gratings by adjusting the top grating’s alpha (e.g. 1.0 shows top grating only, 0 shows bottom grating only, 0.5 shows a 50/50 blend of top and bottom).

What does this plaid_contrast value reflect?

As noted in the MWEL file, the plaid_contrast_rectangle stimulus is there to give you control over the plaid’s overall contrast. If you don’t need that control, you can omit it. It has no effect on the relative contributions of the top and bottom gratings.

You have set the plaid_mask_type as ‘raised cosine’- is this something specific to creating the plaid? Or can it still be a gaussian if I want to keep this consistent?

As mentioned in the MWEL file, you can use a Gaussian if you want. I used a raised cosine just because it obscures the stimulus less, making it easier to assess the symmetry.

Does the order of the queuing of the two non-grating stimuli (the plaid_contrast_rectangle and plaid_mask) matter? For instance, can I queue both of these at the beginning of the experiment and just leave them there?

Yes, the order most definitely matters.

Chris

Hi Chris,
Sorry about that- you did address most of my questions in the MWEL file.
But now I’m not sure how to solve my actual stimulus problem. What I
really want to do is to present a matrix of contrasts [0 0.0625 0.125 0.25
0.5] of the two gratings. I understand how I can use the plaid_contrast
alpha in combination with the top_grating alpha to get the vertical axis
(setting top_grating alpha to 1 and varying plaid_grating contrast along
the range of contrast) and horizontal axis (setting top_grating alpha to 0)
and the diagonal (setting top_grating alpha to 0.5), but I’m not sure how
to manage the other stimuli in the matrix. For instance what combo of
plaid_contrast and top_grating alpha do I use if I want to have a stimulus
that is effectively 0.25 for the top_grating and 0.0625 for the bottom
grating?
Thanks,
Lindsey.

Hi Lindsey,

For instance what combo of plaid_contrast and top_grating alpha do I use if I want to have a stimulus that is effectively 0.25 for the top_grating and 0.0625 for the bottom grating?

It’s not clear what you mean by “0.25 for the top_grating and 0.0625 for the bottom grating”.

Taking, say, the top grating on its own, I assume you mean a “contrast” of 0.25. I put the word in quotes, because what you’re really talking about is blending the grating’s color with a 50% gray background. For a given pixel, each RGB component resulting from this blending is determined by the equation

C_out = C_in * A + 0.5 * (1 - A)

where C_in is the original color component taken from the grating and A is the grating’s alpha multiplier. If the alpha is 1, the resulting color is just the original grating color. If the alpha is 0, the result is 0.5 (50% gray). All other values produce a mixture of the initial color and the gray background.

We can perform this blending for both the top and bottom gratings independently, resulting in two gratings with respective “contrasts” of 0.25 and 0.0625. But then how are we supposed to combine them to make the final stimulus? In other words, in the equation

C_final = C_bottom * f_bottom + C_top * f_top

where C_bottom and C_top are the pixel component color values from the bottom and top grating, respectively, what are f_bottom and f_top? Note that they need to be chosen such that C_final is in the range [0,1] for all components of all pixels. Choosing 0.5 for both f_bottom and f_top seems plausible, but I don’t know if that’s what you intend.

When I was making my example, I found it much more straightforward to think about the final stimulus in terms of the relative contributions of the top and bottom grating (plaid_top_grating_alpha) and the overall contrast of the combination of top and bottom (plaid_contrast). It may be possible to rework things to match your idea of separate “contrasts” for the top and bottom gratings, but first we need to establish how that’s supposed to work (i.e. the values of f_bottom and f_top).

Cheers,
Chris

Hi Lindsey,

Per our telephone discussion, I’ve made some changes to MWorks that should enable construction of your desired stimulus. These changes are in the current nightly build. Also, I’ve attached an updated example experiment that demonstrates one possible implementation.

The enabling feature here is the new blending parameters. In short, these allow you to specify the values of f_bottom and f_top in the equation I described previously. Note that these parameters are now available to most (but not all) stimulus types, not just drifting gratings.

In the example, I’ve handled the contrast parameters in a way that seems sensible to me: When the sum of the top and bottom gratings’ contrasts is equal to one, the plaid has maximal contrast (i.e. the highest highs are 100% white, and the lowest lows are 100% black). When the sum of the contrasts is equal to zero, the “plaid” is a uniform 50% gray and disappears in to the background. Intermediate sums result in intermediate overall contrast levels. However, if this isn’t how you want things to work, I’m certain we can find the correct solution without any further changes to MWorks.

Cheers,
Chris

Attachment: plaid_stimulus.mwel.zip (1.79 KB)

Hi Chris,
Thanks so much for sending this.
I think this seems to be what I’d like- as long as the intermediate values
between 0 and 1 are linear. I’ll try it out.
Also- in the example you sent, the instructions suggest that the order of
presentation matters and that blend factors may need adjustment, but then
in the example you demonstrate that order doesn’t matter. Can you explain
this discrepancy?
Thanks,
Lindsey.

Hi Lindsey,

Also- in the example you sent, the instructions suggest that the order of presentation matters and that blend factors may need adjustment, but then in the example you demonstrate that order doesn’t matter. Can you explain this discrepancy?

I just meant that you shouldn’t cut and paste the stimulus definitions in to a different order, without thinking about the blend factors. The two gratings are indeed interchangeable, in that you can swap the values of their parameters without changing the resulting plaid.

Chris