-
Notifications
You must be signed in to change notification settings - Fork 15
/
rsHRF_deconv_job.m
352 lines (330 loc) · 13.8 KB
/
rsHRF_deconv_job.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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
function out = rsHRF_deconv_job(job,data,data_nuisancerm,flag_ROI, outdir, v, smask_ind, flag_nii_gii)
[Nscans,nvar_data] = size(data);
name = job.raw_outname;
flag_pval_pwgc = job.para_global.flag_pval_pwgc;
flag_save_psc = job.para_global.flag_save_psc;
num_iterations = job.para_global.num_iterations;
flag_parfor = job.para_global.flag_parfor;
%% HRF deconvolution
para.TR = job.HRFE.TR ;
%%% the following parameter (upsample grid) can be > 1 only for Canonical/Fourier/Gamma.
%%% Set = 1 for FIR/sFIR
para.T = job.HRFE.fmri_t; % magnification factor of temporal grid with respect to TR. i.e. para.T=1 for no upsampling, para.T=3 for 3x finer grid
para.T0 = job.HRFE.fmri_t; % position of the reference slice in bins, on the grid defined by para.T. For example, if the reference slice is the middle one, then para.T0=fix(para.T/2)
if para.T==1
para.T0 = 1;
end
min_onset_search = min(job.HRFE.mdelay); % minimum delay allowed between event and HRF onset (seconds)
max_onset_search = max(job.HRFE.mdelay); % maximum delay allowed between event and HRF onset (seconds)
para.dt = para.TR/para.T; % fine scale time resolution.
para.order = job.HRFE.num_basis;
para.AR_lag = job.HRFE.cvi; % AR(1) noise autocorrelation.
para.thr = job.HRFE.thr; % (mean+) para.thr*standard deviation threshold to detect event.
para.len = job.HRFE.hrflen; % length of HRF, in seconds
para.lag = fix(min_onset_search/para.dt):fix(max_onset_search/para.dt);
para.localK = job.HRFE.localK;
if isnan(job.HRFE.tmask(1))
temporal_mask = true(Nscans,1); % temporal mask.
else
temporal_mask = logical(job.HRFE.tmask);
end
if job.HRFE.hrfm<6
hrfmn = {
'Canonical HRF (with time derivative)'
'Canonical HRF (with time and dispersion derivatives)'
'Gamma functions'
'Fourier set'
'Fourier set (Hanning)'}; %
para.name = hrfmn{job.HRFE.hrfm};
tic
[beta_hrf, bf, event_bold] = rsHRF_estimation_temporal_basis(data,para, temporal_mask,flag_parfor);
hrfa = bf*beta_hrf(1:size(bf,2),:); %HRF
hrf_baseline = beta_hrf(1+size(bf,2),:); %HRF baseline value for PSC calculation.
else
tic
if job.HRFE.hrfm==6
para.estimation = 'FIR';
elseif job.HRFE.hrfm==7
para.estimation = 'sFIR';
end
para.T=1; % this needs to be = 1 for FIR
[beta_hrf,event_bold] = rsHRF_estimation_FIR(data,para, temporal_mask,flag_parfor);
hrfa = beta_hrf(1:end-2,:); %HRF
hrf_baseline = beta_hrf(end-1,:); %HRF baseline value for PSC calculation.
end
nvar = size(hrfa,2);
PARA = zeros(3,nvar);
event_number = nan(nvar,1);
if flag_parfor
parfor ii=1:nvar
hrf1 = hrfa(:,ii);
PARA(:,ii) = rsHRF_get_HRF_parameters(hrf1,para.TR/para.T);% estimate HRF parameter
event_number(ii)=length(event_bold{1,ii});
end
else
for ii=1:nvar
hrf1 = hrfa(:,ii);
PARA(:,ii) = rsHRF_get_HRF_parameters(hrf1,para.TR/para.T);% estimate HRF parameter
event_number(ii)=length(event_bold{1,ii});
end
end
fprintf('\nDone HRF estimation %8.2f seconds\n',toc)
if job.savedata.hrfmat_save
fprintf('Save HRF parameters....\n');
%% save HRF parameters
save(fullfile(outdir,[job.prefix,name, '_hrf.mat']), 'para', 'beta_hrf', 'hrfa', 'event_bold', 'event_number','PARA','-v7.3');
if exist('bf','var')
save(fullfile(outdir,[job.prefix,name, '_hrf.mat']), 'bf','-append')
end
end
if ~isempty(job.connectivity)
[connroinfo,conndata_flag] = rsHRF_conn_check(job);
else
connroinfo={}; conndata_flag=0;
end
%% HRF deconvolution -->signals
%whether save the deconvolved signal or perform analysis on deconvolved data
if job.savedata.deconv_save || any(conndata_flag~=1)
fprintf('Deconvolving HRF ...\n');
tic
% T = round(para.len/TR);
if para.T>1
hrfa_TR = resample(hrfa,1,para.T);
else
hrfa_TR = hrfa;
end
data_deconv = nan(size(data));
sigma = std(data);
if job.HRFE.hrfdeconv==1
if flag_parfor
parfor ii=1:nvar
hrf=hrfa_TR(:,ii);
data_deconv(:,ii) = rsHRF_iterative_wiener_deconv(zscore(data_nuisancerm(:,ii)),hrf./sigma(ii),num_iterations);
end
else
for ii=1:nvar
hrf=hrfa_TR(:,ii);
data_deconv(:,ii) = rsHRF_iterative_wiener_deconv(zscore(data_nuisancerm(:,ii)),hrf./sigma(ii),num_iterations);
end
end
elseif job.HRFE.hrfdeconv==2
if flag_parfor
parfor ii=1:nvar
hrf=hrfa_TR(:,ii);
data_deconv(:,ii) = rsHRF_iterative_wiener_deconv(zscore(data(:,ii)),hrf./sigma(ii),num_iterations);
end
else
for ii=1:nvar
hrf=hrfa_TR(:,ii);
data_deconv(:,ii) = rsHRF_iterative_wiener_deconv(zscore(data(:,ii)),hrf./sigma(ii),num_iterations);
end
end
else
disp('^.^') % do not perform deconvolution
end
toc
end
if ~flag_ROI % 3D volume/ 2D surface data
if flag_nii_gii==1
v0 = v(1); v0.dt = [16,0]; v0.n = [1 1];
ext_nii_gii = '.nii';
else
v0 = v;
ext_nii_gii = '.gii';
end
HRF_para_str = {'Height', 'Time2peak','FWHM'};
dat= zeros(v0.dim);
if job.savedata.hrfnii_save
%write nifti maps of the three HRF parameters
for i=1:3
fname = fullfile(outdir,[job.prefix,name,'_',HRF_para_str{i},ext_nii_gii]);
eval(['out.',HRF_para_str{i},'{1} =','''',fname,''';'])
dat(smask_ind)=PARA(i,:);
rsHRF_write_file(fname,dat,flag_nii_gii,v0)
end
% write height PSC
fname = fullfile(outdir,[job.prefix,name,'_Height_PSC',ext_nii_gii]);
out.Height_PSC{1} = fname;
dat(smask_ind)=PARA(1,:)./hrf_baseline;
rsHRF_write_file(fname,dat,flag_nii_gii,v0)
% write number of events
fname = fullfile(outdir,[job.prefix,name,'_event_number',ext_nii_gii]);
out.event_number{1} = fname;
dat(smask_ind)=event_number;
rsHRF_write_file(fname,dat,flag_nii_gii,v0)
end
if job.savedata.hrfmat_save
save(fullfile(outdir,[job.prefix,name, '_hrf.mat']), 'smask_ind','v0','-append')
end
if job.rmoutlier && flag_nii_gii %only for 3D data
PARA_rm = PARA;
pvalue_rm=job.para_global.pvalue_rm;
Inpainted_method =job.para_global.Inpainted ;
for i=1:3
fname = fullfile(outdir,[job.prefix,name,'_Olrm_',HRF_para_str{i},ext_nii_gii]);
eval(['out.Olrm_',HRF_para_str{i},'{1}=','''',fname,''';'])
v0.fname = fname;
dat(smask_ind)=PARA(i,:);
if i==1
id = (PARA_rm(1,:)<=0); %Be Careful
PARA_rm(1,id)=nan;
[PARA_rm(1,:),idx,outliers] = rsHRF_deleteoutliers(PARA_rm(1,:),pvalue_rm,1);
fprintf('Response height outlier: negative/zeros #%d + extreme #%d, [%3.3f %3.3f];\n',nnz(id),length(idx),min(outliers),max(outliers));
dat(smask_ind)=PARA_rm(1,:);
dat=rsHRF_inpaint_nans3(dat,Inpainted_method);
PARA_rm(1,:) = dat(smask_ind);
id_rm = union(find(id),idx);
dat2 = zeros(v0.dim);
PARA_rm0=zeros(1,size(PARA,2));
PARA_rm0(1,id_rm)=1;
dat2(smask_ind)=PARA_rm0;
v00 = v0;
fname = fullfile(outdir,[job.prefix,name,'_outlier_NAN',ext_nii_gii]);
out.outlier{1} = fname;
v00.fname = fname;
spm_write_vol(v00,dat2); clear dat2
else
PARA_rm(i,id_rm)=nan;
dat(smask_ind)=PARA_rm(i,:);
dat=rsHRF_inpaint_nans3(dat,Inpainted_method);
PARA_rm(i,:) = dat(smask_ind);
end
if job.savedata.hrfnii_save
spm_write_vol(v0,dat);
end
end
if job.savedata.hrfnii_save || job.savedata.hrfmat_save
% write number of events
fname = fullfile(outdir,[job.prefix,name,'_Olrm_event_number',ext_nii_gii]);
out.Olrm_event_number{1} = fname;
v0.fname = fname;
event_number_rm = event_number;
event_number_rm(id_rm)=nan;
dat(smask_ind)=event_number_rm;
dat=rsHRF_inpaint_nans3(dat,Inpainted_method);
event_number_rm = dat(smask_ind);
if job.savedata.hrfnii_save
spm_write_vol(v0,dat);
end
if flag_save_psc
%write height PSC
fname = fullfile(outdir,[job.prefix,name,'_Olrm_Height_PSC',ext_nii_gii]);
out.Olrm_Height_PSC{1} = fname;
v0.fname = fname;
HeightPSC_rm = PARA_rm(1,:)./hrf_baseline;
HeightPSC_rm(HeightPSC_rm<=0)=nan;
[HeightPSC_rm,idx,outliers] = rsHRF_deleteoutliers(HeightPSC_rm,pvalue_rm,1);
fprintf('Response height (PSC) outlier: negative/zeros #%d + extreme #%d, [%3.3f %3.3f];\n',nnz(id),length(idx),min(outliers),max(outliers));
dat(smask_ind)=HeightPSC_rm;
dat=rsHRF_inpaint_nans3(dat,Inpainted_method);
HeightPSC_rm = dat(smask_ind);
if job.savedata.hrfnii_save
spm_write_vol(v0,dat);
end
end
if job.savedata.hrfmat_save
if flag_save_psc
save(fullfile(outdir,[job.prefix,name, '_hrf.mat']), 'PARA_rm','event_number_rm','HeightPSC_rm','id_rm','-append')
else
save(fullfile(outdir,[job.prefix,name, '_hrf.mat']), 'PARA_rm','event_number_rm','id_rm','-append')
end
end
end
end
if ~isempty(connroinfo) && any(conndata_flag~=2)
conid = [conndata_flag~=2];
data_nD = nan(Nscans, prod(v0.dim));
data_nD(:,smask_ind) = data;
fprintf('BOLD Connectivity Analysis (%s)...\n',datetime(now,'ConvertFrom','datenum')); tic
rsHRF_conn_run(data_nD, connroinfo(conid,:),v0,name,outdir,flag_pval_pwgc,flag_nii_gii);
fprintf('Done! Elapsed time is %ss\n',num2str(toc));
clear data_nD data
end
if job.savedata.deconv_save || any(conndata_flag~=1)
% writing back deconvolved data into nifti/gifti file
fname = fullfile(outdir,[job.prefix,name,ext_nii_gii]);
out.deconv_data{1} = fname;
if flag_nii_gii==1
v1 = v; dat3 = zeros(v1(1).dim);
for i=1:Nscans
v1(i).fname = fname;
v1(i).dt = [16,0];
dat3(smask_ind) = data_deconv(i,:);
if job.savedata.deconv_save
spm_write_vol(v1(i),dat3);
end
end
else
dat_surf= gifti;
dat = zeros(nvar_data,Nscans);
dat(smask_ind,:) = data_deconv';
dat_surf.cdata = dat;
save(dat_surf,fname,'Base64Binary');
end
if ~isempty(connroinfo) && any(conndata_flag~=1)
conid = [conndata_flag~=1];
data_deconv3D = nan(Nscans, prod(v0.dim));
data_deconv3D(:,smask_ind) = data_deconv;
name2 = [name,'_deconv'];
fprintf('Deconvolved BOLD Connectivity Analysis (%s)...\n',datetime(now,'ConvertFrom','datenum')); tic
rsHRF_conn_run(data_deconv3D, connroinfo(conid,:),v0,name2,outdir,flag_pval_pwgc,flag_nii_gii);
fprintf('Done! Elapsed time is %ss\n',num2str(toc));
end
if job.rmoutlier && job.para_global.rmoutlier_deconv
if job.HRFE.hrfdeconv<3
v1 = v; dat3 = zeros(v1(1).dim);
fname = fullfile(outdir,[job.prefix,name,'_Olrm',ext_nii_gii]);
out.Olrm_deconv_data{1} = fname;
for i=1:Nscans
v1(i).fname = fname;
v1(i).dt = [16,0];
data_deconv_rm= data_deconv(i,:);
data_deconv_rm(id_rm)=nan;
dat3(smask_ind) = data_deconv_rm;
dat3=rsHRF_inpaint_nans3(dat3,Inpainted_method);
data_deconv3D(i,:) = dat3(:);
if job.savedata.deconv_save
spm_write_vol(v1(i),dat3);
end
end
end
if ~isempty(connroinfo)&& any(conndata_flag~=1)
conid = [conndata_flag~=1];
name2 = [name,'_deconv_Olrm'];
fprintf('(Outlier removed) Deconvolved BOLD Connectivity Analysis (%s)...\n',datetime(now,'ConvertFrom','datenum')); tic
rsHRF_conn_run(data_deconv3D, connroinfo(conid,:),v0,name2,outdir,flag_pval_pwgc,flag_nii_gii);
fprintf('Done! Elapsed time is %ss\n',num2str(toc));
clear data_deconv3D
end
clear data_deconv_rm
end
clear data_deconv data
end
clear dat
else %ROI-wise
if ~isempty(job.connectivity)
fprintf('Connectivity analysis...\n');
[connroinfo,conndata_flag] = rsHRF_conn_check(job);
if any(conndata_flag~=2)
conid = [conndata_flag~=2];
rsHRF_conn_run(data, connroinfo(conid,:),[],name,outdir,flag_pval_pwgc);
end
if any(conndata_flag~=1)
conid = [conndata_flag~=1];
name2 = [name,'_deconv'];
rsHRF_conn_run(data_deconv, connroinfo(conid,:),[],name2,outdir,flag_pval_pwgc);
end
end
if job.savedata.deconv_save
try
save(fullfile(outdir,[job.prefix,name, '.mat']),'data','data_deconv','-append');
catch
save(fullfile(outdir,[job.prefix,name, '.mat']),'data','data_deconv','-v7.3');
end
end
clear data data_deconv
out=[];
end
if job.savedata.job_save
save(fullfile(outdir,[job.prefix,name, '_job.mat']), 'job');
end