-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdistortionCorrection.sh
executable file
·369 lines (320 loc) · 11.7 KB
/
distortionCorrection.sh
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
#!/bin/bash
#
# Code to do calculation the distorion
# correction utilizing the ANIMA Software
#
# Robert Welsh
# 2018-04-24
# 2018-08-09
# 2018-08-28 -- fixed to actually work with nii.gz files, and can be in any
# working directory.
# 2018-08-29 -- point to Anima 3.1
# 2021-03-16 -- stop pointing to Anima and hope they have it defined.
# 2021-03-17 -- part of spm12Batch now.
#
# Release 1.2
#
#
# Using the ANIMA that is in the path.
#
# https://github.com/Inria-Visages/Anima-Public/wiki/Registration-tools
#
# Anima must be installed, and the environmental variable SCRIPTSDIR
# needs to be assigned below.
#
# A log of the work is placed in a hidden file called .distortionCorrectionLog
#
# The following files are needed, either specified or determined by the code
#
# run file -- this is the file to be corrected and has the same
# phase encode polarity as the forward image. In fact,
# If no forward image is specified, this image will be used
# as the forward image -- which is normal behavior.
#
# backward -- this is the file that has everything identical to the
# run/forward file except for the polarity of the phase-encode
# blip is opposite
#
# forward -- either defaults to point to the run file or a separate file.
#
# If you have a forward and backward file in the same directory as the run file
# that are called:
#
# *AP* for the backward file
# *PA* for the forward file
#
# Also, this code can handle nifti or nifti-gz files, BUT the file extension
# MUST be specified.
#
# The distortion correction is a multi-step process.
#
# Step 1)
#
# estimate the distortion correction using animaDistortionCorrection
#
# output of distortion correction to : ${RUNFILE}_Correction.nii
#
# Step 2)
#
# application of this correction to the forward image to assess quality
#
# output corrected forward file to first order : dc_1st_${FORWARD}
#
# Step 3)
#
# refinement of the distortation correction using animageBMDistortionCorrection
#
# output of distortion correction to : ${RUNFILE}_Correction.nii
#
# Step 4)
#
# appplication of the resulting correction of Step 3) to the original run file.
#
#
# Setup
function echol(){
DATE=`date`
echo "${DATE} : ${USER} : $1" >> .distortionCorrectionLog
echo "${DATE} : ${USER} : $1"
}
DATE=`date`
VERSION=1.3
# Point to the Anima binaries.
ANIMACOMMAND=`which animaBMDistortionCorrection`
if [ -z "${ANIMACOMMAND}" ]
then
echo
echo FATAL -- CANNOT FIND ANIMA
echo
exit 1
fi
SCRIPTSDIR=`dirname ${ANIMACOMMAND}`
# ------------ SETUP TO RUN NOW ---------------------
RUNNII=$1
# Did they pass anything?
if [ -z "${RUNNII}" ]
then
echo
echo "distortionCorrection.sh [run nifti file] [[backward image]] [[forward image]] [[outputName]]"
echo
echo " Code to utilize the ANIMA distortion correction routines."
echo " Based on https://github.com/Inria-Visages/Anima-Public/wiki/Registration-tools"
echo
echo " [run nifti file] -- nifti file to correct"
echo " [[backward image]] -- will automatically look for a AP image if"
echo " nothing specified"
echo " [[forward image]] -- will automatically look for a PA image if"
echo " nothing specified"
echo " however, if one is not found, then we will"
echo " assume the [run nifti file] is the forward"
echo " image."
echo " [[outputName]] -- to override using \"dc_\""
echo
echo " The output will go to the current working directory."
echo
echo " The [run nifti file] and the [[forward image]] are acquired with the same"
echo " polarity of the phase encode blips, while [[backward image]] has the"
echo " opposite polarity."
echo
echo " A important criteria is that the headers of the two images must match exactly".
echo " Sometimes dcm2nii results in headers that differ in the last decimal -- while "
echo " not relevant to neuroimaging processsing -- but Anima will refuse to work "
echo " with the images unless they match exactly. This uses fslcpgeom and dd to fix this issue."
echo
echo " Also, the order this should take place in the pre-processing steam is a "
echo " scientific question. Movement can effect distortion, but in the limit that "
echo " motion is non-existent, then motion correction could take place first."
echo
echo " Make backups of everthing!"
echo
echo "Robert Welsh - [email protected]"
echo "2021-03-16 Version:${VERSION}"
echo
exit 1
fi
# Get the backward and forward image parameters.
echol "Using the run file ${RUNNII}"
BACKWARD=$2
FORWARD=$3
# check the backward image
if [ -z "${BACKWARD}" ]
then
nBACKWARD=`ls *AP*.nii 2> /dev/null | wc -l `
if [ ${nBACKWARD} != 1 ]
then
echo
echo "Either too make AP images or none to be found"
echo
exit 1
fi
BACKWARD=`ls *AP*.nii`
else
if [ ! -e "${BACKWARD}" ]
then
echo
echo "The backward image you specified does not exist : ${BACKWARD}"
echo
exit 1
fi
fi
echol "Backward image is ${BACKWARD}"
# check the backward image
if [ -z "${FORWARD}" ]
then
nFORWARD=`ls *PA*.nii 2> /dev/null | wc -l `
if [ ${nFORWARD} -gt 1 ]
then
echo
echo "Too many forward images."
echo
exit 1
fi
if [ ${nFORWARD} == 1 ]
then
FORWARD=`ls *PA*.nii`
else
echol "Using the run file as the forward file"
FORWARD=${RUNNII}
fi
else
if [ ! -e "${FORWARD}" ]
then
echo
echo "The forward image you specified does not exist : ${FORWARD}"
echo
exit 1
fi
fi
echol "Forward image is ${FORWARD}"
# Now make sure that the forward and backward images are different!
if [ ${FORWARD} == ${BACKWARD} ]
then
echol "FATAL you specified the same file for the forward and the backward image, that is impossible"
echo
exit 1
fi
# Now see if they passed a prepend name
if [ -z "$4" ]
then
outputName=dc_
else
outputName=$4
fi
# Now get the basenames so that we can be in a different working directory than the actual files.
RUNNIIBASE=`basename ${RUNNII}`
BACKWARDBASE=`basename ${BACKWARD}`
FORWARDBASE=`basename ${FORWARD}`
RUNNIIBASENAME=`echo ${RUNNIIBASE} | sed -e's/\.nii//g' | sed -e 's/\.gz//g'`
FORWARDBASENAME=`echo ${FORWARDBASE} | sed -e's/\.nii//g' | sed -e 's/\.gz//g'`
# Put some output out.
echol "Distortion correcton log is .distortionCorrectionLog"
echol " Starting distortion correction by ${USER}"
echol " Configured as"
echol " RUN : ${RUNNII}"
echol " BACKWARD : ${BACKWARD}"
echol " FORWARD : ${FORWARD}"
echol " OUTPUT : ${outputName}${RUNNIIBASENAME}.nii"
echol " Code Version : ${VERSION}"
echol " Anima Version : ${SCRIPTSDIR}"
echol " -----------------------------------------------"
# Check the geometry of the files to make sure they all match.
# Jump forward 252 bytes and dump 76 bytes, which is where all of the
# geometry lives.
od -h -j 252 -N 76 ${RUNNII} &> .geometry1
od -h -j 252 -N 76 ${BACKWARD} &> .geometry2
od -h -j 252 -N 76 ${FORWARD} &> .geometry3
df1=`diff .geometry1 .geometry2 -q | wc -l | awk '{print $1}'` # run and backward
df2=`diff .geometry1 .geometry3 -q | wc -l | awk '{print $1}'` # run and forward
df3=`diff .geometry2 .geometry3 -q | wc -l | awk '{print $1}'` # forward and backward
fileDiffs=$(( ${df1} + ${df2} + ${df3} ))
if [ ${fileDiffs} -ne 0 ]
then
if [ ${df1} -ne 0 ]
then
df1="<>"
else
df1="="
fi
if [ ${df2} -ne 0 ]
then
df2="<>"
else
df2="="
fi
if [ ${df3} -ne 0 ]
then
df3="<>"
else
df3="="
fi
echol "FATAL File geometries do not match! Currently "
echol " [run]${df1}[backward], [run]${df2}[forward], [backward]${df3}[forward]"
echol "Consider using fslcpgeom to make them match. It is recommended"
echol "to copy the geometry as "
echol " [runfile]->[forward],"
echol " [runfile]->[backward]"
echol "as necessary. Consider using assertGeometry.sh"
echo
exit 1
fi
# Step 1
echol "${SCRIPTSDIR}/animaDistortionCorrection -o ${RUNNIIBASENAME}_Correction.nii -d 1 -b ${BACKWARD} -f ${FORWARD}"
${SCRIPTSDIR}/animaDistortionCorrection -o ${RUNNIIBASENAME}_Correction.nii -d 1 -b ${BACKWARD} -f ${FORWARD} >> .distortionCorrectionLog 2>&1
if [ $? != 0 ]
then
echol "FAILED animaDistortionCorrection"
echo
exit 1
fi
# Now assert the geometry
echol "dd if=${RUNNII} of=${RUNNIIBASENAME}_Correction.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat"
dd if=${RUNNII} of=${RUNNIIBASENAME}_Correction.nii bs=1 skip=252 count=76 seek=252 conv=notrunc
#dd if=${RUNNII} of=${RUNNIIBASENAME}_Correction.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat
# Step 2
echol "${SCRIPTSDIR}/animaApplyDistortionCorrection -f ${FORWARD} -t ${RUNNIIBASENAME}_Correction.nii -o ${outputName}1st_${FORWARDBASENAME}.nii"
${SCRIPTSDIR}/animaApplyDistortionCorrection -f ${FORWARD} -t ${RUNNIIBASENAME}_Correction.nii -o ${outputName}1st_${FORWARDBASENAME}.nii >> .distortionCorrectionLog 2>&1
if [ $? != 0 ]
then
echol "FAILED animaApplyDistortionCorrection"
echo
exit 1
fi
# Now assert the geometry
echol "dd if=${RUNNII} of=${outputName}1st_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat"
dd if=${RUNNII} of=${outputName}1st_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc
#dd if=${RUNNII} of=${outputName}1st_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat
# Step 3
echol "${SCRIPTSDIR}/animaBMDistortionCorrection -f ${FORWARD} -b ${BACKWARD} -i ${RUNNIIBASENAME}_Correction.nii -O ${RUNNIIBASENAME}_BMCorrection.nii -o ${outputName}test_${FORWARDBASENAME}.nii"
${SCRIPTSDIR}/animaBMDistortionCorrection -f ${FORWARD} -b ${BACKWARD} -i ${RUNNIIBASENAME}_Correction.nii -O ${RUNNIIBASENAME}_BMCorrection.nii -o ${outputName}2nd_${FORWARDBASENAME}.nii >> .distortionCorrectionLog 2>&1
if [ $? != 0 ]
then
echol "FAILED animaBMDistortionCorrection"
echo
exit 1
fi
# Now assert the geometry
echol "dd if=${RUNNII} of=${RUNNIIBASENAME}_BMCorrection.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat"
dd if=${RUNNII} of=${RUNNIIBASENAME}_BMCorrection.nii bs=1 skip=252 count=76 seek=252 conv=notrunc
#dd if=${RUNNII} of=${RUNNIIBASENAME}_BMCorrection.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat
echol "dd if=${RUNNII} of=${outputName}2nd_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat"
dd if=${RUNNII} of=${outputName}2nd_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc
#dd if=${RUNNII} of=${outputName}2nd_${FORWARDBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat
# Step 4
echol "${SCRIPTSDIR}/animaApplyDistortionCorrection -f ${RUNNII} -t ${RUNNIIBASENAME}_BMCorrection.nii -o ${outputName}${RUNNIIBASENAME}.nii"
${SCRIPTSDIR}/animaApplyDistortionCorrection -f ${RUNNII} -t ${RUNNIIBASENAME}_BMCorrection.nii -o ${outputName}${RUNNIIBASENAME}.nii >> .distortionCorrectionLog 2>&1
if [ $? != 0 ]
then
echol "FAILED animaApplyDistortionCorrection"
echo
exit 1
fi
# Now assert the geometry
echol "dd if=${RUNNII} of=${outputName}${RUNNIIBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat"
dd if=${RUNNII} of=${outputName}${RUNNIIBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc
#dd if=${RUNNII} of=${outputName}${RUNNIIBASENAME}.nii bs=1 skip=252 count=76 seek=252 conv=notrunc,nocreat
echol "Distortion correction completed with output file : ${outputName}${RUNNIIBASENAME}.nii"
echo
#
# all done
#