QSIPrep: "ValueError: zero-size array to reduction operation minimum which has no identity" during dwidenoise

Summary of what happened:

I am trying to run qsiprep 0.20.0 on a single subject with one T1w image and one dwi image. I am having difficulty understanding the error flagged in the log during the denoising step, and was hoping to get some help with it.

“ValueError: zero-size array to reduction operation minimum which has no identity”

(I’ve tagged both nipype and qsiprep because I can’t tell which is the cause)

Command used (and if a helper script was used, a link to the helper script or the command generated):

export APPTAINERENV_FS_LICENSE=$GROUP_HOME/freesurferlicense.txt
singularity run -e --containall --writable-tmpfs --cleanenv \
/home/groups/jyeatman/software/singularity_images/qsiprep-0.20.0.sif \
/scratch/groups/jyeatman/howard/DBP2/bids \
/scratch/groups/jyeatman/howard/DBP2/qsiprep participant --participant-label sub-$SLURM_ARRAY_TASK_ID \
-w /scratch/groups/jyeatman/howard/DBP2/qsiprep-work \
--nthreads 10 \
--omp-nthreads 8 \
--output-resolution 1.2 \
--infant \
--pepolar-method TOPUP+DRBUDDI 

Version:

singularity build from docker://pennbbl/qsiprep:0.20.0 on HPC cluster

Environment (Docker, Singularity / Apptainer, custom installation):

Apptainer

Data formatted according to a validatable standard? Please provide the output of the validator:

Data BIDSified with ezBIDS and validated on https://bids-standard.github.io/bids-validator/

Summary
10 Files, 85.75MB
1 - Subject
1 - Session
Available Tasks
Available Modalities
MRI
We found 1 Warning in your dataset.
view 1 warning
Warning 1: [Code 113] NO_AUTHORS
Click here for more information about this issue

The Authors field of dataset_description.json should contain an array of fields - with one author per field. This was triggered because there are no authors, which will make DOI registration from dataset metadata impossible.

Relevant log outputs (up to 20 lines):

Node: qsiprep_wf.single_subject_21337_wf.dwi_preproc_acq_b700_dir_PA_wf.pre_hmc_wf.merge_and_denoise_wf.dwi_denoise_acq_b700_dir_PA_dwi_wf.denoiser
Working directory: /scratch/groups/jyeatman/howard/DBP2/qsiprep-work/qsiprep_wf/single_subject_21337_wf/dwi_preproc_acq_b700_dir_PA_wf/pre_hmc_wf/merge_and_denoise_wf/dwi_denoise_acq_b700_dir_PA_dwi_wf/denoiser

Node inputs:

args = <undefined>
bval_scale = <undefined>
environ = {}
extent = (5, 5, 5)
grad_file = <undefined>
grad_fsl = <undefined>
in_bval = <undefined>
in_bvec = <undefined>
in_file = <undefined>
mask = <undefined>
nmse_text = <undefined>
noise_image = <undefined>
nthreads = 1
out_bval = <undefined>
out_bvec = <undefined>
out_file = <undefined>
out_report = dwidenoise_report.svg

Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/pipeline/plugins/multiproc.py", line 67, in run_node
    result["result"] = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/pipeline/engine/nodes.py", line 527, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/pipeline/engine/nodes.py", line 645, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/pipeline/engine/nodes.py", line 771, in _run_command
    raise NodeExecutionError(msg)
nipype.pipeline.engine.nodes.NodeExecutionError: Exception raised while executing Node denoiser.

[…]

