Figure_2.m 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. function fig = Figure_2( strNIXFolderPath, varargin )
  2. % Figure_2.m reproduces Figure 2 in the dataset publication
  3. % fig = Figure_2(strNIXFolderPath) reproduces Figure 2
  4. % strNIXFolderPath is the path of the folder with NIX files
  5. % fig is the figure handle
  6. % Default neuron number plotted is 30
  7. % fig = Figure_2(strNIXFolderPath,nNexampleNeuron) reproduces Figure 2 with the
  8. % example neuron nNexampleNeuron
  9. %
  10. % Add the toolbox 'gramm' to the MATLAB path
  11. % The toolbox can be downloaded from https://github.com/piermorel/gramm
  12. % Example neuron
  13. if(nargin>1)
  14. nExampleNeuron = varargin{1};
  15. else
  16. nExampleNeuron = 30;
  17. end
  18. SPIKES_All = [];
  19. % Load data for all neurons
  20. for nSubject = 1:9
  21. % File name
  22. strNIXFileName = sprintf('Data_Subject_%.2d_Session_01.h5',nSubject);
  23. % Read the NIX file
  24. f = nix.File([strNIXFolderPath,filesep,strNIXFileName],nix.FileMode.ReadOnly);
  25. % NIX data
  26. block = f.blocks{1};
  27. % Multitags for spike times
  28. group_MultiTagsSpikes = block.openGroup('Spike times multitags');
  29. multiTags_SpikeTimes = group_MultiTagsSpikes.multiTags;
  30. % If there are no neurons, continue
  31. if(isempty(multiTags_SpikeTimes))
  32. continue;
  33. end
  34. % List of neurons and trials
  35. % Format for the name is
  36. % 'Multitag_Spike_Times_Unit_<neuron number>_<micro wire name>_Trial_<trial number>'
  37. strSpikeTimeLabels = cellfun(@(x) x.name,multiTags_SpikeTimes,'UniformOutput',0);
  38. strSpikeTimeLabels = cellfun(@(x) strsplit(x,'_'),strSpikeTimeLabels,'UniformOutput',0);
  39. nNeuronsTrialsList = [cell2mat(cellfun(@(x) str2double(x{5}),strSpikeTimeLabels,'UniformOutput',0)),...
  40. cell2mat(cellfun(@(x) str2double(x{9}),strSpikeTimeLabels,'UniformOutput',0))];
  41. ranNeurons = unique(nNeuronsTrialsList(:,1));
  42. ranTrials = unique(nNeuronsTrialsList(:,2));
  43. % Load spike times and waveforms for each neuron
  44. SPIKES = [];
  45. for iNeuron = 1:length(ranNeurons)
  46. nNeuron = ranNeurons(iNeuron);
  47. spikes = [];
  48. for iTrial = 1:length(ranTrials)
  49. nTrial = ranTrials(iTrial);
  50. nDataArray = (nNeuronsTrialsList(:,1)==nNeuron)&(nNeuronsTrialsList(:,2)==nTrial);
  51. % Data array for the selected neuron and trial
  52. dataArray = multiTags_SpikeTimes{nDataArray}.openPositions;
  53. % Read spike times
  54. spike_times = dataArray.readAllData';
  55. spikes = [spikes;[spike_times,nTrial*ones(length(spike_times),1)]];
  56. end
  57. % Store spike times and trial numbers
  58. SPIKES(iNeuron).spikes = spikes;
  59. % Read waveform for the selected neuron
  60. dataArray_Waveform = multiTags_SpikeTimes{nDataArray}.features{1}.openData;
  61. % Store waveforms
  62. SPIKES(iNeuron).waveform = dataArray_Waveform.readAllData';
  63. end
  64. SPIKES_All = [SPIKES_All,SPIKES];
  65. end
  66. %% Firing rates
  67. FiringRatesHz = [];
  68. tTrialDuration = 26; % seconds
  69. for iNeuron = 1:length(SPIKES_All)
  70. nNumberOfTrials = max(SPIKES_All(iNeuron).spikes(:,2));
  71. FiringRatesHz = [FiringRatesHz,length(SPIKES_All(iNeuron).spikes(:,1))/(tTrialDuration*nNumberOfTrials)];
  72. end
  73. %% ISI
  74. isis = [];
  75. for iNeuron = 1:length(SPIKES_All)
  76. isis_ = [];
  77. for iTrial = 1:max(SPIKES_All(iNeuron).spikes(:,2))
  78. isis_ = [isis_;diff(sort(SPIKES_All(iNeuron).spikes(SPIKES_All(iNeuron).spikes(:,2)==iTrial,1))*1000)];
  79. end
  80. isis = [isis;(length(isis_(isis_<3))/length(isis_))*100];
  81. end
  82. %% SNR
  83. snr = [];
  84. waveform = [];
  85. for iNeuron = 1:length(SPIKES_All)
  86. snr_0 = max(abs(SPIKES_All(iNeuron).waveform(:,1)))/mean(SPIKES_All(iNeuron).waveform(:,2));
  87. snr = [snr snr_0];
  88. waveform = [waveform;SPIKES_All(iNeuron).waveform(:,1)'];
  89. end
  90. FR = SPIKES_All(nExampleNeuron).spikes;
  91. %% Firing rate for a single neuron
  92. c = [];
  93. tPre = -2;
  94. tPost = 24;
  95. binSize = 0.1;
  96. ranTrials = {};
  97. for i = 1:max(FR(:,2))
  98. for iCondition = [0,1] % 1 - aversive, 0 - neutral
  99. if(mod(i,2)==iCondition)
  100. spikeTimes = FR(FR(:,2) == i,1);
  101. ranTrials{i} = spikeTimes;
  102. % Trial conditions
  103. c = [c,iCondition+1];
  104. % Binned spikes
  105. temp = histc(spikeTimes,tPre:binSize:tPost);
  106. binned{i} = smooth(temp(1:end-1)/binSize,10);
  107. % Bin centers
  108. bins{i} = (tPre+binSize/2):binSize:(tPost-binSize/2);
  109. end
  110. end
  111. end
  112. %% Plot Figure 2
  113. fig = figure;
  114. fig.Units = 'centimeters';
  115. fig.Position(2:4) = [5,16,16];
  116. % Example neuron
  117. % Firing rate
  118. strTrialCondition = {'Aversive','Neutral'};
  119. catTrialCondition = strTrialCondition(c);
  120. g(1) = gramm('x',bins,'y',binned,'Color',catTrialCondition);
  121. custom_statfun = @(y)([mean(y);
  122. mean(y)-std(y)/sqrt(17);
  123. mean(y)+std(y)/sqrt(17)]);
  124. g(1).stat_summary('setylim',true,'type',custom_statfun);
  125. g(1).set_names('x','','y','Rate (Hz)','Color','');
  126. g(1).set_layout_options('position',[0.05,0.7,0.85,0.25],'Legend_Position',[0.16,0.85,0.25,0.15]);
  127. g(1).set_color_options('map',[1,0,0;0,0,1],'n_color',2,'n_lightness',1);
  128. g(1).axe_property('XLim',[tPre,tPost],'XTick',[],'YLim',[-1,10.5],'YTick',0:5:10,'XColor','none','YColor','k',...
  129. 'FontName','Arial','FontSize',10,'TickDir','out','TickLength',[0.015,0.0250]);
  130. % Spike shape
  131. g(6) = gramm('x',((1:64)-20)/32,'y',waveform(nExampleNeuron,:));
  132. g(6).geom_line();
  133. g(6).set_names('x','Time (ms)','y','\muV');
  134. g(6).set_layout_options('position',[0.75,0.85,0.13,0.12]);
  135. g(6).set_text_options('base_size',4,'interpreter','tex');
  136. % g(6).set_color_options('chroma',0,'lightness',30);
  137. g(6).set_color_options('map',[0,0,0],'n_color',1,'n_lightness',1);
  138. g(6).set_line_options('base_size',1);
  139. g(6).no_legend();
  140. g(6).axe_property('XLim',[(1-20)/32,(64-20)/32],'XTick',[0,1],'YTick',[0,30],'XColor','k','YColor','k',...
  141. 'FontName','Arial','FontSize',7,'TickDir','out','TickLength',[0.08,0.0250]);
  142. % Raster
  143. g(2) = gramm('x',ranTrials,'Color',c);
  144. g(2).geom_raster('geom','point');
  145. g(2).set_point_options('base_size',3);
  146. g(2).set_names('x','Time (s)','y','Trial no. (reordered)');
  147. g(2).set_layout_options('position',[0.05,0.4,0.85,0.28]);
  148. g(2).set_color_options('map',[1,0,0;0,0,1],'n_color',2,'n_lightness',1);
  149. g(2).no_legend();
  150. g(2).axe_property('XLim',[tPre,tPost],'YLim',[-1,11],'YTick',0:5:10,'XColor','k','YColor','k',...
  151. 'FontName','Arial','FontSize',10,'TickDir','out','TickLength',[0.015,0.0250]);
  152. % Spike sorting quality metrics
  153. % ISI
  154. g(3) = gramm('x',isis);
  155. g(3).stat_bin();
  156. g(3).set_layout_options('position',[0.05,0.1,0.25,0.25]);
  157. g(3).set_names('x','Percentage of ISI < 3 ms','y','No. of neurons');
  158. g(3).axe_property('XLim',[-0.15,3.7],'YLim',[0,7],'XColor','k','YColor','k',...
  159. 'FontName','Arial','FontSize',10,'TickDir','out','TickLength',[0.03,0.0250]);
  160. g(3).set_color_options('hue_range',[155,200]);
  161. % Firing rate
  162. g(4) = gramm('x',FiringRatesHz);
  163. g(4).stat_bin();
  164. g(4).set_layout_options('position',[0.35,0.1,0.25,0.25]);
  165. g(4).set_names('x','Firing rate (Hz)','y','No. of neurons');
  166. g(4).axe_property('XLim',[-0.8 20],'YLim',[0,7],'XColor','k','YColor','k',...
  167. 'FontName','Arial','FontSize',10,'TickDir','out','TickLength',[0.03,0.0250]);
  168. g(4).set_color_options('hue_range',[155,200]);
  169. % SNR
  170. g(5) = gramm('x',snr);
  171. g(5).stat_bin();
  172. g(5).set_layout_options('position',[0.65,0.1,0.25,0.25]);
  173. g(5).set_names('x','Waveform peak SNR','y','No. of neurons');
  174. g(5).axe_property('XLim',[-0.4,10],'YLim',[0,7],'XColor','k','YColor','k',...
  175. 'FontName','Arial','FontSize',10,'TickDir','out','TickLength',[0.03,0.0250]);
  176. g(5).set_color_options('hue_range',[155,200]);
  177. % Labels
  178. x = [0.02,0.02,0.34,0.66];
  179. y = [0.98,0.35,0.35,0.35];
  180. l = ['a','b','c','d'];
  181. g(7) = gramm('x',x,'y',y,'label',l);
  182. g(7).geom_label('Color','k','FontWeight','bold','FontName','Arial');
  183. g(7).axe_property('XColor','none','YColor','none','XLim',[0,1],...
  184. 'YLim',[0,1],'Visible','off');
  185. g(7).set_layout_options('position',[0,0,1,1]);
  186. g.draw();
  187. yPosOffset = g(1).facet_axes_handles.Position(1)-g(3).facet_axes_handles.Position(1);
  188. for iAx = 3:5
  189. g(iAx).facet_axes_handles.Position(1) = g(iAx).facet_axes_handles.Position(1)+yPosOffset;
  190. end
  191. % YLabel positions
  192. for iAx = setdiff(1:7,[6,7])
  193. g(iAx).facet_axes_handles.YLabel.Units = 'centimeters';
  194. g(iAx).facet_axes_handles.YLabel.Position(1) = -0.8;
  195. end
  196. g(2).facet_axes_handles.Children(1).MarkerSize = 2.5;
  197. g(2).facet_axes_handles.Children(2).MarkerSize = 2.5;
  198. % Save figure
  199. print('-dpdf','-r600','-painters','Fig2.pdf');
  200. print('-dpng','-r600','-painters','Fig2.png');
  201. end