Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making Matlab Runtime work with ridge extraction #3

Open
Lemez opened this issue Aug 14, 2021 · 35 comments
Open

Making Matlab Runtime work with ridge extraction #3

Lemez opened this issue Aug 14, 2021 · 35 comments

Comments

@Lemez
Copy link

Lemez commented Aug 14, 2021

Hi there,
I'm collaborating on an EEG project in Croatia, and am having difficulties porting the ridge extraction from Matlab to python using pymodalib.
I'm running OSX 15.7.1, currently using Python 3.7.3 and have installed Matlab Runtime Engine 9.6. I don't have a separate Matlab license.

I am getting a MatlabLibraryException when I try to implement wavelet transform or ridge extraction using matlab (implementation="python" works fine for wavelet transform), but as ridge_extraction requires Matlab, I can't get past the error. The DYLD_LIBRARY_PATH seems to be correct, have added it to both .bash_profile and as an environment variable in the script.

Here is my script:

import pymodalib
import pandas as pd
import csv 
import numpy as np
from scipy.io import loadmat
import h5py
import os
import sys
from matplotlib import pyplot as plt

os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"

patient="x"
samplerate = 500.0
fmax_arg = 1.2
fmin_arg = 0.8
file = "path/to/file"

with h5py.File(file, 'r') as f:
  dset = f[patient]
  data = f.get(patient)
  signal = np.array(data)
  times = pymodalib.generate_times(signal, samplerate)
  wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  iamp,iphi,ifreq = pymodalib.ridge_extraction(tfr=wt,frequencies=freq,fs=float(samplerate),method='direct',wopt=wtdict,implementation='matlab')

Traceback is as follows:

Traceback (most recent call last):
  File "moda.py", line 189, in <module>
    wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/algorithms/wavelet.py", line 191, in wavelet_transform
    **kwargs,
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/utils/decorators.py", line 72, in wrapper
    f"The MATLAB-packaged library '{module}' is not installed. Please install "
pymodalib.utils.matlab_runtime.MatlabLibraryException: The MATLAB-packaged library 'WT' is not installed. Please install PyMODA, which supplies the MATLAB-packaged libraries, or check if there is a pure-Python implementation by passing 'implementation="python"' to the function.

Many thanks for your help in advance.

@spmccormack
Copy link
Contributor

spmccormack commented Aug 14, 2021

Sorry about this, I forgot it was a bit poorly documented! I'll see what I can do to improve it.

The MATLAB-packaged libraries (like WT) are currently bundled with the PyMODA source code, even if you're using PyMODAlib without PyMODA. You just need to download the PyMODA repository as a zip file (and extract it) or clone the repo with the terminal command:

git clone https://github.com/luphysics/PyMODA.git

Then you can open a terminal in the main PyMODA folder, and install the required packages with the following command:

# Note: try replacing 'python3' in the command with 'python' or 'python3.7' if it doesn't work.
python3 packages/install.py -ymu 

After running the command, the error with your script should go away and you can delete the PyMODA folder.

As a sidenote: I've noticed an error in PyMODAlib which occurs with the example script for ridge extraction; it might also affect your script. I'll comment when I've fixed it.

@spmccormack
Copy link
Contributor

spmccormack commented Aug 14, 2021

I've fixed the exception which was raised when running ridge_extraction.py from examples/ridge_extraction. If you experience it too, you can upgrade your PyMODAlib with the command:

python3 -m pip install --upgrade pymodalib

(You may need to use python or python3.7 in the command instead.)

@Lemez
Copy link
Author

Lemez commented Aug 14, 2021

Thank you for the quick reply. I cloned the repo inside my current working folder, and ran the upgrade command as you suggested. I have a new error, which is progress! I can confirm that the file matlabruntimeforpython3_7.so is in the right place inside /Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64.

Exception caught during initialization of Python interface. Details: dlopen(/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so, 2): Library not loaded: @rpath/libpython3.7m.dylib
  Referenced from: /Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so
  Reason: image not found
