-
Hi Josh, I have two follow-up questions to the shuffling with constraint and conditional trial after every Nth item in timeline questions you previously answered (thanks again for those answers, big help!) The experiment as it is coded now is a dual task experiment with a 1I-4AFC perception task and a free recall task. There are 96 stimuli in total (which are shuffled with no immediate repeats) and after every 8th trial there is a free recall where participants have to write down as many names of the previous 8 stimuli as they can. Our code (based on your suggestions from my previous two questions) now looks like this: timeline.push({
timeline: [
{
type: 'html-keyboard-response',
stimulus: "<div style='font-size:32px'>+</div>",
choices: jsPsych.NO_KEYS,
trial_duration: 1000
},
{
type: 'audio-keyboard-response',
stimulus: jsPsych.timelineVariable('audio'),
choices: jsPsych.NO_KEYS,
trial_ends_after_audio: true
},
{
type: 'html-button-response',
stimulus: "<p>Which question did the speaker answer?<br></p>",
choices: [jsPsych.timelineVariable('questionSF'),
jsPsych.timelineVariable('questionVF'),
jsPsych.timelineVariable('questionOF'),
jsPsych.timelineVariable('questionBF')],
button_html: '<button class="jspsych-btn-block">%choice%</button>',
margin_vertical: '12px',
data: jsPsych.timelineVariable('data'),
on_finish: function(data){
data.trial = jsPsych.data.get().filter({loop: 'trial', task: 'response'}).count();
if(data.button_pressed == '0'){
data.response = 'SF';
} else if (data.button_pressed == '1'){
data.response = 'VF';
} else if (data.button_pressed == '2'){
data.response = 'OF';
} else {
data.response = 'BF';
}
if(data.button_pressed == data.button){
data.response_correct = true;
} else {
data.response_correct = false;
}
}
},
{
timeline: [{
type: 'survey-text',
questions: [
{ prompt: "<p>Please recall as many names of the previous 8 sentences as you can.<br>" + "You can type in the names in any order you prefer (separated by a space):</p>", placeholder: "e.g. Lisa Tom", name: 'recall', required: true }
],
button_label: 'Continue',
data: {loop: 'trial', task: 'recall'},
on_finish: function(data){
data.recall = JSON.parse(data.responses).recall.split(" ");
}
}],
conditional_function: function(){
if(jsPsych.data.get().filter({loop: 'trial', task: 'response'}).count() % 8){
return false;
} else {
return true;
}
}
}
],
timeline_variables: [
{ audio: 'audio/T1-SF-S1F.wav', data: {button: '0', loop: 'trial', task: 'response', sentence: 'T1', focus: 'SF', speaker: 'S1F', name: 'John'}, questionSF: '"<b>Who</b> kicked the ball?"', questionVF: '"What did John <b>do</b> with the ball?"', questionOF: '"<b>What</b> did John kick?"', questionBF: '"What happened"?' },
{ audio: 'audio/T1-VF-S2F.wav', data: {button: '1', loop: 'trial', task: 'response', sentence: 'T1', focus: 'VF', speaker: 'S2F', name: 'John'}, questionSF: '"<b>Who</b> kicked the ball?"', questionVF: '"What did John <b>do</b> with the ball?"', questionOF: '"<b>What</b> did John kick?"', questionBF: '"What happened"?' },
{ audio: 'audio/T1-OF-S4M.wav', data: {button: '2', loop: 'trial', task: 'response', sentence: 'T1', focus: 'OF', speaker: 'S4M', name: 'John'}, questionSF: '"<b>Who</b> kicked the ball?"', questionVF: '"What did John <b>do</b> with the ball?"', questionOF: '"<b>What</b> did John kick?"', questionBF: '"What happened"?' },
{ audio: 'audio/T1-BF-S3M.wav', data: {button: '3', loop: 'trial', task: 'response', sentence: 'T1', focus: 'BF', speaker: 'S3M', name: 'John'}, questionSF: '"<b>Who</b> kicked the ball?"', questionVF: '"What did John <b>do</b> with the ball?"', questionOF: '"<b>What</b> did John kick?"', questionBF: '"What happened"?' },
{ ... }, // other 22x4=88 stimuli removed to save space
{ audio: 'audio/T24-SF-S1F.wav', data: {button: '0', loop: 'trial', task: 'response', sentence: 'T24', focus: 'SF', speaker: 'S1F', name: 'Susan'}, questionSF: '"<b>Who</b> ate the apple?"', questionVF: '"What did Susan <b>do</b> with the apple?"', questionOF: '"<b>What</b> did Susan eat?"', questionBF: '"What happened"?' },
{ audio: 'audio/T24-VF-S4M.wav', data: {button: '1', loop: 'trial', task: 'response', sentence: 'T24', focus: 'VF', speaker: 'S4M', name: 'Susan'}, questionSF: '"<b>Who</b> ate the apple?"', questionVF: '"What did Susan <b>do</b> with the apple?"', questionOF: '"<b>What</b> did Susan eat?"', questionBF: '"What happened"?' },
{ audio: 'audio/T24-OF-S2F.wav', data: {button: '2', loop: 'trial', task: 'response', sentence: 'T24', focus: 'OF', speaker: 'S2F', name: 'Susan'}, questionSF: '"<b>Who</b> ate the apple?"', questionVF: '"What did Susan <b>do</b> with the apple?"', questionOF: '"<b>What</b> did Susan eat?"', questionBF: '"What happened"?' },
{ audio: 'audio/T24-BF-S3M.wav', data: {button: '3', loop: 'trial', task: 'response', sentence: 'T24', focus: 'BF', speaker: 'S3M', name: 'Susan'}, questionSF: '"<b>Who</b> ate the apple?"', questionVF: '"What did Susan <b>do</b> with the apple?"', questionOF: '"<b>What</b> did Susan eat?"', questionBF: '"What happened"?' },
],
sample: {
type: 'custom',
fn: function(){
var groups = [[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15],[16,17,18,19],[20,21,22,23],[24,25,26,27],[28,29,30,31],[32,33,34,35],[36,37,38,39],[40,41,42,43],[44,45,46,47],[48,49,50,51],[52,53,54,55],[56,57,58,59],[60,61,62,63],[64,65,66,67],[68,69,70,71],[72,73,74,75],[76,77,78,79],[80,81,82,83],[84,85,86,87],[88,89,90,91],[92,93,94,95]];
var all_items = [];
for(var i=0; i<groups.length; i++){
for(var j=0; j<groups[i].length; j++){
all_items.push({group: i, trial_num: groups[i][j]});
}
}
var order = jsPsych.randomization.shuffleNoRepeats(all_items, function(a,b){
return a.group == b.group;
});
return order.map(function(x){ return x.trial_num });
}
}
}); I have two follow-up questions, which I hope you can help me with: 1. Shuffling with multiple constraints 2. Data output Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 19 replies
-
Any suggestions @jodeleeuw? |
Beta Was this translation helpful? Give feedback.
-
Hi Marita, I think these questions are perhaps a bit too specific to be addressed here. It's gonna take a while to read your code and understand it enough to be able to answer your first question. For the second, I would only suggest to add in the // Getting the last html-button-response trial
var last_hbr = jsPsych.data.get().filter({trial_type: 'html-button-response'}).last();
// We get the node id and we "parse" it
var node_id = last_hbr.values().internal_node_id.split("-");
// We remove the end portion (you may actually want to remove less... may need some tinkering)
var node_id_pattern = node_id.slice(0,-1).join("-")+"-";
// Finally we select the trials of interest and add the recall data to them
jsPsych.data.get()
.filter({trial_type: 'html-button-response'})
.filterCustom(function(r){ return r.internal_node_id.startsWith(node_id_pattern); })
.addToAll(data.recall); I only hope that the result of a Hope that helps. |
Beta Was this translation helpful? Give feedback.
Any suggestions @jodeleeuw?