DMDX Help.

Branch Keyword

<Branch N>
<bu N>

Call Keyword

<Call N>

    <Branch> is the ?1 switch alternative, where the next item to be processed will be item number N, all other intervening items will be skipped. If N is negative DMDX rewinds the item file to it's start before seeking to item number N (the sign is ignored once the branching direction is processed, it's not a CR indicator). There can only be one branch per item (regardless of it's type), multiple branches per item can be effected with the <MultiWayBranch> keyword.  Terse abbreviation is branch unconditional.

    Use of the
<NumberOfItems> parameter to generate the ITEM COUNT NOT ZERO message is overridden by the use of any branching options given the impossibility of determining exactly how many responses are to be gathered.

    Branching backwards in DMDX is rather crude, you can only branch backwards to the first occurrence in the item file (as opposed to the most recent occurrence) of item number
N because originally DMTG could not parse an item file backwards. Given the limit of 2.1 billion item numbers with an AZK output file that usually posed no problem however I came across a problem where I had to add the BB2MR option (branch backwards to most recent) that overrides this legacy behavior.  The trick (prior to version was remembering to put the minus sign in front of the destination item number for backwards branching.  As of if DMDX doesn't find an item number after a branch keyword item it will branch to the first occurrence of that item number in the item file unless BB2MR is on in which case it will branch to the most recent occurrence of the item number.

    The <bu> keyword is actually not all that useful by itself, what is of far greater utility are the conditional branches, <BranchifCorrect>, <BranchIf Wrong> and <BranchIfNoResponse>. A simple example of branching is the case where a second question is asked if a first one is answered incorrectly:

+10 "First Question" * <bic 0>;
+11 "Second Question" *;

+10 "Next First Question" *
<bic 0>;
+11 "Next Second Question" *;

~0; is a branching stub and takes almost no time to execute. If you were scrambling that item file a G parameter of 3 would be needed. More sophisticated branching keywords can be found in the Branching Kewords.

    Turning Branch diagnostics on will greatly facilitate figuring out what a wayward script is doing.

Call variant:

     The <call> variant of all branches stores the location of the next item before performing the branch allowing limited subroutine like behavior with the <return> keyword that resumes execution at the item following the item with the call keyword. Calls cannot be nested unless a call stack is first created with the <CallStack> parameter. Branch diagnostics will not reflect the call variant (ie, a call keyword will be referenced as a branch).
    Because the variable that stores the RT for branches to make decisions against is not cleared until another RT is gathered the subroutine can continue to make tests allowing very flexible feedback routines, for example the following items could provide acoustic feedback:

f20 <nfb> <!branchdiagnostics>
0 "Acoustic Feedback Example" <bu 40>;
<biw 20>;
d20 <wav> "correct" <return>;
<binr 30>;
0 d20 <wav> "wrong" <return>;
30 d20 <wav> "noresponse" <return>;

+100 * "target" / <call -10> c;
+110 * "target" / <call -10> c;

The ~ (<SkipDisplay> synonym) is in there to make those items execute as rapidly as possible and the d20 is similarly to make those items execute quickly, the delay value is large enough to allow the audio to be read from disk. Alternatively the RT gathering item's frames could be marked time critical and the feedback items delay all set to 1, the timing errors for feedback would then be ignored and it would be presented as rapidly as possible.  The <mwb> documentation has a non-call based version of this same auditory feedback task that's designed for custom feedback for each item in the instances where you want to give clues and have subjects repeat items till they get them right.

You'll notice we have a commented out branch diagnostics keyword in there <!branchdiagnostics>.  While that's inactive with the bang in front of it if you take that out you'll be able to trace what the item file is doing by looking in the diagnostics or the data file.  You would not want to leave that uncommented in actual data as the spew into the data file can be excessive...

     Another example is where you might want to warn subjects if they are too slow but still gather their RTs without having the time limit truncate the RT:
f20 <nfb> <timeout 8000> <!branchdiagnostics>
0 "RT warning Feedback Example" <bu 1000>;
~999 <bi 998, lastxt .lt. 0>;
~997 <bi 996, lastxt .gt. 4000>;
995 "correct" <return>;
996 "correct, but too slow" <return>;
~998 <bi 994, lastxt .lt. -4000>;
993 "incorrect" <return>;
~994 <bi 992, lasxt .eq. -8000>;
991 "incorrect and too slow" <return>;
992 "too long" <return>;

+100 * "target" / <call -999> c;
+110 * "target" / <call -999> c;

     Another reasonably common sort thing to want to do is to limit the subject to a certain amount of time to complete the task.  Here we have a section of the item file that isn't limited (the 100's) followed by a time limited section (the 200's).  Our example limits it to ten seconds, you'll want to substitute your limit (in milliseconds) for the 10000 in the example.

f20 <cr> <!branchdiagnostics>
0 "Timelimit Example" <bu 1000>;
~999 <bi 998, millisectime .lt. c1>;
0 "Time Limit" <lastframe>;
~998 <return>;

+100 * "target" / ;
+110 * "target" / ;

0 "Time limit starts now" <set c1 = millisectime + 10000>;

+200 * "target" / <call -999>;
+210 * "target" / <call -999>;
+220 * "target" / <call -999>;
+230 * "target" / <call -999>;

0 "The End" <lastframe>;

     In addition the Probabilistic Selection Task example has probabilistic feedback where the same answer is not always right or wrong (as well as using a bunch of other quite advanced techniques).

DMDX Index.