Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generation of scene/snapshots for fMRIQC #203

Merged
merged 17 commits into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from 9 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
38 changes: 7 additions & 31 deletions PostFreeSurfer/scripts/GenerateStructuralScenes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fi
source "$HCPPIPEDIR/global/scripts/newopts.shlib" "$@"
source "$HCPPIPEDIR/global/scripts/debug.shlib" "$@"
source "$HCPPIPEDIR/global/scripts/tempfiles.shlib" "$@"
source "$HCPPIPEDIR/global/scripts/relativePath.shlib" "$@"

#this function gets called by opts_ParseArguments when --help is specified
function usage()
Expand Down Expand Up @@ -118,7 +119,7 @@ verbose=$(opts_StringToBool "$verboseArg")

mkdir -p "$OutputSceneFolder"

# Convert TemplatesFolder and StudyFolder to absolute paths (for convenience in reporting locations).
# Convert TemplatesFolder, StudyFolder, and OutputSceneFolder to absolute paths (for convenience in reporting locations).
TemplatesFolder=$(cd "$TemplatesFolder"; pwd)
StudyFolder=$(cd "$StudyFolder"; pwd)
OutputSceneFolder=$(cd "$OutputSceneFolder"; pwd)
Expand Down Expand Up @@ -153,30 +154,6 @@ function copyTemplateFiles {
fi
}

# ----------------------------
# Function to determine relative paths
# ----------------------------

# We want to use relative paths in the scene file, so that it is robust
# against changes in the base directory path. As long as the relative
# paths between $OutputSceneFolder, $TemplatesFolder, and $StudyFolder are
# preserved, the scene should still work, even if the base directory changes
# (i.e., if the files are moved, or accessed via a different mount point).

# To determine the relative paths, 'realpath --relative-to' is not a robust
# solution, as 'realpath' is not present by default on MacOS, and the
# '--relative-to' option is not supported on older Ubuntu versions.
# So, use the following perl one-liner instead,
# from https://stackoverflow.com/a/17110582

function relativePath {
# both $1 and $2 are absolute paths beginning with /
# returns relative path from $1 to $2
local source=$(cd "$1"; pwd)
local target=$(cd "$2"; pwd)
perl -e 'use File::Spec; print File::Spec->abs2rel(@ARGV) . "\n"' "$target" "$source"
}

# ----------------------------
# Define variables containing the "dummy strings" used in the template scene
# ----------------------------
Expand All @@ -192,19 +169,18 @@ TemplatesFolderDummyStr="TemplatesFolder"

scriptDir=$(pwd)

OutputSceneFolderSubj=$OutputSceneFolder
mkdir -p $OutputSceneFolderSubj
relPathToStudy=$(relativePath $OutputSceneFolderSubj $StudyFolder)
mkdir -p "$OutputSceneFolder"
relPathToStudy=$(relativePath "$OutputSceneFolder" "$StudyFolder")
if [[ "$CopyTemplates" == "TRUE" ]]; then
copyTemplateFiles $TemplatesFolder $OutputSceneFolderSubj
copyTemplateFiles "$TemplatesFolder" "$OutputSceneFolder"
relPathToTemplates="."
else
relPathToTemplates=$(relativePath $OutputSceneFolderSubj $TemplatesFolder)
relPathToTemplates=$(relativePath "$OutputSceneFolder" "$TemplatesFolder")
fi
if ((verbose)); then
echo "TemplatesFolder: $TemplatesFolder"
echo "StudyFolder: $StudyFolder"
echo "OutputSceneFolder: $(cd $OutputSceneFolderSubj; pwd)"
echo "OutputSceneFolder: $OutputSceneFolder"
echo "... relative path to template files (from OutputSceneFolder): $relPathToTemplates"
echo "... relative path to StudyFolder (from OutputSceneFolder): $relPathToStudy"
fi
Expand Down
3 changes: 3 additions & 0 deletions fMRISurface/scripts/CreateDenseTimeseries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ ${CARET7DIR}/wb_command -cifti-create-dense-timeseries \
-right-metric "$NameOffMRI"_s"$SmoothingFWHM".atlasroi.R."$LowResMesh"k_fs_LR.func.gii -roi-right "$DownSampleFolder"/"$Subject".R.atlasroi."$LowResMesh"k_fs_LR.shape.gii \
-timestep "$TR_vol"

# Generate temporal mean of timeseries, for display in fMRIQC
${CARET7DIR}/wb_command -cifti-reduce "$OutputAtlasDenseTimeseries".dtseries.nii MEAN "$OutputAtlasDenseTimeseries"_mean.dscalar.nii

#Assess for zeros in the final dtseries (e.g., due to incomplete spatial coverage)
# (Note that earlier steps do an appreciable amount of dilation to eliminate zeros,
# so zeros remaining in the CIFTI at this point represent a non-trivial issue with spatial coverage)
Expand Down
38 changes: 38 additions & 0 deletions fMRIVolume/GenericfMRIVolumeProcessingPipeline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ Usage: ${script_name} [options]
is NOT applied, regardless of value).
Default: "TRUE" if using --dcmethod="${SPIN_ECHO_METHOD_OPT}"; "FALSE" for all other SDC methods.

[--fmri-qc=<"YES|NO|ONLY">

Controls whether to generate a QC scene and snapshots (YES=default).
ONLY executes *just* the QC script, skipping everything else (e.g., for previous data)

[--processing-mode=<"HCPStyleData" (default) or "LegacyStyleData">

Controls whether the HCP acquisition and processing guidelines should be treated as requirements.
Expand Down Expand Up @@ -568,6 +573,18 @@ then
log_Err_Abort "the --usejacobian option must be 'true' or 'false'"
fi

QCMode=`opts_GetOpt1 "--fmri-qc" $@`
QCMode=`opts_DefaultOpt $QCMode YES`
QCMode="$(echo ${QCMode} | tr '[:upper:]' '[:lower:]')" # Convert to all lowercase
case "$QCMode" in
(yes|no|only)
log_Msg "QCMode: $QCMode"
;;
(*)
log_Err_Abort "unrecognized value '$QCMode' for --fmri-qc, use 'YES', 'NO', or 'ONLY'"
;;
esac

RUN=`opts_GetOpt1 "--printcom" $@` # use ="echo" for just printing everything and not running the commands (default is to run)
log_Msg "RUN: ${RUN}"

Expand Down Expand Up @@ -814,6 +831,16 @@ T1wFolder="$Path"/"$Subject"/"$T1wFolder"
AtlasSpaceFolder="$Path"/"$Subject"/"$AtlasSpaceFolder"
ResultsFolder="$AtlasSpaceFolder"/"$ResultsFolder"/"$NameOffMRI"

if [[ $QCMode == "only" ]] ; then # Generate QC scene and return
log_Msg "Generating fMRI QC scene and snapshots, then exiting"
"$PipelineScripts"/GenerateFMRIScenes.sh \
--study-folder="$Path" \
--subject="$Subject" \
--fmriname="$NameOffMRI"
--output-folder="$ResultsFolder/fMRIQC"
return
fi

mkdir -p ${T1wFolder}/Results/${NameOffMRI}

if [ ! -e "$fMRIFolder" ] ; then
Expand Down Expand Up @@ -1108,6 +1135,7 @@ ${RUN} ${PipelineScripts}/IntensityNormalization.sh \
#Copy selected files to ResultsFolder
${RUN} cp ${fMRIFolder}/${NameOffMRI}_nonlin_norm.nii.gz ${ResultsFolder}/${NameOffMRI}.nii.gz
${RUN} cp ${fMRIFolder}/${NameOffMRI}_SBRef_nonlin_norm.nii.gz ${ResultsFolder}/${NameOffMRI}_SBRef.nii.gz
${RUN} cp ${fMRIFolder}/${NameOffMRI}_SBRef_nonlin_norm_nomask.nii.gz ${ResultsFolder}/${NameOffMRI}_SBRef_nomask.nii.gz
${RUN} cp ${fMRIFolder}/${JacobianOut}_MNI.${FinalfMRIResolution}.nii.gz ${ResultsFolder}/${NameOffMRI}_${JacobianOut}.nii.gz
${RUN} cp ${fMRIFolder}/${FreeSurferBrainMask}.${FinalfMRIResolution}.nii.gz ${ResultsFolder}
${RUN} cp ${fMRIFolder}/${NameOffMRI}_nonlin_mask.nii.gz ${ResultsFolder}/${NameOffMRI}_fovmask.nii.gz
Expand All @@ -1121,6 +1149,16 @@ ${RUN} cp ${fMRIFolder}/Movement_AbsoluteRMS.txt ${ResultsFolder}
${RUN} cp ${fMRIFolder}/Movement_RelativeRMS_mean.txt ${ResultsFolder}
${RUN} cp ${fMRIFolder}/Movement_AbsoluteRMS_mean.txt ${ResultsFolder}

# Generate fMRIQC scene and snapshots
if [[ $QCMode == "yes" ]] ; then
log_Msg "Generating fMRI QC scene and snapshots"
"$PipelineScripts"/GenerateFMRIScenes.sh \
--study-folder="$Path" \
--subject="$Subject" \
--fmriname="$NameOffMRI"
--output-folder="$ResultsFolder/fMRIQC"
fi

#Basic Cleanup
${FSLDIR}/bin/imrm ${fMRIFolder}/${NameOffMRI}_nonlin_norm

Expand Down
113 changes: 113 additions & 0 deletions fMRIVolume/scripts/GenerateFMRIScenes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/bin/bash
set -eu

pipedirguessed=0
if [[ "${HCPPIPEDIR:-}" == "" ]]
then
export HCPPIPEDIR="$(dirname -- "$0")/../.."
pipedirguessed=1
fi

source "$HCPPIPEDIR/global/scripts/newopts.shlib" "$@"
source "$HCPPIPEDIR/global/scripts/debug.shlib" "$@"
source "$HCPPIPEDIR/global/scripts/relativePath.shlib" "$@"

#this function gets called by opts_ParseArguments when --help is specified
function usage()
{
#header text
echo "
$log_ToolName: makes QC scenes and captures for HCP fMRIVolume pipeline

Usage: $log_ToolName PARAMETER...

PARAMETERs are [ ] = optional; < > = user supplied value
"
#automatic argument descriptions
opts_ShowArguments

#do not use exit, the parsing code takes care of it
}

#arguments to opts_Add*: switch, variable to set, name for inside of <> in help text, description, [default value if AddOptional], [compatibility flag, ...]
#help info for option gets printed like "--foo=<$3> - $4"
opts_AddMandatory '--study-folder' 'StudyFolder' 'path' "folder containing all subjects"
opts_AddMandatory '--subject' 'Subject' 'subject ID' ""
opts_AddMandatory '--fmriname' 'fMRIName' 'fMRI run name' ""
opts_AddMandatory '--output-folder' 'OutputSceneFolder' 'path' "output location for QC scene and snapshots"

opts_AddOptional '--verbose' 'verboseArg' 'true|false' "whether to output more messages, default 'false'" 'false'

opts_ParseArguments "$@"

if ((pipedirguessed))
then
log_Err_Abort "HCPPIPEDIR is not set, you must first source your edited copy of Examples/Scripts/SetUpHCPPipeline.sh"
fi

#display the parsed/default values
opts_ShowValues

#processing code goes here

### --------------------------------------------- ###
### Set Defaults
### --------------------------------------------- ###

TemplatesFolder="$HCPPIPEDIR/global/templates/fMRIQC"

verbose=$(opts_StringToBool "$verboseArg")

### --------------------------------------------- ###
### From here onward should not need any modification

mkdir -p "$OutputSceneFolder"

# Convert TemplatesFolder, StudyFolder, and OutputSceneFolder to absolute paths (for convenience in reporting locations).
TemplatesFolder=$(cd "$TemplatesFolder"; pwd)
StudyFolder=$(cd "$StudyFolder"; pwd)
OutputSceneFolder=$(cd "$OutputSceneFolder"; pwd)

# ----------------------------
# Define variables containing the "dummy strings" used in the template scene
# ----------------------------

# The following are matched to actual strings in the TEMPLATE_fMRIQC.scene file
StudyFolderDummyStr="StudyFolder"
SubjectIDDummyStr="SubjectID"
fMRINameDummyStr="fMRIName"

# ----------------------------
# Begin main action of script
# ----------------------------

scriptDir=$(pwd)

mkdir -p "$OutputSceneFolder"
relPathToStudy=$(relativePath "$OutputSceneFolder" "$StudyFolder")
if ((verbose)); then
echo "TemplatesFolder: $TemplatesFolder"
echo "StudyFolder: $StudyFolder"
echo "OutputSceneFolder: $OutputSceneFolder"
echo "... relative path to StudyFolder (from OutputSceneFolder): $relPathToStudy"
fi

# Replace dummy strings in the template scenes to generate
# a scene file appropriate for each subject and fMRI run
sceneFile="$OutputSceneFolder/${Subject}_${fMRIName}.fMRIQC.wb_scene"
sed -e "s|${StudyFolderDummyStr}|${relPathToStudy}|g" \
-e "s|${SubjectIDDummyStr}|${Subject}|g" \
-e "s|${fMRINameDummyStr}|${fMRIName}|g" \
"$TemplatesFolder"/TEMPLATE_fMRIQC.scene > "$sceneFile"

# Generate snapshots
pngDir="$OutputSceneFolder/snapshots"
mkdir -p "${pngDir}"
#numScenes=$(grep "SceneInfo Index" "$OutputSceneFolder/$sceneFile" | wc -l)
#for ((ind = 1; ind <= numScenes; ind++)); do
scenesToCapture="1 2"
for $ind in $scenesToCapture; do
wb_command -show-scene "$OutputSceneFolder/$sceneFile" $ind "${pngDir}/${sceneFile}${ind}.png" 1400 600 -logging OFF
done

log_Msg "fMRI scene generation completed"
11 changes: 9 additions & 2 deletions fMRIVolume/scripts/IntensityNormalization.sh
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,18 @@ echo "${fMRIMask}, ${PctBrainCoverage}, ${PctMaskCoverage}, ${NvoxT1FOVMask}, ${
# for the main fmri timeseries and the scout images (pre-saturation images)
${FSLDIR}/bin/fslmaths ${InputfMRI} $biascom $jacobiancom -mas ${FinalMask} -thr 0 -ing 10000 ${OutputfMRI} -odt float
if [ X${ScoutInput} != X ] ; then
${FSLDIR}/bin/fslmaths ${ScoutInput} $biascom $jacobiancom -mas ${FinalMask} -thr 0 -ing 10000 ${ScoutOutput} -odt float
# Generate both masked and unmasked versions of scout, but with consistent scaling within the mask
ScoutOutputNotMasked=${ScoutOutput}_nomask
${FSLDIR}/bin/fslmaths ${ScoutInput} $biascom $jacobiancom ${ScoutOutputNotMasked} -odt float
# Compute spatial mean within mask, and normalize to a mean of 10000 inside the mask
scaleFactor=$(${FSLDIR}/bin/fslstats ${ScoutOutputNotMasked} -k ${FinalMask} -l 0 -M)
${FSLDIR}/bin/fslmaths ${ScoutOutputNotMasked} -mul 10000 -div $scaleFactor -thr 0 ${ScoutOutputNotMasked} -odt float
# Apply mask to generate masked version
${FSLDIR}/bin/fslmaths ${ScoutOutputNotMasked} -mas ${FinalMask} ${ScoutOutput} -odt float
fi

#Basic Cleanup
#rm ${InputfMRI}.nii.* #Don't delete the unmasked spatially corrected unormalized data by default
#rm ${InputfMRI}.nii.* #Don't delete the spatially corrected but unmasked and unnormalized data by default

echo " "
echo "END: IntensityNormalization"
Expand Down
24 changes: 24 additions & 0 deletions global/scripts/relativePath.shlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/echo This script should not be run directly:

# ----------------------------
# Function to determine relative paths
# ----------------------------

# We want to use relative paths in scene files, so that they are robust
# against changes in the base directory path. As long as the relative paths
# are preserved, the scene should still work, even if the base directory changes
# (i.e., if the files are moved, or accessed via a different mount point).

# To determine the relative paths, 'realpath --relative-to' is not a robust
# solution, as 'realpath' is not present by default on MacOS, and the
# '--relative-to' option is not supported on older Ubuntu versions.
# So, use the following perl one-liner instead,
# from https://stackoverflow.com/a/17110582

function relativePath {
# both $1 and $2 are absolute paths beginning with /
# returns relative path from $1 to $2
local source=$(cd "$1"; pwd)
local target=$(cd "$2"; pwd)
perl -e 'use File::Spec; print File::Spec->abs2rel(@ARGV) . "\n"' "$target" "$source"
}