Skip to content

Commit 4bc40f2

Browse files
committed
Added the feature to read DICOM images into a 4D Nifti image utilizing dicom2niix
updated Dockerfile, README, and nifti_wrapper.py
1 parent dd869b9 commit 4bc40f2

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

Docker/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ WORKDIR /usr/src/app
55
RUN apt-get update && apt-get install -y --no-install-recommends \
66
build-essential \
77
libssl-dev \
8+
wget \
9+
pigz \
10+
&& wget https://github.com/rordenlab/dcm2niix/archive/refs/tags/v1.0.20241211.tar.gz \
11+
&& tar -xzf v1.0.20241211.tar.gz -C /usr/local/bin \
12+
&& rm v1.0.20241211.tar.gz \
13+
&& apt-get remove -y wget \
14+
&& apt-get autoremove -y \
815
&& apt-get clean \
916
&& rm -rf /var/lib/apt/lists/*
1017

Docker/README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This project is designed to run the `nifti_wrapper` script using a Docker contai
2424

2525
Before running the Docker container, here are the available options for the `Docker image` script:
2626

27-
- `input_file`: Path to the input 4D NIfTI file.
27+
- `input_file`: Path to the input 4D NIfTI file or dicom files 4D images like fMRI and DTI/DKI are supported.
2828
- `bvec_file`: Path to the b-vector file.
2929
- `bval_file`: Path to the b-value file.
3030
- `--affine`: Affine matrix for NIfTI image (optional).
@@ -58,4 +58,23 @@ Before running the Docker container, here are the available options for the `Doc
5858

5959
Replace `brain.nii.gz`, `brain.bvec`, and `brain.bval` with the actual file names you want to use.
6060

61+
### Reading in DICOM images
62+
63+
1. you can run the same Docker container using the `docker run` command. This command runs the Docker image with the specified input files:
64+
65+
```sh
66+
sudo docker run -it --rm --name TF2.4_IVIM-MRI_CodeCollection \
67+
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/src/app \
68+
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/app/output \
69+
tf2.4_ivim-mri_codecollection Downloads/dicom_folder
70+
```
71+
72+
Replace `dicom_folder` with the actual directory (containing DICOM Images) you want to use.
73+
74+
[Note that NIfTI and DICOM encode space differently](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Spatial_Coordinates)
75+
76+
77+
##### The goal of dcm2niix is to create FSL format bvec/bval files for processing. A crucial concern is ensuring that the gradient directions are reported in the frame of reference expected by the software you use to fit your tractography. [dicom2niix should generate a ".bvec" file that reports the tensors as expected](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Diffusion_Tensor_Imaging) by FSL's dtifit, where vectors are reported relative to image frame of reference (rather than relative to the scanner bore).
78+
79+
#### It is strongly recommend that users check validate the b-vector directions for their hardware and sequence as [described in a dedicated document](https://www.nitrc.org/docman/?group_id=880)
6180
---

WrapImage/nifti_wrapper.py

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
11
import argparse
22
import json
33
import os
4+
from pathlib import Path
5+
import subprocess
46
import nibabel as nib
57
from src.wrappers.OsipiBase import OsipiBase
68
import numpy as np
79
from tqdm import tqdm
810

11+
def dicom_to_niix(vol_dir: Path):
12+
"""
13+
For converting DICOM images to a (compresssed) 4d nifti image
14+
"""
15+
16+
try:
17+
res = subprocess.run(
18+
[
19+
"dcm2niix",
20+
"-f", "%s_%p", # dcm2niix attempts to provide a sensible file naming scheme
21+
"-o", vol_dir,
22+
"-z", "y", #specifying compressed nii.gz file
23+
# https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage
24+
# for further configuration for general usage see page above
25+
vol_dir
26+
],
27+
capture_output=True,
28+
text=True,
29+
check=True
30+
)
31+
32+
nifti_files = list(Path(vol_dir).glob("*.nii.gz"))
33+
if not nifti_files:
34+
raise RuntimeError("No NIfTI file generated by dcm2niix.")
35+
if len(nifti_files) > 1:
36+
raise RuntimeError("Multiple NIfTI files generated; expected one 4D NIfTI.")
37+
38+
bval_files = list(vol_dir.glob("*.bval"))
39+
bvec_files = list(vol_dir.glob("*.bvec"))
40+
bval_path = str(bval_files[0]) if bval_files else None
41+
bvec_path = str(bvec_files[0]) if bvec_files else None
42+
43+
44+
return vol_dir / "dicom2nifti.nii.gz", bval_path, bvec_path
45+
46+
except subprocess.CalledProcessError as e:
47+
raise RuntimeError(f"dcm2niix failed: {e.stderr}")
48+
949

1050
def read_nifti_file(input_file):
1151
"""
@@ -81,22 +121,35 @@ def loop_over_first_n_minus_1_dimensions(arr):
81121

82122
if __name__ == "__main__":
83123
parser = argparse.ArgumentParser(description="Read a 4D NIfTI phantom file along with BIDS JSON, b-vector, and b-value files.")
84-
parser.add_argument("input_file", type=str, help="Path to the input 4D NIfTI file.")
85-
parser.add_argument("bvec_file", type=str, help="Path to the b-vector file.")
86-
parser.add_argument("bval_file", type=str, help="Path to the b-value file.")
124+
parser.add_argument("input_file", type=Path, help="Path to the input 4D NIfTI file or DICOM files 4D images like fMRI and DTI/DKI are supported..")
125+
parser.add_argument("bvec_file", type=Path, help="Path to the b-vector file.")
126+
parser.add_argument("bval_file", type=Path, help="Path to the b-value file.")
87127
parser.add_argument("--affine", type=float, nargs="+", help="Affine matrix for NIfTI image.")
88128
parser.add_argument("--algorithm", type=str, default="OJ_GU_seg", help="Select the algorithm to use.")
89129
parser.add_argument("--algorithm_args", nargs=argparse.REMAINDER, help="Additional arguments for the algorithm.")
90130

91131
args = parser.parse_args()
92132

93133
try:
134+
if args.input_file.is_dir():
135+
# Convert DICOM to NIfTI using dicom2niix
136+
nifti_file, bval_path, bvec_path = dicom_to_niix(args.input_file) # read dir
137+
if bval_path is None or bvec_path is None:
138+
raise RuntimeError("dcm2niix did not generate bval/bvec files.")
139+
bval_file = Path(bval_path)
140+
bvec_file = Path(bvec_path)
141+
else:
142+
# Assume input is already a NIfTI file
143+
nifti_file = args.input_file
144+
bval_file = args.bval_file
145+
bvec_file = args.bvec_file
146+
94147
# Read the 4D NIfTI file
95-
data, _ = read_nifti_file(args.input_file)
148+
data, _ = read_nifti_file(nifti_file)
96149

97150
# Read the b-vector, and b-value files
98-
bvecs = read_bvec_file(args.bvec_file)
99-
bvals = read_bval_file(args.bval_file)
151+
bvecs = read_bvec_file(bvec_file)
152+
bvals = read_bval_file(bval_file)
100153

101154
# Pass additional arguments to the algorithm
102155

0 commit comments

Comments
 (0)