-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdemo_prf.m
198 lines (168 loc) · 5.86 KB
/
demo_prf.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
function demo_prf(subjCode, isEyelink, isEmulated, runCode)
% demo_prf(subjCode, isEyelink, isEmulated, runCode)
%
% Run fMRI pRF for category stimuli.
%
% Input:
% subjCode <str> subject code
% isEyelink <boo> 0: whether to use EyeLink.
% isEmulated <boo> 1: emulated and will not wait for MRI
% trigger (default). 0: will wait for MRI trigger.
% runCode <int> the run code/number. It can be generated
% based on the output files in Matlab Data/.
%
% Created by Haiyang Jin (2023-Feb-25)
% add the functions folder to the path
funcFolers = {'PTB/', 'fMRI/', 'ImageTools/', 'Utilities/', 'pRF/'};
cellfun(@addpath, funcFolers);
% addpath(genpath('functions/'));
% skip Sync tests
param.SkipSyncTests = 0; % will skip in debug mode
% display the key name for key press
param.dispPress = 1;
%% Experiment inforamtion
param.expCode = '999';
param.expAbbv = 'pRFfaces';
param.outpath= 'output';
%% Process the in-arguments
% subject code
if ~exist('subjCode', 'var')
subjCode = '000';
elseif isnumeric(subjCode) % the subjCode should be a string
subjCode = num2str(subjCode);
end
if ~exist('isEyelink', 'var') || isempty(isEyelink)
isEyelink = 0;
end
% by default, emulated mode is on... (will not wait for fMRI trigger)
if ~exist('isEmulated', 'var') || isempty(isEmulated)
isEmulated = 1;
end
% debug mode
if strcmp(subjCode, '0')
isDebug = 1;
isEmulated = 1;
warning(['Debug mode is on... \nThe subjCode is %s.\n', ...
'Data will not be saved.'], subjCode);
else
isDebug = 0;
end
param.subjCode = subjCode;
param.isDebug = isDebug;
param.isEyelink = isEyelink;
param.isEmulated = isEmulated;
% run Code
if ~exist('runCode', 'var') || isempty(runCode)
runCode = fmri_runcode(param, 48);
end
param.runCode = runCode;
fprintf('\nRun code: %d\n\n', runCode);
%% Stimuli
% load the stimulus
stimPath = fullfile('custom/stimuli/loc_stim', filesep);
param.imgDir = im_dir(stimPath, '', 1);
param.nStimCat = numel(unique({param.imgDir.condition}));
%% Experiment design (ed)
% how many times the same trials will be repeated
param.nRepetition = 1;
% pRF designs (to be used in prf_stimposi())
param.prfcoorsys = 'carte';
param.prfNxy = [3, 3]; % number of columns and rows
param.facevva = 3.2; % (vertical) visual angle 3.2
param.facebtwva = 1.5; % between faces
param.dotva = 0.2;
param.dotcolor = [255; 255; 100; 128]; % transparent yellow
param.circleva = 0.5:3:100;
stimPosiIdx = prod(param.prfNxy) + strcmp(param.prfcoorsys, 'polar');
% experiment design array
clear param.conditionsArray;
param.conditionsArray = {...
'stimPosiIdx', 1:stimPosiIdx; ...
% 'stimPosiX', 1:param.prfNxy(2); ...
% 'stimPosiY', 1:param.prfNxy(1); ...
'stimCategory', 1:param.nStimCat; ... % stimlus (category) conditions
'repeated', 1:param.nRepetition; % block repeated times
};
param.sortBlock = 'repeated';
%% response keys
param.expKeyName = {'escape', '=+'};
param.instructKeyName = 'q';
param.respKeyNames = {'2'; '2@'};
param.respButton = 'red';
%% instructions
if isEmulated
keyStr = sprintf('Key "%s"', param.respKeyNames{1, 1});
continueStr = sprintf('Press "%s" to continue...', param.instructKeyName);
else
keyStr = sprintf('the button with your %s', fmri_key2finger(param.respKeyNames{1, 1}));
continueStr = 'Waiting for the trigger...';
param.instructKeyName = ''; % do not wait for response
end
% instruction texts
param.instructText = sprintf(['Welcome to this experiment... \n\n\n' ...
'Please press %s when the letter at the center is the same as '...
'the previous one. \n\n', ...
'(%s)'], ...
keyStr, continueStr);
%% Dummy volumes
param.dummyDuration = 0; % seconds; fixation duration before any block/trial
param.dummyDurationEnd = 0; % fixation duration after all blocks/trials
%% Trial parameters
% stimuli
param.stimDuration = .3;
param.trialDuration = .5; % The total duration of one trial
param.nStimPerBlock = 4; %
param.nFixaEndPerBlock = 1;
param.stimBloDuration = param.trialDuration * param.nStimPerBlock;
assert(param.nFixaEndPerBlock<param.nStimPerBlock, ...
'The number of fixation trials should be smaller than the stimlus ones.')
%% Fixation parameters
% fixations
param.widthFix = 4;
param.lengthFix = 20;
param.fixDuration = param.stimBloDuration;
% the block numbers for fixation
param.fixBlockN = 2; % randomly interleaved with experimental blocks
param.fixBlockDummy = 2; % 4s per block (16s)
param.fixBlockOverrun = 2; % 4s per block (16s)
%% Setting for the screen
param.frameExpected = 60;
param.forecolor = 'white'; % (white, black, grey or numbers)
param.backcolor = 'grey'; % (white, black, grey or numbers)
param.winrect = []; % [] Window Rect; % default [100 100 1300 900]; %[100 100 600 600];
param.whichscreen = []; % which screen to display stimuli
param.distance = 57; % distance to the screen (cm) 88
param = ptb_screensize(param);
%% Parameters of fonts used in this exp
param.textSize = 20;
param.textFont = 'Helvetica';
param.textColor = 255;
%% Tasks
param.do_task = @prf_nbackletter;
param.nback = 1; % number of repetitions
param.ratio = 0.5; % percentage of blocks have the .nback task
% load letter images
param.imgLetterDir = im_dir('custom/stimuli/letters/');
param.lettervva = 0.4;
%% Eyelink
param.eldummymode = ~isEyelink;
param.warnoffva = 1; % throw warining if average gaze deviate from this visual angle on X or Y
%% Run the Experiment
param.do_trigger = @fmri_vpixx; % mandatory to work with MRI
param.do_trial = @prf_dotrial;
param.do_stim = @prf_stim;
param.do_output = @ptb_outtable;
param.do_attentask = @prf_nbackletter;
param.do_custombg = @prf_background;
% run the fmri experiment in block design
try
prf_runexp(param);
catch error
ListenChar(0);
sca;
rethrow(error);
end
%% remove the path
cellfun(@rmpath, funcFolers);
% rmpath(genpath('functions/'));
end