Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[ENH] New FreeSurfer's license mechanism #787

Merged
merged 14 commits into from
Nov 8, 2017

Conversation

oesteban
Copy link
Member

Enables the online provision of a local license file

@effigies
Copy link
Member

For fmriprep-docker, I would read the user's environment and automatically mount $FS_LICENSE if it exists.

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple comments, nothing major.

@@ -245,11 +246,21 @@ def main():
g_dev.add_argument('-p', '--patch-nipype', metavar='PATH',
type=os.path.abspath,
help='working nipype repository')
g_dev.add_argument('--fs-license', metavar='PATH', type=os.path.abspath,
default=os.getenv('FS_LICENSE', None),
help='folder containing FreeSurfer\'s license.txt file')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's a little bit neither here nor there, I think this is more of a "wrapper" option than a "dev" option.

.circle/tests.sh Outdated
@@ -39,14 +39,14 @@ case ${CIRCLE_NODE_INDEX} in
| tee $HOME/docs/builddocs.log
cat $HOME/docs/builddocs.log && if grep -q "ERROR" $HOME/docs/builddocs.log; then false; else true; fi
fmriprep-docker -i poldracklab/fmriprep:latest --help
fmriprep-docker -i poldracklab/fmriprep:latest --config $HOME/nipype.cfg -w $HOME/ds054/scratch $HOME/data/ds054 $HOME/ds054/out participant --no-freesurfer --debug --write-graph --force-syn
fmriprep-docker --fs-license /tmp/fslicense -i poldracklab/fmriprep:latest --config $HOME/nipype.cfg -w $HOME/ds054/scratch $HOME/data/ds054 $HOME/ds054/out participant --no-freesurfer --debug --write-graph --force-syn
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a --no-freesurfer run, so it's not really testing anything except that fmriprep-docker doesn't fail when it receives the flag.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'm aware.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call it --fs-license-file?

.circle/tests.sh Outdated
# Place mock crash log and rebuild report
UUID="$(date '+%Y%m%d-%H%M%S_')$(uuidgen)"
mkdir -p $HOME/ds054/out/fmriprep/sub-100185/log/$UUID/
cp fmriprep/data/tests/crash_files/*.txt $HOME/ds054/out/fmriprep/sub-100185/log/$UUID/
# Expect one error
set +e
fmriprep-docker -i poldracklab/fmriprep:latest --config $HOME/nipype.cfg -w $HOME/ds054/scratch $HOME/data/ds054 $HOME/ds054/out participant --no-freesurfer --debug --write-graph --force-syn --reports-only --run-uuid $UUID
fmriprep-docker --fs-license /tmp/fslicense -i poldracklab/fmriprep:latest --config $HOME/nipype.cfg -w $HOME/ds054/scratch $HOME/data/ds054 $HOME/ds054/out participant --no-freesurfer --debug --write-graph --force-syn --reports-only --run-uuid $UUID
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also --no-freesurfer.

@effigies
Copy link
Member

Sorry, thought I was done commenting, but it would be helpful to check for the license file at the beginning, ourselves, rather than just letting ReconAll crash.

In run.py, you can add the following check (or similar):

default_license = op.join(os.getenv('FREESURFER_HOME', ''), 'license.txt')
license_file = os.getenv('FS_LICENSE', default_license)
if opts.freesurfer and not os.path.exists(license_file):
    raise RuntimeError(...)

Copy link
Contributor

@chrisgorgo chrisgorgo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it confusing that --fs-license-file is a command line argument for fmriprep-docker but not for native fmriprep. I think it would be better to have it in both places.

poldracklab/fmriprep:latest \
/data /out/out \
participant \
--ignore fieldmaps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be call include --fs-license-file?


It is also possible to run ``fmriprep-docker`` with FreeSurfer processing: ::

$ fmriprep-docker --fs-license $HOME/.licenses/freesurfer /path/to/data/dir /path/to/output/dir participant
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--fs-license-file?

@@ -231,6 +232,9 @@ def main():
type=os.path.abspath,
help='Grid reference image for resampling BOLD files to volume template '
'space.')
g_wrap.add_argument('--fs-license-file', metavar='PATH', type=os.path.abspath,
default=os.getenv('FS_LICENSE', None),
help='folder containing FreeSurfer\'s license.txt file')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

help="Path to FreeSurfer license key file. To obtain it you need to register (for free) at https://surfer.nmr.mgh.harvard.edu/registration.html"

circle.yml Outdated
@@ -20,6 +21,7 @@ dependencies:
- mkdir -p $HOME/ds005/out && sudo setfacl -R -d -m group:ubuntu:rwx $HOME/ds005 && sudo setfacl -R -m group:ubuntu:rwx $HOME/ds005
- mkdir -p $HOME/ds054 && sudo setfacl -d -m group:ubuntu:rwx $HOME/ds054 && sudo setfacl -m group:ubuntu:rwx $HOME/ds054
- mkdir -p $HOME/docs && sudo setfacl -d -m group:ubuntu:rwx $HOME/docs && sudo setfacl -m group:ubuntu:rwx $HOME/docs
- mkdir -p /tmp/fslicense && printf "${FS_LICENSE_CONTENT}" > ${FS_LICENSE}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed - this would be a more robust way to populate the license for CI https://github.com/BIDS-Apps/freesurfer/pull/36/files#diff-29944324a3cbf9f4bd0162dfe3975d88R25

@oesteban oesteban added this to the 1.0.0 milestone Nov 2, 2017
@oesteban
Copy link
Member Author

oesteban commented Nov 6, 2017

Addressing all the latest comments from Chris.

I find it confusing that --fs-license-file is a command line argument for fmriprep-docker but not for native fmriprep. I think it would be better to have it in both places.

Since --fs-license-file is a host option in fmriprep-docker, I don't think we can easily extend it to a fmriprep command, that should take for granted the (correct) installation of FreeSurfer, as nipype would do. I would prefer to keep fmriprep command untouched.

@effigies
Copy link
Member

effigies commented Nov 6, 2017

I agree with @oesteban. It's a necessary feature for fmriprep-docker to be able to inject a license into the container, but fmriprep native does not bundle FreeSurfer. Alerting users to a missing license seems like a reasonable behavior at the native CLI level.

@oesteban
Copy link
Member Author

oesteban commented Nov 6, 2017

Tests are passing, this is RTM

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple [docs only] changes. And want to add a changelog entry?

I'd recommend holding off on merging this until ready to make a new release, though. This is going to cause every build to re-download FreeSurfer until another release is made with this PR included.

$ fmriprep-docker --fs-license-file $HOME/.licenses/freesurfer/license.txt \
/path/to/data/dir /path/to/output/dir participant
RUNNING: docker run --rm -it -v /path/to/data/dir:/data:ro \
-v /path/to_output/dir:/out poldracklab/fmriprep:1.0.0 \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command doesn't have a -v /home/user/.licenses/freesurfer/license.txt:/etc/licenses/freesurfer/license.txt line (or similar.

$ export FS_LICENSE=$HOME/.licenses/freesurfer/license.txt
$ fmriprep-docker /path/to/data/dir /path/to/output/dir participant
RUNNING: docker run --rm -it -v /path/to/data/dir:/data:ro \
-v /path/to_output/dir:/out poldracklab/fmriprep:1.0.0 \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again.

docs/usage.rst Outdated
@@ -29,7 +29,7 @@ Command-Line Arguments
:prog: fmriprep
:nodefault:
:nodefaultconst:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably unintentional space?

@effigies
Copy link
Member

effigies commented Nov 7, 2017

This looks good to me, though, again, I think merging should wait until just before the next release.

@chrisfilo do you still feel that the cli/run.py should have a --fs-license-file option? (See #787 (comment) and #787 (comment).)

@chrisgorgo
Copy link
Contributor

Yes - we need it for OpenNeuro integration that does not support passing files via environment variables.

@oesteban
Copy link
Member Author

oesteban commented Nov 7, 2017 via email

@chrisgorgo
Copy link
Contributor

This feature would have to be added to OpenNeuro specifically for this app. Passing files via command line argument is already supported (as in FreeSurfer BIDS App).

@effigies
Copy link
Member

effigies commented Nov 7, 2017

After talking with Chris, I think he's right we can't get around this. OpenNeuro mounts the file arbitrarily, and then passes that location with a command-line flag. Given we can't tell them where to mount it, cli/run.py needs to be able to handle the flag. I think the easiest thing is to just take the input and os.environ['FS_LICENSE'] = <path>, so that it's automatically passed to all subprocesses. (Rather than wiring it through to all FreeSurfer utilities.)

It doesn't necessarily require any changes to the Dockerfile or fmriprep-docker to handle this case, though it's possible some simplifications will be possible once the underlying executable handles it.

@effigies
Copy link
Member

effigies commented Nov 8, 2017

@chrisfilo Good to go?

@chrisgorgo chrisgorgo merged commit 68efe57 into nipreps:master Nov 8, 2017
@mfalkiewicz
Copy link

Hi guys,
I am having a problem passing the license file to the docker container. Specifically:

$ ls -l /usr/local/freesurfer/license.txt

-rw-r--r-- 1 marcel marcel 34 wrz 5 16:16 /usr/local/freesurfer/license.txt

When I try to run docker (with 1.0.0rc10) I get an error message:

docker run -ti --rm -v /home/marcel/experiments/SDT3/work:/work -v /home/marcel/experiments/SDT3/SDT3_BIDS:/data:ro -v /home/marcel/experiments/SDT3/derivatives/fmriprep:/out poldracklab/fmriprep:latest -w /work --use-aroma --fs-license-file /usr/local/freesurfer/license.txt --omp-nthreads 12 --mem_mb 24000 /data /out participant

Traceback (most recent call last):
File "/usr/local/miniconda/bin/fmriprep", line 11, in
load_entry_point('fmriprep==1.0.0rc10', 'console_scripts', 'fmriprep')()
File "/usr/local/miniconda/lib/python3.6/site-packages/fmriprep/cli/run.py", line 206, in main
raise RuntimeError('ERROR: when --no-freesurfer is not set, a valid '
RuntimeError: ERROR: when --no-freesurfer is not set, a valid license file is required for FreeSurfer to run.

I also tried to mount a local directory inside the container and provide the path to it as --fs-license-file, but it still does not work properly. Any ideas?

@effigies
Copy link
Member

Hi Marcel,

The simplest approach is to use fmriprep-docker (pip install --user --upgrade fmriprep-docker), which will mount the file correctly, automatically, using the following commandL

fmriprep-docker -w /home/marcel/experiments/SDT3/work --use-aroma --omp-nthreads 12 \
    --mem_mb 24000 /home/marcel/experiments/SDT3/SDT3_BIDS \
    /home/marcel/experiments/SDT3/derivatives/fmriprep participant

However, given your current setup, the easiest quick fix is to mount the license file directly into the FreeSurfer directory:

docker run -ti --rm -v /home/marcel/experiments/SDT3/work:/work \
    -v /home/marcel/experiments/SDT3/SDT3_BIDS:/data:ro \
    -v /home/marcel/experiments/SDT3/derivatives/fmriprep:/out \
    -v /usr/local/freesurfer/license.txt:/opt/freesurfer/license.txt:ro \
    poldracklab/fmriprep:latest -w /work --use-aroma --omp-nthreads 12 --mem_mb 24000 \
    /data /out participant

@mfalkiewicz
Copy link

Thank you very much @effigies, this works fine now!

@oesteban oesteban deleted the enh/NewFreeSurfer branch November 16, 2017 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants