23
23
import base64
24
24
25
25
26
- class GiftiMetaData (object ):
26
+ class XmlSerializable (object ):
27
+ """ Basic interface for serializing an object to xml"""
28
+ def _to_xml_element (self ):
29
+ """ Output should be a xml.etree.ElementTree.Element"""
30
+ raise NotImplementedError ()
31
+
32
+ def to_xml (self , enc = 'utf-8' ):
33
+ """ Output should be an xml string with the given encoding.
34
+ (default: utf-8)"""
35
+ return xml .tostring (self ._to_xml_element (), enc )
36
+
37
+
38
+ class GiftiMetaData (XmlSerializable ):
27
39
""" A list of GiftiNVPairs in stored in
28
40
the list self.data """
29
41
def __init__ (self , nvpair = None ):
@@ -51,15 +63,15 @@ def metadata(self):
51
63
self .data_as_dict [ele .name ] = ele .value
52
64
return self .data_as_dict
53
65
54
- def to_xml (self ):
66
+ def _to_xml_element (self ):
55
67
metadata = xml .Element ('MetaData' )
56
68
for ele in self .data :
57
69
md = xml .SubElement (metadata , 'MD' )
58
70
name = xml .SubElement (md , 'Name' )
59
71
value = xml .SubElement (md , 'Value' )
60
72
name .text = ele .name
61
73
value .text = ele .value
62
- return xml . tostring ( metadata , 'utf-8' )
74
+ return metadata
63
75
64
76
def print_summary (self ):
65
77
print (self .metadata )
@@ -75,7 +87,7 @@ def __init__(self, name='', value=''):
75
87
self .value = value
76
88
77
89
78
- class GiftiLabelTable (object ):
90
+ class GiftiLabelTable (XmlSerializable ):
79
91
80
92
def __init__ (self ):
81
93
self .labels = []
@@ -86,7 +98,7 @@ def get_labels_as_dict(self):
86
98
self .labels_as_dict [ele .key ] = ele .label
87
99
return self .labels_as_dict
88
100
89
- def to_xml (self ):
101
+ def _to_xml_element (self ):
90
102
labeltable = xml .Element ('LabelTable' )
91
103
for ele in self .labels :
92
104
label = xml .SubElement (labeltable , 'Label' )
@@ -95,13 +107,13 @@ def to_xml(self):
95
107
for attr in ['Red' , 'Green' , 'Blue' , 'Alpha' ]:
96
108
if getattr (ele , attr .lower (), None ) is not None :
97
109
label .attrib [attr ] = str (getattr (ele , attr .lower ()))
98
- return xml . tostring ( labeltable , 'utf-8' )
110
+ return labeltable
99
111
100
112
def print_summary (self ):
101
113
print (self .get_labels_as_dict ())
102
114
103
115
104
- class GiftiLabel (object ):
116
+ class GiftiLabel (XmlSerializable ):
105
117
key = int
106
118
label = str
107
119
# rgba
@@ -154,7 +166,7 @@ def _arr2txt(arr, elem_fmt):
154
166
return '\n ' .join (fmt % tuple (row ) for row in arr )
155
167
156
168
157
- class GiftiCoordSystem (object ):
169
+ class GiftiCoordSystem (XmlSerializable ):
158
170
dataspace = int
159
171
xformspace = int
160
172
xform = np .ndarray # 4x4 numpy array
@@ -168,7 +180,7 @@ def __init__(self, dataspace=0, xformspace=0, xform=None):
168
180
else :
169
181
self .xform = xform
170
182
171
- def to_xml (self ):
183
+ def _to_xml_element (self ):
172
184
coord_xform = xml .Element ('CoordinateSystemTransformMatrix' )
173
185
if self .xform is not None :
174
186
dataspace = xml .SubElement (coord_xform , 'DataSpace' )
@@ -177,15 +189,15 @@ def to_xml(self):
177
189
xformed_space .text = xform_codes .niistring [self .xformspace ]
178
190
matrix_data = xml .SubElement (coord_xform , 'MatrixData' )
179
191
matrix_data .text = _arr2txt (self .xform , '%10.6f' )
180
- return xml . tostring ( coord_xform , 'utf-8' )
192
+ return coord_xform
181
193
182
194
def print_summary (self ):
183
195
print ('Dataspace: ' , xform_codes .niistring [self .dataspace ])
184
196
print ('XFormSpace: ' , xform_codes .niistring [self .xformspace ])
185
197
print ('Affine Transformation Matrix: \n ' , self .xform )
186
198
187
199
188
- def data_tag (dataarray , encoding , datatype , ordering ):
200
+ def _data_tag_element (dataarray , encoding , datatype , ordering ):
189
201
""" Creates the data tag depending on the required encoding,
190
202
returns as bytes"""
191
203
import zlib
@@ -205,10 +217,15 @@ def data_tag(dataarray, encoding, datatype, ordering):
205
217
206
218
data = xml .Element ('Data' )
207
219
data .text = da
220
+ return data
221
+
222
+
223
+ def data_tag (dataarray , encoding , datatype , ordering ):
224
+ data = _data_tag_element (dataarray , encoding , datatype , ordering )
208
225
return xml .tostring (data , 'utf-8' )
209
226
210
227
211
- class GiftiDataArray (object ):
228
+ class GiftiDataArray (XmlSerializable ):
212
229
213
230
# These are for documentation only; we don't use these class variables
214
231
intent = int
@@ -289,7 +306,7 @@ def from_array(klass,
289
306
cda .meta = GiftiMetaData .from_dict (meta )
290
307
return cda
291
308
292
- def to_xml (self ):
309
+ def _to_xml_element (self ):
293
310
# fix endianness to machine endianness
294
311
self .endian = gifti_endian_codes .code [sys .byteorder ]
295
312
@@ -306,18 +323,18 @@ def to_xml(self):
306
323
data_array .attrib ['Dim%d' % di ] = str (dn )
307
324
308
325
if self .meta is not None :
309
- data_array .append (xml . fromstring ( self .meta .to_xml () ))
326
+ data_array .append (self .meta ._to_xml_element ( ))
310
327
if self .coordsys is not None :
311
- data_array .append (xml . fromstring ( self .coordsys .to_xml () ))
328
+ data_array .append (self .coordsys ._to_xml_element ( ))
312
329
# write data array depending on the encoding
313
330
dt_kind = data_type_codes .dtype [self .datatype ].kind
314
- data_array .append (xml . fromstring (
315
- data_tag (self .data ,
316
- gifti_encoding_codes .specs [self .encoding ],
317
- KIND2FMT [dt_kind ],
318
- self .ind_ord ) ))
331
+ data_array .append (
332
+ _data_tag_element (self .data ,
333
+ gifti_encoding_codes .specs [self .encoding ],
334
+ KIND2FMT [dt_kind ],
335
+ self .ind_ord ))
319
336
320
- return xml . tostring ( data_array , 'utf-8' )
337
+ return data_array
321
338
322
339
def print_summary (self ):
323
340
print ('Intent: ' , intent_codes .niistring [self .intent ])
@@ -345,7 +362,8 @@ def metadata(self):
345
362
return self .meta .metadata
346
363
347
364
348
- class GiftiImage (object ):
365
+ class GiftiImage (XmlSerializable ):
366
+
349
367
def __init__ (self , meta = None , labeltable = None , darrays = None ,
350
368
version = "1.0" ):
351
369
if darrays is None :
@@ -472,18 +490,20 @@ def print_summary(self):
472
490
print ('----end----' )
473
491
474
492
475
- def to_xml (self ):
476
- """ Return XML corresponding to image content """
493
+ def _to_xml_element (self ):
477
494
GIFTI = xml .Element ('GIFTI' , attrib = {
478
495
'Version' : self .version ,
479
496
'NumberOfDataArrays' : str (self .numDA )})
480
497
if self .meta is not None :
481
- GIFTI .append (xml . fromstring ( self .meta .to_xml () ))
498
+ GIFTI .append (self .meta ._to_xml_element ( ))
482
499
if self .labeltable is not None :
483
- GIFTI .append (xml . fromstring ( self .labeltable .to_xml () ))
500
+ GIFTI .append (self .labeltable ._to_xml_element ( ))
484
501
for dar in self .darrays :
485
- GIFTI .append (xml .fromstring (dar .to_xml ()))
502
+ GIFTI .append (dar ._to_xml_element ())
503
+ return GIFTI
486
504
505
+ def to_xml (self , enc = 'utf-8' ):
506
+ """ Return XML corresponding to image content """
487
507
return b"""<?xml version="1.0" encoding="UTF-8"?>
488
508
<!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">
489
- """ + xml . tostring ( GIFTI , 'utf-8' )
509
+ """ + XmlSerializable . to_xml ( self , enc )
0 commit comments