Loop to run topup in all the subject at once

Hey neuroimagers,

I am trying to create a for-loop in terminal to create the fieldmap with the topup function of fsl in all my participants. The base script I have for a single participant is this one:
The base script I have:

#!/bin/bash

# Directorio base
for i in {101,103,106}
do
base_dir="/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS"
participant_dir="/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/sub-$i"
session_dir="/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/sub-$i/ses-1"
fmap_dir="/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/sub-$i/ses-1/fmap"
# Bucle a través de carpetas de participantes
for i in ${fmap_dir}sub-*/; do
            # Bucle a través de archivos en la carpeta fmap
            for i in sub-${i}-ses-1_task-rest_dir_**_fieldmap.nii.gz; do
                # Obtener el nombre base del archivo sin extensión
                base_name="${sub-${i}-ses-1_task-rest_dir_**_fieldmap.*}"

                # Aplicar los comandos de FSL
                fslmerge -t "${base_name}.nii.gz" "${base_name}"_dir-AP_fieldmap.nii.gz "${base_name}"_dir-PA_fieldmap.nii.gz
                topup --imain="${participant_dir}${base_name}.nii.gz" --datain="${base_name}_acq_param.txt" --config=b02b0.cnf --out="${participant_dir}${base_name}_topup_results" --fout="${participant_dir}${base_name}_fieldmap" --iout="${participant_dir}${base_name}_magnitude"
            done

            # Volver al directorio original
            cd -
        fi
    done
done
#!/bin/sh

#  andrea_topup.sh
#  
#
#  Created by Agueda on 13/2/24.
#

If someone have done this before or have an example of a for-loop script that could share with me it would be helpful!

Thank u so much!

Hi @andreacopu

Here is something that I was using before using fmriprep:

#!/bin/sh

source ../Topup_Physio_BIDS/subjects_to_process.cfg

EXPDIR=/Volumes/groupdata/MRI_BIDS_DATABANK/$study
mkdir -p /Volumes/groupdata/MRI_BIDS_DATABANK/$study/derivatives

for sub in $list_sub
do
	sub=sub-${sub}
echo -----starting subject $sub------
OUTDIR=/Volumes/groupdata/MRI_BIDS_DATABANK/$study/derivatives/$sub
SUBDIR=$EXPDIR/$sub/
mkdir -p /Volumes/groupdata/MRI_BIDS_DATABANK/$study/derivatives
mkdir -p ${OUTDIR}
mkdir -p ${OUTDIR}/topup

fslmerge -t "${OUTDIR}/topup/${sub}_FieldmapAP_PA"  "${SUBDIR}fmap/${sub}_dir-AP_epi.nii.gz" "${SUBDIR}fmap/${sub}_dir-PA_epi.nii.gz"


RT=$(jq .TotalReadoutTime "${SUBDIR}fmap/${sub}_dir-AP_epi.json")

direction1=$(jq '.PhaseEncodingDirection' "${SUBDIR}fmap/${sub}_dir-AP_epi.json")
direction2=$(jq '.PhaseEncodingDirection' "${SUBDIR}fmap/${sub}_dir-PA_epi.json")
if [ "$direction1" = '"j-"' ]; then
    phase1='0 -1 0'
elif [ "$direction1" = '"j"' ]; then
    phase1='0 1 0'
fi;
if [ "$direction2" = '"j-"' ]; then
phase2='0 -1 0'
elif [ "$direction2" = '"j"' ]; then
phase2='0 1 0'
fi;
echo   "$phase1 $RT\n$phase1 $RT\n$phase1 $RT\n$phase2 $RT\n$phase2 $RT\n$phase2 $RT" > ${OUTDIR}/topup/${sub}_acqparamsAP_PA.txt

# Correct for EVEN number of slices to use b02b0.cnf
dimz=`fslval ${OUTDIR}/topup/${sub}_FieldmapAP_PA.nii.gz dim3`
if [ `expr $dimz % 2` -eq 1 ]; then
    echo "remove one slice to get odd number of slices"
    #fslroi ${OUTDIR}/topup/${sub}_FieldmapAP_PA.nii.gz ${OUTDIR}/topup/${sub}_FieldmapAP_PA.nii.gz 0 -1 0 -1 1 -1 0 -1
    #topup --imain="${OUTDIR}/topup/${sub}_FieldmapAP_PA" --datain="${OUTDIR}/topup/${sub}_acqparamsAP_PA.txt" --config=b02b0.cnf --out="${OUTDIR}/topup/${sub}_my_topup_results1" --fout="${SUBDIR}fmap/${sub}_fieldmap" --iout="${OUTDIR}/topup/${sub}_my_unwarped_images"
    # to use topup config file for odd slices uncomment line below and comment lines above
    echo "odd number of slices: run topup with specific config file"
    topup --imain="${OUTDIR}/topup/${sub}_FieldmapAP_PA" --datain="${OUTDIR}/topup/${sub}_acqparamsAP_PA.txt" --config=/Users/jsein/hubiC/JUL/Topup_Physio_BIDS/b02b0_oddslices.cnf --out="${OUTDIR}/topup/${sub}_my_topup_results1" --fout="${SUBDIR}fmap/${sub}_fieldmap" --iout="${OUTDIR}/topup/${sub}_my_unwarped_images"

 else       
 	topup --imain="${OUTDIR}/topup/${sub}_FieldmapAP_PA" --datain="${OUTDIR}/topup/${sub}_acqparamsAP_PA.txt" --config=b02b0.cnf --out="${OUTDIR}/topup/${sub}_my_topup_results1" --fout="${SUBDIR}fmap/${sub}_fieldmap" --iout="${OUTDIR}/topup/${sub}_my_unwarped_images"
fi

# new line to extract first volume
fslroi "${SUBDIR}fmap/${sub}_fieldmap" "${SUBDIR}fmap/${sub}_fieldmap" 0 1
#
jq '. + { "Units": "Hz"}' "${SUBDIR}/fmap/${sub}_dir-AP_epi.json" > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}/fmap/${sub}_fieldmap.json"

#
fslmaths "${OUTDIR}/topup/${sub}_my_unwarped_images" -Tmean "${SUBDIR}fmap/${sub}_magnitude"

jq 'del(.IntendedFor)' "${SUBDIR}/"fmap/"${sub}_dir-AP_epi.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}/"fmap/"${sub}_dir-AP_epi.json"
jq 'del(.IntendedFor)' "${SUBDIR}/"fmap/"${sub}_dir-PA_epi.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}/"fmap/"${sub}_dir-PA_epi.json"
jq 'del(.IntendedFor)' "${SUBDIR}/"fmap/"${sub}_fieldmap.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}/"fmap/"${sub}_fieldmap.json"

shim1=$(jq .ShimSetting "${SUBDIR}fmap/${sub}_dir-AP_epi.json")	

list=$(ls "${SUBDIR}func/"*bold.nii.gz)

	for func in $list
	do
		shim2=$(jq .'ShimSetting' ${func//"nii.gz"/"json"})
		funci=${func//$SUBDIR/}
	 	if [ "$shim2" = "$shim1" ]
	 	then
	 		jq --arg funci $funci  '.IntendedFor |= .+  [$funci]' "${SUBDIR}"fmap/"${sub}_dir-AP_epi.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}"fmap/"${sub}_dir-AP_epi.json"
	 		jq --arg funci $funci  '.IntendedFor |= .+  [$funci]' "${SUBDIR}"fmap/"${sub}_dir-PA_epi.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}"fmap/"${sub}_dir-PA_epi.json"
	 		jq --arg funci $funci  '.IntendedFor |= .+  [$funci]' "${SUBDIR}"fmap/"${sub}_fieldmap.json"  > "${OUTDIR}/tmp.$$.json" && mv  "${OUTDIR}/tmp.$$.json" "${SUBDIR}"fmap/"${sub}_fieldmap.json"
	 	fi
	 done

done

Additionally, SDCFlows (which is called internally by fMRIPrep) can be run as a standalone tool on the command line, which is good if your data are in BIDS format.

1 Like

Thank u so much for your help!

Thank you so much for sharing your script with me because it has been a key to run the analysis!

Best,

Andrea

If it helps to someone, here i give you the script that i created basing it in the one from @jsein:

#!/bin/sh
#ml fsl #si no funciona escribir en el terminal
# Sesión 1
acq_parameters=/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/derivatives/task-rest_fieldmap_topup_acq_parameters.txt

for sub in 101 103 106
do
    sub=sub-${sub}
    echo -----starting subject $sub------

    SES1DIR=/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/${sub}/ses-1

    # Verificar si SES1DIR existe
    if [ -d "$SES1DIR" ]; then
        fslmerge -t "${SES1DIR}/fmap/${sub}_ses-1_AP_PA" "${SES1DIR}/fmap/${sub}_ses-1_task-rest_dir-AP_fieldmap.nii.gz" "${SES1DIR}/fmap/${sub}_ses-1_task-rest_dir-PA_fieldmap.nii.gz"
        topup --imain="${SES1DIR}/fmap/${sub}_ses-1_AP_PA" --datain="${acq_parameters}" --config=b02b0.cnf --out="${SES1DIR}/fmap/${sub}_ses-1_topup_results" --fout="${SES1DIR}/fmap/${sub}_ses-1_fieldmap" --iout="${SES1DIR}/fmap/${sub}_ses-1_magnitude"
    else
        echo "El directorio $SES1DIR no existe. Saltando a la siguiente iteración."
    fi
done

# Sesión 6
for sub in 101 103 106
do
    sub=sub-${sub}
    echo -----starting subject $sub------

    SES6DIR=/home/jovyan/neurodesktop-storage/Agueda/BIDS/derivatives/CONN/dynamic_prueba/BIDS/${sub}/ses-6

    # Verificar si SES6DIR existe
    if [ -d "$SES6DIR" ]; then
        fslmerge -t "${SES6DIR}/fmap/${sub}_ses-6_AP_PA" "${SES6DIR}/fmap/${sub}_ses-6_task-rest_dir-AP_fieldmap.nii.gz" "${SES6DIR}/fmap/${sub}_ses-6_task-rest_dir-PA_fieldmap.nii.gz"
        topup --imain="${SES6DIR}/fmap/${sub}_ses-6_AP_PA" --datain="${acq_parameters}" --config=b02b0.cnf --out="${SES6DIR}/fmap/${sub}_ses-6_topup_results" --fout="${SES6DIR}/fmap/${sub}_ses-6_fieldmap" --iout="${SES6DIR}/fmap/${sub}_ses-6_magnitude"
    else
        echo "El directorio $SES6DIR no existe. Saltando a la siguiente iteración."
    fi
done
1 Like