ModuleNotFoundError: No module named 'numpy' when running a command with sct_run_batch with SCT v5.1.0

Description
I am using sct_run_batch and in the shell script called, I call a command from gradient_unwarp. I downloaded SCT 5.1.0 and when calling this line :
gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n

This error occurs:
+ gradient_unwarp.py sub-1000394_T1w_raw_RPI_r.nii.gz sub-1000394_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/usr/local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
  File "/usr/local/lib/python3.7/dist-packages/gradunwarp/core/__init__.py", line 8, in <module>
    from .unwarp_resample import Unwarper
  File "/usr/local/lib/python3.7/dist-packages/gradunwarp/core/unwarp_resample.py", line 8, in <module>
    import numpy as np
ModuleNotFoundError: No module named 'numpy'

I tried runnig the same command in my terminal, there was no error. I went back to SCT v5.0.1 and there was no error, the command worked.
I am running on WSL1 with Ubuntu 18.04.
Steps to Reproduce
See README.md (preprocessing section)

Install SCT 5.1.0

Initialize shell variable with path to gradient correction file

PATH_GRADCORR_FILE=<path-gradcorr>

Run preprocessing (see preprocess_data.sh)

sct_run_batch -jobs -1 -path-data <PATH-DATA> -path-output ~/ukbiobank_preprocess -script preprocess_data.sh -script-args $PATH_GRADCORR_FILE

Expected behavior: Using SCT v5.0.1 or running the command in the terminal:
 gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
gradunwarp-INFO: Parsing /mnt/y/sebeda/coeff.grad/ICM/coeff.grad for harmonics coeffs
gradunwarp-INFO: Evaluating spherical harmonics
gradunwarp-INFO: on a 60^3 grid
gradunwarp-INFO: with extents -300.0mm to 300.0mm
gradunwarp-INFO: along x...
...

Actual behavior: Here is the complete log file of the processing error.
err.preprocess_data_sub-1000394.log

So, the error seems to originate from the gradunwarp package. Did you make sure to install this package with all the dependencies? Can you run it without error from the Terminal?

So, the error seems to originate from the gradunwarp package. Did you make sure to install this package with all the dependencies? Can you run it without error from the Terminal?

Did you make sure to install this package with all the dependencies?

Yes!

Can you run it without error from the Terminal?

Yes, there are no errors when I run it from the terminal or using SCTv5.0.1 @jcohenadad

Did you make sure to install this package with all the dependencies?

Yes!

Can you run it without error from the Terminal?

Yes, there are no errors when I run it from the terminal or using SCTv5.0.1 @jcohenadad

ah yes sorry-- you already mentioned earlier that it works as a standalone from the Terminal... this is very strange because sct_run_batch is essentially a wrapper for shell commands.
What is the output of:
which gradient_unwarp.py

ah yes sorry-- you already mentioned earlier that it works as a standalone from the Terminal... this is very strange because sct_run_batch is essentially a wrapper for shell commands.
What is the output of:
which gradient_unwarp.py

The output is:
/usr/local/bin/gradient_unwarp.py

The output is:
/usr/local/bin/gradient_unwarp.py

hum, i would have to dig deeper-- @joshuacwnewton @kousu @Drulex do you have any clue?

hum, i would have to dig deeper-- @joshuacwnewton @kousu @Drulex do you have any clue?

A quick observation: gradunwarp installs itself using sudo python setup.py install. This is (imo) a strange way of doing things, because it forces us to install it to the system Python. I feel that their choice makes it harder to manage and isolate dependencies, and might be what lead to a situation like this. I'm reminded of this comic.
To make sure numpy is present in the same location as gradunwarp, could you try installing numpy using sudo?
> sudo pip3 install numpy

This should ensure that numpy is installed to your system Python's package directory (which should be /usr/local/lib/python3.7/dist-packages/).

A quick observation: gradunwarp installs itself using sudo python setup.py install. This is (imo) a strange way of doing things, because it forces us to install it to the system Python. I feel that their choice makes it harder to manage and isolate dependencies, and might be what lead to a situation like this. I'm reminded of this comic.
To make sure numpy is present in the same location as gradunwarp, could you try installing numpy using sudo?
> sudo pip3 install numpy

This should ensure that numpy is installed to your system Python's package directory (which should be /usr/local/lib/python3.7/dist-packages/).

To make sure numpy is present in the same location as gradunwarp, could you try installing numpy using sudo?

I would highly discourage using sudo pip install anything because it's a major security risk. That's basically running arbitrary code from the internet as root.
Instead gradunwarp should be installed without root privileges.

To make sure numpy is present in the same location as gradunwarp, could you try installing numpy using sudo?

I would highly discourage using sudo pip install anything because it's a major security risk. That's basically running arbitrary code from the internet as root.
Instead gradunwarp should be installed without root privileges.

Instead gradunwarp should be installed without root privileges.

That was my thinking, too. But, then this happens:
joshua@XPS-15-9560:~/Downloads/gradunwarp-1.2.0$ python3 setup.py install
running install
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building py_modules sources
building extension "gradunwarp.core.interp3_ext" sources
building extension "gradunwarp.core.legendre_ext" sources
building extension "gradunwarp.core.transform_coordinates_ext" sources
building data_files sources
build_src: building npy-pkg config files
running build_py
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
running build_scripts
running install_lib
running install_scripts
changing mode of /usr/local/bin/gradient_unwarp.py to 755
error: [Errno 1] Operation not permitted: '/usr/local/bin/gradient_unwarp.py'

Because of this, I went along with the sudo restriction, but... yeah. On second thought, I think it would be better to take a closer look at ukbiobank-spinalcord-csa's dependency on gradunwarp.

Instead gradunwarp should be installed without root privileges.

That was my thinking, too. But, then this happens:
joshua@XPS-15-9560:~/Downloads/gradunwarp-1.2.0$ python3 setup.py install
running install
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building py_modules sources
building extension "gradunwarp.core.interp3_ext" sources
building extension "gradunwarp.core.legendre_ext" sources
building extension "gradunwarp.core.transform_coordinates_ext" sources
building data_files sources
build_src: building npy-pkg config files
running build_py
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
running build_scripts
running install_lib
running install_scripts
changing mode of /usr/local/bin/gradient_unwarp.py to 755
error: [Errno 1] Operation not permitted: '/usr/local/bin/gradient_unwarp.py'

Because of this, I went along with the sudo restriction, but... yeah. On second thought, I think it would be better to take a closer look at ukbiobank-spinalcord-csa's dependency on gradunwarp.

But have you tried the --prefix option? From https://github.com/Washington-University/gradunwarp#install:

But have you tried the --prefix option? From https://github.com/Washington-University/gradunwarp#install:

Sorry. I think I've distracted from the core problem here. while the gradunwarp installation is concerning, I don't think where gradunwarp is installed relates to the missing numpy dependency.

Sorry. I think I've distracted from the core problem here. while the gradunwarp installation is concerning, I don't think where gradunwarp is installed relates to the missing numpy dependency.

For example installing to local directory:
[drulex@gentoo-p53 tmp]  $  git clone git@github.com:Washington-University/gradunwarp.git
Cloning into 'gradunwarp'...
remote: Enumerating objects: 378, done.
remote: Total 378 (delta 0), reused 0 (delta 0), pack-reused 378
Receiving objects: 100% (378/378), 76.08 KiB | 1.77 MiB/s, done.
Resolving deltas: 100% (206/206), done.
[drulex@gentoo-p53 tmp]  $  cd gradunwarp/
[drulex@gentoo-p53 gradunwarp] [master] $  python setup.py install --prefix ./
running install
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building py_modules sources
building extension "gradunwarp.core.interp3_ext" sources
building extension "gradunwarp.core.legendre_ext" sources
building extension "gradunwarp.core.transform_coordinates_ext" sources
building data_files sources
build_src: building npy-pkg config files
running build_py
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
creating build
creating build/lib.linux-x86_64-3.7
creating build/lib.linux-x86_64-3.7/gradunwarp
creating build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/__init__.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/coeffs.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/globals.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/__init__.py -> build/lib.linux-x86_64-3.7/gradunwarp
copying gradunwarp/core/utils.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/unwarp_resample.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/gradient_unwarp.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
creating build/lib.linux-x86_64-3.7/gradunwarp/core/tests
copying gradunwarp/core/tests/test_utils.py -> build/lib.linux-x86_64-3.7/gradunwarp/core/tests
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
building 'gradunwarp.core.interp3_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

creating build/temp.linux-x86_64-3.7/gradunwarp
creating build/temp.linux-x86_64-3.7/gradunwarp/core
compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/interp3_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/interp3_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/interp3_ext.c: In function ‘interp3’:
gradunwarp/core/interp3_ext.c:97:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   97 |     itr_v = (PyArrayIterObject *) PyArray_IterNew(result);
      |                                                   ^~~~~~
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:97:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:98:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   98 |     itr_r = (PyArrayIterObject *) PyArray_IterNew(R);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:98:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:99:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   99 |     itr_c = (PyArrayIterObject *) PyArray_IterNew(C);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:99:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:100:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  100 |     itr_s = (PyArrayIterObject *) PyArray_IterNew(S);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:100:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:123:9: warning: returning ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} from a function with incompatible return type ‘PyObject *’ {aka ‘struct _object *’} [-Wincompatible-pointer-types]
  123 |  return result;
      |         ^~~~~~
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/interp3_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/interp3_ext.cpython-37m-x86_64-linux-gnu.so
building 'gradunwarp.core.legendre_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/legendre_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/legendre_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/legendre_ext.c: In function ‘legendre’:
gradunwarp/core/legendre_ext.c:86:25: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
   86 |         printf("but mu=%d and nu=%d\n", mu, nu);
      |                        ~^               ~~
      |                         |               |
      |                         int             long int
      |                        %ld
gradunwarp/core/legendre_ext.c:86:35: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
   86 |         printf("but mu=%d and nu=%d\n", mu, nu);
      |                                  ~^         ~~
      |                                   |         |
      |                                   int       long int
      |                                  %ld
gradunwarp/core/legendre_ext.c:99:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   99 |     itr_x = (PyArrayIterObject *) PyArray_IterNew(x);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/legendre_ext.c:99:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/legendre_ext.c:100:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  100 |     itr_r = (PyArrayIterObject *) PyArray_IterNew(result);
      |                                                   ^~~~~~
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/legendre_ext.c:100:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/legendre_ext.c:108:32: warning: format ‘%f’ expects argument of type ‘doubl ’, but argument 2 has type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} [-Wformat=]
  108 |             printf("but got x=%f\n", x);
      |                               ~^     ~
      |                                |     |
      |                                |     PyArrayObject * {aka struct tagPyArrayObject_fields *}
      |                                double
gradunwarp/core/legendre_ext.c:157:12: warning: returning ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} from a function with incompatible return type ‘PyObject *’ {aka ‘struct _object *’} [-Wincompatible-pointer-types]
  157 |     return result;
      |            ^~~~~~
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/legendre_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/legendre_ext.cpython-37m-x86_64-linux-gnu.so
building 'gradunwarp.core.transform_coordinates_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/transform_coordinates_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/transform_coordinates_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/transform_coordinates_ext.c: In function ‘transform_coordinates’:
gradunwarp/core/transform_coordinates_ext.c:102:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  102 |     itr_x = (PyArrayIterObject *) PyArray_IterNew(X);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:102:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:103:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  103 |     itr_y = (PyArrayIterObject *) PyArray_IterNew(Y);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:103:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:104:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  104 |     itr_z = (PyArrayIterObject *) PyArray_IterNew(Z);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:104:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:105:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  105 |     itr_xm = (PyArrayIterObject *) PyArray_IterNew(Xm);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:105:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:106:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  106 |     itr_ym = (PyArrayIterObject *) PyArray_IterNew(Ym);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:106:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:107:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  107 |     itr_zm = (PyArrayIterObject *) PyArray_IterNew(Zm);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:107:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.cpython-37m-x86_64-linux-gnu.so
running build_scripts
creating build/scripts.linux-x86_64-3.7
copying and adjusting gradunwarp/core/gradient_unwarp.py -> build/scripts.linux-x86_64-3.7
changing mode of build/scripts.linux-x86_64-3.7/gradient_unwarp.py from 644 to 755
running install_lib
creating lib
creating lib/python3.7
creating lib/python3.7/site-packages
creating lib/python3.7/site-packages/gradunwarp
copying build/lib.linux-x86_64-3.7/gradunwarp/__init__.py -> .//lib/python3.7/site-packages/gradunwarp
creating lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/legendre_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/interp3_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
creating lib/python3.7/site-packages/gradunwarp/core/tests
copying build/lib.linux-x86_64-3.7/gradunwarp/core/tests/test_utils.py -> .//lib/python3.7/site-packages/gradunwarp/core/tests
copying build/lib.linux-x86_64-3.7/gradunwarp/core/gradient_unwarp.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/unwarp_resample.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/utils.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/globals.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/coeffs.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/__init__.py -> .//lib/python3.7/site-packages/gradunwarp/core
byte-compiling .//lib/python3.7/site-packages/gradunwarp/__init__.py to __init__.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/tests/test_utils.py to test_utils.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/gradient_unwarp.py to gradient_unwarp.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/unwarp_resample.py to unwarp_resample.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/utils.py to utils.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/globals.py to globals.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/coeffs.py to coeffs.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/__init__.py to __init__.cpython-37.pyc
running install_scripts
creating bin
copying build/scripts.linux-x86_64-3.7/gradient_unwarp.py -> .//bin
changing mode of .//bin/gradient_unwarp.py to 755
running install_data
copying gradunwarp/core/interp3_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
copying gradunwarp/core/transform_coordinates_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
copying gradunwarp/core/legendre_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
running install_egg_info
Writing .//lib/python3.7/site-packages/gradunwarp-HCP_1.2.0-py3.7.egg-info
running install_clib
customize UnixCCompiler
[drulex@gentoo-p53 gradunwarp] [master] $  PYTHONPATH+=./ ./bin/gradient_unwarp.py -h
usage:
gradient_unwarp infile outfile manufacturer -g <coefficient file> [optional arguments]

positional arguments:
  infile                The input warped file (nifti or mgh)
  outfile               The output unwarped file (extension should be
                        .nii/.nii.gz/.mgh/.mgz)
  {siemens,ge}          vendor (either "ge" or "siemens" for now)

optional arguments:
  -h, --help            show this help message and exit
  --version, -v         show program's version number and exit
  -g GRADFILE, --gradfile GRADFILE
                        The .grad coefficient file
  -c COEFFILE, --coeffile COEFFILE
                        The .coef coefficient file
  -w, --warp            warp a volume (as opposed to unwarping)
  -n, --nojacobian      Do not perform Jacobian intensity correction
  --fovmin FOVMIN       the minimum extent of harmonics evaluation grid in
                        meters
  --fovmax FOVMAX       the maximum extent of harmonics evaluation grid in
                        meters
  --numpoints NUMPOINTS
                        number of grid points in each direction
  --interp_order ORDER  the order of interpolation(1..4) where 1 is linear -
                        default
  --verbose
[drulex@gentoo-p53 gradunwarp] [master] $

Of course you would need to update PYTHONPATH and add the local dir to PATH

For example installing to local directory:
[drulex@gentoo-p53 tmp]  $  git clone git@github.com:Washington-University/gradunwarp.git
Cloning into 'gradunwarp'...
remote: Enumerating objects: 378, done.
remote: Total 378 (delta 0), reused 0 (delta 0), pack-reused 378
Receiving objects: 100% (378/378), 76.08 KiB | 1.77 MiB/s, done.
Resolving deltas: 100% (206/206), done.
[drulex@gentoo-p53 tmp]  $  cd gradunwarp/
[drulex@gentoo-p53 gradunwarp] [master] $  python setup.py install --prefix ./
running install
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building py_modules sources
building extension "gradunwarp.core.interp3_ext" sources
building extension "gradunwarp.core.legendre_ext" sources
building extension "gradunwarp.core.transform_coordinates_ext" sources
building data_files sources
build_src: building npy-pkg config files
running build_py
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
creating build
creating build/lib.linux-x86_64-3.7
creating build/lib.linux-x86_64-3.7/gradunwarp
creating build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/__init__.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/coeffs.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/globals.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/__init__.py -> build/lib.linux-x86_64-3.7/gradunwarp
copying gradunwarp/core/utils.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/unwarp_resample.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
copying gradunwarp/core/gradient_unwarp.py -> build/lib.linux-x86_64-3.7/gradunwarp/core
creating build/lib.linux-x86_64-3.7/gradunwarp/core/tests
copying gradunwarp/core/tests/test_utils.py -> build/lib.linux-x86_64-3.7/gradunwarp/core/tests
package init file 'gradunwarp/core/tests/__init__.py' not found (or not a regular file)
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
building 'gradunwarp.core.interp3_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

creating build/temp.linux-x86_64-3.7/gradunwarp
creating build/temp.linux-x86_64-3.7/gradunwarp/core
compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/interp3_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/interp3_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/interp3_ext.c: In function ‘interp3’:
gradunwarp/core/interp3_ext.c:97:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   97 |     itr_v = (PyArrayIterObject *) PyArray_IterNew(result);
      |                                                   ^~~~~~
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:97:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:98:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   98 |     itr_r = (PyArrayIterObject *) PyArray_IterNew(R);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:98:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:99:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   99 |     itr_c = (PyArrayIterObject *) PyArray_IterNew(C);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:99:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:100:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  100 |     itr_s = (PyArrayIterObject *) PyArray_IterNew(S);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/interp3_ext.c:100:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/interp3_ext.c:123:9: warning: returning ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} from a function with incompatible return type ‘PyObject *’ {aka ‘struct _object *’} [-Wincompatible-pointer-types]
  123 |  return result;
      |         ^~~~~~
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/interp3_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/interp3_ext.cpython-37m-x86_64-linux-gnu.so
building 'gradunwarp.core.legendre_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/legendre_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/legendre_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/legendre_ext.c: In function ‘legendre’:
gradunwarp/core/legendre_ext.c:86:25: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
   86 |         printf("but mu=%d and nu=%d\n", mu, nu);
      |                        ~^               ~~
      |                         |               |
      |                         int             long int
      |                        %ld
gradunwarp/core/legendre_ext.c:86:35: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
   86 |         printf("but mu=%d and nu=%d\n", mu, nu);
      |                                  ~^         ~~
      |                                   |         |
      |                                   int       long int
      |                                  %ld
gradunwarp/core/legendre_ext.c:99:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
   99 |     itr_x = (PyArrayIterObject *) PyArray_IterNew(x);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/legendre_ext.c:99:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/legendre_ext.c:100:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  100 |     itr_r = (PyArrayIterObject *) PyArray_IterNew(result);
      |                                                   ^~~~~~
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/legendre_ext.c:100:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/legendre_ext.c:108:32: warning: format ‘%f’ expects argument of type ‘doubl ’, but argument 2 has type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} [-Wformat=]
  108 |             printf("but got x=%f\n", x);
      |                               ~^     ~
      |                                |     |
      |                                |     PyArrayObject * {aka struct tagPyArrayObject_fields *}
      |                                double
gradunwarp/core/legendre_ext.c:157:12: warning: returning ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’} from a function with incompatible return type ‘PyObject *’ {aka ‘struct _object *’} [-Wincompatible-pointer-types]
  157 |     return result;
      |            ^~~~~~
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/legendre_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/legendre_ext.cpython-37m-x86_64-linux-gnu.so
building 'gradunwarp.core.transform_coordinates_ext' extension
compiling C sources
C compiler: x86_64-pc-linux-gnu-gcc -pthread -fPIC

compile options: '-I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/lib/python3.7/site-packages/numpy/core/include -I/usr/include/python3.7m -c'
extra options: '-O3'
x86_64-pc-linux-gnu-gcc: gradunwarp/core/transform_coordinates_ext.c
In file included from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /usr/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                 from gradunwarp/core/transform_coordinates_ext.c:10:
/usr/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
gradunwarp/core/transform_coordinates_ext.c: In function ‘transform_coordinates’:
gradunwarp/core/transform_coordinates_ext.c:102:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  102 |     itr_x = (PyArrayIterObject *) PyArray_IterNew(X);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:102:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:103:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  103 |     itr_y = (PyArrayIterObject *) PyArray_IterNew(Y);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:103:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:104:51: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  104 |     itr_z = (PyArrayIterObject *) PyArray_IterNew(Z);
      |                                                   ^
      |                                                   |
      |                                                   PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:104:51: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:105:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  105 |     itr_xm = (PyArrayIterObject *) PyArray_IterNew(Xm);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:105:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:106:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  106 |     itr_ym = (PyArrayIterObject *) PyArray_IterNew(Ym);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:106:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
gradunwarp/core/transform_coordinates_ext.c:107:52: warning: passing argument 1 of ‘(PyObject * (*)(PyObject *))*(PyArray_API + 784)’ from incompatible pointer type [-Wincompatible-pointer-types]
  107 |     itr_zm = (PyArrayIterObject *) PyArray_IterNew(Zm);
      |                                                    ^~
      |                                                    |
      |                                                    PyArrayObject * {aka struct tagPyArrayObject_fields *}
gradunwarp/core/transform_coordinates_ext.c:107:52: note: expected ‘PyObject *’ {aka ‘struct _object *’} but argument is of type ‘PyArrayObject *’ {aka ‘struct tagPyArrayObject_fields *’}
x86_64-pc-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,--as-needed -L. build/temp.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.o -L/usr/lib64 -lpython3.7m -o build/lib.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.cpython-37m-x86_64-linux-gnu.so
running build_scripts
creating build/scripts.linux-x86_64-3.7
copying and adjusting gradunwarp/core/gradient_unwarp.py -> build/scripts.linux-x86_64-3.7
changing mode of build/scripts.linux-x86_64-3.7/gradient_unwarp.py from 644 to 755
running install_lib
creating lib
creating lib/python3.7
creating lib/python3.7/site-packages
creating lib/python3.7/site-packages/gradunwarp
copying build/lib.linux-x86_64-3.7/gradunwarp/__init__.py -> .//lib/python3.7/site-packages/gradunwarp
creating lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/transform_coordinates_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/legendre_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/interp3_ext.cpython-37m-x86_64-linux-gnu.so -> .//lib/python3.7/site-packages/gradunwarp/core
creating lib/python3.7/site-packages/gradunwarp/core/tests
copying build/lib.linux-x86_64-3.7/gradunwarp/core/tests/test_utils.py -> .//lib/python3.7/site-packages/gradunwarp/core/tests
copying build/lib.linux-x86_64-3.7/gradunwarp/core/gradient_unwarp.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/unwarp_resample.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/utils.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/globals.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/coeffs.py -> .//lib/python3.7/site-packages/gradunwarp/core
copying build/lib.linux-x86_64-3.7/gradunwarp/core/__init__.py -> .//lib/python3.7/site-packages/gradunwarp/core
byte-compiling .//lib/python3.7/site-packages/gradunwarp/__init__.py to __init__.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/tests/test_utils.py to test_utils.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/gradient_unwarp.py to gradient_unwarp.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/unwarp_resample.py to unwarp_resample.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/utils.py to utils.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/globals.py to globals.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/coeffs.py to coeffs.cpython-37.pyc
byte-compiling .//lib/python3.7/site-packages/gradunwarp/core/__init__.py to __init__.cpython-37.pyc
running install_scripts
creating bin
copying build/scripts.linux-x86_64-3.7/gradient_unwarp.py -> .//bin
changing mode of .//bin/gradient_unwarp.py to 755
running install_data
copying gradunwarp/core/interp3_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
copying gradunwarp/core/transform_coordinates_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
copying gradunwarp/core/legendre_ext.c -> .//lib/python3.7/site-packages/gradunwarp/core/
running install_egg_info
Writing .//lib/python3.7/site-packages/gradunwarp-HCP_1.2.0-py3.7.egg-info
running install_clib
customize UnixCCompiler
[drulex@gentoo-p53 gradunwarp] [master] $  PYTHONPATH+=./ ./bin/gradient_unwarp.py -h
usage:
gradient_unwarp infile outfile manufacturer -g <coefficient file> [optional arguments]

positional arguments:
  infile                The input warped file (nifti or mgh)
  outfile               The output unwarped file (extension should be
                        .nii/.nii.gz/.mgh/.mgz)
  {siemens,ge}          vendor (either "ge" or "siemens" for now)

