Skip to content

Commit 658030b

Browse files
committed
ENH: Create CaretMetaData object to unify GIFTI/CIFTI-2/CaretSpecFile metadata
1 parent e7e1d46 commit 658030b

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

nibabel/caret.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
3+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
4+
#
5+
# See COPYING file distributed along with the NiBabel package for the
6+
# copyright and license terms.
7+
#
8+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
9+
from collections.abc import MutableMapping
10+
11+
from . import xmlutils as xml
12+
13+
14+
class CaretMetaData(xml.XmlSerializable, MutableMapping):
15+
""" A list of name-value pairs used in various Caret-based XML formats
16+
17+
* Description - Provides a simple method for user-supplied metadata that
18+
associates names with values.
19+
* Attributes: [NA]
20+
* Child Elements
21+
22+
* MD (0...N)
23+
24+
* Text Content: [NA]
25+
26+
MD elements are a single metadata entry consisting of a name and a value.
27+
28+
Attributes
29+
----------
30+
data : mapping of {name: value} pairs
31+
32+
>>> md = CaretMetaData()
33+
>>> md['key'] = 'val'
34+
>>> md
35+
<CaretMetaData {'key': 'val'}>
36+
>>> dict(md)
37+
{'key': 'val'}
38+
>>> md.to_xml()
39+
b'<MetaData><MD><Name>key</Name><Value>val</Value></MD></MetaData>'
40+
41+
Objects may be constructed like any ``dict``:
42+
43+
>>> md = CaretMetaData(key='val')
44+
>>> md.to_xml()
45+
b'<MetaData><MD><Name>key</Name><Value>val</Value></MD></MetaData>'
46+
"""
47+
def __init__(self, *args, **kwargs):
48+
self._data = dict(*args, **kwargs)
49+
50+
def __getitem__(self, key):
51+
""" Get metadata entry by name
52+
53+
>>> md = CaretMetaData({'key': 'val'})
54+
>>> md['key']
55+
'val'
56+
"""
57+
return self._data[key]
58+
59+
def __setitem__(self, key, value):
60+
""" Set metadata entry by name
61+
62+
>>> md = CaretMetaData({'key': 'val'})
63+
>>> dict(md)
64+
{'key': 'val'}
65+
>>> md['newkey'] = 'newval'
66+
>>> dict(md)
67+
{'key': 'val', 'newkey': 'newval'}
68+
>>> md['key'] = 'otherval'
69+
>>> dict(md)
70+
{'key': 'otherval', 'newkey': 'newval'}
71+
"""
72+
self._data[key] = value
73+
74+
def __delitem__(self, key):
75+
""" Delete metadata entry by name
76+
77+
>>> md = CaretMetaData({'key': 'val'})
78+
>>> dict(md)
79+
{'key': 'val'}
80+
>>> del md['key']
81+
>>> dict(md)
82+
{}
83+
"""
84+
del self._data[key]
85+
86+
def __len__(self):
87+
""" Get length of metadata list
88+
89+
>>> md = CaretMetaData({'key': 'val'})
90+
>>> len(md)
91+
1
92+
"""
93+
return len(self._data)
94+
95+
def __iter__(self):
96+
""" Iterate over metadata entries
97+
98+
>>> md = CaretMetaData({'key': 'val'})
99+
>>> for key in md:
100+
... print(key)
101+
key
102+
"""
103+
return iter(self._data)
104+
105+
def __repr__(self):
106+
return f"<{self.__class__.__name__} {self._data!r}>"
107+
108+
def _to_xml_element(self):
109+
metadata = xml.Element('MetaData')
110+
111+
for name_text, value_text in self._data.items():
112+
md = xml.SubElement(metadata, 'MD')
113+
name = xml.SubElement(md, 'Name')
114+
name.text = str(name_text)
115+
value = xml.SubElement(md, 'Value')
116+
value.text = str(value_text)
117+
return metadata

0 commit comments

Comments
 (0)