OSCR

Putative glymphatic dysfunction links extracellular fluid dysregulation to white matter degeneration and clinical impairment in amyotrophic lateral sclerosis.

Code ↔ Paper

2 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 2 matches
  1. [1] § Methods › MRI data preprocessing ↔ alps.sh, lines 1–42 · score 0.91 · MRtrix3, JHU ICBM FA, Diffusion weighted images, FA maps, perivascular space, pipeline
  2. [2] § Methods › Statistical analyses ↔ alps.sh, lines 1–42 · score 0.56 · FA template, JHU ICBM, pipeline, transformations, maps, FSL

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Shell · 757 lines · 56 KB · MIT · 2 matches

  1. #! /bin/bash
  2. #############################################################
  3. # Giuseppe Barisano - [email hidden]
  4. #############################################################
  5. ##### Computing diffusion along perivascular spaces (ALPS) from diffusion-weighted images #####
  6. # REQUIRES: - FSL v. 6.0.3 or newer (https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FslInstallation)
  7. # - MRtrix3 (https://www.mrtrix.org/download/)
  8. # This script assumes that FSL and MRtrix3 are in your $PATH.
  9. # initial directories and parameters
  10. #script_folder="${ALPSDIR}"
  11. script_folder="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )";
  12. # inputs # 1 or 2 dwi files (if 2, they should be of opposite phase encoding direction, e.g., PA and AP)
  13. # REQUIRED INPUTS
  14. dwi1=''
  15. bval1=''
  16. bvec1=''
  17. # Optional input for eddy current correction
  18. json1='' # .json files with details about the diffusion sequence. Tested with .json files generated from dcm2niix https://github.com/rordenlab/dcm2niix)
  19. # Optional second dwi inputs (needs to have opposite phase encoding direction and the first volume of both dwi1 and dwi2 must be a B0 image)
  20. dwi2=''
  21. bval2=''
  22. bvec2=''
  23. json2=''
  24. # optional inputs with default options
  25. denoise=1 # perform the denoise and unringing
  26. rois=2.5 # perform the ROI analysis using the provided ROIs of 2.5 mm radius drawn on JHU-ICBM-FA-1mm.nii.gz
  27. template=1 #use the FSL's JHU-ICBM-FA-1mm.nii.gz as FA template or FSL's MNI template if the structural MRI data is provided.
  28. skip=0 #perform all the steps of the pipeline.
  29. eddy=1 #try to use eddy_cpu
  30. warp=0 #perform linear registration of the FA map to the template.
  31. freg=1 #if the analysis is done on template space, by default it will use FSL's flirt or applywarp to transform the TENSOR file to the template.
  32. struct='' #structural MRI data (can be either a T1-weighted or a T2-weighted image, no FLAIR, no PD)
  33. weight=1 #if a structural MRI data is provided, by default it will be considered a T1-weighted image.
  34. print_usage() {
  35. printf "\nUsage: alps.sh \n\
  36. -a DWI \n\
  37. -b BVAL \n\
  38. -c BVEC \n\
  39. -m METADATA (.json file) \n\
  40. -i DWI (second input with opposite phase encoding) \n\
  41. -j BVAL of second input (MUST BE DEFINED if second dwi input -i is defined) \n\
  42. -k BVEC of second input (MUST BE DEFINED if second dwi input -i is defined) \n\
  43. -n METADATA (.json file) of second input (MUST BE DEFINED if second dwi input -i is defined) \n\
  44. -d DENOISING \n\
  45. -e EDDY (specify which eddy program to use)
  46. -r ROIS \n\
  47. -t TEMPLATE \n\
  48. -v VOLUMETRIC structural MRI data \n\
  49. -h WeigHt of the volumetric structural MRI data \n\
  50. -w WARP the reconstructed FA map to the template \n\
  51. -f Use flirt or applywarp or vecreg to transform the TENSOR file to the template \n\
  52. -s SKIP preprocessing and DTI fitting, i.e. perform ONLY ROI analysis \n\
  53. -o OUTPUT_DIR_NAME \n"
  54. printf "\nDefault values: \n\
  55. -d DENOISING [default = 1]; 0=skip; 1=both denoise and unringing; 2=only denoise; 3=only unringing. \n\
  56. -e EDDY [default = 1]; 0=skip eddy (not recommended); 1=use ${FSLDIR}/bin/eddy_cpu; 2=use ${FSLDIR}/bin/eddy; 3=use ${FSLDIR}/bin/eddy_correct;
  57. alternatively, the user can specify which eddy program to use (e.g., eddy_cuda). The binary file specified by the user must be located in ${FSLDIR}/bin/ (do not include \"${FSLDIR}/bin/\" in the command, just the name of the binary file)\n\
  58. -r ROIS [default = 2.5]; 0=skip ROI analysis; 2.5=ROI analysis with provided ROIs drawn on JHU-ICBM-FA-1mm;
  59. alternatively, a positive number (non-integer numbers are acceptable, e.g., 2.5) that is the radius of the new sphere ROIs that you want to use for ALPS calculation. They will be generated on the default FSL's JHU/MNI 1mm template space and will be available in the output folder.
  60. alternatively, a comma-separated list of 4 custom ROI nifti files can be specified.
  61. ROIs need to be in the following order: 1) LEFT and 2) RIGHT PROJECTION FIBERS (superior corona radiata), 3) LEFT and 4) RIGHT ASSOCIATION FIBERS (superior longitudinal fasciculus)\n\
  62. -t TEMPLATE [default = 1]; 0=ROI analysis in NATIVE space; 1=ROI analysis with FSL's JHU-ICBM-FA-1mm (if no structural MRI data input), MNI_T1_1mm (if structural data input is a T1) or JHU-ICBM-T2-1mm (if structural data input is a T2); \n\
  63. alternatively, the user can specify a template to use. \n\
  64. -v VOLUMETRIC structural MRI data: specify a structural MRI data (a T1w or T2w NIFTI file) to be used for registration of the FA map to the template;
  65. -h weight of the structural MRI data [default = 1]; 1=T1-weighted image; 2=T2-weighted image (no PD, no FLAIR).
  66. -w WARP [default = 0]; 0=perform linear registration of the reconstructed FA map to the template; 1=perform ONLY non-linear registration (warping) of the reconstructed FA map to the template using FSL's suggested default parameters (not recommended). \n\
  67. 2=perform linear (flirt) + non-linear registration (fnirt); option -w is ignored when a structural MRI is used (-v is not empty).
  68. -f method to transform the TENSOR to the template [default = 1]; 1=use flirt (or applywarp if WARP is 1 or 2 or -V is not empty) to transform the TENSOR to the template; \n\
  69. 2=use FSL's vecreg to transform the TENSOR to the template.
  70. -s Option to skip preprocessing and DTI fitting, i.e. performs ONLY ROI analysis [default = 0]; 0 = all the steps are performed; 1= ONLY ROI analysis is performed;
  71. If -s 1, then -o MUST BE DEFINED and MUST CORRESPOND TO THE FOLDER WHERE dxx.nii.gz, dyy.nii.gz and dzz.nii.gz ARE LOCATED. \n\
  72. -o OUTPUT_DIR_NAME [default = 1]; default option will create a folder called \"alps\" located in the directory of the (first) input. \n\
  73. \nExample with 1 input: sh alps.sh -a dwi.nii.gz -b id.bval -c id.bvec -m id.json -d 1 -o alps\n\
  74. \nExample with 2 inputs with opposite phase encoding direction: sh alps.sh -a dwi_PA.nii.gz -b id_PA.bval -c id_PA.bvec -m id_PA.json -i dwi_AP.nii.gz -j id_AP.bval -k id_AP.bvec -n id_AP.json -d 1 -o alps\n"
  75. }
  76. while getopts 'a:b:c:m:i:j:k:n:d:e:r:t:v:h:w:f:s:o:' flag; do
  77. case "${flag}" in
  78. a) dwi1="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  79. b) bval1="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  80. c) bvec1="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  81. m) json1="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  82. i) dwi2="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  83. j) bval2="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  84. k) bvec2="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  85. n) json2="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  86. d) denoise="${OPTARG}" ;;
  87. e) eddy="${OPTARG}" ;;
  88. r) rois="${OPTARG}" ;;
  89. t) template="${OPTARG}" ;;
  90. v) struct="$(echo "$(cd "$(dirname "${OPTARG}")" && pwd)/$(basename "${OPTARG}")")" ;;
  91. h) weight="${OPTARG}" ;;
  92. w) warp="${OPTARG}" ;;
  93. f) freg="${OPTARG}" ;;
  94. s) skip="${OPTARG}" ;;
  95. o) output_dir_name="${OPTARG}" ;;
  96. *) print_usage
  97. exit 1 ;;
  98. esac
  99. done
  100. #INITIAL CHECKS
  101. #INPUTS
  102. if [ $skip -eq 0 ]; then #check the inputs only if are needed
  103. if [ $OPTIND -eq 1 ]; then echo "ERROR! No options were passed"; print_usage; exit 1; fi
  104. if [ ! $dwi1 ]; then echo "ERROR! input dwi (-a) is not defined."; print_usage; exit 1; fi
  105. if [ ! $bval1 ]; then echo "ERROR! bval (-b) is not defined."; print_usage; exit 1; fi
  106. if [ ! $bvec1 ]; then echo "ERROR! bvec (-c) is not defined."; print_usage; exit 1; fi
  107. if [ ! -f "${dwi1}" ]; then echo "ERROR! input $dwi1 does not exist."; exit 1; fi
  108. if [ ! -f "${bval1}" ]; then echo "ERROR! bval file $bval1 does not exist."; exit 1; fi
  109. if [ ! -f "${bvec1}" ]; then echo "ERROR! bvec file $bvec1 does not exist."; exit 1; fi
  110. #OUTPUT ALPS CHECK
  111. if [ -f "${outdir}/alps.stat/alps.csv" ] && [ ! -z "`tail -n 1 "${outdir}/alps.stat/alps.csv" | tr -d ,`" ]; then echo "ERROR! Final output alps.csv already exists and is not empty! Remove/rename the output folder in order to re-run the pipeline with input $dwi1"; exit 1; fi;
  112. # create output directory
  113. if [ ! $output_dir_name ]; then
  114. #study_folder="$(dirname "${dwi1}")"
  115. study_folder=`echo "$(cd "$(dirname -- "${dwi1}")" >/dev/null; pwd -P)"`
  116. outdir="${study_folder}/alps"
  117. else
  118. outdir="${output_dir_name}"
  119. fi
  120. echo "create output directory: ${outdir}"
  121. mkdir -p "${outdir}"
  122. #exec > "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt 2>&1
  123. exec > >(tee -a "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt) 2> >(tee -a "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt >&2)
  124. #if [ ! $json1 ]; then echo "ERROR! metadata .json file (-m) is not defined."; print_usage; exit 1; fi
  125. #CHECK FOR DWI2. Hashtagged, because:
  126. #bvec2 is not used,
  127. #bval2 might be skipped if the user verified that the first volume is a B0 volume
  128. #json2 might be skipped if the user verified that the PE direction is opposite to that of dwi1.
  129. #if [ $dwi2 ]; then if [ ! $bval2 ] || [ ! $bvec2 ] || [ ! $json2 ]; then echo "ERROR! dwi2 (-i) is defined, but bval (-j), bvec (-k), and/or metadata .json file (-n) of the second input is/are not defined."; print_usage; exit 1; fi; fi;
  130. #if [ $bval2 ]; then if [ ! $dwi2 ] || [ ! $bvec2 ] || [ ! $json2 ]; then echo "ERROR! bval (-j) of the second input is defined, but dwi2 (-i), bvec (-k), and/or metadata .json file (-n) of the second input is/are not defined."; print_usage; exit 1; fi; fi;
  131. #if [ $bvec2 ]; then if [ ! $dwi2 ] || [ ! $bval2 ] || [ ! $json2 ]; then echo "ERROR! bvec (-k) of the second input is defined, but dwi2 (-i), bval (-j), and/or metadata .json file (-n) of the second input is/are not defined."; print_usage; exit 1; fi; fi;
  132. #if [ $json2 ]; then if [ ! $dwi2 ] || [ ! $bval2 ] || [ ! $bvec2 ]; then echo "ERROR! metadata .json file (-n) of the second input is defined, but dwi2 (-i), bval (-j), and/or bvec (-k) of the second input is/are not defined."; print_usage; exit 1; fi; fi;
  133. if [ $dwi2 ]; then
  134. if [ ! -f "${dwi2}" ]; then echo "ERROR! second input $dwi2 does not exist."; exit 1; fi;
  135. #if [ $bval2 ]; then if [ ! -f "${bval2}" ]; then echo "ERROR! bval file $bval2 of second input does not exist."; exit 1; fi; fi;
  136. #if [ ! -f "${bvec2}" ]; then echo "ERROR! bvec file $bvec2 of second input does not exist."; exit 1; fi;
  137. #if [ $json2 ]; then if [ ! -f "${json2}" ]; then echo "ERROR! metadata .json file $json2 of second input does not exist."; exit 1; fi; fi;
  138. fi
  139. elif [ $skip -eq 1 ]; then
  140. if [ ! $output_dir_name ]; then echo "ERROR! Option -s is set to 1, therefore option -o MUST BE DEFINED and MUST CORRESPOND TO THE FOLDER WHERE dxx.nii.gz, dyy.nii.gz and dzz.nii.gz ARE LOCATED."; exit 1; fi;
  141. outdir="${output_dir_name}"
  142. #exec > "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt 2>&1
  143. exec > >(tee -a "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt) 2> >(tee -a "${outdir}"/alps_$(date +"%Y-%m-%d_%H-%M-%S")_log.txt >&2)
  144. fi
  145. #ROIS & TEMPLATE
  146. if [ "$rois" != "0" ]; then
  147. if [ "$rois" == "2.5" ]; then
  148. echo "ROI analysis with default ROIs"
  149. rois="${script_folder}/ROIs_JHU_ALPS/L_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/L_SLF.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SLF.nii.gz"
  150. roption=$rois
  151. elif [[ "$rois" =~ ^-?([0-9]+\.?[0-9]*|\.[0-9]+)$ ]]; then
  152. radius=$rois
  153. echo "ROI analysis with user-defined spheric ROIs with radius $radius mm"
  154. rois="${script_folder}/ROIs_JHU_ALPS/L_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/L_SLF.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SLF.nii.gz" #only needed to pass the check below
  155. roption=$radius
  156. else
  157. echo "ROI analysis with user-defined ROIs: $rois"
  158. roption=$rois
  159. fi
  160. n_rois=`echo $rois | awk -F '[,]' '{print NF}'`
  161. if [ $n_rois -ne 4 ]; then echo "ERROR! The number of ROIs is not equal to 4. The string of ROIs must include only 4 elements separated by 3 commas. Please double check that exactly 4 elements and no more than 3 commas are present in your string of ROIs (e.g., no commas is present in file/directory names."; exit 1; fi;
  162. proj_L=`echo "$rois" | cut -d "," -f1`
  163. proj_R=`echo "$rois" | cut -d "," -f2`
  164. assoc_L=`echo "$rois" | cut -d "," -f3`
  165. assoc_R=`echo "$rois" | cut -d "," -f4`
  166. if [ ! -f "${proj_L}" ]; then echo "ERROR! Cannot find the following ROI file: ${proj_L}"; exit 1; fi;
  167. if [ ! -f "${proj_R}" ]; then echo "ERROR! Cannot find the following ROI file: ${proj_R}"; exit 1; fi;
  168. if [ ! -f "${assoc_L}" ]; then echo "ERROR! Cannot find the following ROI file: ${assoc_L}"; exit 1; fi;
  169. if [ ! -f "${assoc_R}" ]; then echo "ERROR! Cannot find the following ROI file: ${assoc_R}"; exit 1; fi;
  170. if [ "$template" != "0" ]; then #analysis in template space. Double check that the template exists.
  171. #conditional for existence of structural MRI data.
  172. if [ ! -z $struct ]; then
  173. if [ ! -f "$struct" ]; then echo "ERROR! User specified to use $struct as structural MRI data, but I could not find it. Please double-check that the file exists."; exit 1; fi;
  174. fi
  175. #conditional for template selection
  176. if [ "$template" == "1" ]; then
  177. if [ -f ${FSLDIR}/data/standard/MNI152_T1_1mm_brain_mask_dil.nii.gz ]; then
  178. template_mask="--refmask=${FSLDIR}/data/standard/MNI152_T1_1mm_brain_mask_dil.nii.gz "
  179. #used only for fnirt (warp > 0 or !-z struct)
  180. fi
  181. if [ -z $struct ]; then
  182. echo "Default FA template will be used: JHU-ICBM-FA-1mm.nii.gz"
  183. template=${FSLDIR}/data/atlases/JHU/JHU-ICBM-FA-1mm.nii.gz
  184. template_abbreviation=JHU-FA
  185. elif [ ! -z $struct ]; then
  186. if [ $weight == "1" ]; then
  187. echo "The structural MRI $struct is a T1-weighted image, therefore the default template that will be used is: MNI152_T1_1mm"
  188. template=${FSLDIR}/data/standard/MNI152_T1_1mm_brain.nii.gz
  189. template_abbreviation=MNI152_T1_1mm
  190. smri="t1w"
  191. elif [ $weight == "2" ]; then
  192. echo "The structural MRI $struct is a T2-weighted image, therefore the default template that will be used is: JHU-ICBM-T2-1mm"
  193. template=${FSLDIR}/data/atlases/JHU/JHU-ICBM-T2-1mm.nii.gz
  194. template_abbreviation=JHU-ICBM-T2-1mm
  195. smri="t2w"
  196. elif [ $weight -ne 1 ] && [ $weight -ne 2 ] && [ "$template" != "0" ] && [ "$template" != "1" ] ; then
  197. echo "ERROR! A structural MRI data has been specified, but the user needs to specify with the option -h whether this is T1-weighted (-h 1) or T2-weighted (-h 2) in order to select a default template. \n\
  198. The only allowed option for -h are 1 or 2. Alternatively, the user can specify the file template to use, and the option -h will be ignored."; exit 1;
  199. fi
  200. fi
  201. else
  202. template="$(echo "$(cd "$(dirname "${template}")" && pwd)/$(basename "${template}")")"
  203. echo "User specified template: $template"
  204. template_abbreviation=template
  205. fi
  206. if [ ! -f "${template}" ]; then echo "ERROR! Cannot find the template "$template". The template file must exist if -t option is not 0."; exit 1; fi;
  207. if [ $warp -ne 0 ] && [ $warp -ne 1 ] && [ $warp -ne 2 ]; then echo "ERROR! The option specified with -w is $warp, which is not an allowed option. -w must be equal to 0 (for linear registration) or 1 (for non-linear registration)."; exit 1; fi;
  208. if [ $freg -ne 1 ] && [ $freg -ne 2 ]; then echo "ERROR! The option specified with -f is $freg, which is not an allowed option. -f must be equal to 1 (for using FSL's flirt and/or applywarp depending on -w) or 2 (for using FSL's vecreg)."; exit 1; fi;
  209. fi
  210. fi
  211. #OPTIONS
  212. if [ "$denoise" != "0" ] && [ "$denoise" != "1" ] && [ "$denoise" != "2" ] && [ "$denoise" != "3" ]; then echo "-d option is equal to $denoise, which is not an allowed option. -d must be equal to 0, 1, 2, or 3, or skipped (which corresponds to -d 1)."; print_usage; exit 1; fi;
  213. if [ "$eddy" == "1" ] && [ ! -f "${FSLDIR}/bin/eddy_cpu" ]; then echo "-e option (eddy) is equal to $eddy (default), which means using ${FSLDIR}/bin/eddy_cpu, but ${FSLDIR}/bin/eddy_cpu cannot be found. -e must be equal to 0 (skip eddy correction, not recommended) 1 (use ${FSLDIR}/bin/eddy_cpu), 2 (use ${FSLDIR}/bin/eddy), 3 (use ${FSLDIR}/bin/eddy_correct), or skipped (default value = 1). If the user wants to use a specific eddy program, this must be located in ${FSLDIR}/bin/"; print_usage; exit 1; fi;
  214. if [ "$eddy" == "2" ] && [ ! -f "${FSLDIR}/bin/eddy" ]; then echo "-e option (eddy) is equal to $eddy (default), which means using ${FSLDIR}/bin/eddy, but ${FSLDIR}/bin/eddy cannot be found. -e must be equal to 0 (skip eddy correction, not recommended) 1 (use ${FSLDIR}/bin/eddy_cpu), 2 (use ${FSLDIR}/bin/eddy), 3 (use ${FSLDIR}/bin/eddy_correct), or skipped (default value = 1). If the user wants to use a specific eddy program, this must be located in ${FSLDIR}/bin/"; print_usage; exit 1; fi;
  215. if [ "$eddy" == "3" ] && [ ! -f "${FSLDIR}/bin/eddy_correct" ]; then echo "-e option (eddy) is equal to $eddy (default), which means using ${FSLDIR}/bin/eddy_correct, but ${FSLDIR}/bin/eddy_correct cannot be found. -e must be equal to 0 (skip eddy correction, not recommended) 1 (use ${FSLDIR}/bin/eddy_cpu), 2 (use ${FSLDIR}/bin/eddy), 3 (use ${FSLDIR}/bin/eddy_correct), or skipped (default value = 1). If the user wants to use a specific eddy program, this must be located in ${FSLDIR}/bin/"; print_usage; exit 1; fi;
  216. if [ "$eddy" != "0" ] && [ "$eddy" != "1" ] && [ "$eddy" != "2" ] && [ "$eddy" != "3" ] && [ ! -f "${FSLDIR}/bin/$eddy" ]; then echo "-e option (eddy) is equal to $eddy, but ${FSLDIR}/bin/$eddy cannot be found. -e must be equal to 0 (skip eddy correction, not recommended) or 1 (use eddy_cpu if available, or eddy if not), or skipped (default value = 1). If the user wants to use a specific eddy program, this must be located in ${FSLDIR}/bin/"; print_usage; exit 1; fi;
  217. if [ "$skip" != "0" ] && [ "$skip" != "1" ]; then echo "-s option is equal to $skip, which is not an allowed option. -s must be equal to 0 or 1, or skipped (default value = 0)."; print_usage; exit 1; fi;
  218. #running check
  219. echo -e "Running ALPS with the following parameters: \n
  220. -a $dwi1 \n
  221. -b $bval1 \n
  222. -c $bvec1 \n
  223. -m $json1 \n
  224. -i $dwi2 \n
  225. -j $bval2 \n
  226. -k $bvec2 \n
  227. -n $json2 \n
  228. -d $denoise \n
  229. -e $eddy \n
  230. -r $roption \n
  231. -t $template \n
  232. -v $struct \n
  233. -h $weight \n
  234. -w $warp \n
  235. -f $freg \n
  236. -s $skip \n
  237. -o $output_dir_name"
  238. # 1. PREPROCESSING (Denoising, unringing, Topup for Opposite EPI acquisitions, Eddy)
  239. if [ $skip -eq 0 ]; then
  240. #copy bval and bvec files into output directory
  241. cp "$bvec1" "${outdir}/bvec1"
  242. cp "$bval1" "${outdir}/bval1"
  243. cd "${outdir}"
  244. ## Denoising and/or unringing
  245. if [ $denoise -ne 0 ]; then
  246. if [ $denoise -eq 1 ]; then
  247. echo "Denoising and unringing $dwi1"
  248. dwidenoise "$dwi1" "${outdir}/dwi1.denoised.nii.gz"
  249. mrdegibbs "${outdir}/dwi1.denoised.nii.gz" "${outdir}/dwi1.denoised.unring.nii.gz"
  250. dwi1_processed="${outdir}/dwi1.denoised.unring.nii.gz"
  251. fi
  252. if [ $denoise -eq 2 ]; then
  253. echo "Denoising $dwi1"
  254. dwidenoise "$dwi1" "${outdir}/dwi1.denoised.nii.gz"
  255. dwi1_processed="${outdir}/dwi1.denoised.nii.gz"
  256. fi
  257. if [ $denoise -eq 3 ]; then
  258. echo "Unringing $dwi1"
  259. mrdegibbs "$dwi1" "${outdir}/dwi1.unring.nii.gz"
  260. dwi1_processed="${outdir}/dwi1.unring.nii.gz"
  261. fi
  262. else
  263. echo "Denoising and unringing skipped by the user (-d 0 option)"
  264. dwi1_processed="${dwi1}"
  265. fi
  266. # IF YOU HAVE A METADATA (JSON) FILE, THEN YOU CAN RUN EDDY with eddy_cpu
  267. if [ -f "${json1}" ]; then
  268. # ACQUISITION PARAMETERS OF FIRST INPUT (REQUIRED FOR EDDY)
  269. #scanner1=$(jq -r '.Manufacturer' "$json1") # -r gives you the raw output
  270. #scanner1=$(cat "${json1}" | grep -w Manufacturer | cut -d ' ' -f2 | tr -d ',')
  271. scanner1=$(cat "${json1}" | awk -F'"' '/"Manufacturer"/ {print $4}')
  272. if [[ "$scanner1" == *"Philips"* ]]
  273. then
  274. #PEdir1=$(jq -r '.PhaseEncodingAxis' "$json1")
  275. #PEdir1=$(cat "${json1}" | grep -w PhaseEncodingAxis | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  276. PEdir1=$(cat "${json1}" | awk -F'"' '/"PhaseEncodingAxis"/ {print $4}')
  277. TotalReadoutTime1=0.1 #this assumes that the readout time is identical for all acquisitions on the Philips scanner. A "realistic" read-out time is ~50-100ms (and eddy accepts 10-200ms). So use 0.1 (i.e., 100 ms), not 1.
  278. else
  279. #PEdir1=$(jq -r '.PhaseEncodingDirection' "$json1")
  280. #TotalReadoutTime1=$(jq -r '.TotalReadoutTime' "$json1")
  281. #PEdir1=$(cat "${json1}" | grep -w PhaseEncodingDirection | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  282. #TotalReadoutTime1=$(cat "${json1}" | grep -w TotalReadoutTime | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  283. PEdir1=$(cat "${json1}" | awk -F'"' '/"PhaseEncodingDirection"/ {print $4}')
  284. TotalReadoutTime1=$(cat "${json1}" | grep -w TotalReadoutTime | cut -d ':' -f2 | cut -d ',' -f1 | xargs)
  285. fi
  286. if [ "$PEdir1" = i ]; then printf "1 0 0 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  287. elif [ "$PEdir1" = i- ]; then printf "-1 0 0 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  288. elif [ "$PEdir1" = j ]; then printf "0 1 0 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  289. elif [ "$PEdir1" = j- ]; then printf "0 -1 0 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  290. elif [ "$PEdir1" = k ]; then printf "0 0 1 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  291. elif [ "$PEdir1" = k- ]; then printf "0 0 -1 $TotalReadoutTime1" > "${outdir}/acqparams.txt";
  292. fi
  293. #IF YOU HAVE A SECOND DWI
  294. if [ "$dwi2" ]; then
  295. echo "2nd DWI is available"
  296. #if [[ "$dwi2" == *".nii" ]]; then gzip "$dwi2"; fi
  297. if [ $denoise -eq 1 ]; then
  298. echo "Denoising and unringing $dwi2"
  299. dwidenoise "$dwi2" "${outdir}/dwi2.denoised.nii.gz"
  300. mrdegibbs "${outdir}/dwi2.denoised.nii.gz" "${outdir}/dwi2.denoised.unring.nii.gz"
  301. dwi2_processed="${outdir}/dwi2.denoised.unring.nii.gz"
  302. elif [ $denoise -eq 2 ]; then
  303. echo "Denoising $dwi2"
  304. dwidenoise "$dwi2" "${outdir}/dwi2.denoised.nii.gz"
  305. dwi2_processed="${outdir}/dwi2.denoised.nii.gz"
  306. elif [ $denoise -eq 3 ]; then
  307. echo "Unringing $dwi2"
  308. mrdegibbs "$dwi2" "${outdir}/dwi2.unring.nii.gz"
  309. dwi2_processed="${outdir}/dwi2.unring.nii.gz"
  310. elif [ $denoise -eq 0 ]; then
  311. dwi2_processed="${dwi2}"
  312. fi
  313. ##
  314. if [ "$json2" ]; then
  315. #scanner2=$(jq -r '.Manufacturer' "$json2")
  316. #scanner2=$(cat "${json2}" | grep -w Manufacturer | cut -d ' ' -f2 | tr -d ',')
  317. scanner2=$(cat "${json2}" | awk -F'"' '/"Manufacturer"/ {print $4}')
  318. if [[ "$scanner2" == *"Philips"* ]]
  319. then
  320. #PEdir2=$(jq -r '.PhaseEncodingAxis' "$json2")- #added "-" to make it opposite to the PEdir1. #Philips scans json files generated with dcm2niix have a problem where the PEdirection is the same (j) even though it is not.
  321. #PEdir2=$(cat "${json2}" | grep -w PhaseEncodingAxis | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  322. PEdir2=$(cat "${json2}" | awk -F'"' '/"PhaseEncodingAxis"/ {print $4}')
  323. TotalReadoutTime2=0.1 #this assumes that the readout time is identical for all acquisitions on the Philips scanner. A "realistic" read-out time is ~50-100ms (and eddy accepts 10-200ms). So use 0.1 (i.e., 100 ms), not 1.
  324. else
  325. #PEdir2=$(jq -r '.PhaseEncodingDirection' "$json2")
  326. #TotalReadoutTime2=$(jq -r '.TotalReadoutTime' "$json2")
  327. #PEdir2=$(cat "${json2}" | grep -w PhaseEncodingDirection | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  328. #TotalReadoutTime2=$(cat "${json2}" | grep -w TotalReadoutTime | cut -d ' ' -f2 | tr -d ',' | tr -d '"')
  329. PEdir2=$(cat "${json2}" | awk -F'"' '/"PhaseEncodingDirection"/ {print $4}')
  330. TotalReadoutTime2=$(cat "${json2}" | grep -w TotalReadoutTime | cut -d ':' -f2 | cut -d ',' -f1 | xargs)
  331. fi
  332. else #if you don't have a json2 file, then assume that the PEdir2 is opposite to PEdir1 and that the TotalReadoutTime2 is equal to TotalReadoutTime1
  333. if [[ "${PEdir1}" == *"-"* ]]; then PEdir2=$(echo ${PEdir1} | tr -d '-')
  334. else PEdir2="${PEdir1}-"
  335. fi
  336. TotalReadoutTime2=$TotalReadoutTime1
  337. fi
  338. # ACQUISITION PARAMETERS (ADDED TO THE PREVIOUS FILE)
  339. if [ "$PEdir2" = i ]; then printf "\n1 0 0 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  340. elif [ "$PEdir2" = i- ]; then printf "\n-1 0 0 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  341. elif [ "$PEdir2" = j ]; then printf "\n0 1 0 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  342. elif [ "$PEdir2" = j- ]; then printf "\n0 -1 0 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  343. elif [ "$PEdir2" = k ]; then printf "\n0 0 1 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  344. elif [ "$PEdir2" = k- ]; then printf "\n0 0 -1 $TotalReadoutTime2" >> "${outdir}/acqparams.txt";
  345. fi
  346. #TOPUP (only if PEdir1 = PEdir2- and both DWI datasets have B0 images as first volume)
  347. b0_dwi1=`head -c 1 "$bval1"`
  348. if [ "$bval2" ]; then #if you don't have a bval2 file, then assume it equal to b0_dwi1, that should be 0.
  349. b0_dwi2=`head -c 1 "$bval2"`
  350. else
  351. b0_dwi2=$b0_dwi1
  352. fi
  353. if [ "${PEdir1}" == "${PEdir2}-" ] || [ "${PEdir2}" == "${PEdir1}-" ] && ([ "${b0_dwi1}" == "${b0_dwi2}" ] && [ "${b0_dwi1}" == "0" ]);
  354. then
  355. b0_1="${outdir}/b0_first_direction.nii.gz"
  356. b0_2="${outdir}/b0_second_direction.nii.gz"
  357. fslroi "$dwi1_processed" "$b0_1" 0 1
  358. fslroi "$dwi2_processed" "$b0_2" 0 1
  359. #check dimensions of b0_1 and b0_2 because sometimes they are different and needs to be coregistered for fslmerge to work
  360. dim1_1=`fslhd "$b0_1" | grep dim1 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  361. dim2_1=`fslhd "$b0_1" | grep dim2 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  362. dim3_1=`fslhd "$b0_1" | grep dim3 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  363. dim1_2=`fslhd "$b0_2" | grep dim1 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  364. dim2_2=`fslhd "$b0_2" | grep dim2 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  365. dim3_2=`fslhd "$b0_2" | grep dim3 | tr -s ' ' | cut -d " " -f2 | head -n 1` #tr with the squeeze option makes all consecutive whitespaces equal to 1 whitespace
  366. if [ "${dim1_1}" != "${dim1_2}" ] || [ "${dim2_1}" != "${dim2_2}" ] || [ "${dim3_1}" != "${dim3_2}" ];
  367. then
  368. flirt -in "${b0_2}" -ref "${b0_1}" -out "${outdir}/b0_second_direction_reg" -omat "${outdir}/b0_2.in.b0_1.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 6
  369. b0_2="${outdir}/b0_second_direction_reg.nii.gz"
  370. echo "b0_2 registered to b0_1"
  371. fi
  372. fslmerge -t "${outdir}/both_b0" "$b0_1" "$b0_2"
  373. temp=`fslhd "${dwi1}" | grep dim3`
  374. dimtmp=( $temp )
  375. n_slices=${dimtmp[1]}
  376. echo "Running FSL TOPUP"
  377. if [ $((n_slices%2)) -eq 0 ] #even number of slices
  378. then
  379. topup --imain=both_b0 --datain=acqparams.txt --config=b02b0.cnf --out=my_topup_results --iout=my_hifi_b0 #which will upon completion create the two files my_topup_results_fieldcoef.nii.gz (an estimate of the susceptibility induced off-resonance field), my_topup_results_movpar.txt and the non-distorted space my_hifi_b0.nii.gz
  380. else #odd number of slices, use a different configuration file (https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=FSL;6c4c9591.2002)
  381. b02b0_1=`find /${FSLDIR} -name "b02b0_1.cnf" | head -n 1` #the location is usually ${FSLDIR}/src/topup/flirtsch/b02b0_1.cnf
  382. if [ -z $b02b0_1 ]; then echo "ERROR! Could not find the configuration file required for running TOPUP on data with odd number of slices (your input has $n_slices slices). Should be in $FSLDIR."; exit 1;
  383. else
  384. topup --imain=both_b0 --datain=acqparams.txt --config=${b02b0_1} --out=my_topup_results --iout=my_hifi_b0 #which will upon completion create the two files my_topup_results_fieldcoef.nii.gz (an estimate of the susceptibility induced off-resonance field), my_topup_results_movpar.txt and the non-distorted space my_hifi_b0.nii.gz
  385. fi
  386. fi
  387. # Processing of topup output
  388. fslmaths my_hifi_b0 -Tmean my_hifi_b0
  389. bet2 my_hifi_b0 b0_brain -m
  390. #EDDY
  391. if [ $eddy == "0" ]; then echo "EDDY skipped by the user (-e option is equal to $eddy)";
  392. else
  393. echo "Running EDDY with TOPUP RESULTS"
  394. temp=`fslhd "${dwi1}" | grep dim4`
  395. dimtmp=( $temp )
  396. n_vol=${dimtmp[1]}
  397. indx=""
  398. for ((i=1; i<=$n_vol; i+=1)); do indx="$indx 1"; done
  399. echo $indx > index.txt
  400. if [ $eddy == "1" ] && [ -f ${FSLDIR}/bin/eddy_cpu ]; then
  401. echo "Found eddy_cpu! Running ${FSLDIR}/bin/eddy_cpu with default options"
  402. eddy_cpu --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --topup=my_topup_results --out=eddy_corrected_data
  403. elif [ $eddy == "2" ] && [ -f ${FSLDIR}/bin/eddy ]; then
  404. echo "Running ${FSLDIR}/bin/eddy with default options";
  405. eddy --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --topup=my_topup_results --out=eddy_corrected_data
  406. elif [ $eddy == "3" ] && [ -f ${FSLDIR}/bin/eddy_correct ]; then
  407. echo "Running ${FSLDIR}/bin/eddy_correct with default options";
  408. eddy_correct "$dwi1_processed" eddy_corrected_data 0 trilinear
  409. else echo "Eddy with user-specified eddy program ${FSLDIR}/bin/$eddy"
  410. "${FSLDIR}/bin/$eddy" --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --topup=my_topup_results --out=eddy_corrected_data
  411. fi
  412. fi
  413. elif [ "${PEdir1}" != "${PEdir2}-" ] || [ "${PEdir2}" != "${PEdir1}-" ] || [ "${b0_dwi1}" != "${b0_dwi2}" ]; then
  414. fslroi "$dwi1_processed" "${outdir}/b0" 0 1
  415. bet2 "${outdir}/b0" "${outdir}/b0_brain" -m
  416. #EDDY
  417. if [ $eddy == "0" ]; then echo "EDDY skipped by the user (-e option is equal to $eddy)";
  418. else
  419. echo "Running EDDY (NO TOPUP) because PE directions are not opposite or b0 images are different"
  420. temp=`fslhd "${dwi1}" | grep dim4`
  421. dimtmp=( $temp )
  422. n_vol=${dimtmp[1]}
  423. indx=""
  424. for ((i=1; i<=$n_vol; i+=1)); do indx="$indx 1"; done
  425. echo $indx > index.txt
  426. if [ $eddy == "1" ] && [ -f ${FSLDIR}/bin/eddy_cpu ]; then
  427. echo "Found eddy_cpu! Running ${FSLDIR}/bin/eddy_cpu with default options"
  428. eddy_cpu --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  429. elif [ $eddy == "2" ] && [ -f ${FSLDIR}/bin/eddy ]; then
  430. echo "Running ${FSLDIR}/bin/eddy with default options";
  431. eddy --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  432. elif [ $eddy == "3" ] && [ -f ${FSLDIR}/bin/eddy_correct ]; then
  433. echo "Running ${FSLDIR}/bin/eddy_correct with default options";
  434. eddy_correct "$dwi1_processed" eddy_corrected_data 0 trilinear
  435. else echo "Eddy with user-specified eddy program ${FSLDIR}/bin/$eddy"
  436. "${FSLDIR}/bin/$eddy" --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  437. fi
  438. fi
  439. fi
  440. elif [ ! "$dwi2" ]; then
  441. fslroi "$dwi1_processed" "${outdir}/b0" 0 1
  442. bet2 "${outdir}/b0" "${outdir}/b0_brain" -m
  443. #EDDY
  444. if [ $eddy == "0" ]; then echo "EDDY skipped by the user (-e option is equal to $eddy)";
  445. else
  446. echo "Running EDDY only (NO TOPUP) because there is no dwi2"
  447. temp=`fslhd "${dwi1}" | grep dim4`
  448. dimtmp=( $temp )
  449. n_vol=${dimtmp[1]}
  450. indx=""
  451. for ((i=1; i<=$n_vol; i+=1)); do indx="$indx 1"; done
  452. echo $indx > index.txt
  453. if [ $eddy == "1" ] && [ -f ${FSLDIR}/bin/eddy_cpu ]; then
  454. echo "Found eddy_cpu! Running ${FSLDIR}/bin/eddy_cpu with default options"
  455. eddy_cpu --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  456. elif [ $eddy == "2" ] && [ -f ${FSLDIR}/bin/eddy ]; then
  457. echo "Running ${FSLDIR}/bin/eddy with default options";
  458. eddy --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  459. elif [ $eddy == "3" ] && [ -f ${FSLDIR}/bin/eddy_correct ]; then
  460. echo "Running ${FSLDIR}/bin/eddy_correct with default options";
  461. eddy_correct "$dwi1_processed" eddy_corrected_data 0 trilinear
  462. else echo "Eddy with user-specified eddy program ${FSLDIR}/bin/$eddy"
  463. "${FSLDIR}/bin/$eddy" --imain="$dwi1_processed" --mask=b0_brain_mask --acqp=acqparams.txt --index=index.txt --bvecs=bvec1 --bvals=bval1 --out=eddy_corrected_data
  464. fi
  465. fi
  466. fi
  467. elif [ ! -f "${json1}" ] && [ $eddy == "3" ]; then
  468. echo "Running ${FSLDIR}/bin/eddy_correct with default options";
  469. eddy_correct "$dwi1_processed" eddy_corrected_data 0 trilinear
  470. fi
  471. # 2. FIT TENSOR
  472. if [ -f "${outdir}/eddy_corrected_data.nii.gz" ]; then
  473. echo "starting DTI FITTING on eddy corrected data"
  474. if [ -f "${outdir}/eddy_corrected_data.eddy_rotated_bvecs" ]; then
  475. echo "Using eddy_rotated_bvecs"
  476. dtifit --data=eddy_corrected_data.nii.gz --out=dti --mask=b0_brain_mask.nii.gz --bvecs=eddy_corrected_data.eddy_rotated_bvecs --bvals=bval1 --save_tensor
  477. else
  478. dtifit --data=eddy_corrected_data.nii.gz --out=dti --mask=b0_brain_mask.nii.gz --bvecs=bvec1 --bvals=bval1 --save_tensor
  479. fi
  480. else
  481. if [ -f "${dwi1_processed}" ]; then
  482. fslroi "$dwi1_processed" "${outdir}/b0" 0 1
  483. bet2 "${outdir}/b0" "${outdir}/b0_brain" -m
  484. echo "starting DTI FITTING on preprocessed diffusion data (denoised and/or unringed, NO TOPUP, NO eddy correction)"
  485. dtifit --data="${dwi1_processed}" --out=dti --mask=b0_brain_mask.nii.gz --bvecs=bvec1 --bvals=bval1 --save_tensor
  486. else
  487. fslroi "$dwi1" "${outdir}/b0" 0 1
  488. bet2 "${outdir}/b0" "${outdir}/b0_brain" -m
  489. echo "starting DTI FITTING on input diffusion data (NO preprocessing (denoising/unringing), NO TOPUP, NO eddy correction)"
  490. dtifit --data="${dwi1}" --out=dti --mask=b0_brain_mask.nii.gz --bvecs=bvec1 --bvals=bval1 --save_tensor
  491. fi
  492. fi
  493. echo "DTI FITTING completed!"
  494. #fslsplit "${outdir}/dti_tensor.nii.gz"
  495. #cp "${outdir}/vol0000.nii.gz" "${outdir}/dxx.nii.gz"
  496. #cp "${outdir}/vol0003.nii.gz" "${outdir}/dyy.nii.gz"
  497. #cp "${outdir}/vol0005.nii.gz" "${outdir}/dzz.nii.gz"
  498. elif [ $skip -eq 1 ]; then
  499. echo "Preprocessing and DTI fitting skipped by the user (-s 1 option). ONLY ROI ANALYSIS IS PERFORMED. Checking all required inputs are available..."
  500. if [ -f "${outdir}/alps.stat/alps.csv" ] && [ ! -z "`tail -n 1 "${outdir}/alps.stat/alps.csv" | tr -d ,`" ]; then echo "ERROR! Final output alps.csv already exists and is not empty! Remove/rename the "alps.stat" folder or the "alps.stat/alps.csv" file in order to run the ROI analysis only (-s 1) in ${outdir}"; exit 1; fi;
  501. if [ -f "${outdir}/dti_FA.nii.gz" ]; then echo "dti_FA.nii.gz is available for ROI analysis"; else echo "ERROR! Cannot find ${outdir}/dti_FA.nii.gz, needed for ROI analysis. Double check that ${outdir}/dti_FA.nii.gz exists; if it does not exist, consider running the whole alps script (-s 0, default option)"; exit 1; fi
  502. if [ -f "${outdir}/dti_tensor.nii.gz" ]; then echo "dti_tensor.nii.gz is available for ROI analysis"; else echo "ERROR! Cannot find ${outdir}/dti_tensor.nii.gz, needed for ROI analysis. Double check that ${outdir}/dti_tensor.nii.gz exists; if it does not exist, consider running the whole alps script (-s 0, default option)"; exit 1; fi
  503. #if [ -f "${outdir}/dxx.nii.gz" ]; then echo "dxx.nii.gz is available for ROI analysis"; else echo "ERROR! Cannot find ${outdir}/dxx.nii.gz, needed for ROI analysis. Double check that ${outdir}/dxx.nii.gz exists; if it does not exist, consider running the whole alps script (-s 0, default option)"; exit 1; fi
  504. #if [ -f "${outdir}/dyy.nii.gz" ]; then echo "dyy.nii.gz is available for ROI analysis"; else echo "ERROR! Cannot find ${outdir}/dyy.nii.gz, needed for ROI analysis. Double check that ${outdir}/dyy.nii.gz exists; if it does not exist, consider running the whole alps script (-s 0, default option)"; exit 1; fi
  505. #if [ -f "${outdir}/dyy.nii.gz" ]; then echo "dzz.nii.gz is available for ROI analysis"; else echo "ERROR! Cannot find ${outdir}/dzz.nii.gz, needed for ROI analysis. Double check that ${outdir}/dzz.nii.gz exists; if it does not exist, consider running the whole alps script (-s 0, default option)"; exit 1; fi
  506. fi
  507. # 3. ROI ANALYSIS
  508. if [ "$rois" != "0" ]
  509. then
  510. if [ -z $radius ]; then
  511. iteration=0
  512. for r in $(echo $rois | tr -s ',' ' '); do
  513. iteration=$((iteration+1))
  514. cp "$r" "${outdir}/"$(basename "$(basename "$r" .gz)" .nii)"_in_${template_abbreviation}.nii.gz";
  515. if [ $iteration -eq 1 ]; then
  516. cp "${outdir}/"$(basename "$(basename "$r" .gz)" .nii)"_in_${template_abbreviation}.nii.gz" "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  517. else
  518. fslmaths "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz" -add "${outdir}/"$(basename "$(basename "$r" .gz)" .nii)"_in_${template_abbreviation}.nii.gz" "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  519. fi
  520. done
  521. cluster -t 1 -i "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz" -o "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  522. #cp "${script_folder}/ROIs_JHU_ALPS/all_ROIs.nii.gz" "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  523. else #generate spheric ROIs in template space
  524. if [ "${template}" == "0" ]; then template_roi=${FSLDIR}/data/atlases/JHU/JHU-ICBM-FA-1mm.nii.gz; template_abbreviation=JHU-FA; else template_roi="${template}"; fi
  525. fslmaths "${template_roi}" -mul 0 -add 1 -roi 116 1 110 1 99 1 0 1 -kernel sphere $radius -fmean -bin "${outdir}/L_SCR_in_${template_abbreviation}.nii.gz" -odt float
  526. fslmaths "${template_roi}" -mul 0 -add 1 -roi 64 1 110 1 99 1 0 1 -kernel sphere $radius -fmean -bin "${outdir}/R_SCR_in_${template_abbreviation}.nii.gz" -odt float
  527. fslmaths "${template_roi}" -mul 0 -add 1 -roi 128 1 110 1 99 1 0 1 -kernel sphere $radius -fmean -bin "${outdir}/L_SLF_in_${template_abbreviation}.nii.gz" -odt float
  528. fslmaths "${template_roi}" -mul 0 -add 1 -roi 52 1 110 1 99 1 0 1 -kernel sphere $radius -fmean -bin "${outdir}/R_SLF_in_${template_abbreviation}.nii.gz" -odt float
  529. fslmaths "${outdir}/L_SCR_in_${template_abbreviation}.nii.gz" -add "${outdir}/R_SCR_in_${template_abbreviation}.nii.gz" -add "${outdir}/L_SLF_in_${template_abbreviation}.nii.gz" -add "${outdir}/R_SLF_in_${template_abbreviation}.nii.gz" -bin "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  530. cluster -t 1 -i "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz" -o "${outdir}/all_ROIs_in_${template_abbreviation}.nii.gz"
  531. fi
  532. rois="${outdir}/L_SCR_in_${template_abbreviation}.nii.gz","${outdir}/R_SCR_in_${template_abbreviation}.nii.gz","${outdir}/L_SLF_in_${template_abbreviation}.nii.gz","${outdir}/R_SLF_in_${template_abbreviation}.nii.gz"
  533. proj_L="${outdir}/L_SCR_in_${template_abbreviation}.nii.gz"
  534. proj_R="${outdir}/R_SCR_in_${template_abbreviation}.nii.gz"
  535. assoc_L="${outdir}/L_SLF_in_${template_abbreviation}.nii.gz"
  536. assoc_R="${outdir}/R_SLF_in_${template_abbreviation}.nii.gz"
  537. #ROIs
  538. echo "starting ROI analysis with projection fibers "$(basename "$proj_L")" (LEFT) and "$(basename "$proj_R")" (RIGHT), and association fibers "$(basename "$assoc_L")" (LEFT) and "$(basename "$assoc_R")" (RIGHT)"
  539. #TEMPLATE
  540. if [ "$template" != "0" ]; then #analysis in template space
  541. if [ -f "$struct" ]; then #if you have structural MRI data
  542. echo "Linear (flirt) + Non-Linear (fnirt) registration to template via structural scan";
  543. cp "$struct" "${outdir}/${smri}.nii.gz"
  544. #hashtagged the following 2 lines because bet2 does not work super well in all struct MRI scans.
  545. #bet2 "${outdir}/${smri}.nii.gz" "${outdir}/${smri}_brain" -m #this is used for flirt dti2struct and flirt struct2template
  546. #flirt -ref "${outdir}/${smri}_brain.nii.gz" -in "${outdir}/dti_FA.nii.gz" -dof 6 -omat "${outdir}/dti2struct.mat"
  547. if [ $weight == "1" ]; then
  548. flirt -ref "${outdir}/${smri}.nii.gz" -in "${outdir}/dti_FA.nii.gz" -dof 6 -out "${outdir}/dti_FA_2_${smri}.nii.gz" -omat "${outdir}/dti2struct.mat"
  549. elif [ $weight == "2" ]; then #if it's a T2, it's better to align the b0 volume rather than the FA, because the b0 contrast is more similar to T2.
  550. if [ -f "${outdir}/b0.nii.gz" ]; then
  551. flirt -ref "${outdir}/${smri}.nii.gz" -in "${outdir}/b0.nii.gz" -dof 6 -out "${outdir}/b0_2_${smri}.nii.gz" -omat "${outdir}/dti2struct.mat"
  552. else #in case you don't have b0 (i.e., you skipped the preprocessing, and are only doing ROI analysis with a dti_FA map ready)
  553. flirt -ref "${outdir}/${smri}.nii.gz" -in "${outdir}/dti_FA.nii.gz" -dof 6 -out "${outdir}/dti_FA_2_${smri}.nii.gz" -omat "${outdir}/dti2struct.mat"
  554. fi
  555. fi
  556. if [ -f "${outdir}/b0_brain_mask.nii.gz" ]; then
  557. flirt -in "${outdir}/b0_brain_mask.nii.gz" -ref "${outdir}/${smri}.nii.gz" -interp nearestneighbour -out "${outdir}/b0_brain_mask_2_struct.nii.gz" -init "${outdir}/dti2struct.mat" -applyxfm
  558. fslmaths "${outdir}/${smri}.nii.gz" -mul "${outdir}/b0_brain_mask_2_struct.nii.gz" "${outdir}/${smri}_brain.nii.gz"
  559. else #in case you don't have b0_brain_mask (i.e., you skipped the preprocessing, and are only doing ROI analysis)
  560. bet2 "${outdir}/dti_FA.nii.gz" "${outdir}/dti_FA_brain" -m
  561. flirt -in "${outdir}/dti_FA_brain_mask.nii.gz" -ref "${outdir}/${smri}.nii.gz" -interp nearestneighbour -out "${outdir}/dti_FA_brain_mask_2_struct.nii.gz" -init "${outdir}/dti2struct.mat" -applyxfm
  562. fslmaths "${outdir}/${smri}.nii.gz" -mul "${outdir}/dti_FA_brain_mask_2_struct.nii.gz" "${outdir}/${smri}_brain.nii.gz"
  563. fi
  564. flirt -ref "${template}" -in "${outdir}/${smri}_brain.nii.gz" -omat "${outdir}/struct2template_aff.mat"
  565. fnirt --in="${outdir}/${smri}.nii.gz" --aff="${outdir}/struct2template_aff.mat" --cout="${outdir}/struct2template_warps" \
  566. --ref="${template}" ${template_mask}--imprefm=1 \
  567. --impinm=1 --imprefval=0 --impinval=0 --subsamp=4,4,2,2,1,1 --miter=5,5,5,5,5,10 --infwhm=8,6,5,4.5,3,2 --reffwhm=8,6,5,4,2,0 \
  568. --lambda=300,150,100,50,40,30 --estint=1,1,1,1,1,0 --applyrefmask=1,1,1,1,1,1 --applyinmask=1 --warpres=10,10,10 --ssqlambda=1 \
  569. --regmod=bending_energy --intmod=global_non_linear_with_bias --intorder=5 --biasres=50,50,50 --biaslambda=10000 --refderiv=0
  570. applywarp --in="${outdir}/dti_FA.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"
  571. applywarp --in="${outdir}/dti_MD.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dti_MD_to_${template_abbreviation}.nii.gz"
  572. if [ "$freg" == "1" ]; then echo "Transformation of the tensor to the template with applywarp";
  573. applywarp --in="${outdir}/dti_tensor.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"
  574. #applywarp --in="${outdir}/dxx.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dxx_in_${template_abbreviation}.nii.gz"
  575. #applywarp --in="${outdir}/dyy.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dyy_in_${template_abbreviation}.nii.gz"
  576. #applywarp --in="${outdir}/dzz.nii.gz" --ref="${template}" --warp="${outdir}/struct2template_warps" --premat="${outdir}/dti2struct.mat" --out="${outdir}/dzz_in_${template_abbreviation}.nii.gz"
  577. elif [ "$freg" == "2" ]; then echo "Transformation of the tensor to the template with vecreg";
  578. vecreg -i "${outdir}/dti_tensor.nii.gz" -r "${template}" -o "${outdir}/dti_tensor_in_struct.nii.gz" -t "${outdir}/dti2struct.mat"
  579. vecreg -i "${outdir}/dti_tensor_in_struct.nii.gz" -r "${template}" -o "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" -w "${outdir}/struct2template_warps"
  580. fi
  581. else
  582. if [ "$warp" == "0" ]; then
  583. if [ ! -f "${outdir}/dti_FA_to_${template_abbreviation}.nii.gz" ]; then
  584. echo "Linear registration to template with flirt and default options";
  585. flirt -in "${outdir}/dti_FA.nii.gz" -ref "${template}" -out "${outdir}/dti_FA_to_${template_abbreviation}.nii.gz" -omat "${outdir}/FA_to_${template_abbreviation}.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12;
  586. flirt -in "${outdir}/dti_MD.nii.gz" -ref "${template}" -out "${outdir}/dti_MD_to_${template_abbreviation}.nii.gz" -init "${outdir}/FA_to_${template_abbreviation}.mat" -applyxfm;
  587. else echo "dti_FA registered to template exists and will NOT be overwritten: ${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"; fi
  588. if [ ! -f "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" ]; then
  589. if [ "$freg" == "1" ]; then echo "Transformation of the tensor to the template with flirt";
  590. flirt -in "${outdir}/dti_tensor.nii.gz" -ref "${template}" -out "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" -init "${outdir}/FA_to_${template_abbreviation}.mat" -applyxfm
  591. #flirt -in "${outdir}/dxx.nii.gz" -ref "${template}" -out "${outdir}/dxx_in_${template_abbreviation}.nii.gz" -init "${outdir}/FA_to_${template_abbreviation}.mat" -applyxfm
  592. #flirt -in "${outdir}/dyy.nii.gz" -ref "${template}" -out "${outdir}/dyy_in_${template_abbreviation}.nii.gz" -init "${outdir}/FA_to_${template_abbreviation}.mat" -applyxfm
  593. #flirt -in "${outdir}/dzz.nii.gz" -ref "${template}" -out "${outdir}/dzz_in_${template_abbreviation}.nii.gz" -init "${outdir}/FA_to_${template_abbreviation}.mat" -applyxfm
  594. elif [ "$freg" == "2" ]; then echo "Transformation of the tensor to the template with vecreg";
  595. vecreg -i "${outdir}/dti_tensor.nii.gz" -r "${template}" -o "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" -t "${outdir}/FA_to_${template_abbreviation}.mat"
  596. #vecreg -i "${outdir}/dxx.nii.gz" -r "${template}" -o "${outdir}/dxx_in_${template_abbreviation}.nii.gz" -t "${outdir}/FA_to_${template_abbreviation}.mat"
  597. #vecreg -i "${outdir}/dyy.nii.gz" -r "${template}" -o "${outdir}/dyy_in_${template_abbreviation}.nii.gz" -t "${outdir}/FA_to_${template_abbreviation}.mat"
  598. #vecreg -i "${outdir}/dzz.nii.gz" -r "${template}" -o "${outdir}/dzz_in_${template_abbreviation}.nii.gz" -t "${outdir}/FA_to_${template_abbreviation}.mat"
  599. fi
  600. else echo "dti_tensor registered to template exists and will NOT be overwritten: ${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"; fi
  601. elif [ "$warp" == "1" ]; then
  602. if [ ! -f "${outdir}/dti_FA_to_${template_abbreviation}.nii.gz" ]; then
  603. echo "Non-Linear registration to template with fnirt and default options (cf. fsl/etc/flirtsch/FA_2_FMRIB58_1mm.cnf)";
  604. fnirt --in="${outdir}/dti_FA.nii.gz" --ref="${template}" ${template_mask}--cout="${outdir}/FA_to_${template_abbreviation}_warps" --imprefm=1 --impinm=1 --imprefval=0 --impinval=0 --subsamp=8,4,2,2 \
  605. --miter=5,5,5,5 --infwhm=12,6,2,2 --reffwhm=12,6,2,2 --lambda=300,75,30,30 --estint=1,1,1,0 --warpres=10,10,10 --ssqlambda=1 \
  606. --regmod=bending_energy --intmod=global_linear --refderiv=0
  607. applywarp --in="${outdir}/dti_FA.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"
  608. applywarp --in="${outdir}/dti_MD.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_MD_to_${template_abbreviation}.nii.gz"
  609. else echo "dti_FA registered to template exists and will NOT be overwritten: ${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"; fi
  610. if [ ! -f "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" ]; then
  611. if [ "$freg" == "1" ]; then echo "Transformation of the tensor to the template with applywarp";
  612. applywarp --in="${outdir}/dti_tensor.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"
  613. #applywarp --in="${outdir}/dxx.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dxx_in_${template_abbreviation}.nii.gz"
  614. #applywarp --in="${outdir}/dyy.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dyy_in_${template_abbreviation}.nii.gz"
  615. #applywarp --in="${outdir}/dzz.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dzz_in_${template_abbreviation}.nii.gz"
  616. elif [ "$freg" == "2" ]; then echo "Transformation of the tensor to the template with vecreg";
  617. vecreg -i "${outdir}/dti_tensor.nii.gz" -r "${template}" -o "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" -w "${outdir}/FA_to_${template_abbreviation}_warps"
  618. fi
  619. else echo "dti_tensor registered to template exists and will NOT be overwritten: ${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"; fi
  620. elif [ "$warp" == "2" ]; then
  621. if [ ! -f "${outdir}/dti_FA_to_${template_abbreviation}.nii.gz" ]; then
  622. echo "Linear (flirt) + Non-Linear (fnirt) registration to template";
  623. flirt -in "${outdir}/dti_FA.nii.gz" -ref "${template}" -omat "${outdir}/FA_to_${template_abbreviation}_aff.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
  624. fnirt --in="${outdir}/dti_FA.nii.gz" --ref="${template}" ${template_mask}--aff="${outdir}/FA_to_${template_abbreviation}_aff.mat" \
  625. --cout="${outdir}/FA_to_${template_abbreviation}_warps" --imprefm=1 --impinm=1 --imprefval=0 --impinval=0 --subsamp=8,4,2,2 \
  626. --miter=5,5,5,5 --infwhm=12,6,2,2 --reffwhm=12,6,2,2 --lambda=300,75,30,30 --estint=1,1,1,0 --warpres=10,10,10 --ssqlambda=1 \
  627. --regmod=bending_energy --intmod=global_linear --refderiv=0
  628. applywarp --in="${outdir}/dti_FA.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"
  629. applywarp --in="${outdir}/dti_MD.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_MD_to_${template_abbreviation}.nii.gz"
  630. else echo "dti_FA registered to template exists and will NOT be overwritten: ${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"; fi
  631. if [ ! -f "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" ]; then
  632. if [ "$freg" == "1" ]; then echo "Transformation of the tensor to the template with applywarp";
  633. applywarp --in="${outdir}/dti_tensor.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"
  634. #applywarp --in="${outdir}/dxx.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dxx_in_${template_abbreviation}.nii.gz"
  635. #applywarp --in="${outdir}/dyy.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dyy_in_${template_abbreviation}.nii.gz"
  636. #applywarp --in="${outdir}/dzz.nii.gz" --ref="${template}" --warp="${outdir}/FA_to_${template_abbreviation}_warps" --out="${outdir}/dzz_in_${template_abbreviation}.nii.gz"
  637. elif [ "$freg" == "2" ]; then echo "Transformation of the tensor to the template with vecreg";
  638. vecreg -i "${outdir}/dti_tensor.nii.gz" -r "${template}" -o "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" -w "${outdir}/FA_to_${template_abbreviation}_warps"
  639. fi
  640. else echo "dti_tensor registered to template exists and will NOT be overwritten: ${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz"; fi
  641. fi
  642. fi
  643. fslroi "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" "${outdir}/dxx_in_${template_abbreviation}.nii.gz" 0 1
  644. fslroi "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" "${outdir}/dyy_in_${template_abbreviation}.nii.gz" 3 1
  645. fslroi "${outdir}/dti_tensor_in_${template_abbreviation}.nii.gz" "${outdir}/dzz_in_${template_abbreviation}.nii.gz" 5 1
  646. dxx="${outdir}/dxx_in_${template_abbreviation}.nii.gz"
  647. dyy="${outdir}/dyy_in_${template_abbreviation}.nii.gz"
  648. dzz="${outdir}/dzz_in_${template_abbreviation}.nii.gz"
  649. fa="${outdir}/dti_FA_to_${template_abbreviation}.nii.gz"
  650. md="${outdir}/dti_MD_to_${template_abbreviation}.nii.gz"
  651. elif [ "$template" == "0" ]; then #analysis in native space
  652. echo "ALPS analysis in native space"
  653. fslroi "${outdir}/dti_tensor.nii.gz" "${outdir}/dxx.nii.gz" 0 1
  654. fslroi "${outdir}/dti_tensor.nii.gz" "${outdir}/dyy.nii.gz" 3 1
  655. fslroi "${outdir}/dti_tensor.nii.gz" "${outdir}/dzz.nii.gz" 5 1
  656. dxx="${outdir}/dxx.nii.gz"
  657. dyy="${outdir}/dyy.nii.gz"
  658. dzz="${outdir}/dzz.nii.gz"
  659. fa="${outdir}/dti_FA.nii.gz"
  660. md="${outdir}/dti_MD.nii.gz"
  661. #if [ "$rois" == "${script_folder}/ROIs_JHU_ALPS/L_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SCR.nii.gz,${script_folder}/ROIs_JHU_ALPS/L_SLF.nii.gz,${script_folder}/ROIs_JHU_ALPS/R_SLF.nii.gz" ]; then
  662. template=${FSLDIR}/data/atlases/JHU/JHU-ICBM-FA-1mm.nii.gz
  663. template_abbreviation=JHU-FA
  664. flirt -ref "${outdir}/dti_FA.nii.gz" -in "${template}" -out "${outdir}/dti_FA_${template_abbreviation}_to_native.nii.gz" -omat "${outdir}/${template_abbreviation}_to_native.mat" -bins 256 -cost corratio -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -dof 12
  665. for r in $(echo $rois | tr -s ',' ' '); do
  666. flirt -in "${r}" -ref "${outdir}/dti_FA.nii.gz" -out "${outdir}/"$(basename "$(basename "$(basename "$r" .gz)" .nii)" _in_${template_abbreviation})"_native.nii.gz" -init "${outdir}/${template_abbreviation}_to_native.mat" -applyxfm -interp nearestneighbour
  667. done
  668. proj_L=${outdir}/"$(basename "$(basename "$(basename "$(echo "${rois}" | cut -d ',' -f1)" .gz)" .nii)" _in_${template_abbreviation})"_native.nii.gz
  669. proj_R=${outdir}/"$(basename "$(basename "$(basename "$(echo "${rois}" | cut -d ',' -f2)" .gz)" .nii)" _in_${template_abbreviation})"_native.nii.gz
  670. assoc_L=${outdir}/"$(basename "$(basename "$(basename "$(echo "${rois}" | cut -d ',' -f3)" .gz)" .nii)" _in_${template_abbreviation})"_native.nii.gz
  671. assoc_R=${outdir}/"$(basename "$(basename "$(basename "$(echo "${rois}" | cut -d ',' -f4)" .gz)" .nii)" _in_${template_abbreviation})"_native.nii.gz
  672. fslmaths "${proj_L}" -add "${proj_R}" -add "${assoc_L}" -add "${assoc_R}" -bin "${outdir}/all_ROIs_native.nii.gz"
  673. cluster -t 1 -i "${outdir}/all_ROIs_native.nii.gz" -o "${outdir}/all_ROIs_native.nii.gz"
  674. #fi
  675. fi
  676. #GATHER STATS
  677. mkdir -p "${outdir}/alps.stat"
  678. echo "id,scanner,x_proj_L,x_assoc_L,y_proj_L,z_assoc_L,x_proj_R,x_assoc_R,y_proj_R,z_assoc_R,alps_L,alps_R,alps" > "${outdir}/alps.stat/alps.csv"
  679. echo "id,scanner,diffusion_metric,proj_L,assoc_L,proj_R,assoc_R,mean_proj,mean_assoc" > "${outdir}/alps.stat/fa+md_alps.csv"
  680. if [[ "$dwi1" == *".nii" ]]; then
  681. id="$(basename "$dwi1" .nii)"
  682. elif [[ $dwi1 == *".nii.gz" ]]; then
  683. id="$(basename "$dwi1" .nii.gz)"
  684. else
  685. id="$(basename "$dwi1")"
  686. fi
  687. x_proj_L="$(fslstats "${dxx}" -k "${proj_L}" -m)"
  688. x_assoc_L="$(fslstats "${dxx}" -k "${assoc_L}" -m)"
  689. y_proj_L="$(fslstats "${dyy}" -k "${proj_L}" -m)"
  690. z_assoc_L="$(fslstats "${dzz}" -k "${assoc_L}" -m)"
  691. x_proj_R="$(fslstats "${dxx}" -k "${proj_R}" -m)"
  692. x_assoc_R="$(fslstats "${dxx}" -k "${assoc_R}" -m)"
  693. y_proj_R="$(fslstats "${dyy}" -k "${proj_R}" -m)"
  694. z_assoc_R="$(fslstats "${dzz}" -k "${assoc_R}" -m)"
  695. alps_L=`echo "(($x_proj_L+$x_assoc_L)/2)/(($y_proj_L+$z_assoc_L)/2)" | bc -l` #proj1 and assoc1 are left side, bc -l needed for decimal printing results
  696. alps_R=`echo "(($x_proj_R+$x_assoc_R)/2)/(($y_proj_R+$z_assoc_R)/2)" | bc -l` #proj2 and assoc2 are right side, bc -l needed for decimal printing results
  697. alps=`echo "($alps_R+$alps_L)/2" | bc -l`
  698. echo "${id},${scanner1},${x_proj_L},${x_assoc_L},${y_proj_L},${z_assoc_L},${x_proj_R},${x_assoc_R},${y_proj_R},${z_assoc_R},${alps_L},${alps_R},${alps}" >> "${outdir}/alps.stat/alps.csv"
  699. #FA and MD values from projection and association areas
  700. for diff in "${fa}" "${md}"; do
  701. pl="$(fslstats "${diff}" -k "${proj_L}" -m)"
  702. pr="$(fslstats "${diff}" -k "${proj_R}" -m)"
  703. al="$(fslstats "${diff}" -k "${assoc_L}" -m)"
  704. ar="$(fslstats "${diff}" -k "${assoc_R}" -m)"
  705. pmean=`echo "($pl+$pr)/2" | bc -l`
  706. amean=`echo "($al+$ar)/2" | bc -l`
  707. if [ "${diff}" == "${fa}" ]; then d="FA"; else d="MD"; fi
  708. echo "${id},${scanner1},${d},${pl},${al},${pr},${ar},${pmean},${amean}" >> "${outdir}/alps.stat/fa+md_alps.csv"
  709. done
  710. elif [ "$rois" == "0" ]; then
  711. echo "ROI analysis skipped by the user.";
  712. fi
  713. echo "Finito! Please cite this repository (https://github.com/gbarisano/alps/) and the paper:
  714. Liu, X, Barisano, G, et al., Cross-Vendor Test-Retest Validation of Diffusion Tensor Image Analysis along the Perivascular Space (DTI-ALPS) for Evaluating Glymphatic System Function, Aging and Disease (2023)"

alps.sh at commit e6f58e7, under MIT · at the source

Overview

Authors: Xin Jin1,2, Yan Fu3, Ting Qiu4, Jianyu Li2, Huixiong Zhang2, Yifan Chen2, Kewei Chen5, Yuanchao Zhang1,2,5, Junling Wang6,7,8,9,10,11, Xiaoping Yi12,13,14, Lena Palaniyappan4, B Blair Braden5
14 affiliations
  1. The Clinical Hospital of Chengdu Brain Science Institute, MOE Key Lab for Neuroinformation, University of Electronic Science and Technology of China, Chengdu, Sichuan P. R. China
  2. School of Life Science and Technology, University of Electronic Science and Technology of China, Chengdu, 610054 Sichuan P. R. China
  3. Department of Radiology, Tongji Hospital, Tongji Medical College, Huazhong University of Science and Technology, Wuhan, P. R. China
  4. Douglas Mental Health University Institute, McGill University, Montreal, QC Canada
  5. College of Health Solutions, Arizona State University, Phoenix, AZ 85287 USA
  6. Department of Neurology, Xiangya Hospital, Central South University, Jiangxi. (National Regional Center for Neurological Diseases), Nanchang, 330038 Jiangxi P. R. China
  7. National Clinical Research Center for Geriatric Diseases(Xiangya Hospital of Central South University), Changsha, 410008 Hunan P. R. China
  8. Key Laboratory of Hunan Province for Neurodegenerative Disorders, Central South University, Changsha, 410008 Hunan P. R. China
  9. Center for Medical Genetics, School of Life Sciences, Central South University, Changsha, 410008 Hunan P. R. China
  10. Engineering Research Center of Hunan Province for Cognitive Impairment Disorders, Central South University, Changsha, 410008 Hunan P. R. China
  11. Hunan International Scientific and Technological Cooperation Base of Neurodegenerative and Neurogenetic Diseases, Changsha, 410008 Hunan P. R. China
  12. Department of Nuclear Medicine and Department of Radiology, Chongqing University Three Gorges Hospital, Chongqing University, Chongqing, 404000 P. R. China
  13. Clinical Research Center (CRC), Medical Pathology Center (MPC), Cancer Early Detection and Treatment Center (CEDTC) and Translational Medicine Research Center (TMRC), Chongqing University Three Gorges Hospital, Chongqing University, Chongqing, 404000 P.R. China
  14. School of Medicine, Chongqing University, Chongqing, 400030 P.R. China
Journal: BMC medicine, volume 24, issue 1, article 405
Dates: received 29 January 2026; accepted 20 May 2026; published online 27 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1186/s12916-026-04948-z · PMID 42204548 · PMCID PMC13397807 · OpenAlex W7162590803
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), human (organism), other condition (population), clinical / translational (subfield)
Methods: Connectivity, Statistics, fMRI & imaging
Keywords: ALS, Glymphatic system, White matter integrity, DTI-ALPS, Free-water fraction
MeSH: Amyotrophic Lateral Sclerosis*, Extracellular Fluid*, Glymphatic System*, White Matter*, Aged, Diffusion Tensor Imaging, Female, Humans, Magnetic Resonance Imaging, Male, Middle Aged (* major topic)
Topic: Cerebrospinal fluid and hydrocephalus (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Funding: Santé (CB-C2022); Scientific Research Program of FuRong Laboratory (No.2024PT5109); National Natural Science Foundation of China (U22A20377); Fundamental Research Funds for the Central Universities of Central South University (2024ZZTS0954); Project Program of National Clinical Research Center for Geriatric Disorders (No. 2022LNJJ09)
Citations: not cited yet (Europe PMC); 69 references in the paper

Abstract

Background: Amyotrophic lateral sclerosis (ALS) is a fatal neurodegenerative disorder characterized by progressive motor neuron degeneration and prominent extra-motor involvement. Impaired clearance of neurotoxic proteins has led to increasing interest in the brain glymphatic system; however, its in vivo associations with brain microstructure and clinical heterogeneity remain incompletely understood.

Methods: One hundred forty-six patients with ALS and 149 demographically matched healthy controls (HCs) underwent multimodal MRI and comprehensive clinical assessments. Putative glymphatic function was quantified using diffusion tensor imaging along perivascular space (DTI-ALPS). Extracellular free water fraction (FWF) and free-water-corrected fractional anisotropy (fwcFA) were derived to characterize extracellular fluid and white matter microstructure. Group differences were assessed using vertex-wise and voxel-wise analyses with correction for multiple comparisons. Associations among imaging metrics and clinical measures were evaluated using correlation and serial mediation analyses.

Results: Compared with HCs, patients with ALS exhibited significantly reduced DTI-ALPS index, widespread increases in cortical FWF, bidirectional alterations in white matter FWF, and extensive reductions in fwcFA across major white matter tracts. Reduced DTI-ALPS was associated with changes in extracellular free water and white matter microstructural integrity, whereas FWF and fwcFA measures were associated with functional, cognitive, and emotional outcomes. Mediation analyses identified significant indirect associations between DTI-ALPS and both functional and cognitive measures through a pathway involving cortical FWF, white matter FWF, and fwcFA, although direct associations were not observed.

Conclusions: These findings provide in vivo evidence that putative glymphatic dysfunction co-occurs with extracellular fluid alterations, white matter microstructural changes, and clinical impairment in ALS. Multi-compartment diffusion imaging may offer complementary markers for characterizing brain microstructure and its clinical relevance in ALS.

Supplementary Information: The online version contains supplementary material available at 10.1186/s12916-026-04948-z.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 2 matches between paragraphs and lines of code.

gbarisano/alps

License: MIT
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Commit: e6f58e7c1b882a799b613e91fe15bab940dc4cd3, 12 September 2025
Languages: Shell (1)
Size: 12 files, 1 script
Software Heritage: not archived
Found in: the text, “MRI data preprocessing”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: FSL (1 file), MRtrix3 (1 file)
Availability: 1 check, the latest on 26 September 2026: the link answers
  • 26 September 2026: the link answers
3 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 1 script, each with its path and the digest of its content;
  • 2 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability

The data supporting the findings of this study are available from the corresponding author upon reasonable request.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 12 authors, 5 keywords, 11 MeSH terms, 5 funders, 69 references.

Cite

This paper

Jin, X., Fu, Y., Qiu, T., Li, J., Zhang, H., Chen, Y., Chen, K., Zhang, Y., Wang, J., Yi, X., Palaniyappan, L., & Braden, B. B. (2026). Putative glymphatic dysfunction links extracellular fluid dysregulation to white matter degeneration and clinical impairment in amyotrophic lateral sclerosis. BMC medicine, 24(1), 405. https://doi.org/10.1186/s12916-026-04948-z

BibTeX

@article{jin2026putative,
author = {Jin, Xin and Fu, Yan and Qiu, Ting and Li, Jianyu and Zhang, Huixiong and Chen, Yifan and Chen, Kewei and Zhang, Yuanchao and Wang, Junling and Yi, Xiaoping and Palaniyappan, Lena and Braden, B Blair},
title = {{Putative glymphatic dysfunction links extracellular fluid dysregulation to white matter degeneration and clinical impairment in amyotrophic lateral sclerosis}},
journal = {BMC medicine},
year = {2026},
month = may,
volume = {24},
number = {1},
pages = {405},
publisher = {BioMed Central},
issn = {1741-7015},
doi = {10.1186/s12916-026-04948-z},
url = {https://doi.org/10.1186/s12916-026-04948-z},
pmid = {42204548},
pmcid = {PMC13397807}
}

RIS

TY - JOUR
AU - Jin, Xin
AU - Fu, Yan
AU - Qiu, Ting
AU - Li, Jianyu
AU - Zhang, Huixiong
AU - Chen, Yifan
AU - Chen, Kewei
AU - Zhang, Yuanchao
AU - Wang, Junling
AU - Yi, Xiaoping
AU - Palaniyappan, Lena
AU - Braden, B Blair
TI - Putative glymphatic dysfunction links extracellular fluid dysregulation to white matter degeneration and clinical impairment in amyotrophic lateral sclerosis
T2 - BMC medicine
J2 - BMC Med
PY - 2026
DA - 2026/05/27
VL - 24
IS - 1
SP - 405
SN - 1741-7015
PB - BioMed Central
DO - 10.1186/s12916-026-04948-z
UR - https://doi.org/10.1186/s12916-026-04948-z
LA - en
ER -

CSL-JSON

{
"id": "10.1186/s12916-026-04948-z",
"type": "article-journal",
"title": "Putative glymphatic dysfunction links extracellular fluid dysregulation to white matter degeneration and clinical impairment in amyotrophic lateral sclerosis",
"container-title": "BMC medicine",
"author": [
{
"family": "Jin",
"given": "Xin"
},
{
"family": "Fu",
"given": "Yan"
},
{
"family": "Qiu",
"given": "Ting"
},
{
"family": "Li",
"given": "Jianyu"
},
{
"family": "Zhang",
"given": "Huixiong"
},
{
"family": "Chen",
"given": "Yifan"
},
{
"family": "Chen",
"given": "Kewei"
},
{
"family": "Zhang",
"given": "Yuanchao"
},
{
"family": "Wang",
"given": "Junling"
},
{
"family": "Yi",
"given": "Xiaoping"
},
{
"family": "Palaniyappan",
"given": "Lena"
},
{
"family": "Braden",
"given": "B Blair"
}
],
"container-title-short": "BMC Med",
"volume": "24",
"issue": "1",
"page": "405",
"DOI": "10.1186/s12916-026-04948-z",
"PMID": "42204548",
"PMCID": "PMC13397807",
"ISSN": "1741-7015",
"publisher": "BioMed Central",
"URL": "https://doi.org/10.1186/s12916-026-04948-z",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
27
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1186/s12916-026-04770-7 [code]
Impairment of brain short association fibers across clinical stages in amyotrophic lateral sclerosis: a new biomarker mirroring disease progression.
Journal: BMC medicine
In common: FSL, structural MRI / diffusion, clinical / translational, other condition, 5 references
[2] doi:10.1073/pnas.2516601123 [code]
Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target.
Journal: Proceedings of the National Academy of Sciences of the United States of America
In common: structural MRI / diffusion, clinical / translational, 6 references
[3] doi:10.1002/trc2.70304 [code]
Thalamic volume alterations mediate glymphatic function and cognitive dysfunction in Alzheimer's disease.
Journal: Alzheimer's & dementia (New York, N. Y.)
In common: structural MRI / diffusion, 6 references
[4] doi:10.1093/braincomms/fcag235 [code]
Association between glymphatic dysfunction and glucose hypometabolism in chronic disorders of consciousness: a multimodal PET/MRI study.
Journal: Brain communications
In common: MRtrix3, FSL, structural MRI / diffusion, other condition, 3 references
[5] doi:10.1016/j.isci.2026.116581
Peripheral inflammation impairs glymphatic function, contributing to neurodegeneration in Alzheimer's disease.
Journal: iScience
In common: structural MRI / diffusion, 5 references
[6] doi:10.3390/ijms27135758
Diffusion Tensor Imaging Along the Perivascular Space (DTI-ALPS) as a Neuroimaging Biomarker of Glymphatic Function in Neurodegenerative Diseases: A Systematic Review.
Journal: International journal of molecular sciences
In common: structural MRI / diffusion, clinical / translational, other condition, 4 references
[7] doi:10.1002/hbm.70553 [code]
Axon Diameter Mapping in the Living Human Brain with Ultra-High-Gradient Diffusion MRI at 500 mT/m Gradient Strength.
Journal: Human brain mapping
In common: MRtrix3, FSL, structural MRI / diffusion, 2 references
[8] doi:10.3389/fneur.2026.1879894
Perivascular diffusion and white matter free water improve identification of cognitive impairment in cerebral small vessel disease.
Journal: Frontiers in neurology
In common: structural MRI / diffusion, clinical / translational, 4 references
[9] doi:10.1038/s41597-026-07461-3
Multimodal ultra-high-field MRI, clinical, cognitive, and genetic profiles across the ALS-FTD spectrum.
Journal: Scientific data
In common: structural MRI / diffusion, other condition, 4 references
[10] doi:10.1002/dad2.70333 [code]
Associations of plasma phosphorylated tau217 with cognitive impairment and brain microstructural alterations in Alzheimer's disease.
Journal: Alzheimer's & dementia (Amsterdam, Netherlands)
In common: MRtrix3, FSL, structural MRI / diffusion, 1 reference

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.