Millisecond Forums

Complicated linking and selection of stimuli

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

By SmaugWithACamera - 3/13/2016

Hey Dave,

I have two really complicated questions (I think) that are partly intertwined with eachother and I don’t know if what either of them asks can be implemented in Inquisit.

A quick description of my experiment:

I have four phases:

1.Normal learning phase in which participants are presented with roughly 60 out of 100 picture stimuli of drawn objects (exact image number still has to be decided).

2.Second learning phase: 40 videos of the previous 60 pictures will be shown again. 20 of the videos will have property A (run forwards) whereas the other 20 will have property B (run backwards). The properties are already part of the videos so they are ready to be implemented as they are.

3.Distractor task

4.Recognition phase, sporting all the 60 pictures from the first phase + 40 unseen stimuli (distractors).

My first question refers to phases 1 and 2. Before the experiment starts I need Inquisit to divide my stimuli (say 100) into 40 distractor elements (phase 4), 20 phase-1-but-not-phase2 stimuli, 20 phase1and-2-video-A and 20 phase1-and-2-video-B stimuli. Of course no element should appear on two lists. Ideally one list would start picking, leaving a reduced list for the next to pick from and so forth.

However my problem is this: each stimulus must be linked with the two corresponding videos. The video of its creation (drawing process) and destruction (reversal of the drawing process) and this link is constant as it obviously wouldn’t make sense to have the drawing/reversal process paired with a wrong object.

Is it possible to create this fixed link for each stimulus with both video A and B?

After that, I’m not quite sure how the selection process for the items (phase 1, 2 and 4) should look like though because this seems to be relatively layered for me:

1.I assume we’ll have 1 entity (list?) linking all stimuli with videos A, 1 entity linking all the stimuli with videos B and one general list for all the stimuli

2.Then from those entities lists will be generated that divide the stimuli into either distractor, exhibit 1, exhibit2 or exhibit 3.

My first idea of drawing the items was that Inquisit draws 20 stimuli from the video-link list A, then 20 of the video-link list B, 20 of the normal list for exhibition and the 40 more from the same list as distractor. However if I draw items from three different pools then I don’t know how to make sure that they don’t overlap.
My second guess is to have those video lists be “inactive” in the beginning and that Inquisit draws the sets from one normal object list, ensuring that there are no double occupancies. Then those temporary “to be video” sets of 20 items each would be linked back to the constant video lists so that at the given point of the experiment those 20-item lists draw the videos from the video “motherpools”.

Is something like this even possible?

----


