-
Notifications
You must be signed in to change notification settings - Fork 9
/
h5py_wrapper.py
169 lines (141 loc) · 4.93 KB
/
h5py_wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 16 11:40:42 2012.
@author: mel
"""
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import (ascii, bytes, chr, dict, filter, hex, input, # noqa
int, map, next, oct, open, pow, range, round,
str, super, zip)
import logging
import h5py
logger = logging.getLogger('abt.anypytools')
def _follow_reftarget(elem):
completename = elem.attrs['CompleteName']
completename = completename.replace(b'.', b'/')
reftarget = elem.attrs['RefTarget'].replace(b'.', b'/')
prefix = completename[:-len(elem.name)]
h5target = reftarget[len(prefix):]
elem = elem.file[h5target]
return elem
def _check_input_path(path):
"""Convert dot notation to stardard h5py path."""
if "/" not in path:
# path does not have traditional h5 format.
if path.startswith('Main.') and 'Output' in path:
path = '/Output' + path.split('Output')[-1]
path = path.replace('.', '/')
return path
class File(h5py.File): # noqa
__doc__ = h5py.File.__doc__
def __init__(self, *args, **kwargs): # noqa
super(File, self).__init__(*args, **kwargs)
self.wrapped = True
def __getitem__(self, path): # noqa
"""."""
path = _check_input_path(path)
try:
elem = super(File, self).file[path]
if isinstance(elem, h5py.Group) and not len(elem.keys()):
if 'RefTarget' in elem.attrs:
elem = _follow_reftarget(elem)
except KeyError:
elem = super(type(self), self)
levels = path.strip('/').split('/')
for level in levels:
if elem.__contains__(level):
elem = elem.__getitem__(level)
else:
try:
elem = _follow_reftarget(elem)
elem = elem.__getitem__(level)
except:
raise KeyError('Entry not found: ' + path)
if isinstance(elem, h5py.Group):
return Group(elem.id)
elif isinstance(elem, h5py.Dataset):
return Dataset(elem.id)
elif isinstance(elem, h5py.File):
return File(elem.id)
@property
def file(self): # noqa
id = super(File, self).file.id
return File(id)
@property
def parent(self): # noqa
id = super(File, self).parent.id
return Group(id)
def __contains__(self, name): # noqa
""" Test if a member name exists """
if super(File, self).__contains__(name):
return True
else:
try:
self.__getitem__(name)
return True
except KeyError:
pass
return False
class Group(h5py.Group): # noqa
__doc__ = h5py.Group.__doc__
def __init__(self, arg): # noqa
super(Group, self).__init__(arg)
self.wrapped = True
def __getitem__(self, path): # noqa
path = _check_input_path(path)
try:
elem = super(Group, self).__getitem__(path)
if isinstance(elem, h5py.Group) and not len(elem.keys()):
if 'RefTarget' in elem.attrs:
elem = _follow_reftarget(elem)
except KeyError:
elem = super(type(self), self)
levels = path.strip('/').split('/')
for level in levels:
if elem.__contains__(level):
elem = elem.__getitem__(level)
else:
try:
elem = _follow_reftarget(elem)
elem = elem.__getitem__(level)
except:
raise KeyError('Entry not found: ' + path)
if isinstance(elem, h5py.Group):
return Group(elem.id)
elif isinstance(elem, h5py.Dataset):
return Dataset(elem.id)
elif isinstance(elem, h5py.File):
return File(elem.id)
@property
def file(self): # noqa
id = super(Group, self).file.id
return File(id)
@property
def parent(self): # noqa
id = super(Group, self).parent.id
return Group(id)
def __contains__(self, name): # noqa
""" Test if a member name exists """
if super(Group, self).__contains__(name):
return True
else:
try:
self.__getitem__(name)
return True
except KeyError:
pass
return False
class Dataset(h5py.Dataset): # noqa
__doc__ = h5py.Dataset.__doc__
def __init__(self, arg): # noqa
super(Dataset, self).__init__(arg)
self.wrapped = True
@property
def file(self): # noqa
id = super(Dataset, self).file.id
return File(id)
@property
def parent(self): # noqa
id = super(Dataset, self).parent.id
return Group(id)