Rotor Task Feedback about Time on Disc??


Author
Message
aquirk
aquirk
Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)
Group: Forum Members
Posts: 31, Visits: 70
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</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: 12K, Visits: 98K
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

aquirk
aquirk
Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)
Group: Forum Members
Posts: 31, Visits: 70
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



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
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



The you do

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

aquirk
aquirk
Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)
Group: Forum Members
Posts: 31, Visits: 70
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



The you do

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

great, thank you!!!


one more question--is it possible to show people's highest score? How could I code so that it specifically showed their highest time on target out of their previous trials?
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
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



The you do

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

great, thank you!!!


one more question--is it possible to show people's highest score? How could I code so that it specifically showed their highest time on target out of their previous trials?

Yes, you can use a list and its maximum property for that:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>

Highest time on target: <%list.ontargettimes.maximum%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>

<list ontargettimes>
/ items = (item.ontargettimes.item.1, item.ontargettimes.item.2, item.ontargettimes.item.3, item.ontargettimes.item.4, item.ontargettimes.item.6, item.ontargettimes.item.6)
</list>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

aquirk
aquirk
Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)Esteemed Member (2.4K reputation)
Group: Forum Members
Posts: 31, Visits: 70
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



The you do

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

great, thank you!!!


one more question--is it possible to show people's highest score? How could I code so that it specifically showed their highest time on target out of their previous trials?

Yes, you can use a list and its maximum property for that:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>

Highest time on target: <%list.ontargettimes.maximum%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>

<list ontargettimes>
/ items = (item.ontargettimes.item.1, item.ontargettimes.item.2, item.ontargettimes.item.3, item.ontargettimes.item.4, item.ontargettimes.item.6, item.ontargettimes.item.6)
</list>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Thanks, this has been working really well. Now what I want to do is let people practice for 7 trials (still getting the same feedback between trials as above), then complete a test trial. For some reason, I keep getting 'nan' when I try to tell people their performance on the test trial. The feedback during the practice trials is still working correctly. Here's the code, and I've bolded relevant parts:


   PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated: 08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright © 08-15-2016 Millisecond Software


BACKGROUND INFO

*Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

*Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:Inquisit build
computer.platform:the platform the script was run on
date, time, subject, group:date and time script was run with the current subject/groupnumber
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
Note: the distance data should only be considered valid if participant continously moved the mouse around;
if few mouse movements are recorded, the collected distance data are questionable

(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:the platform the script was run on
/completed:0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:the number of trials to run (default: 4)
/sum_offDurations_total:the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/NumTrials:the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 1000
/ radius = 225px
/ targetDiscSize = 50
/ restTime = 1000
/ NumTrials = 7
/ rotationtime = 1000
/ rotations = 20
/ highscore = 2
</parameters>

**************************************************************************************************************
**************************************************************************************************************
EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a blue circle moving steadily around a circular track.
~nTry to keep your <%expressions.buttoninstruct1%> on the blue circle at all times.
~nThere will be a total of <%parameters.NumTrials%> practice trials, each lasting <%parameters.trialDuration/1000%> seconds.
~nYou will have <%parameters.restTime/1000%> seconds to rest in between each trial.
~nAfter the practice trials, there will be a test to see what you have learned. 
~n<%expressions.buttoninstruct2%> to begin."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the blue circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "You can now rest for <%parameters.restTime/1000%> seconds before the next practice trial.
~n<%expressions.buttoninstruct2%> if you would like to continue immediately."
/ 4 = "Thank you! To receive payment, please enter the following code on MTurk: <%values.MTURK%>. This page will close after 30 seconds."
/ 5 = "We'd like to know a bit about what you thought about this HIT. Below, please write any comments you think would be useful to pass on to us. For instance, do you think you were paid a fair amount of money for the amount of work you did? Is there something we can do to make the directions clearer? Is there anything we can do to make the HIT more interesting? Any feedback would be helpful!"

</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click the mouse";}
</expressions>

**************************************************************************************************************
!!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = whitesmoke
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount, openended.question.response, response)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:records the script.elapsedtime when mouse goes off target
/offDuration:stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixel) used for the task

<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
/ MTURK = 0
</values>

*******************************************************************************************************************
*******************************************************************************************************************
EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:calculates the radius of the outter track circle in pixels
/radius_innerTrack:calculates the radius of the inner track circle in pixels

/distance:calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
values.usedCanvas = concat(values.usedCanvas, "px, ");
values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
values.usedCanvas = concat(values.usedCanvas, "px)");
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial;
} else {
parameters.trialDuration;
}
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 45%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest1>
/ items = ("Here is how many seconds you've been able to stay on the blue circle during each trial so far:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nYou have <%parameters.resttime/1000%> seconds to rest.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BeforeTest>
/ items = ("The test will begin in <%parameters.resttime/1000%> seconds.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = ("Here is how many seconds you've been able to stay on the blue circle during each trial so far:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nSo far your high score is <%list.ontargettimes.maximum/1000%> seconds. Let's see if you can beat that score on the next trial!
~nYou have <%parameters.resttime/1000%> seconds to rest.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest2>
/ items = ("Here is how many seconds you were able to stay on the blue circle during each practice trial:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nYour high score was <%list.ontargettimes.maximum/1000%> seconds. Good work!
~n<%expressions.buttoninstruct2%> to continue to the test.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest4>
/ items = ("You were able to stay on the disc for <%expressions.timeOnTarget_trial/1000%> seconds during the test. Good work!
~n<%expressions.buttoninstruct2%> to continue.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


<text BetweenTest3>
/ items = ("Now you are going to complete the test. The speed of the blue circle will be different during the test than it was during the practice.
~nFirst, the circle will complete exactly one rotation, so that you can understand what the new speed is.
~nWe aren't scoring this rotation, so you can trace the circle, just watch, or do whatever you want to do to prepare for the test. After this rotation you will have a chance to rest, then the test will begin.
~n<%expressions.buttoninstruct2%> to continue.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 30%)
/ size = (50%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text OpenTxt>
/ items = instructions
/ select = 5
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (400px, 300px)
/ size = (50%, 50%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


<radiobuttons competence>
/caption = "I performed very well during the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons effort>
/caption = "I put a lot of effort into the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons motivation>
/caption = "I was motivated to do well during the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons difficult>
/caption = "The training was very difficult."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons enjoyment>
/caption = "I enjoyed the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons pleasant>
/caption = "The training was pleasant."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>




*******************************************************************************************************************
*******************************************************************************************************************
STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = whitesmoke
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = black
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.rotationtime, parameters.rotations, 0, 50%, 50%, parameters.radius)
/ color = cornflowerblue
/ erase = false
</shape>

<shape testanimatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(2000, 1, 0, 50%, 50%, parameters.radius)
/ color = cornflowerblue
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = cornflowerblue
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

<list ontargettimes>
/ items = (item.ontargettimes.item.1, item.ontargettimes.item.2, item.ontargettimes.item.3, item.ontargettimes.item.4, item.ontargettimes.item.5, item.ontargettimes.item.6, item.ontargettimes.item.7, item.ontargettimes.item.8)
</list>
*******************************************************************************************************************
*******************************************************************************************************************
TRIALS
*******************************************************************************************************************
*******************************************************************************************************************

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
trial.startRotate
]
/ recorddata = false
</trial>

<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
if (trial.rotate.trialcount < parameters.highscore) {
trial.rest1;
} else if (trial.rotate.trialcount < parameters.NumTrials){
trial.rest
}
else {
trial.prequestion;
}
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest]
/ timeout = parameters.restTime
/ branch = [
trial.startRotate;
]
/ recorddata = false
</trial>

<trial rest1>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ timeout = parameters.restTime
/ branch = [
trial.startRotate;
]
/ recorddata = false
</trial>

<trial prequestion>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ branch = [
surveypage.questions1;
]
/ recorddata = false
</trial>



<surveypage questions1>
/caption ="Thank you for completing the training! Before we continue, please evaluate the following statements:"
/ fontstyle = ("Arial", 4%, false, false, false, false, 5, 1)
/itemfontstyle = ("Arial", 3%, false, false, false, false, 5, 1)
/responsefontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ txcolor = black
/questions = [1 = competence, effort, motivation]
/showpagenumbers = false
/showquestionnumbers = false
/backbuttonposition = (10%, 90%)
/nextbuttonposition = (95%, 95%)
/ branch = [
surveypage.questions2;
]
</surveypage>

<surveypage questions2>
/caption ="Please continue evaluating the following statements:"
/ fontstyle = ("Arial", 4%, false, false, false, false, 5, 1)
/itemfontstyle = ("Arial", 3%, false, false, false, false, 5, 1)
/responsefontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ txcolor = black
/questions = [1 = difficult, enjoyment, pleasant]
/showpagenumbers = false
/showquestionnumbers = false
/backbuttonposition = (10%, 90%)
/nextbuttonposition = (95%, 95%)
/ branch = [
trial.prerotation;
]
</surveypage>

<trial prerotation>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest3]
/ validresponse = (lbuttondown)
/ branch = [
trial.startonerotation;
]
/ recorddata = false
</trial>

<trial startonerotation>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.onerotation
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial onerotation>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, testanimatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = 2000
/ branch = [
trial.testrest
]
/ recorddata = true
</trial>

<trial testrest>
/ stimulusframes = [1 = clearscreen, BeforeTest]
/ timeout = parameters.restTime
/ branch = [
trial.starttest;
]
/ recorddata = false
</trial>

<trial starttest>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.test
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial test>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, testanimatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = 1000
/ branch = [
trial.posttest
]
/ recorddata = true
</trial>


<trial posttest>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest4]
/ validresponse = (lbuttondown)
/ branch = [
openended.question;
]
/ recorddata = false
</trial>


<openended question>
/ stimulusframes=[1 = clearscreen, OpenTxt]
/ position = (50, 90)
/ linelength = 40
/ charlimit = 500
/ numlines = 10
/ branch = [
trial.MTURK
]
</openended>

<trial MTURK>
/ ontrialbegin = [
values.MTURK = floor(rand(16001,165000))
]
/ stimulusframes = [1 = PostTestTxt]
/ timeout = 30000
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
expressions.usedCanvas;
]
/ onexptend = [
values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
End of 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: 12K, Visits: 98K
aquirk - Friday, June 9, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
Dave - Monday, May 15, 2017
aquirk - Monday, May 15, 2017
I'm trying to edit the pursuit rotor task script so that participants can see how long they were able to stay on the target in each trial. The original script has one "rotate" trial that repeats itself as many times as you dictate, but in order to show this feedback I created separate rotate trials, and had each record a timeOnTarget_trial value. I was able to get this to work in theory, but some of the values that participants are given are negative, which doesn't make sense. The shortest amount of time you're able to stay on target should be 0.. not negative time.

Does anyone have any ideas how to fix this? Or is there a better way to give this type of feedback that wouldn't introduce this error? I've copied some of the relevant parts of the script below for reference:
<expressions>
/ sum_offDurations_trial1 = list.offDurations_trial1.mean * list.offDurations_trial1.itemcount
/ sum_offDurations_trial2 = list.offDurations_trial2.mean * list.offDurations_trial2.itemcount


/ timeOnTarget_trial1 = if (expressions.sum_offDurations_trial1 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial1;
} else {
parameters.trialDuration;
}
/ timeOnTarget_trial2 = if (expressions.sum_offDurations_trial2 !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial2;
} else {
parameters.trialDuration;
}
</expressions>


<list offDurations_trial1>
</list>
<list offDurations_trial2>
</list>

<trial startRotate1>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate1
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial startRotate2>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate2
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
<trial rotate1>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate1.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate1.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial1.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest1
]
/ recorddata = true
</trial>

