Psychtoolbox

 

For most experiments we don’t want to use the Matlab figure window or command window for input or display, since that is pretty slow and clunky.

So we are going to start using a group of Matlab programs developed especially for doing behavioral experiments. Many groups have developed similar sets of programs: the particular ones we are going to use are called PsychToolbox.

What is Psychtoolbox?

Psychtoolbox is a free set of MATLAB functions which help researchers carry out vision research on Macintosh and Windows computers. It is a collection of matlab functions mainly written to make presenting visual stimuli easier.It was written by David Brainard, Denis Pelli, Mario Kleiner and Allen Ingling.

The current version of Psychtoolbox is based on OpenGL commands. At its most basic level OpenGL is simply a document that describes a set of functions and the precise behaviours that they must perform.

One of the important things about OpenGL is that functions are supposed to work across platforms. From this specification, hardware and software vendors create implementations — libraries of functions created to match the functions stated in the OpenGL specification. Vendors have to meet specific tests to be able to qualify their implementation as an OpenGL implementation. OpenGL is also used in CAD, virtual reality, scientific visualization, information visualization, and flight simulation, as well as (of course) video games.

This is meant to mean that Psychtoolbox works similarly in PCs as in Macs. Sadly this isn't always the case, but in most cases the same Matlab scripts will work on PCs and Macs with little or no modification.

Downloading Psychtoolbox

You need to download PsychToolbox from here:

http://psychtoolbox.org/

Follow the instructions very carefully and accurately, it’s a fiddly process.

Once you have installed PsychToolbox, then you can carry on with this chapter.

Citing Psychtoolbox

Remember to cite the Toolbox. Citing the toolbox isn't just the right thing to do - it's a way of demonstrating that the toolbox is useful so that agencies like the NIH will keep funding it.

"We wrote our experiments in MATLAB, using the Psychophysics Toolbox extensions (Brainard, 1997; Pelli, 1997)."

Brainard, D. H. (1997) The Psychophysics Toolbox, Spatial Vision , 10:443-446. Pelli, D. G. (1997) The VideoToolbox software for visual psychophysics: Transforming numbers into movies, Spatial Vision 10:437-442.

Getting started with PsychToolbox Screen.m

Start with just 1 monitor

Try typing the following into the command window:

ScreenTest   

 

 

***** ScreenTest: Testing Screen 0 *****

 

 

PTB-INFO: This is the OpenGL-Psychtoolbox for Microsoft Windows, version 3.0.8. (Build date: Aug 15 2008)

PTB-INFO: Type 'PsychtoolboxVersion' for more detailed version information.

PTB-INFO: Psychtoolbox is licensed to you under terms of the GNU General Public License (GPL). See file 'License.txt' in the

PTB-INFO: Psychtoolbox root folder for a copy of the GPL license.

 

 

 

OpenGL-Extensions are: GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_blend_color GL_EXT_abgr GL_EXT_texture3D GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_SGIS_texture_edge_clamp GL_SGIS_generate_mipmap GL_EXT_draw_range_elements GL_SGIS_texture_lod GL_EXT_rescale_normal GL_EXT_packed_pixels GL_EXT_separate_specular_color GL_ARB_multitexture GL_EXT_texture_env_combine GL_EXT_bgra GL_EXT_blend_func_separate GL_EXT_secondary_color GL_EXT_fog_coord GL_EXT_texture_env_add GL_ARB_texture_cube_map GL_ARB_transpose_matrix GL_ARB_texture_env_add GL_IBM_texture_mirrored_repeat GL_EXT_multi_draw_arrays GL_NV_blend_square GL_ARB_texture_compression GL_3DFX_texture_compression_FXT1 GL_EXT_texture_filter_anisotropic GL_ARB_texture_border_clamp GL_ARB_point_parameters GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_EXT_texture_compression_s3tc GL_ARB_shadow GL_ARB_window_pos GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_ARB_vertex_program GL_EXT_texture_rectangle GL_ARB_fragment_program GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_ARB_vertex_buffer_object GL_EXT_texture_lod_bias GL_ARB_occlusion_query GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_texture_non_power_of_two GL_ARB_vertex_shader GL_NV_texgen_reflection GL_ARB_point_sprite GL_EXT_blend_equation_separate GL_ARB_depth_texture GL_ARB_texture_rectangle GL_ARB_draw_buffers GL_ARB_pixel_buffer_object GL_WIN_swap_hint GL_EXT_framebuffer_object

 

 

 

PTB-INFO: OpenGL-Renderer is Intel :: Intel Cantiga :: 2.0.0 - Build 7.15.10.4977

PTB-Info: VBL startline = 800 , VBL Endline = 822

PTB-Info: Measured monitor refresh interval from beamposition = 16.656752 ms [60.035716 Hz].

PTB-Info: Will use beamposition query for accurate Flip time stamping.

PTB-Info: Measured monitor refresh interval from VBLsync = 16.656703 ms [60.035889 Hz]. (112 valid samples taken, stddev=0.199544 ms.)

PTB-Info: Reported monitor refresh interval from operating system = 16.666667 ms [60.000000 Hz].

PTB-Info: Small deviations between reported values are normal and no reason to worry.

PTB-INFO: Using OpenGL GL_TEXTURE_RECTANGLE_EXT extension for efficient high-performance texture mapping...

 

***** ScreenTest: Done With Screen 0 *****  

 

If you get the screen going blank and then something like the above then screenTest worked.

If not, then Psychtoolbox isn't working right on your computer. The notes that are spat out of screentest may help you work out what's wrong. If not, contact Geoff or myself.

Writing code using Screen.m

The next stage is also very simple. We are simply going to open an experimental window which will start out being white, we will then make it black and then close it again.

The script below uses a command called Screen, which is one of the core functions of PsychToolbox. Screen is actually not an m file (like the ones you have been writing till now). It is a mex file. This means that it is written in C using OpenGL, and is then compiled to run in Matlab. The reason this was done is because Screen does some pretty funky stuff that would be impossible in Matlab.

FlipScreen.m

 

% FlipScreen.m

%

% opens a window using Psychtoolbox,

% makes the window black, then white, and then closes

% the window again

%

% written for Psychtoolbox 3 on the PC by IF 3/2007

 

clear all


screens=0;

[wPtr,rect]=Screen('OpenWindow',screens, 0, []);

HideCursor;

tic

while toc<2

end

 

Screen('Close', wPtr); 

 

 

 

PTB-INFO: This is the OpenGL-Psychtoolbox for Microsoft Windows, version 3.0.8. (Build date: Aug 15 2008)

PTB-INFO: Type 'PsychtoolboxVersion' for more detailed version information.

PTB-INFO: Psychtoolbox is licensed to you under terms of the GNU General Public License (GPL). See file 'License.txt' in the

PTB-INFO: Psychtoolbox root folder for a copy of the GPL license.

 

 

 

OpenGL-Extensions are: GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_blend_color GL_EXT_abgr GL_EXT_texture3D GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_SGIS_texture_edge_clamp GL_SGIS_generate_mipmap GL_EXT_draw_range_elements GL_SGIS_texture_lod GL_EXT_rescale_normal GL_EXT_packed_pixels GL_EXT_separate_specular_color GL_ARB_multitexture GL_EXT_texture_env_combine GL_EXT_bgra GL_EXT_blend_func_separate GL_EXT_secondary_color GL_EXT_fog_coord GL_EXT_texture_env_add GL_ARB_texture_cube_map GL_ARB_transpose_matrix GL_ARB_texture_env_add GL_IBM_texture_mirrored_repeat GL_EXT_multi_draw_arrays GL_NV_blend_square GL_ARB_texture_compression GL_3DFX_texture_compression_FXT1 GL_EXT_texture_filter_anisotropic GL_ARB_texture_border_clamp GL_ARB_point_parameters GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_EXT_texture_compression_s3tc GL_ARB_shadow GL_ARB_window_pos GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_ARB_vertex_program GL_EXT_texture_rectangle GL_ARB_fragment_program GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_ARB_vertex_buffer_object GL_EXT_texture_lod_bias GL_ARB_occlusion_query GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_texture_non_power_of_two GL_ARB_vertex_shader GL_NV_texgen_reflection GL_ARB_point_sprite GL_EXT_blend_equation_separate GL_ARB_depth_texture GL_ARB_texture_rectangle GL_ARB_draw_buffers GL_ARB_pixel_buffer_object GL_WIN_swap_hint GL_EXT_framebuffer_object

 

 

 

PTB-INFO: OpenGL-Renderer is Intel :: Intel Cantiga :: 2.0.0 - Build 7.15.10.4977

PTB-Info: VBL startline = 800 , VBL Endline = 822

PTB-Info: Measured monitor refresh interval from beamposition = 16.656780 ms [60.035613 Hz].

PTB-Info: Will use beamposition query for accurate Flip time stamping.

PTB-Info: Measured monitor refresh interval from VBLsync = 16.656737 ms [60.035768 Hz]. (50 valid samples taken, stddev=0.001461 ms.)

PTB-Info: Reported monitor refresh interval from operating system = 16.666667 ms [60.000000 Hz].

PTB-Info: Small deviations between reported values are normal and no reason to worry.

PTB-INFO: Using OpenGL GL_TEXTURE_RECTANGLE_EXT extension for efficient high-performance texture mapping...  

 

 

help with Screen

There are two ways of getting help with Screen If you type:

doc Screen 

 

You get some general information about Screen

If you type:

 

Screen 

 

Usage:

 

% Activate compatibility mode: Try to behave like the old MacOS-9 Psychtoolbox:

oldEnableFlag=Screen('Preference', 'EmulateOldPTB', [enableFlag]);

 

% Open or close a window or texture:

[windowPtr,rect]=Screen('OpenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize] [,numberOfBuffers] [,stereomode] [,multisample][,imagingmode]);

[windowPtr,rect]=Screen('OpenOffscreenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize] [,specialFlags] [,multiSample]);

textureIndex=Screen('MakeTexture', WindowIndex, imageMatrix [, optimizeForDrawAngle=0] [, specialFlags=0] [, floatprecision=0] [, textureOrientation=0] [, textureShader=0]);

Screen('Close', [windowOrTextureIndex or list of textureIndices/offscreenWindowIndices]);

Screen('CloseAll');

 

%  Draw lines and solids like QuickDraw and DirectX (OS 9 and Windows):

currentbuffer = Screen('SelectStereoDrawBuffer', windowPtr [, bufferid] [, param1]);

Screen('DrawLine', windowPtr [,color], fromH, fromV, toH, toV [,penWidth]);

Screen('DrawArc',windowPtr,[color],[rect],startAngle,arcAngle)

Screen('FrameArc',windowPtr,[color],[rect],startAngle,arcAngle[,penWidth] [,penHeight] [,penMode])

Screen('FillArc',windowPtr,[color],[rect],startAngle,arcAngle)

Screen('FillRect', windowPtr [,color] [,rect] );

Screen('FrameRect', windowPtr [,color] [,rect] [,penWidth]);

Screen('FillOval', windowPtr [,color] [,rect]);

Screen('FrameOval', windowPtr [,color] [,rect] [,penWidth] [,penHeight] [,penMode]);

Screen('FramePoly', windowPtr [,color], pointList [,penWidth]);

Screen('FillPoly', windowPtr [,color], pointList);

 

% New OpenGL functions for OS X:

Screen('glPoint', windowPtr, color, x, y [,size]);

Screen('gluDisk', windowPtr, color, x, y [,size]);

Screen('DrawDots', windowPtr, xy [,size] [,color] [,center] [,dot_type]);

Screen('DrawLines', windowPtr, xy [,width] [,colors] [,center] [,smooth]);

[sourceFactorOld, destinationFactorOld, colorMaskOld]=('BlendFunction', windowIndex, [sourceFactorNew], [destinationFactorNew], [colorMaskNew]);

 

% Draw Text in windows

textModes = Screen('TextModes');

oldCopyMode=Screen('TextMode', windowPtr [,textMode]);

oldTextSize=Screen('TextSize', windowPtr [,textSize]);

oldStyle=Screen('TextStyle', windowPtr [,style]);

[oldFontName,oldFontNumber]=Screen(windowPtr,'TextFont' [,fontNameOrNumber]);

[normBoundsRect, offsetBoundsRect]=Screen('TextBounds', windowPtr, text);

[newX,newY]=Screen('DrawText', windowPtr, text [,x] [,y] [,color] [,backgroundColor] [,yPositionIsBaseline]);

oldTextColor=Screen('TextColor', windowPtr [,colorVector]);

oldTextBackgroundColor=Screen('TextBackgroundColor', windowPtr [,colorVector]);

 

% Copy an image, very quickly, between textures, offscreen windows and onscreen windows.

[resident [texidresident]] = Screen('PreloadTextures', windowPtr [, texids]);

Screen('DrawTexture', windowPointer, texturePointer [,sourceRect] [,destinationRect] [,rotationAngle] [, filterMode] [, globalAlpha] [, modulateColor] [, textureShader] [, specialFlags] [, auxParameters]);

Screen('DrawTextures', windowPointer, texturePointer(s) [, sourceRect(s)] [, destinationRect(s)] [, rotationAngle(s)] [, filterMode(s)] [, globalAlpha(s)] [, modulateColor(s)] [, textureShader] [, specialFlags] [, auxParameters]);

Screen('CopyWindow', srcWindowPtr, dstWindowPtr, [srcRect], [dstRect], [copyMode])

 

% Copy an image, slowly, between matrices and windows :

imageArray=Screen('GetImage', windowPtr [,rect] [,bufferName] [,floatprecision=0] [,nrchannels=3])

Screen('PutImage', windowPtr, imageArray [,rect]);

 

% Synchronize with the window's screen (on-screen only):

[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('Flip', windowPtr [, when] [, dontclear] [, dontsync] [, multiflip]);

Screen('AsyncFlipBegin', windowPtr [, when] [, dontclear] [, dontsync] [, multiflip]);

[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('AsyncFlipEnd', windowPtr);

[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('AsyncFlipCheckEnd', windowPtr);

[VBLTimestamp StimulusOnsetTime swapCertainTime] = Screen('WaitUntilAsyncFlipCertain', windowPtr);

[telapsed] = Screen('DrawingFinished', windowPtr [, dontclear] [, sync]);

framesSinceLastWait = Screen('WaitBlanking', windowPtr [, waitFrames]);

 

% Load color lookup table of the window's screen (on-screen only):

[gammatable, dacbits, reallutsize] = Screen('ReadNormalizedGammaTable', windowPtrOrScreenNumber);

Screen('LoadNormalizedGammaTable', windowPtrOrScreenNumber, table [, loadOnNextFlip] [, physicalDisplay]);

oldclut = Screen('LoadCLUT', windowPtrOrScreenNumber [, clut] [, startEntry=0] [, bits=8]);

 

% Get (and set) information about a window or screen:

screenNumbers=Screen('Screens' [, physicalDisplays]);

windowPtrs=Screen('Windows');

kind=Screen(windowPtr, 'WindowKind');

isOffscreen=Screen(windowPtr,'IsOffscreen');

hz=Screen('FrameRate', windowPtrOrScreenNumber [, mode] [, reqFrameRate]);

hz=Screen('NominalFrameRate', windowPtrOrScreenNumber [, mode] [, reqFrameRate]);

[ monitorFlipInterval nrValidSamples stddev ]=Screen('GetFlipInterval', windowPtr [, nrSamples] [, stddev] [, timeout]);

screenNumber=Screen('WindowScreenNumber', windowPtr);

rect=Screen('Rect', windowPtrOrScreenNumber);

pixelSize=Screen('PixelSize', windowPtrOrScreenNumber);

pixelSizes=Screen('PixelSizes', windowPtrOrScreenNumber);

[width, height]=Screen('WindowSize', windowPointerOrScreenNumber);

[width, height]=Screen('DisplaySize', ScreenNumber);

[oldmaximumvalue oldclampcolors] = Screen('ColorRange', windowPtr [, maximumvalue][, clampcolors=1]);

info = Screen('GetWindowInfo', windowPtr [, beamposOnly=0]);

resolutions=Screen('Resolutions', screenNumber);

oldResolution=Screen('Resolution', screenNumber [, newwidth] [, newheight] [, newHz] [, newPixelSize] [, specialMode]);

 

% Get/set details of environment, computer, and video card (i.e. screen):

struct=Screen('Version');

comp=Screen('Computer');

oldBool=Screen('Preference', 'IgnoreCase' [,bool]);

tick0Secs=Screen('Preference', 'Tick0Secs', tick0Secs);

psychTableVersion=Screen('Preference', 'PsychTableVersion');

mexFunctionName=Screen('Preference', 'PsychTableCreator');

proc=Screen('Preference', 'Process');

Screen('Preference','SkipSyncTests', skipTest);

Screen('Preference','VisualDebugLevel', level (valid values between 0 and 5));

Screen('Preference', 'ConserveVRAM', mode (valid values between 0 and 3));

Screen('Preference', 'Enable3DGraphics', [enableFlag]);

 

% Helper functions.  Don't call these directly, use eponymous wrappers:

[x, y, buttonVector]= Screen('GetMouseHelper', numButtons);

Screen('HideCursorHelper', windowPntr);

Screen('ShowCursorHelper', windowPntr);

Screen('SetMouseHelper', windowPntrOrScreenNumber, x, y);

 

% Internal testing of Screen

timeList= Screen('GetTimelist');

Screen('ClearTimelist');

Screen('Preference','DebugMakeTexture', enableDebugging);

 

% Movie and multimedia playback functions:

[ moviePtr [duration] [fps] [width] [height] [count]]=Screen('OpenMovie', windowPtr, moviefile [, async=0] [, preloadSecs=1]);

Screen('CloseMovie', moviePtr);

[ texturePtr [timeindex]]=Screen('GetMovieImage', windowPtr, moviePtr, [waitForImage], [fortimeindex], [specialFlags = 0] [, specialFlags2 = 0]);

[droppedframes] = Screen('PlayMovie', moviePtr, rate, [loop], [soundvolume]);

timeindex = Screen('GetMovieTimeIndex', moviePtr);

[oldtimeindex] = Screen('SetMovieTimeIndex', moviePtr, timeindex);

 

% Video capture functions:

videoPtr =Screen('OpenVideoCapture', windowPtr [, deviceIndex] [,roirectangle] [, pixeldepth] [, numbuffers] [, allowfallback] [, targetmoviename] [, recordingflags] [, captureEngineType]);

Screen('CloseVideoCapture', capturePtr);

[fps starttime] = Screen('StartVideoCapture', capturePtr [, captureRateFPS] [, dropframes=0] [, startAt]);

droppedframes = Screen('StopVideoCapture', capturePtr);

[ texturePtr [capturetimestamp] [droppedcount] [summed_intensityOrRawImageMatrix]]=Screen('GetCapturedImage', windowPtr, capturePtr [, waitForImage=1] [,oldTexture] [,specialmode] [,targetmemptr]);

oldvalue = Screen('SetVideoCaptureParameter', capturePtr, 'parameterName' [, value]);

 

% Low level direct access to OpenGL-API functions:

% Online info for each function available by opening a terminal window

% and typing 'man Functionname' + Enter.

 

Screen('glPushMatrix', windowPtr);

Screen('glPopMatrix', windowPtr);

Screen('glLoadIdentity', windowPtr);

Screen('glTranslate', windowPtr, tx, ty [, tz]);

Screen('glScale', windowPtr, sx, sy [, sz]);

Screen('glRotate', windowPtr, angle, [rx = 0], [ry = 0] ,[rz = 1]);

 

% Support for 3D graphics rendering and for interfacing with external OpenGL code:

Screen('Preference', 'Enable3DGraphics', [enableFlag]);  % Enable 3D gfx support.

Screen('BeginOpenGL', windowPtr [, sharecontext]);  % Prepare window for external OpenGL drawing.

Screen('EndOpenGL', windowPtr);  % Finish external OpenGL drawing.

[targetwindow, IsOpenGLRendering] = Screen('GetOpenGLDrawMode');

[textureHandle rect] = Screen('SetOpenGLTextureFromMemPointer', windowPtr, textureHandle, imagePtr, width, height, depth [, upsidedown][, target][, glinternalformat][, gltype][, extdataformat]);

[textureHandle rect] = Screen('SetOpenGLTexture', windowPtr, textureHandle, glTexid, target [, glWidth] [, glHeight] [, glDepth] [, textureShader]);

[ gltexid gltextarget texcoord_u texcoord_v ] =Screen('GetOpenGLTexture', windowPtr, textureHandle [, x][, y]);

 

% Support for plugins and for builtin high performance image processing pipeline:

[ret1, ret2, ...] = Screen('HookFunction', windowPtr, 'Subcommand', 'HookName', arg1, arg2, ...);

proxyPtr = Screen('OpenProxy', windowPtr [, imagingmode]);

transtexid = Screen('TransformTexture', sourceTexture, transformProxyPtr [, sourceTexture2][, targetTexture][, specialFlags]);  

 

You get a list of all the subcommands that are contained within Screen. To get more information about a particular command type:

Screen OpenWindow? 

 

 

Usage:

 

[windowPtr,rect]=Screen('OpenWindow',windowPtrOrScreenNumber [,color] [,rect][,pixelSize][,numberOfBuffers][,stereomode][,multisample][,imagingmode]);

 

Open an onscreen window. Specify a screen by a windowPtr or a screenNumber (0 is

the main screen, with menu bar). "color" is the clut index (scalar or [r g b]

triplet) that you want to poke into each pixel; default is white. If supplied,

"rect" must contain at least one pixel. If a windowPtr is supplied then "rect"

is in the window's coordinates (origin at upper left), and defaults to the whole

window. If a screenNumber is supplied then "rect" is in screen coordinates

(origin at upper left), and defaults to the whole screen. (In all cases,

subsequent references to this new window will use its coordinates: origin at its

upper left.). Please note that while providing a "rect" parameter to open a

normal window instead of a fullscreen window is convenient for debugging, but

drawing performance, stimulus onset timing and onset timestamping may be

impaired, so be careful.

"pixelSize" sets the depth (in bits) of each pixel; default is to leave depth

unchanged. "numberOfBuffers" is the number of buffers to use. Setting anything

else than 2 will be useful for development/debugging of PTB itself but will mess

up any real experiment. "stereomode" Type of stereo display algorithm to use: 0

(default) means: Monoscopic viewing. 1 means: Stereo output via OpenGL on any

stereo hardware that is supported by MacOS-X, e.g., the shutter glasses from

CrystalView. 2 means: Left view compressed into top half, right view into bottom

half. 3 means left view compressed into bottom half, right view compressed into

top half. 4 and 5 allow split screen display where left view is shown in left

half, right view is shown in right half or the display. A value of 5 does the

opposite (cross-fusion). Values of 6,7,8 and 9 enable Anaglyph stereo rendering

of types left=Red, right=Green, vice versa and left=Red, right=Blue and vice

versa. A value of 10 enables multi-window stereo: Open one window for left eye

view, one for right eye view, treat both of them as one single stereo window.

See StereoDemo.m for examples of usage of the different stereo modes. See

ImagingStereoDemo.m for more advanced usage on modern hardware.

"multisample" This parameter, if provided and set to a value greater than zero,

enables automatic hardware anti-aliasing of the display: For each pixel,

'multisample' color samples are computed and combined into a single output pixel

color. Higher numbers provide better quality but consume more video memory and

lead to a reduction in framerate due to the higher computational demand. The

maximum number of samples is hardware dependent. Psychtoolbox will silently

clamp the number to the maximum supported by your hardware if you ask for too

much. On very old hardware, the value will be ignored. Read 'help AntiAliasing'

for more in-depth information about multi-sampling. "imagingmode" This optional

parameter enables PTB's internal image processing pipeline. The pipeline is off

by default. Read 'help PsychGLImageprocessing' for information about this

feature.

Opening or closing a window takes about one to three seconds, depending on type

of connected display. COMPATIBILITY TO OS-9 PTB: If you absolutely need to run

old code for the old MacOS-9 or Windows Psychtoolbox, you can switch into a

compatibility mode by adding the command Screen('Preference', 'EmulateOldPTB',

1) at the very top of your script. This will restore Offscreen windows and

WaitBlanking functionality, but at the same time disable most of the new

features of the OpenGL Psychtoolbox. Please do not write new experiment code in

the old style! Emulation mode is pretty new and may contain significant bugs, so

use with great caution!  

 

Screen DrawText? 

 

 

Usage:

 

[newX,newY]=Screen('DrawText', windowPtr, text [,x] [,y] [,color] [,backgroundColor] [,yPositionIsBaseline]);

 

Draw text. On MS-Windows, "text" may include two-byte (16 bit) Unicode

characters (e.g. Chinese). A standard Matlab/Octave text string is interpreted

as 8 bit ASCII string. If you want to pass a string which contains 16 bit UTF-16

unicode characters, convert the text to a double matrix, ie, mytext =

double(myunicodetext); then pass the double matrix to this function. Unicode

text drawing is supported if you select the default high quality, but slower GDI

text renderer on Windows.

With the optional fast, low quality renderer, neither anti-aliasing nor Unicode

are supported and text positioning may be a bit less accurate, but it is a good

choice if you are in need for speed over everything else. Select it via the

command:

Screen('Preference', 'TextRenderer', 0); inserted at the top of your script.

On Linux, Unicode and anti-aliasing aren't supported yet.

Default "x" "y" is current pen location. "color" is the CLUT index (scalar or [r

g b] triplet) that you want to poke into each pixel; default produces black with

the standard CLUT for this window's pixelSize.  "yPositionIsBaseline" If

specified, will override the global preference setting for text positioning: It

defaults to off. If it is set to 1, the y pen location defines the base line of

drawn text, otherwise it defines the top of the drawn text. Old PTB's had a

behaviour equivalent to setting 1, unfortunately this behaviour wasn't

replicated in pre 3.0.8 PTB's so now we stick to the new behaviour by default.

"newX, newY" return the final pen location. On GNU/Linux the font renderer is

currently a very simple bitmap renderer which doesn't allow for Unicode

rendering or anti-aliasing.Btw.: Screen('Preference', ...); provides a couple of

interesting text preference settings that affect text drawing, e.g., setting

alpha blending and anti-aliasing modes.  

 

 

Caveat

You should bear in mind that you are entering the murky world of not-quite-professional code. Much of this code is written by people like you, in the middle of trying to do real science. This means that commands may not work as stated, help files may be out of date, commands may not even exist.

Code comments for FlipScreen

screens=0;

[wPtr,rect]=Screen('OpenWindow',screens, 0, []);

Currently the command Screen is taking two arguments.

The first argument is the text string 'OpenWindow' which is telling Screen what you want it to do - open a window.

The second argument tells the command Screen which computer monitor you want to use. If you are running more than one monitor on your computer then 0 means the monitor with the menu bar, 1 means any other monitor. For now, if you have any difficulty I would make sure you are only using one monitor.

The third argument tells Screen that you want the screen to be black (0 because screen uses a zero-indexed colormap).

The fourth argument is a default, telling Matlab you want the experimental screen to cover the entire monitor screen.

Two arguments are returned. wPtr is a handle or window pointer to the window - almost like a variable name that refers to the window or a figure handle. We will use it later to poke things into the window.

rect describes the size of the window. You can see how big your monitor's window is by just typing:

rect

You'll learn more about rect a little later.

when using OpenWindow with Screen, you can use up to 9 arguments (many of which you will never use). They are listed in the first line of the help file when you type:

Screen OpenWindow?

[windowPtr,rect]=Screen('OpenWindow',windowPtrOrScreenNumber [,color] [,rect][,pixelSize][,numberOfBuffers][,stereomode][,multisample][,imaging mode]);

The square brackets [] mean that a command is optional - if you don't specify it then Screen will use a default value.

Arguments for Screen

In the first case we are using a single number that is an index into the colormap. Why do we use the 0-255 range even though we are using an index into a colormap? Because Screen is a mex file and was written in C which is a zero-based language.

In the second case we are using 3 values - for the red, green and blue guns. If you look at the Display in the control panels you will notice that your monitor probably thinks that it is a 32 bit monitor (this is also called having a screen depth of 32bits), but these values are on an 8 bit scale. This is because allowing the red gun to take any number between 0-255 takes up 8 bits, allowing the green gun to take any number between 0-255 takes up 8 bits, allowing the blue gun to take any number between 0-255 takes up 8 bits. 3x8 is 24. The other 8 bits are padding – don’t ask me what they are used for.

Why is the first pixel described as 0 instead of 1? Again, because Screen is a mex file and was written in C which is a zero-based language. If you wanted a smaller window that was 250 wide and x 100 pixels tall then you would use the following: [wPtr,rect]=Screen('OpenWindow',screen, [], [0 0 250 100]);

HideCursor

HideCursor

gets rid of the cursor. It will be restored when you close the screen unless you have a crash in the middle. If so, you may need to type ShowCursor in the command window if your cursor remains missing

Pausing

tic
while toc<2
end

this simply pauses the program for 2 seconds

BlackIndex & WhiteIndex

black=BlackIndex(wPtr);

white=WhiteIndex(wPtr);

These commands find the color lookup table values (clut) given the screen depth (whether your monitor is using 8bit or 32bit organization) of your computer that will that will give you black or white. Weirdly, the values of white and black depend on the screen depth, especially on Macs.

FillRect

Screen('FillRect',wPtr,black); Screen('FillRect',wPtr,white);

FillRect fills a rectangle the size of the screen to be black or white

Screen('FillRect', windowPtr [,color] [,rect] )

You can also specify rgb values for the color Screen('FillRect', wPtr , [255 0 0 ]);

or draw a rectangle that is smaller than the window Screen('FillRect', wPtr [0 255 0 ] [0 0 50 50])

Flip

Screen(wPtr, 'Flip');

Whenever you draw something it is drawn offscreen in some nebulous neverland. You then need to Flip the screen so the offscreen window you drew on comes to the onscreen window – the one that is actually on the monitor.

Monitors have a refresh rate of something between 60Hz-120Hz (for a standard monitor). Every refresh begins at the top of the screen, and moves quickly down the screen in a matter of a few milliseconds. The flip command simply tells Matlab to refresh the screen with the image you have drawn offscreen.

Close

Screen('Close', wPtr);

This closes the screen and restores your normal working environment, including your cursor

If your screen freezes

The Screen window will hide the main menu bar and obscure the Matlab command window. That can be a problem if your program stops (perhaps due to an error) before closing the window. The keyboard will seem to be dead because the output of the keyboard is directed to the front most window, which belongs to Screen not Matlab, so Matlab won’t be aware of your typing.

Remain calm.

Force Quit in Windows

ctrl-c

This halts any program. (Type a "c" while holding down the "Ctrl" key).

Alt-Tab brings the Matlab Command window forward. The screen might still be hard to make out (or invisible), if you’ve been playing with the lookup table. Don't let that worry you. Just type

clear Screen

This will cause Matlab to flush Screen. Screen.mex, as part of its exit procedure, cleans up everything it did, closing all its windows and restoring the lookup table of all its displays.

You might want to type:

clear all
clear mex

after killing a program, just to make sure everything is back to normal. clear mex kills any mex files that might be still running

If that didn't work?

Sometimes, Ctrl-C fails to halt progams executing in a Matlab process run with the "-nojvm" option. To halt a runaway Psychtoolbox script in Psychtoolbox you might resort to the Windows Task Manager to kill the Screen program. (Use Ctrl-Alt-Delete to open the Task Manager.)

Force Quit in Mac

Ctrl-c

This halts any program. (Type a "c" while holding down the "Ctrl" key).

Cmd-0 (command-zero; command is the thing that looks like a four leaf clover) brings the Matlab Command window forward. The screen might still be hard to make out (or invisible), if you’ve been playing with the lookup table. Don't let that worry you. Just type

clear Screen

This will cause Matlab to flush Screen. Screen.mex, as part of its exit procedure, cleans up everything it did, closing all its windows and restoring the lookup table of all its displays.

You might want to type:

clear all
clear mex

after killing a program, just to make sure everything is back to normal. clear mex kills any mex files that might be still running

If that didn't work?

Sometimes, Ctrl-C fails to halt progams executing in a Matlab process. To halt a runaway Psychtoolbox script in you might resort to Apple-Command-Escape which executes "Force Quit" on Matlab, closing Matlab and all of its windows.

Force Quit in Linux

Ctrl-Alt-Escape , followed by a mouse click kills the onscreen windows and your Matlab session.

You might want to type:

clear all
clear mex

after killing a program, just to make sure everything is back to normal. clear mex kills any mex files that might be still running

FunkyScreen

Here is another more elaborate example of how you can use Screen

%  FunkyScreen.m

%

%  opens a window using psychtoolbox,

%  makes the window do some funky things

%

%  written for Psychtoolbox 3 on the PC by IF 3/2007

 

screenNum=0;

flipSpd=13; %  a flip every 13 frames

Screen('Preference', 'Verbosity', 0);

Screen('Preference', 'SkipSyncTests',1);

Screen('Preference', 'VisualDebugLevel',0);

 

[wPtr,rect]=Screen('OpenWindow',screenNum);

 

monitorFlipInterval=Screen('GetFlipInterval', wPtr);

 

black=BlackIndex(wPtr);

white=WhiteIndex(wPtr);

 

% blank the Screen and wait a second

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip');

HideCursor;

tic

while toc<1

end

 

% make a rectangle in the middle of the screen flip colors and size

Screen('FillRect',wPtr,black);

vbl=Screen(wPtr, 'Flip'); % collect the time for the first flip with vbl

for i=1:10

    Screen('FillRect',wPtr,[0 0 255], [100 150 200 250]);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

    % flip 13 frames after vbl

    Screen('FillRect',wPtr,[255 0 0], [100 150 400 450]);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

end                                        

 

% blank the screen and wait a while

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

tic

while toc<1

end

 

% make circles flip colors & size

Screen('FillRect',wPtr,black);

vbl=Screen(wPtr, 'Flip');

for i=1:10

    Screen('FillOval',wPtr,[0 180 255], [ 500 500 600 600]);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

    Screen('FillOval',wPtr,[0 255 0], [ 400 400 900 700]);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

end

 

% blank the Screen and wait a second

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

tic

while toc<1

end

 

% make lines that flip colors size  & position

Screen('FillRect',wPtr,black);

vbl=Screen(wPtr, 'Flip');

for i=1:10

    Screen('DrawLine',wPtr,[0 255 255], 500, 200, 700 ,600, 5);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

    Screen('DrawLine',wPtr,[255 255 0], 100, 600, 600 ,100, 5);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

end

 

% blank the Screen and wait a second

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

tic

while toc<1

end

 

% combine the stimuli

Screen('FillRect',wPtr,black);

vbl=Screen(wPtr, 'Flip');

for i=1:10

    Screen('FillRect',wPtr,[0 0 255], [100 150 200 250]);

    Screen('DrawLine',wPtr,[0 255 255], 500, 200, 700 ,600, 5);

    Screen('FillOval',wPtr,[0 180 255], [ 500 500 600 600]);

    Screen('TextSize', wPtr , 150);

    Screen('DrawText', wPtr, 'FUNKY!!', 200, 20, [255 50 255]);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

 

    Screen('FillRect',wPtr,[255 0 0], [100 150 400 450]);

    Screen('FillOval',wPtr,[0 255 0], [ 400 400 900 700]);

    Screen('DrawLine',wPtr,[255 255 0], 100, 600, 600 ,100, 5);

    vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

end

 

% blank the screen and wait a second

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

tic

while toc<1

end

 

Screen('CloseAll');

ShowCursor 

 

Code comments on FunkyScreen

flipSpd=13;

Here you define flipSpd, you are going to make the display flip every 13 frames.

monitorFlipInterval=Screen('GetFlipInterval', wPtr)

You can find out how fast your monitor flips using 'GetFlipInterval'. 1/monitorFlipInterval will tell you the frame rate in Hz of your monitor.

Screen('Preference', 'Verbosity', 0);

Screen('Preference', 'SkipSyncTests',1);

Screen('Preference', 'VisualDebugLevel',0);

 

These tell Matlab not to spit out an annoying series of factoids when you call Screen.

vbl=Screen(wPtr, 'Flip');

This time when you flipped the window you made Screen return the time (according to the computer clock) that it did the flip. That time is saved as vbl.

Screen('FillRect',wPtr,[0 0 255], [100 150 200 250]);

Here we are using FillRect again, but this time we are defining the rect as only being a subset of the entire screen and we are using a color. Remember that the rect is defined as LeTteRBox.

vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

We flip the screen, but this time we are telling it to flip at time | vbl + (13 * monitorFlipInterval)|

This means it will flip 13 frames after the flip where we saved the time of the flip in the variable vbl.

We keep doing the same thing again, but each time vbl refers to the flip that happened on the previous flip. So between each flip there is a 13 frame delay.

Screen('FillOval',wPtr,[0 180 255], [ 500 500 600 600]);

FillOval works just like FillRect except that it draws ovals instead of squares.

Screen('DrawLine',wPtr,[0 255 255], 500, 200, 700 ,600, 5);

DrawLine doesn’t take a rect as an argument. Instead it takes in four separate arguments

  1. starting horizontal position
  2. starting vertical position
  3. ending horizontal position
  4. ending vertical position I guess the mnemonic for that could be HumVee?

Screen('TextSize', wPtr , 150);

Screen('DrawText', wPtr, 'FUNKY!!', 200, 20, [255 50 255]);

Here we are drawing text on the screen. First we define the size of the text as having a font size of 150. Then we draw it on the screen. 200 and 20 refer to the starting horizontal and vertical positions of where you want the text placed (HumVee again).

[255 50 255] refers to the color of the text.

Screen('FillRect',wPtr,[0 0 255], [100 150 200 250]);

Screen('DrawLine',wPtr,[0 255 255], 500, 200, 700 ,600, 5);

Screen('FillOval',wPtr,[0 180 255], [ 500 500 600 600]);

Screen('TextSize', wPtr , 150);

Screen('DrawText', wPtr, 'FUNKY!!', 200, 20, [255 50 255]);

vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));

Here we are drawing more than one thing on the offscreen window before we flip it to the front. The order you draw things in matters, since things will be drawn on top of each other.

 

 

Putting up Matrix Images

 

% PutUpImage.m

% opens a window using Psychtoolbox,

% puts up a 2D image and then a 3D image

%

% written for Psychtoolbox 3 on the PC by IF 3/2007

 

screen=0;

Screen('Preference', 'Verbosity', 0);

Screen('Preference', 'SkipSyncTests',1);

Screen('Preference', 'VisualDebugLevel',0);

 

[wPtr,rect]=Screen('OpenWindow',screen);

HideCursor;

black=BlackIndex(wPtr);

Screen('FillRect',wPtr,black);

Screen(wPtr, 'Flip');

tic

while toc<1

end

 

image2D=255*rand(100, 100);

textureIndex=Screen('MakeTexture', wPtr, image2D);

Screen('DrawTexture', wPtr, textureIndex);

Screen(wPtr, 'Flip');

 

tic

while toc<2

end

 

image3D=255*rand(100, 100, 3);

textureIndex=Screen('MakeTexture', wPtr, image3D);

Screen('DrawTexture', wPtr, textureIndex, [], rect, [],0 );

Screen(wPtr, 'Flip');

tic

while toc<2

end

 

Screen('Close', wPtr); 

 

 

Note that putting up a matrix is slightly different from drawing a rectangle or an oval. You can't directly put the matrix onto the window.  

There is instead an extra step where you need to create a textureIndex using the Screen command 'MakeTexture'. This textureIndex is an index (this might be a moment to re-read the section on 'references', 'indices', 'handles' and 'pointers') into an OpenGL structure that contains the matrix transformed into an image. Once you have created the texture, you can then draw it on the screen.

Make sure you remember this - it's one of the mistakes that beginners with Psychtoolbox often make.


FunkyJon.m

 

Here's a version of funkyscreen done by a student in a previous class with way too much spare time on his hands.

 

% FunkyJon.m

%  This is my Funky li'l m_file written to demonstrate psychtoolbox

%

%  Written by Jon D. Howe 4/16/2007

 

clear all

 

% Initialize variables

screenNum=0;

flipSpd=25; % flip every 25 frames

 

[wPtr,rect]=Screen('OpenWindow',screenNum, 0, []);

 

monitorFlipInterval=Screen('GetFlipInterval',wPtr);

black=BlackIndex(wPtr);

white=WhiteIndex(wPtr);

 

HideCursor;

 

% blank screen and wait a second

Screen('FillRect',wPtr,black);

Screen('Flip',wPtr);

tic

while toc<.2

end

 

% Flip and collect th e time of the flip in vbl

vbl=Screen('Flip', wPtr);

 

% Draw Background

Screen('FillRect', wPtr, [100 255 255]);

Screen('FillRect', wPtr, [0 255 0], [0 2*rect(4)/3 rect(3) rect(4)])

 

% Draw house

Screen('FillRect', wPtr, [0 0 255], [420 300 680 600]);

Screen('FillPoly', wPtr, [100 0 0], [420 300; 540 200; 680 300]);

 

% Draw roof

Screen('DrawLine', wPtr, [50 50 50], 410, 310, 540, 200, 5);

Screen('DrawLine', wPtr, [50 50 50], 690, 310, 540, 200, 5);

 

% Draw doors and windows

% door

Screen('FillRect', wPtr, [200 200 0], [520 450 600 600]);

% window

Screen('FillRect', wPtr, [175 200 256], [440 380 500 440]);

Screen('FrameRect', wPtr, [0 0 0], [440 380 500 440], 3);

Screen('DrawLine', wPtr, [0 0 0], 470, 380, 470, 440, 3);

Screen('DrawLine', wPtr, [0 0 0], 440, 410, 500, 410, 3);

 

% gable window

Screen('FillArc', wPtr, [175 200 256], [520, 260, 600, 320],270,180);

Screen('FrameArc', wPtr, [0 0 0], [520 260 600 320],270,180,3);

 

% Draw tree

Screen('FillRect', wPtr, [100 100 0], [200 400 230 700]);

Screen('FillOval', wPtr, [0 150 0], [50 250 370 550]);

 

% Draw sun

Screen('FillOval', wPtr, [256 256 0], [760 20 920 180]);

Screen('DrawLine', wPtr, [0 0 0], 850, 75, 870, 75, 2);

Screen('FrameOval', wPtr, [0 0 0], [800 65 820 85], 2);

Screen('FrameArc', wPtr, [0 0 0], [800 85 870 160], 90, 180, 2);

 

% Draw name

Screen('TextSize', wPtr, 72);

Screen('DrawText', wPtr, 'Funky Jon''s House', 200, 100, [256 256 256]);

vbl=Screen('Flip', wPtr, vbl+(flipSpd*monitorFlipInterval), 2);

 

tic;

while toc<3

end

 

Screen('CloseAll');

ShowCursor;