BlackrockNEVLoadingEngine.m 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. function [timeStamps, waveForms] = BlackrockNEVLoadingEngine(varargin)
  2. %%
  3. % Blackrock Microsystems NEV loading engine for MClust 3.0.
  4. %
  5. % Kian Torab
  6. % support@blackrockmicro.com
  7. % Blackrock Microsystems
  8. %
  9. % Version 1.3.0.0
  10. %
  11. % Version 1.4 by Saman Hagh Gooie - 13 October 2016
  12. % - Modifed to work with the latest version of the MClust v4.4
  13. if nargin == 1
  14. fn = varargin{1};
  15. elseif nargin == 2
  16. if strcmp(varargin{1}, 'get')
  17. switch (varargin{2})
  18. case 'ChannelValidity'
  19. timeStamps = [true true true true]; return;
  20. case 'ExpectedExtension'
  21. timeStamps = '.nev'; return;
  22. case 'UseFileDialog'
  23. timeStamps = true; return;
  24. case 'filenames'
  25. timeStamps = false; return;
  26. otherwise
  27. error('Unknown get condition.');
  28. end
  29. else
  30. error('2 argins requires "get" as the first argument.');
  31. end
  32. elseif nargin == 3
  33. fn = varargin{1};
  34. recordToGet = varargin{2};
  35. recordUnits = varargin{3};
  36. end
  37. if ~exist(fn, 'file')
  38. disp('File does not exist.');
  39. timeStamps = false;
  40. waveForms = false;
  41. return;
  42. end
  43. clc
  44. %% Reading the entire data if recordUnits is not defined
  45. if ~exist('recordUnits', 'var')
  46. NEV = loadNEV(fn, 'read');
  47. %Determining what channels are in the data file
  48. readElectrodes = unique(NEV.Data.Spikes.Electrode);
  49. %Saving all timestamps from the file into the timeStamp output variable
  50. timeStamps = NEV.Data.Spikes.TimeStamp(NEV.Data.Spikes.Electrode==readElectrodes(1));
  51. timeStamps = timeStampsToTimestampSeconds(timeStamps,NEV.MetaTags.SampleRes);
  52. %Saving all saveforms from the file into the waveForm output variable
  53. waveForms = initializeWaveform(length(timeStamps));
  54. for idx = 1:length(readElectrodes)
  55. waveForms(:,idx,:) = NEV.Data.Spikes.Waveform(1:32,NEV.Data.Spikes.Electrode == readElectrodes(idx))';
  56. end
  57. else
  58. %% Reading the file depending on what recordUnits is defining
  59. switch recordUnits
  60. case 1 %Returning timestamp and waveforms for given timestamps
  61. %Loading the NEV file
  62. NEV = loadNEV(fn, 'read');
  63. %Saving all timestamps in the timeStamps output variable
  64. timeStamps = NEV.Data.Spikes.TimeStamp;
  65. %Converting seconds to NEV timestamps
  66. recordToGet = timeStampsSecondsToTimestamps(recordToGet,NEV.MetaTags.SampleRes);
  67. %Calculating the index of timestamps to get
  68. for idx = 1:length(recordToGet)
  69. IDXtoGet(idx) = find(timeStamps == recordToGet(idx),1);
  70. end
  71. %Saving all timestamps requested by the timestamps
  72. timeStamps = timeStamps(IDXtoGet);
  73. timeStamps = timeStampsToTimestampSeconds(timeStamps,NEV.MetaTags.SampleRes);
  74. %Calculating the number of timestamps
  75. numOfTimestamps = length(timeStamps);
  76. %Preallocating a 3D waveforms matrix
  77. waveForms = initializeWaveform(numOfTimestamps);
  78. %Saving all waveforms in the waveForms output variable
  79. waveForms(:,1,1:32) = NEV.Data.Spikes.Waveform(1:32,IDXtoGet)';
  80. case 2 %Returning timestamp and waveforms for given records
  81. %Loading the NEV file
  82. NEV = loadNEV(fn, 'read');
  83. %Saving the timestamps for the requested records
  84. timeStamps = NEV.Data.Spikes.TimeStamp(1,recordToGet);
  85. timeStamps = timeStampsToTimestampSeconds(timeStamps,NEV.MetaTags.SampleRes);
  86. %Calculating the number of timestamps
  87. numOfTimestamps = length(timeStamps);
  88. %Saving the waveforms for the requested records
  89. waveForms = initializeWaveform(numOfTimestamps);
  90. %Determining what channels are in the data file
  91. readElectrodes = unique(NEV.Data.Spikes.Electrode);
  92. for idx = 1:length(readElectrodes)
  93. temp = NEV.Data.Spikes.Waveform(1:32,NEV.Data.Spikes.Electrode == readElectrodes(idx))';
  94. waveForms(:,idx,:) = temp(recordToGet,:);
  95. end
  96. case 3 %Returning timestamp and waveforms for range of given timestamps
  97. %Loading the NEV file
  98. NEV = loadNEV(fn, 'read');
  99. %Converting timestamps in seconds to timestamps in samples
  100. recordToGet = timeStampsSecondsToTimestamps(recordToGet,NEV.MetaTags.SampleRes);
  101. %Parsing out the timestamp range
  102. tInitial = recordToGet(1);
  103. tEnd = recordToGet(2);
  104. %Saving all timestamps in the timeStamps output variable
  105. timeStamps = NEV.Data.Spikes.TimeStamp;
  106. %Finding timestamps that fall within the range
  107. IDX = find(timeStamps <= tEnd & timeStamps >= tInitial);
  108. %Saving all timestamps that fall within the range
  109. timeStamps = NEV.Data.Spikes.TimeStamp(1,IDX);
  110. timeStamps = timeStampsToTimestampSeconds(timeStamps,NEV.MetaTags.SampleRes);
  111. %Calculating the number of timestamps
  112. numOfTimestamps = length(timeStamps);
  113. %Preallocating a 3D waveforms matrix
  114. waveForms = initializeWaveform(numOfTimestamps);
  115. %Determining what channels are in the data file
  116. readElectrodes = unique(NEV.Data.Spikes.Electrode);
  117. for idx = 1:length(readElectrodes)
  118. temp = NEV.Data.Spikes.Waveform(1:32,NEV.Data.Spikes.Electrode == readElectrodes(idx))';
  119. waveForms(:,idx,:) = temp(IDX,:);
  120. end
  121. case 4 %Returning timestamp and waveforms for the range of given records
  122. %Loading the NEV file
  123. NEV = loadNEV(fn, 'read');
  124. %Creating a range out of the record list
  125. recordToGet = [recordToGet(1):recordToGet(end)];
  126. %Saving the timestamps for the requested records
  127. timeStamps = NEV.Data.Spikes.TimeStamp(1,recordToGet);
  128. timeStamps = timeStampsToTimestampSeconds(timeStamps,NEV.MetaTags.SampleRes);
  129. %Calculating the number of timestamps
  130. numOfTimestamps = length(timeStamps);
  131. %Saving the waveforms for the requested records
  132. waveForms = initializeWaveform(numOfTimestamps);
  133. % Loading the waveforms into a MClust waveform variable
  134. readElectrodes = unique(NEV.Data.Spikes.Electrode);
  135. for idx = 1:length(readElectrodes)
  136. waveForms(:,idx,:) = NEV.Data.Spikes.Waveform(1:32,NEV.Data.Spikes.Electrode == readElectrodes(idx))';
  137. end
  138. %Saving the waveforms for the requested records
  139. waveForms = waveForms(recordToGet, :, :);
  140. case 5 %Returning the number of records in the file
  141. %Loading the NEV file
  142. NEV = loadNEV(fn);
  143. % Returning the number of spikes
  144. timeStamps = size(NEV.Data.Spikes.TimeStamp, 2)/length(unique(NEV.Data.Spikes.Electrode));
  145. waveForms = [];
  146. otherwise
  147. disp('Invalid input for recordUnit');
  148. disp('Values from 1 to 5 are valid only.');
  149. end
  150. end
  151. timeStamps = timeStamps';
  152. %% Uses openNEV (a part of NPMK package: http://bit.ly/brnpmkkit) to open the NEV file
  153. function NEV = loadNEV(fn, input)
  154. if ~exist('input', 'var')
  155. NEV = openNEV(fn, 'nomat', 'nosave');
  156. elseif strcmpi(input, 'noread')
  157. NEV = openNEV(fn, 'nomat', 'nosave');
  158. elseif ~strcmpi(input, 'read')
  159. disp('Invalid input.');
  160. else
  161. NEV = openNEV(fn, 'nomat', 'nosave');
  162. end
  163. %% Initializes the waveform variable depending on the number of spikes in the file
  164. function waveForms = initializeWaveform(numOfTimestamps)
  165. waveForms = zeros(numOfTimestamps, 4, 32);
  166. %% Converts the timestamp samples to timestamp values in seconds
  167. function timeStampsSec = timeStampsToTimestampSeconds(timeStamps, samplingRate)
  168. timeStampsSec = double(timeStamps) / double(samplingRate);
  169. %% Converts the timestamp seconds to timestamp values in samples
  170. function timeStamps = timeStampsSecondsToTimestamps(timeStampsSeconds, samplingRate)
  171. timeStamps = int32(timeStampsSeconds * double(samplingRate));