Skip to content

Commit

Permalink
Add docker, fix subprocess and update to bids 1.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaudbore committed Jun 17, 2024
1 parent aee3749 commit c833933
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 19 deletions.
57 changes: 57 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Conda image for installing FSL tools
FROM continuumio/miniconda3 AS build

# Install FSL tools with conda
COPY environment.yml /tmp/environment.yml
RUN conda env create -f /tmp/environment.yml

# Install and use conda-pack
RUN conda install -c conda-forge conda-pack
RUN conda-pack -n fsl -o /tmp/env.tar && \
mkdir /venv && cd /venv && tar xf /tmp/env.tar && \
rm /tmp/env.tar
RUN /venv/bin/conda-unpack

# Runtime image for executing FSL tools
FROM debian:stable AS runtime

# Copy the conda env from previous stage
COPY --from=build /venv /venv

# Point to conda executables
ENV PATH /venv/bin:$PATH

# Set FSL variables
ENV FSLDIR="/venv"
ENV FSLCONFDIR="${FSLDIR}/config"
ENV FSLOUTPUTTYPE="NIFTI"
ENV FSLMULTIFILEQUIT="TRUE"
ENV FSLTCLSH="${FSLDIR}/bin/fsltclsh"
ENV FSLWISH="${FSLDIR}/bin/fslwish"
ENV FSLGECUDAQ="cuda.q"

# Install dc fro FSL bet and wget for fetching data

Check failure on line 33 in Dockerfile

View workflow job for this annotation

GitHub Actions / Check for spelling errors

fro ==> for, from
RUN apt-get -y update && apt-get -y install dc wget npm unzip

# Fetch data
RUN wget -P ${FSLDIR}/data https://git.fmrib.ox.ac.uk/fsl/data_standard/-/raw/master/MNI152_T1_1mm_brain.nii.gz

# Install bids-validator
RUN npm install -g bids-validator

# Install dcm2niix
WORKDIR /
RUN wget https://github.com/rordenlab/dcm2niix/releases/download/v1.0.20240202/dcm2niix_lnx.zip
RUN unzip dcm2niix_lnx.zip
RUN mv dcm2niix /usr/bin/

# Install dcm2bids

WORKDIR /
ADD . /dcm2bids
WORKDIR /dcm2bids
RUN pip install -e .

RUN pip install pydeface

ENTRYPOINT [""]
8 changes: 4 additions & 4 deletions dcm2bids/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ def setExtraDstFile(self, new_entities):
"""
Return:
The destination filename formatted following
the v1.8.0 BIDS entity key table
https://bids-specification.readthedocs.io/en/v1.8.0/99-appendices/04-entity-table.html
the v1.9.0 BIDS entity key table
https://bids-specification.readthedocs.io/en/v1.9.0/99-appendices/04-entity-table.html
"""

if self.custom_entities.strip() == "":
Expand Down Expand Up @@ -210,8 +210,8 @@ def setDstFile(self):
"""
Return:
The destination filename formatted following
the v1.8.0 BIDS entity key table
https://bids-specification.readthedocs.io/en/v1.8.0/99-appendices/04-entity-table.html
the v1.9.0 BIDS entity key table
https://bids-specification.readthedocs.io/en/v1.9.0/99-appendices/04-entity-table.html
"""
current_name = self.participant.prefix + self.build_suffix
new_name = ''
Expand Down
12 changes: 7 additions & 5 deletions dcm2bids/dcm2bids_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,11 @@ def run(self):

