Gardner Lab

Psychology Department

Neurosciences Institute

Stanford University


日本語   

When things don’t work, there are some very simple bugs you should check for before losing hope.

Short segment lengths cause dropped frames

Setting the length of the segments of a task to “0 second” can result in lots of dropped frames. This happens because mgl adjusts automatically for the difference between the expected (“0 second”) and the actual length of a segment (“always > 0 seconds”). Thus, if the lengths are set to “0 seconds” mgl is forced to make continual adjustments, what affects the speed of the frames display and causes dropped frames.

Return variables

Many of the routines return multiple values–it is really important that you receive these properly. For example, initTask returns both the task and myscreen. Make sure that you call it as follows:

[task{1} myscreen] = initTask(task{1},myscreen,@startSegmentCallback,@screenUpdateCallback,@responseCallback);

If you did not have the myscreen in the left hand side, then initTask will not set fields (primarly myscreen.stimtrace) correctly in your myscreen–which can make saving out traces incorrect. Look out for this not only in initTask but in any function like updateTask to make sure you are always setting the appropriate return variables correctly (check the help on the function–or model your calls after the ones in the templates).

Screen flashes

Sometimes the screen might appear to flash momentarily with your stimulus in a way you don't expect. Often this is due to not calling mglClearScreen at the appropriate place (like at the beginning of a segment or at the beginning of the screenUpdateCallback). The reason for this occurring is often because you are drawing to the back buffer of the double buffered screen and it already has something from before when it was being displayed. Clearing the screen as you start drawing will insure that you don't have any junk from the last screen draw that will show up.

You may also notice screen flashes if you use mglSetGammaTable to reset the gamma table at certain points in your experiment. mglSetGammaTable relies on Mac OS X functions that are not part of the Open GL library, and therefore will not necessarily have the correct timing. Sometimes the gamma table will get set too soon and sometimes too late. If you notice this problem you should add a brief dummy segment in your trial to set the gamma table before the segment that contains your stimuli. Minimizing the command window during the experiment has also been found to substantially reduce these timing issues.

Matlab control

Don't let the window from which you are calling your code be on the screen that is taken over by MGL, or you will lose the ability to stop the code from running or exit if your code is interupted by an error. If you do this, you can always type option-command-ESC (brings up Force-quit applications) to close the window. This will also quit your matlab session.

Clear all

Mgl keeps the status of the display in the global variable called MGL. You can look at the values set in MGL by doing:

global MGL 
MGL

Be aware that if you clear the MGL variable then mgl will no longer know the status of the screen. The current version handles this by closing the display if you clear the MGL variable. If for some reason, you get stuck with an open display that you cannot close, you can try to call mglOpen again and then close. If you have reset the gamma table, you can go into your System Preferences/Displays/Color and reset the gamma table back to normal there. On Linux, you can use xgamma to set the gamma table, or easier, use NVIDIA's settings manager or the ATI settings manager to restore gamma tables. If you still cannot close the display, you can always do option-open apple-escape and quit out of matlab (on Mac). On Linux, Ctrl-C may work, or you may have to kill the matlab process from a terminal. If you only have one screen and it is locked, you can type Ctrl+Alt+F5 to drop out of the X server temporarily; this will allow you to login and kill the Matlab process without restarting X (Ctrl+Alt+F7 to return to X).

Spelling, capitalization, and periods

If an important variable (e.g. stimulus) is misspelled (e.g. sitmulus), or a variable or function name mis-capitalized (e.g. inittask instead of initTask), or you forget to put the period between a variable name and a field name (e.g. stimuluscontrast instead of stimulus.contrast) things won’t work and it’ll be very confusing! MGL will check for some things that it knows about, but it can’t know how you’ve named your variables…

Your task doesn't exit when it's over

First, make sure you've specified a certain number of trials, otherwise it'll go on forever.

Then, make sure you have a while loop around the updateTask call checking the phase number. Even if you only have one phase, you still need to give updateTask a phaseNum variable as input, because the code will only end when the phaseNum gets too big for the while loop (and updateTask increases the phaseNum after all the trials have been run)

Set the data directory

So as to always know where your data will be saved, it's good to set the data directory by doing:

myscreen.datadir = datadirname;

where datadirname is the full path of the directory to which you'd like the data to be saved.

Make sure your displays aren’t mirrored.

Sometimes nothing at all will happen. This can be because your screens are mirrored.

Some common error messages that have to do with cell arrays and how to fix them

Error message saying you haven't specified task.segmin and task.segmax

Make sure you've called initTask with the exact task and phase. For example:

task{1}.seglen = 1;
task{1} = initTask(task{1},myscreen,@startSegmentCallback,@screenUpdateCallback,@responseCallback);

or

task{1}{1}.seglen = 1;
task{1}{1} = initTask(task{1}{1},myscreen,@startSegmentCallback,@screenUpdateCallback,@responseCallback);

Error message saying 'Cell contents reference from a non-cell array object,'

Make sure you are calling updateTask with a cell array. This can be confusing, because even if you only have one task and only one phase, you still need to define task{1} (rather than just 'task') and then call updateTask with 'task' - e.g.:

task{1}.seglen = 1;
task{1} = initTask(task{1},myscreen,@startSegmentCallback,@screenUpdateCallback,@responseCallback);
phaseNum = 1;
while (phaseNum <= length(task)) && ~myscreen.userHitEsc
 [task myscreen phaseNum] = updateTask(task,myscreen,phaseNum);
end

If you're running two tasks, and need to differentiate them, then even if they each only have one phase, you must define task{1}{1} and task{2}{1} and then call updateTask with task{1} and task{2}. For example:

task{1}{1}.seglen = 1;
task{1}{1} = initTask(task{1}{1},myscreen,@startSegmentCallback,@screenUpdateCallback,@responseCallback);
task{2} = setSecondTask(myscreen); % as long as setSecondTask returns a cell array
phaseNum = 1;
while (phaseNum <= length(task{1})) && ~myscreen.userHitEsc
 [task{1} myscreen phaseNum] = updateTask(task{1},myscreen,phaseNum);
 [task{2} myscreen] = updateTask(task{2},myscreen,1);
end

Error message saying 'Attempt to reference field of non-structure array,'

Make sure that you call updateTask and also return from updateTask with the same cell array (see above).

Error message 'Input argument "tnum" is undefined,'

Make sure you are passing in a phaseNum argument in your updateTask function call.

Problem starting/stopping the eye tracker

To control the ASL eye tracker through digital I/O you must have the file

mgl/task/utils/readDigPort/writeDigPort.c

mex'd. You can do

cd mgl/task/utils/readDigPort
mex writeDigPort.c

This compiles the program to send the digital pulse to the eye tracker. Also, if your task crashes at the beginning after it prints out

Dev1/port2

or something similar to that, you probably just need to recompile writeDigPort.c. If you continue to have problems and want to give up, you can delete the mexfile writeDigPort.mexmac and then mgl won't try and set the digital port (This is the default condition that the mgl library is in, because most computers don't have the NI card installed).