DVARSCalc_octave.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. function [DVARS,Stat]=DVARSCalc_octave(V0,varargin)
  2. %[DVARS,Stat]=DVARSCalc_octave(V0,varargin)
  3. % Statistical inference on DVars component to identify corrupted scans.
  4. %
  5. % YOU NEED to install statistics package prior to running this code:
  6. % Here is where to download it: https://octave.sourceforge.io/statistics/
  7. %
  8. % octave:1> pkg install -forge io
  9. % octave:2> pkg load statistics
  10. %
  11. %%%%INPUTS:
  12. %
  13. % V0: Can be (1) a string indicating the path to the
  14. % nifti/cifti file (2) a numerical matrix of size IxT.
  15. % Where I is number of voxels (I=Nx x Ny x Nz) and T is
  16. % number of data-points.
  17. %
  18. % Following arguments are optional:
  19. %
  20. % 'TestMethod': Should be followed by 'Z' for Z-test and 'X2' for
  21. % Chi^2 test [default:'X2'].
  22. % e.g. [DVARS,Stat]=DVARSCalc(V0,'TestMethod','X2')
  23. %
  24. % 'VarType': Method for robust estimate of variance. It can be either
  25. % 'IQR' for full IQR or 'hIQR' for half-IQR.
  26. % [default:'hIQR']
  27. % e.g. [DVARS,Stat]=DVARSCalc(V0,'VarType','IQR')
  28. %
  29. % 'MeanType': Method for robust estimate of expected value. The value
  30. % should be a digit corresponding to the order of
  31. % following methods [default:'median']:
  32. % 'sig2bar','sig2median','median','sigbar2','xbar'.
  33. % For example: MeanType=3 means the method to estimate
  34. % robust expected value is empirical median.
  35. % e.g. [DVARS,Stat]=DVARSCalc(V0,'MeanType',3)
  36. %
  37. % 'TransPower': Power of transformation [default:1/3]
  38. % e.g. [DVARS,Stat]=DVARSCalc(V0,'TestMethod','X2','TransPower',1/3)
  39. %
  40. % 'RDVARS': By passing this arg, the function generates the
  41. % relative DVARS (RDVARS). NB! this might take a while
  42. % due to robust estimate of autocorrelation.
  43. % e.g. [DVARS,Stat]=DVARSCalc(V0,'RDVARS')
  44. %
  45. % 'verbose': Set to 1 if you need the log of runing code [default:1]
  46. % e.g. [DVARS,Stat]=DVARSCalc(V0,'verbose',1)
  47. %
  48. % 'Norm' Intensity normalisation to a given scale.
  49. % e.g.: [V,Stat]=DSEvars(V0,'Norm',100)
  50. %
  51. % 'Scale' Scale the intensity between the data-sets.
  52. % e.g.: [V,Stat]=DSEvars(V0,'Scale',1/10)
  53. %
  54. %%%%OUTPUTS:
  55. %
  56. % DVARS: a vector of size 1xT-1 of classic DVARS measure
  57. % Stat: a structure contains all the details of the statistical inference
  58. % including the standardised DVARS, pvals and further summary stats.
  59. %
  60. %%%%NOTES:
  61. % 1) It is recommended to only use time series of intra-cranial voxels as
  62. % inclusding the extra-cranial may inflate the variance. You can use
  63. % 'bet' in FSL package to remove the extra-cranial areas. The scripts
  64. % automatically remove the zero/NaN voxels.
  65. %
  66. % 2) If the input is set to be a CIFTI file, you require Nifti_Util
  67. % (provided in the directory). For input of CIFTI you require to
  68. % addpath the FieldTrip toolbox from:
  69. % http://www.fieldtriptoolbox.org/reference/ft_read_cifti
  70. %
  71. %
  72. %
  73. %%%%EXAMPLE:
  74. %
  75. % For iid case:
  76. %
  77. % I=4e4; T=1200; Y=randn(I,T);
  78. % [DVARS,Stat]=DVARSCalc(Y,'VarType','hIQR','TestMethod','X2','TransPower',1/3);
  79. % find(Stat.pvals<0.05./(T-1) & Stat.DeltapDvar>5) %print corrupted DVARS data-points
  80. %
  81. % For the case with simulated ouliers:
  82. %
  83. % I=4e4; T=1200;
  84. % Y=randn(I,T);
  85. % Idx_OL=randi(T);
  86. % Y(:,Idx_OL)=Y(:,Idx_OL)+1;
  87. % [DVARS,Stat]=DVARSCalc(Y,'VarType','hIQR','TestMethod','X2','TransPower',1/3);
  88. % find(Stat.pvals<0.05./(T-1) & Stat.DeltapDvar>5) %print corrupted DVARS data-points
  89. %
  90. % To generate a binary regressor, where the significant DVARS data-points
  91. % are 1 and the remaining data-points are 0 you can use DVARSCalc.m as
  92. % below:
  93. %
  94. % PracticalSigThr = 5;
  95. % idx = find(Stat.pvals<0.05./(T-1) & Stat.DeltapDvar>PracticalSigThr);
  96. % DVARSreg = zeros(T0,1);
  97. % DVARSreg(idx) = 1;
  98. % DVARSreg(idx+1) = 1;
  99. %
  100. % Variable PracticalSigThr should be chosen manually for a study. For
  101. % example in case of HCP, we found 5% is a reasonable threshold to
  102. % identify the practically significant data-points. Note that pratically
  103. % significant data-points are subset of statistically significant
  104. % data-points.
  105. %
  106. %%%%REFERENCES
  107. %
  108. % Afyouni S. & Nichols T.E., Insights and inference for DVARS, 2017
  109. % http://www.biorxiv.org/content/early/2017/04/06/125021.1
  110. %
  111. % Soroosh Afyouni & Thomas Nichols, UoW, Feb 2017
  112. %
  113. % https://github.com/asoroosh/DVARS
  114. % http://warwick.ac.uk/tenichols
  115. %
  116. % Please report bugs to srafyouni@gmail.com
  117. %_________________________________________________________________________
  118. fnnf=mfilename; if ~nargin; help(fnnf); return; end; clear fnnf;
  119. %_________________________________________________________________________
  120. %External updates:
  121. % Brunno M. Campos <brunno@fcm.unicamp.br>: int 16bit to double
  122. %ParCheck------------------------------------------------------------------
  123. NDVARS_X2 = 'N/A'; NDVARS_Z = 'N/A'; RelDVARS = 'N/A';
  124. testmeth = 'X2'; nflag = 0;
  125. dd = 1; verbose = 1;
  126. WhichExpVal = 3; WhichVar = 3;
  127. ACf_idx = []; gsrflag = 0;
  128. md = []; scl = [];
  129. % Input Check--------------------------------------------------------------
  130. if sum(strcmpi(varargin,'gsrflag'))
  131. gsrflag = varargin{find(strcmpi(varargin,'gsrflag'))+1};
  132. end
  133. %
  134. if sum(strcmpi(varargin,'verbose'))
  135. verbose = varargin{find(strcmpi(varargin,'verbose'))+1};
  136. end
  137. %
  138. if sum(strcmpi(varargin,'TestMethod'))
  139. testmeth = varargin{find(strcmpi(varargin,'TestMethod'))+1};
  140. if strcmpi(testmeth,'Z')
  141. WhichExpVal = 3;
  142. end
  143. end
  144. %
  145. if sum(strcmpi(varargin,'transpower'))
  146. dd = varargin{find(strcmpi(varargin,'transpower'))+1};
  147. end
  148. %
  149. if sum(strcmpi(varargin,'RDVARS'))
  150. %nflag = varargin{find(strcmpi(varargin,'RDVARS'))+1};
  151. nflag = 1;
  152. end
  153. %
  154. if sum(strcmpi(varargin,'MeanType'))
  155. WhichExpVal = varargin{find(strcmpi(varargin,'MeanType'))+1};
  156. end
  157. %
  158. if sum(strcmpi(varargin,'VarType'))
  159. switch varargin{find(strcmpi(varargin,'VarType'))+1}
  160. case 'IQR'
  161. WhichVar = 2;
  162. case 'hIQR'
  163. WhichVar = 3;
  164. otherwise
  165. error('Unknown VarType! Choose either IQR and hIQR')
  166. end
  167. end
  168. %
  169. if sum(strcmpi(varargin,'norm'))
  170. scl = varargin{find(strcmpi(varargin,'norm'))+1};
  171. end
  172. if sum(strcmpi(varargin,'scale'))
  173. scl = varargin{find(strcmpi(varargin,'scale'))+1};
  174. md = 1;
  175. end
  176. %
  177. if sum(strcmpi(varargin,'tail'))
  178. tsstr = varargin{find(strcmpi(varargin,'tail'))+1};
  179. if strcmpi(tsstr,'both')
  180. warning('The test was designed two tailed to detect downspikes!')
  181. tsflag = 1;
  182. WhichVar = 2; %IQR
  183. WhichExpVal = 3; %Z
  184. testmeth = 'Z';
  185. else
  186. tsflag=0;
  187. end
  188. else
  189. tsflag=0;
  190. end
  191. % Add toolbox to open the images-------------------------------------------
  192. if isempty(strfind(path,'Nifti_Util'))
  193. if verbose; disp('-Nifti_Util added to the path.'); end;
  194. addpath(genpath('Nifti_Util'));
  195. end
  196. %--------------------------------------------------------------------------
  197. if ischar(V0)
  198. [ffpathstr,ffname,ffext]=fileparts(V0);
  199. if verbose; disp(['-Path to the image is: ' ffpathstr]); end;
  200. if ~isempty(strfind(ffname,'.dtseries')) || ~isempty(strfind(ffext,'.dtseries'))
  201. if verbose; disp(['--File is CIFTI: ' ffname ffext]); end;
  202. V1=ft_read_cifti(V0);
  203. V2=V1.dtseries;
  204. I0=size(V2,1); T0=size(V2,2);
  205. Y=V2; clear V2 V1;
  206. elseif isempty(strfind(ffname,'.dtseries')) || ~isempty(strfind(ffname,'.nii'))
  207. if verbose; disp(['--File is NIFTI: ' ffname ffext]); end;
  208. V1 = load_untouch_nii(V0);
  209. V2 = V1.img;
  210. X0 = size(V2,1); Y0 = size(V2,2); Z0 = size(V2,3); T0 = size(V2,4);
  211. I0 = prod([X0,Y0,Z0]);
  212. Y = reshape(V2,[I0,T0]); clear V2 V1;
  213. else
  214. error('Unknown input image.')
  215. end
  216. if verbose; disp('-Image loaded.'); end;
  217. elseif isnumeric(V0) %&& size(V0,1)>size(V0,2)
  218. if verbose; disp('-Input is a Matrix.'); end;
  219. if size(V0,1)<=size(V0,2)
  220. warning('Check the input, matrix should be in form of IxT, where I=XxYxZ!');
  221. end
  222. Y = double(V0); %Just to ensure it works with int 16bit as well.
  223. I0= size(Y,1); T0 = size(Y,2);
  224. %elseif isnumeric(V0) && size(V0,1)<=size(V0,2)
  225. % if verbose; disp('-Input is a Matrix.'); end;
  226. % error('Check the input, matrix should be in form of IxT, where I=XxYxZ!');
  227. end
  228. Y = double(Y);%to work with int 16bit as well.
  229. %Remove voxels of zeros/NaNs----------------------------------------------
  230. nan_idx = find(isnan(sum(Y,2)));
  231. zeros_idx = find(sum(Y,2)==0);
  232. idx = 1:I0;
  233. idx([nan_idx;zeros_idx]) = [];
  234. Y([nan_idx;zeros_idx],:) = [];
  235. I1 = size(Y,1); %update number of voxels
  236. if verbose; disp(['-Extra-cranial areas removed: ' num2str(size(Y,1)) 'x' num2str(size(Y,2))]); end;
  237. mvY0 = mean(Y,2); % untouched grand mean
  238. % Intensity Normalisation----------------------------------------------
  239. IntnstyScl = @(Y,md,scl) (Y./md).*scl;
  240. if ~isempty(scl) && isempty(md)
  241. md = median(mean(Y,2)); %NB median of the mean image
  242. Y = IntnstyScl(Y,md,scl);
  243. if verbose; disp(['-Intensity Normalised by, scale: ' num2str(scl) ' & median: ' num2str(round(md,2)) '.']); end;
  244. elseif ~isempty(scl) && ~isempty(md)
  245. assert(md==1,'4D mean in scalling cannot be anything other than 1!')
  246. Y = IntnstyScl(Y,md,scl);
  247. if verbose; disp(['-Intensity Scaled by ' num2str(scl) '.']); end;
  248. elseif isempty(scl) && isempty(md)
  249. if verbose; disp('-No normalisation/scaling has been set!'); end;
  250. else
  251. error('IntnstyScl :: Something is wrong with param re intensity normalisation')
  252. end
  253. %Centre the data-----------------------------------------------------------
  254. mvY = mean(Y,2);
  255. dmeaner = repmat(mvY,[1,T0]);
  256. Y = Y-dmeaner; clear dmeaner
  257. if verbose; disp(['-Data centred. Untouched Grand Mean: ' num2str(mean(mvY0)) ', Post-norm Grand Mean: ' num2str(mean(mvY))]); end;
  258. %Data GSRed--------------------------------ONLY FOR TEST-------------------
  259. %fcn_GSR = @(Y) Y'-(mean(Y,2)*(pinv(mean(Y,2))*Y'));
  260. %gsrflag=1;
  261. if gsrflag
  262. Y = fcn_GSR(Y);
  263. if verbose; disp('-Data GSRed.'); end;
  264. end
  265. %----------------------------------------^^ONLY FOR TEST-------------------
  266. %*************************************************************************
  267. %This part needs attention:
  268. %1) The test should be switched to Z-test in case of downspikes.
  269. %2) Only IQRsd should be used in case of two tailed
  270. %3) CLEAN this section
  271. %funcs-----
  272. IQRsd = @(x) (quantile(x,0.75)-quantile(x,0.25))./1.349;
  273. H_IQRsd = @(x) (quantile(x,0.5)-quantile(x,0.25))./1.349*2;
  274. %--
  275. if tsflag
  276. Zstat = @(x,m,s) abs((x-m)/s);
  277. else
  278. Zstat = @(x,m,s) (x-m)/s;
  279. end
  280. Zp = @(x,m,s) 1-normcdf(Zstat(x,m,s));
  281. %--
  282. X2stat = @(x,m,s) 2*m/s^2*x;
  283. X2df = @(m,s) 2*m^2/s^2;
  284. % https://github.com/asoroosh/DVARS/issues/7
  285. % Octave doesn't have a upper tail option for chi2cdf():
  286. % chi2cdf(..., 'upper') == (1 - chi2cdf(...))
  287. X2p = @(x,m,s) 1-chi2cdf(X2stat(x,m,s),X2df(m,s));
  288. X2p0 = @(x,m,s) (X2stat(x,m,s)-X2df(m,s))/sqrt(2*X2df(m,s));
  289. %*************************************************************************
  290. %Relative DVARS--------------------------------------------------------
  291. DY = diff(Y,1,2);
  292. DVARS = sqrt(sum(DY.^2)./I1);
  293. if nflag
  294. if verbose; disp(['-Robust estimate of autocorrelation...']); end;
  295. Rob_S = IQRsd(Y');
  296. AC = zeros(1,I1);
  297. for iv=1:I1
  298. if (~mod(iv,10e4) && verbose); disp(['--voxel: ' num2str(iv)]); end;
  299. AC(iv) = madicc(Y(iv,1:end-1),Y(iv,2:end));
  300. end
  301. ACf_idx = isnan(AC);
  302. if any(ACf_idx)
  303. AC(ACf_idx) = []; Rob_S(ACf_idx) = [];
  304. if verbose; disp(['--AC robust estimate was failed on ' num2str(sum(ACf_idx)) ' voxels.']); end;
  305. end
  306. RelDVARS = DVARS./(sqrt((sum(2*(1-AC).*(Rob_S.^2)))./I1));
  307. end
  308. %Inference-----------------------------------------------------------------
  309. DVARS2 = mean(DY.^2);
  310. Rob_S_D = IQRsd(DY')';
  311. MeanNms = {'sig2bar','sig2median','median','sigbar2','xbar'};
  312. Mn = [mean(Rob_S_D.^2),median(Rob_S_D.^2),median(DVARS2),...
  313. mean(Rob_S_D).^2,mean(DVARS2)];
  314. Z = DVARS2.^dd;
  315. M_Z = median(Z);
  316. VarNms = {'S2' , 'IQRd' , 'hIQRd'};
  317. Va = [var(DVARS2) , (1/dd*M_Z^(1/dd-1)*IQRsd(Z))^2 , (1/dd*M_Z^(1/dd-1)*H_IQRsd(Z))^2];
  318. if verbose
  319. disp('-Settings: ')
  320. disp(['--Test Method: ' testmeth]);
  321. disp(['--ExpVal method: ' MeanNms{WhichExpVal}]);
  322. disp(['--VarEst method: ' VarNms{WhichVar}]);
  323. disp(['--Power Transformation: ' num2str(dd)]);
  324. end;
  325. switch testmeth
  326. case 'Z'
  327. M_DV2 = Mn(WhichExpVal);
  328. S_DV2 = sqrt(Va(WhichVar));
  329. Zval = Zstat(DVARS2,M_DV2,S_DV2);
  330. Pval = Zp(DVARS2,M_DV2,S_DV2);
  331. %Pval(Pval==0) = 10e-15; %There is no p-value=0!!
  332. nu = []; c = []; NDVARS_X20=[];
  333. NDVARS_Z=Zval;
  334. case 'X2'
  335. M_DV2 = Mn(WhichExpVal);
  336. S_DV2 = sqrt(Va(WhichVar));
  337. Pval = X2p(DVARS2,M_DV2,S_DV2);
  338. Zval = Zstat(DVARS2,M_DV2,S_DV2);
  339. c = X2stat(DVARS2,M_DV2,S_DV2);
  340. nu = X2df(M_DV2,S_DV2); %Spatial EDF
  341. NDVARS_X2 = -norminv(Pval);
  342. NDVARS_X20 = X2p0(DVARS2,M_DV2,S_DV2);
  343. %only substitute the infs, the rest is better done in matlab.
  344. NDVARS_X2(isinf(NDVARS_X2)) = NDVARS_X20(isinf(NDVARS_X2));
  345. otherwise
  346. error('Unknown test method!')
  347. end
  348. if verbose
  349. % ***array2table is not available in Octave***
  350. % fprintf('\nSettings: TestMethod=%s I=%d T=%d \n',testmeth,I1,T0)
  351. % disp('----Expected Values----------------------------------')
  352. % disp(array2table(Mn,'VariableNames',MeanNms));...
  353. % disp('----Variances----------------------------------------')
  354. % disp(array2table(Va,'VariableNames',VarNms));...
  355. disp(['Means: '])
  356. cnt = 1;
  357. for MeanNmsLab = MeanNms
  358. disp([MeanNmsLab{1} ' : ' num2str(Mn(cnt))]);
  359. cnt = cnt+1;
  360. end
  361. disp(['Variances: '])
  362. cnt = 1;
  363. for VarNmsLab = VarNms
  364. disp([VarNmsLab{1} ' : ' num2str(Va(cnt))]);
  365. cnt = cnt+1;
  366. end
  367. end
  368. Stat.DVARS2 = DVARS2;
  369. %Test stats
  370. Stat.E = Mn;
  371. Stat.S = sqrt(Va);
  372. Stat.nu = nu; %effective spatial degrees of freedom
  373. Stat.c = c;
  374. Stat.pvals = Pval;
  375. Stat.Zval = Zval;
  376. Stat.Mu0 = mean(IQRsd(Y));
  377. Stat.Avar = mean(mean(Y.^2)); % << This is A-var of DSEvar.m!
  378. %Standardised
  379. Stat.RDVARS = RelDVARS;
  380. Stat.SDVARS_X2 = NDVARS_X2;
  381. %Stat.SDVARS_X20 = NDVARS_X20;
  382. Stat.SDVARS_Z = NDVARS_Z;
  383. Stat.DeltapDvar = (DVARS2-median(DVARS2))./(4*Stat.Avar)*100;
  384. %A similar measure, as DeltapDvar is estimated via DSE variance in DSEvar.m as:
  385. % Stat.DeltapDvar = (V.Dvar_ts-median(V.Dvar_ts))/mean(V.Avar_ts)*100;
  386. %General info
  387. Stat.dim = [I1 T0];
  388. Stat.dim0 = [I0 T0];
  389. Stat.RobAC_Fail = find(ACf_idx);
  390. Stat.GrandMean = mean(mvY);
  391. Stat.GrandMean0 = mean(mvY0);
  392. %Config
  393. Stat.Config.TestMeth = testmeth;
  394. Stat.Config.PowerTrans = dd;
  395. Stat.Config.WhichExpVal = MeanNms{WhichExpVal};
  396. Stat.Config.WhichVar = VarNms{WhichVar};
  397. Stat.Config.gsrflag = gsrflag;
  398. Stat.Config.Median2Norm = md;
  399. Stat.Config.Scale2Norm = scl;
  400. Stat.Config.VoxRmvd = [nan_idx;zeros_idx];
  401. function rmad = madicc(x,y)
  402. % Median Absolute Deviation Intraclass Correlation Coefficient
  403. %
  404. % Impliments Median Absolute Deviation Correlation Coefficient, (as
  405. % described in Shevlyakov & Smirnov (2011)), modified to be the
  406. % intraclass version of correlation. The (non-intrasclass)
  407. % estimate is
  408. % r = ( mad(Sp)^2 - mad(Sm)^2 ) / ( mad(Sp)^2 + mad(Sm)^2 )
  409. % where
  410. % Sp = (x-m(x))/mad(x) + (y-m(y))/mad(y);
  411. % Sm = (x-m(x))/mad(x) - (y-m(y))/mad(y);
  412. % and m() is median and mad() is the median absolute deviation,
  413. % mad(x) = m(abs(x-m(x)))
  414. %
  415. % For intraclass correlation we assume mad(x)=mad(y) and so the divisors
  416. % cancel; further, we find a common estimate of the median mm=m([x,y])
  417. % can compute Sp & Sm as:
  418. % Sp = (x-mm) + (y-mm);
  419. % Sm = (x-mm) - (y-mm);
  420. %
  421. %
  422. % REFERENCES
  423. %
  424. % Shevlyakov, G., & Smirnov, P. (2011). Robust estimation of a
  425. % correlation coefficient: an attempt of survey. Australian & New
  426. % Zealand Journal of Statistics, 40(1), 147–156.
  427. %
  428. % Kharin, Y. S., & Voloshko, V. A. (2011). Robust estimation of AR
  429. % coefficients under simultaneously influencing outliers and missing
  430. % values. Journal of Statistical Planning and Inference, 141(9),
  431. % 3276–3288.
  432. %
  433. % 2014-07-08
  434. % Thomas Nichols http://warwick.ac.uk/tenichols
  435. I=find(all(~isnan([x(:) y(:)]),2));
  436. if isempty(I)
  437. rmad=NaN;
  438. else
  439. mx = median(x(I));
  440. my = median(y(I));
  441. Sp = (x(I)-mx) + (y(I)-my);
  442. Sm = (x(I)-mx) - (y(I)-my);
  443. madSp = median(abs(Sp-median(Sp)));
  444. madSm = median(abs(Sm-median(Sm)));
  445. if madSp==0 && madSm==0
  446. rmad = NaN;
  447. else
  448. rmad = (madSp^2 - madSm^2)/(madSp^2 + madSm^2);
  449. end
  450. end
  451. function gsrY=fcn_GSR(Y)
  452. %Global Signal Regression
  453. %Inspired by FSLnets
  454. %For the fMRIDiag, it needs to be transposed.
  455. Y=Y';
  456. mgrot=mean(Y,2);
  457. gsrY=Y-(mgrot*(pinv(mgrot)*Y));
  458. gsrY=gsrY';
  459. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  460. %%%%%%%%%%%%%OLD CODE%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  461. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  462. % if strcmp(DVARS2Smethod,'TR1')
  463. % S_dvars2=diff(quantile(DVARS2,[0.25 0.75]))./1.349;
  464. % nu=(2*E_dvars2.^2)./(S_dvars2.^2);
  465. % c=(2*E_dvars2)./(S_dvars2.^2);
  466. % critval=chi2inv(1-alp/T,nu);
  467. % pvals=1-chi2cdf(DVARS2*c,nu);
  468. % pvals_adj=pvals.*T;
  469. % %disp('Corrupted volumes:')
  470. % RemoveMe=find(DVARS2*c>=critval);
  471. % elseif strcmp(DVARS2Smethod,'TR2')
  472. % YD=diff(Y');
  473. % S_dvars2=2*(diff(quantile(sum(YD(3:T-1,:).*YD(1:T-3,:),2)/I,[0.25 0.75]))./1.349);
  474. % nu=(2*E_dvars2.^2)./(S_dvars2.^2);
  475. % c=(2*E_dvars2)./(S_dvars2.^2);
  476. % critval=chi2inv(1-alp/T,nu);
  477. % pvals=1-chi2cdf(DVARS2*c,nu);
  478. % pvals_adj=pvals.*T;
  479. % RemoveMe=find(DVARS2*c>=critval);
  480. % elseif strcmp(DVARS2Smethod,'TransformationChi2')
  481. % if d_tran==1
  482. % S_dvars2=diff(quantile(DVARS2,[0.25 0.75]))./1.349;
  483. %
  484. % else
  485. % Z = DVARS2.^d_tran;
  486. % S_Z=diff(quantile(Z,[0.25 0.75]))./1.349; %robust std of Z
  487. % E_dvars2=E_dvars2^(1/d_tran);
  488. % S_dvars2=(1/d_tran*E_dvars2^(1/d_tran-1)*S_Z);
  489. % end
  490. % c=2*E_dvars2/S_dvars2^2;
  491. % nu=2*E_dvars2^2/S_dvars2^2;
  492. %
  493. % %pvals=1-normcdf((DVARS2-E_dvars2)/S_dvars2);
  494. % pvals=1-chi2cdf(DVARS2*c,nu);
  495. % pvals_adj=pvals.*T;
  496. % RemoveMe=find(pvals_adj<0.05);
  497. % critval=[];
  498. %
  499. % elseif strcmp(DVARS2Smethod,'TransformationNormal')
  500. % Z=(DVARS2./E_dvars2).^d_tran;
  501. % S_Z=diff(quantile(Z,[0.25 0.75]))./1.349; %robust std of Z
  502. % S_dvars2=sqrt((1./(E_dvars2.^2))*(((1./d_tran)-1).^2)*(S_Z.^2));
  503. %
  504. % Zs=(DVARS2.^d_tran-E_dvars2.^d_tran)./S_dvars2;
  505. % pvals=2*(normcdf(-abs(Zs),0,1));
  506. % pvals_adj=pvals.*T;
  507. % RemoveMe=find(pvals_adj<0.05);
  508. % c=[]; nu=[]; critval=[];
  509. % else
  510. % disp('Robust STD method for DVARS2 has not been identified correctly!')
  511. % end
  512. %MnTrue=2*mean(SD.^2);
  513. %VaTrue=8*mean(SD.^4)/I;
  514. %Stat.iid.Mn=MnTrue;
  515. %Stat.iid.Vn=VaTrue;
  516. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  517. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  518. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%