Merge pull request #69 from jodeleeuw/dev-chunks

Dev chunks
This commit is contained in:
Josh de Leeuw 2014-09-23 16:47:27 -04:00
commit ac5c707516
18 changed files with 1175 additions and 966 deletions

View File

@ -17,11 +17,11 @@
// options // options
var opts = {}; var opts = {};
// exp structure // exp structure
var exp_blocks = []; var root_chunk;
// flow control // flow control
var curr_block = 0; var curr_chunk = 0;
// everything loaded? var global_trial_index = 0;
var initialized = false; var current_trial = {};
// target DOM element // target DOM element
var DOM_target; var DOM_target;
// time that the experiment began // time that the experiment began
@ -33,11 +33,10 @@
core.init = function(options) { core.init = function(options) {
// reset the key variables // reset variables
exp_blocks = []; root_chunk = {};
opts = {}; opts = {};
initialized = false; curr_chunk = 0;
curr_block = 0;
// check if there is a body element on the page // check if there is a body element on the page
var default_display_element = $('body'); var default_display_element = $('body');
@ -63,7 +62,7 @@
'show_progress_bar': false 'show_progress_bar': false
}; };
// import options // override default options if user specifies an option
opts = $.extend({}, defaults, options); opts = $.extend({}, defaults, options);
// set target // set target
@ -72,42 +71,19 @@
// add CSS class to DOM_target // add CSS class to DOM_target
DOM_target.addClass('jspsych-display-element'); DOM_target.addClass('jspsych-display-element');
run(); // create experiment structure
}; root_chunk = parseExpStructure(opts.experiment_structure);
core.data = function() { startExperiment();
var all_data = [];
for (var i = 0; i < exp_blocks.length; i++) {
all_data[i] = exp_blocks[i].data;
}
return all_data;
}; };
core.progress = function() { core.progress = function() {
var total_trials = 0;
for (var i = 0; i < exp_blocks.length; i++) {
total_trials += exp_blocks[i].num_trials;
}
var current_trial_global = 0;
var current_trial_local = -1;
for (var i = 0; i < curr_block; i++) {
current_trial_global += exp_blocks[i].num_trials;
}
if(current_trial_global < total_trials) {
current_trial_global += exp_blocks[curr_block].trial_idx;
current_trial_local = exp_blocks[curr_block].trial_idx;
}
var obj = { var obj = {
"total_blocks": exp_blocks.length, "total_trials": root_chunk.length(),
"total_trials": total_trials, "current_trial_global": global_trial_index
"current_trial_global": current_trial_global, //"current_trial_local": exp_chunks[curr_chunk].currentTrialInChunk,
"current_trial_local": current_trial_local, //"current_timeline_location": curr_chunk + "-" + exp_chunks[curr_chunk].currentBlock
"current_block": curr_block
}; };
return obj; return obj;
@ -149,30 +125,284 @@
return DOM_target; return DOM_target;
} }
// core.finishTrial = function(){
// private functions // // logic to advance to next trial?
//
function run() {
// take the experiment structure and create a set of blocks // handle callback at plugin level
exp_blocks = new Array(opts.experiment_structure.length); if (typeof current_trial.on_finish === 'function') {
current_trial.on_finish(); // TODO: pass in data
}
// iterate through list to create trials // handle callback at whole-experiment level
for (var i = 0; i < exp_blocks.length; i++) { opts.on_trial_finish();
// update progress bar if shown
if (opts.show_progress_bar === true) {
updateProgressBar();
}
global_trial_index++;
// advance chunk
root_chunk.advance();
// check if experiment is over
if(root_chunk.isComplete()){
finishExperiment();
return;
}
doTrial(root_chunk.next());
}
core.currentTrial = function(){
return current_trial;
}
core.initSettings = function(){
return opts;
}
core.currentChunkID = function(){
return root_chunk.activeChunkID();
}
function parseExpStructure(experiment_structure) {
/*var chunks = [];
for(var i=0; i<experiment_structure.length; i++){
var ct = experiment_structure[i].chunk_type;
if(typeof ct !== 'undefined') {
if($.inArray(ct, ["linear", "while"]) > -1){
chunks.push(createExperimentChunk(experiment_structure[i], i));
} else {
throw new Error('Invalid experiment structure definition. Element '+i+' of the experiment_structure array has an invalid chunk_type property');
}
} else if(typeof experiment_structure[i].type !== 'undefined') {
var temp_chunk = {
chunk_type: 'linear',
blocks: [experiment_structure[i]]
}
chunks.push(createExperimentChunk(temp_chunk));
} else {
throw new Error('Invalid experiment structure definition. Element '+i+' of the experiment_structure array is improperly defined');
}
}*/
return createExperimentChunk({
chunk_type: 'root',
blocks: experiment_structure
});
}
function createExperimentChunk(chunk_definition, parent_chunk, relative_id){
var chunk = {};
chunk.timeline = parseChunkDefinition(chunk_definition.blocks);
chunk.parentChunk = parent_chunk;
chunk.relID = relative_id;
chunk.type = chunk_definition.chunk_type; // root, linear, while
chunk.currentTimelineLocation = 0;
// this is the current trial since the last time the chunk was reset
chunk.currentTrialInTimeline = 0;
// this is the current trial since the chunk started (incl. resets)
chunk.currentTrialInChunk = 0;
chunk.iteration = 0;
chunk.length = function(){
// this will recursively get the number of trials on this chunk's timeline
var n = 0;
for(var i=0; i<this.timeline.length; i++){
n += this.timeline[i].length;
}
return n;
}
chunk.activeChunkID = function(){
if(this.timeline[this.currentTimelineLocation].type === 'block'){
return this.chunkID();
} else {
return this.timeline[this.currentTimelineLocation].activeChunkID();
}
}
chunk.chunkID = function() {
if(typeof this.parentChunk === 'undefined') {
return 0 + "-" + this.iteration;
} else {
return this.parentChunk.chunkID() + "." + this.relID + "-" + this.iteration;
}
}
chunk.next = function() {
// return the next trial in the block to be run
if(chunk.isComplete()){
throw new Error('Tried to get completed trial from chunk that is finished.');
} else {
return this.timeline[this.currentTimelineLocation].next();
}
}
chunk.advance = function(){
// increment the current trial in the chunk
this.timeline[this.currentTimelineLocation].advance();
if(this.timeline[this.currentTimelineLocation].isComplete()){
this.currentTimelineLocation++;
}
this.currentTrialInTimeline++;
this.currentTrialInChunk++;
}
chunk.isComplete = function() {
// return true if the chunk is done running trials
// return false otherwise
// linear chunks just go through the blocks in order and are
// done when each trial has been completed once
// the root chunk is a special case of the linear chunk
if(this.type == 'linear' || this.type == 'root'){
if (this.currentTimelineLocation >= this.timeline.length) { return true; }
else { return false; }
}
// while chunks play the block again as long as the continue_function
// returns true
else if(this.type == 'while'){
if (this.currentTimelineLocation >= this.timeline.length) {
if(chunk_definition.continue_function(this.generatedData())){
this.reset();
return false;
} else {
return true;
}
} else {
return false;
}
}
}
chunk.generatedData = function() {
// return an array containing all of the data generated by this chunk for this iteration
var d = jsPsych.data.getTrialsFromChunk(this.chunkID());
return d;
}
chunk.reset = function() {
this.currentTimelineLocation = 0;
this.currentTrialInTimeline = 0;
this.iteration++;
for(var i = 0; i < this.timeline.length; i++){
this.timeline[i].reset();
}
}
function parseChunkDefinition(chunk_timeline){
var timeline = [];
for (var i = 0; i < chunk_timeline.length; i++) {
var ct = chunk_timeline[i].chunk_type;
if(typeof ct !== 'undefined') {
if($.inArray(ct, ["linear", "while"]) > -1){
timeline.push(createExperimentChunk(chunk_timeline[i], chunk, i));
} else {
throw new Error('Invalid experiment structure definition. Element of the experiment_structure array has an invalid chunk_type property');
}
} else {
// create a terminal block ...
// check to make sure plugin is loaded // check to make sure plugin is loaded
var plugin_name = opts.experiment_structure[i].type; var plugin_name = chunk_timeline[i].type;
if (typeof jsPsych[plugin_name] == 'undefined') { if (typeof jsPsych[plugin_name] === 'undefined') {
throw new Error("Failed attempt to create trials using plugin type " + plugin_name + ". Is the plugin loaded?"); throw new Error("Failed attempt to create trials using plugin type " + plugin_name + ". Is the plugin loaded?");
} }
var trials = jsPsych[plugin_name]["create"].call(null, opts["experiment_structure"][i]); var trials = jsPsych[plugin_name].create(chunk_timeline[i]);
// add options that are generic to all plugins // add options that are generic to all plugins
trials = addGenericTrialOptions(trials, opts.experiment_structure[i]); trials = addGenericTrialOptions(trials, chunk_timeline[i]);
exp_blocks[i] = createBlock(trials); timeline.push(createBlock(trials));
} }
}
return timeline;
}
return chunk;
}
function createBlock(trial_list) {
var block = {
trial_idx: 0,
trials: trial_list,
type: 'block',
next: function() {
var curr_trial = this.trials[this.trial_idx];
return curr_trial;
},
isComplete: function() {
if(this.trial_idx >= this.trials.length){
return true;
} else {
return false;
}
},
advance: function() {
this.trial_idx++;
},
reset: function() {
this.trial_idx = 0;
},
length: trial_list.length
};
return block;
}
function startExperiment() {
// show progress bar if requested // show progress bar if requested
if (opts.show_progress_bar === true) { if (opts.show_progress_bar === true) {
@ -182,8 +412,8 @@
// record the start time // record the start time
exp_start_time = new Date(); exp_start_time = new Date();
// begin! - run the first block // begin!
exp_blocks[0].next(); doTrial(root_chunk.next());
} }
function addGenericTrialOptions(trials_arr, opts) { function addGenericTrialOptions(trials_arr, opts) {
@ -228,91 +458,19 @@
return trials_arr; return trials_arr;
} }
function nextBlock() { function finishExperiment() {
curr_block += 1; opts.on_finish(jsPsych.data.getData());
if (curr_block == exp_blocks.length) {
finishExperiment();
}
else {
exp_blocks[curr_block].next();
}
} }
function createBlock(trial_list) { function doTrial(trial) {
var block = {
trial_idx: -1,
trials: trial_list, current_trial = trial;
data: [], // call experiment wide callback
next: function() {
// trial_idx is -1 when block is created, so to start the first trial, trial_idx will be -1.
if(this.trial_idx > -1){
// handle callback at plugin level
if(typeof this.trials[this.trial_idx].on_finish === 'function') {
this.trials[this.trial_idx].on_finish(this.data[this.trial_idx]);
}
// handle callback at whole-experiment level
opts.on_trial_finish();
// update progress bar if shown
if(opts.show_progress_bar === true) {
updateProgressBar();
}
};
this.trial_idx = this.trial_idx + 1;
var curr_trial = this.trials[this.trial_idx];
if (typeof curr_trial == "undefined") {
return this.done();
}
// call on_trial_start()
opts.on_trial_start(); opts.on_trial_start();
do_trial(this, curr_trial);
},
writeData: function(data_object) {
var progress = jsPsych.progress();
var default_data = {
'trial_type': this.trials[this.trial_idx].type,
'trial_index': this.trial_idx,
'trial_index_global': progress.current_trial_global,
'time_elapsed': jsPsych.totalTime(),
'block_index': curr_block
};
var ext_data_object = $.extend({}, data_object, default_data);
this.data[this.trial_idx] = ext_data_object;
opts.on_data_update(ext_data_object);
},
done: nextBlock,
num_trials: trial_list.length
};
return block;
}
function finishExperiment() {
opts["on_finish"].apply((new Object()), [core.data()]);
}
function do_trial(block, trial) {
// execute trial method // execute trial method
jsPsych[trial.type]["trial"].call(this, DOM_target, block, trial); jsPsych[trial.type].trial(DOM_target, trial);
} }
function drawProgressBar() { function drawProgressBar() {
@ -330,17 +488,46 @@
return core; return core;
})(); })();
jsPsych.dataAPI = (function() { jsPsych.data = (function() {
var module = {}; var module = {};
// data storage object
var allData = [];
module.getData = function() {
return $.extend(true, [], allData); // deep clone
}
module.write = function(data_object) {
var progress = jsPsych.progress();
var trial = jsPsych.currentTrial();
var default_data = {
'trial_type': trial.type,
//'trial_index': progress.current_trial_local,
'trial_index_global': progress.current_trial_global,
'time_elapsed': jsPsych.totalTime(),
//'block_index': progress.current_block,
'internal_chunk_id': jsPsych.currentChunkID()
};
var ext_data_object = $.extend({}, data_object, default_data);
allData.push(ext_data_object);
var initSettings = jsPsych.initSettings();
initSettings.on_data_update(ext_data_object); //TODO: FIX callback?
}
// core.dataAsCSV returns a CSV string that contains all of the data // core.dataAsCSV returns a CSV string that contains all of the data
// append_data is an option map object that will append values // append_data is an option map object that will append values
// to every row. for example, if append_data = {"subject": 4}, // to every row. for example, if append_data = {"subject": 4},
// then a column called subject will be added to the data and // then a column called subject will be added to the data and
// it will always have the value 4. // it will always have the value 4.
module.dataAsCSV = function(append_data) { module.dataAsCSV = function(append_data) {
var dataObj = jsPsych.data(); var dataObj = module.getData();
return JSON2CSV(flattenData(dataObj, append_data)); return JSON2CSV(flattenData(dataObj, append_data));
}; };
@ -349,18 +536,18 @@
var data_string; var data_string;
if (format == 'JSON' || format == 'json') { if (format == 'JSON' || format == 'json') {
data_string = JSON.stringify(flattenData(jsPsych.data(), append_data)); data_string = JSON.stringify(flattenData(module.getData(), append_data));
} else if (format == 'CSV' || format == 'csv') { } else if (format == 'CSV' || format == 'csv') {
data_string = module.dataAsCSV(append_data); data_string = module.dataAsCSV(append_data);
} else { } else {
throw new Error('invalid format specified for jsPsych.dataAPI.localSave'); throw new Error('invalid format specified for jsPsych.data.localSave');
} }
saveTextToFile(data_string, filename); saveTextToFile(data_string, filename);
}; };
module.getTrialsOfType = function(trial_type) { module.getTrialsOfType = function(trial_type) {
var data = jsPsych.data(); var data = module.getData();
data = flatten(data); data = flatten(data);
@ -374,6 +561,21 @@
return trials; return trials;
}; };
module.getTrialsFromChunk = function(chunk_id) {
var data = module.getData();
data = flatten(data);
var trials = [];
for (var i = 0; i < data.length; i++) {
if (data[i].internal_chunk_id.slice(0, chunk_id.length) === chunk_id) { // TODO: change this to starts with
trials.push(data[i]);
}
}
return trials;
}
module.displayData = function(format) { module.displayData = function(format) {
format = (typeof format === 'undefined') ? "json" : format.toLowerCase(); format = (typeof format === 'undefined') ? "json" : format.toLowerCase();
if (format != "json" && format != "csv") { if (format != "json" && format != "csv") {
@ -384,7 +586,7 @@
var data_string; var data_string;
if (format == 'json') { if (format == 'json') {
data_string = JSON.stringify(flattenData(jsPsych.data()), undefined, 1); data_string = JSON.stringify(flattenData(module.getData()), undefined, 1);
} else { } else {
data_string = module.dataAsCSV(); data_string = module.dataAsCSV();
} }
@ -397,6 +599,7 @@
} }
// private function to save text file on local drive // private function to save text file on local drive
function saveTextToFile(textstr, filename) { function saveTextToFile(textstr, filename) {
var blobToSave = new Blob([textstr], { var blobToSave = new Blob([textstr], {
type: 'text/plain' type: 'text/plain'
@ -404,8 +607,7 @@
var blobURL = ""; var blobURL = "";
if (typeof window.webkitURL !== 'undefined') { if (typeof window.webkitURL !== 'undefined') {
blobURL = window.webkitURL.createObjectURL(blobToSave); blobURL = window.webkitURL.createObjectURL(blobToSave);
} } else {
else {
blobURL = window.URL.createObjectURL(blobToSave); blobURL = window.URL.createObjectURL(blobToSave);
} }
@ -426,6 +628,7 @@
// //
// A few helper functions to handle data format conversion // A few helper functions to handle data format conversion
// //
function flattenData(data_object, append_data) { function flattenData(data_object, append_data) {
append_data = (typeof append_data === undefined) ? {} : append_data; append_data = (typeof append_data === undefined) ? {} : append_data;
@ -446,6 +649,7 @@
// this function based on code suggested by StackOverflow users: // this function based on code suggested by StackOverflow users:
// http://stackoverflow.com/users/64741/zachary // http://stackoverflow.com/users/64741/zachary
// http://stackoverflow.com/users/317/joseph-sturtevant // http://stackoverflow.com/users/317/joseph-sturtevant
function JSON2CSV(objArray) { function JSON2CSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray; var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var line = ''; var line = '';
@ -609,7 +813,9 @@
var out = shuffle(allsamples); var out = shuffle(allsamples);
if(unpack) { out = unpackArray(out); } if (unpack) {
out = unpackArray(out);
}
return shuffle(out); return shuffle(out);
} }
@ -663,7 +869,8 @@
} }
function shuffle(array) { function shuffle(array) {
var m = array.length, t, i; var m = array.length,
t, i;
// While there remain elements to shuffle… // While there remain elements to shuffle…
while (m) { while (m) {
@ -766,7 +973,10 @@
$(document).keydown(listener_function); $(document).keydown(listener_function);
// create listener id object // create listener id object
listener_id = {type: 'keydown', fn: listener_function}; listener_id = {
type: 'keydown',
fn: listener_function
};
// add this keyboard listener to the list of listeners // add this keyboard listener to the list of listeners
keyboard_listeners.push(listener_id); keyboard_listeners.push(listener_id);
@ -939,8 +1149,7 @@
if (typeof trial[keys[i]] == "function" && process) { if (typeof trial[keys[i]] == "function" && process) {
tmp[keys[i]] = trial[keys[i]].call(); tmp[keys[i]] = trial[keys[i]].call();
} } else {
else {
tmp[keys[i]] = trial[keys[i]]; tmp[keys[i]] = trial[keys[i]];
} }
@ -984,13 +1193,13 @@
// methods used in multiple modules // methods used in multiple modules
// private function to flatten nested arrays // private function to flatten nested arrays
function flatten(arr, out) { function flatten(arr, out) {
out = (typeof out === 'undefined') ? [] : out; out = (typeof out === 'undefined') ? [] : out;
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) { if (Array.isArray(arr[i])) {
flatten(arr[i], out); flatten(arr[i], out);
} } else {
else {
out.push(arr[i]); out.push(arr[i]);
} }
} }

View File

@ -27,7 +27,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -114,17 +114,17 @@
jsPsych.pluginAPI.cancelKeyboardResponse(response_listener); jsPsych.pluginAPI.cancelKeyboardResponse(response_listener);
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"animation_sequence": JSON.stringify(animation_sequence), "animation_sequence": JSON.stringify(animation_sequence),
"responses": JSON.stringify(responses) "responses": JSON.stringify(responses)
}, trial.data)); }, trial.data));
if(trial.timing_post_trial > 0){ if(trial.timing_post_trial > 0){
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
} }
}; };

View File

@ -21,15 +21,15 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
var return_val = trial.func.apply({}, [trial.args]); var return_val = trial.func.apply({}, [trial.args]);
if (typeof return_val !== 'undefined') { if (typeof return_val !== 'undefined') {
block.writeData($.extend({},{ jsPsych.data.write($.extend({},{
value: return_val value: return_val
},trial.data)); },trial.data));
} }
block.next(); jsPsych.finishTrial();
}; };
return plugin; return plugin;

View File

@ -32,7 +32,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -135,7 +135,7 @@
"key_press": info.key "key_press": info.key
}; };
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
jsPsych.pluginAPI.cancelKeyboardResponse(keyboard_listener); jsPsych.pluginAPI.cancelKeyboardResponse(keyboard_listener);
@ -148,10 +148,10 @@
display_element.html(''); // clear everything display_element.html(''); // clear everything
if(trial.timing_post_trial > 0){ if(trial.timing_post_trial > 0){
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
} }
}; };

View File

@ -37,7 +37,7 @@
var cat_trial_complete = false; var cat_trial_complete = false;
plugin.trial = function(display_element, block, trial, part) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -95,7 +95,7 @@
"key_press": info.key "key_press": info.key
}; };
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
display_element.html(''); display_element.html('');
@ -157,10 +157,10 @@
display_element.html(""); display_element.html("");
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
} }

View File

@ -31,7 +31,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -116,7 +116,7 @@
}); });
}); });
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"init_locations": JSON.stringify(init_locations), "init_locations": JSON.stringify(init_locations),
"moves": JSON.stringify(moves), "moves": JSON.stringify(moves),
"final_locations": JSON.stringify(final_locations), "final_locations": JSON.stringify(final_locations),
@ -127,11 +127,11 @@
display_element.html(""); display_element.html("");
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} }
else { else {
block.next(); jsPsych.finishTrial();
} }
} }
})); }));

View File

@ -29,7 +29,7 @@ documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-html
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -46,7 +46,7 @@ documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-html
var finish = function() { var finish = function() {
if (trial.check_fn && !trial.check_fn(display_element)) return; if (trial.check_fn && !trial.check_fn(display_element)) return;
if (trial.cont_key) $(document).unbind('keydown', key_listener); if (trial.cont_key) $(document).unbind('keydown', key_listener);
block.writeData({ jsPsych.data.write({
rt: (new Date()).getTime() - t0, rt: (new Date()).getTime() - t0,
url: trial.url url: trial.url
}); });
@ -56,12 +56,12 @@ documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-html
setTimeout(function() { setTimeout(function() {
display_element.empty(); display_element.empty();
display_element.show(); display_element.show();
block.next(); jsPsych.finishTrial();
}, trial.timing); }, trial.timing);
} }
else { else {
display_element.empty(); display_element.empty();
block.next(); jsPsych.finishTrial();
} }
}; };
if (trial.cont_btn) $('#' + trial.cont_btn).click(finish); if (trial.cont_btn) $('#' + trial.cont_btn).click(finish);

View File

@ -43,7 +43,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -257,7 +257,7 @@
var n_diff = arrayDifferences(trial.configurations, lineIsVisible); var n_diff = arrayDifferences(trial.configurations, lineIsVisible);
var correct = (n_diff === 0); var correct = (n_diff === 0);
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"configuration": JSON.stringify(lineIsVisible), "configuration": JSON.stringify(lineIsVisible),
"target_configuration": JSON.stringify(trial.configurations), "target_configuration": JSON.stringify(trial.configurations),
"rt": response_time, "rt": response_time,
@ -302,11 +302,11 @@
// next trial // next trial
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} }
else { else {
block.next(); jsPsych.finishTrial();
} }
} }

View File

@ -37,7 +37,7 @@
var sd_trial_complete = false; var sd_trial_complete = false;
plugin.trial = function(display_element, block, trial, part) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -122,16 +122,16 @@
"stimulus_2": trial.b_path, "stimulus_2": trial.b_path,
"key_press": info.key "key_press": info.key
}; };
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
display_element.html(''); display_element.html('');
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
} }

View File

@ -40,7 +40,7 @@
var sim_trial_complete = false; var sim_trial_complete = false;
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -63,7 +63,7 @@
} }
if (trial.show_response == "FIRST_STIMULUS") { if (trial.show_response == "FIRST_STIMULUS") {
show_response_slider(display_element, trial, block); show_response_slider(display_element, trial);
} }
setTimeout(function() { setTimeout(function() {
@ -91,7 +91,7 @@
$('#jspsych_sim_stim').css('visibility', 'visible'); $('#jspsych_sim_stim').css('visibility', 'visible');
if (trial.show_response == "SECOND_STIMULUS") { if (trial.show_response == "SECOND_STIMULUS") {
show_response_slider(display_element, trial, block); show_response_slider(display_element, trial);
} }
if (trial.timing_second_stim > 0) { if (trial.timing_second_stim > 0) {
@ -99,7 +99,7 @@
if (!sim_trial_complete) { if (!sim_trial_complete) {
$("#jspsych_sim_stim").css('visibility', 'hidden'); $("#jspsych_sim_stim").css('visibility', 'hidden');
if (trial.show_response == "POST_STIMULUS") { if (trial.show_response == "POST_STIMULUS") {
show_response_slider(display_element, trial, block); show_response_slider(display_element, trial);
} }
} }
}, trial.timing_second_stim); }, trial.timing_second_stim);
@ -107,7 +107,7 @@
} }
function show_response_slider(display_element, trial, block) { function show_response_slider(display_element, trial) {
var startTime = (new Date()).getTime(); var startTime = (new Date()).getTime();
@ -195,7 +195,7 @@
var response_time = endTime - startTime; var response_time = endTime - startTime;
sim_trial_complete = true; sim_trial_complete = true;
var score = $("#slider").slider("value"); var score = $("#slider").slider("value");
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"sim_score": score, "sim_score": score,
"rt": response_time, "rt": response_time,
"stimulus": trial.a_path, "stimulus": trial.a_path,
@ -205,10 +205,10 @@
display_element.html(''); display_element.html('');
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
}); });
} }

View File

@ -38,7 +38,7 @@
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -85,7 +85,7 @@
"key_press": info.key "key_press": info.key
}; };
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
// clear the display // clear the display
display_element.html(''); display_element.html('');
@ -93,10 +93,10 @@
// move on to the next trial // move on to the next trial
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
}; };

View File

@ -29,7 +29,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -143,7 +143,7 @@
}); });
// save data // save data
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"rt": response_time "rt": response_time
}, question_data, trial.data)); }, question_data, trial.data));
@ -151,9 +151,9 @@
// next trial // next trial
if(trial.timing_post_trial > 0){ if(trial.timing_post_trial > 0){
setTimeout(function(){ block.next(); }, trial.timing_post_trial); setTimeout(function(){ jsPsych.finishTrial(); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
}); });

View File

@ -26,7 +26,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -70,7 +70,7 @@
}); });
// save data // save data
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"rt": response_time "rt": response_time
}, question_data, trial.data)); }, question_data, trial.data));
@ -78,9 +78,9 @@
// next trial // next trial
if(trial.timing_post_trial > 0){ if(trial.timing_post_trial > 0){
setTimeout(function(){ block.next(); }, trial.timing_post_trial); setTimeout(function(){ jsPsych.finishTrial(); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
}); });

View File

@ -27,7 +27,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -45,12 +45,12 @@
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} }
else { else {
block.next(); jsPsych.finishTrial();
} // call block.next() to advance the experiment after a delay. }
}; };
@ -73,7 +73,7 @@
} }
function save_data(key, rt) { function save_data(key, rt) {
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"rt": rt, "rt": rt,
"key_press": key "key_press": key
}, trial.data)); }, trial.data));

