staircaseDemo.m

A copy is also included in PsychBench in <PsychBench folder>/demos, so you can run it from there.

<cdcm>% STAIRCASE DEMO<cdcm>
<cdcm>% Coding method<cdcm>
<cdcm>% --------------------------------------------------<cdcm>
 
 
<cdcm>% Each trial shows a picture twice for 0.5 sec each time with 0.5 sec interval<cdcm>
<cdcm>% between them. The first picture is rotated at a random angle. The second<cdcm>
<cdcm>% picture is the same or rotated at a different angle. The subject responds with<cdcm>
<cdcm>% up arrow key press if the pictures have same rotation, or down arrow if they<cdcm>
<cdcm>% have different rotation. Across trials where the rotations are different, the<cdcm>
<cdcm>% magnitude of the difference is staircased using a staircase, and the direction<cdcm>
<cdcm>% of the difference (rotation 2 - rotation 1 = +/-) is balanced. We run 30<cdcm>
<cdcm>% trials with same rotation and 30 trials with different rotations (15 in one<cdcm>
<cdcm>% direction, 15 in the other), all in random order.<cdcm>
<cdcm>%<cdcm>
<cdcm>% Staircase parameters:<cdcm>
<cdcm>% Method:                               fixed step<cdcm>
<cdcm>% Step rule:                            3 correct / 1 incorrect<cdcm>
<cdcm>% Initial value:                        10 (rotation difference magnitude, deg)<cdcm>
<cdcm>% Step sizes:                           -1.5 correct, +2.5 incorrect<cdcm>
<cdcm>% Minimum value:                        0<cdcm>
<cdcm>% Number of fast reversals (1/1 rule): 3<cdcm>
<cdcm>% Fast reversal step sizes:             -3   correct, +5   incorrect<cdcm>
<cdcm>% Maximum number of reversals:          no limit<cdcm>
 
 
 
<cdcm>% Mark start of experiment script<cdcm>
newExperiment
 
 
 
<cdcm>% TRIALS<cdcm>
<cdcm>% 60 trial definitions: 2 same/different x 2 sign x 15 random rotations each.<cdcm>
<cdcm>% Each random rotation is potentially a different value for picture property<cdcm>
<cdcm>% .rotation (see below), so each is a DISTINCT TRIAL which needs a separate<cdcm>
<cdcm>% trial definition.<cdcm>
<cdcm>% ---<cdcm>
<cdkm>for<cdkm> isSame = [true false]
    <cdkm>for<cdkm> sign = [-1 +1]
        <cdkm>for<cdkm> n_rep = 1:15
                    <cdcm>% Make 2 picture objects for the trial<cdcm>
                    pics = pictureObject(2);
 
                    <cdcm>% Properties the same for both pictures<cdcm>
                <cdkm>for<cdkm> n = 1:2
                    pics(n).fileName = <cdsm>"hourglass.png"<cdsm>;
                    pics(n).height = 8;
                    pics(n).report = <cdsm>"rotation"<cdsm>;
                <cdkm>end<cdkm>
 
                    <cdcm>% Picture 1 - random rotation<cdcm>
                    pics(1).rotation = randomNum(0, 360);
                    pics(1).start.t = 0;
                    pics(1).end.t = 0.5;
 
                    <cdcm>% Picture 2...<cdcm>
            <cdkm>if<cdkm> isSame
                    <cdcm>% Same rotation as picture 1<cdcm>
                    pics(2).rotation = pics(1).rotation;
            <cdkm>else<cdkm>
                    <cdcm>% Different rotation than picture 1.<cdcm>
                    <cdcm>% Staircase difference magnitude, balanced difference direction across trials.<cdcm>
                    <cdcm>% Note this takes advantage of number + "string" syntax, e.g. 2+"hello" = "2hello"<cdcm>
                    pics(2).staircase.what = <cdsm>"rotation"<cdsm>;
                <cdkm>if<cdkm> sign == -1
                    pics(2).staircase.setExpr = pics(1).rotation + <cdsm>"-staircaseVal"<cdsm>;
                <cdkm>else<cdkm>
                    pics(2).staircase.setExpr = pics(1).rotation + <cdsm>"+staircaseVal"<cdsm>;
                <cdkm>end<cdkm>
            <cdkm>end<cdkm>
                    pics(2).start.t = 1;
                    pics(2).end.t = 1.5;
 
 
            <cdcm>% Response handler for the trial - up/down arrow key press.<cdcm>
            <cdcm>% You can get key names using showKey() at the MATLAB command line.<cdcm>
            <cdcm>% Raw response value is number of the name in the list we set in .listenKeyNames, i.e. 1 = up, 2 = down.<cdcm>
            <cdcm>% Then translate 1/2 -> true/false (same rotation / not) for all purposes including scoring and recording.<cdcm>
            <cdcm>% Need response scoring on for staircase.<cdcm>
            <cdcm>% Correct response = same rotation / not from loop variable "isSame".<cdcm>
            <cdcm>% By default keyPress elements end when they record a response -> don't need to set .end.<cdcm>
            recorder = keyPressObject;
            recorder.listenKeyNames = [<cdsm>"up"<cdsm> <cdsm>"down"<cdsm>];
            recorder.translateResponse = [
                1 true
                2 false
                ];
            recorder.scoreResponse = true;
            recorder.correctResponse = isSame;
            recorder.start.t = 0;
            recorder.report = [<cdsm>"response"<cdsm> <cdsm>"correctResponse"<cdsm> <cdsm>"responseScore"<cdsm> <cdsm>"responseLatency"<cdsm>];
 
 
            <cdcm>% Add trial definition with default numbering (1, 2, 3, ...)<cdcm>
            addTrial(pics, recorder);
        <cdkm>end<cdkm>
    <cdkm>end<cdkm>
