def peak_merger(maxima, minima, pdf, merge_criteria): ''' Merge any maxima that are closer than the minimum spacing Lists are modified in place. The lower maxima is merged into the higher one. Any minima between merged maxima are deleted ''' for first_index, (max1, max2) in enumerate(consecutive_pairs(maxima)): y_max1 = pdf(max1) y_max2 = pdf(max2) low_index = ((y_max1 < y_max2) and first_index or first_index+1) # Check if these peaks need to be merged if merge_criteria(max1, max2, y_max1, y_max2): print "Merging", max1, max2 # Remove the lower maximum. It's okay to modify this inside the # loop, as if the merge criteria is met the loop is always exited. del maxima[low_index] # Remove all minima between the two points minima[:] = [min for min in minima if min < max1 or min > max2] # Recurse down with the cleaner list peak_merger(maxima, minima, pdf, merge_criteria) # When done merging, escape this loop return None # If no merged candidates found, exit return None
def make_choices(maxima, minima, prob_func, stepsize=5, growth_min=5e-4): ''' Build windows from set of maxima and minima The windows will grow in both directions about the maxima, until they reach a minima or the total change in integraged window area is less than growth_min in the last step ''' windows = izip(maxima, consecutive_pairs(minima)) # Loop over the windows to build for start, (min, max) in windows: last_area = 0.0 total_area = 0.0 # Grow the window in steps until we reach the end low=None; high=None for win_low, win_high in grow_window(start, min, max): last_area = total_area total_area = prob_func(win_low, win_high) low = win_low; high = win_high #if (total_area - last_area) < growth_min: if (last_area/total_area) > (1 - growth_min): # Move to next window break yield (low, high, total_area)