Skip to content

Commit 7aff494

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

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

heudiconv/convert.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import random
1010
import re
1111
import shutil
12+
import gzip
1213
import sys
1314
from types import ModuleType
1415
from typing import TYPE_CHECKING, Any, List, Optional, cast
@@ -630,6 +631,19 @@ def convert(
630631
item_dicoms, prefix, with_prov, bids_options, tmpdir, dcmconfig
631632
)
632633

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

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

0 commit comments

Comments
 (0)