Skip to content

Running on Linux is complex and needs better documentation #8

Description

@dgfitch

Howdy! Not sure if anyone else wants to run this on Linux, but here's the steps I took to get this running in a Rocky Linux-based apptainer container. Some of these look like deprecations or regressions in your code that assumes things about WIndows, but I'm not an expert.

For some reason, I couldn't get things to build straight from dockerhub, so I had to do it in two steps to get a functioning sandbox:

apptainer build pyfacewipe.sif docker://rockylinux/rockylinux:9.3
apptainer build --sandbox pyfacewipe pyfacewipe.sif

Then all the manual config (oh boy here we go)

apptainer shell -e --writable --fakeroot pyfacewipe

Inside the container, at the Apptainer> prompt:

yum install python3 python3-pip python3-devel git gcc wget
mkdir -p /data
cd /opt
git clone https://github.com/olinickalls/PyFaceWipe.git
cd PyFaceWipe/src
python3 -m pip install -r requirements.txt
python3 -m pip install cython
cd ..

Not sure this is exactly the right build tooling fix for the cython error if you just try to build_ext with the code that's on github, but...

vi setup.py

(or whatever editor you're comfortable with)

There's a build error where it can't drop the cython-compiled .so file to the right place, so add this line of parameters to the setup() call in setup.py:

package_dir={'pyfacewipe': 'src/pyfacewipe'},

and then:

cd /opt/PyFaceWipe
python3 setup.py build_ext --inplace

Now we have to download the machine learning weights that are on GitHub Resources:

cd /opt/PyFaceWipe/src/pyfacewipe/models
wget https://github.com/olinickalls/PyFaceWipe/releases/download/v0.1.1/synthstrip.1.pt
wget https://github.com/olinickalls/PyFaceWipe/releases/download/v0.1.1/synthstrip.nocsf.1.pt

Then, I hit some deprecation issues. I'm not sure what exactly is going on, maybe since your requirements.txt doesn't lock any versions, something weird is happening on Linux compared to Windows. But there's some numpy deprecations to fix:

vi /opt/PyFaceWipe/src/pyfacewipe/surfa/io/framed.py

Again, whatever editor, but change nii.get_data() to np.asanyarray(nii.dataobj) on line 795.

vi /opt/PyFaceWipe/src/pyfacewipe/synthstrip_class.py

Here change line 225 to explicitly specify dtype. I'm not sure if int64 is actually correct, I don't know the nibabel internals, but the output images seem good:

out_nb = nib.Nifti1Image(mask.astype(int), affine, dtype=np.dtype("int64"))

Then, since we're in a container and it would be good to be friendly, let's make a couple helper bits:

cd /opt/PyFaceWipe/src
vi run_with_args.py

Here the content is:

#!/usr/bin/env python3

from pyfacewipe import PyFaceWipe
import sys

pfw = PyFaceWipe()

source = sys.argv[1]
output_dir = sys.argv[2]
pfw.deface(source=source, output_dir=output_dir)

And then finally a bash script in /usr/local/bin to allow simple calls. Also, your code makes an assumption that an environment variable COMPUTERNAME is set, which I think is only true on Windows.

vi /usr/local/bin/pyfacewipe
#!/usr/bin/env bash

export COMPUTERNAME=unknown
cd /opt/PyFaceWipe/src

python3 run_with_args.py $*
chmod a+x /usr/local/bin/pyfacewipe

And now you can exit the apptainer and hopefully nothing else needs modification.

To use this in an apptainer exec, launch that bash script like this:

apptainer exec -e --fakeroot --bind /your/data/path:/data pyfacewipe pyfacewipe /data/input.nii.gz /data/pyfacewipe-output

Our imaging scientist is pretty impressed with your results, so thanks for publishing this!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions