ck_xmod_stats_lowfreqlfp.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. %% stats for linear models comparison
  2. for gainopt = -1%[-1 1] % do separate for negative and positive gain
  3. fprintf('===================================================\n');
  4. fprintf(['GAIN MODE (low freq LFP): ' num2str(gainopt) '\n']);
  5. fprintf('===================================================\n');
  6. %% DATA ===================================================================
  7. clear stats
  8. ecc=[]; sz=[]; % eccentricity and size
  9. signal = []; % categorical 1=MRI, 2=MUA, 3-7=LFP bands
  10. area=[]; % categorical 1=V1,4=V4
  11. model=[]; % categorical 1=lin, 2=lin_ng, 3=css, 4=dog
  12. gain=[];
  13. % v1
  14. ecc = [ecc; ...
  15. mri1(m).ECC; ...
  16. mua1(m).ECC; ...
  17. ];
  18. sz = [ sz; ...
  19. mri1(m).S; ...
  20. mua1(m).S; ...
  21. ];
  22. signal = [signal;...
  23. 1*ones(size(mri1(m).S)); ...
  24. 2*ones(size(mua1(m).S)); ...
  25. ];
  26. area = [area; ...
  27. 1*ones(size(mri1(m).S)); ...
  28. 1*ones(size(mua1(m).S)); ...
  29. ];
  30. gain = [gain; ...
  31. mri1(m).G; ...
  32. mua1(m).G; ...
  33. ];
  34. for i=1:5
  35. if i<=3
  36. gainselect = ...
  37. lfp1(i,m).G./abs(lfp1(i,m).G) == gainopt;
  38. ecc = [ecc; lfp1(i,m).ECC(gainselect)];
  39. sz = [ sz; lfp1(i,m).S(gainselect)];
  40. gain = [ gain; lfp1(i,m).G(gainselect)];
  41. signal = [signal; (2+i)*ones(size(lfp1(i,m).ECC(gainselect)))];
  42. area = [area; 1*ones(size(lfp1(i,m).ECC(gainselect)))];
  43. else
  44. ecc = [ecc; lfp1(i,m).ECC];
  45. sz = [ sz; lfp1(i,m).S];
  46. gain = [ gain; lfp1(i,m).G];
  47. signal = [signal; (2+i)*ones(size(lfp1(i,m).S))];
  48. area = [area; 1*ones(size(lfp1(i,m).S))];
  49. end
  50. end
  51. % v4
  52. ecc = [ecc; ...
  53. mri4(m).ECC; ...
  54. mua4(m).ECC; ...
  55. ];
  56. sz = [ sz; ...
  57. mri4(m).S; ...
  58. mua4(m).S; ...
  59. ];
  60. signal = [signal;...
  61. 1*ones(size(mri4(m).S)); ...
  62. 2*ones(size(mua4(m).S)); ...
  63. ];
  64. area = [area; ...
  65. 4*ones(size(mri4(m).S)); ...
  66. 4*ones(size(mua4(m).S)); ...
  67. ];
  68. gain = [gain; ...
  69. mri4(m).G; ...
  70. mua4(m).G; ...
  71. ];
  72. for i=1:5
  73. if i<=3
  74. gainselect = ...
  75. lfp4(i,m).G./abs(lfp4(i,m).G) == gainopt;
  76. ecc = [ecc; lfp4(i,m).ECC(gainselect)];
  77. sz = [ sz; lfp4(i,m).S(gainselect)];
  78. gain = [ gain; lfp4(i,m).G(gainselect)];
  79. signal = [signal; (2+i)*ones(size(lfp4(i,m).ECC(gainselect)))];
  80. area = [area; 4*ones(size(lfp4(i,m).ECC(gainselect)))];
  81. else
  82. ecc = [ecc; lfp4(i,m).ECC];
  83. sz = [ sz; lfp4(i,m).S];
  84. gain = [ gain; lfp4(i,m).G];
  85. signal = [signal; (2+i)*ones(size(lfp4(i,m).S))];
  86. area = [area; 4*ones(size(lfp4(i,m).S))];
  87. end
  88. end
  89. %
  90. if gainopt > 0
  91. sigtype = {1,2,3,4,5,6,7;'mri' ,'mua','alpha-pos','beta-pos','theta-pos','hgam','lgam'};
  92. else
  93. sigtype = {1,2,3,4,5,6,7;'mri' ,'mua','alpha-neg','beta-neg','theta-neg','hgam','lgam'};
  94. end
  95. signal_num=signal;
  96. for i=1:length(signal_num)
  97. sn{i,1}=sigtype{2,signal_num(i)};
  98. end
  99. signal=categorical(signal);
  100. area=categorical(area);
  101. areaname = {' V1', 'V4'};
  102. DT=table(signal,area, ecc, sz, gain);
  103. %% PLOT SCATTER AND FITS ==================================================
  104. f_xmod = figure;
  105. set(f_xmod,'Position',[100 100 2000 800]);
  106. CLR=[...
  107. 0 0 0;...
  108. 0.85,0.33,0.10;...
  109. 0.93,0.69,0.13;...
  110. 0.47,0.67,0.19;...
  111. 0.49,0.18,0.56;...
  112. 0.30,0.75,0.93;...
  113. 0.00,0.45,0.74;...
  114. ];
  115. % do the modelfits and plot scatter and fitlines
  116. % v1 -----
  117. DT1=DT(DT.area==categorical(1) & DT.ecc<=MaxECC,:);
  118. mdl_v1 = fitlm(DT1,'sz ~ 1 + signal*ecc');
  119. slidx = 1+ length(mdl_v1.Coefficients.Estimate)/2;
  120. v1idx=[];
  121. for j=1:length(mdl_v1.CoefficientNames)
  122. if mdl_v1.CoefficientNames{j}(1:3) == 'sig' & ...
  123. mdl_v1.CoefficientNames{j}(end-2:end) ~= 'ecc'
  124. v1idx = [v1idx str2double(mdl_v1.CoefficientNames{j}(8:end))];
  125. end
  126. end
  127. msz = 40;
  128. subplot(2,2,1);
  129. ll={}; US=[sigtype{1,:}]; hold on; ii=1;
  130. for i=1:length(US)
  131. sel=DT1.signal==categorical(i);
  132. if sum(sel)>0
  133. scatter(DT1.ecc(sel),DT1.sz(sel),msz,...
  134. 'Marker','o',...
  135. 'MarkerEdgeColor',CLR(i,:),'MarkerFaceColor',CLR(i,:),...
  136. 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',0.2);
  137. ll{ii}=sigtype{2,i};
  138. ii=ii+1;
  139. end
  140. end
  141. legend(ll,'Location','NorthEastOutside');
  142. title('V1');xlabel('Ecc');ylabel('Sz');
  143. set(gca,'xlim',[0 12.5],'ylim',[0 7],'TickDir','out');
  144. subplot(2,2,2);
  145. ll={}; US=[sigtype{1,:}]; hold on; ii=1;
  146. for i=1:length(US)
  147. sel=DT1.signal==categorical(i);
  148. if sum(sel)>0
  149. x=[0 MaxECC];
  150. if i==1
  151. y=[...
  152. mdl_v1.Coefficients.Estimate(1) + ...
  153. mdl_v1.Coefficients.Estimate(slidx).*x ...
  154. ];
  155. plot(x,y, 'LineWidth',5, 'Color',CLR(i,:));
  156. else
  157. j = find(v1idx==i,1,'first');
  158. y=[...
  159. mdl_v1.Coefficients.Estimate(1) + ...
  160. mdl_v1.Coefficients.Estimate(1+j) + ...
  161. (mdl_v1.Coefficients.Estimate(slidx) + ...
  162. mdl_v1.Coefficients.Estimate(slidx+j)).*x ...
  163. ];
  164. plot(x,y, 'LineWidth',3, 'Color',CLR(i,:));
  165. end
  166. ll{ii}=sigtype{2,i};
  167. ii=ii+1;
  168. end
  169. end
  170. legend(ll,'Location','NorthEastOutside');
  171. title('V1 FIT');xlabel('Ecc');ylabel('Sz');
  172. set(gca,'xlim',[0 12.5],'ylim',[0 7],'TickDir','out');
  173. % v4
  174. DT4=DT(DT.area==categorical(4) & DT.ecc<=MaxECC,:);
  175. mdl_v4 = fitlm(DT4,'sz ~ 1 + signal*ecc');
  176. v4idx=[];
  177. for j=1:length(mdl_v4.CoefficientNames)
  178. if mdl_v4.CoefficientNames{j}(1:3) == 'sig' & ...
  179. mdl_v4.CoefficientNames{j}(end-2:end) ~= 'ecc'
  180. v4idx = [v4idx str2double(mdl_v4.CoefficientNames{j}(8:end))];
  181. end
  182. end
  183. subplot(2,2,3);
  184. ll={}; US=[sigtype{1,:}]; hold on; ii=1;
  185. for i=1:length(US)
  186. sel=DT4.signal==categorical(i);
  187. if sum(sel)>0
  188. scatter(DT4.ecc(sel),DT4.sz(sel),msz,...
  189. 'Marker','o',...
  190. 'MarkerEdgeColor',CLR(i,:),'MarkerFaceColor',CLR(i,:),...
  191. 'MarkerEdgeAlpha',0,'MarkerFaceAlpha',0.25);
  192. ll{ii}=sigtype{2,i};
  193. ii=ii+1;
  194. end
  195. end
  196. legend(ll,'Location','NorthEastOutside');
  197. title('V4');xlabel('Ecc');ylabel('Sz');
  198. set(gca,'xlim',[0 12.5],'ylim',[0 7],'TickDir','out');
  199. subplot(2,2,4);
  200. ll={}; US=[sigtype{1,:}]; hold on; ii=1;
  201. for i=1:length(US)
  202. sel=DT4.signal==categorical(i);
  203. if sum(sel)>0
  204. x=[0 MaxECC];
  205. if i==1
  206. y=[...
  207. mdl_v4.Coefficients.Estimate(1) + ...
  208. mdl_v4.Coefficients.Estimate(slidx).*x ...
  209. ];
  210. plot(x,y, 'LineWidth',5, 'Color',CLR(i,:));
  211. else
  212. j = find(v4idx==i,1,'first');
  213. y=[...
  214. mdl_v4.Coefficients.Estimate(1) + ...
  215. mdl_v4.Coefficients.Estimate(1+j) + ...
  216. (mdl_v4.Coefficients.Estimate(slidx) + ...
  217. mdl_v4.Coefficients.Estimate(slidx+j)).*x ...
  218. ];
  219. plot(x,y, 'LineWidth',3, 'Color',CLR(i,:));
  220. end
  221. ll{ii}=sigtype{2,i};
  222. ii=ii+1;
  223. end
  224. end
  225. legend(ll,'Location','NorthEastOutside');
  226. title('V4 FIT');xlabel('Ecc');ylabel('Sz');
  227. set(gca,'xlim',[0 12.5],'ylim',[0 7],'TickDir','out');
  228. sgtitle(['MODEL: ' MMS{m} ', Rth_mri: ' num2str(Rth_mri) ...
  229. ', Rth_ephys:' num2str(Rth_ephys)],'interpreter','none')
  230. if SaveFigs
  231. saveas(f_xmod,fullfile(pngfld, ['XMOD_REGR_' MMS{m} '.png']));
  232. saveas(f_xmod,fullfile(svgfld, ['XMOD_REGR_' MMS{m} '.svg']));
  233. end
  234. if CloseFigs; close(f_xmod); end
  235. %% WHICH SIGNAL TYPES HAVE SIGNIFICANT ECC-SZ RELATION ====================
  236. areas = [1 4];
  237. st=[sigtype{1,:}];sn=sigtype(2,:);
  238. for a = 1:length(areas) % loop over areas
  239. stats.area(a).signalswithslope = [];
  240. for s = st % loop over signals
  241. sel = ...
  242. DT.area==categorical(areas(a)) & ...
  243. DT.signal==categorical(s) & ...
  244. DT.ecc<=MaxECC;
  245. if sum(sel)>1
  246. tbl = DT(sel,:);
  247. mdl = fitlm(tbl,'sz ~ 1 + ecc');
  248. stats.area(a).signal(s).name = sn{s};
  249. stats.area(a).signal(s).mdl = mdl;
  250. stats.area(a).signal(s).anova = anova(mdl);
  251. stats.area(a).signal(s).ic = mdl.Coefficients(1,:);
  252. stats.area(a).signal(s).sl = mdl.Coefficients(2,:);
  253. CI = coefCI(mdl);
  254. stats.area(a).signal(s).icCI = CI(1,:);
  255. stats.area(a).signal(s).slCI = CI(2,:);
  256. if stats.area(a).signal(s).sl.pValue < 0.05
  257. stats.area(a).signalswithslope = [...
  258. stats.area(a).signalswithslope s];
  259. end
  260. fprintf(['Area ' num2str(areas(a)) ', Signal: ' num2str(sn{s}) ...
  261. ', slope: ' num2str(stats.area(a).signal(s).sl.Estimate) ...
  262. ', n = ' num2str(stats.area(a).signal(s).anova.DF(2)+1) ...
  263. ', t = ' num2str(stats.area(a).signal(s).sl.tStat) ...
  264. ', p = ' num2str(stats.area(a).signal(s).sl.pValue) '\n']);
  265. end
  266. end
  267. end
  268. %% TEST SIGNALS WITH SIGNIFICANT SLOPE TOGETHER IN ONE LINEAR MODEL =======
  269. for a = 1:length(areas) % loop over areas
  270. sel = ...
  271. DT.area==categorical(areas(a)) & ...
  272. ismember(DT.signal,categorical(stats.area(a).signalswithslope)) & ...
  273. DT.ecc<=MaxECC;
  274. % recreate a table to avoid empty signal categories
  275. signal2 = zeros(size(signal_num));
  276. for i=1:length(stats.area(a).signalswithslope)
  277. signal2(signal_num==stats.area(a).signalswithslope(i))=i;
  278. end
  279. signal2 = signal2(sel);
  280. area2 = area(sel);
  281. ecc2=ecc(sel);
  282. sz2=sz(sel);
  283. signal2=categorical(signal2);
  284. tbl2=table(signal2,area2, ecc2, sz2);
  285. mdl2 = fitlm(tbl2,'sz2 ~ signal2*ecc2');
  286. stats.area(a).full.mdl = mdl2;
  287. stats.area(a).full.anova = anova(mdl2);
  288. stats.area(a).full.signals = sn(stats.area(a).signalswithslope);
  289. fprintf('========================================\n')
  290. fprintf(['All significant signal types in one model V' num2str(areas(a)) '\n']);
  291. fprintf('========================================\n')
  292. fprintf('Eccentricity\n')
  293. fprintf(['F = ' num2str(stats.area(a).full.anova.F(2)) ...
  294. ', df = ' num2str(stats.area(a).full.anova.DF(2)) ...
  295. ', p = ' num2str(stats.area(a).full.anova.pValue(2)) '\n']);
  296. fprintf('Signal\n')
  297. fprintf(['F = ' num2str(stats.area(a).full.anova.F(1)) ...
  298. ', df = ' num2str(stats.area(a).full.anova.DF(1)) ...
  299. ', p = ' num2str(stats.area(a).full.anova.pValue(1)) '\n']);
  300. fprintf('Ecc*Signal\n')
  301. fprintf(['F = ' num2str(stats.area(a).full.anova.F(3)) ...
  302. ', df = ' num2str(stats.area(a).full.anova.DF(3)) ...
  303. ', p = ' num2str(stats.area(a).full.anova.pValue(3)) '\n']);
  304. end
  305. clear signal2;
  306. %% TEST SIGNALS WITH SIGNIFICANT SLOPE AGAINST MRI ========================
  307. for a = 1:length(areas) % loop over areas
  308. ss = stats.area(a).signalswithslope; ss(ss==1)=[];
  309. sidx=1;
  310. fprintf('========================================\n')
  311. fprintf(['MRI vs EPHYS V' num2str(areas(a)) '\n']);
  312. fprintf('========================================\n')
  313. for s = ss
  314. sel = ...
  315. DT.area == categorical(areas(a)) & ...
  316. ismember(DT.signal,categorical([1 s])) & ...
  317. DT.ecc <= MaxECC ;
  318. % recreate a table to avoid empty signal categories
  319. signal2 = zeros(size(signal_num));
  320. for i=1:length(stats.area(a).signalswithslope)
  321. signal2(signal_num==stats.area(a).signalswithslope(i))=i;
  322. end
  323. signal2 = signal2(sel);
  324. area2 = area(sel);
  325. ecc2=ecc(sel);
  326. sz2=sz(sel);
  327. signal2=categorical(signal2);
  328. tbl2=table(signal2,area2, ecc2, sz2);
  329. mdl2 = fitlm(tbl2,'sz2 ~ signal2*ecc2');
  330. stats.area(a).sig_vsMRI(sidx).name = sn{s};
  331. stats.area(a).sig_vsMRI(sidx).mdl = mdl2;
  332. stats.area(a).sig_vsMRI(sidx).anova = anova(mdl2);
  333. fprintf(['MRI vs ' stats.area(a).sig_vsMRI(sidx).name '\n']);
  334. fprintf('Eccentricity\n')
  335. fprintf(['F = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.F(2)) ...
  336. ', df = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.DF(2)) ...
  337. ', p = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.pValue(2)) '\n']);
  338. fprintf('Signal\n')
  339. fprintf(['F = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.F(1)) ...
  340. ', df = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.DF(1)) ...
  341. ', p = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.pValue(1)) '\n']);
  342. fprintf('Ecc*Signal\n')
  343. fprintf(['F = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.F(3)) ...
  344. ', df = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.DF(3)) ...
  345. ', p = ' num2str(stats.area(a).sig_vsMRI(sidx).anova.pValue(3)) '\n']);
  346. sidx=sidx+1;
  347. end
  348. end
  349. %% PLOT SLOPES WITH CI AND INDICATE SIGN DIFF FROM MRI ====================
  350. f_slopes = figure;
  351. set(f_slopes,'Position',[100 100 1200 400]);
  352. % V1 -----
  353. subplot(1,2,1); hold on;
  354. mri_sl = stats.area(1).signal(1).sl.Estimate;
  355. mri_sl_bot = stats.area(1).signal(1).slCI(1);
  356. mri_sl_top = stats.area(1).signal(1).slCI(2);
  357. x=[0 10]; xarea=[x fliplr(x)];
  358. yarea=[mri_sl_bot mri_sl_bot mri_sl_top mri_sl_top];
  359. fill(xarea,yarea,'r','EdgeColor','none','FaceAlpha',0.25)
  360. plot(x,[mri_sl mri_sl],'r','Linewidth',3);
  361. for s=2:7
  362. NoData=false;
  363. if isempty(stats.area(1).signal(s).sl)
  364. NoData=true;
  365. end
  366. if~NoData
  367. Y=[stats.area(1).signal(s).sl.Estimate ...
  368. stats.area(1).signal(s).slCI(1) ...
  369. stats.area(1).signal(s).slCI(2)];
  370. % check if this is significantly different from MRI
  371. isSim=false;
  372. for ss = 1:length(stats.area(1).sig_vsMRI)
  373. if strcmp(stats.area(1).signal(s).name,...
  374. stats.area(1).sig_vsMRI(ss).name) & ...
  375. stats.area(1).sig_vsMRI(ss).anova.pValue(3) > 0.05
  376. isSim=true;
  377. end
  378. end
  379. if isSim
  380. bar(s,Y(1),'FaceColor',[0.4660, 0.6740, 0.1880]);
  381. errorbar(s,Y(1),Y(1)-Y(2),Y(3)-Y(1),'k','Linestyle','none');
  382. elseif NoData
  383. % nothing to plot
  384. else
  385. bar(s,Y(1),'FaceColor',[.25 .25 .25]);
  386. errorbar(s,Y(1),Y(1)-Y(2),Y(3)-Y(1),'k','Linestyle','none');
  387. end
  388. end
  389. end
  390. set(gca,'xlim',[1.5 7.5],'ylim',[0 0.5])
  391. set(gca,'xtick',1:7,'xticklabels',sigtype(2,:))
  392. ylabel('Ecc-Sz SLOPE');
  393. title('V1','interpreter','none');
  394. % V4 -----
  395. subplot(1,2,2); hold on;
  396. mri_sl = stats.area(2).signal(1).sl.Estimate;
  397. mri_sl_bot = stats.area(2).signal(1).slCI(1);
  398. mri_sl_top = stats.area(2).signal(1).slCI(2);
  399. x=[0 10]; xarea=[x fliplr(x)];
  400. yarea=[mri_sl_bot mri_sl_bot mri_sl_top mri_sl_top];
  401. fill(xarea,yarea,'r','EdgeColor','none','FaceAlpha',0.25)
  402. plot(x,[mri_sl mri_sl],'r','Linewidth',3);
  403. for s=2:7
  404. NoData=false;
  405. if isempty(stats.area(2).signal(s).sl)
  406. NoData=true;
  407. end
  408. if~NoData
  409. Y=[stats.area(2).signal(s).sl.Estimate ...
  410. stats.area(2).signal(s).slCI(1) ...
  411. stats.area(2).signal(s).slCI(2)];
  412. % check if this is significantly different from MRI
  413. isSim=false;
  414. for ss = 1:length(stats.area(2).sig_vsMRI)
  415. if strcmp(stats.area(2).signal(s).name,...
  416. stats.area(2).sig_vsMRI(ss).name) & ...
  417. stats.area(2).sig_vsMRI(ss).anova.pValue(3) > 0.05
  418. isSim=true;
  419. end
  420. end
  421. if isSim
  422. bar(s,Y(1),'FaceColor',[0.4660, 0.6740, 0.1880]);
  423. errorbar(s,Y(1),Y(1)-Y(2),Y(3)-Y(1),'k','Linestyle','none');
  424. elseif NoData
  425. % nothing to plot
  426. else
  427. bar(s,Y(1),'FaceColor',[.25 .25 .25]);
  428. errorbar(s,Y(1),Y(1)-Y(2),Y(3)-Y(1),'k','Linestyle','none');
  429. end
  430. end
  431. end
  432. set(gca,'xlim',[1.5 7.5],'ylim',[0 0.5])
  433. set(gca,'xtick',1:7,'xticklabels',sigtype(2,:))
  434. ylabel('Ecc-Sz SLOPE');
  435. title('V4','interpreter','none');
  436. sgtitle(['MODEL: ' MMS{m} ', Rth_mri: ' num2str(Rth_mri) ...
  437. ', Rth_ephys:' num2str(Rth_ephys)],'interpreter','none')
  438. if SaveFigs
  439. saveas(f_slopes,fullfile(pngfld, ['XMOD_SlopeComparison_' MMS{m} '.png']));
  440. saveas(f_slopes,fullfile(svgfld, ['XMOD_SlopeComparison_' MMS{m} '.svg']));
  441. end
  442. if CloseFigs; close(f_slopes); end
  443. end