Skip to content

Commit 18d6014

Browse files
authored
Merge pull request #67 from rmarkello/ref/freesurfer
[REF] Allow precomputed spins for spin_data
2 parents 1fc88dd + ee60c3e commit 18d6014

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: python
2-
sudo: false
2+
os: linux
33
dist: xenial
44
notifications:
55
email: change
@@ -9,15 +9,15 @@ python:
99
- 3.7
1010

1111
env:
12-
matrix:
12+
jobs:
1313
- CHECK_TYPE=linting
1414
- CHECK_TYPE=docdoctest
1515
- CHECK_TYPE=test
1616
- CHECK_TYPE=test INSTALL_NUMBA=true
1717
global:
1818
- INSTALL_TYPE=setup
1919

20-
matrix:
20+
jobs:
2121
include:
2222
- python: 3.6
2323
env:

environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ channels:
33
- defaults
44
- conda-forge
55
dependencies:
6-
- python>=3.6
6+
- python==3.7
77
- matplotlib
88
- nibabel
99
- nilearn

netneurotools/freesurfer.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import os
77
import os.path as op
8+
import warnings
89

910
from nibabel.freesurfer import read_annot, read_geometry
1011
import numpy as np
@@ -389,6 +390,10 @@ def spin_data(data, *, lhannot, rhannot, version='fsaverage', n_rotate=1000,
389390
'fsaverage5', 'fsaverage6'}. Default: 'fsaverage'
390391
n_rotate : int, optional
391392
Number of rotations to generate. Default: 1000
393+
spins : array_like, optional
394+
Pre-computed spins to use instead of generating them on the fly. If not
395+
provided will use other provided parameters to create them. Default:
396+
None
392397
drop : list, optional
393398
Specifies regions in {lh,rh}annot that are not present in `data`. NaNs
394399
will be inserted in place of the these regions in the returned data. If
@@ -400,7 +405,8 @@ def spin_data(data, *, lhannot, rhannot, version='fsaverage', n_rotate=1000,
400405
Whether to print occasional status messages. Default: False
401406
return_cost : bool, optional
402407
Whether to return cost array (specified as Euclidean distance) for each
403-
coordinate for each rotation Default: True
408+
coordinate for each rotation. Currently this option is not supported if
409+
pre-computed `spins` are provided. Default: True
404410
405411
Returns
406412
-------
@@ -419,34 +425,47 @@ def spin_data(data, *, lhannot, rhannot, version='fsaverage', n_rotate=1000,
419425
]
420426

421427
# get coordinates and hemisphere designation for spin generation
422-
coords, hemiid = _get_fsaverage_coords(version, 'sphere')
423428
vertices = parcels_to_vertices(data, lhannot=lhannot, rhannot=rhannot,
424429
drop=drop)
425430

426-
if len(vertices) != len(coords):
427-
raise ValueError('Provided annotation files have a different number '
428-
'of vertices than the specified fsaverage surface.\n'
429-
' ANNOTATION: {} vertices\n'
430-
' FSAVERAGE: {} vertices'
431-
.format(len(vertices), len(coords)))
432-
433431
if spins is None:
432+
coords, hemiid = _get_fsaverage_coords(version, 'sphere')
433+
if len(vertices) != len(coords):
434+
raise ValueError('Provided annotation files have a different '
435+
'number of vertices than the specified fsaverage '
436+
'surface.\n ANNOTATION: {} vertices\n '
437+
'FSAVERAGE: {} vertices'
438+
.format(len(vertices), len(coords)))
434439
spins, cost = gen_spinsamples(coords, hemiid, n_rotate=n_rotate,
435440
seed=seed, verbose=verbose)
436441
else:
437442
spins = np.asarray(spins, dtype='int32')
443+
if len(spins) != len(vertices):
444+
raise ValueError('Provided `spins` array has a different number '
445+
'of vertices than the provided annotation files.'
446+
'\n ANNOTATION: {} vertices\n SPINS: '
447+
'{} vertices\n'
448+
.format(len(vertices), len(spins)))
438449
if spins.shape[-1] != n_rotate:
439-
raise ValueError('Provided `spins` does not match number of '
440-
'requested rotations with `n_rotate`. Please '
441-
'check inputs and try again.')
450+
warnings.warn('Shape of provided `spins` array does not match '
451+
'number of rotations requested with `n_rotate`. '
452+
'Ignoring specified `n_rotate` parameter and using '
453+
'all provided `spins`.')
454+
n_rotate = spins.shape[-1]
442455
if return_cost:
443456
raise ValueError('Cannot `return_cost` when `spins` are provided.')
444457

445-
spun = np.zeros((len(data), n_rotate))
458+
spun = np.zeros(data.shape + (n_rotate,))
446459
for n in range(n_rotate):
447-
spun[:, n] = vertices_to_parcels(vertices[spins[:, n]],
448-
lhannot=lhannot, rhannot=rhannot,
449-
drop=drop)
460+
if verbose:
461+
msg = f'Reducing vertices to parcels: {n:>5}/{n_rotate}'
462+
print(msg, end='\b' * len(msg), flush=True)
463+
spun[..., n] = vertices_to_parcels(vertices[spins[:, n]],
464+
lhannot=lhannot, rhannot=rhannot,
465+
drop=drop)
466+
467+
if verbose:
468+
print(' ' * len(msg) + '\b' * len(msg), end='', flush=True)
450469

451470
if return_cost:
452471
return spun, cost

0 commit comments

Comments
 (0)