<trial rotate2>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate2.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate2.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
if (values.previous_targetlocation == 0) {
values.offDuration= script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial2.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
trial.rest2
]
/ recorddata = true
</trial>
<trial rest1>
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate2;
]
/ recorddata = false
</trial>

<trial rest2>
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ timeout = parameters.restTime
/ branch = [
trial.startRotate3;
]
/ recorddata = false
</trial>




You need not (should not) create separate trials -- it's unnecessary. The per-trial on-target duration is available via expressions.timeOnTarget_trial. You can simply display the result during the rest trial:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("You spent <%expressions.timeOnTarget_trial/1000%> seconds on-target.")
/ position = (50%, 30%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Right, but what I want to do is show the person their score on every trial. For example, their 6th time doing it, they should see:

Here is how many seconds you were able to stay on the disc during each trial so far:

Trial 1: 19.57
Trial 2: 10.28
Trial 3: 11.15
Trial 4: 5.47
Trial 5: 6.57
Trial 6: 8.71

You can now rest for 20 seconds before the next trial.
Click the mouse if you would like to continue immediately.

The script you provided will only show the score immediately prior, right?



The you do

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

great, thank you!!!


one more question--is it possible to show people's highest score? How could I code so that it specifically showed their highest time on target out of their previous trials?

Yes, you can use a list and its maximum property for that:

<usermanual>
                       
                                           PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated:      08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright ©  08-15-2016 Millisecond Software


BACKGROUND INFO

                                            *Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

                                              *Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:                                Inquisit build
computer.platform:                    the platform the script was run on
date, time, subject, group:            date and time script was run with the current subject/groupnumber
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:            the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:                the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the distance data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
                                       
(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:                    the platform the script was run on
/completed:                            0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:                        data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:                            the radius of the track in pixels
/targetDiscSize:                    the size of the target disc in pixels
/trialDuration:                        the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:                            the number of trials to run (default: 4)
/sum_offDurations_total:            the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
                                        Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
                                        if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:                the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:    the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:            the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:                the duration of one trial/one rotation in ms (default: 10000ms)
/radius:                    the radius of the track in pixels
/targetDiscSize:            the size of the target disc in pixels
/NumTrials:                    the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
    EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 10000
/ radius = 225px
/ targetDiscSize = 50
/ NumTrials = 4
</parameters>

**************************************************************************************************************
**************************************************************************************************************
    EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a red circle moving steadily around a circular track.
Try to keep your <%expressions.buttoninstruct1%> on the red circle at all times.
There will be a total of <%parameters.NumTrials%> trials, each lasting <%parameters.trialDuration/1000%> sec.
~n<%expressions.buttoninstruct2%>."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the red circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "<%expressions.buttoninstruct2%> to start the next trial."
/ 4 = "Thank you! <%expressions.buttoninstruct2%> to quit."
</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click mouse button";}
</expressions>

**************************************************************************************************************
                !!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
    DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = (124,124,124)
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
    DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
    VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:                    0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:    1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:            records the script.elapsedtime when mouse goes off target
/offDuration:                stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:                data file variable that stores the dimension of the experimental canvas (in pixel) used for the task
                       
<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
</values>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:                            assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:                        calculates the radius of the outter track circle in pixels
/radius_innerTrack:                        calculates the radius of the inner track circle in pixels

/distance:                                calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:                calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:                calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:                    calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:                    calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:        calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:    calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:    calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:                calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:                calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
    values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
    values.usedCanvas = concat(values.usedCanvas, "px, ");
    values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
    values.usedCanvas = concat(values.usedCanvas, "px)");   
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
                        parameters.trialDuration - expressions.sum_offDurations_trial;
                    } else {
                        parameters.trialDuration;
                    }
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
    INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = white
/ position = (50%, 50%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = instructions
/ select = 3
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text ontargetfeedback>
/ items = ("Here is how many seconds you were able to stay on the disc during each trial so far:
Trial 1: <%item.ontargettimes.item.1%>
Trial 2: <%item.ontargettimes.item.2%>
Trial 3: <%item.ontargettimes.item.3%>
Trial 4: <%item.ontargettimes.item.4%>
Trial 5: <%item.ontargettimes.item.5%>
Trial 6: <%item.ontargettimes.item.6%>

Highest time on target: <%list.ontargettimes.maximum%>
")
/ position = (10%, 40%)
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = (0,255,255)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>

<list ontargettimes>
/ items = (item.ontargettimes.item.1, item.ontargettimes.item.2, item.ontargettimes.item.3, item.ontargettimes.item.4, item.ontargettimes.item.6, item.ontargettimes.item.6)
</list>


*******************************************************************************************************************
*******************************************************************************************************************
    STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = (124, 124, 124)
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = green
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.trialDuration, 1, 0, 50%, 50%, parameters.radius)
/ color = red
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = red
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

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

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate
]
/ recorddata = false
</trial>
   
<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
    trial.rotate
]
/ ontrialend = [
    values.previous_targetlocation = 1;
    list.offDurations_trial.reset();
    list.targetDistances_trial.reset();
    list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>
   
<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
    if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_trial.insertitem(expressions.distance, 1);
        list.offTargetDistance_total.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 1) {
            values.startOffTarget = script.elapsedtime;
            values.previous_targetlocation = 0;
        } ;
        1 == 1;
    } else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
        list.targetDistances_total.insertitem(expressions.distance, 1);
        list.targetDistances_trial.insertitem(expressions.distance, 1);
        if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
            values.previous_targetlocation = 1;
        } ;
        1 == 1;
    }
]
/ ontrialend = [
    if (values.previous_targetlocation == 0) {
            values.offDuration = script.elapsedtime - values.startOffTarget;
            list.offDurations_total.insertitem(values.offDuration, 1);
            list.offDurations_trial.insertitem(values.offDuration, 1);
        } ;
]
/ response = correct
/ iscorrectresponse = [
    3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
    if (trial.rotate.trialcount < parameters.NumTrials) {
        trial.rest;
    } else {
        trial.end;
    }
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = BetweenTest, ontargetfeedback]
/ validresponse = (lbuttondown)
/ branch = [
    trial.startRotate;
]
/ recorddata = false
</trial>

