From 0a8d2e3ed65ced7a35f215ede0a0b0cd028d0365 Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Tue, 25 Aug 2026 10:57:57 -0500 Subject: [PATCH 1/7] Add hippocampal fMRISurface processing --- ...ippocampusfMRISurfaceProcessingPipeline.sh | 215 +++++++ .../HippocampalVolumeToSurfaceMapping.sh | 538 ++++++++++++++++++ 2 files changed, 753 insertions(+) create mode 100755 fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh create mode 100755 fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh diff --git a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh new file mode 100755 index 000000000..c38c0f72c --- /dev/null +++ b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh @@ -0,0 +1,215 @@ +#!/bin/bash + +# Requirements for this script +# installed versions of: FSL, Connectome Workbench (wb_command) +# environment: HCPPIPEDIR, FSLDIR, CARET7DIR + +########################################## PIPELINE OVERVIEW ########################################## + +# TODO + +########################################## OUTPUT DIRECTORIES ########################################## + +# TODO + +################################################ SUPPORT FUNCTIONS ################################################## + +set -eu +pipedirguessed=0 +if [[ "${HCPPIPEDIR:-}" == "" ]] +then + pipedirguessed=1 + # Fix this if the script is more than one level below HCPPIPEDIR + export HCPPIPEDIR="$(dirname -- "$0")/.." +fi + +#comment the line back in when done +source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +source "${HCPPIPEDIR}/global/scripts/newopts.shlib" "$@" +source "${HCPPIPEDIR}/global/scripts/processingmodecheck.shlib" # Check processing mode requirements + +opts_SetScriptDescription "Run hippocampal fMRISurface processing" + +opts_AddMandatory '--studyfolder' 'Path' 'path' "folder containing all subjects" "--path" + +opts_AddMandatory '--subject' 'Subject' 'subject ID' "" + +opts_AddMandatory '--fmriname' 'NameOffMRI' 'string' 'fMRI run name, for example rfMRI_REST1_LR' + +opts_AddOptional '--procstring' 'ProcString' 'string' 'processing suffix appended to the 4D fMRI filename; include the leading underscore' "" + +opts_AddMandatory '--smoothingFWHM' 'SmoothingFWHM' 'number' 'smoothing FWHM (mm)' + +opts_AddOptional '--fmri-qc' 'QCMode' 'YES OR NO OR ONLY' "Controls whether to generate a QC scene and snapshots (default=YES). ONLY executes just the QC script." "YES" + +opts_AddOptional '--output-directory' 'OutputDirectory' 'path' 'Directory where pipeline outputs will be written' "" + +opts_AddOptional '--goodvoxel' 'doGoodVoxels' 'YES OR NO' "Controls whether to do goodVoxel procedure (default = YES)" "YES" + +opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels" + +opts_ParseArguments "$@" + +if ((pipedirguessed)) +then + log_Err_Abort "HCPPIPEDIR is not set; first source your edited copy of Examples/Scripts/SetUpHCPPipeline.sh" +fi + +opts_ShowValues + +"${HCPPIPEDIR}/show_version" + +# ------------------------------------------------------------------------------ +# Verify required environment variables are set +# ------------------------------------------------------------------------------ + +log_Check_Env_Var HCPPIPEDIR +log_Check_Env_Var FSLDIR +log_Check_Env_Var CARET7DIR + +HCPPIPEDIR_fMRISurf="${HCPPIPEDIR}/fMRISurface/scripts" + +# ------------------------------------------------------------------------------ +# Parse command-line options +# ------------------------------------------------------------------------------ + +log_Msg "Platform Information Follows:" +uname -a + +QCMode="$(echo "${QCMode}" | tr '[:upper:]' '[:lower:]')" + +doProcessing=1 +doQC=1 + +case "${QCMode}" in + yes) + ;; + no) + doQC=0 + ;; + only) + doProcessing=0 + log_Warn "Only generating fMRI QC scene and snapshots from existing data" + ;; + *) + log_Err_Abort "Unrecognized value '${QCMode}' for --fmri-qc; use YES, NO, or ONLY" + ;; +esac + + +# ------------------------------------------------------------------------------ +# Set up paths +# ------------------------------------------------------------------------------ + +PipelineScripts="${HCPPIPEDIR_fMRISurf}" + +MainSubjectFolder="${Path}/${Subject}" +AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear" +InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" +ResultsFolderName="Results" + +if [ -n "${OutputDirectory}" ]; then + ResultsFolder="${OutputDirectory}/${Subject}/${NameOffMRI}" +else + ResultsFolder="${AtlasSpaceFolder}/${ResultsFolderName}/${NameOffMRI}" +fi + +WorkingDirectory="${ResultsFolder}/tmp" + +mkdir -p "${WorkingDirectory}" + +VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}" + +SBRef="${InputResultsFolder}/${NameOffMRI}_SBRef.nii.gz" + +HippUnfoldFolder="${AtlasSpaceFolder}/HippUnfold" + +if [ ! -f "${VolumefMRI}.nii.gz" ]; then + log_Err_Abort "Cannot find selected fMRI file: ${VolumefMRI}.nii.gz" +fi + +if [ ! -f "${SBRef}" ]; then + log_Err_Abort "Cannot find selected SBRef file: ${SBRef}" +fi + +log_Msg "Selected fMRI file: ${VolumefMRI}.nii.gz" +log_Msg "Selected SBRef file: ${SBRef}" + +# ------------------------------------------------------------------------------ +# Generate fMRI time series within ROIs +# ------------------------------------------------------------------------------ + +if ((doProcessing)); then + + # Make fMRI ribbon + log_Msg "Make fMRI Ribbon" + log_Msg "mkdir -p ${WorkingDirectory}" + + log_Msg "Hippocampal Volume To Surface Mapping" + "${PipelineScripts}/HippocampalVolumeToSurfaceMapping.sh" \ + "${WorkingDirectory}" \ + "${Subject}" \ + "${HippUnfoldFolder}" \ + "${VolumefMRI}" \ + "${SBRef}" \ + "${doGoodVoxels}" \ + "${factor}" + +#Surface Smoothing + # ------------------------------------------------------------------------------ +# Hippocampal Surface Smoothing +# ------------------------------------------------------------------------------ + + log_Msg "Hippocampal Surface Smoothing" + + Sigma=`echo "$SmoothingFWHM / (2 * sqrt(2 * l(2)))" | bc -l` + + Meshes=(native 512 2k 8k 18k) + Structures=(hipp dentate) + + for Mesh in "${Meshes[@]}"; do + for Structure in "${Structures[@]}"; do + for Hemisphere in L R; do + "${CARET7DIR}/wb_command" -metric-smoothing \ + "${HippUnfoldFolder}/${Mesh}/${Subject}.${Hemisphere}.${Structure}_midthickness.${Mesh}.surf.gii" \ + "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI.${Mesh}.func.gii" \ + "${Sigma}" \ + "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_ones.${Mesh}.func.gii" + done + done + done +# ------------------------------------------------------------------------------ +# Combining ROIs into a single CIFTI file +# ------------------------------------------------------------------------------ + + + for Mesh in ${Meshes[@]}; do + "${CARET7DIR}/wb_command" -cifti-create-dense-timeseries \ + "${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}.${Mesh}.dtseries.nii" \ + -metric HIPPOCAMPUS_LEFT "${WorkingDirectory}/${Subject}.L.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.L.hipp_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_RIGHT "${WorkingDirectory}/${Subject}.R.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.R.hipp_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_DENTATE_LEFT "${WorkingDirectory}/${Subject}.L.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.L.dentate_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_DENTATE_RIGHT "${WorkingDirectory}/${Subject}.R.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.R.dentate_ones.${Mesh}.func.gii" + + log_Msg "Generated fMRI time series Cifti file: "${ResultsFolder}/${Subject}.${NameOffMRI}"_AtlasHipp_${ProcString}.${Mesh}.dtseries.nii" + done +fi + +#Uncomment if want to remove the subfoler with intermediate files +#rm -rf "${WorkingDirectory}" + +# if ((doQC)); then +# log_Msg "Generating fMRI QC scene and snapshots" +# "${PipelineScripts}/GenerateFMRIScenes.sh" \ +# --study-folder="${Path}" \ +# --subject="${Subject}" \ +# --fmriname="${NameOffMRI}${ProcString}" \ +# --output-folder="${ResultsFolder}/fMRIQC" +# fi + +log_Msg "Completed!" \ No newline at end of file diff --git a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh new file mode 100755 index 000000000..f942ca482 --- /dev/null +++ b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh @@ -0,0 +1,538 @@ +#!/bin/bash + +# -------------------------------------------------------------------------------- +# Usage Description Function +# -------------------------------------------------------------------------------- + +script_name=$(basename "${0}") + +show_usage() { + cat < 0" \ + "${BinaryRibbon}" \ + -var x \ + "${ProbabilisticRibbon}" + + + # ------------------------------------------------------------------------------ + # Generating good-voxel mask for each structure + # ------------------------------------------------------------------------------ + + if [[ "${doGoodVoxels}" == "YES" ]]; then + + fslmaths "${WorkingDirectory}/${Subject}.cov" \ + -mas "${BinaryRibbon}" \ + "${WorkingDirectory}/${Prefix}_cov_ribbon" + + meanIntensity=$(fslstats "${WorkingDirectory}/${Prefix}_cov_ribbon" -M) + + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon" \ + -div ${meanIntensity} \ + "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" + + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" \ + -bin \ + -s "${NeighborhoodSmoothing}" \ + "${WorkingDirectory}/${Prefix}_SmoothNorm" + + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" \ + -s "${NeighborhoodSmoothing}" \ + -div "${WorkingDirectory}/${Prefix}_SmoothNorm" \ + -dilD \ + "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" + + fslmaths "${WorkingDirectory}/${Subject}.cov" \ + -div ${meanIntensity} \ + -div "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" \ + "${WorkingDirectory}/${Prefix}_cov_norm_modulate" + + fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" \ + -mas "${BinaryRibbon}" \ + "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" + + STD=$(fslstats \ + "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" \ + -S) + + echo "STD: ${STD}" + + MEAN=$(fslstats \ + "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" \ + -M) + + echo "MEAN: ${MEAN}" + + Lower=$(echo "${MEAN} - (${STD} * ${Factor})" | bc -l) + echo "LOWER: ${Lower}" + + Upper=$(echo "${MEAN} + (${STD} * ${Factor})" | bc -l) + echo "UPPER: ${Upper}" + + fslmaths "${WorkingDirectory}/${Subject}.mean" \ + -bin \ + "${WorkingDirectory}/${Prefix}_mask" + + fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" \ + -thr "${Upper}" \ + -bin \ + -sub "${WorkingDirectory}/${Prefix}_mask" \ + -mul -1 \ + -mas "${BinaryRibbon}" \ + "${WorkingDirectory}/${Prefix}_goodvoxels" + fi + + + NativeFolder="${HippUnfoldFolder}/native" + + InnerSurface="${NativeFolder}/${Prefix}_inner.native.surf.gii" + MidSurface="${NativeFolder}/${Prefix}_midthickness.native.surf.gii" + OuterSurface="${NativeFolder}/${Prefix}_outer.native.surf.gii" + + NativeFlat="${NativeFolder}/${Prefix}_flat.native.surf.gii" + NativeSurfArea="${NativeFolder}/${Prefix}_surfarea.native.shape.gii" + + NativeROI="${WorkingDirectory}/${Prefix}_ones.native.func.gii" + + + # ===================================================================== + # Map mean and covariance volumes + # ===================================================================== + + for Map in mean cov; do + + NativeMetric="${WorkingDirectory}/${Prefix}_${Map}.native.func.gii" + NativeAllMetric="${WorkingDirectory}/${Prefix}_${Map}_all.native.func.gii" + + + # ----------------------------------------------------------------- + # Map using good voxels + # ----------------------------------------------------------------- + + if [[ "${doGoodVoxels}" == "YES" ]]; then + + "${WB}" -volume-to-surface-mapping \ + "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ + "${MidSurface}" \ + "${NativeMetric}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ + -dilate-missing ${dilation_dist} \ + -nearest + + else + + "${WB}" -volume-to-surface-mapping \ + "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ + "${MidSurface}" \ + "${NativeMetric}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -dilate-missing ${dilation_dist} \ + -nearest + fi + + "${WB}" -metric-dilate \ + "${NativeMetric}" \ + "${MidSurface}" \ + "${dilation_dist}" \ + "${NativeMetric}" \ + -nearest + + "${WB}" -metric-mask \ + "${NativeMetric}" \ + "${NativeROI}" \ + "${NativeMetric}" + + + # ----------------------------------------------------------------- + # Map using all ribbon voxels + # ----------------------------------------------------------------- + + "${WB}" -volume-to-surface-mapping \ + "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ + "${MidSurface}" \ + "${NativeAllMetric}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -dilate-missing ${dilation_dist} \ + -nearest + + "${WB}" -metric-mask \ + "${NativeAllMetric}" \ + "${NativeROI}" \ + "${NativeAllMetric}" + + + # ----------------------------------------------------------------- + # Resample native metrics using unfolded flat surfaces + # ----------------------------------------------------------------- + + for Mesh in ${Meshes[@]}; do + + MeshFolder="${HippUnfoldFolder}/${Mesh}" + + TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" + TargetSurfArea="${MeshFolder}/${Prefix}_surfarea.${Mesh}.shape.gii" + + TargetROI="${WorkingDirectory}/${Prefix}_ones.${Mesh}.func.gii" + + TargetMetric="${WorkingDirectory}/${Prefix}_${Map}.${Mesh}.func.gii" + TargetAllMetric="${WorkingDirectory}/${Prefix}_${Map}_all.${Mesh}.func.gii" + + + "${WB}" -metric-math \ + "x * 0 + 1" \ + "${TargetROI}" \ + -var x "${TargetSurfArea}" + + + "${WB}" -metric-resample \ + "${NativeMetric}" \ + "${NativeFlat}" \ + "${TargetFlat}" \ + ADAP_BARY_AREA \ + "${TargetMetric}" \ + -area-surfs \ + "${MidSurface}" \ + "${TargetMidSurface}" \ + -current-roi "${NativeROI}" \ + -bypass-sphere-check + + "${WB}" -metric-mask \ + "${TargetMetric}" \ + "${TargetROI}" \ + "${TargetMetric}" + + + "${WB}" -metric-resample \ + "${NativeAllMetric}" \ + "${NativeFlat}" \ + "${TargetFlat}" \ + ADAP_BARY_AREA \ + "${TargetAllMetric}" \ + -area-surfs \ + "${MidSurface}" \ + "${TargetMidSurface}" \ + -current-roi "${NativeROI}" \ + -bypass-sphere-check + + "${WB}" -metric-mask \ + "${TargetAllMetric}" \ + "${TargetROI}" \ + "${TargetAllMetric}" + + + done + + + # ===================================================================== + # Map goodvoxels in volume space + # ===================================================================== + + if [[ "${doGoodVoxels}" == "YES" ]]; then + + NativeGoodVoxels="${WorkingDirectory}/${Prefix}_goodvoxels.native.func.gii" + + "${WB}" -volume-to-surface-mapping \ + "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ + "${MidSurface}" \ + "${NativeGoodVoxels}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -dilate-missing ${dilation_dist} \ + -nearest + + "${WB}" -metric-mask \ + "${NativeGoodVoxels}" \ + "${NativeROI}" \ + "${NativeGoodVoxels}" + + + for Mesh in ${Meshes[@]}; do + + MeshFolder="${HippUnfoldFolder}/${Mesh}" + + TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" + TargetROI="${WorkingDirectory}/${Prefix}_ones.${Mesh}.func.gii" + + TargetGoodVoxels="${WorkingDirectory}/${Prefix}_goodvoxels.${Mesh}.func.gii" + + + "${WB}" -metric-resample \ + "${NativeGoodVoxels}" \ + "${NativeFlat}" \ + "${TargetFlat}" \ + ADAP_BARY_AREA \ + "${TargetGoodVoxels}" \ + -area-surfs \ + "${MidSurface}" \ + "${TargetMidSurface}" \ + -current-roi "${NativeROI}" \ + -bypass-sphere-check + + "${WB}" -metric-mask \ + "${TargetGoodVoxels}" \ + "${TargetROI}" \ + "${TargetGoodVoxels}" + + done + + fi + + + # ===================================================================== + # Map complete fMRI timeseries to native hippocampal surface + # ===================================================================== + + NativefMRI="${WorkingDirectory}/${Prefix}_fMRI.native.func.gii" + + + if [[ "${doGoodVoxels}" == "YES" ]]; then + + "${WB}" -volume-to-surface-mapping \ + "${VolumefMRI}.nii.gz" \ + "${MidSurface}" \ + "${NativefMRI}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ + -dilate-missing ${dilation_dist} \ + -nearest + + else + + "${WB}" -volume-to-surface-mapping \ + "${VolumefMRI}.nii.gz" \ + "${MidSurface}" \ + "${NativefMRI}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -dilate-missing ${dilation_dist} \ + -nearest + + fi + + + "${WB}" -metric-dilate \ + "${NativefMRI}" \ + "${MidSurface}" \ + "${dilation_dist}" \ + "${NativefMRI}" \ + -nearest + + "${WB}" -metric-mask \ + "${NativefMRI}" \ + "${NativeROI}" \ + "${NativefMRI}" + + log_Msg "Generated fMRI file in native space at: ${NativefMRI}" + + + # ===================================================================== + # Resample complete fMRI timeseries to all densities + # ===================================================================== + + for Mesh in ${Meshes[@]}; do + + MeshFolder="${HippUnfoldFolder}/${Mesh}" + + TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" + TargetROI="${WorkingDirectory}/${Prefix}_ones.${Mesh}.func.gii" + + TargetfMRI="${WorkingDirectory}/${Prefix}_fMRI.${Mesh}.func.gii" + + + "${WB}" -metric-resample \ + "${NativefMRI}" \ + "${NativeFlat}" \ + "${TargetFlat}" \ + ADAP_BARY_AREA \ + "${TargetfMRI}" \ + -area-surfs \ + "${MidSurface}" \ + "${TargetMidSurface}" \ + -current-roi "${NativeROI}" \ + -bypass-sphere-check + + + "${WB}" -metric-dilate \ + "${TargetfMRI}" \ + "${TargetMidSurface}" \ + ${dilation_dist} \ + "${TargetfMRI}" \ + -nearest + + + "${WB}" -metric-mask \ + "${TargetfMRI}" \ + "${TargetROI}" \ + "${TargetfMRI}" + + + log_Msg "Generated fMRI file in ${Mesh} mesh at: ${TargetfMRI}" + + + done + done + done +done + +# ===================================================================== +# All voxel mask an good voxel mask +# ===================================================================== + +fslmaths "${WorkingDirectory}/${Subject}.L.hipp.ribbon.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.R.hipp.ribbon.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.L.dentate.ribbon.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.R.dentate.ribbon.nii.gz" \ + -bin \ + "${WorkingDirectory}/${Subject}.allStructures.allVoxels.ribbon.nii.gz" + +fslmaths "${WorkingDirectory}/${Subject}.L.hipp_goodvoxels.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.R.hipp_goodvoxels.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.L.dentate_goodvoxels.nii.gz" \ + -add "${WorkingDirectory}/${Subject}.R.dentate_goodvoxels.nii.gz" \ + -bin \ + "${WorkingDirectory}/${Subject}.all_structures.goodvoxels.nii.gz" From faa663acd7db2efaeaa0b4b266cad14e4cb23f0b Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Fri, 28 Aug 2026 10:20:27 -0500 Subject: [PATCH 2/7] Address hippocampal fMRISurface review comments --- .../HippocampalVolumeToSurfaceMapping.sh | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh index f942ca482..1f867e9ee 100755 --- a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh +++ b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh @@ -30,8 +30,8 @@ if [ -z "${HCPPIPEDIR}" ]; then exit 1 fi -source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib -#source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib +#source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib source "${HCPPIPEDIR}/global/scripts/opts.shlib" # Command line option functions opts_ShowVersionIfRequested "$@" @@ -358,10 +358,9 @@ for Structure in hipp dentate; do "${TargetROI}" \ "${TargetAllMetric}" - + done done - # ===================================================================== # Map goodvoxels in volume space # ===================================================================== @@ -453,7 +452,6 @@ for Structure in hipp dentate; do fi - "${WB}" -metric-dilate \ "${NativefMRI}" \ "${MidSurface}" \ @@ -513,26 +511,26 @@ for Structure in hipp dentate; do log_Msg "Generated fMRI file in ${Mesh} mesh at: ${TargetfMRI}" + # ===================================================================== + # Map VN volume to native hippocampal surface + # ===================================================================== - done + VolumefMRIVN="${VolumefMRI}_vn.nii.gz" + TargetfMRIVN="${WorkingDirectory}/${Prefix}_fMRI_vn.${Mesh}.func.gii" + + "${WB}" -volume-to-surface-mapping \ + "${VolumefMRIVN}" \ + "${TargetMidSurface}" \ + "${TargetfMRIVN}" \ + -cubic + + "${WB}" -metric-mask \ + "${TargetfMRIVN}" \ + "${TargetROI}" \ + "${TargetfMRIVN}" + + log_Msg "Generated VN file in ${Mesh} mesh at: ${TargetfMRIVN}" done done done -# ===================================================================== -# All voxel mask an good voxel mask -# ===================================================================== - -fslmaths "${WorkingDirectory}/${Subject}.L.hipp.ribbon.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.R.hipp.ribbon.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.L.dentate.ribbon.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.R.dentate.ribbon.nii.gz" \ - -bin \ - "${WorkingDirectory}/${Subject}.allStructures.allVoxels.ribbon.nii.gz" - -fslmaths "${WorkingDirectory}/${Subject}.L.hipp_goodvoxels.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.R.hipp_goodvoxels.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.L.dentate_goodvoxels.nii.gz" \ - -add "${WorkingDirectory}/${Subject}.R.dentate_goodvoxels.nii.gz" \ - -bin \ - "${WorkingDirectory}/${Subject}.all_structures.goodvoxels.nii.gz" From 66e912f3adda925af536bc9ff2fbb930233bddab Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Fri, 28 Aug 2026 12:34:17 -0500 Subject: [PATCH 3/7] Update hippocampal fMRISurface processing --- ...ippocampusfMRISurfaceProcessingPipeline.sh | 24 +++++++++++- .../HippocampalVolumeToSurfaceMapping.sh | 39 ++++++++++++++----- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh index c38c0f72c..ba6f7dbee 100755 --- a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh +++ b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh @@ -197,6 +197,28 @@ if ((doProcessing)); then -roi "${WorkingDirectory}/${Subject}.R.dentate_ones.${Mesh}.func.gii" log_Msg "Generated fMRI time series Cifti file: "${ResultsFolder}/${Subject}.${NameOffMRI}"_AtlasHipp_${ProcString}.${Mesh}.dtseries.nii" + +# -------------------------------------------------------------------------- +# Combine VN maps from all four hippocampal structures +# -------------------------------------------------------------------------- + + "${CARET7DIR}/wb_command" -cifti-create-dense-scalar \ + "${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}_vn.${Mesh}.dscalar.nii" \ + -metric HIPPOCAMPUS_LEFT \ + "${WorkingDirectory}/${Subject}.L.hipp_fMRI_vn.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.L.hipp_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_RIGHT \ + "${WorkingDirectory}/${Subject}.R.hipp_fMRI_vn.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.R.hipp_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_DENTATE_LEFT \ + "${WorkingDirectory}/${Subject}.L.dentate_fMRI_vn.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.L.dentate_ones.${Mesh}.func.gii" \ + -metric HIPPOCAMPUS_DENTATE_RIGHT \ + "${WorkingDirectory}/${Subject}.R.dentate_fMRI_vn.${Mesh}.func.gii" \ + -roi "${WorkingDirectory}/${Subject}.R.dentate_ones.${Mesh}.func.gii" + + log_Msg "Generated VN CIFTI file: ${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}_vn.${Mesh}.dscalar.nii" + done fi @@ -212,4 +234,4 @@ fi # --output-folder="${ResultsFolder}/fMRIQC" # fi -log_Msg "Completed!" \ No newline at end of file +log_Msg "Completed!" diff --git a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh index 1f867e9ee..2bc550bcd 100755 --- a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh +++ b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh @@ -440,15 +440,15 @@ for Structure in hipp dentate; do else - "${WB}" -volume-to-surface-mapping \ - "${VolumefMRI}.nii.gz" \ - "${MidSurface}" \ - "${NativefMRI}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -dilate-missing ${dilation_dist} \ - -nearest + "${WB}" -volume-to-surface-mapping \ + "${VolumefMRI}.nii.gz" \ + "${MidSurface}" \ + "${NativefMRI}" \ + -ribbon-constrained \ + "${InnerSurface}" \ + "${OuterSurface}" \ + -dilate-missing ${dilation_dist} + -nearest fi @@ -456,7 +456,7 @@ for Structure in hipp dentate; do "${NativefMRI}" \ "${MidSurface}" \ "${dilation_dist}" \ - "${NativefMRI}" \ + "${NativefMRI}" -nearest "${WB}" -metric-mask \ @@ -466,7 +466,26 @@ for Structure in hipp dentate; do log_Msg "Generated fMRI file in native space at: ${NativefMRI}" + # ===================================================================== + # Map VN volume to native hippocampal surface + # ===================================================================== + + VolumefMRIVN="${VolumefMRI}_vn.nii.gz" + NativefMRIVN="${WorkingDirectory}/${Prefix}_fMRI_vn.native.func.gii" + + "${WB}" -volume-to-surface-mapping \ + "${VolumefMRIVN}" \ + "${MidSurface}" \ + "${NativefMRIVN}" \ + -cubic + + "${WB}" -metric-mask \ + "${NativefMRIVN}" \ + "${NativeROI}" \ + "${NativefMRIVN}" + log_Msg "Generated VN file in native space at: ${NativefMRIVN}" + # ===================================================================== # Resample complete fMRI timeseries to all densities # ===================================================================== From f1c00148aece9b3252bbf3ea5ec803c36d3099a7 Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Thu, 3 Sep 2026 13:47:25 -0500 Subject: [PATCH 4/7] Update hippocampalfMRISurface processing --- ...ippocampusfMRISurfaceProcessingPipeline.sh | 164 ++----- .../HippocampalVolumeToSurfaceMapping.sh | 451 +++++------------- 2 files changed, 140 insertions(+), 475 deletions(-) diff --git a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh index ba6f7dbee..d6a63d179 100755 --- a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh +++ b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -eu # Requirements for this script # installed versions of: FSL, Connectome Workbench (wb_command) # environment: HCPPIPEDIR, FSLDIR, CARET7DIR @@ -24,7 +24,9 @@ then fi #comment the line back in when done -source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +#source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib + source "${HCPPIPEDIR}/global/scripts/newopts.shlib" "$@" source "${HCPPIPEDIR}/global/scripts/processingmodecheck.shlib" # Check processing mode requirements @@ -40,14 +42,11 @@ opts_AddOptional '--procstring' 'ProcString' 'string' 'processing suffix appende opts_AddMandatory '--smoothingFWHM' 'SmoothingFWHM' 'number' 'smoothing FWHM (mm)' -opts_AddOptional '--fmri-qc' 'QCMode' 'YES OR NO OR ONLY' "Controls whether to generate a QC scene and snapshots (default=YES). ONLY executes just the QC script." "YES" - -opts_AddOptional '--output-directory' 'OutputDirectory' 'path' 'Directory where pipeline outputs will be written' "" - opts_AddOptional '--goodvoxel' 'doGoodVoxels' 'YES OR NO' "Controls whether to do goodVoxel procedure (default = YES)" "YES" -opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels" +opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels (default = 1.5)" "1.5" +opts_AddOptional '--resample_mesh' 'MeshString' 'string' 'Resample native mesh to: 512, 2k, 8k, or 18k. Use quote for multiple meshes, e.g. "512 2k 8k"' "512 2k 8k 18k" opts_ParseArguments "$@" if ((pipedirguessed)) @@ -76,162 +75,59 @@ HCPPIPEDIR_fMRISurf="${HCPPIPEDIR}/fMRISurface/scripts" log_Msg "Platform Information Follows:" uname -a -QCMode="$(echo "${QCMode}" | tr '[:upper:]' '[:lower:]')" - -doProcessing=1 -doQC=1 - -case "${QCMode}" in - yes) - ;; - no) - doQC=0 - ;; - only) - doProcessing=0 - log_Warn "Only generating fMRI QC scene and snapshots from existing data" - ;; - *) - log_Err_Abort "Unrecognized value '${QCMode}' for --fmri-qc; use YES, NO, or ONLY" - ;; -esac - - # ------------------------------------------------------------------------------ # Set up paths # ------------------------------------------------------------------------------ -PipelineScripts="${HCPPIPEDIR_fMRISurf}" - MainSubjectFolder="${Path}/${Subject}" AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear" InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" -ResultsFolderName="Results" - -if [ -n "${OutputDirectory}" ]; then - ResultsFolder="${OutputDirectory}/${Subject}/${NameOffMRI}" -else - ResultsFolder="${AtlasSpaceFolder}/${ResultsFolderName}/${NameOffMRI}" -fi - -WorkingDirectory="${ResultsFolder}/tmp" +ResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" +WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" #should 'HippocampalVolumeToSurfaceMapping' be a parameter?' mkdir -p "${WorkingDirectory}" -VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}" +VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}.nii.gz" SBRef="${InputResultsFolder}/${NameOffMRI}_SBRef.nii.gz" HippUnfoldFolder="${AtlasSpaceFolder}/HippUnfold" -if [ ! -f "${VolumefMRI}.nii.gz" ]; then - log_Err_Abort "Cannot find selected fMRI file: ${VolumefMRI}.nii.gz" +if [ ! -f "${VolumefMRI}" ]; then + log_Err_Abort "Cannot find selected fMRI file: ${VolumefMRI}" fi if [ ! -f "${SBRef}" ]; then log_Err_Abort "Cannot find selected SBRef file: ${SBRef}" fi -log_Msg "Selected fMRI file: ${VolumefMRI}.nii.gz" +#Parse MeshString into a mesh array +for Mesh in ${MeshString}; do + if [[ " 512 2k 8k 18k " != *" ${Mesh} "* ]]; then + log_Err_Abort "Invalid mesh: ${Mesh}" + fi +done +Meshes="native ${MeshString}" + +log_Msg "Selected fMRI file: ${VolumefMRI}" log_Msg "Selected SBRef file: ${SBRef}" # ------------------------------------------------------------------------------ -# Generate fMRI time series within ROIs +# Combining ROIs into a single CIFTI time series and vn file # ------------------------------------------------------------------------------ -if ((doProcessing)); then - - # Make fMRI ribbon - log_Msg "Make fMRI Ribbon" - log_Msg "mkdir -p ${WorkingDirectory}" - - log_Msg "Hippocampal Volume To Surface Mapping" - "${PipelineScripts}/HippocampalVolumeToSurfaceMapping.sh" \ - "${WorkingDirectory}" \ - "${Subject}" \ - "${HippUnfoldFolder}" \ - "${VolumefMRI}" \ - "${SBRef}" \ - "${doGoodVoxels}" \ - "${factor}" - -#Surface Smoothing - # ------------------------------------------------------------------------------ -# Hippocampal Surface Smoothing -# ------------------------------------------------------------------------------ +log_Msg "mkdir -p ${WorkingDirectory}" +log_Msg "Hippocampal Volume To Surface Mapping" - log_Msg "Hippocampal Surface Smoothing" - - Sigma=`echo "$SmoothingFWHM / (2 * sqrt(2 * l(2)))" | bc -l` - - Meshes=(native 512 2k 8k 18k) - Structures=(hipp dentate) - - for Mesh in "${Meshes[@]}"; do - for Structure in "${Structures[@]}"; do - for Hemisphere in L R; do - "${CARET7DIR}/wb_command" -metric-smoothing \ - "${HippUnfoldFolder}/${Mesh}/${Subject}.${Hemisphere}.${Structure}_midthickness.${Mesh}.surf.gii" \ - "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI.${Mesh}.func.gii" \ - "${Sigma}" \ - "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_ones.${Mesh}.func.gii" - done - done - done -# ------------------------------------------------------------------------------ -# Combining ROIs into a single CIFTI file -# ------------------------------------------------------------------------------ +# Generate fMRI time series for each of the hippocampal structures: L hipp, R hipp, L dentate, R dentate +"${HCPPIPEDIR_fMRISurf}/HippocampalVolumeToSurfaceMapping.sh" "${ResultsFolder}" "${Subject}" "${HippUnfoldFolder}" "${VolumefMRI}" "${SBRef}" "${doGoodVoxels}" "${factor}" "${Meshes}" - for Mesh in ${Meshes[@]}; do - "${CARET7DIR}/wb_command" -cifti-create-dense-timeseries \ - "${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}.${Mesh}.dtseries.nii" \ - -metric HIPPOCAMPUS_LEFT "${WorkingDirectory}/${Subject}.L.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.L.hipp_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_RIGHT "${WorkingDirectory}/${Subject}.R.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.R.hipp_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_LEFT "${WorkingDirectory}/${Subject}.L.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.L.dentate_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_RIGHT "${WorkingDirectory}/${Subject}.R.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.R.dentate_ones.${Mesh}.func.gii" - - log_Msg "Generated fMRI time series Cifti file: "${ResultsFolder}/${Subject}.${NameOffMRI}"_AtlasHipp_${ProcString}.${Mesh}.dtseries.nii" - -# -------------------------------------------------------------------------- -# Combine VN maps from all four hippocampal structures -# -------------------------------------------------------------------------- - - "${CARET7DIR}/wb_command" -cifti-create-dense-scalar \ - "${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}_vn.${Mesh}.dscalar.nii" \ - -metric HIPPOCAMPUS_LEFT \ - "${WorkingDirectory}/${Subject}.L.hipp_fMRI_vn.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.L.hipp_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_RIGHT \ - "${WorkingDirectory}/${Subject}.R.hipp_fMRI_vn.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.R.hipp_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_LEFT \ - "${WorkingDirectory}/${Subject}.L.dentate_fMRI_vn.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.L.dentate_ones.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_RIGHT \ - "${WorkingDirectory}/${Subject}.R.dentate_fMRI_vn.${Mesh}.func.gii" \ - -roi "${WorkingDirectory}/${Subject}.R.dentate_ones.${Mesh}.func.gii" - - log_Msg "Generated VN CIFTI file: ${ResultsFolder}/${NameOffMRI}_AtlasHipp_${ProcString}_vn.${Mesh}.dscalar.nii" - - done -fi +#Surface Smoothing of each hippocampal structure +"${HCPPIPEDIR_fMRISurf}/HippocampalSmoothing.sh" "${HippUnfoldFolder}" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${SmoothingFWHM}" "${Meshes}" -#Uncomment if want to remove the subfoler with intermediate files -#rm -rf "${WorkingDirectory}" +#Integration of the 4 hippocampal structures into single CIFTI timeseries and vn files +"${HCPPIPEDIR_fMRISurf}/CreateHippocampalCIFTIs.sh" "${ResultsFolder}" "${Subject}" "${NameOffMRI}" "${ProcString}" "${SmoothingFWHM}" "${Meshes}" -# if ((doQC)); then -# log_Msg "Generating fMRI QC scene and snapshots" -# "${PipelineScripts}/GenerateFMRIScenes.sh" \ -# --study-folder="${Path}" \ -# --subject="${Subject}" \ -# --fmriname="${NameOffMRI}${ProcString}" \ -# --output-folder="${ResultsFolder}/fMRIQC" -# fi +log_Msg "GenericHippocampusfMRISurfaceProcessingPipeline Completed!" -log_Msg "Completed!" diff --git a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh index 2bc550bcd..17f84e08a 100755 --- a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh +++ b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -eu # -------------------------------------------------------------------------------- # Usage Description Function # -------------------------------------------------------------------------------- @@ -16,7 +16,7 @@ EOF # Allow script to return a Usage statement, before any other output or checking -if [ "$#" = "0" ]; then +if [[ "$#" = "0" ]]; then show_usage exit 1 fi @@ -25,7 +25,7 @@ fi # Check that HCPPIPEDIR is defined and Load Function Libraries # ------------------------------------------------------------------------------ -if [ -z "${HCPPIPEDIR}" ]; then +if [[ -z "${HCPPIPEDIR}" ]]; then echo "${script_name}: ABORTING: HCPPIPEDIR environment variable must be set" exit 1 fi @@ -41,57 +41,34 @@ if opts_CheckForHelpRequest "$@"; then exit 0 fi -# ------------------------------------------------------------------------------ -# Verify required environment variables are set and log value -# ------------------------------------------------------------------------------ - -log_Check_Env_Var HCPPIPEDIR -log_Check_Env_Var CARET7DIR - # ------------------------------------------------------------------------------ # Start work # ------------------------------------------------------------------------------ -WorkingDirectory="$1" +ResultsFolder="$1" Subject="$2" HippUnfoldFolder="$3" VolumefMRI="$4" SBRef="$5" doGoodVoxels="$6" -Factor="$7" -#Factor="1" # Factor is a scaling factor for how many std units away from mean to set threshold +Factor="$7" # Factor is a scaling factor for how many std units away from mean to set threshold +Meshes="$8" # default: Meshes=(native 512 2k 8k 18k) + NeighborhoodSmoothing="5" # Distinguishes large vs small dropout dilation_dist="10" -Meshes=(512 2k 8k 18k) - -WB="${CARET7DIR}/wb_command" - -mkdir -p "${WorkingDirectory}" - -FirstRibbon="YES" +WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" # ------------------------------------------------------------------------------ # Generating mean, std, and coefficient of variation metric maps # ------------------------------------------------------------------------------ -fslmaths "${VolumefMRI}" \ - -Tmean "${WorkingDirectory}/${Subject}.mean" \ - -odt float - -fslmaths "${VolumefMRI}" \ - -Tstd "${WorkingDirectory}/${Subject}.std" \ - -odt float - -fslmaths "${WorkingDirectory}/${Subject}.std" \ - -div "${WorkingDirectory}/${Subject}.mean" \ - "${WorkingDirectory}/${Subject}.cov" - +fslmaths "${VolumefMRI}" -Tmean "${WorkingDirectory}/${Subject}.mean" -odt float +fslmaths "${VolumefMRI}" -Tstd "${WorkingDirectory}/${Subject}.std" -odt float +fslmaths "${WorkingDirectory}/${Subject}.std" -div "${WorkingDirectory}/${Subject}.mean" "${WorkingDirectory}/${Subject}.cov" for Structure in hipp dentate; do - for Hemisphere in L R; do - # ------------------------------------------------------------------------------ # Establishing input and output files # ------------------------------------------------------------------------------ @@ -99,7 +76,6 @@ for Structure in hipp dentate; do Prefix="${Subject}.${Hemisphere}.${Structure}" ThicknessMetric="${HippUnfoldFolder}/native/${Prefix}_thickness.native.shape.gii" - InnerSurface="${HippUnfoldFolder}/native/${Prefix}_inner.native.surf.gii" MidSurface="${HippUnfoldFolder}/native/${Prefix}_midthickness.native.surf.gii" OuterSurface="${HippUnfoldFolder}/native/${Prefix}_outer.native.surf.gii" @@ -113,38 +89,20 @@ for Structure in hipp dentate; do # Generating an all-ones surface metric # ------------------------------------------------------------------------------ - "${WB}" -metric-math \ - '1' \ - "${OnesMetric}" \ - -var x \ - "${ThicknessMetric}" - + wb_command -metric-math '1' "${OnesMetric}" -var x "${ThicknessMetric}" # ------------------------------------------------------------------------------ # Mapping the all-ones metric into SBRef volume space using the inner and # outer surfaces as ribbon boundaries # ------------------------------------------------------------------------------ - "${WB}" -metric-to-volume-mapping \ - "${OnesMetric}" \ - "${MidSurface}" \ - "${SBRef}" \ - "${ProbabilisticRibbon}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" - + wb_command -metric-to-volume-mapping "${OnesMetric}" "${MidSurface}" "${SBRef}" "${ProbabilisticRibbon}" -ribbon-constrained "${InnerSurface}" "${OuterSurface}" # ------------------------------------------------------------------------------ # Thresholding the fractional ribbon at greater than 0 to create a binary mask # ------------------------------------------------------------------------------ - "${WB}" -volume-math \ - "x > 0" \ - "${BinaryRibbon}" \ - -var x \ - "${ProbabilisticRibbon}" - + wb_command -volume-math "x > 0" "${BinaryRibbon}" -var x "${ProbabilisticRibbon}" # ------------------------------------------------------------------------------ # Generating good-voxel mask for each structure @@ -152,65 +110,23 @@ for Structure in hipp dentate; do if [[ "${doGoodVoxels}" == "YES" ]]; then - fslmaths "${WorkingDirectory}/${Subject}.cov" \ - -mas "${BinaryRibbon}" \ - "${WorkingDirectory}/${Prefix}_cov_ribbon" - + fslmaths "${WorkingDirectory}/${Subject}.cov" -mas "${BinaryRibbon}" "${WorkingDirectory}/${Prefix}_cov_ribbon" meanIntensity=$(fslstats "${WorkingDirectory}/${Prefix}_cov_ribbon" -M) + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon" -div ${meanIntensity} "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" -bin -s "${NeighborhoodSmoothing}" "${WorkingDirectory}/${Prefix}_SmoothNorm" + fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" -s "${NeighborhoodSmoothing}" -div "${WorkingDirectory}/${Prefix}_SmoothNorm" -dilD "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" + fslmaths "${WorkingDirectory}/${Subject}.cov" -div ${meanIntensity} -div "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" "${WorkingDirectory}/${Prefix}_cov_norm_modulate" + fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" -mas "${BinaryRibbon}" "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" - fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon" \ - -div ${meanIntensity} \ - "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" - - fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" \ - -bin \ - -s "${NeighborhoodSmoothing}" \ - "${WorkingDirectory}/${Prefix}_SmoothNorm" - - fslmaths "${WorkingDirectory}/${Prefix}_cov_ribbon_norm" \ - -s "${NeighborhoodSmoothing}" \ - -div "${WorkingDirectory}/${Prefix}_SmoothNorm" \ - -dilD \ - "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" - - fslmaths "${WorkingDirectory}/${Subject}.cov" \ - -div ${meanIntensity} \ - -div "${WorkingDirectory}/${Prefix}_cov_ribbon_norm_s${NeighborhoodSmoothing}" \ - "${WorkingDirectory}/${Prefix}_cov_norm_modulate" - - fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" \ - -mas "${BinaryRibbon}" \ - "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" - - STD=$(fslstats \ - "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" \ - -S) - + STD=$(fslstats "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" -S) echo "STD: ${STD}" - - MEAN=$(fslstats \ - "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" \ - -M) - + MEAN=$(fslstats "${WorkingDirectory}/${Prefix}_cov_norm_modulate_ribbon" -M) echo "MEAN: ${MEAN}" - - Lower=$(echo "${MEAN} - (${STD} * ${Factor})" | bc -l) - echo "LOWER: ${Lower}" - Upper=$(echo "${MEAN} + (${STD} * ${Factor})" | bc -l) echo "UPPER: ${Upper}" - fslmaths "${WorkingDirectory}/${Subject}.mean" \ - -bin \ - "${WorkingDirectory}/${Prefix}_mask" - - fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" \ - -thr "${Upper}" \ - -bin \ - -sub "${WorkingDirectory}/${Prefix}_mask" \ - -mul -1 \ - -mas "${BinaryRibbon}" \ - "${WorkingDirectory}/${Prefix}_goodvoxels" + fslmaths "${WorkingDirectory}/${Subject}.mean" -bin "${WorkingDirectory}/${Prefix}_mask" + fslmaths "${WorkingDirectory}/${Prefix}_cov_norm_modulate" -thr "${Upper}" -bin -sub "${WorkingDirectory}/${Prefix}_mask" -mul -1 -mas "${BinaryRibbon}" "${WorkingDirectory}/${Prefix}_goodvoxels" fi @@ -221,89 +137,50 @@ for Structure in hipp dentate; do OuterSurface="${NativeFolder}/${Prefix}_outer.native.surf.gii" NativeFlat="${NativeFolder}/${Prefix}_flat.native.surf.gii" - NativeSurfArea="${NativeFolder}/${Prefix}_surfarea.native.shape.gii" - NativeROI="${WorkingDirectory}/${Prefix}_ones.native.func.gii" - # ===================================================================== # Map mean and covariance volumes # ===================================================================== for Map in mean cov; do - NativeMetric="${WorkingDirectory}/${Prefix}_${Map}.native.func.gii" NativeAllMetric="${WorkingDirectory}/${Prefix}_${Map}_all.native.func.gii" - # ----------------------------------------------------------------- # Map using good voxels # ----------------------------------------------------------------- if [[ "${doGoodVoxels}" == "YES" ]]; then - - "${WB}" -volume-to-surface-mapping \ - "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ - "${MidSurface}" \ - "${NativeMetric}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ - -dilate-missing ${dilation_dist} \ - -nearest - + wb_command -volume-to-surface-mapping "${WorkingDirectory}/${Subject}.${Map}.nii.gz" "${MidSurface}" "${NativeMetric}" \ + -ribbon-constrained "${InnerSurface}" "${OuterSurface}" -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" -dilate-missing ${dilation_dist} -nearest else - "${WB}" -volume-to-surface-mapping \ - "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ - "${MidSurface}" \ - "${NativeMetric}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -dilate-missing ${dilation_dist} \ - -nearest + wb_command -volume-to-surface-mapping "${WorkingDirectory}/${Subject}.${Map}.nii.gz" "${MidSurface}" "${NativeMetric}" \ + -ribbon-constrained "${InnerSurface}" "${OuterSurface}" -dilate-missing ${dilation_dist} -nearest fi - "${WB}" -metric-dilate \ - "${NativeMetric}" \ - "${MidSurface}" \ - "${dilation_dist}" \ - "${NativeMetric}" \ - -nearest - - "${WB}" -metric-mask \ - "${NativeMetric}" \ - "${NativeROI}" \ - "${NativeMetric}" + wb_command -metric-dilate "${NativeMetric}" "${MidSurface}" "${dilation_dist}" "${NativeMetric}" -nearest + wb_command -metric-mask "${NativeMetric}" "${NativeROI}" "${NativeMetric}" # ----------------------------------------------------------------- # Map using all ribbon voxels # ----------------------------------------------------------------- - "${WB}" -volume-to-surface-mapping \ - "${WorkingDirectory}/${Subject}.${Map}.nii.gz" \ - "${MidSurface}" \ - "${NativeAllMetric}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -dilate-missing ${dilation_dist} \ - -nearest - - "${WB}" -metric-mask \ - "${NativeAllMetric}" \ - "${NativeROI}" \ - "${NativeAllMetric}" - + wb_command -volume-to-surface-mapping "${WorkingDirectory}/${Subject}.${Map}.nii.gz" "${MidSurface}" "${NativeAllMetric}" \ + -ribbon-constrained "${InnerSurface}" "${OuterSurface}" -dilate-missing ${dilation_dist} -nearest + wb_command -metric-mask "${NativeAllMetric}" "${NativeROI}" "${NativeAllMetric}" # ----------------------------------------------------------------- # Resample native metrics using unfolded flat surfaces # ----------------------------------------------------------------- - for Mesh in ${Meshes[@]}; do + for Mesh in ${Meshes}; do + + if [[ "${Mesh}" == "native" ]]; then + continue + fi MeshFolder="${HippUnfoldFolder}/${Mesh}" @@ -316,48 +193,13 @@ for Structure in hipp dentate; do TargetMetric="${WorkingDirectory}/${Prefix}_${Map}.${Mesh}.func.gii" TargetAllMetric="${WorkingDirectory}/${Prefix}_${Map}_all.${Mesh}.func.gii" - - "${WB}" -metric-math \ - "x * 0 + 1" \ - "${TargetROI}" \ - -var x "${TargetSurfArea}" - - - "${WB}" -metric-resample \ - "${NativeMetric}" \ - "${NativeFlat}" \ - "${TargetFlat}" \ - ADAP_BARY_AREA \ - "${TargetMetric}" \ - -area-surfs \ - "${MidSurface}" \ - "${TargetMidSurface}" \ - -current-roi "${NativeROI}" \ - -bypass-sphere-check - - "${WB}" -metric-mask \ - "${TargetMetric}" \ - "${TargetROI}" \ - "${TargetMetric}" - - - "${WB}" -metric-resample \ - "${NativeAllMetric}" \ - "${NativeFlat}" \ - "${TargetFlat}" \ - ADAP_BARY_AREA \ - "${TargetAllMetric}" \ - -area-surfs \ - "${MidSurface}" \ - "${TargetMidSurface}" \ - -current-roi "${NativeROI}" \ - -bypass-sphere-check - - "${WB}" -metric-mask \ - "${TargetAllMetric}" \ - "${TargetROI}" \ - "${TargetAllMetric}" - + wb_command -metric-math "x * 0 + 1" "${TargetROI}" -var x "${TargetSurfArea}" + wb_command -metric-resample "${NativeMetric}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetMetric}" \ + -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check + wb_command -metric-mask "${TargetMetric}" "${TargetROI}" "${TargetMetric}" + wb_command -metric-resample "${NativeAllMetric}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetAllMetric}" \ + -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check + wb_command -metric-mask "${TargetAllMetric}" "${TargetROI}" "${TargetAllMetric}" done done @@ -369,24 +211,15 @@ for Structure in hipp dentate; do NativeGoodVoxels="${WorkingDirectory}/${Prefix}_goodvoxels.native.func.gii" - "${WB}" -volume-to-surface-mapping \ - "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ - "${MidSurface}" \ - "${NativeGoodVoxels}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -dilate-missing ${dilation_dist} \ - -nearest - - "${WB}" -metric-mask \ - "${NativeGoodVoxels}" \ - "${NativeROI}" \ - "${NativeGoodVoxels}" - + wb_command -volume-to-surface-mapping "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" "${MidSurface}" "${NativeGoodVoxels}" \ + -ribbon-constrained "${InnerSurface}" "${OuterSurface}" -dilate-missing ${dilation_dist} -nearest + wb_command -metric-mask "${NativeGoodVoxels}" "${NativeROI}" "${NativeGoodVoxels}" - for Mesh in ${Meshes[@]}; do + for Mesh in ${Meshes}; do + if [[ "${Mesh}" == "native" ]]; then + continue + fi MeshFolder="${HippUnfoldFolder}/${Mesh}" TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" @@ -396,159 +229,95 @@ for Structure in hipp dentate; do TargetGoodVoxels="${WorkingDirectory}/${Prefix}_goodvoxels.${Mesh}.func.gii" - "${WB}" -metric-resample \ - "${NativeGoodVoxels}" \ - "${NativeFlat}" \ - "${TargetFlat}" \ - ADAP_BARY_AREA \ - "${TargetGoodVoxels}" \ - -area-surfs \ - "${MidSurface}" \ - "${TargetMidSurface}" \ - -current-roi "${NativeROI}" \ - -bypass-sphere-check - - "${WB}" -metric-mask \ - "${TargetGoodVoxels}" \ - "${TargetROI}" \ - "${TargetGoodVoxels}" - + wb_command -metric-resample "${NativeGoodVoxels}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetGoodVoxels}" \ + -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check + wb_command -metric-mask "${TargetGoodVoxels}" "${TargetROI}" "${TargetGoodVoxels}" done - fi - # ===================================================================== # Map complete fMRI timeseries to native hippocampal surface # ===================================================================== + for Mesh in ${Meshes}; do - NativefMRI="${WorkingDirectory}/${Prefix}_fMRI.native.func.gii" - - - if [[ "${doGoodVoxels}" == "YES" ]]; then - - "${WB}" -volume-to-surface-mapping \ - "${VolumefMRI}.nii.gz" \ - "${MidSurface}" \ - "${NativefMRI}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" \ - -dilate-missing ${dilation_dist} \ - -nearest - - else - - "${WB}" -volume-to-surface-mapping \ - "${VolumefMRI}.nii.gz" \ - "${MidSurface}" \ - "${NativefMRI}" \ - -ribbon-constrained \ - "${InnerSurface}" \ - "${OuterSurface}" \ - -dilate-missing ${dilation_dist} - -nearest - - fi - - "${WB}" -metric-dilate \ - "${NativefMRI}" \ - "${MidSurface}" \ - "${dilation_dist}" \ - "${NativefMRI}" - -nearest - - "${WB}" -metric-mask \ - "${NativefMRI}" \ - "${NativeROI}" \ - "${NativefMRI}" - - log_Msg "Generated fMRI file in native space at: ${NativefMRI}" - - # ===================================================================== - # Map VN volume to native hippocampal surface - # ===================================================================== - - VolumefMRIVN="${VolumefMRI}_vn.nii.gz" - NativefMRIVN="${WorkingDirectory}/${Prefix}_fMRI_vn.native.func.gii" - - "${WB}" -volume-to-surface-mapping \ - "${VolumefMRIVN}" \ - "${MidSurface}" \ - "${NativefMRIVN}" \ - -cubic - - "${WB}" -metric-mask \ - "${NativefMRIVN}" \ - "${NativeROI}" \ - "${NativefMRIVN}" - - log_Msg "Generated VN file in native space at: ${NativefMRIVN}" - - # ===================================================================== - # Resample complete fMRI timeseries to all densities - # ===================================================================== - - for Mesh in ${Meshes[@]}; do - + TargetfMRI="${ResultsFolder}/${Prefix}_fMRI.${Mesh}.func.gii" MeshFolder="${HippUnfoldFolder}/${Mesh}" - TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" TargetROI="${WorkingDirectory}/${Prefix}_ones.${Mesh}.func.gii" - TargetfMRI="${WorkingDirectory}/${Prefix}_fMRI.${Mesh}.func.gii" + if [[ "${Mesh}" == "native" ]]; then + # Map fMRI volume to native surface + if [[ "${doGoodVoxels}" == "YES" ]]; then - "${WB}" -metric-resample \ - "${NativefMRI}" \ - "${NativeFlat}" \ - "${TargetFlat}" \ - ADAP_BARY_AREA \ - "${TargetfMRI}" \ - -area-surfs \ - "${MidSurface}" \ - "${TargetMidSurface}" \ - -current-roi "${NativeROI}" \ - -bypass-sphere-check + wb_command -volume-to-surface-mapping "${VolumefMRI}" "${TargetMidSurface}" "${TargetfMRI}" -ribbon-constrained "${InnerSurface}" "${OuterSurface}" \ + -volume-roi "${WorkingDirectory}/${Prefix}_goodvoxels.nii.gz" -dilate-missing "${dilation_dist}" -nearest + else + + wb_command -volume-to-surface-mapping "${VolumefMRI}" "${TargetMidSurface}" "${TargetfMRI}" \ + -ribbon-constrained "${InnerSurface}" "${OuterSurface}" -dilate-missing "${dilation_dist}" -nearest + fi + NativefMRI="${TargetfMRI}" + log_Msg "Generated fMRI file in native mesh at: ${TargetfMRI}" + else + # Resample native fMRI surface to target mesh + wb_command -metric-resample "${NativefMRI}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetfMRI}" \ + -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check + + log_Msg "Generated fMRI file in ${Mesh} mesh at: ${TargetfMRI}" + + fi - "${WB}" -metric-dilate \ + # Dilate and mask both native and target-mesh fMRI + wb_command -metric-dilate \ "${TargetfMRI}" \ "${TargetMidSurface}" \ - ${dilation_dist} \ + "${dilation_dist}" \ "${TargetfMRI}" \ -nearest - - "${WB}" -metric-mask \ + wb_command -metric-mask \ "${TargetfMRI}" \ "${TargetROI}" \ "${TargetfMRI}" + done + # ===================================================================== + # Map VN volume to native hippocampal surface + # ===================================================================== + VolumefMRIVN="${VolumefMRI%.nii.gz}_vn.nii.gz" + + if [[ ! -f "${VolumefMRIVN}" ]]; then + log_Err_Abort "Cannot find VN volume: ${VolumefMRIVN}" + fi - log_Msg "Generated fMRI file in ${Mesh} mesh at: ${TargetfMRI}" + FiniteVolumefMRIVN="${WorkingDirectory}/${Subject}_vn_finite.nii.gz" - # ===================================================================== - # Map VN volume to native hippocampal surface - # ===================================================================== + fslmaths "${VolumefMRIVN}" -thr -1e30 -uthr 1e30 -nan "${FiniteVolumefMRIVN}" #Thresholding inf and -inf and replacing nan with 0 - VolumefMRIVN="${VolumefMRI}_vn.nii.gz" - TargetfMRIVN="${WorkingDirectory}/${Prefix}_fMRI_vn.${Mesh}.func.gii" + for Mesh in ${Meshes}; do - "${WB}" -volume-to-surface-mapping \ - "${VolumefMRIVN}" \ - "${TargetMidSurface}" \ - "${TargetfMRIVN}" \ - -cubic + TargetfMRIVN="${ResultsFolder}/${Prefix}_fMRI_vn.${Mesh}.func.gii" + MeshFolder="${HippUnfoldFolder}/${Mesh}" + TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" - "${WB}" -metric-mask \ - "${TargetfMRIVN}" \ - "${TargetROI}" \ - "${TargetfMRIVN}" + if [[ "${Mesh}" == "native" ]]; then + + # Map VN volume to native surface + wb_command -volume-to-surface-mapping "${FiniteVolumefMRIVN}" "${TargetMidSurface}" "${TargetfMRIVN}" -cubic + NativefMRIVN="${TargetfMRIVN}" - log_Msg "Generated VN file in ${Mesh} mesh at: ${TargetfMRIVN}" + log_Msg "Generated VN file in native mesh at: ${TargetfMRIVN}" + else + # Resample native VN surface to other mesh surface + wb_command -metric-resample "${NativefMRIVN}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetfMRIVN}" \ + -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check + + log_Msg "Generated VN file in ${Mesh} mesh at: ${TargetfMRIVN}" + fi done done done From 1c134fd7f332794479c92a68af03f8c300d79dde Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Thu, 3 Sep 2026 13:51:26 -0500 Subject: [PATCH 5/7] Add hippocampal smoothing and CIFTI scripts --- .../scripts/CreateHippocampalCIFTIs.sh | 82 +++++++++++++++++++ fMRISurface/scripts/HippocampalSmoothing.sh | 74 +++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100755 fMRISurface/scripts/CreateHippocampalCIFTIs.sh create mode 100755 fMRISurface/scripts/HippocampalSmoothing.sh diff --git a/fMRISurface/scripts/CreateHippocampalCIFTIs.sh b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh new file mode 100755 index 000000000..ab4b87a2d --- /dev/null +++ b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -eu +# -------------------------------------------------------------------------------- +# Usage Description Function +# -------------------------------------------------------------------------------- + +script_name=$(basename "${0}") + +show_usage() { + cat < Date: Tue, 8 Sep 2026 10:27:32 -0500 Subject: [PATCH 6/7] Update hippocampal fMRISurface processing --- ...ippocampusfMRISurfaceProcessingPipeline.sh | 44 +++++++--- .../scripts/CreateHippocampalCIFTIs.sh | 82 ++++++++++++++----- fMRISurface/scripts/HippocampalSmoothing.sh | 20 ++--- .../HippocampalVolumeToSurfaceMapping.sh | 53 +++++++----- 4 files changed, 134 insertions(+), 65 deletions(-) diff --git a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh index d6a63d179..b7cc08f9b 100755 --- a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh +++ b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh @@ -1,19 +1,40 @@ #!/bin/bash -set -eu + # Requirements for this script # installed versions of: FSL, Connectome Workbench (wb_command) # environment: HCPPIPEDIR, FSLDIR, CARET7DIR ########################################## PIPELINE OVERVIEW ########################################## -# TODO +# This script combines surface metric files from the left and right hippocampus and dentate gyrus +# into CIFTI files for each requested non-native mesh. +# +# The script creates: +# 1. Dense scalar CIFTI files containing mean fMRI intensity of both good voxels and all voxels. +# 2. Dense scalar CIFTI files containing coefficient of variation (COV) of both good voxels and all voxels. +# 3. A dense scalar CIFTI file containing the good-voxel mask when good-voxel processing is enabled. +# 4. A dense timeseries CIFTI file containing smooth fMRI timeseries. +# 5. A dense scalar CIFTI file containing the fMRI variance normalization (VN) data. +# +# Native-mesh files are retained as processing intermediates and are not converted to CIFTI. ########################################## OUTPUT DIRECTORIES ########################################## -# TODO +# ResultsFolder: +# Contains the final hippocampal fMRI CIFTI outputs: +# ${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii +# ${NameOffMRI}_AtlasHipp${ProcString}_vn.${Mesh}.dscalar.nii +# +# WorkingDirectory: +# Contains the hippocampal volume-to-surface mapping outputs and QC CIFTI files: +# ${Subject}.allStructures_mean.${Mesh}.dscalar.nii +# ${Subject}.allStructures_mean_all.${Mesh}.dscalar.nii +# ${Subject}.allStructures_cov.${Mesh}.dscalar.nii +# ${Subject}.allStructures_cov_all.${Mesh}.dscalar.nii +# ${Subject}.allStructures_goodvoxels.${Mesh}.dscalar.nii +# ################################################ SUPPORT FUNCTIONS ################################################## - set -eu pipedirguessed=0 if [[ "${HCPPIPEDIR:-}" == "" ]] @@ -23,8 +44,7 @@ then export HCPPIPEDIR="$(dirname -- "$0")/.." fi -#comment the line back in when done -#source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib source "${HCPPIPEDIR}/global/scripts/newopts.shlib" "$@" @@ -46,7 +66,7 @@ opts_AddOptional '--goodvoxel' 'doGoodVoxels' 'YES OR NO' "Controls whether to d opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels (default = 1.5)" "1.5" -opts_AddOptional '--resample_mesh' 'MeshString' 'string' 'Resample native mesh to: 512, 2k, 8k, or 18k. Use quote for multiple meshes, e.g. "512 2k 8k"' "512 2k 8k 18k" +opts_AddOptional '--resample_mesh' 'MeshString' 'string' 'Resample native mesh to: 512, 2k, 8k, or 18k. Use quote for multiple meshes, e.g. "512 2k 8k"' "2k" opts_ParseArguments "$@" if ((pipedirguessed)) @@ -84,7 +104,7 @@ AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear" InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" ResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" -WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" #should 'HippocampalVolumeToSurfaceMapping' be a parameter?' +WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" mkdir -p "${WorkingDirectory}" VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}.nii.gz" @@ -121,13 +141,13 @@ log_Msg "Hippocampal Volume To Surface Mapping" # Generate fMRI time series for each of the hippocampal structures: L hipp, R hipp, L dentate, R dentate -"${HCPPIPEDIR_fMRISurf}/HippocampalVolumeToSurfaceMapping.sh" "${ResultsFolder}" "${Subject}" "${HippUnfoldFolder}" "${VolumefMRI}" "${SBRef}" "${doGoodVoxels}" "${factor}" "${Meshes}" +"${HCPPIPEDIR_fMRISurf}/HippocampalVolumeToSurfaceMapping.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${HippUnfoldFolder}" "${VolumefMRI}" "${SBRef}" "${doGoodVoxels}" "${factor}" "${Meshes}" #Surface Smoothing of each hippocampal structure -"${HCPPIPEDIR_fMRISurf}/HippocampalSmoothing.sh" "${HippUnfoldFolder}" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${SmoothingFWHM}" "${Meshes}" +"${HCPPIPEDIR_fMRISurf}/HippocampalSmoothing.sh" "${HippUnfoldFolder}" "${WorkingDirectory}" "${Subject}" "${SmoothingFWHM}" "${Meshes}" -#Integration of the 4 hippocampal structures into single CIFTI timeseries and vn files -"${HCPPIPEDIR_fMRISurf}/CreateHippocampalCIFTIs.sh" "${ResultsFolder}" "${Subject}" "${NameOffMRI}" "${ProcString}" "${SmoothingFWHM}" "${Meshes}" +#Integration of the 4 hippocampal structures into single CIFTI files and cleanup of intermediate files +"${HCPPIPEDIR_fMRISurf}/CreateHippocampalCIFTIs.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${NameOffMRI}" "${ProcString}" "${Meshes}" "${doGoodVoxels}" "${SmoothingFWHM}" log_Msg "GenericHippocampusfMRISurfaceProcessingPipeline Completed!" diff --git a/fMRISurface/scripts/CreateHippocampalCIFTIs.sh b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh index ab4b87a2d..d44f65d97 100755 --- a/fMRISurface/scripts/CreateHippocampalCIFTIs.sh +++ b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh @@ -1,7 +1,8 @@ #!/bin/bash -set -eu + # -------------------------------------------------------------------------------- -# Usage Description Function +# A script for the conversion of 4 structures (L hipp, R hipp, L dentate, R dentate) +# into a single CIFTI file and deletion of intermediate func.gii file # -------------------------------------------------------------------------------- script_name=$(basename "${0}") @@ -47,36 +48,75 @@ log_Check_Env_Var HCPPIPEDIR log_Check_Env_Var CARET7DIR # ------------------------------------------------------------------------------ -# Start work +# Loop that detects func.gii for all 4 structures (L hipp, R hipp, L dentate, R dentate), +# merges them into CIFTI files, and deletes the func.gii # ------------------------------------------------------------------------------ log_Msg "START" ResultsFolder="$1" -Subject="$2" -NameOffMRI="$3" -ProcString="$4" -SmoothingFWHM="$5" +WorkingDirectory="$2" +Subject="$3" +NameOffMRI="$4" +ProcString="$5" Meshes="$6" +doGoodVoxels="$7" +SmoothingFWHM="$8" for Mesh in ${Meshes}; do - wb_command -cifti-create-dense-timeseries "${ResultsFolder}/${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii" \ - -metric HIPPOCAMPUS_LEFT "${ResultsFolder}/${Subject}.L.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_RIGHT "${ResultsFolder}/${Subject}.R.hipp_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_LEFT "${ResultsFolder}/${Subject}.L.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_RIGHT "${ResultsFolder}/${Subject}.R.dentate_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" + for LeftHipp in "${WorkingDirectory}/${Subject}.L.hipp_"*.${Mesh}.func.gii; do + + if [[ ! -e "${LeftHipp}" ]]; then + continue + fi + + BaseName=$(basename "${LeftHipp}") + + DataName="${BaseName#${Subject}.L.hipp_}" + DataName="${DataName%.${Mesh}.func.gii}" + + RightHipp="${WorkingDirectory}/${Subject}.R.hipp_${DataName}.${Mesh}.func.gii" + LeftDentate="${WorkingDirectory}/${Subject}.L.dentate_${DataName}.${Mesh}.func.gii" + RightDentate="${WorkingDirectory}/${Subject}.R.dentate_${DataName}.${Mesh}.func.gii" + + if [[ -f "${LeftHipp}" && + -f "${RightHipp}" && + -f "${LeftDentate}" && + -f "${RightDentate}" ]]; then + + if [[ "${DataName}" == fMRI_s* ]]; then + + OutputFile="${ResultsFolder}/${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii" + + wb_command -cifti-create-dense-timeseries "${OutputFile}" \ + -metric HIPPOCAMPUS_LEFT "${LeftHipp}" \ + -metric HIPPOCAMPUS_RIGHT "${RightHipp}" \ + -metric HIPPOCAMPUS_DENTATE_LEFT "${LeftDentate}" \ + -metric HIPPOCAMPUS_DENTATE_RIGHT "${RightDentate}" + + else + + OutputName="${DataName#fMRI_}" + + OutputFile="${WorkingDirectory}/${NameOffMRI}_AtlasHipp${ProcString}_${OutputName}.${Mesh}.dscalar.nii" - log_Msg "Generated fMRI time series CIFTI file: ${ResultsFolder}/${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii" + wb_command -cifti-create-dense-scalar "${OutputFile}" \ + -metric HIPPOCAMPUS_LEFT "${LeftHipp}" \ + -metric HIPPOCAMPUS_RIGHT "${RightHipp}" \ + -metric HIPPOCAMPUS_DENTATE_LEFT "${LeftDentate}" \ + -metric HIPPOCAMPUS_DENTATE_RIGHT "${RightDentate}" + fi - wb_command -cifti-create-dense-scalar "${ResultsFolder}/${NameOffMRI}_AtlasHipp${ProcString}_vn.${Mesh}.dscalar.nii" \ - -metric HIPPOCAMPUS_LEFT "${ResultsFolder}/${Subject}.L.hipp_fMRI_vn.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_RIGHT "${ResultsFolder}/${Subject}.R.hipp_fMRI_vn.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_LEFT "${ResultsFolder}/${Subject}.L.dentate_fMRI_vn.${Mesh}.func.gii" \ - -metric HIPPOCAMPUS_DENTATE_RIGHT "${ResultsFolder}/${Subject}.R.dentate_fMRI_vn.${Mesh}.func.gii" + rm -f \ + "${LeftHipp}" \ + "${RightHipp}" \ + "${LeftDentate}" \ + "${RightDentate}" - log_Msg "Generated VN CIFTI file: ${ResultsFolder}/${NameOffMRI}_AtlasHipp${ProcString}_vn.${Mesh}.dscalar.nii" + log_Msg "Generated CIFTI file: ${OutputFile}" + fi -done + done -log_Msg "END" \ No newline at end of file +done \ No newline at end of file diff --git a/fMRISurface/scripts/HippocampalSmoothing.sh b/fMRISurface/scripts/HippocampalSmoothing.sh index 870c649fb..506af5d68 100755 --- a/fMRISurface/scripts/HippocampalSmoothing.sh +++ b/fMRISurface/scripts/HippocampalSmoothing.sh @@ -1,8 +1,4 @@ #!/bin/bash -set -eu -# -------------------------------------------------------------------------------- -# Usage Description Function -# -------------------------------------------------------------------------------- script_name=$(basename "${0}") @@ -53,11 +49,10 @@ log_Check_Env_Var CARET7DIR log_Msg "START" HippUnfoldFolder="$1" -ResultsFolder="$2" -WorkingDirectory="$3" -Subject="$4" -SmoothingFWHM="$5" -Meshes="$6" +WorkingDirectory="$2" +Subject="$3" +SmoothingFWHM="$4" +Meshes="$5" Sigma=$(echo "${SmoothingFWHM} / (2 * sqrt(2 * l(2)))" | bc -l) @@ -66,7 +61,12 @@ Structures=(hipp dentate) for Mesh in ${Meshes}; do for Structure in "${Structures[@]}"; do for Hemisphere in L R; do - wb_command -metric-smoothing "${HippUnfoldFolder}/${Mesh}/${Subject}.${Hemisphere}.${Structure}_midthickness.${Mesh}.surf.gii" "${ResultsFolder}/${Subject}.${Hemisphere}.${Structure}_fMRI.${Mesh}.func.gii" "${Sigma}" "${ResultsFolder}/${Subject}.${Hemisphere}.${Structure}_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" -roi "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_ones.${Mesh}.func.gii" + if [[ "${Mesh}" == "native" ]] ; then + MeshFolder='Native' + else + MeshFolder="${Mesh}" + fi + wb_command -metric-smoothing "${HippUnfoldFolder}/${MeshFolder}/${Subject}.${Hemisphere}.${Structure}_midthickness.${Mesh}.surf.gii" "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI.${Mesh}.func.gii" "${Sigma}" "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_fMRI_s${SmoothingFWHM}.${Mesh}.func.gii" -roi "${WorkingDirectory}/${Subject}.${Hemisphere}.${Structure}_ones.${Mesh}.func.gii" done done done diff --git a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh index 17f84e08a..a8f4c8f39 100755 --- a/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh +++ b/fMRISurface/scripts/HippocampalVolumeToSurfaceMapping.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eu + # -------------------------------------------------------------------------------- # Usage Description Function # -------------------------------------------------------------------------------- @@ -30,8 +30,8 @@ if [[ -z "${HCPPIPEDIR}" ]]; then exit 1 fi -#source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib -source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib +source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib +#source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib source "${HCPPIPEDIR}/global/scripts/opts.shlib" # Command line option functions opts_ShowVersionIfRequested "$@" @@ -46,13 +46,14 @@ fi # ------------------------------------------------------------------------------ ResultsFolder="$1" -Subject="$2" -HippUnfoldFolder="$3" -VolumefMRI="$4" -SBRef="$5" -doGoodVoxels="$6" -Factor="$7" # Factor is a scaling factor for how many std units away from mean to set threshold -Meshes="$8" # default: Meshes=(native 512 2k 8k 18k) +WorkingDirectory="$2" +Subject="$3" +HippUnfoldFolder="$4" +VolumefMRI="$5" +SBRef="$6" +doGoodVoxels="$7" +Factor="$8" # Factor is a scaling factor for how many std units away from mean to set threshold +Meshes="$9" # options: Meshes=(native 512 2k 8k 18k) NeighborhoodSmoothing="5" # Distinguishes large vs small dropout dilation_dist="10" @@ -75,10 +76,10 @@ for Structure in hipp dentate; do Prefix="${Subject}.${Hemisphere}.${Structure}" - ThicknessMetric="${HippUnfoldFolder}/native/${Prefix}_thickness.native.shape.gii" - InnerSurface="${HippUnfoldFolder}/native/${Prefix}_inner.native.surf.gii" - MidSurface="${HippUnfoldFolder}/native/${Prefix}_midthickness.native.surf.gii" - OuterSurface="${HippUnfoldFolder}/native/${Prefix}_outer.native.surf.gii" + ThicknessMetric="${HippUnfoldFolder}/Native/${Prefix}_thickness.native.shape.gii" + InnerSurface="${HippUnfoldFolder}/Native/${Prefix}_inner.native.surf.gii" + MidSurface="${HippUnfoldFolder}/Native/${Prefix}_midthickness.native.surf.gii" + OuterSurface="${HippUnfoldFolder}/Native/${Prefix}_outer.native.surf.gii" OnesMetric="${WorkingDirectory}/${Prefix}_ones.native.func.gii" ProbabilisticRibbon="${WorkingDirectory}/${Prefix}.ribbon_probabilistic.nii.gz" @@ -130,7 +131,7 @@ for Structure in hipp dentate; do fi - NativeFolder="${HippUnfoldFolder}/native" + NativeFolder="${HippUnfoldFolder}/Native" InnerSurface="${NativeFolder}/${Prefix}_inner.native.surf.gii" MidSurface="${NativeFolder}/${Prefix}_midthickness.native.surf.gii" @@ -240,8 +241,13 @@ for Structure in hipp dentate; do # ===================================================================== for Mesh in ${Meshes}; do - TargetfMRI="${ResultsFolder}/${Prefix}_fMRI.${Mesh}.func.gii" - MeshFolder="${HippUnfoldFolder}/${Mesh}" + if [[ "${Mesh}" == "native" ]]; then + MeshFolder="${HippUnfoldFolder}/Native" + else + MeshFolder="${HippUnfoldFolder}/${Mesh}" + fi + + TargetfMRI="${WorkingDirectory}/${Prefix}_fMRI.${Mesh}.func.gii" TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" TargetROI="${WorkingDirectory}/${Prefix}_ones.${Mesh}.func.gii" @@ -299,12 +305,12 @@ for Structure in hipp dentate; do for Mesh in ${Meshes}; do - TargetfMRIVN="${ResultsFolder}/${Prefix}_fMRI_vn.${Mesh}.func.gii" - MeshFolder="${HippUnfoldFolder}/${Mesh}" - TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" - TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" + TargetfMRIVN="${WorkingDirectory}/${Prefix}_fMRI_vn.${Mesh}.func.gii" - if [[ "${Mesh}" == "native" ]]; then + if [[ "${Mesh}" == "native" ]]; then + MeshFolder="${HippUnfoldFolder}/Native" + TargetFlat="${MeshFolder}/${Prefix}_flat.native.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.native.surf.gii" # Map VN volume to native surface wb_command -volume-to-surface-mapping "${FiniteVolumefMRIVN}" "${TargetMidSurface}" "${TargetfMRIVN}" -cubic @@ -312,6 +318,9 @@ for Structure in hipp dentate; do log_Msg "Generated VN file in native mesh at: ${TargetfMRIVN}" else + MeshFolder="${HippUnfoldFolder}/${Mesh}" + TargetFlat="${MeshFolder}/${Prefix}_flat.${Mesh}.surf.gii" + TargetMidSurface="${MeshFolder}/${Prefix}_midthickness.${Mesh}.surf.gii" # Resample native VN surface to other mesh surface wb_command -metric-resample "${NativefMRIVN}" "${NativeFlat}" "${TargetFlat}" ADAP_BARY_AREA "${TargetfMRIVN}" \ -area-surfs "${MidSurface}" "${TargetMidSurface}" -current-roi "${NativeROI}" -bypass-sphere-check From fd7bc5613e6b41cb2362d977a8c65d69d358eb97 Mon Sep 17 00:00:00 2001 From: Oren Poliva Date: Fri, 11 Sep 2026 15:43:46 -0500 Subject: [PATCH 7/7] Adding TR to dtseries --- ...ippocampusfMRISurfaceProcessingPipeline.sh | 232 +++++++++--------- .../scripts/CreateHippocampalCIFTIs.sh | 8 +- 2 files changed, 122 insertions(+), 118 deletions(-) diff --git a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh index b7cc08f9b..2ee49f627 100755 --- a/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh +++ b/fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh @@ -1,153 +1,153 @@ -#!/bin/bash - -# Requirements for this script -# installed versions of: FSL, Connectome Workbench (wb_command) -# environment: HCPPIPEDIR, FSLDIR, CARET7DIR - -########################################## PIPELINE OVERVIEW ########################################## - -# This script combines surface metric files from the left and right hippocampus and dentate gyrus -# into CIFTI files for each requested non-native mesh. -# -# The script creates: -# 1. Dense scalar CIFTI files containing mean fMRI intensity of both good voxels and all voxels. -# 2. Dense scalar CIFTI files containing coefficient of variation (COV) of both good voxels and all voxels. -# 3. A dense scalar CIFTI file containing the good-voxel mask when good-voxel processing is enabled. -# 4. A dense timeseries CIFTI file containing smooth fMRI timeseries. -# 5. A dense scalar CIFTI file containing the fMRI variance normalization (VN) data. -# -# Native-mesh files are retained as processing intermediates and are not converted to CIFTI. - -########################################## OUTPUT DIRECTORIES ########################################## - -# ResultsFolder: -# Contains the final hippocampal fMRI CIFTI outputs: -# ${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii -# ${NameOffMRI}_AtlasHipp${ProcString}_vn.${Mesh}.dscalar.nii -# -# WorkingDirectory: -# Contains the hippocampal volume-to-surface mapping outputs and QC CIFTI files: -# ${Subject}.allStructures_mean.${Mesh}.dscalar.nii -# ${Subject}.allStructures_mean_all.${Mesh}.dscalar.nii -# ${Subject}.allStructures_cov.${Mesh}.dscalar.nii -# ${Subject}.allStructures_cov_all.${Mesh}.dscalar.nii -# ${Subject}.allStructures_goodvoxels.${Mesh}.dscalar.nii -# - -################################################ SUPPORT FUNCTIONS ################################################## -set -eu -pipedirguessed=0 -if [[ "${HCPPIPEDIR:-}" == "" ]] -then - pipedirguessed=1 - # Fix this if the script is more than one level below HCPPIPEDIR - export HCPPIPEDIR="$(dirname -- "$0")/.." -fi - -source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib -source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib + #!/bin/bash + + # Requirements for this script + # installed versions of: FSL, Connectome Workbench (wb_command) + # environment: HCPPIPEDIR, FSLDIR, CARET7DIR + + ########################################## PIPELINE OVERVIEW ########################################## + + # This script combines surface metric files from the left and right hippocampus and dentate gyrus + # into CIFTI files for each requested non-native mesh. + # + # The script creates: + # 1. Dense scalar CIFTI files containing mean fMRI intensity of both good voxels and all voxels. + # 2. Dense scalar CIFTI files containing coefficient of variation (COV) of both good voxels and all voxels. + # 3. A dense scalar CIFTI file containing the good-voxel mask when good-voxel processing is enabled. + # 4. A dense timeseries CIFTI file containing smooth fMRI timeseries. + # 5. A dense scalar CIFTI file containing the fMRI variance normalization (VN) data. + # + # Native-mesh files are retained as processing intermediates and are not converted to CIFTI. + + ########################################## OUTPUT DIRECTORIES ########################################## + + # ResultsFolder: + # Contains the final hippocampal fMRI CIFTI outputs: + # ${NameOffMRI}_AtlasHipp${ProcString}.${Mesh}.dtseries.nii + # ${NameOffMRI}_AtlasHipp${ProcString}_vn.${Mesh}.dscalar.nii + # + # WorkingDirectory: + # Contains the hippocampal volume-to-surface mapping outputs and QC CIFTI files: + # ${Subject}.allStructures_mean.${Mesh}.dscalar.nii + # ${Subject}.allStructures_mean_all.${Mesh}.dscalar.nii + # ${Subject}.allStructures_cov.${Mesh}.dscalar.nii + # ${Subject}.allStructures_cov_all.${Mesh}.dscalar.nii + # ${Subject}.allStructures_goodvoxels.${Mesh}.dscalar.nii + # + + ################################################ SUPPORT FUNCTIONS ################################################## + set -eu + pipedirguessed=0 + if [[ "${HCPPIPEDIR:-}" == "" ]] + then + pipedirguessed=1 + # Fix this if the script is more than one level below HCPPIPEDIR + export HCPPIPEDIR="$(dirname -- "$0")/.." + fi -source "${HCPPIPEDIR}/global/scripts/newopts.shlib" "$@" -source "${HCPPIPEDIR}/global/scripts/processingmodecheck.shlib" # Check processing mode requirements + source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib + source "${HCPPIPEDIR}/global/scripts/log.shlib" "$@" # Debugging functions; also sources log.shlib -opts_SetScriptDescription "Run hippocampal fMRISurface processing" + source "${HCPPIPEDIR}/global/scripts/newopts.shlib" "$@" + source "${HCPPIPEDIR}/global/scripts/processingmodecheck.shlib" # Check processing mode requirements -opts_AddMandatory '--studyfolder' 'Path' 'path' "folder containing all subjects" "--path" + opts_SetScriptDescription "Run hippocampal fMRISurface processing" -opts_AddMandatory '--subject' 'Subject' 'subject ID' "" + opts_AddMandatory '--studyfolder' 'Path' 'path' "folder containing all subjects" "--path" -opts_AddMandatory '--fmriname' 'NameOffMRI' 'string' 'fMRI run name, for example rfMRI_REST1_LR' + opts_AddMandatory '--subject' 'Subject' 'subject ID' "" -opts_AddOptional '--procstring' 'ProcString' 'string' 'processing suffix appended to the 4D fMRI filename; include the leading underscore' "" + opts_AddMandatory '--fmriname' 'NameOffMRI' 'string' 'fMRI run name, for example rfMRI_REST1_LR' -opts_AddMandatory '--smoothingFWHM' 'SmoothingFWHM' 'number' 'smoothing FWHM (mm)' + opts_AddOptional '--procstring' 'ProcString' 'string' 'processing suffix appended to the 4D fMRI filename; include the leading underscore' "" -opts_AddOptional '--goodvoxel' 'doGoodVoxels' 'YES OR NO' "Controls whether to do goodVoxel procedure (default = YES)" "YES" + opts_AddMandatory '--smoothingFWHM' 'SmoothingFWHM' 'number' 'smoothing FWHM (mm)' -opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels (default = 1.5)" "1.5" + opts_AddOptional '--goodvoxel' 'doGoodVoxels' 'YES OR NO' "Controls whether to do goodVoxel procedure (default = YES)" "YES" -opts_AddOptional '--resample_mesh' 'MeshString' 'string' 'Resample native mesh to: 512, 2k, 8k, or 18k. Use quote for multiple meshes, e.g. "512 2k 8k"' "2k" -opts_ParseArguments "$@" + opts_AddOptional '--factor' 'factor' 'number' "Scaling factor for eliminating high COV voxels (default = 1.5)" "1.5" -if ((pipedirguessed)) -then - log_Err_Abort "HCPPIPEDIR is not set; first source your edited copy of Examples/Scripts/SetUpHCPPipeline.sh" -fi + opts_AddOptional '--resample_mesh' 'MeshString' 'string' 'Resample native mesh to: 512, 2k, 8k, or 18k. Use quote for multiple meshes, e.g. "512 2k 8k"' "2k" + opts_ParseArguments "$@" -opts_ShowValues + if ((pipedirguessed)) + then + log_Err_Abort "HCPPIPEDIR is not set; first source your edited copy of Examples/Scripts/SetUpHCPPipeline.sh" + fi -"${HCPPIPEDIR}/show_version" + opts_ShowValues -# ------------------------------------------------------------------------------ -# Verify required environment variables are set -# ------------------------------------------------------------------------------ + "${HCPPIPEDIR}/show_version" -log_Check_Env_Var HCPPIPEDIR -log_Check_Env_Var FSLDIR -log_Check_Env_Var CARET7DIR + # ------------------------------------------------------------------------------ + # Verify required environment variables are set + # ------------------------------------------------------------------------------ -HCPPIPEDIR_fMRISurf="${HCPPIPEDIR}/fMRISurface/scripts" + log_Check_Env_Var HCPPIPEDIR + log_Check_Env_Var FSLDIR + log_Check_Env_Var CARET7DIR -# ------------------------------------------------------------------------------ -# Parse command-line options -# ------------------------------------------------------------------------------ + HCPPIPEDIR_fMRISurf="${HCPPIPEDIR}/fMRISurface/scripts" -log_Msg "Platform Information Follows:" -uname -a + # ------------------------------------------------------------------------------ + # Parse command-line options + # ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ -# Set up paths -# ------------------------------------------------------------------------------ + log_Msg "Platform Information Follows:" + uname -a -MainSubjectFolder="${Path}/${Subject}" -AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear" -InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" -ResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" + # ------------------------------------------------------------------------------ + # Set up paths + # ------------------------------------------------------------------------------ -WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" -mkdir -p "${WorkingDirectory}" + MainSubjectFolder="${Path}/${Subject}" + AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear" + InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" + ResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}" -VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}.nii.gz" + WorkingDirectory="${ResultsFolder}/HippocampalVolumeToSurfaceMapping" + mkdir -p "${WorkingDirectory}" -SBRef="${InputResultsFolder}/${NameOffMRI}_SBRef.nii.gz" + VolumefMRI="${InputResultsFolder}/${NameOffMRI}${ProcString}.nii.gz" -HippUnfoldFolder="${AtlasSpaceFolder}/HippUnfold" + SBRef="${InputResultsFolder}/${NameOffMRI}_SBRef.nii.gz" -if [ ! -f "${VolumefMRI}" ]; then - log_Err_Abort "Cannot find selected fMRI file: ${VolumefMRI}" -fi + HippUnfoldFolder="${AtlasSpaceFolder}/HippUnfold" -if [ ! -f "${SBRef}" ]; then - log_Err_Abort "Cannot find selected SBRef file: ${SBRef}" -fi + if [ ! -f "${VolumefMRI}" ]; then + log_Err_Abort "Cannot find selected fMRI file: ${VolumefMRI}" + fi -#Parse MeshString into a mesh array -for Mesh in ${MeshString}; do - if [[ " 512 2k 8k 18k " != *" ${Mesh} "* ]]; then - log_Err_Abort "Invalid mesh: ${Mesh}" + if [ ! -f "${SBRef}" ]; then + log_Err_Abort "Cannot find selected SBRef file: ${SBRef}" fi -done -Meshes="native ${MeshString}" -log_Msg "Selected fMRI file: ${VolumefMRI}" -log_Msg "Selected SBRef file: ${SBRef}" + #Parse MeshString into a mesh array + for Mesh in ${MeshString}; do + if [[ " 512 2k 8k 18k " != *" ${Mesh} "* ]]; then + log_Err_Abort "Invalid mesh: ${Mesh}" + fi + done + Meshes="native ${MeshString}" + + log_Msg "Selected fMRI file: ${VolumefMRI}" + log_Msg "Selected SBRef file: ${SBRef}" -# ------------------------------------------------------------------------------ -# Combining ROIs into a single CIFTI time series and vn file -# ------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ + # Combining ROIs into a single CIFTI time series and vn file + # ------------------------------------------------------------------------------ -log_Msg "mkdir -p ${WorkingDirectory}" -log_Msg "Hippocampal Volume To Surface Mapping" + log_Msg "mkdir -p ${WorkingDirectory}" + log_Msg "Hippocampal Volume To Surface Mapping" -# Generate fMRI time series for each of the hippocampal structures: L hipp, R hipp, L dentate, R dentate -"${HCPPIPEDIR_fMRISurf}/HippocampalVolumeToSurfaceMapping.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${HippUnfoldFolder}" "${VolumefMRI}" "${SBRef}" "${doGoodVoxels}" "${factor}" "${Meshes}" + # Generate fMRI time series for each of the hippocampal structures: L hipp, R hipp, L dentate, R dentate + "${HCPPIPEDIR_fMRISurf}/HippocampalVolumeToSurfaceMapping.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${HippUnfoldFolder}" "${VolumefMRI}" "${SBRef}" "${doGoodVoxels}" "${factor}" "${Meshes}" -#Surface Smoothing of each hippocampal structure -"${HCPPIPEDIR_fMRISurf}/HippocampalSmoothing.sh" "${HippUnfoldFolder}" "${WorkingDirectory}" "${Subject}" "${SmoothingFWHM}" "${Meshes}" + #Surface Smoothing of each hippocampal structure + "${HCPPIPEDIR_fMRISurf}/HippocampalSmoothing.sh" "${HippUnfoldFolder}" "${WorkingDirectory}" "${Subject}" "${SmoothingFWHM}" "${Meshes}" -#Integration of the 4 hippocampal structures into single CIFTI files and cleanup of intermediate files -"${HCPPIPEDIR_fMRISurf}/CreateHippocampalCIFTIs.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${NameOffMRI}" "${ProcString}" "${Meshes}" "${doGoodVoxels}" "${SmoothingFWHM}" + #Integration of the 4 hippocampal structures into single CIFTI files and cleanup of intermediate files + "${HCPPIPEDIR_fMRISurf}/CreateHippocampalCIFTIs.sh" "${ResultsFolder}" "${WorkingDirectory}" "${Subject}" "${NameOffMRI}" "${ProcString}" "${Meshes}" "${doGoodVoxels}" "${SmoothingFWHM}" "${VolumefMRI}" -log_Msg "GenericHippocampusfMRISurfaceProcessingPipeline Completed!" + log_Msg "GenericHippocampusfMRISurfaceProcessingPipeline Completed!" diff --git a/fMRISurface/scripts/CreateHippocampalCIFTIs.sh b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh index d44f65d97..ac01040a5 100755 --- a/fMRISurface/scripts/CreateHippocampalCIFTIs.sh +++ b/fMRISurface/scripts/CreateHippocampalCIFTIs.sh @@ -62,7 +62,11 @@ ProcString="$5" Meshes="$6" doGoodVoxels="$7" SmoothingFWHM="$8" +VolumefMRI="$9" +TR=$(wb_command -file-information "$VolumefMRI" -only-step-interval) + +log_Msg "fMRI TR: ${TR} seconds" for Mesh in ${Meshes}; do for LeftHipp in "${WorkingDirectory}/${Subject}.L.hipp_"*.${Mesh}.func.gii; do @@ -93,8 +97,8 @@ for Mesh in ${Meshes}; do -metric HIPPOCAMPUS_LEFT "${LeftHipp}" \ -metric HIPPOCAMPUS_RIGHT "${RightHipp}" \ -metric HIPPOCAMPUS_DENTATE_LEFT "${LeftDentate}" \ - -metric HIPPOCAMPUS_DENTATE_RIGHT "${RightDentate}" - + -metric HIPPOCAMPUS_DENTATE_RIGHT "${RightDentate}" \ + -timestep "${TR}" else OutputName="${DataName#fMRI_}"