Skip to content

Commit d370c0c

Browse files
committed
[REF] Clean up civet to fs transform
This allows for linear mappings, too!
1 parent 733a0dd commit d370c0c

File tree

1 file changed

+15
-43
lines changed

1 file changed

+15
-43
lines changed

netneurotools/civet.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
import nibabel as nib
77
import numpy as np
8-
from scipy.spatial import cKDTree
8+
from scipy.interpolate import griddata
99

1010
from .datasets import fetch_civet, fetch_fsaverage
1111

1212
_MNI305to152 = np.array([[0.9975, -0.0073, 0.0176, -0.0429],
1313
[0.0146, 1.0009, -0.0024, 1.5496],
14-
[-0.0130, -0.0093, 0.9971, 1.1840]])
14+
[-0.0130, -0.0093, 0.9971, 1.1840],
15+
[0.0000, 0.0000, 0.0000, 1.0000]])
1516

1617

1718
def read_civet(fname):
@@ -47,34 +48,9 @@ def read_civet(fname):
4748
return vertices, triangles
4849

4950

50-
def _get_civet_to_fs_mapping(obj, fs):
51-
"""
52-
Returns a mapping between `obj` and `fs` geometry files
53-
54-
Parameters
55-
----------
56-
obj : str or os.PathLike
57-
Path to CIVET geometry file
58-
fs : str or os.PathLike
59-
Path to FreeSurfer geometry file
60-
61-
Returns
62-
-------
63-
idx : (N,) np.ndarray
64-
Mapping from CIVET to FreeSurfer space
65-
"""
66-
67-
vert_cv, _ = read_civet(obj)
68-
vert_fs, _ = nib.freesurfer.read_geometry(fs)
69-
70-
vert_fs = np.c_[vert_fs, np.ones(len(vert_fs))] @ _MNI305to152.T
71-
_, idx = cKDTree(vert_cv).query(vert_fs, k=1, distance_upper_bound=10)
72-
73-
return idx
74-
75-
7651
def civet_to_freesurfer(brainmap, surface='mid', version='v1',
77-
freesurfer='fsaverage6', mapping=None, data_dir=None):
52+
freesurfer='fsaverage6', method='nearest',
53+
data_dir=None):
7854
"""
7955
Projects `brainmap` in CIVET space to `freesurfer` fsaverage space
8056
@@ -92,9 +68,9 @@ def civet_to_freesurfer(brainmap, surface='mid', version='v1',
9268
Which version of FreeSurfer space to project data to. Must be one of
9369
{'fsaverage', 'fsaverage3', 'fsaverage4', 'fsaverage5', 'fsaverage6'}.
9470
Default: 'fsaverage6'
95-
mapping : array_like, optional
96-
If mapping has been pre-computed for `surface` --> `version` and is
97-
provided, this will be used instead of recomputing. Default: None
71+
method : {'nearest', 'linear'}, optional
72+
What method of interpolation to use when projecting the data between
73+
surfaces. Default: 'nearest'
9874
data_dir : str, optional
9975
Path to use as data directory. If not specified, will check for
10076
environmental variable 'NNT_DATA'; if that is not set, will use
@@ -106,8 +82,9 @@ def civet_to_freesurfer(brainmap, surface='mid', version='v1',
10682
Provided `brainmap` mapped to FreeSurfer
10783
"""
10884

85+
brainmap = np.asarray(brainmap)
10986
densities = (81924, 327684)
110-
n_vert = len(brainmap)
87+
n_vert = brainmap.shape[0]
11188
if n_vert not in densities:
11289
raise ValueError('Unable to interpret `brainmap` space; provided '
11390
'array must have length in {}. Received: {}'
@@ -122,15 +99,10 @@ def civet_to_freesurfer(brainmap, surface='mid', version='v1',
12299
data = []
123100
for n, hemi in enumerate(('lh', 'rh')):
124101
sl = slice(n_vert * n, n_vert * (n + 1))
125-
if mapping is None:
126-
idx = _get_civet_to_fs_mapping(getattr(icbm, hemi),
127-
getattr(fsavg, hemi))
128-
else:
129-
idx = mapping[sl]
130-
131-
hdata = np.full(len(idx), np.nan)
132-
mask = idx != n_vert
133-
hdata[mask] = brainmap[sl][idx[mask]]
134-
data.append(hdata)
102+
vert_cv, _ = read_civet(getattr(icbm, hemi))
103+
vert_fs = nib.affines.apply_affine(
104+
_MNI305to152, nib.freesurfer.read_geometry(getattr(fsavg, hemi))[0]
105+
)
106+
data.append(griddata(vert_cv, brainmap[sl], vert_fs, method=method))
135107

136108
return np.hstack(data)

0 commit comments

Comments
 (0)