<trial end>
/ ontrialbegin = [
    item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = PostTestTxt, ontargetfeedback]
/ validresponse = (lbuttondown)
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
    BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
    EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
    expressions.usedCanvas;
]
/ onexptend = [
    values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
                                                End of File
*******************************************************************************************************************

Thanks, this has been working really well. Now what I want to do is let people practice for 7 trials (still getting the same feedback between trials as above), then complete a test trial. For some reason, I keep getting 'nan' when I try to tell people their performance on the test trial. The feedback during the practice trials is still working correctly. Here's the code, and I've bolded relevant parts:


   PURSUIT ROTOR TASK
SCRIPT INFO

original Coder: Jeffrey Q. Ouyang (qijia.ouyang@gmail.com)
last updated: 08-15-2016 by K.Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC

Script Copyright © 08-15-2016 Millisecond Software


BACKGROUND INFO

*Purpose*
This script implements the Pursuit Rotor Task; a task to measure manual dexterity and visual-motor tracking abilities.

References:
-The Multivariate Study of Pursuit Rotor Skill Development, 11 Aug. 2011, http://www.science.smith.edu/departments/EXER_SCI/Faculty/DS/PR.html
-Measuring Hand/Eye Coordination, 11 Aug. 2011, http://www.psywww.com/intropsych/ch07_cognition/measuring_hand_eye_coordination.html
-Pursuit Rotor, 11 Aug. 2011, http://sourceforge.net/apps/mediawiki/pebl/index.php?title=Pursuit_Rotor

*Task*
Participant tracks a red target with mouse cursor, as the target moves steadily in a circular path.


DATA FILE INFORMATION:
The default data stored in the data files are:

(1) Raw data file: 'PursuitRotor_raw*.iqdat' (a separate file for each participant)

build:Inquisit build
computer.platform:the platform the script was run on
date, time, subject, group:date and time script was run with the current subject/groupnumber
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:the number of trials to run (default: 4)
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; by default data is collected unless /recorddata = false is set for a particular trial/block)

/sum_offDurations_trial:the sum of the durations spent OFF the target disk per trial (in ms)
/timeOnTarget_trial:the duration spent ON the target disk per trial (in ms)
/sum_offDurations_total:the sum of the durations spent OFF the target disk across all trials (in ms)
/timeOnTarget_total:the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_trial:the mean distance (in pixels) of recorded mouse positions from the center of the animated circle per trial
/meanOffDistanceDisc_trial:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)per trial
/meanDistanceFromCenterDisc_total:the mean distance (in pixels) of recorded mouse position from the center of the animated circle across trials
/meanOffDistanceDisc_total:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center)across trials
list.targetDistances_trial.itemcount: stores the number of recorded mouse movements per trial
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
Note: the distance data should only be considered valid if participant continously moved the mouse around;
if few mouse movements are recorded, the collected distance data are questionable

