55
66import nibabel as nib
77import numpy as np
8- from scipy .spatial import cKDTree
8+ from scipy .interpolate import griddata
99
1010from .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
1718def 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-
7651def 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