Skip to content

Commit 03d6328

Browse files
authored
Merge pull request #695 from nipreps/bp/missing_ok
FIX: Add unlink() with missing_ok for Python 3.7
2 parents deb3df1 + 0b26e94 commit 03d6328

File tree

4 files changed

+109
-181
lines changed

4 files changed

+109
-181
lines changed

Dockerfile

Lines changed: 93 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# MIT License
44
#
5-
# Copyright (c) 2021 The NiPreps Developers
5+
# Copyright (c) 2022 The NiPreps Developers
66
#
77
# Permission is hereby granted, free of charge, to any person obtaining a copy
88
# of this software and associated documentation files (the "Software"), to deal
@@ -22,29 +22,10 @@
2222
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
# SOFTWARE.
2424

25-
# Use Ubuntu 20.04 LTS
26-
FROM ubuntu:focal-20210416
25+
FROM nipreps/miniconda:py38_1.4.2
2726

28-
# Prepare environment
29-
RUN apt-get update && \
30-
apt-get install -y --no-install-recommends \
31-
apt-utils \
32-
autoconf \
33-
build-essential \
34-
bzip2 \
35-
ca-certificates \
36-
curl \
37-
git \
38-
libtool \
39-
lsb-release \
40-
pkg-config \
41-
unzip \
42-
xvfb && \
43-
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
44-
45-
ENV DEBIAN_FRONTEND="noninteractive" \
46-
LANG="en_US.UTF-8" \
47-
LC_ALL="en_US.UTF-8"
27+
ARG DEBIAN_FRONTEND=noninteractive
28+
ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:${CONDA_PATH}/lib"
4829

4930
# Installing freesurfer
5031
RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.1/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.1.tar.gz | tar zxv --no-same-owner -C /opt \
@@ -69,7 +50,7 @@ RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.1/frees
6950
--exclude='freesurfer/trctrain'
7051

7152
# Simulate SetUpFreeSurfer.sh
72-
ENV FSL_DIR="/opt/fsl-5.0.11" \
53+
ENV FSL_DIR="/opt/fsl" \
7354
OS="Linux" \
7455
FS_OVERRIDE=0 \
7556
FIX_VERTEX_AREA="" \
@@ -86,86 +67,98 @@ ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
8667
MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
8768
PATH="$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"
8869

89-
# FSL 5.0.11 (neurodocker build)
90-
RUN apt-get update -qq \
91-
&& apt-get install -y -q --no-install-recommends \
92-
bc \
93-
dc \
94-
file \
95-
libfontconfig1 \
96-
libfreetype6 \
97-
libgl1-mesa-dev \
98-
libgl1-mesa-dri \
99-
libglu1-mesa-dev \
100-
libgomp1 \
101-
libice6 \
102-
libxcursor1 \
103-
libxft2 \
104-
libxinerama1 \
105-
libxrandr2 \
106-
libxrender1 \
107-
libxt6 \
108-
sudo \
109-
wget \
110-
&& apt-get clean \
111-
&& rm -rf /var/lib/apt/lists/* \
112-
&& echo "Downloading FSL ..." \
113-
&& mkdir -p /opt/fsl-5.0.11 \
114-
&& curl -fsSL --retry 5 https://fsl.fmrib.ox.ac.uk/fsldownloads/fsl-5.0.11-centos6_64.tar.gz \
115-
| tar -xz -C /opt/fsl-5.0.11 --strip-components 1 \
116-
--exclude "fsl/config" \
117-
--exclude "fsl/data/atlases" \
118-
--exclude "fsl/data/first" \
119-
--exclude "fsl/data/mist" \
120-
--exclude "fsl/data/possum" \
121-
--exclude "fsl/data/standard/bianca" \
122-
--exclude "fsl/data/standard/tissuepriors" \
123-
--exclude "fsl/doc" \
124-
--exclude "fsl/etc/default_flobs.flobs" \
125-
--exclude "fsl/etc/fslconf" \
126-
--exclude "fsl/etc/js" \
127-
--exclude "fsl/etc/luts" \
128-
--exclude "fsl/etc/matlab" \
129-
--exclude "fsl/extras" \
130-
--exclude "fsl/include" \
131-
--exclude "fsl/python" \
132-
--exclude "fsl/refdoc" \
133-
--exclude "fsl/src" \
134-
--exclude "fsl/tcl" \
135-
--exclude "fsl/bin/FSLeyes" \
136-
&& find /opt/fsl-5.0.11/bin -type f -not \( \
137-
-name "applywarp" -or \
138-
-name "bet" -or \
139-
-name "bet2" -or \
140-
-name "convert_xfm" -or \
141-
-name "fast" -or \
142-
-name "flirt" -or \
143-
-name "fsl_regfilt" -or \
144-
-name "fslhd" -or \
145-
-name "fslinfo" -or \
146-
-name "fslmaths" -or \
147-
-name "fslmerge" -or \
148-
-name "fslroi" -or \
149-
-name "fslsplit" -or \
150-
-name "fslstats" -or \
151-
-name "imtest" -or \
152-
-name "mcflirt" -or \
153-
-name "melodic" -or \
154-
-name "prelude" -or \
155-
-name "remove_ext" -or \
156-
-name "susan" -or \
157-
-name "topup" -or \
158-
-name "zeropad" \) -delete \
159-
&& find /opt/fsl-5.0.11/data/standard -type f -not -name "MNI152_T1_2mm_brain.nii.gz" -delete
160-
ENV FSLDIR="/opt/fsl-5.0.11" \
161-
PATH="/opt/fsl-5.0.11/bin:$PATH" \
70+
# Install AFNI latest (neurodocker build)
71+
ENV AFNI_DIR="/opt/afni"
72+
RUN echo "Downloading AFNI ..." \
73+
&& mkdir -p ${AFNI_DIR} \
74+
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
75+
| tar -xz -C ${AFNI_DIR} --strip-components 1 \
76+
# Keep only what we use
77+
&& find ${AFNI_DIR} -type f -not \( \
78+
-name "3dTshift" -or \
79+
-name "3dUnifize" -or \
80+
-name "3dAutomask" -or \
81+
-name "3dvolreg" \) -delete
82+
83+
ENV PATH="${AFNI_DIR}:$PATH" \
84+
AFNI_IMSAVE_WARNINGS="NO" \
85+
AFNI_MODELPATH="${AFNI_DIR}/models" \
86+
AFNI_TTATLAS_DATASET="${AFNI_DIR}/atlases" \
87+
AFNI_PLUGINPATH="${AFNI_DIR}/plugins"
88+
89+
# Install AFNI's dependencies
90+
RUN ${CONDA_PATH}/bin/conda install -c conda-forge -c anaconda \
91+
gsl \
92+
xorg-libxp \
93+
scipy=1.8 \
94+
&& ${CONDA_PATH}/bin/conda install -c sssdgc png \
95+
&& sync \
96+
&& ${CONDA_PATH}/bin/conda clean -afy; sync \
97+
&& rm -rf ~/.conda ~/.cache/pip/*; sync \
98+
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.19 \
99+
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.0 \
100+
&& ldconfig
101+
102+
RUN apt-get update \
103+
&& apt-get install -y -q --no-install-recommends \
104+
libcurl4-openssl-dev \
105+
libgdal-dev \
106+
libgfortran-8-dev \
107+
libgfortran4 \
108+
libglw1-mesa \
109+
libgomp1 \
110+
libjpeg62 \
111+
libnode-dev \
112+
libssl-dev \
113+
libudunits2-dev \
114+
libxm4 \
115+
libxml2-dev \
116+
netpbm \
117+
tcsh \
118+
xfonts-base \
119+
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
120+
&& ldconfig
121+
122+
# Installing ANTs 2.3.4 (NeuroDocker build)
123+
ENV ANTSPATH="/opt/ants"
124+
WORKDIR $ANTSPATH
125+
RUN curl -sSL "https://dl.dropbox.com/s/gwf51ykkk5bifyj/ants-Linux-centos6_x86_64-v2.3.4.tar.gz" \
126+
| tar -xzC $ANTSPATH --strip-components 1
127+
ENV PATH="$ANTSPATH:$PATH"
128+
129+
# FSL 5.0.11
130+
RUN curl -sSL https://fsl.fmrib.ox.ac.uk/fsldownloads/fsl-5.0.11-centos6_64.tar.gz | tar zxv --no-same-owner -C /opt \
131+
--exclude='fsl/doc' \
132+
--exclude='fsl/refdoc' \
133+
--exclude='fsl/python/oxford_asl' \
134+
--exclude='fsl/data/possum' \
135+
--exclude='fsl/data/first' \
136+
--exclude='fsl/data/mist' \
137+
--exclude='fsl/data/atlases' \
138+
--exclude='fsl/data/xtract_data' \
139+
--exclude='fsl/extras/doc' \
140+
--exclude='fsl/extras/man' \
141+
--exclude='fsl/extras/src' \
142+
--exclude='fsl/src' \
143+
--exclude='fsl/tcl'
144+
145+
ENV FSLDIR="/opt/fsl" \
146+
PATH="/opt/fsl/bin:$PATH" \
162147
FSLOUTPUTTYPE="NIFTI_GZ" \
163148
FSLMULTIFILEQUIT="TRUE" \
149+
FSLTCLSH="/opt/fsl/bin/fsltclsh" \
150+
FSLWISH="/opt/fsl/bin/fslwish" \
164151
FSLLOCKDIR="" \
165152
FSLMACHINELIST="" \
166153
FSLREMOTECALL="" \
167154
FSLGECUDAQ="cuda.q" \
168-
LD_LIBRARY_PATH="/opt/fsl-5.0.11/lib:$LD_LIBRARY_PATH"
155+
POSSUMDIR="/opt/fsl" \
156+
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/fsl"
157+
158+
# Unless otherwise specified each process should only use one thread - nipype
159+
# will handle parallelization
160+
ENV MKL_NUM_THREADS=1 \
161+
OMP_NUM_THREADS=1
169162

170163
# Convert3D (neurodocker build)
171164
RUN echo "Downloading Convert3D ..." \
@@ -178,88 +171,11 @@ RUN echo "Downloading Convert3D ..." \
178171
ENV C3DPATH="/opt/convert3d-1.0.0" \
179172
PATH="/opt/convert3d-1.0.0/bin:$PATH"
180173

181-
# AFNI latest (neurodocker build)
182-
RUN apt-get update -qq \
183-
&& apt-get install -y -q --no-install-recommends \
184-
apt-utils \
185-
ed \
186-
gsl-bin \
187-
libglib2.0-0 \
188-
libglu1-mesa-dev \
189-
libglw1-mesa \
190-
libgomp1 \
191-
libjpeg62 \
192-
libxm4 \
193-
netpbm \
194-
tcsh \
195-
xfonts-base \
196-
xvfb \
197-
&& apt-get clean \
198-
&& rm -rf /var/lib/apt/lists/* \
199-
&& curl -sSL --retry 5 -o /tmp/multiarch.deb http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/multiarch-support_2.27-3ubuntu1.2_amd64.deb \
200-
&& dpkg -i /tmp/multiarch.deb \
201-
&& rm /tmp/multiarch.deb \
202-
&& curl -sSL --retry 5 -o /tmp/libxp6.deb http://mirrors.kernel.org/debian/pool/main/libx/libxp/libxp6_1.0.2-2_amd64.deb \
203-
&& dpkg -i /tmp/libxp6.deb \
204-
&& rm /tmp/libxp6.deb \
205-
&& curl -sSL --retry 5 -o /tmp/libpng.deb http://snapshot.debian.org/archive/debian-security/20160113T213056Z/pool/updates/main/libp/libpng/libpng12-0_1.2.49-1%2Bdeb7u2_amd64.deb \
206-
&& dpkg -i /tmp/libpng.deb \
207-
&& rm /tmp/libpng.deb \
208-
&& apt-get install -f \
209-
&& apt-get clean \
210-
&& rm -rf /var/lib/apt/lists/* \
211-
&& gsl2_path="$(find / -name 'libgsl.so.19' || printf '')" \
212-
&& if [ -n "$gsl2_path" ]; then \
213-
ln -sfv "$gsl2_path" "$(dirname $gsl2_path)/libgsl.so.0"; \
214-
fi \
215-
&& ldconfig \
216-
&& echo "Downloading AFNI ..." \
217-
&& mkdir -p /opt/afni-latest \
218-
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
219-
| tar -xz -C /opt/afni-latest --strip-components 1 \
220-
--exclude "linux_openmp_64/*.gz" \
221-
--exclude "linux_openmp_64/funstuff" \
222-
--exclude "linux_openmp_64/shiny" \
223-
--exclude "linux_openmp_64/afnipy" \
224-
--exclude "linux_openmp_64/lib/RetroTS" \
225-
--exclude "linux_openmp_64/meica.libs" \
226-
# Keep only what we use
227-
&& find /opt/afni-latest -type f -not \( \
228-
-name "3dTshift" -or \
229-
-name "3dUnifize" -or \
230-
-name "3dAutomask" -or \
231-
-name "3dvolreg" \) -delete
232-
233-
ENV PATH="/opt/afni-latest:$PATH" \
234-
AFNI_IMSAVE_WARNINGS="NO" \
235-
AFNI_PLUGINPATH="/opt/afni-latest"
236-
237-
# Installing ANTs 2.3.3 (NeuroDocker build)
238-
# Note: the URL says 2.3.4 but it is actually 2.3.3
239-
ENV ANTSPATH="/opt/ants" \
240-
PATH="/opt/ants:$PATH"
241-
WORKDIR $ANTSPATH
242-
RUN curl -sSL "https://dl.dropbox.com/s/gwf51ykkk5bifyj/ants-Linux-centos6_x86_64-v2.3.4.tar.gz" \
243-
| tar -xzC $ANTSPATH --strip-components 1
244-
245-
COPY --from=nipreps/miniconda:py38_1.3.2 /opt/conda /opt/conda
246-
247-
RUN ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
248-
echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
249-
echo "conda activate base" >> ~/.bashrc
250-
251-
# Set CPATH for packages relying on compiled libs (e.g. indexed_gzip)
252-
ENV PATH="/opt/conda/bin:$PATH" \
253-
CPATH="/opt/conda/include:$CPATH" \
254-
LD_LIBRARY_PATH="/opt/conda/lib:$LD_LIBRARY_PATH" \
255-
LANG="C.UTF-8" \
256-
LC_ALL="C.UTF-8" \
257-
PYTHONNOUSERSITE=1
258-
259174
# Create a shared $HOME directory
260175
RUN useradd -m -s /bin/bash -G users niworkflows
261176
WORKDIR /home/niworkflows
262-
ENV HOME="/home/niworkflows"
177+
ENV HOME="/home/niworkflows" \
178+
LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
263179

264180
# Unless otherwise specified each process should only use one thread - nipype
265181
# will handle parallelization

niworkflows/interfaces/bids.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
from templateflow.api import templates as _get_template_list
5151
from ..utils.bids import _init_layout, relative_to_root
5252
from ..utils.images import set_consumables, unsafe_write_nifti_header_and_data
53-
from ..utils.misc import splitext as _splitext, _copy_any
53+
from ..utils.misc import splitext as _splitext, _copy_any, unlink
5454

5555
regz = re.compile(r"\.gz$")
5656
_pybids_spec = loads(Path(_pkgres("niworkflows", "data/nipreps.json")).read_text())
@@ -669,7 +669,7 @@ def _run_interface(self, runtime):
669669
new_header.set_data_dtype(data_dtype)
670670
del nii
671671

672-
out_file.unlink(missing_ok=True)
672+
unlink(out_file, missing_ok=True)
673673
if new_data is new_header is None:
674674
_copy_any(orig_file, str(out_file))
675675
else:
@@ -710,11 +710,11 @@ def _run_interface(self, runtime):
710710
legacy_metadata[key] = self._metadata.pop(key)
711711
if legacy_metadata:
712712
sidecar = out_file.parent / f"{_splitext(str(out_file))[0]}.json"
713-
sidecar.unlink(missing_ok=True)
713+
unlink(sidecar, missing_ok=True)
714714
sidecar.write_text(dumps(legacy_metadata, sort_keys=True, indent=2))
715715
# The future: the extension is the first . and everything after
716716
sidecar = out_file.parent / f"{out_file.name.split('.', 1)[0]}.json"
717-
sidecar.unlink(missing_ok=True)
717+
unlink(sidecar, missing_ok=True)
718718
sidecar.write_text(dumps(self._metadata, sort_keys=True, indent=2))
719719
self._results["out_meta"] = str(sidecar)
720720
return runtime

niworkflows/utils/misc.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# https://www.nipreps.org/community/licensing/
2222
#
2323
"""Miscellaneous utilities."""
24+
import os
2425

2526

2627
__all__ = [
@@ -333,5 +334,15 @@ def check_valid_fs_license():
333334
return proc.returncode == 0 and "ERROR:" not in proc.stdout.decode()
334335

335336

337+
def unlink(pathlike, missing_ok=False):
338+
"""Backport of Path.unlink from Python 3.8+ with missing_ok keyword"""
339+
# PY37 hack; drop when python_requires >= 3.8
340+
try:
341+
os.unlink(pathlike)
342+
except FileNotFoundError:
343+
if not missing_ok:
344+
raise
345+
346+
336347
if __name__ == "__main__":
337348
pass

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ python_requires = >= 3.7
2727
install_requires =
2828
attrs
2929
jinja2
30+
markupsafe ~= 2.0.1 # jinja2 imports deprecated function removed in 2.1
3031
matplotlib >= 3.4.2
3132
nibabel ~= 3.0
3233
nilearn >= 0.5.2

0 commit comments

Comments
 (0)