ck_ExampleVoxel.m 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. %% Set-up =================================================================
  2. % figure saving folder
  3. pngfld = fullfile(pwd,'fig_png'); [~,~] = mkdir(pngfld);
  4. svgfld = fullfile(pwd,'fig_svg'); [~,~] = mkdir(svgfld);
  5. % load result if it exists
  6. if isfile('ExampleVoxel.mat')
  7. LoadedResults=true;
  8. load('ExampleVoxel.mat');
  9. else
  10. LoadedResults=false;
  11. end
  12. homefld = pwd;
  13. cd ../../../
  14. SHARED_ROOT_FLD = pwd;
  15. cd(homefld)
  16. addpath(genpath(fullfile(SHARED_ROOT_FLD,...
  17. 'Analysis_code','LISA','OnServer','analyzePRF')));
  18. %% Load files =============================================================
  19. if ~LoadedResults
  20. RESULT_FILE = fullfile(SHARED_ROOT_FLD,'FitResults',...
  21. 'MRI','M01','linhrf_cv1_mhrf','pRF_Sess-linhrf_cv1_mhrf.mat');
  22. load(RESULT_FILE);
  23. modeltype = 'linear_hrf';
  24. DATA_FILE = fullfile(SHARED_ROOT_FLD,'Preprocessed_data','MRI',...
  25. 'M01','AllSessions-avg-cv.mat');
  26. load(DATA_FILE,'stim');
  27. load(DATA_FILE,'sess_wmeanBOLD');
  28. load(DATA_FILE,'sess_wmeanBOLD_inv');
  29. end
  30. %% Prep data and run modelfit =============================================
  31. if ~LoadedResults
  32. % Find voxel with highest R2
  33. R2_1 = result.R2(:,:,:,1);
  34. % get 3d coordinate idx of this voxel
  35. [vx,vy,vz] = ind2sub(size(R2_1), find(R2_1==max(R2_1(:)),1,'first'));
  36. vidx = find(R2_1==max(R2_1(:)),1,'first');
  37. % concat into shape analyzePRF wants
  38. for RUNNR = 1:length(sess_wmeanBOLD)
  39. fmri_data{(RUNNR-1)+RUNNR}=sess_wmeanBOLD{RUNNR}(vx,vy,vz,:); %#ok<*IDISVAR,*NODEF>
  40. stimulus{(RUNNR-1)+RUNNR}=[];
  41. for voln = 1:size(stim.norm{RUNNR},2)
  42. stimulus{(RUNNR-1)+RUNNR} = cat(3, stimulus{(RUNNR-1)+RUNNR}, stim.norm{RUNNR}{voln}); %#ok<*AGROW>
  43. end
  44. if exist('sess_wmeanBOLD_inv') && ~isempty(sess_wmeanBOLD_inv{RUNNR}) %#ok<*EXIST>
  45. fmri_data{RUNNR+RUNNR}=sess_wmeanBOLD_inv{RUNNR}(vx,vy,vz,:);
  46. stimulus{RUNNR+RUNNR}=[];
  47. for voln = 1:size(stim.inv{RUNNR},2)
  48. stimulus{RUNNR+RUNNR} = cat(3, stimulus{RUNNR+RUNNR}, stim.inv{RUNNR}{voln});
  49. end
  50. end
  51. end
  52. % clear empty cell for non-existing inverse stimuli
  53. if isempty(fmri_data{2})
  54. fmri_data(2)=[]; stimulus(2)=[];
  55. end
  56. % copy options from results, but exclude voxel mask
  57. options = result.options; options.vxs=[];
  58. TR = 2.5;
  59. % reshape data
  60. for i = 1:length(fmri_data)
  61. data{i}=squish(fmri_data{i},4)';
  62. end
  63. % run analyzePRF tool for this voxel only
  64. mri_result = analyzePRF_modeltype(stimulus,data,TR/2,options,modeltype);
  65. end
  66. %% Plot fit prediction and data together ==================================
  67. if ~LoadedResults
  68. res = [160 160]; resmx = max(res);
  69. hrf = mri_result.options.hrf; % HRF that was used in the model
  70. degs = mri_result.options.maxpolydeg; % max polynomial deg
  71. % Pre-compute cache for faster execution
  72. [d,xx,yy] = makegaussian2d(resmx,2,2,2,2);
  73. % Prepare the stimuli for use in the model
  74. stimulusPP = {};
  75. for p=1:length(stimulus)
  76. stimulusPP{p} = squish(stimulus{p},2)';
  77. stimulusPP{p} = [stimulusPP{p} p*ones(size(stimulusPP{p},1),1)];
  78. end
  79. % Define the model function.
  80. switch modeltype
  81. case 'css_hrf'
  82. % -- CSS --
  83. % define the model (parameters are R C S G N)
  84. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  85. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  86. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5)),options.hrf,dd(:,prod(res)+1));
  87. case 'linear_hrf'
  88. % -- Linear (skip second step where exponential is fit) --
  89. % define the model (parameters are R C S G)
  90. if options.allowneggain
  91. modelfun = @(pp,dd) conv2run(pp(4) * (dd*[vflatten(placematrix(zeros(res),...
  92. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  93. (2*pi*abs(pp(3))^2))); 0]),options.hrf,dd(:,prod(res)+1));
  94. else
  95. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  96. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  97. (2*pi*abs(pp(3))^2))); 0]),options.hrf,dd(:,prod(res)+1));
  98. end
  99. case 'dog_hrf'
  100. % -- DOG (center surround
  101. % define the model (parameters are R C S G sdratio normamp)
  102. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  103. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  104. (pp(6) .* makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)/pp(5)),abs(pp(3)/pp(5)),xx,yy,0,0) / (2*pi*abs(pp(3)/pp(5))^2)) ...
  105. )) ; 0]),options.hrf,dd(:,prod(res)+1));
  106. case 'css_ephys'
  107. % -- CSS without convolution with HRF
  108. % define the model (parameters are R C S G N)
  109. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  110. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  111. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5));
  112. case 'linear_ephys'
  113. % -- Linear without convolution with HRF
  114. % define the model (parameters are R C S G)
  115. if options.allowneggain
  116. modelfun = @(pp,dd) pp(4) * (dd*[vflatten(placematrix(zeros(res),...
  117. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  118. (2*pi*abs(pp(3))^2))); 0]);
  119. else
  120. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  121. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  122. (2*pi*abs(pp(3))^2))); 0]);
  123. end
  124. case 'dog_ephys'
  125. % -- DOG without convolution with HRF
  126. % define the model (parameters are R C S G sdratio normamp)
  127. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  128. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  129. (pp(6) .* makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)/pp(5)),abs(pp(3)/pp(5)),xx,yy,0,0) / (2*pi*abs(pp(3)/pp(5))^2)) ...
  130. )) ; 0]);
  131. end
  132. % Construct projection matrices that fit and remove the polynomials.
  133. polymatrix = {};
  134. for p=1:length(degs)
  135. polymatrix{p} = projectionmatrix(constructpolynomialmatrix(size(data{p},2),0:degs(p)));
  136. end
  137. % Which voxel should we inspect?
  138. vx = 1; % we only do one here, but let's stay flexible
  139. % Collect the data and the model fit. Remove slow trends in the data.
  140. datats = {}; modelts = {};
  141. for p=1:length(data)
  142. datats{p} = polymatrix{p}*data{p}(vx,:)';
  143. modelts{p} = polymatrix{p}*modelfun(mri_result.params(1,:,vx),single(stimulusPP{p}));
  144. end
  145. end
  146. %% Save the results =======================================================
  147. if ~LoadedResults
  148. save('ExampleVoxel','datats','modelts');
  149. end
  150. %% Visualize the results ==================================================
  151. f=figure; hold on;
  152. set(gcf,'Units','points','Position',[100 100 1000 300]);
  153. plot(datats{4},'ok','MarkerSize',6,'MarkerFaceColor',[.75 .75 .75])
  154. plot(modelts{4},'k','Linewidth',2)
  155. xlabel('Time (stimulus position)'); ylabel('BOLD signal');
  156. ax = axis; axis([.5 460+.5 ax(3:4)]);
  157. title('Time-series data MRI - Example voxel');
  158. legend({'Data','Model'})
  159. saveas(f,fullfile(pngfld, 'ExampleVoxel.png'));
  160. saveas(f,fullfile(svgfld, 'ExampleVoxel.svg'));
  161. close all;