import sys

import numpy as np
import pandas as pd

def findPressureFeet(series):
    sndderiv = series.diff().diff().shift(-2)
    try:
        threshold = np.percentile(sndderiv.dropna(), 98)
    except IndexError as e:
        print("percentile error: {}".format(e), file=sys.stderr)
        return pd.Series()

    peaks = np.diff((sndderiv > threshold).astype(int))
    peakStarts = np.flatnonzero(peaks > 0)
    peakStops  = np.flatnonzero(peaks < 0)

    # Handle the case where we start near a foot
    peakStops = peakStops[peakStops > peakStarts[0]]

    def locateMaxima():
        for start, stop in zip(peakStarts, peakStops):
            idxstart = sndderiv.index.values[start]
            idxstop  = sndderiv.index.values[stop]
            try:
                maximum = sndderiv[idxstart:idxstop].idxmax()
            except ValueError as e:
                print("local maximum error: {} [{} - {}]".format(e, idxstart, idxstop), file=sys.stderr)
                continue
            else:
                yield maximum

    return series[list(locateMaxima())]

def findFlowCycles(series):
    bincycles = (series > series.min()).astype(int)
    idxstarts, = (bincycles.diff().shift(-1) > 0).nonzero()
    idxstops,  = (bincycles.diff() < 0).nonzero()
    cycleStarts = series.iloc[idxstarts]
    cycleStops  = series.iloc[idxstops]

    # Handle the case where we start within a cycle
    cycleStops = cycleStops[cycleStops.index > cycleStarts.index[0]]

    # Filter noise cycles which are shorter than 240ms
    if type(series.index) == pd.tseries.index.DatetimeIndex:
        minSystoleLength = pd.Timedelta('240ms')
        def notShortCycles():
            for (startidx, stopidx) in zip(cycleStarts.index, cycleStops.index):
                if stopidx - startidx >= minSystoleLength:
                    yield (startidx, stopidx)
        (startidx, stopidx) = zip(*notShortCycles())
        cycleStarts = cycleStarts[list(startidx)]
        cycleStops = cycleStops[list(stopidx)]

    return (cycleStarts, cycleStops)

@@ -53,309 +53,971 @@
 def 
-findPressureFeet(series):%0A    sndderiv = series.diff().diff().shift(-2)%0A    try:%0A        threshold = np.percentile(sndderiv.dropna(), 98)%0A    except IndexError as e:%0A        print(%22percentile error: %7B%7D%22.format(e), file=sys.stderr)%0A        return pd.Series()%0A%0A    peaks = np.diff((sndderiv %3E threshold)
+calcSampleRate(series):%0A    if type(series.index) != pd.tseries.index.DatetimeIndex:%0A        print(%22No time information for cycle identification%22, file=sys.stderr)%0A        return 125%0A    starttime = series.index.values%5B0%5D%0A    stopidx = series.index.get_loc(starttime + pd.Timedelta('1s'), method='nearest')%0A    return stopidx%0A%0Adef pulsePeaks(series, deriv):%0A    samplerate = calcSampleRate(series)%0A    winsum   = int(samplerate / 4)%0A    winquant = int(samplerate * 3)%0A    derivsq  = deriv ** 2%0A    integral = derivsq.rolling(window=winsum,center=True).sum()%0A    thres    = integral.rolling(window=winquant).quantile(.7)%0A    thres    = thres.fillna(method='backfill')%0A    return (integral %3E thres).astype(int)%0A%0Adef findPressureFeet(series):%0A    fstderiv = series.diff().shift(-1)%0A    sndderiv = fstderiv.diff().shift(-1)%0A%0A    # Remove deceleration peaks%0A    sndderiv = sndderiv * (fstderiv %3E 0)%0A%0A    peaks = pulsePeaks(series, sndderiv)%0A    peakvar = np.diff(peaks
 .ast
@@ -1062,17 +1062,19 @@
 ero(peak
-s
+var
  %3E 0)%0A  
@@ -1107,17 +1107,19 @@
 ero(peak
-s
+var
  %3C 0)%0A%0A 
@@ -1166,16 +1166,29 @@
  a foot%0A
+    try:%0A    
     peak
@@ -1227,24 +1227,144 @@
 akStarts%5B0%5D%5D
+%0A    except IndexError as e:%0A        print(%22No foot detected: %7B%7D%22.format(e), file=sys.stderr)%0A        return pd.Series()
 %0A%0A    def lo

Implement the new adaptive algorithm for pulse detection.