% Randomtalk.m % Script to generate figures for random fields web page % The script requires spm96 or 99 on the matlab path % and will run in matlab 4 or 5 % % Many thanks to Federico Turkheimer for the code to % correct the variance of the smoothed images % % Matthew Brett - October 1999 % The relationship of p values to Z scores Zscores = spm_invNcdf(1 - [0.05 0.01]); % Constants for image simulations etc Dim = [128 128]; % No of pixels in X, Y VNo = prod(Dim); % Total pixels sFWHM = 8; % Smoothing in number of pixels in x, y seed = 6; % Seed for random no generator alpha = 0.05; % Default alpha level % Image of independent random nos randn('seed', seed); testimg = randn(Dim); figure colormap('bone'); imagesc(testimg) axis xy; set(gca,'Fontsize',18); xlabel('Pixel position in X') ylabel('Pixel position in Y') title('Image 1 - array of independent random numbers') % Bonferroni threshold for this image Bthresh = spm_invNcdf(1 - (alpha / VNo)); % Divide into FWHM chunks and fill square from mean value sqmeanimg = testimg; tarr = ones(sFWHM)* sFWHM; % mutliply up to unit variance for i = 1:sFWHM:Dim(1) for j = 1:sFWHM:Dim(2) Vals = sqmeanimg(i:i+sFWHM-1,j:j+sFWHM-1); sqmeanimg(i:i+sFWHM-1,j:j+sFWHM-1) = tarr * mean(Vals(:)); end end figure colormap('bone'); imagesc(sqmeanimg); axis xy; xlabel('Pixel position in X') ylabel('Pixel position in Y') title(['Taking means over ' num2str(sFWHM) ' by ' num2str(sFWHM) ... ' elements from image 1']) % Bonferroni threshold for the mean-by-square image mBthresh = spm_invNcdf(1 - (alpha / prod(Dim / sFWHM))); % smooth random number image sd = sFWHM/sqrt(8*log(2)); % sigma for this FWHM smmat = spm_sptop(sd, Dim(1)); % (sparse) smoothing matrix in 1D stestimg = smmat * testimg; % apply in x stestimg = (smmat * stestimg')';% then in y stestimg = full(stestimg); % back to non-sparse % Restore smoothed image to unit variance - this code is tough % 2d Gaussian kernel [x,y] = meshgrid(-(Dim(2)-1)/2:(Dim(2)-1)/2,-(Dim(1)-1)/2:(Dim(1)-1)/2); gf = exp(-(x.*x + y.*y)/(2*sd*sd)); gf = gf/sum(sum(gf)); % expectation of variance for this kernel AG = fft2(gf); Pag = AG.*conj(AG); % Power of the noise COV = real(ifft2(Pag)); svar = COV(1,1); % smoothed image to unit variance scf = sqrt(1/svar); stestimg = stestimg .* scf; % display smoothed image figure colormap('bone'); imagesc(stestimg) axis xy;set(gca,'Fontsize',18); xlabel('Pixel position in X') ylabel('Pixel position in Y') title(['Image 1 - smoothed with Gaussian kernel of FWHM ' num2str(sFWHM) ' by ' ... num2str(sFWHM) ' pixels']) % No of resels resels = prod(Dim ./ [sFWHM sFWHM]); % threshold at 2.75 and display th = 2.75; thimg = (stestimg > th); figure colormap('bone'); imagesc(thimg) axis xy;set(gca,'Fontsize',18); xlabel('Pixel position in X') ylabel('Pixel position in Y') title(['Smoothed image thresholded at Z > ' num2str(th)]) % threshold at 3.5 and display th = 3.5; thimg = (stestimg > th); figure colormap('bone'); imagesc(thimg) axis xy;set(gca,'Fontsize',18); xlabel('Pixel position in X') ylabel('Pixel position in Y') title(['Smoothed image thresholded at Z > ' num2str(th)]) % expected EC at various Z thresholds, for two dimensions figure Z = 0:0.01:5; expEC = (resels*(4*log(2))*((2*pi)^(-3/2))*Z).*exp((Z.^2)*(-0.5)); plot(Z, expEC);set(gca,'Fontsize',18); xlabel('Z score threshold') ylabel('Expected EC for thresholded image') title(['Expected EC for smoothed image with ' num2str(resels) ' resels']) return % simulation to test the RFT threshold. % find approx threshold from the vector above tmp = find(Z > 3 & expEC<=alpha); alphaTH = Z(tmp(1)); disp('Doing simulation, please wait...') repeats = 1000; falsepos = zeros(1, repeats); edgepix = sFWHM; % to add edges to image - see below smmat = spm_sptop(sd, Dim(1) + edgepix*2); for i = 1:repeats timg = randn(Dim + edgepix*2); % gives extra edges to throw away stimg = full(smmat*(smmat*(timg))')' * scf; % throw away edges to avoid artefactually high values % at image edges generated by the smoothing stimg = stimg(edgepix+1:Dim(1)+edgepix, edgepix+1:Dim(2)+edgepix); falsepos(i) = any(stimg(:) >= alphaTH); end disp(['False positive rate in simulation was '... num2str(sum(falsepos) / repeats) ' (' ... num2str(alpha) ' expected).'])