Exemple #1
0
 def test_peaks_plot(self):
     data = self.data.copy()
     data[30] = 100
     data[60] = 40
     threshold = 10
     peaks = findpeaks.find_peaks2_short(data, threshold, 3)
     fig = peaks_plot(data=data, starttime=UTCDateTime("2008001"),
                      samp_rate=10, peaks=peaks, show=False,
                      return_figure=True)
     return fig
Exemple #2
0
def _median_window(window,
                   window_start,
                   multiplier,
                   starttime,
                   sampling_rate,
                   debug=0):
    """
    Internal function to aid parallel processing

    :type window: numpy.ndarry
    :param window: Data to look for peaks in.
    :type window_start: int
    :param window_start: Index of window start point in larger array, used \
        for peak indexing.
    :type multiplier: float
    :param multiplier: Multiple of MAD to use as threshold
    :type starttime: obspy.core.utcdatetime.UTCDateTime
    :param starttime: Starttime of window, used in debug plotting.
    :type sampling_rate: float
    :param sampling_rate in Hz, used for debug plotting
    :type debug: int
    :param debug: debug level, if want plots, >= 4.

    :returns: peaks
    :rtype: list
    """
    from eqcorrscan.utils.findpeaks import find_peaks2_short
    from eqcorrscan.utils.plotting import peaks_plot

    MAD = np.median(np.abs(window))
    thresh = multiplier * MAD
    if debug >= 2:
        print('Threshold for window is: ' + str(thresh) + '\nMedian is: ' +
              str(MAD) + '\nMax is: ' + str(np.max(window)))
    peaks = find_peaks2_short(arr=window, thresh=thresh, trig_int=5, debug=0)
    if debug >= 4 and peaks:
        peaks_plot(window, starttime, sampling_rate, save=False, peaks=peaks)
    if peaks:
        peaks = [(peak[0], peak[1] + window_start) for peak in peaks]
    else:
        peaks = []
    return peaks
Exemple #3
0
def _median_window(window, window_start, multiplier, starttime, sampling_rate,
                   debug=0):
    """Internal function to aid parallel processing

    :type window: np.ndarry
    :param window: Data to look for peaks in.
    :type window_start: int
    :param window_start: Index of window start point in larger array, used \
        for peak indexing.
    :type multiplier: float
    :param multiplier: Multiple of MAD to use as threshold
    :type starttime: obspy.UTCDateTime
    :param starttime: Starttime of window, used in debug plotting.
    :type sampling_rate: float
    :param sampling_rate in Hz, used for debug plotting
    :type debug: int
    :param debug: debug level, if want plots, >= 4.

    :returns: peaks
    """
    from eqcorrscan.utils.findpeaks import find_peaks2_short
    from eqcorrscan.utils.plotting import peaks_plot

    MAD = np.median(np.abs(window))
    thresh = multiplier * MAD
    if debug >= 2:
        print('Threshold for window is: ' + str(thresh) +
              '\nMedian is: ' + str(MAD) +
              '\nMax is: ' + str(np.max(window)))
    peaks = find_peaks2_short(arr=window,
                              thresh=thresh, trig_int=5, debug=0)
    if debug >= 4 and peaks:
        peaks_plot(window, starttime, sampling_rate,
                   save=False, peaks=peaks)
    if peaks:
        peaks = [(peak[0], peak[1] + window_start) for peak in peaks]
    else:
        peaks = []
    return peaks
