From fa776aa05bc430b9e7ccbb560f0fd12a6bad05e3 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Wed, 8 Apr 2026 13:48:32 -0400 Subject: [PATCH 01/21] Refactor second-order ensemble pipeline organization and step naming --- trigeminal_second_order.sh | 874 +++++++++++++++++++++++-------------- 1 file changed, 554 insertions(+), 320 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 6b241da..45e95ad 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -1,413 +1,647 @@ #!/bin/bash +set -euo pipefail + # TRIGEMINAL SYSTEM TRACTOGRAPHY - Samir Akeb (2022-2023) # TRIGEMINAL SYSTEM TRACTOGRAPHY - Arnaud Bore (2023-2024) - -# Input structure +# TRIGEMINAL SYSTEM TRACTOGRAPHY - Nasrin Rafiei (2025-2026) +# +# SECOND-ORDER ENSEMBLE VERSION (organized like first-order) +# +# This version adds ensemble tracking to the second-order tracking stage +# using the same style as first-order: +# step_list=(0.1 0.5 1.0) +# theta_list=(20 30 40) +# +# Organized pipeline: +# 1) pool first-order final spinal / remaining_cp bundles +# 2) prepare second-order seed masks and thalamus ROIs +# 3) run second-order tracking for each (step, theta) combo in ORIG +# 4) merge combo outputs per tracking role in ORIG +# 5) register merged tractograms once to MNI +# 6) prepare second-order MNI ROIs and cut masks +# 7) filter merged second-order tractograms into pathway bundles +# 8) cut filtered bundles with label masks +# 9) reject outliers and save final second-order bundles +# +# INPUT: +# subject folder(s) containing: +# /freesurfer/aparc.DKTatlas+aseg.mgz +# /tractoflow/__fa.nii.gz +# /tractoflow/__fodf.nii.gz +# /tractoflow/__t1_warped.nii.gz +# +# EXPECTED FIRST-ORDER OUTPUTS: +# //mni_space/tracking_first_order/final_merged/final/__spinal.trk +# //mni_space/tracking_first_order/final_merged/final/__remaining_cp.trk # -# [input] -# ├── sub-01 -# │ ├── freesurfer -# │ │ └─── aparc.DKTatlas+aseg.mgz -# │ ├── sub-01__fa.nii.gz -# │ ├── sub-01__fodf.nii.gz -# │ └── sub-01__t1_warped.nii.gz -# │ -# ├── S2 -# . -# . - -usage() { echo "$(basename $0) [-s path/to/subjects] [-m path/to/mni] [-o output_dir] [-g] (if you have a gpu)" 1>&2; exit 1; } - -while getopts "s:m:o:g:" args; do +# USAGE EXAMPLE: +# bash trigeminal_second_order.sh \ +# -s /path/to/data/sub-01 \ +# -m /path/to/ROIs_clean \ +# -o /path/to/first_order_output_root \ +# -f 0.15 \ +# -t 10 \ +# -g true +# +# OPTIONAL: +# -p step_size if used with -e, run single combo only +# -e theta_deg if used with -p, run single combo only +# +# DEFAULT ensemble if -p/-e are not both given: +# step = 0.1 0.5 1.0 +# theta = 20 30 40 + +usage() { + cat <&2 +Usage: + $(basename "$0") -s -m -o + [-f fa_threshold] [-t threads] [-g true|false] + [-p step_size] [-e theta_deg] + [--npv_spinal_long N] [--npv_spinal_short N] [--npv_thalamus N] + +Tracking params: + -p step_size If set with -e, runs SINGLE combo (no ensemble) + -e theta_deg If set with -p, runs SINGLE combo (no ensemble) + If -p/-e not provided, ensemble is used: + step = 0.1 0.5 1.0 + theta = 20 30 40 + +Second-order seed budgets (TOTAL per role; auto-split across combos): + --npv_spinal_long N default: 1000 + --npv_spinal_short N default: 100 + --npv_thalamus N default: 500 + +Notes: + - First-order final expected at: /*/mni_space/tracking_first_order/final_merged/final/ + - This script expects first-order transfo in: + //orig_space/transfo/2orig_0GenericAffine.mat + //orig_space/transfo/2orig_1Warp.nii.gz + //orig_space/transfo/2orig_1InverseWarp.nii.gz +EOF + exit 1 +} + +# ------------------------- +# Parse short options first +# ------------------------- +s="" +m="" +o="" +f="" +t="" +g="" +p="" +e="" + +while getopts ":s:m:o:f:t:g:p:e:" args; do case "${args}" in - s) s=${OPTARG};; - m) m=${OPTARG};; - o) o=${OPTARG};; - g) g=${OPTARG};; - *) usage;; + s) s=${OPTARG} ;; + m) m=${OPTARG} ;; + o) o=${OPTARG} ;; + f) f=${OPTARG} ;; + t) t=${OPTARG} ;; + g) g=${OPTARG} ;; + p) p=${OPTARG} ;; + e) e=${OPTARG} ;; + *) usage ;; esac done shift $((OPTIND-1)) -if [ -z "${s}" ] || [ -z "${m}" ] || [ -z "${o}" ]; then +# ------------------------- +# Parse optional long args +# ------------------------- +npv_spinal_long_total=1000 +npv_spinal_short_total=100 +npv_thalamus_total=500 + +while [[ $# -gt 0 ]]; do + case "$1" in + --npv_spinal_long) + npv_spinal_long_total="$2" + shift 2 + ;; + --npv_spinal_short) + npv_spinal_short_total="$2" + shift 2 + ;; + --npv_thalamus) + npv_thalamus_total="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" 1>&2 + usage + ;; + esac +done + +if [[ -z "${s}" || -z "${m}" || -z "${o}" ]]; then usage fi +subject_dir="${s}" +mni_dir="${m}" +out_dir="${o}" +fa_threshold="${f:-0.15}" +nb_threads="${t:-1}" + gpu="" -if [ -n "${g}" ]; then +if [[ -n "${g}" ]]; then gpu="--use_gpu" fi -subject_dir=${s} -mni_dir=${m} -out_dir=${o} +# ------------------------- +# Ensemble grid +# ------------------------- +if [[ -n "${p}" && -n "${e}" ]]; then + step_list=("${p}") + theta_list=("${e}") +else + step_list=(0.1 0.5 1.0) + theta_list=(20 30 40) +fi + +n_combos=$(( ${#step_list[@]} * ${#theta_list[@]} )) + +# Split total budgets across combos (ceiling division) +npv_spinal_long_per_combo=$(( (npv_spinal_long_total + n_combos - 1) / n_combos )) +npv_spinal_short_per_combo=$(( (npv_spinal_short_total + n_combos - 1) / n_combos )) +npv_thalamus_per_combo=$(( (npv_thalamus_total + n_combos - 1) / n_combos )) + +echo "Folder subjects: ${subject_dir}" +echo "Folder MNI: ${mni_dir}" +echo "Output folder: ${out_dir}" +echo "FA threshold: ${fa_threshold}" +echo "GPU: ${gpu}" +echo "Threads: ${nb_threads}" +echo "Tracking grid: steps=${step_list[*]} thetas=${theta_list[*]}" +echo "Second-order budgets per combo:" +echo " spinal long: ${npv_spinal_long_per_combo} (from total ${npv_spinal_long_total})" +echo " spinal short: ${npv_spinal_short_per_combo} (from total ${npv_spinal_short_total})" +echo " thalamus: ${npv_thalamus_per_combo} (from total ${npv_thalamus_total})" + +export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS="${nb_threads}" + +# Detect if -s is one subject folder or a parent folder of many subjects +if [[ -d "${subject_dir}/tractoflow" ]]; then + subject_list=("${subject_dir}") +else + shopt -s nullglob + subject_list=("${subject_dir}"/*/) + shopt -u nullglob +fi + +if [[ ${#subject_list[@]} -eq 0 ]]; then + echo "ERROR: No subject folders found in ${subject_dir}" + exit 1 +fi + +# ============================================================ +# 0) Pool first-order final bundles used by second-order +# ============================================================ +mkdir -p "${out_dir}/mni_space/tracking_first_order/final" -fa_threshold=0.20 +for nside in left right; do + spinal_inputs=() + remaining_inputs=() -npv_from_spinal_track_long=1000 -npv_from_spinal_track_short=100 -npv_from_thalamus_track=500 + for nsub_path in "${subject_list[@]}"; do + nsub=$(basename "${nsub_path}") + spinal_file="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final/${nsub}_${nside}_spinal.trk" + remaining_file="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final/${nsub}_${nside}_remaining_cp.trk" -echo "Folder subjects: " ${subject_dir} -echo "Folder MNI: " ${mni_dir} -echo "Output folder: " ${out_dir} -echo "GPU: " ${gpu} + [[ -f "${spinal_file}" ]] && spinal_inputs+=("${spinal_file}") + [[ -f "${remaining_file}" ]] && remaining_inputs+=("${remaining_file}") + done + + if [[ ${#spinal_inputs[@]} -eq 0 ]]; then + echo "ERROR: No first-order spinal bundles found for side ${nside}." + exit 1 + fi -mkdir -p ${out_dir}/mni_space/tracking_first_order/final/ + if [[ ${#remaining_inputs[@]} -eq 0 ]]; then + echo "ERROR: No first-order remaining_cp bundles found for side ${nside}." + exit 1 + fi -for nside in left right -do - scil_tractogram_math union ${out_dir}/*/mni_space/tracking_first_order/final/*_${nside}_spinal.trk \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk -f + scil_tractogram_math union "${spinal_inputs[@]}" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk" -f - # Building seeding mask by converting spinal bundle TRK to NII scil_tractogram_compute_density_map \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ --binary -f - scil_tractogram_math union ${out_dir}/*/mni_space/tracking_first_order/final/*_${nside}_remaining_cp.trk \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk -f + scil_tractogram_math union "${remaining_inputs[@]}" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk" -f - # Building mask by converting remaining_cp bundle TRK to NII scil_tractogram_compute_density_map \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ --binary -f done -for nsub in ${subject_dir}/*/ -do - nsub=`basename "$nsub"` +# ============================================================ +# 1) Process each subject +# ============================================================ +for nsub_path in "${subject_list[@]}"; do + nsub=$(basename "${nsub_path}") + + mkdir -p "${out_dir}/${nsub}/orig_space/rois" + mkdir -p "${out_dir}/${nsub}/orig_space/tracking_second_order"/{trials,merged,final} + mkdir -p "${out_dir}/${nsub}/mni_space/rois" + mkdir -p "${out_dir}/${nsub}/mni_space/tracking_second_order"/{orig,filtered,segmented,final,cut} - mkdir -p ${out_dir}/${nsub}/orig_space/{rois,tracking_second_order,transfo} - mkdir -p ${out_dir}/${nsub}/orig_space/tracking_second_order/orig - mkdir -p ${out_dir}/${nsub}/mni_space/{rois,tracking_second_order} - mkdir -p ${out_dir}/${nsub}/mni_space/tracking_second_order/{orig,filtered,segmented,final,cut} + orig_rois_dir="${out_dir}/${nsub}/orig_space/rois" + mni_rois_dir="${out_dir}/${nsub}/mni_space/rois" + orig_tracking_dir="${out_dir}/${nsub}/orig_space/tracking_second_order" + mni_tracking_dir_second_order="${out_dir}/${nsub}/mni_space/tracking_second_order" + first_order_final_dir="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final" - orig_rois_dir=${out_dir}/${nsub}/orig_space/rois - mni_rois_dir=${out_dir}/${nsub}/mni_space/rois - orig_tracking_dir=${out_dir}/${nsub}/orig_space/tracking_second_order - mni_tracking_dir_first_order=${out_dir}/${nsub}/mni_space/tracking_first_order - mni_tracking_dir_second_order=${out_dir}/${nsub}/mni_space/tracking_second_order + orig_trials_root="${orig_tracking_dir}/trials" + orig_merged_root="${orig_tracking_dir}/merged" echo "" - echo "|------------- PROCESSING SECOND-ORDER FIBERS TRACTOGRAPHY FOR TRIGEMINAL SYSTEM -------------|" - echo "|------------- FOR DATASET ${nsub} -------------|" + echo "|------------- PROCESSING SECOND-ORDER ENSEMBLE FOR ${nsub} -------------|" echo "" - echo "|------------- 1) Generate local tractography with spinal bundle -------------|" - echo "|------------- 1.2) Seeding Mask + Registration in orig space -------------|" - for nside in left right - do - cp ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz + # ------------------------- + # Safety checks + # ------------------------- + for nside in left right; do + [[ -f "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" ]] || { + echo "ERROR: Missing first-order file ${first_order_final_dir}/${nsub}_${nside}_spinal.trk" + exit 1 + } + [[ -f "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" ]] || { + echo "ERROR: Missing first-order file ${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" + exit 1 + } + done + + [[ -f "${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz" ]] || { + echo "ERROR: Missing ${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz" + exit 1 + } + + [[ -f "${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz" ]] || { + echo "ERROR: Missing ${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz" + exit 1 + } + + [[ -f "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" ]] || { + echo "ERROR: Missing ${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" + echo "Check that -f matches the first-order FA threshold." + exit 1 + } + + [[ -f "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" ]] || { + echo "ERROR: Missing affine transform" + exit 1 + } + + [[ -f "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" ]] || { + echo "ERROR: Missing forward warp" + exit 1 + } + + [[ -f "${out_dir}/${nsub}/orig_space/transfo/2orig_1InverseWarp.nii.gz" ]] || { + echo "ERROR: Missing inverse warp" + exit 1 + } + + # ------------------------- + # 1) Prepare second-order seed masks and thalamus ROIs + # ------------------------- + echo "|------------- 1) Prepare second-order seed masks and thalamus ROIs -------------|" + + echo "|------------- 1.1) Copy pooled spinal seed masks and transform them to orig space -------------|" + for nside in left right; do + cp "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" - # Register density into orig space antsApplyTransforms \ -d 3 \ - -i ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz \ - -r ${subject_dir}/${nsub}/tractoflow/${nsub}__t1_warped.nii.gz \ - -t ${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz \ - -t ${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat \ - -o ${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz + -i "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + -r "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ + -t "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ + -t "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ + -o "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" done - echo "|------------- 1.3) Extract thalamus -------------|" - + echo "|------------- 1.2) Extract thalamus masks from the anatomical segmentation -------------|" Right_Thalamus=(49) Left_Thalamus=(10) - scil_labels_combine ${orig_rois_dir}/${nsub}_right_thalamus_orig.nii.gz \ - --volume_ids ${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz ${Right_Thalamus[*]} --merge_groups -f - - scil_labels_combine ${mni_rois_dir}/${nsub}_right_thalamus_mni.nii.gz \ - --volume_ids ${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz ${Right_Thalamus[*]} --merge_groups -f - - scil_labels_combine ${orig_rois_dir}/${nsub}_left_thalamus_orig.nii.gz \ - --volume_ids ${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz ${Left_Thalamus[*]} --merge_groups -f - - scil_labels_combine ${mni_rois_dir}/${nsub}_left_thalamus_mni.nii.gz \ - --volume_ids ${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz ${Left_Thalamus[*]} --merge_groups -f - - echo "|------------- 1.4) Tracking -------------|" - for nside in left right - do - # Tracking from Spinal bundle - npv 1000 - echo "|------------- 1.4a) Tracking from Spinal bundle - npv ${npv_from_spinal_track_long} -------------|" - scil_tracking_local \ - ${subject_dir}/${nsub}/tractoflow/${nsub}__fodf.nii.gz \ - ${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz \ - ${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz \ - ${orig_tracking_dir}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk \ - --npv ${npv_from_spinal_track_long} \ - -v -f ${gpu} - - # Tracking from Spinal bundle - npv 100 - echo "|------------- 1.4b) Tracking from Spinal bundle - npv ${npv_from_spinal_track_short} -------------|" - scil_tracking_local \ - ${subject_dir}/${nsub}/tractoflow/${nsub}__fodf.nii.gz \ - ${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz \ - ${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz \ - ${orig_tracking_dir}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk \ - --npv ${npv_from_spinal_track_short} \ - -v -f ${gpu} - - # Tracking from Thalamus - echo "|------------- 1.4c) Tracking from Thalamus - npv ${npv_from_thalamus_track} -------------|" - scil_tracking_local \ - ${subject_dir}/${nsub}/tractoflow/${nsub}__fodf.nii.gz \ - ${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz \ - ${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz\ - ${orig_tracking_dir}/orig/${nsub}_${nside}_from_thalamus_npv500.trk \ - --npv ${npv_from_thalamus_track} \ - -v -f ${gpu} + scil_labels_combine "${orig_rois_dir}/${nsub}_right_thalamus_orig.nii.gz" \ + --volume_ids "${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz" ${Right_Thalamus[*]} \ + --merge_groups -f + + scil_labels_combine "${mni_rois_dir}/${nsub}_right_thalamus_mni.nii.gz" \ + --volume_ids "${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz" ${Right_Thalamus[*]} \ + --merge_groups -f + + scil_labels_combine "${orig_rois_dir}/${nsub}_left_thalamus_orig.nii.gz" \ + --volume_ids "${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz" ${Left_Thalamus[*]} \ + --merge_groups -f + + scil_labels_combine "${mni_rois_dir}/${nsub}_left_thalamus_mni.nii.gz" \ + --volume_ids "${mni_rois_dir}/${nsub}_aparc.DKTatlas+aseg_mni.nii.gz" ${Left_Thalamus[*]} \ + --merge_groups -f + + # ------------------------- + # 2) Run second-order ensemble tracking in orig space + # ------------------------- + echo "|------------- 2) Run second-order ensemble tracking in orig space -------------|" + for step_size in "${step_list[@]}"; do + for theta in "${theta_list[@]}"; do + combo_tag="step_${step_size}_theta_${theta}" + mkdir -p "${orig_trials_root}/${combo_tag}" + + echo "|=== Second-order combo: ${combo_tag} ===|" + + for nside in left right; do + # spinal long + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ + "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1000_${combo_tag}.trk" \ + --npv "${npv_spinal_long_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + + # spinal short + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ + "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv100_${combo_tag}.trk" \ + --npv "${npv_spinal_short_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + + # thalamus + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz" \ + "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ + --npv "${npv_thalamus_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + done + done done - echo "|------------- 1.5) Register Tracking in MNI space -------------|" - for ntracking in from_thalamus_npv500.trk from_spinal_track_npv100.trk from_spinal_track_npv1000.trk - do - for nside in left right - do - scil_tractogram_apply_transform \ - ${orig_tracking_dir}/orig/${nsub}_${nside}_${ntracking} \ - ${mni_dir}/MNI/mni_masked.nii.gz \ - ${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_${ntracking} \ - --in_deformation ${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz \ - --remove_invalid \ - --reverse_operation -f + # ------------------------- + # 3) Merge second-order combo tractograms in orig space + # ------------------------- + echo "|------------- 3) Merge second-order combo tractograms in orig space -------------|" + for nside in left right; do + for role in from_thalamus_npv500 from_spinal_track_npv100 from_spinal_track_npv1000; do + files=() + for step_size in "${step_list[@]}"; do + for theta in "${theta_list[@]}"; do + combo_tag="step_${step_size}_theta_${theta}" + f="${orig_trials_root}/${combo_tag}/${nsub}_${nside}_${role}_${combo_tag}.trk" + [[ -f "${f}" ]] && files+=("${f}") + done + done + + if (( ${#files[@]} )); then + scil_tractogram_math concatenate "${files[@]}" \ + "${orig_merged_root}/${nsub}_${nside}_${role}.trk" -f + else + echo "WARN: no files found for ${nside} ${role}" + fi done done - echo "|------------- 1) Done -------------|" - echo "" - echo "|------------- 2) Generate ROIs -------------|" - echo "|------------- 2.1) Registration VPM -------------|" - - for nside in left right - do - cp ${mni_dir}/MNI/Distal/${nside}/VPM.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz - for nroi in ${mni_dir}/MNI/from_${nside}/*; - do - ROI_basename=$(basename $nroi) - cp $nroi ${mni_rois_dir}/${nsub}_second_order_${ROI_basename/nii/_mni.nii} + # ------------------------- + # 4) Register merged second-order tractograms to MNI space + # ------------------------- + echo "|------------- 4) Register merged second-order tractograms to MNI space -------------|" + for nside in left right; do + for role in from_thalamus_npv500 from_spinal_track_npv100 from_spinal_track_npv1000; do + in_trk="${orig_merged_root}/${nsub}_${nside}_${role}.trk" + out_trk="${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_${role}.trk" + + if [[ -f "${in_trk}" ]]; then + scil_tractogram_apply_transform \ + "${in_trk}" \ + "${mni_dir}/MNI/mni_masked.nii.gz" \ + "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ + "${out_trk}" \ + --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ + --remove_invalid \ + --reverse_operation -f + else + echo "WARN: merged orig tractogram not found for ${nside} ${role}" + fi + done + done + + # ------------------------- + # 5) Prepare second-order MNI ROIs and cut masks + # ------------------------- + echo "|------------- 5) Prepare second-order MNI ROIs and cut masks -------------|" + echo "|------------- 5.1) Copy VPM and pathway-specific MNI ROIs -------------|" + + for nside in left right; do + cp "${mni_dir}/MNI/Distal/${nside}/VPM.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" + + for nroi in "${mni_dir}/MNI/from_${nside}"/*.nii.gz; do + [[ -f "${nroi}" ]] || continue + ROI_basename=$(basename "${nroi}") + cp "${nroi}" "${mni_rois_dir}/${nsub}_second_order_${ROI_basename/nii/_mni.nii}" done done - echo "|------------- 2.2) Generate masks -------------|" - for nside in left right - do - if [ "$nside" == "left" ]; then - contra_nside="right"; - else - contra_nside="left"; - fi - - # Generate Cutting masks for DTTT (ipsilateral) - ## For dPSN : Remaining_CP to VPM - scil_volume_math union ${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz \ + echo "|------------- 5.2) Build cut masks for second-order pathway extraction -------------|" + for nside in left right; do + if [[ "${nside}" == "left" ]]; then + contra_nside="right" + else + contra_nside="left" + fi + + scil_volume_math union \ + "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f - scil_labels_from_mask ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz \ + scil_labels_from_mask \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ -f - ## For CS : Spinal bundle to VPM - scil_volume_math union ${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz \ + scil_volume_math union \ + "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz" \ --data_type uint8 -f - scil_labels_from_mask ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz \ + scil_labels_from_mask \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ -f - # Generate Cutting masks for DTTT (controlateral) - ## For CS : Spinal bundle to Thalamus - scil_volume_math union ${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz \ + scil_volume_math union \ + "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz" \ --data_type uint8 -f - scil_labels_from_mask ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz \ + scil_labels_from_mask \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ -f - ## Generate Cutting masks for VTTT (controlateral) - ## For OS and IS : Spinal bundle to Thalamus - scil_volume_math union ${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz \ + scil_volume_math union \ + "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz" \ --data_type uint8 -f - scil_labels_from_mask ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz \ + scil_labels_from_mask \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ -f - #For vPSN : Remaining_CP to VPM - scil_volume_math union ${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz \ - ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz \ + scil_volume_math union \ + "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" \ + "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f - scil_labels_from_mask ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz \ - ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz \ + scil_labels_from_mask \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ -f done - echo "|------------- 2) Done -------------|" - echo "" - echo "|------------- 3) Generate Second-order bundles for trigeminal system -------------|" - for nside in left right - do - if [ "$nside" == "left" ]; then - contra_nside="right"; - else - contra_nside="left"; - fi - - echo "|------------- 3.1) From ${nside} - VTTT (only controlateral) - OS/IS and vPSN -------------|" - # OS and IS + # ------------------------- + # 6) Filter merged second-order tractograms into pathway bundles + # ------------------------- + echo "|------------- 6) Filter merged second-order tractograms into pathway bundles -------------|" + for nside in left right; do + if [[ "${nside}" == "left" ]]; then + contra_nside="right" + else + contra_nside="left" + fi + + echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" + scil_tractogram_filter_by_roi \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk \ - --drawn_roi ${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_Pons_Controlat.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_CaudalMedulla_Controlat.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Pons_Ipsilat.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/cs_plaque.nii.gz 'any' 'exclude' -f - - ## vPSN - ## VPM + "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk" \ + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ + --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_Pons_Controlat.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_CaudalMedulla_Controlat.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Pons_Ipsilat.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/cs_plaque.nii.gz" 'any' 'exclude' -f + scil_tractogram_filter_by_roi \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk \ - --drawn_roi ${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz 'either_end' 'include' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_CaudalMedulla_Controlat.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz 'any' 'include'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_1.bdo 'any' 'exclude'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_2.bdo 'any' 'exclude'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_3.bdo 'any' 'exclude'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_4.bdo 'any' 'exclude'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_5.bdo 'any' 'exclude'\ - --bdo ${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo 'any' 'exclude' -f - - - - echo "|------------- 3.2) ${nside} - DTTT (controlateral) - CS -------------|" + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ + --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_CaudalMedulla_Controlat.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz" 'any' 'include' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_1.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_2.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_3.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_4.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_5.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo" 'any' 'exclude' -f + + echo "|------------- 6.2) ${nside} - DTTT (contralateral) - CS -------------|" scil_tractogram_filter_by_roi \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv500.trk \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${contra_nside}_DTTT_Controlat_CS.trk \ - --drawn_roi ${mni_rois_dir}/${nsub}_${contra_nside}_spinal_density_second_order_seed_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_thalamus_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${contra_nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_CaudalMedulla_Ipsilat.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_Medulla_Controlat.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_EXC_Midbrain_Ipsilat.nii.gz 'any' 'exclude' -f - - echo "|------------- 3.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" - ## CS - ## VPM/Thalamus + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv500.trk" \ + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${contra_nside}_DTTT_Controlat_CS.trk" \ + --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_spinal_density_second_order_seed_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_thalamus_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_CaudalMedulla_Ipsilat.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_Medulla_Controlat.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_EXC_Midbrain_Ipsilat.nii.gz" 'any' 'exclude' -f + + echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" scil_tractogram_filter_by_roi \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz 'either_end' 'include' \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz 'any' 'include' \ - --drawn_roi ${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz 'any' 'exclude' \ - --drawn_roi ${mni_dir}/MNI/midsagittal_plane.nii.gz 'any' 'exclude' -f - - ## dPSN - ## VPM/Thalamus + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk" \ + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/midsagittal_plane.nii.gz" 'any' 'exclude' -f + scil_tractogram_filter_by_roi \ - ${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk \ - --drawn_roi ${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz 'any' 'include' \ - --drawn_roi ${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz 'either_end' 'include' -f + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ + --drawn_roi "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' -f done - echo "|------------- 3) Done -------------|" - echo "" - echo "|------------- 4) Cutting the Second-order bundles -------------|" - for nside in left right - do - if [ "$nside" == "left" ]; then - contra_nside="right"; - else - contra_nside="left"; - fi - echo "|------------- 4.1) ${nside} - VTTT (only controlateral) - vPSN and OS/IS -------------|" - #OS and IS - STEP 1 + # ------------------------- + # 7) Cut filtered second-order bundles with label masks + # ------------------------- + echo "|------------- 7) Cut filtered second-order bundles with label masks -------------|" + for nside in left right; do scil_tractogram_cut_streamlines \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk \ - --labels ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk \ - -f + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" -f - #vPSN scil_tractogram_cut_streamlines \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk \ - --labels ${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk \ - -f + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" -f - echo "|------------- 4.2) ${nside} - DTTT (controlateral) - CS -------------|" - #CS scil_tractogram_cut_streamlines \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk \ - --labels ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk \ - -f - - echo "|------------- 4.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" -f - #CS scil_tractogram_cut_streamlines \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk \ - --labels ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk \ - -f + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" -f - #dPSN scil_tractogram_cut_streamlines \ - ${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk \ - --labels ${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk \ - -f + "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" -f done - echo "|------------- 4) Done -------------|" - echo "" - echo "|------------- 5) Cleaning the Second-order bundles -------------|" - for nside in left right - do - #CS + # ------------------------- + # 8) Reject outliers and save final second-order bundles + # ------------------------- + echo "|------------- 8) Reject outliers and save final second-order bundles -------------|" + for nside in left right; do scil_bundle_reject_outliers \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk \ - ${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk \ - --alpha 0.30 \ - -f + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ + "${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ + --alpha 0.30 -f - for nbundle in DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN - do + for nbundle in DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do scil_bundle_reject_outliers \ - ${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_${nbundle}.trk \ - ${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk \ - --alpha 0.50 \ - -f + "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_${nbundle}.trk" \ + "${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" \ + --alpha 0.50 -f done done - echo "|------------- 5) Done -------------|" - echo "" - echo "|------------- SECOND-ORDER FIBERS TRACTOGRAPHY FOR ${nsub} IS COMPLETED -------------|" - echo "" + echo "|------------- SECOND-ORDER ENSEMBLE FOR ${nsub} IS COMPLETED -------------|" echo "" -done +done \ No newline at end of file From e957718c576e6a4cdb855e7a0b14d17de5195a58 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Wed, 8 Apr 2026 14:46:15 -0400 Subject: [PATCH 02/21] Refactor second-order ensemble pipeline organization and step naming --- trigeminal_second_order.sh | 111 ++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 45e95ad..4558f3e 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -5,51 +5,20 @@ set -euo pipefail # TRIGEMINAL SYSTEM TRACTOGRAPHY - Arnaud Bore (2023-2024) # TRIGEMINAL SYSTEM TRACTOGRAPHY - Nasrin Rafiei (2025-2026) # -# SECOND-ORDER ENSEMBLE VERSION (organized like first-order) -# -# This version adds ensemble tracking to the second-order tracking stage -# using the same style as first-order: -# step_list=(0.1 0.5 1.0) -# theta_list=(20 30 40) +# SECOND-ORDER ENSEMBLE VERSION +# Compatible with the newer original second-order ROI/BDO logic +# while keeping the organized ensemble structure. # # Organized pipeline: -# 1) pool first-order final spinal / remaining_cp bundles -# 2) prepare second-order seed masks and thalamus ROIs -# 3) run second-order tracking for each (step, theta) combo in ORIG -# 4) merge combo outputs per tracking role in ORIG -# 5) register merged tractograms once to MNI -# 6) prepare second-order MNI ROIs and cut masks -# 7) filter merged second-order tractograms into pathway bundles -# 8) cut filtered bundles with label masks -# 9) reject outliers and save final second-order bundles -# -# INPUT: -# subject folder(s) containing: -# /freesurfer/aparc.DKTatlas+aseg.mgz -# /tractoflow/__fa.nii.gz -# /tractoflow/__fodf.nii.gz -# /tractoflow/__t1_warped.nii.gz -# -# EXPECTED FIRST-ORDER OUTPUTS: -# //mni_space/tracking_first_order/final_merged/final/__spinal.trk -# //mni_space/tracking_first_order/final_merged/final/__remaining_cp.trk -# -# USAGE EXAMPLE: -# bash trigeminal_second_order.sh \ -# -s /path/to/data/sub-01 \ -# -m /path/to/ROIs_clean \ -# -o /path/to/first_order_output_root \ -# -f 0.15 \ -# -t 10 \ -# -g true -# -# OPTIONAL: -# -p step_size if used with -e, run single combo only -# -e theta_deg if used with -p, run single combo only -# -# DEFAULT ensemble if -p/-e are not both given: -# step = 0.1 0.5 1.0 -# theta = 20 30 40 +# 0) pool first-order final spinal / remaining_cp bundles +# 1) prepare second-order seed masks and thalamus ROIs +# 2) run second-order tracking for each (step, theta) combo in ORIG +# 3) merge combo outputs per tracking role in ORIG +# 4) register merged tractograms once to MNI +# 5) prepare second-order MNI ROIs and cut masks +# 6) filter merged second-order tractograms into pathway bundles +# 7) cut filtered bundles with label masks +# 8) reject outliers and save final second-order bundles usage() { cat <&2 @@ -70,13 +39,6 @@ Second-order seed budgets (TOTAL per role; auto-split across combos): --npv_spinal_long N default: 1000 --npv_spinal_short N default: 100 --npv_thalamus N default: 500 - -Notes: - - First-order final expected at: /*/mni_space/tracking_first_order/final_merged/final/ - - This script expects first-order transfo in: - //orig_space/transfo/2orig_0GenericAffine.mat - //orig_space/transfo/2orig_1Warp.nii.gz - //orig_space/transfo/2orig_1InverseWarp.nii.gz EOF exit 1 } @@ -362,7 +324,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|=== Second-order combo: ${combo_tag} ===|" for nside in left right; do - # spinal long + # Tracking from Spinal bundle - long scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ @@ -373,7 +335,7 @@ for nsub_path in "${subject_list[@]}"; do --theta "${theta}" \ ${gpu} -v -f - # spinal short + # Tracking from Spinal bundle - short scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ @@ -384,7 +346,7 @@ for nsub_path in "${subject_list[@]}"; do --theta "${theta}" \ ${gpu} -v -f - # thalamus + # Tracking from Thalamus scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz" \ @@ -471,6 +433,7 @@ for nsub_path in "${subject_list[@]}"; do contra_nside="left" fi + # DTTT ipsilateral dPSN : remaining_cp to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ @@ -481,6 +444,7 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ -f + # DTTT ipsilateral CS : spinal to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -491,6 +455,7 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ -f + # DTTT contralateral CS : spinal to thalamus scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -501,6 +466,7 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ -f + # VTTT contralateral OS and IS : spinal to thalamus scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -511,6 +477,7 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ -f + # VTTT contralateral vPSN : remaining_cp to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" \ "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ @@ -535,6 +502,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" + # OS and IS scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ @@ -547,8 +515,13 @@ for nsub_path in "${subject_list[@]}"; do --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_CaudalMedulla_Controlat.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz" 'any' 'include' \ --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Pons_Ipsilat.nii.gz" 'any' 'exclude' \ - --drawn_roi "${mni_dir}/MNI/cs_plaque.nii.gz" 'any' 'exclude' -f + --drawn_roi "${mni_dir}/MNI/cs_plaque.nii.gz" 'any' 'exclude' \ + --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz" 'any' 'include' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_1.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' \ + -f + # vPSN scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ @@ -564,7 +537,8 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_3.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_4.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_5.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo" 'any' 'exclude' -f + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo" 'any' 'exclude' \ + -f echo "|------------- 6.2) ${nside} - DTTT (contralateral) - CS -------------|" scil_tractogram_filter_by_roi \ @@ -575,22 +549,43 @@ for nsub_path in "${subject_list[@]}"; do --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_CaudalMedulla_Ipsilat.nii.gz" 'any' 'include' \ --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_INC_Medulla_Controlat.nii.gz" 'any' 'include' \ - --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_EXC_Midbrain_Ipsilat.nii.gz" 'any' 'exclude' -f + --drawn_roi "${mni_dir}/MNI/from_${contra_nside}/DTTT_Controlat_EXC_Midbrain_Ipsilat.nii.gz" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_1.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_2.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_3.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_4.bdo" 'any' 'exclude' \ + -f echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" + + # CS scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_EXC_Ventral_Brainstem.nii.gz" 'any' 'exclude' \ - --drawn_roi "${mni_dir}/MNI/midsagittal_plane.nii.gz" 'any' 'exclude' -f + --drawn_roi "${mni_dir}/MNI/midsagittal_plane.nii.gz" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_1.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_2.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' \ + -f + # dPSN scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ - --drawn_roi "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' -f + --drawn_roi "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo" 'any' 'exclude' \ + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo" 'any' 'exclude' \ + -f done # ------------------------- From 5d5c0b07fc6a0f9248207aac047dbcc68e174089 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Thu, 9 Apr 2026 12:59:56 -0400 Subject: [PATCH 03/21] Add missing new_ROIs folder from upstream --- ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_1.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_2.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_3.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_4.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_1.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_2.bdo | 9 +++++++++ ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_3.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_1.bdo | 9 +++++++++ .../MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_2.bdo | 9 +++++++++ 17 files changed, 153 insertions(+) create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_1.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_2.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_3.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_4.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_1.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_2.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_3.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_1.bdo create mode 100644 ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_2.bdo diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_1.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_1.bdo new file mode 100644 index 0000000..d5648c9 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_2.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_2.bdo new file mode 100644 index 0000000..c4c3900 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_3.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_3.bdo new file mode 100644 index 0000000..5d4a41c --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_4.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_4.bdo new file mode 100644 index 0000000..0120a3c --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Controlat_4.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_1.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_1.bdo new file mode 100644 index 0000000..efdc7ef --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_2.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_2.bdo new file mode 100644 index 0000000..c27979e --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_3.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_3.bdo new file mode 100644 index 0000000..69d1b98 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_CS_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo new file mode 100644 index 0000000..fabfd30 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo new file mode 100644 index 0000000..67f00ef --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo new file mode 100644 index 0000000..5a261b7 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo new file mode 100644 index 0000000..53cbc7c --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo new file mode 100644 index 0000000..e9be78c --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo new file mode 100644 index 0000000..4482d68 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo new file mode 100644 index 0000000..02faeed --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo new file mode 100644 index 0000000..61ea6d0 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_1.bdo b/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_1.bdo new file mode 100644 index 0000000..bbc7149 --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_2.bdo b/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_2.bdo new file mode 100644 index 0000000..6becd1f --- /dev/null +++ b/ROIs_clean/MNI/from_left/new_ROIs/VTTT_Controlat_OSandIS_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + From 04c15c8c2e72e4bbec1b87eff40f091e346dc171 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 13 Apr 2026 10:24:32 -0400 Subject: [PATCH 04/21] step 9 was added --- .../from_right/new_ROIs/DTTT_Controlat_1.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Controlat_2.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Controlat_3.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Controlat_4.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Ipsilat_CS_1.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Ipsilat_CS_2.bdo | 9 +++++++ .../from_right/new_ROIs/DTTT_Ipsilat_CS_3.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_1.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_2.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_3.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_4.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_5.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_6.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_7.bdo | 9 +++++++ .../new_ROIs/DTTT_Ipsilat_dPSN_8.bdo | 9 +++++++ .../new_ROIs/VTTT_Controlat_OSandIS_1.bdo | 9 +++++++ .../new_ROIs/VTTT_Controlat_OSandIS_2.bdo | 9 +++++++ trigeminal_second_order.sh | 25 ++++++++++++++++++- 18 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_1.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_2.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_3.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_4.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_1.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_2.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_3.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_1.bdo create mode 100644 ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_2.bdo diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_1.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_1.bdo new file mode 100644 index 0000000..abeb8bd --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_2.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_2.bdo new file mode 100644 index 0000000..cdca61c --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_3.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_3.bdo new file mode 100644 index 0000000..827c260 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_4.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_4.bdo new file mode 100644 index 0000000..480308d --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Controlat_4.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_1.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_1.bdo new file mode 100644 index 0000000..54eb273 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_2.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_2.bdo new file mode 100644 index 0000000..4d63d3a --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_3.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_3.bdo new file mode 100644 index 0000000..36fa8a6 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_CS_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo new file mode 100644 index 0000000..4c4b7a4 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo new file mode 100644 index 0000000..d4f1c5d --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo new file mode 100644 index 0000000..c68c84d --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo new file mode 100644 index 0000000..54dca32 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_4.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo new file mode 100644 index 0000000..ce041af --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo new file mode 100644 index 0000000..01fad24 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo new file mode 100644 index 0000000..636001a --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo new file mode 100644 index 0000000..d69d97d --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_1.bdo b/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_1.bdo new file mode 100644 index 0000000..bbc7149 --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_1.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_2.bdo b/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_2.bdo new file mode 100644 index 0000000..6becd1f --- /dev/null +++ b/ROIs_clean/MNI/from_right/new_ROIs/VTTT_Controlat_OSandIS_2.bdo @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 4558f3e..f71cae1 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -213,7 +213,7 @@ for nsub_path in "${subject_list[@]}"; do mkdir -p "${out_dir}/${nsub}/orig_space/rois" mkdir -p "${out_dir}/${nsub}/orig_space/tracking_second_order"/{trials,merged,final} mkdir -p "${out_dir}/${nsub}/mni_space/rois" - mkdir -p "${out_dir}/${nsub}/mni_space/tracking_second_order"/{orig,filtered,segmented,final,cut} + mkdir -p "${out_dir}/${nsub}/mni_space/tracking_second_order"/{orig,filtered,final,cut} orig_rois_dir="${out_dir}/${nsub}/orig_space/rois" mni_rois_dir="${out_dir}/${nsub}/mni_space/rois" @@ -639,4 +639,27 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- SECOND-ORDER ENSEMBLE FOR ${nsub} IS COMPLETED -------------|" echo "" +done + + +echo "|------------- 9) [BACK-TO-ORIG] Register final MNI bundles to orig space -------------|" + +for nside in left right; do + for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + in_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" + out_trk="${orig_tracking_dir}/final/${nsub}_from_${nside}_${nbundle}_orig.trk" + + if [[ -f "${in_trk}" ]]; then + scil_tractogram_apply_transform \ + "${in_trk}" \ + "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ + "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ + "${out_trk}" \ + --inverse \ + --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1InverseWarp.nii.gz" \ + --remove_invalid -f + else + echo "WARN: Final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." + fi + done done \ No newline at end of file From 6f0bf0436ce8d0a9485013d02adbe5b8644ccd90 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 14 Apr 2026 14:10:56 -0400 Subject: [PATCH 05/21] countinue the code if .trk is empty --- trigeminal_second_order.sh | 141 ++++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 17 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index f71cae1..9775ae5 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -113,6 +113,29 @@ if [[ -n "${g}" ]]; then gpu="--use_gpu" fi + + +trk_is_empty() { + local f="$1" + + if [[ ! -f "${f}" ]]; then + return 0 + fi + + local n_str + n_str=$(scil_tractogram_count_streamlines "${f}" 2>/dev/null | grep -Eo '[0-9]+' | tail -n 1 || true) + + if [[ -z "${n_str}" || "${n_str}" -eq 0 ]]; then + return 0 + else + return 1 + fi +} + + + + + # ------------------------- # Ensemble grid # ------------------------- @@ -354,7 +377,22 @@ for nsub_path in "${subject_list[@]}"; do "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ --npv "${npv_thalamus_per_combo}" \ --step "${step_size}" \ - --theta "${theta}" \ + --theta "${theta}" \trk_is_empty() { + local f="$1" + + if [[ ! -f "${f}" ]]; then + return 0 + fi + + local n_str + n_str=$(scil_tractogram_count_streamlines "${f}" 2>/dev/null | grep -Eo '[0-9]+' | tail -n 1 || true) + + if [[ -z "${n_str}" || "${n_str}" -eq 0 ]]; then + return 0 + else + return 1 + fi +} ${gpu} -v -f done done @@ -588,36 +626,105 @@ for nsub_path in "${subject_list[@]}"; do -f done - # ------------------------- - # 7) Cut filtered second-order bundles with label masks - # ------------------------- - echo "|------------- 7) Cut filtered second-order bundles with label masks -------------|" - for nside in left right; do + + +# ------------------------- +# 7) Cut filtered second-order bundles with label masks +# ------------------------- +echo "|------------- 7) Cut filtered second-order bundles with label masks -------------|" +for nside in left right; do + + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else scil_tractogram_cut_streamlines \ - "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ + "${in_trk}" \ --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" -f + "${out_trk}" -f + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else scil_tractogram_cut_streamlines \ - "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ + "${in_trk}" \ --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" -f + "${out_trk}" -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else scil_tractogram_cut_streamlines \ - "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" \ + "${in_trk}" \ --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" -f + "${out_trk}" -f + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else scil_tractogram_cut_streamlines \ - "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ + "${in_trk}" \ --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" -f + "${out_trk}" -f + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else scil_tractogram_cut_streamlines \ - "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ + "${in_trk}" \ --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" -f - done + "${out_trk}" -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi +done + + + + + + + + + + + # ------------------------- # 8) Reject outliers and save final second-order bundles From 74e02d9c533d57995c7cc109562104860a5299c1 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 14 Apr 2026 14:29:07 -0400 Subject: [PATCH 06/21] countinue the code if .trk is empty --- trigeminal_second_order.sh | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 9775ae5..a019c58 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -377,22 +377,7 @@ for nsub_path in "${subject_list[@]}"; do "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ --npv "${npv_thalamus_per_combo}" \ --step "${step_size}" \ - --theta "${theta}" \trk_is_empty() { - local f="$1" - - if [[ ! -f "${f}" ]]; then - return 0 - fi - - local n_str - n_str=$(scil_tractogram_count_streamlines "${f}" 2>/dev/null | grep -Eo '[0-9]+' | tail -n 1 || true) - - if [[ -z "${n_str}" || "${n_str}" -eq 0 ]]; then - return 0 - else - return 1 - fi -} + --theta "${theta}" \ ${gpu} -v -f done done From a81c1f4e3a585b0e45464798a398230860b5acd9 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Fri, 17 Apr 2026 11:53:51 -0400 Subject: [PATCH 07/21] modify path for mni folder --- trigeminal_second_order.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index a019c58..16863cd 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -754,4 +754,8 @@ for nside in left right; do echo "WARN: Final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." fi done -done \ No newline at end of file +done + + + +#test for second_order_path \ No newline at end of file From 96693906fb6d198973521c27e81e59e06cc276ce Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Fri, 17 Apr 2026 13:55:27 -0400 Subject: [PATCH 08/21] no pooled all --- trigeminal_second_order.sh | 318 ++++++++++++++++--------------------- 1 file changed, 134 insertions(+), 184 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 16863cd..b5c3503 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -6,11 +6,17 @@ set -euo pipefail # TRIGEMINAL SYSTEM TRACTOGRAPHY - Nasrin Rafiei (2025-2026) # # SECOND-ORDER ENSEMBLE VERSION -# Compatible with the newer original second-order ROI/BDO logic -# while keeping the organized ensemble structure. +# This script performs tractography of the second order trigeminal system based on the output of +# the first-order tractography pipeline (trigeminal_first_order.sh). +# You should be running the exact command you ran for the first order (same input/output). +# +# SUBJECT-BY-SUBJECT VERSION: +# - no pooled all_left/all_right files +# - each subject uses its own first-order spinal / remaining_cp bundles +# - nothing is created outside the subject folder # # Organized pipeline: -# 0) pool first-order final spinal / remaining_cp bundles +# 0) prepare subject-specific first-order density maps for second-order # 1) prepare second-order seed masks and thalamus ROIs # 2) run second-order tracking for each (step, theta) combo in ORIG # 3) merge combo outputs per tracking role in ORIG @@ -19,6 +25,7 @@ set -euo pipefail # 6) filter merged second-order tractograms into pathway bundles # 7) cut filtered bundles with label masks # 8) reject outliers and save final second-order bundles +# 9) bring final MNI bundles back to ORIG usage() { cat <&2 @@ -109,12 +116,10 @@ fa_threshold="${f:-0.15}" nb_threads="${t:-1}" gpu="" -if [[ -n "${g}" ]]; then +if [[ -n "${g}" && "${g}" == "true" ]]; then gpu="--use_gpu" fi - - trk_is_empty() { local f="$1" @@ -132,10 +137,6 @@ trk_is_empty() { fi } - - - - # ------------------------- # Ensemble grid # ------------------------- @@ -183,52 +184,7 @@ if [[ ${#subject_list[@]} -eq 0 ]]; then fi # ============================================================ -# 0) Pool first-order final bundles used by second-order -# ============================================================ -mkdir -p "${out_dir}/mni_space/tracking_first_order/final" - -for nside in left right; do - spinal_inputs=() - remaining_inputs=() - - for nsub_path in "${subject_list[@]}"; do - nsub=$(basename "${nsub_path}") - spinal_file="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final/${nsub}_${nside}_spinal.trk" - remaining_file="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final/${nsub}_${nside}_remaining_cp.trk" - - [[ -f "${spinal_file}" ]] && spinal_inputs+=("${spinal_file}") - [[ -f "${remaining_file}" ]] && remaining_inputs+=("${remaining_file}") - done - - if [[ ${#spinal_inputs[@]} -eq 0 ]]; then - echo "ERROR: No first-order spinal bundles found for side ${nside}." - exit 1 - fi - - if [[ ${#remaining_inputs[@]} -eq 0 ]]; then - echo "ERROR: No first-order remaining_cp bundles found for side ${nside}." - exit 1 - fi - - scil_tractogram_math union "${spinal_inputs[@]}" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk" -f - - scil_tractogram_compute_density_map \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal.trk" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ - --binary -f - - scil_tractogram_math union "${remaining_inputs[@]}" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk" -f - - scil_tractogram_compute_density_map \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp.trk" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ - --binary -f -done - -# ============================================================ -# 1) Process each subject +# Process each subject # ============================================================ for nsub_path in "${subject_list[@]}"; do nsub=$(basename "${nsub_path}") @@ -237,12 +193,14 @@ for nsub_path in "${subject_list[@]}"; do mkdir -p "${out_dir}/${nsub}/orig_space/tracking_second_order"/{trials,merged,final} mkdir -p "${out_dir}/${nsub}/mni_space/rois" mkdir -p "${out_dir}/${nsub}/mni_space/tracking_second_order"/{orig,filtered,final,cut} + mkdir -p "${out_dir}/${nsub}/mni_space/tracking_first_order/final_subject_second_order" orig_rois_dir="${out_dir}/${nsub}/orig_space/rois" mni_rois_dir="${out_dir}/${nsub}/mni_space/rois" orig_tracking_dir="${out_dir}/${nsub}/orig_space/tracking_second_order" mni_tracking_dir_second_order="${out_dir}/${nsub}/mni_space/tracking_second_order" first_order_final_dir="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final" + subject_first_order_dir="${out_dir}/${nsub}/mni_space/tracking_first_order/final_subject_second_order" orig_trials_root="${orig_tracking_dir}/trials" orig_merged_root="${orig_tracking_dir}/merged" @@ -296,19 +254,35 @@ for nsub_path in "${subject_list[@]}"; do exit 1 } + # ============================================================ + # 0) Prepare subject-specific first-order density maps + # ============================================================ + echo "|------------- 0) Prepare subject-specific first-order density maps -------------|" + for nside in left right; do + scil_tractogram_compute_density_map \ + "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" \ + "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + --binary -f + + scil_tractogram_compute_density_map \ + "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" \ + "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ + --binary -f + done + # ------------------------- # 1) Prepare second-order seed masks and thalamus ROIs # ------------------------- echo "|------------- 1) Prepare second-order seed masks and thalamus ROIs -------------|" - echo "|------------- 1.1) Copy pooled spinal seed masks and transform them to orig space -------------|" + echo "|------------- 1.1) Copy subject spinal seed masks and transform them to orig space -------------|" for nside in left right; do - cp "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + cp "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" antsApplyTransforms \ -d 3 \ - -i "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + -i "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ -r "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ -t "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ -t "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ @@ -347,7 +321,6 @@ for nsub_path in "${subject_list[@]}"; do echo "|=== Second-order combo: ${combo_tag} ===|" for nside in left right; do - # Tracking from Spinal bundle - long scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ @@ -358,7 +331,6 @@ for nsub_path in "${subject_list[@]}"; do --theta "${theta}" \ ${gpu} -v -f - # Tracking from Spinal bundle - short scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ @@ -369,7 +341,6 @@ for nsub_path in "${subject_list[@]}"; do --theta "${theta}" \ ${gpu} -v -f - # Tracking from Thalamus scil_tracking_local \ "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz" \ @@ -456,10 +427,9 @@ for nsub_path in "${subject_list[@]}"; do contra_nside="left" fi - # DTTT ipsilateral dPSN : remaining_cp to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ + "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f scil_labels_from_mask \ @@ -467,7 +437,6 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ -f - # DTTT ipsilateral CS : spinal to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -478,7 +447,6 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ -f - # DTTT contralateral CS : spinal to thalamus scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -489,7 +457,6 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ -f - # VTTT contralateral OS and IS : spinal to thalamus scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ @@ -500,10 +467,9 @@ for nsub_path in "${subject_list[@]}"; do "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ -f - # VTTT contralateral vPSN : remaining_cp to VPM scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" \ - "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" \ + "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f scil_labels_from_mask \ @@ -525,7 +491,6 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" - # OS and IS scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ @@ -544,7 +509,6 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' \ -f - # vPSN scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ @@ -581,7 +545,6 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" - # CS scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ @@ -594,12 +557,11 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' \ -f - # dPSN scil_tractogram_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ - --drawn_roi "${out_dir}/mni_space/tracking_first_order/final/all_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ + --drawn_roi "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo" 'any' 'exclude' \ @@ -611,105 +573,92 @@ for nsub_path in "${subject_list[@]}"; do -f done + # ------------------------- + # 7) Cut filtered second-order bundles with label masks + # ------------------------- + echo "|------------- 7) Cut filtered second-order bundles with label masks -------------|" + for nside in left right; do + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else + scil_tractogram_cut_streamlines \ + "${in_trk}" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ + "${out_trk}" -f -# ------------------------- -# 7) Cut filtered second-order bundles with label masks -# ------------------------- -echo "|------------- 7) Cut filtered second-order bundles with label masks -------------|" -for nside in left right; do - - in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" - out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" - if trk_is_empty "${in_trk}"; then - echo "WARN: ${in_trk} is missing or empty, skipping cut." - else - scil_tractogram_cut_streamlines \ - "${in_trk}" \ - --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ - "${out_trk}" -f - - if trk_is_empty "${out_trk}"; then - echo "WARN: ${out_trk} is empty after cut, removing." - rm -f "${out_trk}" + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi fi - fi - in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" - out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" - if trk_is_empty "${in_trk}"; then - echo "WARN: ${in_trk} is missing or empty, skipping cut." - else - scil_tractogram_cut_streamlines \ - "${in_trk}" \ - --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ - "${out_trk}" -f - - if trk_is_empty "${out_trk}"; then - echo "WARN: ${out_trk} is empty after cut, removing." - rm -f "${out_trk}" - fi - fi + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else + scil_tractogram_cut_streamlines \ + "${in_trk}" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ + "${out_trk}" -f - in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" - out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" - if trk_is_empty "${in_trk}"; then - echo "WARN: ${in_trk} is missing or empty, skipping cut." - else - scil_tractogram_cut_streamlines \ - "${in_trk}" \ - --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ - "${out_trk}" -f - - if trk_is_empty "${out_trk}"; then - echo "WARN: ${out_trk} is empty after cut, removing." - rm -f "${out_trk}" + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi fi - fi - in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" - out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" - if trk_is_empty "${in_trk}"; then - echo "WARN: ${in_trk} is missing or empty, skipping cut." - else - scil_tractogram_cut_streamlines \ - "${in_trk}" \ - --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ - "${out_trk}" -f - - if trk_is_empty "${out_trk}"; then - echo "WARN: ${out_trk} is empty after cut, removing." - rm -f "${out_trk}" - fi - fi + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Controlat_CS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else + scil_tractogram_cut_streamlines \ + "${in_trk}" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ + "${out_trk}" -f - in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" - out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" - if trk_is_empty "${in_trk}"; then - echo "WARN: ${in_trk} is missing or empty, skipping cut." - else - scil_tractogram_cut_streamlines \ - "${in_trk}" \ - --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ - "${out_trk}" -f - - if trk_is_empty "${out_trk}"; then - echo "WARN: ${out_trk} is empty after cut, removing." - rm -f "${out_trk}" + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi fi - fi -done - - - - - - - + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else + scil_tractogram_cut_streamlines \ + "${in_trk}" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ + "${out_trk}" -f + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + in_trk="${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" + out_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty, skipping cut." + else + scil_tractogram_cut_streamlines \ + "${in_trk}" \ + --labels "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ + "${out_trk}" -f + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after cut, removing." + rm -f "${out_trk}" + fi + fi + done # ------------------------- # 8) Reject outliers and save final second-order bundles @@ -729,33 +678,34 @@ done done done - echo "|------------- SECOND-ORDER ENSEMBLE FOR ${nsub} IS COMPLETED -------------|" - echo "" -done - - -echo "|------------- 9) [BACK-TO-ORIG] Register final MNI bundles to orig space -------------|" + # ------------------------- + # 9) [BACK-TO-ORIG] Register final MNI bundles to orig space + # ------------------------- + echo "|------------- 9) [BACK-TO-ORIG] Register final MNI bundles to orig space -------------|" -for nside in left right; do - for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do - in_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" - out_trk="${orig_tracking_dir}/final/${nsub}_from_${nside}_${nbundle}_orig.trk" + for nside in left right; do + for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + in_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" + out_trk="${orig_tracking_dir}/final/${nsub}_from_${nside}_${nbundle}_orig.trk" - if [[ -f "${in_trk}" ]]; then - scil_tractogram_apply_transform \ - "${in_trk}" \ - "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ - "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ - "${out_trk}" \ - --inverse \ - --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1InverseWarp.nii.gz" \ - --remove_invalid -f - else - echo "WARN: Final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." - fi + if [[ -f "${in_trk}" ]]; then + scil_tractogram_apply_transform \ + "${in_trk}" \ + "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ + "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ + "${out_trk}" \ + --inverse \ + --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1InverseWarp.nii.gz" \ + --remove_invalid -f + else + echo "WARN: Final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." + fi + done done -done + echo "|------------- SECOND-ORDER ENSEMBLE FOR ${nsub} IS COMPLETED -------------|" + echo "" +done -#test for second_order_path \ No newline at end of file +#help ,this is second_order_path \ No newline at end of file From 20e781da449f7f009bbe928641a351c4e822da11 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 20 Apr 2026 13:42:10 -0400 Subject: [PATCH 09/21] add help part for step 8 --- trigeminal_second_order.sh | 77 +++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index b5c3503..df22127 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -6,17 +6,14 @@ set -euo pipefail # TRIGEMINAL SYSTEM TRACTOGRAPHY - Nasrin Rafiei (2025-2026) # # SECOND-ORDER ENSEMBLE VERSION -# This script performs tractography of the second order trigeminal system based on the output of -# the first-order tractography pipeline (trigeminal_first_order.sh). -# You should be running the exact command you ran for the first order (same input/output). -# # SUBJECT-BY-SUBJECT VERSION: # - no pooled all_left/all_right files # - each subject uses its own first-order spinal / remaining_cp bundles # - nothing is created outside the subject folder +# - subject-specific density maps are stored directly in mni_space/rois # # Organized pipeline: -# 0) prepare subject-specific first-order density maps for second-order +# 0) prepare subject-specific first-order density maps # 1) prepare second-order seed masks and thalamus ROIs # 2) run second-order tracking for each (step, theta) combo in ORIG # 3) merge combo outputs per tracking role in ORIG @@ -193,14 +190,12 @@ for nsub_path in "${subject_list[@]}"; do mkdir -p "${out_dir}/${nsub}/orig_space/tracking_second_order"/{trials,merged,final} mkdir -p "${out_dir}/${nsub}/mni_space/rois" mkdir -p "${out_dir}/${nsub}/mni_space/tracking_second_order"/{orig,filtered,final,cut} - mkdir -p "${out_dir}/${nsub}/mni_space/tracking_first_order/final_subject_second_order" orig_rois_dir="${out_dir}/${nsub}/orig_space/rois" mni_rois_dir="${out_dir}/${nsub}/mni_space/rois" orig_tracking_dir="${out_dir}/${nsub}/orig_space/tracking_second_order" mni_tracking_dir_second_order="${out_dir}/${nsub}/mni_space/tracking_second_order" first_order_final_dir="${out_dir}/${nsub}/mni_space/tracking_first_order/final_merged/final" - subject_first_order_dir="${out_dir}/${nsub}/mni_space/tracking_first_order/final_subject_second_order" orig_trials_root="${orig_tracking_dir}/trials" orig_merged_root="${orig_tracking_dir}/merged" @@ -256,17 +251,18 @@ for nsub_path in "${subject_list[@]}"; do # ============================================================ # 0) Prepare subject-specific first-order density maps + # Store directly in mni_space/rois # ============================================================ echo "|------------- 0) Prepare subject-specific first-order density maps -------------|" for nside in left right; do scil_tractogram_compute_density_map \ "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" \ - "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ --binary -f scil_tractogram_compute_density_map \ "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" \ - "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ --binary -f done @@ -275,14 +271,11 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- echo "|------------- 1) Prepare second-order seed masks and thalamus ROIs -------------|" - echo "|------------- 1.1) Copy subject spinal seed masks and transform them to orig space -------------|" + echo "|------------- 1.1) Transform subject spinal seed masks to orig space -------------|" for nside in left right; do - cp "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" - antsApplyTransforms \ -d 3 \ - -i "${subject_first_order_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + -i "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ -r "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ -t "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ -t "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ @@ -378,6 +371,9 @@ for nsub_path in "${subject_list[@]}"; do done done + + + # ------------------------- # 4) Register merged second-order tractograms to MNI space # ------------------------- @@ -429,7 +425,7 @@ for nsub_path in "${subject_list[@]}"; do scil_volume_math union \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ - "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f scil_labels_from_mask \ @@ -469,7 +465,7 @@ for nsub_path in "${subject_list[@]}"; do scil_volume_math union \ "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" \ - "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ + "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ --data_type uint8 -f scil_labels_from_mask \ @@ -561,7 +557,7 @@ for nsub_path in "${subject_list[@]}"; do "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ - --drawn_roi "${subject_first_order_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ + --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_1.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_2.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_3.bdo" 'any' 'exclude' \ @@ -660,24 +656,52 @@ for nsub_path in "${subject_list[@]}"; do fi done + + # ------------------------- # 8) Reject outliers and save final second-order bundles # ------------------------- echo "|------------- 8) Reject outliers and save final second-order bundles -------------|" for nside in left right; do - scil_bundle_reject_outliers \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ - "${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ - --alpha 0.30 -f + in_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" + out_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" - for nbundle in DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} missing or empty, skipping outlier rejection." + else scil_bundle_reject_outliers \ - "${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_${nbundle}.trk" \ - "${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" \ - --alpha 0.50 -f + "${in_trk}" \ + "${out_trk}" \ + --alpha 0.30 -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after outlier rejection, removing." + rm -f "${out_trk}" + fi + fi + + for nbundle in DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + in_trk="${mni_tracking_dir_second_order}/cut/${nsub}_from_${nside}_${nbundle}.trk" + out_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" + + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} missing or empty, skipping outlier rejection." + else + scil_bundle_reject_outliers \ + "${in_trk}" \ + "${out_trk}" \ + --alpha 0.50 -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after outlier rejection, removing." + rm -f "${out_trk}" + fi + fi done done + + # ------------------------- # 9) [BACK-TO-ORIG] Register final MNI bundles to orig space # ------------------------- @@ -707,5 +731,4 @@ for nsub_path in "${subject_list[@]}"; do echo "" done - -#help ,this is second_order_path \ No newline at end of file +#this is second_order_path branch \ No newline at end of file From 4f56b75e4389c716492f6923ef284ae151ef2e68 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 27 Apr 2026 14:33:26 -0400 Subject: [PATCH 10/21] modify step 7, for labels with more that 2 ids --- trigeminal_second_order.sh | 147 ++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index df22127..9b65ca2 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -134,6 +134,31 @@ trk_is_empty() { fi } +# ------------------------- +# Helper for step 7 +# ------------------------- +get_label_ids_for_cut() { + local labels_file="$1" + + python - < Date: Thu, 30 Apr 2026 15:28:53 -0400 Subject: [PATCH 11/21] Fix second-order pipeline for empty seeds and multi-label cuts --- trigeminal_second_order.sh | 121 +++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 9b65ca2..c5b1fd5 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -31,18 +31,6 @@ Usage: [-f fa_threshold] [-t threads] [-g true|false] [-p step_size] [-e theta_deg] [--npv_spinal_long N] [--npv_spinal_short N] [--npv_thalamus N] - -Tracking params: - -p step_size If set with -e, runs SINGLE combo (no ensemble) - -e theta_deg If set with -p, runs SINGLE combo (no ensemble) - If -p/-e not provided, ensemble is used: - step = 0.1 0.5 1.0 - theta = 20 30 40 - -Second-order seed budgets (TOTAL per role; auto-split across combos): - --npv_spinal_long N default: 1000 - --npv_spinal_short N default: 100 - --npv_thalamus N default: 500 EOF exit 1 } @@ -134,9 +122,25 @@ trk_is_empty() { fi } -# ------------------------- -# Helper for step 7 -# ------------------------- +mask_has_nonzero_voxels() { + local f="$1" + + if [[ ! -f "${f}" ]]; then + return 1 + fi + + local nz + nz=$(python - < 0).sum())) +PY +) + + [[ "${nz}" -gt 0 ]] +} + get_label_ids_for_cut() { local labels_file="$1" @@ -153,8 +157,6 @@ if len(vals) < 2: elif len(vals) == 2: print(f"{vals[0]} {vals[1]}") else: - # practical default rule: - # if more than 2 nonzero labels exist, use first and last nonzero labels print(f"{vals[0]} {vals[-1]}") PY } @@ -172,7 +174,6 @@ fi n_combos=$(( ${#step_list[@]} * ${#theta_list[@]} )) -# Split total budgets across combos (ceiling division) npv_spinal_long_per_combo=$(( (npv_spinal_long_total + n_combos - 1) / n_combos )) npv_spinal_short_per_combo=$(( (npv_spinal_short_total + n_combos - 1) / n_combos )) npv_thalamus_per_combo=$(( (npv_thalamus_total + n_combos - 1) / n_combos )) @@ -191,7 +192,6 @@ echo " thalamus: ${npv_thalamus_per_combo} (from total ${npv_thalamus_t export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS="${nb_threads}" -# Detect if -s is one subject folder or a parent folder of many subjects if [[ -d "${subject_dir}/tractoflow" ]]; then subject_list=("${subject_dir}") else @@ -205,9 +205,6 @@ if [[ ${#subject_list[@]} -eq 0 ]]; then exit 1 fi -# ============================================================ -# Process each subject -# ============================================================ for nsub_path in "${subject_list[@]}"; do nsub=$(basename "${nsub_path}") @@ -229,9 +226,6 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- PROCESSING SECOND-ORDER ENSEMBLE FOR ${nsub} -------------|" echo "" - # ------------------------- - # Safety checks - # ------------------------- for nside in left right; do [[ -f "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" ]] || { echo "ERROR: Missing first-order file ${first_order_final_dir}/${nsub}_${nside}_spinal.trk" @@ -274,9 +268,9 @@ for nsub_path in "${subject_list[@]}"; do exit 1 } - # ============================================================ + # ------------------------- # 0) Prepare subject-specific first-order density maps - # ============================================================ + # ------------------------- echo "|------------- 0) Prepare subject-specific first-order density maps -------------|" for nside in left right; do scil_tractogram_compute_density_map \ @@ -338,35 +332,47 @@ for nsub_path in "${subject_list[@]}"; do echo "|=== Second-order combo: ${combo_tag} ===|" for nside in left right; do - scil_tracking_local \ - "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ - "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ - "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1000_${combo_tag}.trk" \ - --npv "${npv_spinal_long_per_combo}" \ - --step "${step_size}" \ - --theta "${theta}" \ - ${gpu} -v -f - - scil_tracking_local \ - "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ - "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" \ - "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv100_${combo_tag}.trk" \ - --npv "${npv_spinal_short_per_combo}" \ - --step "${step_size}" \ - --theta "${theta}" \ - ${gpu} -v -f - - scil_tracking_local \ - "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ - "${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz" \ - "${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ - --npv "${npv_thalamus_per_combo}" \ - --step "${step_size}" \ - --theta "${theta}" \ - ${gpu} -v -f + spinal_seed="${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" + thalamus_seed="${orig_rois_dir}/${nsub}_${nside}_thalamus_orig.nii.gz" + wm_mask="${orig_rois_dir}/${nsub}_wm_mask_${fa_threshold}_orig.nii.gz" + + if mask_has_nonzero_voxels "${spinal_seed}"; then + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${spinal_seed}" \ + "${wm_mask}" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1000_${combo_tag}.trk" \ + --npv "${npv_spinal_long_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${spinal_seed}" \ + "${wm_mask}" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv100_${combo_tag}.trk" \ + --npv "${npv_spinal_short_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + else + echo "WARN: spinal seed is missing or empty for ${nside} at ${combo_tag}. Skipping spinal tracking." + fi + + if mask_has_nonzero_voxels "${thalamus_seed}"; then + scil_tracking_local \ + "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ + "${thalamus_seed}" \ + "${wm_mask}" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ + --npv "${npv_thalamus_per_combo}" \ + --step "${step_size}" \ + --theta "${theta}" \ + ${gpu} -v -f + else + echo "WARN: thalamus seed is missing or empty for ${nside} at ${combo_tag}. Skipping thalamus tracking." + fi done done done @@ -729,5 +735,4 @@ PY echo "" done - -#second_order_path \ No newline at end of file +# second_order_path \ No newline at end of file From 98662105c2fb20cbb29c65dd33f8a06d403a722b Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 5 May 2026 13:16:19 -0400 Subject: [PATCH 12/21] add warning for Missing or empty first-order spinal/remaining_cp --- trigeminal_second_order.sh | 288 +++++++++++++++++++++++++++---------- 1 file changed, 216 insertions(+), 72 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index c5b1fd5..89aa6a8 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -161,6 +161,168 @@ else: PY } +safe_compute_density_map() { + local in_trk="$1" + local out_mask="$2" + + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty. Skipping density map." + rm -f "${out_mask}" + return 0 + fi + + scil_tractogram_compute_density_map \ + "${in_trk}" \ + "${out_mask}" \ + --binary -f + + if ! mask_has_nonzero_voxels "${out_mask}"; then + echo "WARN: ${out_mask} has no non-zero voxels after density computation. Removing." + rm -f "${out_mask}" + fi +} + +safe_apply_mask_transform_to_orig() { + local in_mask="$1" + local ref_img="$2" + local warp="$3" + local affine="$4" + local out_mask="$5" + + if ! mask_has_nonzero_voxels "${in_mask}"; then + echo "WARN: ${in_mask} is missing or empty. Skipping mask transform." + rm -f "${out_mask}" + return 0 + fi + + antsApplyTransforms \ + -d 3 \ + -i "${in_mask}" \ + -r "${ref_img}" \ + -t "${warp}" \ + -t "${affine}" \ + -o "${out_mask}" + + if ! mask_has_nonzero_voxels "${out_mask}"; then + echo "WARN: ${out_mask} has no non-zero voxels after transform. Removing." + rm -f "${out_mask}" + fi +} + +safe_build_cut_labels() { + local mask_a="$1" + local mask_b="$2" + local out_mask="$3" + local out_labels="$4" + + if ! mask_has_nonzero_voxels "${mask_a}"; then + echo "WARN: ${mask_a} is missing or empty. Skipping cut-mask construction." + rm -f "${out_mask}" "${out_labels}" + return 0 + fi + + if ! mask_has_nonzero_voxels "${mask_b}"; then + echo "WARN: ${mask_b} is missing or empty. Skipping cut-mask construction." + rm -f "${out_mask}" "${out_labels}" + return 0 + fi + + scil_volume_math union \ + "${mask_a}" \ + "${mask_b}" \ + "${out_mask}" \ + --data_type uint8 -f + + if ! mask_has_nonzero_voxels "${out_mask}"; then + echo "WARN: ${out_mask} has no non-zero voxels after union. Removing." + rm -f "${out_mask}" "${out_labels}" + return 0 + fi + + scil_labels_from_mask \ + "${out_mask}" \ + "${out_labels}" \ + -f +} + +safe_filter_by_roi() { + local in_trk="$1" + local out_trk="$2" + shift 2 + + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty. Skipping filter." + rm -f "${out_trk}" + return 0 + fi + + local args=("$@") + local i=0 + local n=${#args[@]} + + while (( i < n )); do + local key="${args[$i]}" + + if [[ "${key}" == "--drawn_roi" ]]; then + if (( i + 3 >= n )); then + echo "WARN: malformed --drawn_roi arguments for ${out_trk}. Skipping filter." + rm -f "${out_trk}" + return 0 + fi + + local roi_file="${args[$((i + 1))]}" + local roi_action="${args[$((i + 3))]}" + + if [[ ! -f "${roi_file}" ]]; then + echo "WARN: ROI ${roi_file} is missing. Skipping filter for ${out_trk}." + rm -f "${out_trk}" + return 0 + fi + + if [[ "${roi_action}" == "include" ]] && ! mask_has_nonzero_voxels "${roi_file}"; then + echo "WARN: include ROI ${roi_file} is empty. Skipping filter for ${out_trk}." + rm -f "${out_trk}" + return 0 + fi + + i=$((i + 4)) + continue + fi + + if [[ "${key}" == "--bdo" ]]; then + if (( i + 3 >= n )); then + echo "WARN: malformed --bdo arguments for ${out_trk}. Skipping filter." + rm -f "${out_trk}" + return 0 + fi + + local bdo_file="${args[$((i + 1))]}" + + if [[ ! -f "${bdo_file}" ]]; then + echo "WARN: BDO ${bdo_file} is missing. Skipping filter for ${out_trk}." + rm -f "${out_trk}" + return 0 + fi + + i=$((i + 4)) + continue + fi + + i=$((i + 1)) + done + + scil_tractogram_filter_by_roi \ + "${in_trk}" \ + "${out_trk}" \ + "${args[@]}" \ + -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after filtering. Removing." + rm -f "${out_trk}" + fi +} + # ------------------------- # Ensemble grid # ------------------------- @@ -227,14 +389,15 @@ for nsub_path in "${subject_list[@]}"; do echo "" for nside in left right; do - [[ -f "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" ]] || { - echo "ERROR: Missing first-order file ${first_order_final_dir}/${nsub}_${nside}_spinal.trk" - exit 1 - } - [[ -f "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" ]] || { - echo "ERROR: Missing first-order file ${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" - exit 1 - } + if trk_is_empty "${first_order_final_dir}/${nsub}_${nside}_spinal.trk"; then + echo "WARN: Missing or empty first-order spinal file: ${first_order_final_dir}/${nsub}_${nside}_spinal.trk" + echo "WARN: ${nside} spinal-based second-order tracking will be skipped." + fi + + if trk_is_empty "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk"; then + echo "WARN: Missing or empty first-order remaining_cp file: ${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" + echo "WARN: ${nside} remaining_cp-dependent second-order bundles may be skipped." + fi done [[ -f "${orig_rois_dir}/${nsub}_aparc.DKTatlas+aseg_orig.nii.gz" ]] || { @@ -273,15 +436,13 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- echo "|------------- 0) Prepare subject-specific first-order density maps -------------|" for nside in left right; do - scil_tractogram_compute_density_map \ + safe_compute_density_map \ "${first_order_final_dir}/${nsub}_${nside}_spinal.trk" \ - "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ - --binary -f + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" - scil_tractogram_compute_density_map \ + safe_compute_density_map \ "${first_order_final_dir}/${nsub}_${nside}_remaining_cp.trk" \ - "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ - --binary -f + "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" done # ------------------------- @@ -291,13 +452,12 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 1.1) Transform subject spinal seed masks to orig space -------------|" for nside in left right; do - antsApplyTransforms \ - -d 3 \ - -i "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ - -r "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ - -t "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ - -t "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ - -o "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" + safe_apply_mask_transform_to_orig \ + "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ + "${nsub_path}/tractoflow/${nsub}__t1_warped.nii.gz" \ + "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ + "${out_dir}/${nsub}/orig_space/transfo/2orig_0GenericAffine.mat" \ + "${orig_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_orig.nii.gz" done echo "|------------- 1.2) Extract thalamus masks from the anatomical segmentation -------------|" @@ -392,12 +552,15 @@ for nsub_path in "${subject_list[@]}"; do for theta in "${theta_list[@]}"; do combo_tag="step_${step_size}_theta_${theta}" f="${orig_trials_root}/${combo_tag}/${nsub}_${nside}_${role}_${combo_tag}.trk" - [[ -f "${f}" ]] && files+=("${f}") + if ! trk_is_empty "${f}"; then + files+=("${f}") + fi done done if (( ${#files[@]} == 0 )); then - echo "WARN: no files found for ${nside} ${role}" + echo "WARN: no non-empty files found for ${nside} ${role}" + rm -f "${orig_merged_root}/${nsub}_${nside}_${role}.trk" continue fi @@ -430,7 +593,10 @@ PY in_trk="${orig_merged_root}/${nsub}_${nside}_${role}.trk" out_trk="${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_${role}.trk" - if [[ -f "${in_trk}" ]]; then + if trk_is_empty "${in_trk}"; then + echo "WARN: merged orig tractogram missing or empty for ${nside} ${role}" + rm -f "${out_trk}" + else scil_tractogram_apply_transform \ "${in_trk}" \ "${mni_dir}/MNI/mni_masked.nii.gz" \ @@ -439,8 +605,11 @@ PY --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1Warp.nii.gz" \ --remove_invalid \ --reverse_operation -f - else - echo "WARN: merged orig tractogram not found for ${nside} ${role}" + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after transform to MNI. Removing." + rm -f "${out_trk}" + fi fi done done @@ -470,55 +639,35 @@ PY contra_nside="left" fi - scil_volume_math union \ + safe_build_cut_labels \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ - --data_type uint8 -f - scil_labels_from_mask \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" \ - -f + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_dPSN_Cuts_labels_mni.nii.gz" - scil_volume_math union \ + safe_build_cut_labels \ "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz" \ - --data_type uint8 -f - scil_labels_from_mask \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" \ - -f + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Ipsilat_CS_Cuts_labels_mni.nii.gz" - scil_volume_math union \ + safe_build_cut_labels \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz" \ - --data_type uint8 -f - scil_labels_from_mask \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" \ - -f + "${mni_rois_dir}/${nsub}_${nside}_second_order_DTTT_Controlat_CS_Cuts_labels_mni.nii.gz" - scil_volume_math union \ + safe_build_cut_labels \ "${mni_rois_dir}/${nsub}_${contra_nside}_thalamus_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz" \ - --data_type uint8 -f - scil_labels_from_mask \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" \ - -f + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_OSandIS_Cuts_labels_mni.nii.gz" - scil_volume_math union \ + safe_build_cut_labels \ "${mni_rois_dir}/${nsub}_${contra_nside}_VPM_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" \ "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ - --data_type uint8 -f - scil_labels_from_mask \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_mni.nii.gz" \ - "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" \ - -f + "${mni_rois_dir}/${nsub}_${nside}_second_order_VTTT_Controlat_vPSN_Cuts_labels_mni.nii.gz" done # ------------------------- @@ -534,7 +683,7 @@ PY echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" - scil_tractogram_filter_by_roi \ + safe_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -549,10 +698,9 @@ PY --drawn_roi "${mni_dir}/MNI/cs_plaque.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_dir}/MNI/from_${nside}/VTTT_Controlat_INC_VTT_Area.nii.gz" 'any' 'include' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_1.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' \ - -f + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' - scil_tractogram_filter_by_roi \ + safe_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -567,11 +715,10 @@ PY --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_3.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_4.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_5.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo" 'any' 'exclude' \ - -f + --bdo "${mni_dir}/MNI/from_${nside}/VTTT_Controlat/VTTT_Controlat_vPSN_6.bdo" 'any' 'exclude' echo "|------------- 6.2) ${nside} - DTTT (contralateral) - CS -------------|" - scil_tractogram_filter_by_roi \ + safe_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${contra_nside}_DTTT_Controlat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_spinal_density_second_order_seed_mni.nii.gz" 'any' 'include' \ @@ -583,12 +730,11 @@ PY --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_1.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_2.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_3.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_4.bdo" 'any' 'exclude' \ - -f + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Controlat_4.bdo" 'any' 'exclude' echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" - scil_tractogram_filter_by_roi \ + safe_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ @@ -597,10 +743,9 @@ PY --drawn_roi "${mni_dir}/MNI/midsagittal_plane.nii.gz" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_1.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_2.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' \ - -f + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' - scil_tractogram_filter_by_roi \ + safe_filter_by_roi \ "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ @@ -612,8 +757,7 @@ PY --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_5.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_6.bdo" 'any' 'exclude' \ --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_7.bdo" 'any' 'exclude' \ - --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo" 'any' 'exclude' \ - -f + --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_dPSN_8.bdo" 'any' 'exclude' done # ------------------------- @@ -735,4 +879,4 @@ PY echo "" done -# second_order_path \ No newline at end of file +# second_order_path From 79cba4166e175c112a1e116370c034ef9f790fc7 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 12 May 2026 15:48:28 -0400 Subject: [PATCH 13/21] step 3 changed to incremental_concatenate --- trigeminal_second_order.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 89aa6a8..67ad1a5 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -879,4 +879,4 @@ PY echo "" done -# second_order_path +# git checkout -b second_order_incremental_concatenate From 85e5a35cb35ca8357deb5d737526e635d5b6d2a4 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 12 May 2026 15:50:55 -0400 Subject: [PATCH 14/21] Use incremental concatenate for second-order tractograms --- trigeminal_second_order.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 67ad1a5..1d0f24e 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -879,4 +879,4 @@ PY echo "" done -# git checkout -b second_order_incremental_concatenate +#git checkout -b second_order_incremental_concatenate From f200519509d6a2e473d001f916b86a6e74588098 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Tue, 9 Jun 2026 10:42:43 -0400 Subject: [PATCH 15/21] filter by length is added --- trigeminal_second_order.sh | 75 ++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 1d0f24e..30fd4ad 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -540,7 +540,8 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- # 3) Merge second-order combo tractograms in orig space # ------------------------- - echo "|------------- 3) Merge second-order combo tractograms in orig space -------------|" + echo "|------------- 3) Clean and incrementally merge second-order combo tractograms in orig space -------------|" + for nside in left right; do for role in from_thalamus_npv500 from_spinal_track_npv100 from_spinal_track_npv1000; do files=() @@ -552,6 +553,7 @@ for nsub_path in "${subject_list[@]}"; do for theta in "${theta_list[@]}"; do combo_tag="step_${step_size}_theta_${theta}" f="${orig_trials_root}/${combo_tag}/${nsub}_${nside}_${role}_${combo_tag}.trk" + if ! trk_is_empty "${f}"; then files+=("${f}") fi @@ -564,26 +566,69 @@ for nsub_path in "${subject_list[@]}"; do continue fi - echo "Cleaning and merging ${#files[@]} files for ${nside} ${role}" + echo "" + echo "Cleaning ${#files[@]} files for ${nside} ${role}" for f in "${files[@]}"; do - cleaned_f="${clean_dir}/$(basename "${f}")" + base=$(basename "${f}" .trk) + cleaned_f="${clean_dir}/${base}_clean.trk" + + scil_tractogram_remove_invalid \ + "${f}" \ + "${cleaned_f}" \ + --remove_single_point \ + --remove_overlapping_points \ + -f + + if ! trk_is_empty "${cleaned_f}"; then + cleaned_files+=("${cleaned_f}") + else + echo "WARN: cleaned file is empty: ${cleaned_f}" + rm -f "${cleaned_f}" + fi + done -python < Date: Tue, 9 Jun 2026 10:43:58 -0400 Subject: [PATCH 16/21] filter by length is added --- trigeminal_second_order.sh | 102 +++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 30fd4ad..2b70106 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -22,7 +22,8 @@ set -euo pipefail # 6) filter merged second-order tractograms into pathway bundles # 7) cut filtered bundles with label masks # 8) reject outliers and save final second-order bundles -# 9) bring final MNI bundles back to ORIG +# 8.5) filter final second-order bundles by length +# 9) bring final length-filtered MNI bundles back to ORIG usage() { cat <&2 @@ -323,6 +324,36 @@ safe_filter_by_roi() { fi } + +safe_filter_by_length() { + local in_trk="$1" + local out_trk="$2" + local minL="$3" + local maxL="$4" + + if trk_is_empty "${in_trk}"; then + echo "WARN: ${in_trk} is missing or empty. Skipping length filtering." + rm -f "${out_trk}" + return 0 + fi + + echo "Length filtering ${in_trk}" + echo " minL=${minL} maxL=${maxL}" + echo " output=${out_trk}" + + scil_tractogram_filter_by_length \ + "${in_trk}" \ + "${out_trk}" \ + --minL "${minL}" \ + --maxL "${maxL}" \ + --display_counts -f + + if trk_is_empty "${out_trk}"; then + echo "WARN: ${out_trk} is empty after length filtering. Removing." + rm -f "${out_trk}" + fi +} + # ------------------------- # Ensemble grid # ------------------------- @@ -895,14 +926,75 @@ for nsub_path in "${subject_list[@]}"; do done done + # ------------------------- - # 9) [BACK-TO-ORIG] Register final MNI bundles to orig space + # 8.5) Filter final second-order bundles by length # ------------------------- - echo "|------------- 9) [BACK-TO-ORIG] Register final MNI bundles to orig space -------------|" + echo "|------------- 8.5) Filter final second-order bundles by length -------------|" + + mkdir -p "${mni_tracking_dir_second_order}/final_length" + + # Length thresholds are in mm. + # You can modify each bundle independently if needed. + declare -A minL_by_bundle + declare -A maxL_by_bundle + + minL_by_bundle["left_DTTT_Ipsilat_CS"]=10 + maxL_by_bundle["left_DTTT_Ipsilat_CS"]=120 + + minL_by_bundle["right_DTTT_Ipsilat_CS"]=10 + maxL_by_bundle["right_DTTT_Ipsilat_CS"]=120 + + minL_by_bundle["left_DTTT_Ipsilat_dPSN"]=10 + maxL_by_bundle["left_DTTT_Ipsilat_dPSN"]=140 + + minL_by_bundle["right_DTTT_Ipsilat_dPSN"]=10 + maxL_by_bundle["right_DTTT_Ipsilat_dPSN"]=140 + + minL_by_bundle["left_DTTT_Controlat_CS"]=10 + maxL_by_bundle["left_DTTT_Controlat_CS"]=160 + + minL_by_bundle["right_DTTT_Controlat_CS"]=10 + maxL_by_bundle["right_DTTT_Controlat_CS"]=160 + + minL_by_bundle["left_VTTT_Controlat_OSandIS"]=10 + maxL_by_bundle["left_VTTT_Controlat_OSandIS"]=180 + + minL_by_bundle["right_VTTT_Controlat_OSandIS"]=10 + maxL_by_bundle["right_VTTT_Controlat_OSandIS"]=180 + + minL_by_bundle["left_VTTT_Controlat_vPSN"]=10 + maxL_by_bundle["left_VTTT_Controlat_vPSN"]=180 + + minL_by_bundle["right_VTTT_Controlat_vPSN"]=10 + maxL_by_bundle["right_VTTT_Controlat_vPSN"]=180 for nside in left right; do for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + key="${nside}_${nbundle}" + in_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" + out_trk="${mni_tracking_dir_second_order}/final_length/${nsub}_from_${nside}_${nbundle}.trk" + + minL="${minL_by_bundle[${key}]}" + maxL="${maxL_by_bundle[${key}]}" + + safe_filter_by_length \ + "${in_trk}" \ + "${out_trk}" \ + "${minL}" \ + "${maxL}" + done + done + + # ------------------------- + # 9) [BACK-TO-ORIG] Register final length-filtered MNI bundles to orig space + # ------------------------- + echo "|------------- 9) [BACK-TO-ORIG] Register final length-filtered MNI bundles to orig space -------------|" + + for nside in left right; do + for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do + in_trk="${mni_tracking_dir_second_order}/final_length/${nsub}_from_${nside}_${nbundle}.trk" out_trk="${orig_tracking_dir}/final/${nsub}_from_${nside}_${nbundle}_orig.trk" if [[ -f "${in_trk}" ]]; then @@ -915,7 +1007,7 @@ for nsub_path in "${subject_list[@]}"; do --in_deformation "${out_dir}/${nsub}/orig_space/transfo/2orig_1InverseWarp.nii.gz" \ --remove_invalid -f else - echo "WARN: Final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." + echo "WARN: Length-filtered final MNI bundle not found for ${nside} ${nbundle}, skipping back-to-orig." fi done done @@ -924,4 +1016,4 @@ for nsub_path in "${subject_list[@]}"; do echo "" done -# #git checkout -b second_order_incremental_concatenate \ No newline at end of file +# #git checkout -b second_order_filter_length \ No newline at end of file From a3f0b15d3f89d24dabfa6b0e4b58b9b94adf8d08 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Thu, 11 Jun 2026 10:28:28 -0400 Subject: [PATCH 17/21] npvs increased --- trigeminal_second_order.sh | 85 ++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 2b70106..9fc1a9b 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -66,9 +66,9 @@ shift $((OPTIND-1)) # ------------------------- # Parse optional long args # ------------------------- -npv_spinal_long_total=1000 -npv_spinal_short_total=100 -npv_thalamus_total=500 +npv_spinal_long_total=1500 +npv_spinal_short_total=150 +npv_thalamus_total=600 while [[ $# -gt 0 ]]; do case "$1" in @@ -532,7 +532,7 @@ for nsub_path in "${subject_list[@]}"; do "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${spinal_seed}" \ "${wm_mask}" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1000_${combo_tag}.trk" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1500_${combo_tag}.trk" \ --npv "${npv_spinal_long_per_combo}" \ --step "${step_size}" \ --theta "${theta}" \ @@ -542,7 +542,7 @@ for nsub_path in "${subject_list[@]}"; do "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${spinal_seed}" \ "${wm_mask}" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv100_${combo_tag}.trk" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv150_${combo_tag}.trk" \ --npv "${npv_spinal_short_per_combo}" \ --step "${step_size}" \ --theta "${theta}" \ @@ -556,7 +556,7 @@ for nsub_path in "${subject_list[@]}"; do "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${thalamus_seed}" \ "${wm_mask}" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv500_${combo_tag}.trk" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv600_${combo_tag}.trk" \ --npv "${npv_thalamus_per_combo}" \ --step "${step_size}" \ --theta "${theta}" \ @@ -574,7 +574,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 3) Clean and incrementally merge second-order combo tractograms in orig space -------------|" for nside in left right; do - for role in from_thalamus_npv500 from_spinal_track_npv100 from_spinal_track_npv1000; do + for role in from_thalamus_npv600 from_spinal_track_npv150 from_spinal_track_npv1500; do files=() cleaned_files=() clean_dir="${orig_tracking_dir}/trials_cleaned/${nside}_${role}" @@ -665,7 +665,7 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- echo "|------------- 4) Register merged second-order tractograms to MNI space -------------|" for nside in left right; do - for role in from_thalamus_npv500 from_spinal_track_npv100 from_spinal_track_npv1000; do + for role in from_thalamus_npv600 from_spinal_track_npv150 from_spinal_track_npv1500; do in_trk="${orig_merged_root}/${nsub}_${nside}_${role}.trk" out_trk="${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_${role}.trk" @@ -760,7 +760,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv500.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv600.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -777,7 +777,7 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -795,7 +795,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.2) ${nside} - DTTT (contralateral) - CS -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv500.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv600.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${contra_nside}_DTTT_Controlat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_spinal_density_second_order_seed_mni.nii.gz" 'any' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_thalamus_mni.nii.gz" 'any' 'include' \ @@ -811,7 +811,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv100.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv150.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ @@ -822,7 +822,7 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1000.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ @@ -929,55 +929,52 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- # 8.5) Filter final second-order bundles by length + # ------------------------- + # ------------------------- + # 8.5) Filter final second-order bundles by length # ------------------------- echo "|------------- 8.5) Filter final second-order bundles by length -------------|" mkdir -p "${mni_tracking_dir_second_order}/final_length" - # Length thresholds are in mm. - # You can modify each bundle independently if needed. + # ------------------------------------------------------------------ + # Length thresholds in mm. + # Modify these values if needed. + # + # These thresholds are applied to both left and right sides. + # ------------------------------------------------------------------ + declare -A minL_by_bundle declare -A maxL_by_bundle - minL_by_bundle["left_DTTT_Ipsilat_CS"]=10 - maxL_by_bundle["left_DTTT_Ipsilat_CS"]=120 - - minL_by_bundle["right_DTTT_Ipsilat_CS"]=10 - maxL_by_bundle["right_DTTT_Ipsilat_CS"]=120 - - minL_by_bundle["left_DTTT_Ipsilat_dPSN"]=10 - maxL_by_bundle["left_DTTT_Ipsilat_dPSN"]=140 - - minL_by_bundle["right_DTTT_Ipsilat_dPSN"]=10 - maxL_by_bundle["right_DTTT_Ipsilat_dPSN"]=140 - - minL_by_bundle["left_DTTT_Controlat_CS"]=10 - maxL_by_bundle["left_DTTT_Controlat_CS"]=160 + minL_by_bundle["DTTT_Ipsilat_CS"]=0 + maxL_by_bundle["DTTT_Ipsilat_CS"]=100 - minL_by_bundle["right_DTTT_Controlat_CS"]=10 - maxL_by_bundle["right_DTTT_Controlat_CS"]=160 + minL_by_bundle["DTTT_Ipsilat_dPSN"]=0 + maxL_by_bundle["DTTT_Ipsilat_dPSN"]=120 - minL_by_bundle["left_VTTT_Controlat_OSandIS"]=10 - maxL_by_bundle["left_VTTT_Controlat_OSandIS"]=180 + minL_by_bundle["DTTT_Controlat_CS"]=0 + maxL_by_bundle["DTTT_Controlat_CS"]=165 - minL_by_bundle["right_VTTT_Controlat_OSandIS"]=10 - maxL_by_bundle["right_VTTT_Controlat_OSandIS"]=180 + minL_by_bundle["VTTT_Controlat_OSandIS"]=0 + maxL_by_bundle["VTTT_Controlat_OSandIS"]=181 - minL_by_bundle["left_VTTT_Controlat_vPSN"]=10 - maxL_by_bundle["left_VTTT_Controlat_vPSN"]=180 - - minL_by_bundle["right_VTTT_Controlat_vPSN"]=10 - maxL_by_bundle["right_VTTT_Controlat_vPSN"]=180 + minL_by_bundle["VTTT_Controlat_vPSN"]=0 + maxL_by_bundle["VTTT_Controlat_vPSN"]=107 for nside in left right; do - for nbundle in DTTT_Ipsilat_CS DTTT_Ipsilat_dPSN DTTT_Controlat_CS VTTT_Controlat_OSandIS VTTT_Controlat_vPSN; do - key="${nside}_${nbundle}" + for nbundle in \ + DTTT_Ipsilat_CS \ + DTTT_Ipsilat_dPSN \ + DTTT_Controlat_CS \ + VTTT_Controlat_OSandIS \ + VTTT_Controlat_vPSN; do in_trk="${mni_tracking_dir_second_order}/final/${nsub}_from_${nside}_${nbundle}.trk" out_trk="${mni_tracking_dir_second_order}/final_length/${nsub}_from_${nside}_${nbundle}.trk" - minL="${minL_by_bundle[${key}]}" - maxL="${maxL_by_bundle[${key}]}" + minL="${minL_by_bundle[${nbundle}]}" + maxL="${maxL_by_bundle[${nbundle}]}" safe_filter_by_length \ "${in_trk}" \ From 97038879c527b575298e57b95eaf2f27e971fa64 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Thu, 11 Jun 2026 15:36:48 -0400 Subject: [PATCH 18/21] npvs increased by 3 times --- trigeminal_second_order.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 9fc1a9b..55883ec 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -66,9 +66,9 @@ shift $((OPTIND-1)) # ------------------------- # Parse optional long args # ------------------------- -npv_spinal_long_total=1500 -npv_spinal_short_total=150 -npv_thalamus_total=600 +npv_spinal_long_total=3000 +npv_spinal_short_total=300 +npv_thalamus_total=1500 while [[ $# -gt 0 ]]; do case "$1" in From 77f377d9b4049ef3b56754ea47cabbb4a6eff927 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 22 Jun 2026 10:02:11 -0400 Subject: [PATCH 19/21] nvp increased by 3times --- trigeminal_second_order.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 55883ec..d62e10d 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -532,7 +532,7 @@ for nsub_path in "${subject_list[@]}"; do "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${spinal_seed}" \ "${wm_mask}" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv1500_${combo_tag}.trk" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_spinal_track_npv3000_${combo_tag}.trk" \ --npv "${npv_spinal_long_per_combo}" \ --step "${step_size}" \ --theta "${theta}" \ @@ -556,7 +556,7 @@ for nsub_path in "${subject_list[@]}"; do "${nsub_path}/tractoflow/${nsub}__fodf.nii.gz" \ "${thalamus_seed}" \ "${wm_mask}" \ - "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv600_${combo_tag}.trk" \ + "${orig_trials_root}/${combo_tag}/${nsub}_${nside}_from_thalamus_npv1500_${combo_tag}.trk" \ --npv "${npv_thalamus_per_combo}" \ --step "${step_size}" \ --theta "${theta}" \ @@ -574,7 +574,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 3) Clean and incrementally merge second-order combo tractograms in orig space -------------|" for nside in left right; do - for role in from_thalamus_npv600 from_spinal_track_npv150 from_spinal_track_npv1500; do + for role in from_thalamus_npv1500 from_spinal_track_npv300 from_spinal_track_npv3000; do files=() cleaned_files=() clean_dir="${orig_tracking_dir}/trials_cleaned/${nside}_${role}" @@ -665,7 +665,7 @@ for nsub_path in "${subject_list[@]}"; do # ------------------------- echo "|------------- 4) Register merged second-order tractograms to MNI space -------------|" for nside in left right; do - for role in from_thalamus_npv600 from_spinal_track_npv150 from_spinal_track_npv1500; do + for role in from_thalamus_npv1500 from_spinal_track_npv300 from_spinal_track_npv3000; do in_trk="${orig_merged_root}/${nsub}_${nside}_${role}.trk" out_trk="${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_${role}.trk" @@ -760,7 +760,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.1) From ${nside} - VTTT (contralateral) - OS/IS and vPSN -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv600.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${contra_nside}_from_thalamus_npv1500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_OSandIS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -777,7 +777,7 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/VTTT_Controlat_OSandIS_2.bdo" 'any' 'exclude' safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1500.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv3000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_VTTT_Controlat_vPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_left_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ --drawn_roi "${mni_rois_dir}/${nsub}_right_cerebellum_wm_mni.nii.gz" 'any' 'exclude' \ @@ -795,7 +795,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.2) ${nside} - DTTT (contralateral) - CS -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv600.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_thalamus_npv1500.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${contra_nside}_DTTT_Controlat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${contra_nside}_spinal_density_second_order_seed_mni.nii.gz" 'any' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_thalamus_mni.nii.gz" 'any' 'include' \ @@ -822,7 +822,7 @@ for nsub_path in "${subject_list[@]}"; do --bdo "${mni_dir}/MNI/from_${nside}/new_ROIs/DTTT_Ipsilat_CS_3.bdo" 'any' 'exclude' safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv1500.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv3000.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_dPSN.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_remaining_cp_density_mni.nii.gz" 'either_end' 'include' \ @@ -951,13 +951,13 @@ for nsub_path in "${subject_list[@]}"; do maxL_by_bundle["DTTT_Ipsilat_CS"]=100 minL_by_bundle["DTTT_Ipsilat_dPSN"]=0 - maxL_by_bundle["DTTT_Ipsilat_dPSN"]=120 + maxL_by_bundle["DTTT_Ipsilat_dPSN"]=90 minL_by_bundle["DTTT_Controlat_CS"]=0 maxL_by_bundle["DTTT_Controlat_CS"]=165 minL_by_bundle["VTTT_Controlat_OSandIS"]=0 - maxL_by_bundle["VTTT_Controlat_OSandIS"]=181 + maxL_by_bundle["VTTT_Controlat_OSandIS"]=185 minL_by_bundle["VTTT_Controlat_vPSN"]=0 maxL_by_bundle["VTTT_Controlat_vPSN"]=107 From d7ebb042e7aaefd077d493db80988f87f4f6a5fb Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 22 Jun 2026 12:56:51 -0400 Subject: [PATCH 20/21] updated by filter by length --- trigeminal_second_order.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index d62e10d..16331ee 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -811,7 +811,7 @@ for nsub_path in "${subject_list[@]}"; do echo "|------------- 6.3) ${nside} - DTTT (ipsilateral) - dPSN and CS -------------|" safe_filter_by_roi \ - "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv150.trk" \ + "${mni_tracking_dir_second_order}/orig/${nsub}_${nside}_from_spinal_track_npv300.trk" \ "${mni_tracking_dir_second_order}/filtered/${nsub}_from_${nside}_DTTT_Ipsilat_CS.trk" \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_spinal_density_second_order_seed_mni.nii.gz" 'either_end' 'include' \ --drawn_roi "${mni_rois_dir}/${nsub}_${nside}_VPM_mni.nii.gz" 'any' 'include' \ From 9793cb59abdb8894795ef3c9f00d00f599e72148 Mon Sep 17 00:00:00 2001 From: Nasrin Rafiei Date: Mon, 22 Jun 2026 14:32:52 -0400 Subject: [PATCH 21/21] updated by filter by length --- trigeminal_second_order.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trigeminal_second_order.sh b/trigeminal_second_order.sh index 16331ee..f7a43f1 100755 --- a/trigeminal_second_order.sh +++ b/trigeminal_second_order.sh @@ -66,9 +66,9 @@ shift $((OPTIND-1)) # ------------------------- # Parse optional long args # ------------------------- -npv_spinal_long_total=3000 -npv_spinal_short_total=300 -npv_thalamus_total=1500 +npv_spinal_long_total=1000 +npv_spinal_short_total=100 +npv_thalamus_total=500 while [[ $# -gt 0 ]]; do case "$1" in