amp_detect.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. function [spikes,thr,thrmax, noise_std_detect, index] = amp_detect(x,handles)
  2. % Detect spikes with amplitude thresholding. Uses median estimation.
  3. % Detection is done with filters set by fmin_detect and fmax_detect. Spikes
  4. % are stored for sorting using fmin_sort and fmax_sort. This trick can
  5. % eliminate noise in the detection but keeps the spikes shapes for sorting.
  6. %The initial version involves only amp thresholding
  7. %Stationary Wavelet Transform Teager Energy Operator block is added by Andrey.
  8. %Workflow: %1. Amplitude thresholding detects spikes in the prefiltered signal with TCF=4.5
  9. %2. The number of the detected spikes is fed into SWTTEO algorithm
  10. %3. The spike detected by both algorithms are considered as True Positives (within an error window)
  11. x = double(x);
  12. % Depends:
  13. % toolbox : \signal\signal\ellip.m
  14. % other : filtfilt
  15. % other : fix_filter
  16. % other : int_spikes
  17. sr=handles.sr;
  18. w_pre=handles.w_pre;
  19. w_post=handles.w_post;
  20. ref=handles.ref;
  21. detect = handles.detection;
  22. stdmin = handles.stdmin;
  23. stdmax = handles.stdmax;
  24. fmin_detect = handles.detect_fmin;
  25. fmax_detect = handles.detect_fmax;
  26. index1 = [];
  27. spikes = [];
  28. thr = [];
  29. thrmax = [];
  30. noise_std_detect = [];
  31. %% HIGH-PASS FILTER OF THE DATA
  32. %Checks for the signal processing toolbox
  33. [b,a]=ellip(2,0.1,40,[fmin_detect fmax_detect]*2/sr);
  34. xf=filtfilt(b,a,x);
  35. noise_std_detect = median(abs(xf))/0.6745;
  36. thr = stdmin * noise_std_detect; %thr for detection
  37. thrmax = stdmax * noise_std_detect; %thrmax for artifact removal
  38. %% LOCATE SPIKE TIMES
  39. switch detect
  40. case 'pos'
  41. nspk = 0;
  42. xaux = find(xf(w_pre+2:end-w_post-2) > thr) +w_pre+1;
  43. xaux0 = 0;
  44. for i=1:length(xaux)
  45. if xaux(i) >= xaux0 + ref
  46. [maxi, iaux]=max((xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  47. nspk = nspk + 1;
  48. index1(nspk) = iaux + xaux(i) -1;
  49. xaux0 = index1(nspk);
  50. end
  51. end
  52. case 'neg'
  53. nspk = 0;
  54. xaux = find(xf(w_pre+2:end-w_post-2) < -thr) +w_pre+1;
  55. xaux0 = 0;
  56. for i=1:length(xaux)
  57. if xaux(i) >= xaux0 + ref
  58. [maxi, iaux]=min((xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  59. nspk = nspk + 1;
  60. index1(nspk) = iaux + xaux(i) -1;
  61. xaux0 = index1(nspk);
  62. end
  63. end
  64. case 'both'
  65. nspk = 0;
  66. xaux = find(abs(xf(w_pre+2:end-w_post-2)) > thr) +w_pre+1;
  67. xaux0 = 0;
  68. for i=1:length(xaux)
  69. if xaux(i) >= xaux0 + ref
  70. [maxi, iaux]=max(abs(xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  71. nspk = nspk + 1;
  72. if isempty(iaux)
  73. iaux = 0;
  74. end
  75. index1(nspk) = iaux + xaux(i) -1;
  76. xaux0 = index1(nspk);
  77. end
  78. end
  79. end
  80. %% some values for SWTTEO
  81. in.M = xf;
  82. in.SaRa = sr;
  83. %Parameters
  84. params.method = 'numspikes'; %detection with predefined number of spikes
  85. params.numspikes = numel(index1); %same number of spikes as detected with the amplitude thresholding
  86. params.filter = 0; %no addition filtering for SWTTEO algorithm
  87. %Wavelet decomposition level selection based on the sampling frequency
  88. if sr==10000
  89. params.wavLevel=2;
  90. elseif sr==12500
  91. params.wavLevel=3;
  92. elseif sr==25000
  93. params.wavLevel=4;
  94. elseif sr==50000
  95. params.wavLevel=5;
  96. else
  97. error('Is it smth else than MCS or Axion? I know only sampling frequencies 10000, 12500, 25000 and 50000!')
  98. end
  99. %% Getting result for the SET NUMSPIKES from SWTTEO algorithm
  100. index2= SWTTEO(in,params);
  101. %% Selecting the spikes detected by both algorithms within some []error interval
  102. errortime=ceil(2e-4*sr);%(in samples)
  103. check=zeros(1, params.numspikes);
  104. for i=1:params.numspikes
  105. check(i)=any(abs(index2(i)-index1)<=errortime);
  106. end
  107. index=index2.*check;
  108. index=index(index>0);
  109. index=sort(index);
  110. nspk=numel(index);
  111. %% SPIKE STORING (with or without interpolation)
  112. % [SPIKE STORING OUTPUT IS NOT IN USE CURRENTLY, ONLY ARTIFACT REMOVAL]
  113. if ~isempty(index)
  114. ls=w_pre+w_post;
  115. spikes=zeros(nspk,ls+4);
  116. xf=[xf zeros(1,w_post)];
  117. parfor i=1:nspk %Eliminates artifacts
  118. if max(abs( xf(index(i)-w_pre:index(i)+w_post) )) < thrmax
  119. if ~(index(i)+w_post+2 > length(xf))
  120. if index(i)-w_pre-1 < 1
  121. spikes(i,:)=[0 xf(abs(index(i)-w_pre:index(i)+w_post+2))];
  122. else
  123. spikes(i,:)=xf(abs(index(i)-w_pre-1:index(i)+w_post+2));
  124. end
  125. end
  126. end
  127. end
  128. aux = find(spikes(:,w_pre)==0); %erases indexes that were artifacts
  129. spikes(aux,:)=[];
  130. index(aux)=[];
  131. clear x;
  132. end
  133. switch handles.interpolation
  134. %spike storing is currently not in use
  135. case 'n'
  136. %eliminates borders that were introduced for interpolation
  137. spikes(:,end-1:end)=[];
  138. spikes(:,1:2)=[];
  139. case 'y'
  140. %Does interpolation
  141. spikes = int_spikes(spikes,handles);
  142. end