optional arguments:
  -h, --help            show this help message and exit
  --version, -v         show program's version number and exit
  -g GRADFILE, --gradfile GRADFILE
                        The .grad coefficient file
  -c COEFFILE, --coeffile COEFFILE
                        The .coef coefficient file
  -w, --warp            warp a volume (as opposed to unwarping)
  -n, --nojacobian      Do not perform Jacobian intensity correction
  --fovmin FOVMIN       the minimum extent of harmonics evaluation grid in
                        meters
  --fovmax FOVMAX       the maximum extent of harmonics evaluation grid in
                        meters
  --numpoints NUMPOINTS
                        number of grid points in each direction
  --interp_order ORDER  the order of interpolation(1..4) where 1 is linear -
                        default
  --verbose
[drulex@gentoo-p53 gradunwarp] [master] $

Of course you would need to update PYTHONPATH and add the local dir to PATH

Sorry. I think I've distracted from the core problem here. While the system-wide gradunwarp installation is concerning, I don't think where gradunwarp is installed relates to the missing numpy dependency.

Chances are numpy is missing because it's has been installed in the system location instead of the user location (depends on the OS I guess), but using the non-root install would put it in the same place as any user pip installed package.

Sorry. I think I've distracted from the core problem here. While the system-wide gradunwarp installation is concerning, I don't think where gradunwarp is installed relates to the missing numpy dependency.

Chances are numpy is missing because it's has been installed in the system location instead of the user location (depends on the OS I guess), but using the non-root install would put it in the same place as any user pip installed package.

Ah... right. If gradunwarp was installed via sudo, then it won't look in @sandrinebedard's user site-packages, it will try and look in /root/.
joshua@XPS-15-9560:~/Downloads/gradunwarp-1.2.0$ sudo python3 -m site
sys.path = [
    '/home/joshua/Downloads/gradunwarp-1.2.0',
    '/usr/lib/python38.zip',
    '/usr/lib/python3.8',
    '/usr/lib/python3.8/lib-dynload',
    '/usr/local/lib/python3.8/dist-packages',
    '/usr/lib/python3/dist-packages',
]
USER_BASE: '/root/.local' (exists)
USER_SITE: '/root/.local/lib/python3.8/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

Good point.

Ah... right. If gradunwarp was installed via sudo, then it won't look in @sandrinebedard's user site-packages, it will try and look in /root/.
joshua@XPS-15-9560:~/Downloads/gradunwarp-1.2.0$ sudo python3 -m site
sys.path = [
    '/home/joshua/Downloads/gradunwarp-1.2.0',
    '/usr/lib/python38.zip',
    '/usr/lib/python3.8',
    '/usr/lib/python3.8/lib-dynload',
    '/usr/local/lib/python3.8/dist-packages',
    '/usr/lib/python3/dist-packages',
]
USER_BASE: '/root/.local' (exists)
USER_SITE: '/root/.local/lib/python3.8/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

Good point.

@sandrinebedard Could you please try re-installing gradunwarp using a local installation?

 Tangential rant about gradunwarp's installation choices
gradunwarp is really awkward to uninstall because it uses a distutils-based installation and not pip. Normally, we shouldn't have to go near sudo rm to uninstall a Python package.
In fact, it uses numpy.distuils for its own installation to handle its C extensions. This choice is confusing, because numpy.distutils is for internal numpy usage, meant to handle Fortran extensions. Other packages really shouldn't be relying on this, but... I digress.

First, uninstall the existing gradunwarp.
> sudo rm -rf /usr/local/lib/python3.7/dist-packages/gradunwarp*
> sudo rm -f /usr/local/bin/gradient_unwarp.py

Then, install gradunwarp to the .local/ directory. This is also conveniently the location where pip would normally install packages to.
> cd Downloads/gradunwarp-1.2.0/
> python3 setup.py install --prefix ~/.local

Finally, if you haven't already, add ~/.local/bin to your $PATH environement variable.
> echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.bashrc

If this works for you, I also think we should add a disclaimer to ukbiobank-spinalcord-csa's README to avoid the sudo install of gradunwarp and its dependencies.

@sandrinebedard Could you please try re-installing gradunwarp using a local installation?

 Tangential rant about gradunwarp's installation choices
gradunwarp is really awkward to uninstall because it uses a distutils-based installation and not pip. Normally, we shouldn't have to go near sudo rm to uninstall a Python package.
In fact, it uses numpy.distuils for its own installation to handle its C extensions. This choice is confusing, because numpy.distutils is for internal numpy usage, meant to handle Fortran extensions. Other packages really shouldn't be relying on this, but... I digress.

First, uninstall the existing gradunwarp.
> sudo rm -rf /usr/local/lib/python3.7/dist-packages/gradunwarp*
> sudo rm -f /usr/local/bin/gradient_unwarp.py

Then, install gradunwarp to the .local/ directory. This is also conveniently the location where pip would normally install packages to.
> cd Downloads/gradunwarp-1.2.0/
> python3 setup.py install --prefix ~/.local

Finally, if you haven't already, add ~/.local/bin to your $PATH environement variable.
> echo 'export PATH="$HOME/.local/bin/:$PATH"' >> ~/.bashrc

If this works for you, I also think we should add a disclaimer to ukbiobank-spinalcord-csa's README to avoid the sudo install of gradunwarp and its dependencies.

Could you please try re-installing gradunwarp using a local installation?

@joshuacwnewton  I am trying this right now, I'll get back to you!

Could you please try re-installing gradunwarp using a local installation?

@joshuacwnewton  I am trying this right now, I'll get back to you!

I tried re-installing gradunwarp using a local installation and with sct_run_batch, I get this:
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

And gradient_unwarp.py still works fine on the terminal.

I tried re-installing gradunwarp using a local installation and with sct_run_batch, I get this:
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

And gradient_unwarp.py still works fine on the terminal.

Aha! I've just realized issue. You were absolutely right -- it was due to a change between v5.0.1 and v5.1.0.
#3070 introduced a setting to prevent local site-packages/ installations from interfering from SCT. However, as a side effect, that change is interfering with gradunwarp because the environment variable setting is inherited by the call to gradunwarp.

Aha! I've just realized issue. You were absolutely right -- it was due to a change between v5.0.1 and v5.1.0.
#3070 introduced a setting to prevent local site-packages/ installations from interfering from SCT. However, as a side effect, that change is interfering with gradunwarp because the environment variable setting is inherited by the call to gradunwarp.

Actually, to verify that this is indeed the problem, could you please temporarily edit the shell script as follows?
# Gradient distortion correction
- gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n
+ PYTHONNOUSERSITE=false gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n
file_t1="${file_t1}_gradcorr"

If this change fixes the problem, then we can go ahead and think about a more long-term solution.

Actually, to verify that this is indeed the problem, could you please temporarily edit the shell script as follows?
# Gradient distortion correction
- gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n
+ PYTHONNOUSERSITE=false gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n
file_t1="${file_t1}_gradcorr"

If this change fixes the problem, then we can go ahead and think about a more long-term solution.

This is a weird problem to fix, because it's due to a clash between 2 Python-based packages that install themselves in non-standard ways:

spinalcordtoolbox brings its own conda + Python distributions.
gradunwarp uses distutils without setuptools.

Since neither are pip installable, neither are used with virtualenvs, which makes isolating dependencies harder (and reliant on hacky workarounds).

This is a weird problem to fix, because it's due to a clash between 2 Python-based packages that install themselves in non-standard ways:

spinalcordtoolbox brings its own conda + Python distributions.
gradunwarp uses distutils without setuptools.

Since neither are pip installable, neither are used with virtualenvs, which makes isolating dependencies harder (and reliant on hacky workarounds).

@joshuacwnewton I edited the shell script as you described, but the problem is still there :cry: :
+ PYTHONNOUSERSITE=False
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

@joshuacwnewton I edited the shell script as you described, but the problem is still there :cry: :
+ PYTHONNOUSERSITE=False
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

wow @joshuacwnewton thank you so much for finding this bug! you would be an amazing detective

wow @joshuacwnewton thank you so much for finding this bug! you would be an amazing detective

@joshuacwnewton I edited the shell script as you described, but the problem is still there :cry:
+ PYTHONNOUSERSITE=False
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

Hmmm... just to clarify, is PYTHONNOUSERSITE=False on a separate line? It should be on the same line:
PYTHONNOUSERSITE=False gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n

If they are on separate lines, the setting won't be available to child processes.
(The reason I suggest this syntax instead of export is to temporarily set the environment variable for just that one command.)

wow @joshuacwnewton thank you so much for finding this bug! you would be an amazing detective

Thank you! I might be incorrect, though...  :sweat_smile:

@joshuacwnewton I edited the shell script as you described, but the problem is still there :cry:
+ PYTHONNOUSERSITE=False
+ gradient_unwarp.py sub-1000032_T1w_raw_RPI_r.nii.gz sub-1000032_T1w_raw_RPI_r_gradcorr.nii.gz siemens -g /mnt/y/sebeda/coeff.grad/ICM/coeff.grad -n
Traceback (most recent call last):
  File "/home/sabeda/.local/bin/gradient_unwarp.py", line 11, in <module>
    from gradunwarp.core import (globals, coeffs, utils)
ModuleNotFoundError: No module named 'gradunwarp'

Hmmm... just to clarify, is PYTHONNOUSERSITE=False on a separate line? It should be on the same line:
PYTHONNOUSERSITE=False gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n

If they are on separate lines, the setting won't be available to child processes.
(The reason I suggest this syntax instead of export is to temporarily set the environment variable for just that one command.)

wow @joshuacwnewton thank you so much for finding this bug! you would be an amazing detective

Thank you! I might be incorrect, though...  :sweat_smile:

Hmmm... just to clarify, is PYTHONNOUSERSITE=False on a separate line?

No, it is on the same line in my shell script.

Hmmm... just to clarify, is PYTHONNOUSERSITE=False on a separate line?

No, it is on the same line in my shell script.

So sorry, I gave the wrong suggestion. Rather than set to False, it just needs to set to nothing. (PYTHONNOUSERSITE=)
PYTHONNOUSERSITE= gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n

So sorry, I gave the wrong suggestion. Rather than set to False, it just needs to set to nothing. (PYTHONNOUSERSITE=)
PYTHONNOUSERSITE= gradient_unwarp.py ${file_t1}.nii.gz ${file_t1}_gradcorr.nii.gz siemens -g ${PATH_GRADCORR_FILE}/coeff.grad -n

it just needs to set to nothing. (PYTHONNOUSERSITE=)

It works!!! 🎉

it just needs to set to nothing. (PYTHONNOUSERSITE=)

It works!!! 🎉

@sandrinebedard Do mind if I close this, then open an issue in ukbiobank-spinalcord-csa to talk about the gradunwarp installation?

@sandrinebedard Do mind if I close this, then open an issue in ukbiobank-spinalcord-csa to talk about the gradunwarp installation?

Would you mind if I closed this, then opened an issue in ukbiobank-spinalcord-csa to talk about the gradunwarp installation?

Sounds good!

Would you mind if I closed this, then opened an issue in ukbiobank-spinalcord-csa to talk about the gradunwarp installation?

Sounds good!

Closing now. :slightly_smiling_face:
Just to be clear, though: I think the PYTHONNOUSERSITE= fix should be viewed as a temporary solution. A more long-term solution would be to make sure gradunwarp's dependencies are installed somewhere different than the site-packages/ directory.
I've written a more in-depth explanation in points 4. and 5. of https://github.com/sct-pipeline/ukbiobank-spinalcord-csa/issues/31.

Closing now. :slightly_smiling_face:
Just to be clear, though: I think the PYTHONNOUSERSITE= fix should be viewed as a temporary solution. A more long-term solution would be to make sure gradunwarp's dependencies are installed somewhere different than the site-packages/ directory.
I've written a more in-depth explanation in points 4. and 5. of https://github.com/sct-pipeline/ukbiobank-spinalcord-csa/issues/31.

Reopening because @kousu has raised some good points in https://github.com/sct-pipeline/ukbiobank-spinalcord-csa/issues/31#issuecomment-771647698.

On our side, I think setting PYTHONUSERSITE=True and other global variables like it is not a good solution. Most apps, reasonably, assume that they are running on a standard-ish system. Breaking those assumptions makes SCT an incompatible thing like Matlab that people have to containerize to keep running. If we're going to force people to containerize we should at least provide the docker image ourselves.
For another hacky solution: We could try to isolate PYTHONUSERSITE to just SCT itself, maybe? Like, make sure every: subprocess.run([...], env={k: os.environ[k] for k in set(os.environ.keys()) - {'PYTHONUSERSITE'}}). That would be a hacky workaround but at least it wouldn't leak out beyond SCT anymore.

On our side, I think setting PYTHONUSERSITE=True and other global variables like it is not a good solution
We could try to isolate PYTHONUSERSITE to just SCT itself, maybe?