<cdkm>end<cdkm>
<cdcm>% ---<cdcm>
 
 
 
<cdcm>% Trial list: run the trial definitions in random order.<cdcm>
<cdcm>% Randomization of isSame, sign implemented here.<cdcm>
nn = randomOrder(1:60);
setTrialList(nn);
 
 
 
<cdcm>% STAIRCASE OBJECT<cdcm>
<cdcm>% ---<cdcm>
staircase = fixedStepStaircaseObject;
 
<cdcm>% 3 correct / 1 incorrect rule.<cdcm>
staircase.stepRule = [3 1];
 
<cdcm>% Staircase value will apply to picture rotation difference magnitude.<cdcm>
<cdcm>% Initial rotation difference magnitude = 10 deg.<cdcm>
<cdcm>% Staircase value step sizes after correct/incorrect response trials = decrease rotation difference magnitude by 1.5 deg, increase by 2.5 deg.<cdcm>
<cdcm>% Don't step below 0 deg.<cdcm>
staircase.val1 = 10;
staircase.stepSizes = [-1.5 2.5];
staircase.min = 0;
 
<cdcm>% 3 fast (1/1 rule) reversals at start to get near subject's threshold fast.<cdcm>
<cdcm>% Step sizes for fast reversals = -3, +5.<cdcm>
staircase.numFastReversals = 3;
staircase.fastStepSizes = [-3 5];
 
<cdcm>% Report staircase value, reversed true/false, threshold estimate, number of trials run, number of reversals in experiment results.<cdcm>
<cdcm>% For staircases these record properties report at each trial.<cdcm>
staircase.report = [<cdsm>"val"<cdsm> <cdsm>"reversed"<cdsm> <cdsm>"threshold"<cdsm> <cdsm>"numTrialsRan"<cdsm> <cdsm>"numReversals"<cdsm>];
 
 
<cdcm>% Add staircase object to experiment<cdcm>
addToExperiment(staircase)
<cdcm>% ---<cdcm>
 
 
 
<cdcm>% Run<cdcm>
[results, resultsMatrix] = runExperiment;
 
 
 
<cdcm>% See also:<cdcm>
<cdcm>% - response handler property .scoreResponseForStaircase - www.psychbench.org/docs/responsehandler#scoreresponse<cdcm>
<cdcm>% - trial object     property .withStaircase             - www.psychbench.org/docs/trial#withstaircase<cdcm>