Behavioral Control in MATLAB


Running an Experiment

Basic Operation

A task is launched by clicking the Run button in the main menu. This button will become active once a conditions file has been loaded, the appropriate configuration parameters set, and a data file name has been entered. Note that if you enter the Subject Name field or the Experiment Name field and hit [enter], a standardized file name will be filled-in for you.

Clicking Run will launch the control screen (top screenshot, below) and will take control of the secondary screen (lower screenshot). The control screen displays symbols corresponding to the stimuli currently visible to the subject, as well as a ring corresponding to the eye or joystick target. These objects are to-scale. The eye or joystick trace will be updated in real-time as the subject moves. Between trials, the surrounding graphs (behavioral performance, reaction times, and event time-line) will be updated.

control screen
control screen

subject screen
subject's screen

Importantly, MATLAB MUST be running without JAVA enabled.  To disable java, run “matlab –nojvm” from the command prompt.  Applications other than this one instance of MATLAB should be shut-down, particularly if those applications may be running JAVA, such as web-browsers. Note specifically that other instances of MATLAB running in the background (especially those with JAVA enabled) will likely cause the system to behave erratically and will eventually crash MonkeyLogic.

In addition, screen-savers and power-saving options must be disabled so that they do not interfere with task execution.

A behavioral task will continue to execute until either the maximum trials parameter or the maximum blocks parameter is reached (both are specified in the task submenu of the main menu), unless the task is stopped manually (hitting [escape] and then [q] for quit).

Controlling Task Flow: Selecting Conditions and Blocks using Custom-Defined Criteria

To control the flow of the task on-line, the user can specify Matlab functions that select the order of conditions or blocks, and determine when blocks should change. These are to be used when the built-in options for selecting conditions or blocks (e.g., in random, incremental, or decremental order using a pre-specified number of trials per block) are not sufficient. For example, it may be necessary to monitor a subject's performance for evidence of learning before switching blocks, or it may be desired that specific blocks will always (or will never) follow other specific blocks, etc. To accomplish these tasks, three types of functions can be used:

Condition-Selection Function
Block-Selection Function
Block-Change Function

These functions are specified in the MonkeyLogic Main Menu, in the Trial Selection Settings pane. These functions are also described there.

Each of these functions should be written to accept TrialRecord as input, and should produce an output that controls subsequent task flow. In the case of the Condition-Selection Function, the output is a single scalar value that corresponds to the condpition number of the next trial to be run. In the case of the Block-Selection Function, the output should be a scalar value that corresponds to the block number containing the next condition to be run (the specific condition selected to run can depend on either a Condition-Selection Function, or according to the built-in condition-selection options, such as "random without replacement").

To determine when a block should change, but not necessarily which block is chosen (such as might be the case when blocks should be chosen randomly, but should change whenever the subject achieves some behavioral criterion), a Block-Change Function should be specified. This function should also take TrialRecord as input, and the output should either be zero (continue the same block) or non-zero (switch to a new block). In the case of the latter, if no Block-Selection function is specified, the next block will be chosen according to the selected built-in option (e.g., "Incremental").

To determine both when and how blocks should change (e.g., when to change depends on achieving a particular behavioral criterion and which block to actually run at that point needs to follow some specific set of contingencies not achievable with the built-in options), you can specify that the same function is used as both a Block-Selection Function and a Block-Change Function. In this case, if the function returns zero, the same block will continue; a non-zero number here specifies not only that the block should change, but the actual number of the new block that should now be played.

Note that a Condition Selection Function can also signal that a block-change should occur, by returning a value of -1.


To determine that a block should change whenever a subject performs 5-trials-correct in-a-row, and that the next block should be even if the last one were odd or odd if the last one were even, the following code could be employed as both a Block-Selection and a Block-Change Function:

function NewBlock = myblock(TrialRecord)

NewBlock = 0; % default = continue current block
numcorrect = 5; % the number of correct trials in-a-row to reach criterion

t = TrialRecord.CurrentTrialWithinBlock; % t is the ordinal number of the current trial within the current block
e = TrialRecord.TrialErrors; % vector of trial errors; each element = 0 when a trial is correct
b = TrialRecord.CurrentBlock; % b is the current Block being played (not ordinal block number)
B = TrialRecord.BlocksSelected; % the vector of blocks available to be played, as selected in the Main Menu

if t < numcorrect,

if sum(e(end-numcorrect+1:end)), % a non-zero sum means the last numcorrect trials were not all zero

% criterion has been reached, so select a new block

evenblocks = B(B/2 == round(B/2));
oddblocks = B(B/2 ~= round(B/2));

if b/2 == round(b/2), % current block is even, so select an odd block
  numpossible = length(oddblocks);
   r = ceil(numpossible*rand(1));
  NewBlock = oddblocks(r);
else % current block is odd, so select an even block
  numpossible = length(evenblocks);
  r = ceil(numpossible*rand(1));
  NewBlock = evenblocks(r);

Pausing the Task & On-Line Parameter Changes

The task can be paused between trials. To pause task execution, press [escape] any time during the trial or during the first half-second of the inter-trial interval. A menu will appear with some or all of the following options, depending on the experiment:

Resume task
Quit task
Change current block
Reset the recent behavior performance bar
Change behavioral-error handling
[e] or [j]
Re-calibrate eye-signal or joystick (if in-use)
Toggle eye-drift correction (if in-use)
Modify variables declared as editable


Predefined Hotkeys

Timing files allow for the definition of hotkeys via the Hotkey function. But certain hotkeys are already defined:

Pause task
Deliver 100 ms of reward
Reduce user-defined reward duration by 10 ms
Increase user-defined reward duration by 10 ms
Center the eye-position on the current fixation point

(It is recommended that you not define new hotkeys with these characters.)


Displaying a Custom Figure on the Control Screen

The area on the control-screen normally occupied by the reaction time histograms can be used instead for a plot designed by the user. Simply write an Matlab function that expects the TrialRecord structure as input; this structure contains a myriad of behavioral data that can be used for making the figure. From within this function, draw to the current axis (by directly issuing plot calls or other graphical commands without altering the current axis). Make certain to select this function as the "user plot" function near the bottom of the video panel towards the left side of the main menu.

If for some reason focus on the RT graph axis has been lost (e.g., opening and writing to another axis from within the user-plot function), it can be restored by calling:

axis(findobj('tag', 'rtgraph'));

Note that extremely complex figures can slow-down updates to the control-screen, and so could potentially steal time from behavioral sampling. This would be recognized as a drop in the "cycle rate" as displayed on the right side of the control-screen.


Remote Access: Controlling MonkeyLogic via the Web

If web updates are enabled, it is possible to send basic commands to MonkeyLogic via the update page. Inserting the keyword, "ML_CommandEntry" into the HTML template (as is done in the included mlwebsummary.html template) results in the following box appearing on that page at the specified location:

The instruction is a plain-language command for MonkeyLogic to execute. Authorization is the pass-code specified in the ftpinfo.txt file.

The currently-recognized commands are (case-insensitive):

pause | timeout | hold | wait
resume | continue | start
quit | stop | done
error string (e.g., repeat immediately | ignore | repeat delayed)
block n
iti n
maxblocks n
maxtrials n

Alternative options are shown in the same row, separated by a vertical line.

For remote-access commands to work, the directory specified in ftpinfo.txt must allow the execution of PHP scripts. In order to maintain security, system administrators may choose to allow only certain files to have create / write permissions. Specifically, a file called [computername]command.txt (all in small-caps) is created by the PHP script to store the user's remote command. The password is stored and verified locally on the computer running MonkeyLogic.


This site last updated: May, 2014
© 2008-2014