(2) Summary data file: 'PursuitRotor_summary*.iqdat' (a separate file for each participant)

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)
computer.platform:the platform the script was run on
/completed:0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run)
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixels) used for the task
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/NumTrials:the number of trials to run (default: 4)
/sum_offDurations_total:the sum of the durations spent OFF the target disk across all trials (in ms)
list.targetDistances_total.itemcount: stores the number of recorded mouse movements across trials
Note: the (distance) data should only be considered valid if participant continously moved the mouse around;
if few mouse movements are recorded, the collected distance data are questionable
/timeOnTarget_total:the duration spent ON the target disk across trials (in ms)
/meanDistanceFromCenterDisc_total:the mean distance (in pixels) of recorded mouse positions from the center of the animated circle across trials
/meanOffDistanceDisc_total:the mean distance (in pixels) of recorded mouse positions from the target disc (to edges of disc; not the center) across trials


EXPERIMENTAL SET-UP
- task runs 4 trials (default; can be edited under section Editable Parameters) on a 800px x 600px canvas (default; can be edited under section Defaults)
- each trial takes 10s (default; can be edited under section Editable Parameters)
- when participant move the mouse; mouse position is compared to disc position
(Note: task relies on participant continously moving the mouse; if no movements occur, data are not updated and summary values are questionnable)

INSTRUCTIONS
can be edited under section Instructions

EDITABLE CODE:
check below for (relatively) easily editable parameters, stimuli, instructions etc.
Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment.

The parameters you can change are:

/trialDuration:the duration of one trial/one rotation in ms (default: 10000ms)
/radius:the radius of the track in pixels
/targetDiscSize:the size of the target disc in pixels
/NumTrials:the number of trials to run (default: 4)

</usermanual>


**************************************************************************************************************
**************************************************************************************************************
EDITABLE PARAMETERS: change editable parameters here
**************************************************************************************************************
**************************************************************************************************************

<parameters>
/ trialDuration = 1000
/ radius = 225px
/ targetDiscSize = 50
/ restTime = 1000
/ NumTrials = 7
/ rotationtime = 1000
/ rotations = 20
/ highscore = 2
</parameters>

**************************************************************************************************************
**************************************************************************************************************
EDITABLE INSTRUCTIONS: change instructions here
**************************************************************************************************************
**************************************************************************************************************

<item instructions>
/ 1 = "In this task, you will track a blue circle moving steadily around a circular track.
~nTry to keep your <%expressions.buttoninstruct1%> on the blue circle at all times.
~nThere will be a total of <%parameters.NumTrials%> practice trials, each lasting <%parameters.trialDuration/1000%> seconds.
~nYou will have <%parameters.restTime/1000%> seconds to rest in between each trial.
~nAfter the practice trials, there will be a test to see what you have learned. 
~n<%expressions.buttoninstruct2%> to begin."
/ 2 = "Position your <%expressions.buttoninstruct1%> on the blue circle and try to stay on the circle at all times.
~n<%expressions.buttoninstruct2%> to begin - the circle will start moving immediately."
/ 3 = "You can now rest for <%parameters.restTime/1000%> seconds before the next practice trial.
~n<%expressions.buttoninstruct2%> if you would like to continue immediately."
/ 4 = "Thank you! To receive payment, please enter the following code on MTurk: <%values.MTURK%>. This page will close after 30 seconds."
/ 5 = "We'd like to know a bit about what you thought about this HIT. Below, please write any comments you think would be useful to pass on to us. For instance, do you think you were paid a fair amount of money for the amount of work you did? Is there something we can do to make the directions clearer? Is there anything we can do to make the HIT more interesting? Any feedback would be helpful!"

</item>

****************************************************************************************************
general instruction expressions: adjust the instruction text depending on device used to run script
****************************************************************************************************
<expressions>
/ buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"finger";} else {"mouse cursor";}
/ buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"Tap your screen";} else {"Click the mouse";}
</expressions>

**************************************************************************************************************
!!!REMAINING CODE: Customize after careful consideration only!!!
**************************************************************************************************************


*******************************************************************************************************************
*******************************************************************************************************************
DEFAULTS:
*******************************************************************************************************************
*******************************************************************************************************************
requires Inquisit 5.0.1.0 or later

<defaults>
/ screencolor = whitesmoke
/ txbgcolor = transparent
/ txcolor = white
/ minimumversion = "5.0.1.0"
/ canvassize = (800px, 600px)
/ inputdevice = mouse
</defaults>

*******************************************************************************************************************
*******************************************************************************************************************
DATA: this section contains data file information
*******************************************************************************************************************
*******************************************************************************************************************

Note: data file explanations under User Manual Information at the top

***********************
raw data file
***********************
<data>
/ separatefiles = true
/ columns = (build, computer.platform, date, time, subject, group, values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration,
blockcode, blocknum, trialcode, trialnum,
expressions.sum_offDurations_trial, expressions.timeOnTarget_trial, expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_trial, expressions.meanOffDistanceDisc_trial, expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total,
list.targetDistances_trial.itemcount, list.targetDistances_total.itemcount, openended.question.response, response)
</data>

***********************
summary data file
***********************
<summarydata>
/ columns = (script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, computer.platform, values.completed,
values.usedCanvas, parameters.radius, parameters.targetDiscSize, parameters.trialDuration, list.targetDistances_total.itemcount,
expressions.sum_offDurations_total, expressions.timeOnTarget_total,
expressions.meanDistanceFromCenterDisc_total, expressions.meanOffDistanceDisc_total)
/ separatefiles = true
</summarydata>

*******************************************************************************************************************
*******************************************************************************************************************
VALUES: automatically updated
*******************************************************************************************************************
*******************************************************************************************************************
/completed:0 = script was not completed; 1 = script was completed (all conditions run)
/previous_targetlocation:1 = mouse was previously ON target disc; 0 = mouse was previously OFF target task
/startOffTarget:records the script.elapsedtime when mouse goes off target
/offDuration:stores the duration (in ms) of the last time spent OFF target disc
/usedCanvas:data file variable that stores the dimension of the experimental canvas (in pixel) used for the task

<values>
/ completed = 0
/ previous_targetlocation = 1
/ current_targetlocation = 0
/ startOffTarget = 0
/ offDuration = 0
/ usedCanvas = "("
/ MTURK = 0
</values>

*******************************************************************************************************************
*******************************************************************************************************************
EXPRESSIONS
*******************************************************************************************************************
*******************************************************************************************************************

/usedCanvas:assembles a variable for the data file that contains the used canvas pixel information
/radius_outerTrack:calculates the radius of the outter track circle in pixels
/radius_innerTrack:calculates the radius of the inner track circle in pixels

/distance:calculates the distance of the current mouse position from the center of the animated circle in pixels

/sum_offDurations_trial:calculates the sum of the durations spent off the target disk per trial (in ms)
/sum_offDurations_total:calculates the sum of the durations spent off the target disk across all trials (in ms)
/timeOnTarget_trial:calculates the duration spent on the target disk per trial (in ms)
/timeOnTarget_total:calculates the duration spent on the target disk across trials (in ms)

/meanDistanceFromCenterDisc_trial:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial
/meanDistanceFromCenterDisc_total:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials

/meanOffDistanceFromCenterDisc_trial:calulates the mean distance (in pixels) from of the mouse position from the center of the animated circle per trial for mouse positions OFF target
/meanOffDistanceFromCenterDisc_total:calculates the mean distance (in pixels) from of the mouse position from the center of the animated circle across trials for mouse positions OFF target

/meanOffDistanceDisc_trial:calulates the mean distance (in pixels) from of the mouse position outside of the disc per trial
/meanOffDistanceDisc_total:calulates the mean distance (in pixels) from of the mouse position outside of the disc across trials

<expressions>
/ usedCanvas = {
values.usedCanvas = concat(values.usedCanvas, display.canvaswidth);
values.usedCanvas = concat(values.usedCanvas, "px, ");
values.usedCanvas = concat(values.usedCanvas, display.canvasheight);
values.usedCanvas = concat(values.usedCanvas, "px)");
}
/ radius_outerTrack = 1px * parameters.radius*1.03
/ radius_innerTrack = 1px * parameters.radius*0.97

/ distance = sqrt(pow((mouse.x - shape.animatedCircle.hposition),2) + pow((mouse.y - shape.animatedCircle.vposition),2));

/ sum_offDurations_trial = list.offDurations_trial.mean * list.offDurations_trial.itemcount
/ sum_offDurations_total = list.offDurations_total.mean * list.offDurations_total.itemcount
/ timeOnTarget_trial = if (expressions.sum_offDurations_trial !="nan") {
parameters.trialDuration - expressions.sum_offDurations_trial;
} else {
parameters.trialDuration;
}
/ timeOnTarget_total = if (expressions.sum_offDurations_total !=NaN)(parameters.trialDuration*trial.startRotate.trialcount) - expressions.sum_offDurations_total else parameters.trialDuration * trial.startRotate.trialcount;

/ meanDistanceFromCenterDisc_trial = list.targetDistances_trial.mean
/ meanDistanceFromCenterDisc_total = list.targetDistances_total.mean

/ meanOffDistanceFromCenterDisc_trial = list.offTargetDistance_trial.mean
/ meanOffDistanceFromCenterDisc_total = list.offTargetDistance_total.mean

/ meanOffDistanceDisc_trial = expressions.meanOffDistanceFromCenterDisc_trial - parameters.targetDiscSize
/ meanOffDistanceDisc_total = expressions.meanOffDistanceFromCenterDisc_total - parameters.targetDiscSize
</expressions>

<expressions>
/ static_x = 50% + parameters.radius
</expressions>

*******************************************************************************************************************
*******************************************************************************************************************
INSTRUCTIONS
*******************************************************************************************************************
*******************************************************************************************************************