My second question will make the issue even more complicated but if that one can’t be implemented my experiment can at least still run regardless, so it’s not completely mandatory for me (would be nice for extra for the sake of experimental exactitude). (If the first question can't be resolved I have a problem though.)

I would also like to ensure that the frequency of stimuli appearing in each condition (exhibition 1,2,3 and distraction) is even over the course of the whole study (all participants) and not have some stimuli be in one condition disproportionally often whereas some others hardly appear in other categories.

Is it possible to have a counter that “remembers” which stimulus has been in which condition for, say, participant 1, incorporates this information into Inquisit’s selection process for participant 2 (e.g. object 1, being in video condition A for subject 1, doesn’t end up in the same condition for subject 2) and so forth and after 5 participants each (given 100 stimuli) it resets itself?

(This would mean that some of the distractor stimuli will have to appear twice because there are 40 of those and not 20. That’s inevitable but doesn’t matter as much, if each stimulus is at least once on the distractor list and only once on theother lists.)

I fear that it is not possible to program something that remembers and transfers information between participants or at least I can’t think of a way but I wanted to give it a shot either way.

Sorry for the extensive length.

Thank you very much for your time and have a good day

 Smaug
By Dave - 3/13/2016

#1 is certainly possible, but I don't fully understand the selection / linking process based on your description. It seems to me that all you need is a main <list> containing all item numbers (say 1 to 100). The item number is what uniquely defines a given stimulus or stimulus set (image #5 is associated with video a #5 and video b #5). So all you need to do is take your initial 100 item numbers and distribute them to the various conditions at random.

First fill the "learning" list with 60 randomly drawn items from the "main" list /onextptbegin. Then fill the "distractor" list with the remaining 40 items drawn at random. Then sample from the learning list -- draw 20 item numbers and put them in a "video a" <list>, draw another 20 and put them in a "video b" <list>. Done.

Here's an example of the above for 10 items:

<expt>
/ onexptbegin = [list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]

/ onexptbegin = [list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]

/ onexptbegin = [list.learningitemnumbers.reset(); ]

</expt>

<list allitemnumbers>
/ poolsize = 10
/ selectionrate = always
</list>

<list learningitemnumbers>
/ selectionrate = always
</list>

<list distractoritemnumbers>
</list>

<list vid_a_itemnumbers>
</list>

<list vid_b_itemnumbers>
</list>

#2 is not possible. If you need to ensure some kind on balanced stimulus distribution across participants, you need to create fixed sets of stimuli beforehand and treat those sets as between-subjects conditions. I.e., participant 1 receives fixed set A, participant 2 fixed set B, and so forth with the sets assembled such that they ensure the desired distribution across all participants / conditions.
By SmaugWithACamera - 3/14/2016

Hey Dave,

thank you very much. I've written the experiment but I can't check if it works because it always shuts itself down after the demographics section and returns this error message:

https://www.millisecond.com/forums/uploads/images/6eeb46c7-0490-4e67-bc81-db92.png

I can't make much out of this. I thought maybe it has to do with the item listing, so I changed it from /1, /2.../10 to /0, /1.../9 but that didn't change the behaviour and error output.


Here is my script regarding the selection and item aspects:

<include>
/ precondition=[computer.platform == "windows"]
/ file="Hauptstudie.iqx"
</include>

<expt>
/ onexptbegin = [list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]

/ onexptbegin = [list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]
/ onexptbegin = [list.learningitemnumbers.reset(); ]
</expt>




<list allitemnumbers>
/ poolsize = 10
/ selectionrate = always
</list>

<list learningitemnumbers>
/ selectionrate = always
</list>

<list distractoritemnumbers>
</list>

<list vid_a_itemnumbers>
</list>

<list vid_b_itemnumbers>
</list>

<item Bilder>
/1 = "1.png"
/2 = "2.png"
/3 = "3.png"
/4 = "4.png"
/5 = "5.png"
/6 = "6.png"
/7 = "7.png"
/8 = "8.png"
/9 = "9.png"
/10 = "10.png"
</item>

<item Videos_A>
/1 = "1.wmv"
/2 = "2.wmv"
/3 = "3.wmv"
/4 = "4.wmv"
/5 = "5.wmv"
/6 = "6.wmv"
/7 = "7.wmv"
/8 = "8.wmv"
/9 = "9.wmv"
/10 = "10.wmv"
</item>

<item Videos_B>
/1 = "1.wmv.rev.wmv"
/2 = "2.wmv.rev.wmv"
/3 = "3.wmv.rev.wmv"
/4 = "4.wmv.rev.wmv"
/5 = "5.wmv.rev.wmv"
/6 = "6.wmv.rev.wmv"
/7 = "7.wmv.rev.wmv"
/8 = "8.wmv.rev.wmv"
/9 = "9.wmv.rev.wmv"
/10 = "10.wmv.rev.wmv"
</item>

<picture learningitemnumbers>
/items = Bilder
/ select = list.learningitemnumbers.nextvalue
/ size = (75%, 75%)
</picture>

<picture distractoritemnumbers>
/items = Bilder
/ select = list.distractoritemnumbers.nextvalue
/ size = (75%, 75%)
</picture>

<video vid_a_itemnumbers>
/items = Videos_A
/ select = list.vid_a_itemnumbers.nextvalue
/ size = (75%, 75%)
</video>

<video vid_b_itemnumbers>
/items = Videos_B
/ select = list.vid_b_itemnumbers.nextvalue
/ size = (75%, 75%)
</video>


Any idea?

(Out of curiosity: What is the difference between .nextindex and .nextvalue?)



By Dave - 3/14/2016

The <list>s are empty when those <picture> and <video> elements are parsed -- i.e., they contain no items. You cannot do

<picture learningitemnumbers>
/items = Bilder
/ select = list.learningitemnumbers.nextvalue
/ size = (75%, 75%)
</picture>

You need to work with <values> and -- once the lists are set up -- have your trials set those values to items sampled from the respective lists.

<picture learningitemnumbers>
/items = Bilder
/ select = values.learningitem
/ size = (75%, 75%)
</picture

<values>
/ learningitem = 1
...
</values>

<trial learningtrial>
/ ontrialbegin = [values.learningitem = list.learningitemnumbers.nextvalue; ]
...
</trial>

On the difference between *index* and *value*

<list example>
/ items = (23, 42, 666, 23)
</list>

The *value* of the 1st item is 23, its *index* is 1 (it is the 1st item in the list).
The value of the 2nd item is 42, its index is 2.
The value of the 3rd item is 666, its index is 3.
The value of the 4th item is 23, its index is 4.
By SmaugWithACamera - 3/14/2016

Edit: I fixed the issue mentioned above by removing this line.
/ onexptbegin = [list.learningitemnumbers.reset(); ]

Was that important or can it safely be removed?

Because It runs almost smoothly now. There is just one problem:

Normally the list learningitemnumbers should encompass 6 items. However when I run my experiment in the first learning phase (still pictures), inquisit only retrieves 5 different elements from the list and reuses one of those five for the last spot (the trial is supposed to show 6 differen items). In the other learning phases (the video phases) the "hidden" 6th* item can appear though (e.g. in the video phases or in the regocnition phase). In the regocnition phase there is an item overlap again, however it is random and as thus not always the doubled item from learning phase 1.

* Not saying that it is always item at list index 6. It's random which item is left out and which one appears twice.

When I add a 7th line to the list generation process (/onexpbegin=.....) then the items in the first learning phase don't overlap (still /trials = 1 - 6), but the problem with the not-supposed-to-be-there new item in the video conditions still occurs.
Setting the block element /trials to 1-7 results into the same problem I have with the original set-up.


I don't really understand why the learningitemnumbers list is categorically lacks an item when trials access it because the other lists work fine in those situations . At least there never has been a double item because of the list being 'incomplete'. Also, in itself the learningitemnumbers list seems to have six items, otherwise the video lists which feed on it couldn't draw the sixth item.


-----


In case it's needed I added the script for the trials and blocks. (The list selection script is the same except for the removed line and some name changes for the pictures & videos section.)

<trial lernen>
/stimulusframes = [1 = maske, fixation; 66 = learningitem]
/trialduration = 3000
/recorddata = true
/ontrialend = [values.datei = picture.learningitem.currentitem]
</trial>

<trial lernen_a>
/stimulusframes = [1 = maske, fixation; 66 = vid_a_item]
/trialduration = 3000
/recorddata = true
/ontrialend = [values.datei = (video.vid_a_item.currentitem)]
</trial>

<trial lernen_b>
/stimulusframes = [1 = maske, fixation; 66 = vid_b_item]
/trialduration = 3000
/recorddata = true
/ontrialend = [values.datei = (video.vid_b_item.currentitem)]
</trial>

<trial distr>
/stimulusframes = [1 = maske; 2 = distr.text]
/recorddata = false
/trialduration = 3000
/response = noresponse
</trial>

<trial distr.ob>
/stimulusframes = [1 = distractoritem]
/inputdevice = mouse
/correctresponse = (rbuttondown)
/validresponse = (lbuttondown, rbuttondown)
/ontrialend = [values.datei = picture.distractoritem.currentitem]
/responsetrial = (lbuttondown, sicherheit2)
/responsetrial = (rbuttondown, sicherheit2)
/showmousecursor = false
</trial>

<trial objekt>
/stimulusframes = [1 = learningitem]
/inputdevice = mouse
/correctresponse = (rbuttondown)
/validresponse = (lbuttondown, rbuttondown)
/ontrialend = [values.datei = picture.learningitem.currentitem]
/responsetrial = (lbuttondown, sicherheit)
/responsetrial = (rbuttondown, sicherheit)
/showmousecursor = false
</trial>

<block lernen>
/preinstructions = (inst.1)
/screencolor = (0, 0, 0)
/trials = [1 - 6 = lernen]
</block>

<block lernen2>
/preinstructions = (inst.1a)
/screencolor = (0, 0, 0)
/trials = [1 - 4 = noreplace(lernen_a, lernen_b)]
</block>

<block aufgabe>
/screencolor = (0, 0, 0)
/preinstructions = (inst.2)
/trials = [1 = sequence(distr, distr2)]
/showmousecursor = false
</block>

<block abfrage>
/ bgstim = (Hilfe1, Hilfe2)
/preinstructions = (inst.3)
/screencolor = (0, 0, 0)
/trials = [1 - 10 = noreplace(objekt, objekt, objekt, distr.ob, distr.ob)]
</block>
<expt>
/ onexptbegin = [list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.learningitemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex);
    list.distractoritemnumbers.appenditem(list.allitemnumbers.nextindex); ]

