22
22
import numpy as np
23
23
24
24
DEBUG_PRINT = False
25
+
25
26
CIFTI_MAP_TYPES = ('CIFTI_INDEX_TYPE_BRAIN_MODELS' ,
26
27
'CIFTI_INDEX_TYPE_PARCELS' ,
27
28
'CIFTI_INDEX_TYPE_SERIES' ,
71
72
72
73
73
74
class CiftiMetaData (object ):
74
- """ A list of GiftiNVPairs in stored in
75
- the list self.data """
76
- def __init__ (self , nvpair = None ):
75
+ """ A list of CiftiNVPairs in stored in the list self.data """
76
+
77
+ def __init__ (self , nvpair = None ):
77
78
self .data = []
78
- if not nvpair is None :
79
- if isinstance (nvpair , list ):
80
- self .data .extend (nvpair )
79
+ self .add_metadata (nvpair )
80
+
81
+ def _add_remove_metadata (self , metadata , func ):
82
+ pairs = []
83
+ if isinstance (metadata , (list , tuple )):
84
+ if isinstance (metadata [0 ], basestring ):
85
+ if len (metadata ) != 2 :
86
+ raise ValueError ('nvpair must be a 2-list or 2-tuple' )
87
+ pairs = [tuple ((metadata [0 ], metadata [1 ]))]
88
+ else :
89
+ for item in metadata :
90
+ self ._add_remove_metadata (item , func )
91
+ return
92
+ elif isinstance (metadata , dict ):
93
+ pairs = metadata .items ()
94
+ else :
95
+ raise ValueError ('nvpair input must be a list, tuple or dict' )
96
+ for pair in pairs :
97
+ if func == 'add' :
98
+ if pair not in self .data :
99
+ self .data .append (pair )
100
+ elif func == 'remove' :
101
+ self .data .remove (pair )
81
102
else :
82
- self . data . append ( nvpair )
103
+ raise ValueError ( 'Unknown func %s' % func )
83
104
84
- @classmethod
85
- def from_dict (klass , data_dict ):
86
- meda = klass ()
87
- for k ,v in data_dict .items ():
88
- nv = CiftiNVPair (k , v )
89
- meda .data .append (nv )
90
- return meda
105
+ def add_metadata (self , metadata ):
106
+ """Add metadata key-value pairs
91
107
92
- def get_metadata (self ):
93
- """ Returns metadata as dictionary """
94
- self .data_as_dict = {}
95
- for ele in self .data :
96
- self .data_as_dict [ele .name ] = ele .value
97
- return self .data_as_dict
108
+ This allows storing multiple keys with the same name but different
109
+ values.
110
+
111
+
112
+ Parameters
113
+ ----------
114
+ metadata : 2-List, 2-Tuple, Dictionary, List[2-List or 2-Tuple]
115
+ Tuple[2-List or 2-Tuple]
116
+
117
+ Returns
118
+ -------
119
+ None
120
+
121
+ """
122
+ if metadata is None :
123
+ return
124
+ self ._add_remove_metadata (metadata , 'add' )
125
+
126
+ def remove_metadata (self , metadata ):
127
+ if metadata is None :
128
+ return
129
+ self ._add_remove_metadata (metadata , 'remove' )
98
130
99
131
def to_xml (self , prefix = '' , indent = ' ' ):
100
132
if len (self .data ) == 0 :
101
133
return ''
102
134
res = "%s<MetaData>\n " % prefix
103
135
preindent = prefix + indent
104
- for ele in self .data :
136
+ for name , value in self .data :
105
137
nvpair = """%s<MD>
106
138
%s<Name>%s</Name>
107
139
%s<Value>%s</Value>
108
- %s</MD>\n """ % (preindent , preindent + indent , ele . name , preindent + indent ,
109
- ele . value , preindent )
140
+ %s</MD>\n """ % (preindent , preindent + indent , name , preindent + indent ,
141
+ value , preindent )
110
142
res += nvpair
111
143
res += "%s</MetaData>\n " % prefix
112
144
return res
113
145
114
- def print_summary (self ):
115
- print (self .get_metadata ())
116
-
117
-
118
- class CiftiNVPair (object ):
119
-
120
- name = str
121
- value = str
122
-
123
- def __init__ (self , name = '' , value = '' ):
124
- self .name = name
125
- self .value = value
126
146
127
147
class CiftiLabelTable (object ):
128
148
@@ -160,16 +180,6 @@ def print_summary(self):
160
180
161
181
162
182
class CiftiLabel (object ):
163
- key = int
164
- label = str
165
- # rgba
166
- # freesurfer examples seem not to conform
167
- # to datatype "NIFTI_TYPE_RGBA32" because they
168
- # are floats, not unsigned 32-bit integers
169
- red = float
170
- green = float
171
- blue = float
172
- alpha = float
173
183
174
184
def __init__ (self , key = 0 , label = '' , red = None ,\
175
185
green = None , blue = None , alpha = None ):
@@ -337,7 +347,7 @@ def add_cifti_vertices(self, vertices):
337
347
self .vertices .append (vertices )
338
348
self .numVA += 1
339
349
else :
340
- print ( "mim paramater must be of type CiftiMatrixIndicesMap " )
350
+ raise TypeError ( "Not a valid CiftiVertices instance " )
341
351
342
352
def remove_cifti_vertices (self , ith ):
343
353
""" Removes the ith vertices element from the CiftiParcel """
@@ -543,7 +553,7 @@ def add_cifti_brain_model(self, brain_model):
543
553
self .brainModels .append (brain_model )
544
554
self .numBrainModels += 1
545
555
else :
546
- print ( "brain_model parameter must be of type CiftiBrainModel" )
556
+ raise TypeError ( "Not a valid CiftiBrainModel instance " )
547
557
548
558
def remove_cifti_brain_model (self , ith ):
549
559
""" Removes the ith brain model element from the CiftiMatrixIndicesMap """
@@ -561,7 +571,7 @@ def add_cifti_named_map(self, named_map):
561
571
self .namedMaps .append (named_map )
562
572
self .numNamedMaps += 1
563
573
else :
564
- print ( "named_map parameter must be of type CiftiNamedMap" )
574
+ raise TypeError ( "Not a valid CiftiNamedMap instance " )
565
575
566
576
def remove_cifti_named_map (self , ith ):
567
577
""" Removes the ith named_map element from the CiftiMatrixIndicesMap """
@@ -579,7 +589,7 @@ def add_cifti_parcel(self, parcel):
579
589
self .parcels .append (parcel )
580
590
self .numParcels += 1
581
591
else :
582
- print ( "parcel parameter must be of type CiftiParcel" )
592
+ raise TypeError ( "Not a valid CiftiParcel instance " )
583
593
584
594
def remove_cifti_parcel (self , ith ):
585
595
""" Removes the ith parcel element from the CiftiMatrixIndicesMap """
@@ -597,7 +607,7 @@ def add_cifti_surface(self, surface):
597
607
self .surfaces .append (surface )
598
608
self .numSurfaces += 1
599
609
else :
600
- print ( "surface parameter must be of type CiftiSurface" )
610
+ raise TypeError ( "Not a valid CiftiSurface instance " )
601
611
602
612
def remove_cifti_surface (self , ith ):
603
613
""" Removes the ith surface element from the CiftiMatrixIndicesMap """
@@ -614,7 +624,7 @@ def set_cifti_volume(self, volume):
614
624
if isinstance (volume , CiftiVolume ):
615
625
self .volume = volume
616
626
else :
617
- print ( "volume parameter must be of type CiftiVolume" )
627
+ raise TypeError ( "Not a valid CiftiVolume instance " )
618
628
619
629
def remove_cifti_volume (self ):
620
630
""" Removes the volume element from the CiftiMatrixIndicesMap """
@@ -691,7 +701,7 @@ def add_cifti_matrix_indices_map(self, mim):
691
701
self .mims .append (mim )
692
702
self .numMIM += 1
693
703
else :
694
- print ( "mim paramater must be of type CiftiMatrixIndicesMap" )
704
+ raise TypeError ( "Not a valid CiftiMatrixIndicesMap instance " )
695
705
696
706
def remove_cifti_matrix_indices_map (self , ith ):
697
707
""" Removes the ith matrix indices map element from the CiftiMatrix """
@@ -788,7 +798,7 @@ def to_filename(self, filename):
788
798
if not filename .endswith ('nii' ):
789
799
ValueError ('CIFTI files have to be stored as uncompressed NIFTI2' )
790
800
from ..nifti2 import Nifti2Image
791
- from ..nifti1 import Nifti1Extensions , Nifti1Extension
801
+ from ..nifti1 import Nifti1Extension
792
802
data = np .reshape (self .data , [1 , 1 , 1 , 1 ] + list (self .data .shape ))
793
803
header = self .extra
794
804
extension = Nifti1Extension (32 , self .header .to_xml ())
@@ -837,7 +847,7 @@ def load(filename):
837
847
IOError : if `filename` does not exist
838
848
"""
839
849
from ..nifti2 import load as Nifti2load
840
- return Nifti2load (filename )
850
+ return Nifti2load (filename ). as_cifti ()
841
851
842
852
843
853
def save (img , filename ):
0 commit comments