<text IntroTxt>
/ items = instructions
/ select = 1
/ fontstyle = ("Verdana", 2%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 45%)
/ size = (40%, 20%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest1>
/ items = ("Here is how many seconds you've been able to stay on the blue circle during each trial so far:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nYou have <%parameters.resttime/1000%> seconds to rest.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BeforeTest>
/ items = ("The test will begin in <%parameters.resttime/1000%> seconds.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest>
/ items = ("Here is how many seconds you've been able to stay on the blue circle during each trial so far:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nSo far your high score is <%list.ontargettimes.maximum/1000%> seconds. Let's see if you can beat that score on the next trial!
~nYou have <%parameters.resttime/1000%> seconds to rest.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest2>
/ items = ("Here is how many seconds you were able to stay on the blue circle during each practice trial:
~nTrial 1: <%item.ontargettimes.item.1/1000%>
Trial 2: <%item.ontargettimes.item.2/1000%>
Trial 3: <%item.ontargettimes.item.3/1000%>
Trial 4: <%item.ontargettimes.item.4/1000%>
Trial 5: <%item.ontargettimes.item.5/1000%>
Trial 6: <%item.ontargettimes.item.6/1000%>
Trial 7: <%item.ontargettimes.item.7/1000%>
~nYour high score was <%list.ontargettimes.maximum/1000%> seconds. Good work!
~n<%expressions.buttoninstruct2%> to continue to the test.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<text BetweenTest4>
/ items = ("You were able to stay on the disc for <%expressions.timeOnTarget_trial/1000%> seconds during the test. Good work!
~n<%expressions.buttoninstruct2%> to continue.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 20%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>


<text BetweenTest3>
/ items = ("Now you are going to complete the test. The speed of the blue circle will be different during the test than it was during the practice.
~nFirst, the circle will complete exactly one rotation, so that you can understand what the new speed is.
~nWe aren't scoring this rotation, so you can trace the circle, just watch, or do whatever you want to do to prepare for the test. After this rotation you will have a chance to rest, then the test will begin.
~n<%expressions.buttoninstruct2%> to continue.")
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 30%)
/ size = (50%, 15%)
/ hjustify = left
/ valign = center
</text>

<text InstructTxt>
/ items = instructions
/ select = 2
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 50%)
/ size = (30%, 30%)
/ hjustify = left
/ valign = center
</text>

<text OpenTxt>
/ items = instructions
/ select = 5
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (400px, 300px)
/ size = (50%, 50%)
/ hjustify = left
/ valign = center
</text>

<text PostTestTxt>
/ items = instructions
/ select = 4
/ fontstyle = ("Verdana", 2.5%, false, false, false, false, 5, 0)
/ txcolor = black
/ position = (50%, 50%)
/ size = (20%, 15%)
/ hjustify = left
/ valign = center
</text>

<item ontargettimes>
</item>


<radiobuttons competence>
/caption = "I performed very well during the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons effort>
/caption = "I put a lot of effort into the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons motivation>
/caption = "I was motivated to do well during the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons difficult>
/caption = "The training was very difficult."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons enjoyment>
/caption = "I enjoyed the training."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>

<radiobuttons pleasant>
/caption = "The training was pleasant."
/ options = ("Strongly Disagree",
"Disagree",
"Slightly Disagree",
"Neither Agree nor Disagree",
"Slightly Agree",
"Agree",
"Strongly Agree")
/required = true
/orientation = vertical
</radiobuttons>




*******************************************************************************************************************
*******************************************************************************************************************
STIMULI
*******************************************************************************************************************
*******************************************************************************************************************

Note: creates the inner circle (where instructions are posted)/track line
<shape innerTrack>
/ shape = circle
/ size = (expressions.radius_innerTrack*2,expressions.radius_innerTrack*2)
/ position = (50%,50%)
/ color = whitesmoke
/ erase = false
</shape>

Note: creates the outer track line
<shape outerTrack>
/ shape = circle
/ size = (1px * expressions.radius_outerTrack*2, 1px*expressions.radius_outerTrack*2)
/ position = (50%,50%)
/ color = black
/ erase = false
</shape>

<shape animatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(parameters.rotationtime, parameters.rotations, 0, 50%, 50%, parameters.radius)
/ color = cornflowerblue
/ erase = false
</shape>

<shape testanimatedCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ animation = circle(2000, 1, 0, 50%, 50%, parameters.radius)
/ color = cornflowerblue
/ erase = false
</shape>

<shape staticCircle>
/ shape = circle
/ size = (parameters.targetDiscSize, parameters.targetDiscSize)
/ hposition = 1px * (display.canvaswidth/2 + parameters.radius)
/ vposition = 1px * (display.canvasheight/2)
/ color = cornflowerblue
/ erase = false
</shape>

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

*************************************************
Data Lists: used for descriptive statistics
store correct latencies/accuracy data
fill up during runtime
*************************************************

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc per trial
<list targetDistances_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement from the center of the target disc across trials
<list targetDistances_total>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) per trial
<list offTargetDistance_trial>
</list>

Note: stores the distance (in pixels) of each recorded mouse movement that are OFF the target disc from the disc (edge of disc) across trials
<list offTargetDistance_total>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target per trial
<list offDurations_trial>
</list>

Note: stores the duration (in ms) of each recorded mouse movement that are OFF the target across trials
<list offDurations_total>
</list>

<list ontargettimes>
/ items = (item.ontargettimes.item.1, item.ontargettimes.item.2, item.ontargettimes.item.3, item.ontargettimes.item.4, item.ontargettimes.item.5, item.ontargettimes.item.6, item.ontargettimes.item.7, item.ontargettimes.item.8)
</list>
*******************************************************************************************************************
*******************************************************************************************************************
TRIALS
*******************************************************************************************************************
*******************************************************************************************************************

<trial intro>
/ stimulusframes = [1 = outerTrack, innerTrack, introTxt]
/ validresponse = (lbuttondown)
/ branch = [
trial.startRotate
]
/ recorddata = false
</trial>

<trial startRotate>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.rotate
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial rotate>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, animatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = parameters.trialDuration
/ branch = [
if (trial.rotate.trialcount < parameters.highscore) {
trial.rest1;
} else if (trial.rotate.trialcount < parameters.NumTrials){
trial.rest
}
else {
trial.prequestion;
}
]
/ recorddata = true
</trial>

<trial rest>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest]
/ timeout = parameters.restTime
/ branch = [
trial.startRotate;
]
/ recorddata = false
</trial>

<trial rest1>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest1]
/ timeout = parameters.restTime
/ branch = [
trial.startRotate;
]
/ recorddata = false
</trial>

<trial prequestion>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest2]
/ validresponse = (lbuttondown)
/ branch = [
surveypage.questions1;
]
/ recorddata = false
</trial>



<surveypage questions1>
/caption ="Thank you for completing the training! Before we continue, please evaluate the following statements:"
/ fontstyle = ("Arial", 4%, false, false, false, false, 5, 1)
/itemfontstyle = ("Arial", 3%, false, false, false, false, 5, 1)
/responsefontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ txcolor = black
/questions = [1 = competence, effort, motivation]
/showpagenumbers = false
/showquestionnumbers = false
/backbuttonposition = (10%, 90%)
/nextbuttonposition = (95%, 95%)
/ branch = [
surveypage.questions2;
]
</surveypage>

<surveypage questions2>
/caption ="Please continue evaluating the following statements:"
/ fontstyle = ("Arial", 4%, false, false, false, false, 5, 1)
/itemfontstyle = ("Arial", 3%, false, false, false, false, 5, 1)
/responsefontstyle = ("Arial", 2.5%, false, false, false, false, 5, 1)
/ txcolor = black
/questions = [1 = difficult, enjoyment, pleasant]
/showpagenumbers = false
/showquestionnumbers = false
/backbuttonposition = (10%, 90%)
/nextbuttonposition = (95%, 95%)
/ branch = [
trial.prerotation;
]
</surveypage>

<trial prerotation>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest3]
/ validresponse = (lbuttondown)
/ branch = [
trial.startonerotation;
]
/ recorddata = false
</trial>

<trial startonerotation>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.onerotation
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial onerotation>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, testanimatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = 2000
/ branch = [
trial.testrest
]
/ recorddata = true
</trial>

<trial testrest>
/ stimulusframes = [1 = clearscreen, BeforeTest]
/ timeout = parameters.restTime
/ branch = [
trial.starttest;
]
/ recorddata = false
</trial>

<trial starttest>
/ stimulusframes = [1 = outerTrack, innerTrack, staticCircle, InstructTxt]
/ validresponse = (staticCircle)
/ branch = [
trial.test
]
/ ontrialend = [
values.previous_targetlocation = 1;
list.offDurations_trial.reset();
list.targetDistances_trial.reset();
list.offTargetDistance_trial.reset();
]
/ recorddata = false
</trial>

<trial test>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, testanimatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = 1000
/ branch = [
trial.posttest
]
/ recorddata = true
</trial>


<trial posttest>
/ ontrialbegin = [
item.ontargettimes.appenditem(expressions.timeOnTarget_trial)
]
/ stimulusframes = [1 = clearscreen, BetweenTest4]
/ validresponse = (lbuttondown)
/ branch = [
openended.question;
]
/ recorddata = false
</trial>


<openended question>
/ stimulusframes=[1 = clearscreen, OpenTxt]
/ position = (50, 90)
/ linelength = 40
/ charlimit = 500
/ numlines = 10
/ branch = [
trial.MTURK
]
</openended>

<trial MTURK>
/ ontrialbegin = [
values.MTURK = floor(rand(16001,165000))
]
/ stimulusframes = [1 = PostTestTxt]
/ timeout = 30000
/ recorddata = false
</trial>

*******************************************************************************************************************
*******************************************************************************************************************
BLOCKS
*******************************************************************************************************************
*******************************************************************************************************************

<block rotate>
/ trials = [1 = intro]
</block>

*******************************************************************************************************************
*******************************************************************************************************************
EXPERIMENT
*******************************************************************************************************************
*******************************************************************************************************************

<expt>
/ onexptbegin = [
expressions.usedCanvas;
]
/ onexptend = [
values.completed = 1;
]
/ blocks = [1 = rotate]
</expt>

/ blocks = [1 = PreTest; 2 =InstructionDisp; 3=Maintest; 4=Posttest]
*******************************************************************************************************************
End of File
*******************************************************************************************************************


<trial test>
/ stimulusframes = [1 = clearscreen, outerTrack, innerTrack, testanimatedCircle]
/ validresponse = (mousemove)
/ isvalidresponse = [
if (trial.rotate.response == "mousemove" && expressions.distance > parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_trial.insertitem(expressions.distance, 1);
list.offTargetDistance_total.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 1) {
values.startOffTarget = script.elapsedtime;
values.previous_targetlocation = 0;
} ;
1 == 1;
} else if (trial.rotate.response == "mousemove" && expressions.distance <= parameters.targetDiscSize) {
list.targetDistances_total.insertitem(expressions.distance, 1);
list.targetDistances_trial.insertitem(expressions.distance, 1);
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
values.previous_targetlocation = 1;
} ;
1 == 1;
}
]
/ ontrialend = [
if (values.previous_targetlocation == 0) {
values.offDuration = script.elapsedtime - values.startOffTarget;
list.offDurations_total.insertitem(values.offDuration, 1);
list.offDurations_trial.insertitem(values.offDuration, 1);
} ;
]
/ response = correct
/ iscorrectresponse = [
3 == 4
]
/ timeout = 1000
/ branch = [
trial.posttest
]
/ recorddata = true
</trial>

You need to reference trial.test.response in <trial test> -- not trial.rotate.response, i.e. which nonexistent responses given in a completely unrelated <trial>.


GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Explore
Messages
Mentions
Search