if self.bids_validate:
try:
self.logger.info(f"Validate if {self.output_dir} is BIDS valid.")
self.logger.info("Use bids-validator version: ")
run_shell_command(['bids-validator', '-v'])
run_shell_command(['bids-validator', self.bids_dir])
self.logger.info(f"Validate if {self.bids_dir} is BIDS valid.")
bids_version = run_shell_command(['bids-validator', '-v'])
self.logger.info(f"Use bids-validator version: {bids_version.decode()}")
bids_report = run_shell_command(['bids-validator', self.bids_dir])
self.logger.info(bids_report.decode())
except Exception:
self.logger.error("The bids-validator does not seem to work properly. "
"The bids-validator may not be installed on your "
Expand Down Expand Up @@ -186,7 +187,8 @@ def move(self, acq, idList, post_op):
else:
cmd = cmd.replace('dst_file', str(dstFile))

run_shell_command(cmd.split())
std_out = run_shell_command(cmd.split())
self.logger.debug(std_out.decode())
continue

if ".json" in ext:
Expand Down
16 changes: 10 additions & 6 deletions dcm2bids/sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ def searchDcmTagEntity(self, sidecar, desc):
"""
descWithTask = desc.copy()
concatenated_matches = {}
keys_custom_entities = []
entities = []
if "custom_entities" in desc.keys() or self.auto_extract_entities:
if 'custom_entities' in desc.keys():
Expand All @@ -435,10 +436,12 @@ def searchDcmTagEntity(self, sidecar, desc):
else:
descWithTask["custom_entities"] = []

keys_custom_entities = [curr_entity.split('-')[0] for curr_entity in descWithTask["custom_entities"]]

if self.auto_extract_entities:
self.extractors = combine_dict_extractors(self.extractors, DEFAULT.auto_extractors)


# Loop to check if we find self.extractor
for dcmTag in self.extractors:
if dcmTag in sidecar.data.keys():
dcmInfo = sidecar.data.get(dcmTag)
Expand All @@ -447,29 +450,31 @@ def searchDcmTagEntity(self, sidecar, desc):
if not isinstance(dcmInfo, list):
if compile_regex.search(str(dcmInfo)) is not None:
concatenated_matches.update(
compile_regex.search(str(dcmInfo)).groupdict())
compile_regex.search(str(dcmInfo)).groupdict())
else:
for curr_dcmInfo in dcmInfo:
if compile_regex.search(curr_dcmInfo) is not None:
concatenated_matches.update(
compile_regex.search(curr_dcmInfo).groupdict())
compile_regex.search(curr_dcmInfo).groupdict())
break

# Keep entities asked in custom_entities
# If dir found in custom_entities and concatenated_matches.keys we keep it
if "custom_entities" in desc.keys():
entities = set(concatenated_matches.keys()).intersection(set(descWithTask["custom_entities"]))

# custom_entities not a key for extractor or auto_extract_entities
complete_entities = [ent for ent in descWithTask["custom_entities"] if '-' in ent]
entities = entities.union(set(complete_entities))

if self.auto_extract_entities:
auto_acq = '_'.join([descWithTask['datatype'], descWithTask["suffix"]])
if auto_acq in DEFAULT.auto_entities:
# Check if these auto entities have been found before merging
auto_entities = set(concatenated_matches.keys()).intersection(set(DEFAULT.auto_entities[auto_acq]))

left_auto_entities = auto_entities.symmetric_difference(set(DEFAULT.auto_entities[auto_acq]))
left_auto_entities = left_auto_entities.difference(keys_custom_entities)

if left_auto_entities:
self.logger.warning(f"{left_auto_entities} have not been found for datatype '{descWithTask['datatype']}' "
f"and suffix '{descWithTask['suffix']}'.")
Expand All @@ -478,7 +483,6 @@ def searchDcmTagEntity(self, sidecar, desc):
entities = list(set(entities))
descWithTask["custom_entities"] = entities


for curr_entity in entities:
if curr_entity in concatenated_matches.keys():
if curr_entity == 'dir':
Expand Down
9 changes: 6 additions & 3 deletions dcm2bids/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import logging
import os
from pathlib import Path
from subprocess import check_output
from subprocess import check_output, Popen, PIPE


class DEFAULT(object):
Expand Down Expand Up @@ -99,7 +99,7 @@ class DEFAULT(object):
helper_dir = "helper"

# BIDS version
bids_version = "v1.8.0"
bids_version = "v1.9.0"


def write_participants(filename, participants):
Expand Down Expand Up @@ -145,8 +145,11 @@ def run_shell_command(commandLine, log=True):
if log:
logger = logging.getLogger(__name__)
logger.info("Running: %s", " ".join(str(item) for item in commandLine))
return check_output(commandLine)

pipes = Popen(commandLine, stdout=PIPE, stderr=PIPE)
std_out, std_err = pipes.communicate()

return std_out

def convert_dir(dir):
""" Convert Direction
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/parallel.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ First thing first, let's make sure our software are usable.
```sh
(dcm2bids) sam:~$ dcm2bids -v
dcm2bids version: 3.1.0
Based on BIDS version: v1.8.0
Based on BIDS version: v1.9.0
(dcm2bids) sam:~$ parallel --version
GNU parallel 20230722
Copyright (C) 2007-2023 Ole Tange, http://ole.tange.dk and Free Software
Expand Down
9 changes: 9 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: fsl
channels:
- https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/
- conda-forge
- HCC
dependencies:
- fsl-bet2
- fsl-flirt
- pydeface

0 comments on commit c833933

Please sign in to comment.