Millisecond Forums

including multiple stimuli in a trial

https://forums.millisecond.com/Topic17159.aspx

By charlottebooth - 9/17/2015

Hello, I am wondering why my script will only run one distractor image per trial when I have tried to ask it to run 4 at a time?

<picture targets>
/items = ("T_90.jpg", "T_270.jpg")
/select = noreplace
/vposition = 50%
/hposition = counter.targets.selectedvalue
</picture>

<picture distractors>
/items = ("L_90.jpg", "L_270.jpg", "L_0.jpg", "L_180.jpg")
/select = noreplace
/vposition = 50%
/hposition = counter.distractors.selectedvalue
</picture>

<counter targets>
/ items = (5%,5%,5%,5%,5%,95%,95%,95%,95%,95%)
/ select = noreplace
</counter>

<counter distractors>
/ items = (5%,20%,35%,50%,65%,80%,95%)
/ not = (targets)
/ select = noreplace
/ selectionrate = always
</counter>

<trial mytrial>
/ stimulusframes = [1=targets,distractors,distractors,distractors,distractors]
/ validresponse = (anyresponse)
/ ontrialend = [reset(counter.distractors)]
</trial>

<block myblock>
/ trials = [1-10=mytrial]
</block>



By Dave - 9/17/2015

You <trial> only displays two objects -- one called "targets", one called "distractors". The fact that you include the object called "distractors" multiple times in /stimulusframes

/ stimulusframes = [1=targets,distractors,distractors,distractors,distractors]

does not change this fact at all. You are merely including the same, single object multiple times. You need to set up *separate* objects

<picture distractors1>
...
</picture>
...
<picture distractors4>
...
</picture>

and display those separate objects in /stimulusframes

/ stimulusframes = [1=targets,distractors1,distractors2,distractors3,distractors4]
By charlottebooth - 9/17/2015

Thanks! I have changed it now, but I'm having the same problem - I have changed the script now though to include x/y coordinates - might it be something to do with that?


<picture targets>
/items = ("T_90.jpg", "T_270.jpg")
/select = noreplace
/vposition = counter.targetypos.selectedvalue
/hposition = counter.targetxpos.selectedvalue
</picture>

<picture distractor1>
/items = ("L_90.jpg", "L_270.jpg", "L_0.jpg", "L_180.jpg")
/select = noreplace
/vposition = counter.distractorypos.selectedvalue
/hposition = counter.distractorxpos.selectedvalue
</picture>

<picture distractor2>
/items = ("L_90.jpg", "L_270.jpg", "L_0.jpg", "L_180.jpg")
/select = noreplace
/vposition = counter.distractorypos.selectedvalue
/hposition = counter.distractorxpos.selectedvalue
</picture>

<picture distractor3>
/items = ("L_90.jpg", "L_270.jpg", "L_0.jpg", "L_180.jpg")
/select = noreplace
/vposition = counter.distractorypos.selectedvalue
/hposition = counter.distractorxpos.selectedvalue
</picture>


<picture distractor4>
/items = ("L_90.jpg", "L_270.jpg", "L_0.jpg", "L_180.jpg")
/select = noreplace
/vposition = counter.distractorypos.selectedvalue
/hposition = counter.distractorxpos.selectedvalue
</picture>


<counter targetxpos>
/ items = (40%, 50%, 60%)
/ select = noreplace
/selectionrate = trial
</counter>

<counter targetypos>
/ items = (40%, 50%, 60%)
/ select = current(targetxpos)
</counter>

<counter distractorxpos>
/ items = (40%, 50%, 60%)
/ not = (targetxpos)
/ select = noreplace
</counter>

<counter distractorypos>
/items = (40%, 50%, 60%)
/select = current(distractorxpos)
</counter>



<trial mytrial>
/ stimulusframes = [1=targets,distractor1,distractor2,distractor3,distractor4]
/ validresponse = (anyresponse)
/ ontrialend = [reset(counter.distractorxpos)]
</trial>

<block myblock>
/ trials = [1-10=mytrial]
</block>


By Dave - 9/17/2015

Several issues here:

(1) The distractor position <counter>s are not set to the correct /selectionrate. It needs to be *always* as in the previous examples we discussed, because you want to sample *multiple* values from that counter per trial, not just one.

(2) The positions don't make sense -- that's true for both the target and distractor <counter>s

<counter distractorxpos>
/ items = (40%, 50%, 60%)
/ not = (targetxpos)
/ select = noreplace
</counter>

<counter distractorypos>
/items = (40%, 50%, 60%)
/select = current(distractorxpos)
</counter>

defines *3* positions as x/y coordinate pairs; the three pairs are 40%/40%, 50%/50% and 60%/60%. You have 5 objects (1 target, 4 distractors) so you need at least 5 positions. Moreover, *one* of the three positions as taken up by the target, so there are only *two* left for 4 distractors.

Please take another look at https://www.millisecond.com/forums/FindPost10182.aspx which illiustrates how to handle two dimensions. Also: Don't move too fast. First get it to work in *one* dimension. Only then move up to two.

By charlottebooth - 9/21/2015

Thanks Dave that's extremely helpful.

With regard to point (2) about the positions. I get it now that for an 8x6 grid I need to enter every coordinate for the x/y positions. So, I have 48 /items for each <counter> (see below).

<counter targetxpos>
/ items = (29%, 29%, 29%, 29%, 29%, 29%, 35%, 35%, 35%, 35%, 35%, 35%, 41%, 41%, 41%, 41%, 41%, 41%, 47%, 47%, 47%, 47%, 47%, 47%, 53%, 53%, 53%, 53%, 53%, 53%, 59%, 59%, 59%, 59%, 59%, 59%, 65%, 65%, 65%, 65%, 65%, 65%, 71%, 71%, 71%, 71%, 71%, 71%)
/ select = noreplace
/selectionrate = trial
</counter>

<counter targetypos>
/ items = (35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%)
/ select = current(targetxpos)
</counter>


However, I also want to "jitter" the positions slightly by a small fraction, e.g. 0.2%. I have tried entering another 48 items after the ones shown above (e.g. 29.2%, 29.2%).
This does work, however in some trials some pictures are missing. I am supposed to always have 13 pictures shown, but by trying to create this "jitter" I only have between 11-13 pictures.
I don't understand why some are missing! Any ideas?

Thanks,
Charlotte :) 
By Dave - 9/22/2015

Again, several issues here. First, you need to introduce some way for Inquisit to be able to distinguish between the various positions that *share the same x* coordinate. If you look back at the example linked in the previous reply, you'll notice that it does this by introducing a slight difference in the fractional part [1].

<counter type1xpos>
/ items = (25.0000%, 25.0001%, 75.0000%, 75.0001%)
/ select = noreplace
/ selectionrate = trial
</counter>

<counter type1ypos>
/ items = (25.0000%, 75.0000%, 25.0000%, 75.0000%)
/ select = current(type1xpos)
</counter>

<counter type2xpos>
/ items = (25.0000%, 25.0001%, 75.0000%, 75.0001%)
/ select = noreplace
/ not = (type1xpos)
/ selectionrate = always
</counter>

<counter type2ypos>
/ items = (25.0000%, 75.0000%, 25.0000%, 75.0000%)
/ select = current(type2xpos)
</counter>

This ensures that the script "knows" that the two 25s and two 75s in fact indicate different positions and only one of those two positions (the one selected for the target; type1) is blocked from being selected for the distractors (type2).

You also need to make sure to *reset* the distractor counter after each trial, again as in the previous example:

<trial mytrial>
/ pretrialpause = 500
/ stimulusframes =  [1=type1,type2a,type2b,type2c]
/ validresponse = (57)
/ ontrialend = [reset(counter.type2xpos)]
</trial>

Otherwise the counter will run out of item in the midst of some trial, reset (because it doesn't have any items left) and then the same positions can be selected again. I.e., one stimulus will obscure another stimulus because both share the same position.

Work that out first, then deal with the jitter. Hope this helps.

[1] There are other ways to do this. You can abstract from the concrete coordinates by doing something like this:

<values>
/ type1pos = 0
/ type1x = 0
/ type1y = 0
/ type2apos = 0
/ type2ax = 0
/ type2ay = 0
/ type2bpos = 0
/ type2bx = 0
/ type2by = 0
/ type2cpos = 0
/ type2cx = 0
/ type2cy = 0
</values>

<block myblock>
/ trials = [1-4=mytrial]
</block>

<trial mytrial>
/ ontrialbegin = [values.type1pos=counter.type1positions.selectedvalue;
    values.type1x=counter.type1xpos.selectedvalue;
    values.type1y=counter.type1ypos.selectedvalue;

    values.type2apos=counter.type2positions.selectedvalue;
    values.type2ax=counter.type2xpos.selectedvalue;
    values.type2ay=counter.type2ypos.selectedvalue;

    values.type2bpos=counter.type2positions.selectedvalue;
    values.type2bx=counter.type2xpos.selectedvalue;
    values.type2by=counter.type2ypos.selectedvalue;

    values.type2cpos=counter.type2positions.selectedvalue;
    values.type2cx=counter.type2xpos.selectedvalue;
    values.type2cy=counter.type2ypos.selectedvalue;
    ]
/ pretrialpause = 500
/ stimulusframes =  [1=type1,type2a,type2b,type2c]
/ validresponse = (57)
/ ontrialend = [reset(counter.type2positions)]
</trial>

<text type1>
/ items = ("Type 1")
/ hposition = values.type1x
/ vposition = values.type1y
</text>

<text type2a>
/ items = ("Type 2a")
/ hposition = values.type2ax
/ vposition = values.type2ay
</text>

<text type2b>
/ items = ("Type 2b")
/ hposition = values.type2bx
/ vposition = values.type2by
</text>

<text type2c>
/ items = ("Type 2c")
/ hposition = values.type2cx
/ vposition = values.type2cy
</text>

<counter type1positions>
/ items = (1,2,3,4)
/ select = noreplace
/ selectionrate = trial
</counter>

<counter type1xpos>
/ items = (25%, 25%, 75%, 75%)
/ select = current(type1positions)
</counter>

<counter type1ypos>
/ items = (25%, 75%, 25%, 75%)
/ select = current(type1positions)
</counter>

<counter type2positions>
/ items = (1,2,3,4)
/ select = noreplace
/ not = (type1positions)
/ selectionrate = always
</counter>

<counter type2xpos>
/ items = (25%, 25%, 75%, 75%)
/ select = current(type2positions)
/ selectionrate = always
</counter>

<counter type2ypos>
/ items = (25%, 75%, 25%, 75%)
/ select = current(type2positions)
/ selectionrate = always
</counter>



By charlottebooth - 9/22/2015

Hi Dave, thanks again for your great advice.
I think I have followed your instructions here by changing the x coordinates slightly (see below). The program still runs correctly. If this is correct could you suggest the simplest solution for creating a random slight flicker?

<counter targetxpos>
/ items = (29%, 29.0000001%, 29.000001%, 29.00001%, 29.0001%, 29.001%, 35%, 35.0000001%, 35.000001%, 35.00001%, 35.0001%, 35.001%, 41%, 41.0000001%, 41.000001%, 41.00001%, 41.0001%, 41.001%, 47%, 47.0000001%, 47.000001%, 47.00001%, 47.0001%, 47.001%, 53%, 53.0000001%, 53.000001%, 53.00001%, 53.0001%, 53.001%, 59%, 59.0000001%, 59.000001%, 59.00001%, 59.0001%, 59.001%, 65%, 65.0000001%, 65.000001%, 65.00001%, 65.0001%, 65.001%, 71%, 71.0000001%, 71.000001%, 71.00001%, 71.0001%, 71.001%)
/ select = noreplace
/selectionrate = trial
</counter>

<counter targetypos>
/ items = (35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%, 35%, 41%, 47%, 53%, 59%, 65%)
/ select = current(targetxpos)
</counter>

By Dave - 9/22/2015

> could you suggest the simplest solution for creating a random slight flicker?

I'm not sure what you mean by "flicker". If you actually mean "jitter", look at the code in my previous reply. You have all the coordinates stored in separate variables (<values> entries). Those values are populated /ontrialbegin. To introduce position jitter for each element, you can add or subtract a small, random amount from the respective x and y coordinate values.
By charlottebooth - 9/23/2015

Oh great! How exactly would you do this? I have now made all of the values for each target/distractor location! :)
By Dave - 9/23/2015

Let's go back to the example code at the end of my previous reply. Now, suppose you want to randomly jitter each x and y position in steps of 1% to dislocate the stimulus by either 1, 2 or 3% from its nominal x and y coordinates (I'm choosing deliberately large values such that the result is obvious on screen). Then you do:

<values>
/ type1pos = 0
/ type1x = 0
/ type1y = 0
/ type2apos = 0
/ type2ax = 0
/ type2ay = 0
/ type2bpos = 0
/ type2bx = 0
/ type2by = 0
/ type2cpos = 0
/ type2cx = 0
/ type2cy = 0
/ jitterstep = 1%
</values>

<block myblock>
/ trials = [1-4=mytrial]
</block>

<trial mytrial>
/ ontrialbegin = [values.type1pos=counter.type1positions.selectedvalue;
    values.type1x=counter.type1xpos.selectedvalue;
    values.type1y=counter.type1ypos.selectedvalue;

    values.type1x+=values.jitterstep*counter.randomjitter.selectedvalue;
    values.type1y+=values.jitterstep*counter.randomjitter.selectedvalue;


    values.type2apos=counter.type2positions.selectedvalue;
    values.type2ax=counter.type2xpos.selectedvalue;
    values.type2ay=counter.type2ypos.selectedvalue;

    values.type2ax+=values.jitterstep*counter.randomjitter.selectedvalue;
    values.type2ay+=values.jitterstep*counter.randomjitter.selectedvalue;


    values.type2bpos=counter.type2positions.selectedvalue;
    values.type2bx=counter.type2xpos.selectedvalue;
    values.type2by=counter.type2ypos.selectedvalue;

    values.type2bx+=values.jitterstep*counter.randomjitter.selectedvalue;
    values.type2by+=values.jitterstep*counter.randomjitter.selectedvalue;


    values.type2cpos=counter.type2positions.selectedvalue;
    values.type2cx=counter.type2xpos.selectedvalue;
    values.type2cy=counter.type2ypos.selectedvalue;

    values.type2cx+=values.jitterstep*counter.randomjitter.selectedvalue;
    values.type2cy+=values.jitterstep*counter.randomjitter.selectedvalue;

    ]
/ pretrialpause = 500
/ stimulusframes =  [1=type1,type2a,type2b,type2c]
/ validresponse = (57)
/ ontrialend = [reset(counter.type2positions)]
</trial>

<text type1>
/ items = ("Type 1")
/ hposition = values.type1x
/ vposition = values.type1y
</text>

<text type2a>
/ items = ("Type 2a")
/ hposition = values.type2ax
/ vposition = values.type2ay
</text>

<text type2b>
/ items = ("Type 2b")
/ hposition = values.type2bx
/ vposition = values.type2by
</text>

<text type2c>
/ items = ("Type 2c")
/ hposition = values.type2cx
/ vposition = values.type2cy
</text>

<counter type1positions>
/ items = (1,2,3,4)
/ select = noreplace
/ selectionrate = trial
</counter>

<counter type1xpos>
/ items = (25%, 25%, 75%, 75%)
/ select = current(type1positions)
</counter>

<counter type1ypos>
/ items = (25%, 75%, 25%, 75%)
/ select = current(type1positions)
</counter>

<counter type2positions>
/ items = (1,2,3,4)
/ select = noreplace
/ not = (type1positions)
/ selectionrate = always
</counter>

<counter type2xpos>
/ items = (25%, 25%, 75%, 75%)
/ select = current(type2positions)
/ selectionrate = always
</counter>

<counter type2ypos>
/ items = (25%, 75%, 25%, 75%)
/ select = current(type2positions)
/ selectionrate = always
</counter>

<counter randomjitter>
/ items = (-3,-2,-1, 1, 2, 3)
/ selectionrate = always
/ select = replace
</counter>


By charlottebooth - 9/23/2015

Thank you so much!
By charlottebooth - 9/23/2015

Thankyou! This is amazing help :)