Skip to content

Commit

Permalink
Transmit bias pipeline (#298)
Browse files Browse the repository at this point in the history
  • Loading branch information
coalsont authored Nov 15, 2024
1 parent 6957c04 commit daaeafe
Show file tree
Hide file tree
Showing 101 changed files with 11,351 additions and 45 deletions.
185 changes: 185 additions & 0 deletions Examples/Scripts/TransmitBiasBatch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#!/bin/bash
set -eu

#environment configuration
queue="long.q"
EnvironmentScript="${HOME}/projects/Pipelines/Examples/Scripts/SetUpHCPPipeline.sh" #Pipeline environment script

#data location
#DISCUSS: should this be "sessions"? other batch scripts use subjects, but...
subjects=(123456 654321)
StudyFolder="${HOME}/projects/YA_HCP_Final"
GroupName="HCP_S1200"

#general settings
#identifier for the subset of subjects that have transmit field scans
#pseudotransmit doesn't have subject exclusion logic, or if you otherwise have made sure the entire group has good transmit data, you may want to set it equal to the group folder name
partialname=Partial
#partialname="$GroupName"
#set this to a text file that has the scanner transmit voltages for all subjects in the provided list, in order
VoltagesFile="$StudyFolder"/"$GroupName"/Scripts/Voltages.txt
GradientDistortionCoeffs=
RegName=MSMAll
LowResMesh=32
grayordRes=2
transmitRes="$grayordRes"
MyelinMappingFWHM=5
oldMyelinMapping=FALSE
#0 for compiled, 1 for interpreted, 2 for octave
MatlabMode=0

#transmit field acquisition details
#mode must be AFI, B1Tx, or PseudoTransmit
mode="AFI"
#mode="B1Tx"
#mode="PseudoTransmit"

#AFI-specific settings
AFITRone=20
AFITRtwo=120
AFITargetFlipAngle=50

#B1Tx-specific settings
#the value in the phase image where the flip angle was ideal
B1TxPhaseDivisor=800

#PseudoTransmit-specific settings
fMRINames=rfMRI_REST1_AP@rfMRI_REST1_PA
ptbbrthresh=0.5
#set this to an already transmit-corrected group average myelin map
ReferenceTemplate=

#ALSO, edit the input filenames inside the first loop below

#probably shouldn't edit this stuff
if [[ "$RegName" == "" || "$RegName" == "MSMSulc" ]]
then
RegStr=""
else
RegStr="_$RegName"
fi
GMWMtemplate="$StudyFolder"/"$GroupName"/MNINonLinear/GMWMTemplate.nii.gz
GroupCorrected="$StudyFolder"/"$GroupName"/MNINonLinear/fsaverage_LR"$LowResMesh"k/"$partialname".MyelinMap_GroupCorr"$RegStr"."$LowResMesh"k_fs_LR.dscalar.nii
GroupUncorrectedMyelin="$StudyFolder"/"$GroupName"/MNINonLinear/fsaverage_LR"$LowResMesh"k/"$partialname".MyelinMap"$RegStr"."$LowResMesh"k_fs_LR.dscalar.nii
#DISCUSS: not sure if external users need to generate this
AllSubjUncorrected="$StudyFolder"/"$GroupName"/MNINonLinear/fsaverage_LR"$LowResMesh"k/"$partialname".All.MyelinMap"$RegStr"."$LowResMesh"k_fs_LR.dscalar.nii
PTRefValFile="$StudyFolder"/"$GroupName"/PT_refval.txt

source "$EnvironmentScript"

phase1jobids=()
for subject in "${subjects[@]}"
do
#AFI-specific per-subject filenames
AFIImage=

#B1Tx-specific per-subject filenames
B1TxMag=
B1TxPhase=

#Receive bias inputs - ignore this if you used pre-scan normalize or similar
#unprocessed T1w and T2w are required to do receive correction
T1wUnprocList=
T2wUnprocList=
#use these two if you separately acquired bodycoil and headcoil images
BodyCoilImage=
HeadCoilImage=
#use these two if you acquired a PSN T1w and also saved its non-PSN reconstruction (but all the other raw image inputs are non-PSN)
rawT1wPSN=
rawT1wNoPSN=

phase1jobids+=($(fsl_sub -q "$queue" "$HCPPIPEDIR"/TransmitBias/Phase1_IndividualAlign.sh \
--study-folder="$StudyFolder" \
--subject="$subject" \
--mode="$mode" \
--afi-image="$AFIImage" \
--afi-tr-one="$AFITRone" \
--afi-tr-two="$AFITRtwo" \
--b1tx-magnitude="$B1TxMag" \
--b1tx-phase="$B1TxPhase" \
--b1tx-phase-divisor="$B1TxPhaseDivisor" \
--pt-fmri-names="$fMRINames" \
--pt-bbr-threshold="$ptbbrthresh" \
--unproc-t1w-list="$T1wUnprocList" \
--unproc-t2w-list="$T2wUnprocList" \
--receive-bias-body-coil="$BodyCoilImage" \
--receive-bias-head-coil="$HeadCoilImage" \
--raw-psn-t1w="$rawT1wPSN" \
--raw-nopsn-t1w="$rawT1wNoPSN" \
--scanner-grad-coeffs="$GradientDistortionCoeffs" \
--reg-name="$RegName" \
--low-res-mesh="$LowResMesh" \
--grayordinates-res="$grayordRes" \
--transmit-res="$transmitRes" \
--myelin-mapping-fwhm="$MyelinMappingFWHM" \
--old-myelin-mapping="$oldMyelinMapping"))
done

subjectsStr=$(IFS='@'; echo "${subjects[*]}")
useRCFiles=FALSE
if [[ "$T1wUnprocList" != "" ]]
then
useRCFiles=TRUE
fi

mkdir -p "$StudyFolder"/"$GroupName"

phase1jobstr=$(IFS=','; echo "${phase1jobids[*]}")
phase2job=$(fsl_sub -q "$queue" -j "$phase1jobstr" "$HCPPIPEDIR"/TransmitBias/Phase2_GroupAverageFit.sh \
--study-folder="$StudyFolder" \
--subject-list="$subjectsStr" \
--mode="$mode" \
--group-average-name="$GroupName" \
--transmit-group-name="$partialname" \
--manual-receive="$useRCFiles" \
--gmwm-template-out="$GMWMtemplate" \
--average-myelin-out="$GroupUncorrectedMyelin" \
--all-myelin-out="$AllSubjUncorrected" \
--afi-tr-one="$AFITRone" \
--afi-tr-two="$AFITRtwo" \
--afi-angle="$AFITargetFlipAngle" \
--reference-value-out="$PTRefValFile" \
--reg-name="$RegName" \
--low-res-mesh="$LowResMesh" \
--grayordinates-res="$grayordRes" \
--matlab-run-mode="$MatlabMode")

phase3jobids=()
for subject in "${subjects[@]}"
do
phase3jobids+=($(fsl_sub -q "$queue" -j "$phase2job" "$HCPPIPEDIR"/TransmitBias/Phase3_IndividualAdjustment.sh \
--study-folder="$StudyFolder" \
--subject="$subject" \
--mode="$mode" \
--manual-receive="$useRCFiles" \
--gmwm-template="$GMWMtemplate" \
--afi-tr-one="$AFITRone" \
--afi-tr-two="$AFITRtwo" \
--afi-angle="$AFITargetFlipAngle" \
--group-corrected-myelin="$GroupCorrected" \
--myelin-template="$ReferenceTemplate" \
--group-uncorrected-myelin="$GroupUncorrectedMyelin" \
--pt-reference-value-file="$PTRefValFile" \
--reg-name="$RegName" \
--low-res-mesh="$LowResMesh" \
--grayordinates-res="$grayordRes" \
--transmit-res="$transmitRes" \
--matlab-run-mode="$MatlabMode"))
done

phase3jobstr=$(IFS=','; echo "${phase3jobids[*]}")
fsl_sub -q "$queue" -j "$phase3jobstr" "$HCPPIPEDIR"/TransmitBias/Phase4_GroupAverageCorrectedMaps.sh \
--study-folder="$StudyFolder" \
--subject-list="$subjectsStr" \
--mode="$mode" \
--group-average-name="$GroupName" \
--transmit-group-name="$partialname" \
--voltages="$VoltagesFile" \
--afi-tr-one="$AFITRone" \
--afi-tr-two="$AFITRtwo" \
--afi-angle="$AFITargetFlipAngle" \
--average-myelin="$GroupUncorrectedMyelin" \
--reg-name="$RegName" \
--low-res-mesh="$LowResMesh" \
--matlab-run-mode="$MatlabMode"

48 changes: 38 additions & 10 deletions PostFreeSurfer/PostFreeSurferPipeline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,13 @@ PARAMETERs are [ ] = optional; < > = user supplied value

defaultSigma=$(echo "sqrt(200)" | bc -l)

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

#TSC:should --path or --study-folder be the flag displayed by the usage?
opts_AddMandatory '--study-folder' 'StudyFolder' 'path' "folder containing all subjects" "--path"
opts_AddMandatory '--session' 'Session' 'session ID' "session (timepoint, visit) label." "--subject" #legacy --subject option
opts_AddMandatory '--surfatlasdir' 'SurfaceAtlasDIR' 'path' "<HCPpipelines>/global/templates/standard_mesh_atlases or equivalent"
opts_AddMandatory '--grayordinatesres' 'GrayordinatesResolutions' 'number' "usually '2', resolution of grayordinates to use"
opts_AddMandatory '--grayordinatesdir' 'GrayordinatesSpaceDIR' 'path' "<HCPpipelines>/global/templates/<num>_Greyordinates or equivalent, for the given --grayordinatesres"
opts_AddMandatory '--hiresmesh' 'HighResMesh' 'number' "usually '164', the standard mesh for T1w-resolution data data"
opts_AddMandatory '--lowresmesh' 'LowResMeshes' 'number' "usually '32', the standard mesh for fMRI data"
opts_AddOptional '--surfatlasdir' 'SurfaceAtlasDIR' 'path' "path to find low resolution spheres, etc, default <pipelines>/global/templates/standard_mesh_atlases" "$HCPPIPEDIR/global/templates/standard_mesh_atlases"
opts_AddOptional '--grayordinatesres' 'GrayordinatesResolution' 'number' "resolution of grayordinates to use, default 2" '2'
opts_AddOptional '--grayordinatesdir' 'GrayordinatesSpaceDIR' 'path' "<pipelines>/global/templates/<num>_Greyordinates or equivalent, for the given --grayordinatesres"
opts_AddOptional '--hiresmesh' 'HighResMesh' 'number' "the standard mesh for T1w-resolution data data, default 164" '164'
opts_AddOptional '--lowresmesh' 'LowResMeshes' 'number' "the standard mesh(es) to use for fMRI data, like 32@59"
opts_AddMandatory '--subcortgraylabels' 'SubcorticalGrayLabels' 'file' "location of FreeSurferSubcorticalLabelTableLut.txt"
opts_AddMandatory '--freesurferlabels' 'FreeSurferLabels' 'file' "location of FreeSurferAllLut.txt"
opts_AddMandatory '--refmyelinmaps' 'ReferenceMyelinMaps' 'file' "group myelin map to use for bias correction"
Expand Down Expand Up @@ -129,6 +125,38 @@ fi
#display the parsed/default values
opts_ShowValues

#internal scripts don't actually support multiple low res in one call, mostly because they are in different folders
if [[ "$GrayordinatesSpaceDIR" == "" ]]
then
case "$GrayordinatesResolution" in
(2)
GrayordinatesSpaceDIR="$HCPPIPEDIR"/global/templates/91282_Greyordinates
;;
(1.60)
GrayordinatesSpaceDIR="$HCPPIPEDIR"/global/templates/170494_Greyordinates
;;
(*)
log_Err_Abort "grayordinate resolution '$GrayordinatesResolution' not recognized as a standard resolution, please use '2', '1.60', or specify --grayordinatesdir manually"
;;
esac
fi

#internal scripts do support lists for this LowResMeshes though...
if [[ "$LowResMeshes" == "" ]]
then
case "$GrayordinatesResolution" in
(2)
LowResMeshes=32
;;
(1.60)
LowResMeshes=59
;;
(*)
log_Err_Abort "grayordinate resolution '$GrayordinatesResolution' not recognized as a standard resolution, please use '2', '1.60', or specify --lowresmesh manually"
;;
esac
fi

doProcessing=1
doQC=1

Expand Down Expand Up @@ -306,7 +334,7 @@ if ((doProcessing)); then
argList+=("$T1wImageBrainMask") # ${17}
argList+=("$FreeSurferLabels") # ${18}
argList+=("$GrayordinatesSpaceDIR") # ${19}
argList+=("$GrayordinatesResolutions") # ${20}
argList+=("$GrayordinatesResolution") # ${20}
argList+=("$SubcorticalGrayLabels") # ${21}
argList+=("$RegName") # ${22}
argList+=("$InflateExtraScale") # ${23}
Expand Down
Loading

0 comments on commit daaeafe

Please sign in to comment.