# Psychtoolbox Crashing Unpredictably

**URL:** <https://psychtoolbox.discourse.group/t/psychtoolbox-crashing-unpredictably/4238>\
**Category:** Programming Help\
**Tags:** windows\
**Created:** [February 6, 2022, 2:33pm UTC](https://psychtoolbox.discourse.group/t/psychtoolbox-crashing-unpredictably/4238 "2022-02-06T14:33:54Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cassie](https://avatars.discourse-cdn.com/v4/letter/c/db5fbb/32.png) [@Cassie](https://psychtoolbox.discourse.group/u/Cassie)\
**Post date:** [February 6, 2022, 2:33pm UTC](https://psychtoolbox.discourse.group/t/psychtoolbox-crashing-unpredictably/4238/1 "2022-02-06T14:33:54Z")

</div>

PsychtoolboxVersion Output:  
‘3.0.18 – Flavor: Manual Install, 26-Oct-2021 18:56:38.  
I am running this on Windows 10.

I am using Psychtoolbox for a method of constant stimuli task that involves displaying images. A floating adapter image is displayed first for 30 seconds, and then the participant goes through 90 trials. Each trial involves the following: a 2 second blank period showing a black screen and small fixation cross. Then an image (the fixation cross is constantly present) is shown for 0.2 seconds. Then the image disappears, the participant responds with a keypress, and finally, there is a 5 second adaptation period with the same floating adapter image each time. Once the 90th trial is finished, an exit screen is shown, and when the participant presses any key, the Psychtoolbox window closes.  
Sometimes the experiment works fine, with all 90 trials completed with no issue. Sometimes, though, unpredictably, MATLAB or Psychtoolbox seems to freeze on one of the last trials. Sometimes it’s the 88th trial, sometimes the 89th, sometimes the 87th; there is no pattern I can discern. Anyway, what happens is that after the participant responds with a keypress, the floating adapter image never appears. The screen just remains black, with the fixation cross in the middle of the screen. The only way to exit that I’ve found is by hitting the “Window” key to bring up the Start Menu and then attempting to close the Psychtoolbox window from the Taskbar. MATLAB itself then quits and has to be restarted. Because of that, there’s no error message left behind.  
This problem happens both on my laptop running Windows 10, and a desktop computer running Windows 10.  
I saw a very similar issue on this forum that was solved by ensuring that each texture was cleared before a new one was created. I modified my code accordingly, and the experiment actually ran successfully three times in a row (this was remarkable), but then I tried running it a fourth time, and the experiment froze on the 87th trial.  
Here is the main function that runs the experiment, along with a couple of smaller functions I wrote that may possibly be relevant.

function drawImage

arguments  
image {mustBeNumeric};  
location (1,4) double;  
window(1,1) double;  
end

Screen(‘Close’);  
image\_texture = Screen(‘MakeTexture’,window,image);  
Screen(‘DrawTexture’,window,image\_texture,[],location,0);  
end

function drawFixationCross

arguments  
window (1,1) double;  
window\_rect (1,4) double;  
color double;  
arm\_length (1,1) double;  
line\_width (1,1) double;  
end

[x\_center,y\_center] = RectCenter(window\_rect);

x\_coordinates = [-arm\_length arm\_length 0 0];  
y\_coordinates = [0 0 -arm\_length arm\_length];  
coordinates = [x\_coordinates;y\_coordinates];

Screen(‘DrawLines’,window,coordinates,line\_width,color,…  
[x\_center y\_center],0);  
end

function RunExperiment

arguments  
participant (1,1) string;  
object\_number (1,1) double;  
adapter\_view (1,1) string;  
end

%% Sync tests

%{  
NOTE: The third argument of Screen(‘Preference’,‘SkipSyncTests’,[]) must  
be either 0 or 1 (0 = don’t skip; 1 = skip).

If possible, this argument should be set to 0, since doing the sync tests  
will ensure that stimulus presentation timing is super accurate and  
precise.

However, sometimes sync tests fail on certain computers, and if they  
fail, Psychtoolbox can’t run at all (the function will terminate  
immediately and an error message titled “PTB - Error: Synchronization  
Failure!” will be displayed). If this happens, and you’re in a situation  
where extremely accurate and precise timing is not required (experimenting  
with or revising the code, debugging, etc.), then the argument can be set  
to 1.  
%}  
Screen(‘Preference’,‘SkipSyncTests’,0);

%% Load the experiment stimuli and other variables from file

load Variables.mat; %#ok  
clear tutorial\_text;

%% Extra input argument validation

if participant == “”  
error(‘participant cannot be an empty string!’);  
elseif object\_number \< 1 || object\_number \> length(objects) - 1  
error(‘object\_number must be a number from 1 to %d!’,…  
length(objects) - 1);  
elseif adapter\_view == “”  
error(‘adapter\_view cannot be an empty string!’);  
end

%% Set the raw data filename

timestamp = sprintf(’%04d-%02d-%02d\_%02d-%02d-%02d’,round(clock));  
raw\_data\_filename = sprintf(‘RAW\_%s\_obj-%d\_%s\_%s.mat’,…  
participant,object\_number,adapter\_view,timestamp);

%% Get the object’s adapter images and test images

adapter\_images = objects(object\_number).adapters;  
test\_images = objects(object\_number).test;  
if isempty(adapter\_images)  
error(‘No adapter images found for this object!’);  
elseif isempty(test\_images)  
error(‘No test images found for this object!’);  
end  
clear objects;

%% Get the size (in pixels) of the images

%{  
NOTE: The size function’s output has the dimensions in the wrong order,  
so the dimensions have to be switched around.  
%}  
image\_size = size(adapter\_images{1});  
image\_size = [image\_size(2) image\_size(1)];

%% Calculate the number of times each test image must be presented

max\_image\_presentations = trial\_number / length(test\_images);

%% Preallocate arrays to track test image presentations and hold data

tracker = zeros(1,length(test\_images));  
test\_view\_data = strings(1,trial\_number);  
response\_data = zeros(1,trial\_number);  
reaction\_time\_data = zeros(1,trial\_number);

%% Set up Psychtoolbox to display images and text

%{  
NOTE: This also involves establishing the boundaries of the floating area  
that the adapter and test images will be restricted to.  
%}  
PsychDefaultSetup(2);  
screens = Screen(‘Screens’);  
screen\_number = min(screens);  
black = BlackIndex(screen\_number);  
white = WhiteIndex(screen\_number);  
[window,window\_rect] = PsychImaging(‘OpenWindow’,screen\_number,black);  
try  
image\_rect = [0 0 image\_size(1) image\_size(2)];  
[x\_range,y\_range] = calculateLocationRange(window\_rect,…  
floating\_area\_size,image\_size);  
Screen(‘TextSize’,window,text\_size);  
Screen(‘TextFont’,window,‘Courier’);  
HideCursor(window);  
clear screens screen\_number floating\_area\_size image\_size text\_size black;

%% Display the start screen

%{  
NOTE: 65 and 186 are the key codes for the ‘a’ and ‘;’ keys. These key  
codes must be modified if and when the input method is changed.  
%}  
DrawFormattedText(window,start\_screen\_text,‘center’,‘center’,white);  
Screen(‘Flip’,window);  
KbStrokeWait;  
clear start\_screen\_text;  
RestrictKeysForKbCheck([65 186]);

%% Initial adaptation period

adapter\_index = strcmp(adapter\_view,adapter\_views);  
adapter = adapter\_images{adapter\_index};  
clear adapter\_views adapter\_images adapter\_index;  
[location,current\_edge] = chooseRandomLocation(image\_rect,x\_range,y\_range);  
[target\_edge,target\_location] = chooseTargetEdge(location,x\_range,…  
y\_range,current\_edge);  
drawImage(adapter,location,window);  
drawFixationCross(window,window\_rect,fixation\_cross\_color,arm\_length,…  
line\_width);  
Screen(‘Flip’,window);  
seconds\_passed = 0;  
tic;  
while seconds\_passed \< initial\_adaptation\_period  
[location,arrived] = moveTowardLocation(location,target\_location,1);  
if arrived  
[target\_edge,target\_location] = chooseTargetEdge(location,…  
x\_range,y\_range,target\_edge);  
end  
drawImage(adapter,location,window);  
drawFixationCross(window,window\_rect,fixation\_cross\_color,…  
arm\_length,line\_width);  
Screen(‘Flip’,window);  
WaitSecs(time\_to\_travel\_one\_pixel);  
seconds\_passed = toc;  
end

for i = 1:trial\_number  
%% Blank period

```
drawFixationCross(window,window_rect,fixation_cross_color,...
    arm_length,line_width);
Screen('Flip',window);
WaitSecs(blank_period);

%% Test period

%{
NOTE: Keeping track of the image that was presented during the previous
trial (previous_test_index) is necessary to prevent the same image
being displayed twice in succession.
%}
image_chosen = false;
while image_chosen == false
    test_index = randi(length(test_images));
    if i == 1
        image_chosen = true;
    elseif test_index ~= previous_test_index &&...
            tracker(test_index) < max_image_presentations
        image_chosen = true;
    end
end
previous_test_index = test_index;
tracker(test_index) = tracker(test_index) + 1;
test_view_data(i) = test_views(test_index);
current_test = test_images{test_index};
[location,~] = chooseRandomLocation(image_rect,x_range,y_range);
drawImage(current_test,location,window);
drawFixationCross(window,window_rect,fixation_cross_color,...
    arm_length,line_width);
Screen('Flip',window);
WaitSecs(test_period);

%% Response period

%{
NOTE: I inserted a pause of 0.2 seconds because without it, the top_up
adaptation period would start the instant I made my response, and the
speed was actually a little unnerving.
%}
drawFixationCross(window,window_rect,fixation_cross_color,...
    arm_length,line_width);
Screen('Flip',window);
response_made = false; 
start_time = GetSecs;
while response_made == false
    [key_is_pressed,~,key_code] = KbCheck;
    if key_is_pressed
        response_made = true;
    end
end
end_time = GetSecs;
WaitSecs(0.2);
response_data(i) = find(key_code);
reaction_time_data(i) = end_time - start_time;
clc;

%% Save the raw data

saveData(raw_data_filename,participant,object_number,adapter_view,...
    timestamp,test_view_data,response_data,reaction_time_data);

%% Top-up adaptation period

if i == trial_number
    break;
else
    [location,current_edge] = chooseRandomLocation(image_rect,...
        x_range,y_range);
    [target_edge,target_location] = chooseTargetEdge(location,...
        x_range,y_range,current_edge);
    drawImage(adapter,location,window);
    drawFixationCross(window,window_rect,fixation_cross_color,...
        arm_length,line_width);
    Screen('Flip',window);
    seconds_passed = 0;
    tic;
    while seconds_passed < top_up_adaptation_period
        [location,arrived] = moveTowardLocation(location,...
            target_location,1);
        if arrived
            [target_edge,target_location] = ...
                chooseTargetEdge(location,x_range,y_range,target_edge);
        end
        drawImage(adapter,location,window);
        drawFixationCross(window,window_rect,fixation_cross_color,...
            arm_length,line_width);
        Screen('Flip',window);
        WaitSecs(time_to_travel_one_pixel);
        seconds_passed = toc;
    end
end
Screen('Close');

```

end

%% Display the exit screen

RestrictKeysForKbCheck([]);  
DrawFormattedText(window,exit\_screen\_text,‘center’,‘center’,white);  
Screen(‘Flip’,window);  
KbStrokeWait;  
Screen(‘Close’);  
sca;  
sca;

%% Save the raw data

saveData(raw\_data\_filename,participant,object\_number,adapter\_view,…  
timestamp,test\_view\_data,response\_data,reaction\_time\_data);  
fprintf(‘Filename: %s\n’,raw\_data\_filename);  
clear;

%% Handle errors

catch the\_error  
save([‘ERROR\_’ raw\_data\_filename])  
sca;  
sca;  
rethrow(the\_error);  
end  
end

---

<div class="post-metadata">

**Author:** ![mariokleiner](https://avatars.discourse-cdn.com/v4/letter/m/13edae/32.png) [@mariokleiner](https://psychtoolbox.discourse.group/u/mariokleiner)\
**Post date:** [February 6, 2022, 4:59pm UTC](https://psychtoolbox.discourse.group/t/psychtoolbox-crashing-unpredictably/4238/2 "2022-02-06T16:59:36Z")

</div>

Hi,

the main reason for this failure you’ve got already covered with closing textures, so that’s not it - good job with that! Skimming the code does not show obvious red flags.

Apart from that your approach to timing is really broken, assuming you care about timing as some of the code comments suggest. Use WaitSecs and GetSecs for general timing, tic and toc should never show up in a well written script. More importantly use the timestamps and timing mechanisms of Screen(‘Flip’), not WaitSecs etc. like you do now! Our intro pdf, tutorials and demos show how to do timing competently.

Wrt. to the actual cause of freezes, any further advice from my side will require buying priority support `help PsychPaidSupportAndServices`. Ofc. if the problem should be caused by graphics driver or operating system bugs, the by far best course of action is upgrading to Linux, as wrt. OS bugs usually no fix is possible and only some shady workarounds if you are lucky. If you go the route of priority support, provide details about your OS version, graphics card model etc, hardware configuration etc. to make sure paid time is spent efficiently.

-mario
