Branch Conditional Logic


Author
Message
Psych_Josh
Psych_Josh
Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)
Group: Forum Members
Posts: 85, Visits: 397
Dear all,

I'm having a minor issue with some branch conditional logic - 

<trial response>
/stimulustimes = [500 = cross]
/validresponse = ("Q", "P")
/branch = [if (trial.response.response == "Q") trial.trialhappystart]
/branch = [if (trial.response.response == "P") trial.trialsadstart]
/recorddata = false
</trial>

<trial trialhappystart>
/stimulustimes = [500 = cross]
/correctresponse = (" ")
/pretrialpause = 500
/branch = [trial.trialhappyface]
/recorddata = false
</trial>

<trial trialsadstart>
/stimulustimes = [500 = cross]
/correctresponse = (" ")
/pretrialpause = 500
/branch = [trial.trialsadface]
/recorddata = false
</trial>

Somehow, it starts the trial, registers the response (Q or P), but loops back to itself, instead of branching to the designated trial. I thought this would be quite simple, and have looked at multiple examples, but somehow mine fails. If it's relevant, at the block level I have:

<block TimeEstimation>
/onblockbegin = [values.onset=0; values.intervalestimation=0; values.stimuli=0;]
/preinstructions = (main)
/trials = [1-5 = noreplace(response)]
</block>

Many thanks in advance,
Josh
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 response>
...
/branch = [if (trial.response.response == "Q") trial.trialhappystart]
/branch = [if (trial.response.response == "P") trial.trialsadstart]
...
</trial>

The response-property does *not* return the "literal" key value. It returns the associated keyboard scancode (see the "Keyboard Scan Codes" topic in the documentation as well as 'Tools -> Keyboard Scancodes...'). Hence neither of your /branch conditions ever evaluates to true and no branch is executed. They ought to read

/branch = [if (trial.response.response == 16) trial.trialhappystart]
/branch = [if (trial.response.response == 25) trial.trialsadstart]

where 16 is the scan code corresponding to the Q-key on a standard QWERTY (or QWERTZ) keyboard layout and 25 corresponds to P. Note that this will, for example, not work on an AZERTY keyboard, where the A-key is associated with scancode 16 (scancodes more or less indicate physical position on a keyboard, not a particular symbol).

Psych_Josh
Psych_Josh
Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)
Group: Forum Members
Posts: 85, Visits: 397
Hi Dave,

Thanks for quick response. Sadly, this has not resolve the issue. I have attached my script in case that helps!

Many thanks,
Josh
Attachments
Binding_Forum.iqx (581 views, 15.00 KB)
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 response>
/stimulustimes = [500 = cross]
/validresponse = (17, 25)
/branch = [if (trial.response.response == "Q") trial.trialhappystart]
/branch = [if (trial.response.response == "P") trial.trialsadstart]
/recorddata = false
</trial>

This is wrong.

#1: Scancode 17 in your /validresponse attribute is *not* the Q-key. 17 would indicate "W" on most keyboards (but not on all; AZERTY being an exception again).
#2: The /branch attributes *still* try to use literal key values, not scancodes.


<trial response>
/stimulustimes = [500 = cross]
/validresponse = (17, 25)
/branch = [if (trial.response.response == 17) trial.trialhappystart]
/branch = [if (trial.response.response == 25) trial.trialsadstart]
/recorddata = false
</trial>
Psych_Josh
Psych_Josh
Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)
Group: Forum Members
Posts: 85, Visits: 397
Thanks Dave. The keyboard I will be using has Q mapped as 17, but your suggestions have worked regardless.

I also wanted to include the open ended question "Was the previous face positive or negative?" as an attention task that would be presented at random times throughout the experiment, and also didn't want to pester you with another question, however I've found no obvious solution online. The participant will be presented with faces randomly (positive or negative), thus I can't write a simple openended question with a designated correct response, as it will entirely depend on the previous face they've been shown. Therefore, is there a way to manipulate the 'correctresponse' depending on stimuli presented to the participant last (and deliver 'correctmessage'/'errormessage' accordingly)?

<values>
/CatchTrial = 0
</values>

<item catch>
/1 = "Was the previous face positive or negative?"
</item>

<text catch>
/items = ("Was the previous face positive or negative?")
/color = (0,0,0)
/position = (50, 30)
</text>

<openended catchtrial>
/stimulusframes=[1 = catch]
/correctmessage = "Correct!"
/errormessage = "False"
/position = (50, 50)
/buttonlabel = "Click here to advance"
/linelength = 50
/charlimit = 30
/numlines = 1
/size = (500, 50)
/recorddata = true
/required = true
/ontrialend = [values.catchtrial = response]
</openended>

Please let me know if you need anymore information.

Many thanks,
Josh
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
> is there a way to manipulate the 'correctresponse' depending on stimuli presented to the participant last

Yes. You need to store the type of the last presented stimulus somewhere (e.g. in a global variable, meaning a <values> entry) and then use the <openended> element's /iscorrectresponse attribute (*not* correctresponse) to evaluate the response. An example is below. Beyond that, your <openended> has a number of syntax issues, which I've also fixed below. Please review those in addition.

<values>
/ last_stimulus = ""
/ CatchTrial = 0
</values>

<block myblock>
/ trials = [1-4 = noreplace(happytrial, sadtrial); 5 = catchtrial]
</block>

<trial happytrial>
/ ontrialend = [values.last_stimulus = "positive"]
/ stimulusframes = [1=smile]
/ trialduration = 2000
</trial>

<text smile>
/ items = (":-)")
</text>

<trial sadtrial>
/ ontrialend = [values.last_stimulus = "negative"]
/ stimulusframes = [1=frown]
/ trialduration = 2000
</trial>

<text frown>
/ items = (":-(")
</text>

<text catch>
/items = ("Was the previous face positive or negative?")
/color = (0,0,0)
/position = (50, 30)
</text>

<openended catchtrial>
/stimulusframes=[1 = catch]
/correctmessage = true(correcttxt, 1000)
/errormessage = true(errortxt, 1000)
/position = (50, 50)
/buttonlabel = "Click here to advance"
/linelength = 50
/charlimit = 30
/numlines = 1
/size = (500, 50)
/recorddata = true
/required = true
/ontrialend = [values.catchtrial = openended.catchtrial.response]
/ iscorrectresponse = [openended.catchtrial.response == values.last_stimulus]
</openended>

<text correcttxt>
/ items = ("Correct!")
/ position = (50%, 90%)
</text>

<text errortxt>
/ items = ("False")
/ position = (50%, 90%)
</text>

Psych_Josh
Psych_Josh
Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)
Group: Forum Members
Posts: 85, Visits: 397
Thanks Dave, that's a great help. I've translated your codes into my script, and I've attached in case there are any glaring errors (though it runs nicely).

The final point which I've been unable to discover an answer for, is how to run the catch trial randomly through the 80 trials of 'response'. There's the option of it being 'pseudo-random' if I were to just select a random number of trials for it to appear after, e.g.:

<block TimeEstimation>
/onblockbegin = [values.onset=0; values.intervalestimation=0; values.stimuli=0;]
/preinstructions = (main)
/trials = [1-5 = noreplace(response); 6 = catchtrial; 7-14 = noreplace(response); 15 = catchtrial etc.,,)]
</block>

However these seems a bit inelegant, and I'm concerned over that, as it's crucial the participant sees as many of the 80 images (40 positive, 40 negative) as possible (depending on their chosen response), that dividing the trials up in such way would reset the stimuli presented after each time the catch trial is performed and potentially show the same image twice or potentially more. Sorry if this does not make much sense.

Many thanks,
Josh
Attachments
Binding_Two_Response_2401.iqx (583 views, 17.00 KB)
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
The proper way to specify the "pseudo-random" option goes like this:

<block TimeEstimation>
/onblockbegin = [values.onset=0; values.intervalestimation=0; values.stimuli=0;]
/preinstructions = (main)
/trials = [1-5, 7-14, ... = noreplace(response); 6,15, ... = catchtrial; ]
</block>

Neither in the above specification nor in the one in your post will running the catch trial reset stimulus selection.

As for implementing a "fully random" scheduling of catch trials, you don't provide enough info to meaningfully address it. Missing pieces, among others, are how many catch trials you'd want to run across the entire block, how they should be spaced out (e.g. you may not want to have two catch trials occurring in close proximity, etc.).

Psych_Josh
Psych_Josh
Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)Guru (11K reputation)
Group: Forum Members
Posts: 85, Visits: 397
Thanks Dave - as long as pseudo-random option does not reset the stimulus sample selection, it should be fine.

Ideally I would have 5 catch trials spaced between at least 10 response trials apart from one another. I apologise if this is still insufficient information.

Many thanks,
Josh
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 the additional info. One way to go about somewhat randomly scheduling the catch trials would be to select the trial numbers within the block where they should occur using <list>s.

<list catchtrialschedulue>
/ items = (10, 26, 42, 58, 74)
/ selectionmode = sequence
</list>

<list randomizecatchtrialposition>
/ items = (-3, -2, -1, 0, 1, 2, 3)
/ selectionmode = random
/ replace = true
</list>

At the start of the <block> (/onblockbegin), you'd select the trial number for the 1st catch trial. It is to occur around the 10th trial, plus minus 3 trial numbers (i.e., between trial #7 and trial #13). Whenever a catch trial is scheduled, you invoke it via /branch from your other trials.

Every time the catch trial is run then, it selects the trial # for the *next* instance of the catch trial (the 2nd would occur around trial #26 +/- 3 trials and so forth). Details in the attached file.

Attachments
Edited 8 Years Ago by Dave
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Explore
Messages
Mentions
Search