parse.py 3.05 KB
Newer Older
1
import pandas as pd
2
3
import ruamel.yaml
import ruamel.yaml as yaml
4

5
6
7
8

def _stamp_name_by_src_and_type(all_stamps, src, kind=None):
    if kind is None:
        kind = ["time", "cycle"]
9
    return [c for c, v in all_stamps.items() if v["Source"] == src and v["Type"] in kind]
10

11

12
13
def _extract_stamps_by_type(all_stamps, src, kind=None):
    columns = _stamp_name_by_src_and_type(all_stamps, src, kind)
14
    return [x + "_T" for x in columns] + [x + "_C" for x in columns]
15

16
17

def _evaluate_file(file_name, stamps, kind, sender=False):
18
    # Remove first line, as this is the dummy line for intermittently storing data.
19
    df = pd.read_csv(file_name)[1:]
20

21
    df = df[df["Kind"] == kind].drop(["Kind"], axis=1).set_index("SeqNo")
22
23

    # Drop columns of opposing side.
24
    if sender:
25
        df.drop(_extract_stamps_by_type(stamps, "receiver"), axis=1, inplace=True)
26
    else:
27
        df.drop(_extract_stamps_by_type(stamps, "sender"), axis=1, inplace=True)
28
29
30

    # Drop empty rows (as they have probably not been written out).
    return df[pd.notnull(df).all(axis=1)]
31
32


33
def _diff_t_c(df, start, stop):
34
35
    time = df[stop + "_T"] - df[start + "_T"]
    cycles = (df[stop + "_C"] - df[start + "_C"])
36
    return time.astype(float), cycles.astype(float)
37
38


39
def evaluate(sender_file, receiver_file, config, kind=0):
40
41
42
    stamps = config["stamps"]
    df1 = _evaluate_file(sender_file, stamps, kind, True)
    df2 = _evaluate_file(receiver_file, stamps, kind)
43
44
    df = df1.join(df2)

45
46
    tr = config["time_reference"]
    cr = config["cycle_reference"]
47

48
49
    # Determine Channel Duration
    df["Channel_D"] = df[tr["receiver"]["Start"] + "_T"] - df[tr["sender"]["Stop"] + "_T"]
50

51
52
53
    # Correlate Receiver Timestamps with Sender Timestamps (subtracting Channel Duration)
    for s in _stamp_name_by_src_and_type(stamps, "receiver", kind=["time"]):
        df[s + "_T"] -= df["Channel_D"]
54

55
56
57
    for src in ["sender", "receiver"]:
        # Generate Processing Duration
        src_name = src.capitalize()
58

59
        time, cycles = _diff_t_c(df, tr[src]["Start"], tr[src]["Stop"])
60
61
        df[src_name + "_D"] = time
        df[src_name + "_C"] = cycles
62

63
        # Generate Cycle Times
64
65
        time, cycles = _diff_t_c(df, cr[src]["Start"], cr[src]["Stop"])
        df[src_name + "Cycle_D"] = time / cycles
66

67
68
69
70
71
        # Recreate missing timestamps from cycles
        for stamp_name in _stamp_name_by_src_and_type(stamps, src, "cycle"):
            start_stamp = tr[src]["Start"]
            diff = df[stamp_name + "_C"] - df[start_stamp + "_C"]
            df[stamp_name + "_T"] = (diff * df[src_name + "Cycle_D"] + df[start_stamp + "_T"]).astype(int)
72

73
74
75
    # Generate Durations
    for name, duration in config["durations"].items():
        diff = df[duration["Stop"] + "_C"] - df[duration["Start"] + "_C"]
76
        df[name + "_C"] = diff
77
78
        df[name + "_D"] = diff * df[duration["Source"].capitalize() + "Cycle_D"]

79
    df["EndToEnd_D"] = df["Sender_D"] + df["Receiver_D"]
80
81

    return df
82
83
84
85
86
87


def parse_config(file_name="xlap.yml"):
    with open(file_name) as f:
        contents = f.read()
    return yaml.load(contents, Loader=ruamel.yaml.Loader)