/ onexptbegin = [list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_a_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]

/ onexptbegin = [list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue);
    list.vid_b_itemnumbers.appenditem(list.learningitemnumbers.nextvalue); ]
/blocks = [1 = Demographie; 2 = lernen; 3 = lernen2; 4 = aufgabe; 5 = abfrage]
/preinstructions = (instruktion1)
/postinstructions = (abschluss)
</expt>

<data >
/ columns = [subject, blockcode, trialnum, trialcode, latency, response, values.datei, stimulusitem, script.groupid]
/ separatefiles = TRUE
</data>

By SmaugWithACamera - 3/14/2016

Ah, sorry Dave, I started to write my reply but it took me so long that in the mean time you answered. I'll read through your reply now.
By Dave - 3/14/2016

> / onexptbegin = [list.learningitemnumbers.reset(); ]

Is necessary. When you set up the video lists /onexptbegin you *sample* several items -- but not all items --  from list.learningitemnumbers. I.e., once that's done there are a few *unsampled* items left in the list.

Since you want *all* items to be available when the respective trials actually start, the list needs to be reset. Otherwise, the list would sample the (here: 2) unsampled items first, and then reset midway through the experiment because the list ran out of items. That would make *all its* items (here: 6) available again, including the 2 already used.
By SmaugWithACamera - 3/15/2016

