Using if..else statements to calculate custom values


Author
Message
Blazer
Blazer
Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)
Group: Forum Members
Posts: 11, Visits: 94
Hello,

I've been having some trouble getting Inquisit to automatically calculate and output custom variables. It may be that I just don't understand the basic notation for if...else statements in Inquisit. The experiment involves participants watching a video and reacting to a stimulus that appears during the video by pressing the spacebar (scancode 57). However, I also want to record if they may make an erroneous response and react too early to an incorrect stimulus in the video. If they make an erroneous response, they will still watch until the end of the video. Supposing the video lasts 6 seconds and the correct stimulus appears 3 seconds in, here is how I was trying to make Inquisit output a "reactiontime" which would be the difference between the latency and when the correct stimulus appeared:

<values>
/ reactiontime1 = if (trial.trial1.response == 57 && block.block1.latency >= 3000) (block.block1.latency - 3000)  else -8
</values>

<summarydata>
/ columns = [values.reactiontime1]
</summarydata>

<video Video1>
/ items = ("Video1.wmv")
</video>

<trial Trial1>
/ beginresponsetime = 0
/ inputdevice = keyboard
/ validresponse = (57)
/ responseinterrupt = trial
/ timeout = 6000
/ stimulusframes = [1=Video1]
</trial>

<block Block1>
/ preinstructions = (instructions)
/ trials = [1=Trial1]
</block>

<expt Expt1>
/ blocks = [1=(Block1)]
</expt>

When I test the experiment, all I've ever gotten for "values.reactiontime1" is "-8" How can I get to it to actually subtract the 3000 milliseconds from the recorded latency, thus giving me the reaction time for the correct stimulus?

Also, it seems like ever since I started trying these values, the data report of other variables has been affected. It seems it will only record a trial.trial1.response as 57 if I hit spacebar before the correct stimulus appears. If I wait to react to the stimulus, it outputs the response as 0. Why would other variables be affected when I'm just creating new ones and not altering the way the experiment accepts responses?

Lastly, unrelated to this particular issue, but I wouldn't mind someone confirming my understanding of Inquisit 4. There is no possible way to get Inquisit 4 to record two or more valid responses in one trial, right? For instance, if someone reacts too early to an erroneous stimulus in the video, I won't be able to record if they hit spacebar a second time once the correct stimulus appeared, correct?

Please advise.
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: 12K, Visits: 98K
A <values> entry is what you may know as a global variable in other programming languages. It does not update itself automatically. Thus

<values>
/ reactiontime1 = if (trial.trial1.response == 57 && block.block1.latency >= 3000) (block.block1.latency - 3000)  else -8
</values>

will be evaluated *exactly once* as soon as you run the script. At this point the result of that evaluation can only ever be -8. The if-condition will never evaluate to true.

If you want something akin to user defined functions that's evaluated automatically, you'll want to use <expressions>.

> Also, it seems like ever since I started trying these values, the data report of other variables has been affected. It seems it will
> only record a trial.trial1.response as 57 if I hit spacebar before the correct stimulus appears. If I wait to react to the stimulus, it
> outputs the response as 0

Whatever you do with that <values> element, it should not and -- according to my tests -- does not affect those things. The way you've set up the <trial>, it will allow for a response at any time during the video -- be it before or after 3 seconds have elapsed. It will only record a 0 as a response if no valid response has been submitted prior to the trial timing out after 6 seconds. To illustrate this, find attached a data file generated by your script. The response is 57 and its latency is 4594 ms, i.e. well after 3 seconds.

If you are experiencing something else on your system, please first ensure that your Inquisit installation is up to date. If -- after an eventual update -- the issue persists, please provide a data file illustrating it.

> There is no possible way to get Inquisit 4 to record two or more valid responses in one trial, right?

There is a way. It requires the use of /isvalidresponse logic.


<values>
/ rt_premature = ""
</values>