Traceback (most recent call last):
  File "moda.py", line 189, in <module>
    wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/algorithms/wavelet.py", line 191, in wavelet_transform
    **kwargs,
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/utils/decorators.py", line 104, in wrapper
    return func(*args, **kwargs)
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/implementations/matlab/wavelet/wavelet_transform.py", line 61, in wavelet_transform
    import WT
  File "/Users/macintosh/.local/lib/python3.7/site-packages/WT/__init__.py", line 283, in <module>
    _pir.import_cppext()
  File "/Users/macintosh/.local/lib/python3.7/site-packages/WT/__init__.py", line 276, in import_cppext
    self.cppext_handle = importlib.import_module("matlabruntimeforpython" + self.interpreter_version)
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: dlopen(/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so, 2): Library not loaded: @rpath/libpython3.7m.dylib
  Referenced from: /Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so
  Reason: image not found

@spmccormack
Copy link
Contributor

Looks similar to an issue someone had here.

Could you try this terminal command:

find /Users/macintosh/.pyenv/versions/3.7.3/lib/ -name "libpython3.7m.dylib"

And reply with the output? Then we should be able to symlink the file so the Matlab Runtime can find it.

@Lemez
Copy link
Author

Lemez commented Aug 14, 2021

There is no output from that command, but there is a file called libpython3.7m.a in /Users/macintosh/.pyenv/versions/3.7.3/lib

@spmccormack
Copy link
Contributor

Hmm, could you try adding this line to your script (just before the line which starts with os.environ["DYLD_LIBRARY_PATH"]):

os.environ["LD_LIBRARY_PATH"] = f"/Users/macintosh/.pyenv/versions/3.7.3/lib:{os.environ['LD_LIBRARY_PATH']}"

And see if it works?

If it still doesn't work, try adding this as well (just after the line added above):

os.environ["PATH"] = f"{os.environ['LD_LIBRARY_PATH']}:{os.environ['PATH']}"

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Curious, these both fail as LD_LIBRARY_PATH raises a KeyError. I checked os.environ.keys() and the (edited) output is:

KeysView(environ({'SHELL': '/usr/local/bin/bash', 
'PYENV_HOOK_PATH': '/Users/macintosh/.pyenv/pyenv.d
:/usr/local/Cellar/pyenv/1.2.21/pyenv.d
:/usr/local/etc/pyenv.d
:/etc/pyenv.d
:/usr/lib/pyenv/hooks', 
'PYENV_SHELL': 'bash', 'XPC_FLAGS': '0x0',  'HOME': '/Users/Macintosh',
  'PYENV_DIR': '/Users/macintosh/Documents/_localDev/xs',  'USER': 'macintosh', 'COLORFGBG': '7;0', 'LC_TERMINAL_VERSION': '3.4.8', 'SHLVL': '1', 'XPC_SERVICE_NAME': '0',
 'PYENV_ROOT': '/Users/macintosh/.pyenv',
 'PATH': '/Users/macintosh/.pyenv/versions/3.7.3/bin
:/usr/local/Cellar/pyenv/1.2.21/libexec
:/usr/local/Cellar/pyenv/1.2.21/plugins/python-build/bin
:/usr/local/sbin:/Users/macintosh/.pyenv/shims
:/Users/macintosh/.gem/ruby/2.7.2/bin
:/Users/macintosh/.rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/bin
:/Users/macintosh/.rubies/ruby-2.7.2/bin
:/Users/macintosh/.bin:/Users/macintosh/.pyenv/shims:/Users/macintosh/.pyenv/shims
:/Users/macintosh/.pyenv/shims:/usr/local/sbin
:/Users/macintosh/.pyenv/shims
:/Users/macintosh/.bin:/usr/local/sbin:/Users/macintosh/.pyenv/shims
:/Users/macintosh/.bin:/usr/local/sbin:/Users/macintosh/.pyenv/shims
:/Users/macintosh/.bin
:/usr/local/bin
:/usr/bin
:/bin
:/usr/sbin
:/sbin',
 'OLDPWD': '/Users/macintosh/Documents/_localDev/xs/pymoda', }))

Perhaps to add LD_LIBRARY_PATH = /Users/macintosh/.pyenv/versions/3.7.3/lib/libpython3.7m.a to my .bash_profile?

@spmccormack
Copy link
Contributor

