-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathidfx_io.py
More file actions
79 lines (63 loc) · 2.24 KB
/
idfx_io.py
File metadata and controls
79 lines (63 loc) · 2.24 KB
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
import struct
import numpy as np
__all__ = ["readIdfxFile"]
# Read .idfx files which are created
# for debug purposes by DataBlock.DumpToFile(std::string&)
INT_SIZE = 4
NAME_SIZE = 16
DOUBLE_SIZE = 8
FLOAT_SIZE = 4
HEADER_SIZE = 128
# There is one .idfx file per processor
class IdfxFileField(object):
def __init__(self, fh, byteorder="little"):
# read entry name
q = fh.read(NAME_SIZE)
# cut it at the first 0 (cstring format)
n = q.index(b"\x00")
self.name = q[:n].decode("utf-8")
if self.name == "eof":
return
self.ndims = int.from_bytes(fh.read(INT_SIZE), byteorder)
dims = []
for _ in range(self.ndims):
dims.append(int.from_bytes(fh.read(INT_SIZE), byteorder))
ntot = int(np.prod(dims))
raw = struct.unpack(str(ntot) + "d", fh.read(DOUBLE_SIZE * ntot))
self.array = np.asarray(raw).reshape(dims[::-1])
class IdfxFileDataset(object):
def __init__(self, filename):
# identical to DumpDataset
self.filename = filename
self.metadata = {}
with open(filename, "rb") as fh:
self._read_header(fh)
self._read_fields(fh)
def _read_header(self, fh):
# could easily be identical to DumpDataset
headerSize = 128
q = fh.read(headerSize)
n = q.index(b'\x00')
self.header = q[:n].decode('utf-8')
self.metadata["byteorder"] = "little"
def _read_field(self, fh):
# identical to DumpDataset
if self.metadata["byteorder"] is None:
# "little" is a safe bet. If anyone ever *needs* to analyze big-endian data produced
# with old versions of Idefix, then we could offer some flexibility here.
byteorder = "little"
else:
byteorder = self.metadata["byteorder"]
return IdfxFileField(fh, byteorder)
def _read_fields(self, fh):
self.data = {}
while True:
field = self._read_field(fh)
if field.name == "eof":
break
self.data[field.name] = field.array
def __repr__(self):
return "IdfxFileDataset('%s')" % self.filename
# public API
def readIdfxFile(filename):
return IdfxFileDataset(filename)