|
0 |
#!/bin/bash
|
|
1 |
# Copyright 2022. Martin Uecker.
|
|
2 |
# All rights reserved. Use of this source code is governed by
|
|
3 |
# a BSD-style license which can be found in the LICENSE file.
|
|
4 |
#
|
|
5 |
# Author:
|
|
6 |
# 2022 Nick Scholand <scholand@tugraz.at>
|
|
7 |
#
|
|
8 |
# Creation of digital reference object.
|
|
9 |
|
|
10 |
set -e
|
|
11 |
|
|
12 |
LOGFILE=/dev/stdout
|
|
13 |
KSPACE=false
|
|
14 |
SENS=1
|
|
15 |
ROT_ANGLE=0
|
|
16 |
ROT_STEPS=1
|
|
17 |
GEOM=NIST
|
|
18 |
|
|
19 |
title=$(cat <<- EOF
|
|
20 |
Digital Reference Object
|
|
21 |
EOF
|
|
22 |
)
|
|
23 |
|
|
24 |
helpstr=$(cat <<- EOF
|
|
25 |
-S \t\t Diagnostic Sonar geometry (NIST phantom is default)
|
|
26 |
-k \t\t simulate in k-space
|
|
27 |
-a d \t\t angle of rotation
|
|
28 |
-r d \t\t number of rotation steps
|
|
29 |
-s d \t\t number of simulated coils
|
|
30 |
-t <traj> \t define custom trajectory file
|
|
31 |
-l \t\t logfile
|
|
32 |
-h \t\t help
|
|
33 |
|
|
34 |
Please adjust simulation parameters inside the script.
|
|
35 |
EOF
|
|
36 |
)
|
|
37 |
|
|
38 |
usage="Usage: $0 [-h] [-k] [-r d] [-s d] [-t <traj>] <output>"
|
|
39 |
|
|
40 |
echo "$title"
|
|
41 |
echo
|
|
42 |
|
|
43 |
while getopts "hSka:r:s:t:l:" opt; do
|
|
44 |
case $opt in
|
|
45 |
h)
|
|
46 |
echo "$usage"
|
|
47 |
echo
|
|
48 |
echo -e "$helpstr"
|
|
49 |
exit 0
|
|
50 |
;;
|
|
51 |
S)
|
|
52 |
GEOM=SONAR
|
|
53 |
;;
|
|
54 |
k)
|
|
55 |
KSPACE=true
|
|
56 |
;;
|
|
57 |
a)
|
|
58 |
ROT_ANGLE=$OPTARG
|
|
59 |
;;
|
|
60 |
r)
|
|
61 |
ROT_STEPS=$OPTARG
|
|
62 |
;;
|
|
63 |
s)
|
|
64 |
SENS=$OPTARG
|
|
65 |
;;
|
|
66 |
t)
|
|
67 |
TRAJ=$(readlink -f "$OPTARG")
|
|
68 |
;;
|
|
69 |
l)
|
|
70 |
LOGFILE=$(readlink -f "$OPTARG")
|
|
71 |
;;
|
|
72 |
\?)
|
|
73 |
echo "$usage" >&2
|
|
74 |
exit 1
|
|
75 |
;;
|
|
76 |
esac
|
|
77 |
done
|
|
78 |
|
|
79 |
shift $((OPTIND - 1))
|
|
80 |
|
|
81 |
if [ $# != 1 ] ; then
|
|
82 |
|
|
83 |
echo "$usage" >&2
|
|
84 |
exit 1
|
|
85 |
fi
|
|
86 |
|
|
87 |
|
|
88 |
export PATH=$TOOLBOX_PATH:$PATH
|
|
89 |
|
|
90 |
if [ ! -e $TOOLBOX_PATH/bart ] ; then
|
|
91 |
echo "\$TOOLBOX_PATH is not set correctly!" >&2
|
|
92 |
exit 1
|
|
93 |
fi
|
|
94 |
|
|
95 |
|
|
96 |
output=$(readlink -f "$1")
|
|
97 |
|
|
98 |
|
|
99 |
# Tests for usefull input
|
|
100 |
|
|
101 |
if [ ! -z "${TRAJ}" ] && [ "$KSPACE" = false ]; then
|
|
102 |
|
|
103 |
echo "Trajectory only works in k-space domain. Please add [-k]!" >&2
|
|
104 |
exit 1
|
|
105 |
fi
|
|
106 |
|
|
107 |
|
|
108 |
#WORKDIR=$(mktemp -d)
|
|
109 |
# Mac: http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x
|
|
110 |
WORKDIR=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
|
|
111 |
trap 'rm -rf "$WORKDIR"' EXIT
|
|
112 |
cd $WORKDIR
|
|
113 |
|
|
114 |
|
|
115 |
# start group for redirection of output to the logfile
|
|
116 |
{
|
|
117 |
|
|
118 |
case $GEOM in
|
|
119 |
|
|
120 |
NIST)
|
|
121 |
echo "NIST Phantom Geometry"
|
|
122 |
echo "T2 Sphere of Model 130"
|
|
123 |
echo "Relaxation Paramters for 3 T"
|
|
124 |
echo ""
|
|
125 |
|
|
126 |
## Relaxation parameters for T2 Sphere of NIST phantom at 3 T (Model 130)
|
|
127 |
## Stupic, KF, Ainslie, M, Boss, MA, et al.
|
|
128 |
## A standard system phantom for magnetic resonance imaging.
|
|
129 |
## Magn Reson Med. 2021; 86: 1194– 1211. https://doi.org/10.1002/mrm.28779
|
|
130 |
T1=(3 2.48 2.173 1.907 1.604 1.332 1.044 0.802 0.609 0.458 0.337 0.244 0.177 0.127 0.091)
|
|
131 |
T2=(1 0.581 0.404 0.278 0.191 0.133 0.097 0.064 0.046 0.032 0.023 0.016 0.011 0.008 0.006)
|
|
132 |
;;
|
|
133 |
|
|
134 |
SONAR)
|
|
135 |
echo "Diagnostic Sonar Phantom Geometry"
|
|
136 |
echo "Eurospin II"
|
|
137 |
echo "Gels: 3, 4, 7, 10, 14, and 16"
|
|
138 |
echo ""
|
|
139 |
|
|
140 |
## Relaxation parameters for Diagnostic Sonar phantom
|
|
141 |
## Eurospin II, gel nos 3, 4, 7, 10, 14, and 16)
|
|
142 |
## T1 from reference measurements in
|
|
143 |
## Wang, X., Roeloffs, V., Klosowski, J., Tan, Z., Voit, D., Uecker, M. and Frahm, J. (2018),
|
|
144 |
## Model-based T1 mapping with sparsity constraints using single-shot inversion-recovery radial FLASH.
|
|
145 |
## Magn. Reson. Med, 79: 730-740. https://doi.org/10.1002/mrm.26726
|
|
146 |
## T2 from
|
|
147 |
## T. J. Sumpf, A. Petrovic, M. Uecker, F. Knoll and J. Frahm,
|
|
148 |
## Fast T2 Mapping With Improved Accuracy Using Undersampled Spin-Echo MRI and Model-Based Reconstructions With a Generating Function
|
|
149 |
## IEEE Transactions on Medical Imaging, vol. 33, no. 12, pp. 2213-2222, Dec. 2014, doi: 10.1109/TMI.2014.2333370.
|
|
150 |
T1=(3 0.311 0.458 0.633 0.805 1.1158 1.441 3)
|
|
151 |
T2=(1 0.046 0.081 0.101 0.132 0.138 0.166 1)
|
|
152 |
;;
|
|
153 |
*)
|
|
154 |
echo -n "Unknown geometry!\n"
|
|
155 |
exit 1
|
|
156 |
;;
|
|
157 |
esac
|
|
158 |
|
|
159 |
|
|
160 |
# Simulation Parameters
|
|
161 |
# Run `bart sim --seq h` for more details
|
|
162 |
SEQ=ir-flash # Sequence Type
|
|
163 |
TR=0.0034 # Repetition Time [s]
|
|
164 |
TE=0.0021 # Echo Time [s]
|
|
165 |
REP=600 # Number of repetitions
|
|
166 |
IPL=0.01 # Inversion Pulse Length [s]
|
|
167 |
ISP=0.005 # Inversion Spoiler Gradient Length [s]
|
|
168 |
PPL=0 # Preparation Pulse Length [s]
|
|
169 |
TRF=0.001 # Pulse Duration [s]
|
|
170 |
FA=6 # Flip Angle [degree]
|
|
171 |
BWTP=4 # Bandwidth-Time-Product
|
|
172 |
OFF=0 # Off-Resonance [rad/s]
|
|
173 |
MOMSL=0 # Slice Selection Gradient Moment [rad/s]
|
|
174 |
|
|
175 |
|
|
176 |
# Run Simulation
|
|
177 |
for i in `seq 0 $((${#T1[@]}-1))`; do
|
|
178 |
|
|
179 |
echo -e "Tube $i\t T1: ${T1[$i]} s,\tT2[$i]: ${T2[$i]} s"
|
|
180 |
|
|
181 |
bart sim --ODE \
|
|
182 |
--seq $SEQ,tr=$TR,te=$TE,nrep=$REP,ipl=$IPL,isp=$ISP,ppl=$PPL,trf=$TRF,fa=$FA,bwtp=$BWTP,off=$OFF,mom-sl=$MOMSL \
|
|
183 |
-1 ${T1[$i]}:${T1[$i]}:1 -2 ${T2[$i]}:${T2[$i]}:1 \
|
|
184 |
_simu$(printf "%02d" $i)
|
|
185 |
done
|
|
186 |
|
|
187 |
|
|
188 |
# Join individual simulations
|
|
189 |
bart join 7 $(ls _simu*.cfl | sed -e 's/\.cfl//') simu
|
|
190 |
|
|
191 |
# Join simulations in a single dimension (-> 6)
|
|
192 |
bart reshape $(bart bitmask 6 7) ${#T1[@]} 1 simu simu2
|
|
193 |
|
|
194 |
|
|
195 |
# Create Geometry
|
|
196 |
if [ -z "${TRAJ}" ]; then
|
|
197 |
|
|
198 |
if $KSPACE; then
|
|
199 |
|
|
200 |
# Create default trajectory
|
|
201 |
DIM=192
|
|
202 |
SPOKES=$((DIM-1))
|
|
203 |
|
|
204 |
bart traj -x $DIM -y $SPOKES traj
|
|
205 |
|
|
206 |
bart phantom --${GEOM} -b -s $SENS --rotation-steps $ROT_STEPS --rotation-angle $ROT_ANGLE -t traj geom
|
|
207 |
else
|
|
208 |
|
|
209 |
bart phantom --${GEOM} -b -s $SENS --rotation-steps $ROT_STEPS --rotation-angle $ROT_ANGLE geom
|
|
210 |
fi
|
|
211 |
else
|
|
212 |
if $KSPACE; then
|
|
213 |
|
|
214 |
bart phantom --${GEOM} -b -s $SENS --rotation-steps $ROT_STEPS --rotation-angle $ROT_ANGLE -k -t ${TRAJ} geom
|
|
215 |
else
|
|
216 |
|
|
217 |
bart phantom --${GEOM} -b -s $SENS --rotation-steps $ROT_STEPS --rotation-angle $ROT_ANGLE geom
|
|
218 |
fi
|
|
219 |
fi
|
|
220 |
|
|
221 |
# Combine simulated signal and geometry
|
|
222 |
|
|
223 |
bart fmac -s $(bart bitmask 6) geom simu2 $output
|
|
224 |
|
|
225 |
} > $LOGFILE
|
|
226 |
|
|
227 |
[ -d $WORKDIR ] && rm -rf $WORKDIR
|
|
228 |
|
|
229 |
exit 0
|