Millisecond Forums

Data recording troubles part 2: Time estimation strikes back

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

By Psych_Josh - 12/6/2015

Dear all,

A week or so ago I received some fantastic help regarding some data recording problems - alas, I have encountered a few errors, and although my knowledge is growing, I only have a few hairs left of which to pull out, and I'm quite fond of them.

Essentially, I have a task that involves people estimating the amount of time between them pressing the space bar, and an image appearing. There are three different types of faces (happy, sad, neutral) and after the image disappears after 400ms, a time estimation bar appears, where the participant drags the pointer along a scale that is between 100-1000ms, with intervals of 100ms. The experimental conditions are that the face will appear after either 100, 400, or 700ms. The trouble is, is that although the experiment works, and the data records the time they estimated via the time estimation scale, the data file doesn't actually record what time (either 100, 400, or 700ms) the face appears. I was advised to set:

<values>
/onset = 0
</values>

and then, within the trial:

/ontrialend = [values.onset = list.targetdurations.currentvalue]

This appeared to work, and I was convinced that was case closed. However, it produces errors, and records the incorrect time most of the time. Is there something I have implemented incorrectly? I am measuring time perception errors, so I need to compare their time-estimated vs the actual time the stimulus appears. 

Another data recording trouble, is that it records the participant's time estimation for the practice trial, under values.estimation, despite recorddata set to false. I have no idea how this occurs, but that is not surprising, given my lack of knowledge on Inquisit, and I apologise if this issue has been covered in another post.

Lastly, I would like to record a numerical code for the trials, as well as their names, for greater data analysis ease later on. I tried simply:

<values stimuli>
/stimuli = 0
</values>

And then, within <trial trialhappyface>:
/ontrialend = [values.stimuli = 1 ]

With values.stimuli = 2, for <trial trialneutralface> and 3 for <trial trialsadface>, and put the values.stimuli within the data columns. However, that didn't (as you may have guessed) did not work.

I must emphasise my beginner's level of knowledge, so I also apologise if any of my mistakes have been particularly embarrassing. If someone could point me in the right direction, that would be immensely appreciated. My script is just below.

Many thanks again,
Josh

*******************************************************************************************************************
*******************************************************************************************************************
INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************
<instruct>
/windowsize = (90%, 90%)
/ fontstyle = ("Arial", 3.00%, false, false, false, false, 5, 1)
/ txcolor = (black)
/ screencolor = (255, 255, 255)
/ finishlabel = "Press <Spacebar>"
/nextkey = (57)
/nextlabel = "Press <Spacebar> to continue"
/ prevkey = (28)
/prevlabel = "Press <Enter> to go back"
</instruct>

<page consent>^^Welcome!
^^Thank you for your interest in taking part in the research project entitled Emotional valence and Sense of Agency. The aim of the project is to better understand the mechanisms that allow humans to prepare voluntary actions, as well as how we process the effects of our actions.
^^During this experiment you will be asked to perform simple voluntary actions (such as button presses with the left or right hand), while seated at a computer. You will also be asked to provide judgements regarding the time of pictures that appear after you press the button.
^^During the task we will record your action times and action choices, as well as your timing judgements. This data will be used to complete a research report and may contribute towards future scientific publications or research proposals. Data will be kept anonymously, and when used in such reports will be reported anonymously. You have the right to withdraw at any time without prejudice and without providing a reason.
^^By continuing to the experiment, I confirm that I have understood the information provided above and I consent to participating in this experiment.
</page>

<page welcome>^^This task consists of 100 time estimation trials – the first 10 will be practice trials.
^^In the practice trials you will see a fixation cross (‘+’). When you are ready, press the spacebar to produce an image. Afterwards, you will be asked to estimate the time it took for the image to appear.
^^In other words, the time between you pressing the spacebar and the image appearing.
^^To estimate the time, you will be asked to use a scrollbar that will appear after the image. You will be estimating the time in milliseconds (ms). There are 1000ms in 1 second, and an eyeblink takes around 200ms.
</page>

<page welcome2>^^Once you have completed the practice trials and are familiarised with the task, you will proceed onto the main experiment.
^^In the practice trials, you will receive feedback on your time estimation; however, you will not receive feedback in the main experiment.
</page>

<page main>^^Now you will begin the main experiment.^^Again, you will see a fixation cross, and, when you are ready, press the spacebar to produce an image.^^You will not receive any feedback regarding your time, so make sure you estimate the time as accurately as possible.
</page>

<page end>^^Thank you for taking part in the experiment.
</page>


*******************************************************************************************************************
*******************************************************************************************************************
DEFAULTS
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 4.0.3.0

<defaults>
/minimumversion = "4.0.3.0"
/canvasaspectratio = (4,3)
/quitcommand = (Alt+18)
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
VALUES
*******************************************************************************************************************
*******************************************************************************************************************
/completed:0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)

/intervalestimation:stores the participant's estimation

********************
automatically updated
********************
<values>
/completed = 0
/intervalestimation = 0
</values>

<values>
/onset = 0
</values>

*******************************************************************************************************************
*******************************************************************************************************************
DATA
*******************************************************************************************************************
*******************************************************************************************************************

********************
raw data
********************
build:Inquisit build
date, time, subject, group:date and time script was run with the current subject/groupnumber
blockcode, blocknum:the name and number of the current block
trialcode, trialnum: the name and number of the currently recorded trial
(Note: not all trials that are run might record data)
/intervalestimation:stores the participant's estimation
latency: the response latency (in ms)

<data>
/file = "ProspectiveTimeEstimation_rawdata.iqdat"
/separatefiles = true
/columns = [build, date, time, subject, trialcode, values.onset, values.intervalestimation, script.elapsedtime]
/separatefiles = true
</data>

********************
summary data
********************

script.startdate:date script was run
script.starttime:time script was started
script.subjectid:subject id number
script.groupid:group id number
script.elapsedtime:time it took to run script (in ms)
/completed:0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)

<summarydata >
/file = "ProspectiveTimeEstimation_summary.iqdat"
/columns = [script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, values.completed]
</summarydata>


*******************************************************************************************************************
*******************************************************************************************************************
LISTS
*******************************************************************************************************************
*******************************************************************************************************************

<list targetduration>
/items = (100, 200, 300, 400, 500, 600, 700, 800, 900)
/replace = true
</list>

<list targetdurationh>
/items = (100, 400, 700)
/poolsize = 30
/replace = false
</list>

<list targetdurationn>
/items = (100, 400, 700)
/poolsize = 30
/replace = false
</list>

<list targetdurations>
/items = (100, 400, 700)
/poolsize = 30
/replace = false
</list>

*******************************************************************************************************************
*******************************************************************************************************************
STIMULI
*******************************************************************************************************************
*******************************************************************************************************************
Stimuli presentation (Emoticons):
<item emoticonsh>
/1 = "HappyFace.png"
</item>

<picture emoticonsh>
/items = emoticonsh
/position = (50, 50)
</picture>

<item emoticonsn>
/2 = "NeutralFace.png"
</item>

<picture emoticonsn>
/items = emoticonsn
/position = (50, 50)
</picture>

<item emoticonss>
/3 = "SadFace.png"
</item>

<picture emoticonss>
/items = emoticonss
/position = (50, 50)
</picture>


Extra stimuli:

<shape circle>
/shape = circle
/size = (1% * 3/4 * 10, 10%)
/color = green
/position = (50%, 50%)
/erase = false
</shape>

<text cross>
/items = ("+")
/color = (0,0,0)
</text>

<text blank>
/items = (" ")
/color = (0,0,0)
</text>

<shape whiterectangle>
/shape = rectangle
/size = (70%, 70%)
/color = white
/position = (50%, 50%)
/erase = false
</shape>


Time estimation slide scale:

<slider TE_response>
/ caption="How much time before the image appeared (in ms)?"
/ labels=("0s", "100ms", "200ms", "300ms", "400ms", "500ms", "600ms", "700ms", "800ms", "900ms", "1000ms")
/responsefontstyle = ("Arial", 1.5%, false, false, false, false, 5, 1)
/ txcolor = (0, 0, 0)
/ range = (0, 1000)
/ increment = 100
/showticks = true
/slidersize = (70%, 30%)
/position = (10%, 50%)
/defaultresponse = 0
</slider>

*******************************************************************************************************************
*******************************************************************************************************************
TRIALS
*******************************************************************************************************************
*******************************************************************************************************************

