rethresholdNSx.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. function NEV = rethresholdNSx(varargin)
  2. % rethresholdNSx
  3. %
  4. % Opens a NEV file and rethresholds it. It outputs a NEV structure into
  5. % MATLAB. This version currently does not save a new NEV file.
  6. %
  7. % All input arguments are optional. Input arguments must be in the
  8. % following order:
  9. %
  10. % NSx: The data structure holding the channel information
  11. %
  12. % Threshold: The threshold value in µV. This can be a positive or
  13. % negative value.
  14. % DEFAULT: Will automatically set threshold to -65 µV.
  15. %
  16. % FilterFreq: The high-pass filter high-pass corner frequency. For
  17. % example, if the filter is set to 250 then the signal will
  18. % first get high-pass filtered at 250 Hz before getting
  19. % rethrholded.
  20. % DEFAULT: Will automatically high-pass filter signal at
  21. % 250 Hz.
  22. %
  23. % Example:
  24. %
  25. % NEV = rethresholdNSx(NSx, -85, 150);
  26. %
  27. % In the example above, the NSx structure will be high-pass filtered at
  28. % 150 Hz and then rethresholded at -85 µV. All new waveformes will be
  29. % saved in a NEV structure and will get output to MATLAB.
  30. %
  31. % NEV = rethresholdNSx;
  32. %
  33. % In the example above, the user will be propted to choose a NSx file
  34. % then the signal will get high-pass filtered at 150 Hz and then
  35. % rethresholded at -85 µV. All new waveformes will be saved in a NEV
  36. % structure and will get output to MATLAB.
  37. %
  38. % Kian Torab
  39. % Blackrock Microsystems
  40. % kian@blackrockmicro.com
  41. %
  42. % Version 1.0.0.0
  43. %
  44. if nargin > 3
  45. disp('Invalid number of arguments. See ''help rethresholdNSx'' for more information.');
  46. elseif nargin == 3
  47. NSx = varargin{1};
  48. try
  49. NEV = openNEV([NSx.MetaTags.FilePath '/' NSx.MetaTags.Filename(1:end-3) 'nev'], 'read');
  50. catch
  51. disp('Cannot open the corresponding NEV file.');
  52. disp('The NEV file is required. Please place it in the same folder.');
  53. return;
  54. end
  55. threshold = varargin{2};
  56. hpFreq = varargin{3};
  57. elseif nargin == 2
  58. NSx = varargin{1};
  59. try
  60. NEV = openNEV([NSx.MetaTags.FilePath '/' NSx.MetaTags.Filename(1:end-3) 'nev'], 'read');
  61. catch
  62. disp('Cannot open the corresponding NEV file.');
  63. disp('The NEV file is required. Please place it in the same folder.');
  64. return;
  65. end
  66. threshold = varargin{2};
  67. hpFreq = 250;
  68. elseif nargin == 1
  69. NSx = varargin{1};
  70. try
  71. NEV = openNEV([NSx.MetaTags.FilePath '/' NSx.MetaTags.Filename(1:end-3) 'nev'], 'read');
  72. catch
  73. disp('Cannot open the corresponding NEV file.');
  74. disp('The NEV file is required. Please place it in the same folder.');
  75. return;
  76. end
  77. threshold = -85;
  78. hpFreq = 250;
  79. elseif nargin == 0
  80. [fileName pathName] = getFile;
  81. NSx = openNSx([pathName fileName], 'read');
  82. try
  83. NEV = openNEV([pathName fileName(1:end-3) 'nev'], 'read');
  84. catch
  85. disp('Cannot open the corresponding NEV file.');
  86. disp('The NEV file is required. Please place it in the same folder.');
  87. return;
  88. end
  89. threshold = -50;
  90. hpFreq = 250;
  91. end
  92. %% Setting stuff up
  93. newSpikes.TimeStamps = 0;
  94. newSpikes.Electrode = 0;
  95. newSpikes.Unit = 0;
  96. newSpikes.Waveform = zeros(48,1);
  97. firstTimeFlag = 1;
  98. digitizationFactor = 1000/NEV.ElectrodesInfo(1).DigitalFactor;
  99. wavelengthLength = length(NEV.Data.Spikes.Waveform(:,1));
  100. availableChannels = double(NSx.MetaTags.ChannelID)';
  101. %% Highpass filter continuous data
  102. %% Finding the spikes
  103. for channelIDX = 1:length(availableChannels)
  104. if threshold < 0
  105. thresholdTimestamps = find(diff(NSx.Data(channelIDX,:) < threshold*digitizationFactor) == 1);
  106. else
  107. thresholdTimestamps = find(diff(NSx.Data(channelIDX,:) > threshold*digitizationFactor) == 1);
  108. end
  109. idx = 1;
  110. while idx < length(thresholdTimestamps)
  111. refractoryIDX = find(abs(thresholdTimestamps(idx) - thresholdTimestamps) < wavelengthLength);
  112. thresholdTimestamps(refractoryIDX(2:end)) = [];
  113. idx = idx + 1;
  114. end
  115. while length(NSx.Data(channelIDX, :)) - thresholdTimestamps(end) < 38
  116. thresholdTimestamps(end) = [];
  117. end
  118. newSpikes.TimeStamps(end+1:end+length(thresholdTimestamps)) = thresholdTimestamps;
  119. newSpikes.Electrode(end+1:end+length(thresholdTimestamps)) = repmat(NSx.MetaTags.ChannelID(channelIDX), 1, length(thresholdTimestamps));
  120. newSpikes.Unit(end+1:end+length(thresholdTimestamps)) = zeros(1, length(thresholdTimestamps));
  121. if firstTimeFlag
  122. newSpikes.TimeStamps(1) = [];
  123. newSpikes.Electrode(1) = [];
  124. newSpikes.Unit(1) = [];
  125. end
  126. waveformIndices = bsxfun(@plus, thresholdTimestamps', -10:37)';
  127. waveformFlat = NSx.Data(channelIDX, waveformIndices(:));
  128. newSpikes.Waveform(:,end+1:end+length(thresholdTimestamps)) = reshape(waveformFlat, 48, length(waveformFlat)/48);
  129. if firstTimeFlag
  130. newSpikes.Waveform(:,1) = [];
  131. firstTimeFlag = 0;
  132. end
  133. clear waveformFlat;
  134. end
  135. [~, timestampIndex] = sort(newSpikes.TimeStamps);
  136. NEV.Data.Spikes.TimeStamp = newSpikes.TimeStamps(timestampIndex);
  137. NEV.Data.Spikes.Electrode = newSpikes.Electrode(timestampIndex);
  138. NEV.Data.Spikes.Unit = newSpikes.Unit(timestampIndex);
  139. NEV.Data.Spikes.Waveform = newSpikes.Waveform(:,timestampIndex);