A copy is also included in PsychBench in <PsychBench folder>/demos, so you can run it from there.
<cdcm>% loadSheet(), randomBalance() CODING METHOD DEMO<cdcm>
<cdcm>% --------------------------------------------------<cdcm>
<cdcm>% In this demo we lay out condition values and other values for the experiment<cdcm>
<cdcm>% in table form in an Excel spreadsheet (loadSheetDemo.xlsx) and use the tool<cdcm>
<cdcm>% loadSheet() to read them into MATLAB variables which the experiment script<cdcm>
<cdcm>% uses. This semi-visual approach can be helpful for more complex experiments<cdcm>
<cdcm>% without losing the flexibility of the coding method. We also apply complex<cdcm>
<cdcm>% counterbalancing using the tool randomBalance().<cdcm>
<cdcm>%<cdcm>
<cdcm>% There are 40 trials, eaching showing a different stimulus. Each stimulus is a<cdcm>
<cdcm>% pair of point light display actors interacting. The stimulus repeats, with a<cdcm>
<cdcm>% 1 sec break between repetitions, until the experimenter presses any key. (In<cdcm>
<cdcm>% the real experiment this was based on, the experimenter asked the subject<cdcm>
<cdcm>% questions about the stimulus during its display and recorded answers<cdcm>
<cdcm>% externally.)<cdcm>
<cdcm>%<cdcm>
<cdcm>% The 40 stimuli are 2 different takes each of 20 interactions. Each interaction<cdcm>
<cdcm>% is either communicative or physical (type), and friendly or aggressive<cdcm>
<cdcm>% (valence):<cdcm>
<cdcm>%<cdcm>
<cdcm>% 5 communicative friendly interactions x 2 takes<cdcm>
<cdcm>% 5 communicative aggressive interactions x 2 takes<cdcm>
<cdcm>% 5 physical friendly interactions x 2 takes<cdcm>
<cdcm>% 5 physical aggressive interactions x 2 takes<cdcm>
<cdcm>% = 40<cdcm>
<cdcm>%<cdcm>
<cdcm>% Additionally: 20 stimuli are shown unaltered and 20 are shown mirrored left-right,<cdcm>
<cdcm>% and trials are divided into 2 blocks of 20. Block # 1/2 and mirrored yes/no<cdcm>
<cdcm>% are randomly assigned to trials and counterbalanced--see code below for<cdcm>
<cdcm>% details. Order of the resulting trials is then randomized within blocks. We<cdcm>
<cdcm>% start with an instruction trial and we have a break trial between the two<cdcm>
<cdcm>% blocks.<cdcm>
<cdcm>%<cdcm>
<cdcm>% Further practical complications are that some stimulus source data are in<cdcm>
<cdcm>% movie format (mp4) and others are in biomechanical data format (c3d), so we<cdcm>
<cdcm>% need to use different element types: movie or bmlWalker. The c3d displays also<cdcm>
<cdcm>% have various conventions for angle of view and markers (point lights), so some<cdcm>
<cdcm>% require display at an azimuth rotation of 90 deg and/or with different marker<cdcm>
<cdcm>% #s showing. This all needs to be tracked and is plotted out in the Excel table<cdcm>
<cdcm>% too.<cdcm>
newExperiment
<cdcm>% TASK TRIALS<cdcm>
<cdcm>% ==========<cdcm>
<cdcm>% Load loadSheetDemo.xlsx into variables in the workspace. One sheet with<cdcm>
<cdcm>% 40 rows x 14 columns -> 14 40x1 column array variables. Variable names are<cdcm>
<cdcm>% taken from the table's header row. loadSheet() automatically detects data<cdcm>
<cdcm>% types.<cdcm>
<cdcm>%<cdcm>
<cdcm>% nn_interactions - interaction #s (vector of 1-20 x 2)<cdcm>
<cdcm>% interactions - interaction names (array of strings)<cdcm>
<cdcm>% nn_takes - stimulus take #s (vector of 1/2)<cdcm>
<cdcm>% nn_types - type #s (vector of 1/2)<cdcm>
<cdcm>% types - types (array of strings "communicative"/"physical")<cdcm>
<cdcm>% nn_valences - valence #s (vector of 1/2)<cdcm>
<cdcm>% valences - valences (array of strings "friendly"/"aggresive")<cdcm>
<cdcm>% nn_objectTypes - object type #s (vector of 1/2)<cdcm>
<cdcm>% objectTypes - object types (array of strings "movie"/"bmlWalker")<cdcm>
<cdcm>% fileNames - source file names (array of strings)<cdcm>
<cdcm>% azimuths - azimuth angles to show at for bmlWalker stimuli (vector of #)<cdcm>
<cdcm>% nn_markerss - vectors of marker numbers to show for bmlWalker stimuli (cell array of row vectors)<cdcm>
<cdcm>% nn_blocks - block #s (vector of 1/2)<cdcm>
<cdcm>% isMirroreds - left-right mirror stimulus or not (vector of 0/1)<cdcm>
loadSheet(<cdsm>"loadSheetDemo.xlsx"<cdsm>)
<cdcm>% Most of the variables contain values that correspond: one value for each trial<cdcm>
<cdcm>% (rows from the table). The last two variables (nn_blocks, isMirroreds) still<cdcm>
<cdcm>% contain one value for each trial, but for each of those variables we want to<cdcm>
<cdcm>% randomize the assignment of its values across trials. To do this we randomize<cdcm>
<cdcm>% the order in those variables. We also want to do some counterbalancing, so we<cdcm>
<cdcm>% use randomBalance():<cdcm>
<cdcm>% Randomize order of block #s (1/2) so balanced across interactions<cdcm>
<cdcm>% -> Each of blocks 1/2 gets one of each interaction. (This also balances block #<cdcm>
<cdcm>% across types and valences since interactions are equally distributed across<cdcm>
<cdcm>% those.)<cdcm>
nn_blocks = randomBalance(nn_blocks, interactions);
<cdcm>% Randomize order of mirrored (0/1) so balanced across types within blocks<cdcm>
<cdcm>% (communicative/physical) AND across interactions<cdcm>
<cdcm>% -> Within each block, the 10 communicative interactions get 5 not mirrored and<cdcm>
<cdcm>% 5 mirrored, and the same for the 10 physical interactions, AND if an<cdcm>
<cdcm>% interaction in block 1 gets mirrored then its take in block 2 gets<cdcm>
<cdcm>% not mirrored and vice versa<cdcm>
isMirroreds = randomBalance(isMirroreds, {nn_types nn_blocks}, interactions);
<cdcm>% 40 trial definitions<cdcm>
<cdkm>for<cdkm> n = 1:40
<cdcm>% Get values for this trial definition based on index n<cdcm>
n_interaction = nn_interactions(n);
interaction = interactions(n);
n_take = nn_takes(n);
n_type = nn_types(n);
type = types(n);
n_valence = nn_valences(n);
valence = valences(n);
n_objectType = nn_objectTypes(n);
fileName = fileNames(n);
n_block = nn_blocks(n);
isMirrored = isMirroreds(n);
azimuth = azimuths(n);
nn_markers = nn_markerss{n};
<cdcm>% Stimulus<cdcm>
<cdcm>% ---<cdcm>
<cdkm>if<cdkm> n_objectType == 1
<cdcm>% Movie object for mp4 file<cdcm>
stimulus = movieObject;
<cdcm>% Set properties specific to movie object type<cdcm>
stimulus.fileName = fileName;
stimulus.height = 20;
stimulus.maxNumLoops = inf;
stimulus.breakInterval = 1;
<cdkm>else<cdkm>
<cdcm>% bmlWalker object for c3d file<cdcm>
stimulus = bmlWalkerObject;
<cdcm>% Set properties specific to bmlWalker object type<cdcm>
stimulus.fileName = fileName;
stimulus.height = 9.5;
stimulus.dotSize = 0.29;
stimulus.azimuth = azimuth;
stimulus.nn_markers = nn_markers;
stimulus.breakInterval = 1;
<cdkm>end<cdkm>
<cdcm>% Set properties all element types have...<cdcm>
stimulus.flipHorz = isMirrored;
<cdcm>% Default start at trial start; End at response<cdcm>
stimulus.end.response = true;
<cdcm>% See some values in experiment results output<cdcm>
stimulus.info.n_interaction = n_interaction;
stimulus.info.interaction = interaction;
stimulus.info.n_take = n_take;
stimulus.info.n_type = n_type;
stimulus.info.type = type;
stimulus.info.n_valence = n_valence;
stimulus.info.valence = valence;
stimulus.info.fileName = fileName;
stimulus.info.isMirrored = isMirrored;
<cdcm>% ---<cdcm>
<cdcm>% Response handler: any key press<cdcm>
<cdcm>% ---<cdcm>
anyKey = keyPressObject;
<cdcm>% ---<cdcm>
<cdcm>% Trial object just to see some trial-level information in results<cdcm>
<cdcm>% ---<cdcm>
trial = trialObject;
trial.info.n_block = n_block;
<cdcm>% ---<cdcm>
<cdcm>% Add trial definition with custom numbering: 101-120 for block 1, 201-220 for block 2<cdcm>
<cdkm>if<cdkm> n_block == 1
n_trialDefBase = 100;
<cdkm>else<cdkm>
n_trialDefBase = 200;
<cdkm>end<cdkm>
addTrial(stimulus, anyKey, trial, n_trialDefBase);
<cdkm>end<cdkm>
<cdcm>%===<cdcm>
<cdcm>% INTRO, PAUSE TRIALS<cdcm>
<cdcm>% ===<cdcm>
<cdcm>% Intro.<cdcm>
<cdcm>% dialogue object to show text until subject presses any key.<cdcm>
text = dialogueObject;
<cdcm>% Each string in the array is a new line<cdcm>
text.text = [
<cdsm>"In each trial you will see two people and I will ask you some questions about them."<cdsm>
<cdsm>"Press any key to begin..."<cdsm>
];
<cdcm>% Add trial definition with name "intro"<cdcm>
addTrial(text, <cdsm>"intro"<cdsm>);
<cdcm>% Break.<cdcm>
<cdcm>% Use same object from above, just change the text.<cdcm>
text.text = [
<cdsm>"We are half way through the experiment – good job!"<cdsm>
<cdsm>"You can take a break before we continue to the second half..."<cdsm>
];
<cdcm>% Add trial definition with name "pause"<cdcm>
addTrial(text, <cdsm>"pause"<cdsm>);
<cdcm>% ===<cdcm>
<cdcm>% Set trial list: intro, block 1 trials in random order, pause, block 2 trials in random order<cdcm>
nn_trialDefs = {<cdsm>"intro"<cdsm> randomOrder(101:120) <cdsm>"pause"<cdsm> randomOrder(201:220)};
setTrialList(nn_trialDefs)
<cdcm>% You can call "viewExperiment" and "viewExperiment -d" to visualize trials<cdcm>
[results, resultsMat] = runExperiment;