-
Notifications
You must be signed in to change notification settings - Fork 1
/
preprocessDistortion
executable file
·238 lines (204 loc) · 8.07 KB
/
preprocessDistortion
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#!/usr/bin/env bash
set -eo pipefail
ppdistortion_usage() {
cat >&2 <<HEREDOC
USAGE:
preprocessDistortion -phasedir path/to/fm_phase_dicoms/ -magdir path/to/fm_mag_dicoms/ -fm_cfg protocol_cfg [-mrpatt "MR*" ] [-savedir $(pwd) ] [-reverse]
manditory:
-phasedir and -magdir || -mag and -phase || -mag -real -complex || -niidir
-fm_cfg info about protocols, mabye optional
optional:
-mrpatt what dicoms look like
-savedir where to save outputs
-reverse NCANDA reverse (all but site C)
-method gre.nii.gz,gre,NCANDA,BIDSFM
HEREDOC
exit 1
}
# get all the things we need
sourceall() {
local scriptdir=$(dirname $0)
local sourcedir=$scriptdir/preproc_functions
[ ! -d $sourcedir ] && echo "bad source dir! $sourcedir" >&2 && exit 1
for f in convert_or_use_nii waitforlock prepare_gre_fieldmap \
helper_functions preprare_fieldmap_ge_complex;do
source $sourcedir/$f
done
}
val2ARG(){ local s="$1"; s=${s:1}; s=${s^^}; echo "$s";}
set_method(){
[ -n "$METHOD" ] && return 0
local sep="xxxxxxxxx"
local all_ge=$MAG$sep$COMPLEX$sep$REAL$sep
# just mag is okay. but complex or real without the other 2 is a problem
[[ $all_ge =~ $sep$sep ]] && ! [[ $all_ge =~ ^$sep$sep$sep$ ]] &&
exiterr "GE needs all -mag -complex and -real"
## set METHOD
# 20191107: only gre (Siemens, Hallquist) and ge (NCANDA)
# BIDSFM works for siemens ncanda. might work for BIDS too
[[ $all_ge =~ ^$sep$sep$sep$ ]] && METHOD="gre" || METHOD="ge"
# NIIDIR is setup to be NCANDA raw dir
# but might be adapted for BIDS compatible directory
if [[ -n "$NIIDIR" ]]; then
# if we have a "real" nifti file it's ncanda
[ -n "$(find "$NIIDIR" -maxdepth 1 -iname '*real*nii*'\
\( -type f -or -type l \) -print -quit)" ] &&
METHOD="NCANDA" ||
METHOD="BIDSFM" # TODO: does this work for actual bids spec?
fi
}
say_globals(){
# for debuging, print settings
for var in REVERSE NIIDIR PHASEDIR MAGDIR MAG PHASE\
REAL COMPLEX FM_CFG MRPATT SAVEDIR METHOD; do
[ -z "${!var}" ] && continue
eval 'echo '"$var"': ${'"$var"'[@]}'
done
}
parsenewargs(){
local setting=""
local val=""
[ $# -lt 1 ] && ppdistortion_usage;
while [ -n "$1" ]; do
case "$1" in
-h|-help) ppdistortion_usage;;
-r|-reverse) REVERSE="1"; shift ;;
# 20201016 added mag back, add method
-phasedir|-magdir|-mag|-phase|-fm_cfg|-mrpatt|-savedir|-niidir|-method)
setting="$(val2ARG "$1")"
val="$2"
# remove default unless value could be an array arg
! [[ $setting =~ MAG|REAL|COMPLEX ]] && unset $setting;
shift 2;;
-*) exiterr "unkown switch '$1'";;
*)
# if not -arg, add to the last -arg given
[ -z "$setting" ] && exiterr "dont know what to set as '$1'";
val="$1"
shift
;;
esac
if [ -z "${!setting}" ]; then
# everything is an array. if only one item e.g. $MAGDIR will get it
# NB. -ag will not work in bash 4. need bash 5
eval "declare -ag $setting=\"$val\"";
else
# not sure if there is another way to extend an array with varaible name
# using mixed '' and "" like 'literal '"$intereted"' more litteral'
eval "declare -ag $setting"'=(${'"$setting"'[@]}'" $val )"
fi
done
# sanity check
[ -n "$PHASEDIR" -a -n "$PHASE" ] && exiterr "give -phase or -phasedir, not both"
[ -n "$MAGDIR" -a -n "$MAG" ] && exiterr "give -mag or -magdir, not both"
[ -n "$NIIDIR" -a -n "$MAG" ] && exiterr "-niidir only if no other nifitis to provide"
[ -n "$PHASEDIR" -o -n "$PHASE" ] && [ -n "$COMPLEX" -o -n "$REAL" ] &&
exiterr "phase cannot be used with complex/real"
set_method
say_globals
}
testExpected() {
# return true if all expected files exist
# global EXPECT,HAVEEXPECT, SAVEDIR
HAVEEXPECT=()
for f in "${EXPECT[@]}"; do
[ -r "$SAVEDIR/$f" ] && HAVEEXPECT=(${HAVEEXPECT[@]} $f)
done
[ ${#HAVEEXPECT[@]} -eq ${#EXPECT[@]} ]
}
_preprocessDistortion() {
starttime=$(date +%s)
# optional defaults
SAVEDIR=$(pwd)
MRPATT="MR*"
REVERSE="0"
# helperFunctions uses this for rel
export logFile="preprocessDistortion.log"
## prepare
# get functions and args
sourceall
parsenewargs "$@"
# needed for some functions
export fm_cfg="$FM_CFG"
## did we already finish?
# EXPECT=( FM_UD_fmap_mag{,_brain}.nii.gz \
# unwarp/FM_UD_fmap{,_mag}.nii.gz \
# .fieldmap_{magnitude,phase} )
EXPECT=( FM_UD_fmap_mag{,_brain}.nii.gz \
unwarp/FM_UD_fmap{,_mag}.nii.gz )
testExpected && echo "skipping '$SAVEDIR'; have all final files: ${HAVEEXPECT[@]}" && exit 0
local theseargs="$@"
rel "RUNNING: $0 $theseargs" c
if [ ${#HAVEEXPECT[@]} -gt 0 ] ; then
rel "rm -r $SAVEDIR; # and try again; have ${#HAVEEXPECT[@]}/${#EXPECT[@]} expected files: ${HAVEEXPECT[@]}" c
exit 1
fi
[ -r "$SAVEDIR/phase" -o -r "$SAVEDIR/mag" ] &&
rel "have $SAVEDIR/{phase,mag} but did not run prepare, remove $SAVEDIR and try again?" c && exit 1
## get files
[ -z "$SAVEDIR" ] && echo "ERROR missing SAVEDIR!" && return 1
[ ! -d $SAVEDIR ] && mkdir $SAVEDIR
SAVEDIR="$(readlink -f "$SAVEDIR")"
# functions create unwarp and cd into it
case $METHOD in
gre.nii.gz)
cd $SAVEDIR
prepare_gre_fieldmap "$MAG" "$PHASE"
;;
gre)
magdir="$MAGDIR"
phasedir="$PHASEDIR"
[ -z "$magdir" -o -z "$phasedir" ] && echo "ERROR: no magdir or phasedir!? $magdir $phasedir" && return 1
rel "cp -r \"$magdir\" \"$SAVEDIR/mag\" "
rel "cp -r \"$phasedir\" \"$SAVEDIR/phase\" "
cd $SAVEDIR
# run
fm_phase="phase/$MRPATT"
fm_magnitude="mag/$MRPATT"
prepare_gre_fieldmap
;;
NCANDA)
NIIDIR="$(readlink -f $NIIDIR)"
cd $SAVEDIR
prepare_fieldmap_ge_complex "$NIIDIR" $REVERSE
;;
BIDSFM)
NIIDIR="$(readlink -f $NIIDIR)"
cd $SAVEDIR
# TODO: look for json that has "intended for" instead of just using the first
# take the first mag
mag=$(find $NIIDIR -maxdepth 1 \( -type f -or -type l \) -iname '*mag*.nii.gz' -print -quit)
# and first phase
phase=$(find $NIIDIR -maxdepth 1 \( -type f -or -type l \) -iname '*phase*.nii.gz' -print -quit)
[ -z "$mag" -o -z "$phase" ] && exiterr "cant find phase and mag nii.gz in $NIIDIR!"
prepare_gre_fieldmap $mag $phase
;;
*)
exiterr "unknown unwarp method '$METHOD'";
esac
# all methods should drop into "unwarp"
! [[ $(basename $(pwd)) == unwarp ]] && exiterr "w/'$METHOD': in cwd '$(pwd)' is not 'unwarp' directory"
# bet'ed brain needs to be in unwarp directory
[ ! -r FM_UD_fmap_mag_brain.nii.gz -a -r ../FM_UD_fmap_mag_brain.nii.gz ] &&
cp ../FM_UD_fmap_mag_brain.nii.gz ./
[ ! -r FM_UD_fmap_mag_brain.nii.gz ] &&
echo "WARNING: missing $(pwd)/FM_UD_fmap_mag_brain.nii.gz !"
# also need the FM_UD from fm_phase -- actually have it already!
#[ -r fm_phase/FM_UD_fmap.nii.gz -a -d unwarp ] && cp fm_phase/FM_UD_fmap.nii.gz unwarp/
# copy config to save directory
fmcfgfile=$(find_fmconfig $FM_CFG)
[ -z "$fmcfgfile" -o ! -r "$fmcfgfile" ] && exiterr "cannot find config file '$FM_CFG', how did the above work!?"
rel "cp $fmcfgfile $SAVEDIR/unwarp/fm.cfg"
! testExpected && echo "DID NOT FINISH '$SAVEDIR'; have ${HAVEEXPECT[@]}, want ${EXPECT[@]}" && exit 1
# all done
rel "$(date) Finished distortion preprocessing" c
# write git version in completed file flag
command -v preprocessDistortion || return 0 # if sourcing, this doesn't makes sense
gitver=$(cd $(dirname $(which preprocessDistortion )); git log --pretty=format:'%ci %h' -n 1)
echo -e "$gitver\t$(date +%FT%H:%M)\t$(whoami)@$(hostname)\t$starttime\t$(date +%s)" > $SAVEDIR/.preprocessDistortion_complete
}
# if we did not source this file
# but ran it like ./preprocessDistortion
# actually run
[ $(basename $0 ) == "preprocessDistortion" ] &&
_preprocessDistortion "$@"