Skip to content

Commit a8d8d8e

Browse files
updating fit
1 parent 375809b commit a8d8d8e

3 files changed

Lines changed: 699 additions & 0 deletions

File tree

rerun_pydesigner_fit_bids.sh

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# ============================================================
6+
# Batch rerun PyDesigner fitting-only script over BIDS subjects
7+
#
8+
# Expected layout from the original run_pydesigner_bids.sh:
9+
# BIDS_ROOT/
10+
# sub-*/dwi/*_dir-AP_dwi.nii.gz
11+
# sub-*/dwi/*_dir-PA_dwi.nii.gz
12+
# derivatives/dki/sub-*/dwi_preprocessed.nii[.gz]
13+
# derivatives/dki/sub-*/dwi_preprocessed.bvec
14+
# derivatives/dki/sub-*/dwi_preprocessed.bval
15+
# derivatives/dki/sub-*/brain_mask.nii[.gz]
16+
#
17+
# The new run_pydesigner_fit.py is then called on each subject's
18+
# preprocessed PyDesigner files.
19+
# ============================================================
20+
21+
# -----------------------------
22+
# User settings
23+
# -----------------------------
24+
25+
# Run from the BIDS root, or pass BIDS root as first argument:
26+
# ./rerun_pydesigner_fit_bids.sh /path/to/bids_root
27+
BIDS_ROOT="${1:-$(pwd)}"
28+
DERIV_ROOT="${DERIV_ROOT:-${BIDS_ROOT}/derivatives/dki}"
29+
30+
# Path to your updated fitting-only Python script.
31+
# Edit this or export FIT_SCRIPT=/path/to/run_pydesigner_fit.py before running.
32+
FIT_SCRIPT="${FIT_SCRIPT:-${BIDS_ROOT}/run_pydesigner_fit.py}"
33+
PYTHON_CMD="${PYTHON_CMD:-python}"
34+
35+
# New output subdirectory under each subject's derivatives/dki/sub-* folder.
36+
# Using a new folder avoids overwriting the original PyDesigner outputs.
37+
METRICS_DIR_NAME="${METRICS_DIR_NAME:-metrics_refit}"
38+
39+
# Fit options for run_pydesigner_fit.py
40+
NTHREADS="${NTHREADS:-8}"
41+
RES="${RES:-med}"
42+
LMAX_FBI="${LMAX_FBI:-6}"
43+
BVEC_FLIP_X="${BVEC_FLIP_X:-1}"
44+
BVEC_FLIP_Y="${BVEC_FLIP_Y:--1}"
45+
BVEC_FLIP_Z="${BVEC_FLIP_Z:-1}"
46+
47+
# Set these to 0 if you do not want them passed.
48+
DO_RECTIFY="${DO_RECTIFY:-1}"
49+
DO_FBWM="${DO_FBWM:-1}"
50+
51+
# Set DRY_RUN=1 to print commands without executing.
52+
DRY_RUN="${DRY_RUN:-0}"
53+
54+
# Set SKIP_IF_DONE=1 to skip subjects with existing key outputs.
55+
SKIP_IF_DONE="${SKIP_IF_DONE:-0}"
56+
57+
# -----------------------------
58+
# Helpers
59+
# -----------------------------
60+
61+
find_first() {
62+
local root="$1"
63+
shift
64+
65+
local pattern
66+
local hit
67+
for pattern in "$@"; do
68+
hit="$(find "${root}" -type f -name "${pattern}" -print | head -n 1 || true)"
69+
if [[ -n "${hit}" ]]; then
70+
echo "${hit}"
71+
return 0
72+
fi
73+
done
74+
75+
return 1
76+
}
77+
78+
require_file() {
79+
local label="$1"
80+
local file="$2"
81+
if [[ -z "${file}" || ! -f "${file}" ]]; then
82+
echo "[MISSING] ${label}: ${file:-not found}"
83+
return 1
84+
fi
85+
return 0
86+
}
87+
88+
# -----------------------------
89+
# Checks
90+
# -----------------------------
91+
92+
if [[ ! -d "${BIDS_ROOT}" ]]; then
93+
echo "[ERROR] BIDS_ROOT does not exist: ${BIDS_ROOT}"
94+
exit 1
95+
fi
96+
97+
if [[ ! -d "${DERIV_ROOT}" ]]; then
98+
echo "[ERROR] DERIV_ROOT does not exist: ${DERIV_ROOT}"
99+
echo " Did the original PyDesigner BIDS run finish?"
100+
exit 1
101+
fi
102+
103+
if [[ ! -f "${FIT_SCRIPT}" ]]; then
104+
echo "[ERROR] FIT_SCRIPT does not exist: ${FIT_SCRIPT}"
105+
echo " Edit FIT_SCRIPT in this script or export FIT_SCRIPT=/path/to/run_pydesigner_fit.py"
106+
exit 1
107+
fi
108+
109+
RECTIFY_FLAG=()
110+
FBWM_FLAG=()
111+
if [[ "${DO_RECTIFY}" == "1" ]]; then
112+
RECTIFY_FLAG=(--rectify)
113+
fi
114+
if [[ "${DO_FBWM}" == "1" ]]; then
115+
FBWM_FLAG=(--fbwm)
116+
fi
117+
118+
# -----------------------------
119+
# Main loop
120+
# -----------------------------
121+
122+
for SUB_DIR in "${BIDS_ROOT}"/sub-*; do
123+
if [[ ! -d "${SUB_DIR}" ]]; then
124+
continue
125+
fi
126+
127+
SUB_ID="$(basename "${SUB_DIR}")"
128+
RAW_DWI_DIR="${SUB_DIR}/dwi"
129+
PYD_DIR="${DERIV_ROOT}/${SUB_ID}"
130+
OUT_DIR="${PYD_DIR}/${METRICS_DIR_NAME}"
131+
LOG_DIR="${PYD_DIR}/logs"
132+
LOG_FILE="${LOG_DIR}/fit_rerun_${SUB_ID}.log"
133+
134+
echo "============================================================"
135+
echo "Subject: ${SUB_ID}"
136+
echo "Raw DWI dir : ${RAW_DWI_DIR}"
137+
echo "PyDesigner deriv dir: ${PYD_DIR}"
138+
echo "Refit output : ${OUT_DIR}"
139+
echo "============================================================"
140+
141+
if [[ ! -d "${RAW_DWI_DIR}" ]]; then
142+
echo "[SKIP] Missing raw BIDS DWI directory: ${RAW_DWI_DIR}"
143+
echo
144+
continue
145+
fi
146+
147+
if [[ ! -d "${PYD_DIR}" ]]; then
148+
echo "[SKIP] Missing PyDesigner derivative directory: ${PYD_DIR}"
149+
echo
150+
continue
151+
fi
152+
153+
DWI="$(find_first "${PYD_DIR}" "dwi_preprocessed.nii" "dwi_preprocessed.nii.gz" || true)"
154+
BVEC="$(find_first "${PYD_DIR}" "dwi_preprocessed.bvec" || true)"
155+
BVAL="$(find_first "${PYD_DIR}" "dwi_preprocessed.bval" || true)"
156+
MASK="$(find_first "${PYD_DIR}" "brain_mask.nii" "brain_mask.nii.gz" || true)"
157+
158+
missing=0
159+
require_file "preprocessed DWI" "${DWI}" || missing=1
160+
require_file "preprocessed bvec" "${BVEC}" || missing=1
161+
require_file "preprocessed bval" "${BVAL}" || missing=1
162+
require_file "brain mask" "${MASK}" || missing=1
163+
if [[ "${missing}" == "1" ]]; then
164+
echo "[SKIP] Required fitting inputs not found for ${SUB_ID}"
165+
echo
166+
continue
167+
fi
168+
169+
mkdir -p "${OUT_DIR}" "${LOG_DIR}"
170+
171+
if [[ "${SKIP_IF_DONE}" == "1" ]]; then
172+
if [[ -f "${OUT_DIR}/dti_fa.nii" || -f "${OUT_DIR}/dki_mk.nii" || -f "${OUT_DIR}/fbi_faa.nii" ]]; then
173+
echo "[SKIP] Existing refit outputs found in ${OUT_DIR}"
174+
echo
175+
continue
176+
fi
177+
fi
178+
179+
CMD=(
180+
"${PYTHON_CMD}" "${FIT_SCRIPT}"
181+
--dwi "${DWI}"
182+
--bvec "${BVEC}"
183+
--bval "${BVAL}"
184+
--mask "${MASK}"
185+
--out "${OUT_DIR}"
186+
--nthreads "${NTHREADS}"
187+
--res "${RES}"
188+
--lmax-fbi "${LMAX_FBI}"
189+
"${RECTIFY_FLAG[@]}"
190+
"${FBWM_FLAG[@]}"
191+
--bvec-flips "${BVEC_FLIP_X}" "${BVEC_FLIP_Y}" "${BVEC_FLIP_Z}"
192+
)
193+
194+
echo "[RUN] Fitting-only PyDesigner rerun for ${SUB_ID}"
195+
echo "[LOG] ${LOG_FILE}"
196+
echo "Command:"
197+
printf ' %q' "${CMD[@]}"
198+
echo
199+
200+
if [[ "${DRY_RUN}" == "1" ]]; then
201+
echo "[DRY RUN] Command not executed."
202+
echo
203+
continue
204+
fi
205+
206+
{
207+
echo "Started: $(date)"
208+
echo "Subject: ${SUB_ID}"
209+
echo "DWI : ${DWI}"
210+
echo "BVEC: ${BVEC}"
211+
echo "BVAL: ${BVAL}"
212+
echo "MASK: ${MASK}"
213+
echo "OUT : ${OUT_DIR}"
214+
echo "Command:"
215+
printf ' %q' "${CMD[@]}"
216+
echo
217+
echo
218+
219+
"${CMD[@]}"
220+
221+
echo
222+
echo "Finished: $(date)"
223+
} 2>&1 | tee "${LOG_FILE}"
224+
225+
echo "[DONE] ${SUB_ID}"
226+
echo
227+
done
228+
229+
echo "All available subjects processed."

0 commit comments

Comments
 (0)