123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- function GNI=Rest2GNI(RestData,WBMaskName,nVoxelPerSectionMax)
- % function GNI=Rest2GNI(RestData,WBMaskName)
- %
- % Purpose:
- % Calculate GNI from preprocessed resting state data and a whole brain mask
- % if GNI>3, global signal regression may not be necessary
- %
- % reference:
- % Chen G, Chen GY, Xie C, Ward BD, Li W, Antuono P and Li SJ.
- % A Method to Determine the Necessity for Global Signal Regression in Resting-State fMRI Studies
- % Magn Reson Med; doi: 10.1002/mrm.24201(2012)
- % Please cite the reference if you found the method useful.
- %
- % Author: Gang Chen
- % Date: 25 May 2012
- % Version: 1, initial release, limited function, limited testing has been performed. use at your own risk.
- %
- % Requirement:
- % You have to make sure "load_nii.m" and/or "BrikLoad.m" work in your matlab.
- % Google them, you may find the address where you can download them. You can
- % also send an email (gachen@mcw.edu) to me if you have questions.
- %
- % Input:
- % RestData:
- % full path and name of the 4-D preprocessed resting state data,
- % the program will accept .nii and .BRIK + .HEAD format
- % WBMaskName:
- % full path and name of the 3-D whole brain mask, must align to the
- % RestData and have the same matrix size in the first three dimention
- % the program will accept .nii and .BRIK + .HEAD format
- % nVoxelPerSectionMax:
- % This is determined by the memory size of your computer
- % at 100 this program will take less than 1GB memory
- % at 1000 this program will take more memory but runs faster, adjust as
- % needed
- %
- % example usage:
- % clear;
- % clc
- % ResultFolder=['D:\Work\ADNI\LFTC\'];
- % % dir([ResultFolder '*LFTC_NGR*.nii']);
- % RestFiles=dir([ResultFolder '*LFTC_NGR*.nii']);
- % WBMaskName='wWBMask4mm.nii';
- % for i=1:numel(RestFiles)
- % disp(num2str(i))
- % RestData=[ResultFolder RestFiles(i).name];
- % GNI(i)=Rest2GNI(RestData,WBMaskName,100);
- % if GNI(i)<3
- % disp([RestFiles(i).name ' needs global signal regression'])
- % end
- % end
- if strcmpi(RestData(end-3:end),'.nii')
- nii=load_nii(RestData);
- WBTC=nii.img;
- nii=load_nii(WBMaskName);
- WBMask=nii.img;
- elseif strcmpi(RestData(end-3:end),'orig')
- [err, WBTC , BrikInfo, ErrMessage] = BrikLoad(RestData);
- [err, WBMask , BrikInfo, ErrMessage] = BrikLoad(WBMaskName);
- else
- error('unknown data format')
- end
- nTP=size(WBTC,4);
- if nTP<=1
- error('RestData is not a 4-D file')
- end
- nvoxel=size(WBTC,1)*size(WBTC,2)*size(WBTC,3);
- WBTC=reshape(WBTC,[nvoxel nTP]);
- GSTC=WBTC(WBMask==1,:);
- GSTC=DeNaNInf(GSTC); % remove NaN value, sometimes the mask is outside of brain
- GSTC=mean(GSTC,1);
- % % GSTC=mean(WBTC(WBMask==1,:),1);
- [R,P]=MyCorrcoefSmallLarge(GSTC.',WBTC.',nVoxelPerSectionMax);
- P(P>=0.05)=1;
- Z=p2z(P).*sign(R);
- WBMask=double(WBMask);
- Z3D=WBMask;
- Z3D(:)=Z;
- GSConMask=double(Z3D<-1.96).*double(WBMask);
- nGSConVoxel=sum(GSConMask(:));
- GNI=100*nGSConVoxel./sum(WBMask(:));
- function [R,P]=MyCorrcoefSmallLarge(TC_Small,TC_Large,nTC_SectionMax)
- % by default one colume of TC represent one time course.
- % % For testing
- % TC_Small = rand(141,10);
- % TC_Large = rand(141,1079);
- % nTC_SectionMax=500;
- % tic;[R,P]=MyCorrcoefSmallLarge(TC_Small,TC_Large,nTC_SectionMax);toc
- % size(R)
- % [R2,P2]=mycorrcoef(TC_Small,TC_Large);
- % sum(abs(R(:)-R2(:)))
- % sum(abs(P(:)-P2(:)))
- if nargin==2
- nTC_SectionMax=1000;
- end
- nTC=size(TC_Large,2);
- nSection=ceil(nTC/nTC_SectionMax);
- nTC_OneSection=ceil(nTC/nSection);
- R=zeros(size(TC_Small,2),size(TC_Large,2));
- P=R;
- for iSection=1:nSection-1
- [r,p]=mycorrcoef(TC_Small,TC_Large(:,1+(iSection-1)*nTC_OneSection:iSection*nTC_OneSection));
- R(:,1+(iSection-1)*nTC_OneSection:iSection*nTC_OneSection)=r;
- P(:,1+(iSection-1)*nTC_OneSection:iSection*nTC_OneSection)=p;
- end
- [r,p]=mycorrcoef(TC_Small,TC_Large(:,1+(nSection-1)*nTC_OneSection:end));
- R(:,1+(nSection-1)*nTC_OneSection:end)=r;
- P(:,1+(nSection-1)*nTC_OneSection:end)=p;
- return
- function [r,p]=mycorrcoef(TC1,TC2)
- if nargout<=1 % Quickly dispose of most common case.
- %by default one colume of TC represent one time course.
- if size(TC1,1)==size(TC2,1) && size(TC1,1)~=1
- TC=[TC1 TC2];
- [CC]=corrcoef(TC);
- r=CC(1:size(TC1,2),size(TC1,2)+1:size(TC1,2)+size(TC2,2));
- elseif size(TC1,2)==size(TC2,2)
- TC=[TC1;TC2];
- [CC]=corrcoef(TC.');
- r=CC(1:size(TC1,1),size(TC1,1)+1:size(TC1,1)+size(TC2,1));
- end
- p=[];
- else
- %by default one colume of TC represent one time course.
- if size(TC1,1)==size(TC2,1) && size(TC1,1)~=1
- TC=[TC1 TC2];
- [CC,P]=corrcoef(TC);
- r=CC(1:size(TC1,2),size(TC1,2)+1:size(TC1,2)+size(TC2,2));
- p=P(1:size(TC1,2),size(TC1,2)+1:size(TC1,2)+size(TC2,2));
- elseif size(TC1,2)==size(TC2,2)
- TC=[TC1;TC2];
- [CC,P]=corrcoef(TC.');
- r=CC(1:size(TC1,1),size(TC1,1)+1:size(TC1,1)+size(TC2,1));
- p=P(1:size(TC1,1),size(TC1,1)+1:size(TC1,1)+size(TC2,1));
- end
- end
- function m=DeNaNInf(m,Opt)
- if nargin==1
- Opt.Display=0;
- Opt.Fast=0;
- end
- if ~isfield(Opt,'Fast')
- Opt.Fast=0;
- end
- if ~isfield(Opt,'Display')
- Opt.Display=0;
- end
- if Opt.Fast
- if Opt.Display
- nNotFinite=sum(~isfinite(m(:)));
- end
- m(~isfinite(m))=mean(m(isfinite(m)));
- if Opt.Display
- disp([num2str(nNotFinite) ' Non-finite elements (' num2str(100*nNotFinite/numel(m)) '%) replaced by the mean'])
- end
- return
- end
- nNaN=sum(isnan(m(:)));
- m(isnan(m))=mean(m(~isnan(m)));
- if Opt.Display
- disp([num2str(nNaN) ' NaN elements (' num2str(100*nNaN/numel(m)) '%) replaced by the mean'])
- end
- nInf=sum(isinf(m(:)));
- m(isinf(m))=mean(m(~isinf(m)));
- if Opt.Display
- disp([num2str(nInf) ' Inf elements (' num2str(100*nInf/numel(m)) '%) replaced by the mean'])
- end
- function z=p2z(p)
- % See also z2p, normcdf, norminv, ranksum
- z=-norminv(p/2);
|