compileprofile-spacetests 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +115 -0
- package/README.md +147 -34
- package/dist/cjs/common-interfaces.d.ts +60 -0
- package/dist/cjs/common-interfaces.js +2 -0
- package/dist/cjs/emotions.d.ts +2 -7
- package/dist/cjs/emotions.js +56 -22
- package/dist/cjs/gonogo.d.ts +1 -6
- package/dist/cjs/gonogo.js +61 -14
- package/dist/cjs/index.d.ts +2 -5
- package/dist/cjs/nback.d.ts +1 -11
- package/dist/cjs/nback.js +27 -13
- package/dist/cjs/spatial-cognition.d.ts +1 -6
- package/dist/cjs/spatial-cognition.js +69 -14
- package/dist/esm/common-interfaces.d.ts +60 -0
- package/dist/esm/common-interfaces.js +1 -0
- package/dist/esm/emotions.d.ts +2 -7
- package/dist/esm/emotions.js +55 -21
- package/dist/esm/gonogo.d.ts +1 -6
- package/dist/esm/gonogo.js +61 -14
- package/dist/esm/index.d.ts +2 -5
- package/dist/esm/nback.d.ts +1 -11
- package/dist/esm/nback.js +27 -13
- package/dist/esm/spatial-cognition.d.ts +1 -6
- package/dist/esm/spatial-cognition.js +69 -14
- package/example-data/emotions.json +807 -807
- package/example-data/gonogo.json +5392 -5392
- package/example-data/nback.json +892 -892
- package/example-data/participant.json +6 -6
- package/example-data/spatial-cognition.json +462 -462
- package/jest.config.js +13 -13
- package/original/emotion-recognition.R +39 -39
- package/original/gonogo.R +32 -32
- package/package.json +40 -40
- package/src/__tests__/integration/browserInfo.test.ts +16 -16
- package/src/__tests__/integration/emotions.test.ts +172 -64
- package/src/__tests__/integration/gonogo.test.ts +183 -80
- package/src/__tests__/integration/nback.test.ts +148 -55
- package/src/__tests__/integration/spatial-cognition.test.ts +171 -66
- package/src/__tests__/test-utils/testData.ts +79 -79
- package/src/common-interfaces.ts +79 -0
- package/src/emotions.ts +98 -59
- package/src/getters.ts +21 -21
- package/src/gonogo.ts +126 -75
- package/src/index.ts +39 -23
- package/src/nback.ts +61 -53
- package/src/spatial-cognition.ts +112 -54
- package/tsconfig.cjs.json +12 -12
- package/tsconfig.esm.json +14 -14
package/dist/cjs/nback.js
CHANGED
|
@@ -15,25 +15,39 @@ exports.nback_extract_trials = nback_extract_trials;
|
|
|
15
15
|
var nback_results = function (trials) {
|
|
16
16
|
var target_trials = trials.filter(function (o) { return o.is_target; });
|
|
17
17
|
var non_target_trials = trials.filter(function (o) { return !o.is_target; });
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
var correct_trials = trials.filter(function (o) { return o.correct === true; });
|
|
19
|
+
var incorrect_trials = trials.filter(function (o) { return o.correct === false; });
|
|
20
|
+
var total_rt = trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
21
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
22
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
23
|
+
var responded_trials = trials.filter(function (o) { return o.response !== null; });
|
|
24
|
+
var correct_responded_trials = responded_trials.filter(function (o) { return o.correct === true; });
|
|
25
|
+
var incorrect_responded_trials = responded_trials.filter(function (o) { return o.correct === false; });
|
|
26
|
+
var common = {
|
|
27
|
+
n_trials: trials.length,
|
|
28
|
+
n_correct_trials: correct_trials.length,
|
|
29
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
30
|
+
avg_rt_total: trials.length > 0 ? total_rt / responded_trials.length : 0,
|
|
31
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_responded_trials.length : 0,
|
|
32
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_responded_trials.length : 0,
|
|
33
|
+
performance_score: trials.length > 0 ? correct_trials.length * 100 / trials.length : 0
|
|
34
|
+
};
|
|
35
|
+
var special = {
|
|
24
36
|
target_trials: {
|
|
25
37
|
n: target_trials.length,
|
|
26
|
-
avg_rt: target_trials.reduce(function (a, b) { return a + b.rt; }, 0) / target_trials.length,
|
|
27
|
-
avg_acc: target_trials.reduce(function (a, b) { return a + b.correct; }, 0) / target_trials.length,
|
|
38
|
+
avg_rt: target_trials.length > 0 ? target_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / target_trials.length : 0,
|
|
39
|
+
avg_acc: target_trials.length > 0 ? target_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) * 100 / target_trials.length : 0,
|
|
28
40
|
},
|
|
29
41
|
non_target_trials: {
|
|
30
42
|
n: non_target_trials.length,
|
|
31
|
-
avg_rt: non_target_trials.reduce(function (a, b) { return a + b.rt; }, 0) / non_target_trials.length,
|
|
32
|
-
avg_acc: non_target_trials.reduce(function (a, b) { return a + b.correct; }, 0) / non_target_trials.length,
|
|
33
|
-
}
|
|
34
|
-
|
|
43
|
+
avg_rt: non_target_trials.length > 0 ? non_target_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / non_target_trials.length : 0,
|
|
44
|
+
avg_acc: non_target_trials.length > 0 ? non_target_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) * 100 / non_target_trials.length : 0,
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var results = {
|
|
48
|
+
common: common,
|
|
49
|
+
special: special
|
|
35
50
|
};
|
|
36
|
-
results.performance = results.total_trials.avg_acc;
|
|
37
51
|
console.log(results);
|
|
38
52
|
return results;
|
|
39
53
|
};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
n: number;
|
|
3
|
-
avg_rt: number;
|
|
4
|
-
avg_acc: number;
|
|
5
|
-
performance: number;
|
|
6
|
-
}
|
|
1
|
+
import { SpatialResultsStructure } from './common-interfaces';
|
|
7
2
|
declare const spatial_calculate_results: (obj: any[]) => SpatialResultsStructure;
|
|
8
3
|
declare const spatial_extract_trials: (obj: any[]) => any[];
|
|
9
4
|
declare const spatial_results: (obj: any[]) => SpatialResultsStructure;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.spatial_calculate_results = exports.spatial_results = exports.spatial_extract_trials = exports.spatial_extract_image_info = void 0;
|
|
4
|
+
var BEST_SCORE = 1000;
|
|
5
|
+
var WORST_SCORE = 10000;
|
|
4
6
|
var spatial_calculate_results = function (obj) {
|
|
5
7
|
var trials = spatial_extract_trials(obj);
|
|
6
8
|
return spatial_results(trials);
|
|
7
9
|
};
|
|
8
10
|
exports.spatial_calculate_results = spatial_calculate_results;
|
|
11
|
+
var calculate_performance_score = function (avg_rt, avg_acc) {
|
|
12
|
+
var performance = avg_rt / (avg_acc + 0.001);
|
|
13
|
+
performance = Math.min(Math.max(performance, BEST_SCORE), WORST_SCORE);
|
|
14
|
+
var performance_score = (1 - ((performance - BEST_SCORE) / (WORST_SCORE - BEST_SCORE))) * 100;
|
|
15
|
+
return performance_score;
|
|
16
|
+
};
|
|
9
17
|
var spatial_extract_trials = function (obj) {
|
|
10
18
|
var trials = obj.filter(function (o) { return 'stimulus' in o &&
|
|
11
19
|
o.stimulus.startsWith("<img src="); });
|
|
@@ -14,21 +22,68 @@ var spatial_extract_trials = function (obj) {
|
|
|
14
22
|
};
|
|
15
23
|
exports.spatial_extract_trials = spatial_extract_trials;
|
|
16
24
|
var spatial_results = function (obj) {
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
var correct_trials = obj.filter(function (o) { return o.correct === 1 || o.correct === true; });
|
|
26
|
+
var incorrect_trials = obj.filter(function (o) { return o.correct === 0 || o.correct === false; });
|
|
27
|
+
var missing_trials = obj.filter(function (o) { return o.response === null || o.response === undefined; });
|
|
28
|
+
var total_rt = obj.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
29
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
30
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
31
|
+
var missing_rt = missing_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
32
|
+
var avg_rt = obj.length > 0 ? total_rt / obj.length : 0;
|
|
33
|
+
var avg_acc = obj.length > 0 ? correct_trials.length / obj.length : 0;
|
|
34
|
+
var performance_score = calculate_performance_score(avg_rt, avg_acc);
|
|
35
|
+
var common = {
|
|
36
|
+
n_trials: obj.length,
|
|
37
|
+
n_correct_trials: correct_trials.length,
|
|
38
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
39
|
+
avg_rt_total: avg_rt,
|
|
40
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_trials.length : 0,
|
|
41
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_trials.length : 0,
|
|
42
|
+
performance_score: performance_score
|
|
43
|
+
};
|
|
44
|
+
// Group by distance, angle, and rotation for special results
|
|
45
|
+
var by_distance = Object.values(obj.reduce(function (acc, trial) {
|
|
46
|
+
var key = trial.distance || 'unknown';
|
|
47
|
+
if (!acc[key])
|
|
48
|
+
acc[key] = { distance: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
49
|
+
acc[key].trials.push(trial);
|
|
50
|
+
return acc;
|
|
51
|
+
}, {})).map(function (group) {
|
|
52
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
53
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
54
|
+
return group;
|
|
55
|
+
});
|
|
56
|
+
var by_angle = Object.values(obj.reduce(function (acc, trial) {
|
|
57
|
+
var key = trial.angle || 'unknown';
|
|
58
|
+
if (!acc[key])
|
|
59
|
+
acc[key] = { angle: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
60
|
+
acc[key].trials.push(trial);
|
|
61
|
+
return acc;
|
|
62
|
+
}, {})).map(function (group) {
|
|
63
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
64
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
65
|
+
return group;
|
|
66
|
+
});
|
|
67
|
+
var by_rotation = Object.values(obj.reduce(function (acc, trial) {
|
|
68
|
+
var key = trial.rotation || 'unknown';
|
|
69
|
+
if (!acc[key])
|
|
70
|
+
acc[key] = { rotation: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
71
|
+
acc[key].trials.push(trial);
|
|
72
|
+
return acc;
|
|
73
|
+
}, {})).map(function (group) {
|
|
74
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
75
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
76
|
+
return group;
|
|
77
|
+
});
|
|
78
|
+
var special = {
|
|
79
|
+
by_distance: by_distance,
|
|
80
|
+
by_angle: by_angle,
|
|
81
|
+
by_rotation: by_rotation
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
common: common,
|
|
85
|
+
special: special
|
|
22
86
|
};
|
|
23
|
-
var best_score = 1000;
|
|
24
|
-
var worst_score = 10000;
|
|
25
|
-
// results.avg_acc to the power of 5
|
|
26
|
-
//let performance = results.avg_rt / (Math.pow(results.avg_acc, 5) + 0.001);
|
|
27
|
-
var performance = results.avg_rt / (results.avg_acc + 0.001);
|
|
28
|
-
performance = Math.min(Math.max(performance, best_score), worst_score);
|
|
29
|
-
// convert to 0-100 where 100 is the best (200)
|
|
30
|
-
results.performance = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
|
|
31
|
-
return results;
|
|
32
87
|
};
|
|
33
88
|
exports.spatial_results = spatial_results;
|
|
34
89
|
var spatial_extract_image_info = function (obj) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
interface CommonResults {
|
|
2
|
+
n_trials: number;
|
|
3
|
+
n_correct_trials: number;
|
|
4
|
+
n_incorrect_trials: number;
|
|
5
|
+
avg_rt_total: number;
|
|
6
|
+
avg_rt_correct: number;
|
|
7
|
+
avg_rt_incorrect: number;
|
|
8
|
+
performance_score: number;
|
|
9
|
+
}
|
|
10
|
+
interface NbackSpecialResults {
|
|
11
|
+
target_trials: {
|
|
12
|
+
n: number;
|
|
13
|
+
avg_rt: number;
|
|
14
|
+
avg_acc: number;
|
|
15
|
+
};
|
|
16
|
+
non_target_trials: {
|
|
17
|
+
n: number;
|
|
18
|
+
avg_rt: number;
|
|
19
|
+
avg_acc: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface SpatialSpecialResults {
|
|
23
|
+
by_distance: any[];
|
|
24
|
+
by_angle: any[];
|
|
25
|
+
by_rotation: any[];
|
|
26
|
+
}
|
|
27
|
+
interface GonogoSpecialResults {
|
|
28
|
+
by_block: any[];
|
|
29
|
+
go_trials: {
|
|
30
|
+
n: number;
|
|
31
|
+
avg_rt: number;
|
|
32
|
+
avg_acc: number;
|
|
33
|
+
};
|
|
34
|
+
nogo_trials: {
|
|
35
|
+
n: number;
|
|
36
|
+
avg_rt: number;
|
|
37
|
+
avg_acc: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
interface EmotionSpecialResults {
|
|
41
|
+
by_emotion: any[];
|
|
42
|
+
confusion_matrix: any;
|
|
43
|
+
}
|
|
44
|
+
interface NbackResultsStructure {
|
|
45
|
+
common: CommonResults;
|
|
46
|
+
special: NbackSpecialResults;
|
|
47
|
+
}
|
|
48
|
+
interface SpatialResultsStructure {
|
|
49
|
+
common: CommonResults;
|
|
50
|
+
special: SpatialSpecialResults;
|
|
51
|
+
}
|
|
52
|
+
interface GonogoResultsStructure {
|
|
53
|
+
common: CommonResults;
|
|
54
|
+
special: GonogoSpecialResults;
|
|
55
|
+
}
|
|
56
|
+
interface EmotionResultsStructure {
|
|
57
|
+
common: CommonResults;
|
|
58
|
+
special: EmotionSpecialResults;
|
|
59
|
+
}
|
|
60
|
+
export { CommonResults, NbackResultsStructure, SpatialResultsStructure, GonogoResultsStructure, EmotionResultsStructure, NbackSpecialResults, SpatialSpecialResults, GonogoSpecialResults, EmotionSpecialResults };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/emotions.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
n: number;
|
|
3
|
-
avg_rt: number;
|
|
4
|
-
avg_acc: number;
|
|
5
|
-
performance: number;
|
|
6
|
-
}
|
|
1
|
+
import { EmotionResultsStructure } from './common-interfaces';
|
|
7
2
|
declare const emotion_calculate_results: (obj: any[]) => EmotionResultsStructure;
|
|
8
|
-
declare const emotion_results: (obj: any[]) => EmotionResultsStructure;
|
|
9
3
|
declare const emotion_extract_trials: (obj: any[]) => any[];
|
|
4
|
+
declare const emotion_results: (obj: any[]) => EmotionResultsStructure;
|
|
10
5
|
export { EmotionResultsStructure, emotion_calculate_results, emotion_extract_trials, emotion_results };
|
package/dist/esm/emotions.js
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
|
+
var EMOTION_MAP = ["neutral", "sad", "happy", "surprised", "angry"];
|
|
1
2
|
var emotion_calculate_results = function (obj) {
|
|
2
3
|
var trials = emotion_extract_trials(obj);
|
|
3
|
-
// throw if trials is empty
|
|
4
4
|
if (trials.length === 0) {
|
|
5
5
|
throw new Error("No trials found");
|
|
6
6
|
}
|
|
7
7
|
return emotion_results(trials);
|
|
8
8
|
};
|
|
9
|
-
var emotion_results = function (obj) {
|
|
10
|
-
// throw error if obj is empty
|
|
11
|
-
if (obj.length === 0) {
|
|
12
|
-
throw new Error("No trials found");
|
|
13
|
-
}
|
|
14
|
-
var results = {
|
|
15
|
-
n: obj.length,
|
|
16
|
-
avg_rt: obj.reduce(function (a, b) { return a + b.rt; }, 0) / obj.length,
|
|
17
|
-
avg_acc: obj.reduce(function (a, b) { return a + b.correct; }, 0) / obj.length,
|
|
18
|
-
performance: NaN
|
|
19
|
-
};
|
|
20
|
-
var best_score = 1000;
|
|
21
|
-
var worst_score = 10000;
|
|
22
|
-
var performance = results.avg_rt / (Math.pow(results.avg_acc, 5) + 0.001);
|
|
23
|
-
performance = Math.min(Math.max(performance, best_score), worst_score);
|
|
24
|
-
results.performance = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
|
|
25
|
-
return results;
|
|
26
|
-
};
|
|
27
9
|
var emotion_extract_trials = function (obj) {
|
|
28
|
-
var emotionMap = ["neutral", "sad", "happy", "surprised", "angry"];
|
|
29
10
|
// filter trials where response and rt are defined and not null
|
|
30
11
|
var trials = obj.filter(function (o) { return 'response' in o && 'rt' in o && 'emotion' in o; });
|
|
31
12
|
trials = trials.filter(function (o) { return o.response !== null && o.rt !== null; });
|
|
@@ -40,10 +21,63 @@ var emotion_extract_trials = function (obj) {
|
|
|
40
21
|
}
|
|
41
22
|
});
|
|
42
23
|
trials.forEach(function (o) {
|
|
43
|
-
o.emotion_response =
|
|
24
|
+
o.emotion_response = EMOTION_MAP[o.response] || "unknown";
|
|
44
25
|
o.correct = o.emotion === o.emotion_response;
|
|
45
26
|
// in the older ones there were 15 trials per rotation
|
|
46
27
|
});
|
|
47
28
|
return trials;
|
|
48
29
|
};
|
|
30
|
+
var emotion_results = function (obj) {
|
|
31
|
+
if (obj.length === 0) {
|
|
32
|
+
throw new Error("No trials found");
|
|
33
|
+
}
|
|
34
|
+
var correct_trials = obj.filter(function (o) { return o.correct === true; });
|
|
35
|
+
var incorrect_trials = obj.filter(function (o) { return o.correct === false; });
|
|
36
|
+
var total_rt = obj.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
37
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
38
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
39
|
+
var avg_rt = total_rt / obj.length;
|
|
40
|
+
var avg_acc = correct_trials.length / obj.length;
|
|
41
|
+
// Calculate performance score using the existing formula
|
|
42
|
+
var best_score = 1000;
|
|
43
|
+
var worst_score = 10000;
|
|
44
|
+
var performance = avg_rt / (Math.pow(avg_acc, 5) + 0.001);
|
|
45
|
+
performance = Math.min(Math.max(performance, best_score), worst_score);
|
|
46
|
+
var performance_score = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
|
|
47
|
+
var common = {
|
|
48
|
+
n_trials: obj.length,
|
|
49
|
+
n_correct_trials: correct_trials.length,
|
|
50
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
51
|
+
avg_rt_total: avg_rt,
|
|
52
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_trials.length : 0,
|
|
53
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_trials.length : 0,
|
|
54
|
+
performance_score: performance_score
|
|
55
|
+
};
|
|
56
|
+
// Group by emotion for special results
|
|
57
|
+
var by_emotion = EMOTION_MAP.map(function (emotion) {
|
|
58
|
+
var emotion_trials = obj.filter(function (o) { return o.emotion === emotion; });
|
|
59
|
+
return {
|
|
60
|
+
emotion: emotion,
|
|
61
|
+
n: emotion_trials.length,
|
|
62
|
+
avg_rt: emotion_trials.length > 0 ? emotion_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / emotion_trials.length : 0,
|
|
63
|
+
avg_acc: emotion_trials.length > 0 ? emotion_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / emotion_trials.length : 0,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
// Create confusion matrix
|
|
67
|
+
var confusion_matrix = EMOTION_MAP.reduce(function (matrix, actual) {
|
|
68
|
+
matrix[actual] = EMOTION_MAP.reduce(function (row, predicted) {
|
|
69
|
+
row[predicted] = obj.filter(function (o) { return o.emotion === actual && o.emotion_response === predicted; }).length;
|
|
70
|
+
return row;
|
|
71
|
+
}, {});
|
|
72
|
+
return matrix;
|
|
73
|
+
}, {});
|
|
74
|
+
var special = {
|
|
75
|
+
by_emotion: by_emotion,
|
|
76
|
+
confusion_matrix: confusion_matrix
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
common: common,
|
|
80
|
+
special: special
|
|
81
|
+
};
|
|
82
|
+
};
|
|
49
83
|
export { emotion_calculate_results, emotion_extract_trials, emotion_results };
|
package/dist/esm/gonogo.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
n: number;
|
|
3
|
-
avg_rt: number;
|
|
4
|
-
avg_acc: number;
|
|
5
|
-
performance: number;
|
|
6
|
-
}
|
|
1
|
+
import { GonogoResultsStructure } from './common-interfaces';
|
|
7
2
|
declare const gonogo_calculate_results: (data: any[]) => GonogoResultsStructure;
|
|
8
3
|
declare const gonogo_extract_trials: (obj: any[]) => any[];
|
|
9
4
|
declare const gonogo_results: (data: any[]) => GonogoResultsStructure;
|
package/dist/esm/gonogo.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var BEST_SCORE = 300;
|
|
2
|
+
var WORST_SCORE = 5000;
|
|
1
3
|
var gonogo_calculate_results = function (data) {
|
|
2
4
|
var trials = gonogo_extract_trials(data);
|
|
3
5
|
var results = gonogo_results(trials);
|
|
@@ -8,9 +10,7 @@ var gonogo_extract_trials = function (obj) {
|
|
|
8
10
|
var trials = obj.filter(function (o) { return 'image' in o && o.image !== undefined; });
|
|
9
11
|
trials.forEach(function (o) {
|
|
10
12
|
// image is in format <stimulus>_trans_<number>.png
|
|
11
|
-
// extract the stimulus and number
|
|
12
13
|
// "image": "https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/gonogo/aliens/astronaut_trans_1.png",
|
|
13
|
-
// i need to extract the iamge name from the url
|
|
14
14
|
var match = o.image.match(/([^/]+)_(\d+)\.png$/);
|
|
15
15
|
if (match) {
|
|
16
16
|
o.stimulus = match[0];
|
|
@@ -34,7 +34,6 @@ var gonogo_extract_trials = function (obj) {
|
|
|
34
34
|
o.should_go = o.stimulus == "rocket_trans_1.png";
|
|
35
35
|
break;
|
|
36
36
|
case 4:
|
|
37
|
-
// should go in all cases where the goal is NOT the rocket
|
|
38
37
|
o.should_go = !(o.stimulus == "rocket_trans_1.png");
|
|
39
38
|
break;
|
|
40
39
|
default:
|
|
@@ -45,22 +44,70 @@ var gonogo_extract_trials = function (obj) {
|
|
|
45
44
|
});
|
|
46
45
|
return trials;
|
|
47
46
|
};
|
|
47
|
+
// TODO this
|
|
48
|
+
var calculate_performance_score = function (avg_rt, avg_acc) {
|
|
49
|
+
var performance = avg_rt / (Math.pow(avg_acc, 5) + 0.001);
|
|
50
|
+
performance = Math.min(Math.max(performance, BEST_SCORE), WORST_SCORE);
|
|
51
|
+
var performance_score = (1 - ((performance - BEST_SCORE) / (WORST_SCORE - BEST_SCORE))) * 100;
|
|
52
|
+
return performance_score;
|
|
53
|
+
};
|
|
48
54
|
var gonogo_results = function (data) {
|
|
49
55
|
// throw error if obj is empty
|
|
50
56
|
if (data.length === 0) {
|
|
51
57
|
throw new Error("No trials found");
|
|
52
58
|
}
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
var correct_trials = data.filter(function (o) { return o.correct === true; });
|
|
60
|
+
var incorrect_trials = data.filter(function (o) { return o.correct === false; });
|
|
61
|
+
var missing_trials = []; // technically not possible in GNG, as no response is just incorrect
|
|
62
|
+
var go_trials = data.filter(function (o) { return o.should_go === true; });
|
|
63
|
+
var nogo_trials = data.filter(function (o) { return o.should_go === false; });
|
|
64
|
+
var total_rt = data.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
65
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
66
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
67
|
+
var responded_trials = data.filter(function (o) { return o.response !== null; });
|
|
68
|
+
var correct_responded_trials = responded_trials.filter(function (o) { return o.correct === true; });
|
|
69
|
+
var incorrect_responded_trials = responded_trials.filter(function (o) { return o.correct === false; });
|
|
70
|
+
var avg_rt = responded_trials.length > 0 ? total_rt / responded_trials.length : 0;
|
|
71
|
+
var avg_acc = correct_trials.length / data.length;
|
|
72
|
+
// Calculate performance score using the existing formula
|
|
73
|
+
var performance_score = calculate_performance_score(avg_rt, avg_acc);
|
|
74
|
+
var common = {
|
|
75
|
+
n_trials: data.length,
|
|
76
|
+
n_correct_trials: correct_trials.length,
|
|
77
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
78
|
+
avg_rt_total: avg_rt,
|
|
79
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_responded_trials.length : 0,
|
|
80
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_responded_trials.length : 0,
|
|
81
|
+
performance_score: performance_score
|
|
82
|
+
};
|
|
83
|
+
// Group by block for special results
|
|
84
|
+
var by_block = Object.values(data.reduce(function (acc, trial) {
|
|
85
|
+
var key = trial.block_number || 'unknown';
|
|
86
|
+
if (!acc[key])
|
|
87
|
+
acc[key] = { block: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
88
|
+
acc[key].trials.push(trial);
|
|
89
|
+
return acc;
|
|
90
|
+
}, {})).map(function (group) {
|
|
91
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
92
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
93
|
+
return group;
|
|
94
|
+
});
|
|
95
|
+
var special = {
|
|
96
|
+
by_block: by_block,
|
|
97
|
+
go_trials: {
|
|
98
|
+
n: go_trials.length,
|
|
99
|
+
avg_rt: go_trials.length > 0 ? go_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / go_trials.length : 0,
|
|
100
|
+
avg_acc: go_trials.length > 0 ? go_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / go_trials.length : 0,
|
|
101
|
+
},
|
|
102
|
+
nogo_trials: {
|
|
103
|
+
n: nogo_trials.length,
|
|
104
|
+
avg_rt: nogo_trials.length > 0 ? nogo_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / nogo_trials.length : 0,
|
|
105
|
+
avg_acc: nogo_trials.length > 0 ? nogo_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / nogo_trials.length : 0,
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
common: common,
|
|
110
|
+
special: special
|
|
58
111
|
};
|
|
59
|
-
var best_score = 300;
|
|
60
|
-
var worst_score = 5000;
|
|
61
|
-
var performance = results.avg_rt / (Math.pow(results.avg_acc, 5) + 0.001);
|
|
62
|
-
performance = Math.min(Math.max(performance, best_score), worst_score);
|
|
63
|
-
results.performance = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
|
|
64
|
-
return results;
|
|
65
112
|
};
|
|
66
113
|
export { gonogo_calculate_results, gonogo_extract_trials, gonogo_results };
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { NbackResultsStructure } from './
|
|
2
|
-
import { SpatialResultsStructure } from './spatial-cognition';
|
|
3
|
-
import { GonogoResultsStructure } from './gonogo';
|
|
4
|
-
import { EmotionResultsStructure } from './emotions';
|
|
1
|
+
import { NbackResultsStructure, SpatialResultsStructure, GonogoResultsStructure, EmotionResultsStructure, CommonResults } from './common-interfaces';
|
|
5
2
|
declare const NbackResults: (obj: any[]) => NbackResultsStructure;
|
|
6
3
|
declare const SpatialCognitionResults: (obj: any[]) => SpatialResultsStructure;
|
|
7
4
|
declare const GonogoResults: (obj: any[]) => GonogoResultsStructure;
|
|
8
5
|
declare const EmotionResults: (obj: any[]) => EmotionResultsStructure;
|
|
9
|
-
export { NbackResults, SpatialCognitionResults, EmotionResults, GonogoResults };
|
|
6
|
+
export { NbackResults, SpatialCognitionResults, EmotionResults, GonogoResults, NbackResultsStructure, SpatialResultsStructure, GonogoResultsStructure, EmotionResultsStructure, CommonResults };
|
package/dist/esm/nback.d.ts
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
|
+
import { NbackResultsStructure } from './common-interfaces';
|
|
1
2
|
declare const nback_calculate_results: (obj: any[]) => NbackResultsStructure;
|
|
2
3
|
declare const nback_extract_trials: (obj: any[]) => any[];
|
|
3
|
-
interface NbackTrialResultsStructure {
|
|
4
|
-
n: number;
|
|
5
|
-
avg_rt: number;
|
|
6
|
-
avg_acc: number;
|
|
7
|
-
}
|
|
8
|
-
interface NbackResultsStructure {
|
|
9
|
-
total_trials: NbackTrialResultsStructure;
|
|
10
|
-
target_trials: NbackTrialResultsStructure;
|
|
11
|
-
non_target_trials: NbackTrialResultsStructure;
|
|
12
|
-
performance: number;
|
|
13
|
-
}
|
|
14
4
|
declare const nback_results: (trials: any[]) => NbackResultsStructure;
|
|
15
5
|
export { nback_extract_trials, nback_results, nback_calculate_results, NbackResultsStructure };
|
package/dist/esm/nback.js
CHANGED
|
@@ -10,25 +10,39 @@ var nback_extract_trials = function (obj) {
|
|
|
10
10
|
var nback_results = function (trials) {
|
|
11
11
|
var target_trials = trials.filter(function (o) { return o.is_target; });
|
|
12
12
|
var non_target_trials = trials.filter(function (o) { return !o.is_target; });
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
var correct_trials = trials.filter(function (o) { return o.correct === true; });
|
|
14
|
+
var incorrect_trials = trials.filter(function (o) { return o.correct === false; });
|
|
15
|
+
var total_rt = trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
16
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
17
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
18
|
+
var responded_trials = trials.filter(function (o) { return o.response !== null; });
|
|
19
|
+
var correct_responded_trials = responded_trials.filter(function (o) { return o.correct === true; });
|
|
20
|
+
var incorrect_responded_trials = responded_trials.filter(function (o) { return o.correct === false; });
|
|
21
|
+
var common = {
|
|
22
|
+
n_trials: trials.length,
|
|
23
|
+
n_correct_trials: correct_trials.length,
|
|
24
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
25
|
+
avg_rt_total: trials.length > 0 ? total_rt / responded_trials.length : 0,
|
|
26
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_responded_trials.length : 0,
|
|
27
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_responded_trials.length : 0,
|
|
28
|
+
performance_score: trials.length > 0 ? correct_trials.length * 100 / trials.length : 0
|
|
29
|
+
};
|
|
30
|
+
var special = {
|
|
19
31
|
target_trials: {
|
|
20
32
|
n: target_trials.length,
|
|
21
|
-
avg_rt: target_trials.reduce(function (a, b) { return a + b.rt; }, 0) / target_trials.length,
|
|
22
|
-
avg_acc: target_trials.reduce(function (a, b) { return a + b.correct; }, 0) / target_trials.length,
|
|
33
|
+
avg_rt: target_trials.length > 0 ? target_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / target_trials.length : 0,
|
|
34
|
+
avg_acc: target_trials.length > 0 ? target_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) * 100 / target_trials.length : 0,
|
|
23
35
|
},
|
|
24
36
|
non_target_trials: {
|
|
25
37
|
n: non_target_trials.length,
|
|
26
|
-
avg_rt: non_target_trials.reduce(function (a, b) { return a + b.rt; }, 0) / non_target_trials.length,
|
|
27
|
-
avg_acc: non_target_trials.reduce(function (a, b) { return a + b.correct; }, 0) / non_target_trials.length,
|
|
28
|
-
}
|
|
29
|
-
|
|
38
|
+
avg_rt: non_target_trials.length > 0 ? non_target_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / non_target_trials.length : 0,
|
|
39
|
+
avg_acc: non_target_trials.length > 0 ? non_target_trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) * 100 / non_target_trials.length : 0,
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var results = {
|
|
43
|
+
common: common,
|
|
44
|
+
special: special
|
|
30
45
|
};
|
|
31
|
-
results.performance = results.total_trials.avg_acc;
|
|
32
46
|
console.log(results);
|
|
33
47
|
return results;
|
|
34
48
|
};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
n: number;
|
|
3
|
-
avg_rt: number;
|
|
4
|
-
avg_acc: number;
|
|
5
|
-
performance: number;
|
|
6
|
-
}
|
|
1
|
+
import { SpatialResultsStructure } from './common-interfaces';
|
|
7
2
|
declare const spatial_calculate_results: (obj: any[]) => SpatialResultsStructure;
|
|
8
3
|
declare const spatial_extract_trials: (obj: any[]) => any[];
|
|
9
4
|
declare const spatial_results: (obj: any[]) => SpatialResultsStructure;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
var BEST_SCORE = 1000;
|
|
2
|
+
var WORST_SCORE = 10000;
|
|
1
3
|
var spatial_calculate_results = function (obj) {
|
|
2
4
|
var trials = spatial_extract_trials(obj);
|
|
3
5
|
return spatial_results(trials);
|
|
4
6
|
};
|
|
7
|
+
var calculate_performance_score = function (avg_rt, avg_acc) {
|
|
8
|
+
var performance = avg_rt / (avg_acc + 0.001);
|
|
9
|
+
performance = Math.min(Math.max(performance, BEST_SCORE), WORST_SCORE);
|
|
10
|
+
var performance_score = (1 - ((performance - BEST_SCORE) / (WORST_SCORE - BEST_SCORE))) * 100;
|
|
11
|
+
return performance_score;
|
|
12
|
+
};
|
|
5
13
|
var spatial_extract_trials = function (obj) {
|
|
6
14
|
var trials = obj.filter(function (o) { return 'stimulus' in o &&
|
|
7
15
|
o.stimulus.startsWith("<img src="); });
|
|
@@ -9,21 +17,68 @@ var spatial_extract_trials = function (obj) {
|
|
|
9
17
|
return trials;
|
|
10
18
|
};
|
|
11
19
|
var spatial_results = function (obj) {
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
var correct_trials = obj.filter(function (o) { return o.correct === 1 || o.correct === true; });
|
|
21
|
+
var incorrect_trials = obj.filter(function (o) { return o.correct === 0 || o.correct === false; });
|
|
22
|
+
var missing_trials = obj.filter(function (o) { return o.response === null || o.response === undefined; });
|
|
23
|
+
var total_rt = obj.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
24
|
+
var correct_rt = correct_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
25
|
+
var incorrect_rt = incorrect_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
26
|
+
var missing_rt = missing_trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0);
|
|
27
|
+
var avg_rt = obj.length > 0 ? total_rt / obj.length : 0;
|
|
28
|
+
var avg_acc = obj.length > 0 ? correct_trials.length / obj.length : 0;
|
|
29
|
+
var performance_score = calculate_performance_score(avg_rt, avg_acc);
|
|
30
|
+
var common = {
|
|
31
|
+
n_trials: obj.length,
|
|
32
|
+
n_correct_trials: correct_trials.length,
|
|
33
|
+
n_incorrect_trials: incorrect_trials.length,
|
|
34
|
+
avg_rt_total: avg_rt,
|
|
35
|
+
avg_rt_correct: correct_trials.length > 0 ? correct_rt / correct_trials.length : 0,
|
|
36
|
+
avg_rt_incorrect: incorrect_trials.length > 0 ? incorrect_rt / incorrect_trials.length : 0,
|
|
37
|
+
performance_score: performance_score
|
|
38
|
+
};
|
|
39
|
+
// Group by distance, angle, and rotation for special results
|
|
40
|
+
var by_distance = Object.values(obj.reduce(function (acc, trial) {
|
|
41
|
+
var key = trial.distance || 'unknown';
|
|
42
|
+
if (!acc[key])
|
|
43
|
+
acc[key] = { distance: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
44
|
+
acc[key].trials.push(trial);
|
|
45
|
+
return acc;
|
|
46
|
+
}, {})).map(function (group) {
|
|
47
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
48
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
49
|
+
return group;
|
|
50
|
+
});
|
|
51
|
+
var by_angle = Object.values(obj.reduce(function (acc, trial) {
|
|
52
|
+
var key = trial.angle || 'unknown';
|
|
53
|
+
if (!acc[key])
|
|
54
|
+
acc[key] = { angle: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
55
|
+
acc[key].trials.push(trial);
|
|
56
|
+
return acc;
|
|
57
|
+
}, {})).map(function (group) {
|
|
58
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
59
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
60
|
+
return group;
|
|
61
|
+
});
|
|
62
|
+
var by_rotation = Object.values(obj.reduce(function (acc, trial) {
|
|
63
|
+
var key = trial.rotation || 'unknown';
|
|
64
|
+
if (!acc[key])
|
|
65
|
+
acc[key] = { rotation: key, trials: [], avg_rt: 0, avg_acc: 0 };
|
|
66
|
+
acc[key].trials.push(trial);
|
|
67
|
+
return acc;
|
|
68
|
+
}, {})).map(function (group) {
|
|
69
|
+
group.avg_rt = group.trials.reduce(function (a, b) { return a + (b.rt || 0); }, 0) / group.trials.length;
|
|
70
|
+
group.avg_acc = group.trials.reduce(function (a, b) { return a + (b.correct ? 1 : 0); }, 0) / group.trials.length;
|
|
71
|
+
return group;
|
|
72
|
+
});
|
|
73
|
+
var special = {
|
|
74
|
+
by_distance: by_distance,
|
|
75
|
+
by_angle: by_angle,
|
|
76
|
+
by_rotation: by_rotation
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
common: common,
|
|
80
|
+
special: special
|
|
17
81
|
};
|
|
18
|
-
var best_score = 1000;
|
|
19
|
-
var worst_score = 10000;
|
|
20
|
-
// results.avg_acc to the power of 5
|
|
21
|
-
//let performance = results.avg_rt / (Math.pow(results.avg_acc, 5) + 0.001);
|
|
22
|
-
var performance = results.avg_rt / (results.avg_acc + 0.001);
|
|
23
|
-
performance = Math.min(Math.max(performance, best_score), worst_score);
|
|
24
|
-
// convert to 0-100 where 100 is the best (200)
|
|
25
|
-
results.performance = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
|
|
26
|
-
return results;
|
|
27
82
|
};
|
|
28
83
|
var spatial_extract_image_info = function (obj) {
|
|
29
84
|
// from the following field, extract the final image name (map_left_1_90.png), and rotation from the class attribute (rotate_0)
|