Hey Dave,

sorry to get back so soon but I haven't worked with values before and have admittedly no understanding of them so I was unsure what to really do after the ... part in
<values>
/ learningitem = 1
...
</values>

I tried this:

<values>
/learn = 1
/vid1 = 1
/vid2 = 1
/distr = 1
</values>

<picture learningitem>
/items = Bilder
/ select = values.learn
/ size = (75%, 75%)
</picture>

<picture distractoritem>
/items = Bilder
/ select = values.distr
/ size = (75%, 75%)
</picture>

<video vid_a_item>
/items = Videos_A
/ select = values.vid1
/ size = (75%, 75%)
</video>

<video vid_b_item>
/items = Videos_B
/ select = values.vid2
/ size = (75%, 75%)
</video>

and inserted the /ontrialbegin line into every trial but the afore-mentioned error still remains.
(Example:
<trial lernen_a>
/ ontrialbegin = [values.vid1 = list.vid_a_itemnumbers.nextvalue; ] )


Since I don't understand the mechanism of values (and the manual is a bit scarce in its explaination) I didn't really know what else I could alter so I have to come back here without any further progress.
(E.g. I don't understand why you set it to 1 because in the manual all examples are set to 0.)
By Dave - 3/15/2016

values are what you know as global variables in other programming languages. You set them to some value and they keep that value until you set them to something else (e.g. a new item number sampled from a <list>).

They are initialized with a value equal to one in this cases because *files* are involved -- i.e., there can be no such thing as a "zero-th" or "null" item in <picture> or <video> elements. That wouldn't map to any actual file and you'd get an error.
By SmaugWithACamera - 3/15/2016

Hey Dave!

Thank you very much for the explanation! Now it makes sense to me.

The problem still remains though, even after defining values. :unsure: Inquisit still puts out the error I screencapped earlier. (I don't know if it tries to tell me that there is an "undefined" 0th item or if <pictures learningitem> is completely empty. Either way Inquisit can't access it but apparently the other <picture>/<video> elements are fine, even though they are programmed the same way if I'm not mistaken.)

Sorry, I know this is really tedious...
By Dave - 3/15/2016

I am not sure how to answer this without (a) being able to see the current state of the actual code and (b) access to the actual image files. Please be so kind and provide both (please do not include the videos). Thanks.
By SmaugWithACamera - 3/15/2016

Hey Dave,

sure no problem. I've put the whole script and the picture files into a dropbox folder:

https://www.dropbox.com/sh/2qw2xezx3xixwyd/AACUR7r6RJquOxQ_icgJ2eaMa?dl=0

Thanks again!
By Dave - 3/15/2016

Thank you for sharing the files. Turns out this was my boneheaded mistake from the get-go. The final /onexptbegin statement after setting up the lists

<expt>
...
/ onexptbegin = [list.learningitemnumbers.reset(); ]
...
</expt>

ought to actually read

<expt>
...
/ onexptbegin = [list.learningitemnumbers.resetselection(); ]
...
</expt>

in this case to work properly. reset() would not only reset selection, but also return the <list> to its initial (empty) state. Which of course doesn't make any sense here. Sorry about that.
By SmaugWithACamera - 3/16/2016

Great! Now it works exactly as I intended. :)

Thank you very much!

I have one last question regading the presentation of stimuli:

My videos differ in length so if I use a fixed trial duration I'll have problems keeping the presentation free of confoundation because either longer videos will be cut off or there will be a longer break between trials if the videos are shorter.
Is it possible if you have one defined trial that is applied to a pool of videos to let it play out the video and then automatically move on when it's completed or is this kind of dynamic video stimulus presentation impossible?


<trial lernen_b>
/ ontrialbegin = [values.vid2 = list.vid_b_itemnumbers.nextvalue; ]
/stimulusframes = [1 = maske, fixation; 66 = vid_b_item]
/trialduration = 3000 (<--- dummy value as 3000 is too short for any video)
/recorddata = true
/ontrialend = [values.datei = (video.vid_b_item.currentitem)]
</trial>



By Dave - 3/16/2016

Yes. Set the <trial> to some short /timeout or /trialduration and -- importantly -- set the <video> elements' /playthrough attributes to 'true'.
By SmaugWithACamera - 3/16/2016

Hey Dave,

now the experiment runs exactly how I hoped it would.

Thanks a lot for all your your help!