ckadirt commited on
Commit
30f919c
·
verified ·
1 Parent(s): a5588be

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. MindEyeV2/antspy/ants/core/__init__.py +42 -0
  2. MindEyeV2/antspy/ants/core/ants_image_io.py +529 -0
  3. MindEyeV2/antspy/ants/math/__init__.py +14 -0
  4. MindEyeV2/antspy/ants/math/averaging.py +100 -0
  5. MindEyeV2/antspy/ants/math/get_centroids.py +58 -0
  6. MindEyeV2/antspy/ants/math/get_neighborhood.py +187 -0
  7. MindEyeV2/antspy/ants/math/hausdorff_distance.py +40 -0
  8. MindEyeV2/antspy/ants/math/image_similarity.py +67 -0
  9. MindEyeV2/antspy/ants/math/metrics.py +43 -0
  10. MindEyeV2/antspy/ants/math/quantile.py +447 -0
  11. MindEyeV2/antspy/ants/registration/__init__.py +15 -0
  12. MindEyeV2/antspy/ants/registration/affine_initializer.py +70 -0
  13. MindEyeV2/antspy/ants/registration/apply_transforms.py +316 -0
  14. MindEyeV2/antspy/ants/registration/average_transform.py +48 -0
  15. MindEyeV2/antspy/ants/registration/build_template.py +137 -0
  16. MindEyeV2/antspy/ants/registration/compose_displacement_fields.py +33 -0
  17. MindEyeV2/antspy/ants/registration/create_jacobian_determinant_image.py +175 -0
  18. MindEyeV2/antspy/ants/registration/create_warped_grid.py +105 -0
  19. MindEyeV2/antspy/ants/registration/fit_bspline_displacement_field.py +202 -0
  20. MindEyeV2/antspy/ants/registration/fit_bspline_object_to_scattered_data.py +191 -0
  21. MindEyeV2/antspy/ants/registration/fit_thin_plate_spline_displacement_field.py +105 -0
  22. MindEyeV2/antspy/ants/registration/integrate_velocity_field.py +48 -0
  23. MindEyeV2/antspy/ants/registration/invert_displacement_field.py +51 -0
  24. MindEyeV2/antspy/ants/registration/landmark_transforms.py +843 -0
  25. MindEyeV2/antspy/ants/registration/registration.py +1953 -0
  26. MindEyeV2/antspy/ants/registration/simulate_displacement_field.py +90 -0
  27. MindEyeV2/src/slurms/458689.out +4 -0
  28. MindEyeV2/src/slurms/458690.err +0 -0
  29. MindEyeV2/src/slurms/458711.out +135 -0
  30. MindEyeV2/src/slurms/466067.out +54 -0
  31. MindEyeV2/src/slurms/534014.err +0 -0
  32. MindEyeV2/src/slurms/534014.out +889 -0
  33. MindEyeV2/src/slurms/534074.err +46 -0
  34. MindEyeV2/src/slurms/534074.out +44 -0
  35. MindEyeV2/src/slurms/534079.err +0 -0
  36. MindEyeV2/src/slurms/534079.out +1062 -0
  37. MindEyeV2/src/slurms/544384.err +6 -0
  38. MindEyeV2/src/slurms/544384.out +4 -0
  39. MindEyeV2/src/slurms/544386.err +5 -0
  40. MindEyeV2/src/slurms/544386.out +4 -0
  41. MindEyeV2/src/slurms/544387.err +7 -0
  42. MindEyeV2/src/slurms/544387.out +54 -0
  43. MindEyeV2/src/slurms/544389.err +26 -0
  44. MindEyeV2/src/slurms/544389.out +59 -0
  45. MindEyeV2/src/slurms/544390.err +0 -0
  46. MindEyeV2/src/slurms/544492.out +62 -0
  47. MindEyeV2/src/slurms/545089.out +18 -0
  48. MindEyeV2/src/slurms/545090.err +14 -0
  49. MindEyeV2/src/slurms/545090.out +59 -0
  50. MindEyeV2/src/slurms/545091.out +62 -0
MindEyeV2/antspy/ants/core/__init__.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .ants_image_io import (image_header_info,
2
+ image_clone,
3
+ image_read,
4
+ dicom_read,
5
+ image_write,
6
+ make_image,
7
+ from_numpy,
8
+ from_numpy_like,
9
+ new_image_like)
10
+ from .ants_image import (ANTsImage,
11
+ copy_image_info,
12
+ set_origin,
13
+ get_origin,
14
+ set_direction,
15
+ get_direction,
16
+ set_spacing,
17
+ get_spacing,
18
+ is_image,
19
+ from_pointer)
20
+ from .ants_metric_io import (new_ants_metric,
21
+ create_ants_metric,
22
+ supported_metrics)
23
+ from .ants_transform_io import (create_ants_transform,
24
+ new_ants_transform,
25
+ read_transform,
26
+ write_transform,
27
+ transform_from_displacement_field,
28
+ transform_to_displacement_field,
29
+ fsl2antstransform)
30
+ from .ants_transform import (ANTsTransform,
31
+ set_ants_transform_parameters,
32
+ get_ants_transform_parameters,
33
+ get_ants_transform_fixed_parameters,
34
+ set_ants_transform_fixed_parameters,
35
+ apply_ants_transform,
36
+ apply_ants_transform_to_point,
37
+ apply_ants_transform_to_vector,
38
+ apply_ants_transform_to_image,
39
+ invert_ants_transform,
40
+ compose_ants_transforms,
41
+ transform_index_to_physical_point,
42
+ transform_physical_point_to_index)
MindEyeV2/antspy/ants/core/ants_image_io.py ADDED
@@ -0,0 +1,529 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Image IO
3
+ """
4
+
5
+ __all__ = [
6
+ "image_header_info",
7
+ "image_clone",
8
+ "image_read",
9
+ "dicom_read",
10
+ "image_write",
11
+ "make_image",
12
+ "from_numpy",
13
+ "from_numpy_like",
14
+ "new_image_like"
15
+ ]
16
+
17
+ import os
18
+ import json
19
+ import numpy as np
20
+ import warnings
21
+
22
+ import ants
23
+ from ants.internal import get_lib_fn, short_ptype, infer_dtype
24
+ from ants.decorators import image_method
25
+
26
+ _supported_pclasses = {"scalar", "vector", "rgb", "rgba","symmetric_second_rank_tensor"}
27
+ _supported_ptypes = {"unsigned char", "unsigned int", "float", "double"}
28
+ _supported_ntypes = {"uint8", "uint32", "float32", "float64"}
29
+ _unsupported_ptypes = {"char", "unsigned short", "short", "int"}
30
+ _unsupported_ptype_map = {
31
+ "char": "float",
32
+ "unsigned short": "unsigned int",
33
+ "short": "float",
34
+ "int": "float",
35
+ }
36
+ _image_type_map = {"scalar": "", "vector": "V", "rgb": "RGB", "rgba": "RGBA", "symmetric_second_rank_tensor": "SSRT" }
37
+ _ptype_type_map = {
38
+ "unsigned char": "UC",
39
+ "unsigned int": "UI",
40
+ "float": "F",
41
+ "double": "D",
42
+ }
43
+
44
+ _ntype_type_map = {"uint8": "UC", "uint32": "UI", "float32": "F", "float64": "D"}
45
+ _npy_to_itk_map = {
46
+ "uint8": "unsigned char",
47
+ "uint32": "unsigned int",
48
+ "float32": "float",
49
+ "float64": "double",
50
+ }
51
+
52
+ _image_read_dict = {}
53
+ for itype in {"scalar", "vector", "rgb", "rgba", "symmetric_second_rank_tensor"}:
54
+ _image_read_dict[itype] = {}
55
+ for p in _supported_ptypes:
56
+ _image_read_dict[itype][p] = {}
57
+ for d in {2, 3, 4}:
58
+ ita = _image_type_map[itype]
59
+ pa = _ptype_type_map[p]
60
+ _image_read_dict[itype][p][d] = "imageRead%s%s%i" % (ita, pa, d)
61
+
62
+ def from_numpy(
63
+ data, origin=None, spacing=None, direction=None, has_components=False, is_rgb=False
64
+ ):
65
+ """
66
+ Create an ANTsImage object from a numpy array
67
+
68
+ ANTsR function: `as.antsImage`
69
+
70
+ Arguments
71
+ ---------
72
+ data : ndarray
73
+ image data array
74
+
75
+ origin : tuple/list
76
+ image origin
77
+
78
+ spacing : tuple/list
79
+ image spacing
80
+
81
+ direction : list/ndarray
82
+ image direction
83
+
84
+ has_components : boolean
85
+ whether the image has components
86
+
87
+ Returns
88
+ -------
89
+ ANTsImage
90
+ image with given data and any given information
91
+ """
92
+
93
+ # this is historic but should be removed once tests can pass without it
94
+ if data.dtype.name == 'float64':
95
+ data = data.astype('float32')
96
+
97
+ # if dtype is not supported, cast to best available
98
+ best_dtype = infer_dtype(data.dtype)
99
+ if best_dtype != data.dtype:
100
+ data = data.astype(best_dtype)
101
+
102
+ img = _from_numpy(data.T.copy(), origin, spacing, direction, has_components, is_rgb)
103
+ return img
104
+
105
+
106
+ def _from_numpy(
107
+ data, origin=None, spacing=None, direction=None, has_components=False, is_rgb=False
108
+ ):
109
+ """
110
+ Internal function for creating an ANTsImage
111
+ """
112
+ if is_rgb:
113
+ has_components = True
114
+ ndim = data.ndim
115
+ if has_components:
116
+ ndim -= 1
117
+ dtype = data.dtype.name
118
+ ptype = _npy_to_itk_map[dtype]
119
+
120
+ data = np.array(data)
121
+
122
+ if origin is None:
123
+ origin = tuple([0.0] * ndim)
124
+ if spacing is None:
125
+ spacing = tuple([1.0] * ndim)
126
+ if direction is None:
127
+ direction = np.eye(ndim)
128
+
129
+ libfn = get_lib_fn("fromNumpy%s%i" % (_ntype_type_map[dtype], ndim))
130
+
131
+ if not has_components:
132
+ itk_image = libfn(data, data.shape[::-1])
133
+ ants_image = ants.from_pointer(itk_image)
134
+ ants_image.set_origin(origin)
135
+ ants_image.set_spacing(spacing)
136
+ ants_image.set_direction(direction)
137
+ ants_image._ndarr = data
138
+ else:
139
+ arrays = [data[i, ...].copy() for i in range(data.shape[0])]
140
+ data_shape = arrays[0].shape
141
+ ants_images = []
142
+ for i in range(len(arrays)):
143
+ tmp_ptr = libfn(arrays[i], data_shape[::-1])
144
+ tmp_img = ants.from_pointer(tmp_ptr)
145
+ tmp_img.set_origin(origin)
146
+ tmp_img.set_spacing(spacing)
147
+ tmp_img.set_direction(direction)
148
+ tmp_img._ndarr = arrays[i]
149
+ ants_images.append(tmp_img)
150
+ ants_image = ants.merge_channels(ants_images)
151
+ if is_rgb:
152
+ ants_image = ants_image.vector_to_rgb()
153
+ return ants_image
154
+
155
+
156
+ def make_image(
157
+ imagesize,
158
+ voxval=0,
159
+ spacing=None,
160
+ origin=None,
161
+ direction=None,
162
+ has_components=False,
163
+ pixeltype="float",
164
+ ):
165
+ """
166
+ Make an image with given size and voxel value or given a mask and vector
167
+
168
+ ANTsR function: `makeImage`
169
+
170
+ Arguments
171
+ ---------
172
+ shape : tuple/ANTsImage
173
+ input image size or mask
174
+
175
+ voxval : scalar
176
+ input image value or vector, size of mask
177
+
178
+ spacing : tuple/list
179
+ image spatial resolution
180
+
181
+ origin : tuple/list
182
+ image spatial origin
183
+
184
+ direction : list/ndarray
185
+ direction matrix to convert from index to physical space
186
+
187
+ components : boolean
188
+ whether there are components per pixel or not
189
+
190
+ pixeltype : float
191
+ data type of image values
192
+
193
+ Returns
194
+ -------
195
+ ANTsImage
196
+ """
197
+ if ants.is_image(imagesize):
198
+ img = imagesize.clone()
199
+ sel = imagesize > 0
200
+ if voxval.ndim > 1:
201
+ voxval = voxval.flatten()
202
+ if (len(voxval) == int((sel > 0).sum())) or (len(voxval) == 0):
203
+ img[sel] = voxval
204
+ else:
205
+ raise ValueError(
206
+ "Num given voxels %i not same as num positive values %i in `imagesize`"
207
+ % (len(voxval), int((sel > 0).sum()))
208
+ )
209
+ return img
210
+ else:
211
+ if isinstance(voxval, (tuple, list, np.ndarray)):
212
+ array = np.asarray(voxval).astype("float32").reshape(imagesize)
213
+ else:
214
+ array = np.full(imagesize, voxval, dtype="float32")
215
+ image = from_numpy(
216
+ array,
217
+ origin=origin,
218
+ spacing=spacing,
219
+ direction=direction,
220
+ has_components=has_components,
221
+ )
222
+ return image.clone(pixeltype)
223
+
224
+
225
+ def image_header_info(filename):
226
+ """
227
+ Read file info from image header
228
+
229
+ ANTsR function: `antsImageHeaderInfo`
230
+
231
+ Arguments
232
+ ---------
233
+ filename : string
234
+ name of image file from which info will be read
235
+
236
+ Returns
237
+ -------
238
+ dict
239
+ """
240
+ if not os.path.exists(filename):
241
+ raise Exception("filename does not exist")
242
+
243
+ libfn = get_lib_fn("antsImageHeaderInfo")
244
+ retval = libfn(filename)
245
+ retval["dimensions"] = tuple(retval["dimensions"])
246
+ retval["origin"] = tuple([round(o, 4) for o in retval["origin"]])
247
+ retval["spacing"] = tuple([round(s, 4) for s in retval["spacing"]])
248
+ retval["direction"] = np.round(retval["direction"], 4)
249
+ return retval
250
+
251
+ def image_clone(image, pixeltype=None):
252
+ """
253
+ Clone an ANTsImage
254
+
255
+ ANTsR function: `antsImageClone`
256
+
257
+ Arguments
258
+ ---------
259
+ image : ANTsImage
260
+ image to clone
261
+
262
+ dtype : string (optional)
263
+ new datatype for image
264
+
265
+ Returns
266
+ -------
267
+ ANTsImage
268
+ """
269
+ return image.clone(pixeltype)
270
+
271
+
272
+ def image_read(filename, dimension=None, pixeltype="float", reorient=False):
273
+ """
274
+ Read an ANTsImage from file
275
+
276
+ ANTsR function: `antsImageRead`
277
+
278
+ Arguments
279
+ ---------
280
+ filename : string
281
+ Name of the file to read the image from.
282
+
283
+ dimension : int
284
+ Number of dimensions of the image read. This need not be the same as
285
+ the dimensions of the image in the file. Allowed values: 2, 3, 4.
286
+ If not provided, the dimension is obtained from the image file
287
+
288
+ pixeltype : string
289
+ C++ datatype to be used to represent the pixels read. This datatype
290
+ need not be the same as the datatype used in the file.
291
+ Options: unsigned char, unsigned int, float, double
292
+
293
+ reorient : boolean | string
294
+ if True, the image will be reoriented to RPI if it is 3D
295
+ if False, nothing will happen
296
+ if string, this should be the 3-letter orientation to which the
297
+ input image will reoriented if 3D.
298
+ if the image is 2D, this argument is ignored
299
+
300
+ Returns
301
+ -------
302
+ ANTsImage
303
+ """
304
+ if filename.endswith(".npy"):
305
+ filename = os.path.expanduser(filename)
306
+ img_array = np.load(filename)
307
+ if os.path.exists(filename.replace(".npy", ".json")):
308
+ with open(filename.replace(".npy", ".json")) as json_data:
309
+ img_header = json.load(json_data)
310
+ ants_image = from_numpy(
311
+ img_array,
312
+ origin=img_header.get("origin", None),
313
+ spacing=img_header.get("spacing", None),
314
+ direction=np.asarray(img_header.get("direction", None)),
315
+ has_components=img_header.get("components", 1) > 1,
316
+ )
317
+ else:
318
+ img_header = {}
319
+ ants_image = from_numpy(img_array)
320
+
321
+ else:
322
+ filename = os.path.expanduser(filename)
323
+ if not os.path.exists(filename):
324
+ raise ValueError("File %s does not exist!" % filename)
325
+
326
+ hinfo = image_header_info(filename)
327
+ ptype = hinfo["pixeltype"]
328
+ pclass = hinfo["pixelclass"]
329
+ ndim = hinfo["nDimensions"]
330
+ ncomp = hinfo["nComponents"]
331
+ is_rgb = False
332
+ if pclass == "rgb":
333
+ pclass = "vector"
334
+ if pclass == "rgba":
335
+ pclass = "vector"
336
+ if pclass == "symmetric_second_rank_tensor":
337
+ pclass = "vector"
338
+ # is_rgb = True if pclass == "rgb" else False
339
+ if dimension is not None:
340
+ ndim = dimension
341
+
342
+ # error handling on pixelclass
343
+ if pclass not in _supported_pclasses:
344
+ raise ValueError("Pixel class %s not supported!" % pclass)
345
+
346
+ # error handling on pixeltype
347
+ if ptype in _unsupported_ptypes:
348
+ ptype = _unsupported_ptype_map.get(ptype, "unsupported")
349
+ if ptype == "unsupported":
350
+ raise ValueError("Pixeltype %s not supported" % ptype)
351
+
352
+ # error handling on dimension
353
+ if (ndim < 2) or (ndim > 4):
354
+ raise ValueError("Found %i-dimensional image - not supported!" % ndim)
355
+
356
+ libfn = get_lib_fn(_image_read_dict[pclass][ptype][ndim])
357
+ itk_pointer = libfn(filename)
358
+
359
+ ants_image = ants.from_pointer(itk_pointer)
360
+
361
+ if pixeltype is not None:
362
+ ants_image = ants_image.clone(pixeltype)
363
+
364
+ if (reorient != False) and (ants_image.dimension == 3):
365
+ if reorient == True:
366
+ ants_image = ants_image.reorient_image2("RPI")
367
+ elif isinstance(reorient, str):
368
+ ants_image = ants_image.reorient_image2(reorient)
369
+
370
+ return ants_image
371
+
372
+
373
+ def dicom_read(directory, pixeltype="float"):
374
+ """
375
+ Read a set of dicom files in a directory into a single ANTsImage.
376
+ The origin of the resulting 3D image will be the origin of the
377
+ first dicom image read.
378
+
379
+ Arguments
380
+ ---------
381
+ directory : string
382
+ folder in which all the dicom images exist
383
+
384
+ Returns
385
+ -------
386
+ ANTsImage
387
+
388
+ Example
389
+ -------
390
+ >>> import ants
391
+ >>> img = ants.dicom_read('~/desktop/dicom-subject/')
392
+ """
393
+ slices = []
394
+ imgidx = 0
395
+ for imgpath in os.listdir(directory):
396
+ if imgpath.endswith(".dcm"):
397
+ if imgidx == 0:
398
+ tmp = image_read(
399
+ os.path.join(directory, imgpath), dimension=3, pixeltype=pixeltype
400
+ )
401
+ origin = tmp.origin
402
+ spacing = tmp.spacing
403
+ direction = tmp.direction
404
+ tmp = tmp.numpy()[:, :, 0]
405
+ else:
406
+ tmp = image_read(
407
+ os.path.join(directory, imgpath), dimension=2, pixeltype=pixeltype
408
+ ).numpy()
409
+
410
+ slices.append(tmp)
411
+ imgidx += 1
412
+
413
+ slices = np.stack(slices, axis=-1)
414
+ return from_numpy(slices, origin=origin, spacing=spacing, direction=direction)
415
+
416
+ @image_method
417
+ def image_write(image, filename, ri=False):
418
+ """
419
+ Write an ANTsImage to file
420
+
421
+ ANTsR function: `antsImageWrite`
422
+
423
+ Arguments
424
+ ---------
425
+ image : ANTsImage
426
+ image to save to file
427
+
428
+ filename : string
429
+ name of file to which image will be saved
430
+
431
+ ri : boolean
432
+ if True, return image. This allows for using this function in a pipeline:
433
+ >>> img2 = img.smooth_image(2.).image_write(file1, ri=True).threshold_image(0,20).image_write(file2, ri=True)
434
+ if False, do not return image
435
+ """
436
+ if filename.endswith(".npy"):
437
+ img_array = image.numpy()
438
+ img_header = {
439
+ "origin": image.origin,
440
+ "spacing": image.spacing,
441
+ "direction": image.direction.tolist(),
442
+ "components": image.components,
443
+ }
444
+
445
+ np.save(filename, img_array)
446
+ with open(filename.replace(".npy", ".json"), "w") as outfile:
447
+ json.dump(img_header, outfile)
448
+ else:
449
+ image.to_file(filename)
450
+
451
+ if ri:
452
+ return image
453
+
454
+ @image_method
455
+ def clone(image, pixeltype=None):
456
+ """
457
+ Create a copy of the given ANTsImage with the same data and info, possibly with
458
+ a different data type for the image data. Only supports casting to
459
+ uint8 (unsigned char), uint32 (unsigned int), float32 (float), and float64 (double)
460
+
461
+ Arguments
462
+ ---------
463
+ dtype: string (optional)
464
+ if None, the dtype will be the same as the cloned ANTsImage. Otherwise,
465
+ the data will be cast to this type. This can be a numpy type or an ITK
466
+ type.
467
+ Options:
468
+ 'unsigned char' or 'uint8',
469
+ 'unsigned int' or 'uint32',
470
+ 'float' or 'float32',
471
+ 'double' or 'float64'
472
+
473
+ Returns
474
+ -------
475
+ ANTsImage
476
+ """
477
+ if pixeltype is None:
478
+ pixeltype = image.pixeltype
479
+
480
+ if pixeltype not in _supported_ptypes:
481
+ raise ValueError('Pixeltype %s not supported. Supported types are %s' % (pixeltype, _supported_ptypes))
482
+
483
+ if image.has_components and (not image.is_rgb):
484
+ comp_imgs = ants.split_channels(image)
485
+ comp_imgs_cloned = [comp_img.clone(pixeltype) for comp_img in comp_imgs]
486
+ return ants.merge_channels(comp_imgs_cloned, channels_first=image.channels_first)
487
+ else:
488
+ p1_short = short_ptype(image.pixeltype)
489
+ p2_short = short_ptype(pixeltype)
490
+ ndim = image.dimension
491
+ fn_suffix = '%s%i' % (p2_short,ndim)
492
+ libfn = get_lib_fn('antsImageClone%s'%fn_suffix)
493
+ pointer_cloned = libfn(image.pointer)
494
+ return ants.from_pointer(pointer_cloned)
495
+
496
+ copy = clone
497
+
498
+ @image_method
499
+ def new_image_like(image, data):
500
+ """
501
+ Create a new ANTsImage with the same header information, but with
502
+ a new image array.
503
+
504
+ Arguments
505
+ ---------
506
+ data : ndarray or py::capsule
507
+ New array or pointer for the image.
508
+ It must have the same shape as the current
509
+ image data.
510
+
511
+ Returns
512
+ -------
513
+ ANTsImage
514
+ """
515
+ if not isinstance(data, np.ndarray):
516
+ raise ValueError('data must be a numpy array')
517
+ if not image.has_components:
518
+ if data.shape != image.shape:
519
+ raise ValueError('given array shape (%s) and image array shape (%s) do not match' % (data.shape, image.shape))
520
+ else:
521
+ if (data.shape[-1] != image.components) or (data.shape[:-1] != image.shape):
522
+ raise ValueError('given array shape (%s) and image array shape (%s) do not match' % (data.shape[1:], image.shape))
523
+
524
+ return from_numpy(data, origin=image.origin,
525
+ spacing=image.spacing, direction=image.direction,
526
+ has_components=image.has_components)
527
+
528
+ def from_numpy_like(data, image):
529
+ return new_image_like(image, data)
MindEyeV2/antspy/ants/math/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .averaging import average_images
2
+ from .get_centroids import get_centroids
3
+ from .get_neighborhood import get_neighborhood_in_mask, get_neighborhood_at_voxel
4
+ from .hausdorff_distance import hausdorff_distance
5
+ from .image_similarity import image_similarity
6
+ from .metrics import image_mutual_information
7
+ from .quantile import (ilr,
8
+ rank_intensity,
9
+ quantile,
10
+ regress_poly,
11
+ regress_components,
12
+ get_average_of_timeseries,
13
+ compcor,
14
+ bandpass_filter_matrix)
MindEyeV2/antspy/ants/math/averaging.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from tempfile import mktemp
3
+
4
+ import numpy as np
5
+
6
+ import ants
7
+
8
+ __all__ = ['average_images']
9
+
10
+
11
+ def average_images( x, normalize=True, mask=None, imagetype=0, sum_image_threshold=3, return_sum_image=False, verbose=False ):
12
+ """
13
+ average a list of images
14
+
15
+ images will be resampled automatically to the largest image space;
16
+ this is not a registration so images should be in the same physical
17
+ space to begin with.
18
+
19
+ x : a list containing either filenames or antsImages
20
+
21
+ normalize : boolean
22
+
23
+ mask : None or integer; this will perform a masked averaging which can
24
+ be useful when images have only partial coverage. integer greater
25
+ than zero will perform morphological closing.
26
+
27
+ imagetype : integer
28
+ choose 0/1/2/3 mapping to scalar/vector/tensor/time-series
29
+
30
+ sum_image_threshold : integer
31
+ only average regions with overlap greater than or equal to this value
32
+
33
+ return_sum_image : boolean
34
+ returns the average and the image that show ROI overlap; primarily for debugging
35
+
36
+ verbose : boolean
37
+ will print progress
38
+
39
+ Returns
40
+ -------
41
+ ANTsImage
42
+
43
+ Example
44
+ -------
45
+ >>> import ants
46
+ >>> x0=[ ants.get_data('r16'), ants.get_data('r27'), ants.get_data('r62'), ants.get_data('r64') ]
47
+ >>> x1=[]
48
+ >>> for k in range(len(x0)):
49
+ >>> x1.append( ants.image_read( x0[k] ) )
50
+ >>> avg=ants.average_images(x0)
51
+ >>> avg1=ants.average_images(x1)
52
+ >>> avg2=ants.average_images(x1,mask=0)
53
+ >>> avg3=ants.average_images(x1,mask=1,normalize=True)
54
+ """
55
+ import numpy as np
56
+
57
+ def gli( y, normalize=False ):
58
+ if isinstance(y,str):
59
+ y=ants.image_read(y)
60
+ if normalize:
61
+ y=y/y.mean()
62
+ return y
63
+
64
+ biggest=0
65
+ biggestind=0
66
+ for k in range( len( x ) ):
67
+ locimg = gli( x[k], False )
68
+ sz=np.prod( locimg.shape )
69
+ if sz > biggest:
70
+ biggest=sz
71
+ biggestind=k
72
+
73
+ avg = gli( x[biggestind], False ) * 0
74
+ scl = float( 1.0 / len(x))
75
+ if mask is not None:
76
+ sumimg = gli( x[biggestind], False ) * 0
77
+
78
+ for k in range( len( x ) ):
79
+ if verbose and k % 20 == 0:
80
+ print( str(k)+'...', end='',flush=True)
81
+ locimg = gli( x[k], normalize )
82
+ temp = ants.resample_image_to_target( locimg, avg, interp_type='linear', imagetype=imagetype )
83
+ avg = avg + temp
84
+ if mask is not None:
85
+ fgmask = ants.threshold_image(temp,'Otsu',1)
86
+ if mask > 0:
87
+ fgmask = ants.morphology(fgmask,"close",mask)
88
+ sumimg = sumimg + fgmask
89
+
90
+ if return_sum_image:
91
+ return avg * scl, sumimg
92
+ if mask is None:
93
+ avg = avg * scl
94
+ else:
95
+ nonzero = sumimg > sum_image_threshold
96
+ tozero = sumimg <= sum_image_threshold
97
+ avg[nonzero] = avg[nonzero] / sumimg[nonzero]
98
+ avg[tozero] = 0
99
+ return avg
100
+
MindEyeV2/antspy/ants/math/get_centroids.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["get_centroids"]
2
+
3
+ import numpy as np
4
+ import ants
5
+ from ants.decorators import image_method
6
+
7
+ @image_method
8
+ def get_centroids(image, clustparam=0):
9
+ """
10
+ Reduces a variate/statistical/network image to a set of centroids
11
+ describing the center of each stand-alone non-zero component in the image
12
+
13
+ ANTsR function: `getCentroids`
14
+
15
+ Arguments
16
+ ---------
17
+ image : ANTsImage
18
+ image from which centroids will be calculated
19
+
20
+ clustparam : integer
21
+ look at regions greater than or equal to this size
22
+
23
+ Returns
24
+ -------
25
+ ndarray
26
+
27
+ Example
28
+ -------
29
+ >>> import ants
30
+ >>> image = ants.image_read( ants.get_ants_data( "r16" ) )
31
+ >>> image = ants.threshold_image( image, 90, 120 )
32
+ >>> image = ants.label_clusters( image, 10 )
33
+ >>> cents = ants.get_centroids( image )
34
+ """
35
+ imagedim = image.dimension
36
+ if clustparam > 0:
37
+ mypoints = ants.label_clusters(image, clustparam, max_thresh=1e15)
38
+ if clustparam == 0:
39
+ mypoints = image.clone()
40
+ mypoints = ants.label_stats(mypoints, mypoints)
41
+ nonzero = mypoints[["LabelValue"]] > 0
42
+ mypoints = mypoints[nonzero["LabelValue"]]
43
+ mypoints = mypoints.iloc[:, :]
44
+ x = mypoints.x
45
+ y = mypoints.y
46
+
47
+ if imagedim == 3:
48
+ z = mypoints.z
49
+ else:
50
+ z = np.zeros(mypoints.shape[0])
51
+
52
+ if imagedim == 4:
53
+ t = mypoints.t
54
+ else:
55
+ t = np.zeros(mypoints.shape[0])
56
+
57
+ centroids = np.stack([x, y, z, t]).T
58
+ return centroids
MindEyeV2/antspy/ants/math/get_neighborhood.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['get_neighborhood_in_mask',
3
+ 'get_neighborhood_at_voxel']
4
+
5
+ import numpy as np
6
+
7
+ import ants
8
+
9
+ from ants.internal import get_lib_fn
10
+ from ants.decorators import image_method
11
+
12
+ @image_method
13
+ def get_neighborhood_in_mask(image, mask, radius, physical_coordinates=False,
14
+ boundary_condition=None, spatial_info=False, get_gradient=False):
15
+ """
16
+ Get neighborhoods for voxels within mask.
17
+
18
+ This converts a scalar image to a matrix with rows that contain neighbors
19
+ around a center voxel
20
+
21
+ ANTsR function: `getNeighborhoodInMask`
22
+
23
+ Arguments
24
+ ---------
25
+ image : ANTsImage
26
+ image to get values from
27
+
28
+ mask : ANTsImage
29
+ image indicating which voxels to examine. Each voxel > 0 will be used as the
30
+ center of a neighborhood
31
+
32
+ radius : tuple/list
33
+ array of values for neighborhood radius (in voxels)
34
+
35
+ physical_coordinates : boolean
36
+ whether voxel indices and offsets should be in voxel or physical coordinates
37
+
38
+ boundary_condition : string (optional)
39
+ how to handle voxels in a neighborhood, but not in the mask.
40
+ None : fill values with `NaN`
41
+ `image` : use image value, even if not in mask
42
+ `mean` : use mean of all non-NaN values for that neighborhood
43
+
44
+ spatial_info : boolean
45
+ whether voxel locations and neighborhood offsets should be returned along with pixel values.
46
+
47
+ get_gradient : boolean
48
+ whether a matrix of gradients (at the center voxel) should be returned in
49
+ addition to the value matrix (WIP)
50
+
51
+ Returns
52
+ -------
53
+ if spatial_info is False:
54
+ if get_gradient is False:
55
+ ndarray
56
+ an array of pixel values where the number of rows is the size of the
57
+ neighborhood and there is a column for each voxel
58
+
59
+ else if get_gradient is True:
60
+ dictionary w/ following key-value pairs:
61
+ values : ndarray
62
+ array of pixel values where the number of rows is the size of the
63
+ neighborhood and there is a column for each voxel.
64
+
65
+ gradients : ndarray
66
+ array providing the gradients at the center voxel of each
67
+ neighborhood
68
+
69
+ else if spatial_info is True:
70
+ dictionary w/ following key-value pairs:
71
+ values : ndarray
72
+ array of pixel values where the number of rows is the size of the
73
+ neighborhood and there is a column for each voxel.
74
+
75
+ indices : ndarray
76
+ array provinding the center coordinates for each neighborhood
77
+
78
+ offsets : ndarray
79
+ array providing the offsets from center for each voxel in a neighborhood
80
+
81
+ Example
82
+ -------
83
+ >>> import ants
84
+ >>> r16 = ants.image_read(ants.get_ants_data('r16'))
85
+ >>> mask = ants.get_mask(r16)
86
+ >>> mat = ants.get_neighborhood_in_mask(r16, mask, radius=(2,2))
87
+ """
88
+ if not ants.is_image(image):
89
+ raise ValueError('image must be ANTsImage type')
90
+ if not ants.is_image(mask):
91
+ raise ValueError('mask must be ANTsImage type')
92
+ if isinstance(radius, (int, float)):
93
+ radius = [radius]*image.dimension
94
+ if (not isinstance(radius, (tuple,list))) or (len(radius) != image.dimension):
95
+ raise ValueError('radius must be tuple or list with length == image.dimension')
96
+
97
+ boundary = 0
98
+ if boundary_condition == 'image':
99
+ boundary = 1
100
+ elif boundary_condition == 'mean':
101
+ boundary = 2
102
+
103
+ libfn = get_lib_fn('getNeighborhoodMatrix%s' % image._libsuffix)
104
+ retvals = libfn(image.pointer,
105
+ mask.pointer,
106
+ list(radius),
107
+ int(physical_coordinates),
108
+ int(boundary),
109
+ int(spatial_info),
110
+ int(get_gradient))
111
+
112
+ if not spatial_info:
113
+ if get_gradient:
114
+ retvals['values'] = np.asarray(retvals['values'])
115
+ retvals['gradients'] = np.asarray(retvals['gradients'])
116
+ else:
117
+ retvals = np.asarray(retvals['matrix'])
118
+ else:
119
+ retvals['values'] = np.asarray(retvals['values'])
120
+ retvals['indices'] = np.asarray(retvals['indices'])
121
+ retvals['offsets'] = np.asarray(retvals['offsets'])
122
+
123
+ return retvals
124
+
125
+ @image_method
126
+ def get_neighborhood_at_voxel(image, center, kernel, physical_coordinates=False):
127
+ """
128
+ Get a hypercube neighborhood at a voxel. Get the values in a local
129
+ neighborhood of an image.
130
+
131
+ ANTsR function: `getNeighborhoodAtVoxel`
132
+
133
+ Arguments
134
+ ---------
135
+ image : ANTsImage
136
+ image to get values from.
137
+
138
+ center : tuple/list
139
+ indices for neighborhood center
140
+
141
+ kernel : tuple/list
142
+ either a collection of values for neighborhood radius (in voxels) or
143
+ a binary collection of the same dimension as the image, specifying the shape of the neighborhood to extract
144
+
145
+ physical_coordinates : boolean
146
+ whether voxel indices and offsets should be in voxel
147
+ or physical coordinates
148
+
149
+ Returns
150
+ -------
151
+ dictionary w/ following key-value pairs:
152
+ values : ndarray
153
+ array of neighborhood values at the voxel
154
+
155
+ indices : ndarray
156
+ matrix providing the coordinates for each value
157
+
158
+ Example
159
+ -------
160
+ >>> import ants
161
+ >>> img = ants.image_read(ants.get_ants_data('r16'))
162
+ >>> center = (2,2)
163
+ >>> radius = (3,3)
164
+ >>> retval = ants.get_neighborhood_at_voxel(img, center, radius)
165
+ """
166
+ if not ants.is_image(image):
167
+ raise ValueError('image must be ANTsImage type')
168
+
169
+ if (not isinstance(center, (tuple,list))) or (len(center) != image.dimension):
170
+ raise ValueError('center must be tuple or list with length == image.dimension')
171
+
172
+ if (not isinstance(kernel, (tuple,list))) or (len(kernel) != image.dimension):
173
+ raise ValueError('kernel must be tuple or list with length == image.dimension')
174
+
175
+ radius = [int((k-1)/2) for k in kernel]
176
+
177
+ libfn = get_lib_fn('getNeighborhood%s' % image._libsuffix)
178
+ retvals = libfn(image.pointer,
179
+ list(center),
180
+ list(kernel),
181
+ list(radius),
182
+ int(physical_coordinates))
183
+ for k in retvals.keys():
184
+ retvals[k] = np.asarray(retvals[k])
185
+ return retvals
186
+
187
+
MindEyeV2/antspy/ants/math/hausdorff_distance.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["hausdorff_distance"]
2
+
3
+ from ants.decorators import image_method
4
+ from ants.internal import get_lib_fn
5
+
6
+ @image_method
7
+ def hausdorff_distance(image1, image2):
8
+ """
9
+ Get Hausdorff distance between non-zero pixels in two images
10
+
11
+ ANTsR function: `hausdorffDistance`
12
+
13
+ Arguments
14
+ ---------
15
+ source image : ANTsImage
16
+ Source image
17
+
18
+ target_image : ANTsImage
19
+ Target image
20
+
21
+ Returns
22
+ -------
23
+ data frame with "Distance" and "AverageDistance"
24
+
25
+ Example
26
+ -------
27
+ >>> import ants
28
+ >>> r16 = ants.image_read( ants.get_ants_data('r16') )
29
+ >>> r64 = ants.image_read( ants.get_ants_data('r64') )
30
+ >>> s16 = ants.kmeans_segmentation( r16, 3 )['segmentation']
31
+ >>> s64 = ants.kmeans_segmentation( r64, 3 )['segmentation']
32
+ >>> stats = ants.hausdorff_distance(s16, s64)
33
+ """
34
+ image1_int = image1.clone("unsigned int")
35
+ image2_int = image2.clone("unsigned int")
36
+
37
+ libfn = get_lib_fn("hausdorffDistance%iD" % image1_int.dimension)
38
+ d = libfn(image1_int.pointer, image2_int.pointer)
39
+
40
+ return d
MindEyeV2/antspy/ants/math/image_similarity.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ __all__ = ['image_similarity']
4
+
5
+ import ants
6
+ from ants.decorators import image_method
7
+
8
+ @image_method
9
+ def image_similarity(fixed_image, moving_image, metric_type='MeanSquares',
10
+ fixed_mask=None, moving_mask=None,
11
+ sampling_strategy='regular', sampling_percentage=1.):
12
+ """
13
+ Measure similarity between two images.
14
+ NOTE: Similarity is actually returned as distance (i.e. dissimilarity)
15
+ per ITK/ANTs convention. E.g. using Correlation metric, the similarity
16
+ of an image with itself returns -1.
17
+
18
+ ANTsR function: `imageSimilarity`
19
+
20
+ Arguments
21
+ ---------
22
+ fixed : ANTsImage
23
+ the fixed image
24
+
25
+ moving : ANTsImage
26
+ the moving image
27
+
28
+ metric_type : string
29
+ image metric to calculate
30
+ MeanSquares
31
+ Correlation
32
+ ANTSNeighborhoodCorrelation
33
+ MattesMutualInformation
34
+ JointHistogramMutualInformation
35
+ Demons
36
+
37
+ fixed_mask : ANTsImage (optional)
38
+ mask for the fixed image
39
+
40
+ moving_mask : ANTsImage (optional)
41
+ mask for the moving image
42
+
43
+ sampling_strategy : string (optional)
44
+ sampling strategy, default is full sampling
45
+ None (Full sampling)
46
+ random
47
+ regular
48
+
49
+ sampling_percentage : scalar
50
+ percentage of data to sample when calculating metric
51
+ Must be between 0 and 1
52
+
53
+ Returns
54
+ -------
55
+ scalar
56
+
57
+ Example
58
+ -------
59
+ >>> import ants
60
+ >>> x = ants.image_read(ants.get_ants_data('r16'))
61
+ >>> y = ants.image_read(ants.get_ants_data('r30'))
62
+ >>> metric = ants.image_similarity(x,y,metric_type='MeanSquares')
63
+ """
64
+ metric = ants.create_ants_metric(fixed_image, moving_image, metric_type, fixed_mask,
65
+ moving_mask, sampling_strategy, sampling_percentage)
66
+ return metric.get_value()
67
+
MindEyeV2/antspy/ants/math/metrics.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ __all__ = ['image_mutual_information']
5
+
6
+
7
+ from ants.decorators import image_method
8
+ from ants.internal import get_lib_fn
9
+
10
+ @image_method
11
+ def image_mutual_information(image1, image2):
12
+ """
13
+ Compute mutual information between two ANTsImage types
14
+
15
+ ANTsR function: `antsImageMutualInformation`
16
+
17
+ Arguments
18
+ ---------
19
+ image1 : ANTsImage
20
+ image 1
21
+
22
+ image2 : ANTsImage
23
+ image 2
24
+
25
+ Returns
26
+ -------
27
+ scalar
28
+
29
+ Example
30
+ -------
31
+ >>> import ants
32
+ >>> fi = ants.image_read( ants.get_ants_data('r16') ).clone('float')
33
+ >>> mi = ants.image_read( ants.get_ants_data('r64') ).clone('float')
34
+ >>> mival = ants.image_mutual_information(fi, mi) # -0.1796141
35
+ """
36
+ if (image1.pixeltype != 'float') or (image2.pixeltype != 'float'):
37
+ raise ValueError('Both images must have float pixeltype')
38
+
39
+ if image1.dimension != image2.dimension:
40
+ raise ValueError('Both images must have same dimension')
41
+
42
+ libfn = get_lib_fn('antsImageMutualInformation%iD' % image1.dimension)
43
+ return libfn(image1.pointer, image2.pointer)
MindEyeV2/antspy/ants/math/quantile.py ADDED
@@ -0,0 +1,447 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['ilr',
3
+ 'rank_intensity',
4
+ 'quantile',
5
+ 'regress_poly',
6
+ 'regress_components',
7
+ 'get_average_of_timeseries',
8
+ 'compcor',
9
+ 'bandpass_filter_matrix' ]
10
+
11
+ import numpy as np
12
+ from numpy.polynomial import Legendre
13
+ from scipy import linalg
14
+ from scipy.stats import pearsonr
15
+ from scipy.stats import rankdata
16
+ import pandas as pd
17
+ from pandas import DataFrame
18
+ import statsmodels.api as sm
19
+ import statsmodels.formula.api as smf
20
+
21
+ import ants
22
+ from ants.decorators import image_method
23
+
24
+ def rank_intensity( x, mask=None, get_mask=True, method='max', ):
25
+ """
26
+ Rank transform the intensity of the input image with or without masking.
27
+ Intensities will transform from [0,1,2,55] to [0,1,2,3] so this may not be
28
+ appropriate for quantitative images - however, you never know. rank
29
+ transformations generally improve robustness so it is an empirical question
30
+ that should be evaluated.
31
+
32
+ Arguments
33
+ ---------
34
+
35
+ x : ANTsImage
36
+ input image
37
+
38
+ mask : ANTsImage
39
+ optional mask
40
+
41
+ get_mask: boolean
42
+ will estimate a mask when none provided
43
+
44
+ method : a scipy rank method (max,min,average,dense)
45
+
46
+
47
+ return: transformed image
48
+
49
+ Example
50
+ -------
51
+ >>> img = ants.image_read(ants.get_data('r16'))
52
+ >>> ants.rank_intensity(img)
53
+ """
54
+ if mask is not None:
55
+ fir = rankdata( (x*mask).numpy(), method=method )
56
+ elif mask is None and get_mask == True:
57
+ mask = ants.get_mask( x )
58
+ fir = rankdata( (x*mask).numpy(), method=method )
59
+ else:
60
+ fir = rankdata( x.numpy(), method=method )
61
+ fir = fir - 1
62
+ fir = fir.reshape( x.shape )
63
+ rimg = ants.from_numpy( fir.astype(float) )
64
+ rimg = ants.iMath(rimg,"Normalize")
65
+ ants.copy_image_info( x, rimg )
66
+ if mask is not None:
67
+ rimg = rimg * mask
68
+ return( rimg )
69
+
70
+
71
+ def ilr( data_frame, voxmats, ilr_formula, verbose = False ):
72
+ """
73
+ Image-based linear regression.
74
+
75
+ This function simplifies calculating p-values from linear models
76
+ in which there is a similar formula that is applied many times
77
+ with a change in image-based predictors. Image-based variables
78
+ are stored in the input matrix list. They should be named
79
+ consistently in the input formula and in the image list. If they
80
+ are not, an error will be thrown. All input matrices should have
81
+ the same number of rows and columns.
82
+
83
+ This function takes advantage of statsmodels R-style formulas.
84
+
85
+ ANTsR function: `ilr`
86
+
87
+ Arguments
88
+ ---------
89
+
90
+ data_frame: This data frame contains all relevant predictors except for
91
+ the matrices associated with the image variables. One should convert
92
+ any categorical predictors ahead of time using `pd.get_dummies`.
93
+
94
+ voxmats: The named list of matrices that contains the changing
95
+ predictors.
96
+
97
+ ilr_formula: This is a character string that defines a valid regression
98
+ formula in the R-style.
99
+
100
+ verbose: will print a little bit of diagnostic information that allows
101
+ a degree of model checking
102
+
103
+ Returns
104
+ -------
105
+
106
+ A list of different matrices that contain names derived from the
107
+ formula and the coefficients of the regression model. The size of
108
+ the output values ( p-values, t-values, parameter values ) will match
109
+ the input matrix and, as such, can be converted to an image via `make_image`
110
+
111
+ Example
112
+ -------
113
+
114
+ >>> nsub = 20
115
+ >>> mu, sigma = 0, 1
116
+ >>> outcome = np.random.normal( mu, sigma, nsub )
117
+ >>> covar = np.random.normal( mu, sigma, nsub )
118
+ >>> mat = np.random.normal( mu, sigma, (nsub, 500 ) )
119
+ >>> mat2 = np.random.normal( mu, sigma, (nsub, 500 ) )
120
+ >>> data = {'covar':covar,'outcome':outcome}
121
+ >>> df = pd.DataFrame( data )
122
+ >>> vlist = { "mat1": mat, "mat2": mat2 }
123
+ >>> myform = " outcome ~ covar * mat1 "
124
+ >>> result = ants.ilr( df, vlist, myform)
125
+ >>> myform = " mat2 ~ covar + mat1 "
126
+ >>> result = ants.ilr( df, vlist, myform)
127
+
128
+ """
129
+
130
+ nvoxmats = len( voxmats )
131
+ if nvoxmats < 1 :
132
+ raise ValueError('Pass at least one matrix to voxmats list')
133
+ keylist = list(voxmats.keys())
134
+ firstmat = keylist[0]
135
+ voxshape = voxmats[firstmat].shape
136
+ nvox = voxshape[1]
137
+ nmats = len( keylist )
138
+ for k in keylist:
139
+ if voxmats[firstmat].shape != voxmats[k].shape:
140
+ raise ValueError('Matrices must have same number of rows (samples)')
141
+
142
+ # test voxel
143
+ vox = 0
144
+ nrows = data_frame.shape[0]
145
+ data_frame_vox = data_frame.copy()
146
+ for k in range( nmats ):
147
+ data = {keylist[k]: np.random.normal(0,1,nrows) }
148
+ temp = pd.DataFrame( data )
149
+ data_frame_vox = pd.concat([data_frame_vox.reset_index(drop=True),temp], axis=1 )
150
+ mod = smf.ols(formula=ilr_formula, data=data_frame_vox )
151
+ res = mod.fit()
152
+ modelNames = res.model.exog_names
153
+ if verbose:
154
+ print( data_frame_vox )
155
+ print(res.summary())
156
+ nOutcomes = len( modelNames )
157
+ tValsOut = list()
158
+ pValsOut = list()
159
+ bValsOut = list()
160
+ for k in range( len( modelNames ) ):
161
+ bValsOut.append( np.zeros( nvox ) )
162
+ pValsOut.append( np.zeros( nvox ) )
163
+ tValsOut.append( np.zeros( nvox ) )
164
+
165
+ data_frame_vox = data_frame.copy()
166
+ for v in range( nmats ):
167
+ data = {keylist[v]: voxmats[keylist[v]][:,k] }
168
+ temp = pd.DataFrame( data )
169
+ data_frame_vox = pd.concat([data_frame_vox.reset_index(drop=True),temp], axis=1 )
170
+ for k in range( nvox ):
171
+ # first get the correct data frame
172
+ for v in range( nmats ):
173
+ data_frame_vox[ keylist[v] ] = voxmats[keylist[v]][:,k]
174
+ # then get the local model results
175
+ mod = smf.ols(formula=ilr_formula, data=data_frame_vox )
176
+ res = mod.fit()
177
+ tvals = res.tvalues
178
+ pvals = res.pvalues
179
+ bvals = res.params
180
+ for v in range( len( modelNames ) ):
181
+ bValsOut[v][k] = bvals.iloc[v]
182
+ pValsOut[v][k] = pvals.iloc[v]
183
+ tValsOut[v][k] = tvals.iloc[v]
184
+
185
+ bValsOutDict = { }
186
+ tValsOutDict = { }
187
+ pValsOutDict = { }
188
+ for v in range( len( modelNames ) ):
189
+ bValsOutDict[ 'coef_' + modelNames[v] ] = bValsOut[v]
190
+ tValsOutDict[ 'tval_' + modelNames[v] ] = tValsOut[v]
191
+ pValsOutDict[ 'pval_' + modelNames[v] ] = pValsOut[v]
192
+
193
+ return {
194
+ 'modelNames': modelNames,
195
+ 'coefficientValues': bValsOutDict,
196
+ 'pValues': pValsOutDict,
197
+ 'tValues': tValsOutDict }
198
+
199
+
200
+ @image_method
201
+ def quantile(image, q, nonzero=True):
202
+ """
203
+ Get the quantile values from an ANTsImage
204
+
205
+ Examples
206
+ --------
207
+ >>> img = ants.image_read(ants.get_data('r16'))
208
+ >>> ants.quantile(img, 0.5)
209
+ >>> ants.quantile(img, (0.5, 0.75))
210
+ """
211
+ img_arr = image.numpy()
212
+ if isinstance(q, (list,tuple)):
213
+ q = [qq*100. if qq <= 1. else qq for qq in q]
214
+ if nonzero:
215
+ img_arr = img_arr[img_arr>0]
216
+ vals = [np.percentile(img_arr, qq) for qq in q]
217
+ return tuple(vals)
218
+ elif isinstance(q, (float,int)):
219
+ if q <= 1.:
220
+ q = q*100.
221
+ if nonzero:
222
+ img_arr = img_arr[img_arr>0]
223
+ return np.percentile(img_arr[img_arr>0], q)
224
+ else:
225
+ raise ValueError('q argument must be list/tuple or float/int')
226
+
227
+
228
+ def regress_poly(degree, data, remove_mean=True, axis=-1):
229
+ """
230
+ Returns data with degree polynomial regressed out.
231
+ :param bool remove_mean: whether or not demean data (i.e. degree 0),
232
+ :param int axis: numpy array axes along which regression is performed
233
+ """
234
+ timepoints = data.shape[0]
235
+ # Generate design matrix
236
+ X = np.ones((timepoints, 1)) # quick way to calc degree 0
237
+ for i in range(degree):
238
+ polynomial_func = Legendre.basis(i + 1)
239
+ value_array = np.linspace(-1, 1, timepoints)
240
+ X = np.hstack((X, polynomial_func(value_array)[:, np.newaxis]))
241
+ non_constant_regressors = X[:, :-1] if X.shape[1] > 1 else np.array([])
242
+ betas = np.linalg.pinv(X).dot(data)
243
+ if remove_mean:
244
+ datahat = X.dot(betas)
245
+ else: # disregard the first layer of X, which is degree 0
246
+ datahat = X[:, 1:].dot(betas[1:, ...])
247
+ regressed_data = data - datahat
248
+ return regressed_data, non_constant_regressors
249
+
250
+ def regress_components( data, components, remove_mean=True ):
251
+ """
252
+ Returns data with components regressed out.
253
+ :param bool remove_mean: whether or not demean data (i.e. degree 0),
254
+ :param int axis: numpy array axes along which regression is performed
255
+ """
256
+ timepoints = data.shape[0]
257
+ betas = np.linalg.pinv(components).dot(data)
258
+ if remove_mean:
259
+ datahat = components.dot(betas)
260
+ else: # disregard the first layer of X, which is degree 0
261
+ datahat = components[:, 1:].dot(betas[1:, ...])
262
+ regressed_data = data - datahat
263
+ return regressed_data
264
+
265
+
266
+ def get_average_of_timeseries( image, idx=None ):
267
+ """Average the timeseries into a dimension-1 image.
268
+ image: input time series image
269
+ idx: indices over which to average
270
+ """
271
+ imagedim = image.dimension
272
+ if idx is None:
273
+ idx = range( image.shape[ imagedim - 1 ] )
274
+ i0 = ants.slice_image( image, axis=image.dimension-1, idx=idx[0] ) * 0
275
+ wt = 1.0 / len( idx )
276
+ for k in idx:
277
+ i0 = i0 + ants.slice_image( image, axis=image.dimension-1, idx=k ) * wt
278
+ return( i0 )
279
+
280
+ def bandpass_filter_matrix( matrix,
281
+ tr=1, lowf=0.01, highf=0.1, order = 3):
282
+ """
283
+ Bandpass filter the input time series image
284
+
285
+ ANTsR function: `frequencyFilterfMRI`
286
+
287
+ Arguments
288
+ ---------
289
+
290
+ image: input time series image
291
+
292
+ tr: sampling time interval (inverse of sampling rate)
293
+
294
+ lowf: low frequency cutoff
295
+
296
+ highf: high frequency cutoff
297
+
298
+ order: order of the butterworth filter run using `filtfilt`
299
+
300
+ Returns
301
+ -------
302
+ filtered matrix
303
+
304
+ Example
305
+ -------
306
+
307
+ >>> import numpy as np
308
+ >>> import ants
309
+ >>> import matplotlib.pyplot as plt
310
+ >>> brainSignal = np.random.randn( 400, 1000 )
311
+ >>> tr = 1
312
+ >>> filtered = ants.bandpass_filter_matrix( brainSignal, tr = tr )
313
+ >>> nsamples = brainSignal.shape[0]
314
+ >>> t = np.linspace(0, tr*nsamples, nsamples, endpoint=False)
315
+ >>> k = 20
316
+ >>> plt.plot(t, brainSignal[:,k], label='Noisy signal')
317
+ >>> plt.plot(t, filtered[:,k], label='Filtered signal')
318
+ >>> plt.xlabel('time (seconds)')
319
+ >>> plt.grid(True)
320
+ >>> plt.axis('tight')
321
+ >>> plt.legend(loc='upper left')
322
+ >>> plt.show()
323
+ """
324
+ from scipy.signal import butter, filtfilt
325
+
326
+ def butter_bandpass(lowcut, highcut, fs, order ):
327
+ nyq = 0.5 * fs
328
+ low = lowcut / nyq
329
+ high = highcut / nyq
330
+ b, a = butter(order, [low, high], btype='band')
331
+ return b, a
332
+
333
+ def butter_bandpass_filter(data, lowcut, highcut, fs, order ):
334
+ b, a = butter_bandpass(lowcut, highcut, fs, order=order)
335
+ y = filtfilt(b, a, data)
336
+ return y
337
+
338
+ fs = 1/tr # sampling rate based on tr
339
+ nsamples = matrix.shape[0]
340
+ ncolumns = matrix.shape[1]
341
+ matrixOut = matrix.copy()
342
+ for k in range( ncolumns ):
343
+ matrixOut[:,k] = butter_bandpass_filter(
344
+ matrix[:,k], lowf, highf, fs, order=order )
345
+ return matrixOut
346
+
347
+ def clean_data(arr, standardize=True):
348
+ """
349
+ Remove columns from a NumPy array that have no variation or contain NA/Inf values.
350
+ Optionally standardize the remaining data.
351
+
352
+ :param arr: NumPy array to be cleaned.
353
+ :param standardize: Boolean, if True standardize the data.
354
+ :return: Cleaned (and optionally standardized) NumPy array.
355
+ """
356
+ valid_columns = []
357
+
358
+ for i in range(arr.shape[1]):
359
+ column = arr[:, i]
360
+ if np.any(column != column[0]) and not np.any(np.isnan(column)) and not np.any(np.isinf(column)):
361
+ valid_columns.append(i)
362
+
363
+ cleaned_data = arr[:, valid_columns]
364
+
365
+ if standardize:
366
+ mean = np.mean(cleaned_data, axis=0)
367
+ std_dev = np.std(cleaned_data, axis=0)
368
+ # Avoid division by zero in case of zero standard deviation
369
+ std_dev[std_dev == 0] = 1
370
+ cleaned_data = (cleaned_data - mean) / std_dev
371
+
372
+ return cleaned_data
373
+
374
+ def compcor( boldImage, ncompcor=4, quantile=0.975, mask=None, filter_type=False, degree=2 ):
375
+ """
376
+ Compute noise components from the input image
377
+
378
+ ANTsR function: `compcor`
379
+
380
+ this is adapted from nipy code https://github.com/nipy/nipype/blob/e29ac95fc0fc00fedbcaa0adaf29d5878408ca7c/nipype/algorithms/confounds.py
381
+
382
+ Arguments
383
+ ---------
384
+
385
+ boldImage: input time series image
386
+
387
+ ncompcor: number of noise components to return
388
+
389
+ quantile: quantile defining high-variance
390
+
391
+ mask: mask defining brain or specific tissues
392
+
393
+ filter_type: type off filter to apply to time series before computing
394
+ noise components.
395
+
396
+ 'polynomial' - Legendre polynomial basis
397
+ False - None (mean-removal only)
398
+
399
+ degree: order of polynomial used to remove trends from the timeseries
400
+
401
+ Returns
402
+ -------
403
+ dictionary containing:
404
+
405
+ components: a numpy array
406
+
407
+ basis: a numpy array containing the (non-constant) filter regressors
408
+
409
+ Example
410
+ -------
411
+ >>> cc = ants.compcor( ants.image_read(ants.get_ants_data("ch2")) )
412
+
413
+ """
414
+
415
+ def compute_tSTD(M, quantile, x=0, axis=0):
416
+ stdM = np.std(M, axis=axis)
417
+ # set bad values to x
418
+ stdM[stdM == 0] = x
419
+ stdM[np.isnan(stdM)] = x
420
+ tt = round( quantile*100 )
421
+ threshold_std = np.percentile( stdM, tt )
422
+ # threshold_std = quantile( stdM, quantile )
423
+ return { 'tSTD': stdM, 'threshold_std': threshold_std}
424
+ if mask is None:
425
+ temp = ants.slice_image( boldImage, axis=boldImage.dimension-1, idx=0 )
426
+ mask = ants.get_mask( temp )
427
+ imagematrix = ants.timeseries_to_matrix( boldImage, mask )
428
+ temp = compute_tSTD( imagematrix, quantile, 0 )
429
+ tsnrmask = ants.make_image( mask, temp['tSTD'] )
430
+ tsnrmask = ants.threshold_image( tsnrmask, temp['threshold_std'], temp['tSTD'].max() )
431
+ M = ants.timeseries_to_matrix( boldImage, tsnrmask )
432
+ components = None
433
+ basis = np.array([])
434
+ if filter_type in ('polynomial', False):
435
+ M, basis = regress_poly(degree, M)
436
+ # M = M / compute_tSTD(M, 1.)['tSTD']
437
+ # "The covariance matrix C = MMT was constructed and decomposed into its
438
+ # principal components using a singular value decomposition."
439
+ M = clean_data( M, standardize=True )
440
+ u, _, _ = linalg.svd(M, full_matrices=False)
441
+ if components is None:
442
+ components = u[:, :ncompcor]
443
+ else:
444
+ components = np.hstack((components, u[:, :ncompcor]))
445
+ if components is None and ncompcor > 0:
446
+ raise ValueError('No components found')
447
+ return { 'components': components, 'basis': basis }
MindEyeV2/antspy/ants/registration/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .affine_initializer import affine_initializer
2
+ from .apply_transforms import apply_transforms, apply_transforms_to_points
3
+ from .average_transform import average_affine_transform, average_affine_transform_no_rigid
4
+ from .build_template import build_template
5
+ from .compose_displacement_fields import compose_displacement_fields
6
+ from .create_jacobian_determinant_image import create_jacobian_determinant_image, deformation_gradient
7
+ from .create_warped_grid import create_warped_grid
8
+ from .fit_bspline_displacement_field import fit_bspline_displacement_field
9
+ from .fit_bspline_object_to_scattered_data import fit_bspline_object_to_scattered_data
10
+ from .fit_thin_plate_spline_displacement_field import fit_thin_plate_spline_displacement_field
11
+ from .integrate_velocity_field import integrate_velocity_field
12
+ from .invert_displacement_field import invert_displacement_field
13
+ from .landmark_transforms import fit_transform_to_paired_points, fit_time_varying_transform_to_point_sets
14
+ from .registration import registration, motion_correction, label_image_registration
15
+ from .simulate_displacement_field import simulate_displacement_field
MindEyeV2/antspy/ants/registration/affine_initializer.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['affine_initializer']
3
+
4
+ import warnings
5
+ from tempfile import mktemp
6
+
7
+ from ants.internal import get_lib_fn, process_arguments
8
+
9
+
10
+ def affine_initializer(fixed_image, moving_image, search_factor=20,
11
+ radian_fraction=0.1, use_principal_axis=False,
12
+ local_search_iterations=10, mask=None, txfn=None ):
13
+ """
14
+ A multi-start optimizer for affine registration
15
+ Searches over the sphere to find a good initialization for further
16
+ registration refinement, if needed. This is a wrapper for the ANTs
17
+ function antsAffineInitializer.
18
+
19
+ ANTsR function: `affineInitializer`
20
+
21
+ Arguments
22
+ ---------
23
+ fixed_image : ANTsImage
24
+ the fixed reference image
25
+ moving_image : ANTsImage
26
+ the moving image to be mapped to the fixed space
27
+ search_factor : scalar
28
+ degree of increments on the sphere to search
29
+ radian_fraction : scalar
30
+ between zero and one, defines the arc to search over
31
+ use_principal_axis : boolean
32
+ boolean to initialize by principal axis
33
+ local_search_iterations : scalar
34
+ gradient descent iterations
35
+ mask : ANTsImage (optional)
36
+ optional mask to restrict registration
37
+ txfn : string (optional)
38
+ filename for the transformation
39
+
40
+ Returns
41
+ -------
42
+ ndarray
43
+ transformation matrix
44
+
45
+ Example
46
+ -------
47
+ >>> import ants
48
+ >>> fi = ants.image_read(ants.get_ants_data('r16'))
49
+ >>> mi = ants.image_read(ants.get_ants_data('r27'))
50
+ >>> txfile = ants.affine_initializer( fi, mi )
51
+ >>> tx = ants.read_transform(txfile, dimension=2)
52
+ """
53
+
54
+ if txfn is None:
55
+ txfn = mktemp(suffix='.mat')
56
+
57
+ veccer = [fixed_image.dimension, fixed_image, moving_image, txfn,
58
+ search_factor, radian_fraction, int(use_principal_axis),
59
+ local_search_iterations]
60
+ if mask is not None:
61
+ veccer.append(mask)
62
+
63
+ xxx = process_arguments(veccer)
64
+ libfn = get_lib_fn('antsAffineInitializer')
65
+ retval = libfn(xxx)
66
+
67
+ if retval != 0:
68
+ warnings.warn('ERROR: Non-zero exit status!')
69
+
70
+ return txfn
MindEyeV2/antspy/ants/registration/apply_transforms.py ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ __all__ = ['apply_transforms',
4
+ 'apply_transforms_to_points']
5
+
6
+ import os
7
+
8
+ import ants
9
+ from ants.internal import get_lib_fn, process_arguments
10
+
11
+
12
+ def apply_transforms(fixed, moving, transformlist,
13
+ interpolator='linear', imagetype=0,
14
+ whichtoinvert=None, compose=None,
15
+ defaultvalue=0, singleprecision=False, verbose=False, **kwargs):
16
+ """
17
+ Apply a transform list to map an image from one domain to another.
18
+ In image registration, one computes mappings between (usually) pairs
19
+ of images. These transforms are often a sequence of increasingly
20
+ complex maps, e.g. from translation, to rigid, to affine to deformation.
21
+ The list of such transforms is passed to this function to interpolate one
22
+ image domain into the next image domain, as below. The order matters
23
+ strongly and the user is advised to familiarize with the standards
24
+ established in examples.
25
+
26
+ ANTsR function: `antsApplyTransforms`
27
+
28
+ Arguments
29
+ ---------
30
+ fixed : ANTsImage
31
+ fixed image defining domain into which the moving image is transformed. The output will
32
+ have the same pixel type as this image.
33
+
34
+ moving : AntsImage
35
+ moving image to be mapped to fixed space.
36
+
37
+ transformlist : list of strings
38
+ list of transforms generated by ants.registration where each transform is a filename.
39
+
40
+ interpolator : string
41
+ Choice of interpolator. Supports partial matching.
42
+ linear
43
+ nearestNeighbor
44
+ multiLabel for label images (deprecated, prefer genericLabel)
45
+ gaussian
46
+ bSpline
47
+ cosineWindowedSinc
48
+ welchWindowedSinc
49
+ hammingWindowedSinc
50
+ lanczosWindowedSinc
51
+ genericLabel use this for label images
52
+
53
+ imagetype : integer
54
+ choose 0/1/2/3 mapping to scalar/vector/tensor/time-series
55
+
56
+ whichtoinvert : list of booleans (optional)
57
+ Must be same length as transformlist.
58
+ whichtoinvert[i] is True if transformlist[i] is a matrix,
59
+ and the matrix should be inverted. If transformlist[i] is a
60
+ warp field, whichtoinvert[i] must be False.
61
+ If the transform list is a matrix followed by a warp field,
62
+ whichtoinvert defaults to (True,False). Otherwise it defaults
63
+ to [False]*len(transformlist)).
64
+
65
+ compose : string (optional)
66
+ if it is a string pointing to a valid file location,
67
+ this will force the function to return a composite transformation filename.
68
+
69
+ defaultvalue : scalar
70
+ Default voxel value for mappings outside the image domain.
71
+
72
+ singleprecision : boolean
73
+ if True, use float32 for computations. This is useful for reducing memory
74
+ usage for large datasets, at the cost of precision.
75
+
76
+ verbose : boolean
77
+ print command and run verbose application of transform.
78
+
79
+ kwargs : keyword arguments
80
+ extra parameters
81
+
82
+ Returns
83
+ -------
84
+ ANTsImage or string (transformation filename)
85
+
86
+ Example
87
+ -------
88
+ >>> import ants
89
+ >>> fixed = ants.image_read( ants.get_ants_data('r16') )
90
+ >>> moving = ants.image_read( ants.get_ants_data('r64') )
91
+ >>> fixed = ants.resample_image(fixed, (64,64), 1, 0)
92
+ >>> moving = ants.resample_image(moving, (64,64), 1, 0)
93
+ >>> mytx = ants.registration(fixed=fixed , moving=moving ,
94
+ type_of_transform = 'SyN' )
95
+ >>> mywarpedimage = ants.apply_transforms( fixed=fixed, moving=moving,
96
+ transformlist=mytx['fwdtransforms'] )
97
+ """
98
+
99
+ if not isinstance(transformlist, (tuple, list)) and (transformlist is not None):
100
+ transformlist = [transformlist]
101
+
102
+ accepted_interpolators = {"linear", "nearestNeighbor", "multiLabel", "gaussian",
103
+ "bSpline", "cosineWindowedSinc", "welchWindowedSinc",
104
+ "hammingWindowedSinc", "lanczosWindowedSinc", "genericLabel"}
105
+
106
+ if interpolator not in accepted_interpolators:
107
+ raise ValueError('interpolator not supported - see %s' % accepted_interpolators)
108
+
109
+ args = [fixed, moving, transformlist, interpolator]
110
+
111
+ output_pixel_type = 'float' if singleprecision else 'double'
112
+
113
+ if not isinstance(fixed, str):
114
+ if ants.is_image(fixed) and ants.is_image(moving):
115
+ for tl_path in transformlist:
116
+ if not os.path.exists(tl_path):
117
+ raise Exception('Transform %s does not exist' % tl_path)
118
+
119
+ inpixeltype = fixed.pixeltype
120
+ fixed = fixed.clone(output_pixel_type)
121
+ moving = moving.clone(output_pixel_type)
122
+ warpedmovout = moving.clone(output_pixel_type)
123
+ f = fixed
124
+ m = moving
125
+ if (moving.dimension == 4) and (fixed.dimension == 3) and (imagetype == 0):
126
+ raise Exception('Set imagetype 3 to transform time series images.')
127
+
128
+ wmo = warpedmovout
129
+ mytx = []
130
+ if whichtoinvert is None or (isinstance(whichtoinvert, (tuple,list)) and (sum([w is not None for w in whichtoinvert])==0)):
131
+ if (len(transformlist) == 2) and ('.mat' in transformlist[0]) and ('.mat' not in transformlist[1]):
132
+ whichtoinvert = (True, False)
133
+ else:
134
+ whichtoinvert = tuple([False]*len(transformlist))
135
+
136
+ if len(whichtoinvert) != len(transformlist):
137
+ raise ValueError('Transform list and inversion list must be the same length')
138
+
139
+ for i in range(len(transformlist)):
140
+ ismat = False
141
+ if '.mat' in transformlist[i]:
142
+ ismat = True
143
+ if whichtoinvert[i] and (not ismat):
144
+ raise ValueError('Cannot invert transform %i (%s) because it is not a matrix' % (i, transformlist[i]))
145
+ if whichtoinvert[i]:
146
+ mytx = mytx + ['-t', '[%s,1]' % (transformlist[i])]
147
+ else:
148
+ mytx = mytx + ['-t', transformlist[i]]
149
+
150
+ if compose is None:
151
+ args = ['-d', fixed.dimension,
152
+ '-i', m,
153
+ '-o', wmo,
154
+ '-r', f,
155
+ '-n', interpolator]
156
+ args = args + mytx
157
+ if compose:
158
+ tfn = '%scomptx.nii.gz' % compose if not compose.endswith('.h5') else compose
159
+ else:
160
+ tfn = 'NA'
161
+ if compose is not None:
162
+ mycompo = '[%s,1]' % tfn
163
+ args = ['-d', fixed.dimension,
164
+ '-i', m,
165
+ '-o', mycompo,
166
+ '-r', f,
167
+ '-n', interpolator]
168
+ args = args + mytx
169
+
170
+ myargs = process_arguments(args)
171
+
172
+ myverb = int(verbose)
173
+ if verbose:
174
+ print(myargs)
175
+
176
+ processed_args = myargs + ['-z', str(1), '-v', str(myverb), '--float', str(int(singleprecision)), '-e', str(imagetype), '-f', str(defaultvalue)]
177
+ libfn = get_lib_fn('antsApplyTransforms')
178
+ libfn(processed_args)
179
+
180
+ if compose is None:
181
+ return warpedmovout.clone(inpixeltype)
182
+ else:
183
+ if os.path.exists(tfn):
184
+ return tfn
185
+ else:
186
+ return None
187
+
188
+ else:
189
+ return 1
190
+ else:
191
+ args = args + ['-z', str(1), '--float', str(int(singleprecision)), '-e', imagetype, '-f', defaultvalue]
192
+ processed_args = process_arguments(args)
193
+ libfn = get_lib_fn('antsApplyTransforms')
194
+ libfn(processed_args)
195
+
196
+
197
+
198
+
199
+
200
+
201
+ def apply_transforms_to_points( dim, points, transformlist,
202
+ whichtoinvert=None, verbose=False ):
203
+ """
204
+ Apply a transform list to map a pointset from one domain to
205
+ another. In registration, one computes mappings between pairs of
206
+ domains. These transforms are often a sequence of increasingly
207
+ complex maps, e.g. from translation, to rigid, to affine to
208
+ deformation. The list of such transforms is passed to this
209
+ function to interpolate one image domain into the next image
210
+ domain, as below. The order matters strongly and the user is
211
+ advised to familiarize with the standards established in examples.
212
+ Importantly, point mapping goes the opposite direction of image
213
+ mapping, for both reasons of convention and engineering.
214
+
215
+ ANTsR function: `antsApplyTransformsToPoints`
216
+
217
+ Arguments
218
+ ---------
219
+ dim: integer
220
+ dimensionality of the transformation.
221
+
222
+ points: data frame
223
+ moving point set with n-points in rows of at least dim
224
+ columns - we maintain extra information in additional
225
+ columns. this should be a data frame with columns names x, y, z, t.
226
+
227
+ transformlist : list of strings
228
+ list of transforms generated by ants.registration where each transform is a filename.
229
+
230
+ whichtoinvert : list of booleans (optional)
231
+ Must be same length as transformlist.
232
+ whichtoinvert[i] is True if transformlist[i] is a matrix,
233
+ and the matrix should be inverted. If transformlist[i] is a
234
+ warp field, whichtoinvert[i] must be False.
235
+ If the transform list is a matrix followed by a warp field,
236
+ whichtoinvert defaults to (True,False). Otherwise it defaults
237
+ to [False]*len(transformlist)).
238
+
239
+ verbose : boolean
240
+
241
+ Returns
242
+ -------
243
+ data frame of transformed points
244
+
245
+ Example
246
+ -------
247
+ >>> import ants
248
+ >>> fixed = ants.image_read( ants.get_ants_data('r16') )
249
+ >>> moving = ants.image_read( ants.get_ants_data('r27') )
250
+ >>> reg = ants.registration( fixed, moving, 'Affine' )
251
+ >>> d = {'x': [128, 127], 'y': [101, 111]}
252
+ >>> pts = pd.DataFrame(data=d)
253
+ >>> ptsw = ants.apply_transforms_to_points( 2, pts, reg['fwdtransforms'])
254
+ """
255
+
256
+ if not isinstance(transformlist, (tuple, list)) and (transformlist is not None):
257
+ transformlist = [transformlist]
258
+
259
+ args = [dim, points, transformlist, whichtoinvert]
260
+
261
+ for tl_path in transformlist:
262
+ if not os.path.exists(tl_path):
263
+ raise Exception('Transform %s does not exist' % tl_path)
264
+
265
+ mytx = []
266
+
267
+ if whichtoinvert is None or (isinstance(whichtoinvert, (tuple,list)) and (sum([w is not None for w in whichtoinvert])==0)):
268
+ if (len(transformlist) == 2) and ('.mat' in transformlist[0]) and ('.mat' not in transformlist[1]):
269
+ whichtoinvert = (True, False)
270
+ else:
271
+ whichtoinvert = tuple([False]*len(transformlist))
272
+
273
+ if len(whichtoinvert) != len(transformlist):
274
+ raise ValueError('Transform list and inversion list must be the same length')
275
+
276
+ for i in range(len(transformlist)):
277
+ ismat = False
278
+ if '.mat' in transformlist[i]:
279
+ ismat = True
280
+ if whichtoinvert[i] and (not ismat):
281
+ raise ValueError('Cannot invert transform %i (%s) because it is not a matrix' % (i, transformlist[i]))
282
+ if whichtoinvert[i]:
283
+ mytx = mytx + ['-t', '[%s,1]' % (transformlist[i])]
284
+ else:
285
+ mytx = mytx + ['-t', transformlist[i]]
286
+ if dim == 2:
287
+ pointsSub = points[['x','y']]
288
+ if dim == 3:
289
+ pointsSub = points[['x','y','z']]
290
+ if dim == 4:
291
+ pointsSub = points[['x','y','z','t']]
292
+ pointImage = ants.make_image( pointsSub.shape, pointsSub.values.flatten())
293
+ pointsOut = pointImage.clone()
294
+ args = ['-d', dim,
295
+ '-i', pointImage,
296
+ '-o', pointsOut ]
297
+ args = args + mytx
298
+ myargs = process_arguments(args)
299
+
300
+ myverb = int(verbose)
301
+ if verbose:
302
+ print(myargs)
303
+
304
+ processed_args = myargs + [ '-f', str(1), '--precision', str(0)]
305
+ libfn = get_lib_fn('antsApplyTransformsToPoints')
306
+ libfn(processed_args)
307
+ mynp = pointsOut.numpy()
308
+ pointsOutDF = points.copy()
309
+ pointsOutDF['x'] = mynp[:,0]
310
+ if dim >= 2:
311
+ pointsOutDF['y'] = mynp[:,1]
312
+ if dim >= 3:
313
+ pointsOutDF['z'] = mynp[:,2]
314
+ if dim >= 4:
315
+ pointsOutDF['t'] = mynp[:,3]
316
+ return pointsOutDF
MindEyeV2/antspy/ants/registration/average_transform.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from tempfile import mktemp
3
+ import os
4
+
5
+ import ants
6
+ from ants.internal import get_lib_fn, process_arguments
7
+
8
+ __all__ = ['average_affine_transform',
9
+ 'average_affine_transform_no_rigid']
10
+
11
+
12
+ def _average_affine_transform_driver(transformlist, referencetransform=None, funcname="AverageAffineTransform"):
13
+ """
14
+ takes a list of transforms (files at the moment)
15
+ and returns the average
16
+ """
17
+
18
+ # AverageAffineTransform deals with transform files,
19
+ # so this function will need to deal with already
20
+ # loaded files. Doesn't look like the magic
21
+ # available for images has been added for transforms.
22
+ res_temp_file = mktemp(suffix='.mat')
23
+
24
+ # could do some stuff here to cope with transform lists that
25
+ # aren't files
26
+
27
+ # load one of the transforms to figure out the dimension
28
+ tf = ants.read_transform(transformlist[0])
29
+ if referencetransform is None:
30
+ args = [tf.dimension, res_temp_file] + transformlist
31
+ else:
32
+ args = [tf.dimension, res_temp_file] + ['-R', referencetransform] + transformlist
33
+ pargs = process_arguments(args)
34
+ print(pargs)
35
+ libfun = get_lib_fn(funcname)
36
+ status = libfun(pargs)
37
+
38
+ res = ants.read_transform(res_temp_file)
39
+ os.remove(res_temp_file)
40
+ return res
41
+
42
+ def average_affine_transform(transformlist, referencetransform=None):
43
+ return _average_affine_transform_driver(transformlist, referencetransform, "AverageAffineTransform")
44
+
45
+
46
+ def average_affine_transform_no_rigid(transformlist, referencetransform=None):
47
+ return _average_affine_transform_driver(transformlist, referencetransform, "AverageAffineTransformNoRigid")
48
+
MindEyeV2/antspy/ants/registration/build_template.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["build_template"]
2
+
3
+ import numpy as np
4
+ import os
5
+ import shutil
6
+ from tempfile import mktemp
7
+
8
+ import ants
9
+
10
+ def build_template(
11
+ initial_template=None,
12
+ image_list=None,
13
+ iterations=3,
14
+ gradient_step=0.2,
15
+ blending_weight=0.75,
16
+ weights=None,
17
+ useNoRigid=True,
18
+ output_dir=None,
19
+ **kwargs
20
+ ):
21
+ """
22
+ Estimate an optimal template from an input image_list
23
+
24
+ ANTsR function: N/A
25
+
26
+ Arguments
27
+ ---------
28
+ initial_template : ANTsImage
29
+ initialization for the template building
30
+
31
+ image_list : ANTsImages
32
+ images from which to estimate template
33
+
34
+ iterations : integer
35
+ number of template building iterations
36
+
37
+ gradient_step : scalar
38
+ for shape update gradient
39
+
40
+ blending_weight : scalar
41
+ weight for image blending
42
+
43
+ weights : vector
44
+ weight for each input image
45
+
46
+ useNoRigid : boolean
47
+ equivalent of -y in the script. Template update
48
+ step will not use the rigid component if this is True.
49
+
50
+ output_dir : path
51
+ directory name where intermediate transforms are written
52
+
53
+ kwargs : keyword args
54
+ extra arguments passed to ants registration
55
+
56
+ Returns
57
+ -------
58
+ ANTsImage
59
+
60
+ Example
61
+ -------
62
+ >>> import ants
63
+ >>> image = ants.image_read( ants.get_ants_data('r16') )
64
+ >>> image2 = ants.image_read( ants.get_ants_data('r27') )
65
+ >>> image3 = ants.image_read( ants.get_ants_data('r85') )
66
+ >>> timage = ants.build_template( image_list = ( image, image2, image3 ) ).resample_image( (45,45))
67
+ >>> timagew = ants.build_template( image_list = ( image, image2, image3 ), weights = (5,1,1) )
68
+ """
69
+ work_dir = mktemp() if output_dir is None else output_dir
70
+
71
+ def make_outprefix(k: int):
72
+ os.makedirs(os.path.join(work_dir, f"img{k:04d}"), exist_ok=True)
73
+ return os.path.join(work_dir, f"img{k:04d}", "out")
74
+
75
+ if "type_of_transform" not in kwargs:
76
+ type_of_transform = "SyN"
77
+ else:
78
+ type_of_transform = kwargs.pop("type_of_transform")
79
+
80
+ if weights is None:
81
+ weights = np.repeat(1.0 / len(image_list), len(image_list))
82
+ weights = [x / sum(weights) for x in weights]
83
+ if initial_template is None:
84
+ initial_template = image_list[0] * 0
85
+ for i in range(len(image_list)):
86
+ temp = image_list[i] * weights[i]
87
+ temp = ants.resample_image_to_target(temp, initial_template)
88
+ initial_template = initial_template + temp
89
+
90
+ xavg = initial_template.clone()
91
+ for i in range(iterations):
92
+ affinelist = []
93
+ for k in range(len(image_list)):
94
+ w1 = ants.registration(
95
+ xavg, image_list[k], type_of_transform=type_of_transform, outprefix=make_outprefix(k), **kwargs
96
+ )
97
+ L = len(w1["fwdtransforms"])
98
+ # affine is the last one
99
+ affinelist.append(w1["fwdtransforms"][L-1])
100
+
101
+ if k == 0:
102
+ if L == 2:
103
+ wavg = ants.image_read(w1["fwdtransforms"][0]) * weights[k]
104
+ xavgNew = w1["warpedmovout"] * weights[k]
105
+ else:
106
+ if L == 2:
107
+ wavg = wavg + ants.image_read(w1["fwdtransforms"][0]) * weights[k]
108
+ xavgNew = xavgNew + w1["warpedmovout"] * weights[k]
109
+
110
+ if useNoRigid:
111
+ avgaffine = ants.average_affine_transform_no_rigid(affinelist)
112
+ else:
113
+ avgaffine = ants.average_affine_transform(affinelist)
114
+ afffn = os.path.join(work_dir, "avgAffine.mat")
115
+ ants.write_transform(avgaffine, afffn)
116
+
117
+ if L == 2:
118
+ print(wavg.abs().mean())
119
+ wscl = (-1.0) * gradient_step
120
+ wavg = wavg * wscl
121
+ # apply affine to the nonlinear?
122
+ # need to save the average
123
+ wavgA = ants.apply_transforms(fixed=xavgNew, moving=wavg, imagetype=1, transformlist=afffn, whichtoinvert=[1])
124
+ wavgfn = os.path.join(work_dir, "avgWarp.nii.gz")
125
+ ants.image_write(wavgA, wavgfn)
126
+ xavg = ants.apply_transforms(fixed=xavgNew, moving=xavgNew, transformlist=[wavgfn, afffn], whichtoinvert=[0, 1])
127
+ else:
128
+ xavg = ants.apply_transforms(fixed=xavgNew, moving=xavgNew, transformlist=[afffn], whichtoinvert=[1])
129
+
130
+ if blending_weight is not None:
131
+ xavg = xavg * blending_weight + ants.iMath(xavg, "Sharpen") * (
132
+ 1.0 - blending_weight
133
+ )
134
+
135
+ if output_dir is None:
136
+ shutil.rmtree(work_dir)
137
+ return xavg
MindEyeV2/antspy/ants/registration/compose_displacement_fields.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['compose_displacement_fields']
3
+
4
+ import ants
5
+ from ants.internal import get_lib_fn
6
+
7
+
8
+ def compose_displacement_fields(displacement_field,
9
+ warping_field):
10
+ """
11
+ Compose displacement fields.
12
+
13
+ Arguments
14
+ ---------
15
+ displacement_field : ANTsImage displacement field
16
+ displacement field
17
+
18
+ warping_field : ANTsImage displacement field
19
+ warping field
20
+
21
+
22
+ Example
23
+ -------
24
+ >>> import ants
25
+ """
26
+
27
+ libfn = get_lib_fn('composeDisplacementFieldsD%i' % displacement_field.dimension)
28
+ comp_field = libfn(displacement_field.pointer, warping_field.pointer)
29
+
30
+ new_image = ants.from_pointer(comp_field).clone('float')
31
+ return new_image
32
+
33
+
MindEyeV2/antspy/ants/registration/create_jacobian_determinant_image.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ __all__ = ['create_jacobian_determinant_image',
5
+ 'deformation_gradient']
6
+
7
+ from tempfile import mktemp
8
+
9
+ import ants
10
+ from ants.internal import get_lib_fn, process_arguments
11
+
12
+
13
+ def deformation_gradient( warp_image, to_rotation=False, py_based=False ):
14
+ """
15
+ Compute the deformation gradient from an image containing a warp (deformation)
16
+
17
+ ANTsR function: `NA`
18
+
19
+ Arguments
20
+ ---------
21
+ warp_image : ANTsImage (or filename if not py_based)
22
+ image that defines the deformation field (vector pixels)
23
+
24
+ to_rotation : boolean maps deformation gradient to a rotation matrix
25
+
26
+ py_based: boolean uses pure python implementation (maybe slow)
27
+
28
+ Returns
29
+ -------
30
+ ANTsImage with dimension*dimension components indexed in order U_xyz, V_xyz, W_xyz
31
+ where U is the x-component of deformation and xyz are spatial.
32
+
33
+ Note
34
+ -------
35
+ the to_rotation option is still experimental. use with caution.
36
+
37
+ Example
38
+ -------
39
+ >>> import ants
40
+ >>> fi = ants.image_read( ants.get_ants_data('r16'))
41
+ >>> mi = ants.image_read( ants.get_ants_data('r64'))
42
+ >>> fi = ants.resample_image(fi,(128,128),1,0)
43
+ >>> mi = ants.resample_image(mi,(128,128),1,0)
44
+ >>> mytx = ants.registration(fixed=fi , moving=mi, type_of_transform = ('SyN') )
45
+ >>> dg = ants.deformation_gradient( ants.image_read( mytx['fwdtransforms'][0] ) )
46
+ """
47
+ import numpy as np
48
+ def polar_decomposition(X):
49
+ U, d, V = np.linalg.svd(X, full_matrices=False)
50
+ P = np.matmul(U, np.matmul(np.diag(d), np.transpose(U)))
51
+ Z = np.matmul(U, V)
52
+ if np.linalg.det(Z) < 0:
53
+ n = X.shape[0]
54
+ reflection_matrix = np.identity(n)
55
+ reflection_matrix[0,0] = -1.0
56
+ Z = np.matmul(Z, reflection_matrix)
57
+ return({"P" : P, "Z" : Z, "Xtilde" : np.matmul(P, Z)})
58
+ if not py_based:
59
+ if ants.is_image(warp_image):
60
+ txuse = mktemp(suffix='.nii.gz')
61
+ ants.image_write(warp_image, txuse)
62
+ else:
63
+ txuse = warp_image
64
+ warp_image=ants.image_read(txuse)
65
+ if not ants.is_image(warp_image):
66
+ raise RuntimeError("antsimage is required")
67
+ writtenimage = mktemp(suffix='.nrrd')
68
+ dimage = warp_image.split_channels()[0].clone('double')
69
+ dim = dimage.dimension
70
+ tshp = dimage.shape
71
+ args2 = [dim, txuse, writtenimage, int(0), int(0), int(1)]
72
+ processed_args = process_arguments(args2)
73
+ libfn = get_lib_fn('CreateJacobianDeterminantImage')
74
+ libfn(processed_args)
75
+ dg = ants.image_read(writtenimage)
76
+ if to_rotation:
77
+ newshape = tshp + (dim,dim)
78
+ dg = np.reshape( dg.numpy(), newshape )
79
+ it=np.ndindex(tshp)
80
+ for i in it:
81
+ dg[i]=polar_decomposition( dg[i] )['Z']
82
+ newshape = tshp + (dim*dim,)
83
+ dg = np.reshape( dg, newshape )
84
+ dg = ants.from_numpy( dg, has_components=True )
85
+ dg = ants.copy_image_info( dimage, dg )
86
+ import os
87
+ os.remove( writtenimage )
88
+ return dg
89
+ if py_based:
90
+ if not ants.is_image(warp_image):
91
+ raise RuntimeError("antsimage is required")
92
+ dim = warp_image.dimension
93
+ warpnp=warp_image.numpy()
94
+ tshp=warp_image.shape
95
+ tdir=warp_image.direction
96
+ spc = warp_image.spacing
97
+ it=np.ndindex(tshp)
98
+ # print("first we need to rotate the warp by the direction cosines")
99
+ for i in it:
100
+ warpnp[i]=np.dot( tdir,warpnp[i])
101
+ # print("second get deformation gradient")
102
+ dg = []
103
+ for k in range(dim):
104
+ if dim == 2:
105
+ temp=np.stack( np.gradient( warpnp[...,k], spc[0], spc[1], axis=range(dim) ), axis=dim)
106
+ if dim == 3:
107
+ temp=np.stack( np.gradient( warpnp[...,k], spc[0], spc[1], spc[2], axis=range(dim) ), axis=dim)
108
+ dg.append(temp)
109
+ dg = np.stack(dg,axis=dim+1)
110
+ it=np.ndindex(tshp)
111
+ ident = np.eye( dim )
112
+ for i in it:
113
+ dg[i]=dg[i]+ident
114
+ if to_rotation:
115
+ it=np.ndindex(tshp)
116
+ for i in it:
117
+ dg[i]=polar_decomposition( dg[i] )['Z']
118
+ newshape = tshp + (dim*dim,)
119
+ dg = np.reshape( dg, newshape )
120
+ dg = ants.from_numpy( dg, has_components=True )
121
+ dg = ants.copy_image_info( warp_image, dg )
122
+ return dg
123
+
124
+
125
+
126
+ def create_jacobian_determinant_image(domain_image, tx, do_log=False, geom=False):
127
+ """
128
+ Compute the jacobian determinant from a transformation file
129
+
130
+ ANTsR function: `createJacobianDeterminantImage`
131
+
132
+ Arguments
133
+ ---------
134
+ domain_image : ANTsImage
135
+ image that defines transformation domain
136
+
137
+ tx : string
138
+ deformation transformation file name
139
+
140
+ do_log : boolean
141
+ return the log jacobian
142
+
143
+ geom : bolean
144
+ use the geometric jacobian calculation (boolean)
145
+
146
+ Returns
147
+ -------
148
+ ANTsImage
149
+
150
+ Example
151
+ -------
152
+ >>> import ants
153
+ >>> fi = ants.image_read( ants.get_ants_data('r16'))
154
+ >>> mi = ants.image_read( ants.get_ants_data('r64'))
155
+ >>> fi = ants.resample_image(fi,(128,128),1,0)
156
+ >>> mi = ants.resample_image(mi,(128,128),1,0)
157
+ >>> mytx = ants.registration(fixed=fi , moving=mi, type_of_transform = ('SyN') )
158
+ >>> jac = ants.create_jacobian_determinant_image(fi,mytx['fwdtransforms'][0],1)
159
+ """
160
+ dim = domain_image.dimension
161
+ if ants.is_image(tx):
162
+ txuse = mktemp(suffix='.nii.gz')
163
+ ants.image_write(tx, txuse)
164
+ else:
165
+ txuse = tx
166
+ #args = [dim, txuse, do_log]
167
+ dimage = domain_image.clone('double')
168
+ args2 = [dim, txuse, dimage, int(do_log), int(geom)]
169
+ processed_args = process_arguments(args2)
170
+ libfn = get_lib_fn('CreateJacobianDeterminantImage')
171
+ libfn(processed_args)
172
+ jimage = args2[2].clone('float')
173
+
174
+ return jimage
175
+
MindEyeV2/antspy/ants/registration/create_warped_grid.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ __all__ = ['create_warped_grid']
4
+
5
+ import numpy as np
6
+
7
+ import ants
8
+
9
+
10
+ def create_warped_grid(image, grid_step=10, grid_width=2, grid_directions=(True, True),
11
+ fixed_reference_image=None, transform=None, foreground=1, background=0):
12
+ """
13
+ Deforming a grid is a helpful way to visualize a deformation field.
14
+ This function enables a user to define the grid parameters
15
+ and apply a deformable map to that grid.
16
+
17
+ ANTsR function: `createWarpedGrid`
18
+
19
+ Arguments
20
+ ---------
21
+ image : ANTsImage
22
+ input image
23
+
24
+ grid_step : scalar
25
+ width of grid blocks
26
+
27
+ grid_width : scalar
28
+ width of grid lines
29
+
30
+ grid_directions : tuple of booleans
31
+ directions in which to draw grid lines, boolean vector
32
+
33
+ fixed_reference_image : ANTsImage (optional)
34
+ reference image space
35
+
36
+ transform : list/tuple of strings (optional)
37
+ vector of transforms
38
+
39
+ foreground : scalar
40
+ intensity value for grid blocks
41
+
42
+ background : scalar
43
+ intensity value for grid lines
44
+
45
+ Returns
46
+ -------
47
+ ANTsImage
48
+
49
+ Example
50
+ -------
51
+ >>> import ants
52
+ >>> fi = ants.image_read( ants.get_ants_data( 'r16' ) )
53
+ >>> mi = ants.image_read( ants.get_ants_data( 'r64' ) )
54
+ >>> mygr = ants.create_warped_grid( mi )
55
+ >>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = ('SyN') )
56
+ >>> mywarpedgrid = ants.create_warped_grid( mygr, grid_directions=(False,True),
57
+ transform=mytx['fwdtransforms'], fixed_reference_image=fi )
58
+ """
59
+ if ants.is_image(image):
60
+ if len(grid_directions) != image.dimension:
61
+ grid_directions = [True]*image.dimension
62
+ garr = image.numpy() * 0 + foreground
63
+ else:
64
+ if not isinstance(image, (list, tuple)):
65
+ raise ValueError('image arg must be ANTsImage or list or tuple')
66
+ if len(grid_directions) != len(image):
67
+ grid_directions = [True]*len(image)
68
+ garr = np.zeros(image) + foreground
69
+ image = ants.from_numpy(garr)
70
+
71
+ idim = garr.ndim
72
+ gridw = grid_width
73
+
74
+ for d in range(idim):
75
+ togrid = np.arange(-1, garr.shape[d]-1, step=grid_step)
76
+ for i in range(len(togrid)):
77
+ if (d == 0) & (idim == 3) & (grid_directions[d]):
78
+ garr[togrid[i]:(togrid[i]+gridw),...] = background
79
+ garr[0,...] = background
80
+ garr[-1,...] = background
81
+ if (d == 1) & (idim == 3) & (grid_directions[d]):
82
+ garr[:,togrid[i]:(togrid[i]+gridw),:] = background
83
+ garr[:,0,:] = background
84
+ garr[:,-1,:] = background
85
+ if (d == 2) & (idim == 3) & (grid_directions[d]):
86
+ garr[...,togrid[i]:(togrid[i]+gridw)] = background
87
+ garr[...,0] = background
88
+ garr[...,-1] = background
89
+ if (d == 0) & (idim == 2) & (grid_directions[d]):
90
+ garr[togrid[i]:(togrid[i]+gridw),:] = background
91
+ garr[0,:] = background
92
+ garr[-1,:] = background
93
+ if (d == 1) & (idim == 2) & (grid_directions[d]):
94
+ garr[:,togrid[i]:(togrid[i]+gridw)] = background
95
+ garr[:,0] = background
96
+ garr[:,-1] = background
97
+
98
+
99
+ gimage = image.new_image_like(garr)
100
+
101
+ if (transform is not None) and (fixed_reference_image is not None):
102
+ return ants.apply_transforms( fixed=fixed_reference_image, moving=gimage,
103
+ transformlist=transform )
104
+ else:
105
+ return gimage
MindEyeV2/antspy/ants/registration/fit_bspline_displacement_field.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["fit_bspline_displacement_field"]
2
+
3
+ import numpy as np
4
+
5
+ import ants
6
+ from ants.internal import get_lib_fn
7
+
8
+
9
+ def fit_bspline_displacement_field(displacement_field=None,
10
+ displacement_weight_image=None,
11
+ displacement_origins=None,
12
+ displacements=None,
13
+ displacement_weights=None,
14
+ origin=None,
15
+ spacing=None,
16
+ size=None,
17
+ direction=None,
18
+ number_of_fitting_levels=4,
19
+ mesh_size=1,
20
+ spline_order=3,
21
+ enforce_stationary_boundary=True,
22
+ estimate_inverse=False,
23
+ rasterize_points=False):
24
+
25
+ """
26
+ Fit a b-spline object to a dense displacement field image and/or a set of points
27
+ with associated displacements and smooths them using B-splines. The inverse
28
+ can also be estimated.. This is basically a wrapper for the ITK filter
29
+
30
+ https://itk.org/Doxygen/html/classitk_1_1DisplacementFieldToBSplineImageFilter.html}
31
+
32
+ which, in turn is a wrapper for the ITK filter used for the function
33
+ fit_bspline_object_to_scattered_data.
34
+
35
+ ANTsR function: `fitBsplineToDisplacementField`
36
+
37
+ Arguments
38
+ ---------
39
+ displacement_field : ANTs image
40
+ Input displacement field. Either this and/or the points must be specified.
41
+
42
+ displacement_weight_image : ANTs image
43
+ Input image defining weighting of the voxelwise displacements in the displacement_field. I
44
+ If None, defaults to identity weighting for each displacement. Default = None.
45
+
46
+ displacement_origins : 2-D numpy array
47
+ Matrix (number_of_points x dimension) defining the origins of the input
48
+ displacement points. Default = None.
49
+
50
+ displacements : 2-D numpy array
51
+ Matrix (number_of_points x dimension) defining the displacements of the input
52
+ displacement points. Default = None.
53
+
54
+ displacement_weights : 1-D numpy array
55
+ Array defining the individual weighting of the corresponding scattered data value.
56
+ Default = None meaning all values are weighted the same.
57
+
58
+ origin : n-D tuple
59
+ Defines the physical origin of the B-spline object.
60
+
61
+ spacing : n-D tuple
62
+ Defines the physical spacing of the B-spline object.
63
+
64
+ size : n-D tuple
65
+ Defines the size (length) of the B-spline object. Note that the length of the
66
+ B-spline object in dimension d is defined as
67
+ spacing[d] * size[d]-1.
68
+
69
+ direction : 2-D numpy array
70
+ Booleans defining whether or not the corresponding parametric dimension is
71
+ closed (e.g., closed loop). Default = None.
72
+
73
+ number_of_fitting_levels : integer
74
+ Specifies the number of fitting levels.
75
+
76
+ mesh_size : n-D tuple
77
+ Defines the mesh size at the initial fitting level.
78
+
79
+ spline_order : integer
80
+ Spline order of the B-spline object. Default = 3.
81
+
82
+ enforce_stationary_boundary : boolean
83
+ Ensure no displacements on the image boundary. Default = True.
84
+
85
+ estimate_inverse : boolean
86
+ Estimate the inverse displacement field. Default = False.
87
+
88
+ rasterize_points : boolean
89
+ Use nearest neighbor rasterization of points for estimating the
90
+ field (potential speed-up). Default = False.
91
+
92
+ Returns
93
+ -------
94
+ Returns an ANTsImage.
95
+
96
+ Example
97
+ -------
98
+ >>> import ants
99
+ >>> import numpy as np
100
+ >>> points = np.array([[-50, -50]])
101
+ >>> deltas = np.array([[10, 10]])
102
+ >>> bspline_field = ants.fit_bspline_displacement_field(
103
+ >>> displacement_origins=points, displacements=deltas,
104
+ >>> origin=[0.0, 0.0], spacing=[1.0, 1.0], size=[100, 100],
105
+ >>> direction=np.array([[-1, 0], [0, -1]]),
106
+ >>> number_of_fitting_levels=4, mesh_size=(1, 1))
107
+ """
108
+
109
+ if displacement_field is None and (displacement_origins is None or displacements is None):
110
+ raise ValueError("Missing input. Either a displacement field or input point set (origins + displacements) needs to be specified.")
111
+
112
+ if displacement_field is None:
113
+ if origin is None or spacing is None or size is None or direction is None:
114
+ raise ValueError("If the displacement field is not specified, one must fully specify the input physical domain.")
115
+
116
+ if displacement_field is not None and displacement_weight_image is None:
117
+ displacement_weight_image = ants.make_image(displacement_field.shape, voxval=1,
118
+ spacing=displacement_field.spacing, origin=displacement_field.origin,
119
+ direction=displacement_field.direction, has_components=False, pixeltype='float')
120
+
121
+ if displacement_field is not None:
122
+ if origin is None:
123
+ origin = displacement_field.origin
124
+ if spacing is None:
125
+ spacing = displacement_field.spacing
126
+ if direction is None:
127
+ direction = displacement_field.direction
128
+ if size is None:
129
+ size = displacement_field.shape
130
+
131
+ dimensionality = None
132
+ if displacement_field is not None:
133
+ dimensionality = displacement_field.dimension
134
+ else:
135
+ dimensionality = displacement_origins.shape[1]
136
+ if displacements.shape[1] != dimensionality:
137
+ raise ValueError("Dimensionality between origins and displacements does not match.")
138
+
139
+ if displacement_origins is not None:
140
+ if displacement_weights is not None and (len(displacement_weights) != displacement_origins.shape[0]):
141
+ raise ValueError("Length of displacement weights must match the number of displacement points.")
142
+ else:
143
+ displacement_weights = np.ones(displacement_origins.shape[0])
144
+
145
+ if isinstance(mesh_size, int) == False and len(mesh_size) != dimensionality:
146
+ raise ValueError("Incorrect specification for mesh_size.")
147
+
148
+ if origin is not None and len(origin) != dimensionality:
149
+ raise ValueError("Origin is not of length dimensionality.")
150
+
151
+ if spacing is not None and len(spacing) != dimensionality:
152
+ raise ValueError("Spacing is not of length dimensionality.")
153
+
154
+ if size is not None and len(size) != dimensionality:
155
+ raise ValueError("Size is not of length dimensionality.")
156
+
157
+ if direction is not None and (direction.shape[0] != dimensionality and direction.shape[1] != dimensionality):
158
+ raise ValueError("Direction is not of shape dimensionality x dimensionality.")
159
+
160
+ # It would seem that pybind11 doesn't really play nicely when the
161
+ # arguments are 'None'
162
+
163
+ if origin is None:
164
+ origin = np.empty(0)
165
+
166
+ if spacing is None:
167
+ spacing = np.empty(0)
168
+
169
+ if size is None:
170
+ size = np.empty(0)
171
+
172
+ if direction is None:
173
+ direction = np.empty((0, 0))
174
+
175
+ if displacement_origins is None:
176
+ displacement_origins = np.empty((0, 0))
177
+ displacement_weights = np.empty(0)
178
+ else:
179
+ if displacement_weights is None:
180
+ displacement_weights = np.repeat(1.0, displacement_origins.shape[0])
181
+
182
+ number_of_control_points = list(np.array(mesh_size) + np.repeat(spline_order, dimensionality))
183
+
184
+ bspline_field = None
185
+ if displacement_field is not None:
186
+ libfn = get_lib_fn("fitBsplineDisplacementFieldD%i" % (dimensionality))
187
+ bspline_field = libfn(displacement_field.pointer, displacement_weight_image.pointer,
188
+ displacement_origins, displacements, displacement_weights,
189
+ origin, spacing, size, direction,
190
+ number_of_fitting_levels, number_of_control_points, spline_order,
191
+ enforce_stationary_boundary, estimate_inverse)
192
+ elif displacement_field is None and displacements is not None:
193
+ libfn = get_lib_fn("fitBsplineDisplacementFieldToScatteredDataD%i" % (dimensionality))
194
+ bspline_field = libfn(displacement_origins, displacements, displacement_weights,
195
+ origin, spacing, size, direction,
196
+ number_of_fitting_levels, number_of_control_points, spline_order,
197
+ enforce_stationary_boundary, estimate_inverse, rasterize_points)
198
+
199
+
200
+ bspline_displacement_field = ants.from_pointer(bspline_field).clone('float')
201
+ return bspline_displacement_field
202
+
MindEyeV2/antspy/ants/registration/fit_bspline_object_to_scattered_data.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["fit_bspline_object_to_scattered_data"]
2
+
3
+ import numpy as np
4
+
5
+ import ants
6
+ from ants.internal import get_lib_fn
7
+
8
+
9
+ def fit_bspline_object_to_scattered_data(scattered_data,
10
+ parametric_data,
11
+ parametric_domain_origin,
12
+ parametric_domain_spacing,
13
+ parametric_domain_size,
14
+ is_parametric_dimension_closed=None,
15
+ data_weights=None,
16
+ number_of_fitting_levels=4,
17
+ mesh_size=1,
18
+ spline_order=3):
19
+
20
+ """
21
+ Fit a b-spline object to scattered data. This is basically a wrapper
22
+ for the ITK filter
23
+
24
+ https://itk.org/Doxygen/html/classitk_1_1BSplineScatteredDataPointSetToImageFilter.html
25
+
26
+ This filter is flexible in the possible objects that can be approximated.
27
+ Possibilities include:
28
+
29
+ * 1/2/3/4-D curve
30
+ * 2-D surface in 3-D space (not available/templated)
31
+ * 2/3/4-D scalar field
32
+ * 2/3-D displacement field
33
+ * 2/3-D time-varying velocity field
34
+
35
+ In order to understand the input parameters, it is important to understand
36
+ the difference between the parametric and data dimensions. A curve as one
37
+ parametric dimension but the data dimension can be 1-D, 2-D, 3-D, or 4-D.
38
+ In contrast, a 3-D displacement field has a parametric and data dimension
39
+ of 3. The scattered data is what's approximated by the B-spline object and
40
+ the parametric point is the location of scattered data within the domain of
41
+ the B-spline object.
42
+
43
+ ANTsR function: `fitBsplineObjectToScatteredData`
44
+
45
+ Arguments
46
+ ---------
47
+ scattered_data : 2-D numpy array
48
+ Defines the scattered data input to be approximated. Data is organized
49
+ by row --> data v, column ---> data dimension.
50
+
51
+ parametric_data : 2-D numpy array
52
+ Defines the parametric location of the scattered data. Data is organized
53
+ by row --> parametric point, column --> parametric dimension. Note that
54
+ each row corresponds to the same row in the scatteredData.
55
+
56
+ data_weights : 1-D numpy array
57
+ Defines the individual weighting of the corresponding scattered data value.
58
+ Default = None meaning all values are weighted the same.
59
+
60
+ parametric_domain_origin : n-D tuple
61
+ Defines the parametric origin of the B-spline object.
62
+
63
+ parametric_domain_spacing : n-D tuple
64
+ Defines the parametric spacing of the B-spline object. Defines the sampling
65
+ rate in the parametric domain.
66
+
67
+ parametric_domain_size : n-D tuple
68
+ Defines the size (length) of the B-spline object. Note that the length of the
69
+ B-spline object in dimension d is defined as
70
+ parametric_domain_spacing[d] * parametric_domain_size[d]-1.
71
+
72
+ is_parametric_dimension_closed : n-D tuple
73
+ Booleans defining whether or not the corresponding parametric dimension is
74
+ closed (e.g., closed loop). Default = None.
75
+
76
+ number_of_fitting_levels : integer
77
+ Specifies the number of fitting levels.
78
+
79
+ mesh_size : n-D tuple
80
+ Defines the mesh size at the initial fitting level.
81
+
82
+ spline_order : integer
83
+ Spline order of the B-spline object. Default = 3.
84
+
85
+ Returns
86
+ -------
87
+ returns numpy array for B-spline curve (parametric dimension = 1). Otherwise,
88
+ returns an ANTsImage.
89
+
90
+ Example
91
+ -------
92
+ >>> # Perform 2-D curve example
93
+ >>>
94
+ >>> import ants, numpy
95
+ >>> import matplotlib.pyplot as plt
96
+ >>> x = numpy.linspace(-4, 4, num=100)
97
+ >>> y = numpy.exp(-numpy.multiply(x, x)) + numpy.random.uniform(-0.1, 0.1, len(x))
98
+ >>> u = numpy.linspace(0, 1.0, num=len(x))
99
+ >>> scattered_data = numpy.column_stack((x, y))
100
+ >>> parametric_data = numpy.expand_dims(u, axis=-1)
101
+ >>> spacing = 1/(len(x)-1) * 1.0;
102
+ >>> bspline_curve = ants.fit_bspline_object_to_scattered_data(scattered_data,
103
+ >>> parametric_data,
104
+ >>> parametric_domain_origin=[0.0], parametric_domain_spacing=[spacing],
105
+ >>> parametric_domain_size=[len(x)], is_parametric_dimension_closed=None,
106
+ >>> number_of_fitting_levels=5, mesh_size=1)
107
+ >>> plt.plot(x, y, label='Noisy points')
108
+ >>> plt.plot(bspline_curve[:,0], bspline_curve[:,1], label='B-spline curve')
109
+ >>> plt.grid(True)
110
+ >>> plt.axis('tight')
111
+ >>> plt.legend(loc='upper left')
112
+ >>> plt.show()
113
+ >>>
114
+ >>> ###########################################################################
115
+ >>>
116
+ >>> # Perform 2-D scalar field (i.e., image) example
117
+ >>>
118
+ >>> import ants, numpy
119
+ >>> number_of_random_points = 10000
120
+ >>> img = ants.image_read( ants.get_ants_data("r16"))
121
+ >>> img_array = img.numpy()
122
+ >>> row_indices = numpy.random.choice(range(2, img_array.shape[0]), number_of_random_points)
123
+ >>> col_indices = numpy.random.choice(range(2, img_array.shape[1]), number_of_random_points)
124
+ >>> scattered_data = numpy.zeros((number_of_random_points, 1))
125
+ >>> parametric_data = numpy.zeros((number_of_random_points, 2))
126
+ >>> for i in range(number_of_random_points):
127
+ >>> scattered_data[i,0] = img_array[row_indices[i], col_indices[i]]
128
+ >>> parametric_data[i,0] = row_indices[i]
129
+ >>> parametric_data[i,1] = col_indices[i]
130
+ >>> bspline_img = ants.fit_bspline_object_to_scattered_data(
131
+ >>> scattered_data, parametric_data,
132
+ >>> parametric_domain_origin=[0.0, 0.0],
133
+ >>> parametric_domain_spacing=[1.0, 1.0],
134
+ >>> parametric_domain_size = img.shape,
135
+ >>> number_of_fitting_levels=7, mesh_size=1)
136
+ >>>
137
+ >>> ants.plot(img, title="Original")
138
+ >>> ants.plot(bspline_img, title="B-spline approximation")
139
+ """
140
+
141
+ parametric_dimension = parametric_data.shape[1]
142
+ data_dimension = scattered_data.shape[1]
143
+
144
+ if is_parametric_dimension_closed is None:
145
+ is_parametric_dimension_closed = np.repeat(False, parametric_dimension)
146
+
147
+ if isinstance(mesh_size, int) == False and len(mesh_size) != parametric_dimension:
148
+ raise ValueError("Incorrect specification for mesh_size.")
149
+
150
+ if len(parametric_domain_origin) != parametric_dimension:
151
+ raise ValueError("Origin is not of length parametric_dimension.")
152
+
153
+ if len(parametric_domain_spacing) != parametric_dimension:
154
+ raise ValueError("Spacing is not of length parametric_dimension.")
155
+
156
+ if len(parametric_domain_size) != parametric_dimension:
157
+ raise ValueError("Size is not of length parametric_dimension.")
158
+
159
+ if len(is_parametric_dimension_closed) != parametric_dimension:
160
+ raise ValueError("Closed is not of length parametric_dimension.")
161
+
162
+ number_of_control_points = mesh_size + spline_order
163
+
164
+ if isinstance(number_of_control_points, int) == True:
165
+ number_of_control_points = np.repeat(number_of_control_points, parametric_dimension)
166
+
167
+ if parametric_data.shape[0] != scattered_data.shape[0]:
168
+ raise ValueError("The number of points is not equal to the number of scattered data values.")
169
+
170
+ if data_weights is None:
171
+ data_weights = np.repeat(1.0, parametric_data.shape[0])
172
+
173
+ if data_weights.ndim == 2:
174
+ data_weights = np.squeeze(data_weights)
175
+
176
+ if len(data_weights) != parametric_data.shape[0]:
177
+ raise ValueError("The number of weights is not the same as the number of points.")
178
+
179
+ libfn = get_lib_fn("fitBsplineObjectToScatteredDataP%iD%i" % (parametric_dimension, data_dimension))
180
+ bspline_object = libfn(scattered_data.tolist(), parametric_data.tolist(), data_weights.tolist(),
181
+ parametric_domain_origin, parametric_domain_spacing,
182
+ parametric_domain_size, is_parametric_dimension_closed.tolist(),
183
+ number_of_fitting_levels, number_of_control_points.tolist(),
184
+ spline_order)
185
+
186
+ if parametric_dimension == 1:
187
+ return np.array(bspline_object)
188
+ else:
189
+ bspline_image = ants.from_pointer(bspline_object).clone('float')
190
+ return bspline_image
191
+
MindEyeV2/antspy/ants/registration/fit_thin_plate_spline_displacement_field.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["fit_thin_plate_spline_displacement_field"]
2
+
3
+ import numpy as np
4
+
5
+ import ants
6
+ from ants.internal import get_lib_fn
7
+
8
+
9
+ def fit_thin_plate_spline_displacement_field(displacement_origins=None,
10
+ displacements=None,
11
+ origin=None,
12
+ spacing=None,
13
+ size=None,
14
+ direction=None):
15
+
16
+ """
17
+ Fit a thin-plate spline object to a a set of points with associated displacements.
18
+ This is basically a wrapper for the ITK filter
19
+
20
+ https://itk.org/Doxygen/html/itkThinPlateSplineKernelTransform_8h.html
21
+
22
+ ANTsR function: `fitThinPlateSplineToDisplacementField`
23
+
24
+ Arguments
25
+ ---------
26
+
27
+ displacement_origins : 2-D numpy array
28
+ Matrix (number_of_points x dimension) defining the origins of the input
29
+ displacement points. Default = None.
30
+
31
+ displacements : 2-D numpy array
32
+ Matrix (number_of_points x dimension) defining the displacements of the input
33
+ displacement points. Default = None.
34
+
35
+ origin : n-D tuple
36
+ Defines the physical origin of the B-spline object.
37
+
38
+ spacing : n-D tuple
39
+ Defines the physical spacing of the B-spline object.
40
+
41
+ size : n-D tuple
42
+ Defines the size (length) of the spline object. Note that the length of the
43
+ spline object in dimension d is defined as spacing[d] * size[d]-1.
44
+
45
+ direction : 2-D numpy array
46
+ Booleans defining whether or not the corresponding parametric dimension is
47
+ closed (e.g., closed loop). Default = None.
48
+
49
+ Returns
50
+ -------
51
+ Returns an ANTsImage.
52
+
53
+ Example
54
+ -------
55
+ >>> import ants
56
+ >>> import numpy as np
57
+ >>> points = np.array([[-50, -50]])
58
+ >>> deltas = np.array([[10, 10]])
59
+ >>> tps_field = ants.fit_thin_plate_spline_displacement_field(
60
+ >>> displacement_origins=points, displacements=deltas,
61
+ >>> origin=[0.0, 0.0], spacing=[1.0, 1.0], size=[100, 100],
62
+ >>> direction=np.array([[-1, 0], [0, -1]]))
63
+ """
64
+
65
+ dimensionality = displacement_origins.shape[1]
66
+ if displacements.shape[1] != dimensionality:
67
+ raise ValueError("Dimensionality between origins and displacements does not match.")
68
+
69
+ if displacement_origins is None or displacement_origins is None:
70
+ raise ValueError("Missing input. Input point set (origins + displacements) needs to be specified." )
71
+
72
+ if origin is not None and len(origin) != dimensionality:
73
+ raise ValueError("Origin is not of length dimensionality.")
74
+
75
+ if spacing is not None and len(spacing) != dimensionality:
76
+ raise ValueError("Spacing is not of length dimensionality.")
77
+
78
+ if size is not None and len(size) != dimensionality:
79
+ raise ValueError("Size is not of length dimensionality.")
80
+
81
+ if direction is not None and (direction.shape[0] != dimensionality and direction.shape[1] != dimensionality):
82
+ raise ValueError("Direction is not of shape dimensionality x dimensionality.")
83
+
84
+ # It would seem that pybind11 doesn't really play nicely when the
85
+ # arguments are 'None'
86
+
87
+ if origin is None:
88
+ origin = np.empty(0)
89
+
90
+ if spacing is None:
91
+ spacing = np.empty(0)
92
+
93
+ if size is None:
94
+ size = np.empty(0)
95
+
96
+ if direction is None:
97
+ direction = np.empty((0, 0))
98
+
99
+ tps_field = None
100
+ libfn = get_lib_fn("fitThinPlateSplineDisplacementFieldToScatteredDataD%i" % (dimensionality))
101
+ tps_field = libfn(displacement_origins, displacements, origin, spacing, size, direction)
102
+
103
+ tps_displacement_field = ants.from_pointer(tps_field).clone('float')
104
+ return tps_displacement_field
105
+
MindEyeV2/antspy/ants/registration/integrate_velocity_field.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['integrate_velocity_field']
3
+
4
+ import ants
5
+ from ants.internal import get_lib_fn
6
+
7
+
8
+ def integrate_velocity_field(velocity_field,
9
+ lower_integration_bound=0.0,
10
+ upper_integration_bound=1.0,
11
+ number_of_integration_steps=10):
12
+ """
13
+ Integrate velocity field.
14
+
15
+ Arguments
16
+ ---------
17
+ velocity_field : ANTsImage velocity field
18
+ time-varying displacement field
19
+
20
+ lower_integration_bound: float
21
+ Lower time bound for integration in [0, 1]
22
+
23
+ upper_integration_bound: float
24
+ Upper time bound for integration in [0, 1]
25
+
26
+ number_of_integation_steps: integer
27
+ Number of integration steps used in the Runge-Kutta solution
28
+
29
+ Example
30
+ -------
31
+ >>> import ants
32
+ >>> fi = ants.image_read( ants.get_data( "r16" ) )
33
+ >>> mi = ants.image_read( ants.get_data( "r27" ) )
34
+ >>> reg = ants.registration(fi, mi, "TV[2]")
35
+ >>> velocity_field = ants.image_read(reg['velocityfield'][0])
36
+ >>> field = ants.integrate_velocity_field(velocity_field, 0.0, 1.0, 10)
37
+ >>> temp=ants.apply_ants_transform_to_image(
38
+ ants.transform_from_displacement_field( field ), mi, fi )
39
+ """
40
+
41
+ libfn = get_lib_fn('integrateVelocityFieldD%i' % (velocity_field.dimension-1))
42
+ integrated_field = libfn(velocity_field.pointer, lower_integration_bound,
43
+ upper_integration_bound, number_of_integration_steps)
44
+
45
+ new_image = ants.from_pointer(integrated_field).clone('float')
46
+ return new_image
47
+
48
+
MindEyeV2/antspy/ants/registration/invert_displacement_field.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ __all__ = ['invert_displacement_field']
3
+
4
+ import ants
5
+ from ants.internal import get_lib_fn
6
+
7
+
8
+ def invert_displacement_field(displacement_field,
9
+ inverse_field_initial_estimate,
10
+ maximum_number_of_iterations=20,
11
+ mean_error_tolerance_threshold=0.001,
12
+ max_error_tolerance_threshold=0.1,
13
+ enforce_boundary_condition=True):
14
+ """
15
+ Invert displacement field.
16
+
17
+ Arguments
18
+ ---------
19
+ displacement_field : ANTsImage displacement field
20
+ displacement field
21
+
22
+ inverse_field_initial_estimate : ANTsImage displacement field
23
+ initial guess
24
+
25
+ maximum_number_of_iterations : integer
26
+ number of iterations
27
+
28
+ mean_error_tolerance_threshold : float
29
+ mean error tolerance threshold
30
+
31
+ max_error_tolerance_threshold : float
32
+ max error tolerance threshold
33
+
34
+ enforce_boundary_condition : bool
35
+ enforce stationary boundary condition
36
+
37
+
38
+ Example
39
+ -------
40
+ >>> import ants
41
+ """
42
+
43
+ libfn = get_lib_fn('invertDisplacementFieldD%i' % displacement_field.dimension)
44
+ inverse_field = libfn(displacement_field.pointer, inverse_field_initial_estimate.pointer,
45
+ maximum_number_of_iterations, mean_error_tolerance_threshold,
46
+ max_error_tolerance_threshold, enforce_boundary_condition)
47
+
48
+ new_image = ants.from_pointer(inverse_field).clone('float')
49
+ return new_image
50
+
51
+
MindEyeV2/antspy/ants/registration/landmark_transforms.py ADDED
@@ -0,0 +1,843 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["fit_transform_to_paired_points",
2
+ "fit_time_varying_transform_to_point_sets"]
3
+
4
+ import numpy as np
5
+ import math
6
+ import time
7
+
8
+ import ants
9
+
10
+ def convergence_monitoring(values, window_size=10):
11
+ if len(values) >= window_size:
12
+ u = np.linspace(0.0, 1.0, num=window_size)
13
+ scattered_data = np.expand_dims(values[-window_size:], axis=-1)
14
+ parametric_data = np.expand_dims(u, axis=-1)
15
+ spacing = 1 / (window_size-1)
16
+ bspline_line = ants.fit_bspline_object_to_scattered_data(scattered_data, parametric_data,
17
+ parametric_domain_origin=[0.0], parametric_domain_spacing=[spacing],
18
+ parametric_domain_size=[window_size], number_of_fitting_levels=1, mesh_size=1,
19
+ spline_order=1)
20
+ bspline_slope = -(bspline_line[1][0] - bspline_line[0][0]) / spacing
21
+ return(bspline_slope)
22
+ else:
23
+ return None
24
+
25
+
26
+ def fit_transform_to_paired_points(moving_points,
27
+ fixed_points,
28
+ transform_type="affine",
29
+ regularization=1e-6,
30
+ domain_image=None,
31
+ number_of_fitting_levels=4,
32
+ mesh_size=1,
33
+ spline_order=3,
34
+ enforce_stationary_boundary=True,
35
+ displacement_weights=None,
36
+ number_of_compositions=10,
37
+ composition_step_size=0.5,
38
+ sigma=0.0,
39
+ convergence_threshold=1e-6,
40
+ number_of_time_steps=2,
41
+ number_of_integration_steps=100,
42
+ rasterize_points=False,
43
+ verbose=False
44
+ ):
45
+ """
46
+ Estimate a transform from corresponding fixed and moving landmarks.
47
+
48
+ ANTsR function: fitTransformToPairedPoints
49
+
50
+ Arguments
51
+ ---------
52
+ moving_points : array
53
+ Moving points specified in physical space as a n x d matrix where n is the number
54
+ of points and d is the dimensionality.
55
+
56
+ fixed_points : array
57
+ Fixed points specified in physical space as a n x d matrix where n is the number
58
+ of points and d is the dimensionality.
59
+
60
+ transform_type : character
61
+ 'rigid', 'similarity', "affine', 'bspline', 'tps', 'diffeo', 'syn', or 'time-varying (tv)'.
62
+
63
+ regularization : scalar
64
+ Ridge penalty in [0,1] for linear transforms.
65
+
66
+ domain_image : ANTs image
67
+ Defines physical domain of the nonlinear transform. Must be defined for nonlinear
68
+ transforms.
69
+
70
+ number_of_fitting_levels : integer
71
+ Integer specifying the number of fitting levels for the B-spline interpolation of the
72
+ displacement field.
73
+
74
+ mesh_size : integer or array
75
+ Defines the mesh size at the initial fitting level for the B-spline interpolation of the
76
+ displacement field.
77
+
78
+ spline_order : integer
79
+ Spline order of the B-spline displacement field.
80
+
81
+ enforce_stationary_boundary : boolean
82
+ Ensure no displacements on the image boundary (B-spline only).
83
+
84
+ displacement_weights : array
85
+ Defines the individual weighting of the corresponding scattered data value. Default = NULL
86
+ meaning all displacements are weighted the same.
87
+
88
+ number_of_compositions : integer
89
+ Total number of compositions for the diffeomorphic transforms.
90
+
91
+ composition_step_size : scalar
92
+ Scalar multiplication factor of the weighting of the update field for the diffeomorphic transforms.
93
+
94
+ sigma : scalar
95
+ Gaussian smoothing standard deviation of the update field (in mm).
96
+
97
+ convergence_threshold : scalar
98
+ Composition-based convergence parameter for the diff. transforms using a
99
+ window size of 10 values.
100
+
101
+ number_of_time_steps : integer
102
+ Time-varying velocity field parameter.
103
+
104
+ number_of_integration_steps : scalar
105
+ Number of steps used for integrating the velocity field.
106
+
107
+ rasterize_points : boolean
108
+ Use nearest neighbor rasterization of points for estimating the update
109
+ field (potential speed-up). Default = False.
110
+
111
+ verbose : bool
112
+ Print progress to the screen.
113
+
114
+ Returns
115
+ -------
116
+
117
+ ANTs transform
118
+
119
+ Example
120
+ -------
121
+ >>> import ants
122
+ >>> import numpy as np
123
+ >>> fixed = np.array([[50.0,50.0],[200.0,50.0],[200.0,200.0]])
124
+ >>> moving = np.array([[50.0,50.0],[50.0,200.0],[200.0,200.0]])
125
+ >>> xfrm = ants.fit_transform_to_paired_points(moving, fixed, transform_type="affine")
126
+ >>> xfrm = ants.fit_transform_to_paired_points(moving, fixed, transform_type="rigid")
127
+ >>> xfrm = ants.fit_transform_to_paired_points(moving, fixed, transform_type="similarity")
128
+ >>> domain_image = ants.image_read(ants.get_ants_data("r16"))
129
+ >>> xfrm = ants.fit_transform_to_paired_points(moving, fixed, transform_type="bspline", domain_image=domain_image, number_of_fitting_levels=5)
130
+ >>> xfrm = ants.fit_transform_to_paired_points(moving, fixed, transform_type="diffeo", domain_image=domain_image, number_of_fitting_levels=6)
131
+ """
132
+
133
+ def polar_decomposition(X):
134
+ U, d, V = np.linalg.svd(X, full_matrices=False)
135
+ P = np.matmul(U, np.matmul(np.diag(d), np.transpose(U)))
136
+ Z = np.matmul(U, V)
137
+ if np.linalg.det(Z) < 0:
138
+ n = X.shape[0]
139
+ reflection_matrix = np.identity(n)
140
+ reflection_matrix[0,0] = -1.0
141
+ Z = np.matmul(Z, reflection_matrix)
142
+ return({"P" : P, "Z" : Z, "Xtilde" : np.matmul(P, Z)})
143
+
144
+ def create_zero_displacement_field(domain_image):
145
+ field_array = np.zeros((*domain_image.shape, domain_image.dimension))
146
+ field = ants.from_numpy(field_array, origin=domain_image.origin,
147
+ spacing=domain_image.spacing, direction=domain_image.direction,
148
+ has_components=True)
149
+ return(field)
150
+
151
+ def create_zero_velocity_field(domain_image, number_of_time_points=2):
152
+ field_array = np.zeros((*domain_image.shape, number_of_time_points, domain_image.dimension))
153
+ origin = (*domain_image.origin, 0.0)
154
+ spacing = (*domain_image.spacing, 1.0)
155
+ direction = np.eye(domain_image.dimension + 1)
156
+ direction[0:domain_image.dimension,0:domain_image.dimension] = domain_image.direction
157
+ field = ants.from_numpy(field_array, origin=origin, spacing=spacing, direction=direction,
158
+ has_components=True)
159
+ return(field)
160
+
161
+ allowed_transforms = ['rigid', 'affine', 'similarity', 'bspline', 'tps', 'diffeo', 'syn', 'tv', 'time-varying']
162
+ if not transform_type.lower() in allowed_transforms:
163
+ raise ValueError(transform_type + " transform not supported.")
164
+
165
+ transform_type = transform_type.lower()
166
+
167
+ if domain_image is None and transform_type in ['bspline', 'tps', 'diffeo', 'syn', 'tv', 'time-varying']:
168
+ raise ValueError("Domain image needs to be specified.")
169
+
170
+ if not fixed_points.shape == moving_points.shape:
171
+ raise ValueError("Mismatch in the size of the point sets.")
172
+
173
+ if regularization > 1:
174
+ regularization = 1
175
+ elif regularization < 0:
176
+ regularization = 0
177
+
178
+ number_of_points = fixed_points.shape[0]
179
+ dimensionality = fixed_points.shape[1]
180
+
181
+ if transform_type in ['rigid', 'affine', 'similarity']:
182
+ center_fixed = fixed_points.mean(axis=0)
183
+ center_moving = moving_points.mean(axis=0)
184
+
185
+ x = fixed_points - center_fixed
186
+ y = moving_points - center_moving
187
+
188
+ y_prior = np.concatenate((y, np.ones((number_of_points, 1))), axis=1)
189
+
190
+ x11 = np.concatenate((x, np.ones((number_of_points, 1))), axis=1)
191
+ M = x11 * (1.0 - regularization) + regularization * y_prior
192
+ Minv = np.linalg.lstsq(M, y, rcond=None)[0]
193
+
194
+ p = polar_decomposition(Minv[0:dimensionality, 0:dimensionality].T)
195
+ A = p['Xtilde']
196
+ translation = Minv[dimensionality,:] + center_moving - center_fixed
197
+
198
+ if transform_type in ['rigid', 'similarity']:
199
+ # Kabsch algorithm
200
+ # http://web.stanford.edu/class/cs273/refs/umeyama.pdf
201
+
202
+ C = np.dot(y.T, x)
203
+ x_svd = np.linalg.svd(C * (1.0 - regularization) + np.eye(dimensionality) * regularization)
204
+ x_det = np.linalg.det(np.dot(x_svd[0], x_svd[2]))
205
+
206
+ if x_det < 0:
207
+ x_svd[2][dimensionality-1, :] *= -1
208
+
209
+ A = np.dot(x_svd[0], x_svd[2])
210
+
211
+ if transform_type == 'similarity':
212
+ scaling = (math.sqrt((np.power(y, 2).sum(axis=1) / number_of_points).mean()) /
213
+ math.sqrt((np.power(x, 2).sum(axis=1) / number_of_points).mean()))
214
+ A = np.dot(A, np.eye(dimensionality) * scaling)
215
+
216
+ xfrm = ants.create_ants_transform(matrix=A, translation=translation,
217
+ dimension=dimensionality, center=center_fixed)
218
+
219
+ return xfrm
220
+
221
+ elif transform_type == "bspline":
222
+
223
+ bspline_displacement_field = ants.fit_bspline_displacement_field(
224
+ displacement_origins=fixed_points,
225
+ displacements=moving_points - fixed_points,
226
+ displacement_weights=displacement_weights,
227
+ origin=domain_image.origin,
228
+ spacing=domain_image.spacing,
229
+ size=domain_image.shape,
230
+ direction=domain_image.direction,
231
+ number_of_fitting_levels=number_of_fitting_levels,
232
+ mesh_size=mesh_size,
233
+ spline_order=spline_order,
234
+ enforce_stationary_boundary=enforce_stationary_boundary,
235
+ rasterize_points=rasterize_points)
236
+
237
+ xfrm = ants.transform_from_displacement_field(bspline_displacement_field)
238
+
239
+ return xfrm
240
+
241
+ elif transform_type == "tps":
242
+
243
+ tps_displacement_field = ants.fit_thin_plate_spline_displacement_field(
244
+ displacement_origins=fixed_points,
245
+ displacements=moving_points - fixed_points,
246
+ origin=domain_image.origin,
247
+ spacing=domain_image.spacing,
248
+ size=domain_image.shape,
249
+ direction=domain_image.direction)
250
+
251
+ xfrm = ants.transform_from_displacement_field(tps_displacement_field)
252
+
253
+ return xfrm
254
+
255
+ elif transform_type == "diffeo":
256
+
257
+ if verbose:
258
+ start_total_time = time.time()
259
+
260
+ updated_fixed_points = np.empty_like(fixed_points)
261
+ updated_fixed_points[:] = fixed_points
262
+
263
+ total_field = create_zero_displacement_field(domain_image)
264
+ total_field_xfrm = None
265
+
266
+ error_values = []
267
+ for i in range(number_of_compositions):
268
+
269
+ if verbose:
270
+ start_time = time.time()
271
+
272
+ update_field = ants.fit_bspline_displacement_field(
273
+ displacement_origins=updated_fixed_points,
274
+ displacements=moving_points - updated_fixed_points,
275
+ displacement_weights=displacement_weights,
276
+ origin=domain_image.origin,
277
+ spacing=domain_image.spacing,
278
+ size=domain_image.shape,
279
+ direction=domain_image.direction,
280
+ number_of_fitting_levels=number_of_fitting_levels,
281
+ mesh_size=mesh_size,
282
+ spline_order=spline_order,
283
+ enforce_stationary_boundary=True,
284
+ rasterize_points=rasterize_points
285
+ )
286
+
287
+ update_field = update_field * composition_step_size
288
+ if sigma > 0:
289
+ update_field = ants.smooth_image(update_field, sigma)
290
+
291
+ total_field = ants.compose_displacement_fields(update_field, total_field)
292
+ total_field_xfrm = ants.transform_from_displacement_field(total_field)
293
+
294
+ if i < number_of_compositions - 1:
295
+ for j in range(updated_fixed_points.shape[0]):
296
+ updated_fixed_points[j,:] = total_field_xfrm.apply_to_point(tuple(fixed_points[j,:]))
297
+
298
+ error_values.append(np.mean(np.sqrt(np.sum(np.square(updated_fixed_points - moving_points), axis=1, keepdims=True))))
299
+ convergence_value = convergence_monitoring(error_values)
300
+ if verbose:
301
+ end_time = time.time()
302
+ diff_time = end_time - start_time
303
+ print("Composition " + str(i) + ": error = " + str(error_values[-1]) +
304
+ " (convergence = " + str(convergence_value) + ", elapsed time = " + str(diff_time) + ")")
305
+ if not convergence_value is None and convergence_value <= convergence_threshold:
306
+ break
307
+
308
+ if verbose:
309
+ end_total_time = time.time()
310
+ diff_total_time = end_total_time - start_total_time
311
+ print("Total elapsed time = " + str(diff_total_time) + ".")
312
+
313
+ return(total_field_xfrm)
314
+
315
+ elif transform_type == "syn":
316
+
317
+ if verbose:
318
+ start_total_time = time.time()
319
+
320
+ updated_fixed_points = np.empty_like(fixed_points)
321
+ updated_fixed_points[:] = fixed_points
322
+ updated_moving_points = np.empty_like(moving_points)
323
+ updated_moving_points[:] = moving_points
324
+
325
+ total_field_fixed_to_middle = create_zero_displacement_field(domain_image)
326
+ total_inverse_field_fixed_to_middle = create_zero_displacement_field(domain_image)
327
+
328
+ total_field_moving_to_middle = create_zero_displacement_field(domain_image)
329
+ total_inverse_field_moving_to_middle = create_zero_displacement_field(domain_image)
330
+
331
+ error_values = []
332
+ for i in range(number_of_compositions):
333
+
334
+ if verbose:
335
+ start_time = time.time()
336
+
337
+ update_field_fixed_to_middle = ants.fit_bspline_displacement_field(
338
+ displacement_origins=updated_fixed_points,
339
+ displacements=updated_moving_points - updated_fixed_points,
340
+ displacement_weights=displacement_weights,
341
+ origin=domain_image.origin,
342
+ spacing=domain_image.spacing,
343
+ size=domain_image.shape,
344
+ direction=domain_image.direction,
345
+ number_of_fitting_levels=number_of_fitting_levels,
346
+ mesh_size=mesh_size,
347
+ spline_order=spline_order,
348
+ enforce_stationary_boundary=True,
349
+ rasterize_points=rasterize_points
350
+ )
351
+
352
+ update_field_moving_to_middle = ants.fit_bspline_displacement_field(
353
+ displacement_origins=updated_moving_points,
354
+ displacements=updated_fixed_points - updated_moving_points,
355
+ displacement_weights=displacement_weights,
356
+ origin=domain_image.origin,
357
+ spacing=domain_image.spacing,
358
+ size=domain_image.shape,
359
+ direction=domain_image.direction,
360
+ number_of_fitting_levels=number_of_fitting_levels,
361
+ mesh_size=mesh_size,
362
+ spline_order=spline_order,
363
+ enforce_stationary_boundary=True,
364
+ rasterize_points=rasterize_points
365
+ )
366
+
367
+ update_field_fixed_to_middle = update_field_fixed_to_middle * composition_step_size
368
+ update_field_moving_to_middle = update_field_moving_to_middle * composition_step_size
369
+ if sigma > 0:
370
+ update_field_fixed_to_middle = ants.smooth_image(update_field_fixed_to_middle, sigma)
371
+ update_field_moving_to_middle = ants.smooth_image(update_field_moving_to_middle, sigma)
372
+
373
+ # Add the update field to both forward displacement fields.
374
+
375
+ total_field_fixed_to_middle = ants.compose_displacement_fields(update_field_fixed_to_middle, total_field_fixed_to_middle)
376
+ total_field_moving_to_middle = ants.compose_displacement_fields(update_field_moving_to_middle, total_field_moving_to_middle)
377
+
378
+ # Iteratively estimate the inverse fields.
379
+
380
+ total_inverse_field_fixed_to_middle = ants.invert_displacement_field(total_field_fixed_to_middle, total_inverse_field_fixed_to_middle)
381
+ total_inverse_field_moving_to_middle = ants.invert_displacement_field(total_field_moving_to_middle, total_inverse_field_moving_to_middle)
382
+
383
+ total_field_fixed_to_middle = ants.invert_displacement_field(total_inverse_field_fixed_to_middle, total_field_fixed_to_middle)
384
+ total_field_moving_to_middle = ants.invert_displacement_field(total_inverse_field_moving_to_middle, total_field_moving_to_middle)
385
+
386
+ total_field_fixed_to_middle_xfrm = ants.transform_from_displacement_field(total_field_fixed_to_middle)
387
+ total_field_moving_to_middle_xfrm = ants.transform_from_displacement_field(total_field_moving_to_middle)
388
+
389
+ total_inverse_field_fixed_to_middle_xfrm = ants.transform_from_displacement_field(total_inverse_field_fixed_to_middle)
390
+ total_inverse_field_moving_to_middle_xfrm = ants.transform_from_displacement_field(total_inverse_field_moving_to_middle)
391
+
392
+ if i < number_of_compositions - 1:
393
+ for j in range(updated_fixed_points.shape[0]):
394
+ updated_fixed_points[j,:] = total_field_fixed_to_middle_xfrm.apply_to_point(tuple(fixed_points[j,:]))
395
+ updated_moving_points[j,:] = total_field_moving_to_middle_xfrm.apply_to_point(tuple(moving_points[j,:]))
396
+
397
+ error_values.append(np.mean(np.sqrt(np.sum(np.square(updated_fixed_points - updated_moving_points), axis=1, keepdims=True))))
398
+ convergence_value = convergence_monitoring(error_values)
399
+ if verbose:
400
+ end_time = time.time()
401
+ diff_time = end_time - start_time
402
+ print("Composition " + str(i) + ": error = " + str(error_values[-1]) +
403
+ " (convergence = " + str(convergence_value) + ", elapsed time = " + str(diff_time) + ")")
404
+ if not convergence_value is None and convergence_value <= convergence_threshold:
405
+ break
406
+
407
+ total_forward_field = ants.compose_displacement_fields(total_inverse_field_moving_to_middle, total_field_fixed_to_middle)
408
+ total_forward_xfrm = ants.transform_from_displacement_field(total_forward_field)
409
+ total_inverse_field = ants.compose_displacement_fields(total_inverse_field_fixed_to_middle, total_field_moving_to_middle)
410
+ total_inverse_xfrm = ants.transform_from_displacement_field(total_inverse_field)
411
+
412
+ if verbose:
413
+ end_total_time = time.time()
414
+ diff_total_time = end_total_time - start_total_time
415
+ print("Total elapsed time = " + str(diff_total_time) + ".")
416
+
417
+ return_dict = {'forward_transform' : total_forward_xfrm,
418
+ 'inverse_transform' : total_inverse_xfrm,
419
+ 'fixed_to_middle_transform' : total_field_fixed_to_middle_xfrm,
420
+ 'middle_to_fixed_transform' : total_inverse_field_fixed_to_middle_xfrm,
421
+ 'moving_to_middle_transform' : total_field_moving_to_middle_xfrm,
422
+ 'middle_to_moving_transform' : total_inverse_field_moving_to_middle_xfrm
423
+ }
424
+ return(return_dict)
425
+
426
+ elif transform_type == "tv" or transform_type == "time-varying":
427
+
428
+ if verbose:
429
+ start_total_time = time.time()
430
+
431
+ updated_fixed_points = np.empty_like(fixed_points)
432
+ updated_fixed_points[:] = fixed_points
433
+ updated_moving_points = np.empty_like(moving_points)
434
+ updated_moving_points[:] = moving_points
435
+
436
+ velocity_field = create_zero_velocity_field(domain_image, number_of_time_steps)
437
+ velocity_field_array = velocity_field.numpy()
438
+
439
+ last_update_derivative_field = create_zero_velocity_field(domain_image, number_of_time_steps)
440
+ last_update_derivative_field_array = last_update_derivative_field.numpy()
441
+
442
+ error_values = []
443
+ for i in range(number_of_compositions):
444
+
445
+ if verbose:
446
+ start_time = time.time()
447
+
448
+ update_derivative_field = create_zero_velocity_field(domain_image, number_of_time_steps)
449
+ update_derivative_field_array = update_derivative_field.numpy()
450
+
451
+ average_error = 0.0
452
+ for n in range(number_of_time_steps):
453
+
454
+ t = n / (number_of_time_steps - 1.0)
455
+
456
+ if n > 0:
457
+ integrated_forward_field = ants.integrate_velocity_field(velocity_field, 0.0, t, number_of_integration_steps)
458
+ integrated_forward_field_xfrm = ants.transform_from_displacement_field(integrated_forward_field)
459
+ for j in range(updated_fixed_points.shape[0]):
460
+ updated_fixed_points[j,:] = integrated_forward_field_xfrm.apply_to_point(tuple(fixed_points[j,:]))
461
+ else:
462
+ updated_fixed_points[:] = fixed_points
463
+
464
+ if n < number_of_time_steps - 1:
465
+ integrated_inverse_field = ants.integrate_velocity_field(velocity_field, 1.0, t, number_of_integration_steps)
466
+ integrated_inverse_field_xfrm = ants.transform_from_displacement_field(integrated_inverse_field)
467
+ for j in range(updated_moving_points.shape[0]):
468
+ updated_moving_points[j,:] = integrated_inverse_field_xfrm.apply_to_point(tuple(moving_points[j,:]))
469
+ else:
470
+ updated_moving_points[:] = moving_points
471
+
472
+ update_derivative_field_at_timepoint = ants.fit_bspline_displacement_field(
473
+ displacement_origins=updated_fixed_points,
474
+ displacements=updated_moving_points - updated_fixed_points,
475
+ displacement_weights=displacement_weights,
476
+ origin=domain_image.origin,
477
+ spacing=domain_image.spacing,
478
+ size=domain_image.shape,
479
+ direction=domain_image.direction,
480
+ number_of_fitting_levels=number_of_fitting_levels,
481
+ mesh_size=mesh_size,
482
+ spline_order=spline_order,
483
+ enforce_stationary_boundary=True,
484
+ rasterize_points=rasterize_points
485
+ )
486
+
487
+ if sigma > 0:
488
+ update_derivative_field_at_timepoint = ants.smooth_image(update_derivative_field_at_timepoint, sigma)
489
+
490
+ update_derivative_field_at_timepoint_array = update_derivative_field_at_timepoint.numpy()
491
+ grad_norms = np.sqrt(np.sum(np.square(update_derivative_field_at_timepoint_array), axis=-1, keepdims=False))
492
+ max_norm = np.amax(grad_norms)
493
+ median_norm = np.median(grad_norms)
494
+ if verbose:
495
+ print(" integration point " + str(t) + ": max_norm = " + str(max_norm) + ", median_norm = " + str(median_norm))
496
+ update_derivative_field_at_timepoint_array /= max_norm
497
+ if domain_image.dimension == 2:
498
+ update_derivative_field_array[:,:,n,:] = update_derivative_field_at_timepoint_array
499
+ elif domain_image.dimension == 3:
500
+ update_derivative_field_array[:,:,:,n,:] = update_derivative_field_at_timepoint_array
501
+
502
+ rmse = np.mean(np.sqrt(np.sum(np.square(updated_moving_points - updated_fixed_points), axis=1, keepdims=True)))
503
+ average_error = (average_error * n + rmse) / (n + 1)
504
+
505
+ update_derivative_field_array = (update_derivative_field_array + last_update_derivative_field_array) * 0.5
506
+ last_update_derivative_field_array = np.empty_like(update_derivative_field_array)
507
+ last_update_derivative_field_array[:] = update_derivative_field_array
508
+
509
+ velocity_field_array = velocity_field_array + update_derivative_field_array * composition_step_size
510
+ velocity_field = ants.from_numpy(velocity_field_array, origin=velocity_field.origin,
511
+ spacing=velocity_field.spacing, direction=velocity_field.direction,
512
+ has_components=True)
513
+
514
+ error_values.append(average_error)
515
+ convergence_value = convergence_monitoring(error_values)
516
+ if verbose:
517
+ end_time = time.time()
518
+ diff_time = end_time - start_time
519
+ print("Composition " + str(i) + ": error = " + str(error_values[-1]) +
520
+ " (convergence = " + str(convergence_value) + ", elapsed time = " + str(diff_time) + ")")
521
+ if not convergence_value is None and convergence_value <= convergence_threshold:
522
+ break
523
+
524
+ forward_xfrm = ants.transform_from_displacement_field(ants.integrate_velocity_field(velocity_field, 0.0, 1.0, number_of_integration_steps))
525
+ inverse_xfrm = ants.transform_from_displacement_field(ants.integrate_velocity_field(velocity_field, 1.0, 0.0, number_of_integration_steps))
526
+
527
+ if verbose:
528
+ end_total_time = time.time()
529
+ diff_total_time = end_total_time - start_total_time
530
+ print("Total elapsed time = " + str(diff_total_time) + ".")
531
+
532
+ return_dict = {'forward_transform': forward_xfrm,
533
+ 'inverse_transform': inverse_xfrm,
534
+ 'velocity_field': velocity_field}
535
+ return(return_dict)
536
+
537
+ else:
538
+ raise ValueError("Unrecognized transform_type.")
539
+
540
+
541
+ def fit_time_varying_transform_to_point_sets(point_sets,
542
+ time_points=None,
543
+ initial_velocity_field=None,
544
+ number_of_time_steps=None,
545
+ domain_image=None,
546
+ number_of_fitting_levels=4,
547
+ mesh_size=1,
548
+ spline_order=3,
549
+ displacement_weights=None,
550
+ number_of_compositions=10,
551
+ composition_step_size=0.5,
552
+ number_of_integration_steps=100,
553
+ sigma=0.0,
554
+ convergence_threshold=1e-6,
555
+ rasterize_points=False,
556
+ verbose=False
557
+ ):
558
+ """
559
+
560
+ Estimate a time-varying transform from corresponding point sets (> 2).
561
+
562
+ ANTsR function: fitTimeVaryingTransformToPointSets
563
+
564
+ Arguments
565
+ ---------
566
+ point_sets : list of arrays
567
+ Corresponding points across sets specified in physical space as a n x d matrix where n
568
+ is the number of points and d is the dimensionality.
569
+
570
+ time_points : array of ordered scalars between 0 and 1
571
+ Set of scalar values, one for each point-set, designating its time position in the velocity
572
+ flow. If not set, it defaults to equal spacing between 0 and 1.
573
+
574
+ initial_velocity_field : initial ANTs velocity field
575
+ Optional velocity field for initializing optimization. Overrides the number of integration
576
+ points.
577
+
578
+ number_of_time_steps : integer
579
+ Time-varying velocity field parameter. Needs to be equal to or greater than the number of
580
+ point sets. If not specified, it defaults to the number of point sets.
581
+
582
+ domain_image : ANTs image
583
+ Defines physical domain of the nonlinear transform. Must be defined.
584
+
585
+ number_of_fitting_levels : integer
586
+ Integer specifying the number of fitting levels for the B-spline interpolation of the
587
+ displacement field.
588
+
589
+ mesh_size : integer or array
590
+ Defines the mesh size at the initial fitting level for the B-spline interpolation of the
591
+ displacement field..
592
+
593
+ spline_order : integer
594
+ Spline order of the B-spline displacement field.
595
+
596
+ displacement_weights : array
597
+ Defines the individual weighting of the corresponding scattered data value. Default = NULL
598
+ meaning all displacements are weighted the same.
599
+
600
+ number_of_compositions : integer
601
+ Total number of compositions.
602
+
603
+ composition_step_size : scalar
604
+ Scalar multiplication factor of the weighting of the update field.
605
+
606
+ number_of_integration_steps : scalar
607
+ Number of steps used for integrating the velocity field.
608
+
609
+ sigma : scalar
610
+ Gaussian smoothing standard deviation of the update field (in mm).
611
+
612
+ convergence_threshold : scalar
613
+ Composition-based convergence parameter using a window size of 10 values.
614
+
615
+ rasterize_points : boolean
616
+ Use nearest neighbor rasterization of points for estimating the update field (potential
617
+ speed-up). Default = False.
618
+
619
+ verbose : bool
620
+ Print progress to the screen.
621
+
622
+ Returns
623
+ -------
624
+
625
+ ANTs transform
626
+
627
+ Example
628
+ -------
629
+ >>> import ants
630
+ >>> import numpy as np
631
+ """
632
+
633
+ def create_zero_velocity_field(domain_image, number_of_time_points=2):
634
+ field_array = np.zeros((*domain_image.shape, number_of_time_points, domain_image.dimension))
635
+ origin = (*domain_image.origin, 0.0)
636
+ spacing = (*domain_image.spacing, 1.0)
637
+ direction = np.eye(domain_image.dimension + 1)
638
+ direction[0:domain_image.dimension,0:domain_image.dimension] = domain_image.direction
639
+ field = ants.from_numpy(field_array, origin=origin, spacing=spacing, direction=direction,
640
+ has_components=True)
641
+ return(field)
642
+
643
+ if not isinstance(point_sets, list):
644
+ raise ValueError("point_sets should be a list of corresponding point sets.")
645
+
646
+ number_of_point_sets = len(point_sets)
647
+
648
+ if time_points is not None and len(time_points) != number_of_point_sets:
649
+ raise ValueError("The number of time points should be the same as the number of point sets.")
650
+
651
+ if time_points is None:
652
+ time_points = np.linspace(0.0, 1.0, number_of_point_sets)
653
+ time_points = np.array(time_points)
654
+
655
+ if np.any(time_points < 0.0) or np.any(time_points > 1.0):
656
+ raise ValueError("time point values should be between 0 and 1.")
657
+
658
+ if number_of_point_sets < 3:
659
+ raise ValueError("Expecting three or greater point sets.")
660
+
661
+ if domain_image is None:
662
+ raise ValueError("Domain image needs to be specified.")
663
+
664
+ number_of_points = point_sets[0].shape[0]
665
+ dimensionality = point_sets[0].shape[1]
666
+ for i in range(1, number_of_point_sets):
667
+ if point_sets[i].shape[0] != number_of_points:
668
+ raise ValueError("Point sets should match in terms of the number of points.")
669
+ if point_sets[i].shape[1] != dimensionality:
670
+ raise ValueError("Point sets should match in terms of dimensionality.")
671
+
672
+ if verbose:
673
+ start_total_time = time.time()
674
+
675
+ updated_fixed_points = np.zeros(point_sets[0].shape)
676
+ updated_moving_points = np.zeros(point_sets[0].shape)
677
+
678
+ velocity_field = None
679
+ if initial_velocity_field is None:
680
+ if number_of_time_steps is None:
681
+ number_of_time_steps = len(time_points)
682
+ if number_of_time_steps < number_of_point_sets:
683
+ raise ValueError("The number of integration points should be at least as great as the number of point sets.")
684
+ velocity_field = create_zero_velocity_field(domain_image, number_of_time_steps)
685
+ else:
686
+ velocity_field = ants.image_clone(initial_velocity_field)
687
+ number_of_time_steps = initial_velocity_field.shape[-1]
688
+ velocity_field_array = velocity_field.numpy()
689
+
690
+ last_update_derivative_field = create_zero_velocity_field(domain_image, number_of_time_steps)
691
+ last_update_derivative_field_array = last_update_derivative_field.numpy()
692
+
693
+ error_values = []
694
+ for i in range(number_of_compositions):
695
+
696
+ if verbose:
697
+ start_time = time.time()
698
+
699
+ update_derivative_field = create_zero_velocity_field(domain_image, number_of_time_steps)
700
+ update_derivative_field_array = update_derivative_field.numpy()
701
+
702
+ average_error = 0.0
703
+ for n in range(number_of_time_steps):
704
+
705
+ t = n / (number_of_time_steps - 1.0)
706
+
707
+ t_index = 0
708
+ for j in range(1, number_of_point_sets):
709
+ if time_points[j-1] <= t and time_points[j] >= t:
710
+ t_index = j
711
+ break
712
+
713
+ if n > 0 and n < number_of_time_steps - 1 and time_points[t_index-1] == t:
714
+ updated_fixed_points[:] = point_sets[t_index-1]
715
+ integrated_inverse_field = ants.integrate_velocity_field(velocity_field, time_points[t_index], t, number_of_integration_steps)
716
+ integrated_inverse_field_xfrm = ants.transform_from_displacement_field(integrated_inverse_field)
717
+ for j in range(updated_moving_points.shape[0]):
718
+ updated_moving_points[j,:] = integrated_inverse_field_xfrm.apply_to_point(tuple(point_sets[t_index][j,:]))
719
+
720
+ update_derivative_field_at_timepoint_forward = ants.fit_bspline_displacement_field(
721
+ displacement_origins=updated_fixed_points,
722
+ displacements=updated_moving_points - updated_fixed_points,
723
+ displacement_weights=displacement_weights,
724
+ origin=domain_image.origin,
725
+ spacing=domain_image.spacing,
726
+ size=domain_image.shape,
727
+ direction=domain_image.direction,
728
+ number_of_fitting_levels=number_of_fitting_levels,
729
+ mesh_size=mesh_size,
730
+ spline_order=spline_order,
731
+ enforce_stationary_boundary=True,
732
+ rasterize_points=rasterize_points
733
+ )
734
+
735
+ updated_moving_points[:] = point_sets[t_index-1]
736
+ integrated_forward_field = ants.integrate_velocity_field(velocity_field, time_points[t_index-2], t, number_of_integration_steps)
737
+ integrated_forward_field_xfrm = ants.transform_from_displacement_field(integrated_forward_field)
738
+ for j in range(updated_fixed_points.shape[0]):
739
+ updated_fixed_points[j,:] = integrated_forward_field_xfrm.apply_to_point(tuple(point_sets[t_index-2][j,:]))
740
+
741
+ update_derivative_field_at_timepoint_back = ants.fit_bspline_displacement_field(
742
+ displacement_origins=updated_fixed_points,
743
+ displacements=updated_moving_points - updated_fixed_points,
744
+ displacement_weights=displacement_weights,
745
+ origin=domain_image.origin,
746
+ spacing=domain_image.spacing,
747
+ size=domain_image.shape,
748
+ direction=domain_image.direction,
749
+ number_of_fitting_levels=number_of_fitting_levels,
750
+ mesh_size=mesh_size,
751
+ spline_order=spline_order,
752
+ enforce_stationary_boundary=True,
753
+ rasterize_points=rasterize_points
754
+ )
755
+
756
+ update_derivative_field_at_timepoint = (update_derivative_field_at_timepoint_forward +
757
+ update_derivative_field_at_timepoint_back) / 2.0
758
+
759
+ else:
760
+ if t == 0.0 and time_points[t_index-1] == 0.0:
761
+ updated_fixed_points[:] = point_sets[0]
762
+ else:
763
+ integrated_forward_field = ants.integrate_velocity_field(velocity_field, time_points[t_index-1], t, number_of_integration_steps)
764
+ integrated_forward_field_xfrm = ants.transform_from_displacement_field(integrated_forward_field)
765
+ for j in range(updated_fixed_points.shape[0]):
766
+ updated_fixed_points[j,:] = integrated_forward_field_xfrm.apply_to_point(tuple(point_sets[t_index-1][j,:]))
767
+
768
+ if t == 1.0 and time_points[t_index] == 1.0:
769
+ updated_moving_points[:] = point_sets[-1]
770
+ else:
771
+ integrated_inverse_field = ants.integrate_velocity_field(velocity_field, time_points[t_index], t, number_of_integration_steps)
772
+ integrated_inverse_field_xfrm = ants.transform_from_displacement_field(integrated_inverse_field)
773
+ for j in range(updated_moving_points.shape[0]):
774
+ updated_moving_points[j,:] = integrated_inverse_field_xfrm.apply_to_point(tuple(point_sets[t_index][j,:]))
775
+
776
+ update_derivative_field_at_timepoint = ants.fit_bspline_displacement_field(
777
+ displacement_origins=updated_fixed_points,
778
+ displacements=updated_moving_points - updated_fixed_points,
779
+ displacement_weights=displacement_weights,
780
+ origin=domain_image.origin,
781
+ spacing=domain_image.spacing,
782
+ size=domain_image.shape,
783
+ direction=domain_image.direction,
784
+ number_of_fitting_levels=number_of_fitting_levels,
785
+ mesh_size=mesh_size,
786
+ spline_order=spline_order,
787
+ enforce_stationary_boundary=True,
788
+ rasterize_points=rasterize_points
789
+ )
790
+
791
+ if sigma > 0:
792
+ update_derivative_field_at_timepoint = ants.smooth_image(update_derivative_field_at_timepoint, sigma)
793
+
794
+ update_derivative_field_at_timepoint_array = update_derivative_field_at_timepoint.numpy()
795
+ grad_norms = np.sqrt(np.sum(np.square(update_derivative_field_at_timepoint_array), axis=-1, keepdims=False))
796
+ max_norm = np.amax(grad_norms)
797
+ median_norm = np.median(grad_norms)
798
+ if verbose:
799
+ print(" integration point " + str(t) + ": max_norm = " + str(max_norm) + ", median_norm = " + str(median_norm))
800
+ update_derivative_field_at_timepoint_array /= max_norm
801
+ if domain_image.dimension == 2:
802
+ update_derivative_field_array[:,:,n,:] = update_derivative_field_at_timepoint_array
803
+ elif domain_image.dimension == 3:
804
+ update_derivative_field_array[:,:,:,n,:] = update_derivative_field_at_timepoint_array
805
+
806
+ rmse = np.mean(np.sqrt(np.sum(np.square(updated_moving_points - updated_fixed_points), axis=1, keepdims=True)))
807
+ average_error = (average_error * n + rmse) / (n + 1)
808
+
809
+ update_derivative_field_array = (update_derivative_field_array + last_update_derivative_field_array) * 0.5
810
+ last_update_derivative_field_array = np.empty_like(update_derivative_field_array)
811
+ last_update_derivative_field_array[:] = update_derivative_field_array
812
+
813
+ velocity_field_array += (update_derivative_field_array * composition_step_size)
814
+ velocity_field = ants.from_numpy(velocity_field_array, origin=velocity_field.origin,
815
+ spacing=velocity_field.spacing, direction=velocity_field.direction,
816
+ has_components=True)
817
+
818
+ error_values.append(average_error)
819
+ convergence_value = convergence_monitoring(error_values)
820
+ if verbose:
821
+ end_time = time.time()
822
+ diff_time = end_time - start_time
823
+ print("Composition " + str(i) + ": error = " + str(error_values[-1]) +
824
+ " (convergence = " + str(convergence_value) + ", elapsed time = " + str(diff_time) + ")")
825
+ if not convergence_value is None and convergence_value <= convergence_threshold:
826
+ break
827
+
828
+ forward_xfrm = ants.transform_from_displacement_field(ants.integrate_velocity_field(velocity_field, 0.0, 1.0, number_of_integration_steps))
829
+ inverse_xfrm = ants.transform_from_displacement_field(ants.integrate_velocity_field(velocity_field, 1.0, 0.0, number_of_integration_steps))
830
+
831
+ if verbose:
832
+ end_total_time = time.time()
833
+ diff_total_time = end_total_time - start_total_time
834
+ print("Total elapsed time = " + str(diff_total_time) + ".")
835
+
836
+ return_dict = {'forward_transform': forward_xfrm,
837
+ 'inverse_transform': inverse_xfrm,
838
+ 'velocity_field': velocity_field}
839
+ return(return_dict)
840
+
841
+
842
+
843
+
MindEyeV2/antspy/ants/registration/registration.py ADDED
@@ -0,0 +1,1953 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ANTsPy Registration
3
+ """
4
+ __all__ = ["registration",
5
+ "motion_correction",
6
+ "label_image_registration"]
7
+
8
+ import numpy as np
9
+ from tempfile import mktemp
10
+ import glob
11
+ import re
12
+ import pandas as pd
13
+ import itertools
14
+
15
+ import ants
16
+ from ants.internal import get_lib_fn, get_pointer_string, process_arguments
17
+
18
+ def registration(
19
+ fixed,
20
+ moving,
21
+ type_of_transform="SyN",
22
+ initial_transform=None,
23
+ outprefix="",
24
+ mask=None,
25
+ moving_mask=None,
26
+ mask_all_stages=False,
27
+ grad_step=0.2,
28
+ flow_sigma=3,
29
+ total_sigma=0,
30
+ aff_metric="mattes",
31
+ aff_sampling=32,
32
+ aff_random_sampling_rate=0.2,
33
+ syn_metric="mattes",
34
+ syn_sampling=32,
35
+ reg_iterations=(40, 20, 0),
36
+ aff_iterations=(2100, 1200, 1200, 10),
37
+ aff_shrink_factors=(6, 4, 2, 1),
38
+ aff_smoothing_sigmas=(3, 2, 1, 0),
39
+ write_composite_transform=False,
40
+ random_seed=None,
41
+ verbose=False,
42
+ multivariate_extras=None,
43
+ restrict_transformation=None,
44
+ smoothing_in_mm=False,
45
+ singleprecision=True,
46
+ **kwargs
47
+ ):
48
+ """
49
+ Register a pair of images either through the full or simplified
50
+ interface to the ANTs registration method.
51
+
52
+ ANTsR function: `antsRegistration`
53
+
54
+ Arguments
55
+ ---------
56
+ fixed : ANTsImage
57
+ fixed image to which we register the moving image.
58
+
59
+ moving : ANTsImage
60
+ moving image to be mapped to fixed space.
61
+
62
+ type_of_transform : string
63
+ A linear or non-linear registration type. Mutual information metric by default.
64
+ See Notes below for more.
65
+
66
+ initial_transform : list of strings (optional)
67
+ transforms to prepend. If None, a translation is computed to align the image centers of mass.
68
+ To use an identity transform, set this to 'Identity'.
69
+
70
+ outprefix : string
71
+ output will be named with this prefix.
72
+
73
+ mask : ANTsImage (optional)
74
+ Registration metric mask in the fixed image space.
75
+
76
+ moving_mask : ANTsImage (optional)
77
+ Registration metric mask in the moving image space.
78
+
79
+ mask_all_stages : boolean
80
+ If true, apply metric mask(s) to all registration stages, instead of just the final stage.
81
+
82
+ grad_step : scalar
83
+ gradient step size (not for all tx)
84
+
85
+ flow_sigma : scalar
86
+ smoothing for update field
87
+ At each iteration, the similarity metric and gradient is calculated.
88
+ That gradient field is also called the update field and is smoothed
89
+ before composing with the total field (i.e., the estimate of the total
90
+ transform at that iteration). This total field can also be smoothed
91
+ after each iteration.
92
+
93
+ total_sigma : scalar
94
+ smoothing for total field
95
+
96
+ aff_metric : string
97
+ the metric for the affine part (GC, mattes, meansquares)
98
+
99
+ aff_sampling : scalar
100
+ number of bins for the mutual information metric
101
+
102
+ aff_random_sampling_rate : scalar
103
+ the fraction of points used to estimate the metric. this can impact
104
+ speed but also reproducibility and/or accuracy.
105
+
106
+ syn_metric : string
107
+ the metric for the syn part (CC, mattes, meansquares, demons)
108
+
109
+ syn_sampling : scalar
110
+ the nbins or radius parameter for the syn metric
111
+
112
+ reg_iterations : list/tuple of integers
113
+ vector of iterations for syn. we will set the smoothing and multi-resolution parameters based on the length of this vector.
114
+
115
+ aff_iterations : list/tuple of integers
116
+ vector of iterations for low-dimensional (translation, rigid, affine) registration.
117
+
118
+ aff_shrink_factors : list/tuple of integers
119
+ vector of multi-resolution shrink factors for low-dimensional (translation, rigid, affine) registration.
120
+
121
+ aff_smoothing_sigmas : list/tuple of integers
122
+ vector of multi-resolution smoothing factors for low-dimensional (translation, rigid, affine) registration.
123
+
124
+ random_seed : integer
125
+ random seed to improve reproducibility. note that the number of ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS should be 1 if you want perfect reproducibility.
126
+
127
+ write_composite_transform : boolean
128
+ Boolean specifying whether or not the composite transform (and its inverse, if it exists) should be written to an hdf5 composite file. This is false by default so that only the transform for each stage is written to file.
129
+
130
+ verbose : boolean
131
+ request verbose output (useful for debugging)
132
+
133
+ multivariate_extras : additional metrics for multi-metric registration
134
+ list of additional images and metrics which will
135
+ trigger the use of multiple metrics in the registration
136
+ process in the deformable stage. Each multivariate metric needs 5
137
+ entries: name of metric, fixed, moving, weight,
138
+ samplingParam. the list of lists should be of the form ( (
139
+ "nameOfMetric2", img, img, weight, metricParam ) ). Another
140
+ example would be ( ( "MeanSquares", f2, m2, 0.5, 0
141
+ ), ( "CC", f2, m2, 0.5, 2 ) ) . This is only compatible
142
+ with the SyNOnly or antsRegistrationSyN* transformations.
143
+
144
+ restrict_transformation : This option allows the user to restrict the
145
+ optimization of the displacement field, translation, rigid or
146
+ affine transform on a per-component basis. For example, if
147
+ one wants to limit the deformation or rotation of 3-D volume
148
+ to the first two dimensions, this is possible by specifying a
149
+ weight vector of ‘(1,1,0)’ for a 3D deformation field or
150
+ ‘(1,1,0,1,1,0)’ for a rigid transformation. Restriction
151
+ currently only works if there are no preceding
152
+ transformations.
153
+
154
+ smoothing_in_mm : boolean ; currently only impacts low dimensional registration
155
+
156
+ singleprecision : boolean
157
+ if True, use float32 for computations. This is useful for reducing memory
158
+ usage for large datasets, at the cost of precision.
159
+
160
+ kwargs : keyword args
161
+ extra arguments
162
+
163
+ Returns
164
+ -------
165
+ dict containing follow key/value pairs:
166
+ `warpedmovout`: Moving image warped to space of fixed image.
167
+ `warpedfixout`: Fixed image warped to space of moving image.
168
+ `fwdtransforms`: Transforms to move from moving to fixed image.
169
+ `invtransforms`: Transforms to move from fixed to moving image.
170
+
171
+ Notes
172
+ -----
173
+ type_of_transform can be one of:
174
+ - "Translation": Translation transformation.
175
+ - "Rigid": Rigid transformation: Only rotation and translation.
176
+ - "Similarity": Similarity transformation: scaling, rotation and translation.
177
+ - "QuickRigid": Rigid transformation: Only rotation and translation.
178
+ May be useful for quick visualization fixes.'
179
+ - "DenseRigid": Rigid transformation: Only rotation and translation.
180
+ Employs dense sampling during metric estimation.'
181
+ - "BOLDRigid": Rigid transformation: Parameters typical for BOLD to
182
+ BOLD intrasubject registration'.'
183
+ - "Affine": Affine transformation: Rigid + scaling.
184
+ - "AffineFast": Fast version of Affine.
185
+ - "BOLDAffine": Affine transformation: Parameters typical for BOLD to
186
+ BOLD intrasubject registration'.'
187
+ - "TRSAA": translation, rigid, similarity, affine (twice). please set
188
+ regIterations if using this option. this would be used in
189
+ cases where you want a really high quality affine mapping
190
+ (perhaps with mask).
191
+ - "Elastic": Elastic deformation: Affine + deformable.
192
+ - "ElasticSyN": Symmetric normalization: Affine + deformable
193
+ transformation, with mutual information as optimization
194
+ metric and elastic regularization.
195
+ - "SyN": Symmetric normalization: Affine + deformable transformation,
196
+ with mutual information as optimization metric.
197
+ - "SyNRA": Symmetric normalization: Rigid + Affine + deformable
198
+ transformation, with mutual information as optimization metric.
199
+ - "SyNOnly": Symmetric normalization with no rigid or affine stages.
200
+ Uses mutual information as optimization metric. Affine alignment is
201
+ from the initial_transform arg, either provide the .mat from linear
202
+ registration or use initial_transform='Identity' if the images are
203
+ already affinely aligned.
204
+ Can be useful if you want to run an unmasked affine followed by
205
+ masked deformable registration.
206
+ - "SyNCC": SyN, but with cross-correlation as the metric.
207
+ - "SyNabp": SyN optimized for abpBrainExtraction.
208
+ - "SyNBold": SyN, but optimized for registrations between BOLD and T1 images.
209
+ - "SyNBoldAff": SyN, but optimized for registrations between BOLD
210
+ and T1 images, with additional affine step.
211
+ - "SyNAggro": SyN, but with more aggressive registration
212
+ (fine-scale matching and more deformation).
213
+ Takes more time than SyN.
214
+ - "TV[n]": time-varying diffeomorphism with where 'n' indicates number of
215
+ time points in velocity field discretization. The initial transform
216
+ should be computed, if needed, in a separate call to ants.registration.
217
+ - "TVMSQ": time-varying diffeomorphism with mean square metric
218
+ - "TVMSQC": time-varying diffeomorphism with mean square metric for very large deformation
219
+ - "antsRegistrationSyN[x]": recreation of the antsRegistrationSyN.sh script in ANTs
220
+ where 'x' is one of the transforms available:
221
+ t: translation (1 stage)
222
+ r: rigid (1 stage)
223
+ a: rigid + affine (2 stages)
224
+ s: rigid + affine + deformable syn (3 stages)
225
+ sr: rigid + deformable syn (2 stages)
226
+ so: deformable syn only (1 stage)
227
+ b: rigid + affine + deformable b-spline syn (3 stages)
228
+ br: rigid + deformable b-spline syn (2 stages)
229
+ bo: deformable b-spline syn only (1 stage)
230
+ - "antsRegistrationSyNQuick[x]": recreation of the antsRegistrationSyNQuick.sh script in ANTs.
231
+ x options as above.
232
+ - "antsRegistrationSyNRepro[x]": reproducible registration. x options as above.
233
+ - "antsRegistrationSyNQuickRepro[x]": quick reproducible registration. x options as above.
234
+
235
+ Example
236
+ -------
237
+ >>> import ants
238
+ >>> fi = ants.image_read(ants.get_ants_data('r16'))
239
+ >>> mi = ants.image_read(ants.get_ants_data('r64'))
240
+ >>> fi = ants.resample_image(fi, (60,60), 1, 0)
241
+ >>> mi = ants.resample_image(mi, (60,60), 1, 0)
242
+ >>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'SyN' )
243
+ >>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'antsRegistrationSyN[t]' )
244
+ >>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'antsRegistrationSyN[b]' )
245
+ >>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'antsRegistrationSyN[s]' )
246
+ """
247
+ if isinstance(fixed, list) and (moving is None):
248
+ processed_args = process_arguments(fixed)
249
+ libfn = get_lib_fn("antsRegistration")
250
+ reg_exit = libfn(processed_args)
251
+ if (reg_exit != 0):
252
+ raise RuntimeError(f"Registration failed with error code {reg_exit}")
253
+ else:
254
+ return 0
255
+
256
+ if not (ants.is_image(fixed) and ants.is_image(moving)):
257
+ raise ValueError("Fixed and moving images must be ANTsImage objects")
258
+
259
+ if type_of_transform == "":
260
+ type_of_transform = "SyN"
261
+
262
+ if isinstance(type_of_transform, (tuple, list)) and (len(type_of_transform) == 1):
263
+ type_of_transform = type_of_transform[0]
264
+
265
+ if (outprefix == "") or len(outprefix) == 0:
266
+ outprefix = mktemp()
267
+
268
+ if np.sum(np.isnan(fixed.numpy())) > 0:
269
+ raise ValueError("fixed image has NaNs - replace these")
270
+ if np.sum(np.isnan(moving.numpy())) > 0:
271
+ raise ValueError("moving image has NaNs - replace these")
272
+
273
+ if fixed.dimension != moving.dimension:
274
+ raise ValueError("Fixed and moving image dimensions are not the same.")
275
+ # ----------------------------
276
+
277
+ myiterations = aff_iterations
278
+ args = [fixed, moving, type_of_transform, outprefix]
279
+ myf_aff = "6x4x2x1" # old fixed params
280
+ mys_aff = "3x2x1x0" # old fixed params
281
+ if (
282
+ type(aff_shrink_factors) is int
283
+ or type(aff_smoothing_sigmas) is int
284
+ or type(aff_iterations) is int
285
+ ):
286
+ if type(aff_smoothing_sigmas) is not int:
287
+ raise ValueError("aff_smoothing_sigmas should be a single integer.")
288
+ if type(aff_iterations) is not int:
289
+ raise ValueError("aff_iterations should be a single integer.")
290
+ if type(aff_shrink_factors) is not int:
291
+ raise ValueError("aff_shrink_factors should be a single integer.")
292
+ myf_aff = aff_shrink_factors
293
+ mys_aff = aff_smoothing_sigmas
294
+ myiterations = aff_iterations
295
+
296
+ if restrict_transformation is not None:
297
+ if type(restrict_transformation) is tuple:
298
+ restrict_transformationchar = "x".join([str(ri) for ri in restrict_transformation])
299
+
300
+ if type(aff_shrink_factors) is tuple:
301
+ myf_aff = "x".join([str(ri) for ri in aff_shrink_factors])
302
+ mys_aff = "x".join([str(ri) for ri in aff_smoothing_sigmas])
303
+ myiterations = "x".join([str(ri) for ri in aff_iterations])
304
+ if len(aff_iterations) != len(aff_smoothing_sigmas):
305
+ raise ValueError(
306
+ "aff_iterations length should equal aff_smoothing_sigmas length."
307
+ )
308
+ if len(aff_iterations) != len(aff_shrink_factors):
309
+ raise ValueError(
310
+ "aff_iterations length should equal aff_shrink_factors length."
311
+ )
312
+ if len(aff_shrink_factors) != len(aff_smoothing_sigmas):
313
+ raise ValueError(
314
+ "aff_shrink_factors length should equal aff_smoothing_sigmas length."
315
+ )
316
+
317
+ if type_of_transform == "AffineFast":
318
+ type_of_transform = "Affine"
319
+ myiterations = "2100x1200x0x0"
320
+ if type_of_transform == "BOLDAffine":
321
+ type_of_transform = "Affine"
322
+ myf_aff = "2x1"
323
+ mys_aff = "1x0"
324
+ myiterations = "100x20"
325
+ if type_of_transform == "QuickRigid":
326
+ type_of_transform = "Rigid"
327
+ myiterations = "20x20x0x0"
328
+ if type_of_transform == "DenseRigid":
329
+ type_of_transform = "Rigid"
330
+ aff_random_sampling_rate = 1.0
331
+ if type_of_transform == "BOLDRigid":
332
+ type_of_transform = "Rigid"
333
+ myf_aff = "2x1"
334
+ mys_aff = "1x0"
335
+ myiterations = "100x20"
336
+
337
+ if smoothing_in_mm:
338
+ mys_aff = mys_aff + 'mm'
339
+
340
+ mysyn = "SyN[%f,%f,%f]" % (grad_step, flow_sigma, total_sigma)
341
+ if type_of_transform == "Elastic":
342
+ mysyn = "GaussianDisplacementField[%f,%f,%f]" % (grad_step, flow_sigma, total_sigma)
343
+ itlen = len(reg_iterations) # NEED TO CHECK THIS
344
+ if itlen == 0:
345
+ smoothingsigmas = 0
346
+ shrinkfactors = 1
347
+ synits = reg_iterations
348
+ else:
349
+ smoothingsigmas = np.arange(0, itlen)[::-1].astype(
350
+ "float32"
351
+ ) # NEED TO CHECK THIS
352
+ shrinkfactors = 2 ** smoothingsigmas
353
+ shrinkfactors = shrinkfactors.astype("int")
354
+ smoothingsigmas = "x".join([str(ss)[0] for ss in smoothingsigmas])
355
+ shrinkfactors = "x".join([str(ss) for ss in shrinkfactors])
356
+ synits = "x".join([str(ri) for ri in reg_iterations])
357
+
358
+ inpixeltype = fixed.pixeltype
359
+ output_pixel_type = 'float' if singleprecision else 'double'
360
+
361
+ tvTypes = [
362
+ "TV[1]",
363
+ "TV[2]",
364
+ "TV[3]",
365
+ "TV[4]",
366
+ "TV[5]",
367
+ "TV[6]",
368
+ "TV[7]",
369
+ "TV[8]",
370
+ ]
371
+ allowable_tx = {
372
+ "SyNBold",
373
+ "SyNBoldAff",
374
+ "ElasticSyN",
375
+ "Elastic",
376
+ "SyN",
377
+ "SyNRA",
378
+ "SyNOnly",
379
+ "SyNAggro",
380
+ "SyNCC",
381
+ "TRSAA",
382
+ "SyNabp",
383
+ "SyNLessAggro",
384
+ "TV[1]",
385
+ "TV[2]",
386
+ "TV[3]",
387
+ "TV[4]",
388
+ "TV[5]",
389
+ "TV[6]",
390
+ "TV[7]",
391
+ "TV[8]",
392
+ "TVMSQ",
393
+ "TVMSQC",
394
+ "Rigid",
395
+ "Similarity",
396
+ "Translation",
397
+ "Affine",
398
+ "AffineFast",
399
+ "BOLDAffine",
400
+ "QuickRigid",
401
+ "DenseRigid",
402
+ "BOLDRigid"
403
+ }
404
+ ttexists = type_of_transform in allowable_tx
405
+
406
+ # Perform checking of antsRegistrationSyN transforms later
407
+ if not "antsRegistrationSyN" in type_of_transform and not ttexists:
408
+ raise ValueError(f'{type_of_transform} does not exist')
409
+
410
+ initx = initial_transform
411
+ if isinstance(initx, str):
412
+ initx = [initx]
413
+ # if isinstance(initx, ANTsTransform):
414
+ # tempTXfilename = tempfile( fileext = '.mat' )
415
+ # initx = invertAntsrTransform( initialTransform )
416
+ # initx = invertAntsrTransform( initx )
417
+ # writeAntsrTransform( initx, tempTXfilename )
418
+ # initx = tempTXfilename
419
+ moving = moving.clone(output_pixel_type)
420
+ fixed = fixed.clone(output_pixel_type)
421
+ # NOTE: this may be better for general purpose applications: TBD
422
+ # moving = ants.iMath( moving.clone("float"), "Normalize" )
423
+ # fixed = ants.iMath( fixed.clone("float"), "Normalize" )
424
+ warpedfixout = moving.clone()
425
+ warpedmovout = fixed.clone()
426
+ f = get_pointer_string(fixed)
427
+ m = get_pointer_string(moving)
428
+ wfo = get_pointer_string(warpedfixout)
429
+ wmo = get_pointer_string(warpedmovout)
430
+ if mask is not None:
431
+ mask_binary = mask != 0
432
+ f_mask_str = get_pointer_string(mask_binary)
433
+ else:
434
+ f_mask_str = "NA"
435
+
436
+ if moving_mask is not None:
437
+ moving_mask_binary = moving_mask != 0
438
+ m_mask_str = get_pointer_string(moving_mask_binary)
439
+ else:
440
+ m_mask_str = "NA"
441
+
442
+ maskopt = "[%s,%s]" % (f_mask_str, m_mask_str)
443
+
444
+ if mask_all_stages:
445
+ earlymaskopt = maskopt;
446
+ else:
447
+ earlymaskopt = "[NA,NA]"
448
+
449
+ if initx is None:
450
+ initx = ["[%s,%s,1]" % (f, m)]
451
+ # ------------------------------------------------------------
452
+ if type_of_transform == "SyNBold":
453
+ args = [
454
+ "-d",
455
+ str(fixed.dimension),
456
+ "-r"
457
+ ] + initx + [
458
+ "-m",
459
+ "%s[%s,%s,1,%s,regular,%s]"
460
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
461
+ "-t",
462
+ "Rigid[0.25]",
463
+ "-c",
464
+ "[1200x1200x100,1e-6,5]",
465
+ "-s",
466
+ "2x1x0",
467
+ "-f",
468
+ "4x2x1",
469
+ "-x",
470
+ earlymaskopt,
471
+ "-m",
472
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
473
+ "-t",
474
+ mysyn,
475
+ "-c",
476
+ "[%s,1e-7,8]" % synits,
477
+ "-s",
478
+ smoothingsigmas,
479
+ "-f",
480
+ shrinkfactors,
481
+ "-u",
482
+ "1",
483
+ "-z",
484
+ "1",
485
+ "-o",
486
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
487
+ "-x",
488
+ maskopt
489
+ ]
490
+ # ------------------------------------------------------------
491
+ elif type_of_transform == "SyNBoldAff":
492
+ args = [
493
+ "-d",
494
+ str(fixed.dimension),
495
+ "-r"
496
+ ] + initx + [
497
+ "-m",
498
+ "%s[%s,%s,1,%s,regular,%s]"
499
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
500
+ "-t",
501
+ "Rigid[0.25]",
502
+ "-c",
503
+ "[1200x1200x100,1e-6,5]",
504
+ "-s",
505
+ "2x1x0",
506
+ "-f",
507
+ "4x2x1",
508
+ "-x",
509
+ earlymaskopt,
510
+ "-m",
511
+ "%s[%s,%s,1,%s,regular,%s]"
512
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
513
+ "-t",
514
+ "Affine[0.25]",
515
+ "-c",
516
+ "[200x20,1e-6,5]",
517
+ "-s",
518
+ "1x0",
519
+ "-f",
520
+ "2x1",
521
+ "-x",
522
+ earlymaskopt,
523
+ "-m",
524
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
525
+ "-t",
526
+ mysyn,
527
+ "-c",
528
+ "[%s,1e-7,8]" % (synits),
529
+ "-s",
530
+ smoothingsigmas,
531
+ "-f",
532
+ shrinkfactors,
533
+ "-u",
534
+ "1",
535
+ "-z",
536
+ "1",
537
+ "-o",
538
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
539
+ "-x",
540
+ maskopt
541
+ ]
542
+ # ------------------------------------------------------------
543
+ elif type_of_transform == "ElasticSyN":
544
+ args = [
545
+ "-d",
546
+ str(fixed.dimension),
547
+ "-r"
548
+ ] + initx + [
549
+ "-m",
550
+ "%s[%s,%s,1,%s,regular,%s]"
551
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
552
+ "-t",
553
+ "Affine[0.25]",
554
+ "-c",
555
+ "2100x1200x200x0",
556
+ "-s",
557
+ "3x2x1x0",
558
+ "-f",
559
+ "4x2x2x1",
560
+ "-x",
561
+ earlymaskopt,
562
+ "-m",
563
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
564
+ "-t",
565
+ mysyn,
566
+ "-c",
567
+ "[%s,1e-7,8]" % (synits),
568
+ "-s",
569
+ smoothingsigmas,
570
+ "-f",
571
+ shrinkfactors,
572
+ "-u",
573
+ "1",
574
+ "-z",
575
+ "1",
576
+ "-o",
577
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
578
+ "-x",
579
+ maskopt
580
+ ]
581
+ # ------------------------------------------------------------
582
+ elif type_of_transform == "SyN" or type_of_transform == "Elastic":
583
+ args = [
584
+ "-d",
585
+ str(fixed.dimension),
586
+ "-r"
587
+ ] + initx + [
588
+ "-m",
589
+ "%s[%s,%s,1,%s,regular,%s]"
590
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
591
+ "-t",
592
+ "Affine[0.25]",
593
+ "-c",
594
+ "2100x1200x1200x0",
595
+ "-s",
596
+ "3x2x1x0",
597
+ "-f",
598
+ "4x2x2x1",
599
+ "-x",
600
+ earlymaskopt,
601
+ "-m",
602
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
603
+ "-t",
604
+ mysyn,
605
+ "-c",
606
+ "[%s,1e-7,8]" % synits,
607
+ "-s",
608
+ smoothingsigmas,
609
+ "-f",
610
+ shrinkfactors,
611
+ "-u",
612
+ "1",
613
+ "-z",
614
+ "1",
615
+ "-o",
616
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
617
+ "-x",
618
+ maskopt
619
+ ]
620
+ # ------------------------------------------------------------
621
+ elif type_of_transform == "SyNRA":
622
+ args = [
623
+ "-d",
624
+ str(fixed.dimension),
625
+ "-r"
626
+ ] + initx + [
627
+ "-m",
628
+ "%s[%s,%s,1,%s,regular,%s]"
629
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
630
+ "-t",
631
+ "Rigid[0.25]",
632
+ "-c",
633
+ "2100x1200x1200x0",
634
+ "-s",
635
+ "3x2x1x0",
636
+ "-f",
637
+ "4x2x2x1",
638
+ "-x",
639
+ earlymaskopt,
640
+ "-m",
641
+ "%s[%s,%s,1,%s,regular,%s]"
642
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
643
+ "-t",
644
+ "Affine[0.25]",
645
+ "-c",
646
+ "2100x1200x1200x0",
647
+ "-s",
648
+ "3x2x1x0",
649
+ "-f",
650
+ "4x2x2x1",
651
+ "-x",
652
+ earlymaskopt,
653
+ "-m",
654
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
655
+ "-t",
656
+ mysyn,
657
+ "-c",
658
+ "[%s,1e-7,8]" % synits,
659
+ "-s",
660
+ smoothingsigmas,
661
+ "-f",
662
+ shrinkfactors,
663
+ "-u",
664
+ "1",
665
+ "-z",
666
+ "1",
667
+ "-o",
668
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
669
+ "-x",
670
+ maskopt
671
+ ]
672
+ # ------------------------------------------------------------
673
+ elif type_of_transform == "SyNOnly":
674
+ args = [
675
+ "-d",
676
+ str(fixed.dimension),
677
+ "-r"
678
+ ] + initx + [
679
+ "-m",
680
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
681
+ "-t",
682
+ mysyn,
683
+ "-c",
684
+ "[%s,1e-7,8]" % synits,
685
+ "-s",
686
+ smoothingsigmas,
687
+ "-f",
688
+ shrinkfactors,
689
+ "-u",
690
+ "1",
691
+ "-z",
692
+ "1",
693
+ "-o",
694
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
695
+ ]
696
+ if multivariate_extras is not None:
697
+ metrics = []
698
+ for kk in range(len(multivariate_extras)):
699
+ metrics.append("-m")
700
+ metricname = multivariate_extras[kk][0]
701
+ metricfixed = get_pointer_string(
702
+ multivariate_extras[kk][1]
703
+ )
704
+ metricmov = get_pointer_string(
705
+ multivariate_extras[kk][2]
706
+ )
707
+ metricWeight = multivariate_extras[kk][3]
708
+ metricSampling = multivariate_extras[kk][4]
709
+ metricString = "%s[%s,%s,%s,%s]" % (
710
+ metricname,
711
+ metricfixed,
712
+ metricmov,
713
+ metricWeight,
714
+ metricSampling,
715
+ )
716
+ metrics.append(metricString)
717
+ args = [
718
+ "-d",
719
+ str(fixed.dimension),
720
+ "-r"
721
+ ] + initx + [
722
+ "-m",
723
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
724
+ ]
725
+ args1 = [
726
+ "-t",
727
+ mysyn,
728
+ "-c",
729
+ "[%s,1e-7,8]" % synits,
730
+ "-s",
731
+ smoothingsigmas,
732
+ "-f",
733
+ shrinkfactors,
734
+ "-u",
735
+ "1",
736
+ "-z",
737
+ "1",
738
+ "-o",
739
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
740
+ ]
741
+ for kk in range(len(metrics)):
742
+ args.append(metrics[kk])
743
+ for kk in range(len(args1)):
744
+ args.append(args1[kk])
745
+ args.append("-x")
746
+ args.append(maskopt)
747
+ # ------------------------------------------------------------
748
+ elif type_of_transform == "SyNAggro":
749
+ args = [
750
+ "-d",
751
+ str(fixed.dimension),
752
+ "-r"
753
+ ] + initx + [
754
+ "-m",
755
+ "%s[%s,%s,1,%s,regular,%s]"
756
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
757
+ "-t",
758
+ "Affine[0.25]",
759
+ "-c",
760
+ "2100x1200x1200x100",
761
+ "-s",
762
+ "3x2x1x0",
763
+ "-f",
764
+ "4x2x2x1",
765
+ "-x",
766
+ earlymaskopt,
767
+ "-m",
768
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
769
+ "-t",
770
+ mysyn,
771
+ "-c",
772
+ "[%s,1e-7,8]" % synits,
773
+ "-s",
774
+ smoothingsigmas,
775
+ "-f",
776
+ shrinkfactors,
777
+ "-u",
778
+ "1",
779
+ "-z",
780
+ "1",
781
+ "-o",
782
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
783
+ "-x",
784
+ maskopt
785
+ ]
786
+ # ------------------------------------------------------------
787
+ elif type_of_transform == "SyNCC":
788
+ syn_metric = "CC"
789
+ syn_sampling = 4
790
+ synits = "2100x1200x1200x20"
791
+ smoothingsigmas = "3x2x1x0"
792
+ shrinkfactors = "4x3x2x1"
793
+ mysyn = "SyN[0.15,3,0]"
794
+
795
+ args = [
796
+ "-d",
797
+ str(fixed.dimension),
798
+ "-r"
799
+ ] + initx + [
800
+ "-m",
801
+ "%s[%s,%s,1,%s,regular,%s]"
802
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
803
+ "-t",
804
+ "Rigid[1]",
805
+ "-c",
806
+ "2100x1200x1200x0",
807
+ "-s",
808
+ "3x2x1x0",
809
+ "-f",
810
+ "4x4x2x1",
811
+ "-x",
812
+ earlymaskopt,
813
+ "-m",
814
+ "%s[%s,%s,1,%s,regular,%s]"
815
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
816
+ "-t",
817
+ "Affine[1]",
818
+ "-c",
819
+ "1200x1200x100",
820
+ "-s",
821
+ "2x1x0",
822
+ "-f",
823
+ "4x2x1",
824
+ "-x",
825
+ earlymaskopt,
826
+ "-m",
827
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
828
+ "-t",
829
+ mysyn,
830
+ "-c",
831
+ "[%s,1e-7,8]" % synits,
832
+ "-s",
833
+ smoothingsigmas,
834
+ "-f",
835
+ shrinkfactors,
836
+ "-u",
837
+ "1",
838
+ "-z",
839
+ "1",
840
+ "-o",
841
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
842
+ "-x",
843
+ maskopt
844
+ ]
845
+ # ------------------------------------------------------------
846
+ elif type_of_transform == "TRSAA":
847
+ itlen = len(reg_iterations)
848
+ itlenlow = round(itlen / 2 + 0.0001)
849
+ dlen = itlen - itlenlow
850
+ _myconvlow = [2000] * itlenlow + [0] * dlen
851
+ myconvlow = "x".join([str(mc) for mc in _myconvlow])
852
+ myconvhi = "x".join([str(r) for r in reg_iterations])
853
+ myconvhi = "[%s,1.e-7,10]" % myconvhi
854
+ args = [
855
+ "-d",
856
+ str(fixed.dimension),
857
+ "-r"
858
+ ] + initx + [
859
+ "-m",
860
+ "%s[%s,%s,1,%s,regular,%s]"
861
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
862
+ "-t",
863
+ "Translation[1]",
864
+ "-c",
865
+ myconvlow,
866
+ "-s",
867
+ smoothingsigmas,
868
+ "-f",
869
+ shrinkfactors,
870
+ "-x",
871
+ earlymaskopt,
872
+ "-m",
873
+ "%s[%s,%s,1,%s,regular,%s]"
874
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
875
+ "-t",
876
+ "Rigid[1]",
877
+ "-c",
878
+ myconvlow,
879
+ "-s",
880
+ smoothingsigmas,
881
+ "-f",
882
+ shrinkfactors,
883
+ "-x",
884
+ earlymaskopt,
885
+ "-m",
886
+ "%s[%s,%s,1,%s,regular,%s]"
887
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
888
+ "-t",
889
+ "Similarity[1]",
890
+ "-c",
891
+ myconvlow,
892
+ "-s",
893
+ smoothingsigmas,
894
+ "-f",
895
+ shrinkfactors,
896
+ "-x",
897
+ earlymaskopt,
898
+ "-m",
899
+ "%s[%s,%s,1,%s,regular,%s]"
900
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
901
+ "-t",
902
+ "Affine[1]",
903
+ "-c",
904
+ myconvhi,
905
+ "-s",
906
+ smoothingsigmas,
907
+ "-f",
908
+ shrinkfactors,
909
+ "-x",
910
+ earlymaskopt,
911
+ "-m",
912
+ "%s[%s,%s,1,%s,regular,%s]"
913
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
914
+ "-t",
915
+ "Affine[1]",
916
+ "-c",
917
+ myconvhi,
918
+ "-s",
919
+ smoothingsigmas,
920
+ "-f",
921
+ shrinkfactors,
922
+ "-u",
923
+ "1",
924
+ "-z",
925
+ "1",
926
+ "-o",
927
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
928
+ "-x",
929
+ maskopt
930
+ ]
931
+ # ------------------------------------------------------------s
932
+ elif type_of_transform == "SyNabp":
933
+ args = [
934
+ "-d",
935
+ str(fixed.dimension),
936
+ "-r"
937
+ ] + initx + [
938
+ "-m",
939
+ "mattes[%s,%s,1,32,regular,0.25]" % (f, m),
940
+ "-t",
941
+ "Rigid[0.1]",
942
+ "-c",
943
+ "1000x500x250x100",
944
+ "-s",
945
+ "4x2x1x0",
946
+ "-f",
947
+ "8x4x2x1",
948
+ "-x",
949
+ earlymaskopt,
950
+ "-m",
951
+ "mattes[%s,%s,1,32,regular,0.25]" % (f, m),
952
+ "-t",
953
+ "Affine[0.1]",
954
+ "-c",
955
+ "1000x500x250x100",
956
+ "-s",
957
+ "4x2x1x0",
958
+ "-f",
959
+ "8x4x2x1",
960
+ "-x",
961
+ earlymaskopt,
962
+ "-m",
963
+ "CC[%s,%s,0.5,4]" % (f, m),
964
+ "-t",
965
+ "SyN[0.1,3,0]",
966
+ "-c",
967
+ "50x10x0",
968
+ "-s",
969
+ "2x1x0",
970
+ "-f",
971
+ "4x2x1",
972
+ "-u",
973
+ "1",
974
+ "-z",
975
+ "1",
976
+ "-o",
977
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
978
+ "-x",
979
+ maskopt
980
+ ]
981
+ # ------------------------------------------------------------
982
+ elif type_of_transform == "SyNLessAggro":
983
+ args = [
984
+ "-d",
985
+ str(fixed.dimension),
986
+ "-r"
987
+ ] + initx + [
988
+ "-m",
989
+ "%s[%s,%s,1,%s,regular,%s]"
990
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
991
+ "-t",
992
+ "Affine[0.25]",
993
+ "-c",
994
+ "2100x1200x1200x100",
995
+ "-s",
996
+ "3x2x1x0",
997
+ "-f",
998
+ "4x2x2x1",
999
+ "-x",
1000
+ earlymaskopt,
1001
+ "-m",
1002
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
1003
+ "-t",
1004
+ mysyn,
1005
+ "-c",
1006
+ "[%s,1e-7,8]" % synits,
1007
+ "-s",
1008
+ smoothingsigmas,
1009
+ "-f",
1010
+ shrinkfactors,
1011
+ "-u",
1012
+ "1",
1013
+ "-z",
1014
+ "1",
1015
+ "-o",
1016
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1017
+ "-x",
1018
+ maskopt
1019
+ ]
1020
+ # ------------------------------------------------------------
1021
+ elif type_of_transform in tvTypes:
1022
+ if grad_step is None:
1023
+ grad_step = 1.0
1024
+ nTimePoints = type_of_transform.split("[")[1].split("]")[0]
1025
+ tvtx = (
1026
+ "TimeVaryingVelocityField["
1027
+ + str(grad_step)
1028
+ + ","
1029
+ + nTimePoints
1030
+ + ","
1031
+ + str(flow_sigma)
1032
+ + ",0.0,"
1033
+ + str(total_sigma)
1034
+ + ",0]"
1035
+ )
1036
+ args = [
1037
+ "-d",
1038
+ str(fixed.dimension),
1039
+ "-r"
1040
+ ] + initx + [
1041
+ "-m",
1042
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
1043
+ "-t",
1044
+ tvtx,
1045
+ "-c",
1046
+ "[%s,1e-7,8]" % synits,
1047
+ "-s",
1048
+ smoothingsigmas,
1049
+ "-f",
1050
+ shrinkfactors,
1051
+ "-u",
1052
+ "1",
1053
+ "-z",
1054
+ "0",
1055
+ "-o",
1056
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1057
+ "-x",
1058
+ maskopt
1059
+ ]
1060
+ elif type_of_transform == "TVMSQ":
1061
+ if grad_step is None:
1062
+ grad_step = 1.0
1063
+
1064
+ tvtx = "TimeVaryingVelocityField[%s, 4, 0.0,0.0, 0.5,0 ]" % str(
1065
+ grad_step
1066
+ )
1067
+ args = [
1068
+ "-d",
1069
+ str(fixed.dimension),
1070
+ # '-r', initx,
1071
+ "-m",
1072
+ "%s[%s,%s,1,%s]" % (syn_metric, f, m, syn_sampling),
1073
+ "-t",
1074
+ tvtx,
1075
+ "-c",
1076
+ "[%s,1e-7,8]" % synits,
1077
+ "-s",
1078
+ smoothingsigmas,
1079
+ "-f",
1080
+ shrinkfactors,
1081
+ "-u",
1082
+ "1",
1083
+ "-z",
1084
+ "0",
1085
+ "-o",
1086
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1087
+ "-x",
1088
+ maskopt
1089
+ ]
1090
+ # ------------------------------------------------------------
1091
+ elif type_of_transform == "TVMSQC":
1092
+ if grad_step is None:
1093
+ grad_step = 2.0
1094
+
1095
+ tvtx = "TimeVaryingVelocityField[%s, 8, 1.0,0.0, 0.05,0 ]" % str(
1096
+ grad_step
1097
+ )
1098
+ args = [
1099
+ "-d",
1100
+ str(fixed.dimension),
1101
+ # '-r', initx,
1102
+ "-m",
1103
+ "demons[%s,%s,0.5,0]" % (f, m),
1104
+ "-m",
1105
+ "meansquares[%s,%s,1,0]" % (f, m),
1106
+ "-t",
1107
+ tvtx,
1108
+ "-c",
1109
+ "[1200x1200x100x20x0,0,5]",
1110
+ "-s",
1111
+ "8x6x4x2x1vox",
1112
+ "-f",
1113
+ "8x6x4x2x1",
1114
+ "-u",
1115
+ "1",
1116
+ "-z",
1117
+ "0",
1118
+ "-o",
1119
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1120
+ "-x",
1121
+ maskopt
1122
+ ]
1123
+ # ------------------------------------------------------------
1124
+ elif (
1125
+ (type_of_transform == "Rigid")
1126
+ or (type_of_transform == "Similarity")
1127
+ or (type_of_transform == "Translation")
1128
+ or (type_of_transform == "Affine")
1129
+ ):
1130
+ args = [
1131
+ "-d",
1132
+ str(fixed.dimension),
1133
+ "-r"
1134
+ ] + initx + [
1135
+ "-m",
1136
+ "%s[%s,%s,1,%s,regular,%s]"
1137
+ % (aff_metric, f, m, aff_sampling, aff_random_sampling_rate),
1138
+ "-t",
1139
+ "%s[0.25]" % type_of_transform,
1140
+ "-c",
1141
+ myiterations,
1142
+ "-s",
1143
+ mys_aff,
1144
+ "-f",
1145
+ myf_aff,
1146
+ "-u",
1147
+ "1",
1148
+ "-z",
1149
+ "1",
1150
+ "-o",
1151
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1152
+ "-x",
1153
+ maskopt
1154
+ ]
1155
+ # ------------------------------------------------------------
1156
+ elif "antsRegistrationSyN" in type_of_transform:
1157
+
1158
+ do_quick = False
1159
+ if "Quick" in type_of_transform:
1160
+ do_quick = True
1161
+
1162
+ subtype_of_transform = "s"
1163
+ spline_distance = 26
1164
+ metric_parameter = 4
1165
+ if do_quick:
1166
+ metric_parameter = 32
1167
+
1168
+ if "[" in type_of_transform and "]" in type_of_transform:
1169
+ subtype_of_transform = type_of_transform.split("[")[1].split(
1170
+ "]"
1171
+ )[0]
1172
+ if "," in subtype_of_transform:
1173
+ subtype_of_transform_args = subtype_of_transform.split(",")
1174
+ subtype_of_transform = subtype_of_transform_args[0]
1175
+ if not ( subtype_of_transform == "b"
1176
+ or subtype_of_transform == "br"
1177
+ or subtype_of_transform == "bo"
1178
+ or subtype_of_transform == "s"
1179
+ or subtype_of_transform == "sr"
1180
+ or subtype_of_transform == "so" ):
1181
+ raise ValueError("Extra parameters are only valid for 's' or 'b' SyN transforms.")
1182
+ metric_parameter = subtype_of_transform_args[1]
1183
+ if len(subtype_of_transform_args) > 2:
1184
+ spline_distance = subtype_of_transform_args[2]
1185
+
1186
+ do_repro = False
1187
+ if "Repro" in type_of_transform:
1188
+ do_repro = True
1189
+
1190
+ if do_quick == True:
1191
+ rigid_convergence = "[1000x500x250x0,1e-6,10]"
1192
+ else:
1193
+ rigid_convergence = "[1000x500x250x100,1e-6,10]"
1194
+ rigid_shrink_factors = "8x4x2x1"
1195
+ rigid_smoothing_sigmas = "3x2x1x0vox"
1196
+
1197
+ if do_quick == True:
1198
+ affine_convergence = "[1000x500x250x0,1e-6,10]"
1199
+ else:
1200
+ affine_convergence = "[1000x500x250x100,1e-6,10]"
1201
+ affine_shrink_factors = "8x4x2x1"
1202
+ affine_smoothing_sigmas = "3x2x1x0vox"
1203
+
1204
+ linear_metric="MI[%s,%s,1,32,Regular,0.25]"
1205
+ if do_repro == True:
1206
+ linear_metric="GC[%s,%s,1,1,Regular,0.25]"
1207
+
1208
+ if do_quick == True:
1209
+ syn_convergence = "[100x70x50x0,1e-6,10]"
1210
+ metric_parameter = 32
1211
+ syn_metric = "MI[%s,%s,1,%s]" % (f, m, metric_parameter)
1212
+ else:
1213
+ metric_parameter = 2
1214
+ syn_convergence = "[100x70x50x20,1e-6,10]"
1215
+ syn_metric = "CC[%s,%s,1,%s]" % (f, m, metric_parameter)
1216
+ syn_shrink_factors = "8x4x2x1"
1217
+ syn_smoothing_sigmas = "3x2x1x0vox"
1218
+
1219
+ if do_quick == True and do_repro == True:
1220
+ syn_convergence = "[100x70x50x0,1e-6,10]"
1221
+ metric_parameter = 2
1222
+ syn_metric = "CC[%s,%s,1,%s]" % (f, m, metric_parameter)
1223
+
1224
+ if random_seed is None and do_repro == True:
1225
+ random_seed = str( 1 )
1226
+
1227
+ tx = "Rigid"
1228
+ if subtype_of_transform == "t":
1229
+ tx = "Translation"
1230
+
1231
+ rigid_stage = [
1232
+ "--transform",
1233
+ tx + "[0.1]",
1234
+ "--metric",
1235
+ linear_metric % (f, m),
1236
+ "--convergence",
1237
+ rigid_convergence,
1238
+ "--shrink-factors",
1239
+ rigid_shrink_factors,
1240
+ "--smoothing-sigmas",
1241
+ rigid_smoothing_sigmas,
1242
+ ]
1243
+
1244
+ affine_stage = [
1245
+ "--transform",
1246
+ "Affine[0.1]",
1247
+ "--metric",
1248
+ linear_metric % (f, m),
1249
+ "--convergence",
1250
+ affine_convergence,
1251
+ "--shrink-factors",
1252
+ affine_shrink_factors,
1253
+ "--smoothing-sigmas",
1254
+ affine_smoothing_sigmas,
1255
+ ]
1256
+
1257
+ if subtype_of_transform == "sr" or subtype_of_transform == "br":
1258
+ if do_quick == True:
1259
+ syn_convergence = "[50x0,1e-6,10]"
1260
+ else:
1261
+ syn_convergence = "[50x20,1e-6,10]"
1262
+ syn_shrink_factors = "2x1"
1263
+ syn_smoothing_sigmas = "1x0vox"
1264
+
1265
+ syn_stage = [
1266
+ "--metric",
1267
+ syn_metric,
1268
+ ]
1269
+
1270
+ if multivariate_extras is not None:
1271
+ for kk in range(len(multivariate_extras)):
1272
+ syn_stage.append("--metric")
1273
+ metricname = multivariate_extras[kk][0]
1274
+ metricfixed = get_pointer_string(
1275
+ multivariate_extras[kk][1]
1276
+ )
1277
+ metricmov = get_pointer_string(
1278
+ multivariate_extras[kk][2]
1279
+ )
1280
+ metricWeight = multivariate_extras[kk][3]
1281
+ metricSampling = multivariate_extras[kk][4]
1282
+ metricString = "%s[%s,%s,%s,%s]" % (
1283
+ metricname,
1284
+ metricfixed,
1285
+ metricmov,
1286
+ metricWeight,
1287
+ metricSampling,
1288
+ )
1289
+ syn_stage.append(metricString)
1290
+
1291
+ syn_stage.append("--convergence")
1292
+ syn_stage.append(syn_convergence)
1293
+ syn_stage.append("--shrink-factors")
1294
+ syn_stage.append(syn_shrink_factors)
1295
+ syn_stage.append("--smoothing-sigmas")
1296
+ syn_stage.append(syn_smoothing_sigmas)
1297
+
1298
+ if (
1299
+ subtype_of_transform == "b"
1300
+ or subtype_of_transform == "br"
1301
+ or subtype_of_transform == "bo"
1302
+ ):
1303
+ syn_stage.insert(0, "BSplineSyN[0.1," + str(spline_distance) + ",0,3]")
1304
+ syn_stage.insert(0, "--transform")
1305
+
1306
+ if (
1307
+ subtype_of_transform == "s"
1308
+ or subtype_of_transform == "sr"
1309
+ or subtype_of_transform == "so"
1310
+ ):
1311
+ syn_stage.insert(0, "SyN[0.1,3,0]")
1312
+ syn_stage.insert(0, "--transform")
1313
+
1314
+ args = [
1315
+ "-d",
1316
+ str(fixed.dimension),
1317
+ "-r"
1318
+ ] + initx + [
1319
+ "-o",
1320
+ "[%s,%s,%s]" % (outprefix, wmo, wfo),
1321
+ ]
1322
+
1323
+ if subtype_of_transform == "r" or subtype_of_transform == "t":
1324
+ args.append(rigid_stage)
1325
+ if subtype_of_transform == "a":
1326
+ args.append(rigid_stage)
1327
+ args.append(affine_stage)
1328
+ if subtype_of_transform == "b" or subtype_of_transform == "s":
1329
+ args.append(rigid_stage)
1330
+ args.append(affine_stage)
1331
+ args.append(syn_stage)
1332
+ if subtype_of_transform == "br" or subtype_of_transform == "sr":
1333
+ args.append(rigid_stage)
1334
+ args.append(syn_stage)
1335
+ if subtype_of_transform == "bo" or subtype_of_transform == "so":
1336
+ args.append(syn_stage)
1337
+
1338
+ args.append("-x")
1339
+ args.append(maskopt)
1340
+
1341
+ args = list(
1342
+ itertools.chain.from_iterable(
1343
+ itertools.repeat(x, 1) if isinstance(x, str) else x
1344
+ for x in args
1345
+ )
1346
+ )
1347
+
1348
+ # ------------------------------------------------------------
1349
+
1350
+ if random_seed is not None:
1351
+ args.append("--random-seed")
1352
+ args.append(random_seed)
1353
+
1354
+ if restrict_transformation is not None:
1355
+ args.append("-g")
1356
+ args.append(restrict_transformationchar)
1357
+
1358
+ args.append("--float")
1359
+ args.append(str(int(singleprecision)))
1360
+ args.append("--write-composite-transform")
1361
+ args.append(write_composite_transform * 1)
1362
+ if verbose:
1363
+ args.append("-v")
1364
+ args.append("1")
1365
+
1366
+ processed_args = process_arguments(args)
1367
+ libfn = get_lib_fn("antsRegistration")
1368
+ if verbose:
1369
+ print("antsRegistration " + ' '.join(processed_args))
1370
+ reg_exit = libfn(processed_args)
1371
+ if (reg_exit != 0):
1372
+ raise RuntimeError(f"Registration failed with error code {reg_exit}")
1373
+ afffns = glob.glob(outprefix + "*" + "[0-9]GenericAffine.mat")
1374
+ fwarpfns = glob.glob(outprefix + "*" + "[0-9]Warp.nii.gz")
1375
+ iwarpfns = glob.glob(outprefix + "*" + "[0-9]InverseWarp.nii.gz")
1376
+ vfieldfns = glob.glob(outprefix + "*" + "[0-9]VelocityField.nii.gz")
1377
+ # print(afffns, fwarpfns, iwarpfns)
1378
+ if len(afffns) == 0:
1379
+ afffns = ""
1380
+ if len(fwarpfns) == 0:
1381
+ fwarpfns = ""
1382
+ if len(iwarpfns) == 0:
1383
+ iwarpfns = ""
1384
+ if len(vfieldfns) == 0:
1385
+ vfieldfns = ""
1386
+
1387
+ alltx = sorted(
1388
+ set(glob.glob(outprefix + "*" + "[0-9]*"))
1389
+ - set(glob.glob(outprefix + "*VelocityField*"))
1390
+ )
1391
+ findinv = np.where(
1392
+ [re.search("[0-9]InverseWarp.nii.gz", ff) for ff in alltx]
1393
+ )[0]
1394
+ findfwd = np.where([re.search("[0-9]Warp.nii.gz", ff) for ff in alltx])[
1395
+ 0
1396
+ ]
1397
+ if len(findinv) > 0:
1398
+ fwdtransforms = list(
1399
+ reversed(
1400
+ [ff for idx, ff in enumerate(alltx) if idx != findinv[0]]
1401
+ )
1402
+ )
1403
+ invtransforms = [
1404
+ ff for idx, ff in enumerate(alltx) if idx != findfwd[0]
1405
+ ]
1406
+ else:
1407
+ fwdtransforms = list(reversed(alltx))
1408
+ invtransforms = alltx
1409
+
1410
+ if write_composite_transform:
1411
+ fwdtransforms = outprefix + "Composite.h5"
1412
+ invtransforms = outprefix + "InverseComposite.h5"
1413
+
1414
+ if not vfieldfns:
1415
+ return {
1416
+ "warpedmovout": warpedmovout.clone(inpixeltype),
1417
+ "warpedfixout": warpedfixout.clone(inpixeltype),
1418
+ "fwdtransforms": fwdtransforms,
1419
+ "invtransforms": invtransforms,
1420
+ }
1421
+ else:
1422
+ return {
1423
+ "warpedmovout": warpedmovout.clone(inpixeltype),
1424
+ "warpedfixout": warpedfixout.clone(inpixeltype),
1425
+ "fwdtransforms": fwdtransforms,
1426
+ "invtransforms": invtransforms,
1427
+ "velocityfield": vfieldfns,
1428
+ }
1429
+
1430
+ def motion_correction(
1431
+ image,
1432
+ fixed=None,
1433
+ type_of_transform="BOLDRigid",
1434
+ mask=None,
1435
+ fdOffset=50,
1436
+ outprefix="",
1437
+ verbose=False,
1438
+ **kwargs
1439
+ ):
1440
+ """
1441
+ Correct time-series data for motion.
1442
+
1443
+ ANTsR function: `antsrMotionCalculation`
1444
+
1445
+ Arguments
1446
+ ---------
1447
+ image: antsImage, usually ND where D=4.
1448
+
1449
+ fixed: Fixed image to register all timepoints to. If not provided,
1450
+ mean image is used.
1451
+
1452
+ type_of_transform : string
1453
+ A linear or non-linear registration type. Mutual information metric and rigid transformation by default.
1454
+ See ants registration for details.
1455
+
1456
+ mask: mask for image (ND-1). If not provided, estimated from data.
1457
+ 2023-02-05: a performance change - previously, we estimated a mask
1458
+ when None is provided and would pass this to the registration. this
1459
+ impairs performance if the mask estimate is bad. in such a case, we
1460
+ prefer no mask at all. As such, we no longer pass the mask to the
1461
+ registration when None is provided.
1462
+
1463
+ fdOffset: offset value to use in framewise displacement calculation
1464
+
1465
+ outprefix : string
1466
+ output will be named with this prefix plus a numeric extension.
1467
+
1468
+ verbose: boolean
1469
+
1470
+ kwargs: keyword args
1471
+ extra arguments - these extra arguments will control the details of registration that is performed. see ants registration for more.
1472
+
1473
+ Returns
1474
+ -------
1475
+ dict containing follow key/value pairs:
1476
+ `motion_corrected`: Moving image warped to space of fixed image.
1477
+ `motion_parameters`: transforms for each image in the time series.
1478
+ `FD`: Framewise displacement generalized for arbitrary transformations.
1479
+
1480
+ Notes
1481
+ -----
1482
+ Control extra arguments via kwargs. see ants.registration for details.
1483
+
1484
+ Example
1485
+ -------
1486
+ >>> import ants
1487
+ >>> fi = ants.image_read(ants.get_ants_data('ch2'))
1488
+ >>> mytx = ants.motion_correction( fi )
1489
+ """
1490
+ idim = image.dimension
1491
+ ishape = image.shape
1492
+ nTimePoints = ishape[idim - 1]
1493
+ if fixed is None:
1494
+ wt = 1.0 / nTimePoints
1495
+ fixed = ants.slice_image(image, axis=idim - 1, idx=0) * 0
1496
+ for k in range(nTimePoints):
1497
+ temp = ants.slice_image(image, axis=idim - 1, idx=k)
1498
+ fixed = fixed + ants.iMath(temp,"Normalize") * wt
1499
+ if mask is None:
1500
+ mask = ants.get_mask(fixed)
1501
+ useMask=None
1502
+ else:
1503
+ useMask=mask
1504
+ FD = np.zeros(nTimePoints)
1505
+ motion_parameters = list()
1506
+ motion_corrected = list()
1507
+ centerOfMass = mask.get_center_of_mass()
1508
+ npts = pow(2, idim - 1)
1509
+ pointOffsets = np.zeros((npts, idim - 1))
1510
+ myrad = np.ones(idim - 1).astype(int).tolist()
1511
+ mask1vals = np.zeros(int(mask.sum()))
1512
+ mask1vals[round(len(mask1vals) / 2)] = 1
1513
+ mask1 = ants.make_image(mask, mask1vals)
1514
+ myoffsets = ants.get_neighborhood_in_mask(
1515
+ mask1, mask1, radius=myrad, spatial_info=True
1516
+ )["offsets"]
1517
+
1518
+ mycols = list("xy")
1519
+ if idim - 1 == 3:
1520
+ mycols = list("xyz")
1521
+ useinds = list()
1522
+ for k in range(myoffsets.shape[0]):
1523
+ if abs(myoffsets[k, :]).sum() == (idim - 2):
1524
+ useinds.append(k)
1525
+ myoffsets[k, :] = myoffsets[k, :] * fdOffset / 2.0 + centerOfMass
1526
+ fdpts = pd.DataFrame(data=myoffsets[useinds, :], columns=mycols)
1527
+ if verbose:
1528
+ print("Progress:")
1529
+ counter = 0
1530
+ for k in range(nTimePoints):
1531
+ mycount = round(k / nTimePoints * 100)
1532
+ if verbose and mycount == counter:
1533
+ counter = counter + 10
1534
+ print(mycount, end="%.", flush=True)
1535
+ temp = ants.slice_image(image, axis=idim - 1, idx=k)
1536
+ temp = ants.iMath(temp, "Normalize")
1537
+ if temp.numpy().var() > 0:
1538
+ if outprefix != "":
1539
+ outprefixloc = outprefix + "_" + str.zfill( str(k), 5 ) + "_"
1540
+ myreg = registration(
1541
+ fixed, temp, type_of_transform=type_of_transform, mask=useMask,
1542
+ outprefix=outprefixloc, **kwargs
1543
+ )
1544
+ else:
1545
+ myreg = registration(
1546
+ fixed, temp, type_of_transform=type_of_transform, mask=useMask, **kwargs
1547
+ )
1548
+ fdptsTxI = ants.apply_transforms_to_points(
1549
+ idim - 1, fdpts, myreg["fwdtransforms"]
1550
+ )
1551
+ if k > 0 and motion_parameters[k - 1] != "NA":
1552
+ fdptsTxIminus1 = ants.apply_transforms_to_points(
1553
+ idim - 1, fdpts, motion_parameters[k - 1]
1554
+ )
1555
+ else:
1556
+ fdptsTxIminus1 = fdptsTxI
1557
+ # take the absolute value, then the mean across columns, then the sum
1558
+ FD[k] = (fdptsTxIminus1 - fdptsTxI).abs().mean().sum()
1559
+ motion_parameters.append(myreg["fwdtransforms"])
1560
+ mywarped = ants.apply_transforms( fixed,
1561
+ ants.slice_image(image, axis=idim - 1, idx=k),
1562
+ myreg["fwdtransforms"] )
1563
+ motion_corrected.append(mywarped)
1564
+ else:
1565
+ motion_parameters.append("NA")
1566
+ motion_corrected.append(temp)
1567
+
1568
+ if verbose:
1569
+ print("Done")
1570
+ return {
1571
+ "motion_corrected": ants.list_to_ndimage(image, motion_corrected),
1572
+ "motion_parameters": motion_parameters,
1573
+ "FD": FD,
1574
+ }
1575
+
1576
+ def label_image_registration(fixed_label_images,
1577
+ moving_label_images,
1578
+ fixed_intensity_images=None,
1579
+ moving_intensity_images=None,
1580
+ fixed_mask=None,
1581
+ moving_mask=None,
1582
+ type_of_linear_transform='affine',
1583
+ type_of_deformable_transform='antsRegistrationSyNQuick[so]',
1584
+ label_image_weighting=1.0,
1585
+ output_prefix='',
1586
+ random_seed=None,
1587
+ verbose=False):
1588
+
1589
+ """
1590
+ Perform pairwise registration using fixed and moving sets of label
1591
+ images (and, optionally, sets of corresponding intensity images).
1592
+
1593
+ Arguments
1594
+ ---------
1595
+ fixed_label_images : single or list of ANTsImage
1596
+ A single (or set of) fixed label image(s).
1597
+
1598
+ moving_label_images : single or list of ANTsImage
1599
+ A single (or set of) moving label image(s).
1600
+
1601
+ fixed_intensity_images : single or list of ANTsImage
1602
+ Optional---a single (or set of) fixed intensity image(s).
1603
+
1604
+ moving_intensity_images : single or list of ANTsImage
1605
+ Optional---a single (or set of) moving intensity image(s).
1606
+
1607
+ fixed_mask : ANTsImage
1608
+ Defines region for similarity metric calculation in the space
1609
+ of the fixed image.
1610
+
1611
+ moving_mask : ANTsImage
1612
+ Defines region for similarity metric calculation in the space
1613
+ of the moving image.
1614
+
1615
+ type_of_linear_transform : string
1616
+ Use label images with the centers of mass to a calculate linear
1617
+ transform of type 'rigid', 'similarity', or 'affine'.
1618
+
1619
+ type_of_deformable_transform : string
1620
+ Only works with deformable-only transforms, specifically the family
1621
+ of antsRegistrationSyN*[so] or antsRegistrationSyN*[bo] transforms.
1622
+ See 'type_of_transform' in ants.registration. Additionally, one can
1623
+ use a list to pass a more tailored deformably-only transform
1624
+ optimization using SyN or BSplineSyN transforms. The order of
1625
+ parameters in the list would be 1) transform specification, i.e.
1626
+ "SyN" or "BSplineSyN", 2) gradient (real), 3) intensity metric (string),
1627
+ 4) intensity metric parameter (real), 5) convergence iterations per level
1628
+ (tuple) 6) smoothing factors per level (tuple), 7) shrink factors per level
1629
+ (tuple). An example would type_of_deformable_transform = ["SyN", 0.2, "CC",
1630
+ 4, (100,50,10), (2,1,0), (4,2,1)].
1631
+
1632
+ label_image_weighting : float or list of floats
1633
+ Relative weighting for the label images.
1634
+
1635
+ output_prefix : string
1636
+ Define the output prefix for the filenames of the output transform
1637
+ files.
1638
+
1639
+ random_seed : integer
1640
+ Definition for deformable registration.
1641
+
1642
+ verbose : boolean
1643
+ Print progress to the screen.
1644
+
1645
+ Returns
1646
+ -------
1647
+ Set of transforms definining the mapping to/from the fixed image domain
1648
+ to the moving image domain.
1649
+
1650
+ Example
1651
+ -------
1652
+ >>> import ants
1653
+ >>>
1654
+ >>> r16 = ants.image_read(ants.get_ants_data('r16'))
1655
+ >>> r16_seg1 = ants.threshold_image(r16, "Kmeans", 3) - 1
1656
+ >>> r16_seg2 = ants.threshold_image(r16, "Kmeans", 5) - 1
1657
+ >>> r64 = ants.image_read(ants.get_ants_data('r64'))
1658
+ >>> r64_seg1 = ants.threshold_image(r64, "Kmeans", 3) - 1
1659
+ >>> r64_seg2 = ants.threshold_image(r64, "Kmeans", 5) - 1
1660
+ >>> reg = ants.label_image_registration([r16_seg1, r16_seg2],
1661
+ [r64_seg1, r64_seg2],
1662
+ fixed_intensity_images=r16,
1663
+ moving_intensity_images=r64,
1664
+ type_of_linear_transform='affine',
1665
+ type_of_deformable_transform='antsRegistrationSyNQuick[bo]',
1666
+ label_image_weighting=[1.0, 2.0],
1667
+ verbose=True)
1668
+ """
1669
+
1670
+ # Perform validation check on the input
1671
+
1672
+ if isinstance(fixed_label_images, ants.ANTsImage):
1673
+ fixed_label_images = [ants.image_clone(fixed_label_images)]
1674
+ if isinstance(moving_label_images, ants.ANTsImage):
1675
+ moving_label_images = [ants.image_clone(moving_label_images)]
1676
+
1677
+ if len(fixed_label_images) != len(moving_label_images):
1678
+ raise ValueError("The number of fixed and moving label images do not match.")
1679
+
1680
+ if fixed_intensity_images is not None or moving_intensity_images is not None:
1681
+ if isinstance(fixed_intensity_images, ants.ANTsImage):
1682
+ fixed_intensity_images = [ants.image_clone(fixed_intensity_images)]
1683
+ if isinstance(moving_intensity_images, ants.ANTsImage):
1684
+ moving_intensity_images = [ants.image_clone(moving_intensity_images)]
1685
+ if len(fixed_intensity_images) != len(moving_intensity_images):
1686
+ raise ValueError("The number of fixed and moving intensity images do not match.")
1687
+
1688
+ label_image_weights = list()
1689
+ if isinstance(label_image_weighting, (int, float)):
1690
+ label_image_weights = [label_image_weighting] * len(fixed_label_images)
1691
+ else:
1692
+ label_image_weights = tuple(label_image_weighting)
1693
+ if len(fixed_label_images) != len(label_image_weights):
1694
+ raise ValueError("The length of label_image_weights must" +
1695
+ "match the number of label image pairs.")
1696
+
1697
+ image_dimension = fixed_label_images[0].dimension
1698
+
1699
+ if output_prefix == "" or output_prefix is None or len(output_prefix) == 0:
1700
+ output_prefix = mktemp()
1701
+
1702
+ allowable_linear_transforms = ['rigid', 'similarity', 'affine']
1703
+ if not type_of_linear_transform in allowable_linear_transforms:
1704
+ raise ValueError("Unrecognized linear transform.")
1705
+
1706
+ do_deformable = True
1707
+ if type_of_deformable_transform is None or len(type_of_deformable_transform) == 0:
1708
+ do_deformable = False
1709
+
1710
+ common_label_ids = list()
1711
+ total_number_of_labels = 0
1712
+ for i in range(len(fixed_label_images)):
1713
+ fixed_label_geoms = ants.label_geometry_measures(fixed_label_images[i])
1714
+ fixed_label_ids = np.array(fixed_label_geoms['Label'])
1715
+ moving_label_geoms = ants.label_geometry_measures(moving_label_images[i])
1716
+ moving_label_ids = np.array(moving_label_geoms['Label'])
1717
+ common_label_ids.append(np.intersect1d(moving_label_ids, fixed_label_ids))
1718
+ total_number_of_labels += len(common_label_ids[i])
1719
+ if verbose:
1720
+ print("Common label ids for image pair ", str(i), ": ", common_label_ids[i])
1721
+ if len(common_label_ids[i]) == 0:
1722
+ raise ValueError("No common labels for image pair " + str(i))
1723
+
1724
+ if verbose:
1725
+ print("Total number of labels: " + str(total_number_of_labels))
1726
+
1727
+ ##############################
1728
+ #
1729
+ # Linear transform
1730
+ #
1731
+ ##############################
1732
+
1733
+ linear_xfrm = None
1734
+ if type_of_linear_transform is not None:
1735
+
1736
+ if verbose:
1737
+ print("\n\nComputing linear transform.\n")
1738
+
1739
+ if total_number_of_labels < 3:
1740
+ raise ValueError(" Number of labels must be >= 3.")
1741
+
1742
+ fixed_centers_of_mass = np.zeros((total_number_of_labels, image_dimension))
1743
+ moving_centers_of_mass = np.zeros((total_number_of_labels, image_dimension))
1744
+ deformable_multivariate_extras = list()
1745
+
1746
+ count = 0
1747
+ for i in range(len(common_label_ids)):
1748
+ for j in range(len(common_label_ids[i])):
1749
+ label = common_label_ids[i][j]
1750
+ if verbose:
1751
+ print(" Finding centers of mass for image pair " + str(i) + ", label " + str(label))
1752
+ fixed_single_label_image = ants.threshold_image(fixed_label_images[i], label, label, 1, 0)
1753
+ fixed_centers_of_mass[count, :] = ants.get_center_of_mass(fixed_single_label_image)
1754
+ moving_single_label_image = ants.threshold_image(moving_label_images[i], label, label, 1, 0)
1755
+ moving_centers_of_mass[count, :] = ants.get_center_of_mass(moving_single_label_image)
1756
+ count += 1
1757
+ if do_deformable:
1758
+ deformable_multivariate_extras.append(["MSQ", fixed_single_label_image,
1759
+ moving_single_label_image,
1760
+ label_image_weights[i], 0])
1761
+
1762
+ linear_xfrm = ants.fit_transform_to_paired_points(moving_centers_of_mass,
1763
+ fixed_centers_of_mass,
1764
+ transform_type=type_of_linear_transform,
1765
+ verbose=verbose)
1766
+
1767
+ linear_xfrm_file = output_prefix + "0GenericAffine.mat"
1768
+ ants.write_transform(linear_xfrm, linear_xfrm_file)
1769
+
1770
+ ##############################
1771
+ #
1772
+ # Deformable transform
1773
+ #
1774
+ ##############################
1775
+
1776
+ if do_deformable:
1777
+
1778
+ if verbose:
1779
+ print("\n\nComputing deformable transform using images.\n")
1780
+
1781
+ intensity_metric = "CC"
1782
+ intensity_metric_parameter = 2
1783
+ syn_shrink_factors = "8x4x2x1"
1784
+ syn_smoothing_sigmas = "3x2x1x0vox"
1785
+ syn_convergence = "[100x70x50x20,1e-6,10]"
1786
+ spline_distance = 26
1787
+ gradient_step = 0.1
1788
+ syn_transform = "SyN"
1789
+
1790
+ syn_stage = list()
1791
+
1792
+ if isinstance(type_of_deformable_transform, list):
1793
+
1794
+ if (len(type_of_deformable_transform) != 7 or
1795
+ not isinstance(type_of_deformable_transform[0], str) or
1796
+ not isinstance(type_of_deformable_transform[1], float) or
1797
+ not isinstance(type_of_deformable_transform[2], str) or
1798
+ not isinstance(type_of_deformable_transform[3], int) or
1799
+ not isinstance(type_of_deformable_transform[4], tuple) or
1800
+ not isinstance(type_of_deformable_transform[5], tuple) or
1801
+ not isinstance(type_of_deformable_transform[6], tuple)):
1802
+ raise ValueError("Incorrect specification for type_of_deformable_transform. See help menu.")
1803
+
1804
+ syn_transform = type_of_deformable_transform[0]
1805
+ gradient_step = type_of_deformable_transform[1]
1806
+ intensity_metric = type_of_deformable_transform[2]
1807
+ intensity_metric_parameter = type_of_deformable_transform[3]
1808
+
1809
+ t = type_of_deformable_transform[4]
1810
+ tstr = ''.join(map(lambda x: str(x) + 'x', t[:len(t)-1])) + str(t[len(t)-1])
1811
+ syn_convergence = "[" + tstr + ",1e-6,10]"
1812
+
1813
+ t = type_of_deformable_transform[5]
1814
+ tstr = ''.join(map(lambda x: str(x) + 'x', t[:len(t)-1])) + str(t[len(t)-1])
1815
+ syn_smoothing_sigmas = tstr + "vox"
1816
+
1817
+ t = type_of_deformable_transform[6]
1818
+ syn_shrink_factors = ''.join(map(lambda x: str(x) + 'x', t[:len(t)-1])) + str(t[len(t)-1])
1819
+
1820
+ else:
1821
+
1822
+ do_quick = False
1823
+ if "Quick" in type_of_deformable_transform:
1824
+ do_quick = True
1825
+ elif "Repro" in type_of_deformable_transform:
1826
+ random_seed = str(1)
1827
+
1828
+ if "[" in type_of_deformable_transform and "]" in type_of_deformable_transform:
1829
+ subtype_of_deformable_transform = type_of_deformable_transform.split("[")[1].split("]")[0]
1830
+ if not ('bo' in subtype_of_deformable_transform or 'so' in subtype_of_deformable_transform):
1831
+ raise ValueError("Only 'so' or 'bo' transforms are available.")
1832
+ else:
1833
+ if 'bo' in subtype_of_deformable_transform:
1834
+ syn_transform = "BSplineSyN"
1835
+ if "," in subtype_of_deformable_transform:
1836
+ subtype_of_deformable_transform_args = subtype_of_deformable_transform.split(",")
1837
+ subtype_of_deformable_transform = subtype_of_deformable_transform_args[0]
1838
+ intensity_metric_parameter = subtype_of_deformable_transform_args[1]
1839
+ if len(subtype_of_deformable_transform_args) > 2:
1840
+ spline_distance = subtype_of_deformable_transform_args[2]
1841
+
1842
+ if do_quick:
1843
+ intensity_metric = "MI"
1844
+ if intensity_metric_parameter is None:
1845
+ intensity_metric_parameter = 32
1846
+ syn_convergence = "[100x70x50x0,1e-6,10]"
1847
+
1848
+ if fixed_intensity_images is not None and len(fixed_intensity_images) > 0:
1849
+ for i in range(len(fixed_intensity_images)):
1850
+ syn_stage.append("--metric")
1851
+ metric_string = "%s[%s,%s,%s,%s]" % (
1852
+ intensity_metric,
1853
+ get_pointer_string(fixed_intensity_images[i]),
1854
+ get_pointer_string(moving_intensity_images[i]),
1855
+ 1.0, intensity_metric_parameter)
1856
+ syn_stage.append(metric_string)
1857
+
1858
+ for kk in range(len(deformable_multivariate_extras)):
1859
+ syn_stage.append("--metric")
1860
+ metricString = "%s[%s,%s,%s,%s]" % (
1861
+ "MSQ",
1862
+ get_pointer_string(deformable_multivariate_extras[kk][1]),
1863
+ get_pointer_string(deformable_multivariate_extras[kk][2]),
1864
+ deformable_multivariate_extras[kk][3], 0.0)
1865
+ syn_stage.append(metricString)
1866
+
1867
+ syn_stage.append("--convergence")
1868
+ syn_stage.append(syn_convergence)
1869
+ syn_stage.append("--shrink-factors")
1870
+ syn_stage.append(syn_shrink_factors)
1871
+ syn_stage.append("--smoothing-sigmas")
1872
+ syn_stage.append(syn_smoothing_sigmas)
1873
+
1874
+ if syn_transform == "SyN":
1875
+ syn_stage.insert(0, "SyN[" + str(gradient_step) + ",3,0]")
1876
+ else:
1877
+ syn_stage.insert(0, "BSplineSyN[" + str(gradient_step) + "," + str(spline_distance) + ",0,3]")
1878
+ syn_stage.insert(0, "--transform")
1879
+
1880
+ args = None
1881
+ if linear_xfrm is None:
1882
+ args = ["-d", str(image_dimension),
1883
+ "-o", output_prefix]
1884
+ else:
1885
+ args = ["-d", str(image_dimension),
1886
+ "-r", linear_xfrm_file,
1887
+ "-o", output_prefix]
1888
+ args.append(syn_stage)
1889
+
1890
+ fixed_mask_string = 'NA'
1891
+ if fixed_mask is not None:
1892
+ fixed_mask_binary = fixed_mask != 0
1893
+ fixed_mask_string = get_pointer_string(fixed_mask_binary)
1894
+
1895
+ moving_mask_string = 'NA'
1896
+ if moving_mask is not None:
1897
+ moving_mask_binary = moving_mask != 0
1898
+ moving_mask_string = get_pointer_string(moving_mask_binary)
1899
+
1900
+ mask_option = "[%s,%s]" % (fixed_mask_string, moving_mask_string)
1901
+
1902
+ args.append("-x")
1903
+ args.append(mask_option)
1904
+
1905
+ args = list(itertools.chain.from_iterable(
1906
+ itertools.repeat(x, 1)
1907
+ if isinstance(x, str)
1908
+ else x for x in args))
1909
+
1910
+ args.append("--float")
1911
+ args.append("1")
1912
+
1913
+ if random_seed is not None:
1914
+ args.append("--random-seed")
1915
+ args.append(random_seed)
1916
+
1917
+ if verbose:
1918
+ args.append("-v")
1919
+ args.append("1")
1920
+
1921
+ processed_args = process_arguments(args)
1922
+ if verbose:
1923
+ print("antsRegistration " + ' '.join(processed_args))
1924
+
1925
+ libfn = get_lib_fn("antsRegistration")
1926
+ deformable_registration_exit_error = libfn(processed_args)
1927
+
1928
+ if deformable_registration_exit_error != 0:
1929
+ raise RuntimeError(f"Registration failed with error code {deformable_registration_exit_error}")
1930
+
1931
+ all_xfrms = sorted(set(glob.glob(output_prefix + "*" + "[0-9]*")))
1932
+
1933
+ find_inverse_warps = np.where([re.search("[0-9]InverseWarp.nii.gz", ff) for ff in all_xfrms])[0]
1934
+ find_forward_warps = np.where([re.search("[0-9]Warp.nii.gz", ff) for ff in all_xfrms])[0]
1935
+
1936
+ if len(find_inverse_warps) > 0:
1937
+ fwdtransforms = [all_xfrms[find_forward_warps[0]], linear_xfrm_file]
1938
+ invtransforms = [linear_xfrm_file, all_xfrms[find_inverse_warps[0]]]
1939
+ else:
1940
+ fwdtransforms = [linear_xfrm_file]
1941
+ invtransforms = [linear_xfrm_file]
1942
+
1943
+ if verbose:
1944
+ print("\n\nResulting transforms")
1945
+ print(" fwdtransforms: ", fwdtransforms)
1946
+ print(" invtransforms: ", invtransforms)
1947
+
1948
+ return {
1949
+ "fwdtransforms": fwdtransforms,
1950
+ "invtransforms": invtransforms,
1951
+ }
1952
+
1953
+
MindEyeV2/antspy/ants/registration/simulate_displacement_field.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = ["simulate_displacement_field"]
2
+
3
+ import numpy as np
4
+
5
+
6
+ import ants
7
+ from ants.internal import get_lib_fn
8
+
9
+
10
+
11
+ def simulate_displacement_field(domain_image,
12
+ field_type="bspline",
13
+ number_of_random_points=1000,
14
+ sd_noise=10.0,
15
+ enforce_stationary_boundary=True,
16
+ number_of_fitting_levels=4,
17
+ mesh_size=1,
18
+ sd_smoothing=4.0):
19
+ """
20
+ simulate displacement field using either b-spline or exponential transform
21
+
22
+ ANTsR function: `simulateDisplacementField`
23
+
24
+ Arguments
25
+ ---------
26
+ domain_image : ANTsImage
27
+ Domain image
28
+
29
+ field_type : string
30
+ Either "bspline" or "exponential".
31
+
32
+ number_of_random_points : integer
33
+ Number of displacement points.
34
+
35
+ sd_noise : float
36
+ Standard deviation of the displacement field noise.
37
+
38
+ enforce_stationary_boundary : boolean
39
+ Determines fixed boundary conditions.
40
+
41
+ number_of_fitting_levels : integer
42
+ Number of fitting levels (b-spline only).
43
+
44
+ mesh_size : integer or n-D tuple
45
+ Determines fitting resolution at base level (b-spline only).
46
+
47
+ sd_smoothing : float
48
+ Standard deviation of the Gaussian smoothing in mm (exponential only).
49
+
50
+ Returns
51
+ -------
52
+ ANTs vector image.
53
+
54
+ Example
55
+ -------
56
+ >>> import ants
57
+ >>> domain = ants.image_read( ants.get_ants_data('r16'))
58
+ >>> exp_field = ants.simulate_displacement_field(domain, field_type="exponential")
59
+ >>> bsp_field = ants.simulate_displacement_field(domain, field_type="bspline")
60
+ >>> bsp_xfrm = ants.transform_from_displacement_field(bsp_field * 3)
61
+ >>> domain_warped = ants.apply_ants_transform_to_image(bsp_xfrm, domain, domain)
62
+ """
63
+
64
+ image_dimension = domain_image.dimension
65
+
66
+ if field_type == 'bspline':
67
+ if isinstance(mesh_size, int) == False and len(mesh_size) != image_dimension:
68
+ raise ValueError("Incorrect specification for mesh_size.")
69
+
70
+ spline_order = 3
71
+ number_of_control_points = mesh_size + spline_order
72
+
73
+ if isinstance(number_of_control_points, int) == True:
74
+ number_of_control_points = np.repeat(number_of_control_points, image_dimension)
75
+
76
+ libfn = get_lib_fn("simulateBsplineDisplacementField%iD" % image_dimension)
77
+ field = libfn(domain_image.pointer, number_of_random_points, sd_noise,
78
+ enforce_stationary_boundary, number_of_fitting_levels, number_of_control_points)
79
+ bspline_field = ants.from_pointer(field).clone('float')
80
+ return bspline_field
81
+
82
+ elif field_type == 'exponential':
83
+ libfn = get_lib_fn("simulateExponentialDisplacementField%iD" % image_dimension)
84
+ field = libfn(domain_image.pointer, number_of_random_points, sd_noise,
85
+ enforce_stationary_boundary, sd_smoothing)
86
+ exp_field = ants.from_pointer(field).clone('float')
87
+ return exp_field
88
+
89
+ else:
90
+ raise ValueError("Unrecognized field type.")
MindEyeV2/src/slurms/458689.out ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-158-103
2
+ MASTER_PORT=11437
3
+ WORLD_SIZE=1
4
+ model_name=semantic_cluster_1.2_average_after_wd-2_no_prior_multi
MindEyeV2/src/slurms/458690.err ADDED
The diff for this file is too large to render. See raw diff
 
MindEyeV2/src/slurms/458711.out ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-128-54
2
+ MASTER_PORT=13306
3
+ WORLD_SIZE=1
4
+ model_name=semantic_cluster_1.2_average_after_wd-2_no_prior_multi
5
+ Top-1 Precision: 0.00%
6
+ LOCAL RANK 0
7
+ PID of this process = 1462175
8
+ device: cuda
9
+ Distributed environment: DistributedType.NO
10
+ Num processes: 1
11
+ Process index: 0
12
+ Local process index: 0
13
+ Device: cuda
14
+
15
+ Mixed precision type: fp16
16
+
17
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
18
+ subj_list [2 3 4 5 6 7 8] num_sessions 40
19
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
20
+ batch_size = 3 num_iterations_per_epoch = 1428 num_samples_per_epoch = 30000
21
+ Training with 40 sessions
22
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj02/train/{0..39}.tar
23
+ num_voxels for subj02: 14278
24
+ Training with 40 sessions
25
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj03/train/{0..31}.tar
26
+ num_voxels for subj03: 15226
27
+ Training with 40 sessions
28
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj04/train/{0..29}.tar
29
+ num_voxels for subj04: 13153
30
+ Training with 40 sessions
31
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj05/train/{0..39}.tar
32
+ num_voxels for subj05: 13039
33
+ Training with 40 sessions
34
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj06/train/{0..31}.tar
35
+ num_voxels for subj06: 17907
36
+ Training with 40 sessions
37
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj07/train/{0..39}.tar
38
+ num_voxels for subj07: 12682
39
+ Training with 40 sessions
40
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj08/train/{0..29}.tar
41
+ num_voxels for subj08: 14386
42
+ Loaded all subj train dls and betas!
43
+
44
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj02/new_test/0.tar
45
+ Loaded test dl for subj2!
46
+
47
+ Loaded all 73k possible NSD images to cpu! (73000, 3, 224, 224)
48
+ param counts:
49
+ 103,094,272 total
50
+ 103,094,272 trainable
51
+ param counts:
52
+ 103,094,272 total
53
+ 103,094,272 trainable
54
+ torch.Size([2, 1, 14278]) torch.Size([2, 1, 1024])
55
+ param counts:
56
+ 453,360,280 total
57
+ 453,360,280 trainable
58
+ param counts:
59
+ 556,454,552 total
60
+ 556,454,552 trainable
61
+ b.shape torch.Size([2, 1, 1024])
62
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
63
+ param counts:
64
+ 259,865,216 total
65
+ 259,865,200 trainable
66
+ param counts:
67
+ 816,319,768 total
68
+ 816,319,752 trainable
69
+ semantic_cluster_onehot.shape torch.Size([73000, 41])
70
+ num_seman_clusters 41
71
+ 25198
72
+ 4018
73
+ 43195
74
+ 71165
75
+ 46430
76
+ param counts:
77
+ 17,465,385 total
78
+ 17,465,385 trainable
79
+ param counts:
80
+ 833,785,153 total
81
+ 833,785,137 trainable
82
+ total_steps 214200
83
+
84
+ Done with model preparations!
85
+ param counts:
86
+ 833,785,153 total
87
+ 833,785,137 trainable
88
+ wandb mindeye_semantic_cluster_0.2 run semantic_cluster_1.2_average_after_wd-2_no_prior_multi
89
+ wandb_config:
90
+ {'model_name': 'semantic_cluster_1.2_average_after_wd-2_no_prior_multi', 'global_batch_size': '21', 'batch_size': 3, 'num_epochs': 150, 'num_sessions': 40, 'num_params': 833785137, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': False, 'max_lr': 3e-05, 'mixup_pct': 0.33, 'num_samples_per_epoch': 30000, 'num_test': 3000, 'ckpt_interval': 999, 'ckpt_saving': True, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1, 'train_url': '/weka/proj-medarc/shared/mindeyev2_dataset/wds/subj08/train/{0..29}.tar', 'test_url': '/weka/proj-medarc/shared/mindeyev2_dataset/wds/subj02/new_test/0.tar'}
91
+ wandb_id: semantic_cluster_1.2_average_after_wd-2_no_prior_multi
92
+ semantic_cluster_1.2_average_after_wd-2_no_prior_multi starting with epoch 0 / 150
93
+ loss_SM 4.119326591491699
94
+ loss_SM 3.8062686920166016
95
+ loss_SM 3.625744104385376
96
+ loss_SM 3.795665979385376
97
+ loss_SM 3.7455356121063232
98
+ loss_SM 3.976097583770752
99
+ loss_SM 3.781947612762451
100
+ loss_SM 3.6605281829833984
101
+ loss_SM 3.5571987628936768
102
+ loss_SM 3.4420573711395264
103
+ loss_SM 4.0613837242126465
104
+ loss_SM 3.6241164207458496
105
+ loss_SM 3.496047258377075
106
+ loss_SM 3.7202847003936768
107
+ loss_SM 3.770786762237549
108
+ loss_SM 3.5442707538604736
109
+ loss_SM 3.864955425262451
110
+ loss_SM 3.5894718170166016
111
+ loss_SM 3.7825520038604736
112
+ loss_SM 4.742745399475098
113
+ loss_SM 3.456333637237549
114
+ loss_SM 3.6668992042541504
115
+ loss_SM 4.704915523529053
116
+ loss_SM 3.688209056854248
117
+ loss_SM 4.23974609375
118
+ loss_SM 4.481863975524902
119
+ loss_SM 3.4336636066436768
120
+ loss_SM 4.053106307983398
121
+ loss_SM 4.140625
122
+ loss_SM 5.718982696533203
123
+ loss_SM 4.348353862762451
124
+ loss_SM 3.981166362762451
125
+ loss_SM 4.858863353729248
126
+ loss_SM 4.771158695220947
127
+ loss_SM 3.880603551864624
128
+ loss_SM 4.3950018882751465
129
+ loss_SM 6.392113208770752
130
+ loss_SM 3.8019206523895264
131
+ loss_SM 5.100527763366699
132
+ loss_SM 4.1439032554626465
133
+ loss_SM 6.9605889320373535
134
+ loss_SM 5.183436870574951
135
+ [2024-07-10 02:10:10,985] [INFO] [real_accelerator.py:191:get_accelerator] Setting ds_accelerator to cuda (auto detect)
MindEyeV2/src/slurms/466067.out ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-133-122
2
+ MASTER_PORT=15846
3
+ WORLD_SIZE=1
4
+ model_name=augmented_image_one
5
+ LOCAL RANK 0
6
+ PID of this process = 2199630
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 14
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ batch_size = 21 num_iterations_per_epoch = 250 num_samples_per_epoch = 5254
20
+ param counts:
21
+ 6,905,856 total
22
+ 6,905,856 trainable
23
+ param counts:
24
+ 6,905,856 total
25
+ 6,905,856 trainable
26
+ torch.Size([2, 1, 1685]) torch.Size([2, 1, 4096])
27
+ param counts:
28
+ 1,887,861,400 total
29
+ 1,887,861,400 trainable
30
+ param counts:
31
+ 1,894,767,256 total
32
+ 1,894,767,256 trainable
33
+ b.shape torch.Size([2, 1, 4096])
34
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
35
+ param counts:
36
+ 259,865,216 total
37
+ 259,865,200 trainable
38
+ param counts:
39
+ 2,154,632,472 total
40
+ 2,154,632,456 trainable
41
+ total_steps 20000
42
+
43
+ Done with model preparations!
44
+ param counts:
45
+ 2,154,632,472 total
46
+ 2,154,632,456 trainable
47
+ wandb bold5000 run augmented_image_one
48
+ wandb_config:
49
+ {'model_name': 'augmented_image_one', 'global_batch_size': '21', 'batch_size': 21, 'num_epochs': 80, 'num_sessions': 14, 'num_params': 2154632456, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': True, 'max_lr': 0.0003, 'mixup_pct': 0.33, 'num_samples_per_epoch': 5254, 'num_test': 370, 'ckpt_interval': 999, 'ckpt_saving': False, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1}
50
+ wandb_id: augmented_image_one
51
+ augmented_image_one starting with epoch 0 / 80
52
+
53
+ ===Finished!===
54
+
MindEyeV2/src/slurms/534014.err ADDED
The diff for this file is too large to render. See raw diff
 
MindEyeV2/src/slurms/534014.out ADDED
@@ -0,0 +1,889 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-139-113
2
+ MASTER_PORT=11065
3
+ final_subj01_pretrained_20sess_24bs
4
+ device: cuda
5
+ torch.Size([18, 1, 15724]) torch.Size([18, 3, 425, 425])
6
+ torch.Size([18, 1, 15724])
7
+ param counts:
8
+ 83,653,863 total
9
+ 0 trainable
10
+ param counts:
11
+ 64,409,600 total
12
+ 64,409,600 trainable
13
+ param counts:
14
+ 1,903,020,028 total
15
+ 1,903,020,028 trainable
16
+ param counts:
17
+ 1,967,429,628 total
18
+ 1,967,429,628 trainable
19
+ param counts:
20
+ 259,865,216 total
21
+ 259,865,200 trainable
22
+ param counts:
23
+ 2,227,294,844 total
24
+ 2,227,294,828 trainable
25
+
26
+ ---loading /weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_20sess_24bs/last.pth ckpt---
27
+
28
+ [2024-11-07 03:38:28,497] [INFO] [real_accelerator.py:191:get_accelerator] Setting ds_accelerator to cuda (auto detect)
29
+ Processing zero checkpoint '/weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_20sess_24bs/last'
30
+ Detected checkpoint of type zero stage ZeroStageEnum.gradients, world_size: 8
31
+ Parsing checkpoint created by deepspeed==0.12.2
32
+ Reconstructed Frozen fp32 state dict with 1 params 16 elements
33
+ Reconstructed fp32 state dict with 230 params 2227294828 elements
34
+ ckpt loaded!
35
+ Initialized embedder #0: FrozenOpenCLIPImageEmbedder with 1909889025 params. Trainable: False
36
+ Initialized embedder #1: ConcatTimestepEmbedderND with 0 params. Trainable: False
37
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
38
+ vector_suffix torch.Size([1, 1024])
39
+ torch.Size([1, 15724]) torch.Size([1, 15724])
40
+ ['a table with a lamp on it']
41
+ torch.Size([1, 15724]) torch.Size([1, 15724])
42
+ ['a motorcycle is parked on the side of the road.']
43
+ torch.Size([1, 15724]) torch.Size([1, 15724])
44
+ ['a room with a view']
45
+ torch.Size([1, 15724]) torch.Size([1, 15724])
46
+ ['a red and white striped bed']
47
+ torch.Size([1, 15724]) torch.Size([1, 15724])
48
+ ['a display of a variety of items.']
49
+ torch.Size([1, 15724]) torch.Size([1, 15724])
50
+ ['a large display of items.']
51
+ torch.Size([1, 15724]) torch.Size([1, 15724])
52
+ ['a small room with a lot of furniture.']
53
+ torch.Size([1, 15724]) torch.Size([1, 15724])
54
+ ['a large building with a lot of people around it.']
55
+ torch.Size([1, 15724]) torch.Size([1, 15724])
56
+ ['a room with a lot of furniture.']
57
+ torch.Size([1, 15724]) torch.Size([1, 15724])
58
+ ['a building with a lot of windows']
59
+ torch.Size([1, 15724]) torch.Size([1, 15724])
60
+ ['a room with a lot of furniture.']
61
+ torch.Size([1, 15724]) torch.Size([1, 15724])
62
+ ['a chair that you sit in.']
63
+ torch.Size([1, 15724]) torch.Size([1, 15724])
64
+ ['a wooden bench with a large amount of furniture.']
65
+ torch.Size([1, 15724]) torch.Size([1, 15724])
66
+ ['a picture of a room.']
67
+ torch.Size([1, 15724]) torch.Size([1, 15724])
68
+ ['a picture of a car.']
69
+ torch.Size([1, 15724]) torch.Size([1, 15724])
70
+ ['a room with a lot of furniture.']
71
+ torch.Size([1, 15724]) torch.Size([1, 15724])
72
+ ['a room with a lot of furniture.']
73
+ torch.Size([1, 15724]) torch.Size([1, 15724])
74
+ ['a fire hydrant is next to a sidewalk.']
75
+ torch.Size([18, 3, 256, 256])
76
+ torch.Size([1, 15724]) torch.Size([1, 15724])
77
+ ['a large wooden table.']
78
+ torch.Size([1, 15724]) torch.Size([1, 15724])
79
+ ['a small room with a lot of furniture.']
80
+ torch.Size([1, 15724]) torch.Size([1, 15724])
81
+ ['a large room with a table and chairs.']
82
+ torch.Size([1, 15724]) torch.Size([1, 15724])
83
+ ['a red and white sign']
84
+ torch.Size([1, 15724]) torch.Size([1, 15724])
85
+ ['a display of items for sale.']
86
+ torch.Size([1, 15724]) torch.Size([1, 15724])
87
+ ['a motorcycle parked next to a building.']
88
+ torch.Size([1, 15724]) torch.Size([1, 15724])
89
+ ['a small room with a lot of furniture.']
90
+ torch.Size([1, 15724]) torch.Size([1, 15724])
91
+ ['a large group of people.']
92
+ torch.Size([1, 15724]) torch.Size([1, 15724])
93
+ ['a small room with a lot of furniture.']
94
+ torch.Size([1, 15724]) torch.Size([1, 15724])
95
+ ['a building with a lot of windows.']
96
+ torch.Size([1, 15724]) torch.Size([1, 15724])
97
+ ['a small room with a lot of furniture.']
98
+ torch.Size([1, 15724]) torch.Size([1, 15724])
99
+ ['a woman standing in front of a chair.']
100
+ torch.Size([1, 15724]) torch.Size([1, 15724])
101
+ ['a large wooden table.']
102
+ torch.Size([1, 15724]) torch.Size([1, 15724])
103
+ ['a large display of furniture.']
104
+ torch.Size([1, 15724]) torch.Size([1, 15724])
105
+ ['a cat sitting on a table.']
106
+ torch.Size([1, 15724]) torch.Size([1, 15724])
107
+ ['a bathroom with a sink and a mirror.']
108
+ torch.Size([1, 15724]) torch.Size([1, 15724])
109
+ ['a room with a lot of furniture.']
110
+ torch.Size([1, 15724]) torch.Size([1, 15724])
111
+ ['a street with a lot of trees and a building.']
112
+ torch.Size([18, 3, 256, 256])
113
+ torch.Size([1, 15724]) torch.Size([1, 15724])
114
+ ['a wooden fence with a white base.']
115
+ torch.Size([1, 15724]) torch.Size([1, 15724])
116
+ ['a small building with a lot of windows.']
117
+ torch.Size([1, 15724]) torch.Size([1, 15724])
118
+ ['a large room with a lot of furniture.']
119
+ torch.Size([1, 15724]) torch.Size([1, 15724])
120
+ ['a red and white striped chair']
121
+ torch.Size([1, 15724]) torch.Size([1, 15724])
122
+ ['a display of items for sale.']
123
+ torch.Size([1, 15724]) torch.Size([1, 15724])
124
+ ['a display of a car and a motorcycle.']
125
+ torch.Size([1, 15724]) torch.Size([1, 15724])
126
+ ['a small room with a lot of furniture.']
127
+ torch.Size([1, 15724]) torch.Size([1, 15724])
128
+ ['a large group of people.']
129
+ torch.Size([1, 15724]) torch.Size([1, 15724])
130
+ ['a table with a piece of wood on it']
131
+ torch.Size([1, 15724]) torch.Size([1, 15724])
132
+ ['a building with a lot of windows.']
133
+ torch.Size([1, 15724]) torch.Size([1, 15724])
134
+ ['a kitchen with a counter and a refrigerator.']
135
+ torch.Size([1, 15724]) torch.Size([1, 15724])
136
+ ['a small room with a lot of furniture.']
137
+ torch.Size([1, 15724]) torch.Size([1, 15724])
138
+ ['a picture of a large room.']
139
+ torch.Size([1, 15724]) torch.Size([1, 15724])
140
+ ['a building with a lot of windows.']
141
+ torch.Size([1, 15724]) torch.Size([1, 15724])
142
+ ['a cat sitting on a table.']
143
+ torch.Size([1, 15724]) torch.Size([1, 15724])
144
+ ['a small room with a lot of furniture.']
145
+ torch.Size([1, 15724]) torch.Size([1, 15724])
146
+ ['a large white building.']
147
+ torch.Size([1, 15724]) torch.Size([1, 15724])
148
+ ['a fire hydrant is in the foreground.']
149
+ torch.Size([18, 3, 256, 256])
150
+ torch.Size([1, 15724]) torch.Size([1, 15724])
151
+ ['a large wooden table.']
152
+ torch.Size([1, 15724]) torch.Size([1, 15724])
153
+ ['a red and white chair']
154
+ torch.Size([1, 15724]) torch.Size([1, 15724])
155
+ ['a room with a lot of furniture.']
156
+ torch.Size([1, 15724]) torch.Size([1, 15724])
157
+ ['a man standing in a room.']
158
+ torch.Size([1, 15724]) torch.Size([1, 15724])
159
+ ['a display of items in a room.']
160
+ torch.Size([1, 15724]) torch.Size([1, 15724])
161
+ ['a display of a motorcycle.']
162
+ torch.Size([1, 15724]) torch.Size([1, 15724])
163
+ ['a small room with a lot of furniture.']
164
+ torch.Size([1, 15724]) torch.Size([1, 15724])
165
+ ['a large group of people.']
166
+ torch.Size([1, 15724]) torch.Size([1, 15724])
167
+ ['a room with a lot of furniture.']
168
+ torch.Size([1, 15724]) torch.Size([1, 15724])
169
+ ['a building with a lot of windows.']
170
+ torch.Size([1, 15724]) torch.Size([1, 15724])
171
+ ['a counter with a lot of items on it.']
172
+ torch.Size([1, 15724]) torch.Size([1, 15724])
173
+ ['a woman sitting in a chair.']
174
+ torch.Size([1, 15724]) torch.Size([1, 15724])
175
+ ['a large wooden structure.']
176
+ torch.Size([1, 15724]) torch.Size([1, 15724])
177
+ ['a large wooden table.']
178
+ torch.Size([1, 15724]) torch.Size([1, 15724])
179
+ ['a cat sitting on a chair.']
180
+ torch.Size([1, 15724]) torch.Size([1, 15724])
181
+ ['a room with a lot of furniture.']
182
+ torch.Size([1, 15724]) torch.Size([1, 15724])
183
+ ['a room with a lot of furniture.']
184
+ torch.Size([1, 15724]) torch.Size([1, 15724])
185
+ ['a red and white fire hydrant']
186
+ torch.Size([18, 3, 256, 256])
187
+ torch.Size([1, 15724]) torch.Size([1, 15724])
188
+ ['a building with a lot of windows.']
189
+ torch.Size([1, 15724]) torch.Size([1, 15724])
190
+ ['a small room with a lot of furniture.']
191
+ torch.Size([1, 15724]) torch.Size([1, 15724])
192
+ ['a display of items in a room.']
193
+ torch.Size([1, 15724]) torch.Size([1, 15724])
194
+ ['a man standing in front of a bed.']
195
+ torch.Size([1, 15724]) torch.Size([1, 15724])
196
+ ['a display of items for sale.']
197
+ torch.Size([1, 15724]) torch.Size([1, 15724])
198
+ ['a picture of a very old looking room.']
199
+ torch.Size([1, 15724]) torch.Size([1, 15724])
200
+ ['a small room with a lot of furniture.']
201
+ torch.Size([1, 15724]) torch.Size([1, 15724])
202
+ ['a large building with a lot of windows.']
203
+ torch.Size([1, 15724]) torch.Size([1, 15724])
204
+ ['a room with a lot of furniture.']
205
+ torch.Size([1, 15724]) torch.Size([1, 15724])
206
+ ['a building with a lot of windows']
207
+ torch.Size([1, 15724]) torch.Size([1, 15724])
208
+ ['a small room with a lot of stuff on it.']
209
+ torch.Size([1, 15724]) torch.Size([1, 15724])
210
+ ['a small room with a lot of furniture.']
211
+ torch.Size([1, 15724]) torch.Size([1, 15724])
212
+ ['a wooden bench with a large back.']
213
+ torch.Size([1, 15724]) torch.Size([1, 15724])
214
+ ['a building with a lot of windows.']
215
+ torch.Size([1, 15724]) torch.Size([1, 15724])
216
+ ['a cat sitting on a table.']
217
+ torch.Size([1, 15724]) torch.Size([1, 15724])
218
+ ['a room with a lot of furniture.']
219
+ torch.Size([1, 15724]) torch.Size([1, 15724])
220
+ ['a large room with a lot of furniture.']
221
+ torch.Size([1, 15724]) torch.Size([1, 15724])
222
+ ['a flower pot is on the table.']
223
+ torch.Size([18, 3, 256, 256])
224
+ torch.Size([1, 15724]) torch.Size([1, 15724])
225
+ ['a bench with a plant on it.']
226
+ torch.Size([1, 15724]) torch.Size([1, 15724])
227
+ ['a small room with a lot of furniture.']
228
+ torch.Size([1, 15724]) torch.Size([1, 15724])
229
+ ['a table with a vase and a plant on it.']
230
+ torch.Size([1, 15724]) torch.Size([1, 15724])
231
+ ['a red and white bus']
232
+ torch.Size([1, 15724]) torch.Size([1, 15724])
233
+ ['a display of items for sale.']
234
+ torch.Size([1, 15724]) torch.Size([1, 15724])
235
+ ['a display of a stuffed animal.']
236
+ torch.Size([1, 15724]) torch.Size([1, 15724])
237
+ ['a small room with a lot of furniture.']
238
+ torch.Size([1, 15724]) torch.Size([1, 15724])
239
+ ['a large parking lot with a lot of parked cars.']
240
+ torch.Size([1, 15724]) torch.Size([1, 15724])
241
+ ['a small room with a lot of furniture.']
242
+ torch.Size([1, 15724]) torch.Size([1, 15724])
243
+ ['a building with a lot of windows.']
244
+ torch.Size([1, 15724]) torch.Size([1, 15724])
245
+ ['a large piece of furniture.']
246
+ torch.Size([1, 15724]) torch.Size([1, 15724])
247
+ ['a woman sitting in a chair.']
248
+ torch.Size([1, 15724]) torch.Size([1, 15724])
249
+ ['a view of a large room.']
250
+ torch.Size([1, 15724]) torch.Size([1, 15724])
251
+ ['a picture of a building.']
252
+ torch.Size([1, 15724]) torch.Size([1, 15724])
253
+ ['a small room with a lot of furniture.']
254
+ torch.Size([1, 15724]) torch.Size([1, 15724])
255
+ ['a room with a lot of furniture.']
256
+ torch.Size([1, 15724]) torch.Size([1, 15724])
257
+ ['a large building with a lot of windows.']
258
+ torch.Size([1, 15724]) torch.Size([1, 15724])
259
+ ['a fire hydrant is in the foreground.']
260
+ torch.Size([18, 3, 256, 256])
261
+ torch.Size([1, 15724]) torch.Size([1, 15724])
262
+ ['a building with a lot of windows.']
263
+ torch.Size([1, 15724]) torch.Size([1, 15724])
264
+ ['a red and white chair']
265
+ torch.Size([1, 15724]) torch.Size([1, 15724])
266
+ ['a room with a lot of furniture.']
267
+ torch.Size([1, 15724]) torch.Size([1, 15724])
268
+ ['a large bed with a red cover.']
269
+ torch.Size([1, 15724]) torch.Size([1, 15724])
270
+ ['a display of items for sale.']
271
+ torch.Size([1, 15724]) torch.Size([1, 15724])
272
+ ['a display of a motorcycle.']
273
+ torch.Size([1, 15724]) torch.Size([1, 15724])
274
+ ['a small room with a lot of furniture.']
275
+ torch.Size([1, 15724]) torch.Size([1, 15724])
276
+ ['a large group of people.']
277
+ torch.Size([1, 15724]) torch.Size([1, 15724])
278
+ ['a small room with a lot of furniture.']
279
+ torch.Size([1, 15724]) torch.Size([1, 15724])
280
+ ['a building with a lot of windows']
281
+ torch.Size([1, 15724]) torch.Size([1, 15724])
282
+ ['a small room with a lot of furniture.']
283
+ torch.Size([1, 15724]) torch.Size([1, 15724])
284
+ ['a woman is standing in front of a chair.']
285
+ torch.Size([1, 15724]) torch.Size([1, 15724])
286
+ ['a large wooden bench.']
287
+ torch.Size([1, 15724]) torch.Size([1, 15724])
288
+ ['a large room with a lot of furniture.']
289
+ torch.Size([1, 15724]) torch.Size([1, 15724])
290
+ ['a cat sitting on a table.']
291
+ torch.Size([1, 15724]) torch.Size([1, 15724])
292
+ ['a room with a lot of stuff on it']
293
+ torch.Size([1, 15724]) torch.Size([1, 15724])
294
+ ['a large building with a lot of windows.']
295
+ torch.Size([1, 15724]) torch.Size([1, 15724])
296
+ ['a fire hydrant in a garden.']
297
+ torch.Size([18, 3, 256, 256])
298
+ torch.Size([1, 15724]) torch.Size([1, 15724])
299
+ ['a building with a lot of windows.']
300
+ torch.Size([1, 15724]) torch.Size([1, 15724])
301
+ ['a small room with a lot of furniture.']
302
+ torch.Size([1, 15724]) torch.Size([1, 15724])
303
+ ['a room with a lot of furniture.']
304
+ torch.Size([1, 15724]) torch.Size([1, 15724])
305
+ ['a bed or beds in a room at the hotel']
306
+ torch.Size([1, 15724]) torch.Size([1, 15724])
307
+ ['a display of items']
308
+ torch.Size([1, 15724]) torch.Size([1, 15724])
309
+ ['a display of a stuffed animal.']
310
+ torch.Size([1, 15724]) torch.Size([1, 15724])
311
+ ['a room with a lot of furniture.']
312
+ torch.Size([1, 15724]) torch.Size([1, 15724])
313
+ ['a large group of people.']
314
+ torch.Size([1, 15724]) torch.Size([1, 15724])
315
+ ['a small room with a lot of furniture.']
316
+ torch.Size([1, 15724]) torch.Size([1, 15724])
317
+ ['a building with a lot of windows']
318
+ torch.Size([1, 15724]) torch.Size([1, 15724])
319
+ ['a small room with a lot of furniture.']
320
+ torch.Size([1, 15724]) torch.Size([1, 15724])
321
+ ['a chair that you sit in.']
322
+ torch.Size([1, 15724]) torch.Size([1, 15724])
323
+ ['a large wooden structure.']
324
+ torch.Size([1, 15724]) torch.Size([1, 15724])
325
+ ['a building with a lot of windows.']
326
+ torch.Size([1, 15724]) torch.Size([1, 15724])
327
+ ['a small room with a lot of furniture.']
328
+ torch.Size([1, 15724]) torch.Size([1, 15724])
329
+ ['a room with a lot of furniture.']
330
+ torch.Size([1, 15724]) torch.Size([1, 15724])
331
+ ['a large white building.']
332
+ torch.Size([1, 15724]) torch.Size([1, 15724])
333
+ ['a plant with a flower in it.']
334
+ torch.Size([18, 3, 256, 256])
335
+ torch.Size([1, 15724]) torch.Size([1, 15724])
336
+ ['a bench with a plant in it.']
337
+ torch.Size([1, 15724]) torch.Size([1, 15724])
338
+ ['a chair that you sit in.']
339
+ torch.Size([1, 15724]) torch.Size([1, 15724])
340
+ ['a room with a lot of furniture.']
341
+ torch.Size([1, 15724]) torch.Size([1, 15724])
342
+ ['a picture of a room.']
343
+ torch.Size([1, 15724]) torch.Size([1, 15724])
344
+ ['a display of various items.']
345
+ torch.Size([1, 15724]) torch.Size([1, 15724])
346
+ ['a display of a stuffed animal.']
347
+ torch.Size([1, 15724]) torch.Size([1, 15724])
348
+ ['a stuffed toy.']
349
+ torch.Size([1, 15724]) torch.Size([1, 15724])
350
+ ['a large group of luggage.']
351
+ torch.Size([1, 15724]) torch.Size([1, 15724])
352
+ ['a table with a mirror']
353
+ torch.Size([1, 15724]) torch.Size([1, 15724])
354
+ ['a building with a lot of windows']
355
+ torch.Size([1, 15724]) torch.Size([1, 15724])
356
+ ['a small room with a lot of stuff on it']
357
+ torch.Size([1, 15724]) torch.Size([1, 15724])
358
+ ['a large white and red chair.']
359
+ torch.Size([1, 15724]) torch.Size([1, 15724])
360
+ ['a large wooden bench.']
361
+ torch.Size([1, 15724]) torch.Size([1, 15724])
362
+ ['a large building with a lot of windows.']
363
+ torch.Size([1, 15724]) torch.Size([1, 15724])
364
+ ['a small room with a lot of furniture.']
365
+ torch.Size([1, 15724]) torch.Size([1, 15724])
366
+ ['a room with a lot of furniture.']
367
+ torch.Size([1, 15724]) torch.Size([1, 15724])
368
+ ['a room with a lot of furniture.']
369
+ torch.Size([1, 15724]) torch.Size([1, 15724])
370
+ ['a planter with a plant']
371
+ torch.Size([18, 3, 256, 256])
372
+ torch.Size([1, 15724]) torch.Size([1, 15724])
373
+ ['a wooden bench with a plant on it.']
374
+ torch.Size([1, 15724]) torch.Size([1, 15724])
375
+ ['a red and white striped chair']
376
+ torch.Size([1, 15724]) torch.Size([1, 15724])
377
+ ['a large window with a view of a building.']
378
+ torch.Size([1, 15724]) torch.Size([1, 15724])
379
+ ['a man standing in front of a building.']
380
+ torch.Size([1, 15724]) torch.Size([1, 15724])
381
+ ['a display of items for sale.']
382
+ torch.Size([1, 15724]) torch.Size([1, 15724])
383
+ ['a motorcycle is parked on the side of the road.']
384
+ torch.Size([1, 15724]) torch.Size([1, 15724])
385
+ ['a room with a bed and a table']
386
+ torch.Size([1, 15724]) torch.Size([1, 15724])
387
+ ['a large building with a lot of windows.']
388
+ torch.Size([1, 15724]) torch.Size([1, 15724])
389
+ ['a small room with a lot of furniture.']
390
+ torch.Size([1, 15724]) torch.Size([1, 15724])
391
+ ['a building with a lot of windows']
392
+ torch.Size([1, 15724]) torch.Size([1, 15724])
393
+ ['a small room with a lot of furniture.']
394
+ torch.Size([1, 15724]) torch.Size([1, 15724])
395
+ ['a woman standing in front of a chair.']
396
+ torch.Size([1, 15724]) torch.Size([1, 15724])
397
+ ['a large wooden bench.']
398
+ torch.Size([1, 15724]) torch.Size([1, 15724])
399
+ ['a building with a lot of windows.']
400
+ torch.Size([1, 15724]) torch.Size([1, 15724])
401
+ ['a small room with a lot of furniture.']
402
+ torch.Size([1, 15724]) torch.Size([1, 15724])
403
+ ['a room with a lot of furniture.']
404
+ torch.Size([1, 15724]) torch.Size([1, 15724])
405
+ ['a large room with a lot of furniture.']
406
+ torch.Size([1, 15724]) torch.Size([1, 15724])
407
+ ['a plant with a flower in it.']
408
+ torch.Size([18, 3, 256, 256])
409
+ torch.Size([18, 10, 3, 256, 256])
410
+ saved final_subj01_pretrained_20sess_24bs outputs!
411
+ device: cuda
412
+ final_subj01_pretrained_20sess_24bs
413
+ torch.Size([18, 3, 425, 425]) torch.Size([18, 10, 3, 768, 768]) torch.Size([18, 10, 256, 1664]) torch.Size([18, 10, 3, 768, 768]) (18, 10)
414
+ Initialized embedder #0: FrozenCLIPEmbedder with 123060480 params. Trainable: False
415
+ Initialized embedder #1: FrozenOpenCLIPEmbedder2 with 694659841 params. Trainable: False
416
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
417
+ Initialized embedder #3: ConcatTimestepEmbedderND with 0 params. Trainable: False
418
+ Initialized embedder #4: ConcatTimestepEmbedderND with 0 params. Trainable: False
419
+ Restored from /weka/proj-medarc/shared/mindeyev2_dataset/zavychromaxl_v30.safetensors with 1 missing and 1 unexpected keys
420
+ Missing Keys: ['denoiser.sigmas']
421
+ Unexpected Keys: ['conditioner.embedders.0.transformer.text_model.embeddings.position_ids']
422
+ crossattn torch.Size([1, 77, 2048])
423
+ vector_suffix torch.Size([1, 1536])
424
+ ---
425
+ crossattn_uc torch.Size([1, 77, 2048])
426
+ vector_uc torch.Size([1, 2816])
427
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
428
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
429
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
430
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
431
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
432
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
433
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
434
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
435
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
436
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
437
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
438
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
439
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
440
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
441
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
442
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
443
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
444
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
445
+ final_enhancedrecons torch.Size([18, 10, 3, 256, 256])
446
+ saved evals/final_subj01_pretrained_20sess_24bs/final_subj01_pretrained_20sess_24bs_all_enhancedrecons_imagery.pt
447
+ device: cuda
448
+ torch.Size([18, 1, 15724]) torch.Size([18, 3, 425, 425])
449
+ torch.Size([18, 1, 15724])
450
+ param counts:
451
+ 83,653,863 total
452
+ 0 trainable
453
+ param counts:
454
+ 64,409,600 total
455
+ 64,409,600 trainable
456
+ param counts:
457
+ 1,903,020,028 total
458
+ 1,903,020,028 trainable
459
+ param counts:
460
+ 1,967,429,628 total
461
+ 1,967,429,628 trainable
462
+ param counts:
463
+ 259,865,216 total
464
+ 259,865,200 trainable
465
+ param counts:
466
+ 2,227,294,844 total
467
+ 2,227,294,828 trainable
468
+
469
+ ---loading /weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_20sess_24bs/last.pth ckpt---
470
+
471
+ [2024-11-07 04:05:42,120] [INFO] [real_accelerator.py:191:get_accelerator] Setting ds_accelerator to cuda (auto detect)
472
+ Processing zero checkpoint '/weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_20sess_24bs/last'
473
+ Detected checkpoint of type zero stage ZeroStageEnum.gradients, world_size: 8
474
+ Parsing checkpoint created by deepspeed==0.12.2
475
+ Reconstructed Frozen fp32 state dict with 1 params 16 elements
476
+ Reconstructed fp32 state dict with 230 params 2227294828 elements
477
+ ckpt loaded!
478
+ Initialized embedder #0: FrozenOpenCLIPImageEmbedder with 1909889025 params. Trainable: False
479
+ Initialized embedder #1: ConcatTimestepEmbedderND with 0 params. Trainable: False
480
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
481
+ vector_suffix torch.Size([1, 1024])
482
+ torch.Size([1, 15724]) torch.Size([1, 15724])
483
+ ['a bed and a bed']
484
+ torch.Size([1, 15724]) torch.Size([1, 15724])
485
+ ['a red and white building']
486
+ torch.Size([1, 15724]) torch.Size([1, 15724])
487
+ ['a street with a street light and a street sign.']
488
+ torch.Size([1, 15724]) torch.Size([1, 15724])
489
+ ['a red and white building']
490
+ torch.Size([1, 15724]) torch.Size([1, 15724])
491
+ ['a large building with a lot of windows.']
492
+ torch.Size([1, 15724]) torch.Size([1, 15724])
493
+ ['a man standing next to a building.']
494
+ torch.Size([1, 15724]) torch.Size([1, 15724])
495
+ ['a surfer is riding a wave.']
496
+ torch.Size([1, 15724]) torch.Size([1, 15724])
497
+ ['a beach with a bunch of people on it']
498
+ torch.Size([1, 15724]) torch.Size([1, 15724])
499
+ ['a large tree']
500
+ torch.Size([1, 15724]) torch.Size([1, 15724])
501
+ ['a street with a lot of traffic.']
502
+ torch.Size([1, 15724]) torch.Size([1, 15724])
503
+ ['a table with a bunch of food on it']
504
+ torch.Size([1, 15724]) torch.Size([1, 15724])
505
+ ['a group of people sitting down.']
506
+ torch.Size([1, 15724]) torch.Size([1, 15724])
507
+ ['a man standing on top of a surfboard.']
508
+ torch.Size([1, 15724]) torch.Size([1, 15724])
509
+ ['a zebra standing in a field.']
510
+ torch.Size([1, 15724]) torch.Size([1, 15724])
511
+ ['a group of trees']
512
+ torch.Size([1, 15724]) torch.Size([1, 15724])
513
+ ['a person is standing in front of a car.']
514
+ torch.Size([1, 15724]) torch.Size([1, 15724])
515
+ ['a table with a bunch of food on it']
516
+ torch.Size([1, 15724]) torch.Size([1, 15724])
517
+ ['a plate of food on a table.']
518
+ torch.Size([18, 3, 256, 256])
519
+ torch.Size([1, 15724]) torch.Size([1, 15724])
520
+ ['a bed and a bed']
521
+ torch.Size([1, 15724]) torch.Size([1, 15724])
522
+ ['a man standing next to a car.']
523
+ torch.Size([1, 15724]) torch.Size([1, 15724])
524
+ ['a street with a traffic light and a street sign.']
525
+ torch.Size([1, 15724]) torch.Size([1, 15724])
526
+ ['a small building with a lot of windows.']
527
+ torch.Size([1, 15724]) torch.Size([1, 15724])
528
+ ['a large white and black boat.']
529
+ torch.Size([1, 15724]) torch.Size([1, 15724])
530
+ ['a man standing on a bench next to a building.']
531
+ torch.Size([1, 15724]) torch.Size([1, 15724])
532
+ ['a surfer is riding a wave.']
533
+ torch.Size([1, 15724]) torch.Size([1, 15724])
534
+ ['a beach with a bunch of people on it']
535
+ torch.Size([1, 15724]) torch.Size([1, 15724])
536
+ ['a large brown tree.']
537
+ torch.Size([1, 15724]) torch.Size([1, 15724])
538
+ ['a street with a lot of traffic.']
539
+ torch.Size([1, 15724]) torch.Size([1, 15724])
540
+ ['a table with a bunch of food on it']
541
+ torch.Size([1, 15724]) torch.Size([1, 15724])
542
+ ['a group of people standing around each other.']
543
+ torch.Size([1, 15724]) torch.Size([1, 15724])
544
+ ['a man standing on a beach next to a surfboard.']
545
+ torch.Size([1, 15724]) torch.Size([1, 15724])
546
+ ['a zebra standing in a field.']
547
+ torch.Size([1, 15724]) torch.Size([1, 15724])
548
+ ['a group of animals standing around.']
549
+ torch.Size([1, 15724]) torch.Size([1, 15724])
550
+ ['a man is sitting on a chair.']
551
+ torch.Size([1, 15724]) torch.Size([1, 15724])
552
+ ['a table with a bunch of food on it']
553
+ torch.Size([1, 15724]) torch.Size([1, 15724])
554
+ ['a table with a plate of food on it']
555
+ torch.Size([18, 3, 256, 256])
556
+ torch.Size([1, 15724]) torch.Size([1, 15724])
557
+ ['a bed and a bed']
558
+ torch.Size([1, 15724]) torch.Size([1, 15724])
559
+ ['a man riding a bike on top of a surfboard.']
560
+ torch.Size([1, 15724]) torch.Size([1, 15724])
561
+ ['a street with a street light and a street sign.']
562
+ torch.Size([1, 15724]) torch.Size([1, 15724])
563
+ ['a red and white skateboard']
564
+ torch.Size([1, 15724]) torch.Size([1, 15724])
565
+ ['a large display of animals.']
566
+ torch.Size([1, 15724]) torch.Size([1, 15724])
567
+ ['a man standing next to a building.']
568
+ torch.Size([1, 15724]) torch.Size([1, 15724])
569
+ ['a surfer is riding a wave.']
570
+ torch.Size([1, 15724]) torch.Size([1, 15724])
571
+ ['a beach with a lot of people on it.']
572
+ torch.Size([1, 15724]) torch.Size([1, 15724])
573
+ ['a large tree']
574
+ torch.Size([1, 15724]) torch.Size([1, 15724])
575
+ ['a street with a lot of traffic.']
576
+ torch.Size([1, 15724]) torch.Size([1, 15724])
577
+ ['a table with a bunch of food on it']
578
+ torch.Size([1, 15724]) torch.Size([1, 15724])
579
+ ['a group of people sitting down.']
580
+ torch.Size([1, 15724]) torch.Size([1, 15724])
581
+ ['a man standing on top of a surfboard.']
582
+ torch.Size([1, 15724]) torch.Size([1, 15724])
583
+ ['a zebra standing in a field.']
584
+ torch.Size([1, 15724]) torch.Size([1, 15724])
585
+ ['a group of trees']
586
+ torch.Size([1, 15724]) torch.Size([1, 15724])
587
+ ['a person is sitting down.']
588
+ torch.Size([1, 15724]) torch.Size([1, 15724])
589
+ ['a table with a bunch of food on it']
590
+ torch.Size([1, 15724]) torch.Size([1, 15724])
591
+ ['a plate with food on it']
592
+ torch.Size([18, 3, 256, 256])
593
+ torch.Size([1, 15724]) torch.Size([1, 15724])
594
+ ['a large bed with a table cloth.']
595
+ torch.Size([1, 15724]) torch.Size([1, 15724])
596
+ ['a red and white car']
597
+ torch.Size([1, 15724]) torch.Size([1, 15724])
598
+ ['a street with a street light and a street sign.']
599
+ torch.Size([1, 15724]) torch.Size([1, 15724])
600
+ ['a small building with a large window.']
601
+ torch.Size([1, 15724]) torch.Size([1, 15724])
602
+ ['a large water fountain.']
603
+ torch.Size([1, 15724]) torch.Size([1, 15724])
604
+ ['a man standing on a sidewalk next to a building.']
605
+ torch.Size([1, 15724]) torch.Size([1, 15724])
606
+ ['a surfer riding a wave on a surfboard.']
607
+ torch.Size([1, 15724]) torch.Size([1, 15724])
608
+ ['a beach with a bunch of people on it']
609
+ torch.Size([1, 15724]) torch.Size([1, 15724])
610
+ ['a large tree.']
611
+ torch.Size([1, 15724]) torch.Size([1, 15724])
612
+ ['a street with a lot of traffic.']
613
+ torch.Size([1, 15724]) torch.Size([1, 15724])
614
+ ['a table with a bunch of food on it']
615
+ torch.Size([1, 15724]) torch.Size([1, 15724])
616
+ ['a couple of people standing around each other.']
617
+ torch.Size([1, 15724]) torch.Size([1, 15724])
618
+ ['a man standing on top of a surfboard.']
619
+ torch.Size([1, 15724]) torch.Size([1, 15724])
620
+ ['a zebra standing in a field.']
621
+ torch.Size([1, 15724]) torch.Size([1, 15724])
622
+ ['a group of trees']
623
+ torch.Size([1, 15724]) torch.Size([1, 15724])
624
+ ['a man is standing next to a motorcycle.']
625
+ torch.Size([1, 15724]) torch.Size([1, 15724])
626
+ ['a table filled with lots of food.']
627
+ torch.Size([1, 15724]) torch.Size([1, 15724])
628
+ ['a plate of food on a table.']
629
+ torch.Size([18, 3, 256, 256])
630
+ torch.Size([1, 15724]) torch.Size([1, 15724])
631
+ ['a bed with a white sheet and a blue sheet and a white sheet and a brown blanket.']
632
+ torch.Size([1, 15724]) torch.Size([1, 15724])
633
+ ['a motorcycle is parked on the side of the road.']
634
+ torch.Size([1, 15724]) torch.Size([1, 15724])
635
+ ['a street with a street light and a street sign.']
636
+ torch.Size([1, 15724]) torch.Size([1, 15724])
637
+ ['a small area with a lot of stuff on it.']
638
+ torch.Size([1, 15724]) torch.Size([1, 15724])
639
+ ['a large statue of a person.']
640
+ torch.Size([1, 15724]) torch.Size([1, 15724])
641
+ ['a man standing on a bench.']
642
+ torch.Size([1, 15724]) torch.Size([1, 15724])
643
+ ['a surfer is riding a wave.']
644
+ torch.Size([1, 15724]) torch.Size([1, 15724])
645
+ ['a beach with a lot of people on it.']
646
+ torch.Size([1, 15724]) torch.Size([1, 15724])
647
+ ['a large tree']
648
+ torch.Size([1, 15724]) torch.Size([1, 15724])
649
+ ['a street with a lot of traffic.']
650
+ torch.Size([1, 15724]) torch.Size([1, 15724])
651
+ ['a plate of food on a table.']
652
+ torch.Size([1, 15724]) torch.Size([1, 15724])
653
+ ['a stuffed toy bear.']
654
+ torch.Size([1, 15724]) torch.Size([1, 15724])
655
+ ['a man standing on a beach next to a surfboard.']
656
+ torch.Size([1, 15724]) torch.Size([1, 15724])
657
+ ['a zebra standing in a field.']
658
+ torch.Size([1, 15724]) torch.Size([1, 15724])
659
+ ['a group of animals standing on top of a grass covered field.']
660
+ torch.Size([1, 15724]) torch.Size([1, 15724])
661
+ ['a motor bike is parked on the side of the road.']
662
+ torch.Size([1, 15724]) torch.Size([1, 15724])
663
+ ['a table with a bunch of food on it']
664
+ torch.Size([1, 15724]) torch.Size([1, 15724])
665
+ ['a plate with food on it']
666
+ torch.Size([18, 3, 256, 256])
667
+ torch.Size([1, 15724]) torch.Size([1, 15724])
668
+ ['a bed and a bed']
669
+ torch.Size([1, 15724]) torch.Size([1, 15724])
670
+ ['a red and white motorcycle']
671
+ torch.Size([1, 15724]) torch.Size([1, 15724])
672
+ ['a street sign and a street sign']
673
+ torch.Size([1, 15724]) torch.Size([1, 15724])
674
+ ['a red and white car']
675
+ torch.Size([1, 15724]) torch.Size([1, 15724])
676
+ ['a large display of animals.']
677
+ torch.Size([1, 15724]) torch.Size([1, 15724])
678
+ ['a man sitting on a bench next to a bench.']
679
+ torch.Size([1, 15724]) torch.Size([1, 15724])
680
+ ['a surfer riding a wave.']
681
+ torch.Size([1, 15724]) torch.Size([1, 15724])
682
+ ['a beach with a lot of people on it.']
683
+ torch.Size([1, 15724]) torch.Size([1, 15724])
684
+ ['a large tree.']
685
+ torch.Size([1, 15724]) torch.Size([1, 15724])
686
+ ['a street with a lot of traffic.']
687
+ torch.Size([1, 15724]) torch.Size([1, 15724])
688
+ ['a table with a bunch of food on it']
689
+ torch.Size([1, 15724]) torch.Size([1, 15724])
690
+ ['a group of people sitting down.']
691
+ torch.Size([1, 15724]) torch.Size([1, 15724])
692
+ ['a man standing on top of a surfboard.']
693
+ torch.Size([1, 15724]) torch.Size([1, 15724])
694
+ ['a zebra standing in a field.']
695
+ torch.Size([1, 15724]) torch.Size([1, 15724])
696
+ ['a group of trees']
697
+ torch.Size([1, 15724]) torch.Size([1, 15724])
698
+ ['a red and white motorcycle']
699
+ torch.Size([1, 15724]) torch.Size([1, 15724])
700
+ ['a table with a bunch of food on it']
701
+ torch.Size([1, 15724]) torch.Size([1, 15724])
702
+ ['a table with a plate of food on it']
703
+ torch.Size([18, 3, 256, 256])
704
+ torch.Size([1, 15724]) torch.Size([1, 15724])
705
+ ['a bed and a bed']
706
+ torch.Size([1, 15724]) torch.Size([1, 15724])
707
+ ['a man riding a bike down a street.']
708
+ torch.Size([1, 15724]) torch.Size([1, 15724])
709
+ ['a street with a street light and a street sign.']
710
+ torch.Size([1, 15724]) torch.Size([1, 15724])
711
+ ['a small building with a lot of windows.']
712
+ torch.Size([1, 15724]) torch.Size([1, 15724])
713
+ ['a large tree with a few leaves.']
714
+ torch.Size([1, 15724]) torch.Size([1, 15724])
715
+ ['a man standing next to a bench.']
716
+ torch.Size([1, 15724]) torch.Size([1, 15724])
717
+ ['a surfer riding a wave.']
718
+ torch.Size([1, 15724]) torch.Size([1, 15724])
719
+ ['a beach with a bunch of people on it']
720
+ torch.Size([1, 15724]) torch.Size([1, 15724])
721
+ ['a large tree.']
722
+ torch.Size([1, 15724]) torch.Size([1, 15724])
723
+ ['a street with a lot of traffic.']
724
+ torch.Size([1, 15724]) torch.Size([1, 15724])
725
+ ['a table with a bunch of food on it']
726
+ torch.Size([1, 15724]) torch.Size([1, 15724])
727
+ ['a group of people standing around each other.']
728
+ torch.Size([1, 15724]) torch.Size([1, 15724])
729
+ ['a man standing on top of a surfboard.']
730
+ torch.Size([1, 15724]) torch.Size([1, 15724])
731
+ ['a zebra standing in a field.']
732
+ torch.Size([1, 15724]) torch.Size([1, 15724])
733
+ ['a group of trees']
734
+ torch.Size([1, 15724]) torch.Size([1, 15724])
735
+ ['a red and white striped chair']
736
+ torch.Size([1, 15724]) torch.Size([1, 15724])
737
+ ['a table with a bunch of food on it']
738
+ torch.Size([1, 15724]) torch.Size([1, 15724])
739
+ ['a plate with food on it']
740
+ torch.Size([18, 3, 256, 256])
741
+ torch.Size([1, 15724]) torch.Size([1, 15724])
742
+ ['a room with a bed and a table']
743
+ torch.Size([1, 15724]) torch.Size([1, 15724])
744
+ ['a red and white car']
745
+ torch.Size([1, 15724]) torch.Size([1, 15724])
746
+ ['a street with a street sign and a street sign.']
747
+ torch.Size([1, 15724]) torch.Size([1, 15724])
748
+ ['a red and white sign']
749
+ torch.Size([1, 15724]) torch.Size([1, 15724])
750
+ ['a large statue of a bird.']
751
+ torch.Size([1, 15724]) torch.Size([1, 15724])
752
+ ['a couple of people standing on a bench.']
753
+ torch.Size([1, 15724]) torch.Size([1, 15724])
754
+ ['a surfer is riding a wave.']
755
+ torch.Size([1, 15724]) torch.Size([1, 15724])
756
+ ['a beach with a beach and a beach with a few people.']
757
+ torch.Size([1, 15724]) torch.Size([1, 15724])
758
+ ['a large tree.']
759
+ torch.Size([1, 15724]) torch.Size([1, 15724])
760
+ ['a street with a lot of traffic.']
761
+ torch.Size([1, 15724]) torch.Size([1, 15724])
762
+ ['a table with a bunch of food on it']
763
+ torch.Size([1, 15724]) torch.Size([1, 15724])
764
+ ['a group of people sitting down.']
765
+ torch.Size([1, 15724]) torch.Size([1, 15724])
766
+ ['a man standing on a beach next to a surfboard.']
767
+ torch.Size([1, 15724]) torch.Size([1, 15724])
768
+ ['a zebra standing in a field.']
769
+ torch.Size([1, 15724]) torch.Size([1, 15724])
770
+ ['a group of animals standing around.']
771
+ torch.Size([1, 15724]) torch.Size([1, 15724])
772
+ ['a piece of luggage sitting on a table.']
773
+ torch.Size([1, 15724]) torch.Size([1, 15724])
774
+ ['a table with a bunch of food on it']
775
+ torch.Size([1, 15724]) torch.Size([1, 15724])
776
+ ['a plate with a bunch of food on it']
777
+ torch.Size([18, 3, 256, 256])
778
+ torch.Size([1, 15724]) torch.Size([1, 15724])
779
+ ['a large white and red table.']
780
+ torch.Size([1, 15724]) torch.Size([1, 15724])
781
+ ['a red and white motorcycle']
782
+ torch.Size([1, 15724]) torch.Size([1, 15724])
783
+ ['a street with a street light and a street sign.']
784
+ torch.Size([1, 15724]) torch.Size([1, 15724])
785
+ ['a red and white striped sign']
786
+ torch.Size([1, 15724]) torch.Size([1, 15724])
787
+ ['a large statue of a person.']
788
+ torch.Size([1, 15724]) torch.Size([1, 15724])
789
+ ['a man standing next to a bench.']
790
+ torch.Size([1, 15724]) torch.Size([1, 15724])
791
+ ['a surfer riding a wave.']
792
+ torch.Size([1, 15724]) torch.Size([1, 15724])
793
+ ['a beach with a bunch of people on it']
794
+ torch.Size([1, 15724]) torch.Size([1, 15724])
795
+ ['a large tree.']
796
+ torch.Size([1, 15724]) torch.Size([1, 15724])
797
+ ['a street with a lot of traffic.']
798
+ torch.Size([1, 15724]) torch.Size([1, 15724])
799
+ ['a table with a plate of food on it']
800
+ torch.Size([1, 15724]) torch.Size([1, 15724])
801
+ ['a display of stuffed animals.']
802
+ torch.Size([1, 15724]) torch.Size([1, 15724])
803
+ ['a man standing on a beach next to a body of water.']
804
+ torch.Size([1, 15724]) torch.Size([1, 15724])
805
+ ['a zebra standing in a field.']
806
+ torch.Size([1, 15724]) torch.Size([1, 15724])
807
+ ['a group of animals standing around.']
808
+ torch.Size([1, 15724]) torch.Size([1, 15724])
809
+ ['a red and white striped chair']
810
+ torch.Size([1, 15724]) torch.Size([1, 15724])
811
+ ['a table with a bunch of food on it']
812
+ torch.Size([1, 15724]) torch.Size([1, 15724])
813
+ ['a plate with food on it']
814
+ torch.Size([18, 3, 256, 256])
815
+ torch.Size([1, 15724]) torch.Size([1, 15724])
816
+ ['a bed with a blanket and a blanket.']
817
+ torch.Size([1, 15724]) torch.Size([1, 15724])
818
+ ['a car is parked on the street.']
819
+ torch.Size([1, 15724]) torch.Size([1, 15724])
820
+ ['a street with a street sign and a pole.']
821
+ torch.Size([1, 15724]) torch.Size([1, 15724])
822
+ ['a skateboard on a sidewalk']
823
+ torch.Size([1, 15724]) torch.Size([1, 15724])
824
+ ['a large building with a lot of windows.']
825
+ torch.Size([1, 15724]) torch.Size([1, 15724])
826
+ ['a man standing on a bench next to a tree.']
827
+ torch.Size([1, 15724]) torch.Size([1, 15724])
828
+ ['a surfer riding a wave.']
829
+ torch.Size([1, 15724]) torch.Size([1, 15724])
830
+ ['a beach with a lot of people on it.']
831
+ torch.Size([1, 15724]) torch.Size([1, 15724])
832
+ ['a large tree.']
833
+ torch.Size([1, 15724]) torch.Size([1, 15724])
834
+ ['a street with a lot of traffic.']
835
+ torch.Size([1, 15724]) torch.Size([1, 15724])
836
+ ['a table with a bunch of food on it']
837
+ torch.Size([1, 15724]) torch.Size([1, 15724])
838
+ ['a group of people standing around each other.']
839
+ torch.Size([1, 15724]) torch.Size([1, 15724])
840
+ ['a man standing on top of a surfboard.']
841
+ torch.Size([1, 15724]) torch.Size([1, 15724])
842
+ ['a zebra standing in a field.']
843
+ torch.Size([1, 15724]) torch.Size([1, 15724])
844
+ ['a group of trees']
845
+ torch.Size([1, 15724]) torch.Size([1, 15724])
846
+ ['a red and white striped chair']
847
+ torch.Size([1, 15724]) torch.Size([1, 15724])
848
+ ['a table with a bunch of food on it']
849
+ torch.Size([1, 15724]) torch.Size([1, 15724])
850
+ ['a plate with food on it']
851
+ torch.Size([18, 3, 256, 256])
852
+ torch.Size([18, 10, 3, 256, 256])
853
+ saved final_subj01_pretrained_20sess_24bs outputs!
854
+ device: cuda
855
+ final_subj01_pretrained_20sess_24bs
856
+ torch.Size([18, 3, 425, 425]) torch.Size([18, 10, 3, 768, 768]) torch.Size([18, 10, 256, 1664]) torch.Size([18, 10, 3, 768, 768]) (18, 10)
857
+ Initialized embedder #0: FrozenCLIPEmbedder with 123060480 params. Trainable: False
858
+ Initialized embedder #1: FrozenOpenCLIPEmbedder2 with 694659841 params. Trainable: False
859
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
860
+ Initialized embedder #3: ConcatTimestepEmbedderND with 0 params. Trainable: False
861
+ Initialized embedder #4: ConcatTimestepEmbedderND with 0 params. Trainable: False
862
+ Restored from /weka/proj-medarc/shared/mindeyev2_dataset/zavychromaxl_v30.safetensors with 1 missing and 1 unexpected keys
863
+ Missing Keys: ['denoiser.sigmas']
864
+ Unexpected Keys: ['conditioner.embedders.0.transformer.text_model.embeddings.position_ids']
865
+ crossattn torch.Size([1, 77, 2048])
866
+ vector_suffix torch.Size([1, 1536])
867
+ ---
868
+ crossattn_uc torch.Size([1, 77, 2048])
869
+ vector_uc torch.Size([1, 2816])
870
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
871
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
872
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
873
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
874
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
875
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
876
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
877
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
878
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
879
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
880
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
881
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
882
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
883
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
884
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
885
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
886
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
887
+ all_enhancedrecons torch.Size([10, 3, 256, 256])
888
+ final_enhancedrecons torch.Size([18, 10, 3, 256, 256])
889
+ saved evals/final_subj01_pretrained_20sess_24bs/final_subj01_pretrained_20sess_24bs_all_enhancedrecons_vision.pt
MindEyeV2/src/slurms/534074.err ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
  0%| | 0/1000 [00:00<?, ?it/s]
 
 
 
 
 
 
 
 
 
1
  0%| | 0/1000 [00:08<?, ?it/s]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [NbConvertApp] Converting notebook enhanced_recon_inference_old.ipynb to python
2
+ [NbConvertApp] Writing 13074 bytes to enhanced_recon_inference_old.py
3
+ [NbConvertApp] Converting notebook recon_inference_old.ipynb to python
4
+ [NbConvertApp] Writing 17064 bytes to recon_inference_old.py
5
+ /admin/home-ckadirt/fmri/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.
6
+ warnings.warn(
7
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 2. Setting context_dim to [1664, 1664] now.
8
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 2. Setting context_dim to [1664, 1664] now.
9
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
10
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
11
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
12
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
13
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
14
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 10. Setting context_dim to [1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664] now.
15
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 2. Setting context_dim to [1664, 1664] now.
16
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 2. Setting context_dim to [1664, 1664] now.
17
+ WARNING:sgm.modules.attention:SpatialTransformer: Found context dims [1664] of depth 1, which does not match the specified 'depth' of 2. Setting context_dim to [1664, 1664] now.
18
+
19
  0%| | 0/1000 [00:00<?, ?it/s]
20
+
21
+
22
+
23
+
24
+ /admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/utils/checkpoint.py:429: UserWarning: torch.utils.checkpoint: please pass in use_reentrant=True or use_reentrant=False explicitly. The default value of use_reentrant will be updated to be False in the future. To maintain current behavior, pass use_reentrant=True. It is recommended that you use use_reentrant=False. Refer to docs for more details on the differences between the two variants.
25
+ warnings.warn(
26
+ /admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/utils/checkpoint.py:61: UserWarning: None of the inputs have requires_grad=True. Gradients will be None
27
+ warnings.warn(
28
+
29
  0%| | 0/1000 [00:08<?, ?it/s]
30
+ Traceback (most recent call last):
31
+ File "/weka/proj-fmri/ckadirt/MindEyeV2/src/recon_inference_old.py", line 446, in <module>
32
+ if plotting:
33
+ ^^^^^^^^
34
+ NameError: name 'plotting' is not defined
35
+ Traceback (most recent call last):
36
+ File "/weka/proj-fmri/ckadirt/MindEyeV2/src/enhanced_recon_inference_old.py", line 100, in <module>
37
+ all_recons = torch.load(f"evals/{model_name}/{model_name}_all_recons.pt") # these are the unrefined MindEye2 recons!
38
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/serialization.py", line 986, in load
40
+ with _open_file_like(f, 'rb') as opened_file:
41
+ ^^^^^^^^^^^^^^^^^^^^^^^^
42
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/serialization.py", line 435, in _open_file_like
43
+ return _open_file(name_or_buffer, mode)
44
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
45
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/serialization.py", line 416, in __init__
46
+ super().__init__(open(name, mode))
47
+ ^^^^^^^^^^^^^^^^
48
+ FileNotFoundError: [Errno 2] No such file or directory: 'evals/final_subj01_pretrained_3sess_24bs/final_subj01_pretrained_3sess_24bs_all_recons.pt'
MindEyeV2/src/slurms/534074.out ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-150-188
2
+ MASTER_PORT=13997
3
+ final_subj01_pretrained_3sess_24bs
4
+ new_sessions
5
+ device: cuda
6
+ num_voxels for subj01: 15724
7
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj01/new_test/0.tar
8
+ Loaded test dl for subj1!
9
+
10
+ 0 3000 3000 1000
11
+ param counts:
12
+ 83,653,863 total
13
+ 0 trainable
14
+ param counts:
15
+ 64,409,600 total
16
+ 64,409,600 trainable
17
+ param counts:
18
+ 1,903,020,028 total
19
+ 1,903,020,028 trainable
20
+ param counts:
21
+ 1,967,429,628 total
22
+ 1,967,429,628 trainable
23
+ param counts:
24
+ 259,865,216 total
25
+ 259,865,200 trainable
26
+ param counts:
27
+ 2,227,294,844 total
28
+ 2,227,294,828 trainable
29
+
30
+ ---loading /weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_3sess_24bs/last.pth ckpt---
31
+
32
+ [2024-11-07 02:45:52,200] [INFO] [real_accelerator.py:191:get_accelerator] Setting ds_accelerator to cuda (auto detect)
33
+ Processing zero checkpoint '/weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_3sess_24bs/last'
34
+ Detected checkpoint of type zero stage ZeroStageEnum.gradients, world_size: 8
35
+ Parsing checkpoint created by deepspeed==0.12.2
36
+ Reconstructed Frozen fp32 state dict with 1 params 16 elements
37
+ Reconstructed fp32 state dict with 230 params 2227294828 elements
38
+ ckpt loaded!
39
+ Initialized embedder #0: FrozenOpenCLIPImageEmbedder with 1909889025 params. Trainable: False
40
+ Initialized embedder #1: ConcatTimestepEmbedderND with 0 params. Trainable: False
41
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
42
+ vector_suffix torch.Size([1, 1024])
43
+ ['a group of people sitting around a table.']
44
+ device: cuda
MindEyeV2/src/slurms/534079.err ADDED
The diff for this file is too large to render. See raw diff
 
MindEyeV2/src/slurms/534079.out ADDED
@@ -0,0 +1,1062 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-150-188
2
+ MASTER_PORT=17419
3
+ final_subj01_pretrained_3sess_24bs
4
+ new_sessions
5
+ device: cuda
6
+ num_voxels for subj01: 15724
7
+ /weka/proj-medarc/shared/mindeyev2_dataset/wds/subj01/new_test/0.tar
8
+ Loaded test dl for subj1!
9
+
10
+ 0 3000 3000 1000
11
+ param counts:
12
+ 83,653,863 total
13
+ 0 trainable
14
+ param counts:
15
+ 64,409,600 total
16
+ 64,409,600 trainable
17
+ param counts:
18
+ 1,903,020,028 total
19
+ 1,903,020,028 trainable
20
+ param counts:
21
+ 1,967,429,628 total
22
+ 1,967,429,628 trainable
23
+ param counts:
24
+ 259,865,216 total
25
+ 259,865,200 trainable
26
+ param counts:
27
+ 2,227,294,844 total
28
+ 2,227,294,828 trainable
29
+
30
+ ---loading /weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_3sess_24bs/last.pth ckpt---
31
+
32
+ [2024-11-07 02:53:00,068] [INFO] [real_accelerator.py:191:get_accelerator] Setting ds_accelerator to cuda (auto detect)
33
+ Processing zero checkpoint '/weka/proj-fmri/ckadirt/MindEyeV2/train_logs/final_subj01_pretrained_3sess_24bs/last'
34
+ Detected checkpoint of type zero stage ZeroStageEnum.gradients, world_size: 8
35
+ Parsing checkpoint created by deepspeed==0.12.2
36
+ Reconstructed Frozen fp32 state dict with 1 params 16 elements
37
+ Reconstructed fp32 state dict with 230 params 2227294828 elements
38
+ ckpt loaded!
39
+ Initialized embedder #0: FrozenOpenCLIPImageEmbedder with 1909889025 params. Trainable: False
40
+ Initialized embedder #1: ConcatTimestepEmbedderND with 0 params. Trainable: False
41
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
42
+ vector_suffix torch.Size([1, 1024])
43
+ ['a group of people sitting around a table.']
44
+ ['a man standing in front of a counter.']
45
+ ['a surfer riding a wave.']
46
+ ['a giraffe standing in the grass.']
47
+ ['a city street with a lot of traffic.']
48
+ ['a plate of food']
49
+ ['a piece of paper sitting on a table.']
50
+ ['a man standing on top of a field.']
51
+ ['a cat sitting on top of a wooden bench.']
52
+ ['a surfer riding a wave.']
53
+ ['a plane is parked on the runway.']
54
+ ['a surfer on a surfboard in the ocean.']
55
+ ['a large grassy area.']
56
+ ['a woman sitting in a chair next to a couch.']
57
+ ['a large train on a steel track.']
58
+ ['a room with a lot of furniture.']
59
+ ['a man sitting down in a chair.']
60
+ ['a boat on a body of water.']
61
+ ['a young girl is playing with a frisbee.']
62
+ ['a bathroom with a toilet and sink.']
63
+ ['a child is holding a toy.']
64
+ ['a group of people standing around each other.']
65
+ ['a clock tower with a tower in the background.']
66
+ ['a man and a woman are walking together.']
67
+ ['a large grassy area.']
68
+ ['a man sitting in a chair next to a table.']
69
+ ['a plate of food with a spoon.']
70
+ ['a plane is parked on the runway.']
71
+ ['a couple of birds standing on top of a water.']
72
+ ['a man sitting on a bench next to a wall.']
73
+ ['a plate of food with a bowl of fruit on it.']
74
+ ['a kitchen with a table and chairs.']
75
+ ['a room with a lot of furniture.']
76
+ ['a white bathroom with a toilet and a sink.']
77
+ ['a plate of food with a fork on it.']
78
+ ['a train is driving through a city.']
79
+ ['a bus driving down a street.']
80
+ ['a plate of food']
81
+ ['a man standing on a sidewalk.']
82
+ ['a boat is parked on the water.']
83
+ ['a woman standing on a tennis court.']
84
+ ['a giraffe standing in a field.']
85
+ ['a truck parked next to a truck.']
86
+ ['a large herd of cattle.']
87
+ ['a vase with flowers on it.']
88
+ ['a kite is flying in the sky.']
89
+ ['a plate of food']
90
+ ['a truck is parked on the side of the road.']
91
+ ['a street with a car and a bus.']
92
+ ['a woman standing on a sidewalk.']
93
+ ['a tree with a lot of leaves.']
94
+ ['a man standing on a sidewalk.']
95
+ ['a large group of people standing around a building.']
96
+ ['a plane flying in the sky.']
97
+ ['a car is parked on the side of the road.']
98
+ ['a large building with a clock on it.']
99
+ ['a bicycle parked on the side of a road.']
100
+ ['a large body of water.']
101
+ ['a plate of food']
102
+ ['a baseball player is standing in front of a bat.']
103
+ ['a man standing on a sidewalk next to a building.']
104
+ ['a room with a lot of furniture.']
105
+ ['a man standing on a tennis court.']
106
+ ['a plate of food']
107
+ ['a man standing on a sidewalk.']
108
+ ['a table with food on it']
109
+ ['a surfer riding a wave.']
110
+ ['a man riding a skateboard.']
111
+ ['a group of people standing around each other.']
112
+ ['a zebra standing in the grass.']
113
+ ['a clock tower with a clock on it.']
114
+ ['a surfer riding a wave.']
115
+ ['a giraffe standing next to a tree.']
116
+ ['a plate of food with a fork.']
117
+ ['a large field with a lot of grass and a kite.']
118
+ ['a bus driving down a street.']
119
+ ['a kite flying in the sky over a field.']
120
+ ['a man sitting down next to a table.']
121
+ ['a table with a bunch of food on it']
122
+ ['a plate with food on it']
123
+ ['a small stuffed animal.']
124
+ ['a train is driving down the tracks.']
125
+ ['a giraffe standing next to a tree.']
126
+ ['a large open area with a lot of people walking around.']
127
+ ['a large field with a bunch of animals in it']
128
+ ['a surfer on a surfboard.']
129
+ ['a man standing on a tennis court.']
130
+ ['a large brown and white cat.']
131
+ ['a man standing on a sidewalk.']
132
+ ['a man standing on a skateboard.']
133
+ ['a herd of cattle grazing on a lush green field.']
134
+ ['a room with a lot of furniture.']
135
+ ['a street with a car and a car']
136
+ ['a table with a plate on it']
137
+ ['a clock on a building.']
138
+ ['a plate of food with a spoon.']
139
+ ['a surfer riding a wave.']
140
+ ['a bunch of different types of food.']
141
+ ['a cat laying on a bed next to a wall.']
142
+ ['a kitchen with a lot of counter space.']
143
+ ['a group of people sitting around a table.']
144
+ ['a building with a clock on it.']
145
+ ['a man riding a bike down a street.']
146
+ ['a dog is standing in the grass.']
147
+ ['a skateboarder is riding on a skateboard.']
148
+ ['a bathroom with a toilet and a sink.']
149
+ ['a bird is standing on a piece of wood.']
150
+ ['a large grassy field.']
151
+ ['a man riding a surfboard on top of a wave.']
152
+ ['a vintage car parked in front of a building.']
153
+ ['a large building with a clock on it.']
154
+ ['a skateboarder is standing on a sidewalk.']
155
+ ['a room with a view']
156
+ ['a surfer on a surfboard in the ocean.']
157
+ ['a plate of food']
158
+ ['a plane is parked on the runway.']
159
+ ['a man standing next to a woman.']
160
+ ['a man standing on top of a lush green field.']
161
+ ['a man standing on a sidewalk.']
162
+ ['a plate of food with a fork']
163
+ ['a large jetliner sitting on top of a runway.']
164
+ ['a group of people sitting on top of a building.']
165
+ ['a bathroom with a sink and a mirror.']
166
+ ['a bathroom with a toilet and a sink.']
167
+ ['a man on a skateboard in a park.']
168
+ ['a plate of food with a knife.']
169
+ ['a kitchen with a lot of furniture.']
170
+ ['a room with a table and chairs']
171
+ ['a woman standing on a sidewalk next to a building.']
172
+ ['a small kitchen with a lot of furniture.']
173
+ ['a tree in a field']
174
+ ['a man on a surfboard in the water.']
175
+ ['a table with a bunch of chairs']
176
+ ['a man standing on top of a beach.']
177
+ ['a herd of cattle grazing on a lush green field.']
178
+ ['a man wearing a suit and tie.']
179
+ ['a man and a woman on a sidewalk.']
180
+ ['a boat is parked on the water.']
181
+ ['a giraffe standing in a field.']
182
+ ['a kitchen with a sink and a counter.']
183
+ ['a plate of food.']
184
+ ['a group of animals standing on top of a grass covered field.']
185
+ ['a white and black picture of a room.']
186
+ ['a group of people sitting down.']
187
+ ['a bathroom with a toilet and sink.']
188
+ ['a large building with a clock on it.']
189
+ ['a table with a bunch of items on it']
190
+ ['a field with a few animals in it.']
191
+ ['a plane flying in the sky.']
192
+ ['a tree with a lot of leaves.']
193
+ ['a plane is flying in the air.']
194
+ ['a surfer riding a wave.']
195
+ ['a plate of food with a fork.']
196
+ ['a street with a fire hydrant and a building.']
197
+ ['a skier is skiing down a hill.']
198
+ ['a zebra standing in a field.']
199
+ ['a group of people standing around a field.']
200
+ ['a kitchen with a counter and a sink.']
201
+ ['a man is holding a cell phone.']
202
+ ['a large grassy area.']
203
+ ['a room with a view']
204
+ ['a young child is laying down on a bed.']
205
+ ['a man standing on a tennis court.']
206
+ ['a man riding a bike down a street.']
207
+ ['a bathroom with a toilet and sink.']
208
+ ['a bus driving down a street.']
209
+ ['a bus driving down a street.']
210
+ ['a table with a bunch of chairs']
211
+ ['a man standing on top of a beach next to a surfboard.']
212
+ ['a building with a clock on it.']
213
+ ['a young man playing a game of tennis.']
214
+ ['a street with a lot of cars parked on it.']
215
+ ['a clock on a wall']
216
+ ['a surfer riding a wave.']
217
+ ['a large body of water']
218
+ ['a plane is parked on the runway.']
219
+ ['a plate of food with a bowl of food on it.']
220
+ ['a man is sitting down and looking at the camera.']
221
+ ['a glass vase filled with flowers.']
222
+ ['a man standing on a field.']
223
+ ['a dog on a beach near a body of water.']
224
+ ['a train is parked on the tracks.']
225
+ ['a bathroom with a toilet and sink.']
226
+ ['a skier is skiing down a hill.']
227
+ ['a woman is sitting in a chair.']
228
+ ['a large building with a clock on it.']
229
+ ['a man on a beach with a surfboard.']
230
+ ['a group of animals standing around.']
231
+ ['a man standing next to a wall.']
232
+ ['a large elephant is standing in the grass.']
233
+ ['a bench with a bench']
234
+ ['a large tree.']
235
+ ['a large building with a clock on it.']
236
+ ['a motorcycle parked on the side of a road.']
237
+ ['a cat sitting on a bench.']
238
+ ['a group of people standing around each other.']
239
+ ['a bathroom with a toilet and a sink.']
240
+ ['a bus driving down a street.']
241
+ ['a zebra standing on a dirt field.']
242
+ ['a train is driving down the tracks.']
243
+ ['a group of people standing on top of a beach.']
244
+ ['a group of people standing on top of a field.']
245
+ ['a train is parked on the side of the road.']
246
+ ['a man on a snowboard in the snow.']
247
+ ['a large group of people on a field.']
248
+ ['a plate of food with a bowl of food on it.']
249
+ ['a train driving down a street next to a building.']
250
+ ['a clock tower with a clock on it.']
251
+ ['a clock on a building.']
252
+ ['a group of people standing around each other.']
253
+ ['a clock on a wall']
254
+ ['a train is driving down the tracks.']
255
+ ['a train is driving down the tracks.']
256
+ ['a kitchen with a sink and a counter.']
257
+ ['a room with a table and chairs']
258
+ ['a plane is flying in the sky.']
259
+ ['a bus driving down a street.']
260
+ ['a surfer riding a wave.']
261
+ ['a group of people sitting down.']
262
+ ['a plate of food.']
263
+ ['a man standing next to a woman.']
264
+ ['a clock tower on a building.']
265
+ ['a herd of cattle grazing on a field.']
266
+ ['a woman holding a cell phone.']
267
+ ['a large tree with a few leaves.']
268
+ ['a large body of water.']
269
+ ['a large blue sky.']
270
+ ['a motorcycle parked on the side of a road.']
271
+ ['a zebra standing in the grass.']
272
+ ['a plate of food with a fork.']
273
+ ['a train is driving down the tracks.']
274
+ ['a train is parked on the tracks.']
275
+ ['a small kitchen with a lot of stuff on the counter.']
276
+ ['a man standing next to a building.']
277
+ ['a truck parked on the side of a road.']
278
+ ['a child with a toy.']
279
+ ['a man standing on top of a lush green field.']
280
+ ['a large elephant standing in a field.']
281
+ ['a man standing on a bench.']
282
+ ['a kite is flying in the sky.']
283
+ ['a cat sitting on top of a table.']
284
+ ['a large body of water.']
285
+ ['a large field with a train and a large field with a lot of grass.']
286
+ ['a man riding a skateboard on top of a snow covered slope.']
287
+ ['a man riding a skateboard on top of a sidewalk.']
288
+ ['a plane is parked on the runway.']
289
+ ['a bus driving down a street.']
290
+ ['a plate of food with a fork.']
291
+ ['a tennis player is holding a racket.']
292
+ ['a skateboarder is standing on a sidewalk.']
293
+ ['a group of cows standing on top of a field.']
294
+ ['a small table with a vase on it.']
295
+ ['a man standing on a sidewalk.']
296
+ ['a skateboarder is riding down a hill.']
297
+ ['a dog is standing in front of a wall.']
298
+ ['a kitchen with a counter and a sink.']
299
+ ['a large body of water.']
300
+ ['a person sitting down in a chair.']
301
+ ['a beach with a lot of people and a building.']
302
+ ['a skateboarder is riding on a skateboard.']
303
+ ['a cat sitting on a bench.']
304
+ ['a plate of food is sitting on a table.']
305
+ ['a man riding a surfboard on top of a wave.']
306
+ ['a train is parked on the tracks.']
307
+ ['a man standing on a beach.']
308
+ ['a surfer on a surfboard in the ocean.']
309
+ ['a man standing next to a bus.']
310
+ ['a skateboarder is riding in a skate park.']
311
+ ['a giraffe standing in the grass.']
312
+ ['a vase with flowers and a vase with flowers.']
313
+ ['a man riding a skateboard down a snow covered slope.']
314
+ ['a large grassy area.']
315
+ ['a street sign and a street sign.']
316
+ ['a plate of food with a fork.']
317
+ ['a man standing on a bed.']
318
+ ['a small room with a lot of stuff on it.']
319
+ ['a man and a woman are sitting down.']
320
+ ['a man standing on a beach next to a boat.']
321
+ ['a cat laying on a bed next to a wall.']
322
+ ['a skateboarder is riding on a skateboard.']
323
+ ['a small herd of cattle grazing.']
324
+ ['a building with a clock on it.']
325
+ ['a large body of water.']
326
+ ['a clock tower with a clock on it.']
327
+ ['a giraffe standing next to a tree.']
328
+ ['a person standing on a sidewalk.']
329
+ ['a room with a view']
330
+ ['a man is wearing a suit and tie.']
331
+ ['a train is driving on the tracks.']
332
+ ['a room with a lot of furniture.']
333
+ ['a man standing on top of a tennis court.']
334
+ ['a bird is sitting on a branch.']
335
+ ['a man sitting down next to a table.']
336
+ ['a man sitting down next to a woman.']
337
+ ['a man standing in front of a wall.']
338
+ ['a baseball player standing on a field.']
339
+ ['a man standing on a tennis court.']
340
+ ['a clock on a building.']
341
+ ['a room with a view']
342
+ ['a group of people standing around each other.']
343
+ ['a beach with a dog and a fence.']
344
+ ['a small herd of cattle grazing.']
345
+ ['a man on a skateboard in a park.']
346
+ ['a train is parked on the tracks.']
347
+ ['a bus driving down a street.']
348
+ ['a man standing next to a woman.']
349
+ ['a cat is standing on a table.']
350
+ ['a large field with a fence and a field with a field and a fence.']
351
+ ['a dog sitting on a couch.']
352
+ ['a bathroom with a sink and a mirror.']
353
+ ['a plate of food']
354
+ ['a cat laying on a bed.']
355
+ ['a couple of animals standing on a grass covered field.']
356
+ ['a man standing in a room with a television.']
357
+ ['a large body of water.']
358
+ ['a street with a car and a street with a traffic sign.']
359
+ ['a man sitting on a couch next to a chair.']
360
+ ['a couple of elephants in the water.']
361
+ ['a surfer riding a wave.']
362
+ ['a bunch of different colored items.']
363
+ ['a giraffe standing in a field.']
364
+ ['a car is parked on the side of the road.']
365
+ ['a bathroom with a toilet and sink.']
366
+ ['a large grassy area.']
367
+ ['a cat sitting on a table.']
368
+ ['a group of people standing around a table.']
369
+ ['a man standing on a sidewalk.']
370
+ ['a bird is sitting on a branch.']
371
+ ['a surfer riding a wave.']
372
+ ['a man on a surfboard in the water.']
373
+ ['a large building with a lot of windows.']
374
+ ['a man riding a bike down a street.']
375
+ ['a man riding a horse on top of a field.']
376
+ ['a large bird flying over a large field.']
377
+ ['a large tree']
378
+ ['a plate of food with a bunch of food on it.']
379
+ ['a man standing on top of a building.']
380
+ ['a zebra standing on a dirt field.']
381
+ ['a bathroom with a toilet and sink.']
382
+ ['a man riding a skateboard on top of a sidewalk.']
383
+ ['a group of people sitting around a table.']
384
+ ['a large room with a lot of furniture.']
385
+ ['a man standing on a skateboard next to a skateboard.']
386
+ ['a man standing on a skateboard.']
387
+ ['a bathroom with a sink and mirror.']
388
+ ['a large body of water']
389
+ ['a tree with a lot of leaves.']
390
+ ['a tree in a field']
391
+ ['a kite is flying in the sky.']
392
+ ['a large tree with a few leaves.']
393
+ ['a herd of cattle grazing on a lush green field.']
394
+ ['a room with a lot of furniture.']
395
+ ['a large building with a lot of windows.']
396
+ ['a plane is parked on the runway.']
397
+ ['a street with a lot of buildings.']
398
+ ['a man standing on a beach.']
399
+ ['a giraffe standing next to a tree.']
400
+ ['a cat sitting on a table.']
401
+ ['a dog is standing in the grass.']
402
+ ['a street with a street sign and a street.']
403
+ ['a man and a woman are standing together.']
404
+ ['a cow standing on a grass covered field.']
405
+ ['a plate of food']
406
+ ['a kitchen with a sink and a counter.']
407
+ ['a man sitting down in a chair.']
408
+ ['a couple of elephants standing on top of a dirt field.']
409
+ ['a man standing in front of a wall.']
410
+ ['a plane is parked on the runway.']
411
+ ['a large elephant is standing in the grass.']
412
+ ['a plate of food']
413
+ ['a plate of food with a fork.']
414
+ ['a small pond with a small pond.']
415
+ ['a picture of a building with a clock on it.']
416
+ ['a man standing in a field.']
417
+ ['a man standing on top of a beach.']
418
+ ['a man riding a horse on a lush green field.']
419
+ ['a street with a fire hydrant.']
420
+ ['a man standing on a beach next to a surfboard.']
421
+ ['a man riding a snowboard on top of a snow covered slope.']
422
+ ['a building with a clock on it.']
423
+ ['a bus driving down a street next to a bus.']
424
+ ['a skateboarder is doing a trick.']
425
+ ['a street with a traffic light and a street with a traffic light.']
426
+ ['a large elephant is standing in the grass.']
427
+ ['a surfer is riding a wave.']
428
+ ['a plane is flying in the sky.']
429
+ ['a bathroom with a toilet and a sink.']
430
+ ['a man standing on a beach next to a woman.']
431
+ ['a small bird sitting on top of a table.']
432
+ ['a kitchen with a counter and a sink']
433
+ ['a man riding a bike on a beach.']
434
+ ['a small herd of cattle grazing.']
435
+ ['a bird standing on a branch.']
436
+ ['a room with a table and chairs']
437
+ ['a herd of cattle grazing on a lush green field.']
438
+ ['a truck parked next to a building.']
439
+ ['a bed and a bed']
440
+ ['a desk with a laptop on it']
441
+ ['a street with a car and a street with a traffic light.']
442
+ ['a small animal is standing on a rock.']
443
+ ['a train is parked in front of a building.']
444
+ ['a street sign and a street sign']
445
+ ['a bathroom with a toilet and a sink.']
446
+ ['a couple of animals that are laying down']
447
+ ['a man standing on a field.']
448
+ ['a clock on a building.']
449
+ ['a table with a bunch of food on it']
450
+ ['a truck parked next to a truck.']
451
+ ['a dog is standing on a sidewalk.']
452
+ ['a herd of cattle grazing on a field.']
453
+ ['a bus driving down a street.']
454
+ ['a large grassy area.']
455
+ ['a beach with a bunch of people on it']
456
+ ['a group of animals standing on top of a grass covered field.']
457
+ ['a group of trees with leaves.']
458
+ ['a man is wearing a suit and tie.']
459
+ ['a man holding a cell phone.']
460
+ ['a man sitting on a bench next to a building.']
461
+ ['a plate of food']
462
+ ['a man standing on top of a lush green field.']
463
+ ['a kitchen with a stove and a refrigerator.']
464
+ ['a kitchen with a table and chairs.']
465
+ ['a computer desk with a keyboard and a monitor.']
466
+ ['a plate of food with a knife.']
467
+ ['a skateboarder is standing on a skateboard.']
468
+ ['a man standing in front of a building.']
469
+ ['a surfer on a surfboard in the ocean.']
470
+ ['a skateboarder is standing on a skateboard.']
471
+ ['a bathroom with a toilet and a sink.']
472
+ ['a bathroom with a toilet and sink.']
473
+ ['a room with a lot of furniture.']
474
+ ['a group of animals standing around each other.']
475
+ ['a small bench with a large rock on it.']
476
+ ['a large kite flying in the sky.']
477
+ ['a group of people sitting around a table.']
478
+ ['a white wall and a black and white floor']
479
+ ['a group of animals standing on top of a grass covered field.']
480
+ ['a plate of food with a fork.']
481
+ ['a cat is standing on a tree.']
482
+ ['a plate of food with a fork.']
483
+ ['a baseball player is standing in front of a ball.']
484
+ ['a large building with a lot of windows.']
485
+ ['a kitchen with a sink and a counter.']
486
+ ['a group of people sitting around a table.']
487
+ ['a giraffe standing next to a tree.']
488
+ ['a man standing next to a motorcycle.']
489
+ ['a bathroom with a toilet and a sink.']
490
+ ['a bus driving down a street.']
491
+ ['a desk with a laptop on it.']
492
+ ['a clock tower with a clock on it.']
493
+ ['a room with a view']
494
+ ['a bunch of different types of animals.']
495
+ ['a man riding a surfboard on top of a wave.']
496
+ ['a group of people standing on top of a building.']
497
+ ['a large jetliner sitting on top of a cement.']
498
+ ['a herd of cattle grazing.']
499
+ ['a man on a snowboard in the snow.']
500
+ ['a bathroom with a toilet and a sink.']
501
+ ['a herd of zebra grazing on a field.']
502
+ ['a man standing next to a woman.']
503
+ ['a surfer riding a wave.']
504
+ ['a woman sitting on a couch next to a cell phone.']
505
+ ['a skateboarder is riding on a skateboard.']
506
+ ['a herd of cattle grazing.']
507
+ ['a building with a clock on it.']
508
+ ['a man wearing a suit and tie.']
509
+ ['a large body of water.']
510
+ ['a group of animals standing on top of a grass covered field.']
511
+ ['a tree in a field']
512
+ ['a large body of water.']
513
+ ['a kitchen with a table and chairs.']
514
+ ['a surfer on a surfboard in the ocean.']
515
+ ['a herd of cattle grazing on a lush green field.']
516
+ ['a dog is standing in a room.']
517
+ ['a man sitting in a chair.']
518
+ ['a large elephant standing in a field.']
519
+ ['a small building with a lot of windows.']
520
+ ['a man standing in front of a wall.']
521
+ ['a building with a clock on it.']
522
+ ['a surfer on a surfboard']
523
+ ['a bench with a plant in it.']
524
+ ['a cat sitting on a table.']
525
+ ['a man riding a bike on top of a dirt road.']
526
+ ['a man riding a surfboard on top of a body of water.']
527
+ ['a large brown and white animal.']
528
+ ['a group of people standing around each other.']
529
+ ['a large tree.']
530
+ ['a table with a plate and a plate on it']
531
+ ['a large building with a clock on it.']
532
+ ['a kitchen with a lot of furniture.']
533
+ ['a plate of food.']
534
+ ['a train is parked on the tracks.']
535
+ ['a man standing next to a woman.']
536
+ ['a man standing on a sidewalk.']
537
+ ['a building with a clock on it.']
538
+ ['a herd of cattle grazing on a lush green field.']
539
+ ['a large kite flying in the sky.']
540
+ ['a herd of cattle grazing on a lush green field.']
541
+ ['a man standing in front of a wall.']
542
+ ['a couple of elephants standing in a field.']
543
+ ['a couple of animals standing on top of a grass covered field.']
544
+ ['a skateboarder is standing on a sidewalk.']
545
+ ['a bus driving down a street.']
546
+ ['a close up of a bear']
547
+ ['a giraffe standing in the grass.']
548
+ ['a zebra standing in a field.']
549
+ ['a room with a view']
550
+ ['a man is holding a cell phone.']
551
+ ['a desk with a laptop on it.']
552
+ ['a surfer on a surfboard.']
553
+ ['a train is driving down the street.']
554
+ ['a train is driving down the tracks.']
555
+ ['a bus driving down a street.']
556
+ ['a kitchen with a lot of furniture.']
557
+ ['a man standing on a sidewalk next to a building.']
558
+ ['a table with a bunch of food on it']
559
+ ['a field with a few grass on it.']
560
+ ['a table with a variety of foods.']
561
+ ['a large area of grass.']
562
+ ['a cell phone sitting on top of a table.']
563
+ ['a plate of food']
564
+ ['a herd of cattle grazing on a field.']
565
+ ['a man standing next to a man.']
566
+ ['a group of people standing on top of a grass covered field.']
567
+ ['a woman standing on a sidewalk.']
568
+ ['a group of people standing on top of a lake.']
569
+ ['a surfer is riding a wave.']
570
+ ['a man wearing a hat and holding a cell phone.']
571
+ ['a snow covered hill with a ski slope.']
572
+ ['a man standing next to a child.']
573
+ ['a man on a surfboard in the water.']
574
+ ['a large group of people.']
575
+ ['a large body of water']
576
+ ['a giraffe standing next to a tree.']
577
+ ['a man standing on a sidewalk.']
578
+ ['a large elephant is standing in the grass.']
579
+ ['a plate of food']
580
+ ['a bus driving down a street.']
581
+ ['a desk with a laptop and a monitor.']
582
+ ['a man riding a surfboard on top of a body of water.']
583
+ ['a vase with a plant in it.']
584
+ ['a bird is standing on a branch.']
585
+ ['a baby sitting on a bed.']
586
+ ['a building with a clock on it.']
587
+ ['a large body of water.']
588
+ ['a room with a table and chairs']
589
+ ['a room with a table, chairs, and a lamp.']
590
+ ['a room with a bed and a desk.']
591
+ ["a close up of a person's head"]
592
+ ['a plane is parked on the runway.']
593
+ ['a man is holding a cell phone.']
594
+ ['a herd of cattle grazing on a lush green field.']
595
+ ['a large group of people.']
596
+ ['a cat sitting on a bench.']
597
+ ['a large building with a clock on it.']
598
+ ['a vintage motor cycle parked in a parking lot.']
599
+ ['a cat is sitting on a chair.']
600
+ ['a baseball player is standing on a field.']
601
+ ['a man standing in front of a kite.']
602
+ ['a dog is standing in front of a dog.']
603
+ ['a table with a bunch of food on it']
604
+ ['a man is sitting down.']
605
+ ['a large grassy area.']
606
+ ['a stuffed toy cat and a stuffed toy cat.']
607
+ ['a bus parked on the side of the road.']
608
+ ['a group of zebras standing around.']
609
+ ['a herd of cattle grazing on a field.']
610
+ ['a small herd of animals.']
611
+ ['a bathroom with a toilet and sink.']
612
+ ['a display of items in a room.']
613
+ ['a man standing next to a table.']
614
+ ['a table with a bunch of items on it']
615
+ ['a bathroom with a toilet and a sink.']
616
+ ['a tree in a field']
617
+ ['a woman standing on a sidewalk.']
618
+ ['a large body of water.']
619
+ ['a small dog is walking on the beach.']
620
+ ['a man standing on a field next to a horse.']
621
+ ['a man sitting on a bench next to a bench.']
622
+ ['a plate of food.']
623
+ ['a plane flying in the sky.']
624
+ ['a giraffe standing in a field.']
625
+ ['a person holding a piece of food.']
626
+ ['a man standing next to a building.']
627
+ ['a woman standing in a field.']
628
+ ['a large rock.']
629
+ ['a herd of elephants walking across a river.']
630
+ ['a dog is standing in front of a window.']
631
+ ['a man riding a bike on a sidewalk.']
632
+ ['a large grassy area.']
633
+ ['a kite is flying in the sky.']
634
+ ['a black and white photo of a cow.']
635
+ ['a group of people standing around a field.']
636
+ ['a man riding a bike on top of a sandy beach.']
637
+ ['a man standing on top of a skateboard.']
638
+ ['a couple of cats sitting on top of a table.']
639
+ ['a baby elephant standing next to a baby elephant.']
640
+ ['a child is holding a baby.']
641
+ ['a bunch of different types of food.']
642
+ ['a plate of food']
643
+ ['a bicycle is parked on the side of the road.']
644
+ ['a group of people standing around a fence.']
645
+ ['a large building with a clock on it.']
646
+ ['a man standing on a skateboard next to a skateboard.']
647
+ ['a truck parked on the side of a road.']
648
+ ['a train is parked on the tracks.']
649
+ ['a man is holding a cell phone.']
650
+ ['a giraffe standing next to a tree.']
651
+ ['a surfer on a beach with a surfboard.']
652
+ ['a man sitting on a bench.']
653
+ ['a large bus driving down a street.']
654
+ ['a kite flying over a large body of water.']
655
+ ['a man standing next to a building.']
656
+ ['a group of people standing around each other.']
657
+ ['a cat is sitting on a ledge.']
658
+ ['a man standing next to a woman.']
659
+ ['a small grassy area.']
660
+ ['a bathroom with a toilet and sink.']
661
+ ['a surfer on a surfboard in the ocean.']
662
+ ['a baseball player standing next to a batter.']
663
+ ['a large building with a clock on it.']
664
+ ['a man riding a skateboard down a snow covered slope.']
665
+ ['a street with a car and a car']
666
+ ['a giraffe standing in a field.']
667
+ ['a herd of cattle grazing on a lush green field.']
668
+ ['a field with a few animals']
669
+ ['a surfer is riding a wave.']
670
+ ['a man standing next to a water.']
671
+ ['a bird sitting on a branch.']
672
+ ['a man riding a bike down a street.']
673
+ ['a bed with a pillow and a blanket on it.']
674
+ ['a large group of people.']
675
+ ['a couple of birds sitting on top of a water.']
676
+ ['a large display of items.']
677
+ ['a surfer on a surfboard in the ocean.']
678
+ ['a room with a lot of furniture.']
679
+ ['a surfer is riding a wave.']
680
+ ['a dog on a beach near a beach.']
681
+ ['a dog is standing on a grass covered field.']
682
+ ['a plate of food']
683
+ ['a motorcycle parked on the side of a road.']
684
+ ['a cow standing on a field.']
685
+ ['a boat is parked on the shore of a lake.']
686
+ ['a bathroom with a toilet and a sink.']
687
+ ['a large building with a clock on it.']
688
+ ['a plate of food with a fork.']
689
+ ['a surfer is riding his board on the beach.']
690
+ ['a surfer is riding his surfboard.']
691
+ ['a large building with a lot of windows.']
692
+ ['a surfer riding a wave.']
693
+ ['a young girl is holding a cell phone.']
694
+ ['a man standing on top of a surfboard.']
695
+ ['a dog is sitting on a table.']
696
+ ['a man and a woman are standing on a beach.']
697
+ ['a train is parked in front of a building.']
698
+ ['a plate of food with a fork.']
699
+ ['a table with food on it']
700
+ ['a bathroom with a toilet and a sink.']
701
+ ['a train is parked on the tracks.']
702
+ ['a clock tower with a tower in the background.']
703
+ ['a kitchen with a counter and a sink.']
704
+ ['a man is holding a cell phone.']
705
+ ['a truck parked on the side of a road.']
706
+ ['a group of animals standing together.']
707
+ ['a surfer riding a wave on a surfboard.']
708
+ ['a large building with a lot of windows.']
709
+ ['a large field with a lot of grass and a lot of people on it.']
710
+ ['a picture of a table with a bunch of flowers on it.']
711
+ ['a tennis player is holding a racket.']
712
+ ['a desk with a laptop on it.']
713
+ ['a truck is driving down the street.']
714
+ ['a man riding a skateboard on top of a lake.']
715
+ ['a field with grazing animals.']
716
+ ['a small room with a lot of furniture.']
717
+ ['a bird standing on a rock.']
718
+ ['a group of people standing on top of a grass covered field.']
719
+ ['a desk with a computer and a laptop on it.']
720
+ ['a small dog is standing in the foreground.']
721
+ ['a young woman is holding a small dog.']
722
+ ['a man standing on a sidewalk.']
723
+ ['a cow standing on top of a grass covered field.']
724
+ ['a man walking on a sidewalk.']
725
+ ['a man standing on a beach next to a body of water.']
726
+ ['a man standing on a field.']
727
+ ['a man standing on a field.']
728
+ ['a large building with a lot of windows.']
729
+ ['a man standing on a tennis court.']
730
+ ['a group of people sitting on top of a building.']
731
+ ['a giraffe standing next to a tree.']
732
+ ['a skier is skiing down a hill.']
733
+ ['a desk with a laptop and a monitor']
734
+ ['a large boat on a lake.']
735
+ ['a train driving down a train track.']
736
+ ['a giraffe standing next to a tree.']
737
+ ['a small piece of a wall.']
738
+ ['a couple of animals that are standing in the grass.']
739
+ ['a bathroom with a toilet and sink.']
740
+ ['a building with a clock on it.']
741
+ ['a table with a bunch of items on it']
742
+ ['a table with a laptop on it']
743
+ ['a couple of people standing in front of a building.']
744
+ ['a picture of a tree.']
745
+ ['a white bed and a brown couch.']
746
+ ['a table with a variety of foods on it.']
747
+ ['a tree with a few leaves.']
748
+ ['a herd of sheep grazing on a lush green field.']
749
+ ['a pair of birds in a field.']
750
+ ['a man riding a snowboard down a snow covered slope.']
751
+ ['a man sitting down in a chair.']
752
+ ['a horse is walking in the grass.']
753
+ ['a surfer riding a wave.']
754
+ ['a man standing on top of a building.']
755
+ ['a piece of furniture with a piece of furniture.']
756
+ ['a woman standing on a sidewalk next to a skateboard.']
757
+ ['a zebra standing in a field.']
758
+ ['a plate of food with a fork.']
759
+ ['a young girl is holding a small piece of paper.']
760
+ ['a fruit bowl with a fruit inside.']
761
+ ['a cat is sitting on a car.']
762
+ ['a street with a traffic light and a street sign.']
763
+ ['a city street with a traffic light.']
764
+ ['a person standing on a sidewalk.']
765
+ ['a kitchen with a table and chairs.']
766
+ ['a beach with a bunch of people on it']
767
+ ['a bunch of different types of fruit']
768
+ ['a train is parked on the side of the road.']
769
+ ['a picture of a clock and some flowers']
770
+ ['a room with a table and chairs']
771
+ ['a bathroom with a toilet and a sink.']
772
+ ['a man walking down a street.']
773
+ ['a table with a chair']
774
+ ['a man riding a snowboard down a snow covered slope.']
775
+ ['a man standing on top of a beach.']
776
+ ['a plate of food']
777
+ ['a man standing on a beach next to a surfboard.']
778
+ ['a snowboarder is on a snowy hill.']
779
+ ['a bus driving down a street.']
780
+ ['a bunch of vegetables on a table']
781
+ ['a kitchen with a lot of furniture.']
782
+ ['a bathroom with a toilet and sink.']
783
+ ['a small animal is standing on a grass covered field.']
784
+ ['a street with a street light and a street sign.']
785
+ ['a bathroom with a toilet and a sink.']
786
+ ['a man standing next to a man.']
787
+ ['a cat sitting on a table.']
788
+ ['a clock tower with a tower in the background.']
789
+ ['a group of horses grazing.']
790
+ ['a bus driving down a street.']
791
+ ['a surfer is riding a wave.']
792
+ ['a surfer is riding a wave.']
793
+ ['a plate of food with a fork.']
794
+ ['a man standing next to a woman.']
795
+ ['a bathroom with a toilet and a sink.']
796
+ ['a plane is parked on the runway.']
797
+ ['a baseball player standing on a field.']
798
+ ['a train is parked on the tracks.']
799
+ ['a man is holding a cell phone.']
800
+ ['a bathroom with a toilet and a sink.']
801
+ ['a baseball player is standing on a field.']
802
+ ['a bus driving down a street.']
803
+ ['a plane is parked on the tarmac.']
804
+ ['a herd of cattle grazing on a lush green field.']
805
+ ['a group of people sitting around a table.']
806
+ ['a man on a surfboard in the water.']
807
+ ['a plate of food with a plate of food on it.']
808
+ ['a young child is sitting in a chair.']
809
+ ['a building with a clock on it.']
810
+ ['a truck is parked next to a truck.']
811
+ ['a small room with a lot of furniture.']
812
+ ['a giraffe standing in a field.']
813
+ ['a small grassy field.']
814
+ ['a skateboarder is riding his skateboard.']
815
+ ['a clock on a building.']
816
+ ['a group of animals standing on top of a grass covered field.']
817
+ ['a surfer is riding a wave.']
818
+ ['a couple of bears standing around.']
819
+ ['a baseball player is standing in front of a fence.']
820
+ ['a small grassy area.']
821
+ ['a plate of food with a fork']
822
+ ['a truck is parked on the street.']
823
+ ['a plate of food with a fork.']
824
+ ['a young woman is holding a baby.']
825
+ ['a kitchen with a counter and a microwave.']
826
+ ['a room with a table, chair, and a lamp.']
827
+ ['a vase with flowers and a vase with flowers.']
828
+ ['a man standing on a sidewalk.']
829
+ ['a skateboarder is riding down a hill.']
830
+ ['a surfer riding a wave.']
831
+ ['a bathroom with a sink and a mirror.']
832
+ ['a woman with her back turned.']
833
+ ['a kitchen with a sink and a counter.']
834
+ ['a clock tower with a clock on it.']
835
+ ['a man standing on a field.']
836
+ ['a building with a clock on it.']
837
+ ['a man on a surfboard in the ocean.']
838
+ ['a man on a beach with a surfboard.']
839
+ ['a small room with a lot of furniture.']
840
+ ['a man standing on a tennis court.']
841
+ ['a bathroom with a toilet and a sink.']
842
+ ['a table with plates of food on it']
843
+ ['a plate of food with a fork.']
844
+ ['a couple of cows standing on top of a grass covered field.']
845
+ ['a zebra standing in a field.']
846
+ ['a herd of cattle grazing on a field.']
847
+ ['a table with a bunch of food on it']
848
+ ['a street with a lot of cars parked in it.']
849
+ ['a man standing next to a child.']
850
+ ['a large passenger jet.']
851
+ ['a bus is parked in front of a building.']
852
+ ['a skateboarder is in the foreground.']
853
+ ['a couple of bears standing on top of a grass covered field.']
854
+ ['a giraffe standing on top of a dirt field.']
855
+ ['a train is parked in front of a building.']
856
+ ['a young woman standing next to a child.']
857
+ ['a truck parked on the side of a road.']
858
+ ['a tree with a lot of leaves.']
859
+ ['a man standing next to a woman.']
860
+ ['a man standing on a tennis court.']
861
+ ['a surfer on a surfboard.']
862
+ ['a kitchen with a table and a stove']
863
+ ['a man and a woman are standing together.']
864
+ ['a street scene with a large truck and a large truck.']
865
+ ['a group of people standing around each other.']
866
+ ['a group of trees']
867
+ ['a group of animals that are in the grass.']
868
+ ['a small room with a lot of furniture.']
869
+ ['a man standing on a beach next to a beach.']
870
+ ['a view of a room.']
871
+ ['a large truck is parked on the side of the road.']
872
+ ['a man standing on a skateboard.']
873
+ ['a plate of food on a table.']
874
+ ['a large body of water.']
875
+ ['a man riding a bike down a street next to a road.']
876
+ ['a street light with a street sign and a traffic light.']
877
+ ['a man standing on a sidewalk next to a building.']
878
+ ['a large elephant is standing in the grass.']
879
+ ['a bathroom with a sink and a mirror.']
880
+ ['a cat sitting on a chair.']
881
+ ['a small dog is sitting on a bench.']
882
+ ['a cat sitting on top of a table.']
883
+ ['a herd of cattle grazing on a lush green field.']
884
+ ['a large tree.']
885
+ ['a room with a view']
886
+ ['a surfer is riding a wave.']
887
+ ['a skateboarder is riding on a skateboard.']
888
+ ['a woman standing on a sidewalk.']
889
+ ['a table with a bunch of items on it']
890
+ ['a man standing in front of a building.']
891
+ ['a living room with a couch and a television.']
892
+ ['a man is holding a cell phone.']
893
+ ['a herd of sheep grazing on a lush green hillside.']
894
+ ['a plate of food with a fork.']
895
+ ['a clock tower with a clock on it.']
896
+ ['a plate of food with a bowl of food on it.']
897
+ ['a car parked on the side of a road.']
898
+ ['a room with a view']
899
+ ['a train is driving on the tracks.']
900
+ ['a large jetliner sitting on top of a lush green field.']
901
+ ['a plate of food']
902
+ ['a dog on a beach near a body of water.']
903
+ ['a man standing next to a fence.']
904
+ ['a table with a bunch of chairs']
905
+ ['a surfer on a surfboard in the ocean.']
906
+ ['a desk with a computer on it.']
907
+ ['a small white and blue fire hydrant.']
908
+ ['a surfer on a surfboard in the ocean.']
909
+ ['a plate of food with a fork on it.']
910
+ ['a clock on a building']
911
+ ['a desk with a computer on it']
912
+ ['a man riding a surfboard on top of a body of water.']
913
+ ['a man riding a skateboard on top of a lake.']
914
+ ['a flower arrangement with a vase.']
915
+ ['a tree in a field']
916
+ ['a truck is parked next to a truck.']
917
+ ['a small room with a lot of furniture.']
918
+ ['a small tree']
919
+ ['a man standing next to a fence.']
920
+ ['a man standing on a tennis court.']
921
+ ['a picture of a field.']
922
+ ['a large body of water.']
923
+ ['a group of animals standing on top of a grass covered field.']
924
+ ['a road with a car on it']
925
+ ['a man riding a bike on a sidewalk.']
926
+ ['a kitchen with a stove and a sink.']
927
+ ['a man standing on a field.']
928
+ ['a man standing on a field.']
929
+ ['a room with a lot of furniture.']
930
+ ['a man standing on a sidewalk next to a fence.']
931
+ ['a kitchen with a stove and a microwave.']
932
+ ['a plate of food with a bowl of food on it.']
933
+ ['a cat is standing in a room.']
934
+ ['a man standing next to a woman.']
935
+ ['a train is driving down the tracks.']
936
+ ['a large field with a lot of grass and trees.']
937
+ ['a desk with a laptop and a keyboard']
938
+ ['a large area of trees.']
939
+ ['a vase with flowers and a vase with flowers.']
940
+ ['a giraffe standing in a field.']
941
+ ['a cat sitting on a chair.']
942
+ ['a giraffe standing in the grass.']
943
+ ['a plane is flying in the air.']
944
+ ['a plane is parked on the runway.']
945
+ ['a kitchen with a counter and a refrigerator.']
946
+ ['a surfer riding a wave.']
947
+ ['a dining room with a table and chairs.']
948
+ ['a surfer riding a wave.']
949
+ ['a plate of food with a plate of food on it.']
950
+ ['a surfer on a wave']
951
+ ['a large building with a lot of windows.']
952
+ ['a small herd of sheep grazing.']
953
+ ['a group of elephants.']
954
+ ['a couple of elephants standing on top of a dirt field.']
955
+ ['a plane flying over a blue sky.']
956
+ ['a large grassy field.']
957
+ ['a display of various types of food.']
958
+ ['a group of people sitting around a table.']
959
+ ['a man standing on a field.']
960
+ ['a large field with a few animals in it.']
961
+ ['a kitchen with a counter top.']
962
+ ['a young man is sitting in a car.']
963
+ ['a room with a lot of furniture.']
964
+ ['a man standing in front of a tree.']
965
+ ['a boat on a body of water.']
966
+ ['a train is parked on the tracks.']
967
+ ['a large area with a lot of furniture.']
968
+ ['a bathroom with a sink and a mirror.']
969
+ ['a bus driving down a street next to a bus.']
970
+ ['a herd of zebra grazing on a lush green field.']
971
+ ['a small room with a lot of furniture.']
972
+ ['a plate of food with a fork.']
973
+ ['a man standing next to a building.']
974
+ ['a man standing on a tennis court.']
975
+ ['a truck parked on the side of a road.']
976
+ ['a young man is holding a camera.']
977
+ ['a surfer on a surfboard in the ocean.']
978
+ ['a man standing on a beach.']
979
+ ['a boat on a body of water.']
980
+ ['a tree in a field']
981
+ ['a table with a vase and a vase on it.']
982
+ ['a table with some food on it']
983
+ ['a bed with a pillow and a blanket']
984
+ ['a group of people standing around a table.']
985
+ ['a zebra standing on a dirt field.']
986
+ ['a large field with a lot of grass and trees.']
987
+ ['a bowl of fruit on a table.']
988
+ ['a bus driving down a street.']
989
+ ['a surfer on a surfboard in the ocean.']
990
+ ['a man standing on a skateboard next to a tree.']
991
+ ['a surfer is riding a wave.']
992
+ ['a large bird standing on top of a rock.']
993
+ ['a man riding a surfboard on top of a wave.']
994
+ ['a table with a bunch of food on it']
995
+ ['a large body of water.']
996
+ ['a room with a lot of furniture.']
997
+ ['a table with a bunch of food on it']
998
+ ['a man standing on a beach.']
999
+ ['a dog is standing in the grass.']
1000
+ ['a herd of cattle grazing on a lush green hillside.']
1001
+ ['a herd of cattle grazing.']
1002
+ ['a surfer is riding a wave.']
1003
+ ['a man standing in front of a wall.']
1004
+ ['a large building with a lot of windows.']
1005
+ ['a group of people standing around a building.']
1006
+ ['a man standing on a sidewalk.']
1007
+ ['a snowboarder is skiing down a hill.']
1008
+ ['a child eating a meal.']
1009
+ ['a man on a surfboard in the water.']
1010
+ ['a man and a woman in a room.']
1011
+ ['a man standing on a sidewalk next to a building.']
1012
+ ['a giraffe standing next to a tree.']
1013
+ ['a bathroom with a toilet and a sink.']
1014
+ ['a large jetliner sitting on top of a lush green field.']
1015
+ ['a baseball player is on the field.']
1016
+ ['a woman is wearing a black and white dress.']
1017
+ ['a small room with a lot of furniture.']
1018
+ ['a zebra standing on a dirt field.']
1019
+ ['a bus driving down a street.']
1020
+ ['a large room with a table and chairs.']
1021
+ ['a large body of water']
1022
+ ['a man walking on a sidewalk.']
1023
+ ['a large animal standing in a field.']
1024
+ ['a plate of food with a plate of food on it.']
1025
+ ['a plane is flying in the air.']
1026
+ ['a man standing on top of a sidewalk.']
1027
+ ['a kitchen with a lot of appliances']
1028
+ ['a large number of windows.']
1029
+ ['a group of people standing around each other.']
1030
+ ['a bus driving down a street.']
1031
+ ['a herd of cattle grazing.']
1032
+ ['a skateboarder is standing in a skate park.']
1033
+ ['a large boat on a lake.']
1034
+ ['a group of people walking down a street.']
1035
+ ['a man standing on a beach next to a tree.']
1036
+ ['a woman holding a cell phone.']
1037
+ ['a dog is standing on a beach.']
1038
+ ['a man standing on top of a surfboard.']
1039
+ ['a train is driving past a train.']
1040
+ ['a giraffe standing in the grass.']
1041
+ ['a bathroom with a toilet and a sink.']
1042
+ ['a room with a bed and a table']
1043
+ torch.Size([1000, 3, 256, 256])
1044
+ saved final_subj01_pretrained_3sess_24bs outputs!
1045
+ device: cuda
1046
+ final_subj01_pretrained_3sess_24bs
1047
+ torch.Size([18, 3, 425, 425]) torch.Size([1000, 3, 768, 768]) torch.Size([1000, 256, 1664]) torch.Size([1000, 3, 768, 768]) (1000,)
1048
+ Initialized embedder #0: FrozenCLIPEmbedder with 123060480 params. Trainable: False
1049
+ Initialized embedder #1: FrozenOpenCLIPEmbedder2 with 694659841 params. Trainable: False
1050
+ Initialized embedder #2: ConcatTimestepEmbedderND with 0 params. Trainable: False
1051
+ Initialized embedder #3: ConcatTimestepEmbedderND with 0 params. Trainable: False
1052
+ Initialized embedder #4: ConcatTimestepEmbedderND with 0 params. Trainable: False
1053
+ Restored from /weka/proj-medarc/shared/mindeyev2_dataset/zavychromaxl_v30.safetensors with 1 missing and 1 unexpected keys
1054
+ Missing Keys: ['denoiser.sigmas']
1055
+ Unexpected Keys: ['conditioner.embedders.0.transformer.text_model.embeddings.position_ids']
1056
+ crossattn torch.Size([1, 77, 2048])
1057
+ vector_suffix torch.Size([1, 1536])
1058
+ ---
1059
+ crossattn_uc torch.Size([1, 77, 2048])
1060
+ vector_uc torch.Size([1, 2816])
1061
+ all_enhancedrecons torch.Size([1000, 3, 256, 256])
1062
+ saved evals/final_subj01_pretrained_3sess_24bs/final_subj01_pretrained_3sess_24bs_all_enhancedrecons.pt
MindEyeV2/src/slurms/544384.err ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [NbConvertApp] Converting notebook TrainB5k.ipynb to python
2
+ [NbConvertApp] Writing 52126 bytes to TrainB5k.py
3
+ File "/weka/proj-fmri/ckadirt/MindEyeV2/src/TrainB5k.py", line 1317
4
+ for i in train_dl
5
+ ^
6
+ SyntaxError: expected ':'
MindEyeV2/src/slurms/544384.out ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-146-13
2
+ MASTER_PORT=11088
3
+ WORLD_SIZE=1
4
+ model_name=augmented_image_one
MindEyeV2/src/slurms/544386.err ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ [NbConvertApp] Converting notebook TrainB5k.ipynb to python
2
+ [NbConvertApp] Writing 52128 bytes to TrainB5k.py
3
+ slurmstepd: error: *** REASON: burst_buffer/lua: Stage-out in progress ***
4
+ slurmstepd: error: *** JOB 544386 ON ip-10-0-130-125 CANCELLED AT 2024-12-06T23:01:13 ***
5
+ slurmstepd: error: *** REASON: burst_buffer/lua: Stage-out in progress ***
MindEyeV2/src/slurms/544386.out ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-130-125
2
+ MASTER_PORT=17288
3
+ WORLD_SIZE=1
4
+ model_name=augmented_image_one
MindEyeV2/src/slurms/544387.err ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ [NbConvertApp] Converting notebook TrainB5k.ipynb to python
2
+ [NbConvertApp] Writing 52128 bytes to TrainB5k.py
3
+ Traceback (most recent call last):
4
+ File "/weka/proj-fmri/ckadirt/MindEyeV2/src/TrainB5k.py", line 819, in <module>
5
+ "train_url": train_url,
6
+ ^^^^^^^^^
7
+ NameError: name 'train_url' is not defined. Did you mean: 'train_dl'?
MindEyeV2/src/slurms/544387.out ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-130-125
2
+ MASTER_PORT=15229
3
+ WORLD_SIZE=1
4
+ model_name=augmented_image_one
5
+ LOCAL RANK 0
6
+ PID of this process = 1825637
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ Training with 15 sessions
20
+ Loaded all subj train dls and betas!
21
+
22
+ Loaded all subj train dls and betas!
23
+
24
+ Loaded test dl for subj1!
25
+
26
+ batch_size = 21 num_iterations_per_epoch = 205 num_samples_per_epoch = 4323
27
+ param counts:
28
+ 712,785,920 total
29
+ 712,785,920 trainable
30
+ param counts:
31
+ 712,785,920 total
32
+ 712,785,920 trainable
33
+ torch.Size([2, 1, 174019]) torch.Size([2, 1, 4096])
34
+ param counts:
35
+ 1,887,861,400 total
36
+ 1,887,861,400 trainable
37
+ param counts:
38
+ 2,600,647,320 total
39
+ 2,600,647,320 trainable
40
+ b.shape torch.Size([2, 1, 4096])
41
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
42
+ param counts:
43
+ 259,865,216 total
44
+ 259,865,200 trainable
45
+ param counts:
46
+ 2,860,512,536 total
47
+ 2,860,512,520 trainable
48
+ total_steps 16400
49
+
50
+ Done with model preparations!
51
+ param counts:
52
+ 2,860,512,536 total
53
+ 2,860,512,520 trainable
54
+ wandb mindeye run augmented_image_one
MindEyeV2/src/slurms/544389.err ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
0
  0%| | 0/80 [00:00<?, ?it/s]
1
  0%| | 0/80 [00:07<?, ?it/s]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [NbConvertApp] Converting notebook TrainB5k.ipynb to python
2
+ [NbConvertApp] Writing 52131 bytes to TrainB5k.py
3
+ wandb: Currently logged in as: ckadirt. Use `wandb login --relogin` to force relogin
4
+ wandb: wandb version 0.19.0 is available! To upgrade, please run:
5
+ wandb: $ pip install wandb --upgrade
6
+ wandb: Tracking run with wandb version 0.17.1
7
+ wandb: Run data is saved locally in /weka/proj-fmri/ckadirt/MindEyeV2/src/wandb/run-20241206_230633-augmented_image_one
8
+ wandb: Run `wandb offline` to turn off syncing.
9
+ wandb: Syncing run augmented_image_one
10
+ wandb: ⭐️ View project at https://stability.wandb.io/ckadirt/mindeye
11
+ wandb: 🚀 View run at https://stability.wandb.io/ckadirt/mindeye/runs/augmented_image_one
12
+
13
  0%| | 0/80 [00:00<?, ?it/s]
14
  0%| | 0/80 [00:07<?, ?it/s]
15
+ Traceback (most recent call last):
16
+ File "/weka/proj-fmri/ckadirt/MindEyeV2/src/TrainB5k.py", line 1048, in <module>
17
+ accelerator.backward(loss)
18
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/accelerate/accelerator.py", line 1987, in backward
19
+ self.scaler.scale(loss).backward(**kwargs)
20
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/_tensor.py", line 492, in backward
21
+ torch.autograd.backward(
22
+ File "/admin/home-ckadirt/fmri/lib/python3.11/site-packages/torch/autograd/__init__.py", line 251, in backward
23
+ Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
24
+ torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 6.50 GiB. GPU 0 has a total capacty of 79.11 GiB of which 1006.94 MiB is free. Including non-PyTorch memory, this process has 78.12 GiB memory in use. Of the allocated memory 61.43 GiB is allocated by PyTorch, and 15.89 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
25
+ wandb: - 0.071 MB of 0.071 MB uploaded
26
+ wandb: ⭐️ View project at: https://stability.wandb.io/ckadirt/mindeye
27
+ wandb: Synced 5 W&B file(s), 0 media file(s), 3 artifact file(s) and 1 other file(s)
28
+ wandb: Find logs at: ./wandb/run-20241206_230633-augmented_image_one/logs
MindEyeV2/src/slurms/544389.out ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-130-125
2
+ MASTER_PORT=11619
3
+ WORLD_SIZE=1
4
+ model_name=augmented_image_one
5
+ LOCAL RANK 0
6
+ PID of this process = 1826787
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ Training with 15 sessions
20
+ Loaded all subj train dls and betas!
21
+
22
+ Loaded all subj train dls and betas!
23
+
24
+ Loaded test dl for subj1!
25
+
26
+ batch_size = 21 num_iterations_per_epoch = 205 num_samples_per_epoch = 4323
27
+ param counts:
28
+ 712,785,920 total
29
+ 712,785,920 trainable
30
+ param counts:
31
+ 712,785,920 total
32
+ 712,785,920 trainable
33
+ torch.Size([2, 1, 174019]) torch.Size([2, 1, 4096])
34
+ param counts:
35
+ 1,887,861,400 total
36
+ 1,887,861,400 trainable
37
+ param counts:
38
+ 2,600,647,320 total
39
+ 2,600,647,320 trainable
40
+ b.shape torch.Size([2, 1, 4096])
41
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
42
+ param counts:
43
+ 259,865,216 total
44
+ 259,865,200 trainable
45
+ param counts:
46
+ 2,860,512,536 total
47
+ 2,860,512,520 trainable
48
+ total_steps 16400
49
+
50
+ Done with model preparations!
51
+ param counts:
52
+ 2,860,512,536 total
53
+ 2,860,512,520 trainable
54
+ wandb mindeye run augmented_image_one
55
+ wandb_config:
56
+ {'model_name': 'augmented_image_one', 'global_batch_size': '21', 'batch_size': 21, 'num_epochs': 80, 'num_sessions': 15, 'num_params': 2860512520, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': True, 'max_lr': 0.0003, 'mixup_pct': 0.33, 'num_samples_per_epoch': 4323, 'num_test': 480, 'ckpt_interval': 999, 'ckpt_saving': False, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1}
57
+ wandb_id: augmented_image_one
58
+ torch.Size([21, 174019]) torch.Size([21, 3, 224, 224]) torch.Size([21]) torch.Size([21])
59
+ augmented_image_one starting with epoch 0 / 80
MindEyeV2/src/slurms/544390.err ADDED
The diff for this file is too large to render. See raw diff
 
MindEyeV2/src/slurms/544492.out ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-172-177
2
+ MASTER_PORT=12285
3
+ WORLD_SIZE=1
4
+ model_name=bold5k_v1
5
+ LOCAL RANK 0
6
+ PID of this process = 1733288
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ Training with 15 sessions
20
+ Loaded all subj train dls and betas!
21
+
22
+ Loaded all subj train dls and betas!
23
+
24
+ Loaded test dl for subj1!
25
+
26
+ batch_size = 21 num_iterations_per_epoch = 205 num_samples_per_epoch = 4323
27
+ param counts:
28
+ 6,905,856 total
29
+ 6,905,856 trainable
30
+ param counts:
31
+ 6,905,856 total
32
+ 6,905,856 trainable
33
+ torch.Size([2, 1, 1685]) torch.Size([2, 1, 4096])
34
+ param counts:
35
+ 1,887,861,400 total
36
+ 1,887,861,400 trainable
37
+ param counts:
38
+ 1,894,767,256 total
39
+ 1,894,767,256 trainable
40
+ b.shape torch.Size([2, 1, 4096])
41
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
42
+ param counts:
43
+ 259,865,216 total
44
+ 259,865,200 trainable
45
+ param counts:
46
+ 2,154,632,472 total
47
+ 2,154,632,456 trainable
48
+ total_steps 16400
49
+
50
+ Done with model preparations!
51
+ param counts:
52
+ 2,154,632,472 total
53
+ 2,154,632,456 trainable
54
+ wandb mindeye run bold5k_v1
55
+ wandb_config:
56
+ {'model_name': 'bold5k_v1', 'global_batch_size': '21', 'batch_size': 21, 'num_epochs': 80, 'num_sessions': 15, 'num_params': 2154632456, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': True, 'max_lr': 0.0003, 'mixup_pct': 0.33, 'num_samples_per_epoch': 4323, 'num_test': 480, 'ckpt_interval': 999, 'ckpt_saving': False, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1}
57
+ wandb_id: bold5k_v1
58
+ torch.Size([21, 1685]) torch.Size([21, 3, 224, 224]) torch.Size([21]) torch.Size([21])
59
+ bold5k_v1 starting with epoch 0 / 80
60
+
61
+ ===Finished!===
62
+
MindEyeV2/src/slurms/545089.out ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-133-32
2
+ MASTER_PORT=12592
3
+ WORLD_SIZE=1
4
+ model_name=bold5k_nsdm1
5
+ LOCAL RANK 0
6
+ PID of this process = 840677
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
MindEyeV2/src/slurms/545090.err ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
0
  0%| | 0/80 [00:00<?, ?it/s]slurmstepd: error: *** REASON: burst_buffer/lua: Stage-out in progress ***
 
 
 
1
+ [NbConvertApp] Converting notebook TrainB5k.ipynb to python
2
+ [NbConvertApp] Writing 52203 bytes to TrainB5k.py
3
+ wandb: Currently logged in as: ckadirt. Use `wandb login --relogin` to force relogin
4
+ wandb: wandb version 0.19.0 is available! To upgrade, please run:
5
+ wandb: $ pip install wandb --upgrade
6
+ wandb: Tracking run with wandb version 0.17.1
7
+ wandb: Run data is saved locally in /weka/proj-fmri/ckadirt/MindEyeV2/src/wandb/run-20241210_215527-bold5k_nsdm1
8
+ wandb: Run `wandb offline` to turn off syncing.
9
+ wandb: Syncing run bold5k_nsdm1
10
+ wandb: ⭐️ View project at https://stability.wandb.io/ckadirt/mindeye
11
+ wandb: 🚀 View run at https://stability.wandb.io/ckadirt/mindeye/runs/bold5k_nsdm1
12
+
13
  0%| | 0/80 [00:00<?, ?it/s]slurmstepd: error: *** REASON: burst_buffer/lua: Stage-out in progress ***
14
+ slurmstepd: error: *** JOB 545090 ON ip-10-0-133-32 CANCELLED AT 2024-12-10T21:56:08 ***
15
+ slurmstepd: error: *** REASON: burst_buffer/lua: Stage-out in progress ***
MindEyeV2/src/slurms/545090.out ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-133-32
2
+ MASTER_PORT=15871
3
+ WORLD_SIZE=1
4
+ model_name=bold5k_nsdm1
5
+ LOCAL RANK 0
6
+ PID of this process = 841814
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ Training with 15 sessions
20
+ Loaded all subj train dls and betas!
21
+
22
+ Loaded all subj train dls and betas!
23
+
24
+ Loaded test dl for subj1!
25
+
26
+ batch_size = 21 num_iterations_per_epoch = 205 num_samples_per_epoch = 4323
27
+ param counts:
28
+ 91,324,416 total
29
+ 91,324,416 trainable
30
+ param counts:
31
+ 91,324,416 total
32
+ 91,324,416 trainable
33
+ torch.Size([2, 1, 22295]) torch.Size([2, 1, 4096])
34
+ param counts:
35
+ 1,887,861,400 total
36
+ 1,887,861,400 trainable
37
+ param counts:
38
+ 1,979,185,816 total
39
+ 1,979,185,816 trainable
40
+ b.shape torch.Size([2, 1, 4096])
41
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
42
+ param counts:
43
+ 259,865,216 total
44
+ 259,865,200 trainable
45
+ param counts:
46
+ 2,239,051,032 total
47
+ 2,239,051,016 trainable
48
+ total_steps 16400
49
+
50
+ Done with model preparations!
51
+ param counts:
52
+ 2,239,051,032 total
53
+ 2,239,051,016 trainable
54
+ wandb mindeye run bold5k_nsdm1
55
+ wandb_config:
56
+ {'model_name': 'bold5k_nsdm1', 'global_batch_size': '21', 'batch_size': 21, 'num_epochs': 80, 'num_sessions': 15, 'num_params': 2239051016, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': True, 'max_lr': 0.0003, 'mixup_pct': 0.33, 'num_samples_per_epoch': 4323, 'num_test': 480, 'ckpt_interval': 999, 'ckpt_saving': False, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1}
57
+ wandb_id: bold5k_nsdm1
58
+ torch.Size([21, 22295]) torch.Size([21, 3, 224, 224]) torch.Size([21]) torch.Size([21])
59
+ bold5k_nsdm1 starting with epoch 0 / 80
MindEyeV2/src/slurms/545091.out ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MASTER_ADDR=ip-10-0-133-32
2
+ MASTER_PORT=13257
3
+ WORLD_SIZE=1
4
+ model_name=bold5k_nsdm1
5
+ LOCAL RANK 0
6
+ PID of this process = 842903
7
+ device: cuda
8
+ Distributed environment: DistributedType.NO
9
+ Num processes: 1
10
+ Process index: 0
11
+ Local process index: 0
12
+ Device: cuda
13
+
14
+ Mixed precision type: fp16
15
+
16
+ distributed = False num_devices = 1 local rank = 0 world size = 1 data_type = torch.float16
17
+ subj_list [1] num_sessions 15
18
+ dividing batch size by subj_list, which will then be concatenated across subj during training...
19
+ Training with 15 sessions
20
+ Loaded all subj train dls and betas!
21
+
22
+ Loaded all subj train dls and betas!
23
+
24
+ Loaded test dl for subj1!
25
+
26
+ batch_size = 21 num_iterations_per_epoch = 205 num_samples_per_epoch = 4323
27
+ param counts:
28
+ 91,324,416 total
29
+ 91,324,416 trainable
30
+ param counts:
31
+ 91,324,416 total
32
+ 91,324,416 trainable
33
+ torch.Size([2, 1, 22295]) torch.Size([2, 1, 4096])
34
+ param counts:
35
+ 1,887,861,400 total
36
+ 1,887,861,400 trainable
37
+ param counts:
38
+ 1,979,185,816 total
39
+ 1,979,185,816 trainable
40
+ b.shape torch.Size([2, 1, 4096])
41
+ torch.Size([2, 256, 1664]) torch.Size([2, 256, 1664]) torch.Size([1]) torch.Size([1])
42
+ param counts:
43
+ 259,865,216 total
44
+ 259,865,200 trainable
45
+ param counts:
46
+ 2,239,051,032 total
47
+ 2,239,051,016 trainable
48
+ total_steps 30750
49
+
50
+ Done with model preparations!
51
+ param counts:
52
+ 2,239,051,032 total
53
+ 2,239,051,016 trainable
54
+ wandb mindeye run bold5k_nsdm1
55
+ wandb_config:
56
+ {'model_name': 'bold5k_nsdm1', 'global_batch_size': '21', 'batch_size': 21, 'num_epochs': 150, 'num_sessions': 15, 'num_params': 2239051016, 'clip_scale': 1.0, 'prior_scale': 30.0, 'blur_scale': 0.5, 'use_image_aug': True, 'max_lr': 0.0003, 'mixup_pct': 0.33, 'num_samples_per_epoch': 4323, 'num_test': 480, 'ckpt_interval': 999, 'ckpt_saving': False, 'seed': 42, 'distributed': False, 'num_devices': 1, 'world_size': 1}
57
+ wandb_id: bold5k_nsdm1
58
+ torch.Size([21, 22295]) torch.Size([21, 3, 224, 224]) torch.Size([21]) torch.Size([21])
59
+ bold5k_nsdm1 starting with epoch 0 / 150
60
+
61
+ ===Finished!===
62
+