55
66import os
77import os .path as op
8+ import warnings
89
910from nibabel .freesurfer import read_annot , read_geometry
1011import 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