dwidenoise: [ 50%] compressing image "sub-21337_acq-b700_dir-PA_dwi_LAS_noise.nii.gz"...e[0Ke[?7he[?7l
	dwidenoise: [100%] compressing image "sub-21337_acq-b700_dir-PA_dwi_LAS_noise.nii.gz"...e[0Ke[?7h
	dwidenoise: [100%] compressing image "sub-21337_acq-b700_dir-PA_dwi_LAS_noise.nii.gz"e[0K
Traceback:
	Traceback (most recent call last):
	  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/interfaces/base/core.py", line 398, in run
	    runtime = self._post_run_hook(runtime)
	  File "/usr/local/miniconda/lib/python3.10/site-packages/nipype/interfaces/mixins/reporting.py", line 50, in _post_run_hook
	    self._generate_report()
	  File "/usr/local/miniconda/lib/python3.10/site-packages/qsiprep/interfaces/denoise.py", line 90, in _generate_report
	    cuts = cuts_from_bbox(contour_nii or mask_nii, cuts=self._n_cuts)
	  File "/usr/local/miniconda/lib/python3.10/site-packages/qsiprep/niworkflows/viz/utils.py", line 205, in cuts_from_bbox
	    start_coords = B.min(0)
	  File "/usr/local/miniconda/lib/python3.10/site-packages/numpy/core/_methods.py", line 44, in _amin
	    return umr_minimum(a, axis, None, out, keepdims, initial, where)
	ValueError: zero-size array to reduction operation minimum which has no identity

Screenshots / relevant information:

Hi @chiuhoward,

This error seems to be caused by trying to find the minimum of an empty matrix (e.g., ValueError: zero-size array to reduction operation minimum which has no identity · Issue #15 · ccpem/mrcfile · GitHub). I have not seen this in QSIPrep and it is not immediately clear to me why this would happen. Has this error happened for other subjects in your dataset, and can you also see if the error persists when running on a fresh working directory on a more “vanilla” qsiprep run by removing --infant and --pepolar-method TOPUP+DRBUDDI temporarily? Could also help to know how data were converted from dicom to nifti.

Best,
Steven

This is happening while plotting slices for the visual reports. It’s possible that there was an issue with masking the data, since the slices come from the mask. Is this happening with all your subjects?

Hi Steven and Matt,

thanks for the replies.

Running the more “vanilla” version of qsiprep by removing --infant and --pepolar-method TOPUP+DRBUDDI still resulted in a crash at the same point.

The anatomical T1w NIFTI + json was converted from DICOM locally through dcm2niix in the command line with no additional flags, and the dwi NIFTI was downloaded from Flywheel with the associated json file, I had to add "PhaseEncodingDirection": “j” to the DWI json as documented in the .str accessor thread to get qsiprep to run before this error occurred. I believe that the dwi NIFTI was converted previously using a gear from Flywheel but I will have to look into that.

I did visually inspect the T1w and dwi images on Flywheel before downloading them (they looked ok), but I will try running it on another subject to see if this error still persists.

Just to update - I ran the same command with two different subjects, and one completed while the other crashed. For the subjects that failed, the DWI json file was specified very differently, so I suspect that might be the cause.

The one that failed looks like this

{
    "acquisition_matrix": [
        96,
        96
    ],
    "acquisition_number": 1,
    "bidsinfo": {
        "EchoTime": 0.0625,
        "EffectiveEchoSpacing": 0.000792,
        "NumberOfVolumesDiscardedByScanner": 4,
        "PhaseEncodingDirection": "j",
        "PixelBandwidth": 2,
        "ReconMatrixPE": 96,
        "RepetitionTime": 2.1,
        "SliceTiming": [
            0,
            1.05,
            0.21,
            1.26,
            0.42,
            1.47,
            0.63,
            1.68,
            0.84,
            1.89,
            0,
            1.05,
            0.21,
            1.26,
            0.42,
            1.47,
            0.63,
            1.68,
            0.84,
            1.89,
            0,
            1.05,
            0.21,
            1.26,
            0.42,
            1.47,
            0.63,
            1.68,
            0.84,
            1.89
        ],
        "TaskName": "DTIpe0b700mux32mm",
        "TotalReadoutTime": 0.07524
    },
    "effective_echo_spacing": 0.000792,
    "exam_datetime": "20210307 181556",
    "exam_number": 33934,
    "flip_angle": 77,
    "fov": [
        192,
        192
    ],
    "mecho_times": [
        62500
    ],
    "mt_offset_hz": 0,
    "mux_cal_duration": 12.6,
    "mux_cal_file": "",
    "mux_cal_type": "internal",
    "num_acquired_timepoints": 72,
    "num_bands": 3,
    "num_echos": 1,
    "num_mux_cal_cycle": 2,
    "num_mux_cal_timepoints": 6,
    "num_mux_cal_volumes_in_nifti": 2,
    "num_muxed_slices": 10,
    "num_receivers": 8,
    "num_slices": 30,
    "num_usable_volumes_in_nifti": 66,
    "num_volumes_in_nifti": 68,
    "operator": "EMM",
    "partial_ky": 0.67,
    "patient_id": "ANON33934",
    "phase_encode_direction": 1,
    "phase_encode_polarity": 0,
    "phase_encode_undersample": 1,
    "pixel_bandwidth": 125,
    "protocol_name": "Preemie Brain MR2",
    "psd_name": "muxarcepi2",
    "receive_coil_name": "8HRBRAIN",
    "recon_method": "'split-slice-grappa_sense1'",
    "recon_num_virtual_coils": 16,
    "recon_time": "2021-08-25 08:23:04.846587",
    "recon_use_GPU": "0",
    "recon_version": "e5f8688",
    "scanner_name": "chmr2",
    "series_description": "DTI pe0 b700 mux3 2mm",
    "series_number": 10,
    "slice_timing": [
        0,
        1.05,
        0.21,
        1.26,
        0.42,
        1.47,
        0.63,
        1.68,
        0.84,
        1.89,
        0,
        1.05,
        0.21,
        1.26,
        0.42,
        1.47,
        0.63,
        1.68,
        0.84,
        1.89,
        0,
        1.05,
        0.21,
        1.26,
        0.42,
        1.47,
        0.63,
        1.68,
        0.84,
        1.89
    ],
    "te": 0.0625,
    "ti": 0,
    "tr": 2.1,
    "Manufacturer": "n/a",
    "RepetitionTime": 2.1,
    "PhaseEncodingDirection": "j"
}

while the one that completed looks very different.

{
    "Modality": "MR",
    "MagneticFieldStrength": 3,
    "ImagingFrequency": 127.716171,
    "Manufacturer": "GE",
    "InternalPulseSequenceName": "EPI2",
    "ManufacturersModelName": "SIGNA Premier",
    "InstitutionName": "LPCH",
    "DeviceSerialNumber": "00000415723CHMR7",
    "StationName": "LPCHMRIMR7",
    "BodyPartExamined": "Head",
    "PatientPosition": "HFS",
    "ProcedureStepDescription": "MRI BRAIN WO CONTRAST",
    "SoftwareVersions": "29\\LX\\RX29.1_R01_2111.a",
    "MRAcquisitionType": "2D",
    "SeriesDescription": "DTI pe0 b700 HB3 2mm",
    "ProtocolName": "Preemie Brain",
    "ScanningSequence": "EP\\RM",
    "SequenceVariant": "NONE",
    "ScanOptions": "CL_GEMS\\SAT_GEMS\\EDR_GEMS\\EPI_GEMS\\HYPERBAND_GEMS\\PFF\\FS",
    "PulseSequenceName": "cni_epi2",
    "ImageType": [
        "ORIGINAL",
        "PRIMARY",
        "OTHER"
    ],
    "SeriesNumber": 13,
    "AcquisitionTime": "02:14:30.000000",
    "AcquisitionNumber": 1,
    "SliceThickness": 2,
    "SpacingBetweenSlices": 2,
    "SAR": 0.95844,
    "EchoTime": 0.0644,
    "RepetitionTime": 2.416,
    "FlipAngle": 90,
    "PhaseEncodingPolarityGE": "Flipped",
    "ShimSetting": [
        97,
        -32,
        -415
    ],
    "PrescanReuseString": "RN/s4,Cal/s4,Coil/s3",
    "NumberOfDiffusionT2GE": 2,
    "TensorFileNumberGE": 1999,
    "DiffGradientCyclingGE": "ALLTR",
    "CoilString": "48HAP",
    "MultibandAccelerationFactor": 3,
    "PercentPhaseFOV": 100,
    "PercentSampling": 100,
    "AcquisitionMatrixPE": 96,
    "ReconMatrixPE": 256,
    "EffectiveEchoSpacing": 0.000247373,
    "TotalReadoutTime": 0.06308,
    "PixelBandwidth": 1953.12,
    "PhaseEncodingDirection": "j",
    "ImageOrientationPatientDICOM": [
        1,
        0,
        0,
        0,
        1,
        0
    ],
    "InPlanePhaseEncodingDirectionDICOM": "COL",
    "ConversionSoftware": "dcm2niix",
    "ConversionSoftwareVersion": "v1.0.20230411"
}

However, as the json files are so different, I cannot pinpoint the exact field that causes the denoising step to fail.

Hi @chiuhoward,

These appear to be different acquisitions altogether. Did these come from the same scanner? How was that first json/nii made? It looks like the second was a straight forward dcm2niix on a GE sequence, but I do not know of any software that produces jsons like your failing example.

Best,
Steven

Hi Steven,

the first json was made from a scan a few years ago, so the people I’ve asked don’t know how the json file was made. It wasn’t used in the Flywheel gears so it was ignored.

I tried running the same 2 subjects with a “good” json file and it still failed, so I suspect that the issue is with my raw data for these particular scans.

I just have one last question about the masking step that Matt mentioned, could a truncated FOV in the dwi scan cause the masking step to fail? That was the one other difference I noticed between the two scans that failed (both screenshots on top) and the one that didn’t (bottom screenshot). The range of values in the grayscale bar also varies massively.

Thank you both so much for your time once again.



Hi @chiuhoward,

What kind of files are you visualizing there? Any chance you have the source data from the scanner and can reconvert the data to nifti?

Best,
Steven

Hi Steven,

these are three b700 DWI images that I was trying to feed through qsiprep (with the T1w images) for these three subjects.

The source files for these DWI NIFTIs are pfiles (*.7.zip) which unzip to a folder that contains a *.7.gz, *_param.dat, *_ref.h5, *_vrgf.dat, and *_tensor.dat rather than DICOMs. I have no experience working with pfiles, so I will have to ask around for conversion options…