123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- function [TabDat,xSVC] = spm_VOI(SPM,xSPM,hReg,xY)
- % List of local maxima and adjusted p-values for a small Volume of Interest
- % FORMAT [TabDat,xSVC] = spm_VOI(SPM,xSPM,hReg,[xY])
- %
- % SPM - Structure containing analysis details (see spm_spm)
- %
- % xSPM - Structure containing SPM, distribution & filtering details
- % Required fields are:
- % .swd - SPM working directory - directory containing current SPM.mat
- % .Z - minimum of n Statistics {filtered on u and k}
- % .n - number of conjoint tests
- % .STAT - distribution {Z, T, X or F}
- % .df - degrees of freedom [df{interest}, df{residual}]
- % .u - height threshold
- % .k - extent threshold {resels}
- % .XYZ - location of voxels {voxel coords}
- % .XYZmm - location of voxels {mm}
- % .S - search Volume {voxels}
- % .R - search Volume {resels}
- % .FWHM - smoothness {voxels}
- % .M - voxels -> mm matrix
- % .VOX - voxel dimensions {mm}
- % .DIM - image dimensions {voxels} - column vector
- % .Vspm - mapped statistic image(s)
- % .Ps - uncorrected P values in searched volume (for voxel FDR)
- % .Pp - uncorrected P values of peaks (for peak FDR)
- % .Pc - uncorrected P values of cluster extents (for cluster FDR)
- % .uc - 0.05 critical thresholds for FWEp, FDRp, FWEc, FDRc
- %
- % hReg - Handle of results section XYZ registry (see spm_results_ui.m)
- % xY - VOI structure
- %
- % TabDat - Structure containing table data (see spm_list.m)
- % xSVC - Thresholded xSPM data (see spm_getSPM.m)
- %__________________________________________________________________________
- %
- % spm_VOI is called by the SPM results section and takes variables in
- % SPM to compute p-values corrected for a specified volume of interest.
- %
- % The volume of interest may be defined as a box or sphere centred on
- % the current voxel or by a mask image.
- %
- % If the VOI is defined by a mask this mask must have been defined
- % independently of the SPM (e.g. using a mask based on an orthogonal
- % contrast).
- %
- % External mask images should be in the same orientation as the SPM
- % (i.e. as the input used in stats estimation). The VOI is defined by
- % voxels with values greater than 0.
- %
- % See also: spm_list
- %__________________________________________________________________________
- % Copyright (C) 1999-2014 Wellcome Trust Centre for Neuroimaging
- % Karl Friston
- % $Id: spm_VOI.m 6080 2014-07-01 16:00:22Z guillaume $
- %-Parse arguments
- %--------------------------------------------------------------------------
- if nargin < 2, error('Not enough input arguments.'); end
- if nargin < 3, hReg = []; end
- if nargin < 4, xY = []; end
- Num = spm_get_defaults('stats.results.svc.nbmax'); % maxima per cluster
- Dis = spm_get_defaults('stats.results.svc.distmin'); % distance among maxima {mm}
- %-Title
- %--------------------------------------------------------------------------
- spm('FigName',['SPM{',xSPM.STAT,'}: Small Volume Correction']);
- %-Get current location {mm}
- %--------------------------------------------------------------------------
- try
- xyzmm = xY.xyz;
- catch
- xyzmm = spm_results_ui('GetCoords');
- end
-
- %-Specify search volume
- %--------------------------------------------------------------------------
- if isfield(xY,'def')
- switch xY.def
- case 'sphere'
- SPACE = 'S';
- case 'box'
- SPACE = 'B';
- case 'mask'
- SPACE = 'I';
- otherwise
- error('Unknown VOI type.');
- end
- else
- str = sprintf(' at [%.0f,%.0f,%.0f]',xyzmm(1),xyzmm(2),xyzmm(3));
- SPACE = spm_input('Search volume...',-1,'m',...
- {['Sphere',str],['Box',str],'Image'},['S','B','I']);
- end
- %-Voxels in entire search volume {mm}
- %--------------------------------------------------------------------------
- XYZmm = SPM.xVol.M(1:3,:)*[SPM.xVol.XYZ; ones(1, SPM.xVol.S)];
- Q = ones(1,size(xSPM.XYZmm,2));
- O = ones(1,size( XYZmm,2));
- FWHM = xSPM.FWHM;
- switch SPACE
- case 'S' %-Sphere
- %----------------------------------------------------------------------
- if ~isfield(xY,'spec')
- D = spm_input('radius of VOI {mm}',-2);
- else
- D = xY.spec;
- end
- str = sprintf('%0.1fmm sphere',D);
- j = find(sum((xSPM.XYZmm - xyzmm*Q).^2) <= D^2);
- k = find(sum(( XYZmm - xyzmm*O).^2) <= D^2);
- D = D./xSPM.VOX;
- case 'B' %-Box
- %----------------------------------------------------------------------
- if ~isfield(xY,'spec')
- D = spm_input('box dimensions [k l m] {mm}',-2);
- else
- D = xY.spec;
- end
- if length(D)~=3, D = ones(1,3)*D(1); end
- str = sprintf('%0.1f x %0.1f x %0.1f mm box',D(1),D(2),D(3));
- j = find(all(abs(xSPM.XYZmm - xyzmm*Q) <= D(:)*Q/2));
- k = find(all(abs( XYZmm - xyzmm*O) <= D(:)*O/2));
- D = D./xSPM.VOX;
- case 'I' %-Mask Image
- %----------------------------------------------------------------------
- if ~isfield(xY,'spec')
- [VM,sts] = spm_select([1 Inf],'image','Image defining search volume');
- if ~sts, TabDat = []; xSVC = []; return; end
- else
- VM = xY.spec;
- end
- D = spm_vol(VM);
- if numel(D) > 1
- fprintf('Computing union of all masks.\n');
- spm_check_orientations(D);
- D2 = struct(...
- 'fname', ['virtual_SVC_mask' spm_file_ext],...
- 'dim', D(1).dim,...
- 'dt', [spm_type('uint8') spm_platform('bigend')],...
- 'mat', D(1).mat,...
- 'n', 1,...
- 'pinfo', [1 0 0]',...
- 'descrip', 'SVC mask');
- D2.dat = false(D2.dim);
- for i=1:numel(D)
- D2.dat = D2.dat | spm_read_vols(D(i));
- end
- D2.dat = uint8(D2.dat);
- D = D2;
- end
- str = spm_file(D.fname,'short30');
- str = regexprep(str, {'\\' '\^' '_' '{' '}'}, ...
- {'\\\\' '\\^' '\\_' '\\{' '\\}'}); % Escape TeX special characters
- str = sprintf('image mask: %s',str);
- VOX = sqrt(sum(D.mat(1:3,1:3).^2));
- FWHM = FWHM.*(xSPM.VOX./VOX);
- XYZ = D.mat \ [xSPM.XYZmm; ones(1, size(xSPM.XYZmm, 2))];
- j = find(spm_sample_vol(D, XYZ(1,:), XYZ(2,:), XYZ(3,:),0) > 0);
- XYZ = D.mat \ [ XYZmm; ones(1, size( XYZmm, 2))];
- k = find(spm_sample_vol(D, XYZ(1,:), XYZ(2,:), XYZ(3,:),0) > 0);
- end
- xSPM.S = length(k);
- xSPM.R = spm_resels(FWHM,D,SPACE);
- xSPM.Z = xSPM.Z(j);
- xSPM.XYZ = xSPM.XYZ(:,j);
- xSPM.XYZmm = xSPM.XYZmm(:,j);
- %-Restrict FDR to the search volume
- %--------------------------------------------------------------------------
- df = xSPM.df;
- STAT = xSPM.STAT;
- DIM = xSPM.DIM;
- R = xSPM.R;
- n = xSPM.n;
- Vspm = xSPM.Vspm;
- u = xSPM.u;
- S = xSPM.S;
- try, xSPM.Ps = xSPM.Ps(k); end
- if STAT ~= 'P'
- [up, xSPM.Pp] = spm_uc_peakFDR(0.05,df,STAT,R,n,Vspm,k,u);
- uu = spm_uc(0.05,df,STAT,R,n,S);
- end
- try % if STAT == 'T'
- V2R = 1/prod(xSPM.FWHM(DIM>1));
- [uc, xSPM.Pc, ue] = spm_uc_clusterFDR(0.05,df,STAT,R,n,Vspm,k,V2R,u);
- catch
- uc = NaN;
- ue = NaN;
- xSPM.Pc = [];
- end
- try, xSPM.uc = [uu up ue uc]; end
- %-Tabulate p values
- %--------------------------------------------------------------------------
- str = sprintf('search volume: %s',str);
- if any(strcmp(SPACE,{'S','B'}))
- str = sprintf('%s at [%.0f,%.0f,%.0f]',str,xyzmm(1),xyzmm(2),xyzmm(3));
- end
- TabDat = spm_list('List',xSPM,hReg,Num,Dis,str);
- if nargout > 1, xSVC = xSPM; end
- %-Reset title
- %--------------------------------------------------------------------------
- spm('FigName',['SPM{',xSPM.STAT,'}: Results']);
|