Skip to content

Commit b9c8474

Browse files
authored
Merge pull request #60 from Unique-Usman/wrapper
A python script to wrap image read and write for Nifti Images.
2 parents 94ee6d4 + 14d1793 commit b9c8474

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

WrapImage/nifti_wrapper.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import argparse
2+
import json
3+
import os
4+
import nibabel as nib
5+
from src.wrappers.OsipiBase import OsipiBase
6+
import numpy as np
7+
from tqdm import tqdm
8+
9+
10+
def read_nifti_file(input_file):
11+
"""
12+
For reading the 4d nifti image
13+
"""
14+
nifti_img = nib.load(input_file)
15+
return nifti_img.get_fdata(), nifti_img.header
16+
17+
def read_json_file(json_file):
18+
"""
19+
For reading the json file
20+
"""
21+
22+
if not os.path.exists(json_file):
23+
raise FileNotFoundError(f"File '{json_file}' not found.")
24+
25+
with open(json_file, "r") as f:
26+
try:
27+
json_data = json.load(f)
28+
except json.JSONDecodeError as e:
29+
raise ValueError(f"Error decoding JSON in file '{json_file}': {e}")
30+
31+
return json_data
32+
33+
def read_bval_file(bval_file):
34+
"""
35+
For reading the bval file
36+
"""
37+
if not os.path.exists(bval_file):
38+
raise FileNotFoundError(f"File '{bval_file}' not found.")
39+
40+
bval_data = np.genfromtxt(bval_file, dtype=float)
41+
return bval_data
42+
43+
def read_bvec_file(bvec_file):
44+
"""
45+
For reading the bvec file
46+
"""
47+
if not os.path.exists(bvec_file):
48+
raise FileNotFoundError(f"File '{bvec_file}' not found.")
49+
50+
bvec_data = np.genfromtxt(bvec_file)
51+
bvec_data = np.transpose(bvec_data) # Transpose the array
52+
return bvec_data
53+
54+
def save_nifti_file(data, output_file, affine=None, **kwargs):
55+
"""
56+
For saving the 3d nifti images of the output of the algorithm
57+
"""
58+
if affine is None:
59+
affine = np.eye(data.ndim + 1)
60+
output_img = nib.nifti1.Nifti1Image(data, affine , **kwargs)
61+
nib.save(output_img, output_file)
62+
63+
def loop_over_first_n_minus_1_dimensions(arr):
64+
"""
65+
Loops over the first n-1 dimensions of a numpy array.
66+
67+
Args:
68+
arr: A numpy array.
69+
70+
Yields:
71+
A tuple containing the indices for the current iteration and a flattened view of the remaining dimensions.
72+
"""
73+
n = arr.ndim
74+
for idx in np.ndindex(*arr.shape[:n-1]):
75+
flat_view = arr[idx].flatten()
76+
yield idx, flat_view
77+
78+
79+
80+
if __name__ == "__main__":
81+
parser = argparse.ArgumentParser(description="Read a 4D NIfTI phantom file along with BIDS JSON, b-vector, and b-value files.")
82+
parser.add_argument("input_file", type=str, help="Path to the input 4D NIfTI file.")
83+
parser.add_argument("bvec_file", type=str, help="Path to the b-vector file.")
84+
parser.add_argument("bval_file", type=str, help="Path to the b-value file.")
85+
parser.add_argument("--affine", type=float, nargs="+", help="Affine matrix for NIfTI image.")
86+
parser.add_argument("--algorithm", type=str, default="OJ_GU_seg", help="Select the algorithm to use.")
87+
parser.add_argument("algorithm_args", nargs=argparse.REMAINDER, help="Additional arguments for the algorithm.")
88+
89+
args = parser.parse_args()
90+
91+
try:
92+
# Read the 4D NIfTI file
93+
data, _ = read_nifti_file(args.input_file)
94+
95+
# Read the b-vector, and b-value files
96+
bvecs = read_bvec_file(args.bvec_file)
97+
bvals = read_bval_file(args.bval_file)
98+
99+
# Pass additional arguments to the algorithm
100+
101+
fit = OsipiBase(algorithm=args.algorithm)
102+
f_image = []
103+
Dp_image = []
104+
D_image = []
105+
106+
# This is necessary for the tqdm to display progress bar.
107+
n = data.ndim
108+
total_iteration = np.prod(data.shape[:n-1])
109+
for idx, view in tqdm(loop_over_first_n_minus_1_dimensions(data), desc=f"{args.algorithm} is fitting", dynamic_ncols=True, total=total_iteration):
110+
[f_fit, Dp_fit, D_fit] = fit.osipi_fit(view, bvals)
111+
f_image.append(f_fit)
112+
Dp_image.append(Dp_fit)
113+
D_image.append(D_fit)
114+
115+
# Convert lists to NumPy arrays
116+
f_image = np.array(f_image)
117+
Dp_image = np.array(Dp_image)
118+
D_image = np.array(D_image)
119+
120+
# Reshape arrays if needed
121+
f_image = f_image.reshape(data.shape[:data.ndim-1])
122+
Dp_image = Dp_image.reshape(data.shape[:data.ndim-1])
123+
D_image = D_image.reshape(data.shape[:data.ndim-1])
124+
125+
save_nifti_file(f_image, "f.nii.gz", args.affine)
126+
save_nifti_file(Dp_image, "dp.nii.gz", args.affine)
127+
save_nifti_file(D_image, "d.nii.gz", args.affine)
128+
129+
except Exception as e:
130+
print(f"Error: {e}")
131+

0 commit comments

Comments
 (0)