def zero_crossings(y, x=None, direction=None):
    "\n      Find zero-crossing points in a discrete vector, using linear interpolation.\n\n      direction: 'up' or 'down', to select only up-crossings or down-crossings\n\n      returns: \n          x values xzc such that y(yzc)==0\n          indexes izc, such that the zero is between y[izc] (excluded) and y[izc+1] (included)\n\n      if direction is not provided, also returns:\n              sign, equal to 1 for up crossing\n    "
    if (x is None):
        x = np.arange(len(y))
    if np.any(((x[1:] - x[0:(- 1)]) <= 0.0)):
        raise Exception('x values need to be in ascending order')
    iBef = np.where(((y[1:] * y[0:(- 1)]) < 0.0))[0]
    xzc = (x[iBef] - ((y[iBef] * (x[(iBef + 1)] - x[iBef])) / (y[(iBef + 1)] - y[iBef])))
    iZero = np.where((y == 0.0))[0]
    iZero = iZero[np.where(((iZero > 0) & (iZero < (x.size - 1))))]
    iZero = iZero[np.where(((y[(iZero - 1)] * y[(iZero + 1)]) < 0.0))]
    xzc = np.concatenate((xzc, x[iZero]))
    iBef = np.concatenate((iBef, iZero))
    iSort = np.argsort(xzc)
    (xzc, iBef) = (xzc[iSort], iBef[iSort])
    sign = np.sign((y[(iBef + 1)] - y[iBef]))
    if (direction == 'up'):
        I = np.where((sign == 1))[0]
        return (xzc[I], iBef[I])
    elif (direction == 'down'):
        I = np.where((sign == (- 1)))[0]
        return (xzc[I], iBef[I])
    elif (direction is not None):
        raise Exception('Direction should be either `up` or `down`')
    return (xzc, iBef, sign)
Find zero-crossing points in a discrete vector, using linear interpolation.

direction: 'up' or 'down', to select only up-crossings or down-crossings

returns: 
    x values xzc such that y(yzc)==0
    indexes izc, such that the zero is between y[izc] (excluded) and y[izc+1] (included)

if direction is not provided, also returns:
        sign, equal to 1 for up crossing
def zero_crossings(y, x=None, direction=None):
    "\n      Find zero-crossing points in a discrete vector, using linear interpolation.\n\n      direction: 'up' or 'down', to select only up-crossings or down-crossings\n\n      returns: \n          x values xzc such that y(yzc)==0\n          indexes izc, such that the zero is between y[izc] (excluded) and y[izc+1] (included)\n\n      if direction is not provided, also returns:\n              sign, equal to 1 for up crossing\n    "
    if (x is None):
        x = np.arange(len(y))
    if np.any(((x[1:] - x[0:(- 1)]) <= 0.0)):
        raise Exception('x values need to be in ascending order')
    iBef = np.where(((y[1:] * y[0:(- 1)]) < 0.0))[0]
    xzc = (x[iBef] - ((y[iBef] * (x[(iBef + 1)] - x[iBef])) / (y[(iBef + 1)] - y[iBef])))
    iZero = np.where((y == 0.0))[0]
    iZero = iZero[np.where(((iZero > 0) & (iZero < (x.size - 1))))]
    iZero = iZero[np.where(((y[(iZero - 1)] * y[(iZero + 1)]) < 0.0))]
    xzc = np.concatenate((xzc, x[iZero]))
    iBef = np.concatenate((iBef, iZero))
    iSort = np.argsort(xzc)
    (xzc, iBef) = (xzc[iSort], iBef[iSort])
    sign = np.sign((y[(iBef + 1)] - y[iBef]))
    if (direction == 'up'):
        I = np.where((sign == 1))[0]
        return (xzc[I], iBef[I])
    elif (direction == 'down'):
        I = np.where((sign == (- 1)))[0]
        return (xzc[I], iBef[I])
    elif (direction is not None):
        raise Exception('Direction should be either `up` or `down`')
    return (xzc, iBef, sign)