function varargout = spm_list(varargin)
% Display and analysis of SPM{.}
% FORMAT TabDat = spm_list('List', SPM,VOL,Dis,Num,Title,hReg)
% Summary list of local maxima for entire volume of interest
% FORMAT TabDat = spm_list('ListCluster',SPM,VOL,Dis,Num,Title,hReg)
% List of local maxima for a single suprathreshold cluster
%
% SPM - 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 {voxels}
% .XYZ - location of voxels {voxel coords}
% .XYZmm - location of voxels {mm}
%
% VOL - structure containing details of volume analysed
% - required fields are:
% .S - search Volume {voxels}
% .R - search Volume {resels}
% .FWHM - smoothness {voxels}
% .M - voxels - > mm matrix
% .VOX - voxel dimensions {mm}
% .Vspm - mapped statistic image(s)
% .Msk - mask
%
% (see spm_getSPM for further details of SPM & VOL structures)
%
% Dis - Minimum distance between maxima
% {defaults (missing or empty) to 8mm for 'List', 4mm for 'ListCluster'}
% Num - Maxiumum number of local maxima tabulated per cluster
% {defaults (missing or empty) to 3 for 'List', Inf for 'ListCluster'}
% Title - Title text for table {defaults on missing or empty}
% hReg - Handle of results section XYZ registry (see spm_results_ui.m)
%
% TabDat - Structure containing table data
% - fields are
% .tit - table Title (string)
% .hdr - table header (2x11 cell array)
% .fmt - fprintf format strings for table data (1x11 cell array)
% .str - table filtering note (string)
% .ftr - table footnote information (4x2 cell array)
% .dat - table data (Nx11 cell array)
%
% ----------------
%
% FORMAT spm_list('TxtList',TabDat,c)
% Prints a tab-delimited text version of the table
% TabDat - Structure containing table data (format as above)
% c - Column of table data to start text table at
% (E.g. c=3 doesn't print set-level results contained in columns 1 & 2)
% ----------------
%
% FORMAT spm_list('SetCoords',xyz,hAx,hC)
% Highlighting of table co-ordinates (used by results section registry)
% xyz - 3-vector of new co-ordinate
% hAx - table axis (the registry object for tables)
% hReg - Handle of caller (not used)
%_______________________________________________________________________
%
% spm_list characterizes SPMs (thresholded at u and k) in terms of
% excursion sets (a collection of face, edge and vertex connected
% subsets or clusters). The currected significance of the results are
% based on set, cluster and voxel-level inferences using distributional
% approximations from the Theory of Gaussian Feilds. These
% distributions assume that the SPM is a reasonable lattice
% approximation of a continuous random field with known component field
% smoothness.
%
% The p values are based on the probability of obtaining c, or more,
% clusters of k, or more, resels above u, in the volume S analysed =
% P(u,k,c). For specified thresholds u, k, the set-level inference is
% based on the observed number of clusters C, = P(u,k,C). For each
% cluster of size K the cluster-level inference is based on P(u,K,1)
% and for each voxel (or selected maxima) of height U, in that cluster,
% the voxel-level inference is based on P(U,0,1). All three levels of
% inference are supported with a tabular presentation of the p values
% and the underlying statistic:
%
% Set-level - c = number of suprathreshold clusters
% - P = prob(c or more clusters in the search volume)
%
% Cluster-level - k = number of voxels in this cluster
% - Pc = prob(k or more voxels in the search volume)
% - Pu = prob(k or more voxels in a cluster)
%
% Voxel-level - T/F = Statistic upon which the SPM is based
% - Ze = The eqivalent Z score - prob(Z > Ze) = prob(t > T)
% - Pc = prob(Ze or higher in the search volume)
% - Qu = Expd(Prop of false positives among voxels >= Ze)
% - Pu = prob(Ze or higher at that voxel)
%
% x,y,z (mm) - Coordinates of the voxel
%
% The table is grouped by regions and sorted on the Ze-variate of the
% primary maxima. Ze-variates (based on the uncorrected p value) are the
% Z score equivalent of the statistic. Volumes are expressed in voxels.
%
% Clicking on values in the table returns the value to the Matlab
% workspace. In addition, clicking on the co-ordinates jumps the
% results section cursor to that location. The table has a context menu
% (obtained by right-clicking in the background of the table),
% providing options to print the current table as a text table, or to
% extract the table data to the Matlab workspace.
%
%_______________________________________________________________________
% @(#)spm_list.m 2.34 Karl Friston, Andrew Holmes 01/06/23
% @(#)spm_list.m 1.8 UM Biostatistics ver., T. Nichols 01/06/27
%-Parse arguments, default to 'list' if varargin{1} not an Action string
%-----------------------------------------------------------------------
if nargin==0, error('Insufficient arguments'), end
if ~ischar(varargin{1})
warning('Direct usage Grandfathered: Use an action string!')
spm_list('list',varargin{:});
return
end
%=======================================================================
switch lower(varargin{1}), case 'list' %-List
%=======================================================================
% FORMAT TabDat = spm_list('list',SPM,VOL,Dis,Num,Title,hReg)
%-Tolerance for p-value underflow, when computing equivalent Z's
%-----------------------------------------------------------------------
tol = eps*10;
%-Parse arguments
%-----------------------------------------------------------------------
if nargin<3, error('insufficient arguments'), end
if nargin<7, hReg=[]; else, hReg = varargin{7}; end
if nargin<6, Title = '';
else, Title = varargin{6}; end
if isempty(Title), Title = ['volume summary',...
' (p-values corrected for entire volume)']; end
if nargin<5, Num = [];
else, Num = varargin{5}; end
if isempty(Num), Num = 03; end
if nargin<4, Dis = [];
else, Dis = varargin{4}; end
if isempty(Dis), Dis = 08; end
% VOL is varargin{3} - Use by reference for speed
% SPM is varargin{2} - Don't copy into local variables
%-Get current location (to highlight selected voxel in table)
%-----------------------------------------------------------------------
xyzmm = spm_results_ui('GetCoords');
%-Extract data from structures
%-----------------------------------------------------------------------
S = varargin{3}.S;
R = varargin{3}.R;
FWHM = varargin{3}.FWHM;
v2r = 1/prod(FWHM(~isinf(FWHM))); %-voxels to resels
n = varargin{2}.n;
STAT = varargin{2}.STAT;
df = varargin{2}.df;
u = varargin{2}.u;
k = varargin{2}.k*v2r;
Vspm = varargin{3}.Vspm; % Needed for FDR
Msk = varargin{3}.Msk; %
nZ = length(varargin{2}.Z); %
%-Setup graphics pane
%-----------------------------------------------------------------------
spm('Pointer','Watch')
Fgraph = spm_figure('GetWin','Graphics');
spm_results_ui('Clear',Fgraph)
FS = spm('FontSizes'); %-Scaled font sizes
PF = spm_platform('fonts'); %-Font names (for this platform)
%-Table header & footer
%=======================================================================
%-Table axes & Title
%-----------------------------------------------------------------------
hAx = axes('Position',[0.05 0.1 0.9 0.4],...
'DefaultTextFontSize',FS(8),...
'DefaultTextInterpreter','Tex',...
'DefaultTextVerticalAlignment','Baseline',...
'Units','points',...
'Visible','off');
AxPos = get(hAx,'Position'); set(hAx,'YLim',[0,AxPos(4)])
dy = FS(9);
y = floor(AxPos(4)) - dy;
text(0,y,['Statistics: \it\fontsize{',num2str(FS(9)),'}',Title],...
'FontSize',FS(11),'FontWeight','Bold'); y = y - dy/2;
line([0 1],[y y],'LineWidth',3,'Color','r'), y = y - 9*dy/8;
%-Construct table header
%-----------------------------------------------------------------------
set(gca,'DefaultTextFontName',PF.helvetica,'DefaultTextFontSize',FS(8))
Hc = [];
h = text(0.01,y, 'set-level','FontSize',FS(9)); Hc = [Hc,h];
h=line([0.00,0.11],[y-dy/4,y-dy/4],'LineWidth',0.5,'Color','r');Hc = [Hc,h];
h = text(0.02,y-9*dy/8, '\itp '); Hc = [Hc,h];
h = text(0.08,y-9*dy/8, '\itc '); Hc = [Hc,h];
text(0.22,y, 'cluster-level','FontSize',FS(9))
line([0.15,0.41],[y-dy/4,y-dy/4],'LineWidth',0.5,'Color','r')
text(0.16,y-9*dy/8, '\itp \rm_{corrected}')
text(0.26,y-9*dy/8, '\itk \rm_E')
text(0.33,y-9*dy/8, '\itp \rm_{uncorrected}')
text(0.60,y, 'voxel-level','FontSize',FS(9))
line([0.46,0.86],[y-dy/4,y-dy/4],'LineWidth',0.5,'Color','r')
text(0.46,y-9*dy/8, '\itp \rm_{FWE-corr}')
text(0.55,y-9*dy/8, '\itp \rm_{FDR-corr}');
text(0.64,y-9*dy/8, sprintf('\\it%c',STAT))
text(0.72,y-9*dy/8, '(\itZ\rm_\equiv)')
text(0.79,y-9*dy/8, '\itp \rm_{uncorrected}')
text(0.93,y - dy/2,['x,y,z \fontsize{',num2str(FS(8)),'}\{mm\}']);
%-Headers for text table...
TabDat.tit = Title;
TabDat.hdr = { 'set', 'c';...
'set', 'p';...
'cluster', 'p(cor)';...
'cluster', 'equivk';...
'cluster', 'p(unc)';...
'voxel', 'p(FWE-cor)';...
'voxel', 'p(FDR-cor)';...
'voxel', STAT;...
'voxel', 'equivZ';...
'voxel', 'p(unc)';...
'', 'x,y,z {mm}'}';...
TabDat.fmt = { '%-0.3f', '%g',... %-Set
'%0.3f', '%0.0f', '%0.3f',... %-Cluster
'%0.3f', '%0.3f', '%6.2f', '(%5.2f)', '%0.3f',...%-Voxel
'%3.0f %3.0f %3.0f'}; %-XYZ
%-Column Locations
tCol = [ 0.00 0.07 ... %-Set
0.16 0.26 0.34 ... %-Cluster
0.46 0.55 0.62 0.71 0.80 ...%-Voxel
0.92]; %-XYZ
y = y - 7*dy/4;
line([0 1],[y y],'LineWidth',1,'Color','r')
y = y - 5*dy/4;
y0 = y;
%-Table filtering note
%-----------------------------------------------------------------------
if isinf(Num)
TabDat.str = sprintf('table shows all local maxima > %.1fmm apart',Dis);
else
TabDat.str = sprintf(['table shows at most %d local maxima ',...
'> %.1fmm apart per cluster'],Num,Dis);
end
text(0.5,4,TabDat.str,'HorizontalAlignment','Center','FontName',PF.helvetica,...
'FontSize',FS(8),'FontAngle','Italic')
%-Volume, resels and smoothness
%-----------------------------------------------------------------------
FWHMmm = FWHM.*varargin{3}.VOX'; % FWHM {mm}
Pz = spm_P(1,0,u,df,STAT,1,n,S);
Pu = spm_P(1,0,u,df,STAT,R,n,S);
[Qu QPs] = spm_P_FDR(u,df,STAT,n,Vspm,Msk);
[P Pn Em En EN] = spm_P(1,k,u,df,STAT,R,n,S);
%-Footnote with SPM parameters
%-----------------------------------------------------------------------
line([0 1],[0 0],'LineWidth',1,'Color','r')
set(gca,'DefaultTextFontName',PF.helvetica,...
'DefaultTextInterpreter','None','DefaultTextFontSize',FS(8))
TabDat.ftr = cell(5,2);
TabDat.ftr{1} = ...
sprintf('Height threshold: %c = %0.2f, p = %0.3f (%0.3f FWE-corr, %0.3f FDR-corr)',...
STAT,u,Pz,Pu,Qu);
TabDat.ftr{2} = ...
sprintf('Extent threshold: k = %0.0f voxels, p = %0.3f (%0.3f corrected)',...
k/v2r,Pn,P);
TabDat.ftr{3} = ...
sprintf('Expected voxels per cluster, <k> = %0.3f',En/v2r);
TabDat.ftr{4} = ...
sprintf('Expected number of clusters, <c> = %0.2f',Em*Pn);
TabDat.ftr{5} = ...
sprintf('Expected number of false discoveries, <#FD|R> <= %0.2f',...
Qu*nZ);
TabDat.ftr{6} = ...
sprintf('Degrees of freedom = [%0.1f, %0.1f]',df);
TabDat.ftr{7} = ...
sprintf(['Smoothness FWHM = %0.1f %0.1f %0.1f {mm} ',...
' = %0.1f %0.1f %0.1f {voxels}'],FWHMmm,FWHM);
TabDat.ftr{8} = ...
sprintf('Search volume: S = %0.0f mm^3 = %0.0f voxels = %0.1f resels',...
S*prod(varargin{3}.VOX),S,R(end));
TabDat.ftr{9} = ...
sprintf(['Voxel size: [%0.1f, %0.1f, %0.1f] mm ',...
' (1 resel = %0.2f voxels)'],...
varargin{3}.VOX,prod(FWHM));
text(0.0,-1*dy,TabDat.ftr{1},...
'UserData',[u,Pz,Pu,Qu],'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.0,-2*dy,TabDat.ftr{2},...
'UserData',[k/v2r,Pn,P],'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.0,-3*dy,TabDat.ftr{3},...
'UserData',En/v2r,'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.0,-4*dy,TabDat.ftr{4},...
'UserData',Em*Pn,'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.0,-5*dy,TabDat.ftr{5},...
'UserData',Qu*nZ,'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.5,-1*dy,TabDat.ftr{6},...
'UserData',df,'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.5,-2*dy,TabDat.ftr{7},...
'UserData',FWHMmm,'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.5,-3*dy,TabDat.ftr{8},...
'UserData',[S*prod(varargin{3}.VOX),S,R(end)],...
'ButtonDownFcn','get(gcbo,''UserData'')')
text(0.5,-4*dy,TabDat.ftr{9},...
'UserData',[varargin{3}.VOX',prod(FWHM)],...
'ButtonDownFcn','get(gcbo,''UserData'')')
%-Characterize excursion set in terms of maxima
% (sorted on Z values and grouped by regions)
%=======================================================================
if ~length(varargin{2}.Z)
text(0.5,y-6*dy,'no suprathreshold clusters',...
'HorizontalAlignment','Center',...
'FontAngle','Italic','FontWeight','Bold',...
'FontSize',FS(16),'Color',[1,1,1]*.5);
TabDat.dat = cell(0,11);
varargout = {TabDat};
spm('Pointer','Arrow')
return
end
% Includes Darren Gitelman's code for working around bug in
% spm_max for conjunctions with negative thresholds
%-----------------------------------------------------------------------
minz = abs(min(min(varargin{2}.Z)));
zscores = 1+minz+varargin{2}.Z;
[N Z XYZ A] = spm_max(zscores,varargin{2}.XYZ);
Z = Z-minz-1;
%-----------------------------------------------------------------------
%-Convert cluster sizes from voxels to resels
%-----------------------------------------------------------------------
if isfield(varargin{3},'VRVP')
V2R = spm_sample_vol(varargin{3}.VRVP,XYZ(1,:),XYZ(2,:),XYZ(3,:),0);
else
V2R = v2r;
end
N = N.*V2R;
%-Convert maxima locations from voxels to mm
%-----------------------------------------------------------------------
XYZmm = varargin{3}.M(1:3,:)*[XYZ; ones(1,size(XYZ,2))];
%-Table proper (& note all data in cell array)
%=======================================================================
%-Pagination variables
%-----------------------------------------------------------------------
hPage = [];
set(gca,'DefaultTextFontName',PF.courier,'DefaultTextFontSize',FS(7))
%-Set-level p values {c} - do not display if reporting a single cluster
%-----------------------------------------------------------------------
c = max(A); %-Number of clusters
Pc = spm_P(c,k,u,df,STAT,R,n,S); %-Set-level p-value
if c > 1;
h = text(tCol(1),y,sprintf(TabDat.fmt{1},Pc),'FontWeight','Bold',...
'UserData',Pc,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(2),y,sprintf(TabDat.fmt{2},c),'FontWeight','Bold',...
'UserData',c,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
else
set(Hc,'Visible','off')
end
TabDat.dat = {Pc,c}; %-Table data
TabLin = 1; %-Table data line
%-Local maxima p-values & statistics
%-----------------------------------------------------------------------
HlistXYZ = [];
while prod(size(find(finite(Z))))
% Paginate if necessary
%---------------------------------------------------------------
if y < min(Num+1,3)*dy
h = text(0.5,-5*dy,...
sprintf('Page %d',spm_figure('#page')),...
'FontName',PF.helvetica,'FontAngle','Italic',...
'FontSize',FS(8));
spm_figure('NewPage',[hPage,h])
hPage = [];
y = y0;
end
%-Find largest remaining local maximum
%---------------------------------------------------------------
[U,i] = max(Z); % largest maxima
j = find(A == A(i)); % maxima in cluster
%-Compute cluster {k} and voxel-level {u} p values for this cluster
%---------------------------------------------------------------
Pz = spm_P(1,0, U,df,STAT,1,n,S);% uncorrected p value
Pu = spm_P(1,0, U,df,STAT,R,n,S);% FWE-corrected {based on Z)
Qu = spm_P_FDR( U,df,STAT,n,QPs);% FDR-corrected {based on Z)
[Pk Pn] = spm_P(1,N(i),u,df,STAT,R,n,S);% [un]corrected {based on k)
Nv = N(i)/v2r; % extent {voxels}
if Pz<tol % Equivalent Z-variate
Ze = Inf; % (underflow => can't compute)
else
Ze = spm_invNcdf(1 -Pz);
end
%-Print cluster and maximum voxel-level p values {Z}
%---------------------------------------------------------------
h = text(tCol(3),y,sprintf(TabDat.fmt{3},Pk),'FontWeight','Bold',...
'UserData',Pk,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(4),y,sprintf(TabDat.fmt{4},Nv),'FontWeight','Bold',...
'UserData',Nv,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(5),y,sprintf(TabDat.fmt{5},Pn),'FontWeight','Bold',...
'UserData',Pn,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(6),y,sprintf(TabDat.fmt{6},Pu),'FontWeight','Bold',...
'UserData',Pu,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(7),y,sprintf(TabDat.fmt{7},Qu),'FontWeight','Bold',...
'UserData',Qu,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(8),y,sprintf(TabDat.fmt{8},U),'FontWeight','Bold',...
'UserData',U,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(9),y,sprintf(TabDat.fmt{9},Ze),'FontWeight','Bold',...
'UserData',Ze,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(10),y,sprintf(TabDat.fmt{10},Pz),'FontWeight','Bold',...
'UserData',Pz,'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(11),y,sprintf(TabDat.fmt{11},XYZmm(:,i)),...
'FontWeight','Bold',...
'Tag','ListXYZ',...
'ButtonDownFcn',...
'spm_mip_ui(''SetCoords'',get(gcbo,''UserData''));',...
'Interruptible','off','BusyAction','Cancel',...
'UserData',XYZmm(:,i));
HlistXYZ = [HlistXYZ, h];
if spm_XYZreg('Edist',xyzmm,XYZmm(:,i))<tol & ~isempty(hReg)
set(h,'Color','r')
end
hPage = [hPage, h];
y = y - dy;
[TabDat.dat{TabLin,3:11}] = deal(Pk,Nv,Pn,Pu,Qu,U,Ze,Pz,XYZmm(:,i));
TabLin = TabLin + 1;
%-Print Num secondary maxima (> Dis mm apart)
%---------------------------------------------------------------
[l q] = sort(-Z(j)); % sort on Z value
D = i;
for i = 1:length(q)
d = j(q(i));
if min(sqrt(sum((XYZmm(:,D)-XYZmm(:,d)*ones(1,size(D,2))).^2)))>Dis;
if length(D) < Num
% Paginate if necessary
%-----------------------------------------------
if y < dy
h = text(0.5,-5*dy,sprintf('Page %d',...
spm_figure('#page')),...
'FontName',PF.helvetica,...
'FontAngle','Italic',...
'FontSize',FS(8));
spm_figure('NewPage',[hPage,h])
hPage = [];
y = y0;
end
% voxel-level p values {Z}
%-----------------------------------------------
Pz = spm_P(1,0,Z(d),df,STAT,1,n,S);
Pu = spm_P(1,0,Z(d),df,STAT,R,n,S);
Qu = spm_P_FDR(Z(d),df,STAT,n,QPs);
if Pz<tol, Ze=Inf; else, Ze = spm_invNcdf(1 - Pz); end
h = text(tCol(6),y,sprintf(TabDat.fmt{6},Pu),...
'UserData',Pu,...
'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(7),y,sprintf(TabDat.fmt{7},Qu),...
'UserData',Qu,...
'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(8),y,sprintf(TabDat.fmt{8},Z(d)),...
'UserData',Z(d),...
'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(9),y,sprintf(TabDat.fmt{9},Ze),...
'UserData',Ze,...
'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(10),y,sprintf(TabDat.fmt{10},Pz),...
'UserData',Pz,...
'ButtonDownFcn','get(gcbo,''UserData'')');
hPage = [hPage, h];
h = text(tCol(11),y,...
sprintf(TabDat.fmt{11},XYZmm(:,d)),...
'Tag','ListXYZ',...
'ButtonDownFcn',[...
'spm_mip_ui(''SetCoords'',',...
'get(gcbo,''UserData''));'],...
'Interruptible','off','BusyAction','Cancel',...
'UserData',XYZmm(:,d));
HlistXYZ = [HlistXYZ, h];
if spm_XYZreg('Edist',xyzmm,XYZmm(:,d))<tol & ~isempty(hReg)
set(h,'Color','r')
end
hPage = [hPage, h];
D = [D d];
y = y - dy;
[TabDat.dat{TabLin,6:11}] = ...
deal(Pu,Qu,Z(d),Ze,Pz,XYZmm(:,d));
TabLin = TabLin+1;
end
end
end
Z(j) = NaN; % Set local maxima to NaN
end % end region
%-Number and register last page (if paginated)
%-----------------------------------------------------------------------
if spm_figure('#page')>1
h = text(0.5,-5*dy,sprintf('Page %d/%d',spm_figure('#page')*[1,1]),...
'FontName',PF.helvetica,'FontSize',FS(8),'FontAngle','Italic');
spm_figure('NewPage',[hPage,h])
end
%-End: Store TabDat in UserData of axes & reset pointer
%=======================================================================
h = uicontextmenu('Tag','TabDat',...
'UserData',TabDat);
set(gca,'UIContextMenu',h,...
'Visible','on',...
'XColor','w','YColor','w')
uimenu(h,'Label','Table')
uimenu(h,'Separator','on','Label','Print text table',...
'Tag','TD_TxtTab',...
'CallBack',...
'spm_list(''txtlist'',get(get(gcbo,''Parent''),''UserData''),3)',...
'Interruptible','off','BusyAction','Cancel');
uimenu(h,'Separator','off','Label','Extract table data structure',...
'Tag','TD_Xdat',...
'CallBack','get(get(gcbo,''Parent''),''UserData'')',...
'Interruptible','off','BusyAction','Cancel');
uimenu(h,'Separator','on','Label','help',...
'Tag','TD_Xdat',...
'CallBack','spm_help(''spm_list'')',...
'Interruptible','off','BusyAction','Cancel');
%-Setup registry
%-----------------------------------------------------------------------
set(hAx,'UserData',struct('hReg',hReg,'HlistXYZ',HlistXYZ))
spm_XYZreg('Add2Reg',hReg,hAx,'spm_list');
%-Return TabDat structure & reset pointer
%-----------------------------------------------------------------------
varargout = {TabDat};
spm('Pointer','Arrow')
%=======================================================================
case 'listcluster' %-List for current cluster only
%=======================================================================
% FORMAT TabDat = spm_list('listcluster',SPM,VOL,Dis,Num,Title,hReg)
spm('Pointer','Watch')
%-Parse arguments
%-----------------------------------------------------------------------
if nargin<3, error('insufficient arguments'), end
if nargin<7, hReg=[]; else, hReg = varargin{7}; end
if nargin<6, Title = '';
else, Title = varargin{6}; end
if isempty(Title), Title = ['single cluster summary',...
' (p-values corrected for entire volume)']; end
if nargin<5, Num = [];
else, Num = varargin{5}; end
if isempty(Num), Num = Inf; end
if nargin<4, Dis = [];
else, Dis = varargin{4}; end
if isempty(Dis), Dis = 04; end
VOL = varargin{3};
SPM = varargin{2};
%-if there are suprathreshold voxels, filter out all but current cluster
%-----------------------------------------------------------------------
if length(SPM.Z)
%-Jump to voxel nearest current location
[xyzmm,i] = spm_XYZreg('NearestXYZ',...
spm_results_ui('GetCoords'),SPM.XYZmm);
spm_results_ui('SetCoords',SPM.XYZmm(:,i));
%-Find selected cluster
A = spm_clusters(SPM.XYZ);
j = find(A == A(i));
SPM.Z = SPM.Z(j);
SPM.XYZ = SPM.XYZ(:,j);
SPM.XYZmm = SPM.XYZmm(:,j);
if isfield(VOL,'Rd'), VOL.Rd = VOL.Rd(:,j); end
end
%-Call 'list' functionality to produce table
%-----------------------------------------------------------------------
varargout = {spm_list('list',SPM,VOL,Dis,Num,Title,hReg)};
%=======================================================================
case 'txtlist' %-Print ASCII text table
%=======================================================================
% FORMAT spm_list('TxtList',TabDat,c)
if nargin<2, error('Insufficient arguments'), end
if nargin<3, c=1; else, c=varargin{3}; end
TabDat = varargin{2};
%-Table Title
%-----------------------------------------------------------------------
fprintf('\n\nSTATISTICS: %s\n',TabDat.tit)
fprintf('%c','='*ones(1,80)), fprintf('\n')
%-Table header
%-----------------------------------------------------------------------
fprintf('%s\t',TabDat.hdr{1,c:end-1}), fprintf('%s\n',TabDat.hdr{1,end})
fprintf('%s\t',TabDat.hdr{2,c:end-1}), fprintf('%s\n',TabDat.hdr{2,end})
fprintf('%c','-'*ones(1,80)), fprintf('\n')
%-Table data
%-----------------------------------------------------------------------
for i = 1:size(TabDat.dat,1)
for j=c:size(TabDat.dat,2)
fprintf(TabDat.fmt{j},TabDat.dat{i,j})
fprintf('\t')
end
fprintf('\n')
end
for i=1:max(1,11-size(TabDat.dat,1)), fprintf('\n'), end
fprintf('%s\n',TabDat.str)
fprintf('%c','-'*ones(1,80)), fprintf('\n')
%-Table footer
%-----------------------------------------------------------------------
fprintf('%s\n',TabDat.ftr{:})
fprintf('%c','='*ones(1,80)), fprintf('\n\n')
%=======================================================================
case 'setcoords' %-Co-ordinate change
%=======================================================================
% FORMAT spm_list('SetCoords',xyz,hAx,hReg)
if nargin<3, error('Insufficient arguments'), end
hAx = varargin{3};
xyz = varargin{2};
UD = get(hAx,'UserData');
HlistXYZ = UD.HlistXYZ(ishandle(UD.HlistXYZ));
%-Set all co-ord strings to black
%-----------------------------------------------------------------------
set(HlistXYZ,'Color','k')
%-If co-ord matches a string, highlight it in red
%-----------------------------------------------------------------------
XYZ = get(HlistXYZ,'UserData');
if iscell(XYZ), XYZ = cat(2,XYZ{:}); end
[null,i,d] = spm_XYZreg('NearestXYZ',xyz,XYZ);
if d<eps
set(HlistXYZ(i),'Color','r')
end
%=======================================================================
otherwise %-Unknown action string
%=======================================================================
error('Unknown action string')
%=======================================================================
end
%=======================================================================