Ah, maybe just try adding these lines instead (I'm using diff syntax to make it clearer which lines have been added, so don't include the leading + symbol):

import pymodalib
import pandas as pd
import csv 
import numpy as np
from scipy.io import loadmat
import h5py
import os
import sys
from matplotlib import pyplot as plt

+os.environ["LD_LIBRARY_PATH"] = f"/Users/macintosh/.pyenv/versions/3.7.3/lib"
+os.environ["PATH"] = f"{os.environ['LD_LIBRARY_PATH']}:{os.environ['PATH']}"

os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"
+os.environ["DYLD_LIBRARY_PATH"] = f'{os.environ["LD_LIBRARY_PATH"]}:{os.environ["DYLD_LIBRARY_PATH"]})'

patient="x"
samplerate = 500.0
fmax_arg = 1.2
fmin_arg = 0.8
file = "path/to/file"

with h5py.File(file, 'r') as f:
  dset = f[patient]
  data = f.get(patient)
  signal = np.array(data)
  times = pymodalib.generate_times(signal, samplerate)
  wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  iamp,iphi,ifreq = pymodalib.ridge_extraction(tfr=wt,frequencies=freq,fs=float(samplerate),method='direct',wopt=wtdict,implementation='matlab')

If that works then we'll know whether we should edit ~/.bash_profile.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Unfortunately it is still failing to find this libpython3.7m.dylib file:

Exception caught during initialization of Python interface. Details: dlopen(/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so, 2): Library not loaded: @rpath/libpython3.7m.dylib
  Referenced from: /Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so
  Reason: image not found
Traceback (most recent call last):
  File "moda.py", line 191, in <module>
    wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/algorithms/wavelet.py", line 191, in wavelet_transform
    **kwargs,
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/utils/decorators.py", line 104, in wrapper
    return func(*args, **kwargs)
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pymodalib/implementations/matlab/wavelet/wavelet_transform.py", line 61, in wavelet_transform
    import WT
  File "/Users/macintosh/.local/lib/python3.7/site-packages/WT/__init__.py", line 283, in <module>
    _pir.import_cppext()
  File "/Users/macintosh/.local/lib/python3.7/site-packages/WT/__init__.py", line 276, in import_cppext
    self.cppext_handle = importlib.import_module("matlabruntimeforpython" + self.interpreter_version)
  File "/Users/macintosh/.pyenv/versions/3.7.3/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: dlopen(/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so, 2): Library not loaded: @rpath/libpython3.7m.dylib
  Referenced from: /Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64/matlabruntimeforpython3_7.so
  Reason: image not found

I searched through my user directory and I can't see a libpython.*.dylib file anywhere.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

The pyenv/versions/3.7.3/lib directory contains:

python3.7 directory
pkgconfig directory
libpython3.7m.a

The pyenv/versions/3.7.3/include directory contains a dir called python3.7m which contains a number of .h files.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Would you recommend to uninstall pyenv and install 3.7.3 globally?

@spmccormack
Copy link
Contributor

spmccormack commented Aug 15, 2021

Would you recommend to uninstall pyenv and install 3.7.3 globally?

Yup, I think uninstalling pyenv and using Homebrew to install Python 3.7 is the easiest solution. I've only ever tested it with Homebrew. I'm not sure which command would be used to install Python 3.7 with Homebrew (rather than a newer version) though - maybe brew install [email protected] or brew install [email protected] etc.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Rrrrr... now scipy is playing up:

Traceback (most recent call last):
  File "moda.py", line 2, in <module>
    import pymodalib
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/__init__.py", line 19, in <module>
    from pymodalib.algorithms.group_coherence import group_coherence, dual_group_coherence
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/algorithms/group_coherence.py", line 25, in <module>
    from scipy.stats import ranksums
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/stats/__init__.py", line 441, in <module>
    from .stats import *
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/stats/stats.py", line 37, in <module>
    from scipy.spatial.distance import cdist
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/spatial/__init__.py", line 102, in <module>
    from ._geometric_slerp import geometric_slerp
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/spatial/_geometric_slerp.py", line 8, in <module>
    from scipy.spatial.distance import euclidean
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/spatial/distance.py", line 124, in <module>
    from ..special import rel_entr
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/__init__.py", line 643, in <module>
    from . import _ufuncs
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so, 2): Symbol not found: __gfortran_stop_numeric_f08
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so
  Expected in: /Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64/libgfortran.3.dylib
 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so