For what it's worth, I think the change we make to  PYTHONNOUSERSITE is generally well isolated: It's only set in the context of SCT scripts, because it gets set in the launcher. As soon as an SCT script exits, the environment variables return to normal.
https://github.com/neuropoly/spinalcordtoolbox/blob/255140ade8632524122e09ea53908bb56cf10ca3/spinalcordtoolbox/compat/launcher.py#L27-L28
The issue only occurs when  sct_run_batch is called via its CLI launcher, which calls a shell script, which then calls a Python-based program, which then requires access specifically the user site-packages/.
I think we still want to isolate SCT itself from user site packages (what's the point of even bundling SCT a conda environment if it offers no isolation? See https://github.com/neuropoly/spinalcordtoolbox/issues/3067), but we also want to exclude non-SCT commands specifically for sct_run_batch. Hm...

We could try to isolate PYTHONUSERSITE to just SCT itself, maybe?

For what it's worth, I think the change we make to  PYTHONNOUSERSITE is generally well isolated: It's only set in the context of SCT scripts, and I believe as soon as an SCT script exits, the environment variables return to normal.

Yes! Environment vars are well designed in that respect!

I think we still want to isolate SCT itself from user site packages, since this is patching over a conda issue specifically. (See https://github.com/neuropoly/spinalcordtoolbox/issues/3067 and https://github.com/conda-forge/python-feedstock/issues/171),

😩

What a gordian knot.


VS Code node server crashes on remote Linux due to VS Code remote SSH PHP development

Does this issue occur when all extensions are disabled?: Unclear, due to issue happening sporadically, every few days.

Version: 1.89.1 (user setup)
Commit: dc96b837cf6bb4af9cd736aa3af08cf8279f7685
Date: 2024-05-07T05:13:33.891Z
Electron: 28.2.8
ElectronBuildId: 27744544
Chromium: 120.0.6099.291
Node.js: 18.18.2
V8: 12.0.267.19-electron.0
OS: Windows_NT x64 10.0.19045
Steps to Reproduce:

Have remote SSH extensions as well as PHP development extensions installed. Like PHP Debug (by xdebug), PHP Intelephense, Remote Development, Remote SSH.
Have VSC open with a decently large remote PHP project and leave it open for a few days.
Sometimes every day, sometimes every several days observe a node crash with a large 4.5GB core file on the remote Linux system. I tried installing as many debug symbols as I could to produce a gdb bt and got this:

gdb /home/archon810/.vscode-server/cli/servers/Stable-b58957e67ee1e712cebf466b995adf4c5307b2bd/server/node core.node.10*
GNU gdb (GDB; devel:gcc) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/archon810/.vscode-server/cli/servers/Stable-b58957e67ee1e712cebf466b995adf4c5307b2bd/server/node...

warning: Can't open file /var/run/nscd/db0KeEPE (deleted) during file-backed mapping note processing
[New LWP 10578]
[New LWP 10580]
[New LWP 10582]
[New LWP 10579]
[New LWP 10586]
[New LWP 10585]
[New LWP 10591]
[New LWP 10592]
[New LWP 10587]
[New LWP 10593]
[New LWP 10581]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `/home/archon810/.vscode-server/cli/servers/Stable-b58957e67ee1e712cebf466b995ad'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007fdb0bb07d2b in raise () from /lib64/libc.so.6
[Current thread is 1 (Thread 0x7fdb0c0ba7c0 (LWP 10578))]
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-150300.63.1.x86_64
(gdb) bt
#0  0x00007fdb0bb07d2b in raise () from /lib64/libc.so.6
#1  0x00007fdb0bb093e5 in abort () from /lib64/libc.so.6
#2  0x0000000000b85bd1 in node::Abort() ()
#3  0x0000000000a94834 in node::OOMErrorHandler(char const*, bool) ()
#4  0x0000000000d66d10 in v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) ()
#5  0x0000000000d670b7 in v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) ()
#6  0x0000000000f447c5 in v8::internal::Heap::FatalProcessOutOfMemory(char const*) ()
#7  0x0000000000f456c8 in v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) ()
#8  0x0000000000f55bd3 in v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*, v8::GCCallbackFlags) [clone .constprop.1331] ()
#9  0x0000000000f56a48 in v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) ()
#10 0x0000000000f59c15 in v8::internal::Heap::HandleGCRequest() ()
#11 0x0000000000ed7d6f in v8::internal::StackGuard::HandleInterrupts() ()
#12 0x00000000012b4fc3 in v8::internal::NativeRegExpMacroAssembler::CheckStackGuardState(v8::internal::Isolate*, int, v8::internal::RegExp::CallOrigin, unsigned long*, v8::internal::Code, unsigned long*, unsigned char const**, unsigned char const**) ()
#13 0x00000000015dfc7c in v8::internal::RegExpMacroAssemblerX64::CheckStackGuardState(unsigned long*, unsigned long, unsigned long) ()
#14 0x0000000007331c44 in ?? ()
#15 0x00007fff034a29e0 in ?? ()
#16 0x0000000000f3f012 in v8::internal::Heap::MonotonicallyIncreasingTimeInMs() const ()
#17 0x00000000012b51d2 in v8::internal::NativeRegExpMacroAssembler::Execute(v8::internal::String, int, unsigned char const*, unsigned char const*, int*, int, v8::internal::Isolate*, v8::internal::JSRegExp) ()
#18 0x00000000012b52e2 in v8::internal::NativeRegExpMacroAssembler::Match(v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>, int*, int, int, v8::internal::Isolate*) ()
#19 0x00000000012c6618 in v8::internal::RegExpImpl::IrregexpExecRaw(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>, int, int*, int) ()
#20 0x00000000012c6b3c in v8::internal::RegExpImpl::IrregexpExec(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSRegExp>, v8::internal::Handle<v8::internal::String>, int, v8::internal::Handle<v8::internal::RegExpMatchInfo>, v8::internal::RegExp::ExecQuirks) ()
#21 0x00000000012ebe9e in v8::internal::Runtime_RegExpExec(int, unsigned long*, v8::internal::Isolate*) ()
#22 0x0000000001705b39 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit ()
#23 0x0000000001768923 in Builtins_RegExpPrototypeTestFast ()
#24 0x00000000075d5309 in ?? ()
#25 0x00000b9d3d364909 in ?? ()
#26 0x0000000000000000 in ?? ()
(gdb) quit

Any ideas? Apologies if I'm filing in the wrong place or without enough information.

That seems likely. Thanks for checking that out, and filing an issue on intelephense. Looks like the process is running out of memory and unfortunately it is possible for extensions to crash the EH in that way.


Check Result String for Late Submissions (with/without exercise due date)

One last thing that I would like to clarify before approving. When I open exercise page for File Upload Exercise with late submission that received grade, I see

On my course page I see it a bit differently (it is greyed out):

So if I understand correctly we say not graded here and instead of showing the points received, we show only the percentage right? I also think the color should be gray on both places to stay consistent

Thanks for pointing that out! I adjusted the colors.

Good work @sascha11110 ! I see that you did a lot of changes and refactored the code even further. I tested the coloring on the test server and now indeed it becomes gray, but usually when you navigate to the same submission again. As shown below, on the course details page I see yellow result, I go into exercise details and now it is gray. When I navigate back to the course details it also becomes gray. And this happens also to text and modeling exercises and sometimes in different order (color in course details is correct and color in exercise details is wrong).
Also the submissions for the exercises that don't have due date are marked Late submission as well.

Originally posted by @maxr96 in https://github.com/ls1intum/Artemis/pull/657#issuecomment-538952237

I cannot reproduce this issue. @maxr96 can you share more steps on how to reproduce this?
I discussed with @krusche and we decided to merge #657 and fix this in a follow up.


Not possible to set min/max for timeseries axis

Expected behavior
I have 2 exactly the same charts showing same data with the only difference, that one chart is "time" and the other one is "timeseries". Both charts have min/max dates set on x axis to display full year. Both charts's axis should start with Jan and end with Dec.
Current behavior
"time" chart works as expected, but "timeseries" chart does not show full year on the x axis. It looks like the data between "min" and the first data point and between the last data point and "max" is removed as a part of timeseries functionality.
Reproducible sample
https://codepen.io/mp3500/pen/GRbqJwY
Optional extra steps/info to reproduce
No response
Possible solution
No response
Context
No response
chart.js version
v4.4.1
Browser name and version
Chrome 126.0.6478.128 64bit
Link to your project
No response

This was changed with v4.3.1, we also stumbled over that problem and had to fix versions, to be able to use zoom plugin with time series.
https://github.com/chartjs/Chart.js/pull/11388 -> https://github.com/chartjs/Chart.js/pull/11388/files#diff-f646705ee87e1da4be6cb4fca41e8322ba91e9db6f31ff76b2a868d9ff7f35e5R114
From my point of view, min and max should not be ignored or the behavior should be configurable.

I just encountered this bug too. I'd appreciate it if someone could look into this.

Now that I have looked into it again I have come to the conclusion, that the current behaviour is exactly, what the purpose of the time-series scale is in comparison to the time scale, to have the same distance between any data point independent of the time difference between the data points.

However, for the time series scale, each data point is spread equidistant.

So if you need a linear scale that does not depend on the data, you should use the time scale.
The issue should be closed.

My use-case is a bit different: I'm implementing panning with a timeseries on a candlestick chart. Overscrolling on the left should load new data from a server. But since overscrolling a timeseries is impossible, this feature is basically impossible to implement.
I think there should be a way to set min/max in a linear way on a timeseries. For example by index of a dataset.
So [5, 10] should show the datapoints at index 5 through 10. If that interval goes out of bounds, it should adjust accordingly (possible because points are spread equidistant). So [-5, 10] would show datapoints from 0 to 10, but with padding in the beginning that is 5 times the width of the distant between datapoints.

I was also using candlestick charts when reported this bug. I just wanted to make my report as simple as possible, so I used scatter charts and did not go into too many details.
Basically, my original problem was that I wanted to display candlestick chart with no weekends/holidays and with extra space (1 month or so) on the right. I was able to make that extra space using time chart and min/max properties, but then weekends/holidays were shown as blank points in the chart. If I used timeseries, weekend/holiday problem was gone, but now I was not able to make a space on a right hand side using min/max properties because of how timeseries works.
Havent received any feedback regarding my bug report, so I came up with a workaround myself. I simply added more fake data to the candlestick data, where open price was set to "undefined" and high, low and close was set to the latest real close price. In this way, those fake bars were not showing on a chart, but the chart space was still reserved for them and my chart got extended to the right by the number of fake bars the way I wanted.
I am not sure if min/max should work for timeseries or not, but I hope that my usage scenario might help to make decision.

I simply added more fake data to the candlestick data, where open price was set to "undefined" and high, low and close was set to the latest real close price.

I had the same idea but couldn't figure out how to hide those datapoints. Thank you for that workaround!


Test UI: Right-click context menu action executes against wrong item when multiple tests selected

Version: 1.60.0-insider (Universal)
Commit: 7c25c174726ab969db3f99058cdf24bcfae1cfbe
Date: 2021-08-11T05:13:17.497Z
Electron: 13.1.8
Chrome: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Darwin arm64 20.5.0
Steps to Reproduce:

Create extension that contributes a command to testing/item/context
Populate test UI with 3 tests and select all 3 tests (i.e. multi-select)
Right-click on the bottom item and run the contributed command

Expected Outcome:
Either:
(a) the command is executed for all test items, or
(b) the command is executed for the item where I right-clicked
Actual Outcome:
The command appears to be executed only once, for the first test that appears in the Test Explorer (not the test that I right-clicked).

I like the idea of being able to run a command for multiple selected items (i.e. behavior (a)). I also think it would be ideal if there was a context key that I could use to know that multiple items are selected so that I can show/hide commands based on whether command should run in "single" or "multiple" context.

All items will be given as positional arguments, so if you deal with multiple you can handle then via registerCommand('myCommand', (...items) => {})


Workaround for ISIS-1497: AbstractIsisSessionTemplate does not lookup adapter for OidDtos correctly.

can patch in BackgroundCommandExecution.

revert by #11


refactor(webSocket): rename back to webSocket ala 5.0

BREAKING CHANGE: UNBREAKING websocket to be named webSocket again, just like it was in 5.0. Now you should import from rxjs/webSocket

Got it, I didn't update the tsconfig files

Error: ENOENT: no such file or directory, lstat '/home/travis/build/ReactiveX/rxjs/src/websocket/package.json'

Build still seems failing, looks related with case sensitivity.

Coverage increased (+0.2%) to 96.708% when pulling 9da773b837b0f8a8afa82c7f97e7071bc71fd84d on benlesh:revert-webSocket-name into f4d7d0240475044dd384496127756739297a7087 on ReactiveX:master.


Monitor Event Mesh Page contains no content

Issue description
The page is empty.
Feedback Type (Optional)
content gaps
Page Title on SAP Help Portal (prefilled)
Monitor Event Mesh
Page URL on SAP Help Portal (prefilled)
https://help.sap.com/docs/integration-suite/sap-integration-suite/monitor-event-mesh

Hi @sebastianesch, thank you for your feedback! We’ll look into it and come back to you if we have any questions.


Model 3.0 Implementation

Model 3.0 Implementation

Description

Category:
implementation
JIRA issue: MIC-4285
Research reference:
https://vivarium-research.readthedocs.io/en/latest/models/other_models/hemoglobin_anemia_and_iron_deficiency/hemoglobin/index.html?highlight=hemoglobin

Changes and notes

Add hemoglobin component and pipeline to simulation
Simulants get random draws for which distribution to sample from (gamma vs. gumbel) and for their hemoglobin percentile. Those are then used as source for their hemoglobin concentration values. In turn, hemoglobin concentration is used to determine anemia status.
Since I copied a lot from IV Iron, i commented out things that i do not need currently for the exposures but anticipate needing soon (aka model 4).
Verification and Testing

Simulation runs and simulants get state table values for required hemoglobin propensities

converting back to draft, since there are some anemia-related functions I missed and need to integrate

A few differences from IV Iron:
Since we are handling maternal disorders and anemia YLDs separately, I needed to trim parts of the IV Iron MaternalDisability component. While I was at it, i fully separated Anemia-related methods into its own class distinct from Hemoglobin.


Fix lint errors

What this PR does / why we need it:

Fixes lint errors on CI like on https://github.com/openshift-knative/serving/pull/758

/assign @skonto

I guess since pint passes we are ok :)
/lgtm


Allow shell executor to inherit environment vars

This fixes issue 'PATH issue with Shell executor #1'
In the config.toml you are able to specify a bool to inherit all the environment vars of the running process. Defaults to false to conform to current behaviour.

Thanks. I think that more common approach is that you think that env are inherited. Maybe we could expose option to disable it and enable it by default?

I set default to false so it won't change the existing behaviour. I was really surprised it didn't inherit the environment vars by default. So it seems already three people are assuming it would inherit by default.
Changing the default behaviour to 'default inherit' with an opt-out config option would be my preference.
Let me know if you want me to update the pull request.

Yes. It's expected behaviour. If you can I would be happy to merge it :)

Thanks. With a few other changes I released it as 0.1.8.


Create a repository for the navbar microfrontend

@honohunter , the navbar is supposed to be part of the openemp-ui-dashboard along with the drawer, are you suggesting to have it separated from that repo?

@chinzou yes, as said in the official documentation of single-spa here:
https://single-spa.js.org/docs/recommended-setup#applications-versus-parcels-versus-utility-modules
also in their shown example here:
https://github.com/react-microfrontends


types/model: init with Name and Digest types

This is awesome and much needed - left a small comment on whether we could we get away without iter / rangefunc ?


Error in group /  Aggreation

Exercism Aggregate error:
CLASS zcl_itab_aggregation DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    TYPES group TYPE c LENGTH 1.
    TYPES: BEGIN OF initial_numbers_type,
             group  TYPE group,
             number TYPE i,
           END OF initial_numbers_type,
           initial_numbers TYPE STANDARD TABLE OF initial_numbers_type WITH EMPTY KEY.

    TYPES: BEGIN OF aggregated_data_type,
             group   TYPE group,
             count   TYPE i,
             sum     TYPE i,
             min     TYPE i,
             max     TYPE i,
             average TYPE f,
           END OF aggregated_data_type,
           aggregated_data TYPE STANDARD TABLE OF aggregated_data_type WITH EMPTY KEY.

    METHODS perform_aggregation
      IMPORTING
        initial_numbers        TYPE initial_numbers
      RETURNING
        VALUE(aggregated_data) TYPE aggregated_data.
  PROTECTED SECTION.
  PRIVATE SECTION.

ENDCLASS.

CLASS zcl_itab_aggregation IMPLEMENTATION.
  METHOD perform_aggregation.
    LOOP AT initial_numbers INTO DATA(g) GROUP BY g-group .
      DATA(group_count) = REDUCE #( INIT i = 0 FOR c IN GROUP g NEXT i += 1 ).
      DATA(group_sum)   = REDUCE #( INIT j = 0 FOR s IN GROUP g NEXT j += s-number ).
      INSERT VALUE #(
        group = g-group
        count = group_count
        sum = group_sum
        min = REDUCE #( INIT min_number = 9999
                        FOR m IN GROUP g
                        NEXT min_number = nmin( val1 = min_number val2 = m-number ) )
        max = REDUCE #( INIT max_number = 0
                        FOR n IN GROUP g
                        NEXT max_number = nmax(  val1 = max_number val2 = n-number ) )
        average = group_sum / group_count
        ) INTO TABLE aggregated_data.
    ENDLOOP.
  ENDMETHOD.

ENDCLASS.

Error from Exercism:
./zcl_itab_aggregation.clas.abap[56, 7]  - Statement does not exist in ABAPopen-abap(or a parser error), "DATA" (parser_error) [E] ./zcl_itab_aggregation.clas.abap[57, 7]  - Statement does not exist in ABAPopen-abap(or a parser error), "DATA" (parser_error) [E] ./zcl_itab_aggregation.clas.abap[61, 7]  - "group_count" not found, findTop (check_syntax) [E] ./zcl_itab_aggregation.clas.abap[62, 7]  - "group_sum" not found, findTop (check_syntax) [E] ./zcl_itab_aggregation.clas.abap[66, 12] - Variable "M" contains unknown: Type error, not a table type g-items (unknown_types) [E] ./zcl_itab_aggregation.clas.abap[67, 7]  - Component "items" not found in structure (check_syntax) [E] ./zcl_itab_aggregation.clas.abap[75, 12] - Variable "N" contains unknown: Type error, not a table type g-items (unknown_types) [E] ./zcl_itab_aggregation.clas.abap[76, 7]  - Component "items" not found in structure (check_syntax) [E] ./zcl_itab_aggregation.clas.abap[81, 7]  - "group_sum" not found, findTop (check_syntax) [E] abaplint: 9 issue(s) found

first fix = https://github.com/abaplint/abaplint/pull/2706


8.15.6 - General API Feedback while upgrading from NEST.

Elastic.Clients.Elasticsearch version: 8.15.6
Elasticsearch version: 8.15.1
.NET runtime version: 8.x
Operating system version: Any
Description of the problem including expected versus actual behavior:
While upgrading I've noticed a few things that really made the conversion harder than it had to be and I feel like the feedback below would have made things easier. I get that the purpose of the rewrite was to make maintenance easier, but on the other end is consumers/customers that have large investments in existing api's / elastic.

Defining new aggregations with a (dynamic agg name) using your object model is impossible now as you can't define agg names (only internal variant name and variant...) kinda makes the aggregation type useless for consumers.
Kept the existing interfaces, they were not hurting anything especially around code gen.
leverage interfaces more for very common fields like IProperty.Fields (tons of properties have fields, other common properties) having something like IHaveField or anything... This change with concrete types forces us to check tons of concrete types which makes maintaining it even harder as new types are added. No common interface for the tons of aggregation types seems like a miss?
There is 0 point to have such an internalized api (worst case make the setters internal / private). This has made things much harder than it should be especially around aggregations / sorting. The property names chosen for some like VariantName kinda adds to the confusion.
1 way implicit conversions for aggregations requires lots of boxing, type casting, and harder to go back the other way, especially with internalized. Also this method might make your serializer implementation slightly easier to generate, but harder to work with. It also means the aggregations don't actually represent what is supported (e.g., meta, sub aggs).
Leverage debugger displays / record types for better dx.
Using library types like FluentDictionary for SearchRequest Aggregations. I get there is a constructor that takes a dictionary but using custom types like this does make using the descriptors a bit harder for some use cases.8. I've logged other issues below which seem like bigger problem areas to solve.Expected behavior

Easier to use api's and less internalized things leading to a better experience.
Reference: https://github.com/FoundatioFx/Foundatio.Parsers/pull/84
Also apologies if the labels are incorrect for or this issue:

https://github.com/elastic/elasticsearch-net/issues/8334
https://github.com/elastic/elasticsearch-net/issues/8335
https://github.com/elastic/elasticsearch-net/issues/8336
https://github.com/elastic/elasticsearch-net/issues/8337
https://github.com/elastic/elasticsearch-net/issues/8338

Thank you.

Hi @niemyjski, thank you for the detailed feedback.
Quite a few of these design decisions were made before I took over the maintainer role for the .NET clients. It probably makes sense to discuss some of these points during the call together with Martijn.

If I understood correctly, you are mainly missing a way to implement custom aggregation variants (custom name, custom aggregation type) with the new client. Is that correct?
The new client was pretty much built from the ground, so I imagine it was not really about "keeping" something but rather about "reimplementing" it. Martijn and Steve had very very tight deadlines to get a the first version going which required them to keep the scope very small for the beginning. This was more than a year before I joined, which means I can only speculate here as well.
I can see how these kinds of interfaces might be useful for reflective code (especially in your parser project), but in the end, I still think the use-case is kinda nieche. I'm always open for improvements (having examples of a few more real world use-cases would surely help!), but at the same time, please remember that I'm currently the only person working on the .NET client (and related .NET projects which have high priority as well). This means that I have to prioritize very carefully.
Setters are usually public where they should be public and internal when they are not meant to be used. One main reason is to avoid breaking changes when code generation internals are changing. This gives us a bit more freedom in the long term. The fields VariantName and Variant are using internal terminology and are marked as internal for this exact reason. However, I agree that there are cases where it would be desirable to have (controlled) access to some of the currently internal fields. In case of aggregations, this probably relates to 1. where I could definitely see me adding a public API that allows to create custom aggregations.
Happy to do some brainstorming about simplifying the Aggregation type and to allow easier conversions etc. It's not that I don't see the benefits of the old structure. However, the new structuring does not only make serialization easier (and more performant!), but as well maps 1:1 to the actual ES REST API. This significantly reduces confusion for new users that just want to write their existing JSON queries using the .NET client.
What are your major pain points here? Do you have concrete types in mind for which you would love to have better debugger representations? This, again, is something that can't easily be auto-generated which means I probably won't implement this for the broad range of types. It will require manual effort to do the initial implementation and as well increases the maintainance burden in the long term. I'm definitely open to implement this feature for some types where it really makes debugging a lot easier.
What are you suggesting here? I could imagine adding an overload that directly accepts IDictionary<string, Action<AggregationDescriptor<T>> for example.

Yes, this is easy todo with the descriptor but not easy to do if you want to say build up your own aggregations from a string and then set those onto a descriptor once everything is resolved.
I get that, just don't get why they had to go, it makes migration that much harder for customers.
See 2
+1
This sounds like a plan, let me try to work around #8334 and maybe this will solve some of my issues.
If you use record types you get debugger displays and equality for free (and easier immutability). Just an observation I had looking through the code and will be way easier to debug agg based things once I am running.
That would be my suggestion, use or have overloads for BCL types to make the api a bit easier to use. This was the first one I came across.


make all objects reference global app variable instead of a reference (Trac #27)

Migrated from http://microfluidics.utoronto.ca/ticket/27
{
    "status": "closed",
    "changetime": "2014-04-17T19:39:01",
    "description": "",
    "reporter": "cfobel",
    "cc": "",
    "resolution": "fixed",
    "_ts": "1397763541728826",
    "component": "microdrop",
    "summary": "make all objects reference global app variable instead of a reference",
    "priority": "major",
    "keywords": "",
    "version": "0.1",
    "time": "2012-01-04T03:27:08",
    "milestone": "Microdrop 1.0",
    "owner": "cfobel",
    "type": "enhancement"
}

Trac update at 20120104T07:14:51:

<EMAIL_ADDRESS>commented:

commit 84f730888b6fad85d9f1dca8fdf7b4e6beccdde4
Author: Christian Fobel<EMAIL_ADDRESS>Date:   Wed Jan 4 02:06:48 2012 -0500
[SUBMODULE] Update dmf_control_board,video_reco...

[SUBMODULE] Update dmf_control_board, video_recorder plugins.
Use app_context.get_app() to get App instance.  Fixes #31.

<EMAIL_ADDRESS>changed resolution from "" to "fixed"
<EMAIL_ADDRESS>changed status from "new" to "closed"

Trac update at 20140417T19:39:01: ryan changed component from "core" to "microdrop"


chore(doc-52)-fixing-some-English-in-py-API

Rephrasing some items in English. No breaking changes. From my perspective, no tests required.

working on fixing the conflicts


Fix typo

Before submitting a pull request, please make sure the following is done:

Fork the repository and create your branch from master.

Run the build.py and test.py scripts.

If you are fixing something, add tests that fail in the current version and pass in yours.

If you're developing a new feature open an issue first to discuss it. Some features may be useful to you but harmful to others be it because of performance, new dependencies or different perspectives.

One more time: Don't forget to add tests.

Ensure the entire test suite is passing and overral performance is not degraded.

Thanks :)

Thank you for this awesome project.
I am reading the documentation, I will submit PRs once I find more, actually, I just push another one.
I am not sure if I have enough time to go through them all tonight, otherwise I would try to make one PR instead.


Calender month grid view

I want to a year of all month in grid view 4 column and 3 row like
Jan   Feb   Mar   Apr
May  Jun Jul Aug
Sep Oct Nov Dec

See #164


add an API server endpoint

This now provides a Go app that contains an API server and a Console. Both are on the same hostname/port - go to http://host:port/console/ to get the UI, and go to http://host:port/api to get the API server

This smells like progress. merging...

can you please specify what port? also, it says this is the api server - does this PR add any API or just the ability to add REST api? it is a very big PR and it was not clear from the description

@abonas the port default is 20000 but is configurable in the yaml or overridden via the envvar SERVER_PORT - see https://github.com/swift-sunshine/swscore/blob/master/config/config.go#L50
When deployed in OpenShift, you can specify it like this:
    server:
      port: 20001

as you see in the example configmap here:
https://github.com/swift-sunshine/swscore/blob/master/deploy/openshift/sws-configmap.yaml#L10-L12
It adds the ability to add any HTTP API (REST or otherwise). It adds a dummy endpoint at the root "/api" context - you will see a hello-world type message if you deploy this and go to that URL.
Also, the PR looks big, but a lot of it is committing the third party gorilla lib into vendor/. Ignore the vendor/ files.


Crashes on the connection to XDJ-RX

Hi,
I really like your idea of displaying track information overlay on OBS.
But when I tried with my XDJ-RX it crashes on connecting. The XDJ-RX unit freezes, and power cycle is needed.
I wonder if there is anything I can do to help exploring the issue?

Hi. Unfortunately this does not work with the XDJ-RX.
See https://github.com/Deep-Symmetry/dysentery/issues/1#issuecomment-348392940


Enable visual tests

Connects to https://github.com/vaadin/components-team-tasks/issues/314

This change is

We need to modify default test to include at least disabled and checked statuses

Review status: 0 of 9 files reviewed at latest revision, all discussions resolved.

Comments from Reviewable

Review status: all files reviewed at latest revision, all discussions resolved.

Comments from Reviewable


Add python unit testing to Travis

A unit test was also added to test the image generation script.

@pvaneck what's with the fonts directory?

@stevemart Since the script being tested expects a directory of true type fonts for character image generation, I wanted to give it an actual one containing a .ttf font file.


Feature Request: Chat: Add DnD mode to pause all notifications for few hours (like Slack)

To use Keybase chat as a Slack replacement it's very important to be able to temporary mute all notifications to concentrate on work.

Generally the notifications system has to be overhauled:

systemwide defaults
pausing notifications for a few hours (like in Slack, WhatsApp, Signal, Telegram and any other sensible messaging apps)
setting periods when notifications are active and periods when notifications are silenced

Until then, people won't be convinced by the superiority of encryption to significanlty downgrade their user experience.