2
\$\begingroup\$

I want to implement following trigger function in Python:

Input:

  • time vector t [n dimensional numpy vector]
  • data vector y [n dimensional numpy vector] (values correspond to t vector)
  • threshold tr [float]
  • Threshold type vector tr_type [m dimensional list of int values]

Output:

  • Threshold time vector tr_time [m dimensional list of float values]

Function:

I would like to return tr_time which consists of the exact (preffered also interpolated which is not yet in code below) time values at which y is crossing tr (crossing means going from less then to greater then or the other way around). The different values in tr_time correspond to the tr_type vector: the elements of tr_type indicate the number of the crossing and if this is an upgoing or a downgoing crossing. For example 1 means first time y goes from less then tr to greater than tr, -3 means the third time y goes from greater then tr to less then tr (third time means along the time vector t)

For the moment I have next code:

import numpy as np
import matplotlib.pyplot as plt


def trigger(t, y, tr, tr_type):
    triggermarker = np.diff(1 * (y > tr))
    positiveindices = [i for i, x in enumerate(triggermarker) if x == 1]
    negativeindices = [i for i, x in enumerate(triggermarker) if x == -1]
    triggertime = []
    for i in tr_type:
        if i >= 0:
            triggertime.append(t[positiveindices[i - 1]])
        elif i < 0:
            triggertime.append(t[negativeindices[i - 1]])
    return triggertime


t = np.linspace(0, 20, 1000)
y = np.sin(t)
tr = 0.5
tr_type = [1, 2, -2]
print(trigger(t, y, tr, tr_type))
plt.plot(t, y)
plt.grid()

Now I'm pretty new to Python so I was wondering if there is a more Pythonic and more efficient way to implement this. For example whitout for loops or without the need to write seperate code for upgoing or downgoing crossings.

thanks!

\$\endgroup\$
1
\$\begingroup\$

If y will always be a sine wave, then you're going about this the wrong way. Rather than calculating trigger_marker based on whether y exceeds tr, you should be calling asin(tr) to see where in the cycle the trigger will be crossed. You would then avoid the need for most of your lists and loops.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.