Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

cRF_process.m 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. %% base folders >> adjust for your system =================================
  2. base_fld = fullfile(pwd, 'cRF');
  3. % NB! Monkey L = M3; Monkey A = M4
  4. %% Do some processing and organization ====================================
  5. % read csv files
  6. warning off
  7. cRF=readtable(fullfile(base_fld,'allRF.csv'));
  8. warning on
  9. minSNR = 3; minR2 = 0.25;
  10. SNR = [...
  11. cRF.SNR_fromRF_rightward ...
  12. cRF.SNR_fromRF_leftward ...
  13. cRF.SNR_fromRF_upward ...
  14. cRF.SNR_fromRF_downward ];
  15. SNR(SNR<minSNR)=NaN;
  16. cRF.incSNR = mean(SNR,2)>0;
  17. R2 = [...
  18. cRF.R2_rightward ...
  19. cRF.R2_leftward ...
  20. cRF.R2_upward ...
  21. cRF.R2_downward ];
  22. R2(R2<minR2)=NaN;
  23. cRF.incR2 = mean(R2,2)>0;
  24. cRF.incSNRandR2 = mean(SNR,2)>minSNR & mean(R2,2)>minR2;
  25. % rewrite borders
  26. cRF.Lp = cRF.RF_left_edge_pixels_;
  27. cRF.Rp = cRF.RF_right_edge_pixels_;
  28. cRF.Tp = cRF.RF_top_edge_pixels_;
  29. cRF.Bp = cRF.RF_bottom_edge_pixels_;
  30. % rewrite centers
  31. cRF.HCd = cRF.RFCenterX_degrees_;
  32. cRF.VCd = cRF.RFCenterY_degrees_;
  33. % recalc
  34. cRF.HSp = cRF.Rp-cRF.Lp;
  35. cRF.HCp = (cRF.Rp+cRF.Lp)./2;
  36. cRF.VSp = cRF.Tp-cRF.Bp;
  37. cRF.VCp = (cRF.Tp+cRF.Bp)./2;
  38. % calculate pixel-deg conversion
  39. ppd = nanmean(cRF.HCp./cRF.HCd);
  40. % size in deg
  41. cRF.HSd = cRF.HSp./ppd; % in deg based on 1.65*SD
  42. cRF.VSd = cRF.VSp./ppd; % in deg based on 1.65*SD
  43. % size in SD >> NOTE THAT THIS IS RADIUS NOW, DO NOT /2 LATER!!
  44. cRF.HSsd = cRF.HSd./3.3; % in deg based on SD
  45. cRF.VSsd = cRF.VSd./3.3; % in deg based on SD
  46. cRF.SZsd = sqrt((cRF.HSsd.^2)+(cRF.VSsd.^2));
  47. % add area
  48. cRF.Area = ones(size(cRF.Array_ID));
  49. cRF.Area(strcmp(cRF.MID, 'A') & (cRF.Array_ID == 2 | cRF.Array_ID == 5))=4;
  50. cRF.Area(strcmp(cRF.MID, 'L') & (cRF.Array_ID == 2 | cRF.Array_ID == 3))=4;
  51. %% Horizontal/vertical cRF size ===========================================
  52. % horizontal vs vertical size
  53. M3idx = strcmp(cRF.MID,'L') & cRF.incSNRandR2 ;
  54. M4idx = strcmp(cRF.MID,'A') & cRF.incSNRandR2 ;
  55. figure;
  56. subplot(1,3,1);hold on
  57. plot([-1 6],[-1 6],'r')
  58. scatter(cRF.HSsd(M3idx), cRF.VSsd(M3idx),'b')
  59. scatter(cRF.HSsd(M4idx), cRF.VSsd(M4idx),'k')
  60. plot([0 0],[-1 6],'k--');plot([-1 6],[0 0],'k--');
  61. xlabel('Horizontal RF-size (SD) edge-based')
  62. ylabel('Vertical RF-size (SD) edge-based')
  63. set(gca, 'xlim',[-1 6],'ylim',[-1 6]);
  64. subplot(1,3,2);hold on
  65. plot([-1 6],[-1 6],'r')
  66. scatter(cRF.HSsd(M3idx), cRF.SZsd(M3idx),'b')
  67. scatter(cRF.HSsd(M4idx), cRF.SZsd(M4idx),'k')
  68. plot([0 0],[-1 6],'k--');plot([-1 6],[0 0],'k--');
  69. xlabel('Horizontal RF-size (SD) edge-based')
  70. ylabel('RF-size (SD) edge-based')
  71. set(gca, 'xlim',[-1 6],'ylim',[-.5 6]);
  72. subplot(1,3,3);hold on
  73. plot([-1 6],[-1 6],'r')
  74. scatter(cRF.VSsd(M3idx), cRF.SZsd(M3idx),'b')
  75. scatter(cRF.VSsd(M4idx), cRF.SZsd(M4idx),'k')
  76. plot([0 0],[-1 6],'k--');plot([-1 6],[0 0],'k--');
  77. xlabel('Vertical RF-size (SD) edge-based')
  78. ylabel('RF-size (SD) edge-based')
  79. set(gca, 'xlim',[-1 6],'ylim',[-.5 6]);
  80. legend({'x=y','M3','M4'}, 'Location','SouthEast')
  81. fprintf(['nChan L: ' num2str(sum(M3idx)) ...
  82. ', nChan A: ' num2str(sum(M4idx)) '\n'])
  83. %% cRF symmetry ===========================================================
  84. figure;
  85. subplot(1,3,1);hold on
  86. plot([-1 6],[-1 6],'k--')
  87. scatter(cRF.HSsd(M3idx), cRF.VSsd(M3idx),'k')
  88. scatter(cRF.HSsd(M4idx), cRF.VSsd(M4idx),'r')
  89. xlabel('Horizontal RF-size (SD)')
  90. ylabel('Vertical RF-size (SD)')
  91. set(gca, 'xlim',[0 5],'ylim',[0 5]);
  92. legend({'HSz=VSz','M3','M4'})
  93. subplot(1,3,2);hold on
  94. histogram(cRF.HSsd(M3idx)./cRF.VSsd(M3idx),0.45:0.05:1.55)
  95. nm=nanmedian(cRF.HSsd(M3idx)./cRF.VSsd(M3idx));
  96. plot([nm nm],[0 120],'k--')
  97. title(['M3, median:' num2str(nm)]); xlabel('HSz/VSz'); ylabel('#electrodes')
  98. subplot(1,3,3);hold on
  99. histogram(cRF.HSsd(M4idx)./cRF.VSsd(M4idx),0.45:0.05:1.55)
  100. nm=nanmedian(cRF.HSsd(M4idx)./cRF.VSsd(M4idx));
  101. plot([nm nm],[0 100],'k--')
  102. title(['M4, median:' num2str(nm)]); xlabel('HSz/VSz'); ylabel('#electrodes')
  103. % stats
  104. [p,h,stats] = signrank(cRF.HSsd(M3idx),cRF.VSsd(M3idx));
  105. fprintf(['M3: Difference HSz vs VSz: Wilcoxon z = ' ...
  106. num2str(stats.zval) ', p = ' num2str(p) '\n']);
  107. [p,h,stats] = signrank(cRF.HSsd(M4idx),cRF.VSsd(M4idx));
  108. fprintf(['M4: Difference HSz vs VSz: Wilcoxon z = ' ...
  109. num2str(stats.zval) ', p = ' num2str(p) '\n']);
  110. %% aspect ratio ===========================================================
  111. sigmat3 = sort([cRF.HSsd(M3idx), cRF.VSsd(M3idx)],2,'descend');
  112. sigmat4 = sort([cRF.HSsd(M4idx), cRF.VSsd(M4idx)],2,'descend');
  113. figure;
  114. subplot(1,3,1);hold on
  115. plot([-1 6],[-1 6],'k--')
  116. scatter(sigmat3(:,1), sigmat3(:,2),'k')
  117. scatter(sigmat4(:,1), sigmat4(:,2),'r')
  118. xlabel('Largest SD'); ylabel('Smallest SD')
  119. set(gca, 'xlim',[0 5],'ylim',[0 5]);
  120. legend({'unity','M3','M4'})
  121. subplot(1,3,2);hold on
  122. histogram(sigmat3(:,1)./sigmat3(:,2),0.95:0.05:5.05)
  123. nm=nanmedian(sigmat3(:,1)./sigmat3(:,2));
  124. IQR=[nm-iqr(sigmat3(:,1)./sigmat3(:,2))/2 nm+iqr(sigmat3(:,1)./sigmat3(:,2))/2];
  125. plot([nm nm],[0 180],'k--')
  126. title(['M3, median:' num2str(nm)]); xlabel('aspect ratio'); ylabel('#electrodes')
  127. fprintf(['M3 median: ' num2str(nm) ', IQR:' num2str(IQR(1)) ' ' num2str(IQR(2)) '\n'])
  128. ar=sigmat3(:,1)./sigmat3(:,2);
  129. fprintf(['M3: ' num2str(sum(ar>2)) '/' num2str(length(ar)) ...
  130. ' cRFs with aspect ratio >2 (' num2str(100*sum(ar>2)/length(ar)) '%%)\n' ]);
  131. subplot(1,3,3);hold on
  132. histogram(sigmat4(:,1)./sigmat4(:,2),0.95:0.05:5.05)
  133. nm=nanmedian(sigmat4(:,1)./sigmat4(:,2));
  134. IQR=[nm-iqr(sigmat4(:,1)./sigmat4(:,2))/2 nm+iqr(sigmat4(:,1)./sigmat4(:,2))/2];
  135. plot([nm nm],[0 120],'k--')
  136. title(['M4, median:' num2str(nm)]); xlabel('aspect ratio'); ylabel('#electrodes')
  137. fprintf(['M4 median: ' num2str(nm) ', IQR:' num2str(IQR(1)) ' ' num2str(IQR(2)) '\n'])
  138. ar=sigmat4(:,1)./sigmat4(:,2);
  139. fprintf(['M4: ' num2str(sum(ar>2)) '/' num2str(length(ar)) ...
  140. ' cRFs with aspect ratio >2 (' num2str(100*sum(ar>2)/length(ar)) '%%)\n' ]);
  141. % stats
  142. [p,h,stats] = signrank(sigmat3(:,1), sigmat3(:,2));
  143. fprintf(['M3: Difference HSz vs VSz: Wilcoxon z = ' ...
  144. num2str(stats.zval) ', p = ' num2str(p) '\n']);
  145. [p,h,stats] = signrank(sigmat4(:,1), sigmat4(:,2));
  146. fprintf(['M4: Difference HSz vs VSz: Wilcoxon z = ' ...
  147. num2str(stats.zval) ', p = ' num2str(p) '\n']);
  148. %% restructure for compatibility
  149. warning off
  150. cRF_map1 = readtable(fullfile(base_fld,'combined_A_RF_with_SD.csv'));
  151. cRF_map2 = readtable(fullfile(base_fld,'combined_L_RF_with_SD.csv'));
  152. cRF_map = [cRF_map1;cRF_map2];
  153. warning on
  154. clear RFs
  155. M = {'M03','M04'}; % L,A
  156. % add NSP number
  157. Arr_num = 1:16;
  158. NSP_num = [1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8];
  159. clear idx
  160. idx{1} = strcmp(cRF.MID,'L');
  161. idx{2} = strcmp(cRF.MID,'A');
  162. for m=1:2
  163. save_fld = fullfile(base_fld,M{m});
  164. mkdir(save_fld)
  165. Tbl=cRF(idx{m},:);
  166. idxm = strcmp(cRF_map.Monkey,M{m});
  167. Tbl_map = cRF_map(idxm,:);
  168. NSP_map=[];
  169. for i = 1:8
  170. a = Arr_num(NSP_num == i);
  171. arr_sel = (Tbl.Array_ID == a(1) | Tbl.Array_ID == a(2));
  172. NSP_data = [Tbl.Electrode_ID(arr_sel) ...
  173. Tbl.Array_ID(arr_sel) ...
  174. nan(size(Tbl.Array_ID(arr_sel))) ];
  175. for el = 1:length(NSP_data)
  176. NSP_data(el,3) = ...
  177. Tbl_map.within_NSP_electrode_ID(...
  178. Tbl_map.Electrode_ID == NSP_data(el,1) & ...
  179. Tbl_map.Array_ID == NSP_data(el,2));
  180. end
  181. NSP_order = NSP_data(:,3);
  182. meanChannelSNR = mean([...
  183. Tbl.SNR_fromRF_rightward(arr_sel) ...
  184. Tbl.SNR_fromRF_leftward(arr_sel) ...
  185. Tbl.SNR_fromRF_upward(arr_sel) ...
  186. Tbl.SNR_fromRF_downward(arr_sel) ...
  187. ],2);
  188. meanChannelSNR = meanChannelSNR(NSP_order);
  189. meanChannelR2 = mean([...
  190. Tbl.R2_rightward(arr_sel) ...
  191. Tbl.R2_leftward(arr_sel) ...
  192. Tbl.R2_upward(arr_sel) ...
  193. Tbl.R2_downward(arr_sel) ...
  194. ],2);
  195. meanChannelR2 = meanChannelR2(NSP_order);
  196. XX = Tbl.RFCenterX_degrees_(arr_sel);
  197. YY = Tbl.RFCenterY_degrees_(arr_sel);
  198. SZsd = Tbl.SZsd(arr_sel);
  199. HV = [Tbl.HSsd(arr_sel) Tbl.VSsd(arr_sel)];
  200. TH = Tbl.RFTheta_degrees_(arr_sel);
  201. SZlisted = Tbl.RFSize_degrees_(arr_sel);
  202. Areas = Tbl.Area(arr_sel);
  203. for c = 1:128
  204. RFs{1,NSP_order(c)}.centrex = XX(c)*ppd;
  205. RFs{1,NSP_order(c)}.centrey = YY(c)*ppd;
  206. RFs{1,NSP_order(c)}.xdeg = XX(c);
  207. RFs{1,NSP_order(c)}.ydeg = YY(c);
  208. RFs{1,NSP_order(c)}.sz = SZsd(c)*ppd;
  209. RFs{1,NSP_order(c)}.szdeg = SZsd(c);
  210. RFs{1,NSP_order(c)}.szdeg_hv = HV(c,:);
  211. RFs{1,NSP_order(c)}.szlisteddeg = SZlisted(c);
  212. RFs{1,NSP_order(c)}.theta = TH(c);
  213. RFs{1,NSP_order(c)}.ecc = sqrt(XX(c).^2 + YY(c).^2);
  214. RFs{1,NSP_order(c)}.area = Areas(c);
  215. end
  216. save([save_fld '/RFs_instance' num2str(i)], ...
  217. 'meanChannelSNR','meanChannelR2','RFs')
  218. end
  219. end