-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathfsl.py
141 lines (122 loc) · 5.17 KB
/
fsl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""Class to add FSL installation to Dockerfile.
FSL wiki: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/
FSL license: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Licence
"""
# Author: Jakub Kaczmarzyk <[email protected]>
from __future__ import absolute_import, division, print_function
from distutils.version import LooseVersion
import logging
try:
from urllib.parse import urljoin # Python 3
except ImportError:
from urlparse import urljoin # Python 2
from neurodocker.utils import check_url, indent
logger = logging.getLogger(__name__)
class FSL(object):
"""Add Dockerfile instructions to install FSL.
Parameters
----------
version : str
Version of FSL.
pkg_manager : {'apt', 'yum'}
Linux package manager.
use_binaries : bool
If true, use binaries from FSL's website (default true).
use_installer : bool
If true, install FSL using FSL's Python installer. Only works on
CentOS/RHEL (default false).
check_urls : bool
If true, raise error if a URL used by this class responds with an error
code.
Notes
-----
Look into ReproNim/simple_workflow to learn how to install specific versions
of FSL on Debian (https://github.com/ReproNim/simple_workflow).
"""
def __init__(self, version, pkg_manager, use_binaries=True,
use_installer=False, check_urls=True):
self.version = LooseVersion(version)
self.pkg_manager = pkg_manager
self.use_binaries = use_binaries
self.use_installer = use_installer
self.check_urls = check_urls
self._check_args()
self.cmd = self._create_cmd()
def _check_args(self):
"""Raise `ValueError` if combinations of arguments are invalid."""
if not self.use_binaries + self.use_installer:
raise ValueError("Please specify installation method.")
if self.use_binaries and self.use_installer:
raise ValueError("More than one installation method specified.")
if self.use_installer and self.pkg_manager != 'yum':
raise ValueError("FSL's Python installer works only on "
"CentOS/RHEL-based systems.")
return True
def _create_cmd(self):
"""Return full Dockerfile instructions to install FSL."""
comment = ("#-----------------------------------------------"
"\n# Install FSL {}"
"\n# Please review FSL's license:"
"\n# https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Licence"
"\n#-----------------------------------------------"
"".format(self.version))
if self.use_binaries:
url = self._get_binaries_url()
cmd = self.install_binaries(url)
elif self.use_installer:
cmd = self.install_with_pyinstaller(self.check_urls)
return "\n".join((comment, cmd))
@staticmethod
def install_with_pyinstaller(check_urls=False):
"""Return Dockerfile instructions to install FSL using FSL's Python
installer. This will install the latest version and only works on
CentOS/RHEL.
"""
workdir_cmd = "WORKDIR /opt"
url = "https://fsl.fmrib.ox.ac.uk/fsldownloads/fslinstaller.py"
if check_urls:
check_url(url)
cmd = ("curl -sSL -o fslinstaller.py {url}"
"\n&& python fslinstaller.py --dest=/opt --quiet"
"\n&& . /opt/fsl/etc/fslconf/fsl.sh"
"\n&& rm -f fslinstaller.py"
"".format(url=url))
cmd = indent("RUN", cmd)
path_cmd = ("FSLDIR=/opt/fsl"
"\n&& PATH=/opt/fsl/bin:$PATH")
path_cmd = indent("ENV", path_cmd)
return "\n".join((workdir_cmd, cmd, path_cmd))
def _get_binaries_url(self):
"""Return URL to binaries for requested version."""
base = "https://fsl.fmrib.ox.ac.uk/fsldownloads/"
if self.version >= LooseVersion('5.0.9'):
url = urljoin(base, "fsl-{ver}-centos6_64.tar.gz")
else:
url = urljoin(base, "oldversions/fsl-{ver}-centos5_64.tar.gz")
url = url.format(ver=self.version)
if self.check_urls:
check_url(url)
return url
@staticmethod
def install_binaries(url):
"""Return Dockerfile instructions to install FSL using binaries hosted
on FSL's website.
"""
cmd = ('curl -sSL {url}'
'\n| tar zx -C /opt'
'\n&& FSLPYFILE=/opt/fsl/etc/fslconf/fslpython_install.sh'
'\n&& [ -f $FSLPYFILE ] && $FSLPYFILE -f /opt/fsl -q || true'
''.format(url=url))
cmd = indent("RUN", cmd)
env_cmd = ("FSLDIR=/opt/fsl"
"\nPATH=/opt/fsl/bin:$PATH"
"\nFSLLOCKDIR="
"\nFSLMACHINELIST="
"\nFSLMULTIFILEQUIT=TRUE"
"\nFSLOUTPUTTYPE=NIFTI_GZ"
"\nFSLTCLSH=/opt/fsl/bin/fsltclsh"
"\nFSLWISH=/opt/fsl/bin/fslwish"
"\nLD_LIBRARY_PATH=/opt/fsl/lib/lib:$LD_LIBRARY_PATH"
"\nPOSSUMDIR=/opt/fsl")
env_cmd = indent("ENV", env_cmd)
return "\n".join((cmd, env_cmd))