关于jsPsych image-audio-response插件获取单个刺激准确反应时间的技术问询
Hey there! I’ve tinkered with jsPsych custom plugins before, so let’s work through this RT issue you’re facing. The core problem here is that the plugin’s default RT calculation is tied to the entire trial duration, not individual stimuli—so when you run multi-stimulus trials, all stimuli inherit the same "trial start to trial end" time, even if you don’t respond. Here’s how to fix it:
1. Modify the Plugin Source Code (Most Reliable Solution)
The cleanest way to get per-stimulus RT is to tweak the plugin’s code to track timestamps for each individual stimulus. Here’s what to do:
Step 1: Add a Timestamp Tracker for Each Stimulus
In the plugin’s main file, add a variable to store the start time of the currently displayed stimulus:
let current_stimulus_start_time;
Step 2: Record Start Time When Each Stimulus Loads
Find the function that displays the next stimulus (likely named something like show_next_stimulus or render_stimulus). Add a line to capture the start time right when the stimulus appears:
function show_next_stimulus() { // Existing code to render the image/stimulus... current_stimulus_start_time = performance.now(); }
Step 3: Calculate and Store Per-Stimulus RT
Find where the plugin handles recording completion (when the user stops speaking or the stimulus switches). Add logic to calculate the RT for the current stimulus and store it alongside the stimulus data:
function handle_recording_end() { // Existing code to stop recording... // Calculate RT for the current stimulus const stimulus_rt = performance.now() - current_stimulus_start_time; // Append this RT to the trial data (link it to the current stimulus) jsPsych.data.get().last().append({ stimulus: current_stimulus, // Replace with your variable for the active stimulus stimulus_rt: stimulus_rt }); }
Step 4: Handle Non-Response Cases
For trials where the user doesn’t respond, you’ll want to calculate RT as the time the stimulus was displayed until it switches. Add this logic in the function that advances to the next stimulus:
function advance_to_next_stimulus() { if (!recording_started) { // Check if no response was made const stimulus_rt = performance.now() - current_stimulus_start_time; jsPsych.data.get().last().append({ stimulus: current_stimulus, stimulus_rt: stimulus_rt, response: null }); } // Existing code to load next stimulus... }
2. Workaround Without Modifying the Plugin (Quick Fix)
If you don’t want to edit the plugin source, you can add custom timing logic in your trial configuration:
let stimulus_timestamps = []; const trial = { type: 'image-audio-response', stimuli: ['img1.jpg', 'img2.jpg', 'img3.jpg'], on_load: function() { // Record start time when the first stimulus loads stimulus_timestamps.push({stimulus: 'img1.jpg', start: performance.now()}); }, // Add a custom event listener if the plugin triggers a "stimulus change" event on_event: function(event) { if (event.type === 'stimulus_changed') { const last_stimulus = stimulus_timestamps[stimulus_timestamps.length - 1]; last_stimulus.end = performance.now(); last_stimulus.rt = last_stimulus.end - last_stimulus.start; // Push new stimulus start time stimulus_timestamps.push({stimulus: event.stimulus, start: performance.now()}); } }, on_finish: function(data) { // Add the final stimulus RT to the trial data const last_stimulus = stimulus_timestamps[stimulus_timestamps.length - 1]; last_stimulus.end = performance.now(); last_stimulus.rt = last_stimulus.end - last_stimulus.start; data.per_stimulus_rt = stimulus_timestamps; } };
This workaround relies on tracking stimulus changes manually and appending the RT data to the trial’s final output.
Key Notes
- After modifying the plugin, make sure to test with your multi-stimulus trial setup—you should now see unique RT values for each stimulus, even if no response is given.
- If you go the plugin modification route, save a copy of the edited plugin (e.g.,
jspsych-image-audio-response-custom.js) to avoid overwriting the original when updating jsPsych.
内容的提问来源于stack exchange,提问作者IWILSO

