Millisecond Forums

if statement based on latency of multiple responses within single trial

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

By eleonora_parr - 3/9/2021

Deal Inquisiters, 
I am trying to build an experiment in which participants are presented with circles of different colors, displayed behind a checkerboard.
Whenever the darker circle is presented on the screen (in the code red_circle), they have to press the spacebar by synchronizing the more they can their response with the appearance of the figure on the screen.
The problem is that I want to calculate their accuracy in giving this response for each trial. The accuracy is calculated according to the distance between each spacebar press and each circle appearance. Specifically, the response is considered accurate whenever they managed to press the spacebar in a time window comprised between 125 ms after & -750 ms before the real appearance of the red circle. The problem is that we have many circles displayed within a single trial == many responses given and many latencies. For each of these latencies, we need to repeat this procedure, that is : calculate if every single response can be considered accurate vs. inaccurate (calculated according to the explained criteria).
Then, the ratio between correct/incorrect "stored" responses represent the "accuracy", according to which the next trial is displayed. This is needed as, if participants are very inaccurate, we need to display a trial that presents the circle with an higher constrast (more visible). Instead, if they are very accurate, we need to display a trial which presents the circle with a lower contrast (less visible). All this is needed because we want to reach a certain level of performance for each subject. 

I hope that this would be possible: here is the code 
Thank you very much to all of you!!
Eleonora



<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>


<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){values.spacebarpresscount += 1; values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),","); false}; ]

</trial>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
    1=pre;2=acc;break;3=acc
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>

By Dave - 3/9/2021

I don't think what you want is possible.
By Dave - 3/9/2021

Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.
By eleonora_parr - 3/10/2021

Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora
By Dave - 3/10/2021

eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.
By Dave - 3/10/2021

Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.

Look, the code works like this:
- After the trial has completed and all latencies and onsets during the trial have been collected, it takes the first observed onset and constructs the interval around that onset.
- It then goes through all the latencies observed and checks if any of them falls within the interval for that first onset. If so, the accuracy count is increased by one.
- It then moves on to the next, 2nd observed onset, constructs the interval around it, and again moves through ALL observed latencies and checks if any of them fall within the interval. Again, if so, the accuracy count is increased accordingly.
- This is repeated until all latencies have been checked against every onset interval.
By eleonora_parr - 3/10/2021

Dave - 3/10/2021
Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.

Look, the code works like this:
- After the trial has completed and all latencies and onsets during the trial have been collected, it takes the first observed onset and constructs the interval around that onset.
- It then goes through all the latencies observed and checks if any of them falls within the interval for that first onset. If so, the accuracy count is increased by one.
- It then moves on to the next, 2nd observed onset, constructs the interval around it, and again moves through ALL observed latencies and checks if any of them fall within the interval. Again, if so, the accuracy count is increased accordingly.
- This is repeated until all latencies have been checked against every onset interval.

Oh, I thought that this could be the reason why the number of the accuracy was a bit weird. But now I suspect that the problem is here :

if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
   values.sum_acc_latencies += 1;
  };

I think that the code is not actually checking for a value in between these two, but instead it considers the response as accurate just if that latency is *greater than* or *lower than* the specified values. So, for example, if my response was at 1663 ms, than this is compared with this first range of -750 and 125 ms: the response is then considered correct because 1663>-750. I've tried to substitute < and > with &gt. and &lt. but for some reasons it gives me an error. Could this be the problem ? Do you know if I can check that by substituting the operators with different tricks? 

Thank you so much

Eleonora
By Dave - 3/10/2021

eleonora_parr - 3/10/2021
Dave - 3/10/2021
Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.

Look, the code works like this:
- After the trial has completed and all latencies and onsets during the trial have been collected, it takes the first observed onset and constructs the interval around that onset.
- It then goes through all the latencies observed and checks if any of them falls within the interval for that first onset. If so, the accuracy count is increased by one.
- It then moves on to the next, 2nd observed onset, constructs the interval around it, and again moves through ALL observed latencies and checks if any of them fall within the interval. Again, if so, the accuracy count is increased accordingly.
- This is repeated until all latencies have been checked against every onset interval.

