AFNI 3dretroicor: `*** Error transforming resp data` on fmriprep'd data

Hi,

In a follow-up to this post, I am using AFNI 3dretroicor to filter out physio noise from rest data.

Currently, I am running into the same issue as this user: When running with only the cardiac file, 3dretroicor appears to work, but when including the respiratory file, it crashes with the vague error *** Error transforming resp data.

Here is an example command:

3dretroicor -prefix sub-s001_ses-1_task-taskA_run-1_space-MNI152NLin2009cAsym_desc-preproc_bold_retroicor.nii.gz -card func/sub-s001_ses-1_task-taskA_run-1_recording-cardiac_physio.slibase.1D -resp func/sub-s001_ses-1_task-taskA_run-1_recording-respiratory_physio.slibase.1D func/sub-s001_ses-1_task-taskA_run-1_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz

(removing the -resp …respiratory_physio.slibase.1D argument works, as reported by the other user.)

I am using AFNI 21.1.00, and the data were preprocessed with FMRIPREP LTS 20.2. The 1D files were created by calling RetroTS.py on the raw physio files using 2 commands like the following:

python /Users/henrymj/Documents/afni/src/jzosky/RetroTS.py -phys_file func/sub-s001_ses-1_task-taskA_run-1_physio.tsv.gz -phys_json func/sub-s001_ses-1_task-taskA_run-1_physio.json -n 8 -v 0.68 -prefix func/sub-s001_ses-1_task-taskA_run-1_recording-respiratory_physio -respiration_out 1 -cardiac_out 0

python /Users/henrymj/Documents/afni/src/jzosky/RetroTS.py -phys_file func/sub-s001_ses-1_task-taskA_run-1_physio.tsv.gz -phys_json func/sub-s001_ses-1_task-taskA_run-1_physio.json -n 8 -v 0.68 -prefix func/sub-s001_ses-1_task-taskA_run-1_recording-cardiac_physio -respiration_out 0 -cardiac_out 1

Here are the details of the preprocessed nifti image:

<class 'nibabel.nifti1.Nifti1Image'>
data shape (89, 105, 89, 1030)
affine: 
[[   2.20000005    0.            0.          -96.5       ]
 [   0.            2.20000005    0.         -132.5       ]
 [   0.            0.            2.20000005  -78.5       ]
 [   0.            0.            0.            1.        ]]
metadata:
<class 'nibabel.nifti1.Nifti1Header'> object, endian='<'
sizeof_hdr      : 348
data_type       : b''
db_name         : b''
extents         : 0
session_error   : 0
regular         : b'r'
dim_info        : 0
dim             : [  4  89 105  89   1030   1   1   1]
intent_p1       : 0.0
intent_p2       : 0.0
intent_p3       : 0.0
intent_code     : none
datatype        : float32
bitpix          : 32
slice_start     : 0
pixdim          : [1.   2.2  2.2  2.2  0.68 1.   1.   1.  ]
vox_offset      : 0.0
scl_slope       : nan
scl_inter       : nan
slice_end       : 0
slice_code      : unknown
xyzt_units      : 10
cal_max         : 15254.564
cal_min         : -1786.5756
slice_duration  : 0.0
toffset         : 0.0
glmax           : 0
glmin           : 0
descrip         : b'xform matrices modified by FixHeaderApplyTransforms (niworkflows v1.3.1).'
aux_file        : b''
qform_code      : mni
sform_code      : mni
quatern_b       : 0.0
quatern_c       : 0.0
quatern_d       : 0.0
qoffset_x       : -96.5
qoffset_y       : -132.5
qoffset_z       : -78.5
srow_x          : [  2.2   0.    0.  -96.5]
srow_y          : [   0.     2.2    0.  -132.5]
srow_z          : [  0.    0.    2.2 -78.5]
intent_name     : b''
magic           : b'n+1'

Update (but not a solution): I misread the user’s solution when I first attempting implementing it. I tried again changing slice_duration to nimg.header['dim'][3]/nimg.header['pixdim'][4] (my tr is already in seconds; it is .68s), which in this case was 130.88235, but that produced no change in behavior.

Any help would be sincerely appreciated!

3dretroicor hasn’t been updated in a very long time, and we typically use RetroTS.py instead, not in combination with 3dretroicorr. See the help for afni_proc.py for examples 5a,b,c on how to integrate the output of RetroTS.py into your analysis.

1 Like

@henrymj, this usage does not look quite correct.
Note that 3dretroicor (which I confess to having never actually used) predates RetroTS. From the help output, it looks like the original physio signals would be input to it, not those from RetroTS.py.
To use RetroTS.py, consider the good suggestion by @dglen, to apply it with afni_proc.py. If, for some reason, you do not want to use the proc script, at least review what afni_proc.py does, to regress those 13 per-slice signals early in the processing stream.