Problem in trigger_onset function

Hello,

I have a problem with Obspy library.

When I use classic STA/LTA function with a determined Trigger on and Trigger off thresholds, the function returns this error:

File “/home/andrea/anaconda3/lib/python3.8/site-packages/obspy/signal/trigger.py”, line 370, in trigger_onset
while of[0] < on[0]:
IndexError: deque index out of range

I set STA as 1, LTA as 10, Trigger on as 2 and Trigger off as 3.

My input is a SAC file with a duration of 3600 seconds, sampling rate at 50 Hz.

Please, let me know about the error (it depends on my input?).

Thank you in advance.
Best regards,
Andrea Di Benedetto

Hi Andrea, you might be running into this issue: trigger_onset() fails if characteristic function does not drop below off-threshold before hitting the end of the characteristic function · Issue #2891 · obspy/obspy · GitHub

There is a draft for a fix, you could try if that change fixes your problem too: trigger: try to fix a bug when characteristic function does not fall below off threshold at end of trace by megies · Pull Request #3013 · obspy/obspy · GitHub

1 Like

Hi Tobias,

thank you for your response. I tried the fix cited by you in this link:

Now for that signal (and other signals) it worked. The problem is that for another signal, it gets me this error:

Traceback (most recent call last):
  File "eq_automatic_cut.py", line 163, in <module>
    triggers = trigger_onset(cft, trig_on, trig_off)
  File "/home/andrea/anaconda3/lib/python3.8/site-packages/obspy/signal/trigger.py", line 365, in trigger_onset
    of.extend([ind2[-1]])
IndexError: index -1 is out of bounds for axis 0 with size 0

How could I resolve?

Thank you for your help

If it helps, currently the trigger_onset function I modified according to your suggestions is this:

def trigger_onset(charfct, thres1, thres2, max_len=9e99, max_len_delete=False):
    # 1) find indices of samples greater than threshold
    # 2) calculate trigger "of" times by the gap in trigger indices
    #    above the threshold i.e. the difference of two following indices
    #    in ind is greater than 1
    # 3) in principle the same as for "of" just add one to the index to get
    #    start times, this operation is not supported on the compact
    #    syntax
    # 4) as long as there is a on time greater than the actual of time find
    #    trigger on states which are greater than last of state an the
    #    corresponding of state which is greater than current on state
    # 5) if the signal stays above thres2 longer than max_len an event
    #    is triggered and following a new event can be triggered as soon as
    #    the signal is above thres1
    ind1 = np.where(charfct > thres1)[0]
    if len(ind1) == 0:
        return []
    ind2 = np.where(charfct > thres2)[0]
    #
    on = deque([ind1[0]])
    of = deque([-1])
    # determine the indices where charfct falls below off-threshold
    ind2_ = np.empty_like(ind2, dtype=bool)
    ind2_[:-1] = np.diff(ind2) > 1
    # next line is commented due to "deque index out of range" problem
    # last occurence is missed by the diff, add it manually
    #ind2_[-1] = True
    of.extend(ind2[ind2_].tolist())
    on.extend(ind1[np.where(np.diff(ind1) > 1)[0] + 1].tolist())
    # include last pick if trigger is on or drop it
    if max_len_delete:
        # drop it
        of.extend([1e99])
        on.extend([on[-1]])
    else:
        # include it
        of.extend([ind2[-1]])
    
    # add last sample to ensure trigger gets switched off if ctf does not fall
    # below off-threshold before hitting the end
    of.append(len(charfct))    
    #
    pick = []
    while on[-1] > of[0]:
        while on[0] <= of[0]:
            on.popleft()
        while of[0] < on[0]:
            of.popleft()
        if of[0] - on[0] > max_len:
            if max_len_delete:
                on.popleft()
                continue
            of.appendleft(on[0] + max_len)
        pick.append([on[0], of[0]])
    return np.array(pick, dtype=np.int64)

Looks like your characteristic function never goes above off-threshold.
I’d recommend simply plotting the characteristic function together with the thresholds

plt.plot(ctf)
plt.axhline(on_thresh, color='r')
plt.axhline(off_thresh, color='b')
plt.show()

This is the plot output.

This signal is long 25 seconds and I’m using these settings:
sta=1
lta=10

on_thresh=2
off_thresh=3

Maybe the problem is about the signal duration? do I have to use signals of at least a certain length?

It happened again with another signal with 40 seconds as duration.

The plot is similar as the previous plot that I sent.

It’s exactly that edge case what’s described in the tickets I linked above and what is gonna be fixed with the PR I linked above.
Why are you using an off-threshold that is higher than the on-threshold anyway? That’s kinda unusual. You start a trigger that you are unsure whether it can even un-trigger at all, since it’s unclear if the off-threshold will ever be reached, which is implied by the off-condition being “ctf falls below off-threshold”.

1 Like

Thank you Tobias. Sorry for the late response.
I solved it using the appropriate thresholds.

I suggest to insert a warning in the library if you use unusual thresholds