-
Notifications
You must be signed in to change notification settings - Fork 2
/
tedana_deriv
executable file
·134 lines (107 loc) · 4.1 KB
/
tedana_deriv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env bash
#
# run tendana from minimally preprocessed:
# fmriprep --me-output-echos
# also warp
#
# 20230120WF - init
# 20230207WF - mni for both optcom and optcomDenoised
#
tedana_from_echo1(){
outdir=$(dirname "$f")
prefix=$(basename "$f" _echo-1_desc-preproc_bold.nii.gz)
! [[ "$prefix" =~ sub-[^_]*_ses-[^_]* ]] && warn "nos sub-*_ses- in '$prefix'" && return 2
sub_ses=${BASH_REMATCH[0]}
tedana_mni="$outdir/${prefix}_space-MNI152NLin2009cAsym_desc-optcomDenoised_bold.nii.gz"
test -r "$tedana_mni" &&
warn "# already finished. have '$_'" && return 0
! python -c 'import tedana' &&
warn "tedana not available! 'pip install tedana --user'" && exit 22
# warping files
transform_nonlin="${outdir/func/anat}/${sub_ses}_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5"
transform_lin="$outdir/${prefix}_from-scanner_to-T1w_mode-image_xfm.txt"
# this is high res mniref of t1 (likely 1mm^3)
#mniref="${outdir/func/anat}/${sub_ses}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
# this is lower res w/epi dims. using mask for 3D. 4D preproc_bold as ref messes with transform
mniref="${outdir}/${prefix}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
# this is probably not the correct file to use!
sdc_nonlin_all=("${outdir/func/fmap}/${sub_ses}_"fmap*_desc-coeff_fieldmap.nii.gz)
sdc_nonlin="${sdc_nonlin_all[0]}"
# exit early if we can't warp. dont run tedana over and over again
# alterantively. only run tedana if we haven't?
for v in transform_nonlin transform_lin mniref `: sdc_nonlin`; do
test -z "${!v}" -o ! -r "${!v}" && warn "cannot find $v like '$_'" && return 3
done
#shellcheck disable=2206 # no spaces in fmriprep deriv path or we're in trouble
echos=(${f/echo-1/echo-*})
mapfile -t echotimes < <(jq .EchoTime*1000 "${echos[@]/.nii.gz/.json}")
# todo: echos == echotimes
tedana_epi="$outdir/${prefix}_desc-optcomDenoised_bold.nii.gz"
dryrun \
niinote "$tedana_epi" \
tedana \
--out-dir "$outdir" --prefix "$prefix" \
--convention bids \
-e "${echotimes[@]}" \
-d "${echos[@]}" || return 1
test -r tedana_report.html && dryrun mv "$_" "${prefix}_$_"
# define function (closure -- use top level function local vars)
warp_tedana() {
local in="$1"; shift # tedana_epi
local out="$1"; shift # $tedana_mni
dryrun \
niinote "${out}" \
antsApplyTransforms \
-d 3 -e 3 -v \
-i "$in" \
--output "$out" \
--reference-image "$mniref" \
--transform "$transform_nonlin" \
--transform "$transform_lin" \
#--transform "$sdc_nonlin" \
dryrun 3drefit -space MNI "${out}"
}
# todo warp to MNI
# https://brainhack-princeton.github.io/handbook/content_pages/04-03-registration.html
# warping both optcomDenoised and optcom
warp_tedana "$tedana_epi" "$tedana_mni"
warp_tedana "$outdir/${prefix}_desc-optcom_bold.nii.gz"\
"$outdir/${prefix}_space-MNI152NLin2009cAsym_desc-optcom_bold.nii.gz"
# TODO: gsr, wm, csf
#3droistats -mask
}
tedana_main() {
if [[ $# -eq 0 || "${1:-}" =~ ^-h ]]; then
cat <<-EOF
USAGE:
$0 all # looks in deriv/ for fmriprep output
$0 deriv/sub-XXX/ses-YYY/func/*_task-*_run-*_echo-1_desc-preproc_bold.nii.gz
runs tedana for all echos in sequence of each given '*echo-1*.nii.gz' file
OUTPUT:
*_space-MNI152NLin2009cAsym_desc-optcomDenoised_bold.nii.gz
TODO:
* confirm optcomDenoise is ideal output (continue to avoid --gscontrol mir)
* apply SDC?
* recalc gsr, csf, wm, ... in _desc-confounds_timeseries.tsv?
EOF
exit 1
fi
[ "$1" == "all" ] &&
FILES=(deriv/sub-*/ses-*/func/*_task-*_run-*_echo-1_desc-preproc_bold.nii.gz) ||
FILES=("$@")
for f in "${FILES[@]}"; do
[[ ! $f =~ echo-1 ]] && warn "ERROR: bad input file. no echo-1 in '$f'" && continue
tedana_from_echo1 "$f"
break
done
return 0
}
# if not sourced (testing), run as command
eval "$(iffmain "tedana_main")"
####
# testing with bats. use like
# bats ./01.2_tedana.bash --verbose-run
####
tedana_main_test() { #@test
return 1
}