How to take stimuli from several lists for RSVP task


Author
Message
KO
KO
KO
posted 9 Years Ago HOT
Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)
Group: Forum Members
Posts: 18, Visits: 107
Hi all,

I'm currently putting together an affective RSVP task where T1 is a neutral stimulus and T2 is an affective stimulus. For this reason, I need to include two target lists as well as a list of distractor items. Also, then, while the items are meant to appear in a designated order in terms of their placement within the stream of words, the items are meant to be randomised in terms of the order in which the words actually sit on the specific list that they come from, and no item from any list is to appear more than once. 

I know, since you'll notice I'm new here (and so this experiment in fact represents my first attempt at doing coding) and also because I've read a lot of the answers to the questions posted, what you might ask me next. It's a fair enough question to ask what I've tried to do by myself prior to posting this question. In answer, I have previously done the tutorials, looked up and used the two RSVP tasks that Millisecond Software made available to download (AttentionalBlink and Simple_SimpleAttentionalBlink) as models and attempted to replicate parts of this that seem useful while still trying to make it suit what I'm doing, and tried to look for a post where someone else has had similar issues that might display the sort of coding I'm after. 

Anyway, unfortunately, even after doing all that, at this point I feel as though I must be missing something pretty fundamental for the experiment to never include the two target stimuli, Target1 and Target2, when it is running through, which is the major issue I keep coming up against. (To explain that in a little more detail, what I mean is that it will go through the distractors and display them (although I'm not sure that they are being displayed in randomised order as they are meant to be and I think they may be being repeated here) and it will even ask what T1 and T2 were in the response part of the trial as it is meant to do, but it won't actually include T1 and T2 in the stream of stimuli.)  

I'm going to include here the trial sections, since it's my belief that something that I've set up in the coding in this section is probably at least one of the bigger aspects of the problems I'm running up against. (Please see below.)

Any and all help would be very much appreciated.   :-)


************************************************************
Trial Sequence
*************************************************************
<trial t1_T2_fixation>
/ontrialbegin = [values.streamelement_count = 0]
/ontrialbegin = [values.target1_stim = ""; values.target2_stim = ""]
/ontrialbegin = [values.trialcount_perblock += 1]
/stimulusframes = [1 = fixation]
/trialduration = values.fixationduration
/branch = [trial.target1_target2_streamelement]
/recorddata = false
/errormessage = false
</trial>




<trial Target1_Target2_streamelement>
/ontrialbegin = [values.streamelement_count += 1]
/ontrialbegin = [values.word = list.words_distractors.nextvalue]
/ontrialbegin = [text.currentword.textcolor = values.wordcolor]
/stimulusframes = [1 = currentword]
/ontrialend = [values.wordsshown = values.wordsshown +1]
/timeout = values.stimuluspresentation
/posttrialpause = values.word_ISI
/recorddata = false
/errormessage = false
/branch=[if (values.wordsshown == values.target1_streamposition) trial.words_target1; else trial.target1_target2_streamelement]
/branch=[if (values.streamelement_count == values.max_streamelements) trial.responsecue; else trial.target1_target2_streamelement]
/branch=[if (values.wordsshown == values.target2_streamposition) trial.words_target2; else trial.target1_target2_streamelement]
</trial>


<trial words_target1>
/ontrialbegin = [values.streamelement_count += 1]
/ontrialbegin = [values.word = list.words_target1.nextvalue]
/ontrialbegin = [text.currentword.textcolor = values.wordcolor]
/ontrialbegin = [if (values.Target1_stim == true) values.lag = values.target1_streamposition]
/ontrialbegin = [if (values.Target1_stim == true) values.Target1_stim = list.words_target1.nextvalue]
/ontrialbegin = [values.target1_streamposition = values.target2_streamposition - values.lag]
/ontrialbegin = [if (values.streamelement_count == values.target1_streamposition)
                        {    values.target1_stim = values.word;
                            text.currentword.textcolor = values.target1stim_color}]
/stimulusframes = [1 = currentword]
/ontrialend = [values.wordsshown = values.wordsshown +1]
/timeout = values.stimuluspresentation
/posttrialpause = values.word_ISI
/recorddata = false
/errormessage = false
/branch=[if (values.wordsshown == values.target2_streamposition) trial.words_target2; else trial.target1_target2_streamelement]
</trial>



