MakeTm4Tm9RFs_fig3.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. ccc
  2. %% Define search path.
  3. parentDir = fileparts(fileparts(mfilename('fullpath')));
  4. saveFolder = [parentDir filesep 'data'];
  5. load([saveFolder filesep 'Fig3-data_Tm9GCaMP6f-Tm4jRGECO1a_ONOFFPaperNew']);
  6. %%
  7. figDir = [parentDir filesep 'figures' filesep 'Fig3' filesep];
  8. if ~exist(figDir, 'dir'); mkdir(figDir); end
  9. %% Genereta figure 3b
  10. onOffPerCell{1} = cell2mat(cellfun(@(x) cell2mat(cellfun(@(y) y, x(:, 1), 'uni', 0)), onoffData, 'Uni', 0)')';
  11. onOffPerCell{2} = cell2mat(cellfun(@(x) cell2mat(cellfun(@(y) y, x(:, 2), 'uni', 0)), onoffData, 'Uni', 0)')';
  12. timePoints = (0: size(onOffPerCell{1}, 2)-1) /10;
  13. plotONOFFTracesFromCell(onOffPerCell, {'Tm4', 'Tm9'}, [figDir filesep], brewermap(2, 'PrGn'));
  14. %% Save data from plot.
  15. dataFileName = [figDir filesep 'Fig3.xls'];
  16. DataTable = createRFsTable(onOffPerCell{1}, 'Time_seconds_Tm4');
  17. DataTable(:, 1).Time_seconds_Tm4 = timePoints(:);
  18. writetable(DataTable, dataFileName, 'Sheet', 'Fig3b', 'Range', 'A1');
  19. DataTable = createRFsTable(onOffPerCell{2}, 'Time_seconds_Tm9');
  20. DataTable(:, 1).Time_seconds_Tm9 = timePoints(:);
  21. writetable(DataTable, dataFileName, 'Sheet', 'Fig3b', 'Range', ['A' num2str(size(onOffPerCell{1}, 2) + 3)])
  22. %% Reanalyze data of dual imaging.
  23. ccc
  24. parentDir = fileparts(fileparts(mfilename('fullpath')));
  25. saveFolder = [parentDir filesep 'data'];
  26. load([saveFolder filesep 'Fig3-data_Tm9GCaMP6f-Tm4jRGECO1a_All']);
  27. %%
  28. figDir = [parentDir filesep 'figures' filesep 'Fig3' filesep];
  29. if ~exist(figDir, 'dir'); mkdir(figDir); end
  30. %%
  31. [nFlies, nLayers, nStims] = size(dataEdges);
  32. % New functions use cell arrays.
  33. dataEdges = mat2cell(dataEdges, ones(1, nFlies), ones(1, nLayers), ones(1, nStims));
  34. % Get tuning curves.
  35. tuningStat = 'maxAbs';
  36. % tuningStat = 'median';
  37. barRFs = collectRFs(dataEdges, tuningStat);
  38. % Remove blanck epoch.
  39. barRFs = cellfun(@(x) x(:, 2: end), barRFs, 'Uni', 0);
  40. barRFs([2, 4], :) = cellfun(@(x) x(:, 3: end - 2), barRFs([2, 4], :), 'Uni', 0);
  41. %%
  42. fitStructOff = cellfun(@(x) fitGaussian1(1: size(x, 2), x, 1), barRFs(1:2, :), 'Uni', 0);
  43. fitStructOn = cellfun(@(x) fitGaussian1(1: size(x, 2), x, -1), barRFs(3:4, :), 'Uni', 0);
  44. fitStructBars = [fitStructOff; fitStructOn];
  45. %% Extract the parameters for the analysis of spatial RFs.
  46. for iChannel = 1: 2
  47. amp{iChannel} = cell2mat(cellfun(@(x) arrayfun(@(y) y.fit.a1, x, 'uni', 1), ...
  48. fitStructBars(:, iChannel), 'uni', 0));
  49. pos{iChannel} = cell2mat(cellfun(@(x) arrayfun(@(y) y.fit.b1, x, 'uni', 1), ...
  50. fitStructBars(:, iChannel), 'uni', 0));
  51. width{iChannel} = cell2mat(cellfun(@(x) arrayfun(@(y) y.fit.c1, x, 'uni', 1), ...
  52. fitStructBars(:, iChannel), 'uni', 0));
  53. rsquare{iChannel} = cell2mat(cellfun(@(x) arrayfun(@(y) y.gof.rsquare, x, 'uni', 1), ...
  54. fitStructBars(:, iChannel), 'uni', 0));
  55. end
  56. pos = cellfun(@(x) 2 * (x - 1), pos, 'uni', 0);
  57. width = cellfun(@(x) 2 * (2 * sqrt(log(2))) * x, width, 'uni', 0);
  58. %%
  59. % barRFs = cellfun(@(x) alignRFsToAbsMax(x, 0), barRFs, 'uni', 0);
  60. % The screen is about 48-60 deg, we center the RFs at about the center 24
  61. % deg, using the fit positions for higher presicion.
  62. for iChannel = 1: 2
  63. lagsBars = round((pos{iChannel}(1: 4, :) - 25) / 2);
  64. for iBar = 1: size(barRFs, 1)
  65. barRFs{iBar, iChannel} = alignRFsToAbsMax(barRFs{iBar, iChannel}, 0, lagsBars(iBar, :)');
  66. end
  67. end
  68. %% Use all data for fig3c-d
  69. splitSign = 1;
  70. doSmoothing = 1;
  71. rSquareCutoff = -20;
  72. plotImage = 1;
  73. hue = [];
  74. useSubplots = 1;
  75. for iChannel = 1: 2
  76. rSquareArray = rsquare{iChannel}';
  77. % Check good fit for all stim.
  78. [rfInds{1: 2, iChannel}] = deal(all(rSquareArray(:, [1: 2]) >= rSquareCutoff, 2));
  79. [rfInds{3: 4, iChannel}] = deal(all([rSquareArray(:, [1:2]) >= rSquareCutoff ...
  80. rSquareArray(:, [3:4]) >= -20], 2));
  81. end
  82. %% Figure 3c, examples extracted from here.
  83. hFig = createPrintFig(10 * [ 1 1]);
  84. for iChannel = 1: 2
  85. subplot(2, 2, 2 * iChannel - 1);
  86. plotRFEnsemble(barRFs{2, iChannel}, barRFs{1, iChannel}, ...
  87. splitSign, doSmoothing, rfInds{1, iChannel}, plotImage, hue, useSubplots)
  88. subplot(2, 2, 2 * iChannel);
  89. plotRFEnsemble(barRFs{4, iChannel}, barRFs{3, iChannel}, ...
  90. splitSign, doSmoothing, rfInds{3, iChannel}, plotImage, hue, useSubplots)
  91. end
  92. figFileName = ['RFIm-ON-OFF-Noise-raw-ON-norm'];
  93. print(hFig, [figDir filesep figFileName '.pdf'], '-dpdf')
  94. %% For the mean images in fig. 3d
  95. filteredRFs = cellfun(@(x, y) x(y, :), barRFs, rfInds, 'uni', 0);
  96. maxNorm = @(x, dim) x ./ max(abs(x), [], dim);
  97. getRow = @(x, nRow) x(nRow, :);
  98. % normRFs = cellfun(@(x) cell2mat(arrayfun(@(y) smooth(getRow(maxNorm(x,2), y))', 1: size(x, 1), 'uni', 0)'), ...
  99. % barRFs, 'uni', 0);
  100. normRFs = cellfun(@(x) cell2mat(arrayfun(@(y) smooth(getRow(x, y))', 1: size(x, 1), 'uni', 0)'), ...
  101. filteredRFs, 'uni', 0);
  102. normRFs = cellfun(@(x) maxNorm(x,2), normRFs, 'uni', 0);
  103. % Maximum of the mean tuning curve to normalize image accross stimuli.
  104. maxPerStim = max(cellfun(@(x) max(abs(mean(x))), filteredRFs, 'uni', 1), [], 2);
  105. maxPerPolarity = max(reshape(maxPerStim, [2 2]));
  106. hFig = createPrintFig(15 * [ 1 1 / 3]);
  107. for iRFType = 1:4
  108. subplot_tight(1, 4, iRFType);
  109. % imshow(getRFIm(mean(normRFs{2*iRFType}), mean(normRFs{2*iRFType - 1})))
  110. imshow(getRFIm(mean(filteredRFs{2*iRFType}), mean(filteredRFs{2*iRFType - 1}), ...
  111. maxPerPolarity(2 - mod(iRFType, 2))))
  112. end
  113. %%
  114. figFileName = ['RFIm-ON-OFF-Noise-mean'];
  115. print(hFig, [figDir filesep figFileName '.pdf'], '-dpdf')
  116. %% For the mean traces in fig 3d.
  117. hFig = createPrintFig(15 * [ 1 2/3]);
  118. labelsCell = {'Tm4 off x' 'Tm4 off y' 'Tm4 on x' 'Tm4 on y'...
  119. 'Tm9 off x' 'Tm9 off y' 'Tm9 on x' 'Tm9 on y'};
  120. rfsToPlot = filteredRFs; % or normRFs.
  121. plotONOFFTracesFromCell(rfsToPlot, labelsCell, [figDir filesep], brewermap(8, 'Paired'))
  122. hSubAx = plotLasagnaTracesFromCell(gcf, rfsToPlot, brewermap(8, 'Paired'));
  123. ylim(hSubAx(:, 1), [-1 1]);
  124. arrayfun(@(x) set(get(x, 'YAxis'), 'Visible', 'on'), hSubAx(1, :))
  125. cellfun(@(x) caxis(ZeroCenteredBounds(x, [0 100])), rfsToPlot, 'uni', 0)
  126. arrayfun(@prettifyAxes, hSubAx)
  127. arrayfun(@offsetAxes, hSubAx)
  128. set(hSubAx, 'Visible', 'off')
  129. % figFileName = ['RFcurves-ON-OFF-Noise-XY-lasagna'];
  130. % print(hFig, [figDir figFileName '.pdf'], '-dpdf')
  131. %%
  132. dataFileName = [figDir filesep 'Fig3.xls'];
  133. DataTable = createRFsTable(rfsToPlot{1, 1}, 'Tm4_OFF_horizontal_position_deg');
  134. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A1')
  135. DataTable = createRFsTable(rfsToPlot{2, 1}, 'Tm4_OFF_vertical_position_deg');
  136. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A29')
  137. DataTable = createRFsTable(rfsToPlot{3, 1}, 'Tm4_ON_horizontal_position_deg');
  138. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A56')
  139. DataTable = createRFsTable(rfsToPlot{4, 1}, 'Tm4_ON_vertical_position_deg');
  140. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A83')
  141. DataTable = createRFsTable(rfsToPlot{1, 2}, 'Tm9_OFF_horizontal_position_deg');
  142. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A110')
  143. DataTable = createRFsTable(rfsToPlot{2, 2}, 'Tm9_OFF_vertical_position_deg');
  144. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A137')
  145. DataTable = createRFsTable(rfsToPlot{3, 2}, 'Tm9_ON_horizontal_position_deg');
  146. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A164')
  147. DataTable = createRFsTable(rfsToPlot{4, 2}, 'Tm9_ON_vertical_position_deg');
  148. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A191')
  149. %%
  150. splitSign = 1;
  151. doSmoothing = 1;
  152. rSquareCutoff = 0.5;
  153. plotImage = 1;
  154. hue = [];
  155. useSubplots = 1;
  156. % for iChannel = 1: 2
  157. % rSquareArray = rsquare{iChannel}';
  158. % % Check good fit for all stim.
  159. % indsToPlot = all([rSquareArray(:, [1:2]) >= rSquareCutoff ...
  160. % rSquareArray(:, [3:4]) >= 0.1], 2);
  161. % rfInds{:, iChannel} = indsToPlot;
  162. % end
  163. for iChannel = 1: 2
  164. rSquareArray = rsquare{iChannel}';
  165. % Check good fit for all stim.
  166. [rfInds{1: 2, iChannel}] = deal(all(rSquareArray(:, [1: 2]) >= rSquareCutoff, 2));
  167. [rfInds{3: 4, iChannel}] = deal(all([rSquareArray(:, [1:2]) >= rSquareCutoff ...
  168. rSquareArray(:, [3:4]) >= 0.2], 2));
  169. end
  170. %% Figure 3e
  171. hFig = createPrintFig(15 * [1/2 1/2]);
  172. meanWidth = {mean(width{1}(1: 2, rfInds{1, 1}))
  173. mean(width{2}(1: 2, rfInds{1, 2}))
  174. mean(width{2}(3: 4, rfInds{3, 2}))};
  175. beanPlot(meanWidth, {'Tm4 off', 'Tm9 off', ' Tm9 on'}, flipud(brewermap(4, 'Set1')), 1, gca,'unbounded', 'vertical', false, true)
  176. figFileName = ['RF-ON-OFF-Noise-Width-Bean'];
  177. print(hFig, [figDir filesep figFileName '.pdf'], '-dpdf')
  178. %% Save data for Fig 3e
  179. sheetName = 'Fig3e';
  180. xlswrite(dataFileName, {'Tm4-FHWM-OFF-bars'}, sheetName, 'A1')
  181. xlswrite(dataFileName, meanWidth{1}, sheetName, 'B1')
  182. xlswrite(dataFileName, {'Tm9-FHWM-OFF-bars'}, sheetName, 'A2')
  183. xlswrite(dataFileName, meanWidth{2}, sheetName, 'B2')
  184. xlswrite(dataFileName, {'Tm9-FHWM-ON-bars'}, sheetName, 'A3')
  185. xlswrite(dataFileName, meanWidth{3}, sheetName, 'B3')
  186. %% For revision, reviewer 3 plot some raw traces.
  187. %
  188. receptiveFieldTraces = collectRFTraces(dataEdges);
  189. filteredRFTraces = cellfun(@(x, y) x(y, :), receptiveFieldTraces, rfInds, 'uni', 0);
  190. rng(1001)
  191. subsampleInds = randsample(min(cellfun(@(x) size(x, 1), receptiveFieldTraces(1, :))) - 1, 10);
  192. filteredRFTraces = receptiveFieldTraces;
  193. %% Attempt to plot traces correctly, this is working now!
  194. deleteLastROI = 1;
  195. % Define the array to compare to randomized recordings.
  196. xOffStimFileName = 'StandingStripe_1s_XAxis_5degWide_2degSep_m1.0Con_rand_USEFRUSTUM.txt';
  197. yOffStimFileName = 'StandingStripe_1s_YAxis_5degWide_2degSep_m1.0Con_rand_USEFRUSTUM.txt';
  198. xOnStimFileName = 'StandingStripe_1s_XAxis_5degWide_2degSep_p1.0Con_rand_USEFRUSTUM.txt';
  199. yOnStimFileName = 'StandingStripe_1s_YAxis_5degWide_2degSep_p1.0Con_rand_USEFRUSTUM.txt';
  200. barStimFileNames = {xOffStimFileName, yOffStimFileName, xOnStimFileName, yOnStimFileName};
  201. %%
  202. % Take rows as ROIs.
  203. hFunYOffsetTraces = @(traces, yOffset) ...
  204. bsxfun(@plus, traces, yOffset * (1: size(traces, 1))');
  205. %%
  206. nChannels = numel(dataEdges{1}.roiTCsInterp);
  207. % receptiveFieldsAll = cell(4, nChannels);
  208. cellCounter = zeros(2, 4);
  209. hFig = createPrintFig(30 * [1 1 / 2]);
  210. axInds(1, :) = [1, 2, 5, 6];
  211. axInds(2, :) = [3, 4, 7, 8];
  212. for iFly = 1: size(dataEdges, 1)
  213. % flyPathInd = iFly;
  214. for jStim = 2:5
  215. % Find index of matching stimulus.
  216. rfInd = find(strcmp(dataEdges{iFly, 1, jStim}.stimulusName, barStimFileNames));
  217. if ~isempty(rfInd)
  218. for kChannel = 1: nChannels
  219. dataTmp = dataEdges{iFly, 1, jStim};
  220. nEpochs = numel(dataTmp.stimFrameInds);
  221. nCells = size(dataTmp.roiTCs{kChannel}, 2);
  222. roiTCs = dataTmp.roiTCs{kChannel};
  223. % Add a fake epoch at the end.
  224. dataTmp.stimFrameInds{end + 1} = dataTmp.stimFrameInds{end}(end) + ...
  225. (1: numel(dataTmp.stimFrameInds{end}));
  226. roiTCs(:, :, dataTmp.stimFrameInds{end}) = nan;
  227. indsCellArray = [dataTmp.stimFrameInds(1: end - 1);
  228. repmat(dataTmp.stimFrameInds(end), 1, nEpochs)];
  229. interleavedCellArray = reshape(indsCellArray, 1, []);
  230. plotIndsVec = cat(2, interleavedCellArray{:});
  231. roiTraces = squeeze(roiTCs(:, 1: end - 1 * deleteLastROI, plotIndsVec));
  232. times = dataTmp.frameDuration * (1: numel(plotIndsVec));
  233. hAx(kChannel, rfInd) = subplot(2, 4, axInds(kChannel, rfInd));
  234. plot(times, hFunYOffsetTraces(roiTraces + cellCounter(kChannel, rfInd), 1));
  235. hold on
  236. cellCounter(kChannel, rfInd) = cellCounter(kChannel, rfInd) + nCells;
  237. rawTracesStruct(iFly, rfInd, kChannel).times = times;
  238. rawTracesStruct(iFly, rfInd, kChannel).traces = roiTraces;
  239. end
  240. end
  241. end
  242. end
  243. %% This is figure S2
  244. close all
  245. hFig = createPrintFig(30 * [1 1 / 2]);
  246. axInds(1, :) = [1, 2, 5, 6];
  247. axInds(2, :) = [3, 4, 7, 8];
  248. flyInd = 10; % Good examples 4, 6, 7, and 10
  249. genotypeColors = [166,118,29; 27,158,119] / 255;
  250. for iStim = 1: 4
  251. for jChannel = 1: 2
  252. hTracesAx(jChannel, iStim) = subplot(2, 4, axInds(jChannel, iStim));
  253. tmpTimes = rawTracesStruct(flyInd, iStim, jChannel).times;
  254. tmpTraces = rawTracesStruct(flyInd, iStim, jChannel).traces;
  255. plot(tmpTimes, hFunYOffsetTraces(tmpTraces, 0.7), ...
  256. 'Color', genotypeColors(jChannel, :), 'LineWidth', 1);
  257. axis tight
  258. hLines = arrayfun(@(x) refline(0, x), 0.7 * (1: size(tmpTraces, 1)));
  259. [hLines.Color] = deal([1 1 1] * 0.5);
  260. [hLines.LineWidth] = deal(0.5);
  261. end
  262. end
  263. xlabel(hTracesAx(5), 'Time (s)')
  264. ylabel(hTracesAx(5), '\DeltaF/F_0')
  265. setFontForThesis(hTracesAx, gcf);
  266. arrayfun(@prettifyAxes, hTracesAx)
  267. arrayfun(@offsetAxes, hTracesAx)
  268. figFileName = ['Fig3-suppl-meanTraces-sortedPositions'];
  269. print(hFig, [figDir figFileName '.pdf'], '-dpdf')
  270. %%
  271. DataTable = createRFsTable(rfsToPlot{1, 1}, 'Tm4_OFF_horizontal_position_deg');
  272. writetable(DataTable, dataFileName, 'Sheet', 'Fig3cd', 'Range', 'A1')
  273. %%
  274. flyInd = 10; % Good examples 4, 6, 7, and 10
  275. sheetName = 'SupFig3ac';
  276. startRow = 1;
  277. stimNameStrCell = {'Tm4_OFF_horizontal_bar_time_seconds', 'Tm4_OFF_vertical_bar_time_seconds', ...
  278. 'Tm4_ON_horizontal_bar_time_seconds', 'Tm4_ON_vertical_bar_time_seconds'};
  279. for iStim = 1: 4
  280. DataTable = createRFsTable(rawTracesStruct(flyInd, iStim, 1).traces, stimNameStrCell{iStim});
  281. DataTable(:, 1).(stimNameStrCell{iStim}) = rawTracesStruct(flyInd, iStim, 1).times(:);
  282. writetable(DataTable, dataFileName, 'Sheet', sheetName, 'Range', ['A' num2str(startRow)]);
  283. startRow = startRow + size(DataTable, 1) + 2;
  284. end
  285. sheetName = 'SupFig3bd';
  286. startRow = 1;
  287. stimNameStrCell = {'Tm9_OFF_horizontal_bar_time_seconds', 'Tm9_OFF_vertical_bar_time_seconds', ...
  288. 'Tm9_ON_horizontal_bar_time_seconds', 'Tm9_ON_vertical_bar_time_seconds'};
  289. for iStim = 1: 4
  290. DataTable = createRFsTable(rawTracesStruct(flyInd, iStim, 2).traces, stimNameStrCell{iStim});
  291. DataTable(:, 1).(stimNameStrCell{iStim}) = rawTracesStruct(flyInd, iStim, 2).times(:);
  292. writetable(DataTable, dataFileName, 'Sheet', sheetName, 'Range', ['A' num2str(startRow)]);
  293. startRow = startRow + size(DataTable, 1) + 2;
  294. end