|
9 | 9 | "This notebook explores the implementation of *deobliquing* operations in AFNI, in order to be able to correctly manipulate transforms generated by the tool, and to produce transforms that can be correctly applied with AFNI.\n",
|
10 | 10 | "Most of the preparation comes from the previous notebook.\n",
|
11 | 11 | "\n",
|
12 |
| - "### Preparation" |
| 12 | + "This notebook is the test bed for resolving [issue #45](https://github.com/poldracklab/nitransforms/issues/45)" |
| 13 | + ] |
| 14 | + }, |
| 15 | + { |
| 16 | + "cell_type": "markdown", |
| 17 | + "metadata": {}, |
| 18 | + "source": [ |
| 19 | + "### Preamble\n", |
| 20 | + "Prepare a Python environment and use a temporal directory for the outputs. After that, fetch the actual file from NiBabel documentation." |
13 | 21 | ]
|
14 | 22 | },
|
15 | 23 | {
|
|
72 | 80 | "!wget https://nipy.org/nibabel/_downloads/62985f4c43f499609fa65cb2eb955b79/someones_anatomy.nii.gz"
|
73 | 81 | ]
|
74 | 82 | },
|
| 83 | + { |
| 84 | + "cell_type": "markdown", |
| 85 | + "metadata": {}, |
| 86 | + "source": [ |
| 87 | + "### Load in the image\n", |
| 88 | + "Let's first visualize the example image, and retain some copies of the original header and affine." |
| 89 | + ] |
| 90 | + }, |
75 | 91 | {
|
76 | 92 | "cell_type": "code",
|
77 | 93 | "execution_count": 78,
|
|
109 | 125 | "nii.orthoview()"
|
110 | 126 | ]
|
111 | 127 | },
|
| 128 | + { |
| 129 | + "cell_type": "markdown", |
| 130 | + "metadata": {}, |
| 131 | + "source": [ |
| 132 | + "### Generating variants\n", |
| 133 | + "Playing with the affine header and the data array ordering of axes and elements we generate several versions of the dataset with different orientations (LAS, LPS, oblique, LPS oblique)." |
| 134 | + ] |
| 135 | + }, |
112 | 136 | {
|
113 | 137 | "cell_type": "code",
|
114 | 138 | "execution_count": 79,
|
|
148 | 172 | "lpsnew.to_filename('someones_anatomy_lpsrot.nii.gz')"
|
149 | 173 | ]
|
150 | 174 | },
|
| 175 | + { |
| 176 | + "cell_type": "markdown", |
| 177 | + "metadata": {}, |
| 178 | + "source": [ |
| 179 | + "### Print affines of interest\n", |
| 180 | + "Output some affines that we will want to compare to their counterparts generated by AFNI and stored in the NIfTI header" |
| 181 | + ] |
| 182 | + }, |
151 | 183 | {
|
152 | 184 | "cell_type": "code",
|
153 | 185 | "execution_count": 194,
|
|
208 | 240 | "cell_type": "markdown",
|
209 | 241 | "metadata": {},
|
210 | 242 | "source": [
|
211 |
| - "### Run `3dWarp -deoblique`" |
| 243 | + "### Run `3dWarp -deoblique`\n", |
| 244 | + "Generate one example image after \"deobliquing\", to then see if we can generate equivalent composite transforms" |
212 | 245 | ]
|
213 | 246 | },
|
214 | 247 | {
|
|
260 | 293 | "Warp(in_file='someones_anatomy_rot.nii.gz', deoblique=True, verbose=True, out_file='deob.nii.gz').run()"
|
261 | 294 | ]
|
262 | 295 | },
|
| 296 | + { |
| 297 | + "cell_type": "markdown", |
| 298 | + "metadata": {}, |
| 299 | + "source": [ |
| 300 | + "### Generating AFNI's \"deobliquing\" matrices\n", |
| 301 | + "\n", |
| 302 | + "Based on the image's information, we need to reconstruct AFNI's `WARPDRIVE_MATVEC_FOR_000000` affine, and then check that the results of applying such a matrix ends in the same outcome with AFNI and NiTransforms tools." |
| 303 | + ] |
| 304 | + }, |
263 | 305 | {
|
264 | 306 | "cell_type": "code",
|
265 | 307 | "execution_count": 204,
|
|
302 | 344 | "cell_type": "markdown",
|
303 | 345 | "metadata": {},
|
304 | 346 | "source": [
|
305 |
| - "### Inspecting affines and headers" |
| 347 | + "### Inspecting affines and headers\n", |
| 348 | + "Generate a rotation affine to apply on the original affine of an image, and try to reconstruct the inverse of it as AFNI calculates it.\n", |
| 349 | + "\n", |
| 350 | + "The following cells are just prior information useful for when we arrive to the next section" |
306 | 351 | ]
|
307 | 352 | },
|
308 | 353 | {
|
|
1043 | 1088 | "cell_type": "markdown",
|
1044 | 1089 | "metadata": {},
|
1045 | 1090 | "source": [
|
1046 |
| - "### Reverse-engineering matrix compositions of oblique datasets" |
| 1091 | + "### Reverse-engineering matrix compositions of oblique datasets\n", |
| 1092 | + "Calculating AFNI's affines based on the oblique image information" |
1047 | 1093 | ]
|
1048 | 1094 | },
|
1049 | 1095 | {
|
|
1098 | 1144 | "print(R)"
|
1099 | 1145 | ]
|
1100 | 1146 | },
|
| 1147 | + { |
| 1148 | + "cell_type": "markdown", |
| 1149 | + "metadata": {}, |
| 1150 | + "source": [ |
| 1151 | + "### Visually test whether we correctly apply dual transforms with both tools\n", |
| 1152 | + "Load images generated with AFNI and with NiTransforms to check whether NiTransforms is operating as expected" |
| 1153 | + ] |
| 1154 | + }, |
1101 | 1155 | {
|
1102 | 1156 | "cell_type": "code",
|
1103 | 1157 | "execution_count": 195,
|
|
1152 | 1206 | "# nb.load('moved-affine-oblique-inv-T-for-master.nii.gz').orthoview()"
|
1153 | 1207 | ]
|
1154 | 1208 | },
|
| 1209 | + { |
| 1210 | + "cell_type": "markdown", |
| 1211 | + "metadata": {}, |
| 1212 | + "source": [ |
| 1213 | + "If both derivatives are resampled in the same space, the following figure should be almost (or fully) blank." |
| 1214 | + ] |
| 1215 | + }, |
1155 | 1216 | {
|
1156 | 1217 | "cell_type": "code",
|
1157 | 1218 | "execution_count": 196,
|
|
1184 | 1245 | "deob = nb.load('deob.nii.gz')\n",
|
1185 | 1246 | "nb.Nifti1Image(np.abs(deob.get_fdata() - nb.load('deob-for2.nii.gz').get_fdata()), deob.affine, deob.header).orthoview()"
|
1186 | 1247 | ]
|
1187 |
| - }, |
1188 |
| - { |
1189 |
| - "cell_type": "code", |
1190 |
| - "execution_count": null, |
1191 |
| - "metadata": {}, |
1192 |
| - "outputs": [], |
1193 |
| - "source": [] |
1194 | 1248 | }
|
1195 | 1249 | ],
|
1196 | 1250 | "metadata": {
|
|
0 commit comments