View File

@ -41,7 +41,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
trial = jsPsych.pluginAPI.normalizeTrialVariables(trial); trial = jsPsych.pluginAPI.normalizeTrialVariables(trial);
@ -169,15 +169,15 @@
// this line merges together the trial_data object and the generic // this line merges together the trial_data object and the generic
// data object (trial.data), and then stores them. // data object (trial.data), and then stores them.
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
// go to next trial // go to next trial
if(trial.timing_post_trial > 0){ if(trial.timing_post_trial > 0){
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
} }
}; };

View File

@ -35,7 +35,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -144,18 +144,18 @@
jsPsych.pluginAPI.cancelKeyboardResponse(key_listener); jsPsych.pluginAPI.cancelKeyboardResponse(key_listener);
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"stimuli": JSON.stringify(trial.stims), "stimuli": JSON.stringify(trial.stims),
"responses": JSON.stringify(responses) "responses": JSON.stringify(responses)
}, trial.data)); }, trial.data));
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} }
else { else {
block.next(); jsPsych.finishTrial();
} }
} }
}; };

View File

@ -31,7 +31,7 @@
return trials; return trials;
}; };
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -48,17 +48,17 @@
display_element.html(''); display_element.html('');
block.writeData($.extend({}, { jsPsych.data.write($.extend({}, {
"stimuli": JSON.stringify(trial.stimuli) "stimuli": JSON.stringify(trial.stimuli)
}, trial.data)); }, trial.data));
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} }
else { else {
block.next(); jsPsych.finishTrial();
} }
} }
}; };

View File

@ -48,7 +48,7 @@
var xab_trial_complete = false; var xab_trial_complete = false;
plugin.trial = function(display_element, block, trial) { plugin.trial = function(display_element, trial) {
// if any trial variables are functions // if any trial variables are functions
// this evaluates the function and replaces // this evaluates the function and replaces
@ -162,7 +162,7 @@
"stimulus_b": trial.b_path, "stimulus_b": trial.b_path,
"key_press": info.key "key_press": info.key
}; };
block.writeData($.extend({}, trial_data, trial.data)); jsPsych.data.write($.extend({}, trial_data, trial.data));
display_element.html(''); // remove all display_element.html(''); // remove all
@ -171,10 +171,10 @@
// move on to the next trial after timing_post_trial milliseconds // move on to the next trial after timing_post_trial milliseconds
if (trial.timing_post_trial > 0) { if (trial.timing_post_trial > 0) {
setTimeout(function() { setTimeout(function() {
block.next(); jsPsych.finishTrial();
}, trial.timing_post_trial); }, trial.timing_post_trial);
} else { } else {
block.next(); jsPsych.finishTrial();
} }
}; };