fig2_BtoG.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. clear % clear workspace
  2. close all; % close all open figures
  3. % load pvV1_uInfo
  4. load('/Users/busse/code/work/CTfeedbackSize/to_publish/data/pvV1.mat')
  5. %% plot parameters
  6. mean_color = [218 165 35]/255; % color for mean
  7. pinkEx = [255 20 147]/255; % color for example neurons
  8. % percentage of layer thickness based on: Heumann D, Rabinowicz T (1977) Postnatal development of mouse cerebral neocortex. II Quantitative cytoarchitectonics of visual and auditory areas. J Hirnforsch 18: 483-500
  9. % Layers I II/III IV V VI Total
  10. % Relative thickness (%) 13 26 13 24 24 100
  11. % assumptions: thickness of V1 of 1 mm
  12. % 0: base of layer 4
  13. rel_layerDepth = [-520 -390 -130 0 240 480];
  14. rel_layerCenters = [-455 -260 -65 120 360]; % add half of each layer thickness
  15. %% 2b: example tuning curves
  16. %% 2c: V1 suppression across layers
  17. rng(1);
  18. layer_names = {'1', '2/3', '4', '5', '6'};
  19. n_layers = numel(layer_names);
  20. % compute means, CIs, SEMs across layers
  21. layer_mean = nan(1, n_layers);
  22. layer_sem = nan(1, n_layers);
  23. layer_ci = nan(2, n_layers);
  24. for ilayer = 1 : n_layers
  25. layer_log = strcmp({pvV1_uInfo.layer}, layer_names(ilayer)) & ...
  26. ~[pvV1_uInfo.put_pv]; % find neurons in layer, but exclude the putative PVs
  27. % add 0.0001 to numerator and denominator to make log2 work for 0 firing rates
  28. layer_mean(ilayer) = mean(log2(([pvV1_uInfo(layer_log).frL]+0.0001) ./ ...
  29. ([pvV1_uInfo(layer_log).frC]+0.0001)));
  30. % compute confidence intervals via bootstrapping
  31. temp = bootstrp(100, @(x) {mean(log2(x))}, ...
  32. ([pvV1_uInfo(layer_log).frL]+0.0001) ./([pvV1_uInfo(layer_log).frC]+0.0001));
  33. layer_ci(:, ilayer) = prctile([temp{:}], [2.5, 97.5]);
  34. layer_sem(ilayer) = var([temp{:}]);
  35. fprintf('Layer %s: mean %3.2f (%3.2f, %3.2f)\n', ...
  36. layer_names{ilayer}, layer_mean(ilayer), ...
  37. layer_ci(1, ilayer), layer_ci(2, ilayer));
  38. end
  39. fprintf('\n');
  40. % make plot
  41. xLim = 9;
  42. layerY = [rel_layerDepth' rel_layerDepth']'/1000;
  43. layerX = [repmat(-xLim,6,1) repmat(xLim,6,1)]';
  44. modRats = log2(([pvV1_uInfo.frL]+0.001) ./ ([pvV1_uInfo.frC]+0.001));
  45. modRats(modRats < -8) = -8.5;
  46. figure('Name', 'Born et al. (2021), Fig. 3c'); hold on;
  47. plot(modRats, [pvV1_uInfo.relative_depth], 'ko', 'MarkerSize', 4);
  48. plot(layer_mean, rel_layerCenters/1000, 'o', 'Color', mean_color, 'MarkerSize', 4);
  49. line(layer_ci, [rel_layerCenters; rel_layerCenters]/1000, 'Color', mean_color)
  50. % add layer boundaries
  51. line(layerX, layerY, 'Color', 'k')
  52. line([0 0], [-0.4 0.4], 'Color', 'k')
  53. set(gca, 'YDir', 'reverse', 'XLim', [-xLim xLim], ...
  54. 'YLim', [rel_layerDepth(1)/1000 rel_layerDepth(end)/1000])
  55. xlabel('Fold change')
  56. ylabel('Relative depth (mm)')
  57. %% load uInfo for dLGN recordings
  58. load('/Users/busse/code/work/CTfeedbackSize/to_publish/data/pvdLGN.mat');
  59. %% 2e: example raster plots
  60. exIdx = [96 216];
  61. timelims{1} = [-0.5, 0.75];
  62. timelims{2} = [-0.5, 1.325];
  63. figure('Name', 'Born et al. (2021), Fig. 3e_1'); hold on;
  64. plotRaster_pub(pvLGN_uInfo(exIdx(1)).spikeTimes', timelims{1});
  65. line([0 0.25], [1 1], 'Color', 'k');
  66. set(gca, 'YColor', 'w')
  67. ylabel('')
  68. figure('Name', 'Born et al. (2021), Fig. 3e_2'); hold on;
  69. plotRaster_pub(pvLGN_uInfo(exIdx(2)).spikeTimes', timelims{2});
  70. line([0 1], [1 1], 'Color', 'k');
  71. set(gca, 'YColor', 'w')
  72. ylabel('')
  73. %% 2f: firing rate during spontaneous visual activity (corresponding to size 0)
  74. % mean rate before onset of V1 suppression and during V1 suppression
  75. pv_meanBefore = arrayfun(@(u) nanmean(u.rateBefore), pvLGN_uInfo);
  76. pv_meanDuring = arrayfun(@(u) nanmean(u.rateDuring), pvLGN_uInfo);
  77. % statistics: signrank treats nan as missing value (i.e. ignores it)
  78. p_rates = signrank(pv_meanBefore, pv_meanDuring);
  79. % change in rate, n
  80. n_rates = nnz(~isnan(pv_meanBefore) & ~isnan(pv_meanDuring));
  81. fprintf('dLGN mean rate before %3.1f sp/s, during %3.1f sp/s V1 suppression\n', ...
  82. mean(pv_meanBefore), mean(pv_meanDuring));
  83. fprintf('\tp(signrank) = %0.2g (N = %d)\n', p_rates, n_rates);
  84. % prepare for plotting
  85. scale_out = 1.2; % outliers will be plotted at max+10%
  86. ymin_r = 0;
  87. ymaxVal_r = 20;
  88. ymax_r = ymin_r + (ymaxVal_r-ymin_r)*scale_out;
  89. pv_meanBefore(pv_meanBefore > ymaxVal_r) = ymax_r;
  90. pv_meanDuring(pv_meanDuring > ymaxVal_r) = ymax_r;
  91. % make the plot
  92. figure('Name', 'Born et al. (2021), Fig. 3f'); hold on;
  93. plot(pv_meanBefore, pv_meanDuring, 'ko', 'MarkerSize', 4);
  94. hold on;
  95. plot(pv_meanBefore(exIdx), pv_meanDuring(exIdx), 'ko', 'MarkerSize', 4, ...
  96. 'MarkerEdgeColor', pinkEx, 'MarkerFaceColor', pinkEx);
  97. plot(mean(pv_meanBefore), mean(pv_meanDuring), 'ko', 'MarkerSize', 4, ...
  98. 'MarkerEdgeColor', mean_color, 'MarkerFaceColor', mean_color);
  99. hline = refline(1,0); % line of unity slope
  100. set(hline, 'color', 0.6*ones(1,3));
  101. axis equal; axis square
  102. set(gca, 'XLim', [0 ymax_r], 'YLim', [0 ymax_r], ...
  103. 'XTick', [0:10:ymaxVal_r ymax_r], 'YTick', [0:10:ymaxVal_r ymax_r]);
  104. xlabel('Control');
  105. ylabel('V1 suppression');
  106. title('Firing rate (sp/s)');
  107. %% 2g: burst ratios
  108. % compute burst data
  109. % compute burst tonic ratio before vs. during V1 suppression
  110. pv_btBefore = arrayfun(@(u) nanmean(u.btRatioBefore), pvLGN_uInfo);
  111. pv_btDuring = arrayfun(@(u) nanmean(u.btRatioDuring), pvLGN_uInfo);
  112. n_bts = nnz(~isnan(pv_btBefore) & ~isnan(pv_btDuring));
  113. pburst_pv = signrank(pv_btBefore, pv_btDuring); % treats nan as missign values
  114. fprintf('\ndLGN burst ratio before and during V1 suppression\n')
  115. fprintf('\tmean before: %3.2f%%\n\tmean during: %3.2f%%\n\tsignrank p = %02g\n\tN = %d\n', ...
  116. nanmean(pv_btBefore)*100, nanmean(pv_btDuring)*100, ...
  117. pburst_pv, n_bts);
  118. % compute burst lengths before vs. during V1 suppression
  119. pvblenBefore = cell2mat(arrayfun(@(bt) cat(1, bt.blengthBefore{:}), ...
  120. pvLGN_uInfo, 'uniformoutput', 0)');
  121. pvblenBefore(pvblenBefore < 1) = []; % 0 burst length: tonic spikes
  122. pvblenDuring = cell2mat(arrayfun(@(bt) cat(1, bt.blengthDuring{:}), ...
  123. pvLGN_uInfo, 'uniformoutput', 0)');
  124. pvblenDuring(pvblenDuring < 1) = [];
  125. [~,p_blen] = kstest2(pvblenBefore, pvblenDuring);
  126. p_med_blen = ranksum(pvblenBefore, pvblenDuring);
  127. fprintf('\ndLGN burst lengths before / during V1 suppression\n')
  128. fprintf('\tmedian before: %d\n\tmedian during: %d\n\tkstest: p = %0.2g\n\tranksum: p = %02g\n\tN = %d/%d\n', ...
  129. median(pvblenBefore), median(pvblenDuring), ...
  130. p_blen, p_med_blen, numel(pvblenBefore), numel(pvblenDuring));
  131. % prepare for plotting
  132. btTicks = [10^-2 10^-1 10^0];
  133. btTickLabels = [0.01 0.1 1];
  134. % adjust for plotting
  135. pv_btBefore(pv_btBefore == 0) = 10^-2.5;
  136. pv_btDuring(pv_btDuring == 0) = 10^-2.5;
  137. figure('Name', 'Born et al. (2021), Fig. 3g');
  138. loglog(pv_btBefore, pv_btDuring, 'ko', 'MarkerSize', 4);
  139. hold on;
  140. loglog(pv_btBefore(exIdx), pv_btDuring(exIdx), 'ko', 'MarkerSize', 4, ...
  141. 'MarkerEdgeColor', pinkEx, 'MarkerFaceColor', pinkEx);
  142. loglog(nanmean(pv_btBefore), nanmean(pv_btDuring), 'ko', 'MarkerSize', 4, ...
  143. 'MarkerEdgeColor', mean_color, 'MarkerFaceColor', mean_color);
  144. hline = refline(1,0);
  145. set(hline, 'color', 0.6*ones(1,3));
  146. axis equal; axis square
  147. set(gca, 'XLim', [10^-2.5 10^0], 'YLim', [10^-2.5 10^0], ...
  148. 'XTick', btTicks, 'YTick', btTicks, ...
  149. 'XTickLabel', btTickLabels, 'YTickLabel', btTickLabels, ...
  150. 'XMinorTick','off', 'YMinorTick','off');
  151. xlabel('Control');
  152. ylabel('V1 suppression');
  153. % inset for distribution of burst lengths
  154. figure('Name', 'Born et al. (2021), Fig. 3g inset'); hold on;
  155. ecdf(pvblenBefore)
  156. ecdf(pvblenDuring)
  157. sh = get(gca, 'Children'); % to set the color of the individual ecdfs
  158. set(sh(1), 'Color', [0 143 210]/255);
  159. set(sh(2), 'Color', 'k');
  160. ylabel('CDF')
  161. set(gca, 'XLim', [2 inf], 'YTick', [0 1])
  162. xlabel('sp/burst')