function cat_stat_analyze_ROIs(spmmat,alpha,show_results) % Statistical analysis of ROI data using an existing SPM design saved in a SPM.mat file % %__________________________________________________________________________ % Christian Gaser % $Id: cat_stat_analyze_ROIs.m 1428 2019-02-08 13:44:55Z gaser $ if nargin < 1 spmmat = spm_select(1,'SPM.mat','Select SPM.mat file to get design'); end load(spmmat); % write beta images write_beta = 0; % compare correlation coefficients between samples compare_two_samples = 0; cwd = fileparts(spmmat); %-Check that model has been estimated if ~isfield(SPM, 'xVol') str = { 'This model has not been estimated.';... 'Would you like to estimate it now?'}; if spm_input(str,1,'bd','yes|no',[1,0],1) cd(cwd) SPM = spm_spm(SPM); else return end end % select contrast [Ic,xCon] = spm_conman(SPM,'T&F',1,'Select contrast',' ',1); % check whether two groups are compared with each other con = xCon(Ic).c; ind_con = find(con~=0); c_sort_unique = sort(unique(con(ind_con))); if compare_two_samples if numel(c_sort_unique) == 2 if all(c_sort_unique==[-1 1]') compare_two_samples = 1; end end end % not yet ready to use % threshold for p-values spm_clf('Interactive'); if nargin < 2 alpha = spm_input('p-value',1,'r',0.05,1,[0,1]); end % mesh detected? if isfield(SPM.xVol,'G') mesh_detected = 1; pattern = 'catROIs_'; subfolder = 'surf'; else mesh_detected = 0; pattern = 'catROI_'; subfolder = 'mri'; end % filenames of existing design P = SPM.xY.P; n = numel(P); pth = cell(n,1); fname = cell(n,1); for i=1:n [pth{i},nam,ext] = fileparts(P{i}); fname{i} = [nam ext]; end [tmp, pat] = spm_str_manip(fname,'C'); % get prepending pattern if ~mesh_detected prepend = fname{1}; % check whether prepending pattern is not based on GM/WM if isempty(strfind(prepend,'mwp')) & isempty(strfind(prepend,'m0wp')) fprintf('\nWARNING: ROI analysis is only supported for VBM of GM/WM/CSF. No ROI values for DBM will be estimated.\n',prepend); end end roi_files_found = 0; % get names of ROI xml files using saved filename in SPM.mat for i=1:numel(P) [pth,nam,ext] = fileparts(P{i}); % check whether a label subfolder exists and replace the name with "label" if strcmp(pth(end-length(subfolder)+1:end),subfolder) pth(end-length(subfolder)+1:end) = []; pth_label = [pth 'label']; else pth_label = pth; end if ~exist(pth_label,'dir') fprintf('Label folder %s was not found.\n',pth_label); break end sname = [pattern '*' pat.m{i} '*.xml']; files = cat_vol_findfiles(pth_label,sname); switch numel(files) case 0 fprintf('Label file %s not found in %s. Please check whether you have extracted ROI-based surface values or have moved your data.\n',sname,pth_label); case 1 roi_names{i} = files{1}; roi_files_found = roi_files_found + 1; otherwise % if multiple files were found select that one with the longer filename ind = zeros(numel(files),1); for j=1:numel(files) [rpth,rnam,rext] = fileparts(files{j}); tmp = strfind(nam,rnam(numel(pattern)+1:end)); if isempty(tmp), tmp = Inf; end ind(j) = tmp; end % check for longer filename (=smaller index) [mi,ni] = min(ind); % use longer filename roi_names{i} = files{ni}; roi_files_found = roi_files_found + 1; end disp(roi_names{i}) end % select files interactively of no xml files were found if roi_files_found ~= n roi_names0 = cellstr(spm_select(n ,'xml','Select xml files in the same order of your SPM design.',{},'',pattern)); roi_names = roi_names0; roi_files_found = 0; for i=1:numel(P) [pth,nam,ext] = fileparts(P{i}); sname = [pattern '*' pat.m{i} '*.xml']; files = cat_vol_findfiles(fileparts(roi_names0{i}),sname); switch numel(files) case 0 fprintf('Order of filenames is uncorrect. Please take casre of the same order of file selection as in your SPM design.\n'); case 1 roi_names{i} = files{1}; roi_files_found = roi_files_found + 1; otherwise % if multiple files were found select that one with the longer filename ind = zeros(numel(files),1); for j=1:numel(files) [rpth,rnam,rext] = fileparts(files{j}); tmp = strfind(nam,rnam(numel(pattern)+1:end)); if isempty(tmp), tmp = Inf; end ind(j) = tmp; end % check for longer filename (=smaller index) [mi,ni] = min(ind); % use longer filename roi_names{i} = files{ni}; roi_files_found = roi_files_found + 1; end disp(roi_names{i}) end if roi_files_found ~= n fprintf('%d label files found with pattern %s. Please only retain data from the current analysis.\n',roi_files_found,sname); return end end % use 1st xml file to get the available atlases % xml-reading is here using old style to be compatible to old xml-files and functions xml = convert(xmltree(deblank(roi_names{1}))); % get selected atlas and measure [sel_atlas, sel_measure, atlas, measure] = get_atlas_measure(xml); % get names IDs and values of selected atlas and measure inside ROIs [ROInames ROIids ROIvalues] = get_ROI_measure(roi_names, sel_atlas, sel_measure); % get name of contrast str_con = deblank(xCon(Ic).name); % replace spaces with "_" and characters like "<" or ">" with "gt" or "lt" str_con(strfind(str_con,' ')) = '_'; strpos = strfind(str_con,' > '); if ~isempty(strpos), str_con = [str_con(1:strpos-1) '_gt_' str_con(strpos+1:end)]; end strpos = strfind(str_con,' < '); if ~isempty(strpos), str_con = [str_con(1:strpos-1) '_lt_' str_con(strpos+1:end)]; end strpos = strfind(str_con,'>'); if ~isempty(strpos), str_con = [str_con(1:strpos-1) 'gt' str_con(strpos+1:end)]; end strpos = strfind(str_con,'<'); if ~isempty(strpos), str_con = [str_con(1:strpos-1) 'lt' str_con(strpos+1:end)]; end str_con = spm_str_manip(str_con,'v'); % build X and Y for GLM Y = ROIvalues; X = SPM.xX.X; % compare correlation coefficients after Fisher z-transformation if compare_two_samples % get two samples according to contrast -1 1 Y1 = Y(find(X(:,find(c==-1))),:); Y2 = Y(find(X(:,find(c== 1))),:); % estimate correlation and apply Fisher transformation r1 = corrcoef(Y1); r2 = corrcoef(Y2); z1 = atanh(r1); z2 = atanh(r2); Dz = (z1-z2)./sqrt(1/(size(Y1,1)-3)+1/(size(Y2,1)-3)); Pz = (1-spm_Ncdf(abs(Dz))); Pzfdr = spm_P_FDR(Pz); Pz(isnan(Pz)) = 1; Pzfdr(isnan(Pzfdr)) = 1; opt.label = ROInames; ind = (Pzfdr 2 [Psort0, indP0] = sort(p); n = length(Psort0); Pcorr{3} = ones(size(p)); for k=1:n Pval = p(indP0(k))*(n+1-k); if Pval 1 sel_measure = spm_input('Select measure','+1','m',useful_measures); else sel_measure = 1; end measure = useful_measures{sel_measure}; % remove spaces measure = deblank(measure); %_______________________________________________________________________ function [ROInames ROIids ROIvalues] = get_ROI_measure(roi_names, sel_atlas, sel_measure) % get names, IDs and values inside ROI for a selected atlas % % FORMAT [ROInames ROIids ROIvalues] = get_ROI_measure(roi_names, sel_atlas, sel_measure); % roi_names - cell of ROI xml files % sel_atlas - index of selected atlas % sel_measure - index of selected measure % % ROInames - array 2*rx1 of ROI names (r - # of ROIs) % ROIids - array 2*rx1 of ROI IDs for left and right hemisphere % ROIvalues - cell nxr of values inside ROI (n - # of data) n_data = length(roi_names); spm_progress_bar('Init',n_data,'Load xml-files','subjects completed') for i=1:n_data xml = cat_io_xml(deblank(roi_names{i})); % remove leading catROI*_ part from name [path2, ID] = fileparts(roi_names{i}); ind = strfind(ID,'_'); ID = ID(ind(1)+1:end); atlases = fieldnames(xml); measures = fieldnames(xml.(atlases{sel_atlas}).data); ROInames = xml.(atlases{sel_atlas}).names; ROIids = xml.(atlases{sel_atlas}).ids; % check that all measures were found try tmp = measures{sel_measure}; catch for j = 1:numel(measures) fprintf('Available measures in %s:\n %s\n',roi_names{i},measures{j}); end error('Please check your label files. Measure is not available in %s.\n',roi_names{i}); end val = xml.(atlases{sel_atlas}).data.(measures{sel_measure}); if i==1, ROIvalues = zeros(n_data, numel(val)); end ROIvalues(i,:) = xml.(atlases{sel_atlas}).data.(measures{sel_measure}); spm_progress_bar('Set',i); end spm_progress_bar('Clear');