Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- MindEyeV2/antspy/ants/core/__init__.py +42 -0
- MindEyeV2/antspy/ants/core/ants_image_io.py +529 -0
- MindEyeV2/antspy/ants/math/__init__.py +14 -0
- MindEyeV2/antspy/ants/math/averaging.py +100 -0
- MindEyeV2/antspy/ants/math/get_centroids.py +58 -0
- MindEyeV2/antspy/ants/math/get_neighborhood.py +187 -0
- MindEyeV2/antspy/ants/math/hausdorff_distance.py +40 -0
- MindEyeV2/antspy/ants/math/image_similarity.py +67 -0
- MindEyeV2/antspy/ants/math/metrics.py +43 -0
- MindEyeV2/antspy/ants/math/quantile.py +447 -0
- MindEyeV2/antspy/ants/registration/__init__.py +15 -0
- MindEyeV2/antspy/ants/registration/affine_initializer.py +70 -0
- MindEyeV2/antspy/ants/registration/apply_transforms.py +316 -0
- MindEyeV2/antspy/ants/registration/average_transform.py +48 -0
- MindEyeV2/antspy/ants/registration/build_template.py +137 -0
- MindEyeV2/antspy/ants/registration/compose_displacement_fields.py +33 -0
- MindEyeV2/antspy/ants/registration/create_jacobian_determinant_image.py +175 -0
- MindEyeV2/antspy/ants/registration/create_warped_grid.py +105 -0
- MindEyeV2/antspy/ants/registration/fit_bspline_displacement_field.py +202 -0
- MindEyeV2/antspy/ants/registration/fit_bspline_object_to_scattered_data.py +191 -0
- MindEyeV2/antspy/ants/registration/fit_thin_plate_spline_displacement_field.py +105 -0
- MindEyeV2/antspy/ants/registration/integrate_velocity_field.py +48 -0
- MindEyeV2/antspy/ants/registration/invert_displacement_field.py +51 -0
- MindEyeV2/antspy/ants/registration/landmark_transforms.py +843 -0
- MindEyeV2/antspy/ants/registration/registration.py +1953 -0
- MindEyeV2/antspy/ants/registration/simulate_displacement_field.py +90 -0
- MindEyeV2/src/slurms/458689.out +4 -0
- MindEyeV2/src/slurms/458690.err +0 -0
- MindEyeV2/src/slurms/458711.out +135 -0
- MindEyeV2/src/slurms/466067.out +54 -0
- MindEyeV2/src/slurms/534014.err +0 -0
- MindEyeV2/src/slurms/534014.out +889 -0
- MindEyeV2/src/slurms/534074.err +46 -0
- MindEyeV2/src/slurms/534074.out +44 -0
- MindEyeV2/src/slurms/534079.err +0 -0
- MindEyeV2/src/slurms/534079.out +1062 -0
- MindEyeV2/src/slurms/544384.err +6 -0
- MindEyeV2/src/slurms/544384.out +4 -0
- MindEyeV2/src/slurms/544386.err +5 -0
- MindEyeV2/src/slurms/544386.out +4 -0
- MindEyeV2/src/slurms/544387.err +7 -0
- MindEyeV2/src/slurms/544387.out +54 -0
- MindEyeV2/src/slurms/544389.err +26 -0
- MindEyeV2/src/slurms/544389.out +59 -0
- MindEyeV2/src/slurms/544390.err +0 -0
- MindEyeV2/src/slurms/544492.out +62 -0
- MindEyeV2/src/slurms/545089.out +18 -0
- MindEyeV2/src/slurms/545090.err +14 -0
- MindEyeV2/src/slurms/545090.out +59 -0
- 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 |
+
|