Help with a nested timeline #1911
-
Hi I'm trying to build an experiment with the following basic structure: each trial consists of an experimental item and then 3 distractor items. Here's some simplified code displaying filenames instead of using actual audio. My question is how do I set up my When I specify the distractors as an array for the var mystimuli = [
{ exp_item: 'audio/P_exp_1.mp3',
distractors: [ { dist_item: 'audio/P_filler_1.mp3'}, {dist_item: 'audio/P_filler_2.mp3'}, {dist_item: 'audio/P_filler_3.mp3' } ] },
{ exp_item: 'audio/P_exp_2.mp3',
distractors: [ { dist_item: 'audio/P_filler_1.mp3'}, {dist_item: 'audio/P_filler_2.mp3'}, {dist_item: 'audio/P_filler_3.mp3'} ] }
];
var timeline = [];
var judgment_trial = {
type: 'html-button-response',
stimulus: jsPsych.timelineVariable('exp_item'),
choices: ['TRUE', 'FALSE']
};
var dist_trial = {
type: 'html-button-response',
stimulus: jsPsych.timelineVariable('dist_item'),
choices: ['TRUE', 'FALSE']
};
var fixed_distractor_trials = {
timeline: [dist_trial],
timeline_variables:
[ { dist_item: 'audio/P_filler_1.mp3'}, {dist_item: 'audio/P_filler_2.mp3'}, {dist_item: 'audio/P_filler_3.mp3'} ]
};
// why doesn't this work?
var variable_distractor_trials = {
timeline: [dist_trial],
timeline_variables: jsPsych.timelineVariable('distractors')
};
var judgment_task = {
timeline: [judgment_trial,fixed_distractor_trials],
// timeline: [judgment_trial,variable_distractor_trials] // why doesn't this version work?
timeline_variables: mystimuli,
randomize_order: true
};
timeline.push(judgment_task);
jsPsych.init({
timeline: timeline }); |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hi @amunn, first, thanks very much for providing simplified reproducible code - very helpful!! Second, your approach to setting up the nested timeline with variable_distractor_trials seems perfectly sensible to me. I'm guessing the problem is that jsPsych needs the timeline_variables array to be known when the page loads, and perhaps using the Here's a different method you can try: var timeline = [];
var mystimuli = [
{ exp_item: 'audio/P_exp_1.mp3',
distractors: [ { dist_item: 'audio/P_filler_1.mp3'}, {dist_item: 'audio/P_filler_2.mp3'}, {dist_item: 'audio/P_filler_3.mp3' } ]
},
{ exp_item: 'audio/P_exp_2.mp3',
distractors: [ { dist_item: 'audio/P_filler_1.mp3'}, {dist_item: 'audio/P_filler_2.mp3'}, {dist_item: 'audio/P_filler_3.mp3'} ]
}
];
// global variables to hold the current distractor array and distractor index during the experiment
var curr_distractor_array, curr_index;
var judgment_trial = {
type: 'html-button-response',
stimulus: jsPsych.timelineVariable('exp_item'),
choices: ['TRUE', 'FALSE'],
on_finish: function() {
// set up the shuffled array of distractors associated with this trial
curr_distractor_array = jsPsych.randomization.shuffle(jsPsych.timelineVariable('distractors'));
// (re)set the distractor index to 0
curr_index = 0;
}
};
var dist_trial = {
type: 'html-button-response',
stimulus: function() {
// get the current distractor item, then the dist_item from that object, and use that as the stimulus
return curr_distractor_array[curr_index].dist_item;
},
choices: ['TRUE', 'FALSE']
};
var variable_distractor_trials = {
timeline: [dist_trial],
loop_function() {
curr_index++;
// if we've reached the last distractor item, then stop the loop, otherwise continue
if (curr_index == curr_distractor_array.length) {
return false;
} else {
return true;
}
}
};
var judgment_task = {
timeline: [judgment_trial, variable_distractor_trials],
timeline_variables: mystimuli,
randomize_order: true
};
timeline.push(judgment_task); Let me know if that works, and if you have any questions. |
Beta Was this translation helpful? Give feedback.
-
Hi, I have a similar problem and I was wondering if anyone has any suggestions. My experiment has the following structure: 3 vowels played in a row per trial, and 4 trials per block. I can't seem to get the const stim_order = [
{"group":0,"block":1,"trial":1,"path":"stim/A/IH1.wav","istarget":0},{"group":0,"block":1,"trial":1,"path":"stim/A/OO3.wav"},{"group":0,"block":1,"trial":1,"path":"stim/A/EH2.wav"},{"group":0,"block":1,"trial":2,"path":"stim/A/AA3.wav"},{"group":0,"block":1,"trial":2,"path":"stim/A/OO1.wav"},{"group":0,"block":1,"trial":2,"path":"stim/A/EH2.wav"},{"group":0,"block":1,"trial":3,"path":"stim/A/AA1.wav"},{"group":0,"block":1,"trial":3,"path":"stim/A/EH2.wav"},{"group":0,"block":1,"trial":3,"path":"stim/A/UH3.wav"},
{"group":0,"block":1,"trial":4,"path":"stim/A/AA1.wav"},{"group":0,"block":1,"trial":4,"path":"stim/A/EH2.wav"},{"group":0,"block":1,"trial":4,"path":"stim/A/AA3.wav"},{"group":0,"block":2,"trial":1,"path":"stim/A/OO1.wav"},{"group":0,"block":2,"trial":1,"path":"stim/A/UH2.wav"},{"group":0,"block":2,"trial":1,"path":"stim/A/AA1.wav"},{"group":0,"block":2,"trial":2,"path":"stim/A/OO1.wav"},{"group":0,"block":2,"trial":2,"path":"stim/A/AH2.wav"},{"group":0,"block":2,"trial":2,"path":"stim/A/EH1.wav"},{"group":0,"block":2,"trial":3,"path":"stim/A/UH1.wav"},{"group":0,"block":2,"trial":3,"path":"stim/A/EH2.wav"},{"group":0,"block":2,"trial":3,"path":"stim/A/AA1.wav"},
{"group":0,"block":2,"trial":4,"path":"stim/A/UH1.wav"},{"group":0,"block":2,"trial":4,"path":"stim/A/EH2.wav"},{"group":0,"block":2,"trial":4,"path":"stim/A/OO1.wav"}]
let timeline = [];
let group = 0;
let block_number = 1;
let trial = 1;
// make play_vowel
const play_vowel = {
type: "audio-keyboard-response",
stimulus: jsPsych.timelineVariable("path"),
};
// make a trial that executes play_vowel
function make_trial(block_number, trial) {
return {
timeline: [play_vowel],
timeline_variables: stim_order.filter(function (el) {
return (
el.group === group &&
el.block === block_number &&
el.trial === trial
);
}),
};
}
// make a block which executes make_trial
function make_block(block_number) {
return {
timeline: [
make_trial(block_number, trial),
],
repetitions: 8, // not sure if this is part of the problem
loop_function() { // not sure if I should iterate trial here
console.log({ trial })
trial++;
}
};
}
timeline.push(make_block(block_number)) // block 1
block_number++
timeline.push(make_block(block_number)) // block 2 |
Beta Was this translation helpful? Give feedback.
Hi @amunn, first, thanks very much for providing simplified reproducible code - very helpful!! Second, your approach to setting up the nested timeline with variable_distractor_trials seems perfectly sensible to me. I'm guessing the problem is that jsPsych needs the timeline_variables array to be known when the page loads, and perhaps using the
jsPsych.timelineVariable
function to generate different arrays based on other timeline variables doesn't meet that criteria. So I don't think this is a bug, but rather something that hasn't been implemented. @jodeleeuw can correct me if I'm wrong.Here's a different method you can try: