Negative values in CIFTI by XCP-D postprocessing

Hi all,

I have a question regarding the negative values in the dtseries/ptseries.nii outputs of the xcp-d. I have done preprocessing using fmriprep, and used xcp-d with the codes below:

singularity run --cleanenv \
-B /path/to/fmriprep:/fmriprep_dir \
-B /path/to/output:/output_dir \
-B /path/to/freesurfer:/toolboxes \
xcp_d-0.5.0.simg /fmriprep_dir/ /output_dir/ participant \
--fs-license-file /toolboxes/license.txt --warp-surfaces-native2std \
--participant-label [subjid] --input-type fmriprep --smoothing 6 -p acompcor --cifti \
--lower-bpf 0.008 --upper-bpf 0.08 --head-radius auto --fd-thresh 0.5

Apologies for my naive question but I wonder why there are negative values in the denoised bold data (see below). I have worked with fMRI data and also ptseries/dtseries outputs of the HCP but I haven’t seen negative values before. To me, it seems that the data have been kind of Z-scored/detrended, which I assume are default Nilearn denoising arguments. Is it possible to not detrend/standardize data using XCP-D? This can be useful in cases where we want to concatenate several regions’ timeseries together.

Best,
Amir

p.s. loading these cifti outputs using ciftiopen in MATLAB generated a warning: appears to not be version 2, converting using wb_command

XCP-D’s denoising step includes intercept and linear trend terms, so the resulting denoised data will be mean-centered. You can disable the denoising step if you’d like, with --nuisance-parameters none, in versions >= 0.5.0.

EDIT: If you have a more detailed error message, I’d be happy to take a look at the CIFTI issue.

Thanks. I don’t want the disable the denoising, but I was also interested in averaging multiple regions together, e.g., in a network-manner for connectivity purposes based on Pearson’s correlation. Please correct me if I’m wrong, but I assume Z-scoring or demeaning will make this concatenation across networks not feasible.

Regarding that issue with loading CIFTIs inside MATLAB, I think it was more of a warning rather than an error.

Amir

Hi @AmirHussein,

Can you explain a little more about your approach here? You usually don’t want to do a double average (that is, make a new region out of averaging two XCP atlas region timeseries together, which themselves were made out of averaging time-series). The reason is that a simple average would assume the two regions are equally weighted, which is not the case unless the two regions are the same size.

Best,
Steven

Hi Steven,

Thanks for your comment. You’re right. One workaround is to possibly multiply each region by its number of voxels (I assume since they’re based on templates, you can obtain them), concatenate all together, and calculate a new mean. Standardizing and demeaning the data may make this workaround not possible. Are there any easier approaches?

Amir

The denoising (including demeaning) is done voxel-wise, so I don’t think that would adversely impact your multi-region averaging.

You may want to simply create a new CIFTI parcellation (i.e., dlabel) for extracting average time-series data. I recently needed to combine select parcels on either hemisphere from a single atlas; here is my code:

# Extract DMN ROIs
while read roi; do

	wb_command \
		-cifti-label-to-roi Schaefer2018_600Parcels_17Networks_order.dlabel.nii \
		Schaefer2018_600Parcels_17Networks_order_${roi}.dscalar.nii \
		-name $roi \

done < DMN_rois.txt

# Combine bilateral ROIs

id=1

for roi in IPL PCC PFC Temp PHC; do

	LH_ROI=Schaefer2018_600Parcels_17Networks_order_17Networks_LH_*${roi}*.dscalar.nii
	RH_ROI=Schaefer2018_600Parcels_17Networks_order_17Networks_RH*${roi}*.dscalar.nii
	OUT_ROI=Schaefer2018_600Parcels_17Networks_order_17Networks_${roi}.dscalar.nii

	wb_command \
		-cifti-math \
		-var a $LH_ROI \
		-var b $RH_ROI \
		"((a + b) > 0) * "${id}"" \
		${OUT_ROI}

	# Labels are given unique IDs to be combined in the dlabel parcellation
	(( id++ ))

done

# Combine all ROIs

OUT_ROI=Schaefer2018_600Parcels_17Networks_order_17Networks_DMN_ROIs.dscalar.nii

wb_command \
	-cifti-math \
	-var a Schaefer2018_600Parcels_17Networks_order_17Networks_IPL.dscalar.nii \
	-var b Schaefer2018_600Parcels_17Networks_order_17Networks_PCC.dscalar.nii \
	-var c Schaefer2018_600Parcels_17Networks_order_17Networks_PFC.dscalar.nii \
	-var d Schaefer2018_600Parcels_17Networks_order_17Networks_Temp.dscalar.nii \
	-var e Schaefer2018_600Parcels_17Networks_order_17Networks_PHC.dscalar.nii \
	"a + b + c + d + e" \
	${OUT_ROI}

# Turn dscalar into dlabel

wb_command \
	-cifti-label-import \
	${OUT_ROI} \
	DMN_label-list.txt \
	Schaefer2018_600Parcels_17Networks_order_DMN_ROIs.dlabel.nii

Then you can extract correlation matrices using the following commands:


# Parcelate dtseries
wb_command \
	-cifti-parcellate \
	$sub/$ses/func/${sub}_${ses}_task-rest_run-1_space-fsLR_den-91k_desc-denoised_bold.dtseries.nii \
	Schaefer2018_600Parcels_17Networks_order_DMN_ROIs.dlabel.nii \
	COLUMN \
	${sub}/${ses}/func/${sub}_${ses}_task-rest_run-1_space-fsLR_atlas-617_DMN_ROIs_den-91k_timeseries.ptseries.nii; 

# Create pconn.nii
wb_command \
	-cifti-correlation ${sub}/${ses}/func/${sub}_${ses}_task-rest_run-1_space-fsLR_atlas-617_DMN_ROIs_den-91k_timeseries.ptseries.nii \
	${sub}/$ses/func/${sub}_${ses}_task-rest_run-1_space-fsLR_atlas-617_DMN_ROIs_den-91k_timeseries.pconn.nii;

# Convert pconn to txt file
wb_command \
	-cifti-convert \
	-to-text \
	${sub}/$ses/func/${sub}_${ses}_task-rest_run-1_space-fsLR_atlas-617_DMN_ROIs_den-91k_timeseries.pconn.nii \
	${sub}/$ses/func/${sub}_${ses}_task-rest_run-1_space-fsLR_atlas-617_DMN_ROIs_den-91k_timeseries.pconn.txt;

Hope this helps! Let me know if you have any questions.

Cheers,
Bram