forked from rock-core/tools-pocolog2msgpack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpocolog2msgpack.py
More file actions
79 lines (67 loc) · 3.06 KB
/
Copy pathpocolog2msgpack.py
File metadata and controls
79 lines (67 loc) · 3.06 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 msgpack
def object2relational(input_filename, output_filename, whitelist=()):
"""Convert a MsgPack logfile from object-oriented to relational storage.
The log data produced by pocolog2msgpack can usually be accessed with
log[port_name][sample_idx][field_a]...[field_b]. This is an
object-oriented view of the data because you can easily access a whole
object from the log. This is not convenient if you want to use the data
for, e.g., machine learning, where you typically need the whole dataset
in a 2D array, i.e. a relational view on the data, in which you can
access data in the form log[port_name][feature][sample_idx].
Parameters
----------
input_filename : str
Name of the original logfile
output_filename : str
Name of the converted logfile
whitelist : list or tuple
Usually arrays and vectors (represented as lists in Python) are handled
as basic types and are put in a single column because they can have
dynamic sizes. This is a list of fields that will be scanned
recursively and interpreted as arrays with a fixed length. Note that
you only have to give the name of the field, not the port name.
An example would be ["elements", "names"] if you want fully unravel
a JointState object.
"""
with open(input_filename, "rb") as f:
log = msgpack.unpack(f, encoding="utf8")
port_names = [k for k in log.keys() if not k.endswith(".meta")]
converted_log = dict()
for port_name in port_names:
if len(log[port_name]) == 0:
continue
all_keys = _extract_keys(log[port_name][0], whitelist)
_convert_data(converted_log, log, port_name, all_keys)
_convert_metadata(converted_log, log, port_name)
with open(output_filename, "wb") as f:
msgpack.pack(converted_log, f)
def _extract_keys(sample, whitelist=(), keys=()):
if isinstance(sample, dict):
result = []
for k in sample.keys():
result.extend(_extract_keys(sample[k], whitelist, keys + (k,)))
return result
elif isinstance(sample, list) and (".".join(map(str, keys)) in whitelist):
result = []
for i in range(len(sample)):
result.extend(_extract_keys(sample[i], whitelist, keys + (i,)))
return result
else:
return [keys]
def _convert_data(converted_log, log, port_name, all_keys):
converted_log[port_name] = dict()
for keys in all_keys:
new_key = ".".join(map(str, keys))
if new_key == "":
new_key = "data"
converted_log[port_name][new_key] = []
for t in range(len(log[port_name])):
value = log[port_name][t]
for k in keys:
value = value[k]
converted_log[port_name][new_key].append(value)
def _convert_metadata(converted_log, log, port_name):
metadata = log[port_name + ".meta"]
converted_log[port_name]["timestamp"] = metadata["timestamps"]
n_rows = len(metadata["timestamps"])
converted_log[port_name]["type"] = [metadata["type"]] * n_rows