Skip to content

Commit b6eafe4

Browse files
committed
included masking option | updated comments
1 parent 54883ab commit b6eafe4

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

code/IRM.m

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
% - n_slices : number of slices
3535
%
3636
% optional inputs are
37-
% - hrf : either a column vector containing a single hemodynamic
37+
% - hrf : either a column vector containing a single hemodynamic
3838
% response used for every voxel;
3939
% or a matrix with a unique hemodynamic response along
4040
% its columns for each voxel.
41-
% By default the canonical two-gamma hemodynamic response
41+
% By default the canonical two-gamma hemodynamic response
4242
% function is generated internally based on the scan parameters.
4343
%
4444
% this class has the following functions
@@ -125,9 +125,9 @@
125125

126126
function hrf = get_hrf(self)
127127
% returns the hemodynamic response used by the class.
128-
% If a single hrf is used for every voxel, this function
128+
% If a single hrf is used for every voxel, this function
129129
% returns a column vector.
130-
% If a unique hrf is used for each voxel, this function returns
130+
% If a unique hrf is used for each voxel, this function returns
131131
% a matrix with columns corresponding to time and the remaining
132132
% dimensions reflecting the spatial dimensions of the data.
133133
if size(self.hrf,2)>1
@@ -144,10 +144,10 @@
144144
end
145145

146146
function tc = get_timecourses(self)
147-
% returns the timecourses predicted based on the stimulus
148-
% protocol and each combination of the input-referred model
147+
% returns the timecourses predicted based on the stimulus
148+
% protocol and each combination of the input-referred model
149149
% parameters as a time-by-combinations matrix.
150-
% Note that the predicted timecourses have not been convolved
150+
% Note that the predicted timecourses have not been convolved
151151
% with a hemodynamic response.
152152
tc = ifft(self.tc_fft);
153153
end
@@ -170,7 +170,7 @@ function set_stimulus(self,stimulus)
170170
end
171171

172172
function create_timecourse(self,FUN,xdata)
173-
% creates predicted timecourses based on the stimulus protocol
173+
% creates predicted timecourses based on the stimulus protocol
174174
% and a range of parameters for an input referred model.
175175
%
176176
% required inputs are
@@ -195,7 +195,7 @@ function create_timecourse(self,FUN,xdata)
195195

196196
for p=1:self.n_predictors
197197
self.idx(:,p) = mod(floor(i/prod(n_observations(p+1:end))),...
198-
n_observations(p)) + 1;
198+
n_observations(p)) + 1;
199199
end
200200

201201
tc = zeros(self.n_samples,self.n_points);
@@ -217,9 +217,9 @@ function create_timecourse(self,FUN,xdata)
217217
% returns the corresponding parameter values of the
218218
% input-referred model. The class returns a structure with two
219219
% fields.
220-
% - R: correlations (fit) - dimension corresponds to the
220+
% - R: correlations (fit) - dimension corresponds to the
221221
% dimensions of the data.
222-
% - P: estimate parameters - dimension corresponds to the
222+
% - P: estimate parameters - dimension corresponds to the
223223
% dimensions of the data + 1.
224224
%
225225
% required inputs are
@@ -228,6 +228,7 @@ function create_timecourse(self,FUN,xdata)
228228
%
229229
% optional inputs are
230230
% - threshold: minimum voxel intensity (default = 100.0)
231+
% - mask : binary mask for selecting voxels
231232

232233
text = 'mapping input-referred model...';
233234
fprintf('%s\n',text)
@@ -236,16 +237,26 @@ function create_timecourse(self,FUN,xdata)
236237
p = inputParser;
237238
addRequired(p,'data',@isnumeric);
238239
addOptional(p,'threshold',100);
240+
addOptional(p,'mask',[]);
239241
p.parse(data,varargin{:});
240242

241243
data = p.Results.data;
242244
threshold = p.Results.threshold;
245+
mask = p.Results.mask;
243246

