Source code for pocolog2msgpack.object2relational

import msgpack


[docs] 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) 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