6 A library of helping functions for spotting force spectroscopy peaks.
8 Copyright 2007 by Fabrizio Benedetti and Massimo Sandal
10 This program is released under the GNU General Public License version 2.
13 from numpy import mean
15 def conv_dx(data,vect):
17 Returns the right-centered convolution of data with vector vect
26 for k in range(window):
27 temparr[j]+=data[j+k]*vect[k]
33 Calculates the absolute deviation of a vector
43 def noise_absdev(data,positive=False,maxcut=0.2,stable=0.005):
45 Returns the standard deviation of the noise.
46 The logic is: we cut the most negative (or positive) data points until the absolute deviation
47 becomes stable (it doesn't vary more than 0.005) or we have cut more than maxcut*len(data) points.
48 Then calculate the absolute deviation.
50 If positive=True we cut the most positive data points, False=we cut the negative ones.
52 #TOD: check if this is necessary
53 out=[item for item in data] #we copy just to be sure...
58 temp_absdev=absdev(out)
60 for index in range(len(out)):
62 cut_absdev=absdev(out[cutindex:]) #we jump five points after five points...
63 if 1-(cut_absdev/temp_absdev) < stable and cutindex<(maxcut*len(out)):
64 temp_absdev=cut_absdev
70 def abovenoise(convoluted,noise_level,cut_index=0,abs_devs=4):
72 Generates a vector which is 0 where the vector is less than abs_devs*noise_level ; 1 if not (spike).
74 #calculate absolute noise deviation
75 #noise_level=noise_absdev(convoluted[cut_index:])
79 for index in range(len(convoluted)):
83 #FIXME: should calculate the *average* (here we assume that convolution mean is 0, which is FALSE!)
84 if convoluted[index] < -1*noise_level*abs_devs:
85 above.append(convoluted[index])
90 def find_peaks(above, seedouble=10):
92 Finds individual peak location.
93 abovenoise() finds all points above a given threshold in the convolution. This point is often not unique
94 but there is a "cluster" of points above a threshold.
95 Here we obtain only the coordinates of the largest *convolution* spike for each cluster.
97 above=vector obtained from abovenoise()
98 seedouble=value at which we want to "delete" double peaks. That is, if two peaks have a distance
99 < than $seedouble points , only the first is kept.
105 for index in range(len(above)):
106 if above[index] != 0:
107 nonzero.append(index)
109 if len(nonzero) != 0:
111 nonzero.append(nonzero[0]+1)
112 peaks_size.append(min(above[nonzero[0]:nonzero[-1]]))
113 peaks_location.append(above[nonzero[0]:nonzero[-1]].index(peaks_size[-1])+nonzero[0])
118 #recursively eliminate double peaks
119 #(maybe not the smartest of cycles, but i'm asleep...)
121 while temp_location != []:
123 if len(peaks_location)>1:
124 for index in range(len(peaks_location)-1):
125 if peaks_location[index+1]-peaks_location[index] < seedouble:
126 temp_location=peaks_location[:index]+peaks_location[index+1:]
127 if temp_location != []:
128 peaks_location=temp_location
130 return peaks_location,peaks_size