#!/bin/bash
# 错误处理函数
handle_error() {
local command="$1"
echo "错误:$command 执行失败于受试者 $subject"
echo "最后执行的命令: $BASH_COMMAND"
exit 1
}
# 定义数据路径
data_dir="/home/userroot/FMRI20250227/OLD_DATA"
output_dir="/home/userroot/FMRI20250227/fsl_fmri_pps_ds_250227"
standard_template="/home/userroot/fsl/data/standard/MNI152_T1_2mm_brain.nii.gz"
# 确保输出文件夹存在
mkdir -p "$output_dir" || { echo "无法创建输出目录"; exit 1; }
# 定义预处理参数
TR=2.5
fwhm=6
highpass_cutoff=0.01
lowpass_cutoff=0.1
# 计算时间滤波参数
hp_sigma=$(awk -v TR=$TR -v hpc=$highpass_cutoff 'BEGIN { print (1/(hpc*TR))/2 }')
lp_sigma=$(awk -v TR=$TR -v lpc=$lowpass_cutoff 'BEGIN { print (1/(lpc*TR))/2 }')
# 遍历受试者
for subject_dir in $(find "$data_dir" -mindepth 1 -maxdepth 1 -type d | sort); do
subject=$(basename "$subject_dir")
subject_output_dir="$output_dir/$subject"
# 检查是否为有效目录
if [ ! -d "$subject_dir" ]; then
echo "跳过非目录文件:$subject"
continue
fi
# 创建目录结构
mkdir -p "${subject_output_dir}"/{func,anat,reg,qc} || { echo "目录创建失败"; continue; }
# 获取数据文件
func_data=("$subject_dir"/*_REST.nii.gz)
struct_data=("$subject_dir"/*_T1.nii.gz)
# 检查文件数量
if [ ${#func_data[@]} -ne 1 ]; then
echo "错误:在 $subject_dir 中找到 ${#func_data[@]} 个功能数据文件"
continue
fi
if [ ${#struct_data[@]} -ne 1 ]; then
echo "错误:在 $subject_dir 中找到 ${#struct_data[@]} 个结构数据文件"
continue
fi
echo "正在处理受试者:$subject"
# 1. 删除前四个时间点
echo "步骤 1/10:删除前四个时间点"
fslroi "${func_data[0]}" "${subject_output_dir}/func/rest_tm.nii.gz" 4 -1 || handle_error "fslroi"
# 2. 切片时间校正
echo "步骤 2/10:切片时间校正"
slicetimer -i "${subject_output_dir}/func/rest_tm.nii.gz" \
-o "${subject_output_dir}/func/rest_tm_st.nii.gz" \
-r $TR --odd || handle_error "slicetimer"
# 3. 运动校正
echo "步骤 3/10:运动校正"
mcflirt -in "${subject_output_dir}/func/rest_tm_st.nii.gz" \
-out "${subject_output_dir}/func/rest_tm_st_mc" \
-mats -plots -rmsrel -rmsabs -report -stats || handle_error "mcflirt"
# 保存运动参数
mv "${subject_output_dir}/func/rest_tm_st_mc.par" "${subject_output_dir}/qc/motion.par" || { echo "无法移动运动参数文件"; continue; }
# 4. 计算均值图像
echo "步骤 4/10:计算功能像均值"
fslmaths "${subject_output_dir}/func/rest_tm_st_mc.nii.gz" \
-Tmean "${subject_output_dir}/func/rest_tm_st_mc_mean.nii.gz" || handle_error "fslmaths"
# 5. 功能像脑提取
echo "步骤 5.1/10:均值功能像脑提取"
bet "${subject_output_dir}/func/rest_tm_st_mc_mean.nii.gz" "${subject_output_dir}/func/rest_tm_st_mc_mean_bet.nii.gz" -f 0.3 -g 0.2 || handle_error "bet_rest"
# 5. 结构像脑提取
echo "步骤 5.2/10:结构像脑提取"
bet "${struct_data[0]}" "${subject_output_dir}/anat/T1_brain.nii.gz" \
-B -R -f 0.5 -g -0.2 \
# 6. 功能像到结构像配准
echo "步骤 6/10:功能像到结构像配准"
flirt -in "${subject_output_dir}/func/rest_tm_st_mc_mean_bet.nii.gz" \
-ref "${subject_output_dir}/anat/T1_brain.nii.gz" \
-out "${subject_output_dir}/func/rest_st_mc_reg.nii.gz" \
-omat "${subject_output_dir}/reg/func2anat.mat" \
-dof 12 -cost normmi \
-searchrx -30 30 -searchry -30 30 -searchrz -30 30 || handle_error "flirt"
# 7. 结构像到标准空间线性配准
echo "步骤 7/10:结构像线性配准"
flirt -in "${subject_output_dir}/anat/T1_brain.nii.gz" \
-ref "$standard_template" \
-out "${subject_output_dir}/reg/T1_lin2mni.nii.gz" \
-omat "${subject_output_dir}/reg/lin2mni.mat" \
-dof 12 \
-interp trilinear || handle_error "flirt"
# 8. 非线性配准 (FNIRT)
echo "步骤 8/10:非线性配准"
fnirt --in="${subject_output_dir}/anat/T1_brain.nii.gz" \
--aff="${subject_output_dir}/reg/lin2mni.mat" \
--ref="$standard_template" \
--cout="${subject_output_dir}/reg/T1_warpcoef.nii.gz" \
--config=T1_2_MNI152_2mm \
--iout="${subject_output_dir}/reg/T1_nlin2mni.nii.gz" || { echo "FNIRT失败"; continue; }
# 9. 应用变形场到功能数据
echo "步骤 9/10:应用变形场"
applywarp --in="${subject_output_dir}/func/rest_tm_st_mc.nii.gz" \
--ref="$standard_template" \
--warp="${subject_output_dir}/reg/T1_warpcoef.nii.gz" \
--out="${subject_output_dir}/func/rest_mni.nii.gz" \
--premat="${subject_output_dir}/reg/func2anat.mat" \
--interp=spline --verbose || handle_error "applywarp"
# 10. 时间滤波和空间平滑
echo "步骤 10/10:时间滤波和平滑"
fslmaths "${subject_output_dir}/func/rest_mni.nii.gz" \
-Tmean "${subject_output_dir}/func/rest_mni_mean.nii.gz" || handle_error "fslmaths"
fslmaths "${subject_output_dir}/func/rest_mni.nii.gz" \
-bptf $hp_sigma $lp_sigma \
-add "${subject_output_dir}/func/rest_mni_mean.nii.gz" \
"${subject_output_dir}/func/rest_mni_filt.nii.gz" || handle_error "fslmaths"
fslmaths "${subject_output_dir}/func/rest_mni_filt.nii.gz" \
-s $fwhm \
"${subject_output_dir}/func/rest_mni_filt_sm.nii.gz" || handle_error "fslmaths"
echo "受试者:"$subject" 已处理完"
done
echo "全部处理完成!"
find "/home/userroot/FMRI20250227/OLD_DATA" -mindepth 1 -maxdepth 1 -type d | sort > subjects_list.txt
cat subjects_list.txt | parallel -j 32 bash fsl_fmri_pps_ds_250224.sh {}