Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions fMRISurface/GenericHippocampusfMRISurfaceProcessingPipeline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#!/bin/bash

# Requirements for this script
# installed versions of: FSL, Connectome Workbench (wb_command)
# environment: HCPPIPEDIR, FSLDIR, CARET7DIR

@coalsont coalsont Sep 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how useful this list is, as all of these are always set up by SetUpHCP....


########################################## PIPELINE OVERVIEW ##########################################

# TODO

########################################## OUTPUT DIRECTORIES ##########################################

# TODO

################################################ SUPPORT FUNCTIONS ##################################################

set -eu

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant set -eu. Also, if we aren't going to fill these documentation sections in, I wouldn't bother having them (yet).

Suggested change
########################################## 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 on lines +37 to +49

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this entire file indented now? This has made some of my previous comments no longer show up on the diff ("files") page (github thinks they are outdated because the lines were edited).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reformatted the indentation because I understood your earlier feedback to mean that all of my scripts should follow the same style, specifically four-space indentation. This script had previously been using two-space indentation. I did not realize that reformatting the entire file would cause some of your earlier comments to appear outdated in GitHub. I’ll avoid broad formatting changes like this in future revisions so that existing review comments and the substantive diff remain easier to track.

@coalsont coalsont Sep 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, by "entire file indented", I meant that after this change, there are now 4 spaces before even the first line of the script. Anything that isn't in any conditional/loop/function/etc context should have zero spaces/tabs before the first character. Concretely:

Suggested change
################################################ 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
################################################ 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

I prefer four spaces per indentation level, so in any new scripts that would be appreciated. In existing scripts, following whatever convention is already present (as long as it is consistent) means that the per-line commit history remains more useful.

#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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this implemented? If not, it should be taken out.


opts_AddOptional '--output-directory' 'OutputDirectory' 'path' 'Directory where pipeline outputs will be written' ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
opts_AddOptional '--output-directory' 'OutputDirectory' 'path' 'Directory where pipeline outputs will be written' ""
opts_AddOptional '--output-directory' 'OutputDirectory' 'path' 'Directory where pipeline outputs will be written for testing purposes' ""


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"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably have a default value.

Single stage with...apparently half a standard deviation threshold may have been chosen for cortex due to substantial outlier effects (multi-stage and/or dilation to isolate partial voxel effects would probably be a better approach). The single stage approach may work particularly poorly with a much smaller ROI like hippocampus.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Oren did an analysis to figure this out, so we should use that as the default.


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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if we are not doing this.



# ------------------------------------------------------------------------------
# Set up paths
# ------------------------------------------------------------------------------

PipelineScripts="${HCPPIPEDIR_fMRISurf}"

MainSubjectFolder="${Path}/${Subject}"
Comment thread
orenpoliva marked this conversation as resolved.
Outdated
AtlasSpaceFolder="${MainSubjectFolder}/MNINonLinear"
InputResultsFolder="${AtlasSpaceFolder}/Results/${NameOffMRI}"
ResultsFolderName="Results"

if [ -n "${OutputDirectory}" ]; then
ResultsFolder="${OutputDirectory}/${Subject}/${NameOffMRI}"
else
ResultsFolder="${AtlasSpaceFolder}/${ResultsFolderName}/${NameOffMRI}"
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems specific to your testing.


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
# ------------------------------------------------------------------------------

@glasserm glasserm Aug 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be moved into a module in the future for parallelism with fMRISurface (and eventual inclusion in fMRISurface). If you insist on keeping it in the main pipeline, please put it in a function with the appropriate I/O so that it can easily be copied into the appropriate fMRISurface module when the time comes.

# 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" \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are all-ones files, you don't need to use -roi at all. The reason the -roi option exists is because the cortical surfaces are topologically spheres, even though some of the sphere vertices don't actually represent cortex.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.

-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"

@glasserm glasserm Aug 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also need to be moved into a module for parallelism with fMRISurface and eventual folding into fMRI surface. If you insist on keeping it in the main pipeline, please put it in a function with the appropriate I/O so that it can easily be copied into the appropriate fMRISurface module when the time comes.


# --------------------------------------------------------------------------
# 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

#Uncomment if want to remove the subfoler with intermediate files
#rm -rf "${WorkingDirectory}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems dangerous.


# 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete if not doing.


log_Msg "Completed!"
Loading