compileprofile-spacetests 0.1.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.
Files changed (45) hide show
  1. package/README.md +35 -0
  2. package/dist/cjs/getters.d.ts +2 -0
  3. package/dist/cjs/getters.js +22 -0
  4. package/dist/cjs/gonogo.d.ts +3 -0
  5. package/dist/cjs/gonogo.js +30 -0
  6. package/dist/cjs/index.d.ts +5 -0
  7. package/dist/cjs/index.js +13 -0
  8. package/dist/cjs/nback.d.ts +15 -0
  9. package/dist/cjs/nback.js +40 -0
  10. package/dist/cjs/spatial-cognition.d.ts +11 -0
  11. package/dist/cjs/spatial-cognition.js +54 -0
  12. package/dist/esm/getters.d.ts +2 -0
  13. package/dist/esm/getters.js +20 -0
  14. package/dist/esm/gonogo.d.ts +3 -0
  15. package/dist/esm/gonogo.js +30 -0
  16. package/dist/esm/index.d.ts +5 -0
  17. package/dist/esm/index.js +9 -0
  18. package/dist/esm/nback.d.ts +15 -0
  19. package/dist/esm/nback.js +35 -0
  20. package/dist/esm/spatial-cognition.d.ts +11 -0
  21. package/dist/esm/spatial-cognition.js +48 -0
  22. package/example-data/emotions.json +808 -0
  23. package/example-data/gonogo.json +5393 -0
  24. package/example-data/nback.json +893 -0
  25. package/example-data/participant.json +7 -0
  26. package/example-data/spatial-cognition.json +463 -0
  27. package/jest.config.js +14 -0
  28. package/original/emotion-recognition.R +39 -0
  29. package/original/gonogo.R +32 -0
  30. package/package.json +40 -0
  31. package/src/__tests__/integration/browserInfo.test.ts +17 -0
  32. package/src/__tests__/integration/nback.test.ts +56 -0
  33. package/src/__tests__/integration/spatial-cognition.test.ts +59 -0
  34. package/src/__tests__/test-utils/testData.ts +80 -0
  35. package/src/getters.ts +21 -0
  36. package/src/gonogo.ts +37 -0
  37. package/src/index.ts +12 -0
  38. package/src/nback.ts +53 -0
  39. package/src/norms/emotions.json +0 -0
  40. package/src/norms/gonogo.json +0 -0
  41. package/src/norms/nback.json +0 -0
  42. package/src/norms/spatial-cognition.json +0 -0
  43. package/src/spatial-cognition.ts +59 -0
  44. package/tsconfig.cjs.json +13 -0
  45. package/tsconfig.esm.json +15 -0
@@ -0,0 +1,56 @@
1
+ import { nback_extract_trials, nback_results,
2
+ nback_calculate_results, NBackResults } from '../../nback';
3
+ import { loadTestData } from '../test-utils/testData';
4
+
5
+ describe('N-Back Task Integration Tests', () => {
6
+ const testData = loadTestData('nback');
7
+
8
+ describe('nback_extract_trials', () => {
9
+ it('should extract only trials with is_target field', () => {
10
+ const trials = nback_extract_trials(testData.nback);
11
+ expect(trials.every(trial => trial.is_target !== null)).toBe(true);
12
+ expect(trials.length).toBe(60);
13
+ });
14
+ });
15
+
16
+ describe('nback_results', () => {
17
+ const trials = nback_extract_trials(testData.nback);
18
+ const results = nback_results(trials);
19
+
20
+ it('should calculate correct total trials metrics', () => {
21
+ expect(results.total_trials).toHaveProperty('n');
22
+ expect(results.total_trials).toHaveProperty('avg_rt');
23
+ expect(results.total_trials).toHaveProperty('avg_acc');
24
+ expect(results.total_trials.n).toBeGreaterThan(0);
25
+ });
26
+
27
+ it('should calculate correct target trials metrics', () => {
28
+ expect(results.target_trials).toHaveProperty('n');
29
+ expect(results.target_trials).toHaveProperty('avg_rt');
30
+ expect(results.target_trials).toHaveProperty('avg_acc');
31
+ expect(results.target_trials.n).toBeGreaterThan(0);
32
+ });
33
+
34
+ it('should calculate correct non-target trials metrics', () => {
35
+ expect(results.non_target_trials).toHaveProperty('n');
36
+ expect(results.non_target_trials).toHaveProperty('avg_rt');
37
+ expect(results.non_target_trials).toHaveProperty('avg_acc');
38
+ expect(results.non_target_trials.n).toBeGreaterThan(0);
39
+ });
40
+
41
+ it('should calculate performance score', () => {
42
+ expect(results.performance).not.toBeNaN();
43
+ expect(results.performance).toBeGreaterThanOrEqual(0);
44
+ expect(results.performance).toBeLessThanOrEqual(1);
45
+ });
46
+ });
47
+
48
+ describe('nback_calculate_results', () => {
49
+ it('should calculate results correctly', () => {
50
+ const results = nback_calculate_results(testData.nback);
51
+ expect(results).toBeDefined();
52
+ // Check that results matches NBackResults type structure
53
+ //expect results to have the same structure as NBackResults
54
+ });
55
+ });
56
+ });
@@ -0,0 +1,59 @@
1
+ // test out the spatial_extract_image_info function
2
+ import { spatial_extract_image_info, spatial_results } from '../../spatial-cognition';
3
+ import { loadTestData } from '../test-utils/testData';
4
+
5
+ const ImageInfoTestData = [
6
+ {
7
+ stimulus: "<img src=\"https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/spatialcognition/map_left_1_90.png\" class=\"max-w-none rotate_90\" width=\"512\" height=\"512\" alt=\"Mapa\">",
8
+ rt: 1411,
9
+ response: 0,
10
+ plugin_version: "2.0.0",
11
+ time_elapsed: 73045,
12
+ attempted: false
13
+ },
14
+ {
15
+ stimulus: "<img src=\"https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/spatialcognition/map_left_3_180.png\" class=\"max-w-none rotate_270\" width=\"512\" height=\"512\" alt=\"Mapa\">",
16
+ rt: 1411,
17
+ response: 1,
18
+ plugin_version: "2.0.0",
19
+ time_elapsed: 73045,
20
+ }
21
+ ];
22
+
23
+ describe('spatial_extract_image_info test data', () => {
24
+ test('processes test data correctly', () => {
25
+ const resultsTestData = spatial_extract_image_info(ImageInfoTestData);
26
+ expect(resultsTestData.length).toBe(2);
27
+
28
+ expect(resultsTestData[0].image).toBe('map_left_1_90.png');
29
+ expect(resultsTestData[0].direction).toBe('left');
30
+ expect(resultsTestData[0].distance).toBe('1');
31
+ expect(resultsTestData[0].angle).toBe('90');
32
+ expect(resultsTestData[0].rotation).toBe('90');
33
+ expect(resultsTestData[0].response).toBe('left');
34
+ expect(resultsTestData[0].correct).toBe(true);
35
+
36
+ expect(resultsTestData[1].image).toBe('map_left_3_180.png');
37
+ expect(resultsTestData[1].direction).toBe('left');
38
+ expect(resultsTestData[1].distance).toBe('3');
39
+ expect(resultsTestData[1].angle).toBe('180');
40
+ expect(resultsTestData[1].rotation).toBe('270');
41
+ expect(resultsTestData[1].response).toBe('right');
42
+ expect(resultsTestData[1].correct).toBe(false);
43
+ });
44
+
45
+ test('processes real data correctly', () => {
46
+ const testData = loadTestData('spatial-cognition');
47
+ const resultData = spatial_extract_image_info(testData.spatialCognition);
48
+ expect(resultData).toBeDefined();
49
+ });
50
+ });
51
+
52
+ describe('spatial_results test data', () => {
53
+ test('processes test data correctly', () => {
54
+ const resultsTestData = spatial_results(ImageInfoTestData);
55
+ console.log(resultsTestData);
56
+ expect(resultsTestData).toBeDefined();
57
+ });
58
+ });
59
+
@@ -0,0 +1,80 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // Define interfaces for our test data types
5
+ export interface TestDataFiles {
6
+ spatialCognition: any[];
7
+ nback: any[];
8
+ participant: any[];
9
+ gonogo: any[];
10
+ emotions: any[];
11
+ }
12
+
13
+ // Function to load all test data
14
+ export function loadTestData(type: string): TestDataFiles {
15
+ const dataDir = path.join(process.cwd(), 'example-data');
16
+
17
+ if (type === 'spatialCognition') {
18
+ return {
19
+ spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
20
+ nback: [],
21
+ participant: [],
22
+ gonogo: [],
23
+ emotions: []
24
+ };
25
+ }
26
+ if (type === 'nback') {
27
+ return {
28
+ spatialCognition: [],
29
+ nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
30
+ participant: [],
31
+ gonogo: [],
32
+ emotions: []
33
+ };
34
+ }
35
+ if (type === 'participant') {
36
+ return {
37
+ spatialCognition: [],
38
+ nback: [],
39
+ participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
40
+ gonogo: [],
41
+ emotions: []
42
+ };
43
+ }
44
+ if (type === 'gonogo') {
45
+ return {
46
+ spatialCognition: [],
47
+ nback: [],
48
+ participant: [],
49
+ gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
50
+ emotions: []
51
+ };
52
+ }
53
+ if (type === 'emotions') {
54
+ return {
55
+ spatialCognition: [],
56
+ nback: [],
57
+ participant: [],
58
+ gonogo: [],
59
+ emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
60
+ };
61
+ }
62
+ if (type === 'all') {
63
+ return {
64
+ spatialCognition: JSON.parse(fs.readFileSync(path.join(dataDir, 'spatial-cognition.json'), 'utf-8')),
65
+ nback: JSON.parse(fs.readFileSync(path.join(dataDir, 'nback.json'), 'utf-8')),
66
+ participant: JSON.parse(fs.readFileSync(path.join(dataDir, 'participant.json'), 'utf-8')),
67
+ gonogo: JSON.parse(fs.readFileSync(path.join(dataDir, 'gonogo.json'), 'utf-8')),
68
+ emotions: JSON.parse(fs.readFileSync(path.join(dataDir, 'emotions.json'), 'utf-8'))
69
+ };
70
+ }
71
+
72
+ // Default return for unknown types
73
+ return {
74
+ spatialCognition: [],
75
+ nback: [],
76
+ participant: [],
77
+ gonogo: [],
78
+ emotions: []
79
+ };
80
+ }
package/src/getters.ts ADDED
@@ -0,0 +1,21 @@
1
+ function getBrowserInformation(data: any[]): any {
2
+ const browserInfo = data.find(row => row.trial_type === "browser-check");
3
+ if (!browserInfo) {
4
+ return null;
5
+ }
6
+ return {
7
+ os: browserInfo.os,
8
+ mobile: browserInfo.mobile,
9
+ fullscreen: browserInfo.fullscreen,
10
+ vsync_rate: browserInfo.vsync_rate,
11
+ webcam: browserInfo.webcam,
12
+ microphone: browserInfo.microphone,
13
+ browser: browserInfo.browser,
14
+ browser_version: browserInfo.browser_version,
15
+ webaudio: browserInfo.webaudio,
16
+ width: browserInfo.width,
17
+ height: browserInfo.height
18
+ };
19
+ }
20
+
21
+ export { getBrowserInformation };
package/src/gonogo.ts ADDED
@@ -0,0 +1,37 @@
1
+ // gonogo_create_trial_table <- function(txt) {
2
+ // arr <- fromJSON(txt)
3
+ // df <- as.data.frame(fromJSON(arr[[1]]))
4
+ // GONOGO_IMAGE_PATH <- "https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/gonogo/"
5
+ // df <- filter(df, !is.na(image))
6
+ // df <- select(df, trial_index, time_elapsed, rt,
7
+ // response, block_number, image)
8
+ // df$image <- gsub(GONOGO_IMAGE_PATH, "", df$image)
9
+ // df$image <- gsub(".png", "", df$image)
10
+ // df <- df %>%
11
+ // mutate(
12
+ // should_go = case_when(
13
+ // block_number == 1 & grepl("astronaut_trans_1", image) ~ TRUE,
14
+ // block_number == 2 & grepl("alien_trans_1", image) ~ TRUE,
15
+ // block_number == 3 & grepl("rocket_trans_1", image) ~ TRUE,
16
+ // block_number == 4 & !grepl("rocket_trans_1", image) ~ TRUE,
17
+ // TRUE ~ FALSE),
18
+ // did_go = !is.na(response),
19
+ // correct = should_go == did_go
20
+ // )
21
+ // return(df)
22
+ // }
23
+
24
+ const gonogo_calculate_results = (data: any) => {
25
+
26
+ }
27
+
28
+ const gonogo_extract_trials = (data: any) => {
29
+
30
+ // GONOGO_IMAGE_PATH <- "https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/gonogo/"
31
+
32
+ }
33
+
34
+
35
+ const gonogo_results = (data: any) => {
36
+
37
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { NBackResults, nback_calculate_results } from './nback';
2
+ import { spatial_calculate_results, SpatialResults } from './spatial-cognition';
3
+
4
+ const NbackResults = (obj: any[]): NBackResults => {
5
+ return nback_calculate_results(obj);
6
+ }
7
+
8
+ const SpatialCognitionResults = (obj: any[]): SpatialResults => {
9
+ return spatial_calculate_results(obj);
10
+ }
11
+
12
+ export { NbackResults, SpatialCognitionResults };
package/src/nback.ts ADDED
@@ -0,0 +1,53 @@
1
+ // from the passed json extract those objects that have field is_target
2
+ const nback_calculate_results = (obj: any[]): NBackResults => {
3
+ const trials = nback_extract_trials(obj);
4
+ return nback_results(trials);
5
+ }
6
+
7
+ const nback_extract_trials = (obj: any[]): any[] => {
8
+ const trials = obj.filter((o: any) => 'is_target' in o);
9
+ return trials;
10
+ }
11
+
12
+ interface NbackTrialResults {
13
+ n: number;
14
+ avg_rt: number;
15
+ avg_acc: number;
16
+ }
17
+
18
+ interface NBackResults {
19
+ total_trials: NbackTrialResults;
20
+ target_trials: NbackTrialResults;
21
+ non_target_trials: NbackTrialResults;
22
+ performance: number;
23
+ }
24
+
25
+ const nback_results = (trials: any[]): NBackResults => {
26
+ const target_trials = trials.filter((o: any) => o.is_target);
27
+ const non_target_trials = trials.filter((o: any) => !o.is_target);
28
+
29
+ let results = {
30
+ total_trials: {
31
+ n: trials.length,
32
+ avg_rt: trials.reduce((a, b) => a + b.rt, 0)/trials.length,
33
+ avg_acc: trials.reduce((a, b) => a + b.correct, 0)/trials.length,
34
+ },
35
+ target_trials: {
36
+ n: target_trials.length,
37
+ avg_rt: target_trials.reduce((a, b) => a + b.rt, 0)/target_trials.length,
38
+ avg_acc: target_trials.reduce((a, b) => a + b.correct, 0)/target_trials.length,
39
+ },
40
+ non_target_trials: {
41
+ n: non_target_trials.length,
42
+ avg_rt: non_target_trials.reduce((a, b) => a + b.rt, 0)/non_target_trials.length,
43
+ avg_acc: non_target_trials.reduce((a, b) => a + b.correct, 0)/non_target_trials.length,
44
+ },
45
+ performance: NaN
46
+ }
47
+ results.performance = results.total_trials.avg_acc;
48
+ console.log(results);
49
+ return results;
50
+ }
51
+
52
+ export { nback_extract_trials, nback_results,
53
+ nback_calculate_results, NBackResults };
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,59 @@
1
+ interface SpatialResults {
2
+ n: number;
3
+ avg_rt: number;
4
+ avg_acc: number;
5
+ performance: number;
6
+ }
7
+
8
+ const spatial_calculate_results = (obj: any[]): SpatialResults => {
9
+ const trials = spatial_extract_trials(obj);
10
+ return spatial_results(trials);
11
+ }
12
+
13
+ const spatial_extract_trials = (obj: any[]) => {
14
+ let trials = obj.filter((o: any) => 'stimulus' in o &&
15
+ o.stimulus.startsWith("<img src="));
16
+ trials = spatial_extract_image_info(trials);
17
+ return trials;
18
+ }
19
+
20
+ const spatial_results = (obj: any[]): SpatialResults => {
21
+ const results = {
22
+ n: obj.length,
23
+ avg_rt: obj.reduce((a, b) => a + b.rt, 0) / obj.length,
24
+ avg_acc: obj.reduce((a, b) => a + b.correct, 0) / obj.length,
25
+ performance: NaN
26
+ }
27
+ const best_score = 1000;
28
+ const worst_score = 10000;
29
+ // results.avg_acc to the power of 5
30
+ let performance = results.avg_rt / (Math.pow(results.avg_acc, 5) + 0.001);
31
+ if (performance < best_score) {
32
+ performance = best_score;
33
+ }
34
+ if (performance > worst_score) {
35
+ performance = worst_score;
36
+ }
37
+ // convert to 0-100 where 100 is the best (200)
38
+ results.performance = (1 - ((performance - best_score) / (worst_score - best_score))) * 100;
39
+ return results;
40
+ }
41
+
42
+ const spatial_extract_image_info = (obj: any[]) => {
43
+ // from the following field, extract the final image name (map_left_1_90.png), and rotation from the class attribute (rotate_0)
44
+ // "stimulus": "<img src=\"https://unyavwofnmwihnpvkjji.supabase.co/storage/v1/object/public/test-stimuli/spatialcognition/map_left_1_90.png\" class=\"max-w-none rotate_0\" width=\"512\" height=\"512\" alt=\"Mapa\">",
45
+ obj.forEach((o: any) => {
46
+ // the image name is map_left_1_90.png
47
+ o.image = o.stimulus.match(/map_(left|right)_(\d+)_(\d+)\.png/)?.[0];
48
+ o.direction = o.stimulus.match(/map_(left|right)_(\d+)_(\d+)\.png/)?.[1];
49
+ o.distance = o.stimulus.match(/map_(left|right)_(\d+)_(\d+)\.png/)?.[2];
50
+ o.angle = o.stimulus.match(/map_(left|right)_(\d+)_(\d+)\.png/)?.[3];
51
+ o.rotation = o.stimulus.match(/rotate_(\d+)/)?.[1];
52
+ o.response = o.response === 1 ? "right" : "left";
53
+ o.correct = o.response === o.direction;
54
+ });
55
+ return obj;
56
+ }
57
+
58
+ export { spatial_extract_image_info, spatial_extract_trials,
59
+ spatial_results, spatial_calculate_results, SpatialResults };
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "declaration": true,
5
+ "outDir": "./dist/cjs",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true
10
+ },
11
+ "include": ["src"],
12
+ "exclude": ["node_modules", "**/__tests__/*"]
13
+ }
@@ -0,0 +1,15 @@
1
+ // tsconfig.esm.json - For ES modules
2
+ {
3
+ "compilerOptions": {
4
+ "module": "esnext",
5
+ "declaration": true,
6
+ "outDir": "./dist/esm",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "moduleResolution": "node",
11
+ "forceConsistentCasingInFileNames": true
12
+ },
13
+ "include": ["src"],
14
+ "exclude": ["node_modules", "**/__tests__/*"]
15
+ }