*********
Practice trials
*********

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

Note: presents a face after correct response
Spacebar advances to time estimation
<trial practicedot>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.practicedot.insertstimulustime(shape.circle, list.targetduration.nextvalue)]
/ontrialbegin = [trial.practicedot.insertstimulustime(shape.whiterectangle, list.targetduration.currentvalue+400)]
/ontrialend = [trial.practicedot.setstimulustime(shape.whiterectangle, list.targetduration.currentvalue)]
/ontrialend = [trial.practicedot.resetstimulusframes(100)]
/timeout = (list.targetduration.currentvalue+1000)
/branch = [surveypage.tep]
/recorddata = false
</trial>

Note: presents time estimation slide scale

<surveypage TEp>
/questions = [1 = TE_response]
/showpagenumbers = false
/ontrialend = [values.intervalestimation = slider.te_response.response]
/recorddata = false
/branch = [trial.feedback]
</surveypage>

<trial feedback>
/stimulustimes = [100 = endtrial]
/pretrialpause = 200
/correctresponse = (57)
/recorddata = false
</trial>

<text endtrial>
/items = ("The time interval to be estimated was: <%list.targetduration.currentvalue%>ms

Your estimation: <%slider.te_response.response%>ms

Press <Spacebar> to continue")
</text>

*********
Emoticon presentation - Positive
*********

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

Note: presents a face after correct response
Spacebar advances to time estimation
<trial trialhappyface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialhappyface.insertstimulustime(picture.emoticonsh, list.targetdurationh.nextvalue)]
/ontrialbegin = [trial.trialhappyface.insertstimulustime(shape.whiterectangle, list.targetdurationh.currentvalue+400)]
/ontrialend = [trial.trialhappyface.setstimulustime(shape.whiterectangle, list.targetdurationh.currentvalue)]
/ontrialend = [values.onset = list.targetdurations.currentvalue]
/ontrialend = [trial.trialhappyface.resetstimulusframes(100)]
/timeout = (list.targetdurationh.currentvalue+1000)
/branch = [surveypage.te]
/recorddata = true
</trial>



*********
Emoticon presentation - Neutral
*********

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

Note: presents a face after correct response
Spacebar advances to time estimation
<trial trialneutralface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialneutralface.insertstimulustime(picture.emoticonsn, list.targetdurationn.nextvalue)]
/ontrialbegin = [trial.trialneutralface.insertstimulustime(shape.whiterectangle, list.targetdurationn.currentvalue+400)]
/ontrialend = [trial.trialneutralface.setstimulustime(shape.whiterectangle, list.targetdurationn.currentvalue)]
/ontrialend = [values.onset = list.targetdurations.currentvalue]
/ontrialend = [trial.trialneutralface.resetstimulusframes(100)]
/timeout = (list.targetdurationn.currentvalue+1000)
/branch = [surveypage.te]
/recorddata = true
</trial>



*********
Emoticon presentation - Sad
*********

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

Note: presents a face after correct response
Spacebar advances to time estimation
<trial trialsadface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialsadface.insertstimulustime(picture.emoticonss, list.targetdurations.nextvalue)]
/ontrialbegin = [trial.trialsadface.insertstimulustime(shape.whiterectangle, list.targetdurations.currentvalue+400)]
/ontrialend = [trial.trialsadface.setstimulustime(shape.whiterectangle, list.targetdurations.currentvalue)]
/ontrialend = [values.onset = list.targetdurations.currentvalue]
/ontrialend = [trial.trialsadface.resetstimulusframes(100)]
/timeout = (list.targetdurations.currentvalue+1000)
/branch = [surveypage.te]
/recorddata = true
</trial>

<surveypage TE>
/questions = [1 = TE_response]
/showpagenumbers = false
/ontrialend = [values.intervalestimation = slider.te_response.response]
/recorddata = false
</surveypage>


*******************************************************************************************************************
*******************************************************************************************************************
BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************
<block PracticeBlock>
/preinstructions = (consent, welcome, welcome2)
/trials = [1-10 = noreplace(practice)]
</block>


<block TimeEstimation>
/preinstructions = (main)
/postinstructions = (end)
/trials = [1-90 = noreplace(trialhappystart, trialsadstart, trialneutralstart)]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************
<expt >
/blocks = [1 = PracticeBlock; 2 = TimeEstimation]
/onexptend = [values.completed = 1]
</expt>

