JiscMail Logo
Email discussion lists for the UK Education and Research communities

Help for SPM Archives


SPM Archives

SPM Archives


SPM@JISCMAIL.AC.UK


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

SPM Home

SPM Home

SPM  January 2019

SPM January 2019

Options

Subscribe or Unsubscribe

Subscribe or Unsubscribe

Log In

Log In

Get Password

Get Password

Subject:

Re: CAT12 extract surface values from significant cluster / "display surface results" error

From:

Christian Gaser <[log in to unmask]>

Reply-To:

Christian Gaser <[log in to unmask]>

Date:

Fri, 4 Jan 2019 17:30:46 +0100

Content-Type:

multipart/mixed

Parts/Attachments:

Parts/Attachments

text/plain (142 lines) , cat_surf_results.m (2443 lines)

Dear Cameron,

On 3 Jan 2019, at 5:13, Cameron McKay wrote:

> Hi Christian,
>
> Thank you! That fix seems to work, but only for surface data that have 
> been
> resampled to the 164k mesh. Data resampled to the 32k mesh still give 
> me
> that error.

Probably you have not used the „Estimate Surface Models“ function in 
CAT12 but the default „Estimate“ in SPM12. This will cause some 
issues (i.e. the underlying surface in the result section is the first 
surface and not the Freesurfer average surface) and will prevent that 
32k meshes are correctly recognized. Anyway, I have changed the 
recognition of 32k meshes which should work now for all cases 
(hopefully).

>
> Once I've loaded in the surface results, I noticed I'm not able to 
> access
> the dropdown "Threshold..." menu because it is grayed out. 
> Additionally,
> when I select "Plot mean data inside cluster" from the "Data 
> Cursor..."
> menu, it isn't always clear what cluster is being used (potentially 
> because
> I am not able to adjust the thresholding). For example, the hover text 
> that
> appears next to the data cursor tends to treat the left and right
> hemispheres as the only two clusters and the values returned for my
> contrasts include negative numbers.
The tool isn’t really useful for SPM maps without any threshold. If 
you have used the results of the TFCE-toolbox or you have converted your 
SPM maps to log-P maps this will result in log-scaled maps with p-values 
that can be easily thresholded. In that case the threshold menu is 
enabled. However, you can also use your SPM maps that were thresholded 
using the Results function in SPM12.
>
> Do those numbers represent actual thickness values from each subject, 
> beta
> weights from my model, or something else? The numbers I'm most 
> interested
> in are the actual thickness values for each subject. Additionally, 
> what are
> the differences between the "predicted" and "adjusted" values 
> outputted
> here?
The tool provided the same functionality for plotting predicted (using 
the model estimates + error) and adjusted (estimated values with 
correction for nuisance parameters + error). However, the so-called 
(contrast) estimates were always corrected for mean and other effects. 
Thus, I have now added an option for plotting raw values from the 
resampled surfaces without any corrections. Please try the attached 
code.

Best,

Christian


Christian Gaser, Ph.D.
Professor of Computational Neuroscience/Neuroimaging
Biomagnetic Center
Structural Brain Mapping Group
Department of Neurology
Jena University Hospital
Am Klinikum 1, D-07747 Jena, Germany
Tel: ++49-3641-9325778 Fax:   ++49-3641-9325772
e-mail: [log in to unmask]
http://www.neuro.uni-jena.de

>
> Thanks for your help!
> Cameron
>
> On Wed, Jan 2, 2019 at 4:37 AM Christian Gaser 
> <[log in to unmask]>
> wrote:
>
>> Hi Cameron,
>>
>> you can try the newest version of cat_surf_results that is attached.
>>
>> Please check that your surface files are resampled using the same 
>> (and
>> hopefully not too old) version of cat_surf_resamp.m if the attached
>> function is still causing the same error.
>>
>> Best,
>>
>> Christian
>>
>> On Tue, 1 Jan 2019 14:15:55 -0500, Cameron McKay 
>> <[log in to unmask]>
>> wrote:
>>
>>> Hi,
>>>
>>> I'm trying to extract cortical thickness values from a significant 
>>> cluster
>>> from between-group F- and t-contrasts in CAT12 (with the latest 
>>> version of
>>> SPM12). I'd like use mean cortical thickness within that cluster 
>>> from each
>>> subject to perform some additional analyses. I tried following the 
>>> steps
>>> used in the previous thread linked below, but got an error message 
>>> when
>>> loading in the spmF and spmT contrasts.
>>>
>>>
>> https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1802&L=spm&F=&S=&P=378788
>>>
>>> My error when using "Display Surface Results" was:
>>>
>>> Index in position 1 exceeds array bounds (must not exceed 64984).
>>>> Error in cat_surf_results (line 395)
>>>>                                 H.S{1}.Y = Y(1:163842, :);
>>>> Error in cat_surf_results>select_data (line 1633)
>>>> cat_surf_results('disp', H.S{1}.name, H.S{2}.name);
>>>>
>>>> Error while evaluating DestroyedObject Callback.
>>>
>>>
>>> I checked in debug mode and noticed that Y is a 64984x1 double at 
>>> line 395
>>> of cat_surf_results, so I'm not sure why I'm getting this error. 
>>> Hopefully
>>> Christian or someone else has some insight into this!
>>>
>>> Thanks in advance!
>>> Cameron
>>>
>>
>>





function y = cat_surf_results(action, varargin) % Visualise results for both hemispheres of surface-based analysis (preferable on log P-maps) % % FORMAT y = cat_surf_results('Disp',leftSurface,rightSurface) % leftSurface - a GIfTI filename/object or patch structure % rightSurface - a GIfTI filename/object or patch structure % % y - adjusted, predicted or raw response %_______________________________________________________________________ % Christian Gaser % $Id: cat_surf_results.m 1408 2018-12-20 15:05:05Z gaser $ global H % remove any existing data if isfield(H,'S')     H = rmfield(H,'S'); end %-Input parameters %-------------------------------------------------------------------------- if ~nargin, action = 'Disp'; end if ~ischar(action)     varargin = {action varargin{:}};     action = 'Disp'; end % set start values y = []; H.clip = []; H.clim = []; H.XTick = []; H.bkg_col = [0 0 0]; H.show_inv = 0; H.no_neg = 0; H.transp = 1; H.Col = [0 0 0; .8 .8 .8; 1 .5 .5]; H.FS = spm('FontSizes'); H.n_surf = 1; H.thresh_value = 0; H.cursor_mode = 1; H.text_mode = 1; H.border_mode = 0; H.is32k = 0; H.str32k = ''; H.SPM_found = 1; %-Action %-------------------------------------------------------------------------- switch lower(action)          %-Display     %======================================================================     case 'disp'                  % positions         ws = spm('Winsize', 'Graphics');         ss = get(0, 'Screensize');         if 2.6 * ws(3) > ss(3)             ws(3) = ws(3) / (2.6 * ws(3) / ss(3));         end                  % result window with 5 surface views and alternative positions without top view and only with lateral views         H.viewpos = {[0.025 0.450 0.375 0.375; 0.025 0.450 0.375 0.375; 0.025 2.000 0.375 0.375],... % lh medial                      [0.025 0.025 0.375 0.375; 0.025 0.025 0.375 0.375; 0.175 0.350 0.175 0.350],... % lh lateral                      [0.600 0.450 0.375 0.375; 0.600 0.450 0.375 0.375; 0.600 2.000 0.375 0.375],... % rh medial                      [0.600 0.025 0.375 0.375; 0.600 0.025 0.375 0.375; 0.675 0.350 0.175 0.350],... % rh lateral                      [0.300 0.150 0.400 0.500; 0.300 2.000 0.400 0.500; 0.300 2.000 0.400 0.500],... % lh+rh top                      [0.400 0.750 0.200 0.225; 0.400 0.300 0.200 0.225; 0.400 0.750 0.200 0.225]}; % data plot                  % change size and position of flatmaps for >= R20014b         if spm_check_version('matlab', '8.4') >= 0             H.viewpos{2}(3, :) = [-0.075 0.150 0.650 0.650]; % lh lateral             H.viewpos{4}(3, :) = [0.425 0.150 0.650 0.650]; % rh lateral         end                  % figure 1 with result window         H.pos{1} = struct( ...             'fig', [10 10 2 * ws(3) ws(3)], ... % figure             'cbar', [0.400 -0.180 0.200 0.300; 0.440 0.025 0.120 0.120]);% colorbar                  % figure 2 with GUI         H.pos{2} = struct(...           'fig', [2*ws(3)+10 10 0.6*ws(3) ws(3)],...           'sel', [0.290 0.930 0.425 0.050],...           'nam', [0.050 0.875 0.900 0.050],...           'surf', [0.050 0.800 0.425 0.050],'mview', [0.525 0.800 0.425 0.050],...           'text', [0.050 0.725 0.425 0.050],'thresh', [0.525 0.725 0.425 0.050],...           'cmap', [0.050 0.650 0.425 0.050],'atlas', [0.525 0.650 0.425 0.050],...           'cursor',[0.050 0.575 0.425 0.050],'border', [0.525 0.575 0.425 0.050],...           'info', [0.050 0.500 0.425 0.050],'bkg', [0.525 0.500 0.425 0.050],...           'nocbar',[0.050 0.425 0.425 0.050],'transp', [0.525 0.425 0.425 0.050],...           'inv', [0.050 0.350 0.425 0.050],'hide_neg',[0.525 0.350 0.425 0.050],...           'ovmin', [0.050 0.175 0.425 0.070],'ovmax', [0.525 0.175 0.425 0.070],...           'save', [0.050 0.050 0.425 0.050],'close', [0.525 0.050 0.425 0.050]);                  % create figures 1+2         for i = 1:2             H.figure(i) = figure(i + 11);             clf(H.figure(i));                          set(H.figure(i), 'MenuBar', 'none', 'Position', H.pos{i}.fig, ...                 'Name', 'Results', 'NumberTitle', 'off', 'Renderer', 'OpenGL');         end                  % define S structure that contains information for lh and rh         H.S{1}.name = ''; H.S{1}.side = 'lh';         H.S{2}.name = ''; H.S{2}.side = 'rh';                  % closing all windows         H.close = uicontrol(H.figure(2), ...             'string', 'Close', 'Units', 'normalized', ...             'position', H.pos{2}.close, ...             'style', 'Pushbutton', 'HorizontalAlignment', 'center', ...             'callback', 'for i=2:26, try close(i); end; end;', ...             'ToolTipString', 'Close windows', ...             'Interruptible', 'on', 'Enable', 'on');                  % select results for lh and rh         H.sel = uicontrol(H.figure(2), ...             'string', 'Select Surface Data', 'Units', 'normalized', ...             'position', H.pos{2}.sel, ...             'style', 'Pushbutton', 'HorizontalAlignment', 'center', ...             'callback', @select_data, ...             'ToolTipString', 'Select results (up to 24) for both hemispheres (e.g. log-p maps)', ...             'Interruptible', 'on', 'Enable', 'on');                  str = {'Surface...', 'Central', 'Inflated', 'Dartel', 'Flatmap'};         tmp = {{@select_surf, 1}, ...                {@select_surf, 2}, ...                {@select_surf, 3}, ...                {@select_surf, 4}};                  % underlying surface         H.surf = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.surf, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Underlying Surface', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Threshold...', 'No threshold', 'P<0.05', 'P<0.01', 'P<0.001'};         tmp = {{@select_thresh, 0}, ...                {@select_thresh, 1.3}, ...                {@select_thresh, 2}, ...                {@select_thresh, 3}};                  % threshold         H.thresh = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.thresh, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Threshold', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Colormap...', 'jet', 'hot', 'hsv', 'cold-hot'};         tmp = {{@select_cmap, 1}, ...                {@select_cmap, 2}, ...                {@select_cmap, 3}, ...                {@select_cmap, 4}};                  % colormap         H.cmap = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.cmap, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Threshold', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Atlas Labeling...', 'Desikan-Killiany DK40', 'Destrieux 2009', 'HCP Multi-Modal Parcellation'};         tmp = {{@select_atlas, 1}, ...                {@select_atlas, 2}, ...                {@select_atlas, 3}};                  % atlas for labeling         H.atlas = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.atlas, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Atlas Labeling', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Data Cursor...', 'Disable data cursor', 'Atlas regions: Desikan-Killiany DK40', ...             'Atlas regions: Destrieux 2009', 'Atlas region: HCP Multi-Modal Parcellation', ...             'Plot data at vertex', ...             'Plot mean data inside cluster', 'Enable/Disable rotate3d'};         tmp = {{@select_cursor, 0}, ...                {@select_cursor, 1}, ...                {@select_cursor, 2}, ...                {@select_cursor, 3}, ...                {@select_cursor, 4}, ...                {@select_cursor, 5}, ...                {@select_cursor, 6}};                  % data cursor for data plotting and atlas names         H.cursor = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.cursor, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Data Cursor Mode', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'View...', 'Show top view', 'Show bottom view', 'Show only lateral and medial views'};         tmp = {{@select_view, 1}, ...                {@select_view, -1}, ...                {@select_view, 2}};                  % view         H.mview = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.mview, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Select View', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Texture...', 'Mean curvature', 'Sulcal depth'};         tmp = {{@select_texture, 1}, ...                {@select_texture, 2}};                  % underlying texture         H.text = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.text, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Select Underlying Texture', ...             'Interruptible', 'on', 'Enable', 'off');                  str = {'Atlas Border Overlay...', 'No Overlay', 'Desikan-Killiany DK40', 'Destrieux 2009', ...                'HCP Multi-Modal Parcellation'};         tmp = {{@select_border, 0}, ...                {@select_border, 1}, ...                {@select_border, 2}, ...                {@select_border, 3}};                  % atlas for border overlay         H.border = uicontrol(H.figure(2), ...             'string', str, 'Units', 'normalized', ...             'position', H.pos{2}.border, 'UserData', tmp, ...             'style', 'PopUp', 'HorizontalAlignment', 'center', ...             'callback', 'spm(''PopUpCB'',gcbo)', ...             'ToolTipString', 'Atlas Border Overlay', ...             'Interruptible', 'on', 'Enable', 'off');                  % invert results         H.inv = uicontrol(H.figure(2), ...             'string', 'Invert colormap', 'Units', 'normalized', ...             'position', H.pos{2}.inv, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_inv}, ...             'ToolTipString', 'Invert results', ...             'Interruptible', 'on', 'Enable', 'off');                  % show only results for pos. contrast         H.hide_neg = uicontrol(H.figure(2), ...             'string', 'Hide neg. results', 'Units', 'normalized', ...             'position', H.pos{2}.hide_neg, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_hide_neg}, ...             'ToolTipString', 'Hide neg. results', ...             'Interruptible', 'on', 'Enable', 'off');                  % white background         H.bkg = uicontrol(H.figure(2), ...             'string', 'White background', 'Units', 'normalized', ...             'position', H.pos{2}.bkg, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_bkg}, ...             'ToolTipString', 'White background', ...             'Interruptible', 'on', 'Enable', 'off');                  % transparent view         H.transp = uicontrol(H.figure(2), ...             'string', 'Disable transparency', 'Units', 'normalized', ...             'position', H.pos{2}.transp, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_transp}, ...             'ToolTipString', 'Disable transparent overlay', ...             'Interruptible', 'on', 'Enable', 'off');                  H.info = uicontrol(H.figure(2), ...             'string', 'Show filename', 'Units', 'normalized', ...             'position', H.pos{2}.info, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_info}, ...             'ToolTipString', 'Show file information in image', ...             'Interruptible', 'on', 'Enable', 'off');                  H.nocbar = uicontrol(H.figure(2), ...             'string', 'Hide colorbar', 'Units', 'normalized', ...             'position', H.pos{2}.nocbar, ...             'style', 'CheckBox', 'HorizontalAlignment', 'center', ...             'callback', {@checkbox_nocbar}, ...             'ToolTipString', 'Hide colorbar', ...             'Interruptible', 'on', 'Enable', 'off');                  H.save = uicontrol(H.figure(2), ...             'string', 'Save', 'Units', 'normalized', ...             'position', H.pos{2}.save, ...             'style', 'Pushbutton', 'HorizontalAlignment', 'center', ...             'callback', {@save_image}, ...             'ToolTipString', 'Save png image', ...             'Interruptible', 'on', 'Enable', 'off');                  if nargin >= 3                          H.S{1}.name = varargin{1};             H.S{2}.name = varargin{2};                          [pth{1}, nm1, ext1] = spm_fileparts(H.S{1}.name(1, :));             [pth{2}, nm2, ext2] = spm_fileparts(H.S{2}.name(1, :));                          % SPM.mat found for both hemispheres (not working yet)             if strcmp([nm1 ext1], 'SPM.mat') || strcmp([nm2 ext2], 'SPM.mat')                 H.logP = 0;                                  if strcmp([nm1 ext1], 'SPM.mat')                     ind = 1;                 else ind = 2; end                                  swd1 = pwd;                 spm_figure('GetWin', 'Interactive');                 cd(pth{ind})                 xSPM.swd = pwd;                 [xSPM, v] = spm_getSPM(xSPM);                 cd(swd1);                                  dat = struct('XYZ', v.XYZ, ...                     't', v.Z', ...                     'mat', v.M, ...                     'dim', v.DIM, ...                     'dat', v.Z');                                  H.S{ind}.info = cat_surf_info(H.S{ind}.name, 0);                 g = gifti(H.S{ind}.info.Pmesh);                                  mat = v.M;                 V = g.vertices;                 XYZ = double(inv(mat) * [V'; ones(1, size(V, 1))]);                 H.S{ind}.Y = spm_sample_vol(Y, XYZ(1, :), XYZ(2, :), XYZ(3, :), 0)';                 H.S{ind}.Y = spm_mesh_project(g.vertices, dat)';             else                                  H.logP = 1;                 meshes_merged = 0;                                  for ind = 1:2                                          % read meshes                     H.S{ind}.info = cat_surf_info(H.S{ind}.name, 1);                                          if H.S{ind}.info(1).nvertices == 64984                         H.str32k = '_32k';                         H.is32k = 1;                     else                         H.str32k = '';                         H.is32k = 0;                     end                     if strcmp(H.S{ind}.info(1).side, 'mesh')                         meshes_merged = 1;                         if ind == 1                             H.S{ind}.info(1).side = 'lh';                             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ...                                 ['templates_surfaces' H.str32k], 'lh.central.freesurfer.gii');                         else                             H.S{ind}.info(1).side = 'rh';                             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ....                                 ['templates_surfaces' H.str32k], 'rh.central.freesurfer.gii');                         end                     end                     H.S{ind}.M = gifti(H.S{ind}.info(1).Pmesh);                                          % get adjacency information                     H.S{ind}.A = spm_mesh_adjacency(H.S{ind}.M);                                          % cdata found?                     if meshes_merged                         if ind == 1                             try                                 Y = spm_data_read(spm_data_hdr_read(H.S{ind}.name));                             catch                                 error('No data in surfaces found.');                             end                             if H.is32k                                 H.S{1}.Y = Y(1:32492, :);                                 H.S{2}.Y = Y(32493:end, :);                             else                                 H.S{1}.Y = Y(1:163842, :);                                 H.S{2}.Y = Y(163843:end, :);                             end                         end                     else                         gind = gifti(H.S{ind}.name);                         if isfield(gind,'cdata')                             H.S{ind}.Y = spm_data_read(spm_data_hdr_read(H.S{ind}.name));                         else                             if ind == 1                                 gind = gifti(H.S{2}.name);                                 if isfield(gind,'cdata')                                     if isnumeric(gind.cdata)                                         H.S{1}.Y = zeros(size(gind.cdata));                                     else                                         H.S{1}.Y = zeros(gind.cdata.dim);                                     end                                     H.S{1}.name = '';                                 else                                     error('No data in surfaces found.');                                 end                             else                                 gind = gifti(H.S{1}.name);                                 if isfield(gind,'cdata')                                     if isnumeric(gind.cdata)                                         H.S{2}.Y = zeros(size(gind.cdata));                                     else                                         H.S{2}.Y = zeros(gind.cdata.dim);                                     end                                     H.S{2}.name = '';                                 else                                     error('No data in surfaces found.');                                 end                             end                         end                     end                                                            % check whether name contains 'log' that indicates a logP file                     for i = 1:size(H.S{ind}.name, 1)                         if isempty(strfind(H.S{ind}.info(i).ff, 'log'))                             H.logP = 0;                         end                     end                 end             end                          % rescue original name for later result selection             H.S1 = H.S{1};             H.S2 = H.S{2};                          H.n_surf = max(numel(H.S{1}.info), numel(H.S{2}.info));             H.view = 1;             H.show_transp = 1;             H.disable_cbar = 0;             H.white_bgk = 0;             H.show_info = 0;                          % result selection or RGB overlay if more than one result was loaded             if H.n_surf > 1                 % pre-select 1st mesh if we cannot use RGB overlay                 %if H.n_surf > 3                 if 1                     sel = 1;                     if isempty(H.S1.name)                         error('Do not mix meshes with different resolutions (i.e. 164k vs. 32k)');                     end                     H.S{1}.name = H.S1.name(sel, :);                     H.S{2}.name = H.S2.name(sel, :);                     H.S{1}.Y = H.S1.Y(:, sel);                     H.S{2}.Y = H.S2.Y(:, sel);                 end                                  % delete old selection ui                 delete(H.sel);                 H = rmfield(H, 'sel');                                  str = cell(1, H.n_surf + 2);                 tmp = cell(1, H.n_surf + 1);                 str{1} = ('Select Result...');                 for s = 1:H.n_surf                     str{s + 1} = H.S1.name(s, :);                     tmp{s} = {@select_results, s};                 end                                  % print selected filename                 H.nam = axes('Parent', H.figure(2), 'Position', H.pos{2}.nam);                 cla(H.nam);                 axis(H.nam, 'off')                 text(0.5, 0.5, spm_str_manip(H.S{1}.name, 'k60d'), 'Parent', H.nam, 'Interpreter', 'none', ...                     'FontSize', H.FS(7), 'HorizontalAlignment', 'center');                                  % set # of surfaces back to "1" if we cannot use RGB overlay                 if 1, H.n_surf = 1; end                 %if H.n_surf > 3, H.n_surf = 1; end                                  % new selection ui                 str{s + 2} = 'Select new data';                 tmp{s + 1} = {@select_data};                 H.sel = uicontrol(H.figure(2), ...                     'string', str, 'Units', 'normalized', ...                     'position', H.pos{2}.sel, 'UserData', tmp, ...                     'style', 'Popup', 'HorizontalAlignment', 'center', ...                     'callback', 'spm(''PopUpCB'',gcbo)', ...                     'ToolTipString', 'Select results', ...                     'Interruptible', 'on', 'Enable', 'on');             end                          display_results_all;                          H.SPM_found = 1;             for i = 1:2                 SPM_name = fullfile(H.S{i}.info(1).pp, 'SPM.mat');                                  % SPM.mat exist?                 if ~isempty(H.S{i}.name)                     H.SPM_found = 0;                 end             end             % Don't allow plot functions for RGB maps or if SPM.mat was not found             if H.n_surf > 1 & H.SPM_found                 str = {'Data Cursor...', 'Disable data cursor', 'Atlas regions: Desikan-Killiany DK40', ...                     'Atlas regions: Destrieux 2009', 'Atlas region: HCP Multi-Modal Parcellation', ...                     'Enable/Disable rotate3d'};                 tmp = {{@select_cursor, 0}, ...                        {@select_cursor, 1}, ...                        {@select_cursor, 2}, ...                        {@select_cursor, 3}, ...                        {@select_cursor, 5}};                                  H.cursor = uicontrol(H.figure(2), ...                     'string', str, 'Units', 'normalized', ...                     'position', H.pos{2}.cursor, 'UserData', tmp, ...                     'style', 'PopUp', 'HorizontalAlignment', 'center', ...                     'callback', 'spm(''PopUpCB'',gcbo)', ...                     'ToolTipString', 'Data Cursor Mode', ...                     'Interruptible', 'on', 'Enable', 'off');             end                          % enable some menus only if mesh data can be assumed to be resampled             if (length(H.S{1}.Y) == 32492 | length(H.S{1}.Y) == 163842)                 set(H.surf, 'Enable', 'on');                 set(H.text, 'Enable', 'on');                 set(H.cursor, 'Enable', 'on');                 set(H.border, 'Enable', 'on');             end                          set(H.save, 'Enable', 'on');             set(H.mview, 'Enable', 'on');             set(H.nocbar, 'Enable', 'on');             set(H.bkg, 'Enable', 'on');             set(H.transp, 'Enable', 'on');             set(H.info, 'Enable', 'on');                          if min(min(H.S{1}.Y(:)), min(H.S{2}.Y(:))) < 0 & H.n_surf == 1                 set(H.inv, 'Enable', 'on');                 set(H.hide_neg, 'Enable', 'on');                 set(H.hide_neg, 'Value', 0);             end                          if H.n_surf == 1                 set(H.cmap, 'Enable', 'on');             end                          H.rdata{1} = [];             H.rdata{2} = [];             H.rdata{3} = [];             for ind = 1:2                 atlas_name = fullfile(spm('dir'), 'toolbox', 'cat12', ['atlases_surfaces' H.str32k], ...                 [H.S{ind}.info(1).side '.aparc_DK40.freesurfer.annot']);                 [vertices, rdata0, colortable, rcsv1] = cat_io_FreeSurfer('read_annotation', atlas_name);                 H.rdata{1} = [H.rdata{1} rdata0];                 atlas_name = fullfile(spm('dir'), 'toolbox', 'cat12', ['atlases_surfaces' H.str32k], ...                 [H.S{ind}.info(1).side '.aparc_a2009s.freesurfer.annot']);                 [vertices, rdata0, colortable, rcsv2] = cat_io_FreeSurfer('read_annotation', atlas_name);                 H.rdata{2} = [H.rdata{2} rdata0];                 atlas_name = fullfile(spm('dir'), 'toolbox', 'cat12', ['atlases_surfaces' H.str32k], ...                 [H.S{ind}.info(1).side '.aparc_HCP_MMP1.freesurfer.annot']);                 [vertices, rdata0, colortable, rcsv3] = cat_io_FreeSurfer('read_annotation', atlas_name);                 H.rdata{3} = [H.rdata{3} rdata0];             end             H.rcsv{1} = rcsv1;             H.rcsv{2} = rcsv2;             H.rcsv{3} = rcsv3;                          H.dcm_obj = datacursormode(H.figure(1));             set(H.dcm_obj, 'Enable', 'on', 'SnapToDataVertex', 'on', ...                 'DisplayStyle', 'datatip', 'Updatefcn', {@myDataCursorAtlas, H});             figure(H.figure(2))                      end                  %-ColourBar         %======================================================================     case {'colourbar', 'colorbar'}         if isempty(varargin), varargin{1} = gca; end         if length(varargin) == 1, varargin{2} = 'on'; end         H = getHandles(varargin{1});         d = getappdata(H.patch(1), 'data');         col = getappdata(H.patch(1), 'colourmap');         if strcmpi(varargin{2}, 'off')             if isfield(H, 'colourbar') & ishandle(H.colourbar)                 delete(H.colourbar);                 H = rmfield(H, 'colourbar');                 setappdata(H.axis, 'handles', H);             end             return;         end         if isempty(d) || ~any(d(:)), varargout = {H}; return; end         if isempty(col), col = jet(256); end         if ~isfield(H, 'colourbar') || ~ishandle(H.colourbar)             % H.colourbar = colorbar('peer',gca,'NorthOutside');             H.colourbar = colorbar('NorthOutside');             set(H.colourbar, 'Tag', '');             set(get(H.colourbar, 'Children'), 'Tag', '');         end         c(1:size(col, 1), 1, 1:size(col, 2)) = col;         ic = findobj(H.colourbar, 'Type', 'image');         clim = getappdata(H.patch(1), 'clim');         if isempty(clim), clim = [false NaN NaN]; end                  if size(d, 1) > size(d, 2), d = d'; end                  % Update colorbar colors if clipping is used         H.clip = getappdata(H.patch(1), 'clip');         if ~isempty(H.clip)             if ~isnan(H.clip(2)) & ~isnan(H.clip(3))                 ncol = length(col);                 col_step = (clim(3) - clim(2)) / ncol;                 cmin = max([1, ceil((H.clip(2) - clim(2)) / col_step)]);                 cmax = min([ncol, floor((H.clip(3) - clim(2)) / col_step)]);                 col(cmin:cmax, :) = repmat([0.5 0.5 0.5], (cmax - cmin + 1), 1);                 c(1:size(col, 1), 1, 1:size(col, 2)) = col;             end         end         if H.n_surf > 1             set(ic, 'CData', c(1:H.n_surf, :, :));             set(ic, 'YData', [1 H.n_surf]);             set(H.colourbar, 'YLim', [1 H.n_surf]);             set(H.colourbar, 'YTickLabel', []);         else             set(ic, 'CData', c);             clim = getappdata(H.patch(1), 'clim');             if isempty(clim), clim = [false min(d) max(d)]; end             set(ic, 'YData', clim(2:3));             set(H.colourbar, 'YLim', clim(2:3));         end         setappdata(H.axis, 'handles', H);                  %-ColourMap         %======================================================================     case {'colourmap', 'colormap'}         if isempty(varargin), varargin{1} = gca; end         H = getHandles(varargin{1});         if length(varargin) == 1             varargout = {getappdata(H.patch(1), 'colourmap')};             return;         else             setappdata(H.patch(1), 'colourmap', varargin{2});             d = getappdata(H.patch(1), 'data');             H = updateTexture(H, d);         end         if nargin > 1             colormap(varargin{2});         end                  %-CLim         %======================================================================     case 'clim'         if isempty(varargin), varargin{1} = gca; end         H = getHandles(varargin{1});         if length(varargin) == 1             c = getappdata(H.patch, 'clim');             if ~isempty(c), c = c(2:3); end             varargout = {c};             return;         else             if strcmp(varargin{2}, 'on') || isempty(varargin{2}) || any(~isfinite(varargin{2}))                 setappdata(H.patch, 'clim', [false NaN NaN]);             else                 setappdata(H.patch, 'clim', [true varargin{2}]);             end             d = getappdata(H.patch, 'data');             H = updateTexture(H, d);                      end                  if nargin > 1 & isnumeric(varargin{2}) & numel(varargin{2}) == 2             caxis(H.axis, varargin{2});         else             caxis(H.axis, [min(d), max(d)])         end                  %-CLip         %======================================================================     case 'clip'         if isempty(varargin), varargin{1} = gca; end         H = getHandles(varargin{1});         if length(varargin) == 1             c = getappdata(H.patch, 'clip');             if ~isempty(c), c = c(2:3); end             varargout = {c};             return;         else             if isempty(varargin{2}) || any(~isfinite(varargin{2}))                 for ind = 1:5                     setappdata(H.patch(ind), 'clip', [false NaN NaN]);                 end             else                 for ind = 1:5                     setappdata(H.patch(ind), 'clip', [true varargin{2}]);                 end             end             for ind = 1:5                 d = getappdata(H.patch, 'data');                 H = updateTexture(H, ind, d);             end         end end %----------------------------------------------------------------------- function H = select_thresh(thresh) %----------------------------------------------------------------------- global H H.thresh_value = thresh; H.clip = [true -thresh thresh]; H.no_neg = get(H.hide_neg, 'Value'); % get min value for both hemispheres min_d = min(min(min(getappdata(H.patch(1), 'data'))), min(min(getappdata(H.patch(3), 'data')))); clim = getappdata(H.patch(1), 'clim'); % rather use NaN values for zero threshold if thresh == 0     H.clip = [false NaN NaN]; end if H.no_neg     H.clip = [true -Inf thresh];     clim = [true 0 clim(3)];     set(H.slider_min, 'Value', 0); end for ind = 1:5     % correct lower clim to "0" if no values are exceeding threshold     if min_d > -thresh         setappdata(H.patch(ind), 'clim', [true 0 clim(3)]);     elseif thresh == 0         setappdata(H.patch(ind), 'clim', [true -clim(3) clim(3)]);     end          setappdata(H.patch(ind), 'clip', H.clip);     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     min_d = min(min_d, min(d(:)));     H = updateTexture(H, ind, d, col, H.show_transp); end % correct value of slider if no values are exceeding threshold if min_d > -thresh & H.n_surf == 1     set(H.slider_min, 'Value', 0); end set(H.atlas, 'Enable', 'on'); if ~H.disable_cbar     H = show_colorbar(H); end %----------------------------------------------------------------------- function H = select_cmap(cmap) %----------------------------------------------------------------------- global H switch cmap     case 1         col = jet(256);     case 2         col = hot(256);     case 3         col = hsv(256);     case 4         col = [1 - hot(128); (hot(128))]; end for ind = 1:5     setappdata(H.patch(ind), 'col', col);     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end if ~H.disable_cbar     H = show_colorbar(H); end %----------------------------------------------------------------------- function H = select_atlas(atlas) %----------------------------------------------------------------------- global H % get threshold from clipping thresh = [0 0]; if ~isempty(H.clip)     if ~isnan(H.clip(2)) & ~isnan(H.clip(3))         thresh = [H.clip(2:3)];     end end % atlas name if atlas == 1     atlas_name = 'Desikan-Killiany DK40 Atlas'; elseif atlas == 2     atlas_name = 'Destrieux 2009 Atlas'; elseif atlas == 3     atlas_name = 'HCP Multi-Modal Parcellation'; end % go through left and right hemisphere for ind = [1 3]          % atlas data     rcsv = H.rcsv{atlas};     rdata = H.rdata{atlas}(:, round(ind / 2));          A = H.S{round(ind / 2)}.A;     A = A + speye(size(A));     d0 = getappdata(H.patch(ind), 'data');          % go through all surfaces     for indsurf = 1:H.n_surf         d = d0(indsurf, :);                  % apply thresholds         dp = d >= thresh(2); indp = find(dp);         dn = d <= thresh(1); indn = find(dn);                  % go through pos. effects         if ~isempty(indp)                          C = find_connected_component(A, dp);             C = C(indp);             rdata2 = rdata(indp);                          fprintf('\n\n______________________________________________________\n');             fprintf('%s: Positive effects in %s', atlas_name, H.S{round(ind / 2)}.info(1).side);             fprintf('\n%s', spm_str_manip(H.S{round(ind / 2)}.info(indsurf).fname, 'k50d'));             fprintf('\n______________________________________________________\n\n');                          if H.logP, fprintf('%7s\t%8s\t%s\n', 'P-value', 'Size', 'Overlap of atlas region');             else, fprintf('%7s\t%8s\t%s\n', 'Value ', 'Size', 'Overlap of atlas region'); end                          for i = 1:max(C)                 N = find(C == i);                 k = length(N);                                  dmax = d(indp); dmax = max(dmax(N));                                  if H.logP, fprintf('\n%1.5f\t%8d', 10^(-dmax), k);                 else, fprintf('\n%6.1f\t%8d', dmax, k); end                                  Nrdata = rdata2(N);                 roi_size = zeros(size(rcsv, 1) - 1, 1);                                  for j = 2:size(rcsv, 1)                     ind3 = find(Nrdata == rcsv{j, 1});                     roi_size(j - 1) = 100 * length(ind3) / k;                 end                                  % sort wrt size                 [ii, jj] = sort(roi_size, 'descend');                 jj(ii == 0) = [];                                  for j = 1:length(jj)                     if roi_size(jj(j)) > 1                         if j == 1, fprintf('\t%3.0f%s\t%s\n', roi_size(jj(j)), '%', rcsv{jj(j) + 1, 2});                         else, fprintf('%7s\t%8s\t%3.0f%s\t%s\n', ' ', ' ', ...                                 roi_size(jj(j)), '%', rcsv{jj(j) + 1, 2});                         end                     end                 end             end         end                  % go through neg. effects         if ~isempty(indn)                          C = find_connected_component(A, dn);             C = C(indn);             rdata2 = rdata(indn);                          fprintf('\n\n______________________________________________________\n');             fprintf('%s: Negative effects in %s', atlas_name, H.S{round(ind / 2)}.info(1).side);             fprintf('\n%s', spm_str_manip(H.S{round(ind / 2)}.info(indsurf).fname, 'k50d'));             fprintf('\n______________________________________________________\n\n');                          if H.logP, fprintf('%7s\t%8s\t%s\n', 'P-value', 'Size', 'Overlap of atlas region');             else, fprintf('%7s\t%8s\t%s\n', 'Value ', 'Size', 'Overlap of atlas region'); end                          for i = 1:max(C)                 N = find(C == i);                 k = length(N);                                  dmin = d(indn); dmin = min(dmin(N));                 if H.logP, fprintf('\n%1.5f\t%8d', 10^(dmin), k);                 else, fprintf('\n%6.1f\t%8d', -dmin, k); end                                  Nrdata = rdata2(N);                 roi_size = zeros(size(rcsv, 1) - 1, 1);                 for j = 2:size(rcsv, 1)                     ind3 = find(Nrdata == rcsv{j, 1});                     roi_size(j - 1) = 100 * length(ind3) / k;                 end                                  % sort wrt size                 [ii, jj] = sort(roi_size, 'descend');                 jj(ii == 0) = [];                                  for j = 1:length(jj)                     if roi_size(jj(j)) > 1                         if j == 1, fprintf('\t%3.0f%s\t%s\n', roi_size(jj(j)), '%', rcsv{jj(j) + 1, 2});                         else, fprintf('%7s\t%8s\t%3.0f%s\t%s\n', ' ', ' ', ...                                 roi_size(jj(j)), '%', rcsv{jj(j) + 1, 2});                         end                     end                 end             end         end     end end %----------------------------------------------------------------------- function H = select_results(sel) %----------------------------------------------------------------------- global H clearDataCursorPlot(H) H.S{1}.name = H.S1.name(sel, :); H.S{2}.name = H.S2.name(sel, :); H.S{1}.Y = H.S1.Y(:, sel); H.S{2}.Y = H.S2.Y(:, sel); H.S{1}.info = cat_surf_info(H.S{1}.name, 0); H.S{2}.info = cat_surf_info(H.S{2}.name, 0); % check whether data for left or right hemipshere are all non-zero ind1 = find(H.S{1}.Y(:) ~= 0); ind2 = find(H.S{2}.Y(:) ~= 0); % estimate min value > 0 and min/max values if ~isempty(ind1) & ~isempty(ind2)     H.S{1}.thresh = min(H.S{1}.Y(H.S{1}.Y(:) > 0));     H.S{1}.thresh = min(H.S{1}.thresh, min(H.S{2}.Y(H.S{2}.Y(:) > 0)));     H.S{1}.min = min(min(H.S{1}.Y(~isinf(H.S{1}.Y))), min(H.S{2}.Y(~isinf(H.S{2}.Y))));     H.S{1}.max = max(max(H.S{1}.Y(~isinf(H.S{1}.Y))), max(H.S{2}.Y(~isinf(H.S{2}.Y)))); elseif isempty(ind1)     H.S{1}.thresh = min(H.S{2}.Y(H.S{2}.Y(:) > 0));     H.S{1}.min = min(H.S{2}.Y(~isinf(H.S{2}.Y)));     H.S{1}.max = max(H.S{2}.Y(~isinf(H.S{2}.Y))); elseif isempty(ind2)     H.S{1}.thresh = min(H.S{1}.Y(H.S{1}.Y(:) > 0));     H.S{1}.min = min(H.S{1}.Y(~isinf(H.S{1}.Y)));     H.S{1}.max = max(H.S{1}.Y(~isinf(H.S{1}.Y))); end mn = H.S{1}.min; % deal with neg. values if H.S{1}.min < 0     mnx = max(abs([H.S{1}.min, H.S{1}.max]));     H.S{1}.min = - mnx;     H.S{1}.max = mnx; end % add 10% to min/max values H.S{1}.max = round(1100 * H.S{1}.max) / 1000; if H.S{1}.min < 0     H.S{1}.min = round(1100 * H.S{1}.min) / 1000; else     H.S{1}.min = round(900 * H.S{1}.min) / 1000; end % correct lower clim to "0" if no values are exceeding threshold if mn > -H.thresh_value     H.clim = [true 0 H.S{1}.max]; else     H.clim = [true H.S{1}.min H.S{1}.max]; end % only apply thresholds that are slightly larger than zero if H.S{1}.thresh > 0.00015 & H.thresh_value == 0     H.clip = [true -H.S{1}.thresh H.S{1}.thresh]; else     H.clip = [true -H.thresh_value H.thresh_value]; end % rather use NaN values for zero threshold if H.thresh == 0     H.clip = [false NaN NaN]; end if H.no_neg     H.clip = [true -Inf H.clip(3)];     set(H.slider_min, 'Value', 0); end H.n_surf = 1; for ind = 1:5     if H.S{1}.thresh > 0.00015         setappdata(H.patch(ind), 'clip', H.clip);     end     setappdata(H.patch(ind), 'clim', H.clim);     col = getappdata(H.patch(ind), 'col');          if ind > 4         d = [H.S{1}.Y; H.S{2}.Y];     else         d = H.S{round(ind / 2)}.Y;     end          H = updateTexture(H, ind, d, col, H.show_transp); end % correct value of slider if no values are exceeding threshold if H.S{1}.min > - H.thresh_value     set(H.slider_min, 'Value', 0); end % update file information and colorbar checkbox_info; if ~H.disable_cbar     H = show_colorbar(H); end % print selected filename cla(H.nam); axis(H.nam, 'off') text(0.5, 0.5, spm_str_manip(H.S{1}.name, 'k60d'), 'Parent', H.nam, 'Interpreter', 'none', ...     'FontSize', H.FS(7), 'HorizontalAlignment', 'center'); %----------------------------------------------------------------------- function H = select_surf(surf) %----------------------------------------------------------------------- global H for ind = 1:2     switch surf         case 1             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], ...             [H.S{ind}.info(1).side '.central.freesurfer.gii']);         case 2             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], ...             [H.S{ind}.info(1).side '.inflated.freesurfer.gii']);         case 3             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], ...             [H.S{ind}.info(1).side '.central.Template_T1_IXI555_MNI152_GS.gii']);         case 4             H.S{ind}.info(1).Pmesh = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], [H.S{ind}.info(1).side '.patch.freesurfer.gii']);     end          H.S{ind}.M = gifti(H.S{ind}.info(1).Pmesh); end figure(H.figure(1)); for ind = 1:5     if ind < 5 % single hemisphere views         M = H.S{round(ind / 2)}.M;     else         M.faces = [H.S{1}.M.faces; H.S{2}.M.faces + size(H.S{1}.M.vertices, 1)];         M.vertices = [H.S{1}.M.vertices; H.S{2}.M.vertices];         M.mat = H.S{1}.M.mat;     end          set(H.patch(ind), 'Vertices', M.vertices);     set(H.patch(ind), 'Faces', M.faces);          % rescale axis except for flatmaps     Ha = getappdata(H.patch(ind), 'axis');     axes(Ha);          if surf < 4         axis(Ha, 'image');         axis(Ha, 'off');     end end % only show lateral views for flatmaps if surf == 4     select_view(3) elseif H.view == 3     select_view(1) end % don't show data cursor, view functions and data plot that will not work for flatmaps if surf == 4     set(H.cursor, 'Enable', 'off');     set(H.mview, 'Enable', 'off');     clearDataCursorPlot(H); else     set(H.cursor, 'Enable', 'on');     set(H.mview, 'Enable', 'on'); end %----------------------------------------------------------------------- function display_results_all(obj, event_obj) %----------------------------------------------------------------------- global H if (size(H.S{1}.Y) > 1 | size(H.S{2}.Y) > 1) & min(min(H.S{1}.Y(:)), min(H.S{2}.Y(:))) < 0     disp('Warning: Only results with positive values are displayed!'); end % clear larger area and set background color to update labels and title H.Ha = axes('Parent', H.figure(1), 'Position', [-.1 -.1 1.1 1.1], 'Color', H.bkg_col); cla(H.Ha); H.renderer = get(H.figure(1), 'Renderer'); set(H.figure(1), 'Renderer', 'OpenGL'); %-Get mesh curvature and sulcal depth %------------------------------------------------------------------ for i = 1:2     g1 = gifti(fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], [H.S{i}.info(1).side '.mc.freesurfer.gii']));     g2 = gifti(fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], [H.S{i}.info(1).side '.sqrtsulc.freesurfer.gii']));     H.S{i}.curv = cell(2, 1);     H.S{i}.curv{1} = g1.cdata;     H.S{i}.curv{2} = g2.cdata; end if H.view == 1 % top view     vv = [90 0; -90 0; -90 0; 90 0; 0 90]; else % bottom view     vv = [90 0; -90 0; -90 0; 90 0; 0 -90]; end for ind = 1:5     display_results(ind, H.viewpos{ind}(abs(H.view), :), vv(ind, :)); end figure(H.figure(1)); % prepare dataplot axes H.dataplot = axes('Position', H.viewpos{6}(abs(H.view), :), 'Parent', H.figure(1), 'Color', H.bkg_col); H.figure(1) = ancestor(H.dataplot, 'figure'); try axes(H.dataplot); end axis off % check whether data for left or right hemipshere are all non-zero ind1 = find(H.S{1}.Y(:) ~= 0); ind2 = find(H.S{2}.Y(:) ~= 0); % estimate min value > 0 and min/max values if ~isempty(ind1) & ~isempty(ind2)     H.S{1}.thresh = min(H.S{1}.Y(H.S{1}.Y(:) > 0));     H.S{1}.thresh = min(H.S{1}.thresh, min(H.S{2}.Y(H.S{2}.Y(:) > 0)));     H.S{1}.min = min(min(H.S{1}.Y(~isinf(H.S{1}.Y))), min(H.S{2}.Y(~isinf(H.S{2}.Y))));     H.S{1}.max = max(max(H.S{1}.Y(~isinf(H.S{1}.Y))), max(H.S{2}.Y(~isinf(H.S{2}.Y)))); elseif isempty(ind1)     H.S{1}.thresh = min(H.S{2}.Y(H.S{2}.Y(:) > 0));     H.S{1}.min = min(H.S{2}.Y(~isinf(H.S{2}.Y)));     H.S{1}.max = max(H.S{2}.Y(~isinf(H.S{2}.Y))); elseif isempty(ind2)     H.S{1}.thresh = min(H.S{1}.Y(H.S{1}.Y(:) > 0));     H.S{1}.min = min(H.S{1}.Y(~isinf(H.S{1}.Y)));     H.S{1}.max = max(H.S{1}.Y(~isinf(H.S{1}.Y))); end % deal with neg. values if H.S{1}.min < 0     mnx = max(abs([H.S{1}.min, H.S{1}.max]));     H.S{1}.min = - mnx;     H.S{1}.max = mnx; end % add 10% to min/max values H.S{1}.max = round(1100 * H.S{1}.max) / 1000; if H.S{1}.min < 0     H.S{1}.min = round(1100 * H.S{1}.min) / 1000; else     H.S{1}.min = round(900 * H.S{1}.min) / 1000; end H.clim = [true H.S{1}.min H.S{1}.max]; % only apply thresholds that are slightly larger than zero if H.S{1}.thresh > 0.00015     H.clip = [true -H.S{1}.thresh H.S{1}.thresh]; end for ind = 1:5     if H.S{1}.thresh > 0.00015         setappdata(H.patch(ind), 'clip', H.clip);     end     setappdata(H.patch(ind), 'clim', [true H.S{1}.min H.S{1}.max]);     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end % only show threshold popup if log-name was found and minimal value > 0 is < 1 if H.logP & (H.S{1}.thresh < 1)     set(H.thresh, 'Enable', 'on'); end if H.n_surf == 1     % get sure that image is thresholded and there are at least 20% zero/NaN areas     if (sum(d ~= 0) / numel(d) < 0.8)         set(H.atlas, 'Enable', 'on');     end end if ~H.disable_cbar     H = show_colorbar(H); end % show slider for range of results if H.n_surf == 1          % allow slider a more extended range     mnx = ceil(2 * max(abs([H.S{1}.min H.S{1}.max])));          H.slider_min = sliderPanel( ...         'Parent', H.figure(2), ...         'Title', 'Overlay min', ...         'Position', H.pos{2}.ovmin, ...         'Backgroundcolor', [0.8 0.8 0.8], ...         'Min', - mnx, ...         'Max', mnx, ...         'Value', H.S{1}.min, ...         'FontName', 'Verdana', ...         'FontSize', 8, ...         'NumFormat', '%f', ...         'Callback', @slider_clim_min);          H.slider_max = sliderPanel( ...         'Parent', H.figure(2), ...         'Title', 'Overlay max', ...         'Position', H.pos{2}.ovmax, ...         'Backgroundcolor', [0.8 0.8 0.8], ...         'Min', - mnx, ...         'Max', mnx, ...         'Value', H.S{1}.max, ...         'FontName', 'Verdana', ...         'FontSize', 8, ...         'NumFormat', '%f', ...         'Callback', @slider_clim_max); end %----------------------------------------------------------------------- function H = show_colorbar(H) %----------------------------------------------------------------------- % show colorbar figure(H.figure(1)) if H.n_surf == 1          if isfield(H, 'cbar')         try delete(H.cbar); end         H = rmfield(H, 'cbar');     end          H.cbar = axes('Parent', H.figure(1), 'Position', H.pos{1}.cbar(1, :), 'Color', [0.5 0.5 0.5], 'Visible', 'off');     H.colourbar = colorbar('peer', H.cbar, 'Northoutside');          if H.logP, title(H.cbar, 'p-value', 'Color', 1 - H.bkg_col); end     clim = getappdata(H.patch(1), 'clim');     axis(H.cbar, 'off');          if clim(3) > clim(2)         caxis([clim(2) clim(3)]);     end          col = getappdata(H.patch(1), 'col');     colormap(col);          % Update colorbar colors if clipping is used     clip = getappdata(H.patch(1), 'clip');     if ~isempty(clip)         if ~isnan(clip(2)) & ~isnan(clip(3))             ncol = length(col);             col_step = (clim(3) - clim(2)) / ncol;             cmin = max([1, ceil((clip(2) - clim(2)) / col_step)]);             cmax = min([ncol, floor((clip(3) - clim(2)) / col_step)]);             col(cmin:cmax, :) = repmat([0.5 0.5 0.5], (cmax - cmin + 1), 1);             colormap(col);         end     end          if H.logP                  XTick = get(H.colourbar, 'XTick');                  % save original XTick values         if isempty(H.XTick), H.XTick = XTick; end                  % if threshold is between 1.3..1.4 (p<0.05) change XTick accordingly and correct by 0.3         if ~isempty(clip)             if clip(3) >= 1.3 & clip(3) <= 1.4                 XTick_step = ceil((clim(3) - clim(2)) / 5);                 if clip(2) <= - 1.3 & clip(2) >= - 1.4                     XTick = [(round(clim(2)) - 0.3):XTick_step: - 1.3 0 1.3:XTick_step:(round(clim(3)) + 0.3)];                 else                     XTick = [0 1.3:XTick_step:(round(clim(3)) + 0.3)];                 end             else                 if ~isempty(H.XTick), XTick = H.XTick; end             end         else             % rescue original XThick values if clipping is changed             if ~isempty(H.XTick), XTick = H.XTick; end         end                  % change XTickLabel         XTickLabel = [];         for i = 1:length(XTick)             if XTick(i) > 0                 XTickLabel = char(XTickLabel, remove_zeros(sprintf('%.g', 10^(-XTick(i)))));             elseif XTick(i) < 0                 XTickLabel = char(XTickLabel, remove_zeros(sprintf('-%.g', 10^(XTick(i)))));             else                 XTickLabel = char(XTickLabel, '');             end         end         set(H.colourbar, 'XTickLabel', XTickLabel(2:end, :), 'XTick', XTick);     end % end H.logP          set(H.colourbar, 'XColor', 1 - H.bkg_col, 'YColor', 1 - H.bkg_col);      else          if ~isfield(H, 'cbar') || ~ishandle(H.cbar)         H.cbar = axes('Parent', H.figure(1), 'Position', H.pos{1}.cbar(2, :), 'Color', [0.5 0.5 0.5], 'Enable', 'off');     end          % RGB colorbar     if H.n_surf == 3         cb = [8 1 1 4 2 2 8; ...               8 1 6 7 5 2 8; ...               8 8 3 3 3 8 8];     else %RG colorbar         cb = [8 1 1 4 2 2 8; ...               8 1 1 4 2 2 8];     end     imagesc(cb);     colormap([1 0 0; 0 1 0; 0 0 1; 1 1 0; 0 1 1; 1 0 1; 1 1 1; H.bkg_col]);     axis(H.cbar, 'off'); axis('image'); end %----------------------------------------------------------------------- function display_results(ind, win, vw) %----------------------------------------------------------------------- global H % rescue old color before a new H.patch is created try     col = getappdata(H.patch(ind), 'col'); catch     col = []; end if ind < 5 % single hemisphere views     M = H.S{round(ind / 2)}.M;     Mc.cdata = H.S{round(ind / 2)}.Y; else     Ml = H.S{1}.M;     Mr = H.S{2}.M;     Mcl.cdata = H.S{1}.Y;     Mcr.cdata = H.S{2}.Y;          % check whether number of data for lh/rh differ and fill with zeros     diff_size_Y = size(H.S{1}.Y, 2) - size(H.S{2}.Y, 2);     if diff_size_Y > 0         Mcr.cdata = [Mcr.cdata zeros(size(H.S{2}.Y, 1), 1)];     end     if diff_size_Y < 0         Mcl.cdata = [Mcl.cdata; zeros(size(H.S{1}.Y, 1), 1)];     end          M.faces = [Ml.faces; Mr.faces + size(Ml.vertices, 1)];     M.vertices = [Ml.vertices; Mr.vertices];     M.mat = Ml.mat;     Mc.cdata = [Mcl.cdata; Mcr.cdata]; end if isfield(Mc, 'cdata')     M.cdata = Mc.cdata; else     M.cdata = []; end H.axis = axes('Position', win, 'Parent', H.figure(1), 'Visible', 'off'); H.figure(1) = ancestor(H.axis, 'figure'); figure(H.figure(1)); axes(H.axis); if isfield(M, 'facevertexcdata')     H.cdata = M.facevertexcdata; else     H.cdata = []; end if ~isfield(M, 'vertices') || ~isfield(M, 'faces')     error('cat_surf_results:nomesh', 'ERROR:cat_surf_render: No input mesh.'); end %% -Patch %------------------------------------------------------------------ P = struct('vertices', M.vertices, 'faces', double(M.faces)); H.patch(ind) = patch(P, ...     'FaceColor', [0.6 0.6 0.6], ...     'EdgeColor', 'none', ...     'FaceLighting', 'gouraud', ...     'SpecularStrength', 0.1, ...     'AmbientStrength', 1.0, ...     'DiffuseStrength', 0.6, ...     'SpecularExponent', 15, ...     'Clipping', 'off', ...     'DeleteFcn', {@myDeleteFcn, H.renderer}, ...     'Visible', 'off', ...     'Tag', 'CATSurfRender', ...     'Parent', H.axis); setappdata(H.patch(ind), 'patch', P); setappdata(H.patch(ind), 'axis', H.axis); %-Apply texture to mesh %------------------------------------------------------------------ if isfield(M, 'facevertexcdata')     T = M.facevertexcdata; elseif isfield(M, 'cdata')     T = M.cdata; else     T = []; end if isempty(col)     H = updateTexture(H, ind, T); else     H = updateTexture(H, ind, T, col); end axis(H.axis, 'image'); axis(H.axis, 'off'); view(H.axis, vw); material(H.figure(1), 'dull'); % default lighting H.light(1) = camlight('headlight'); set(H.light(1), 'Parent', H.axis); setappdata(H.axis, 'handles', H); set(H.patch(ind), 'Visible', 'on'); camlight(H.light(1),'headlight') %========================================================================== function [H, C] = updateTexture(H, ind, v, col, transp) %-Project data onto surface mesh %-------------------------------------------------------------------------- if size(v, 2) < size(v, 1)     v = v'; end v(isinf(v)) = NaN; %-Get colourmap %-------------------------------------------------------------------------- if ~exist('col', 'var')     if size(v, 1) == 1         col = jet(256);     else         % use RGB colormap         col = zeros(256, 3, size(v, 1));         for i = 1:3             col(:, i, i) = 1;         end     end end setappdata(H.patch(ind), 'data', v); setappdata(H.patch(ind), 'col', col); if ~exist('FaceColor', 'var') || isempty(FaceColor), FaceColor = 'interp'; end %-Get curvature %-------------------------------------------------------------------------- if ind < 5 % single hemisphere views     curv = H.S{round(ind / 2)}.curv{H.text_mode}; else     curv = [H.S{1}.curv{H.text_mode}; H.S{2}.curv{H.text_mode}]; end if size(curv, 2) == 1          % emphasize mean curvature values by using sqrt     % if H.text_mode==1     if 1         indneg = find(curv < 0);         curv(indneg) = - ((-curv(indneg)).^0.5);         indpos = find(curv > 0);         curv(indpos) = (curv(indpos).^0.5);         curv = curv - min(curv);     end          curv = 0.5 + repmat(curv, 1, 3);     curv = curv / max(curv(:));          % for sulcal depth (with no neg. values) use inverted values     if H.text_mode == 2         curv = 1 - curv;     end end %-Create RGB representation of data according to colourmap %-------------------------------------------------------------------------- C = zeros(size(v, 2), 3); clim = getappdata(H.patch(ind), 'clim'); if isempty(clim), clim = [false NaN NaN]; end mi = clim(2); ma = clim(3); if any(v(:))     if ~clim(1), mi = min(v(:)); ma = max(v(:)); end     % don't allow negative values for multiple maps     if size(v, 1) > 1 & mi < 0         if ~isempty(H.clip)             H.clip(2) = - Inf;         else             H.clip = [true -Inf 0];         end     end     for i = 1:size(v, 1)         C = C + squeeze(ind2rgb(floor(((v(i, :) - mi) / (ma - mi)) * size(col, 1)), col(:, :, i)));     end end if ~isempty(H.clip)     v(v > H.clip(2) & v < H.clip(3)) = NaN;     setappdata(H.patch(ind), 'clip', [true H.clip(2) H.clip(3)]); end setappdata(H.patch(ind), 'clim', [true mi ma]); H.clim = [true mi ma]; %-Build texture by merging curvature and data %-------------------------------------------------------------------------- if size(v, 1) > 1 % RGB     for i = 1:size(v, 1)         C(:, i) = any(v(i, :), 1)' .* C(:, i);     end else     C = repmat(any(v, 1), 3, 1)' .* C; end % add curvature pattern if transparency is defined if nargin > 4     if transp & size(C, 1) == size(curv, 1)         C = (0.5 + 0.5 * curv) .* C;     end end % replace regions below threshold by curvature ind0 = repmat(~any(v, 1), 3, 1)'; if size(C, 1) == size(curv, 1)     C(ind0) = curv(ind0); else     C(ind0) = 0; end %-Add atlas border %-------------------------------------------------------------------------- if H.border_mode     if ind < 5 % single hemisphere views         A = H.S{round(ind / 2)}.A;         A = sparse(1:size(H.S{round(ind / 2)}.M.vertices, 1), 1:size(H.S{round(ind / 2)}.M.vertices, 1), 1 ./ sum(A, 2)) * A;         rdata = H.rdata{H.border_mode}(:, round(ind / 2));         C0 = (A - speye(size(A))) * double(rdata);         C(round(C0) ~= 0, :) = 0;     else         C0 = [];         for i = 1:2             A = H.S{i}.A;             A = sparse(1:size(H.S{i}.M.vertices, 1), 1:size(H.S{i}.M.vertices, 1), 1 ./ sum(A, 2)) * A;             rdata = H.rdata{H.border_mode}(:, i);             C0 = [C0; (A - speye(size(A))) * double(rdata)];         end         C(round(C0) ~= 0, :) = 0;     end end set(H.patch(ind), 'FaceVertexCData', C, 'FaceColor', FaceColor); %----------------------------------------------------------------------- function select_data(obj, event_obj) %----------------------------------------------------------------------- global H H.logP = 1; lh = []; rh = []; lh_rh = []; P = spm_select([1 24], 'mesh', 'Select up to 24 maps for left and right hemisphere'); info = cat_surf_info(P); n = size(P, 1); for i = 1:n          if info(i).nvertices == 64984         H.str32k = '_32k';         H.is32k = 1;     else         H.str32k = '';         H.is32k = 0;     end          % check whether name contains 'log' that indicates a logP file     if isempty(strfind(info(i).ff, 'log'))         H.logP = 0;     end          % check where left and right hemisphere data were found     if strcmp(info(i).side, 'lh')         lh = [lh i];     elseif strcmp(info(i).side, 'rh')         rh = [rh i];     elseif strcmp(info(i).side, 'mesh')         lh_rh = [lh_rh i];     end end % merged meshes? if ~isempty(lh_rh)     % don't mix mesh and lh+rh data     if ~isempty(lh) || ~isempty(rh)         error('Mixing of left and right with merged surface data is not supported.');     end          H.merged = 1;     H.S{1}.name = P(lh_rh, :);     H.S{2}.name = P(lh_rh, :); else % lh or rh meshes     H.merged = 0;     H.S{1}.name = P(lh, :);     H.S{2}.name = P(rh, :);     if numel(lh) > 1 || numel(rh) > 1         msg = 'Warning: Display of multiple left and right surface data will not work correctly. Please only use merged hemisphere data for multiple selected surface data or just select one left and right data set.';         h = spm('alert*', msg, '', spm('CmdLine'), 1);         select_data;     end end if isempty(H.S{2}.name)     H.S{2}.name = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], 'rh.central.freesurfer.gii'); elseif isempty(H.S{1}.name)     H.S{1}.name = fullfile(spm('dir'), 'toolbox', 'cat12', ['templates_surfaces' H.str32k], 'lh.central.freesurfer.gii'); end cat_surf_results('disp', H.S{1}.name, H.S{2}.name); %========================================================================== function save_image(obj, event_obj, filename) global H %% dcm_obj = datacursormode(H.figure(1)); set(dcm_obj, 'Enable', 'off'); figure(H.figure(1)) try     delete(findall(gca, 'Type', 'hggroup', 'HandleVisibility', 'off')); end if ~exist('filename', 'var')          nm = H.S{1}.info(1).ff;     [pp, nm] = spm_fileparts(H.S{1}.name);     filename = [nm '.png'];          % end with _0???.ext?     if length(nm) > 4         if strcmp(nm(length(nm) - 4:length(nm) - 3), '_0')                          SPM_name = fullfile(pp, 'SPM.mat');                          % SPM.mat exist?             if exist(SPM_name, 'file')                 load(SPM_name);                 xCon = SPM.xCon;                 Ic = str2double(nm(length(nm) - 3:length(nm)));                 str_num = deblank(xCon(Ic).name);                                  % replace spaces with "_" and characters like "<" or ">" with "gt" or "lt"                 str_num(strfind(str_num, ' ')) = '_';                 strpos = strfind(str_num, ' > ');                 if ~isempty(strpos), str_num = [str_num(1:strpos - 1) '_gt_' str_num(strpos + 1:end)]; end                 strpos = strfind(str_num, ' < ');                 if ~isempty(strpos), str_num = [str_num(1:strpos - 1) '_lt_' str_num(strpos + 1:end)]; end                 strpos = strfind(str_num, '>');                 if ~isempty(strpos), str_num = [str_num(1:strpos - 1) 'gt' str_num(strpos + 1:end)]; end                 strpos = strfind(str_num, '<');                 if ~isempty(strpos), str_num = [str_num(1:strpos - 1) 'lt' str_num(strpos + 1:end)]; end                 str_num = spm_str_manip(str_num, 'v');                                  if ~isempty(H.clip)                     if isnan(H.clip(3))                         str_thresh = '_';                     else                         str_thresh = sprintf('P%g_', round(1000 * 10^(-H.clip(3))) / 10);                     end                 else                     str_thresh = '_';                 end                 filename = ['logP_' str_thresh str_num '.png'];             end         end     end          [filename, newpth] = uiputfile({ ...         '*.png' 'PNG files (*.png)'}, 'Save as', filename); else     [pth, nam, ext] = fileparts(filename);     if isempty(pth), pth = cd; end     if ~strcmp({'.gii', '.png'}, ext), nam = [nam ext]; end     if isempty(nam)         [filename, newpth] = uiputfile({ ...             '*.png' 'PNG files (*.png)'}, 'Save as', nam);     else         filename = fullfile(pth, [nam '.png']);         newpth = pth;     end end % keep background color set(H.figure(1), 'InvertHardcopy', 'off', 'PaperPositionMode', 'auto'); if isdeployed     deployprint(H.figure(1), '-dpng', '-opengl', fullfile(newpth, filename)); else     print(H.figure(1), '-dpng', '-r300', '-opengl', fullfile(newpth, filename)); end %========================================================================== function slider_clim_min(hObject, evt) global H figure(H.figure(1)) val = get(hObject, 'Value'); c = getappdata(H.patch(1), 'clim'); for ind = 1:5     setappdata(H.patch(ind), 'clim', [true val c(3)]);     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end % update colorbar if H.n_surf == 1 & ~H.disable_cbar     H = show_colorbar(H); end H.clim = [true val c(3)]; %========================================================================== function slider_clim_max(hObject, evt) global H figure(H.figure(1)) val = get(hObject, 'Value'); c = getappdata(H.patch(1), 'clim'); for ind = 1:5     setappdata(H.patch(ind), 'clim', [true c(2) val]);     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end % update colorbar if H.n_surf == 1 & ~H.disable_cbar     H = show_colorbar(H); end H.clim = [true c(2) val]; %========================================================================== function checkbox_inv(obj, event_obj) global H H.show_inv = get(H.inv, 'Value'); for ind = 1:5     setappdata(H.patch(ind), 'clip', H.clip);     col = getappdata(H.patch(ind), 'col');     setappdata(H.patch(ind), 'col', flipud(col));     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, flipud(col), H.show_transp); end if ~H.disable_cbar     H = show_colorbar(H); end %----------------------------------------------------------------------- function H = checkbox_hide_neg(obj, event_obj) %----------------------------------------------------------------------- global H H.no_neg = get(H.hide_neg, 'Value'); thresh = H.thresh_value; clip = getappdata(H.patch(1), 'clip'); clim = getappdata(H.patch(1), 'clim'); % get min value for both hemispheres min_d = min(min(min(getappdata(H.patch(1), 'data'))), min(min(getappdata(H.patch(3), 'data')))); if H.no_neg     H.clip = [true -Inf thresh];     H.clim = [true 0 clim(3)];     set(H.slider_min, 'Value', 0); else     H.clip = [true -thresh thresh];     if min_d < -thresh         H.clim = [true -clim(3) clim(3)];         set(H.slider_min, 'Value', -clim(3));     end end for ind = 1:5     setappdata(H.patch(ind), 'clip', H.clip);     setappdata(H.patch(ind), 'clim', H.clim);     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     min_d = min(min_d, min(d(:)));     H = updateTexture(H, ind, d, col, H.show_transp); end % correct value of slider if no values are exceeding threshold if min_d > -thresh & H.n_surf == 1     set(H.slider_min, 'Value', 0); end set(H.atlas, 'Enable', 'on'); if ~H.disable_cbar     H = show_colorbar(H); end %========================================================================== function checkbox_transp(obj, event_obj) global H H.show_transp = ~get(H.transp, 'Value'); for ind = 1:5     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end % update colorbar if H.n_surf == 1 & ~H.disable_cbar     H = show_colorbar(H); end %========================================================================== function checkbox_bkg(obj, event_obj) global H H.white_bgk = get(H.bkg, 'Value'); if H.white_bgk     H.bkg_col = [1 1 1]; else     H.bkg_col = [0 0 0]; end set(H.Ha, 'Color', H.bkg_col); set(get(H.cbar, 'Title'), 'Color', 1 - H.bkg_col); if H.show_info     set(get(getappdata(H.patch(1), 'axis'), 'Title'), 'Color', 1 - H.bkg_col);     set(get(getappdata(H.patch(3), 'axis'), 'Title'), 'Color', 1 - H.bkg_col); end if H.n_surf == 1     set(H.colourbar, 'XColor', 1 - H.bkg_col, 'YColor', 1 - H.bkg_col); end if ~H.disable_cbar     H = show_colorbar(H); end if isfield(H, 'dataplot')     try, set(H.dataplot, 'XColor', 1 - H.bkg_col, 'YColor', 1 - H.bkg_col, 'Color', H.bkg_col); end end %========================================================================== function checkbox_info(obj, event_obj) global H H.show_info = get(H.info, 'Value'); if H.show_info     set(get(getappdata(H.patch(1), 'axis'), 'Title'), 'String', ...         spm_str_manip(H.S{1}.name, 'k50d'), 'Interpreter', 'none', 'Color', 1 - H.bkg_col)     set(get(getappdata(H.patch(3), 'axis'), 'Title'), 'String', ...         spm_str_manip(H.S{2}.name, 'k50d'), 'Interpreter', 'none', 'Color', 1 - H.bkg_col) else     set(get(getappdata(H.patch(1), 'axis'), 'Title'), 'String', '')     set(get(getappdata(H.patch(3), 'axis'), 'Title'), 'String', '') end %========================================================================== function checkbox_nocbar(obj, event_obj) global H H.disable_cbar = get(H.nocbar, 'Value'); if H.disable_cbar     % delete colorbar and title     if H.n_surf == 1         set(H.colourbar, 'Visible', 'off')         set(get(H.cbar, 'Title'), 'Visible', 'off')     else % delete only axis         cla(H.cbar);     end else     if H.n_surf == 1         set(get(H.cbar, 'Title'), 'Visible', 'on')         set(H.colourbar, 'Visible', 'on')         H = show_colorbar(H);     else         H = show_colorbar(H);     end end %========================================================================== function H = getHandles(H) if ~nargin || isempty(H), H = gca; end if ishandle(H) & ~isappdata(H, 'handles')     a = H; clear H;     H.axis = a;     H.figure(1) = ancestor(H.axis, 'figure');     H.patch = findobj(H.axis, 'type', 'patch');     H.light = findobj(H.axis, 'type', 'light');     H.rotate3d = rotate3d(H.figure(1));     setappdata(H.axis, 'handles', H); else     H = getappdata(H, 'handles'); end %========================================================================== function select_view(view) global H % check that view changed if view ~= H.view          if view > 0 % top view         vv = [90 0; -90 0; -90 0; 90 0; 0 90];     else % bottom view         vv = [90 0; -90 0; -90 0; 90 0; 0 -90];     end          for ind = 1:5         Ha = getappdata(H.patch(ind), 'axis');         set(Ha, 'position', H.viewpos{ind}(abs(view), :), 'View', vv(ind, :));     end          axes(Ha);     camlight(H.light(1),'headlight')          if isfield(H, 'dataplot')         set(H.dataplot, 'Position', H.viewpos{6}(abs(view), :), 'Parent', H.figure(1), 'Color', H.bkg_col);     end          % save view     H.view = view; end %========================================================================== function select_texture(text_mode) global H % check that view changed if text_mode ~= H.text_mode          if text_mode == 1 % mean curvature         H.text_mode = 1;     else % sulcal depth         H.text_mode = 2;     end          for ind = 1:5         col = getappdata(H.patch(ind), 'col');         d = getappdata(H.patch(ind), 'data');         H = updateTexture(H, ind, d, col, H.show_transp);     end      end %========================================================================== function select_border(border_mode) global H H.border_mode = border_mode; for ind = 1:5     col = getappdata(H.patch(ind), 'col');     d = getappdata(H.patch(ind), 'data');     H = updateTexture(H, ind, d, col, H.show_transp); end %========================================================================== function select_cursor(cursor_mode) global H dcm_obj = datacursormode(H.figure(1)); H.cursor_mode = cursor_mode; switch H.cursor_mode          case 0 % disable and delete datatip         rotate3d off;                  clearDataCursorPlot(H)     case {1, 2, 3}         clearDataCursorPlot(H)         set(dcm_obj, 'Enable', 'on', 'SnapToDataVertex', 'on', ...             'DisplayStyle', 'datatip', 'Updatefcn', {@myDataCursorAtlas, H});     case {4, 5}         figure(H.figure(1))                  try             delete(findall(gca, 'Type', 'hggroup', 'HandleVisibility', 'off'));         end                  SPM_found = 1;         for i = 1:(2-H.merged)             SPM_name = fullfile(H.S{i}.info(1).pp, 'SPM.mat');                          % SPM.mat exist?             if exist(SPM_name, 'file')                 load(SPM_name);                 % if analysis was moved we have to correct header structure                 SPM.VResMS = spm_data_hdr_read(fullfile(H.S{i}.info(1).pp,SPM.VResMS.fname));                 Vbeta = spm_data_hdr_read(fullfile(H.S{i}.info(1).pp,SPM.Vbeta(1).fname));                 for j=2:numel(SPM.Vbeta)                   Vbeta(j) = spm_data_hdr_read(fullfile(H.S{i}.info(1).pp,SPM.Vbeta(j).fname));                 end                 SPM.Vbeta = Vbeta;                 H.SPM{i} = SPM;                 if i == 1                     str = 'predicted, adjusted or raw values?';                     H.predicted = spm_input(str, 1, 'b', {'predicted', 'adjusted', 'raw'}, [1 0 -1]);                                          % ask for contrast for predicted or adjusted data                     if H.predicted >= 0                         H.Ic = spm_input('Which contrast?', 2, 'm', {SPM.xCon.name});                     end                 end             elseif ~isempty(H.S{i}.name)                 SPM_found = 0;                 spm('alert!', 'No SPM.mat file found.\nPlease check that you have not moved your files or your result file was moved from the folder where the SPM.mat is stored.', 1);             end         end                  if SPM_found             set(dcm_obj, 'Enable', 'on', 'SnapToDataVertex', 'on', ...                 'DisplayStyle', 'datatip', 'Updatefcn', {@myDataCursorCluster});             fprintf('The values are available at the MATLAB command line as variable ''y''\n');         end     case 6 % enable/disable rotate3d         clearDataCursorPlot(H)         rotate3d;         disp('Use mouse to rotate views.'); end %========================================================================== function clearDataCursorPlot(H) if isfield(H, 'dataplot')     cla(H.dataplot);     axis(H.dataplot, 'off'); end figure(H.figure(1)) try     dcm_obj = datacursormode(H.figure(1));     set(dcm_obj, 'Enable', 'off');     delete(findall(gca, 'Type', 'hggroup', 'HandleVisibility', 'off')); end %========================================================================== function txt = myDataCursorCluster(obj, evt) global H y % first entries are atlases plot_mean = H.cursor_mode - 4; pos = get(evt, 'Position'); i = ismember(get(H.patch(1), 'vertices'), pos, 'rows'); node = find(i); ind = 1; node_list = 1:numel(get(H.patch(1), 'vertices')); if isempty(node)     i = ismember(get(H.patch(3), 'vertices'), pos, 'rows');     node = find(i);     ind = 3;     node_list = 1:numel(get(H.patch(3), 'vertices')); end % get threshold from clipping thresh = [0 0]; if ~isempty(H.clip)     if ~isnan(H.clip(2)) & ~isnan(H.clip(3))         thresh = [H.clip(2:3)];     end end if plot_mean          found_node = [];     cluster_number = 0;     cluster_side = 0;          A = H.S{round(ind / 2)}.A;     A = A + speye(size(A));     d = getappdata(H.patch(ind), 'data');          % apply thresholds     dp = d >= thresh(2); indp = find(dp);     dn = d <= thresh(1); indn = find(dn);          % go through pos. effects     if ~isempty(indp)                  C = find_connected_component(A, dp);         C = C(indp);         node_list2 = node_list(indp);                  for i = 1:max(C)             N = find(C == i);             XYZ = node_list2(N);             found_node = find(XYZ == node);             if ~isempty(found_node)                 cluster_number = i;                 cluster_side = ind;                 break;             end         end     end              % go through neg. effects if no node was found     if ~isempty(indn) & isempty(found_node)                  C = find_connected_component(A, dn);         C = C(indn);         node_list2 = node_list(indn);                  for i = 1:max(C)             N = find(C == i);             XYZ = node_list2(N);             found_node = find(XYZ == node);             if ~isempty(found_node)                 cluster_number = i;                 cluster_side = ind;                 break;             end         end         cstr = 'neg. ';     else         cstr = '';     end          if isempty(found_node)         txt = {'Cursor outside of cluster'};     else         if cluster_side == 1             txt = {sprintf('lh: Cluster %s%d', cstr, cluster_number)};         else             txt = {sprintf('rh: Cluster %s%d', cstr, cluster_number)};         end     end else     % use single node as region     XYZ = node;     txt = {sprintf('Node %d', node)}; end % for merged meshe we only have one SPM.mat with data from both hemispheres if H.merged     % add offset for right hemisphere     if round(ind / 2) == 2         if H.is32k             XYZ = XYZ + 32492;         else             XYZ = XYZ + 163842;         end     end          % always one mesh     ind = 1; end [y, cbeta, CI] = get_cluster_data(H, XYZ, ind); % if no cluster was selected set data to zero if plot_mean & isempty(found_node)     y(:) = 0;     cbeta(:) = 0;     CI(:) = 0; end cla(H.dataplot) hold(H.dataplot, 'on') set(H.dataplot, 'XColor', 1 - H.bkg_col, 'YColor', 1 - H.bkg_col, 'GridColor',[0.5 0.5 0.5],...       'YGrid','on','GridColorMode','auto','Visible','on'); if H.predicted >=0   ystr = 'contrast estimate';   h = bar(H.dataplot, cbeta);   set(h, 'FaceColor', H.Col(2, :))      % standard error   %--------------------------------------------------------------   CI = CI / 2;   for j = 1:length(cbeta)       line([j j], ([CI(j) -CI(j)] + cbeta(j)), 'LineWidth', 6, 'Color', H.Col(3, :), 'Parent', H.dataplot)   end   set(H.dataplot, 'XLim', [0.4 (length(cbeta) + 0.6)], 'XTicklabel', '', 'XTick', [], 'YGrid','off') else   ystr = 'raw data';   h = plot(H.dataplot, y);   set(h, 'Color', H.Col(3, :))   set(H.dataplot, 'XLim', [0 (length(y))], 'XTicklabel', '', 'XTick', []) end xX = H.SPM{1}.xX; iH = xX.iH; % plot group coding for Anovas with more than 1 group and native data if ~isempty(iH) & numel(iH)>1 & (H.predicted < 0) & isempty(xX.iB)     yl = get(H.dataplot,'YLim');     pcol = gray(numel(iH)+2);     for i=1:numel(iH)         ind_data = find(any(xX.X(:,xX.iH(i)),2));                  % plot only if ind_data is a continuous row         if all(diff(ind_data)==1)             line([min(ind_data)-0.5 max(ind_data)+0.5], [yl(1) yl(1)], 'LineWidth', 6, 'Color', pcol(i+1,:), 'Parent', H.dataplot)         end     end      end nm = H.S{1}.info(1).ff; Ic = []; % end with _0???.ext? if length(nm) > 4     if strcmp(nm(length(nm) - 4:length(nm) - 3), '_0')         Ic = str2double(nm(length(nm) - 3:length(nm)));     end else   if isfield(H,'Ic')       Ic = H.Ic;   end end if ~isempty(Ic)     xlabel(H.dataplot, H.SPM{round(ind / 2)}.xCon(Ic).name, 'FontSize', H.FS(12), 'Color', 1 - H.bkg_col) end if plot_mean     ylabel(H.dataplot, sprintf('mean %s\ninside cluster',ystr), 'FontSize', H.FS(12), 'Color', 1 - H.bkg_col) else     ylabel(H.dataplot, sprintf('%s',ystr), 'FontSize', H.FS(12), 'Color', 1 - H.bkg_col) end hold(H.dataplot, 'off') assignin('base', 'y', y); %========================================================================== function [y, cbeta, CI] = get_cluster_data(H, XYZ, ind) SPM = H.SPM{round(ind / 2)}; Ic = []; if isfield(H,'Ic')     Ic = H.Ic; end predicted = H.predicted; % get raw data and whiten y = spm_data_read(SPM.xY.VY, 'xyz', XYZ); % for adjusted or predicted data use model estimations %------------------------------------------------------------------ if predicted >= 0     y = spm_filter(SPM.xX.K, SPM.xX.W * y);     R = spm_sp('r', SPM.xX.xKXs, y);          beta = spm_data_read(SPM.Vbeta,'xyz',XYZ);     ResMS = spm_data_read(SPM.VResMS, 'xyz', XYZ);          ResMS = mean(ResMS, 2);     Bcov = ResMS * SPM.xX.Bcov;          % compute contrast of parameter estimates and 90% C.I.     %------------------------------------------------------------------     cbeta = SPM.xCon(Ic).c' * beta;     cbeta = mean(cbeta, 2);          CI = 1.6449; % = spm_invNcdf(1 - 0.05);     SE = sqrt(diag(SPM.xCon(Ic).c' * Bcov * SPM.xCon(Ic).c));     CI = CI * SE;          % predicted or adjusted response     %------------------------------------------------------------------     if predicted == 1                  % fitted (predicted) data (Y = X1*beta)         %--------------------------------------------------------------         % this should be SPM.xX.xKXs.X instead of SPM.xX.X below         Y = SPM.xX.X * SPM.xCon(Ic).c * pinv(SPM.xCon(Ic).c) * beta;     else                  % fitted (corrected) data (Y = X1o*beta)         %--------------------------------------------------------------         Y = spm_FcUtil('Yc', SPM.xCon(Ic), SPM.xX.xKXs, beta);              end     y = Y + R; else     cbeta = [];     CI = []; end y = cat_stat_nanmean(y, 2); %========================================================================== function txt = myDataCursorAtlas(obj, evt, H) pos = get(evt, 'Position'); if H.cursor_mode == 1     txt = {'Desikan DK40'}; elseif H.cursor_mode == 2     txt = {'Destrieux 2009'}; elseif H.cursor_mode == 3     txt = {'HCP_MMP1'}; end i = ismember(get(H.patch(1), 'vertices'), pos, 'rows'); node = find(i); ind = 1; if isempty(node)     i = ismember(get(H.patch(3), 'vertices'), pos, 'rows');     node = find(i);     ind = 2; end rdata_pos = H.rdata{H.cursor_mode}(node, ind); rcsv = H.rcsv{H.cursor_mode}; for j = 2:size(rcsv, 1)     if rdata_pos == rcsv{j, 1}         txt = {txt{:} [H.S{ind}.side ' ' rcsv{j, 2}]};         j = size(rcsv, 1);     end end %========================================================================== function myDeleteFcn(obj, evt, renderer) try rotate3d(get(obj, 'parent'), 'off'); end set(ancestor(obj, 'figure'), 'Renderer', renderer); %========================================================================== function s = remove_zeros(s) pos = length(s); while pos > 1     if strcmp(s(pos), '0')         s(pos) = '';         pos = pos - 1;     else break     end end %========================================================================== function C = find_connected_component(A, T); % find connected components % FORMAT C = find_connected_component(A,T) % A - a [nxn[ (reduced) adjacency matrix % T - a [nx1] data vector (using NaNs or logicals), n = #vertices % % C - a [nx1] vector of cluster indices % % modified version from spm_mesh_clusters.m 5065 2012-11-16 20:00:21Z guillaume % %-Input parameters %-------------------------------------------------------------------------- if ~islogical(T)     T = ~isnan(T); end A1 = A; A1(~T, :) = []; A1(:, ~T) = []; %-And perform Dulmage-Mendelsohn decomposition to find connected components %-------------------------------------------------------------------------- [p, q, r] = dmperm(A1); N = diff(r); CC = zeros(size(A1, 1), 1); for i = 1:length(r) - 1     CC(p(r(i):r(i + 1) - 1)) = i; end C = NaN(numel(T), 1); C(T) = CC; %-Sort connected component labels according to their size %-------------------------------------------------------------------------- [N, ni] = sort(N(:), 1, 'descend'); [ni, ni] = sort(ni); C(T) = ni(C(T));

Top of Message | Previous Page | Permalink

JiscMail Tools


RSS Feeds and Sharing


Advanced Options


Archives

May 2024
April 2024
March 2024
February 2024
January 2024
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
2006
2005
2004
2003
2002
2001
2000
1999
1998


JiscMail is a Jisc service.

View our service policies at https://www.jiscmail.ac.uk/policyandsecurity/ and Jisc's privacy policy at https://www.jisc.ac.uk/website/privacy-notice

For help and support help@jisc.ac.uk

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager