3333 DATA_FILE6 ,
3434)
3535
36+ rng = np .random .default_rng ()
37+
3638
3739def test_agg_data ():
3840 surf_gii_img = load (get_test_data ('gifti' , 'ascii.gii' ))
@@ -81,7 +83,7 @@ def test_gifti_image():
8183 assert gi .numDA == 0
8284
8385 # Test from numpy numeric array
84- data = np .random . random (( 5 ,) )
86+ data = rng .random ( 5 , dtype = np . float32 )
8587 da = GiftiDataArray (data )
8688 gi .add_gifti_data_array (da )
8789 assert gi .numDA == 1
@@ -98,7 +100,7 @@ def test_gifti_image():
98100
99101 # Remove one
100102 gi = GiftiImage ()
101- da = GiftiDataArray (np .zeros ((5 ,)), intent = 0 )
103+ da = GiftiDataArray (np .zeros ((5 ,), np . float32 ), intent = 0 )
102104 gi .add_gifti_data_array (da )
103105
104106 gi .remove_gifti_data_array_by_intent (3 )
@@ -126,6 +128,42 @@ def assign_metadata(val):
126128 pytest .raises (TypeError , assign_metadata , 'not-a-meta' )
127129
128130
131+ @pytest .mark .parametrize ('label' , data_type_codes .value_set ('label' ))
132+ def test_image_typing (label ):
133+ dtype = data_type_codes .dtype [label ]
134+ if dtype == np .void :
135+ return
136+ arr = 127 * rng .random (20 )
137+ try :
138+ cast = arr .astype (label )
139+ except TypeError :
140+ return
141+ darr = GiftiDataArray (cast , datatype = label )
142+ img = GiftiImage (darrays = [darr ])
143+
144+ # Force-write always works
145+ force_rt = img .from_bytes (img .to_bytes (mode = 'force' ))
146+ assert np .array_equal (cast , force_rt .darrays [0 ].data )
147+
148+ # Compatibility mode does its best
149+ if np .issubdtype (dtype , np .integer ) or np .issubdtype (dtype , np .floating ):
150+ compat_rt = img .from_bytes (img .to_bytes (mode = 'compat' ))
151+ compat_darr = compat_rt .darrays [0 ].data
152+ assert np .allclose (cast , compat_darr )
153+ assert compat_darr .dtype in ('uint8' , 'int32' , 'float32' )
154+ else :
155+ with pytest .raises (ValueError ):
156+ img .to_bytes (mode = 'compat' )
157+
158+ # Strict mode either works or fails
159+ if label in ('uint8' , 'int32' , 'float32' ):
160+ strict_rt = img .from_bytes (img .to_bytes (mode = 'strict' ))
161+ assert np .array_equal (cast , strict_rt .darrays [0 ].data )
162+ else :
163+ with pytest .raises (ValueError ):
164+ img .to_bytes (mode = 'strict' )
165+
166+
129167def test_dataarray_empty ():
130168 # Test default initialization of DataArray
131169 null_da = GiftiDataArray ()
@@ -195,6 +233,38 @@ def test_dataarray_init():
195233 assert gda (ext_offset = 12 ).ext_offset == 12
196234
197235
236+ @pytest .mark .parametrize ('label' , data_type_codes .value_set ('label' ))
237+ def test_dataarray_typing (label ):
238+ dtype = data_type_codes .dtype [label ]
239+ code = data_type_codes .code [label ]
240+ arr = np .zeros ((5 ,), dtype = dtype )
241+
242+ # Default interface: accept standards-conformant arrays, reject else
243+ if dtype in ('uint8' , 'int32' , 'float32' ):
244+ assert GiftiDataArray (arr ).datatype == code
245+ else :
246+ with pytest .raises (ValueError ):
247+ GiftiDataArray (arr )
248+
249+ # Explicit override - permit for now, may want to warn or eventually
250+ # error
251+ assert GiftiDataArray (arr , datatype = label ).datatype == code
252+ assert GiftiDataArray (arr , datatype = code ).datatype == code
253+ # Void is how we say we don't know how to do something, so it's not unique
254+ if dtype != np .dtype ('void' ):
255+ assert GiftiDataArray (arr , datatype = dtype ).datatype == code
256+
257+ # Side-load data array (as in parsing)
258+ # We will probably always want this to load legacy images, but it's
259+ # probably not ideal to make it easy to silently propagate nonconformant
260+ # arrays
261+ gda = GiftiDataArray ()
262+ gda .data = arr
263+ gda .datatype = data_type_codes .code [label ]
264+ assert gda .data .dtype == dtype
265+ assert gda .datatype == data_type_codes .code [label ]
266+
267+
198268def test_labeltable ():
199269 img = GiftiImage ()
200270 assert len (img .labeltable .labels ) == 0
@@ -303,7 +373,7 @@ def test_metadata_list_interface():
303373
304374
305375def test_gifti_label_rgba ():
306- rgba = np .random . rand (4 )
376+ rgba = rng .random (4 )
307377 kwargs = dict (zip (['red' , 'green' , 'blue' , 'alpha' ], rgba ))
308378
309379 gl1 = GiftiLabel (** kwargs )
@@ -332,13 +402,17 @@ def assign_rgba(gl, val):
332402 assert np .all ([elem is None for elem in gl4 .rgba ])
333403
334404
335- def test_print_summary ():
336- for fil in [DATA_FILE1 , DATA_FILE2 , DATA_FILE3 , DATA_FILE4 , DATA_FILE5 , DATA_FILE6 ]:
337- gimg = load (fil )
338- gimg .print_summary ()
405+ @pytest .mark .parametrize (
406+ 'fname' , [DATA_FILE1 , DATA_FILE2 , DATA_FILE3 , DATA_FILE4 , DATA_FILE5 , DATA_FILE6 ]
407+ )
408+ def test_print_summary (fname , capsys ):
409+ gimg = load (fname )
410+ gimg .print_summary ()
411+ captured = capsys .readouterr ()
412+ assert captured .out .startswith ('----start----\n ' )
339413
340414
341- def test_gifti_coord ():
415+ def test_gifti_coord (capsys ):
342416 from ..gifti import GiftiCoordSystem
343417
344418 gcs = GiftiCoordSystem ()
@@ -347,6 +421,15 @@ def test_gifti_coord():
347421 # Smoke test
348422 gcs .xform = None
349423 gcs .print_summary ()
424+ captured = capsys .readouterr ()
425+ assert captured .out == '\n ' .join (
426+ [
427+ 'Dataspace: NIFTI_XFORM_UNKNOWN' ,
428+ 'XFormSpace: NIFTI_XFORM_UNKNOWN' ,
429+ 'Affine Transformation Matrix: ' ,
430+ ' None\n ' ,
431+ ]
432+ )
350433 gcs .to_xml ()
351434
352435
@@ -471,7 +554,7 @@ def test_darray_dtype_coercion_failures():
471554 datatype = darray_dtype ,
472555 )
473556 gii = GiftiImage (darrays = [da ])
474- gii_copy = GiftiImage .from_bytes (gii .to_bytes ())
557+ gii_copy = GiftiImage .from_bytes (gii .to_bytes (mode = 'force' ))
475558 da_copy = gii_copy .darrays [0 ]
476559 assert np .dtype (da_copy .data .dtype ) == np .dtype (darray_dtype )
477560 assert_array_equal (da_copy .data , da .data )
0 commit comments