detect_spikes.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. function [spikes,thr,thrmax, noise_std_detect, noise_std_sorted, 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 (only amp thresholding) version was taken by Meeri from
  7. %some ?? Wave Clus PROGRAM Get_spikes ?? or so
  8. %Stationary Wavelet Transform Teager Energy Operator block is added by Andrey.
  9. %Workflow: %1. Amplitude thresholding detects spikes in the prefiltered signal with TCF=4.5
  10. %2. The number of the detected spikes is fed into SWTTEO algorithm
  11. %3. The spike detected by both algorithms are considered as True Positives (within error window)
  12. x = double(x);
  13. % Depends:
  14. % toolbox : \signal\signal\ellip.m
  15. % other : filtfilt
  16. % other : fix_filter
  17. % other : int_spikes
  18. %
  19. % 090814 korjattu ohi-indeksointi lis??m?ll? tarkistukset spike storing
  20. % osioon
  21. sr=handles.par.sr;
  22. w_pre=handles.par.w_pre;
  23. w_post=handles.par.w_post;
  24. ref=handles.par.ref;
  25. detect = handles.par.detection;
  26. stdmin = handles.par.stdmin;
  27. stdmax = handles.par.stdmax;
  28. fmin_detect = handles.par.detect_fmin;
  29. fmax_detect = handles.par.detect_fmax;
  30. fmin_sort = handles.par.sort_fmin;
  31. fmax_sort = handles.par.sort_fmax;
  32. index1 = [];
  33. spikes = [];
  34. thr = [];
  35. thrmax = [];
  36. noise_std_detect = [];
  37. noise_std_sorted = [];
  38. % HIGH-PASS FILTER OF THE DATA
  39. xf=zeros(length(x),1);
  40. if exist('ellip') %Checks for the signal processing toolbox
  41. [b,a]=ellip(2,0.1,40,[fmin_detect fmax_detect]*2/sr);
  42. xf_detect=filtfilt(b,a,x);
  43. [b,a]=ellip(2,0.1,40,[fmin_sort fmax_sort]*2/sr);
  44. xf=filtfilt(b,a,x);
  45. else
  46. xf=fix_filter(x); %Does a bandpass filtering between [300 3000] without the toolbox.
  47. xf_detect = xf;
  48. end
  49. lx=length(xf);
  50. %clear x; MOVED TO THE END
  51. noise_std_detect = median(abs(xf_detect))/0.6745;
  52. noise_std_sorted = median(abs(xf))/0.6745;
  53. thr = stdmin * noise_std_detect; %thr for detection is based on detected settings.
  54. thrmax = stdmax * noise_std_sorted; %thrmax for artifact removal is based on sorted settings.
  55. % LOCATE SPIKE TIMES
  56. switch detect
  57. case 'pos'
  58. nspk = 0;
  59. xaux = find(xf_detect(w_pre+2:end-w_post-2) > thr) +w_pre+1;
  60. xaux0 = 0;
  61. for i=1:length(xaux)
  62. if xaux(i) >= xaux0 + ref
  63. [maxi, iaux]=max((xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  64. nspk = nspk + 1;
  65. index1(nspk) = iaux + xaux(i) -1;
  66. xaux0 = index1(nspk);
  67. end
  68. end
  69. case 'neg'
  70. nspk = 0;
  71. xaux = find(xf_detect(w_pre+2:end-w_post-2) < -thr) +w_pre+1;
  72. xaux0 = 0;
  73. for i=1:length(xaux)
  74. if xaux(i) >= xaux0 + ref
  75. [maxi, iaux]=min((xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  76. nspk = nspk + 1;
  77. index1(nspk) = iaux + xaux(i) -1;
  78. xaux0 = index1(nspk);
  79. end
  80. end
  81. case 'both'
  82. nspk = 0;
  83. % palauttaa ei-nollat ja lis?? niihin w_pre+1
  84. % absoluuttisista arvoista
  85. % jotka xf_detectiss? v?lill? w_pre+2:end-w_post-2
  86. xaux = find(abs(xf_detect(w_pre+2:end-w_post-2)) > thr) +w_pre+1;
  87. xaux0 = 0;
  88. for i=1:length(xaux)
  89. if xaux(i) >= xaux0 + ref
  90. [maxi, iaux]=max(abs(xf(xaux(i):xaux(i)+floor(ref/2)-1))); %introduces alignment
  91. nspk = nspk + 1;
  92. if isempty(iaux)
  93. iaux = 0;
  94. end
  95. index1(nspk) = iaux + xaux(i) -1; % heitt?? virheilmon: index sis?lt?? spiketimet, maxi ja iaux tyhji?
  96. xaux0 = index1(nspk);
  97. end
  98. end
  99. end
  100. %some values for SWTTEO
  101. in.M = xf_detect;
  102. in.SaRa = sr;
  103. %Parameters
  104. params.method = 'numspikes';
  105. params.numspikes = numel(index1);
  106. params.filter = 0;
  107. if sr==10000
  108. params.wavLevel=2;
  109. elseif sr==12500
  110. params.wavLevel=3;
  111. elseif sr==25000
  112. params.wavLevel=4;
  113. elseif sr==50000
  114. params.wavLevel=5;
  115. else
  116. error('Is it smth else than MCS or Axion? I know only sampling frequencies 10000, 12500, 25000 and 50000!')
  117. end
  118. %Getting result for the SET NUMSPIKES from SWTTEO algorithm
  119. index2= SWTTEO(in,params);
  120. %Selecting the spikes detected by both algorithms within some []error
  121. %interval
  122. errortime=ceil(2e-4*sr);%(in samples)
  123. check=zeros(1, params.numspikes);
  124. for i=1:params.numspikes
  125. check(i)=any(abs(index2(i)-index1)<=errortime);
  126. end
  127. index=index2.*check;
  128. index=index(index>0);
  129. index=sort(index);
  130. nspk=numel(index);
  131. % SPIKE STORING (with or without interpolation)
  132. % tehd??n vain jos spikej? indexiss?!
  133. if ~isempty(index)
  134. ls=w_pre+w_post;
  135. spikes=zeros(nspk,ls+4);
  136. xf=[xf zeros(1,w_post)]; % xf ja zeros ei yhteensopivia
  137. parfor i=1:nspk %Eliminates artifacts
  138. if max(abs( xf(index(i)-w_pre:index(i)+w_post) )) < thrmax
  139. % jos piikin indeksi datan vika tai tokavika piste niin aiheuttaa
  140. % ohi indeksoinnin, eik? piikkimuotokaan ole kokonainen
  141. % eli eliminoidaan artifactina
  142. if ~(index(i)+w_post+2 > length(xf))
  143. % lis?t??n nollaborderia, koska piikki aivan datan alussa
  144. if index(i)-w_pre-1 < 1
  145. spikes(i,:)=[0 xf(abs(index(i)-w_pre:index(i)+w_post+2))];
  146. else
  147. spikes(i,:)=xf(abs(index(i)-w_pre-1:index(i)+w_post+2));
  148. % aiheuttaa ongelman jos index(i)-w_pre-1 < 1
  149. % tai
  150. % jos index(i)+w_post+2 > length(xf)
  151. % eli jos piikki on datassa alle w_pren p??ss? alusta
  152. % tai aivan datan lopussa
  153. % --> t?ll?in ei saada kokonaista piikkimuotoa, joten
  154. end
  155. end
  156. end
  157. end
  158. aux = find(spikes(:,w_pre)==0); %erases indexes that were artifacts
  159. spikes(aux,:)=[];
  160. index(aux)=[];
  161. clear x; %moved from line 57
  162. end
  163. switch handles.par.interpolation
  164. case 'n'
  165. %eliminates borders that were introduced for interpolation
  166. spikes(:,end-1:end)=[]; % laittaa kaikille vikan ja tokavikan []
  167. spikes(:,1:2)=[]; % laittaa kaikille ekan ja tokan []
  168. case 'y'
  169. %Does interpolation
  170. spikes = int_spikes(spikes,handles);
  171. end