Have installed pymodalib-0.11.3b1 and python 3.7.3 directly from python.org (taking care to follow uninstall pyenv instructions here

@spmccormack
Copy link
Contributor

spmccormack commented Aug 15, 2021

Could you try updating pip:

python3 -m pip install --user --upgrade pip

And then install these particular numpy and scipy versions:

python3 -m pip install --force-reinstall scipy==1.4.1 numpy==1.18.3

Edit: Added --force-reinstall parameter to the second command, run the edited command if you've already tried the unedited one and it didn't work.

@spmccormack
Copy link
Contributor

If it's still failing after that (check the edit in my previous comment if you haven't seen it), check for the location of the fortran dylib:

find ~ -name "libgfortran.3.dylib" 

If nothing appears from that command, try:

sudo find /Library/Frameworks/ -name "libgfortran.3.dylib" 

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

The force reinstalls result in the same error message as previously.
Output from find is:
/Users/macintosh/.pymoda/PyMODA/PyMODA.app/Contents/MacOS/libgfortran.3.dylib /Library/Frameworks//Python.framework/Versions/3.7/lib/python3.7/site-packages/numpy/.dylibs/libgfortran.3.dylib /Library/Frameworks//Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/.dylibs/libgfortran.3.dylib

@spmccormack
Copy link
Contributor

Ok, could you try adding this line:

import pymodalib
import pandas as pd
import csv 
import numpy as np
from scipy.io import loadmat
import h5py
import os
import sys
from matplotlib import pyplot as plt

os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"
+os.environ["DYLD_LIBRARY_PATH"] = f'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numpy/.dylibs:/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/.dylibs:{os.environ["DYLD_LIBRARY_PATH"]})'

patient="x"
samplerate = 500.0
fmax_arg = 1.2
fmin_arg = 0.8
file = "path/to/file"

with h5py.File(file, 'r') as f:
  dset = f[patient]
  data = f.get(patient)
  signal = np.array(data)
  times = pymodalib.generate_times(signal, samplerate)
  wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  iamp,iphi,ifreq = pymodalib.ridge_extraction(tfr=wt,frequencies=freq,fs=float(samplerate),method='direct',wopt=wtdict,implementation='matlab')

@spmccormack
Copy link
Contributor

spmccormack commented Aug 15, 2021

If that doesn't work, try removing the line from the previous comment and then creating this symlink:

sudo ln -s /Library/Frameworks//Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/.dylibs/libgfortran.3.dylib /Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

These both give the same error message as above.

Output for the symlink above is ln: /Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64/libgfortran.3.dylib: File exists

@spmccormack
Copy link
Contributor

Hmm, it would be interesting to see what the error message is when you insert these lines here:

+import os
+if "DYLD_LIBRARY_PATH" in os.environ:
+    del os.environ["DYLD_LIBRARY_PATH"]
+from scipy.stats import ranksums
import pymodalib
import pandas as pd
import csv 
import numpy as np
from scipy.io import loadmat
import h5py
import os
import sys
from matplotlib import pyplot as plt

os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"

patient="x"
samplerate = 500.0
fmax_arg = 1.2
fmin_arg = 0.8
file = "path/to/file"

with h5py.File(file, 'r') as f:
  dset = f[patient]
  data = f.get(patient)
  signal = np.array(data)
  times = pymodalib.generate_times(signal, samplerate)
  wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
  iamp,iphi,ifreq = pymodalib.ridge_extraction(tfr=wt,frequencies=freq,fs=float(samplerate),method='direct',wopt=wtdict,implementation='matlab')

This might help us to find a workaround.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Relevant os.environ output is:

environ({'SHELL': '/usr/local/bin/bash', 'PWD': '/Users/macintosh/Documents/_localDev/xs', 
'DYLD_LIBRARY_PATH': '/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64',
 'TMPDIR': '/var/folders/lg/vthm0cwn2cvdd0fz13mdyx9w0000gn/T/', 
'PATH': '/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/sbin:/Users/macintosh/.gem/ruby/2.7.2/bin:/Users/macintosh/.rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/bin:/Users/macintosh/.rubies/ruby-2.7.2/bin:/Users/macintosh/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', 
TERM_PROGRAM': 'iTerm.app', '_': '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7',
 '__PYVENV_LAUNCHER__': '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7'}

The error message after adding the above code is:

Traceback (most recent call last):
  File "moda.py", line 6, in <module>
    from scipy.stats import ranksums
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/stats/__init__.py", line 384, in <module>
    from .stats import *
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/stats/stats.py", line 179, in <module>
    from scipy.spatial.distance import cdist
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/spatial/__init__.py", line 107, in <module>
    from . import distance, transform
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/spatial/distance.py", line 125, in <module>
    from ..special import rel_entr
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/__init__.py", line 634, in <module>
    from . import _ufuncs
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so, 2): Symbol not found: __gfortran_stop_numeric_f08
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so
  Expected in: /Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64/libgfortran.3.dylib
 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/special/_ufuncs.cpython-37m-darwin.so

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

Perhaps this all means that I need to get scipy working as a first step. I'll search for some options.

@Lemez
Copy link
Author

Lemez commented Aug 15, 2021

On digging a bit, I see that I don;t have a PYTHONPATH variable set, perhaps this is the issue. Will look into it further this evening, thanks so much for your help so far.

----SYSPATH---
/Users/macintosh/Documents/_localDev/xs
/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload
/Users/macintosh/Library/Python/3.7/lib/python/site-packages
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
1.7.1
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/__init__.py
Macintosh-MacBook-Pro:xs macintosh$ python3 install.py
----PATH---
/Library/Frameworks/Python.framework/Versions/3.7/bin
/usr/local/sbin
/Users/macintosh/.gem/ruby/2.7.2/bin
/Users/macintosh/.rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/bin
/Users/macintosh/.rubies/ruby-2.7.2/bin
/Users/macintosh/.bin
/Library/Frameworks/Python.framework/Versions/3.7/bin
/usr/local/sbin
/Users/macintosh/.bin
/Library/Frameworks/Python.framework/Versions/3.7/bin
/usr/local/sbin
/Users/macintosh/.bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
----PYTHONPATH---
Traceback (most recent call last):
  File "install.py", line 6, in <module>
    print('\n'.join(os.environ["PYTHONPATH"].split(":")))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
    raise KeyError(key) from None
KeyError: 'PYTHONPATH'

@spmccormack
Copy link
Contributor

spmccormack commented Aug 15, 2021

No worries, and sorry I can't help more effectively - unfortunately it's not really possible for me to get macOS running in a VM for testing.

The weird part is that it seems to be trying to find the .dylib file in a Matlab directory (second-last line of error message):

 Expected in: /Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64/libgfortran.3.dylib

It looks to me like there's an environment variable which is causing Scipy to try and use an incompatible .dylib file with the same name from the Matlab Runtime.

I'd suggest trying to remove the DYLD_LIBRARY_PATH variable from ~/.bash_profile, then opening a new terminal and seeing if a simple script using Scipy works:

import os 
assert not "DYLD_LIBRARY_PATH" in os.environ, "Env variable should not be set"
from scipy.stats import ranksums
print("Success")

If it doesn't work, we should know it's definitely a problem with Scipy.

You could also try setting the PYTHONPATH to /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/.dylibs, although probably best to avoid if possible.

@Lemez
Copy link
Author

Lemez commented Aug 18, 2021

The script above works, so it seems that it is not a problem with scipy. The good news is that pymodalib is loading as before when I change implementation to "python", the bad news is that the implementation="matlab" is still causing the error:

pymodalib.utils.matlab_runtime.MatlabLibraryException: The MATLAB-packaged library 'WT' is not installed. Please install PyMODA

Is there any way I might try to export ridge_extraction from PYMODA and use that function directly?

Another alternative might be to try a different Python VM like anaconda and see if that runs into similar issues?

@spmccormack
Copy link
Contributor

spmccormack commented Aug 21, 2021