<trial words_target2>
/ontrialbegin = [values.streamelement_count += 1]
/ontrialbegin = [values.word = list.words_distractors.nextvalue]
/ontrialbegin = [text.currentword.textcolor = values.wordcolor]
/ontrialbegin = [if (values.target2_stim == true) values.lag = values.target2_streamposition]
/ontrialbegin = [if (values.target2_stim == true) values.target2_stim = list.words_target2.nextvalue]
/ontrialbegin = [values.target2_streamposition = list.target2position]
/ontrialbegin = [if (values.streamelement_count == values.target2_streamposition)
                        {    values.target2_stim = values.word;
                            text.currentword.textcolor = values.target2stim_color}]
/stimulusframes = [1 = currentword]
/ontrialend = [values.wordsshown = values.wordsshown +1]
/timeout = values.stimuluspresentation
/posttrialpause = values.word_ISI
/recorddata = false
/errormessage = false
/branch= [trial.target1_target2_streamelement]
</trial>



********************************
Trial response
*********************************
<trial responsecue>
/stimulusframes = [1 = responsecue]
/recorddata = false
/trialduration = values.responsecue_duration
/recorddata = false
/branch = [openended.Target1]
/errormessage = false
</trial>

Note: openended.targetnaming
collects the response for T1
<openended Target1>
/stimulusframes = [1 = Targetnamingtaskinstructions1]
/linelength = 20
/numlines = 1
/buttonlabel = "Click to continue"
/branch = [openended.target2]
/recorddata = true
</openended>



Note: collects the response for T2
<Openended Target2>
/stimulusframes = [1 = Targetnamingtaskinstructions2]
/linelength = 20
/numlines = 1
/buttonlabel = "Click to continue"
/recorddata = true
</openended>




Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 13K, Visits: 104K
Your <trial>s display a stimulus called "currentword". At the beginning of each trial, the item selection for currentword is performed by pulling an item's index number from either the distractor <list> or one of the two target <list>s. You need to make sure that the index numbers contained in those lists actually correspond to the distractor and target item numbers in the "currentwords" stimulus respectively. Suppose you have 4 distractors, 4 target1 items and 4 target2 items. Then

<text currentword>
/ items = allitems
/ select = values.word
...
</text>

<item allitems>
/ 1 = "distractor 1"
/ 2 = "distractor 2"
/ 3 = "distractor 3"
/ 4 = "distractor 4"

/ 5 = "target1 1"
/ 6 = "target1 2"
/ 7 = "target1 3"
/ 8 = "target1 4"

/ 9 = "target2 1"
/ 10 = "target2 2"
/ 11 = "target2 3"
/ 12 = "target2 4"
</item>

then the respective <list> elements would have to reflect the above item numbers like so:

<list words_distractors>
/ items = (1,2,3,4)
...
</list>

<list words_target1>
/ items = (5,6,7,8)
...
</list>

<list words_target2>
/ items = (9,10,11,12)
...
</list>

Also, <trial words_target2> is pulling from the wrong list altogether:

<trial words_target2>
/ontrialbegin = [values.streamelement_count += 1]
/ontrialbegin = [values.word = list.words_distractors.nextvalue]
...
</trial>

There are various other issues and you should review your code in detail. For example, it is unclear what you aim to achieve with


<trial words_target1>
/ontrialbegin = [values.streamelement_count += 1]
/ontrialbegin = [values.word = list.words_target1.nextvalue]
/ontrialbegin = [text.currentword.textcolor = values.wordcolor]
/ontrialbegin = [if (values.Target1_stim == true) values.lag = values.target1_streamposition]
/ontrialbegin = [if (values.Target1_stim == true) values.Target1_stim = list.words_target1.nextvalue]

...
</trial>

I cannot see any place in your code where you actually set values.target1_stim (or values.target2_stim for that matter) to either true or false. Instead you set those to the empty string in

<trial t1_T2_fixation>
/ontrialbegin = [values.streamelement_count = 0]
/ontrialbegin = [values.target1_stim = ""; values.target2_stim = ""]
...
</trial>

Finally, for testing purposes, set your various /recorddata attributes to true. That will enable you to better track down your programming errors by examining the data file.

Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 13K, Visits: 104K
Since I happen to have it around, attached is another RSVP script which may be useful to work through as an example to learn from. It is somewhat simpler than the ones you'll find in the test library and thus may be easier to grasp.

Attachments
rsvp.iqx (815 views, 5.00 KB)
KO
KO
Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)
Group: Forum Members
Posts: 18, Visits: 107
Hi Dave,

Thank you so much for your prompt and informative responses to my message. :-)

