Skip to content

DerivativesDataSink inconsistent byte order #1029

@liningpan

Description

@liningpan

What happened?

DerivativesDataSink could produce invalid/corrupted NIfTI file, where the endianness of the header is inconsistent with the data volume.

fmriprep use DerivativesDataSink to coerce averaged boldref into float32 data type. If the input NIfTI file is in big endian and the volume require data type conversion (i.e. in i16), the call to unsafe write will generate an output nifti file with a big endian header and a little endian (machine native) data volume, which will obviously corrupt downstream steps. (PS: antsAI will seg fault if none of the start locations worked, which made debugging this even less obvious).

data_dtype = self.inputs.data_dtype or self._default_dtypes[self.inputs.suffix]

if new_data is new_header is None:
_copy_any(orig_file, str(out_file))
else:
orig_img = nb.load(orig_file)
if new_data is None:
set_consumables(new_header, orig_img.dataobj)
new_data = orig_img.dataobj.get_unscaled()
else:
# Without this, we would be writing nans
# This is our punishment for hacking around nibabel defaults
new_header.set_slope_inter(slope=1.0, inter=0.0)
unsafe_write_nifti_header_and_data(
fname=out_file, header=new_header, data=new_data
)

def unsafe_write_nifti_header_and_data(fname, header, data):

What command did you use?

I ran into this issue through fmriprep. This is a intrinsic operation in niworkflows

What version of the software are you running?

fmriprep 25.2.3 sigularity (built from docker)

How are you running this software?

Singularity

Is your data BIDS valid?

Yes

Are you reusing any previously computed results?

No

Please copy and paste any relevant log output.

Additional information / screenshots

No response

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions