loadSheetDemo.m

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;