Oh, I thought that this could be the reason why the number of the accuracy was a bit weird. But now I suspect that the problem is here :

if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
   values.sum_acc_latencies += 1;
  };

I think that the code is not actually checking for a value in between these two, but instead it considers the response as accurate just if that latency is *greater than* or *lower than* the specified values. So, for example, if my response was at 1663 ms, than this is compared with this first range of -750 and 125 ms: the response is then considered correct because 1663>-750. I've tried to substitute < and > with &gt. and &lt. but for some reasons it gives me an error. Could this be the problem ? Do you know if I can check that by substituting the operators with different tricks? 

Thank you so much

Eleonora

No. 1663 will not be considered accurate for the interval -750 to 125. There is a logical AND (&&). If the latency is greater than (or equal to) -750 AND AT THE SAME TIME smaller than (or exactly equal to) 125, THEN it will be considered accurate.
By Dave - 3/10/2021

Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/10/2021
Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.

Look, the code works like this:
- After the trial has completed and all latencies and onsets during the trial have been collected, it takes the first observed onset and constructs the interval around that onset.
- It then goes through all the latencies observed and checks if any of them falls within the interval for that first onset. If so, the accuracy count is increased by one.
- It then moves on to the next, 2nd observed onset, constructs the interval around it, and again moves through ALL observed latencies and checks if any of them fall within the interval. Again, if so, the accuracy count is increased accordingly.
- This is repeated until all latencies have been checked against every onset interval.

Oh, I thought that this could be the reason why the number of the accuracy was a bit weird. But now I suspect that the problem is here :

if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
   values.sum_acc_latencies += 1;
  };

I think that the code is not actually checking for a value in between these two, but instead it considers the response as accurate just if that latency is *greater than* or *lower than* the specified values. So, for example, if my response was at 1663 ms, than this is compared with this first range of -750 and 125 ms: the response is then considered correct because 1663>-750. I've tried to substitute < and > with &gt. and &lt. but for some reasons it gives me an error. Could this be the problem ? Do you know if I can check that by substituting the operators with different tricks? 

Thank you so much

Eleonora

No. 1663 will not be considered accurate for the interval -750 to 125. There is a logical AND (&&). If the latency is greater than (or equal to) -750 AND AT THE SAME TIME smaller than (or exactly equal to) 125, THEN it will be considered accurate.

For what it's worth, your confusion may be due to the displayed final accuracy value. It is calculated as the percentage of observed latencies that have been graded as accurate. I.e. suppose 37 latencies have been observed during the trial, and 26 of these fall into some onset bucket, then the accuracy displayed is caculated as 26/37*100 = 70.27%.

If you wish to calculate the accuracy differently, you are free to do so by adjusting the calculatiion in the score trial accordingly.
By eleonora_parr - 3/11/2021

Dave - 3/10/2021
Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/10/2021
Dave - 3/10/2021
eleonora_parr - 3/10/2021
Dave - 3/9/2021
Dave - 3/9/2021
I don't think what you want is possible.

Okay, here is something to try:


<shape red_circle>
/ color = (180,180,180)
/ position = (50%,50%)
/ shape = circle
/size=(10%, 10%)
</shape>


<shape black_circle>
/ color = (185,185,185)
/ position = (50%,50%)
/ shape = circle
/ size=(10%, 10%)
</shape>

<shape blank>
/ color = (192,192,192)
/ position = (50%,50%)
/ shape = rectangle
/size=(30%, 30%)
</shape>

<trial blank>
/stimulusframes=[1=blank]
/ trialduration = 3000
</trial>

<text cross>
/items=("+")
/position = (50%, 50%)
</text>

<picture checker>
/items=("scacchieracc.png")
/ position = (50%, 50%)
/ size = (30%, 30%)
</picture>

<trial fixate>
/ stimulusframes = [1=cross]
/ trialduration = 2000
</trial>

<values>
/timeofresponse=""
/spacebarpresscount =""
/accuracy = ""
</values>

<trial acc>
/ ontrialbegin = [
    values.spacebarpresscount = "";
    values.timeofresponse = "";
    values.accuracy = "";
    values.current_onset = "";
    values.current_max = "";
    values.current_min = "";
    values.current_latency = "";
    values.sum_acc_latencies = 0;
    values.bucketcount = 0;
    values.latencycount = 0;
    
    list.acc.reset();
    list.latencies.reset();
    list.onsets.reset();
]
/pretrialpause = 1000
/stimulustimes=[
0=red_circle, checker;
1007=red_circle, checker;
2082=red_circle, checker;
3220=red_circle, checker;
4399=red_circle, checker;
5570=red_circle, checker;
6708=red_circle, checker;
7936=red_circle, checker;
9059=red_circle, checker;
10259=red_circle, checker;
11460=red_circle, checker;
12633=red_circle, checker;
13893=red_circle, checker;
15069=red_circle, checker;
16284=red_circle, checker;
17449=red_circle, checker;
18591=red_circle, checker;
19795=red_circle, checker;
20915=red_circle, checker;
22149=red_circle, checker;
23244=red_circle, checker;
24398=red_circle, checker;
25567=red_circle, checker;
26690=red_circle, checker;
27885=red_circle, checker;
28998=red_circle, checker;
30208=red_circle, checker;
31421=red_circle, checker;
32539=red_circle, checker;
33702=red_circle, checker;
34789=red_circle, checker;
35849=red_circle, checker;
36972=red_circle, checker;
38018=red_circle, checker;
39172=red_circle, checker;
40341=red_circle, checker;
41437=red_circle, checker;
42572=red_circle, checker;
43681=red_circle, checker;
44758=red_circle, checker;
45918=red_circle, checker;
46995=red_circle, checker;
48090=red_circle, checker;

50=black_circle, checker;
1057=black_circle, checker;
2132=black_circle, checker;
3270=black_circle, checker;
4449=black_circle, checker;
5620=black_circle, checker;
6758=black_circle, checker;
7986=black_circle, checker;
9109=black_circle, checker;
10309=black_circle, checker;
11510=black_circle, checker;
12683=black_circle, checker;
13943=black_circle, checker;
15119=black_circle, checker;
16334=black_circle, checker;
17499=black_circle, checker;
18641=black_circle, checker;
19845=black_circle, checker;
20965=black_circle, checker;
22199=black_circle, checker;
23294=black_circle, checker;
24448=black_circle, checker;
25617=black_circle, checker;
26740=black_circle, checker;
27935=black_circle, checker;
29048=black_circle, checker;
30258=black_circle, checker;
31471=black_circle, checker;
32589=black_circle, checker;
33752=black_circle, checker;
34839=black_circle, checker;
35899=black_circle, checker;
37022=black_circle, checker;
38068=black_circle, checker;
39222=black_circle, checker;
40391=black_circle, checker;
41487=black_circle, checker;
42622=black_circle, checker;
43731=black_circle, checker;
44808=black_circle, checker;
45968=black_circle, checker;
47045=black_circle, checker;
48140=black_circle, checker;
]
/ trialduration = 48140+1000
/ inputdevice = keyboard
/ beginresponsetime = -1
/ responseinterrupt = trial
/ validresponse = (-57, 0)
/ correctresponse = (0)
/ showmousecursor = false
/ isvalidresponse = [if(trial.acc.response==57){
    values.spacebarpresscount += 1;
    values.timeofresponse=concat(concat(values.timeofresponse, trial.acc.latency),",");
    list.latencies.appenditem(trial.acc.latency);
    false}
    ;
]
/ ontrialend = [
    list.onsets.appenditem(shape.red_circle.stimulusonset.1);
    list.onsets.appenditem(shape.red_circle.stimulusonset.2);
    list.onsets.appenditem(shape.red_circle.stimulusonset.3);
    list.onsets.appenditem(shape.red_circle.stimulusonset.4);
    list.onsets.appenditem(shape.red_circle.stimulusonset.5);
    list.onsets.appenditem(shape.red_circle.stimulusonset.6);
    list.onsets.appenditem(shape.red_circle.stimulusonset.7);
    list.onsets.appenditem(shape.red_circle.stimulusonset.8);
    list.onsets.appenditem(shape.red_circle.stimulusonset.9);
    list.onsets.appenditem(shape.red_circle.stimulusonset.10);
    list.onsets.appenditem(shape.red_circle.stimulusonset.11);
    list.onsets.appenditem(shape.red_circle.stimulusonset.12);
    list.onsets.appenditem(shape.red_circle.stimulusonset.13);
    list.onsets.appenditem(shape.red_circle.stimulusonset.14);
    list.onsets.appenditem(shape.red_circle.stimulusonset.15);
    list.onsets.appenditem(shape.red_circle.stimulusonset.16);
    list.onsets.appenditem(shape.red_circle.stimulusonset.17);
    list.onsets.appenditem(shape.red_circle.stimulusonset.18);
    list.onsets.appenditem(shape.red_circle.stimulusonset.19);
    list.onsets.appenditem(shape.red_circle.stimulusonset.20);
    list.onsets.appenditem(shape.red_circle.stimulusonset.21);
    list.onsets.appenditem(shape.red_circle.stimulusonset.22);
    list.onsets.appenditem(shape.red_circle.stimulusonset.23);
    list.onsets.appenditem(shape.red_circle.stimulusonset.24);
    list.onsets.appenditem(shape.red_circle.stimulusonset.25);
    list.onsets.appenditem(shape.red_circle.stimulusonset.26);
    list.onsets.appenditem(shape.red_circle.stimulusonset.27);
    list.onsets.appenditem(shape.red_circle.stimulusonset.28);
    list.onsets.appenditem(shape.red_circle.stimulusonset.29);
    list.onsets.appenditem(shape.red_circle.stimulusonset.30);
    list.onsets.appenditem(shape.red_circle.stimulusonset.31);
    list.onsets.appenditem(shape.red_circle.stimulusonset.32);
    list.onsets.appenditem(shape.red_circle.stimulusonset.33);
    list.onsets.appenditem(shape.red_circle.stimulusonset.34);
    list.onsets.appenditem(shape.red_circle.stimulusonset.35);
    list.onsets.appenditem(shape.red_circle.stimulusonset.36);
    list.onsets.appenditem(shape.red_circle.stimulusonset.37);
    list.onsets.appenditem(shape.red_circle.stimulusonset.38);
    list.onsets.appenditem(shape.red_circle.stimulusonset.39);
    list.onsets.appenditem(shape.red_circle.stimulusonset.40);
    list.onsets.appenditem(shape.red_circle.stimulusonset.41);
    list.onsets.appenditem(shape.red_circle.stimulusonset.42);
    list.onsets.appenditem(shape.red_circle.stimulusonset.43);
]
/ branch = [
    trial.construct_bucket;
]
</trial>

<list latencies>
/ select = sequence
</list>

<list onsets>
/ select = sequence
</list>

<list acc>
</list>

<values>
/ current_onset = 0
/ current_min = 0
/ current_max = 0
/ current_latency = ""
/ bucketcount = 0
/ latencycount = 0
/ sum_acc_latencies = 0
</values>


<trial construct_bucket>
/ ontrialbegin = [
    values.bucketcount += 1;
    values.latencycount = 0;
    values.current_onset = list.onsets.nextvalue;
    values.current_min = values.current_onset - 750;
    values.current_max = values.current_onset + 125;
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    trial.check_latencies;
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial check_latencies>
/ ontrialbegin = [
    values.latencycount += 1;
    values.current_latency = list.latencies.nextvalue;
    if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
        values.sum_acc_latencies += 1;
    };
]
// stimulusframes = [1=clearscreen, debug]
/ branch = [
    if (values.latencycount < list.latencies.itemcount) {
        trial.check_latencies;
    } else if (values.bucketcount < list.onsets.itemcount) {
        trial.construct_bucket;
    } else {
        trial.score_result;
    }
]
/ trialduration = 0
/ recorddata = false
</trial>

<trial score_result>
/ ontrialbegin = [
    values.accuracy = values.sum_acc_latencies/list.latencies.itemcount;
]
/ stimulusframes = [1=clearscreen, debug]
/ validresponse = (57)
</trial>

<text debug>
/ items = ("Bucket <%values.bucketcount%> of <%list.onsets.itemcount%>
Latency <%values.latencycount%> of <%list.latencies.itemcount%>
Onset: <%values.current_onset%>| Min Latency: <%values.current_min%> | Max Latency: <%values.current_max%>
Current Latency: <%values.current_latency%>
Accurate Latencies: <%values.sum_acc_latencies%> of <%list.latencies.itemcount%>
Final Accuracy: <%values.accuracy *100%>%")
/ erase = false
/ size = (60%, 40%)
</text>


<block pre>
/ trials = [1=fixate; 2=blank]
</block>

<block acc>
/ trials = [1=acc]
</block>

<expt >
/blocks=[
1=pre;2=acc;
]
</expt>

<data>
/ columns = [date,time,group,subject, display.refreshrate, display.canvaswidth, display.canvasheight, trialduration, values.timeofresponse,values.spacebarpresscount,
shape.black_circle.stimulusonset.1
shape.black_circle.stimulusonset.2
shape.black_circle.stimulusonset.3
shape.black_circle.stimulusonset.4
shape.black_circle.stimulusonset.5
shape.black_circle.stimulusonset.6
shape.black_circle.stimulusonset.7
shape.black_circle.stimulusonset.8
shape.black_circle.stimulusonset.9
shape.black_circle.stimulusonset.10
shape.black_circle.stimulusonset.11
shape.black_circle.stimulusonset.12
shape.black_circle.stimulusonset.13
shape.black_circle.stimulusonset.14
shape.black_circle.stimulusonset.15
shape.black_circle.stimulusonset.16
shape.black_circle.stimulusonset.17
shape.black_circle.stimulusonset.18
shape.black_circle.stimulusonset.19
shape.black_circle.stimulusonset.20
shape.black_circle.stimulusonset.21
shape.black_circle.stimulusonset.22
shape.black_circle.stimulusonset.23
shape.black_circle.stimulusonset.24
shape.black_circle.stimulusonset.25
shape.black_circle.stimulusonset.26
shape.black_circle.stimulusonset.27
shape.black_circle.stimulusonset.28
shape.black_circle.stimulusonset.29
shape.black_circle.stimulusonset.30
shape.black_circle.stimulusonset.31
shape.black_circle.stimulusonset.32
shape.black_circle.stimulusonset.33
shape.black_circle.stimulusonset.34
shape.black_circle.stimulusonset.35
shape.black_circle.stimulusonset.36
shape.black_circle.stimulusonset.37
shape.black_circle.stimulusonset.38
shape.black_circle.stimulusonset.39
shape.black_circle.stimulusonset.40
shape.black_circle.stimulusonset.41
shape.black_circle.stimulusonset.42
shape.black_circle.stimulusonset.43


shape.red_circle.stimulusonset.1
shape.red_circle.stimulusonset.2
shape.red_circle.stimulusonset.3
shape.red_circle.stimulusonset.4
shape.red_circle.stimulusonset.5
shape.red_circle.stimulusonset.6
shape.red_circle.stimulusonset.7
shape.red_circle.stimulusonset.8
shape.red_circle.stimulusonset.9
shape.red_circle.stimulusonset.10
shape.red_circle.stimulusonset.11
shape.red_circle.stimulusonset.12
shape.red_circle.stimulusonset.13
shape.red_circle.stimulusonset.14
shape.red_circle.stimulusonset.15
shape.red_circle.stimulusonset.16
shape.red_circle.stimulusonset.17
shape.red_circle.stimulusonset.18
shape.red_circle.stimulusonset.19
shape.red_circle.stimulusonset.20
shape.red_circle.stimulusonset.21
shape.red_circle.stimulusonset.22
shape.red_circle.stimulusonset.23
shape.red_circle.stimulusonset.24
shape.red_circle.stimulusonset.25
shape.red_circle.stimulusonset.26
shape.red_circle.stimulusonset.27
shape.red_circle.stimulusonset.28
shape.red_circle.stimulusonset.29
shape.red_circle.stimulusonset.30
shape.red_circle.stimulusonset.31
shape.red_circle.stimulusonset.32
shape.red_circle.stimulusonset.33
shape.red_circle.stimulusonset.34
shape.red_circle.stimulusonset.35
shape.red_circle.stimulusonset.36
shape.red_circle.stimulusonset.37
shape.red_circle.stimulusonset.38
shape.red_circle.stimulusonset.39
shape.red_circle.stimulusonset.40
shape.red_circle.stimulusonset.41
shape.red_circle.stimulusonset.42
shape.red_circle.stimulusonset.43
]
</data>

<defaults>
/ screencolor = (192,192,192)
/ txbgcolor = (192,192,192)
/ txcolor = white
/ fontstyle = ("Trebuchet MS", 3.11%, false, false, false, false, 5, 1)
</defaults>


What this does:
- It stores all the latencies encountered during the trial in a list.latencies.
- It stores all the stimulus onsets for shape.red_circle during the trial in list.onsets.

After trial.acc, trial.construct_bucket builds an interval around an onset and then iterates through all latencies, checking whether a given latency falls into the given bucket or not. This process is repeated for all onsets encountered, one after the other. The accuracy is then calculated as the amount of latencies that fall into buckets divided by the amount of all all latencies.

I do not have the time for extensive testing or cross-checking or validating results by hand. This would fall on you.

Dear Dave, this is awesome!! thank you very much!!It works!
My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.
What I mean is that in this code we are comparing the first onset with the first spacebar press (according to the criteria -750 and 125 ms), then the second onset with the second latency and so on. But it could easily happen that the first response that the subject gave was not synchronized with the *first* circle onset but with the third instead. I am desperately try to achieve that by modifying your code but unsuccesfully .

What I am trying to do is something like: IF (onset.nextvalue - ALL latencies >= values.current_min && onset.nextvalue - ALL latencies <= values.current_max  ) { values.sum_acc_latencies += 1; };]

