getSpikePositions.m 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. function idx2 = getSpikePositions(input_sig,fs,orig_sig,params)
  2. %GETSPIKEPOSITIONS computes spike positions from thresholded data
  3. %
  4. % This function computes the exact spike locations based on a thresholded
  5. % signal. The spike locations are indicated as non-zero elements in
  6. % input_sig and are accordingly evaluated.
  7. %
  8. % The outputs are the spike positions in absolute index values (no time
  9. % dependance).
  10. %
  11. % Author: F.Lieb, February 2016
  12. %
  13. %Define a fixed spike duration, prevents from zeros before this duration is
  14. %over
  15. %maxoffset
  16. spikeduration = 10e-4*fs; %10e-4
  17. %minoffset
  18. minoffset = 3e-4*fs; %3e-4
  19. offset = floor(5e-4*fs); %5e-4 %was 2e-4, dunno why
  20. L = length(input_sig);
  21. L2 = length(orig_sig);
  22. switch params.method
  23. case 'numspikes'
  24. out = input_sig;
  25. np = 0;
  26. idx2 = zeros(1,params.numspikes);
  27. while (np < params.numspikes)
  28. [~, idxmax] = max(out);
  29. idxl = idxmax;
  30. idxr = idxmax;
  31. out(idxmax) = 0;
  32. offsetcounter = 0;
  33. while( (out(max(1,idxl-2)) < out(max(1,idxl-1)) ||...
  34. offsetcounter < minoffset) &&...
  35. offsetcounter < spikeduration )
  36. out(max(1,idxl-1)) = 0;
  37. idxl = idxl-1;
  38. offsetcounter = offsetcounter + 1;
  39. end
  40. offsetcounter = 0;
  41. while( (out(min(L,idxr+2)) < out(min(L,idxr+1)) ||...
  42. offsetcounter < minoffset ) &&...
  43. offsetcounter < spikeduration )
  44. out(min(L,idxr+1)) = 0;
  45. idxr = idxr+1;
  46. offsetcounter = offsetcounter + 1;
  47. end
  48. %new approach
  49. indexx = min(L2, idxmax-offset:idxmax+offset);
  50. %indexx = min(L2,idxl-offset:idxr+offset); %old approach
  51. indexx = max(offset,indexx);
  52. idxx = find( abs(orig_sig(indexx)) == ...
  53. max( abs(orig_sig(indexx) )),1,'first');
  54. idx2(np+1) = idxmax - offset + idxx-1;
  55. np = np + 1;
  56. end
  57. case {'energy'}
  58. rel_norm = params.rel_norm;
  59. p = params.p;
  60. ysig = input_sig;
  61. normy = norm(input_sig);
  62. L = length(input_sig);
  63. %min and max length of signal duration
  64. maxoffset = 12;
  65. minoffset = 6;
  66. offset = 5;
  67. idx2 = [];
  68. np = 0;
  69. maxspikecount = 300;
  70. temp = 0;
  71. %while( norm(ysig) > (1-p)*normy )
  72. while( 1 )
  73. norm_old = norm(ysig);
  74. [~, idxmax] = max(ysig);
  75. idxl = idxmax;
  76. idxr = idxmax;
  77. ysig(idxmax) = 0;
  78. offsetcounter = 0;
  79. while ( ( ysig(max(1,idxl-2)) < ysig(max(1,idxl-1)) ||...
  80. offsetcounter < minoffset ) && ...
  81. offsetcounter < maxoffset )
  82. ysig(max(1,idxl-1)) = 0;
  83. idxl = idxl - 1;
  84. %if (ysig(max(1,idxl))==0)
  85. % break;
  86. %end
  87. offsetcounter = offsetcounter + 1;
  88. end
  89. offsetcounter = 0;
  90. while ( ( ysig(min(L,idxr+2)) < ysig(min(L,idxr+1)) ||...
  91. offsetcounter < minoffset ) && ...
  92. offsetcounter < maxoffset )
  93. ysig(min(L,idxr+1)) = 0;
  94. idxr = idxr + 1;
  95. %if (ysig(min(L,idxr)) == 0)
  96. % break;
  97. %end
  98. offsetcounter = offsetcounter + 1;
  99. end
  100. indexx = min(L, idxmax-offset:idxmax+offset);
  101. %indexx = min(L2,idxl-offset:idxr+offset); %old approach
  102. indexx = max(offset,indexx);
  103. idxx = find( abs(orig_sig(indexx)) == ...
  104. max( abs(orig_sig(indexx) )),1,'first');
  105. idx2(np+1) = idxmax - offset + idxx-1;
  106. np = np + 1;
  107. fprintf('rel norm: %f\n', (norm_old-norm(ysig))/norm_old);
  108. temp(np+1) = (norm_old-norm(ysig))/norm_old;
  109. if (norm_old-norm(ysig))/norm_old < rel_norm
  110. if length(idx2)>1
  111. idx2 = idx2(1:end-1);
  112. else
  113. idx2 = [];
  114. end
  115. break
  116. end
  117. if np > maxspikecount
  118. break;
  119. end
  120. end
  121. %figure(2), plot(temp);
  122. case {'auto','lambda'}
  123. %helper variables
  124. idx2=[];
  125. iii=1;
  126. test2 = input_sig;
  127. %loop until the input_sig is only zeros
  128. while (sum(test2) ~= 0)
  129. %get the first nonzero position
  130. tmp = find(test2,1,'first');
  131. test2(tmp) = 0;
  132. %tmp2 is the counter until the spike duration
  133. tmp2 = min(length(test2),tmp + 1);%protect against end of vec
  134. counter = 0;
  135. %search for the end of the spike
  136. while(test2(tmp2) ~= 0 || counter<spikeduration )
  137. test2(tmp2) = 0;
  138. tmp2 = min(length(test2),tmp2 + 1);
  139. counter = counter + 1;
  140. end
  141. %spike location is in intervall [tmp tmp2], look for the max
  142. %element in the original signal with some predefined offset:
  143. indexx = min(length(orig_sig),tmp-offset:tmp2+offset);
  144. indexx = max(offset,indexx);
  145. idxx = find( abs(orig_sig(indexx)) == ...
  146. max( abs(orig_sig(indexx) )),1,'first');
  147. idx2(iii) = tmp - offset + idxx-1;
  148. iii = iii+1;
  149. end
  150. otherwise
  151. error('unknown method');
  152. end