244247
data = reshape(data(1:self.n_samples,:,:,:),...
245248
self.n_samples,self.n_total);
246249
mean_signal = mean(data);
247250
data = zscore(data);
248-
mag_d = sqrt(sum(data.^2));
251+
252+
if isempty(mask)
253+
mask = mean_signal>=threshold;
254+
end
255+
mask = mask(:);
256+
voxel_index = find(mask);
257+
n_voxels = numel(voxel_index);
258+
259+
mag_d = sqrt(sum(data(:,mask).^2));
249260

250261
results.R = zeros(self.n_total,1);
251262
results.P = zeros(self.n_total,self.n_predictors);
@@ -257,38 +268,40 @@ function create_timecourse(self,FUN,xdata)
257268
tc = zscore(ifft(self.tc_fft.*hrf_fft))';
258269

259270
mag_tc = sqrt(sum(tc.^2,2));
260-
for v=1:self.n_total
261-
if mean_signal(v)>threshold
262-
CS = (tc*data(:,v))./...
263-
(mag_tc*mag_d(v));
264-
id = isinf(CS) | isnan(CS);
265-
CS(id) = 0;
266-
[results.R(v),j] = max(CS);
267-
for p=1:self.n_predictors
268-
results.P(v,p) = self.xdata{p}(self.idx(j,p));
269-
end
271+
for m=1:n_voxels
272+
v = voxel_index(m);
273+
274+
CS = (tc*data(:,v))./...
275+
(mag_tc*mag_d(v));
276+
id = isinf(CS) | isnan(CS);
277+
CS(id) = 0;
278+
[results.R(v),j] = max(CS);
279+
for p=1:self.n_predictors
280+
results.P(v,p) = self.xdata{p}(self.idx(j,p));
270281
end
282+
271283
waitbar(v/self.n_total,wb)
272284
end
273285
else
274286
hrf_fft_all = fft([self.hrf;...
275287
zeros(self.n_samples-self.l_hrf,self.n_total)]);
276-
for v=1:self.n_total
277-
if mean_signal(v)>threshold
278-
hrf_fft = repmat(hrf_fft_all(:,v),...
279-
[1,self.n_points]);
280-
tc = zscore(ifft(self.tc_fft.*hrf_fft))';
281-
mag_tc = sqrt(sum(tc.^2,2));
282-
283-
CS = (tc*data(:,v))./...
284-
(mag_tc*mag_d(v));
285-
id = isinf(CS) | isnan(CS);
286-
CS(id) = 0;
287-
[results.R(v),j] = max(CS);
288-
for p=1:self.n_predictors
289-
results.P(v,p) = self.xdata(self.idx(j,p),p);
290-
end
288+
for m=1:n_voxels
289+
v = voxel_index(m);
290+
291+
hrf_fft = repmat(hrf_fft_all(:,v),...
292+
[1,self.n_points]);
293+
tc = zscore(ifft(self.tc_fft.*hrf_fft))';
294+
mag_tc = sqrt(sum(tc.^2,2));
295+
296+
CS = (tc*data(:,v))./...
297+
(mag_tc*mag_d(v));
298+
id = isinf(CS) | isnan(CS);
299+
CS(id) = 0;
300+
[results.R(v),j] = max(CS);
301+
for p=1:self.n_predictors
302+
results.P(v,p) = self.xdata(self.idx(j,p),p);
291303
end
304+
292305
waitbar(v/self.n_total,wb)
293306
end
294307
end

code/RRT.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ function optimize_lambda(self,data,range,varargin)
173173
% - range : a range of candidate values for lambda.
174174
%
175175
% optional inputs are
176-
% - mask : mask file for selecting voxels
176+
% - mask : binary mask for selecting voxels
177177
% - permute: permute the observations (if the data has no
178178
% temporal structure).
179179

code/pRF.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ function create_timecourses(self,varargin)
319319
%
320320
% optional inputs are
321321
% - threshold: minimum voxel intensity (default = 100.0)
322+
% - mask : binary mask for selecting voxels
322323

323324
text = 'mapping population receptive fields...';
324325
fprintf('%s\n',text)

0 commit comments

Comments
 (0)