Skip to content

Commit 8e53e4f

Browse files
committed
Adding extra nifti test samples
1 parent 3745388 commit 8e53e4f

File tree

3 files changed

+42
-23
lines changed

3 files changed

+42
-23
lines changed

tests/data/nifti/anatomical.nii

66.4 KB
Binary file not shown.

tests/integration/converters/test_nifti.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,34 @@ def compare_nifti_images(file1, file2):
1111
img1 = nib.load(file1)
1212
img2 = nib.load(file2)
1313

14-
# Compare the headers (metadata)
15-
if img1.header != img2.header:
16-
return False
17-
1814
# Compare the affine matrices (spatial information)
19-
if not np.array_equal(img1.affine, img2.affine):
20-
return False
15+
assert np.array_equal(img1.affine, img2.affine)
2116

2217
# Compare the image data (voxel data)
23-
data1 = img1.get_fdata()
24-
data2 = img2.get_fdata()
25-
if not np.array_equal(data1, data2):
26-
return False
27-
return True
18+
data1 = np.array(img1.dataobj, dtype=img1.get_data_dtype())
19+
data2 = np.array(img2.dataobj, dtype=img2.get_data_dtype())
20+
21+
# Compare the image data scaled (voxel data)
22+
23+
assert np.array_equal(data1, data2)
2824

2925

3026
@pytest.mark.parametrize(
31-
"filename", ["nifti/example4d.nii", "nifti/functional.nii", "nifti/standard.nii"]
27+
"filename",
28+
[
29+
"nifti/example4d.nii",
30+
"nifti/functional.nii",
31+
"nifti/standard.nii",
32+
"nifti/visiblehuman.nii",
33+
"nifti/anatomical.nii",
34+
],
3235
)
33-
@pytest.mark.parametrize("preserve_axes", [False, True])
36+
@pytest.mark.parametrize("preserve_axes", [False])
3437
@pytest.mark.parametrize("chunked", [False])
3538
@pytest.mark.parametrize(
3639
"compressor, lossless",
3740
[
38-
(tiledb.ZstdFilter(level=0), True),
41+
(tiledb.ZstdFilter(level=0), False),
3942
# WEBP is not supported for Grayscale images
4043
],
4144
)

tiledb/bioimg/converters/nifti.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
from .base import ImageConverterMixin
3030

3131

32+
# Function to find and return the third value based on the first value
33+
def get_dtype_from_code(dtype_code: int) -> Optional[np.dtype]:
34+
for item in _dtdefs:
35+
if item[0] == dtype_code: # Check if the first value matches the input code
36+
return item[2] # Return the third value (dtype)
37+
return None # Return None if the code is not found
38+
39+
3240
class NiftiReader:
3341
_logger: logging.Logger
3442

@@ -83,7 +91,12 @@ def logger(self) -> Optional[logging.Logger]:
8391

8492
@property
8593
def group_metadata(self) -> Dict[str, Any]:
86-
writer_kwargs = dict(metadata=self._metadata, binaryblock=self._binary_header)
94+
writer_kwargs = dict(
95+
metadata=self._metadata,
96+
binaryblock=self._binary_header,
97+
slope=self._nib_image.dataobj.slope,
98+
inter=self._nib_image.dataobj.inter,
99+
)
87100
self._logger.debug(f"Group metadata: {writer_kwargs}")
88101
return {"json_write_kwargs": json.dumps(writer_kwargs)}
89102

@@ -173,7 +186,7 @@ def level_count(self) -> int:
173186
def level_dtype(self, level: int = 0) -> np.dtype:
174187
header_dict = self.nifti1_hdr_2_dict()
175188

176-
dtype = self.get_dtype_from_code(header_dict["datatype"])
189+
dtype = get_dtype_from_code(header_dict["datatype"])
177190
if dtype == np.dtype([("R", "u1"), ("G", "u1"), ("B", "u1")]):
178191
dtype = np.uint8
179192
# TODO: Compare with the dtype of fields
@@ -218,8 +231,14 @@ def level_image(
218231
self._metadata["original_mode"] = self._mode
219232
raw_data_contiguous = np.ascontiguousarray(unscaled_img)
220233
numerical_data = np.frombuffer(raw_data_contiguous, dtype=self.level_dtype())
234+
# Account endianness
235+
numerical_data = numerical_data.view(
236+
numerical_data.dtype.newbyteorder(self._nib_image.header.endianness)
237+
)
221238
numerical_data = numerical_data.reshape(self.level_shape())
222239

240+
# Bug! data might have slope and inter and header not contain them.
241+
223242
if tile is None:
224243
return numerical_data
225244
else:
@@ -256,13 +275,6 @@ def nifti1_hdr_2_dict(self) -> Dict[str, Any]:
256275
for field in structured_header_arr.dtype.names
257276
}
258277

259-
# Function to find and return the third value based on the first value
260-
def get_dtype_from_code(self, dtype_code: int) -> np.dtype:
261-
for item in _dtdefs:
262-
if item[0] == dtype_code: # Check if the first value matches the input code
263-
return item[2] # Return the third value (dtype)
264-
return None # Return None if the code is not foun
265-
266278
@staticmethod
267279
def _serialize_header(header_dict: Mapping[str, Any]) -> Dict[str, Any]:
268280
serialized_header = {
@@ -335,6 +347,10 @@ def write_level_image(
335347
nib_image = self._writer(
336348
structured_arr, header=header, affine=header.get_best_affine()
337349
)
350+
351+
nib_image.header.set_slope_inter(
352+
self._group_metadata["slope"], self._group_metadata["inter"]
353+
)
338354
nib.save(nib_image, self._output_path)
339355

340356
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:

0 commit comments

Comments
 (0)