This message is really just to say that, since I'm going to need some time to review the information that you've given me in order to then respond to your feedback more fully. So again, thank you very much for that, and I'll post a proper response when I've had a chance to work through all the information and coding etc. that you've provided.

KO
KO
Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)
Group: Forum Members
Posts: 18, Visits: 107
Hi again Dave,

So I've had time to go over in detail the RSVP script you provided. It's definitely a lot simpler to understand than the other two scripts that I downloaded from the Inquisit website previously, so I was really grateful that you included that in your last post. Thank you! :-0 
Oh, and I also really appreciated your inclusion of the <text debug> which has really helped me with figuring out what goes wrong when I've been making changes to that script. (I also did look at the additional ideas you had on how to create two or more lists from the one <text> section, and I appreciated your help with that, but ultimately it seemed most straightforward to use the script that you provided and expand on that.) 
So what I did was add an additional <text> section so that I now have one for T1 and one for T2 <text Target1> and <text Target2>, with one set of stimuli within each of these sections (so that I could separate out the two sets of stimuli). So then I have also separated out T1 and T2 coding into 2 trial sections:

<trial target1trial>
/ ontrialbegin = [values.currentposition += 1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.target1.currentitem)]
/ ontrialend = [if(values.t1position==values.currentposition) values.t1item=text.target1.currentitem]
/ stimulusframes = [1=target1, debug]
/ trialduration = 100
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [if(values.t2position==values.currentposition+1)
    trial.target2trial else trial.distractortrial]
</trial>


<trial target2trial>
/ ontrialbegin = [values.currentposition += 1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.target2.currentitem)]
/ ontrialend = [if(values.t2position==values.currentposition) values.t2item=text.target2.currentitem]
/ stimulusframes = [1=target2, debug]
/ trialduration = 100
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [trial.distractortrial]
</trial>


* Just because it's important to the issue I'm about to mention next I'll also say that I've changed the positions of T1 and T2 as well, as in this practice block:

3 T1 positions (3,4,5) x 4 T2 lags (1,2,3,4) > 24 trials
<list pt1positionlist>
/ items = (3,4,5,3,4,5,3,4,5,3,4,5,
    3,4,5,3,4,5,3,4,5,3,4,5)
/ selectionmode = random
/ replace = false
</list>

<list pt2laglist>
/ items = (1,1,1,1,1,1,2,2,2,2,2,2,
    3,3,3,3,3,3,4,4,4,4,4,4)
/ selectionmode = list.pt1positionlist.currentindex
</list>

So, on to the current problem. When looking at the <text debug> as the monkey runs through the task, it appears that there is no issue with the task when T2 immediately follows T1. However, if T2 does not follow directly after T1, then T2 does not appear in the trial at all. Because T2 does follow T1 if it is presented immediately after T1 I believe that the problem is most likely located in the <trial distractor.trial> section, probably somewhere in the branching section. 

I've had a few thoughts on this, and I think it must be some sort of additional conditional statement required here, or else some change of coding in the branching section as I've written it. In any case, I'm out of ideas now since nothing I've tried has fixed the problem. This is what I've got in the distractor trial at the moment:

<trial distractortrial>
/ ontrialbegin = [values.currentposition += 1]
/ontrialbegin = [values.t1position==values.currentposition+1 || values.t2position==values.currentposition+1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.distractor.currentitem)]
/ stimulusframes = [1=distractor, debug]
/ trialduration = 100
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [if (values.currentposition >= values.streamlength) openended.responsetrial]
/ branch = [if (values.t1position == values.currentposition +1) trial.target1trial else trial.distractortrial]
/ branch = [if (values.t2position == values.currentposition +1) trial.target2trial else trial.distractortrial]
</trial>

Could you please tell me what thing/s I'm doing wrong here/what corrections I need to make to this code so that T2 consistently runs?

Many thanks once again for your previous help and really hoping for some more help on this again sometime soon. :-)





Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 13K, Visits: 104K
<trial distractortrial>
/ ontrialbegin = [values.currentposition += 1]
/ontrialbegin = [values.t1position==values.currentposition+1 || values.t2position==values.currentposition+1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.distractor.currentitem)]
/ stimulusframes = [1=distractor, debug]
/ trialduration = 100
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [if (values.currentposition >= values.streamlength) openended.responsetrial]
/ branch = [if (values.t1position == values.currentposition +1) trial.target1trial else trial.distractortrial]
/ branch = [if (values.t2position == values.currentposition +1) trial.target2trial else trial.distractortrial]
</trial>

The problem is the 'else' in the above /branch attribute. /branch attrbutes are examined in the order given. Think about what happens:

If (values.t1position) evaluates to 'true', trial.target1trial is called. *In all other cases* ("else"), trial.distractortrial is called. Your code never even gets to evaluating the last /branch attribute.

Your code should read


<trial distractortrial>
/ ontrialbegin = [values.currentposition += 1]
/ontrialbegin = [values.t1position==values.currentposition+1 || values.t2position==values.currentposition+1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.distractor.currentitem)]
/ stimulusframes = [1=distractor, debug]
/ trialduration = 100
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [if (values.currentposition >= values.streamlength) openended.responsetrial]
/ branch = [if (values.t1position == values.currentposition +1) trial.target1trial
                else if (values.t2position == values.currentposition +1)
                else trial.distractortrial]
</trial>
KO
KO
Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)
Group: Forum Members
Posts: 18, Visits: 107
Hi Dave,

Thank you again so much for all of your help!
The RSVP task is now working just as it should, and I am so pleased about that! :-)
I hadn't actually understood that branching worked in the way that you described in your last post, so I'm also really glad to learn that so as to hopefully avoid making that particular mistake again in future.


Other than that, there's just one thing I'm going to mention for anyone else who's reading this post, just something minor I had to add to that line of code that Dave corrected for it to work properly for me:
<trial distractortrial>
/ ontrialbegin = [values.currentposition += 1]
/ontrialbegin = [values.t1position==values.currentposition+1 || values.t2position==values.currentposition+1]
/ ontrialend = [values.streamstring = concat(values.streamstring, text.distractor.currentitem)]
/ stimulusframes = [1=distractor, debug]
/ trialduration = 700
/ posttrialpause = 50
/ validresponse = (noresponse)
/ recorddata = false
/ branch = [if (values.currentposition >= values.streamlength) openended.responsetrial]
/ branch = [if (values.t1position == values.currentposition +1) trial.target1trial
                else if (values.t2position == values.currentposition +1) trial.target2trial
                else trial.distractortrial]
</trial>


Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 13K, Visits: 104K
> else if (values.t2position == values.currentposition +1) trial.target2trial

Ooops, my mistake. Sorry about that.

KO
KO
Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)Esteemed Member (2.5K reputation)
Group: Forum Members
Posts: 18, Visits: 107
Hi again,

So, it's all going really well now. I just wanted to post about two things that tripped me up for a while with regard to the RSVP task as I've been in the process of figuring out what I'm doing and how to get the RSVP task working in the way that I needed it to. I'm posting them because I thought perhaps they might potentially also trip others like me who are still getting to know how to use Inquisit.

The first thing is to do with the "range attribute". It took me a while to realise that the inclusion of the range attribute in my openended trial section was what was causing the non-monkey version of the program not to allow me to continue on past my first response when I started piloting my task. Not to say that you can't use the range attribute in your openended trial section, only that including it means that your response has to fall within certain parameters, that is of course, it turns out, what range attribute is all about. However, I wasn't doing that with regard to the words I needed to input into that section. Anyway, I've just taken that out completely and now I don't get stuck there anymore.

The second thing I had difficulties with was in regard to how to get the program to in a sense "see" the correct answers I was inputting into the program as correct. Again, this took me far longer to figure out than it probably should have, but it turns out this was down to the way in which the "concat" part of the programming, again, within the openended trial section, was set up. So, in the case of my RSVP task I'm having participants enter in two words. Unfortunately, however, with the way that the coding there started out, correct words were marked as incorrect because the program would only accept what was effectively only one word. So, in terms of setting this up, this means that rather than have the program be like this:  concat("basket", "ball"), which has to be entered as "basketball", it needed to be set up like this: concat(concat("United", " "), "States"), so that the two words could be entered separately, as in "United States"  
(By the way, these two specific examples used above are taken from the functions sections of help which is where I went to and so finally figured out what was going wrong in this case).

Anyway, hope that helps some other people who've maybe been grappling with these same issues!  :-)



Dave
Dave
Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)Supreme Being (1M reputation)
Group: Administrators
Posts: 13K, Visits: 104K
Thanks for posting this. I'm sure it will be useful to others.

I think trying to figure things out for yourself is a great -- maybe the best -- way to learn.

It's also perfectly fine to post any questions you have / problems you encounter here. That's what this place is for.

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Explore
Messages
Mentions
Search