Commit 47076547 authored by Shaun Warrington's avatar Shaun Warrington
Browse files

Merge branch 'xtract_stats' into 'master'

XTRACT stats

See merge request !13
parents 5a3285c7 a8371341
......@@ -16,13 +16,16 @@ Saad Jbabdi, Kathryn Bryant, Shaun Warrington, Marina Charquero-Ballester, Gwena
The XTRACT viewer helper script was written by Shaun Warrington
The XTRACT stats helper script was written by Shaun Warrington
---------------------------------------------------------------------
## Citations:
Warrington S, Bryant K, Charquero-Ballester M, Douaud G, Jbabdi S*, Mars R*, Sotiropoulos SN* (Submitted)
Standardised protocols for automated tractography and connectivity blueprints in the human and macaque brain.
Warrington S, Bryant K, Khrapitchev A, Sallet J, Charquero-Ballester M, Douaud G, Jbabdi S*, Mars R*,
Sotiropoulos SN* (2020) XTRACT - Standardised protocols for automated tractography in the human and
macaque brain. NeuroImage. DOI: 10.1016/j.neuroimage.2020.116923
de Groot M; Vernooij MW. Klein S, Ikram MA, Vos FM, Smith SM, Niessen WJ, Andersson JLR (2013)
Improving alignment in Tract-based spatial statistics: Evaluation and optimization of image registration.
......@@ -53,7 +56,7 @@ NeuroImage, 76(1), 400-411. DOI: 10.1016/j.neuroimage.2013.03.015
Optional arguments:
-list List the tract names used in XTRACT
-str <file> Structures file (format: <tractName> per line OR format: <tractName> [samples=1], 1 means 1000, '#' to skip lines)
-p <folder> Protocols folder (all masks in same standard space) (Default=$FSLDIR/etc/xtract_data/<SPECIES>)
-p <folder> Protocols folder (all masks in same standard space) (Default=$FSLDIR/data/xtract_data/<SPECIES>)
-stdwarp <std2diff> <diff2std> Standard2diff and Diff2standard transforms (Default=bedpostx_dir/xfms/{standard2diff,diff2standard})
-gpu Use GPU version
-res <mm> Output resolution (Default=same as in protocol folders unless '-native' used)
......@@ -69,18 +72,56 @@ NeuroImage, 76(1), 400-411. DOI: 10.1016/j.neuroimage.2013.03.015
---------------------------------------------------------------------
## Running XTRACT:
XTRACT automatically detects if $SGE_ROOT is set and if so uses FSL_SUB.
For optimal performance, use the GPU version!!!!
XTRACT automatically detects if $SGE_ROOT is set and if so uses FSL_SUB. For optimal performance, use the GPU version!!!!
**Outputs of XTRACT**
Under outputDir:
- "commands.txt" - XTRACT processing commands
- "logs" - directory containing the probtrackx log files
- "tracts" - directory continaing tractography results
- "tractName" - directory per tract, each continaing:
- "waytotal" - txt file continaing the number of valid streamlines
- "density.nii.gz" - nifti file containing the fibre probability distribution
- "density_lenths.nii.gz" - nifti file containing the fibre lengths, i.e. each voxel is the
average streamline length - this is the "-ompl" probtrackx option
- "densityNorm.nii.gz" - nifti file continaing the waytotal normalised fibre probability distribution
(the "density.nii.gz" divided by the total number of valid streamlines)
- If the protocol calls for reverse-seeding:
- "tractsInv" - directory continaing the above for the seed-target reversed run
- "sum_waytotal" and "sum_density.nii.gz" - the summed waytotal and fibre probability distribution
- If the "-native" option is being used:
- "masks" - directory
- "tractName" - directory per tract continaing the native space protocol masks
The primary output is the "densityNorm.nii.gz" file.
**Pre-processing**
Prior to running XTRACT, you must complete the FDT processing pipeline:
1. Brain extraction using BET
2. Susceptibility distortion correction using topup (only if spin-echo fieldmaps have been
acquired - if you don't have these, skip to step 3)
3. Eddy current distortion and motion correction using eddy
4. Fit the crossing fibre model using bedpostx
5. Registration to standard space (MNI152), see the FDT pipeline
Your data should now be ready to run XTRACT!
---------------------------------------------------------------------
## Atlases:
- For HUMAN, XTRACT uses the MNI152 standard space in $FSLDIR/etc/standard
- For HUMAN, XTRACT uses the MNI152 standard space in $FSLDIR/data/standard
- For MACAQUE, XTRACT uses the F99 atlas in Caret - see http://brainvis.wustl.edu/wiki/index.php/Caret:Atlases
We also provide a copy of the F99 atlas in $FSLDIR/etc/xtract_data/standard/F99. This includes a helper script for registering your own diffusion/structural data to the F99 altas
We also provide a copy of the F99 atlas in $FSLDIR/data/xtract_data/standard/F99. This
includes a helper script for registering your own diffusion/structural data to the F99 altas
When running XTRACT with the '-species' option, a predefined list of tracts is automatically extracted. Currently the following tracts are available:
......@@ -118,7 +159,7 @@ OR
tractName nsamples, per line
For an example, see $FSLDIR/etc/xtract_data/Human/structureList
For an example, see $FSLDIR/data/xtract_data/Human/structureList
---------------------------------------------------------------------
......@@ -142,15 +183,19 @@ Then create the following NIFTI files (with this exact naming) and copy them int
- invert (empty file to indicate that a seed->target and target->seed run will be added and combined)
if such an option is required a single "target.nii.gz" file is also expected
All the masks above should be in standard space (e.g. MNI152 or F99) if you want to run the same tracking for a collection of subjects.
All the masks above should be in standard space (e.g. MNI152 or F99) if you want to run
the same tracking for a collection of subjects.
Next, make a structure file using the format <tractName> <nsamples> per line and call XTRACT using -species <SPECIES> -str <file> -p <folder>, pointing to your new protocols folder 'mytrack'.
Next, make a structure file using the format `<tractName> <nsamples>` per line and call XTRACT
using `-species <SPECIES> -str <file> -p <folder>`, pointing to your new protocols folder 'mytrack'.
---------------------------------------------------------------------
## Visualising results with FSLEYES
The output of XTRACT is a folder that contains tracts in separate folders. We provide a convenient script that can load these tracts (or a subset of the tracts) into FSLEYES using different colours for the different tracts but matching the left/right colours
The output of XTRACT is a folder that contains tracts in separate folders. We provide a
convenient script that can load these tracts (or a subset of the tracts) into FSLEYES using
different colours for the different tracts but matching the left/right colours
```
__ _______ ____ _ ____ _____ _
......@@ -184,3 +229,54 @@ The output of XTRACT is a folder that contains tracts in separate folders. We pr
Default = 0.001 0.1
```
---------------------------------------------------------------------
## Extracting tract-wise summary statistics
A common usage of the XTRACT output is to summarise tracts in terms of simple summary
statistics, such as their volume and microstructural properties (e.g. mean FA). We provide XTRACT
stats to get such summary statistics in a quick and simple way.
You can use XTRACT stats with any modelled diffusion data, e.g. DTI, bedpostx, DKI.
Simply provide; the directory (and basename of files, if any) leading to the diffusion
data of interest, the directory containing the XTRACT output, the warp field (or use 'native'
if tracts are already in diffusion space). If tracts are not in diffusion space, you must also
provide a reference image in diffusion space (e.g. FA map).
e.g. call: xtract_stats -d /home/DTI/dti_ -xtract /home/xtract -w /home/warp/standard2diff -r /home/DTI/dti_FA
The output (a .csv file) by default contains the tract volume (mm3) and the mean, median and
standard deviation of the probability, length, FA and MD for each tract.
```
__ _______ ____ _ ____ _____ _ _
\ \/ /_ _| _ \ / \ / ___|_ _|__| |_ __ _| |_ ___
\ / | | | |_) | / _ \| | | |/ __| __/ _ | __/ __|
/ \ | | | _ < / ___ \ |___ | |\__ \ || (_| | |_\__ \
/_/\_\ |_| |_| \_\/_/ \_\____| |_||___/\__\__ _|\__|___/
Usage:
xtract_stats -d <dir_basename> -xtract <XTRACT_dir> -w <xtract2diff> [options]
Compulsory arguments:
-d <folder_basename> Path to microstructure folder and basename of data (e.g. /home/DTI/dti_)
-xtract <folder> Path to XTRACT output folder
-w <xtract2diff> EITHER XTRACT results to diffusion space transform OR 'native' if tracts are already in diffusion space
Optional arguments:
-r <reference> If not 'native', provide reference image in diffusion space (e.g. /home/DTI/dti_FA)
-out <path> Output filepath (Default <XTRACT_dir>/stats.csv)
-str <file> Structures file (as in XTRACT) (Default is all tracts under <XTRACT_dir>)
-thr <float> Threshold applied to tract probability map (default = 0.001 = 0.1%)
-meas <list> Comma separated list of features to extract (Default = vol,prob,length,FA,MD - assumes DTI folder has been provided)
vol = tract volume, prob = tract probability, length = tract length
Additional metrics must follow file naming conventions. e.g. for dti_L1 use 'L1'
-keepfiles Keep temporary files
```
......@@ -11,7 +11,7 @@
ptxbin_gpu=$FSLDIR/bin/probtrackx2_gpu
# Location of xtract data
datadir=$FSLDIR/etc/xtract_data
datadir=$FSLDIR/data/xtract_data
Usage() {
cat << EOF
......@@ -29,7 +29,7 @@ Usage:
Optional arguments:
-list List the tract names used in XTRACT
-str <file> Structures file (format: <tractName> per line OR format: <tractName> [samples=1], 1 means 1000, '#' to skip lines)
-p <folder> Protocols folder (all masks in same standard space) (Default=$FSLDIR/etc/xtract_data/<SPECIES>)
-p <folder> Protocols folder (all masks in same standard space) (Default=$FSLDIR/data/xtract_data/<SPECIES>)
-stdwarp <std2diff> <diff2std> Standard2diff and Diff2standard transforms (Default=bedpostx_dir/xfms/{standard2diff,diff2standard})
-gpu Use GPU version
-res <mm> Output resolution (Default=same as in protocol folders unless '-native' used)
......
#!/bin/bash
# Written by Shaun Warrington
Usage() {
cat << EOF
Usage:
xtract_stats -d <dir_basename> -xtract <XTRACT_dir> -w <xtract2diff> [options]
Compulsory arguments:
-d <folder_basename> Path to microstructure folder and basename of data (e.g. /home/DTI/dti_)
-xtract <folder> Path to XTRACT output folder
-w <xtract2diff> EITHER XTRACT results to diffusion space transform OR 'native' if tracts are already in diffusion space
Optional arguments:
-r <reference> If not 'native', provide reference image in diffusion space (e.g. /home/DTI/dti_FA)
-out <path> Output filepath (Default <XTRACT_dir>/stats.csv)
-str <file> Structures file (as in XTRACT) (Default is all tracts under <XTRACT_dir>)
-thr <float> Threshold applied to tract probability map (default = 0.001 = 0.1%)
-meas <list> Comma separated list of features to extract (Default = vol,prob,length,FA,MD - assumes DTI folder has been provided)
vol = tract volume, prob = tract probability, length = tract length
Additional metrics must follow file naming conventions. e.g. for dti_L1 use 'L1'
-keepfiles Keep temporary files
EOF
exit 1
}
Splash (){
cat <<EOF
__ _______ ____ _ ____ _____ _ _
\ \/ /_ _| _ \ / \ / ___|_ _|__| |_ __ _| |_ ___
\ / | | | |_) | / _ \| | | |/ __| __/ _ | __/ __|
/ \ | | | _ < / ___ \ |___ | |\__ \ || (_| | |_\__ \\
/_/\_\ |_| |_| \_\/_/ \_\____| |_||___/\__\__ _|\__|___/
EOF
}
Splash
[ "$1" = "" ] && Usage
# Set default options
d=""
ref=""
xout=""
str=""
xtract2diff=""
out=""
thr=0.001
nat=0
keepfiles=0
meas="vol,prob,length,FA,MD"
# Parse command-line arguments
while [ ! -z "$1" ];do
case "$1" in
-d) d=$2;shift;;
-xtract) xout=$2;shift;;
-w) xtract2diff=$2;shift;;
-r) ref=$2;shift;;
-str) str=$2;shift;;
-thr) thr=$2;shift;;
-out) out=$2;shift;;
-meas) meas=$2;shift;;
-keepfiles) keepfiles=1;shift;;
*) echo "Unknown option '$1'";exit 1;;
esac
shift
done
# Check compulsory arguments
if [ "$xtract2diff" == "" ];then
echo "Must set compulsory argument '-w'"
echo "EITHER XTRACT results to diffusion space transform OR 'native' if tracts are in diffusion space"
elif [ "$xtract2diff" == "native" ];then
nat=1
echo "Tracts are in diffusion space"
else
if [ `$FSLDIR/bin/imtest $xtract2diff` -eq 0 ];then
echo "Image $xtract2diff not found."
exit 1
fi
fi
errflag=0
if [ "$d" == "" ];then
echo "Must set compulsory argument '-d'"
errflag=1
elif [ ! -d `dirname "$d"` ];then
echo "Microstructure folder $d not found"
errflag=1
fi
if [ $nat -eq 0 ];then
if [ "$ref" == "" ];then
echo "Native space option not selected. Must set argument '-r'"
exit 1
elif [ `$FSLDIR/bin/imtest $ref` -eq 0 ];then
echo "Reference image $ref not found"
errflag=1
fi
fi
if [ "$xout" == "" ];then
echo "Must set compulsory argument '-xtract'"
errflag=1
elif [ ! -d $xout ];then
echo "XTRACT output folder $xout not found"
errflag=1
fi
if [ "$meas" == "" ];then
echo "You have used the '-meas' flag but have not provided any arguments"
errflag=1
fi
# Convert to array
IFS=','; read -ra meas <<< "$meas"; IFS=' ';
echo "Getting summary stats for: ${meas[@]}"
# Check for images
for t in "${meas[@]}"; do
if [ "${t}" == "vol" ] || [ "${t}" == "prob" ] || [ "${t}" == "length" ]; then
# do nothing
foo=0
else
# check for file
if [ `$FSLDIR/bin/imtest ${d}${t}` -eq 0 ];then
echo "Microstructure image file ${d}${t} not found"
echo "Exiting now..."
exit 1
fi
fi
done
# Check structure list
# Location of temp folder
tmpdir=`mktemp -d`
if [ "$str" == "" ];then
echo "Running for all tracts under ${xout}/tracts"
str=${tmpdir}/temp_struct
rm -rf $str
for struc in `ls -l ${xout}/tracts | egrep '^d' | awk '{print $NF}'`;do
echo "$struc" >> $str
done
fi
if [ ! -f $str ];then
echo "Structures files $str not found"
errflag=1
fi
# Set output path
if [ "$out" == "" ];then
out=${xout}/stats.csv
elif [ ! "${out: -4}" == ".csv" ];then
out=${out}.csv
fi
if [ "$errflag" -eq 1 ];then
echo ""
echo "Exit without doing anything.."
exit 1
fi
echo ""
# Make CSV header row
hdr="tract"
for t in "${meas[@]}"; do
if [ "${t}" == "vol" ]; then
t="${t} (mm3)";
else
if [ "${t}" == "length" ]; then t="${t} (mm)"; fi
if [ "${t}" == "MD" ]; then t="${t} (mm2.s-1)"; fi
t="median_${t}, mean_${t}, stddev_${t}"
fi
hdr="${hdr}, ${t}"
done
rm -rf $out
echo "${hdr}" > $out
while read structstring; do
struct=`echo $structstring | awk '{print $1}'`
# skip empty lines and lines that start with '#'
if [ "${struct:0:1}" == "#" ];then
# do nothing
foo=0
#echo "----- Skip line $structstring -----"
elif [ "$struct" == "" ];then
# do nothing
foo=0
#echo "----- Skip empty line -----"
else
# dealing with warping
tract=${xout}/tracts/${struct}/densityNorm
tract_length=${xout}/tracts/${struct}/density_lengths
if [ `$FSLDIR/bin/imtest $tract` -eq 0 ];then
echo "Couldn't find images for $struct - skipping.."
else
echo "Processing $struct"
if [ $nat -eq 0 ];then
tract=${tmpdir}/densityNorm_diffspace
${FSLDIR}/bin/applywarp -i ${xout}/tracts/${struct}/densityNorm -w $xtract2diff -r $ref -o $tract --interp=spline
tract_length=${tmpdir}/density_lengths_diffspace
# only warp if actually using tract lengths
if [[ "${meas[@]}" =~ "length" ]];then
tract_length=${tmpdir}/density_lengths_diffspace
${FSLDIR}/bin/applywarp -i ${xout}/tracts/${struct}/density_lengths -w $xtract2diff -r $ref -o $tract_length --interp=spline
fi
fi
# binarise prob map
${FSLDIR}/bin/fslmaths $tract -thr $thr -bin ${tract}_bin
stats_out=()
for t in "${meas[@]}"; do
if [ "${t}" == "vol" ]; then
# tract volume
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats $tract -l $thr -V | awk '{print $2}'`)
elif [ "${t}" == "prob" ]; then
# median and mean probability (and standard deviation)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats $tract -l $thr -P 50 -M`)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats $tract -l $thr -S`)
elif [ "${t}" == "length" ]; then
# median and mean path length (and standard deviation)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats $tract_length -k ${tract}_bin -P 50 -M`)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats $tract_length -k ${tract}_bin -S`)
else
# median and mean microstructure measure (and standard deviations)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats ${d}${t} -k ${tract}_bin -P 50 -M`)
stats_out=(${stats_out[@]} `${FSLDIR}/bin/fslstats ${d}${t} -k ${tract}_bin -S`)
fi
done
# convert array to CSV format and output
stats_out=$( IFS=$','; echo "${stats_out[*]}" )
echo "$struct, ${stats_out}" >> $out
# clean-up
if [ $keepfiles -eq 0 ];then
if [ $nat -eq 0 ];then
rm ${tract}.nii.gz ${tract}_bin.nii.gz
if [[ "${meas[@]}" =~ "length" ]];then rm ${tract_length}.nii.gz; fi
else
rm ${tract}_bin.nii.gz
fi
else
if [ $nat -eq 0 ];then
cp ${tract}.nii.gz ${xout}/tracts/${struct}/densityNorm_diffspace_bin.nii.gz
cp ${tract}_bin.nii.gz ${xout}/tracts/${struct}/densityNorm_diffspace_bin.nii.gz
if [[ "${meas[@]}" =~ "length" ]];then cp ${tract_length}.nii.gz ${xout}/tracts/${struct}/density_lengths_diffspace.nii.gz; fi
else
cp ${tract}_bin.nii.gz ${xout}/tracts/${struct}/densityNorm_bin.nii.gz
fi
fi
fi
fi
done < $str
rm -rf $tmpdir
#EOF
......@@ -99,7 +99,7 @@ if [ "$spec" == "" ];then
elif [ $spec == HUMAN ];then
brain=${FSLDIR}/data/standard/FSL_HCP1065_FA_1mm.nii.gz
elif [ $spec == MACAQUE ];then
brain=${FSLDIR}/etc/xtract_data/standard/F99/mri/struct_brain.nii.gz
brain=${FSLDIR}/data/xtract_data/standard/F99/mri/struct_brain.nii.gz
elif [ ! "$spec" == "HUMAN" ] && [ ! "$spec" == "MACAQUE" ];then
echo "Unrecognised option '$spec'. Must set '-species' using HUMAN or MACAQUE"
errflag=1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment