示例#1
0
def find_peaks_dep(arr, thresh, trig_int, debug=0,\
               starttime=UTCDateTime('1970-01-01'), samp_rate=1.0):
    """
    Function to determine peaks in an array of data above a certain threshold.

    Depreciated peak-finding routine, very slow, but accurate.  If all else fails
    this one should work.

    :type arr: ndarray
    :param arr: 1-D numpy array is required
    :type thresh: float
    :param thresh: The threshold below which will be considered noise and peaks\
    will not be found in.
    :type trig_int: int
    :param trig_int: The minimum difference in samples between triggers,\
    if multiple peaks within this window this code will find the highest.

    :return: peaks, locs: Lists of peak values and locations.
    """

    # Perform some checks
    if trig_int < 3:
        import sys
        print 'Trigger interval must be greater than two samples to find maxima'
        sys.exit()
    #from joblib import Parallel, delayed
    # Will find peaks in the absolute then transfer these to the true values
    sig=np.abs(arr)-thresh
    true_peaks=[]
    for i in xrange(int(trig_int),int(len(sig)-trig_int), int(trig_int)):
        window=sig[i-trig_int:i+trig_int] # Define a moving window containing
                                          # data from +/- the trigger iterval
        peaks=[]
        locs=[]
        for j in xrange(1,len(window)-1):
            # Find all turning points within the window
            if window[j] > 0.0 and window[j] > window[j+1] and window[j] > window[j-1]:
                peaks.append(window[j])
                locs.append(i-trig_int+j)
        # Find maximum peak in window
        if peaks:
            true_peaks.append((np.max(np.array(peaks)),\
                               locs[np.argmax(np.array(peaks))]))
    # Get unique values
    peaks=sorted(list(set(true_peaks)), key=lambda loc: loc[1])
    # Find highest peak in peaks within trig_int of each other
    for i in xrange(1,len(peaks)-1):
        if peaks[i+1][1]-peaks[i][1] < trig_int:
            if peaks[i][0] < peaks[i+1][0]:
                peaks[i]=peaks[i+1]
            else:
                peaks[i+1]=peaks[i]
        elif peaks[i][1]-peaks[i-1][1] < trig_int:
            if peaks[i][0] < peaks[i-1][0]:
                peaks[i]=peaks[i-1]
            else:
                peaks[i-1]=peaks[i]
    peaks=sorted(list(set(peaks)), key=lambda loc: loc[1])
    if debug >= 3:
        from utils import EQcorrscan_plotting
        EQcorrscan_plotting.peaks_plot(arr, starttime, samp_rate, True, peaks,
                                        'debug_output/peaks_'+\
                                        str(starttime.year)+'-'+\
                                        str(starttime.month)+'-'+\
                                        str(starttime.day)+'.pdf')
    return peaks
示例#2
0
def find_peaks2(arr,thresh, trig_int, debug=0, maxwidth=10,\
                starttime=UTCDateTime('1970-01-01'), samp_rate=1.0):
    """
    Function to determine peaks in an array of data using scipy find_peaks_cwt,
    works fast in certain cases, but for match_filter cccsum peak finding,
    find_peaks2_short works better.  Test it out and see which works best for
    your application.

    :type arr: ndarray
    :param arr: 1-D numpy array is required
    :type thresh: float
    :param thresh: The threshold below which will be considered noise and peaks\
    will not be found in.
    :type trig_int: int
    :param trig_int: The minimum difference in samples between triggers,\
    if multiple peaks within this window this code will find the highest.
    :type debug: int
    :param debug: Optional, debug level 0-5
    :type maxwidth: int
    :param maxwidth: Maximum peak width to look for in samples

    :return: peaks, locs: Lists of peak values and locations.

    """
    from scipy.signal import find_peaks_cwt
    # Set everything below the threshold to zero
    image=np.copy(arr)
    image=np.abs(image)
    image[image<thresh]=thresh
    # We need to check if the number of samples in the image is prime, if it
    # is this method will be really slow, so we add a pad to the end to make
    # it not of prime length!
    if is_prime(len(image)):
        image=np.append(image, 0.0)
        print 'Input array has a prime number of samples, appending a zero'
        print len(image)
    if len(image[image>thresh])==0:
        print 'No values over threshold found'
        return []
    if debug > 0:
        print 'Found '+str(len(image[image>thresh]))+' samples above the threshold'
    initial_peaks=[]
    peaks=[]
    # Find the peaks
    print 'Finding peaks'
    peakinds = find_peaks_cwt(image, np.arange(1,maxwidth))
    initial_peaks=[(image[peakind], peakind) for peakind in peakinds]
    # Sort initial peaks according to amplitude
    print 'sorting peaks'
    peaks_sort=sorted(initial_peaks, key=lambda amplitude:amplitude[0],\
                      reverse=True)
    # Debugging
    if debug>=4:
        for peak in initial_peaks:
            print peak
    if initial_peaks:
        peaks.append(peaks_sort[0]) # Definitely take the biggest peak
        if debug > 3:
            print 'Added the biggest peak of '+str(peaks[0][0])+' at sample '+\
                    str(peaks[0][1])
        if len(initial_peaks) > 1:
            if debug>3:
                print 'Multiple peaks found, checking them now to see if they overlap'
            for next_peak in peaks_sort:#i in xrange(1,len(peaks_sort)): # Loop through the amplitude sorted peaks
                # if the next highest amplitude peak is within trig_int of any
                # peak already in peaks then we don't want it, else, add it
                #next_peak=peaks_sort[i]
                if debug>3:
                    print next_peak
                for peak in peaks:
                    add=False # Use add as a switch for whether or not to append
                    # next peak to peaks, if once gone through all the peaks
                    # it is True, then we will add it, otherwise we won't!
                    if abs(next_peak[1]-peak[1]) < trig_int:
                        if debug>3:
                            print 'Difference in time is '+str(next_peak[1]-peak[1])
                            print 'Which is less than '+str(trig_int)
                        add=False
                        # Need to exit the loop here if false
                        break
                    else:
                        add=True
                if add:
                    if debug>3:
                        print 'Adding peak of '+str(next_peak[0])+' at sample '+\
                                str(next_peak[1])
                    peaks.append(next_peak)
                elif debug >3:
                    print 'I did not add peak of '+str(next_peak[0])+\
                            ' at sample '+str(next_peak[1])

        if debug >= 3:
            from utils import EQcorrscan_plotting
            EQcorrscan_plotting.peaks_plot(image, starttime, samp_rate, True, peaks,
                                            'debug_output/peaks_'+\
                                              str(starttime.year)+'-'+\
                                              str(starttime.month)+'-'+\
                                              str(starttime.day)+'.pdf')
        peaks=sorted(peaks, key=lambda time:time[1], reverse=False)
        return peaks
    else:
        print 'No peaks for you!'
        return peaks
示例#3
0
def find_peaks2_short(arr,thresh, trig_int, debug=0, \
                starttime=UTCDateTime('1970-01-01'), samp_rate=1.0):
    """
    Function to determine peaks in an array of data above a certain threshold.
    Uses a mask to remove data below threshold and finds peaks in what is left.

    :type arr: ndarray
    :param arr: 1-D numpy array is required
    :type thresh: float
    :param thresh: The threshold below which will be considered noise and peaks\
    will not be found in.
    :type trig_int: int
    :param trig_int: The minimum difference in samples between triggers,\
    if multiple peaks within this window this code will find the highest.
    :type debug: int
    :param debug: Optional, debug level 0-5

    :return: peaks, locs: Lists of peak values and locations.

    """
    from scipy import ndimage
    # Set everything below the threshold to zero
    image=np.copy(arr)
    image=np.abs(image)
    image[image<thresh]=0
    if len(image[image>thresh])==0:
        print 'No values over threshold found'
        return []
    if debug > 0:
        print 'Found '+str(len(image[image>thresh]))+' samples above the threshold'
    initial_peaks=[]
    peaks=[]
    # Find the peaks
    labeled_image, number_of_objects= ndimage.label(image)
    peak_slices = ndimage.find_objects(labeled_image)
    for peak_slice in peak_slices:
        #print 'Width of peak='+str(peak_slice[0].stop-peak_slice[0].start)
        window=arr[peak_slice[0].start:peak_slice[0].stop]
        initial_peaks.append((max(window),peak_slice[0].start+np.argmax(window)))
    # Sort initial peaks according to amplitude
    peaks_sort=sorted(initial_peaks, key=lambda amplitude:amplitude[0],\
                      reverse=True)
    # Debugging
    if debug>=4:
        for peak in initial_peaks:
            print peak
    if initial_peaks:
        peaks.append(peaks_sort[0]) # Definitely take the biggest peak
        if debug > 3:
            print 'Added the biggest peak of '+str(peaks[0][0])+' at sample '+\
                    str(peaks[0][1])
        if len(initial_peaks) > 1:
            if debug>3:
                print 'Multiple peaks found, checking them now to see if they overlap'
            for next_peak in peaks_sort:#i in xrange(1,len(peaks_sort)): # Loop through the amplitude sorted peaks
                # if the next highest amplitude peak is within trig_int of any
                # peak already in peaks then we don't want it, else, add it
                #next_peak=peaks_sort[i]
                if debug>3:
                    print next_peak
                for peak in peaks:
                    add=False # Use add as a switch for whether or not to append
                    # next peak to peaks, if once gone through all the peaks
                    # it is True, then we will add it, otherwise we won't!
                    if abs(next_peak[1]-peak[1]) < trig_int:
                        if debug>3:
                            print 'Difference in time is '+str(next_peak[1]-peak[1])
                            print 'Which is less than '+str(trig_int)
                        add=False
                        # Need to exit the loop here if false
                        break
                    else:
                        add=True
                if add:
                    if debug>3:
                        print 'Adding peak of '+str(next_peak[0])+' at sample '+\
                                str(next_peak[1])
                    peaks.append(next_peak)
                elif debug >3:
                    print 'I did not add peak of '+str(next_peak[0])+\
                            ' at sample '+str(next_peak[1])

        if debug >= 3:
            from utils import EQcorrscan_plotting
            EQcorrscan_plotting.peaks_plot(image, starttime, samp_rate, True, peaks,
                                            'debug_output/peaks_'+\
                                              str(starttime.year)+'-'+\
                                              str(starttime.month)+'-'+\
                                              str(starttime.day)+'.pdf')
        peaks=sorted(peaks, key=lambda time:time[1], reverse=False)
        return peaks
    else:
        print 'No peaks for you!'
        return peaks