@@ -208,6 +208,207 @@ def test_cifti2types():
208208 assert_true (count > 0 , "No exercise of " + klass .__name__ )
209209
210210
211+ @needs_nibabel_data ('nitest-cifti2' )
212+ def test_read_geometry ():
213+ img = ci .Cifti2Image .from_filename (DATA_FILE6 )
214+ geometry_mapping = img .header .matrix .get_index_map (1 )
215+
216+ # For every brain model in ones.dscalar.nii defines:
217+ # brain structure name, number of grayordinates, first vertex or voxel, last vertex or voxel
218+ expected_geometry = [('CIFTI_STRUCTURE_CORTEX_LEFT' , 29696 , 0 , 32491 ),
219+ ('CIFTI_STRUCTURE_CORTEX_RIGHT' , 29716 , 0 , 32491 ),
220+ ('CIFTI_STRUCTURE_ACCUMBENS_LEFT' , 135 , [49 , 66 , 28 ], [48 , 72 , 35 ]),
221+ ('CIFTI_STRUCTURE_ACCUMBENS_RIGHT' , 140 , [40 , 66 , 29 ], [43 , 66 , 36 ]),
222+ ('CIFTI_STRUCTURE_AMYGDALA_LEFT' , 315 , [55 , 61 , 21 ], [56 , 58 , 31 ]),
223+ ('CIFTI_STRUCTURE_AMYGDALA_RIGHT' , 332 , [34 , 62 , 20 ], [36 , 61 , 31 ]),
224+ ('CIFTI_STRUCTURE_BRAIN_STEM' , 3472 , [42 , 41 , 0 ], [46 , 50 , 36 ]),
225+ ('CIFTI_STRUCTURE_CAUDATE_LEFT' , 728 , [50 , 72 , 32 ], [53 , 60 , 49 ]),
226+ ('CIFTI_STRUCTURE_CAUDATE_RIGHT' , 755 , [40 , 68 , 33 ], [37 , 62 , 49 ]),
227+ ('CIFTI_STRUCTURE_CEREBELLUM_LEFT' , 8709 , [49 , 35 , 4 ], [46 , 37 , 37 ]),
228+ ('CIFTI_STRUCTURE_CEREBELLUM_RIGHT' , 9144 , [38 , 35 , 4 ], [44 , 38 , 36 ]),
229+ ('CIFTI_STRUCTURE_DIENCEPHALON_VENTRAL_LEFT' , 706 , [52 , 53 , 26 ], [56 , 49 , 35 ]),
230+ ('CIFTI_STRUCTURE_DIENCEPHALON_VENTRAL_RIGHT' , 712 , [39 , 54 , 26 ], [35 , 49 , 36 ]),
231+ ('CIFTI_STRUCTURE_HIPPOCAMPUS_LEFT' , 764 , [55 , 60 , 21 ], [54 , 44 , 39 ]),
232+ ('CIFTI_STRUCTURE_HIPPOCAMPUS_RIGHT' , 795 , [33 , 60 , 21 ], [38 , 45 , 39 ]),
233+ ('CIFTI_STRUCTURE_PALLIDUM_LEFT' , 297 , [56 , 59 , 32 ], [55 , 61 , 39 ]),
234+ ('CIFTI_STRUCTURE_PALLIDUM_RIGHT' , 260 , [36 , 62 , 32 ], [35 , 62 , 39 ]),
235+ ('CIFTI_STRUCTURE_PUTAMEN_LEFT' , 1060 , [51 , 66 , 28 ], [58 , 64 , 43 ]),
236+ ('CIFTI_STRUCTURE_PUTAMEN_RIGHT' , 1010 , [34 , 66 , 29 ], [31 , 62 , 43 ]),
237+ ('CIFTI_STRUCTURE_THALAMUS_LEFT' , 1288 , [55 , 47 , 33 ], [52 , 53 , 46 ]),
238+ ('CIFTI_STRUCTURE_THALAMUS_RIGHT' , 1248 , [32 , 47 , 34 ], [38 , 55 , 46 ])]
239+ current_index = 0
240+ for from_file , expected in zip (geometry_mapping .brain_models , expected_geometry ):
241+ assert_true (from_file .model_type in ("CIFTI_MODEL_TYPE_SURFACE" , "CIFTI_MODEL_TYPE_VOXELS" ))
242+ assert_equal (from_file .brain_structure , expected [0 ])
243+ assert_equal (from_file .index_offset , current_index )
244+ assert_equal (from_file .index_count , expected [1 ])
245+ current_index += from_file .index_count
246+
247+ if from_file .model_type == 'CIFTI_MODEL_TYPE_SURFACE' :
248+ assert_equal (from_file .voxel_indices_ijk , None )
249+ assert_equal (len (from_file .vertex_indices ), expected [1 ])
250+ assert_equal (from_file .vertex_indices [0 ], expected [2 ])
251+ assert_equal (from_file .vertex_indices [- 1 ], expected [3 ])
252+ assert_equal (from_file .surface_number_of_vertices , 32492 )
253+ else :
254+ assert_equal (from_file .vertex_indices , None )
255+ assert_equal (from_file .surface_number_of_vertices , None )
256+ assert_equal (len (from_file .voxel_indices_ijk ), expected [1 ])
257+ assert_equal (from_file .voxel_indices_ijk [0 ], expected [2 ])
258+ assert_equal (from_file .voxel_indices_ijk [- 1 ], expected [3 ])
259+ assert_equal (current_index , img .shape [1 ])
260+
261+ expected_affine = [[- 2 , 0 , 0 , 90 ],
262+ [ 0 , 2 , 0 , - 126 ],
263+ [ 0 , 0 , 2 , - 72 ],
264+ [ 0 , 0 , 0 , 1 ]]
265+ expected_dimensions = (91 , 109 , 91 )
266+ assert_true ((geometry_mapping .volume .transformation_matrix_voxel_indices_ijk_to_xyz .matrix ==
267+ expected_affine ).all ())
268+ assert_equal (geometry_mapping .volume .volume_dimensions , expected_dimensions )
269+
270+
271+ @needs_nibabel_data ('nitest-cifti2' )
272+ def test_read_parcels ():
273+ img = ci .Cifti2Image .from_filename (DATA_FILE4 )
274+ parcel_mapping = img .header .matrix .get_index_map (1 )
275+
276+ expected_parcels = [('MEDIAL.WALL' , ((719 , 20 , 28550 ), (810 , 21 , 28631 ))),
277+ ('BA2_FRB08' , ((516 , 6757 , 17888 ), (461 , 6757 , 17887 ))),
278+ ('BA1_FRB08' , ((211 , 5029 , 17974 ), (214 , 3433 , 17934 ))),
279+ ('BA3b_FRB08' , ((444 , 3436 , 18065 ), (397 , 3436 , 18065 ))),
280+ ('BA4p_FRB08' , ((344 , 3445 , 18164 ), (371 , 3443 , 18175 ))),
281+ ('BA3a_FRB08' , ((290 , 3441 , 18140 ), (289 , 3440 , 18140 ))),
282+ ('BA4a_FRB08' , ((471 , 3446 , 18181 ), (455 , 3446 , 19759 ))),
283+ ('BA6_FRB08' , ((1457 , 2 , 30951 ), (1400 , 2 , 30951 ))),
284+ ('BA17_V1_FRB08' , ((629 , 23155 , 25785 ), (635 , 23155 , 25759 ))),
285+ ('BA45_FRB08' , ((245 , 10100 , 18774 ), (214 , 10103 , 18907 ))),
286+ ('BA44_FRB08' , ((226 , 10118 , 19240 ), (273 , 10119 , 19270 ))),
287+ ('hOc5_MT_FRB08' , ((104 , 15019 , 23329 ), (80 , 15023 , 23376 ))),
288+ ('BA18_V2_FRB08' , ((702 , 95 , 25902 ), (651 , 98 , 25903 ))),
289+ ('V3A_SHM07' , ((82 , 4 , 25050 ), (82 , 4 , 25050 ))),
290+ ('V3B_SHM07' , ((121 , 13398 , 23303 ), (121 , 13398 , 23303 ))),
291+ ('LO1_KPO10' , ((54 , 15007 , 23543 ), (54 , 15007 , 23543 ))),
292+ ('LO2_KPO10' , ((79 , 15013 , 23636 ), (79 , 15013 , 23636 ))),
293+ ('PITd_KPO10' , ((53 , 15018 , 23769 ), (65 , 15018 , 23769 ))),
294+ ('PITv_KPO10' , ((72 , 23480 , 23974 ), (72 , 23480 , 23974 ))),
295+ ('OP1_BSW08' , ((470 , 8421 , 18790 ), (470 , 8421 , 18790 ))),
296+ ('OP2_BSW08' , ((67 , 10 , 31060 ), (67 , 10 , 31060 ))),
297+ ('OP3_BSW08' , ((119 , 10137 , 18652 ), (119 , 10137 , 18652 ))),
298+ ('OP4_BSW08' , ((191 , 16613 , 19429 ), (192 , 16613 , 19429 ))),
299+ ('IPS1_SHM07' , ((54 , 11775 , 14496 ), (54 , 11775 , 14496 ))),
300+ ('IPS2_SHM07' , ((71 , 11771 , 14587 ), (71 , 11771 , 14587 ))),
301+ ('IPS3_SHM07' , ((114 , 11764 , 14783 ), (114 , 11764 , 14783 ))),
302+ ('IPS4_SHM07' , ((101 , 11891 , 12653 ), (101 , 11891 , 12653 ))),
303+ ('V7_SHM07' , ((140 , 11779 , 14002 ), (140 , 11779 , 14002 ))),
304+ ('V4v_SHM07' , ((81 , 23815 , 24557 ), (90 , 23815 , 24557 ))),
305+ ('V3d_KPO10' , ((90 , 23143 , 25192 ), (115 , 23143 , 25192 ))),
306+ ('14c_OFP03' , ((22 , 19851 , 21311 ), (22 , 19851 , 21311 ))),
307+ ('13a_OFP03' , ((20 , 20963 , 21154 ), (20 , 20963 , 21154 ))),
308+ ('47s_OFP03' , ((211 , 10182 , 20343 ), (211 , 10182 , 20343 ))),
309+ ('14r_OFP03' , ((54 , 21187 , 21324 ), (54 , 21187 , 21324 ))),
310+ ('13m_OFP03' , ((103 , 20721 , 21075 ), (103 , 20721 , 21075 ))),
311+ ('13l_OFP03' , ((101 , 20466 , 20789 ), (101 , 20466 , 20789 ))),
312+ ('32pl_OFP03' , ((14 , 19847 , 21409 ), (14 , 19847 , 21409 ))),
313+ ('25_OFP03' , ((8 , 19844 , 27750 ), (8 , 19844 , 27750 ))),
314+ ('47m_OFP03' , ((200 , 10174 , 20522 ), (200 , 10174 , 20522 ))),
315+ ('47l_OFP03' , ((142 , 10164 , 19969 ), (160 , 10164 , 19969 ))),
316+ ('Iai_OFP03' , ((153 , 10188 , 20199 ), (153 , 10188 , 20199 ))),
317+ ('10r_OFP03' , ((138 , 19811 , 28267 ), (138 , 19811 , 28267 ))),
318+ ('11m_OFP03' , ((92 , 20850 , 21165 ), (92 , 20850 , 21165 ))),
319+ ('11l_OFP03' , ((200 , 20275 , 21029 ), (200 , 20275 , 21029 ))),
320+ ('47r_OFP03' , ((259 , 10094 , 20535 ), (259 , 10094 , 20535 ))),
321+ ('10m_OFP03' , ((102 , 19825 , 21411 ), (102 , 19825 , 21411 ))),
322+ ('Iam_OFP03' , ((15 , 20346 , 20608 ), (15 , 20346 , 20608 ))),
323+ ('Ial_OFP03' , ((89 , 10194 , 11128 ), (89 , 10194 , 11128 ))),
324+ ('24_OFP03' , ((39 , 19830 , 28279 ), (36 , 19830 , 28279 ))),
325+ ('Iapm_OFP03' , ((7 , 20200 , 20299 ), (7 , 20200 , 20299 ))),
326+ ('10p_OFP03' , ((480 , 19780 , 28640 ), (480 , 19780 , 28640 ))),
327+ ('V6_PHG06' , ((72 , 12233 , 12869 ), (72 , 12233 , 12869 ))),
328+ ('ER_FRB08' , ((103 , 21514 , 26470 ), (103 , 21514 , 26470 ))),
329+ ('13b_OFP03' , ((60 , 21042 , 21194 ), (71 , 21040 , 21216 )))]
330+
331+ assert_equal (img .shape [1 ], len (expected_parcels ))
332+ assert_equal (len (list (parcel_mapping .parcels )), len (expected_parcels ))
333+
334+ for (name , expected_surfaces ), parcel in zip (expected_parcels , parcel_mapping .parcels ):
335+ assert_equal (parcel .name , name )
336+ assert_equal (len (parcel .vertices ), 2 )
337+ for vertices , orientation , (length , first_element , last_element ) in zip (parcel .vertices , ('LEFT' , 'RIGHT' ),
338+ expected_surfaces ):
339+ assert_equal (len (vertices ), length )
340+ assert_equal (vertices [0 ], first_element )
341+ assert_equal (vertices [- 1 ], last_element )
342+ assert_equal (vertices .brain_structure , 'CIFTI_STRUCTURE_CORTEX_%s' % orientation )
343+
344+
345+ @needs_nibabel_data ('nitest-cifti2' )
346+ def test_read_scalar ():
347+ img = ci .Cifti2Image .from_filename (DATA_FILE2 )
348+ scalar_mapping = img .header .matrix .get_index_map (0 )
349+
350+ expected_names = ('MyelinMap_BC_decurv' , 'corrThickness' )
351+ assert_equal (img .shape [0 ], len (expected_names ))
352+ assert_equal (len (list (scalar_mapping .named_maps )), len (expected_names ))
353+
354+ expected_meta = [('PaletteColorMapping' , '<PaletteColorMapping Version="1">\n <ScaleMo' )]
355+ for scalar , name in zip (scalar_mapping .named_maps , expected_names ):
356+ assert_equal (scalar .map_name , name )
357+
358+ assert_equal (len (scalar .metadata ), len (expected_meta ))
359+ print (expected_meta [0 ], scalar .metadata .data .keys ())
360+ for key , value in expected_meta :
361+ assert_true (key in scalar .metadata .data .keys ())
362+ assert_equal (scalar .metadata [key ][:len (value )], value )
363+
364+ assert_equal (scalar .label_table , None , ".dscalar file should not define a label table" )
365+
366+
367+ @needs_nibabel_data ('nitest-cifti2' )
368+ def test_read_series ():
369+ img = ci .Cifti2Image .from_filename (DATA_FILE4 )
370+ series_mapping = img .header .matrix .get_index_map (0 )
371+ assert_equal (series_mapping .series_start , 0. )
372+ assert_equal (series_mapping .series_step , 1. )
373+ assert_equal (series_mapping .series_unit , 'SECOND' )
374+ assert_equal (series_mapping .series_exponent , 0. )
375+ assert_equal (series_mapping .number_of_series_points , img .shape [0 ])
376+
377+
378+ @needs_nibabel_data ('nitest-cifti2' )
379+ def test_read_labels ():
380+ img = ci .Cifti2Image .from_filename (DATA_FILE5 )
381+ label_mapping = img .header .matrix .get_index_map (0 )
382+
383+ expected_names = ['Composite Parcellation-lh (FRB08_OFP03_retinotopic)' ,
384+ 'Brodmann lh (from colin.R via pals_R-to-fs_LR)' ,
385+ 'MEDIAL WALL lh (fs_LR)' ]
386+ assert_equal (img .shape [0 ], len (expected_names ))
387+ assert_equal (len (list (label_mapping .named_maps )), len (expected_names ))
388+
389+ some_expected_labels = {0 : ('???' , (0.667 , 0.667 , 0.667 , 0.0 )),
390+ 1 : ('MEDIAL.WALL' , (0.075 , 0.075 , 0.075 , 1.0 )),
391+ 2 : ('BA2_FRB08' , (0.467 , 0.459 , 0.055 , 1.0 )),
392+ 3 : ('BA1_FRB08' , (0.475 , 0.722 , 0.859 , 1.0 )),
393+ 4 : ('BA3b_FRB08' , (0.855 , 0.902 , 0.286 , 1.0 )),
394+ 5 : ('BA4p_FRB08' , (0.902 , 0.573 , 0.122 , 1.0 )),
395+ 89 : ('36_B05' , (0.467 , 0.0 , 0.129 , 1.0 )),
396+ 90 : ('35_B05' , (0.467 , 0.067 , 0.067 , 1.0 )),
397+ 91 : ('28_B05' , (0.467 , 0.337 , 0.271 , 1.0 )),
398+ 92 : ('29_B05' , (0.267 , 0.0 , 0.529 , 1.0 )),
399+ 93 : ('26_B05' , (0.757 , 0.2 , 0.227 , 1.0 )),
400+ 94 : ('33_B05' , (0.239 , 0.082 , 0.373 , 1.0 )),
401+ 95 : ('13b_OFP03' , (1.0 , 1.0 , 0.0 , 1.0 ))}
402+
403+ for named_map , name in zip (label_mapping .named_maps , expected_names ):
404+ assert_equal (named_map .map_name , name )
405+ assert_equal (len (named_map .metadata ), 0 )
406+ assert_equal (len (named_map .label_table ), 96 )
407+ for index , (label , rgba ) in some_expected_labels .items ():
408+ assert_equal (named_map .label_table [index ].label , label )
409+ assert_equal (named_map .label_table [index ].rgba , rgba )
410+
411+
211412class TestCifti2SingleHeader (TestNifti2SingleHeader ):
212413 header_class = _Cifti2AsNiftiHeader
213414 _pixdim_message = 'pixdim[1,2,3] should be zero or positive'
0 commit comments