oedisc.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. function [AllTimeStamps, AllWaveForms] = oedisc(data,ts,sr,thr,varargin)
  2. %OEDISC Unit discrimination.
  3. % [T W] = OEDISC(DATA,TS,SR,THR) performs threshold discrimination of
  4. % continuous timestamped (TS) unit data (DATA) sampled at the rate SR
  5. % using the specified threshold (THR). Peak times (T, 'TimeStamps') and
  6. % spike waveforms (W, 'WaveForms') are saved for each tetrode. A 750 us
  7. % censored period is applied and the larger spike is kept. Time window
  8. % for waveform data is set to -300 to 1000 us.
  9. %
  10. % OEDISC(DATA,TS,SR,THR,DR) saves the results in the specified directory
  11. % (DR). If DR is empty, the data is not saved.
  12. %
  13. % See also READ_INTAN_DATA.
  14. % Balazs Hangya, Institute of Experimental Medicine
  15. % hangya.balazs@koki.mta.hu
  16. % 30-Jan-2018
  17. % Default arguments
  18. prs = inputParser;
  19. addRequired(prs,'data',@isnumeric) % raw or filtered data
  20. addRequired(prs,'ts',@isnumeric) % timestamps
  21. addRequired(prs,'sr',@isnumeric) % sampling rate
  22. addRequired(prs,'thr',@isnumeric) % discrimination threshold
  23. addOptional(prs,'resdir',['C:' filesep 'Balazs' filesep '_data' filesep 'Intan' filesep 'Tina' filesep],...
  24. @(s)ischar(s)|isempty(s)) % results directory
  25. addParameter(prs,'Filtering','enable',@(s)ischar(s)|...
  26. ismember(s,{'disable','enable'})) % switch for filtering
  27. parse(prs,data,ts,sr,thr,varargin{:})
  28. g = prs.Results;
  29. % File name
  30. savestr0 = ['save(''' g.resdir filesep 'TT'];
  31. % Sampling rate
  32. nqf = sr / 2; % Nyquist freq.
  33. deadtime = 0.00075; % 750 us dead time
  34. dtp = deadtime * sr; % dead time in data points
  35. % Waveform window
  36. win = [-0.0003 0.0006]; % -300 to 600 us
  37. winp = round(win*sr); % waveform window in data points
  38. % Threshold discrimintaion
  39. NumChannels = size(data,2); % number of channels - 16
  40. NumTetrodes = NumChannels / 4; % number of tetrodes - 4
  41. [tvdisc, tpeaks, AllTimeStamps, AllWaveForms] = deal(cell(1,NumTetrodes));
  42. for iT = 1:NumTetrodes
  43. [cvdisc, tdata, cpeaks] = deal(cell(1,4));
  44. for iC = 1:4
  45. chnum = (iT - 1) * 4 + iC; % current channel
  46. disp(['tetrode: ' num2str(iT) ' Channel: ' num2str(chnum)])
  47. cdata = data(:,chnum)'; % data from one channel
  48. if isequal(g.Filtering,'enable')
  49. [b,a] = butter(3,[700 7000]/nqf,'bandpass'); % Butterworth filter
  50. unit = filter(b,a,cdata); % filter
  51. elseif isequal(g.Filtering,'disable')
  52. unit = cdata;
  53. else
  54. error('oedisc:InputArg','Unsupported input argument for filtering.')
  55. end
  56. [cvdisc{iC}, cpeaks{iC}] = disc(-unit,thr); % discriminate (spike times)
  57. tdata{iC} = -unit; % data from the current tetrode
  58. end
  59. tvdisc{iT} = cell2mat(cvdisc);
  60. tpeaks{iT} = cell2mat(cpeaks);
  61. [tvdisc{iT}, inx] = sort(tvdisc{iT},'ascend'); % all spike times from one tetrode
  62. tpeaks{iT} = tpeaks{iT}(inx);
  63. % Dead time
  64. dtv = diff(tvdisc{iT}); % ISI
  65. dtpk = diff(tpeaks{iT}); % comparison of neighboring peaks
  66. while any(dtv<dtp)
  67. censor_inx = dtv < dtp; % ISI < dead time
  68. peak_comp = dtpk > 0;
  69. delete_inx1 = censor_inx & peak_comp;
  70. delete_inx2 = [0 censor_inx & ~peak_comp];
  71. tvdisc{iT}([find(delete_inx1) find(delete_inx2)]) = [];
  72. tpeaks{iT}([find(delete_inx1) find(delete_inx2)]) = [];
  73. dtv = diff(tvdisc{iT}); % ISI
  74. dtpk = diff(tpeaks{iT}); % comparison of neighboring peaks
  75. end
  76. tvdisc{iT}(tvdisc{iT}<=-winp(1)|tvdisc{iT}>=size(data,1)-winp(2)) = []; % we may lose some spikes near the ends of the file
  77. % Waveform
  78. winx = repmat(tvdisc{iT}(:)+winp(1),1,sum(abs(winp))) + repmat(0:sum(abs(winp))-1,length(tvdisc{iT}),1);
  79. wv = nan(size(winx,1),4,size(winx,2)); % waveforms: spikes x channels x time
  80. for iC = 1:4
  81. wv(:,iC,:) = tdata{iC}(winx); % waveform data
  82. end
  83. WaveForms = wv;
  84. AllWaveForms{iT} = WaveForms;
  85. % Spike times
  86. spike_times = ts(tvdisc{iT});
  87. TimeStamps = spike_times;
  88. AllTimeStamps{iT} = TimeStamps;
  89. savestr = [savestr0 num2str(iT) ''',''WaveForms'',''TimeStamps'');'];
  90. % Save
  91. if ~isempty(g.resdir)
  92. eval(savestr)
  93. end
  94. end