Выполняется только часть кода и не отображается сообщение об ошибке

#matlab #gaussian #psychtoolbox

#matlab #гауссовский #psychtoolbox

Вопрос:

Я использую MATLAB 2020 Psychtoolbox в Mac OS, и каждый раз, когда я запускаю этот код, экран становится серым, за которым следует звуковой сигнал ошибки, однако в окне командной строки сообщение об ошибке не отображается. Как мне выполнить весь код?

 % Clear the workspace
close all;
clearvars;
sca;

% Setup PTB with some default values
PsychDefaultSetup(2);

% Seed the random number generator. Here we use the an older way to be
% compatible with older systems. Newer syntax would be rng('shuffle'). Look
% at the help function of rand "help rand" for more information
rand('seed', sum(100 * clock));

  % Set the screen number to the external secondary monitor if there is one
% connected
screenNumber = max(Screen('Screens'));

% Define white, grey and black
white = WhiteIndex(screenNumber);
grey = white / 2;
black = BlackIndex(screenNumber);

% Open an on screen window
[window, windowRect] = PsychImaging('OpenWindow', screenNumber, grey);

% Get the size of the on screen window
[screenXpixels, screenYpixels] = Screen('WindowSize', window);

% Query the frame duration
ifi = Screen('GetFlipInterval', window);

