def find_peaks(histogram, thrs=5, kernel_radius=30, kernel_sigma=6.0, minima_as_boundries=True): """ Finds peaks within the histogram. This is done by first applying a Gaussian filter with size (2*kernel_radius)-1 and sigma kernel_sigma to the histogram. Peaks are found by inspecting the gradient at each bin; once two minima are located the maximum between them is inspected, if its height (compared to the larger of the two minima) is greater than the threshold (thrs) then the bin it corresponds to is added to the returned list of bins. If minima_as_boundries is true then this returns a pair of values: [max_peak_bin, current_minima_bin]. This allows the minima to be used as a boundary. """ # TODO re-write this for new histogram kernel = gaussian_kernel(kernel_size=kernel_radius, sigma=kernel_sigma) hist = convolve(histogram, kernel) res = [] previous_y = 0 # height of previous bin previous_gradient = 0 # gradient at previous bin previous_max_y = 999999 # maxima's height previous_min_y = 0 # minima's height (for thrs) previous_max_x = 999999 # maxima's bin for current_x, current_y in hist: gradient = current_y - previous_y # set the gradient for easy testing if gradient > 0: gradient = 1 elif gradient < 0: gradient = -1 else: gradient = 0 # Check if a minima or maxima has been found and if # it's a minima check if it is to one side of a # maxima of suitable height if previous_gradient < 0 and gradient >= 0: # found minima check the previous maxima if (previous_max_y - max(previous_min_y, current_y) > thrs): # real peak found between two minima if minima_as_boundries: res.append([previous_max_x, current_x]) else: res.append(previous_max_x) # update the minima irrespective of if it is associated with a peak previous_min_y = current_y elif previous_gradient > 0 and gradient <= 0: # maxima; store then check against thrs at next minima previous_max_y = current_y previous_max_x = current_x # set values for next bin previous_y = current_y previous_gradient = gradient return res
def test(): print 'float_range(6)', float_range(6) print 'float_range(6, 7)', float_range(6, 7) print 'float_range(3, 10, 0.6)', float_range(3, 10, 0.2) print '*'*40 h = Histogram(bins = [1,3,5,9,7,]) print "h = Histogram(bins = [1,3,5,9,7,])" print 'h.get_bin_at(0)', h.get_bin_at(0) print 'h.get_bin_at(10)', h.get_bin_at(10) print 'h.get_bin_at(1.1)', h.get_bin_at(1.1) print 'h.get_bin_at(8.9)', h.get_bin_at(8.9) print 'h[-1]', h[-1] print '*'*40 print 'Histogram([1,2,2,4,4,4])' print Histogram([1,2,2,4,4,4]) print 'Histogram(bins=[1,2,3,7,])' print Histogram(bins=[1,2,3,7,]) print 'Histogram([1,1,1,2,2,2,4,4,4], [1,2,3,7,])' print Histogram([1,1,1,2,2,2,4,4,4], [1,2,3,7,]) print '*'*40 print 'file_to_histogram(test_hist1.txt)' hf = file_to_histogram('test_hist1.txt') print '*'*40 print "iteration test => for i in hf: print i" for i in hf: print i a = hf[0].copy() a[0] += 1 print '*'*40 print "copy test: a = b.copy(); a[0] = b[0] + 1" print "A", a print "B", hf[0] print '*'*40 print '\n file_to_histogram(test_hist1.txt, [1,4])' hf2 = file_to_histogram('test_hist1.txt', [1,4]) for i in hf2: print "\t", i print '\n file_to_histogram(test_hist2.txt, [1,9])' hf3 =file_to_histogram('test_hist2.txt', [1,9]) for i in hf3: print "\t", i # h2[2].plot() print '\n file_to_histogram(test_hist1.txt, [1,2,3,5])', h3 =file_to_histogram('test_hist1.txt', [1,2,3,5]) for i in hf: print "\t", i print '*'*40 h3[1].shift_bins(-5) print h3[1] h3[1].add_histo(h3[1]) print h3[1] print '*'*40 print "stress test" hf4 = file_to_histogram('data/test_223.txt') hf5 = file_to_histogram('data/test_209.txt') # pedestal # hf5[0].plot() # for i in hf4: print "\t", i print "produce plots (smoothed and unsmoothed)" # f = hf4[0].plot() k = gaussian_kernel(30, 6) hc = convolve(hf4[1], k) hc2 = convolve(hf5[1], k) # f2 = hc.plot() print '*'*40 print "find peaks", find_peaks(hc) print "find peaks2", find_peaks(hc2) show()