0001 function outdata = ensemble_fmri_make4Dnifti(indata,defs)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 global r
0073
0074 outdata = ensemble_init_data_struct();
0075 outdata.type = 'make4Dnifti';
0076
0077 r = init_results_struct;
0078
0079 r.type = 'make4Dnifti';
0080 r.report_on_fly = 1;
0081
0082 dstr = datestr(now(),30);
0083
0084
0085 for idata = 1:length(indata)
0086 if isfield(indata{idata},'type')
0087 switch indata{idata}.type
0088 case 'sinfo'
0089 sinfo = indata{idata};
0090 sinfo = sinfo.data;
0091 proc_subs = {sinfo(:).id};
0092 nsub_proc = length(proc_subs);
0093 case {'epi','realign_epi'}
0094 epidata = indata{idata};
0095 epicol = set_var_col_const(epidata.vars);
0096 case {'paths'}
0097 pathdata = indata{idata};
0098 pcol = set_var_col_const(pathdata.vars);
0099 end
0100 end
0101 end
0102
0103
0104 check_vars = {'sinfo','pathdata','epidata'};
0105 check_required_vars;
0106
0107
0108
0109
0110 if (iscell(indata) && ~isempty(indata) && isfield(indata{1},'task') && ...
0111 ~isempty(strmatch('return_outdir',indata{1}.task))) || ...
0112 (isstruct(indata) && isfield(indata,'task') && ...
0113 ~isempty(strmatch('return_outdir',indata.task)))
0114
0115 if exist('pathdata','var') && ~isempty(pathdata.data{1})
0116 if length(nsub_proc) == 1
0117 pfilt = struct();
0118 pfilt.include.all.subject_id = proc_subs;
0119 lpathdata = ensemble_filter(pathdata,pfilt);
0120 if ~isempty(lpathdata.data{1})
0121 sfilt = pfilt;
0122 sfilt.include.all.path_type = {'epi_outdir'};
0123 spathdata = ensemble_filter(lpathdata,sfilt);
0124 if length(spathdata.data{1}) == 1
0125
0126 outdata = spathdata.data{pcol.path}{1};
0127 else
0128 sfilt = pfilt;
0129 sfilt.include.all.path_type = {'sess_outdir'};
0130 spathdata = ensemble_filter(lpathdata,sfilt);
0131 if length(spathdata.data{1}) == 1;
0132 outdata = spathdata.data{pcol.path}{1};
0133 else
0134 sfilt = pfilt;
0135 sfilt.include.all.path_type = {'sub_outdir'};
0136 spathdata = ensemble_filter(lpathdata,sfilt);
0137 if length(spathdata.data{1}) == 1;
0138 outdata = spathdata.data{pcol.path}{1};
0139 end
0140 end
0141 end
0142 end
0143 else
0144 if isfield(defs,'paths') && isfield(defs.paths,'grouptime') && ...
0145 ~isempty(defs.paths.grouptime) && exist(defs.paths.grouptime)
0146 outdata = defs.paths.grouptime;
0147 end
0148 end
0149 end
0150 if ~exist('outdata','var') || ~exist(outdata,'dir'), outdata = ''; end
0151 return
0152 end
0153
0154
0155 outdata.vars = [outdata.vars 'sinfo'];
0156 sinfo_idx = length(outdata.vars);
0157 outdata.data{sinfo_idx} = ensemble_init_data_struct();
0158 outdata.data{sinfo_idx}.type = 'sinfo';
0159 outdata.data{sinfo_idx}.data = sinfo;
0160
0161
0162 outdata.vars = [outdata.vars 'epi'];
0163 epi_idx = length(outdata.vars);
0164 outdata.data{epi_idx} = ensemble_init_data_struct();
0165 outdata.data{epi_idx}.type=epidata.type;
0166 outdata.data{epi_idx}.vars = epidata.vars;
0167 outdata.data{epi_idx}.data{1} = {};
0168 outdata.data{epi_idx}.data{2} = [];
0169 outdata.data{epi_idx}.data{3} = [];
0170 outdata.data{epi_idx}.data{4} = [];
0171 outdata.data{epi_idx}.data{5} = {};
0172
0173
0174 outdata.vars = [outdata.vars 'mean_epi'];
0175 mepi_idx = length(outdata.vars);
0176 outdata.data{mepi_idx} = ensemble_init_data_struct();
0177 outdata.data{mepi_idx}.type = 'mean_epi';
0178 outdata.data{mepi_idx}.vars = epidata.vars;
0179 outdata.data{mepi_idx}.data = outdata.data{epi_idx}.data;
0180
0181
0182 outdata.vars = [outdata.vars 'std_epi'];
0183 sepi_idx = length(outdata.vars);
0184 outdata.data{sepi_idx} = ensemble_init_data_struct();
0185 outdata.data{sepi_idx}.type = 'std_epi';
0186 outdata.data{sepi_idx}.vars = epidata.vars;
0187 outdata.data{sepi_idx}.data = outdata.data{epi_idx}.data;
0188
0189
0190 outdata.vars = [outdata.vars 'zscore_epi'];
0191 zepi_idx = length(outdata.vars);
0192 outdata.data{zepi_idx} = ensemble_init_data_struct();
0193 outdata.data{zepi_idx}.type = 'zscore_epi';
0194 outdata.data{zepi_idx}.vars = epidata.vars;
0195 outdata.data{zepi_idx}.data = outdata.data{epi_idx}.data;
0196
0197
0198 outdata.vars = [outdata.vars 'betmasks'];
0199 bet_idx = length(outdata.vars);
0200 outdata.data{bet_idx} = ensemble_init_data_struct();
0201 outdata.data{bet_idx}.type='betmasks';
0202 outdata.data{bet_idx}.vars = epidata.vars;
0203 outdata.data{bet_idx}.data{1} = {};
0204 outdata.data{bet_idx}.data{2} = [];
0205 outdata.data{bet_idx}.data{3} = [];
0206 outdata.data{bet_idx}.data{4} = [];
0207 outdata.data{bet_idx}.data{5} = {};
0208
0209
0210 CONCAT = 'by_session';
0211 bet_params = '-m -f 0.4 -n';
0212 name_stub = '';
0213 if isfield(defs,'make4Dnifti')
0214
0215 if isfield(defs.make4Dnifti,'CONCAT') ...
0216 && ~isempty(defs.make4Dnifti.CONCAT) ...
0217 && ~isempty(strmatch(defs.make4Dnifti.CONCAT,...
0218 {'by_session','by_run'}))
0219 CONCAT = defs.make4Dnifti.CONCAT;
0220 end
0221
0222 if isfield(defs.make4Dnifti,'bet_params')...
0223 && ischar(defs.make4Dnifti.bet_params) && ...
0224 ~isempty(defs.make4Dnifti.bet_params)
0225 bet_params = defs.make4Dnifti.bet_params;
0226 end
0227
0228 if isfield(defs.make4Dnifti,'tmpdir') ...
0229 && ischar(defs.make4Dnifti.tmpdir) ...
0230 && ~isempty(defs.make4Dnifti.tmpdir)
0231 check_dir(defs.make4Dnifti.tmpdir);
0232 tmpstub = fullfile(defs.make4Dnifti.tmpdir,'tmp_make4Dnifti');
0233 else
0234 tmpstub = 'tmp_make4Dnifti';
0235 end
0236
0237 if isfield(defs.make4Dnifti,'name_stub') && ...
0238 ischar(defs.make4Dnifti.name_stub)
0239 name_stub = defs.make4Dnifti.name_stub;
0240 if isempty(strmatch(name_stub(1),'_'))
0241 name_stub = ['_' name_stub];
0242 end
0243 end
0244 end
0245
0246
0247 if ~isempty(strmatch(CONCAT,{'by_subject','all'}))
0248 error('all/by_subject concatenation not yet supported');
0249 end
0250
0251
0252
0253
0254
0255 sub_files = {};
0256 sub_masks = {};
0257
0258 for isub=1:nsub_proc
0259
0260 subid = sinfo(isub).id;
0261 msg = sprintf('\t\tPROCESSING SUBJECT (%d/%d): %s\n', isub, nsub_proc,subid);
0262 r = update_report(r,msg);
0263
0264 if isempty([sinfo(isub).sessinfo.use_epi_runs]) || ~any([sinfo(isub).sessinfo.use_session])
0265 msg = sprintf('no good runs for subject %d (%s), SKIPPING\n',isub,subid);
0266 r = update_report(r,msg);
0267 continue
0268 end
0269
0270
0271 sfilt.include.all.subject_id = {subid};
0272 sdata = ensemble_filter(epidata,sfilt);
0273
0274
0275 spdata = ensemble_filter(pathdata,sfilt);
0276
0277
0278 nsess = length(sinfo(isub).sessinfo);
0279
0280
0281
0282
0283
0284 sess_files = {};
0285 sess_masks = {};
0286
0287 for isess = 1:nsess
0288 sess = sinfo(isub).sessinfo(isess);
0289
0290 if ~sess.use_session
0291 msg = sprintf('\t\t\tSkipping session %d\n', isess);
0292 r = update_report(r,msg);
0293 continue
0294 end
0295
0296
0297 sessfilt.include.all.session = isess;
0298 sessdata = ensemble_filter(sdata,sessfilt);
0299
0300
0301 sesspdata = ensemble_filter(spdata,sessfilt);
0302
0303
0304
0305
0306
0307 [runm,urun] = make_mask_mtx(sessdata.data{epicol.run});
0308 nruns = length(urun);
0309
0310 run_files = {};
0311 run_masks = {};
0312
0313 for irun = 1:nruns
0314 lrun = urun(irun);
0315 runfilt.include.all.run = lrun;
0316 rundata = ensemble_filter(sessdata,runfilt);
0317
0318 flist = rundata.data{epicol.path};
0319 check_ext(flist);
0320
0321 runfilt.include.all.path_type = {'run_outdir'};
0322 pdata = ensemble_filter(pathdata,runfilt);
0323 outpath = pdata.data{pcol.path}{1};
0324
0325 if length(flist) > 1
0326
0327
0328
0329 outfstub = sprintf('%s_%d_run%d%s',subid,sess.ensemble_id,...
0330 lrun,name_stub);
0331
0332 outfname = fullfile(outpath,outfstub);
0333 status = unix(sprintf('fslmerge -t %s %s',outfname,...
0334 cell2str(flist,' ')));
0335 if status
0336 error('error merging %d files into a 4D nifti',length(flist));
0337 end
0338 else
0339 outfname = flist{1};
0340 end
0341
0342 outdata.data{epi_idx} = ensemble_add_data_struct_row(...
0343 outdata.data{epi_idx},'subject_id',subid,'session',...
0344 isess,'ensemble_id',sess.ensemble_id,'run',lrun,'path',outfname);
0345
0346
0347 maskfname = fullfile(outpath,sprintf('%s_%d_run%d%s',subid,...
0348 sess.ensemble_id,lrun,name_stub));
0349 fstr = sprintf('bet %s %s %s',outfname,maskfname,bet_params);
0350 status = unix(fstr);
0351 if status
0352 error('error calculating bet mask: %s, sess %d, run %d',...
0353 subid,isess,lrun);
0354 end
0355
0356 run_masks{irun} = sprintf('%s_mask.nii.gz',maskfname);
0357
0358 outdata.data{bet_idx} = ensemble_add_data_struct_row(...
0359 outdata.data{bet_idx},'subject_id',subid,'session',...
0360 isess,'ensemble_id',sess.ensemble_id,'run',lrun,...
0361 'path',maskfname);
0362
0363
0364 meanfname = fullfile(outpath,sprintf('mean_run%d%s',lrun,name_stub));
0365 fstr = sprintf('fslmaths %s -Tmean %s',outfname,meanfname);
0366 status = unix(fstr);
0367 if status
0368 error('error calculating mean image: %s, sess %d, run %d',...
0369 subid,isess,lrun);
0370 end
0371
0372 outdata.data{mepi_idx} = ensemble_add_data_struct_row(...
0373 outdata.data{mepi_idx},'subject_id',subid,'session',...
0374 isess,'ensemble_id',sess.ensemble_id,'run',lrun,'path',meanfname);
0375
0376
0377 stdfname = fullfile(outpath,sprintf('std_run%d%s',lrun,name_stub));
0378 fstr = sprintf('fslmaths %s -Tstd %s',outfname,stdfname);
0379 status = unix(fstr);
0380 if status
0381 error('error calculating std images: %s, sess %d, run %d',...
0382 subid,isess,lrun);
0383 end
0384
0385 outdata.data{sepi_idx} = ensemble_add_data_struct_row(...
0386 outdata.data{sepi_idx},'subject_id',subid,'session',...
0387 isess,'ensemble_id',sess.ensemble_id,'run',lrun,'path',stdfname);
0388
0389
0390 zfname = fullfile(outpath,sprintf('zscore_run%d%s',lrun,name_stub));
0391 fstr = sprintf('fslmaths %s -sub %s %s',outfname,meanfname,tmpstub);
0392 status = unix(fstr);
0393 if status
0394 error('error mean-centering images: %s, sess %d, run %d',...
0395 subid,isess,lrun);
0396 end
0397
0398 fstr = sprintf('fslmaths %s -div %s -mas %s %s',...
0399 tmpstub,stdfname,maskfname,zfname);
0400 status = unix(fstr);
0401 if status
0402 error('error calculating std images: %s, sess %d, run %d',...
0403 subid,isess,lrun);
0404 end
0405
0406 unix(sprintf('rm %s*',tmpstub));
0407
0408 run_files{irun} = zfname;
0409
0410 outdata.data{zepi_idx} = ensemble_add_data_struct_row(...
0411 outdata.data{zepi_idx},'subject_id',subid,'session',...
0412 isess,'ensemble_id',sess.ensemble_id,'run',lrun,'path',zfname);
0413
0414 end
0415
0416
0417 if ~isempty(strmatch(CONCAT,{'by_subject','by_session','all'}))
0418
0419 sessfilt.include.all.path_type = {'epi_outdir'};
0420 soddata = ensemble_filter(sesspdata,sessfilt);
0421 sodpath = soddata.data{epicol.path}{1};
0422
0423
0424 smfname = fullfile(sodpath,sprintf('mask_concat_sess%d%s',isess,name_stub));
0425 rmasks = cell2str(run_masks,' ');
0426 fstr = sprintf('fslmerge -t %s %s',smfname,rmasks);
0427 status = unix(fstr);
0428 if status
0429 error('error concatenating run masks: %s, sess %d',subid,isess);
0430 end
0431
0432 fstr = sprintf('fslmaths %s -Tmean -thr 1 %s',smfname,smfname);
0433 status = unix(fstr);
0434 if status
0435 error('error getting mask intersect: %s, sess %d',subid,isess);
0436 end
0437
0438 sess_masks{isess} = smfname;
0439
0440 outdata.data{bet_idx} = ensemble_add_data_struct_row(...
0441 outdata.data{bet_idx},'subject_id',subid,'session',...
0442 isess,'ensemble_id',sess.ensemble_id,'run',0,'path',smfname);
0443
0444
0445 szfname = fullfile(sodpath,sprintf('zscore_concat_sess%d%s',isess,name_stub));
0446 rzscored = cell2str(run_files,' ');
0447 fstr = sprintf('fslmerge -t %s %s',szfname,rzscored);
0448 status = unix(fstr);
0449 if status
0450 error('error concatenating zscored runs: %s, sess %d',subid,isess);
0451 end
0452
0453
0454 fstr = sprintf('fslmaths %s -add 20 -mul 200 -mas %s %s',...
0455 szfname,smfname,szfname);
0456 status = unix(fstr);
0457 if status
0458 error('error applying a positive offset to %s',szfname);
0459 end
0460
0461 sess_files{isess} = szfname;
0462
0463 outdata.data{zepi_idx} = ensemble_add_data_struct_row(...
0464 outdata.data{zepi_idx},'subject_id',subid,'session',...
0465 isess,'ensemble_id',sess.ensemble_id,'run',0,'path',szfname);
0466 end
0467
0468 end
0469
0470
0471 if ~isempty(strmatch(CONCAT,{'by_subject','all'}))
0472 if nsess > 1
0473
0474 else
0475 sub_files{isub} = sess_files{1};
0476 sub_masks{isub} = sess_masks{1};
0477 end
0478 end
0479
0480 end
0481
0482
0483 if ~isempty(strmatch(CONCAT,{'all'}))
0484 if nsub > 1
0485
0486 else
0487
0488
0489 end
0490 end
0491
0492
0493
0494
0495
0496
0497 function xt = check_ext(flist)
0498
0499
0500
0501
0502 nf = length(flist);
0503 xt = '';
0504
0505 for i = 1:nf
0506 [fp,fn,fx] = fileparts(flist{i});
0507 if isempty(fx)
0508 good = false;
0509 error('no file extension');
0510 else
0511 if i==1
0512 xt = fx;
0513 elseif isempty(strmatch(fx,xt,'exact'))
0514 good = false;
0515 error('file extension mismatch');
0516 end
0517 end
0518 end
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703