The script above works, so it seems that it is not a problem with scipy. The good news is that pymodalib is loading as before when I change implementation to "python", the bad news is that the implementation="matlab" is still causing the error:

pymodalib.utils.matlab_runtime.MatlabLibraryException: The MATLAB-packaged library 'WT' is not installed. Please install PyMODA

I think this might be happening because you reinstalled Python; have you tried following the instructions in this comment again?

Hopefully that will fix this issue and we'll be back to the more recent problem. I should be able to implement a workaround for it today or tomorrow.

@Lemez
Copy link
Author

Lemez commented Aug 21, 2021 via email

@spmccormack
Copy link
Contributor

spmccormack commented Aug 30, 2021

By the way, I've pushed a change which may fix the issue. Could you try installing from the dev branch using:

python -m pip install git+https://github.com/luphysics/PyMODAlib.git@dev --upgrade

Edit: There was a small mistake in that version; in the unlikely event that you'd already installed it, just re-run the command above!

And then run your script, ensuring that this line is still present near the start:

And then run your script, ensuring that the os.environ[... line is replaced with these lines:

-os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"
+from pymodalib.utils import macos
+
+macos.configure_dyld_library_path(
+    "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:"
+    "/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:"
+    "/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:"
+    "/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"
+)

Here's an easier-to-copy block (just make sure you remember to remove the old os.environ line):

from pymodalib.utils import macos

macos.configure_dyld_library_path(
    "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:"
    "/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:"
    "/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:"
    "/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"
)

@Lemez
Copy link
Author

Lemez commented Aug 31, 2021 via email

@Lemez
Copy link
Author

Lemez commented Sep 2, 2021

I followed the above suggestions (reinstalling PYMODA and then the pymodalib fix as above. Now I have the following ImportError:

ImportError: cannot import name 'macos' from 'pymodalib.utils' (/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/utils/__init__.py)

The wavelet transform with python implementation is working as intended. I think we're close!

@spmccormack
Copy link
Contributor

Sorry for the slow reply; I've pushed a fix for the import issue you were experiencing, could you try uninstalling your PyMODAlib:

python -m pip uninstall pymodalib -y

And then following the instructions from this comment again? Hopefully we'll get some useful results this time!

@Lemez
Copy link
Author

Lemez commented Sep 6, 2021

I've followed the uninstall and reinstall as you suggested.
from pymodalib.utils import macos and macos.configure_dyld_library_path are working fine now.

When I either try to run wavelet_transform(implementation='matlab') or ridge_extraction, I get the same error message, at which point the script hangs:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/utils/decorators.py:96: RuntimeWarning: Trying to set MATLAB Runtime variables...
  "Trying to set MATLAB Runtime variables...", RuntimeWarning

Verbose output is as follows:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/utils/decorators.py:96: RuntimeWarning: Trying to set MATLAB Runtime variables...
  "Trying to set MATLAB Runtime variables...", RuntimeWarning
# /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/queues.cpython-37.pyc matches /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/queues.py
# code object from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/queues.cpython-37.pyc'
# extension module '_multiprocess' loaded from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_multiprocess.cpython-37m-darwin.so'
# extension module '_multiprocess' executed from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_multiprocess.cpython-37m-darwin.so'
import '_multiprocess' # <_frozen_importlib_external.ExtensionFileLoader object at 0x7fb30a150048>
# /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/connection.cpython-37.pyc matches /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/connection.py
# code object from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/connection.cpython-37.pyc'
# /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/util.cpython-37.pyc matches /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/util.py
# code object from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/util.cpython-37.pyc'
import 'multiprocess.util' # <_frozen_importlib_external.SourceFileLoader object at 0x7fb30a50dba8>
import 'multiprocess.connection' # <_frozen_importlib_external.SourceFileLoader object at 0x7fb30a150e10>
import 'multiprocess.queues' # <_frozen_importlib_external.SourceFileLoader object at 0x7fb309d97668>
# /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/synchronize.cpython-37.pyc matches /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/synchronize.py
# code object from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/synchronize.cpython-37.pyc'
import 'multiprocess.synchronize' # <_frozen_importlib_external.SourceFileLoader object at 0x7fb30a504e48>
# /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/popen_fork.cpython-37.pyc matches /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/popen_fork.py
# code object from '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/multiprocess/__pycache__/popen_fork.cpython-37.pyc'
import 'multiprocess.popen_fork' # <_frozen_importlib_external.SourceFileLoader object at 0x7fb30a52a470>

@spmccormack
Copy link
Contributor

spmccormack commented Sep 6, 2021

I get the same error message, at which point the script hangs:

Sorry, could you clarify which error message you get?


I would expect it to hang for a while; it's hard to judge how long it will take for it to run, but the example script from this repository (which uses a signal of around 10,000 samples) will take around 1-2 minutes on a Macbook, so you could expect substantially longer calculations if your signal is larger. There's also a long delay on the first run, I think caused by the Matlab Runtime building some caches.

There's no real way to monitor its progress and it does normally appear to hang, but you can watch the CPU and RAM usage to see if it's doing anything.


This part is actually normal, so nothing to worry about:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pymodalib/utils/decorators.py:96: RuntimeWarning: Trying to set MATLAB Runtime variables...
  "Trying to set MATLAB Runtime variables...", RuntimeWarning

Just to check, was the verbose output caused by stopping the program with Ctrl+C, or did it happen without intervention?

@Lemez
Copy link
Author

Lemez commented Sep 6, 2021

Sorry for the confusion: I mean that I get the above error message both when I run wavelet_transform(implementation='matlab') and ridge_extraction. The verbose output (from running the script with the -v flag) was without any intervention.

I'm fairly sure that the script is hanging (for both wavelet_transform(implementation='matlab') and ridge_extraction), as I left it for some 15 minutes, using a test file in .hdf5 format (which works fine in the rest of pymodalib) which is 3 seconds long (at 500 samples per second). Using the same test file with the python implementation of wavelet_transform renders in under 1 second.

I'll leave the wavelet_transform(implementation='matlab') and also (belatedly, apologies) your example ridge_extraction.py script to run overnight to see if, as you suggest, it's just taking a while to build the Matlab Runtime caches, and report back tomorrow.

EDIT: unfortunately no progress after leaving it all night

@spmccormack
Copy link
Contributor

spmccormack commented Sep 16, 2021

Sorry for the late reply! Could you see if there's any difference in behaviour if you put everything inside an if __name__ == "__main__": block, i.e. something like this:

if __name__ == "__main__":
    # Note: This is based on the code from your first post, just as an example. (Use your newer code)
    import pymodalib
    import pandas as pd
    import csv 
    import numpy as np
    from scipy.io import loadmat
    import h5py
    import os
    import sys
    from matplotlib import pyplot as plt

    os.environ["DYLD_LIBRARY_PATH"] = "/Applications/MATLAB/MATLAB_Runtime/v96/runtime/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/sys/os/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/bin/maci64:/Applications/MATLAB/MATLAB_Runtime/v96/extern/bin/maci64"

    patient="x"
    samplerate = 500.0
    fmax_arg = 1.2
    fmin_arg = 0.8
    file = "path/to/file"

    with h5py.File(file, 'r') as f:
        dset = f[patient]
        data = f.get(patient)
        signal = np.array(data)
        times = pymodalib.generate_times(signal, samplerate)
        wt, freq,wtdict = pymodalib.wavelet_transform(signal, samplerate, resolution=wt_resolution,cut_edges=False,fmax=fmax_arg,fmin=fmin_arg,wavelet=wavelet,return_opt=True,implementation='matlab')
        iamp,iphi,ifreq =         pymodalib.ridge_extraction(tfr=wt,frequencies=freq,fs=float(samplerate),method='direct',wopt=wtdict,implementation='matlab')

Also, if that doesn't make any difference, could you try adding the following lines at the start while retaining the new main guard:

if __name__ == "__main__":
    ### These lines added ###
    import multiprocess
    import multiprocessing

    start_method = "spawn"
    multiprocess.set_start_method(start_method)
    multiprocessing.set_start_method(start_method)
    ### End of added code ###

    # Rest of code continues here
    import pymodalib
    import pandas as pd
    # ... 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants