ck_ExampleElectrode.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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('ExampleElectrode.mat')
  7. LoadedResults=true;
  8. load('ExampleElectrode.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. modeltype = 'linear_ephys'; TR=0.5;
  19. %% Load files =============================================================
  20. if ~LoadedResults
  21. RESULT_FILE = fullfile(SHARED_ROOT_FLD,'FitResults',...
  22. 'EPHYS','Combined','AllFits_ephys_cv1.mat');
  23. load(RESULT_FILE);
  24. RES = R(1).model(1);
  25. maxi=[];
  26. for i=1:8
  27. maxi = [maxi; i max(RES.MUA(i).R2(:,1)) ...
  28. find(RES.MUA(i).R2(:,1)==max(RES.MUA(i).R2(:,1)),1,'first')];
  29. end
  30. lidx = find(maxi(:,2)==max(maxi(:,2)),1,'first');
  31. inst_elec = [lidx max(lidx,3)];
  32. inst=lidx; ch=inst_elec(2);
  33. %mMUA and mLFP hold the data
  34. muafile = fullfile(SHARED_ROOT_FLD,'Preprocessed_data','EPHYS',...
  35. 'M03','mua',['M03_20180807_B2_array_' num2str(lidx) '_mMUA.mat']);
  36. lfpfile = fullfile(SHARED_ROOT_FLD,'Preprocessed_data','EPHYS',...
  37. 'M03','lfp',['M03_20180807_B2_array_' num2str(lidx) '_mLFP.mat']);
  38. stimfile = fullfile(SHARED_ROOT_FLD,'Preprocessed_data','EPHYS',...
  39. 'M03','stim','M03_STIM.mat']);
  40. load(muafile); load(lfpfile);
  41. warning off; load(stimfile); warning on;
  42. cv=0;
  43. end
  44. %% Prep data and run modelfit =============================================
  45. if ~LoadedResults
  46. mua_data={};
  47. fprintf('Concatenating stimuli and volumes...\n');
  48. mua_data{1} = []; mua_data{1} = cat(1,mua_data{1},mMUA(ch).bar);
  49. stimulus{1}=[];
  50. for imgnr=1:length(STIM.img)
  51. stimulus{1}=cat(3,stimulus{1},STIM.img{imgnr});
  52. end
  53. inv_idx = [150:-1:121 180:-1:151 210:-1:181 240:-1:211];
  54. mua_data2{1}=[];
  55. for elec = 1:size(mua_data{1},1)
  56. mua_data2{1} = cat(1,mua_data2{1},...
  57. mean([mua_data{1}(elec,1:120);mua_data{1}(elec,inv_idx)],1));
  58. end
  59. mua_data_org = mua_data; mua_data = mua_data2; clear ephys_data2
  60. stimulus{1}=[];
  61. for imgnr=1:length(STIM.img)
  62. % RESAMPLE STIMULUS >> 295 x 295 means 10px = 1 deg
  63. rsIMG = imresize(STIM.img{imgnr} ,[295 295]);
  64. stimulus{1}=cat(3,stimulus{1},rsIMG);
  65. end
  66. options = R(1).model(1).MUA(1).options;
  67. options.xvalmode = cv;
  68. options.maxpolydeg = 0;
  69. options.vxs = 1;
  70. % run modelfit
  71. result_mua= analyzePRF_modeltype(stimulus,mua_data_org,TR,options,modeltype);
  72. for fb=1:5 % loop over frequency bands
  73. % concatenate -----
  74. lfp_data={};
  75. fprintf(['Frequency band ' num2str(fb) '\n']);
  76. fprintf('Concatenating stimuli and volumes...\n');
  77. lfp_data{1} = [];
  78. lfp_data{1}=cat(1,lfp_data{1},...
  79. mLFP(ch).freq(fb).bar - mLFP(ch).freq(fb).BL);
  80. inv_idx = [150:-1:121 180:-1:151 210:-1:181 240:-1:211];
  81. lfp_data2{1}=[];
  82. for elec = 1:size(lfp_data{1},1)
  83. lfp_data2{1} = cat(1,lfp_data2{1},...
  84. mean([lfp_data{1}(elec,1:120);lfp_data{1}(elec,inv_idx)],1));
  85. end
  86. lfp_data_org{fb} = lfp_data; lfp_data = lfp_data2; clear lfp_data2
  87. result_lfp(fb) = analyzePRF_modeltype(stimulus,lfp_data_org{fb},TR,options,modeltype);
  88. end
  89. end
  90. %% Save the results =======================================================
  91. if ~LoadedResults
  92. save('ExampleElectrode','TR','stimulus','modeltype',...
  93. 'mua_data_org','result_mua',...
  94. 'lfp_data_org','result_lfp');
  95. end
  96. %% Plot fit prediction and data together ==================================
  97. % === MUA ===
  98. data = mua_data_org; tr=TR;
  99. res = [size(stimulus{1},1) size(stimulus{1},2)];
  100. resmx = max(res);
  101. degs = result_mua.options.maxpolydeg;
  102. [d,xx,yy] = makegaussian2d(resmx,2,2,2,2);
  103. options = result_mua.options;
  104. stimulusPP = {};
  105. for p=1:length(stimulus)
  106. stimulusPP{p} = squish(stimulus{p},2)'; % this flattens the image so that the dimensionality is now frames x pixels
  107. stimulusPP{p} = [stimulusPP{p} p*ones(size(stimulusPP{p},1),1)]; % this adds a dummy column to indicate run breaks
  108. end
  109. switch modeltype
  110. case 'css_hrf'
  111. % -- CSS --
  112. % define the model (parameters are R C S G N)
  113. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  114. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  115. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5)),options.hrf,dd(:,prod(res)+1));
  116. case 'linear_hrf'
  117. % -- Linear (skip second step where exponential is fit) --
  118. % define the model (parameters are R C S G)
  119. if options.allowneggain
  120. modelfun = @(pp,dd) conv2run(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]),options.hrf,dd(:,prod(res)+1));
  123. else
  124. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  125. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  126. (2*pi*abs(pp(3))^2))); 0]),options.hrf,dd(:,prod(res)+1));
  127. end
  128. case 'dog_hrf'
  129. % -- DOG (center surround
  130. % define the model (parameters are R C S G sdratio normamp)
  131. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  132. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  133. (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)) ...
  134. )) ; 0]),options.hrf,dd(:,prod(res)+1));
  135. case 'css_ephys'
  136. % -- CSS without convolution with HRF
  137. % define the model (parameters are R C S G N)
  138. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  139. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  140. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5));
  141. case 'linear_ephys'
  142. % -- Linear without convolution with HRF
  143. % define the model (parameters are R C S G)
  144. if options.allowneggain
  145. modelfun = @(pp,dd) pp(4) * (dd*[vflatten(placematrix(zeros(res),...
  146. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  147. (2*pi*abs(pp(3))^2))); 0]);
  148. else
  149. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  150. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  151. (2*pi*abs(pp(3))^2))); 0]);
  152. end
  153. case 'dog_ephys'
  154. % -- DOG without convolution with HRF
  155. % define the model (parameters are R C S G sdratio normamp)
  156. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  157. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  158. (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)) ...
  159. )) ; 0]);
  160. end
  161. polymatrix = {};
  162. for p=1:length(degs)
  163. polymatrix{p} = projectionmatrix(constructpolynomialmatrix(size(data{p},2),0:degs(p)));
  164. end
  165. % Which channel should we inspect?
  166. ch = 1; %4;
  167. datats = {}; modelts = {};
  168. for p=1:length(data)
  169. datats{p} = polymatrix{p}*data{p}(ch,:)';
  170. modelts{p} = polymatrix{p}*modelfun(result_mua.params(1,:,ch),single(stimulusPP{p}));
  171. end
  172. % Visualize the results
  173. f=figure; hold on;
  174. set(gcf,'Units','points','Position',[100 100 1000 300]);
  175. plot(.5:0.5:120,cat(1,datats{:}),'ok','MarkerSize',6,'MarkerFaceColor',[.75 .75 .75]);
  176. plot(.5:0.5:120,cat(1,modelts{:}),'k','Linewidth',2);
  177. xlabel('Time (stimulus position)'); ylabel('Signal');
  178. ax = axis; set(gca,'xlim',[0 121]);
  179. %axis([.5 1200+.5 ax(3:4)]);
  180. title('Time-series data MUA - Example electrode');
  181. legend({'Data','Model'})
  182. saveas(f,fullfile(pngfld, 'ExampleElectrode_MUA.png'));
  183. saveas(f,fullfile(svgfld, 'ExampleElectrode_MUA.svg'));
  184. % === LFP ===
  185. for fb=1:5
  186. data = lfp_data_org{fb};
  187. res = [size(stimulus{1},1) size(stimulus{1},2)];
  188. resmx = max(res);
  189. degs = result_lfp(fb).options.maxpolydeg;
  190. [d,xx,yy] = makegaussian2d(resmx,2,2,2,2);
  191. options = result_lfp(fb).options;
  192. stimulusPP = {};
  193. for p=1:length(stimulus)
  194. stimulusPP{p} = squish(stimulus{p},2)'; % this flattens the image so that the dimensionality is now frames x pixels
  195. stimulusPP{p} = [stimulusPP{p} p*ones(size(stimulusPP{p},1),1)]; % this adds a dummy column to indicate run breaks
  196. end
  197. switch modeltype
  198. case 'css_hrf'
  199. % -- CSS --
  200. % define the model (parameters are R C S G N)
  201. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  202. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  203. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5)),options.hrf,dd(:,prod(res)+1));
  204. case 'linear_hrf'
  205. % -- Linear (skip second step where exponential is fit) --
  206. % define the model (parameters are R C S G)
  207. if options.allowneggain
  208. modelfun = @(pp,dd) conv2run(pp(4) * (dd*[vflatten(placematrix(zeros(res),...
  209. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  210. (2*pi*abs(pp(3))^2))); 0]),options.hrf,dd(:,prod(res)+1));
  211. else
  212. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  213. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  214. (2*pi*abs(pp(3))^2))); 0]),options.hrf,dd(:,prod(res)+1));
  215. end
  216. case 'dog_hrf'
  217. % -- DOG (center surround
  218. % define the model (parameters are R C S G sdratio normamp)
  219. modelfun = @(pp,dd) conv2run(posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  220. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  221. (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)) ...
  222. )) ; 0]),options.hrf,dd(:,prod(res)+1));
  223. case 'css_ephys'
  224. % -- CSS without convolution with HRF
  225. % define the model (parameters are R C S G N)
  226. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  227. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  228. (2*pi*abs(pp(3))^2))); 0]) .^ posrect(pp(5));
  229. case 'linear_ephys'
  230. % -- Linear without convolution with HRF
  231. % define the model (parameters are R C S G)
  232. if options.allowneggain
  233. modelfun = @(pp,dd) pp(4) * (dd*[vflatten(placematrix(zeros(res),...
  234. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  235. (2*pi*abs(pp(3))^2))); 0]);
  236. else
  237. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res),...
  238. makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / ...
  239. (2*pi*abs(pp(3))^2))); 0]);
  240. end
  241. case 'dog_ephys'
  242. % -- DOG without convolution with HRF
  243. % define the model (parameters are R C S G sdratio normamp)
  244. modelfun = @(pp,dd) posrect(pp(4)) * (dd*[vflatten(placematrix(zeros(res), ...
  245. (makegaussian2d(resmx,pp(1),pp(2),abs(pp(3)),abs(pp(3)),xx,yy,0,0) / (2*pi*abs(pp(3))^2)) - ...
  246. (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)) ...
  247. )) ; 0]);
  248. end
  249. polymatrix = {};
  250. for p=1:length(degs)
  251. polymatrix{p} = projectionmatrix(constructpolynomialmatrix(size(data{p},2),0:degs(p)));
  252. end
  253. % Which channel should we inspect?
  254. ch = 1;
  255. datats = {}; modelts = {};
  256. for p=1:length(data)
  257. datats{p} = polymatrix{p}*data{p}(ch,:)';
  258. modelts{p} = polymatrix{p}*modelfun(result_lfp(fb).params(1,:,ch),single(stimulusPP{p}));
  259. end
  260. % Visualize the results
  261. f=figure; hold on;
  262. set(gcf,'Units','points','Position',[100 100 1000 300]);
  263. plot(.5:0.5:120,cat(1,datats{:}),'ok','MarkerSize',6,'MarkerFaceColor',[.75 .75 .75]);
  264. plot(.5:0.5:120,cat(1,modelts{:}),'k','Linewidth',2);
  265. xlabel('Time (stimulus position)'); ylabel('Signal');
  266. ax = axis; set(gca,'xlim',[0 121]);
  267. title(['Time-series data LFP fb-' num2str(fb) ' - Example electrode']);
  268. legend({'Data','Model'})
  269. saveas(f,fullfile(pngfld, ['ExampleElectrode_LFP-' num2str(fb) '.png']));
  270. saveas(f,fullfile(svgfld, ['ExampleElectrode_LFP-' num2str(fb) '.svg']));
  271. end
  272. close all;