<data>
/ columns = [date time subject blocknum blockcode trialnum trialcode stimulusitem response latency values.rt_premature]
/ separatefiles = true
</data>
 
<video Video1>
/ items = ("Video1.wmv")
</video>

<trial Trial1>
/ ontrialbegin = [values.rt_premature=""; ]
/ beginresponsetime = 0
/ inputdevice = keyboard
/ validresponse = (57)
/ isvalidresponse = [if(trial.trial1.elapsedtime<3000 && trial.trial1.response == 57) {values.rt_premature=trial.trial1.latency; false;} else if
    (trial.trial1.elapsedtime>=3000 && trial.trial1.response == 57) {true}]
/ responseinterrupt = trial
/ timeout = 6000
/ stimulusframes = [1=Video1]
</trial>

<block Block1>
/ trials = [1=Trial1]
</block>

<expt Expt1>
/ blocks = [1=Block1]
</expt>

Via the /isvalidresponse attribute above, a premature response (prior to 3000ms) will be evaluated as invalid (false), so the trial will continue accepting responses. However, the latency of that 1st, premature response is stored in a variable (<values> entry) and written to the data file.

Attachments
experiment.iqdat (866 views, 358 bytes)
Blazer
Blazer
Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)
Group: Forum Members
Posts: 11, Visits: 94
Dave,

Thanks for the advice! It works great except for one very odd problem. If I repeatedly mash the spacebar during the whole trial, I can still get latency values before the appearance of the stimulus. For instance, it would accept a latency value of 11102 even if the logic refused any values lower than 12220. I believe I was able to solve the issue, and I think it has something to do with why my data output was also acting wonky.

Trying out the experiment on my old home laptop, the length of the videos is almost doubled from lag. It should have occurred to me that Inquisit was tsill running a consistent timer despite my computer's slow video. Thus, whenever I hit spacebar in reaction to the stimulus, it was long past the timeout period, resulting in a response of "0." That may have been the case yesterday as well, but that was on a fairly good lab computer. I will have to test that one.Additionally, the computer's slowness probably affected the "trial.trial1.elapsedtime" and made it out of sync with the latency. When I changed the isvalidreponse logic to be dependent on latency, I didn't get valid responses from before the stimulus appearance time.

Thanks for your help!

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: 12K, Visits: 98K
I can confirm that video performance will depend a lot on system characteristics (processor speed, RAM, codec performance, driver performance, video resolution) and performance can vary substantially from system to system depending on the various moving parts involved. It very much sounds like performance bottlenecks were the most significant issue here.

Blazer
Blazer
Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)Esteemed Member (1.9K reputation)
Group: Forum Members
Posts: 11, Visits: 94
One thing that I am curious about, though it is not too relevant to the current experiment, is how one would set up Inquisit to record all responses given by the participant, until they responded post-correct stimulus. It seems that the script that you provided overwrites the latency each time the participant responds until the appearance of the correct stimulus. I think I can imagine how one could set up the possibility for a set number of possible premature responses being recorded with rt_premtaure1, rt_premature2, etc. and using conditional statements that test if the previous rt_premature != -8. Is there a shortcut for that or way to make the possible premature responses nearly unlimited.

As I said, this experiment is mainly interested in if they respond early at all, but recording the variables as described above may be interesting.

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: 12K, Visits: 98K
As you suggested, you either need to set up N variables (as many as reasonably needed; values.rt_premature1, values.rt_premature2, etc.) and populate them in order. Alternatively, you could concatenate the various premature rts and store the resulting string of rts in a single variable.

/ isvalidresponse = [if(trial.trial1.elapsedtime<3000 && trial.trial1.response == 57) {values.rt_premature=concat(concat(values.rt_premature, ","), trial.trial1.latency); false;} else if
    (trial.trial1.elapsedtime>=3000 && trial.trial1.response == 57) {true}]
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Explore
Messages
Mentions
Search