% Batch script for preprocessing and statistics for single subject % event-related fMRI example dataset R. Henson, 20/5/03 spm('defaults','FMRI') global defaults global Ufp Ufp = 0.001; nsub = 1; nses = 1; cwd = '/windows/D/SPMCourseData/SingleSub/SPM2' % CHANGE TO YOUR PATH cd(cwd) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for sub=1:nsub P = cell(1,nses); for ses=1:nses dir{ses} = sprintf('Data'); % directories can be generalised for >1 ses/sub P{ses} = spm_get('Files',dir{ses},'sM*.img'); end cd(dir{1}); % where spm2.ps is output V = spm_vol(P); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Realignment (coregister only) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% disp(sprintf('sub %d, coregistering...',sub)) spm_realign(V); % If want HIGHER quality (but slower!)) % FlagsC = struct('quality',1,'fwhm',5,'rtm',1,'wrap',[0 1 0],'interp',7); % spm_realign(V,FlagsC); % eval('!ghostview spm2.ps') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Unwarp (and reslice) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% disp(sprintf('sub %d, unwarping...',sub)) uwe_flags = struct( 'order', defaults.unwarp.estimate.basfcn,... 'sfield', [],... 'regorder', defaults.unwarp.estimate.regorder,... 'lambda', defaults.unwarp.estimate.regwgt,... 'jm', defaults.unwarp.estimate.jm,... 'fot', [4 5],... % pitch and roll 'sot', [],... % no second-order 'fwhm', defaults.unwarp.estimate.fwhm,... 'rem', defaults.unwarp.estimate.rem,... 'noi', defaults.unwarp.estimate.noi,... 'exp_round', defaults.unwarp.estimate.expround); uwr_flags = struct( 'wrap', [0 1 0],... 'interp', 7,... 'mask', 1,... 'which', 2,... 'mean', 1); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Estimate unwarping parameters for j=1:length(P) tmpP = spm_vol(P{j}(1,:)); uwe_flags.M = tmpP.mat; ds = spm_uw_estimate(P{j},uwe_flags); ads(j) = ds; [path,name,ext,ver] = fileparts(P{j}(1,:)); pefile = fullfile(path,[name '_uw.mat']); save(pefile,'ds'); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Write unwarped images (more efficient if spm_uw_apply returned VO) spm_uw_apply(ads,uwr_flags); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Reload unwarped images cd(cwd); P = cell(1,nses); for ses=1:nses dir{ses} = sprintf('Data'); % directories can be generalised for >1 ses/sub P{ses} = spm_get('Files',dir{ses},'usM*.img'); end cd(dir{1}); % where spm2.ps is output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Memory map the mean image (not affected by slice-timing below) meanf = [spm_str_manip(P{1}(1,:),'h') '/mean',... spm_str_manip(P{1}(1,:),'t')]; Vm = spm_vol(meanf); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Slice-timing correction (optional; could be before spatial realignment if interleaved) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TR = 2; num_slices = 24; ref_slice = 12; % middle slice in time slice_time = TR /num_slices; slice_gap = slice_time; % continuous scanning slice_ord = [num_slices:-1:1]; % descending acquisition [num_slices:-1:1] spm_slice_timing(P, slice_ord, ref_slice, [slice_time slice_gap]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Reload slice-time corrected images cd(cwd); P = cell(1,nses); for ses=1:nses dir{ses} = sprintf('Data'); % directories can be generalised for >1 ses/sub P{ses} = spm_get('Files',dir{ses},'ausM*.img'); end V = spm_vol(P); V = cat(1,V{:}); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Normalization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% defaults.normalise.write.vox = [3 3 3]; defaults.normalise.write.interp = 7; defaults.normalise.write.wrap = [0 1 0]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Estimate unwarping parameters matname = [spm_str_manip(Vm.fname,'sd') '_sn.mat']; VG = fullfile(spm('Dir'),'templates','EPI.mnc'); params = spm_normalise(VG,Vm,matname,'','',defaults.normalise.estimate); msk = spm_write_sn(V,params,defaults.normalise.write,'mask'); disp(sprintf('sub %d, determining normalisation parameters...',sub)) spm_write_sn(Vm,params,defaults.normalise.write,msk); % write nmean % eval('!ghostview spm2.ps') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Write normalised disp(sprintf('sub %d, writing normalised',sub)) for i=1:length(V), VO(i) = spm_write_sn(V(i),params,defaults.normalise.write,msk); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Smoothing %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% disp(sprintf('sub %d, smoothing',sub)) for i=1:length(VO), [pth,nam,ext] = fileparts(V(i).fname); fname = fullfile(pth,['sw' nam ext]); spm_smooth(VO(i),fname,8); end; clear VO end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Categorical Stats model (see README) for one session/subject % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cd(cwd) load sots swd = [cwd '/CatStats']; eval(sprintf('!mkdir %s',swd)); cd(swd); % number of scans and sessions %--------------------------------------------------------------------------- SPM.nscan = ones(1,nses)*351; % basis functions and timing parameters %--------------------------------------------------------------------------- SPM.xBF.name = 'hrf (with time and dispersion derivatives)'; SPM.xBF.order = 3; SPM.xBF.length = 32; % length in seconds SPM.xBF.T = num_slices; % number of time bins per scan SPM.xBF.T0 = ref_slice; % middle slice/timebin SPM.xBF.UNITS = 'scans'; % OPTIONS: 'scans'|'secs' for onsets SPM.xBF.Volterra = 1; % OPTIONS: 1|2 = order of convolution % Trial specification: Onsets, duration (UNITS) and parameters for modulation %--------------------------------------------------------------------------- ncon = 4; cnam = {'N1','N2','F1','F2'}; for ses=1:nses for c=1:ncon SPM.Sess(ses).U(c).name = {cnam{c}}; SPM.Sess(ses).U(c).ons = sots{c}; SPM.Sess(ses).U(c).dur = 0; SPM.Sess(ses).U(c).P(1).name = 'none'; end end % design (user specified covariates, eg movement parameters) %--------------------------------------------------------------------------- % (note inclusion of movement parameters makes unwarping somewhat redundant, % but done here to illustrate facilities of SPM) rnam = {'X','Y','Z','x','y','z'}; for ses=1:nses dir{ses} = '../Data'; % directories can be generalised for >1 ses/sub fn = spm_get('Files',dir{ses},'rp_*.txt'); [r1,r2,r3,r4,r5,r6] = textread(fn,'%f%f%f%f%f%f'); SPM.Sess(ses).C.C = [r1 r2 r3 r4 r5 r6]; SPM.Sess(ses).C.name = rnam; end % global normalization: OPTIONS:'Scaling'|'None' %--------------------------------------------------------------------------- SPM.xGX.iGXcalc = 'None'; % low frequency confound: high-pass cutoff (secs) [Inf = no filtering] %--------------------------------------------------------------------------- for ses=1:nses SPM.xX.K(ses).HParam = 128; end % intrinsic autocorrelations: OPTIONS: 'none'|'AR(1) + w' %----------------------------------------------------------------------- SPM.xVi.form = 'AR(1)'; % specify data: matrix of filenames and TR %=========================================================================== for ses=1:nses dir{ses} = '../Data'; % directories can be generalised for >1 ses/sub tmp{ses} = spm_get('files',dir{ses},'swau*.img'); end SPM.xY.P = cat(1,tmp{:}); SPM.xY.RT = TR; % Configure design matrix %=========================================================================== SPM = spm_fmri_spm_ui(SPM); % Estimate parameters %=========================================================================== SPM = spm_spm(SPM); % Add extra contrasts %=========================================================================== ocon = length(SPM.xCon); % default contrasts eb = eye(SPM.xBF.order); % basis functions cnam{1} = 'Canonical HRF: Faces > Baseline'; cwgt{1} = [kron([1 1 1 1],eb(1,:)) zeros(1,6)]; % zeros = movement params ctyp{1} = 'T'; cnam{2} = 'Effects of REAL interest'; cwgt{2} = [eye(4*SPM.xBF.order) zeros(4*SPM.xBF.order,6)]; ctyp{2} = 'F'; cnam{3} = 'Canonical HRF: F vs N'; cwgt{3} = [kron([-1 -1 1 1],eb(1,:)) zeros(1,6)]; ctyp{3} = 'T'; cnam{4} = 'Canonical + Derivatives: 1 vs 2'; cwgt{4} = [kron([1 -1 1 -1],eb) zeros(SPM.xBF.order,6)]; ctyp{4} = 'F'; cnam{5} = 'Movement parameters'; cwgt{5} = [zeros(6,4*SPM.xBF.order) eye(6)]; ctyp{5} = 'F'; for c = 1:length(cnam) cw = [cwgt{c} zeros(size(cwgt{c},1),1)]'; % pad with zero for constant SPM.xCon(c+ocon) = spm_FcUtil('Set',cnam{c},ctyp{c},'c',cw,SPM.xX.xKXs); end % and evaluate %--------------------------------------------------------------------------- spm_contrasts(SPM); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Now press RESULTS (and see README)! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Parametric Stats model (see README) for one session/subject % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cd(cwd) load lags swd = [cwd '/ParStats']; eval(sprintf('!mkdir %s',swd)); cd(swd); % number of scans and sessions %--------------------------------------------------------------------------- SPM.nscan = ones(1,nses)*351; % basis functions and timing parameters %--------------------------------------------------------------------------- SPM.xBF.name = 'hrf (with time and dispersion derivatives)'; SPM.xBF.order = 3; SPM.xBF.length = 32; % length in seconds SPM.xBF.T = num_slices; % number of time bins per scan SPM.xBF.T0 = ref_slice; % middle slice/timebin SPM.xBF.UNITS = 'scans'; % OPTIONS: 'scans'|'secs' for onsets SPM.xBF.Volterra = 1; % OPTIONS: 1|2 = order of convolution % Trial specification: Onsets, duration (UNITS) and parameters for modulation %--------------------------------------------------------------------------- for ses=1:nses SPM.Sess(ses).U(1).name = {'Face'}; SPM.Sess(ses).U(1).ons = sots'; SPM.Sess(ses).U(1).dur = 0; SPM.Sess(ses).U(1).P(1).name = 'Lag'; SPM.Sess(ses).U(1).P(1).P = lag'; SPM.Sess(ses).U(1).P(1).h = 1; SPM.Sess(ses).U(1).P(1).i = [1 2]; SPM.Sess(ses).U(1).P(2).name = 'Fame'; SPM.Sess(ses).U(1).P(2).P = fam'; SPM.Sess(ses).U(1).P(2).h = 1; SPM.Sess(ses).U(1).P(2).i = [1 3]; SPM.Sess(ses).U(1).P(3).name = 'FameXLag'; SPM.Sess(ses).U(1).P(3).P = famlag'; SPM.Sess(ses).U(1).P(3).h = 1; SPM.Sess(ses).U(1).P(3).i = [1 4]; end % design (user specified covariates, eg movement parameters) %--------------------------------------------------------------------------- % (note inclusion of movement parameters makes unwarping somewhat redundant, % but done here to illustrate facilities of SPM) rnam = {'X','Y','Z','x','y','z'}; for ses=1:nses dir{ses} = '../Data'; % directories can be generalised for >1 ses/sub fn = spm_get('Files',dir{ses},'rp_*.txt'); [r1,r2,r3,r4,r5,r6] = textread(fn,'%f%f%f%f%f%f'); SPM.Sess(ses).C.C = [r1 r2 r3 r4 r5 r6]; SPM.Sess(ses).C.name = rnam; end % global normalization: OPTIONS:'Scaling'|'None' %--------------------------------------------------------------------------- SPM.xGX.iGXcalc = 'None'; % low frequency confound: high-pass cutoff (secs) [Inf = no filtering] %--------------------------------------------------------------------------- for ses=1:nses SPM.xX.K(ses).HParam = 128; end % intrinsic autocorrelations: OPTIONS: 'none'|'AR(1) + w' %----------------------------------------------------------------------- SPM.xVi.form = 'AR(1)'; % specify data: matrix of filenames and TR %=========================================================================== clear tmp for ses=1:nses dir{ses} = '../Data'; % directories can be generalised for >1 ses/sub tmp{ses} = spm_get('files',dir{ses},'swau*.img'); end SPM.xY.P = cat(1,tmp{:}); SPM.xY.RT = TR; % Configure design matrix %=========================================================================== SPM = spm_fmri_spm_ui(SPM); % Estimate parameters %=========================================================================== SPM = spm_spm(SPM); % Add extra contrasts %=========================================================================== ocon = length(SPM.xCon); eb = eye(SPM.xBF.order); % basis functions clear cnam cnam{1} = 'Faces vs Baseline'; cwgt{1} = [kron([1 0 0 0],eb) zeros(3,6)]; % zeros = movement params ctyp{1} = 'F'; cnam{2} = 'Effects of lag'; cwgt{2} = [kron([0 1 0 0],eb) zeros(3,6)]; ctyp{2} = 'F'; for c = 1:length(cnam) cw = [cwgt{c} zeros(size(cwgt{c},1),1)]'; % pad with zero for constant SPM.xCon(c+ocon) = spm_FcUtil('Set',cnam{c},ctyp{c},'c',cw,SPM.xX.xKXs); end % and evaluate %--------------------------------------------------------------------------- spm_contrasts(SPM); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Now press RESULTS (and see README)! % Parametric plots do not work for some reason?