% Set up alpha-blending for smooth (anti-aliased) lines
Screen('BlendFunction', window, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');

% Setup the text type for the window
Screen('TextFont', window, 'Ariel');
Screen('TextSize', window, 36);

% Get the centre coordinate of the window
[xCenter, yCenter] = RectCenter(windowRect);


%----------------------------------------------------------------------
%                       Keyboard information
%----------------------------------------------------------------------

% Define the keyboard keys that are listened for. We will be using the left
% and right arrow keys as response keys for the task and the escape key as
% a exit/reset key
escapeKey = KbName('ESCAPE');
leftKey = KbName('LeftArrow');
rightKey = KbName('RightArrow');
downKey = KbName('DownArrow');

%----------------------------------------------------------------------
%                       Fixation cross
%----------------------------------------------------------------------

% Here we set the size of the arms of our fixation cross
fixCrossDimPix = 10;

% Now we set the coordinates (these are all relative to zero we will let
% the drawing routine center the cross in the center of our monitor for us)
xCoords = [-fixCrossDimPix fixCrossDimPix 0 0];
yCoords = [0 0 -fixCrossDimPix fixCrossDimPix];
allCoords = [xCoords; yCoords];

% Set the line width for our fixation cross
lineWidthPix = 4;

%----------------------------------------------------------------------
%                            Colors
%----------------------------------------------------------------------

% We are going to use three colors for this demo. Red, Green and blue.
wordList = {'Green', 'Magenta', 'Orange'};
Colors = [0 1 0; 1 0 1; 0.8500 0.3250 0.0980];

%----------------------------------------------------------------------
%                  Define positions of sequences
%----------------------------------------------------------------------

leftX = screenXpixels/2.5;
leftY = screenXpixels/1.6;
rightX = screenXpixels/1.7;
rightY = screenYpixels/1.6;
upX = screenXpixels/2.1;
upY = screenYpixels/2.6;

left = [leftX leftY];
right = [rightX rightY];
up = [upX upY];

%----------------------------------------------------------------------
%                  Randomise temporal order of trials
%----------------------------------------------------------------------
 
trialorder = [1 0 0 0 0];
randtemp = shuffle(trialorder);

%----------------------------------------------------------------------
%                           Trial loop
%----------------------------------------------------------------------
nTrials = 5;

for trial = 1:randtemp
    
    % randomise position of sequences
    randpos = shuffle(left, right, up);
    
    % fixation cross
    % Draw the fixation cross in white, set it to the center of our screen and
    % set good quality antialiasing
    Screen('DrawLines', window, allCoords,...
    lineWidthPix, white, [xCenter yCenter], 2);

    % Derive distributions
    seq1 = distribution(0.02, 0.126, 0.146, 0.106, 5); % high variance
    seq2 = distribution(0.02, 0.126, 0.146, 0.106, 5); % low variance
    seq3 = distribution(0.02, 0.126, 0.146, 0.106, 5); % low variance
    
    seq4 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq5 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq6 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    
    seq7 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq8 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq9 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    
    seq10 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq11 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq12 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    
    seq13 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq14 = distribution(0.02, 0.126, 0.146, 0.106, 5);
    seq15 = distribution(0.02, 0.126, 0.146, 0.106, 5);

    if trial == 1 
       DrawFormattedText(window, 'Name the color nn Press Any Key To Begin',...
       'center', 'center', black);
       Screen('Flip', window);
       KbStrokeWait;
    end
    
    if randtemp() == 0
        % trail 1
        Screen('DrawText', num2str(seq1), white, randpos(1));
        Screen('DrawText', num2str(seq2), white, randpos(2));
        Screen('DrawText', num2str(seq3), white, randpos(3));
        WaitSecs(0.75)
        Screen('Flip', window);
        KbStrokeWait;
           
        Screen('DrawText', num2str(seq2), white, randpos(1));
        Screen('DrawText', num2str(seq3), white, randpos(2));
        WaitSecs(0.75)
        Screen('Flip', window);
        KbStrokeWait;
        
        %trial 2
        %repeat
        
    else 
        Screen('DrawText', num2str(seq13), white, randpos(1));
        Screen('DrawText', num2str(seq14), white, randpos(2));
        Screen('DrawText', num2str(seq15), white, randpos(3));
        WaitSecs(0.75)
        Screen('Flip', window);
        KbStrokeWait;
           
        Screen('DrawText', num2str(seq13), white, randpos(1));
        Screen('DrawText', num2str(seq14), white, randpos(2));
        WaitSecs(0.75)
        Screen('Flip', window);
        KbStrokeWait;
    end
end       

        

      

% Flip to the screen
Screen('Flip', window);

% Wait for a key press
KbStrokeWait;

% Clear the screen
sca
  

Функция ‘distribution’ — это самодельная функция, которая генерирует распределение случайных чисел по Гауссу с заданным средним значением, дисперсией, верхним пределом, нижним пределом и заданным количеством чисел:

 function distribution(va, mu, ul, ll, nvals)
 multiplier=10;
 x = mu   randi(multiplier*nvals,1)*sqrt(va); % Generate sufficient random numbers
 idx = (ll <= x) amp; (x <= ul); % Extract the value in the given range [min max]
 while sum(idx)<nvals
    multiplier=multiplier 1;
    x = mu   randi(multiplier*nvals,1)*sqrt(va); % Generate sufficient random numbers
    idx = (ll <= x) amp; (x <= ul); % Extract the value in the given range [min max]
 end
 x = x(idx);
 x = x(1:nvals); % Extract numbers
  

Ответ №1:

Вы видите серый экран только потому, что ошибка не приводит к закрытию окна Psychtoolbox (для которого вы установили серый фон). Чтобы закрыть экран и отобразить ошибку, оберните свой код в инструкцию try, catch, которая закроет экран и повторно загрузит ошибку, если она обнаружена.

Например (здесь слово CODE является просто заполнителем, вместо этого замените его вашим фактическим кодом)

 try
    CODE
catch e
    sca;
    rethrow(e)
end
  

В этом случае, если в теле инструкции try обнаружена ошибка, она перейдет к инструкции catch, вызывающей ошибку e . Сначала экран будет закрыт с помощью sca , затем ошибка будет фактически показана с помощью rethrow .

Что касается фактической ошибки, с которой вы столкнулись, я думаю, что с вашим текущим кодом по крайней мере несколько проблем:

  1. Функция Shuffle в Psychtoolbox пишется с заглавной буквы — ‘Shuffle’ и имеет один ввод. Здесь вы используете ‘shuffle’ и предоставляете три отдельных ввода.

    Вместо того, чтобы предоставлять ‘left’, ‘right’ и ‘up’ в качестве отдельных входных данных, объединил их в элементы массива с одной ячейкой:

    замена: randpos = shuffle(left, right, up);

    с: randpos = Shuffle({left, right, up});

    и выберите их как элементы массива ячеек:

    замена: Screen('DrawText', num2str(seq1), white, randpos(1));

    с: Screen('DrawText', window, num2str(seq1), white, [], black, randpos{1}(1), randpos{1}(2));

  2. В определенную вами функцию распространения вы не включили выходной аргумент. Замените текущую первую строку функции на: function x = distribution(va, mu, ul, ll, nvals)

  3. KbStrokeWait без входного параметра проверяется только первая подключенная клавиатура. Это может быть игнорирование нажатий клавиш, например, если вы используете внешнюю клавиатуру на ноутбуке. Использование KbStrokeWait(-3) проверит все подключенные устройства.

  4. Похоже, что ваша функция распределения либо не сходится к решению, либо требует много времени для определения решения, поскольку, похоже, она случайным образом генерирует значения, а затем проверяет, достаточно ли их в желаемом интервале. Вместо этого я бы начал со встроенной функции для генерации случайных нормальных значений. Например, следующее сгенерирует 5 значений из распределения со средним значением 0,02 и дисперсией 0,126. Однако в нем не реализована проверка того, что все сгенерированные значения находятся в заданном диапазоне: randn(1, 5) * sqrt(0.126) 0.02;

  5. В вызове DrawText отсутствует указатель на окно.

Могут быть и другие проблемы, но решение этих проблем поможет вам начать.

Комментарии:

1. Привет, я заменил код, как вы предложили, для рандомизации положения стимулов, но я не уверен, как ссылаться на отдельные координаты x и y в векторах «влево», «вправо» и «вверх» в массиве randpos. При использовании предложенного вами кода возникает следующая ошибка: Error using Screen Usage: [newX,newY,textHeight]=Screen('DrawText', windowPtr, text [,x] [,y] [,color] [,backgroundColor] [,yPositionIsBaseline] [,swapTextDirection]); Error in Third_draft (line 218) Screen('DrawText', window, num2str(seq1), randpos{1}, randpos{1}, [0 1 0]); Спасибо!

2. Извините за это, я обновил свой ответ. Поскольку вы сохраняете X и Y в одном массиве, но экранной функции они нужны как отдельные переменные, вам придется дважды индексировать в массив randpos, один раз для X и один раз для Y: Screen(‘DrawText’, window, num2str(seq1), white, [], black, randpos{1}(1), randpos{1}(2));