From 3f9f95387ad2a75ab4e9bc69a33bdaa1908ad1ad Mon Sep 17 00:00:00 2001 From: Chu Yi Chang <79338042+cchang-vassar@users.noreply.github.com> Date: Thu, 8 Aug 2024 17:12:13 -0400 Subject: [PATCH 1/4] separate plugins and extensions in README --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5484d616..eed19205 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,16 @@ However we would encourage contributors to respond to issues/questions and to ma Contributions to `jspsych-contrib` that are broadly useful, well-documented, and well-tested may be added to the main `jsPsych` repository, with the contributor's permission. -## List of available plugins/extensions +## List of available plugins -The jsPsych plugins/extensions that have been contributed by community members can be found in the `/packages` directory. +The jsPsych plugins that have been contributed by community members can be found in the `/packages` directory. The `/packages` directory also contains four template sub-folders that can be used as a starting point for contributing a plugin/extension (see the [Guidelines for contributions](#guidelines-for-contributions) section). -Plugin/Extension | Contributor | Description +Plugin | Contributor | Description ----------- | ----------- | ----------- [audio-multi-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-audio-multi-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an audio file using both button clicks and key presses. [audio-swipe-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-audio-swipe-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an audio file using swipe gestures and keyboard responses. [corsi-blocks](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-corsi-blocks/README.md) | [Josh de Leeuw](https://github.com/jodeleeuw) | This plugin displays a configurable Corsi blocks task and records a series of click responses. -[countdown](https://github.com/jspsych/jspsych-contrib/blob/main/packages/extension-countdown/README.md) | [Shaobin Jiang](https://github.com/Shaobin-Jiang) | This extension adds a countdown during a trial. [gamepad](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-gamepad/README.md) | [Shaobin Jiang](https://github.com/Shaobin-Jiang) | This plugin allows one to use gamepads in a jsPsych experiment. [html-choice](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-html-choice/README.md) | [Younes Strittmatter](https://github.com/younesStrittmatter) | This plugin displays clickable html elements that can be used to present a choice. [html-keyboard-response-raf](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-html-keyboard-response-raf/README.md) | [Josh de Leeuw](https://github.com/jodeleeuw) | This plugin displays an arbitrary HTML string and collects responses using the keyboard. It uses requestAnimationFrame for timing. @@ -36,7 +35,6 @@ Plugin/Extension | Contributor | Description [image-swipe-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-image-swipe-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an image stimulus using swipe gestures and keyboard responses. [ios](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-ios/README.md) | [Isaac Kinley](https://github.com/kinleyid) | This plugin implements a continuous version of the Inclusion of Other in the Self (IOS) Scale ([Aron et al., 1992](https://doi.org/10.1037/0022-3514.63.4.596)). [libet-intentional-blinding](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-libet-intentional-binding/README.md) | [Isaac Kinley](https://github.com/kinleyid) | This plugin measures intentional binding using a Libet clock, and allows the participant to estimate the timing of events by adjusting the clock hand themselves. -[mediapipe-face-mesh](https://github.com/jspsych/jspsych-contrib/blob/main/packages/extension-mediapipe-face-mesh/README.md) | [Martin Grewe](https://github.com/mgrewe) | This extension provides online tracking of facial posture during trials using the [MediaPipe Face Mesh](https://google.github.io/mediapipe/solutions/face_mesh) library. [nextcloud-filedrop](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-nextcloud-filedrop/README.md) | [Martin Grewe](https://github.com/mgrewe) | This plugin provides permanent storage of data collected during an experiment using a nextcloud instance. [pipe](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-pipe/readme.md) | [Josh de Leeuw](https://github.com/jodeleeuw) | This plugin facilitates communication with the DataPipe service (https://pipe.jspsych.org) for sending data to the OSF. [rdk](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-rdk/docs/jspsych-rdk.md#jspsych-rdk-plugin) | [Sivananda Rajananda](https://github.com/vrsivananda) | This plugin displays a Random Dot Kinematogram (RDK) and allows the subject to report the primary direction of motion by pressing a key on the keyboard. @@ -47,6 +45,16 @@ Plugin/Extension | Contributor | Description [vsl-animate-occlusion](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-vsl-animate-occlusion/docs/jspsych-vsl-animate-occlusion.md#jspsych-vsl-animate-occlusion-plugin) | [Josh de Leeuw](https://github.com/jodeleeuw) | The VSL (visual statistical learning) animate occlusion plugin displays an animated sequence of shapes that disappear behind an occluding rectangle while they change from one shape to another. [vsl-grid-scene](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-vsl-grid-scene/docs/jspsych-vsl-grid-scene.md#jspsych-vsl-grid-scene-plugin) | [Josh de Leeuw](https://github.com/jodeleeuw) | The VSL (visual statistical learning) grid scene plugin displays images arranged in a grid. +## List of available extensions + +The jsPsych extensions that have been contributed by community members can be found in the `/packages` directory. +The `/packages` directory also contains four template sub-folders that can be used as a starting point for contributing a plugin/extension (see the [Guidelines for contributions](#guidelines-for-contributions) section). + +Extension | Contributor | Description +----------- | ----------- | ----------- +[countdown](https://github.com/jspsych/jspsych-contrib/blob/main/packages/extension-countdown/README.md) | [Shaobin Jiang](https://github.com/Shaobin-Jiang) | This extension adds a countdown during a trial. +[mediapipe-face-mesh](https://github.com/jspsych/jspsych-contrib/blob/main/packages/extension-mediapipe-face-mesh/README.md) | [Martin Grewe](https://github.com/mgrewe) | This extension provides online tracking of facial posture during trials using the [MediaPipe Face Mesh](https://google.github.io/mediapipe/solutions/face_mesh) library. + ## Guidelines for contributions Contributions to this repository must: From 3462071a8162dcf5e348f59c7bb8d06c222f0d08 Mon Sep 17 00:00:00 2001 From: Josh de Leeuw Date: Fri, 9 Aug 2024 11:38:35 -0400 Subject: [PATCH 2/4] updates to data structure and simulation, remove test that cannot run without mock video element --- .changeset/young-pumpkins-argue.md | 5 +++ .../src/index.spec.ts | 15 +++++-- .../src/index.ts | 39 +++++++++++++------ 3 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 .changeset/young-pumpkins-argue.md diff --git a/.changeset/young-pumpkins-argue.md b/.changeset/young-pumpkins-argue.md new file mode 100644 index 00000000..f28ad5a9 --- /dev/null +++ b/.changeset/young-pumpkins-argue.md @@ -0,0 +1,5 @@ +--- +"@jspsych-contrib/plugin-video-several-keyboard-responses": major +--- + +Make data `rt` `key` and `video_time` fields always be an array, even when multiple responses are not allowed. Improve compatibility of simulation mode, though there are still some likely inconsistencies. diff --git a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts index e270ff9d..2e35e597 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts @@ -40,12 +40,17 @@ describe("video-several-keyboard-responses simulation", () => { await expectFinished(); - expect(getData().values()[0].rt).toBeGreaterThan(0); - expect(typeof getData().values()[0].response).toBe("string"); + const data = getData().values()[0]; + + console.log(data); + + expect(data.rt.every((value) => value > 0)).toBe(true); + expect(data.response.length).toEqual(data.rt.length); + expect(data.video_time.length).toEqual(data.rt.length); }); // can't run this until we mock video elements. - test("visual mode works", async () => { + test.skip("visual mode works", async () => { const jsPsych = initJsPsych(); const timeline = [ @@ -53,7 +58,8 @@ describe("video-several-keyboard-responses simulation", () => { type: videoSeveralKeyboardResponses, stimulus: ["foo.mp4"], prompt: "foo", - trial_duration: 1000, + trial_ends_after_video: true, + response_ends_trial: false, }, ]; @@ -78,5 +84,6 @@ describe("video-several-keyboard-responses simulation", () => { expect(rt.every((value) => value > 0)).toBe(true); expect(response.every((value) => typeof value === "string")).toBe(true); expect(video_time.every((value) => typeof value === "number")).toBe(true); + expect(response.length).toEqual(rt.length); }); }); diff --git a/packages/plugin-video-several-keyboard-responses/src/index.ts b/packages/plugin-video-several-keyboard-responses/src/index.ts index c8f4f32b..6f53c67d 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.ts @@ -295,14 +295,8 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { "#jspsych-video-several-keyboard-responses-stimulus" ).className += " responded"; - // by default only record the first response if (response.key == null) { - if (!trial.multiple_responses_allowed) { - // Would make sense to add it to a list, but then it would not be backwards compatible? - response = { rt: info.rt, key: info.key, video_time: video_element.currentTime }; - } else { - response = { rt: [info.rt], key: [info.key], video_time: [video_element.currentTime] }; - } + response = { rt: [info.rt], key: [info.key], video_time: [video_element.currentTime] }; } else if (trial.multiple_responses_allowed) { response.rt.push(info.rt); response.key.push(info.key); @@ -366,7 +360,9 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { const respond = () => { if (data.rt !== null) { - this.jsPsych.pluginAPI.pressKey(data.response, data.rt); + for (let i = 0; i < data.rt.length; i++) { + this.jsPsych.pluginAPI.pressKey(data.response[i], data.rt[i]); + } } }; @@ -378,16 +374,35 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { } private create_simulation_data(trial: TrialType, simulation_options) { + let n_responses = this.jsPsych.randomization.randomInt(1, 5); + if (!trial.multiple_responses_allowed) { + n_responses = 1; + } + + const rts = []; + const responses = []; + let last_rt = 0; + for (let i = 0; i < n_responses; i++) { + const rt = Math.round(this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true)); + rts.push(rt + last_rt); + last_rt = rt; + responses.push(this.jsPsych.pluginAPI.getValidKey(trial.choices)); + } + + console.log(rts); + const default_data = { stimulus: trial.stimulus, - rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true), - response: this.jsPsych.pluginAPI.getValidKey(trial.choices), - video_time: 0, + response: responses, + rt: rts, + video_time: rts, }; const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options); - this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data); + //this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data); + + console.log(data); return data; } From 382f07594e073be70e7c6b281f7ec95d70e73c82 Mon Sep 17 00:00:00 2001 From: Josh de Leeuw Date: Fri, 9 Aug 2024 11:44:07 -0400 Subject: [PATCH 3/4] remove console.log statements --- .../plugin-video-several-keyboard-responses/src/index.spec.ts | 2 -- packages/plugin-video-several-keyboard-responses/src/index.ts | 4 ---- 2 files changed, 6 deletions(-) diff --git a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts index 2e35e597..580113f7 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts @@ -42,8 +42,6 @@ describe("video-several-keyboard-responses simulation", () => { const data = getData().values()[0]; - console.log(data); - expect(data.rt.every((value) => value > 0)).toBe(true); expect(data.response.length).toEqual(data.rt.length); expect(data.video_time.length).toEqual(data.rt.length); diff --git a/packages/plugin-video-several-keyboard-responses/src/index.ts b/packages/plugin-video-several-keyboard-responses/src/index.ts index 6f53c67d..6549e2e3 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.ts @@ -389,8 +389,6 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { responses.push(this.jsPsych.pluginAPI.getValidKey(trial.choices)); } - console.log(rts); - const default_data = { stimulus: trial.stimulus, response: responses, @@ -402,8 +400,6 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { //this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data); - console.log(data); - return data; } } From 7c22c65e6b6281a351b7771e0c909a88b8edee15 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 9 Aug 2024 15:45:37 +0000 Subject: [PATCH 4/4] chore(release): version packages --- .changeset/young-pumpkins-argue.md | 5 ----- package-lock.json | 2 +- .../plugin-video-several-keyboard-responses/CHANGELOG.md | 6 ++++++ packages/plugin-video-several-keyboard-responses/README.md | 2 +- .../plugin-video-several-keyboard-responses/package.json | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) delete mode 100644 .changeset/young-pumpkins-argue.md diff --git a/.changeset/young-pumpkins-argue.md b/.changeset/young-pumpkins-argue.md deleted file mode 100644 index f28ad5a9..00000000 --- a/.changeset/young-pumpkins-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@jspsych-contrib/plugin-video-several-keyboard-responses": major ---- - -Make data `rt` `key` and `video_time` fields always be an array, even when multiple responses are not allowed. Improve compatibility of simulation mode, though there are still some likely inconsistencies. diff --git a/package-lock.json b/package-lock.json index d4259ceb..0cfe97e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18530,7 +18530,7 @@ }, "packages/plugin-video-several-keyboard-responses": { "name": "@jspsych-contrib/plugin-video-several-keyboard-responses", - "version": "1.0.0", + "version": "2.0.0", "license": "MIT", "devDependencies": { "@jspsych/config": "^2.0.0", diff --git a/packages/plugin-video-several-keyboard-responses/CHANGELOG.md b/packages/plugin-video-several-keyboard-responses/CHANGELOG.md index f5736774..bef411eb 100644 --- a/packages/plugin-video-several-keyboard-responses/CHANGELOG.md +++ b/packages/plugin-video-several-keyboard-responses/CHANGELOG.md @@ -1,5 +1,11 @@ # @jspsych-contrib/plugin-video-several-keyboard-responses +## 2.0.0 + +### Major Changes + +- [#130](https://github.com/jspsych/jspsych-contrib/pull/130) [`3462071a8162dcf5e348f59c7bb8d06c222f0d08`](https://github.com/jspsych/jspsych-contrib/commit/3462071a8162dcf5e348f59c7bb8d06c222f0d08) Thanks [@jodeleeuw](https://github.com/jodeleeuw)! - Make data `rt` `key` and `video_time` fields always be an array, even when multiple responses are not allowed. Improve compatibility of simulation mode, though there are still some likely inconsistencies. + ## 1.0.0 ### Major Changes diff --git a/packages/plugin-video-several-keyboard-responses/README.md b/packages/plugin-video-several-keyboard-responses/README.md index 37d2bb9a..95eb8135 100644 --- a/packages/plugin-video-several-keyboard-responses/README.md +++ b/packages/plugin-video-several-keyboard-responses/README.md @@ -9,7 +9,7 @@ This plugin plays a video and records responses generated by the keyboard, based ### In browser ```js - + ``` ### Via NPM diff --git a/packages/plugin-video-several-keyboard-responses/package.json b/packages/plugin-video-several-keyboard-responses/package.json index 6ad1178a..8ccd9d0b 100644 --- a/packages/plugin-video-several-keyboard-responses/package.json +++ b/packages/plugin-video-several-keyboard-responses/package.json @@ -1,6 +1,6 @@ { "name": "@jspsych-contrib/plugin-video-several-keyboard-responses", - "version": "1.0.0", + "version": "2.0.0", "description": "jsPsych plugin for playing a video file and getting several keyboard responses", "type": "module", "main": "dist/index.cjs",