Revision 1334b35ab863540044333bbdec70a68fb19ab611 authored by Daisuke MATSUYOSHI on 02 October 2020, 04:04:54 UTC, committed by Tim Coalson on 16 February 2021, 01:12:52 UTC
Fixed typo and made a variable name consistent between VolumeProcessingPipelineBatch and SurfaceProcessingPipelineBatch
1 parent 5bcf9f4
FreeSurferPipeline.sh
#!/bin/bash
#~ND~FORMAT~MARKDOWN~
#~ND~START~
#
# # FreeSurferPipeline.sh
#
# ## Copyright Notice
#
# Copyright (C) 2015-2018 The Human Connectome Project/Connectome Coordination Facility
#
# * Washington University in St. Louis
# * University of Minnesota
# * Oxford University
#
# ## Author(s)
#
# * Matthew F. Glasser, Department of Anatomy and Neurobiology, Washington University in St. Louis
# * Timothy B. Brown, Neuroinformatics Research Group, Washington University in St. Louis
#
# ## Product
#
# [Human Connectome Project](http://www.humanconnectome.org) (HCP) Pipelines
#
# ## License
#
# See the [LICENSE](https://github.com/Washington-University/Pipelines/blob/master/LICENSE.md) file
#
#~ND~END~
# Configure custom tools
# - Determine if the PATH is configured so that the custom FreeSurfer v6 tools used by this script
# (the recon-all.v6.hires script and other scripts called by the recon-all.v6.hires script)
# are found on the PATH. If all such custom scripts are found, then we do nothing here.
# If any one of them is not found on the PATH, then we change the PATH so that the
# versions of these scripts found in ${HCPPIPEDIR}/FreeSurfer/custom are used.
configure_custom_tools()
{
local which_recon_all
local which_conf2hires
local which_longmc
which_recon_all=$(which recon-all.v6.hires)
which_conf2hires=$(which conf2hires)
which_longmc=$(which longmc)
if [[ "${which_recon_all}" = "" || "${which_conf2hires}" == "" || "${which_longmc}" = "" ]] ; then
export PATH="${HCPPIPEDIR}/FreeSurfer/custom:${PATH}"
log_Warn "We were not able to locate one of the following required tools:"
log_Warn "recon-all.v6.hires, conf2hires, or longmc"
log_Warn ""
log_Warn "To be able to run this script using the standard versions of these tools,"
log_Warn "we added ${HCPPIPEDIR}/FreeSurfer/custom to the beginning of the PATH."
log_Warn ""
log_Warn "If you intended to use some other version of these tools, please configure"
log_Warn "your PATH before invoking this script, such that the tools you intended to"
log_Warn "use can be found on the PATH."
log_Warn ""
log_Warn "PATH set to: ${PATH}"
fi
}
# Show tool versions
show_tool_versions()
{
# Show HCP pipelines version
log_Msg "Showing HCP Pipelines version"
${HCPPIPEDIR}/show_version
# Show recon-all version
log_Msg "Showing recon-all.v6.hires version"
local which_recon_all=$(which recon-all.v6.hires)
log_Msg ${which_recon_all}
recon-all.v6.hires -version
# Show tkregister version
log_Msg "Showing tkregister version"
which tkregister
tkregister -version
# Show mri_concatenate_lta version
log_Msg "Showing mri_concatenate_lta version"
which mri_concatenate_lta
mri_concatenate_lta -version
# Show mri_surf2surf version
log_Msg "Showing mri_surf2surf version"
which mri_surf2surf
mri_surf2surf -version
# Show fslmaths location
log_Msg "Showing fslmaths location"
which fslmaths
}
validate_freesurfer_version()
{
if [ -z "${FREESURFER_HOME}" ]; then
log_Err_Abort "FREESURFER_HOME must be set"
fi
freesurfer_version_file="${FREESURFER_HOME}/build-stamp.txt"
if [ -f "${freesurfer_version_file}" ]; then
freesurfer_version_string=$(cat "${freesurfer_version_file}")
log_Msg "INFO: Determined that FreeSurfer full version string is: ${freesurfer_version_string}"
else
log_Err_Abort "Cannot tell which version of FreeSurfer you are using."
fi
# strip out extraneous stuff from FreeSurfer version string
freesurfer_version_string_array=(${freesurfer_version_string//-/ })
freesurfer_version=${freesurfer_version_string_array[5]}
freesurfer_version=${freesurfer_version#v} # strip leading "v"
log_Msg "INFO: Determined that FreeSurfer version is: ${freesurfer_version}"
# break FreeSurfer version into components
# primary, secondary, and tertiary
# version X.Y.Z ==> X primary, Y secondary, Z tertiary
freesurfer_version_array=(${freesurfer_version//./ })
freesurfer_primary_version="${freesurfer_version_array[0]}"
freesurfer_primary_version=${freesurfer_primary_version//[!0-9]/}
freesurfer_secondary_version="${freesurfer_version_array[1]}"
freesurfer_secondary_version=${freesurfer_secondary_version//[!0-9]/}
freesurfer_tertiary_version="${freesurfer_version_array[2]}"
freesurfer_tertiary_version=${freesurfer_tertiary_version//[!0-9]/}
if [[ $(( ${freesurfer_primary_version} )) -lt 6 ]]; then
# e.g. 4.y.z, 5.y.z
log_Err_Abort "FreeSurfer version 6.0.0 or greater is required. (Use FreeSurferPipeline-v5.3.0-HCP.sh if you want to continue using FreeSurfer 5.3)"
fi
}
# Show usage information
show_usage()
{
cat <<EOF
${g_script_name}: Run FreeSurfer processing pipeline
Usage: ${g_script_name}: PARAMETER...
PARAMETERs are: [ ] = optional; < > = user supplied value
[--help] : show usage information and exit
one from the following group is required
--subject-dir=<path to subject directory>
--subjectDIR=<path to subject directory>
--subject=<subject ID>
one from the following group is required, unless --existing-subject is set
--t1w-image=<path to T1w image>
--t1=<path to T1w image>
one from the following group is required, unless --existing-subject is set
--t1w-brain=<path to T1w brain mask>
--t1brain=<path to T1w brain mask>
one from the following group is required, unless --existing-subject is set
--t2w-image=<path to T2w image>
--t2=<path to T2w image>
[--seed=<recon-all seed value>]
[--flair] (experimental)
Indicates that recon-all is to be run with the -FLAIR/-FLAIRpial options
(rather than the -T2/-T2pial options).
The FLAIR input image itself should still be provided via the '--t2' argument.
[--existing-subject]
Indicates that the script is to be run on top of an already existing analysis/subject.
This excludes the '-i' and '-T2/-FLAIR' flags from the invocation of recon-all (i.e., uses previous input volumes).
[The --t1w-image, --t1w-brain and --t2w-image arguments, if provided, are ignored].
It also excludes the -all' flag from the invocation of recon-all.
Consequently, user needs to explicitly specify which recon-all stage(s) to run using the --extra-reconall-arg flag.
This flag allows for the application of FreeSurfer edits.
[--extra-reconall-arg=token] (repeatable)
Generic single token (no whitespace) argument to pass to recon-all.
Provides a mechanism to:
(i) customize the recon-all command
(ii) specify the recon-all stage(s) to be run (e.g., in the case of FreeSurfer edits)
If you want to avoid running all the stages inherent to the '-all' flag in recon-all,
you also need to include the --existing-subject flag.
The token itself may include dashes and equal signs (although Freesurfer doesn't currently use
equal signs in its argument specification).
e.g., [--extra-reconall-arg=-3T] is the correct syntax for adding the stand-alone "-3T" flag to recon-all.
But, [--extra-reconall-arg="-norm3diters 3"] is NOT acceptable.
For recon-all flags that themselves require an argument, you can handle that by specifying
--extra-reconall-arg multiple times (in the proper sequential fashion).
e.g., [--extra-reconall-arg=-norm3diters --extra-reconall-arg=3]
will be translated to "-norm3diters 3" when passed to recon-all
[--no-conf2hires]
Indicates that the script should NOT include -conf2hires as an argument to recon-all.
By default, -conf2hires *IS* included, so that recon-all will place the surfaces on the
hires T1 (and T2).
This is an advanced option, intended for situations where:
(i) the original T1w and T2w images are NOT "hires" (i.e., they are 1 mm isotropic or worse), or
(ii) you want to be able to run some flag in recon-all, without also regenerating the surfaces.
e.g., [--existing-subject --extra-reconall-arg=-show-edits --no-conf2hires]
[--processing-mode=(HCPStyleData|LegacyStyleData)]
Controls whether the HCP acquisition and processing guidelines should be treated as requirements.
"HCPStyleData" (the default) follows the processing steps described in Glasser et al. (2013)
and requires 'HCP-Style' data acquistion.
"LegacyStyleData" allows additional processing functionality and use of some acquisitions
that do not conform to 'HCP-Style' expectations.
In this script, it allows not having a high-resolution T2w image.
PARAMETERs can also be specified positionally as:
${g_script_name} <path to subject directory> <subject ID> <path to T1w image> <path to T1w brain mask> <path to T2w image> [<recon-all seed value>]
Note that the positional approach to specifying parameters does NOT support the
--existing-subject, --extra-reconall-arg, --no-conf2hires, and --processing-mode options.
The positional approach should be considered deprecated, and may be removed in a future version.
EOF
}
get_options()
{
local arguments=($@)
# Note that the ($@) construction parses the arguments into an array of values using spaces as the delimiter
# initialize global output variables
unset p_subject_dir
unset p_subject
unset p_t1w_image
unset p_t1w_brain
unset p_t2w_image
unset p_seed
unset p_flair
unset p_existing_subject
unset p_extra_reconall_args
p_conf2hires="TRUE" # Default is to include -conf2hires flag; do NOT make this variable 'local'
# parse arguments
local num_args=${#arguments[@]}
local argument
local index=0
local extra_reconall_arg
while [ "${index}" -lt "${num_args}" ]; do
argument=${arguments[index]}
case ${argument} in
--help)
show_usage
exit 0
;;
--subject-dir=*)
p_subject_dir=${argument#*=}
index=$(( index + 1 ))
;;
--subjectDIR=*)
p_subject_dir=${argument#*=}
index=$(( index + 1 ))
;;
--subject=*)
p_subject=${argument#*=}
index=$(( index + 1 ))
;;
--t1w-image=*)
p_t1w_image=${argument#*=}
index=$(( index + 1 ))
;;
--t1=*)
p_t1w_image=${argument#*=}
index=$(( index + 1 ))
;;
--t1brain=*)
p_t1w_brain=${argument#*=}
index=$(( index + 1 ))
;;
--t1w-brain=*)
p_t1w_brain=${argument#*=}
index=$(( index + 1 ))
;;
--t2w-image=*)
p_t2w_image=${argument#*=}
index=$(( index + 1 ))
;;
--t2=*)
p_t2w_image=${argument#*=}
index=$(( index + 1 ))
;;
--seed=*)
p_seed=${argument#*=}
index=$(( index + 1 ))
;;
--flair)
p_flair="TRUE"
index=$(( index + 1 ))
;;
--existing-subject)
p_existing_subject="TRUE"
index=$(( index + 1 ))
;;
--extra-reconall-arg=*)
extra_reconall_arg=${argument#*=}
p_extra_reconall_args+="${extra_reconall_arg} "
index=$(( index + 1 ))
;;
--processing-mode=*)
p_processing_mode=${argument#*=}
index=$(( index + 1 ))
;;
--no-conf2hires)
p_conf2hires="FALSE"
index=$(( index + 1 ))
;;
*)
show_usage
log_Err_Abort "unrecognized option: ${argument}"
;;
esac
done
local error_count=0
# ------------------------------------------------------------------------------
# Compliance check
# ------------------------------------------------------------------------------
ProcessingMode=${p_processing_mode:-HCPStyleData}
Compliance="HCPStyleData"
ComplianceMsg=""
# -- T2w image
if [ -z "${p_t2w_image}" ] || [ "${p_t2w_image}" = "NONE" ]; then
if [ -z "${p_existing_subject}" ]; then
ComplianceMsg+=" --t2w-image= or --t2= not present or set to NONE"
Compliance="LegacyStyleData"
fi
p_t2w_image="NONE"
fi
check_mode_compliance "${ProcessingMode}" "${Compliance}" "${ComplianceMsg}"
# ------------------------------------------------------------------------------
# check required parameters
# ------------------------------------------------------------------------------
if [ -z "${p_subject_dir}" ]; then
log_Err "Subject Directory (--subject-dir= or --subjectDIR= or --path= or --study-folder=) required"
error_count=$(( error_count + 1 ))
else
log_Msg "Subject Directory: ${p_subject_dir}"
fi
if [ -z "${p_subject}" ]; then
log_Err "Subject (--subject=) required"
error_count=$(( error_count + 1 ))
else
log_Msg "Subject: ${p_subject}"
fi
if [ -z "${p_t1w_image}" ]; then
if [ -z "${p_existing_subject}" ]; then
log_Err "T1w Image (--t1w-image= or --t1=) required"
error_count=$(( error_count + 1 ))
else
p_t1w_image="NONE" # Need something assigned as a placeholder for positional parameters
fi
else
log_Msg "T1w Image: ${p_t1w_image}"
fi
if [ -z "${p_t1w_brain}" ]; then
if [ -z "${p_existing_subject}" ]; then
log_Err "T1w Brain (--t1w-brain= or --t1brain=) required"
error_count=$(( error_count + 1 ))
else
p_t1w_brain="NONE" # Need something assigned as a placeholder for positional parameters
fi
else
log_Msg "T1w Brain: ${p_t1w_brain}"
fi
# NOTE: Check for T2w image has moved upwards, as missing T2w is allowed in LegacyStyleData processing mode.
# show optional parameters if specified
if [ ! -z "${p_seed}" ]; then
log_Msg "Seed: ${p_seed}"
fi
if [ ! -z "${p_flair}" ]; then
log_Msg "FLAIR (using -FLAIR/-FLAIRpial rather than -T2/-T2pial in recon-all): ${p_flair}"
fi
if [ ! -z "${p_existing_subject}" ]; then
log_Msg "Existing subject (exclude -all, -i, -T2/-FLAIR, and -emregmask flags from recon-all): ${p_existing_subject}"
fi
if [ ! -z "${p_extra_reconall_args}" ]; then
log_Msg "Extra recon-all arguments: ${p_extra_reconall_args}"
fi
if [ ! -z "${p_conf2hires}" ]; then
log_Msg "Include -conf2hires flag in recon-all: ${p_conf2hires}"
fi
if [ ! -z "${p_processing_mode}" ] ; then
log_Msg "ProcessingMode: ${p_processing_mode}"
fi
if [ ${error_count} -gt 0 ]; then
log_Err_Abort "For usage information, use --help"
fi
}
#
# Generate T1w in NIFTI format and in rawavg space
# that has been aligned by BBR but not undergone
# FreeSurfer intensity normalization
#
make_t1w_hires_nifti_file()
{
local working_dir
local t1w_input_file
local t1w_output_file
local mri_convert_cmd
local return_code
working_dir="${1}"
pushd "${working_dir}"
# We should already have the necessary T1w volume.
# It's the rawavg.mgz file. We just need to convert
# it to NIFTI format.
t1w_input_file="rawavg.mgz"
t1w_output_file="T1w_hires.nii.gz"
if [ ! -e "${t1w_input_file}" ]; then
log_Err_Abort "Expected t1w_input_file: ${t1w_input_file} DOES NOT EXIST"
fi
mri_convert_cmd="mri_convert ${t1w_input_file} ${t1w_output_file}"
log_Msg "Creating ${t1w_output_file} with mri_convert_cmd: ${mri_convert_cmd}"
${mri_convert_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "mri_convert command failed with return code: ${return_code}"
fi
popd
}
#
# Generate T2w in NIFTI format and in rawavg space
# that has been aligned by BBR but not undergone
# FreeSurfer intensity normalization
#
make_t2w_hires_nifti_file()
{
local working_dir
local t2w_input_file
local target_volume
local t2w_output_file
local mri_vol2vol_cmd
local return_code
local t2_or_flair
working_dir="${1}"
pushd "${working_dir}"
if [ "${p_flair}" = "TRUE" ]; then
t2_or_flair="FLAIR"
else
t2_or_flair="T2"
fi
# The rawavg.${t2_or_flair}.prenorm.mgz file must exist.
# Then we need to move (resample) it to
# the target volume and convert it to NIFTI format.
t2w_input_file="rawavg.${t2_or_flair}.prenorm.mgz"
target_volume="rawavg.mgz"
t2w_output_file="T2w_hires.nii.gz"
if [ ! -e "${t2w_input_file}" ]; then
log_Err_Abort "Expected t2w_input_file: ${t2w_input_file} DOES NOT EXIST"
fi
if [ ! -e "${target_volume}" ]; then
log_Err_Abort "Expected target_volume: ${target_volume} DOES NOT EXIST"
fi
mri_vol2vol_cmd="mri_vol2vol"
mri_vol2vol_cmd+=" --mov ${t2w_input_file}"
mri_vol2vol_cmd+=" --targ ${target_volume}"
mri_vol2vol_cmd+=" --regheader"
mri_vol2vol_cmd+=" --o ${t2w_output_file}"
log_Msg "Creating ${t2w_output_file} with mri_vol2vol_cmd: ${mri_vol2vol_cmd}"
${mri_vol2vol_cmd}
return_code=$?
if [ "${return_code}" != 0 ]; then
log_Err_Abort "mri_vol2vol command failed with return code: ${return_code}"
fi
popd
}
#
# Generate QC file - T1w X T2w
#
make_t1wxt2w_qc_file()
{
local working_dir
local t1w_input_file
local t2w_input_file
local output_file
local fslmaths_cmd
local return_code
working_dir="${1}"
pushd "${working_dir}"
# We should already have generated the T1w_hires.nii.gz and T2w_hires.nii.gz files
t1w_input_file="T1w_hires.nii.gz"
t2w_input_file="T2w_hires.nii.gz"
output_file="T1wMulT2w_hires.nii.gz"
if [ ! -e "${t1w_input_file}" ]; then
log_Err_Abort "Expected t1w_input_file: ${t1w_input_file} DOES NOT EXIST"
fi
if [ ! -e "${t2w_input_file}" ]; then
log_Err_Abort "Expected t2w_input_file: ${t2w_input_file} DOES NOT EXIST"
fi
fslmaths_cmd="fslmaths"
fslmaths_cmd+=" ${t1w_input_file}"
fslmaths_cmd+=" -mul ${t2w_input_file}"
fslmaths_cmd+=" -sqrt ${output_file}"
log_Msg "Creating ${output_file} with fslmaths_cmd: ${fslmaths_cmd}"
${fslmaths_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "fslmaths command failed with return code: ${return_code}"
fi
popd
}
main()
{
local SubjectDIR
local SubjectID
local T1wImage
local T1wImageBrain
local T2wImage
local recon_all_seed
local flair="FALSE"
local existing_subject="FALSE"
local extra_reconall_args
local conf2hires="TRUE"
local num_cores
local zero_threshold_T1wImage
local return_code
local recon_all_cmd
local mridir
local transformsdir
local eye_dat_file
local tkregister_cmd
local mri_concatenate_lta_cmd
local mri_surf2surf_cmd
local t2_or_flair
local T2wtoT1wFile="T2wtoT1w.mat" # Calling this file T2wtoT1w.mat regardless of whether the input to recon-all was -T2 or -FLAIR
local OutputOrigT1wToT1w="OrigT1w2T1w" # Needs to match name used in PostFreeSurfer (N.B. "OrigT1" here refers to the T1w/T1w.nii.gz file; NOT FreeSurfer's "orig" space)
# ----------------------------------------------------------------------
log_Msg "Starting main functionality"
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
log_Msg "Retrieve positional parameters"
# ----------------------------------------------------------------------
SubjectDIR="${1}"
SubjectID="${2}"
T1wImage="${3}" # Irrelevant if '--existing-subject' flag is set
T1wImageBrain="${4}" # Irrelevant if '--existing-subject' flag is set
T2wImage="${5}" # Irrelevant if '--existing-subject' flag is set
recon_all_seed="${6}"
## MPH: Hack!
# For backwards compatibility, continue to allow positional specification of parameters for the above set of 6 parameters.
# But any new parameters/options in the script will only be accessible via a named parameter/flag.
# Here, we retrieve those from the global variable that was set in get_options()
if [ "${p_flair}" = "TRUE" ]; then
flair=${p_flair}
fi
if [ "${p_existing_subject}" = "TRUE" ]; then
existing_subject=${p_existing_subject}
fi
if [ ! -z "${p_extra_reconall_args}" ]; then
extra_reconall_args="${p_extra_reconall_args}"
fi
if [ ! -z "${p_conf2hires}" ]; then
conf2hires=${p_conf2hires}
fi
# ----------------------------------------------------------------------
# Log values retrieved from positional parameters
# ----------------------------------------------------------------------
log_Msg "SubjectDIR: ${SubjectDIR}"
log_Msg "SubjectID: ${SubjectID}"
log_Msg "T1wImage: ${T1wImage}"
log_Msg "T1wImageBrain: ${T1wImageBrain}"
log_Msg "T2wImage: ${T2wImage}"
log_Msg "recon_all_seed: ${recon_all_seed}"
log_Msg "flair: ${flair}"
log_Msg "existing_subject: ${existing_subject}"
log_Msg "extra_reconall_args: ${extra_reconall_args}"
log_Msg "conf2hires: ${conf2hires}"
# ----------------------------------------------------------------------
log_Msg "Figure out the number of cores to use."
# ----------------------------------------------------------------------
# Both the SGE and PBS cluster schedulers use the environment variable NSLOTS to indicate the
# number of cores a job will use. If this environment variable is set, we will use it to
# determine the number of cores to tell recon-all to use.
num_cores=0
if [[ -z ${NSLOTS} ]]; then
num_cores=8
else
num_cores="${NSLOTS}"
fi
log_Msg "num_cores: ${num_cores}"
if [ "${existing_subject}" != "TRUE" ]; then
# If --existing-subject is NOT set, AND PostFreeSurfer has been run, then
# certain files need to be reverted to their PreFreeSurfer output versions
if [ `imtest ${SubjectDIR}/xfms/${OutputOrigT1wToT1w}` = 1 ]; then
log_Err "The --existing-subject flag was not invoked AND PostFreeSurfer has already been run."
log_Err "If attempting to run FreeSurfer de novo, certain files (e.g., <subj>/T1w/{T1w,T2w}_acpc_dc*) need to be reverted to their PreFreeSurfer outputs."
log_Err_Abort "If this is the goal, delete ${SubjectDIR}/${SubjectID} AND re-run PreFreeSurfer, before invoking FreeSurfer again."
fi
# ----------------------------------------------------------------------
log_Msg "Thresholding T1w image to eliminate negative voxel values"
# ----------------------------------------------------------------------
zero_threshold_T1wImage=$(remove_ext ${T1wImage})_zero_threshold.nii.gz
log_Msg "...This produces a new file named: ${zero_threshold_T1wImage}"
fslmaths ${T1wImage} -thr 0 ${zero_threshold_T1wImage}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "fslmaths command failed with return_code: ${return_code}"
fi
fi
# ----------------------------------------------------------------------
log_Msg "Call custom recon-all: recon-all.v6.hires"
# ----------------------------------------------------------------------
recon_all_cmd="recon-all.v6.hires"
recon_all_cmd+=" -subjid ${SubjectID}"
recon_all_cmd+=" -sd ${SubjectDIR}"
if [ "${existing_subject}" != "TRUE" ]; then # input volumes only necessary first time through
recon_all_cmd+=" -all"
recon_all_cmd+=" -i ${zero_threshold_T1wImage}"
recon_all_cmd+=" -emregmask ${T1wImageBrain}"
if [ "${T2wImage}" != "NONE" ]; then
if [ "${flair}" = "TRUE" ]; then
recon_all_cmd+=" -FLAIR ${T2wImage}"
else
recon_all_cmd+=" -T2 ${T2wImage}"
fi
fi
fi
# By default, refine pial surfaces using T2 (if T2w image provided).
# If for some other reason the -T2pial flag needs to be excluded from recon-all,
# this can be accomplished using --extra-reconall-arg=-noT2pial
if [ "${T2wImage}" != "NONE" ]; then
if [ "${flair}" = "TRUE" ]; then
recon_all_cmd+=" -FLAIRpial"
else
recon_all_cmd+=" -T2pial"
fi
fi
recon_all_cmd+=" -openmp ${num_cores}"
if [ ! -z "${recon_all_seed}" ]; then
recon_all_cmd+=" -norandomness -rng-seed ${recon_all_seed}"
fi
if [ ! -z "${extra_reconall_args}" ]; then
recon_all_cmd+=" ${extra_reconall_args}"
fi
# The -conf2hires flag should come after the ${extra_reconall_args} string, since it needs
# to have the "final say" over a couple settings within recon-all
if [ "${conf2hires}" = "TRUE" ]; then
recon_all_cmd+=" -conf2hires"
fi
log_Msg "...recon_all_cmd: ${recon_all_cmd}"
${recon_all_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "recon-all command failed with return_code: ${return_code}"
fi
if [ "${existing_subject}" != "TRUE" ]; then
# ----------------------------------------------------------------------
log_Msg "Clean up file: ${zero_threshold_T1wImage}"
# ----------------------------------------------------------------------
rm ${zero_threshold_T1wImage}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "rm ${zero_threshold_T1wImage} failed with return_code: ${return_code}"
fi
fi
## MPH: Portions of the following are unnecesary in the case of ${existing_subject} = "TRUE"
## but rather than identify what is and isn't strictly necessary (which itself may interact
## with the specific stages run in recon-all), we'll simply run it all to be safe that all
## files created following recon-all are appropriately updated
# ----------------------------------------------------------------------
log_Msg "Creating eye.dat"
# ----------------------------------------------------------------------
mridir=${SubjectDIR}/${SubjectID}/mri
transformsdir=${mridir}/transforms
mkdir -p ${transformsdir}
eye_dat_file=${transformsdir}/eye.dat
log_Msg "...This creates ${eye_dat_file}"
echo "${SubjectID}" > ${eye_dat_file}
echo "1" >> ${eye_dat_file}
echo "1" >> ${eye_dat_file}
echo "1" >> ${eye_dat_file}
echo "1 0 0 0" >> ${eye_dat_file}
echo "0 1 0 0" >> ${eye_dat_file}
echo "0 0 1 0" >> ${eye_dat_file}
echo "0 0 0 1" >> ${eye_dat_file}
echo "round" >> ${eye_dat_file}
if [ "${T2wImage}" != "NONE" ]; then
# ----------------------------------------------------------------------
log_Msg "Making T2w to T1w registration available in FSL format"
# ----------------------------------------------------------------------
pushd ${mridir}
if [ "${flair}" = "TRUE" ]; then
t2_or_flair="FLAIR"
else
t2_or_flair="T2"
fi
log_Msg "...Create a registration between the original conformed space and the rawavg space"
tkregister_cmd="tkregister"
tkregister_cmd+=" --mov orig.mgz"
tkregister_cmd+=" --targ rawavg.mgz"
tkregister_cmd+=" --regheader"
tkregister_cmd+=" --noedit"
tkregister_cmd+=" --reg deleteme.dat"
tkregister_cmd+=" --ltaout transforms/orig-to-rawavg.lta"
tkregister_cmd+=" --s ${SubjectID}"
log_Msg "......The following produces deleteme.dat and transforms/orig-to-rawavg.lta"
log_Msg "......tkregister_cmd: ${tkregister_cmd}"
${tkregister_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "tkregister command failed with return_code: ${return_code}"
fi
log_Msg "...Concatenate the ${t2_or_flair}raw->orig and orig->rawavg transforms"
mri_concatenate_lta_cmd="mri_concatenate_lta"
mri_concatenate_lta_cmd+=" transforms/${t2_or_flair}raw.lta"
mri_concatenate_lta_cmd+=" transforms/orig-to-rawavg.lta"
mri_concatenate_lta_cmd+=" Q.lta"
log_Msg "......The following concatenates transforms/${t2_or_flair}raw.lta and transforms/orig-to-rawavg.lta to get Q.lta"
log_Msg "......mri_concatenate_lta_cmd: ${mri_concatenate_lta_cmd}"
${mri_concatenate_lta_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "mri_concatenate_lta command failed with return_code: ${return_code}"
fi
log_Msg "...Convert to FSL format"
tkregister_cmd="tkregister"
tkregister_cmd+=" --mov orig/${t2_or_flair}raw.mgz"
tkregister_cmd+=" --targ rawavg.mgz"
tkregister_cmd+=" --reg Q.lta"
tkregister_cmd+=" --fslregout transforms/${T2wtoT1wFile}"
tkregister_cmd+=" --noedit"
log_Msg "......The following produces the transforms/${T2wtoT1wFile} file that we need"
log_Msg "......tkregister_cmd: ${tkregister_cmd}"
${tkregister_cmd}
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "tkregister command failed with return_code: ${return_code}"
fi
log_Msg "...Clean up"
rm deleteme.dat
rm Q.lta
popd
fi
# ----------------------------------------------------------------------
log_Msg "Creating white surface files in rawavg space"
# ----------------------------------------------------------------------
pushd ${mridir}
export SUBJECTS_DIR="$SubjectDIR"
reg=$mridir/transforms/orig2rawavg.dat
# generate registration between conformed and hires based on headers
# Note that the convention of tkregister2 is that the resulting $reg is the registration
# matrix that maps from the "--targ" space into the "--mov" space.
tkregister2 --mov ${mridir}/rawavg.mgz --targ ${mridir}/orig.mgz --noedit --regheader --reg $reg
#The ?h.white.deformed surfaces are used in FreeSurfer BBR registrations for fMRI and diffusion and have been moved into the HCP's T1w space so that BBR produces a transformation containing only the minor adjustment to the registration.
mri_surf2surf --s ${SubjectID} --sval-xyz white --reg $reg --tval-xyz ${mridir}/rawavg.mgz --tval white.deformed --surfreg white --hemi lh
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "mri_surf2surf command for left hemisphere failed with return_code: ${return_code}"
fi
mri_surf2surf --s ${SubjectID} --sval-xyz white --reg $reg --tval-xyz ${mridir}/rawavg.mgz --tval white.deformed --surfreg white --hemi rh
return_code=$?
if [ "${return_code}" != "0" ]; then
log_Err_Abort "mri_surf2surf command for right hemisphere failed with return_code: ${return_code}"
fi
popd
# ----------------------------------------------------------------------
log_Msg "Generating QC file"
# ----------------------------------------------------------------------
make_t1w_hires_nifti_file "${mridir}"
if [ "${T2wImage}" != "NONE" ]; then
make_t2w_hires_nifti_file "${mridir}"
make_t1wxt2w_qc_file "${mridir}"
fi
# ----------------------------------------------------------------------
log_Msg "Completing main functionality"
# ----------------------------------------------------------------------
}
# Global processing - everything above here should be in a function
g_script_name=$(basename "${0}")
# Allow script to return a Usage statement, before any other output or checking
if [ "$#" = "0" ]; then
show_usage
exit 1
fi
# ------------------------------------------------------------------------------
# Check that HCPPIPEDIR is defined and Load Function Libraries
# ------------------------------------------------------------------------------
if [ -z "${HCPPIPEDIR}" ]; then
echo "${g_script_name}: ABORTING: HCPPIPEDIR environment variable must be set"
exit 1
fi
source "${HCPPIPEDIR}/global/scripts/debug.shlib" "$@" # Debugging functions; also sources log.shlib
source ${HCPPIPEDIR}/global/scripts/opts.shlib # Command line option functions
source ${HCPPIPEDIR}/global/scripts/processingmodecheck.shlib # Check processing mode requirements
opts_ShowVersionIfRequested $@
if opts_CheckForHelpRequest $@; then
show_usage
exit 0
fi
${HCPPIPEDIR}/show_version
# ------------------------------------------------------------------------------
# Verify required environment variables are set and log value
# ------------------------------------------------------------------------------
log_Check_Env_Var HCPPIPEDIR
log_Check_Env_Var FREESURFER_HOME
# Platform info
log_Msg "Platform Information Follows: "
uname -a
# Configure the use of FreeSurfer v6 custom tools
configure_custom_tools
# Show tool versions
show_tool_versions
# Validate version of FreeSurfer in use
validate_freesurfer_version
# Determine whether named or positional parameters are used
if [[ ${1} == --* ]]; then
# Named parameters (e.g. --parameter-name=parameter-value) are used
log_Msg "Using named parameters"
# Get command line options
# Sets the following parameter variables:
# p_subject_dir, p_subject, p_t1w_image, p_t2w_image, p_seed (optional)
get_options "$@"
# Invoke main functionality using positional parameters
# ${1} ${2} ${3} ${4} ${5} ${6}
main "${p_subject_dir}" "${p_subject}" "${p_t1w_image}" "${p_t1w_brain}" "${p_t2w_image}" "${p_seed}"
else
# Positional parameters are used
log_Msg "Using positional parameters"
main $@
fi
log_Msg "Completed!"
exit 0
Computing file changes ...