Repository: obspy/obspy

Issue:
Baer picker failing with fi_prep_cif_var error
**Description of the Problem**

I recently installed obspy on a new python install. Everything appeared to be working until I ran the tests for a package that made a call to the obspy.signal.trigger.pk_baer, which gives the following error:

```
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [5], in <module>
----> 1 p_pick, phase_info = pk_baer(trace.data, df, 20, 60, 7.0, 12.0, 100, 100)

File ~/Gits/obspy/obspy/signal/trigger.py:406, in pk_baer(reltrc, samp_int, tdownmax, tupevent, thr1, thr2, preset_len, p_dur, return_cf)
    402 # index in pk_mbaer.c starts with 1, 0 index is lost, length must be
    403 # one shorter
    404 args = (len(reltrc) - 1, C.byref(pptime), pfm, samp_int,
    405         tdownmax, tupevent, thr1, thr2, preset_len, p_dur, cf_p)
--> 406 errcode = clibsignal.ppick(reltrc, *args)
    407 if errcode != 0:
    408     raise MemoryError("Error in function ppick of mk_mbaer.c")

RuntimeError: ffi_prep_cif_var failed
```

It seems fairly likely to me that one of the libraries I have installed introduced a problem in this environment compared to my old environment. I'm just not sure how to begin figuring out the issue. I tried it in my old environment just to be sure and it works fine.

**Steps to Reproduce**
Running the tests yields the following failures:
FAILED obspy/signal/tests/test_trigger.py::TriggerTestCase::test_pk_baer
FAILED obspy/signal/tests/test_trigger.py::TriggerTestCase::test_pk_baer_cf
in addition to a third, unrelated error in TauPy

Additionally, going through the trigger/picker tutorial will also reproduce the problem (this is probably what the test code is doing, anyways):
```
from obspy.core import read
from obspy.signal.trigger import pk_baer
trace = read("https://examples.obspy.org/ev0_6.a01.gse2")[0]
df = trace.stats.sampling_rate
p_pick, phase_info = pk_baer(trace.data, df,20, 60, 7.0, 12.0, 100, 100)
```

**Versions**
ObsPy: 1.2.2.post0+547.g221c7ef4a9.obspy.master  (I tried both this and 1.2.2 as downloaded from conda-forge)
Python: 3.8.12
OS: Ubuntu 16

**Obspy Installation**
I tried installing obspy in two different ways and got the same result both ways: `conda install -c conda-forge obspy` (technically I used mamba, but that shouldn't matter) and from the latest master (`pip install -e {path_to_source}').

**Old Environment**
Obspy: 1.2.2 (installed from conda)
Python: 3.8.8
OS: Ubuntu 16

Thank you,
Shawn


Discussion:
can confirm the tutorial works for me on the current master, python 3.8.10, ubuntu 20.04 (edit: also works osx/ py 3.9.9)

i don't use anaconda so don't know how it works exactly but i wonder if there is some incompatible library hanging around that might be fixed with a series of updates and re-installs
Hi @shawnboltz 

Can you try this:

```bash
conda install libffi=3.3.*
```

And let us know if that fixes the issue?
Hey @d-chambers,

I just tried that, but unfortunately I'm getting the following error when I try to install it... it looks like something I need to sort out on my end:

```
Encountered problems while solving:
  - package libglib-2.70.2-h174f98d_1 requires libffi >=3.4.2,<3.5.0a0, but none of the providers can be installed
```

Doing a little more digging, it would seem that the version of Qt that I'm using (5.12.9) requires this version of libglib, so that's something that I will have to work out on my end.

Thanks for the clue, though. That helped a ton.
Update: I got it fixed. I ended up recreating my environment with libffi pinned to <3.4 and that seemed to resolve the issue.
I'll close this issue as it appears to be a conda packaging problem which hopefully will vanish as time goes bye.
See also #2758
@megies I am temporarily reopening this issue to discuss how it is best fixed for the conda-forge feedstock.

Pinning libffi to ~~`<1.4`~~ `<3.4` will probably work. Can this be done only for linux and py3.8 in the coda receipe?

The only relating item in the [release notes](https://github.com/libffi/libffi/releases/tag/v3.4.2) of libffi ~~1.4.2~~ 3.4.2 is

```
    Reject float and small integer argument in ffi_prep_cif_var().
      Callers must promote these types themselves.
```

Maybe you can make something out of it.
> The only relating item in the [release notes](https://github.com/libffi/libffi/releases/tag/v3.4.2) of libffi 1.4.2 is
> 
> ```
>     Reject float and small integer argument in ffi_prep_cif_var().
>       Callers must promote these types themselves.
> ```
> 
> Maybe you can make something out of it.

Interesting, but I think we should try to ignore it unless we see more nodes failing in the future..
Slightly confused, but I guess libffi 1.4.2 is what I see as 3.4.2 in the conda packages (and the above release notes too?)
Of course, sorry for the confusion.
I've skipped those two tests on one CI runner for now, reopening this so we can eventually re-enable those tests

Resolving patch:
diff --git a/obspy/signal/headers.py b/obspy/signal/headers.py
--- a/obspy/signal/headers.py
+++ b/obspy/signal/headers.py
@@ -61,7 +61,7 @@
     np.ctypeslib.ndpointer(dtype=np.float32, ndim=1,
                            flags='C_CONTIGUOUS'),
     C.c_int, C.POINTER(C.c_int), C.c_char_p, C.c_float, C.c_int, C.c_int,
-    C.c_float, C.c_float, C.c_int, C.c_int]
+    C.c_float, C.c_float, C.c_int, C.c_int, C.POINTER(C.c_float)]
 clibsignal.ppick.restype = C.c_int
 
 clibsignal.ar_picker.argtypes = [


Test patch:
diff --git a/obspy/signal/tests/test_trigger.py b/obspy/signal/tests/test_trigger.py
--- a/obspy/signal/tests/test_trigger.py
+++ b/obspy/signal/tests/test_trigger.py
@@ -4,13 +4,11 @@
 """
 import gzip
 import os
-import sys
 import unittest
 import warnings
 from ctypes import ArgumentError
 
 import numpy as np
-import pytest
 from numpy.testing import assert_array_almost_equal, assert_array_equal
 
 from obspy import Stream, UTCDateTime, read
@@ -82,10 +80,6 @@ def test_rec_sta_lta_raise(self):
         self.assertRaises(ArgumentError, clibsignal.recstalta,
                           np.array([1], dtype=np.int32), charfct, ndat, 5, 10)
 
-    @pytest.mark.xfail(
-        os.environ.get('CI') == 'true'
-        and os.environ.get('RUNNER_OS') == 'Linux'
-        and '3.8.13' in sys.version, reason='see #2984')
     def test_pk_baer(self):
         """
         Test pk_baer against implementation for UNESCO short course
@@ -100,10 +94,6 @@ def test_pk_baer(self):
         self.assertEqual(nptime, 17545)
         self.assertEqual(pfm, 'IPU0')
 
-    @pytest.mark.xfail(
-        os.environ.get('CI') == 'true'
-        and os.environ.get('RUNNER_OS') == 'Linux'
-        and '3.8.13' in sys.version, reason='see #2984')
     def test_pk_baer_cf(self):
         """
         Test pk_baer against implementation for UNESCO short course