enter sorted data from first task as timeline_variables for second task #1361
-
Hello, var trialsR=[];
var images = new Array('i1.jpg','i2.jpg','i3.jpg,'i4.jpg')
//shuffle function
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
// Rating trials
images = shuffleArray(images);
for (var i = 0; i <= images.length-1; i++) {
//generate trial variables for each image
var trial_image_string = string1.concat(images[i], string2);
var rating_trial = {
data: { ttype: 'rating_task', image: images[i]},
type: 'html-slider-response',
stimulus: trial_image_string,
labels: ['0 (least)', '10 (most)'],
slider_width: 500,
slider_start: Math.random()*100,
require_movement: true,
prompt: '<p>How much do you prefer to eat this food?</p>'
//stimulus_duration: 5000
}
trialsR.push(rating_trial);
}; I know I could have done this with timeline_variables as my list of images, but bare with me. var list_combined = [];
var list_paired = [];
//paired choice instructions
var choice_instructions = {
type: 'html-keyboard-response',
stimulus: '<p class="title">Choice Task</b></p>\
<p class="instruct2">Pairs of stimuli will be shown. Please select the one you prefer.</p>\
<p class="instruct2">Press "j" to select the stimulus on the left and "k" to select the stimulus on the right. You will have up to 3 seconds to make your choice.</p>\
<p class="instruct">Press "j" or "k" to continue.',
choices: ['j','k'],
on_start: function() {
// this function aims to get and sort responses
var sort_image = jsPsych.data.get().select('image').values;
var sort_values = jsPsych.data.get().select('response').values;
//1) combine the arrays:
for (var j = 0; j < images.length; j++){
list_combined.push({'image': sort_image[j], 'value': sort_values[j]});
};
//2) sort based on values:
list_combined.sort(function(a, b) {
return ((a.value < b.value) ? -1 : ((a.value == b.value) ? 0 : 1));
});
for (var i = 0; i <= pair_counts; i++) {
//randomnize left and right displays
var position = [(2*i),(2*i+1)];
shuffleArray(position);
var left = position[0];
var right = position[1];
list_paired.push({'image_l': list_combined[left].image, 'value_l': list_combined[left].value, 'image_r': list_combined[right].image, 'value_r': list_combined[right].value});
};
shuffleArray(list_paired);
return list_paired;
}
}; so now I have this list paired which is an array that has my per trial (i have 2 choice trials in this case) that specifies the stimulus that should go on the right and the stimulus that goes on the right. But even though this global variable list_paired is only generated when the instructions for the choice task, it is not recognized when entered as timeline_variables below var string1 = '<img src=';
var stringP = '<img style=\"border: 5px solid #555;width: 300px;padding: 20px;margin:5px\" src=';
var string2 = '></img>';
var string_picked = "<img style=\"border: 5px solid #55CC33;width: 300px;padding: 20px;margin:5px\" src=";
var trial_variables = {
'stimulus_duration':3000,
'trial_duration':3000,
'selection_confirm_duration':1000,
'feedback_duration':1500,
'fixation_duration':1000
};
// choice trials
var choice_trial = {
timeline:[
// ## choice trial
{
type: 'html-keyboard-response',
// these are the data that will be saved out
data: { ttype: 'choice_task', stim_left: jsPsych.timelineVariable('image_l',true) , stim_right:jsPsych.timelineVariable('image_r',true) , val_left: jsPsych.timelineVariable('value_l',true) , val_right: jsPsych.timelineVariable('value_r',true)
},
stimulus: function(){
var html= stringP+jsPsych.timelineVariable('image_l',true)+string2;
html += stringP+jsPsych.timelineVariable('image_r',true)+string2;
html += "<p class='subtitle2'>Left (j) --------------------------- Right (k)</p>"
return html;
},
choices: ['j', 'k'],
// durations defined at beginning of script
stimulus_duration: trial_variables.stimulus_duration,
trial_duration: trial_variables.trial_duration,
response_ends_trial: true,
},
// ## highlight trial
{
type: 'html-keyboard-response',
data: { ttype: 'choice_confirm' },
stimulus: function() {
var last_trial = jsPsych.data.get().last(1).values()[0];
if (last_trial.key_press == jsPsych.pluginAPI.convertKeyCharacterToKeyCode('j')) {
return([string_picked + jsPsych.timelineVariable('image_l',true) + string2 + stringP + jsPsych.timelineVariable('image_r',true) + string2]+'<p class="subtitle2"> </p>');
} else if (last_trial.key_press == jsPsych.pluginAPI.convertKeyCharacterToKeyCode('k')) {
return([stringP + jsPsych.timelineVariable('image_l',true) + string2 + string_picked + jsPsych.timelineVariable('image_r',true) + string2]+'<p class="subtitle2"> </p>');
} else {
return("<div style='font-size:40px'>Too Slow<br /><br />(Press j=left / k=right)</div>");
}
},
choices: jsPsych.NO_KEYS,
stimulus_duration: trial_variables.selection_confirm_duration,
trial_duration: trial_variables.selection_confirm_duration,
response_ends_trial: false,
},
// ## fixation trial
{
type: 'html-keyboard-response',
data: { ttype: 'fixiation' },
stimulus: '<div><div class="fix">+</div><p> </p></div>',
choices: jsPsych.NO_KEYS,
stimulus_duration: trial_variables.fixation_duration,
trial_duration: trial_variables.fixation_duration,
response_ends_trial: false
}
],
timeline_variables: [list_paired]
};
trialsR.push(choice_trial);
jsPsych.init({
timeline: trialsR,
preload_images: images,
show_progress_bar: true,
on_finish: function() {
jsPsych.data.displayData();
},
default_iti: 0
}); It seems that the global variable list_paired is not recognized in timeline_variables: [list_paired] timeline_variables: [
{image_r:'i1.jpg',image_l:'i2.jpg',value_r:58,value_l:23},
{image_r:'i3.jpg',image_l:'i4.jpg',value_r:18,value_l:73}
] then it works, so it really has to do with feeding that sorted list to the timeline_varaibles. Any ideas? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @abakkour! I'm not sure whether it's possible to create a timeline_variables array dynamically during the experiment, but I think it's not. @jodeleeuw? One way to do this is to switch to using a looping timeline instead of timeline_variables for this part of the experiment. The So assuming that the list_paired array is created during the experiment with this structure: [
{image_r:'i1.jpg',image_l:'i2.jpg',value_r:58,value_l:23},
{image_r:'i3.jpg',image_l:'i4.jpg',value_r:18,value_l:73}
] Then I think you can do this: var trial_count = 0;
var choice_trial_loop = {
timeline: [
type: 'html-keyboard-response',
stimulus: function() {
return '<p>This is trial number '+trial_count.toString()+'.</p><img src="'+list_paired[trial_count].image_r+'">';
}
],
loop_function: function() {
trial_count++;
if (trial_count+1 == list_paired.length) {
return false;
} else {
return true;
}
}
}; (Note that I haven't tested this code so there may be typos etc.) |
Beta Was this translation helpful? Give feedback.
Hi @abakkour!
I'm not sure whether it's possible to create a timeline_variables array dynamically during the experiment, but I think it's not. @jodeleeuw?
One way to do this is to switch to using a looping timeline instead of timeline_variables for this part of the experiment. The
loop_function
in your looping timeline would keep track of the trial number, which allows you to index thelist_paired
array to get the appropriate variables for each trial. This also allows you to end the loop once your trial count reaches the length of thelist_paired
array. Thetimeline
in your looping timeline would contain the trials that are currently in your timeline_variables procedure (choice_trial
), bu…