Skip to content

Commit a72d5ec

Browse files
committed
Recompress files where dcm2niix failed
1 parent 900ccdc commit a72d5ec

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

heudiconv/convert.py

+48
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,19 @@ def convert(
630630
item_dicoms, prefix, with_prov, bids_options, tmpdir, dcmconfig
631631
)
632632

633+
# try to handle compression failures from dcm2niix
634+
if outtype == 'nii.gz':
635+
converted_files = res.outputs.converted_files
636+
if not isinstance(converted_files, list):
637+
converted_files = [converted_files]
638+
uncompressed = [x for x in converted_files if x.endswith('.nii')]
639+
if len(uncompressed) > 0:
640+
lgr.warning("Conversion returned uncompressed nifti (>4GB?) - "
641+
"trying to salvage by recompressing ourselves. "
642+
"This might take a while ")
643+
if not recompress_failed(uncompressed):
644+
raise RuntimeError("Error compressing nifti")
645+
633646
bids_outfiles = save_converted_files(
634647
res,
635648
item_dicoms,
@@ -1099,3 +1112,38 @@ def bvals_are_zero(bval_file: str | list) -> bool:
10991112

11001113
bvals_unique = set(float(b) for b in bvals)
11011114
return bvals_unique == {0.0} or bvals_unique == {5.0}
1115+
1116+
1117+
def recompress_failed(niftis: list) -> bool:
1118+
"""Tries to recompress nifti files with built-in gzip module
1119+
1120+
Parameters
1121+
----------
1122+
niftis : list
1123+
list of nifti file paths
1124+
1125+
Returns
1126+
-------
1127+
True if all nifits were successfully compressed. False otherwise.
1128+
"""
1129+
1130+
import zlib
1131+
import gzip
1132+
from nibabel import load as nb_load
1133+
from nibabel.filebasedimages import ImageFileError
1134+
1135+
for nifti in niftis:
1136+
try:
1137+
img = nb_load(nifti)
1138+
# read everything to catch truncated/corrupted files
1139+
_ = img.get_fdata() # type:ignore[attr-defined]
1140+
with open(nifti, 'rb') as f_in:
1141+
with gzip.open(nifti + '.gz', 'wb', compresslevel=6) as f_out:
1142+
shutil.copyfileobj(f_in, f_out)
1143+
# nipype results still carry uncompressed file names and they will
1144+
# be renamed to '.nii.gz' later
1145+
os.rename(nifti + '.gz', nifti)
1146+
except (OSError, ImageFileError, zlib.error):
1147+
return False
1148+
1149+
return True

0 commit comments

Comments
 (0)