33
33
DATA_FILE6 ,
34
34
)
35
35
36
+ rng = np .random .default_rng ()
37
+
36
38
37
39
def test_agg_data ():
38
40
surf_gii_img = load (get_test_data ('gifti' , 'ascii.gii' ))
@@ -81,7 +83,7 @@ def test_gifti_image():
81
83
assert gi .numDA == 0
82
84
83
85
# Test from numpy numeric array
84
- data = np .random . random (( 5 ,) )
86
+ data = rng .random ( 5 , dtype = np . float32 )
85
87
da = GiftiDataArray (data )
86
88
gi .add_gifti_data_array (da )
87
89
assert gi .numDA == 1
@@ -98,7 +100,7 @@ def test_gifti_image():
98
100
99
101
# Remove one
100
102
gi = GiftiImage ()
101
- da = GiftiDataArray (np .zeros ((5 ,)), intent = 0 )
103
+ da = GiftiDataArray (np .zeros ((5 ,), np . float32 ), intent = 0 )
102
104
gi .add_gifti_data_array (da )
103
105
104
106
gi .remove_gifti_data_array_by_intent (3 )
@@ -126,6 +128,42 @@ def assign_metadata(val):
126
128
pytest .raises (TypeError , assign_metadata , 'not-a-meta' )
127
129
128
130
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
+
129
167
def test_dataarray_empty ():
130
168
# Test default initialization of DataArray
131
169
null_da = GiftiDataArray ()
@@ -195,6 +233,38 @@ def test_dataarray_init():
195
233
assert gda (ext_offset = 12 ).ext_offset == 12
196
234
197
235
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
+
198
268
def test_labeltable ():
199
269
img = GiftiImage ()
200
270
assert len (img .labeltable .labels ) == 0
@@ -303,7 +373,7 @@ def test_metadata_list_interface():
303
373
304
374
305
375
def test_gifti_label_rgba ():
306
- rgba = np .random . rand (4 )
376
+ rgba = rng .random (4 )
307
377
kwargs = dict (zip (['red' , 'green' , 'blue' , 'alpha' ], rgba ))
308
378
309
379
gl1 = GiftiLabel (** kwargs )
@@ -332,13 +402,17 @@ def assign_rgba(gl, val):
332
402
assert np .all ([elem is None for elem in gl4 .rgba ])
333
403
334
404
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 ' )
339
413
340
414
341
- def test_gifti_coord ():
415
+ def test_gifti_coord (capsys ):
342
416
from ..gifti import GiftiCoordSystem
343
417
344
418
gcs = GiftiCoordSystem ()
@@ -347,6 +421,15 @@ def test_gifti_coord():
347
421
# Smoke test
348
422
gcs .xform = None
349
423
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
+ )
350
433
gcs .to_xml ()
351
434
352
435
@@ -471,7 +554,7 @@ def test_darray_dtype_coercion_failures():
471
554
datatype = darray_dtype ,
472
555
)
473
556
gii = GiftiImage (darrays = [da ])
474
- gii_copy = GiftiImage .from_bytes (gii .to_bytes ())
557
+ gii_copy = GiftiImage .from_bytes (gii .to_bytes (mode = 'force' ))
475
558
da_copy = gii_copy .darrays [0 ]
476
559
assert np .dtype (da_copy .data .dtype ) == np .dtype (darray_dtype )
477
560
assert_array_equal (da_copy .data , da .data )
0 commit comments