A copy is also included in PsychBench in <PsychBench folder>/demos, so you can run it from there.
<cdcm>% SCANNER, SYNC IN EACH BLOCK, JITTERED INTER-STIMULUS INTERVAL DEMO<cdcm>
<cdcm>% Coding method<cdcm>
<cdcm>% --------------------------------------------------<cdcm>
<cdcm>% Same as scannerSyncInBlocksDemo.m except here we randomly jitter<cdcm>
<cdcm>% inter-stimulus interval (from start of one stimulus to start of the next<cdcm>
<cdcm>% stimulus) from 5, 6, 7, 8 sec, counterbalanced within two blocks of 12 trials<cdcm>
<cdcm>% each. We run two blocks and sync with the scanner before each one.<cdcm>
<cdcm>% See scannerSyncInBlocksDemo.m for more commenting.<cdcm>
<cdcm>% Mark start of experiment script<cdcm>
newExperiment
<cdcm>% Define trial containing keyPress object to register trigger and sync experiment<cdcm>
<cdcm>% -<cdcm>
<cdcm>% Simulate trigger by key press for this tutorial.<cdcm>
<cdcm>% Many scanners send triggers as key presses, in which case would use a keyPress object in a real experiment too.<cdcm>
<cdcm>% By default listens for any key (could be changed in property .listenKeyNames).<cdcm>
syncer = keyPressObject;
<cdcm>% Listen for key press from default keyboard just for this demo.<cdcm>
<cdcm>% In a real experiment would need to set this to point to whatever device the trigger is coming from.<cdcm>
syncer.n_device = [];
<cdcm>% Register input as a trigger instead of response from subject<cdcm>
syncer.registerTrigger = true;
<cdcm>% Sync experiment at trigger so can set subsequent trials to start at times from sync<cdcm>
syncer.syncExperiment = true;
<cdcm>% Default start at trial start.<cdcm>
<cdcm>% By default keyPress elements end when they record a trigger/response -> don't need to set .end.<cdcm>
<cdcm>% Report sync time ( = trigger time)<cdcm>
syncer.report = <cdsm>"syncTime"<cdsm>;
addTrial(syncer, <cdsm>"sync"<cdsm>);
<cdcm>% -<cdcm>
fileNames = [<cdsm>"sphere.png"<cdsm> <cdsm>"cube.png"<cdsm> <cdsm>"hourglass.png"<cdsm>];
<cdcm>% 2 blocks of task trials.<cdcm>
<cdcm>% Each trial that runs in the experiment needs its own trial definition since<cdcm>
<cdcm>% each has a different combination of picture file + value in trial object<cdcm>
<cdcm>% property .start (-> stimulus interval).<cdcm>
<cdkm>for<cdkm> n_block = 1:2
<cdcm>% 12 inter-stimulus interval offsets randomly sampled from 0, 1, 2, 3 sec, counterbalanced within the block.<cdcm>
<cdcm>% Random order here randomizes which offsets go with which picture trials.<cdcm>
isiOffsets = randomOrder(rep([0 1 2 3], 3));
<cdcm>% 12 trial definitions in the block: 3 pictures x 4 repetitions<cdcm>
n_trialInBlock = 0;
<cdkm>for<cdkm> n_rep = 1:4
<cdkm>for<cdkm> f = 1:3
n_trialInBlock = n_trialInBlock+1;
<cdcm>% Picture stimulus<cdcm>
pic = pictureObject;
pic.fileName = fileNames(f);
pic.height = 8;
pic.end.response = true;
pic.report = [<cdsm>"fileName"<cdsm> <cdsm>"startTime"<cdsm>];
<cdcm>% Response handler - any key press from subject<cdcm>
recorder = keyPressObject;
recorder.report = <cdsm>"responseTime"<cdsm>;
<cdcm>% Set trial to start at fixed time relative to sync in a past trial using trial object property .start field .t_sync.<cdcm>
<cdcm>% Base 0.75 sec from sync if this is the first trial to run after it, 5 sec increments for subsequent trials.<cdcm>
<cdcm>% Then + random offset for the trial.<cdcm>
<cdcm>% So last trial in block always starts 0.75 + 11*5 + 3*0 + 3*1 + 3*2 + 3*3 = 73.75 sec from the block's sync.<cdcm>
trial = trialObject;
trial.start.t_sync = [0.75 5]+isiOffsets(n_trialInBlock);
<cdcm>% Add trial definition with default numbering (1, 2, 3, ...)<cdcm>
addTrial(pic, recorder, trial);
<cdkm>end<cdkm>
<cdkm>end<cdkm>
<cdkm>end<cdkm>
<cdcm>% Set trial list: sync, block, sync, block.<cdcm>
<cdcm>% Random order here randomizes order of picture trials.<cdcm>
nn = {<cdsm>"sync"<cdsm> randomOrder(1:12) <cdsm>"sync"<cdsm> randomOrder(13:24)};
setTrialList(nn)
<cdcm>% Run<cdcm>
[results, resultsMatrix] = runExperiment;