Laboratory of Neuropsychology, NIMH

 

Undocumented MonkeyLogic Functions and Other Notes

This information that is not part of the standard MonkeyLogic documentation.

Main menu problems with Matlab R2012

Some of the menu labels are not drawn when using Matlab R2012.

Error in xycalibrate() during eye calibration

If you get an error with the function 'nanmean' in xycalibrate.... still working on a fix.

Improved randomization

Improved randomization before first trial starts. Code now meets Mathworks specifications for Matlab random generator seeding.

User can change the hardware defaults  with Initio.m

The MonkeyLogic file initio.m has a header that can be modified to configure the input ranges of the data acquisition hardware.  This is useful if the default values do not reflect the ranges of the hardware you are using. The header looks like this:

configIO.AI.BufferingConfig = [16 1024]; %[1 2000];
configIO.AI.InputRange = [-10 10];
configIO.Reward.TriggerValue = 5; %if analog, number of volts to trigger or hold at (will be "1" if digital).

Trial buffer size controls maximum trial length (configIO.AI.BufferingConfig)

The default maximum trial size is 16 seconds.  You can change that from 1 second to up to 2000 seconds.

Eyetracker voltage (configIO.AI.InputRange)

The InputRange parameter defines the range of voltages that Monkeylogic expects from the eyetracker or other input device.

Reward output voltage (configIO.Reward.TriggerValue)

TriggerValue sets the output voltage of the reward pulse when an analog output channel is used.

Joystick changes (trialholder.m, eyejoytrack function)

The joystick input has been fixed in Version 1.1. Previous versions took inputs from the eyetracker’s x and y input positions.

Preload videos

In case you need to run a single video repeatedly over the course of an experiment, the ‘Preload Videos’ option ensures that the video is loaded on the first trial and the preloaded frames are retained for the duration of the experiment, ensuring that there are no delays between trials.   To use this, set the value of the MLConfig.PreloadVideo in the experiment’s configuration file to 1 and save the .mat file.

Registering NI DAQ

In order to set up the hardware devices for Monkeylogic, they first need to be registered in Matlab through the daqregister command. Matlab needs to be run in Administrator mode for this to work. For NI devices, the adaptor is called ‘nidaq’.

bhv_read has been updated in V 1.0 and V 1.1

If you see this error message you are using an outdated version of bhv_read:

??? Error: The input character is not valid in MATLAB statements or expressions.

Error in ==> bhv_read at 155
       BHV.InfoByCond{i} = eval(sprintf('struct(%s)',BHV.InfoByCond{i}));

Error in ==> behaviorsummary at 60
   bhv = bhv_read(inputfile);

pic taskobjects in the conditions file uses two different units

While specifying the pic taskobject in the conditions file (filename, Xpos, Ypos, Width, Height) the two optional resizing parameters, Width and Height need to be specified in pixels, not in degrees of visual angle. 
Xpos, Ypos           degress of visual angle
Width, height         pixels

New version of ML Helper with Version 1.1

An updated version of ML Helper is available.  ML Helper is the program that disables keyboard and mice during the trial).  New features are:

Ctrl + Alt + Shift + Q
This will cause mlhelper to release the keyboard and mouse and exit.  This should only be used when monkeylogic crashes entirely in a way that doesn't tell ML Helper to stop running 

Ctrl + Alt + Shift + T
This will cause ML Helper to toggle between completely releasing the keyboard and mouse, and re-disabling whatever was disabled before the toggle was performed (by pressing the keystroke again).

Block Change & Block Select functions

Block Change

A BlockChange function is called on every trial, and if the output is nonzero, a flag is set that indicates the next block should be selected, according the Block Selection menu option in the "Trial Selection" sub-menu on the main menu. In other words, this function determines when a block change should occur, but not necessarily what that next block will actually be.

Block Select

A BlockSelect function, on the other hand, determines which block should be selected next, whenever the time for a block change arrives, based upon the criterion set in the main menu; this function doesn't determine when a block changes, but simply what the block changes to, when it's called at the time of a block transition. The output of this function is simply the number of the block that should now begin running.

Importantly, you can combine these functions by writing a single function and specifying it as both the BlockChange and BlockSelect function.  This function is now called on every trial to determine if a block change should occur (i.e., when the output is nonzero). Furthermore, the output is not simply a flag (as when only a BlockChange function is used), but is now the number of the new block that should begin running.

This way, the user has the ability to write a simple function that determines

  1. Only when a block should change;
  2. What the new block should be, but only when it's time for that new block based upon menu
    options
  3. Both the timing of the block switch and the actual block to be run.

Block Change (Block Switch) function examples

Here are some example block selection functions.

The following function waits for four correct responses in a row, and then waits additional number of correct responses, before initiating a block switch.

learning_block_switch.m
function block = learning_block_switch(TrialRecord)
consecutive_crit = 10;
totalcorrect_crit= 35; % includes consecutive_crit corrects to criterion
block = TrialRecord.CurrentBlock;
blocktransitions = find(diff(TrialRecord.BlocksPlayed)) + 1;
if isempty(blocktransitions),
   firsttrialthisblock = 1;
else
   firsttrialthisblock = max(blocktransitions);
end

thisblockindex = firsttrialthisblock:length(TrialRecord.BlocksPlayed);
thisblock = TrialRecord.TrialErrors(thisblockindex);
corrects = (thisblock == 0);
incorrects = (thisblock == 6);
p = thisblock(corrects | incorrects);
thresh = consecutive(p, 0, consecutive_crit);
if thresh > 0,
   totalcorrects = sum(p(thresh:length(p)) == 0);
   if totalcorrects >= totalcorrect_crit,
       block = 1;
   else
       block = 0;
   end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function result = consecutive(vector, element, howmany)
lv = length(vector);
pvector = zeros(1, lv+2);
pvector(lv + 2) = element + 1;
pvector(2:lv+1) = vector;
pvector(1) = element + 1;
f = find(pvector ~= element);
fdiff = diff(f);
candidates = find(fdiff > howmany);
if isempty(candidates),
   result = 0;
   return
end
result = sum(fdiff(1:min(candidates)-1)) + 1;

 

This function is a little more complicated than the previous one. See the comments.

spacevsobject_blockselect.m
function nextblock = spacevsobject_blockselect(TrialRecord)
% This function will select the next block using the following rules:
% 1) The first block of the day is always an object task block
% 2) The same task is run exactly 2 blocks in a row before switching tasks
% 3) Within a task, blocks are chosen in a pseudo-random fashion such that
%    all four blocks are played every cycle of 4 blocks
% 4) At the beginning of a new cycle of 4 blocks (within a task), the first
%    block cannot be the same as the last block of the previous cycle
b = TrialRecord.BlocksPlayed;
if isempty(b),
   nextblock = ceil(rand(1)*4);
   return
end
b = delete_repetitions(b);
lastblocknum = length(b);
is_odd = mod(lastblocknum, 2);
spatialtask = (b > 4);
objecttask  = (b < 5);
if spatialtask(lastblocknum) && is_odd,
   choose_spatial = 1;
elseif spatialtask(lastblocknum) && ~ is_odd,
   choose_spatial = 0;
elseif objecttask(lastblocknum) && is_odd,
   choose_spatial = 0;
elseif objecttask(lastblocknum) && ~is_odd,
   choose_spatial = 1;
end
if choose_spatial,
   possible_blocks = [5 6 7 8];
   blocksplayed = b(spatialtask);
else %choose object block
   possible_blocks = [1 2 3 4];
   blocksplayed = b(objecttask);
end

lastblockthistask = length(blocksplayed);
if lastblockthistask < 4,
   blocks_remaining = setdiff(possible_blocks, blocksplayed);
else
   cycle = mod(lastblockthistask+1, 4);
   cycle(cycle == 0) = 4;
   if cycle == 1,
       blocks_remaining = setdiff(possible_blocks, blocksplayed(lastblockthistask)); %so that no block is immediately repeated
   else
       choiceindx = cycle-2;
       blocks_remaining = setdiff(possible_blocks, blocksplayed(lastblockthistask-choiceindx:lastblockthistask));
   end
end


nextblock = blocks_remaining(ceil(rand(1)*length(blocks_remaining)));
       
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function output = delete_repetitions(input)
if length(input) < 2,
   output = input;
   return
end
input = cat(2, 0, input);
output = input(find(diff(input))+1);

 

Taskobject presentation

Lower numbered taskobjects will always appear above higher numbered taskobjects if they are presented at the same time during a trial. In order to ensure that your stimuli are presented correctly, please ensure to put them in the correct order in your conditions’ file.

Updated goodmonkey( ) function

The goodmonkey function has been modified thus:
Additional input parameters – additional input parameters must now be specified with the name of the parameter. The current list of parameters is:

    1. ‘num_rewards’ – this parameter takes in a number that specifies how many rewards are to be dispensed after successful completion of a trial.
    2. ‘pause_time’ – this parameter takes in an interval of time (in ms) that occurs between multiple rewards. Please specify this parameter only when specifying num_rewards > 1.
    3. ‘trigger_val’ – this parameter is new. It allows you to specify a variable voltage to goodmonkey to output to the reward line. The default voltage is 5V (as specified in initio.m), and this parameter can be used to change that value. This will only work if the reward is assigned to an analog output.

Example:
          goodmonkey(120, ‘num_rewards’, 3, ‘pause_time’, 40, ‘trigger_val’, 4.5)

The above call has goodmonkey deliver 3 user-specified rewards of duration 120 ms with a pause of 40 ms between them. It delivers a voltage of 4.5 V to the analog output line that has been assigned to the reward.

The advantage of this new set-up is that it allows users the flexibility of specifying parameters in any order they choose, and also the ease of being able to pair values to the parameter name, improving readability of the code.

Default Configuration file

A default_cfg.mat has been added to the Monkeylogic package. Please ensure to copy this into your experiment directory before running Monkeylogic.

Default eventmarker( ) actions

To send event 25 to just the behavioral file, incude a second parameter.

eventmarker(25,1);    % the 1 indicates for BHV file only

Eventmarkers can be sent to 3 possible places:

  1. Behavioral (BHV) file
  2. Digital output port (with strobe)
  3. Both 1 and 2 above

To set the default action if no second parameter is used. Note, the default action affect not only the eventmarker() function, but also the EventMarker option of the toggleobject() function. 

eventmarker(‘default’);   % send to both
eventmarker(‘explicit’);  % do not send an event unless a target has been specified
eventmarker(‘bhv’);  % send event only to the BHV file
eventmarker(‘strobe’); % send event only to the digital output port

The mouse and system keys are now disabled during task execution

Prevents crashes due to loss of fullscreen window focus.

bhv_variable( )

You can add your own variables to a BHV file using this function.

bhv_variable('var_name',var_value);

var_name
variable name is a string of up to 32 letters

var_value  
Must be a scalar or a vector of length 128 or less, with a data type of char or numeric.  The numeric data will be converted to type double. 

bhv_variable() should be called every trial for each variable.

user_warning( )

user_warning() displays a warning message to the control screen.
user_warning(‘Too many leftward errors:  %d’, left_errors);
The command is called with string and format argument like fprintf().  Warnings will appear in red in the upper left corner of the subject screen replica. A stack of warnings is maintained, and when the stack size is greater than one, the stack size is displayed along with the most recent warning. The user can hit the 'w' key to remove the most recent warning from the stack.

Skipped video frames (event code 200)

Skipped video frames are marked  by command line output, a user_warning(), and event code 200. Note, if your event code hardware only handles 7 bits (like a parallel port), this event code will crash your task.

abort_trial( )

This command terminates the current trial and starts the intertrial interval.  The trial will be marked with an error code of 9. 
abort_trial();

Simulation mode

The simulation mode can be accessed by pressing 's' in the escape menu. This will override normal inputs to the eye position, joystick position, and buttons. The user then can then simulate eye and joystick motion and button status via the keyboard. Simulation Mode has its own documentation.

Main menu advanced dropdown options

Run Matlab with the java accelerator (omit the –nojvm option), then run MonkeyLogic. 
The menu provides these advanced options:

  1. Override the normal mouse and system keys disable function. 
  2. Preload all video data during initialization (which reduces ITI lags when video files are large). Look for memory errors if these files are too large.
  3. Overwrite hardware-specific configuration settings with those in the local default_cfg.mat file.

set_frame_order( )

Rearrange the order of frames in a video task object.
set_frame_order(task_object_number,frame_order);
or
set_frame_order(task_object_number,frame_order,eventmarkers);

Example 1:
frame_order = [ 12 11 10 9 8 7 6 5 4 3 2 1 ];    % reverse order of a video
set_frame_order(Pic_3,frame_order);

Example 2:
frame_order  = [ 12 11 10 9 8 7 6 5 4 3 2 1 ];    % reverse order of a video
frame_events= [23 23 23 23 23 23 22 23 23 23 23 23];  % tag 7th frame
set_frame_order(Pic_3,frame_order,frame_events);

 

 

 


[Home][DIRP] [NIMH] [NIH]

Return to the Home Page
Send web site comments to the WEBMASTER.

last updated 27 April 2012