diff --git a/N-back.psyexp b/N-back.psyexp
index 18b0a53f411f484952a71ce70bf8630daff3bd9b..bfdc7569bbf89e0d7aaa826300f7d1ebbecc981b 100644
--- a/N-back.psyexp
+++ b/N-back.psyexp
@@ -140,7 +140,7 @@
-
+
@@ -149,7 +149,7 @@
-
+
@@ -162,10 +162,10 @@
-
+
-
+
@@ -175,7 +175,7 @@
-
+
@@ -190,12 +190,12 @@
-
+
-
+
@@ -364,6 +364,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/N-back.py b/N-back.py
index b7ef03ffd82bd1a292263881d01e742ceeb47ae2..f890c862370e6305e2e306a7274375c205392378 100644
--- a/N-back.py
+++ b/N-back.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
This experiment was created using PsychoPy3 Experiment Builder (v2020.1.3),
- on May 13, 2020, at 14:12
+ on May 13, 2020, at 14:27
If you publish work using this script the most relevant publication is:
Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019)
diff --git a/N-backtest.psyexp b/N-backtest.psyexp
new file mode 100644
index 0000000000000000000000000000000000000000..d6d9f9d9905cf64e8c46b642627b7594b903baab
--- /dev/null
+++ b/N-backtest.psyexp
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/N-backtest-legacy-browsers.js b/html/N-backtest-legacy-browsers.js
new file mode 100644
index 0000000000000000000000000000000000000000..e3a2bc3cde6278c1207aa88ed2adf780be16a7f7
--- /dev/null
+++ b/html/N-backtest-legacy-browsers.js
@@ -0,0 +1,370 @@
+/*******************
+ * N-Backtest Test *
+ *******************/
+
+// init psychoJS:
+const psychoJS = new PsychoJS({
+ debug: true
+});
+
+// open window:
+psychoJS.openWindow({
+ fullscr: true,
+ color: new util.Color([0, 0, 0]),
+ units: 'height',
+ waitBlanking: true
+});
+
+// store info about the experiment session:
+let expName = 'N-backtest'; // from the Builder filename that created this script
+let expInfo = {'participant': '', 'session': '001'};
+
+// schedule the experiment:
+psychoJS.schedule(psychoJS.gui.DlgFromDict({
+ dictionary: expInfo,
+ title: expName
+}));
+
+const flowScheduler = new Scheduler(psychoJS);
+const dialogCancelScheduler = new Scheduler(psychoJS);
+psychoJS.scheduleCondition(function() { return (psychoJS.gui.dialogComponent.button === 'OK'); }, flowScheduler, dialogCancelScheduler);
+
+// flowScheduler gets run if the participants presses OK
+flowScheduler.add(updateInfo); // add timeStamp
+flowScheduler.add(experimentInit);
+const trialsLoopScheduler = new Scheduler(psychoJS);
+flowScheduler.add(trialsLoopBegin, trialsLoopScheduler);
+flowScheduler.add(trialsLoopScheduler);
+flowScheduler.add(trialsLoopEnd);
+flowScheduler.add(quitPsychoJS, '', true);
+
+// quit if user presses Cancel in dialog box:
+dialogCancelScheduler.add(quitPsychoJS, '', false);
+
+psychoJS.start({
+ expName: expName,
+ expInfo: expInfo,
+ });
+
+
+var frameDur;
+function updateInfo() {
+ expInfo['date'] = util.MonotonicClock.getDateStr(); // add a simple timestamp
+ expInfo['expName'] = expName;
+ expInfo['psychopyVersion'] = '2020.1.3';
+ expInfo['OS'] = window.navigator.platform;
+
+ // store frame rate of monitor if we can measure it successfully
+ expInfo['frameRate'] = psychoJS.window.getActualFrameRate();
+ if (typeof expInfo['frameRate'] !== 'undefined')
+ frameDur = 1.0 / Math.round(expInfo['frameRate']);
+ else
+ frameDur = 1.0 / 60.0; // couldn't get a reliable measure so guess
+
+ // add info from the URL:
+ util.addInfoFromUrl(expInfo);
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var trialClock;
+var grid_lines;
+var target_square;
+var fixation_2;
+var response;
+var globalClock;
+var routineTimer;
+function experimentInit() {
+ // Initialize components for Routine "trial"
+ trialClock = new util.Clock();
+ grid_lines = new visual.ImageStim({
+ win : psychoJS.window,
+ name : 'grid_lines', units : undefined,
+ image : 'grid.png', mask : undefined,
+ ori : 0, pos : [0, 0], size : [0.5, 0.5],
+ color : new util.Color([1, 1, 1]), opacity : 1,
+ flipHoriz : false, flipVert : false,
+ texRes : 128, interpolate : true, depth : 0.0
+ });
+ target_square = new visual.Rect ({
+ win: psychoJS.window, name: 'target_square',
+ width: [0.15, 0.15][0], height: [0.15, 0.15][1],
+ ori: 0, pos: [0, 0],
+ lineWidth: 1, lineColor: new util.Color([1, 1, 1]),
+ fillColor: new util.Color([1, 1, 1]),
+ opacity: 1, depth: -1, interpolate: true,
+ });
+
+ fixation_2 = new visual.TextStim({
+ win: psychoJS.window,
+ name: 'fixation_2',
+ text: '+',
+ font: 'Arial',
+ units: undefined,
+ pos: [0, 0], height: 0.05, wrapWidth: undefined, ori: 0,
+ color: new util.Color('white'), opacity: 1,
+ depth: -2.0
+ });
+
+ response = new core.Keyboard({psychoJS: psychoJS, clock: new util.Clock(), waitForStart: true});
+
+ // Create some handy timers
+ globalClock = new util.Clock(); // to track the time since experiment started
+ routineTimer = new util.CountdownTimer(); // to track time remaining of each (non-slip) routine
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var trials;
+var currentLoop;
+function trialsLoopBegin(thisScheduler) {
+ // set up handler to look after randomisation of conditions etc
+ trials = new TrialHandler({
+ psychoJS: psychoJS,
+ nReps: 5, method: TrialHandler.Method.RANDOM,
+ extraInfo: expInfo, originPath: undefined,
+ trialList: '../../Users/Ryan/Downloads/PavloviaNback/N-back-1.xlsx',
+ seed: undefined, name: 'trials'
+ });
+ psychoJS.experiment.addLoop(trials); // add the loop to the experiment
+ currentLoop = trials; // we're now the current loop
+
+ // Schedule all the trials in the trialList:
+ trials.forEach(function() {
+ const snapshot = trials.getSnapshot();
+
+ thisScheduler.add(importConditions(snapshot));
+ thisScheduler.add(trialRoutineBegin(snapshot));
+ thisScheduler.add(trialRoutineEachFrame(snapshot));
+ thisScheduler.add(trialRoutineEnd(snapshot));
+ thisScheduler.add(endLoopIteration(thisScheduler, snapshot));
+ });
+
+ return Scheduler.Event.NEXT;
+}
+
+
+function trialsLoopEnd() {
+ psychoJS.experiment.removeLoop(trials);
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var t;
+var frameN;
+var _response_allKeys;
+var trialComponents;
+function trialRoutineBegin(trials) {
+ return function () {
+ //------Prepare to start Routine 'trial'-------
+ t = 0;
+ trialClock.reset(); // clock
+ frameN = -1;
+ routineTimer.add(2.000000);
+ // update component parameters for each repeat
+ target_square.setPos(location);
+ response.keys = undefined;
+ response.rt = undefined;
+ _response_allKeys = [];
+ // keep track of which components have finished
+ trialComponents = [];
+ trialComponents.push(grid_lines);
+ trialComponents.push(target_square);
+ trialComponents.push(fixation_2);
+ trialComponents.push(response);
+
+ trialComponents.forEach( function(thisComponent) {
+ if ('status' in thisComponent)
+ thisComponent.status = PsychoJS.Status.NOT_STARTED;
+ });
+
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+var frameRemains;
+var continueRoutine;
+function trialRoutineEachFrame(trials) {
+ return function () {
+ //------Loop for each frame of Routine 'trial'-------
+ let continueRoutine = true; // until we're told otherwise
+ // get current time
+ t = trialClock.getTime();
+ frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
+ // update/draw components on each frame
+
+ // *grid_lines* updates
+ if (t >= 0.0 && grid_lines.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ grid_lines.tStart = t; // (not accounting for frame time here)
+ grid_lines.frameNStart = frameN; // exact frame index
+
+ grid_lines.setAutoDraw(true);
+ }
+
+ frameRemains = 0.0 + 2.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (grid_lines.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ grid_lines.setAutoDraw(false);
+ }
+
+ // *target_square* updates
+ if (t >= 0.0 && target_square.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ target_square.tStart = t; // (not accounting for frame time here)
+ target_square.frameNStart = frameN; // exact frame index
+
+ target_square.setAutoDraw(true);
+ }
+
+ frameRemains = 0.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (target_square.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ target_square.setAutoDraw(false);
+ }
+
+ // *fixation_2* updates
+ if (t >= 1.0 && fixation_2.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ fixation_2.tStart = t; // (not accounting for frame time here)
+ fixation_2.frameNStart = frameN; // exact frame index
+
+ fixation_2.setAutoDraw(true);
+ }
+
+ frameRemains = 1.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (fixation_2.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ fixation_2.setAutoDraw(false);
+ }
+
+ // *response* updates
+ if (t >= 0.0 && response.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ response.tStart = t; // (not accounting for frame time here)
+ response.frameNStart = frameN; // exact frame index
+
+ // keyboard checking is just starting
+ psychoJS.window.callOnFlip(function() { response.clock.reset(); }); // t=0 on next screen flip
+ psychoJS.window.callOnFlip(function() { response.start(); }); // start on screen flip
+ psychoJS.window.callOnFlip(function() { response.clearEvents(); });
+ }
+
+ frameRemains = 0.0 + 2.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (response.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ response.status = PsychoJS.Status.FINISHED;
+ }
+
+ if (response.status === PsychoJS.Status.STARTED) {
+ let theseKeys = response.getKeys({keyList: ['space'], waitRelease: false});
+ _response_allKeys = _response_allKeys.concat(theseKeys);
+ if (_response_allKeys.length > 0) {
+ response.keys = _response_allKeys[_response_allKeys.length - 1].name; // just the last key pressed
+ response.rt = _response_allKeys[_response_allKeys.length - 1].rt;
+ // was this correct?
+ if (response.keys == corrAns) {
+ response.corr = 1;
+ } else {
+ response.corr = 0;
+ }
+ }
+ }
+
+ // check for quit (typically the Esc key)
+ if (psychoJS.experiment.experimentEnded || psychoJS.eventManager.getKeys({keyList:['escape']}).length > 0) {
+ return quitPsychoJS('The [Escape] key was pressed. Goodbye!', false);
+ }
+
+ // check if the Routine should terminate
+ if (!continueRoutine) { // a component has requested a forced-end of Routine
+ return Scheduler.Event.NEXT;
+ }
+
+ continueRoutine = false; // reverts to True if at least one component still running
+ trialComponents.forEach( function(thisComponent) {
+ if ('status' in thisComponent && thisComponent.status !== PsychoJS.Status.FINISHED) {
+ continueRoutine = true;
+ }
+ });
+
+ // refresh the screen if continuing
+ if (continueRoutine && routineTimer.getTime() > 0) {
+ return Scheduler.Event.FLIP_REPEAT;
+ } else {
+ return Scheduler.Event.NEXT;
+ }
+ };
+}
+
+
+function trialRoutineEnd(trials) {
+ return function () {
+ //------Ending Routine 'trial'-------
+ trialComponents.forEach( function(thisComponent) {
+ if (typeof thisComponent.setAutoDraw === 'function') {
+ thisComponent.setAutoDraw(false);
+ }
+ });
+ // was no response the correct answer?!
+ if (response.keys === undefined) {
+ if (['None','none',undefined].includes(corrAns)) {
+ response.corr = 1; // correct non-response
+ } else {
+ response.corr = 0; // failed to respond (incorrectly)
+ }
+ }
+ // store data for thisExp (ExperimentHandler)
+ psychoJS.experiment.addData('response.keys', response.keys);
+ psychoJS.experiment.addData('response.corr', response.corr);
+ if (typeof response.keys !== 'undefined') { // we had a response
+ psychoJS.experiment.addData('response.rt', response.rt);
+ }
+
+ response.stop();
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+function endLoopIteration(thisScheduler, loop) {
+ // ------Prepare for next entry------
+ return function () {
+ if (typeof loop !== 'undefined') {
+ // ------Check if user ended loop early------
+ if (loop.finished) {
+ // Check for and save orphaned data
+ if (psychoJS.experiment.isEntryEmpty()) {
+ psychoJS.experiment.nextEntry(loop);
+ }
+ thisScheduler.stop();
+ } else {
+ const thisTrial = loop.getCurrentTrial();
+ if (typeof thisTrial === 'undefined' || !('isTrials' in thisTrial) || thisTrial.isTrials) {
+ psychoJS.experiment.nextEntry(loop);
+ }
+ }
+ return Scheduler.Event.NEXT;
+ }
+ };
+}
+
+
+function importConditions(trials) {
+ return function () {
+ psychoJS.importAttributes(trials.getCurrentTrial());
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+function quitPsychoJS(message, isCompleted) {
+ // Check for and save orphaned data
+ if (psychoJS.experiment.isEntryEmpty()) {
+ psychoJS.experiment.nextEntry();
+ }
+ psychoJS.window.close();
+ psychoJS.quit({message: message, isCompleted: isCompleted});
+
+ return Scheduler.Event.QUIT;
+}
diff --git a/html/N-backtest.js b/html/N-backtest.js
new file mode 100644
index 0000000000000000000000000000000000000000..b8abcf13e24abbf82786bf0e565e55cf9916e217
--- /dev/null
+++ b/html/N-backtest.js
@@ -0,0 +1,376 @@
+/*******************
+ * N-Backtest Test *
+ *******************/
+
+import { PsychoJS } from './lib/core-2020.1.js';
+import * as core from './lib/core-2020.1.js';
+import { TrialHandler } from './lib/data-2020.1.js';
+import { Scheduler } from './lib/util-2020.1.js';
+import * as util from './lib/util-2020.1.js';
+import * as visual from './lib/visual-2020.1.js';
+import * as sound from './lib/sound-2020.1.js';
+
+// init psychoJS:
+const psychoJS = new PsychoJS({
+ debug: true
+});
+
+// open window:
+psychoJS.openWindow({
+ fullscr: true,
+ color: new util.Color([0, 0, 0]),
+ units: 'height',
+ waitBlanking: true
+});
+
+// store info about the experiment session:
+let expName = 'N-backtest'; // from the Builder filename that created this script
+let expInfo = {'participant': '', 'session': '001'};
+
+// schedule the experiment:
+psychoJS.schedule(psychoJS.gui.DlgFromDict({
+ dictionary: expInfo,
+ title: expName
+}));
+
+const flowScheduler = new Scheduler(psychoJS);
+const dialogCancelScheduler = new Scheduler(psychoJS);
+psychoJS.scheduleCondition(function() { return (psychoJS.gui.dialogComponent.button === 'OK'); }, flowScheduler, dialogCancelScheduler);
+
+// flowScheduler gets run if the participants presses OK
+flowScheduler.add(updateInfo); // add timeStamp
+flowScheduler.add(experimentInit);
+const trialsLoopScheduler = new Scheduler(psychoJS);
+flowScheduler.add(trialsLoopBegin, trialsLoopScheduler);
+flowScheduler.add(trialsLoopScheduler);
+flowScheduler.add(trialsLoopEnd);
+flowScheduler.add(quitPsychoJS, '', true);
+
+// quit if user presses Cancel in dialog box:
+dialogCancelScheduler.add(quitPsychoJS, '', false);
+
+psychoJS.start({
+ expName: expName,
+ expInfo: expInfo,
+ });
+
+
+var frameDur;
+function updateInfo() {
+ expInfo['date'] = util.MonotonicClock.getDateStr(); // add a simple timestamp
+ expInfo['expName'] = expName;
+ expInfo['psychopyVersion'] = '2020.1.3';
+ expInfo['OS'] = window.navigator.platform;
+
+ // store frame rate of monitor if we can measure it successfully
+ expInfo['frameRate'] = psychoJS.window.getActualFrameRate();
+ if (typeof expInfo['frameRate'] !== 'undefined')
+ frameDur = 1.0 / Math.round(expInfo['frameRate']);
+ else
+ frameDur = 1.0 / 60.0; // couldn't get a reliable measure so guess
+
+ // add info from the URL:
+ util.addInfoFromUrl(expInfo);
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var trialClock;
+var grid_lines;
+var target_square;
+var fixation_2;
+var response;
+var globalClock;
+var routineTimer;
+function experimentInit() {
+ // Initialize components for Routine "trial"
+ trialClock = new util.Clock();
+ grid_lines = new visual.ImageStim({
+ win : psychoJS.window,
+ name : 'grid_lines', units : undefined,
+ image : 'grid.png', mask : undefined,
+ ori : 0, pos : [0, 0], size : [0.5, 0.5],
+ color : new util.Color([1, 1, 1]), opacity : 1,
+ flipHoriz : false, flipVert : false,
+ texRes : 128, interpolate : true, depth : 0.0
+ });
+ target_square = new visual.Rect ({
+ win: psychoJS.window, name: 'target_square',
+ width: [0.15, 0.15][0], height: [0.15, 0.15][1],
+ ori: 0, pos: [0, 0],
+ lineWidth: 1, lineColor: new util.Color([1, 1, 1]),
+ fillColor: new util.Color([1, 1, 1]),
+ opacity: 1, depth: -1, interpolate: true,
+ });
+
+ fixation_2 = new visual.TextStim({
+ win: psychoJS.window,
+ name: 'fixation_2',
+ text: '+',
+ font: 'Arial',
+ units: undefined,
+ pos: [0, 0], height: 0.05, wrapWidth: undefined, ori: 0,
+ color: new util.Color('white'), opacity: 1,
+ depth: -2.0
+ });
+
+ response = new core.Keyboard({psychoJS: psychoJS, clock: new util.Clock(), waitForStart: true});
+
+ // Create some handy timers
+ globalClock = new util.Clock(); // to track the time since experiment started
+ routineTimer = new util.CountdownTimer(); // to track time remaining of each (non-slip) routine
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var trials;
+var currentLoop;
+function trialsLoopBegin(thisScheduler) {
+ // set up handler to look after randomisation of conditions etc
+ trials = new TrialHandler({
+ psychoJS: psychoJS,
+ nReps: 5, method: TrialHandler.Method.RANDOM,
+ extraInfo: expInfo, originPath: undefined,
+ trialList: '../../Users/Ryan/Downloads/PavloviaNback/N-back-1.xlsx',
+ seed: undefined, name: 'trials'
+ });
+ psychoJS.experiment.addLoop(trials); // add the loop to the experiment
+ currentLoop = trials; // we're now the current loop
+
+ // Schedule all the trials in the trialList:
+ for (const thisTrial of trials) {
+ const snapshot = trials.getSnapshot();
+ thisScheduler.add(importConditions(snapshot));
+ thisScheduler.add(trialRoutineBegin(snapshot));
+ thisScheduler.add(trialRoutineEachFrame(snapshot));
+ thisScheduler.add(trialRoutineEnd(snapshot));
+ thisScheduler.add(endLoopIteration(thisScheduler, snapshot));
+ }
+
+ return Scheduler.Event.NEXT;
+}
+
+
+function trialsLoopEnd() {
+ psychoJS.experiment.removeLoop(trials);
+
+ return Scheduler.Event.NEXT;
+}
+
+
+var t;
+var frameN;
+var _response_allKeys;
+var trialComponents;
+function trialRoutineBegin(trials) {
+ return function () {
+ //------Prepare to start Routine 'trial'-------
+ t = 0;
+ trialClock.reset(); // clock
+ frameN = -1;
+ routineTimer.add(2.000000);
+ // update component parameters for each repeat
+ target_square.setPos(location);
+ response.keys = undefined;
+ response.rt = undefined;
+ _response_allKeys = [];
+ // keep track of which components have finished
+ trialComponents = [];
+ trialComponents.push(grid_lines);
+ trialComponents.push(target_square);
+ trialComponents.push(fixation_2);
+ trialComponents.push(response);
+
+ for (const thisComponent of trialComponents)
+ if ('status' in thisComponent)
+ thisComponent.status = PsychoJS.Status.NOT_STARTED;
+
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+var frameRemains;
+var continueRoutine;
+function trialRoutineEachFrame(trials) {
+ return function () {
+ //------Loop for each frame of Routine 'trial'-------
+ let continueRoutine = true; // until we're told otherwise
+ // get current time
+ t = trialClock.getTime();
+ frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
+ // update/draw components on each frame
+
+ // *grid_lines* updates
+ if (t >= 0.0 && grid_lines.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ grid_lines.tStart = t; // (not accounting for frame time here)
+ grid_lines.frameNStart = frameN; // exact frame index
+
+ grid_lines.setAutoDraw(true);
+ }
+
+ frameRemains = 0.0 + 2.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (grid_lines.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ grid_lines.setAutoDraw(false);
+ }
+
+ // *target_square* updates
+ if (t >= 0.0 && target_square.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ target_square.tStart = t; // (not accounting for frame time here)
+ target_square.frameNStart = frameN; // exact frame index
+
+ target_square.setAutoDraw(true);
+ }
+
+ frameRemains = 0.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (target_square.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ target_square.setAutoDraw(false);
+ }
+
+ // *fixation_2* updates
+ if (t >= 1.0 && fixation_2.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ fixation_2.tStart = t; // (not accounting for frame time here)
+ fixation_2.frameNStart = frameN; // exact frame index
+
+ fixation_2.setAutoDraw(true);
+ }
+
+ frameRemains = 1.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (fixation_2.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ fixation_2.setAutoDraw(false);
+ }
+
+ // *response* updates
+ if (t >= 0.0 && response.status === PsychoJS.Status.NOT_STARTED) {
+ // keep track of start time/frame for later
+ response.tStart = t; // (not accounting for frame time here)
+ response.frameNStart = frameN; // exact frame index
+
+ // keyboard checking is just starting
+ psychoJS.window.callOnFlip(function() { response.clock.reset(); }); // t=0 on next screen flip
+ psychoJS.window.callOnFlip(function() { response.start(); }); // start on screen flip
+ psychoJS.window.callOnFlip(function() { response.clearEvents(); });
+ }
+
+ frameRemains = 0.0 + 2.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
+ if (response.status === PsychoJS.Status.STARTED && t >= frameRemains) {
+ response.status = PsychoJS.Status.FINISHED;
+ }
+
+ if (response.status === PsychoJS.Status.STARTED) {
+ let theseKeys = response.getKeys({keyList: ['space'], waitRelease: false});
+ _response_allKeys = _response_allKeys.concat(theseKeys);
+ if (_response_allKeys.length > 0) {
+ response.keys = _response_allKeys[_response_allKeys.length - 1].name; // just the last key pressed
+ response.rt = _response_allKeys[_response_allKeys.length - 1].rt;
+ // was this correct?
+ if (response.keys == corrAns) {
+ response.corr = 1;
+ } else {
+ response.corr = 0;
+ }
+ }
+ }
+
+ // check for quit (typically the Esc key)
+ if (psychoJS.experiment.experimentEnded || psychoJS.eventManager.getKeys({keyList:['escape']}).length > 0) {
+ return quitPsychoJS('The [Escape] key was pressed. Goodbye!', false);
+ }
+
+ // check if the Routine should terminate
+ if (!continueRoutine) { // a component has requested a forced-end of Routine
+ return Scheduler.Event.NEXT;
+ }
+
+ continueRoutine = false; // reverts to True if at least one component still running
+ for (const thisComponent of trialComponents)
+ if ('status' in thisComponent && thisComponent.status !== PsychoJS.Status.FINISHED) {
+ continueRoutine = true;
+ break;
+ }
+
+ // refresh the screen if continuing
+ if (continueRoutine && routineTimer.getTime() > 0) {
+ return Scheduler.Event.FLIP_REPEAT;
+ } else {
+ return Scheduler.Event.NEXT;
+ }
+ };
+}
+
+
+function trialRoutineEnd(trials) {
+ return function () {
+ //------Ending Routine 'trial'-------
+ for (const thisComponent of trialComponents) {
+ if (typeof thisComponent.setAutoDraw === 'function') {
+ thisComponent.setAutoDraw(false);
+ }
+ }
+ // was no response the correct answer?!
+ if (response.keys === undefined) {
+ if (['None','none',undefined].includes(corrAns)) {
+ response.corr = 1; // correct non-response
+ } else {
+ response.corr = 0; // failed to respond (incorrectly)
+ }
+ }
+ // store data for thisExp (ExperimentHandler)
+ psychoJS.experiment.addData('response.keys', response.keys);
+ psychoJS.experiment.addData('response.corr', response.corr);
+ if (typeof response.keys !== 'undefined') { // we had a response
+ psychoJS.experiment.addData('response.rt', response.rt);
+ }
+
+ response.stop();
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+function endLoopIteration(thisScheduler, loop) {
+ // ------Prepare for next entry------
+ return function () {
+ if (typeof loop !== 'undefined') {
+ // ------Check if user ended loop early------
+ if (loop.finished) {
+ // Check for and save orphaned data
+ if (psychoJS.experiment.isEntryEmpty()) {
+ psychoJS.experiment.nextEntry(loop);
+ }
+ thisScheduler.stop();
+ } else {
+ const thisTrial = loop.getCurrentTrial();
+ if (typeof thisTrial === 'undefined' || !('isTrials' in thisTrial) || thisTrial.isTrials) {
+ psychoJS.experiment.nextEntry(loop);
+ }
+ }
+ return Scheduler.Event.NEXT;
+ }
+ };
+}
+
+
+function importConditions(trials) {
+ return function () {
+ psychoJS.importAttributes(trials.getCurrentTrial());
+ return Scheduler.Event.NEXT;
+ };
+}
+
+
+function quitPsychoJS(message, isCompleted) {
+ // Check for and save orphaned data
+ if (psychoJS.experiment.isEntryEmpty()) {
+ psychoJS.experiment.nextEntry();
+ }
+ psychoJS.window.close();
+ psychoJS.quit({message: message, isCompleted: isCompleted});
+
+ return Scheduler.Event.QUIT;
+}
diff --git a/html/index.html b/html/index.html
index 53d2f8b2de719da33193b5b0297f859cb77b8d7c..0b3eef8382a809fc7d071f17bd9a268a548d4d80 100644
--- a/html/index.html
+++ b/html/index.html
@@ -2,7 +2,7 @@
- N-back [PsychoPy]
+ N-backtest [PsychoPy]
@@ -28,13 +28,13 @@
-
+
-
+