Thank you so much again!

Eleonora

> My only problem at the moment is that this comparison should not be a 1:1 - so that one onset is compared with one and only latency everytime.

The code I provided is NOT a 1:1. EVERY latency is checked for EVERY onset interval.

Look, the code works like this:
- After the trial has completed and all latencies and onsets during the trial have been collected, it takes the first observed onset and constructs the interval around that onset.
- It then goes through all the latencies observed and checks if any of them falls within the interval for that first onset. If so, the accuracy count is increased by one.
- It then moves on to the next, 2nd observed onset, constructs the interval around it, and again moves through ALL observed latencies and checks if any of them fall within the interval. Again, if so, the accuracy count is increased accordingly.
- This is repeated until all latencies have been checked against every onset interval.

Oh, I thought that this could be the reason why the number of the accuracy was a bit weird. But now I suspect that the problem is here :

if (values.current_latency >= values.current_min && values.current_latency <= values.current_max){
   values.sum_acc_latencies += 1;
  };

I think that the code is not actually checking for a value in between these two, but instead it considers the response as accurate just if that latency is *greater than* or *lower than* the specified values. So, for example, if my response was at 1663 ms, than this is compared with this first range of -750 and 125 ms: the response is then considered correct because 1663>-750. I've tried to substitute < and > with &gt. and &lt. but for some reasons it gives me an error. Could this be the problem ? Do you know if I can check that by substituting the operators with different tricks? 

Thank you so much

Eleonora

No. 1663 will not be considered accurate for the interval -750 to 125. There is a logical AND (&&). If the latency is greater than (or equal to) -750 AND AT THE SAME TIME smaller than (or exactly equal to) 125, THEN it will be considered accurate.

For what it's worth, your confusion may be due to the displayed final accuracy value. It is calculated as the percentage of observed latencies that have been graded as accurate. I.e. suppose 37 latencies have been observed during the trial, and 26 of these fall into some onset bucket, then the accuracy displayed is caculated as 26/37*100 = 70.27%.

If you wish to calculate the accuracy differently, you are free to do so by adjusting the calculatiion in the score trial accordingly.

Dear Dave,
I just wanted to thank you, you were completely right -- the weird level of accuracy was given by a stupid mistake that I did with the timing, now everything works thanks to you! 
You are a genius, I am so grateful to you! 

Eleonora