VMHC.m 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. % VMHC.m
  2. % Note: requires Tools for NIfTI and ANALYZE image
  3. % (https://www.mathworks.com/matlabcentral/fileexchange/8797-tools-for-nifti-and-analyze-image)
  4. % Requires DPABI toolbox (http://rfmri.org/dpabi) for cluster inference
  5. main_path = '';
  6. useGlobalSignal = false;
  7. %% CALCULATE HOMOTOPIC VOXEL-WISE CORRELATIONS:
  8. % Load Mask and Get Voxel-wies Coordinates:
  9. % Middle 2 voxels: 138-139
  10. % Struct: .0703 x .0703 mm
  11. % Funct: .1406 x .5 mm (2 x 7.12 struct voxels equivalent)
  12. mask = load_nii(fullfile(main_path, 'mirrored_groupwise_template.nii'));
  13. ind = find(mask.img(:)>0); [x,y,z] = ind2sub(size(mask.img),ind);
  14. ind = x<139; numvox = sum(ind);
  15. x = x(ind); y = y(ind); z = z(ind);
  16. r_x = zeros(size(x)); for i = 1:length(x); r_x(i) = 139+(138-x(i)); end
  17. nscan = 19;
  18. % Perform denoising:
  19. Fs = .3124; TR = 1.0671*3; time = (TR:TR:TR*175)'; time_sq = time.^2;
  20. intercept = ones(175,1); homotopy_img = zeros(276,256,59,nscan); % voxel-wise homotopy data
  21. h_wait = waitbar(0,sprintf('Loading functional series %02g...',i));
  22. signals = cell(1,nscan); globalSignal = zeros(175,19);
  23. funct_path_outer = '';
  24. for i = 1:nscan
  25. % Check which physio data is usable:
  26. if all(physio_params{i}(:,2)==mode(physio_params{i}(:,2))) % iso is a constant, therefore unnecessary
  27. physio_use = physio_params{i}(:,1);
  28. else
  29. physio_use = physio_params{i};
  30. end
  31. % Load Functional:
  32. waitbar(0, h_wait,sprintf('Loading functional series %02g...',i));
  33. funct_path = fullfile(funct_path_outer,sprintf('funct_%02g',i));
  34. funct4D = zeros(276,256,59,175);
  35. for j = 6:180
  36. waitbar(j/180,h_wait);
  37. funct = load_nii(fullfile(funct_path,sprintf('s_R_mirror_funct3D_bird_%02g_time_%03g.nii',[i,j])));
  38. globalSignal(j-5, i) = nanmean(funct.img(mask.img(:)>0));
  39. funct4D(:,:,:,j-5) = funct.img;
  40. end
  41. % Calculate correlations:
  42. waitbar(0,h_wait,sprintf('Calculating homotopic correlations for series %02g...',i));
  43. signals{i}{1} = zeros(175,numvox); signals{i}{2} = zeros(175,numvox);
  44. for j = 1:numvox
  45. if rem(j,10000)==0; waitbar(j/numvox,h_wait); end
  46. signals{i}{1}(:,j) = squeeze(funct4D(x(j),y(j),z(j),:));
  47. signals{i}{2}(:,j) = squeeze(funct4D(r_x(j),y(j),z(j),:));
  48. if useGlobalSignal
  49. [~,~,signals{i}{1}(:,j)] = regress(signals{i}{1}(:,j),[intercept,time,time_sq,motion_params{i},CSF{i},physio_use,globalSignal(:,i)]);
  50. [~,~,signals{i}{2}(:,j)] = regress(signals{i}{2}(:,j),[intercept,time,time_sq,motion_params{i},CSF{i},physio_use,globalSignal(:,i)]);
  51. else
  52. [~,~,signals{i}{1}(:,j)] = regress(signals{i}{1}(:,j),[intercept,time,time_sq,motion_params{i},CSF{i},physio_use]);
  53. [~,~,signals{i}{2}(:,j)] = regress(signals{i}{2}(:,j),[intercept,time,time_sq,motion_params{i},CSF{i},physio_use]);
  54. end
  55. end
  56. [signals{i}{1},~,~] = bst_bandpass_filtfilt(signals{i}{1}',Fs,.008,.1,0,'iir');
  57. [signals{i}{2},~,~] = bst_bandpass_filtfilt(signals{i}{2}',Fs,.008,.1,0,'iir');
  58. signals{i}{1} = signals{i}{1}'; signals{i}{2} = signals{i}{2}';
  59. r = fast_corr(signals{i}{1},signals{i}{2});
  60. for j = 1:numvox
  61. homotopy_img(x(j),y(j),z(j),i) = r(j);
  62. homotopy_img(r_x(j),y(j),z(j),i) = r(j);
  63. end
  64. end; close(h_wait)
  65. %% t-statistics across subjects
  66. controlCovariates = true;
  67. covariates = [zscore(age), zscore(temps), zscore(iso)];
  68. % Calculate t-stats summarizing voxel-wise homotopy across birds/scans:
  69. homotopy_t = zeros(size(mask.img));
  70. age_t = homotopy_t;
  71. h_wait = waitbar(0,'Calculating t-statistics...');
  72. for i = 1:numvox
  73. if rem(i,1000)==0; waitbar(i/numvox, h_wait); end
  74. zvec = fisherz(squeeze(homotopy_img(x(i),y(i),z(i),:)));
  75. if controlCovariates
  76. lm = fitlm(covariates, zvec);
  77. homotopy_t(x(i),y(i),z(i)) = lm.Coefficients.tStat(1);
  78. homotopy_t(r_x(i),y(i),z(i)) = lm.Coefficients.tStat(1);
  79. age_t(x(i),y(i),z(i)) = lm.Coefficients.tStat(2);
  80. age_t(r_x(i),y(i),z(i)) = lm.Coefficients.tStat(2);
  81. else
  82. [~,~,~,stats] = ttest(zvec);
  83. homotopy_t(x(i),y(i),z(i)) = stats.tstat;
  84. homotopy_t(r_x(i),y(i),z(i)) = stats.tstat;
  85. end
  86. end; close(h_wait)
  87. % Save t-Stats Images:
  88. % Middle 2 voxels: 138-139
  89. img = mask; img.img = homotopy_t; img.img(137:140,:,:) = 0; % Discard 2 voxels on each side of midline
  90. if controlCovariates
  91. save_nii(img,fullfile(main_path,'t_stat_homotopy_controlled.nii'))
  92. img2 = mask; img2.img = age_t;
  93. save_nii(img2, fullfile(main_path,'t_stat_age_controlled.nii'))
  94. else
  95. save_nii(img, fullfile(main_path,'t_stat_homotopy.nii'))
  96. end
  97. img.img(135:142,:,:) = 0; % Discard 4 voxels on each side of midline
  98. if controlCovariates
  99. save_nii(img,fullfile(main_path,'t_stat_homotopy_8voxgap_controlled.nii'))
  100. img2.img(136:141,:,:) = 0;
  101. save_nii(img2, fullfile(main_path,'t_stat_age_8voxgap_controlled.nii'))
  102. else
  103. save_nii(img,fullfile(main_path,'t_stat_homotopy_8voxgap.nii'))
  104. end
  105. %% Run cluster inference: Homotopy
  106. % Extract the significant clusters of homotopy using cluster-extent method
  107. % on only 1 hemisphere (hemispheres are mirror images)
  108. if controlCovariates
  109. StatsImgFile = fullfile(main_path,'t_stat_homotopy_8voxgap_controlled.nii'); % more conservative midline deletion
  110. OutputName = fullfile(main_path,'T_homotopy_clusters_controlled.nii');
  111. else
  112. StatsImgFile = fullfile(main_path,'t_stat_homotopy_8voxgap.nii'); % more conservative midline deletion
  113. OutputName = fullfile(main_path,'T_homotopy_clusters.nii');
  114. end
  115. MaskFile = fullfile(main_path, 'mirrored_groupwise_template.nii');
  116. IsTwoTailed = false; VoxelPThreshold = .001; ClusterPThreshold = .05;
  117. Flag = 'T'; Df1 = 18; Df2 = []; VoxelSize = mask.hdr.dime.pixdim(2:4);
  118. Header = []; dLh = [];
  119. [Data_Corrected, ClusterSize, Header] = y_GRF_Threshold(StatsImgFile, ...
  120. VoxelPThreshold,IsTwoTailed,ClusterPThreshold,OutputName,MaskFile,...
  121. Flag,Df1,Df2,VoxelSize,Header, dLh);
  122. y_ClusterReport(Data_Corrected, Header, 18) % 18 is the cluster (voxel neighbor) connectivity criterion
  123. % Save bilateral version of cluster-thresholded t-stats:
  124. if controlCovariates
  125. clusterT = load_nii(fullfile(main_path,'ClusterThresholded_T_homotopy_clusters_controlled.nii'));
  126. clusterT.img(143:276,:,:) = clusterT.img(134:-1:1,:,:); % 135:142 voxels were discarded, so start from 143:(134+142)
  127. save_nii(clusterT,fullfile(main_path,'T_homotopy_clusters_bilat_controlled.nii'));
  128. else
  129. clusterT = load_nii(fullfile(main_path,'ClusterThresholded_T_homotopy_clusters.nii'));
  130. clusterT.img(143:276,:,:) = clusterT.img(134:-1:1,:,:); % 135:142 voxels were discarded, so start from 143:(134+142)
  131. save_nii(clusterT,fullfile(main_path,'T_homotopy_clusters_bilat.nii'));
  132. end