*******************************************************************************************************************
End of File
*******************************************************************************************************************
By Dave - 12/6/2015

Josh,

Your <trial happyface> draws from list.targetdurationh

<trial trialhappyface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialhappyface.insertstimulustime(picture.emoticonsh, list.targetdurationh.nextvalue)]
...
/ontrialend = [values.onset = list.targetdurations.currentvalue]
...
</trial>

yet you write the currentvalue of a completely *different* list to values.onset in that <trial>. You need to fix that, i.e., you need to do

<trial trialhappyface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialhappyface.insertstimulustime(picture.emoticonsh, list.targetdurationh.nextvalue)]
/ontrialbegin = [trial.trialhappyface.insertstimulustime(shape.whiterectangle, list.targetdurationh.currentvalue+400)]
/ontrialend = [trial.trialhappyface.setstimulustime(shape.whiterectangle, list.targetdurationh.currentvalue)]
/ontrialend = [values.onset = list.targetdurationh.currentvalue]
...
</trial>

<trial trialneutralface>
/stimulustimes = [1 = whiterectangle]
/ontrialbegin = [trial.trialneutralface.insertstimulustime(picture.emoticonsn, list.targetdurationn.nextvalue)]
/ontrialbegin = [trial.trialneutralface.insertstimulustime(shape.whiterectangle, list.targetdurationn.currentvalue+400)]
/ontrialend = [trial.trialneutralface.setstimulustime(shape.whiterectangle, list.targetdurationn.currentvalue)]
/ontrialend = [values.onset = list.targetdurationn.currentvalue]
...
</trial>

and so forth.

As to your 2nd question:

> Another data recording trouble, is that it records the participant's time estimation for the practice trial, under values.estimation, despite
> recorddata set to false. I have no idea how this occur.

The /recorddata setting has nothing to do with this. /recorddata = false means that Inquisit will not add a line of data to the file for the respective <trial>. And that's exactly what the script does and should do. values.intervalestimation is a global variable. Whatever its state is in a given trial gets logged to the data file. When your test <block> starts -- for which you do record data -- the state of values.estimation is whatever you set it to during the *practice* block -- regardless of whether you recorded any data for that <block>'s trials or not -- *until* some trial in your test block *changes* that state.

If you don't want this, you need to reset the global variable to zero at the beginning of the test <block>.

As to your 3rd question:

> Lastly, I would like to record a numerical code for the trials, as well as their names, for greater data analysis ease later on. I tried simply:
>
> <values stimuli>
> /stimuli = 0
> </values>
>
> And then, within <trial trialhappyface>:
> /ontrialend = [values.stimuli = 1 ]
>
> With values.stimuli = 2, for <trial trialneutralface> and 3 for <trial trialsadface>, and put the values.stimuli within the data columns.
> However, that didn't (as you may have guessed) did not work.

That's exactly how it works. However, since none of the code you describe above is actually in the script you posted, I cannot tell you what you did wrong.

Finally, please do not paste entire lengthy scripts into a message's body. Instead attach the actual script file to your post.
By Psych_Josh - 12/6/2015

Hi Dave,

Thanks again for your continued help.

The first issue has been resolved - many thanks.

The second issue I understand - thank you for clarifying. How do I set the global variable to zero at the beginning of the test <block>, so that I do not incur the value.intervalestimation from the practice trial?

To illustrate, in the image below, the 900 under values.intervalestimation is from one practice trial, yet the values.onset adjacent to it is from the first test trial (thus corresponding to the 400 underneath the 900).
 
http://www.millisecond.com/forums/uploads/images/fcf1ea10-d2cb-4f37-ab7b-867a.png

The third issue has been resolved - I had written <values stimuli>, incorrectly. Thanks for your help.

Also, apologies for posting the whole script - I was only following examples set by other users on here.
By Dave - 12/6/2015

> How do I set the global variable to zero at the beginning of the test <block>, so that I do not incur the value.intervalestimation from the
> practice trial?

Look at the /onblockbegin attribute in the test <block> in the script attached to my previous reply.
By Psych_Josh - 12/7/2015

Hi Dave,

Sorry - instead of there being the number from the practice trial, it instead displays the '0' in the values.intervalestimation instead.

http://www.millisecond.com/forums/uploads/images/a14004a9-2124-46e5-96de-861f.png

Thanks for your continued help!
By Dave - 12/7/2015

Josh,

Neither <trial trialhappyface> nor <trial trialsadface> nor <trial trialneutralface> collect the interval estimation value. That only happens *after* the respective <trial> in <surveypage te>:

<trial trialhappyface>
...
/branch = [surveypage.te]
</trial>

<surveypage TE>
/questions = [1 = TE_response]
/showpagenumbers = false
/ontrialend = [values.intervalestimation = slider.te_response.response]
/recorddata = false
</surveypage>

for which you do not log any data to the file. The row for "trialhappyface" cannot possibly reflect some response that has not been collected yet.
By Psych_Josh - 12/7/2015

Hi Dave,

Thanks. I understand that, where the correct number was incorrectly appearing, it was actually recording it for the trial beforehand but incorrectly placing it in the next data row. I switch all the trials to recorddata = false, and switched surverypage.te = true, and it records properly now.

Thanks for your help!

One other quick thing that I've spent the last 2 hours trying to work out, is how to record openended responses? They need to enter in their specific ID, so, as predicted, /correctresponse or valid/repsonse does not work.

I have this so far:
<openended paID>
/position = (50, 50)
/buttonlabel = "Click here to advance"
/linelength = 50
/charlimit = 30
/numlines = 1
/size = (500, 50)
/recorddata = true
</openended>

What would I need to enter, either here or in the data section, for it to record? 

Many thanks,
Josh
By Psych_Josh - 12/7/2015

Sorry - I forgot to mention in the last post also - is there a way for participants to have copied text via ctrl+C and be able to paste it into the text box, also?

Thanks again, apologies for the double posting,

Josh
By Dave - 12/7/2015

You don't need /validresponse or /correctresponse. You need to run your <openended> element via some <block> at the appropriate point in time. You need to log the response column to the data file to capture responses. Alternatively, use a <values> entry as you already do in other places and log that value to the data file.
By Dave - 12/7/2015

As for your copy & paste question: Copied from where and when? Generally, though, the answer is no. You cannot CTRL+C, for example, an item displayed by a <text> element in a script.
By Psych_Josh - 12/7/2015

Hi Dave,

Thanks for your response. I've been trying to source a method, as I don't want to keep pestering you with questions, but I'm having trouble logging the response column to the data file to capture responses. Ideally I would like to record their response/data as a string, and from my inquisition I believe the 'response' data column only records ASCII codes.

Many thanks again,
Josh
By Dave - 12/7/2015

This place is for asking question -- it's not pestering at all.

As to your question:
#1: Keypress responses in *<trial>* elements are recorded as *keyboard scancodes* (not the same as ASCII codes). There is no way to change that.
#2: Your last question involved an *<openended>* element, however. The response column will reflect whatever the participant typed. This will *not* be translated to keyboard scancodes or ASCII codes. I.e., if a participant responds "banana", that's exactly what the response column will have in it.
By Psych_Josh - 12/8/2015

Wonderful, thanks for clearing that up Dave - everything's working and data recording is correct. I'm ready to publish the study online now - thanks again!

Josh
By Psych_Josh - 12/9/2015

Hi Dave,

Sorry to bother you with one more question (and if you would prefer me to start a new topic I'll happily do so), but I wish to host my study via Prolific Academic, which requires a link back to the latter's website at the end of the study; thus, how do I add a hyperlink? I have searched, and attempted:

<item prolink>
/1 = "*hyperlink goes here*"
</item>
 
<trial link>
/stimulustimes = [1 = prolink]
/timeout = 1000000
</trial>

<block link>
/trials = [1 = noreplace(link)]
</block>

Alas, this does not work (as you might have guessed).

Any help would be greatly appreciated.

Many thanks,
Josh
By Dave - 12/9/2015

That's not something you do in the script. Instead you specify the URL you want to redirect to in your web experiment's settings:

https://www.millisecond.com/forums/uploads/images/0a530cb4-c414-4239-b1eb-6a93.png
By Psych_Josh - 12/9/2015

That's fantastic Dave, thanks a lot!