Exemple #4
0
def find_peaks2_short(arr, thresh, trig_int, debug=0, starttime=False,
                      samp_rate=1.0):
    """
    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: numpy.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 starttime: obspy.core.utcdatetime.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    :rtype: list


    >>> import numpy as np
    >>> arr = np.random.randn(100)
    >>> threshold = 10
    >>> arr[40] = 20
    >>> arr[60] = 100
    >>> find_peaks2_short(arr, threshold, 3)
    [(20.0, 40), (100.0, 60)]
    """
    if not starttime:
        starttime = UTCDateTime(0)
    # 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:
        if debug > 0:
            print('No values over threshold found')
        return []
    if debug > 0:
        print(' '.join(['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),
                              int(peak_slice[0].start + np.argmax(window))))
    if initial_peaks:
        peaks = decluster(peaks=initial_peaks, trig_int=trig_int, debug=debug)
        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(['peaks_',
                              starttime.datetime.strftime('%Y-%m-%d'),
                              '.pdf'])
            plotting.peaks_plot(data=image, starttime=starttime,
                                samp_rate=samp_rate, save=True,
                                peaks=peaks, savefile=_fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return peaks
Exemple #5
0
def find_peaks2_short(arr,
                      thresh,
                      trig_int,
                      debug=0,
                      starttime=False,
                      samp_rate=1.0,
                      full_peaks=False):
    """
    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: numpy.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 starttime: obspy.core.utcdatetime.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.
    :type full_peaks: bool
    :param full_peaks:
        If True, will remove the issue eluded to below, by declustering within
        data-sections above the threshold, rather than just taking the peak
        within that section. This will take more time. This defaults to True
        for match_filter.

    :return: peaks: Lists of tuples of peak values and locations.
    :rtype: list


    >>> import numpy as np
    >>> arr = np.random.randn(100)
    >>> threshold = 10
    >>> arr[40] = 20
    >>> arr[60] = 100
    >>> find_peaks2_short(arr, threshold, 3)
    [(20.0, 40), (100.0, 60)]

    .. note::
        peak-finding is optimised for zero-mean cross-correlation data where
        fluctuations are frequent.  Because of this, in certain cases some
        peaks may be missed if the trig_int is short and the threshold is low.
        Consider the following case:

        >>> arr = np.array([1, .2, .2, .2, .2, 1, .2, .2, .2, .2, 1])
        >>> find_peaks2_short(arr, thresh=.2, trig_int=3)
        [(1.0, 0)]

        Whereas you would expect the following:

        >>> arr = np.array([1, .2, .2, .2, .2, 1, .2, .2, .2, .2, 1])
        >>> find_peaks2_short(arr, thresh=.2, trig_int=3, full_peaks=True)
        [(1.0, 0), (1.0, 5), (1.0, 10)]

        This is rare and unlikely to happen for correlation cases, where
        trigger intervals are usually large and thresholds high.

    """
    if not starttime:
        starttime = UTCDateTime(0)
    # Set everything below the threshold to zero
    image = np.copy(arr)
    image = np.abs(image)
    debug_print("Threshold: {0}\tMax: {1}".format(thresh, max(image)), 2,
                debug)
    image[image < thresh] = 0
    if len(image[image > thresh]) == 0:
        debug_print("No values over threshold {0}".format(thresh), 0, debug)
        return []
    debug_print(
        'Found {0} samples above the threshold'.format(
            len(image[image > thresh])), 0, debug)
    initial_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:
        window = arr[peak_slice[0].start:peak_slice[0].stop]
        if peak_slice[0].stop - peak_slice[0].start > trig_int and full_peaks:
            peaks = decluster(peaks=window,
                              trig_int=trig_int,
                              index=np.arange(peak_slice[0].start,
                                              peak_slice[0].stop))
        else:
            peaks = [(window[np.argmax(abs(window))],
                      int(peak_slice[0].start + np.argmax(abs(window))))]
        initial_peaks.extend(peaks)
    peaks = decluster(peaks=np.array(list(zip(*initial_peaks))[0]),
                      index=np.array(list(zip(*initial_peaks))[1]),
                      trig_int=trig_int)
    if initial_peaks:
        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(
                ['peaks_',
                 starttime.datetime.strftime('%Y-%m-%d'), '.pdf'])
            plotting.peaks_plot(data=image,
                                starttime=starttime,
                                samp_rate=samp_rate,
                                save=True,
                                peaks=peaks,
                                savefile=_fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return []
Exemple #6
0
def find_peaks2(arr, thresh, trig_int, debug=0, maxwidth=10,
                starttime=False, samp_rate=1.0):
    r"""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
    :type starttime: osbpy.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    """
    from scipy.signal import find_peaks_cwt
    import numpy as np
    from obspy import UTCDateTime
    if not starttime:
        starttime = UTCDateTime(0)
    # 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:
        msg = ' '.join(['Found', str(len(image[image > thresh])),
                        'samples above the threshold'])
        print(msg)
    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)
    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:
            msg = ' '.join(['Added the biggest peak of', str(peaks[0][0]),
                            'at sample', str(peaks[0][1])])
            print(msg)
        if len(initial_peaks) > 1:
            if debug > 3:
                msg = ' '.join(['Multiple peaks found, checking them',
                                'now to see if they overlap'])
                print(msg)
            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:
                            msg = ' '.join(['Difference in time is',
                                            str(next_peak[1] - peak[1]), '\n'
                                            'Which is less than',
                                            str(trig_int)])
                            print(msg)
                        add = False
                        # Need to exit the loop here if false
                        break
                    else:
                        add = True
                if add:
                    if debug > 3:
                        msg = ' '.join(['Adding peak of', str(next_peak[0]),
                                        'at sample', str(next_peak[1])])
                        print(msg)
                    peaks.append(next_peak)
                elif debug > 3:
                    msg = ' '.join(['I did not add peak of',
                                    str(next_peak[0]), 'at sample',
                                    str(next_peak[1])])
                    print(msg)

        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(['peaks_',
                              starttime.datetime.strftime('%Y-%m-%d'),
                              '.pdf'])
            print(' '.join(['Saving plot to', _fname]))
            plotting.peaks_plot(image, starttime, samp_rate, True,
                                peaks, _fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return peaks
Exemple #7
0
def find_peaks_dep(arr, thresh, trig_int, debug=0, starttime=False,
                   samp_rate=1.0):
    r"""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.
    :type starttime: osbpy.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    """
    import numpy as np
    from obspy import UTCDateTime
    if not starttime:
        starttime = UTCDateTime(0)
    # Perform some checks
    if trig_int < 3:
        msg = 'Trigger interval must be greater than 2 samples to find maxima'
        raise IOError(msg)
    # 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 eqcorrscan.utils import plotting
        _fname = ''.join(['peaks_',
                          starttime.datetime.strftime('%Y-%m-%d'),
                          '.pdf'])
        plotting.peaks_plot(arr, starttime, samp_rate, True, peaks,
                            _fname)
    return peaks
Exemple #8
0
def find_peaks2_short(arr, thresh, trig_int, debug=0, starttime=False,
                      samp_rate=1.0):
    r"""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
    :type starttime: osbpy.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    """
    from scipy import ndimage
    import numpy as np
    from obspy import UTCDateTime
    if not starttime:
        starttime = UTCDateTime(0)
    # 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(' '.join(['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(' '.join(['Added the biggest peak of', str(peaks[0][0]),
                            'at sample', str(peaks[0][1])]))
        if len(initial_peaks) > 1:
            if debug > 3:
                msg = ' '.join(['Multiple peaks found, checking',
                                'them now to see if they overlap'])
                print(msg)
            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:
                            msg = ' '.join(['Difference in time is',
                                            str(next_peak[1]-peak[1]), '\n',
                                            'Which is less than',
                                            str(trig_int)])
                            print(msg)
                        add = False
                        # Need to exit the loop here if false
                        break
                    else:
                        add = True
                if add:
                    if debug > 3:
                        msg = ' '.join(['Adding peak of', str(next_peak[0]),
                                        'at sample', str(next_peak[1])])
                        print(msg)
                    peaks.append(next_peak)
                elif debug > 3:
                    msg = ' '.join(['I did not add peak of', str(next_peak[0]),
                                    'at sample', str(next_peak[1])])
                    print(msg)

        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(['peaks_',
                              starttime.datetime.strftime('%Y-%m-%d'),
                              '.pdf'])
            plotting.peaks_plot(image, starttime, samp_rate, True,
                                peaks, _fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return peaks
Exemple #9
0
def find_peaks2_short(arr, thresh, trig_int, debug=0, starttime=False,
                      samp_rate=1.0):
    """
    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: numpy.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 starttime: obspy.core.utcdatetime.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    :rtype: list


    >>> import numpy as np
    >>> arr = np.random.randn(100)
    >>> threshold = 10
    >>> arr[40] = 20
    >>> arr[60] = 100
    >>> find_peaks2_short(arr, threshold, 3)
    [(20.0, 40), (100.0, 60)]
    """
    if not starttime:
        starttime = UTCDateTime(0)
    # 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:
        if debug > 0:
            print('No values over threshold found')
        return []
    if debug > 0:
        print(' '.join(['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),
                              int(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(' '.join(['Added the biggest peak of', str(peaks[0][0]),
                            'at sample', str(peaks[0][1])]))
        if len(initial_peaks) > 1:
            if debug > 3:
                msg = ' '.join(['Multiple peaks found, checking',
                                'them now to see if they overlap'])
                print(msg)
            for next_peak in peaks_sort:
                # i in range(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:
                    # 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:
                            msg = ' '.join(['Difference in time is',
                                            str(next_peak[1] - peak[1]), '\n',
                                            'Which is less than',
                                            str(trig_int)])
                            print(msg)
                        add = False
                        # Need to exit the loop here if false
                        break
                    else:
                        add = True
                if add:
                    if debug > 3:
                        msg = ' '.join(['Adding peak of', str(next_peak[0]),
                                        'at sample', str(next_peak[1])])
                        print(msg)
                    peaks.append(next_peak)
                elif debug > 3:
                    msg = ' '.join(['I did not add peak of', str(next_peak[0]),
                                    'at sample', str(next_peak[1])])
                    print(msg)

        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(['peaks_',
                              starttime.datetime.strftime('%Y-%m-%d'),
                              '.pdf'])
            plotting.peaks_plot(data=image, starttime=starttime,
                                samp_rate=samp_rate, save=True,
                                peaks=peaks, savefile=_fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return peaks
Exemple #10
0
def find_peaks_dep(arr, thresh, trig_int, debug=0, starttime=False,
                   samp_rate=1.0):
    """
    Determine peaks in an array of data above a certain threshold: depreciated.

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

    :type arr: numpy.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 starttime: obspy.core.utcdatetime.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    :rtype: list

    >>> import numpy as np
    >>> arr = np.random.randn(100)
    >>> threshold = 10
    >>> arr[40] = 20
    >>> arr[60] = 100
    >>> find_peaks_dep(arr, threshold, 3)
    [(20.0, 40), (100.0, 60)]
    """
    if not starttime:
        starttime = UTCDateTime(0)
    # Perform some checks
    if trig_int < 3:
        msg = 'Trigger interval must be greater than 2 samples to find maxima'
        raise IOError(msg)
    # 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 range(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 range(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 range(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 eqcorrscan.utils import plotting
        _fname = ''.join(['peaks_',
                          starttime.datetime.strftime('%Y-%m-%d'),
                          '.pdf'])
        plotting.peaks_plot(arr, starttime, samp_rate, True, peaks,
                            _fname)
    peaks = [(peak[0] + thresh, peak[1]) for peak in peaks]
    return peaks
Exemple #11
0
def find_peaks2(arr,
                thresh,
                trig_int,
                debug=0,
                maxwidth=10,
                starttime=False,
                samp_rate=1.0):
    r"""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
    :type starttime: osbpy.UTCDateTime
    :param starttime: Starttime for plotting, only used if debug > 2.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz, only used for plotting if debug > 2.

    :return: peaks: Lists of tuples of peak values and locations.
    """
    from scipy.signal import find_peaks_cwt
    import numpy as np
    from obspy import UTCDateTime
    if not starttime:
        starttime = UTCDateTime(0)
    # 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:
        msg = ' '.join([
            'Found',
            str(len(image[image > thresh])), 'samples above the threshold'
        ])
        print(msg)
    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)
    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:
            msg = ' '.join([
                'Added the biggest peak of',
                str(peaks[0][0]), 'at sample',
                str(peaks[0][1])
            ])
            print(msg)
        if len(initial_peaks) > 1:
            if debug > 3:
                msg = ' '.join([
                    'Multiple peaks found, checking them',
                    'now to see if they overlap'
                ])
                print(msg)
            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:
                            msg = ' '.join([
                                'Difference in time is',
                                str(next_peak[1] - peak[1]), '\n'
                                'Which is less than',
                                str(trig_int)
                            ])
                            print(msg)
                        add = False
                        # Need to exit the loop here if false
                        break
                    else:
                        add = True
                if add:
                    if debug > 3:
                        msg = ' '.join([
                            'Adding peak of',
                            str(next_peak[0]), 'at sample',
                            str(next_peak[1])
                        ])
                        print(msg)
                    peaks.append(next_peak)
                elif debug > 3:
                    msg = ' '.join([
                        'I did not add peak of',
                        str(next_peak[0]), 'at sample',
                        str(next_peak[1])
                    ])
                    print(msg)

        if debug >= 3:
            from eqcorrscan.utils import plotting
            _fname = ''.join(
                ['peaks_',
                 starttime.datetime.strftime('%Y-%m-%d'), '.pdf'])
            print(' '.join(['Saving plot to', _fname]))
            plotting.peaks_plot(image, starttime, samp_rate, True, peaks,
                                _fname)
        peaks = sorted(peaks, key=lambda time: time[1], reverse=False)
        return peaks
    else:
        print('No peaks for you!')
        return peaks