@@ -94,84 +94,6 @@ def _csc_matrix_cast(x):
9494 return csc_matrix (x )
9595
9696
97- ###############################################################################
98- # Backporting nibabel's read_geometry
99-
100- def _get_read_geometry ():
101- """Get the geometry reading function."""
102- try :
103- import nibabel as nib
104- has_nibabel = True
105- except ImportError :
106- has_nibabel = False
107- if has_nibabel :
108- from nibabel .freesurfer import read_geometry
109- else :
110- read_geometry = _read_geometry
111- return read_geometry
112-
113-
114- def _read_geometry (filepath , read_metadata = False , read_stamp = False ):
115- """Backport from nibabel."""
116- from .surface import _fread3 , _fread3_many
117- volume_info = dict ()
118-
119- TRIANGLE_MAGIC = 16777214
120- QUAD_MAGIC = 16777215
121- NEW_QUAD_MAGIC = 16777213
122- with open (filepath , "rb" ) as fobj :
123- magic = _fread3 (fobj )
124- if magic in (QUAD_MAGIC , NEW_QUAD_MAGIC ): # Quad file
125- nvert = _fread3 (fobj )
126- nquad = _fread3 (fobj )
127- (fmt , div ) = (">i2" , 100. ) if magic == QUAD_MAGIC else (">f4" , 1. )
128- coords = np .fromfile (fobj , fmt , nvert * 3 ).astype (np .float64 ) / div
129- coords = coords .reshape (- 1 , 3 )
130- quads = _fread3_many (fobj , nquad * 4 )
131- quads = quads .reshape (nquad , 4 )
132- #
133- # Face splitting follows
134- #
135- faces = np .zeros ((2 * nquad , 3 ), dtype = np .int64 )
136- nface = 0
137- for quad in quads :
138- if (quad [0 ] % 2 ) == 0 :
139- faces [nface ] = quad [0 ], quad [1 ], quad [3 ]
140- nface += 1
141- faces [nface ] = quad [2 ], quad [3 ], quad [1 ]
142- nface += 1
143- else :
144- faces [nface ] = quad [0 ], quad [1 ], quad [2 ]
145- nface += 1
146- faces [nface ] = quad [0 ], quad [2 ], quad [3 ]
147- nface += 1
148-
149- elif magic == TRIANGLE_MAGIC : # Triangle file
150- create_stamp = fobj .readline ().rstrip (b'\n ' ).decode ('utf-8' )
151- fobj .readline ()
152- vnum = np .fromfile (fobj , ">i4" , 1 )[0 ]
153- fnum = np .fromfile (fobj , ">i4" , 1 )[0 ]
154- coords = np .fromfile (fobj , ">f4" , vnum * 3 ).reshape (vnum , 3 )
155- faces = np .fromfile (fobj , ">i4" , fnum * 3 ).reshape (fnum , 3 )
156-
157- if read_metadata :
158- volume_info = _read_volume_info (fobj )
159- else :
160- raise ValueError ("File does not appear to be a Freesurfer surface" )
161-
162- coords = coords .astype (np .float64 )
163-
164- ret = (coords , faces )
165- if read_metadata :
166- if len (volume_info ) == 0 :
167- warnings .warn ('No volume information contained in the file' )
168- ret += (volume_info ,)
169- if read_stamp :
170- ret += (create_stamp ,)
171-
172- return ret
173-
174-
17597###############################################################################
17698# NumPy Generator (NumPy 1.17)
17799
@@ -234,36 +156,6 @@ def _read_volume_info(fobj):
234156 return volume_info
235157
236158
237- def _serialize_volume_info (volume_info ):
238- """An implementation of nibabel.freesurfer.io._serialize_volume_info, since
239- old versions of nibabel (<=2.1.0) don't have it."""
240- keys = ['head' , 'valid' , 'filename' , 'volume' , 'voxelsize' , 'xras' , 'yras' ,
241- 'zras' , 'cras' ]
242- diff = set (volume_info .keys ()).difference (keys )
243- if len (diff ) > 0 :
244- raise ValueError ('Invalid volume info: %s.' % diff .pop ())
245-
246- strings = list ()
247- for key in keys :
248- if key == 'head' :
249- if not (np .array_equal (volume_info [key ], [20 ]) or np .array_equal (
250- volume_info [key ], [2 , 0 , 20 ])):
251- warnings .warn ("Unknown extension code." )
252- strings .append (np .array (volume_info [key ], dtype = '>i4' ).tobytes ())
253- elif key in ('valid' , 'filename' ):
254- val = volume_info [key ]
255- strings .append ('{} = {}\n ' .format (key , val ).encode ('utf-8' ))
256- elif key == 'volume' :
257- val = volume_info [key ]
258- strings .append ('{} = {} {} {}\n ' .format (
259- key , val [0 ], val [1 ], val [2 ]).encode ('utf-8' ))
260- else :
261- val = volume_info [key ]
262- strings .append ('{} = {:0.10g} {:0.10g} {:0.10g}\n ' .format (
263- key .ljust (6 ), val [0 ], val [1 ], val [2 ]).encode ('utf-8' ))
264- return b'' .join (strings )
265-
266-
267159##############################################################################
268160# adapted from scikit-learn
269161
@@ -877,28 +769,9 @@ def stable_cumsum(arr, axis=None, rtol=1e-05, atol=1e-08):
877769 return out
878770
879771
880- # This shim can be removed once NumPy 1.19.0+ is required (1.18.4 has sign bug)
881- def svd (a , hermitian = False ):
882- if hermitian : # faster
883- s , u = np .linalg .eigh (a )
884- sgn = np .sign (s )
885- s = np .abs (s )
886- sidx = np .argsort (s )[..., ::- 1 ]
887- sgn = np .take_along_axis (sgn , sidx , axis = - 1 )
888- s = np .take_along_axis (s , sidx , axis = - 1 )
889- u = np .take_along_axis (u , sidx [..., None , :], axis = - 1 )
890- # singular values are unsigned, move the sign into v
891- vt = (u * sgn [..., np .newaxis , :]).swapaxes (- 2 , - 1 ).conj ()
892- np .abs (s , out = s )
893- return u , s , vt
894- else :
895- return np .linalg .svd (a )
896-
897-
898772###############################################################################
899773# From nilearn
900774
901-
902775def _crop_colorbar (cbar , cbar_vmin , cbar_vmax ):
903776 """
904777 crop a colorbar to show from cbar_vmin to cbar_vmax
@@ -915,31 +788,18 @@ def _crop_colorbar(cbar, cbar_vmin, cbar_vmax):
915788 new_tick_locs = np .linspace (cbar_vmin , cbar_vmax ,
916789 len (cbar_tick_locs ))
917790
918- # matplotlib >= 3.2.0 no longer normalizes axes between 0 and 1
919- # See https://matplotlib.org/3.2.1/api/prev_api_changes/api_changes_3.2.0.html
920- # _outline was removed in
921- # https://github.com/matplotlib/matplotlib/commit/03a542e875eba091a027046d5ec652daa8be6863
922- # so we use the code from there
923- if _compare_version (matplotlib .__version__ , '>=' , '3.2.0' ):
924- cbar .ax .set_ylim (cbar_vmin , cbar_vmax )
925- X = cbar ._mesh ()[0 ]
926- X = np .array ([X [0 ], X [- 1 ]])
927- Y = np .array ([[cbar_vmin , cbar_vmin ], [cbar_vmax , cbar_vmax ]])
928- N = X .shape [0 ]
929- ii = [0 , 1 , N - 2 , N - 1 , 2 * N - 1 , 2 * N - 2 , N + 1 , N , 0 ]
930- x = X .T .reshape (- 1 )[ii ]
931- y = Y .T .reshape (- 1 )[ii ]
932- xy = (np .column_stack ([y , x ])
933- if cbar .orientation == 'horizontal' else
934- np .column_stack ([x , y ]))
935- cbar .outline .set_xy (xy )
936- else :
937- cbar .ax .set_ylim (cbar .norm (cbar_vmin ), cbar .norm (cbar_vmax ))
938- outline = cbar .outline .get_xy ()
939- outline [:2 , 1 ] += cbar .norm (cbar_vmin )
940- outline [2 :6 , 1 ] -= (1. - cbar .norm (cbar_vmax ))
941- outline [6 :, 1 ] += cbar .norm (cbar_vmin )
942- cbar .outline .set_xy (outline )
791+ cbar .ax .set_ylim (cbar_vmin , cbar_vmax )
792+ X = cbar ._mesh ()[0 ]
793+ X = np .array ([X [0 ], X [- 1 ]])
794+ Y = np .array ([[cbar_vmin , cbar_vmin ], [cbar_vmax , cbar_vmax ]])
795+ N = X .shape [0 ]
796+ ii = [0 , 1 , N - 2 , N - 1 , 2 * N - 1 , 2 * N - 2 , N + 1 , N , 0 ]
797+ x = X .T .reshape (- 1 )[ii ]
798+ y = Y .T .reshape (- 1 )[ii ]
799+ xy = (np .column_stack ([y , x ])
800+ if cbar .orientation == 'horizontal' else
801+ np .column_stack ([x , y ]))
802+ cbar .outline .set_xy (xy )
943803
944804 cbar .set_ticks (new_tick_locs )
945805 cbar .update_ticks ()
@@ -951,7 +811,7 @@ def _crop_colorbar(cbar, cbar_vmin, cbar_vmax):
951811# Here we choose different defaults to speed things up by default
952812try :
953813 import numba
954- if _compare_version (numba .__version__ , '<' , '0.48 ' ):
814+ if _compare_version (numba .__version__ , '<' , '0.53.1 ' ):
955815 raise ImportError
956816 prange = numba .prange
957817 def jit (nopython = True , nogil = True , fastmath = True , cache = True ,
0 commit comments