import numpy as np import math import pandas as pd import collections from operator import itemgetter from sklearn import datasets, linear_model def _extract_duration_by_src(all_durations, src): return [c for c, v in all_durations.items() if v["Source"] == src] def _stamp_name_by_src_and_type(all_stamps, src, kind=None): if kind is None: kind = ["time", "cycle"] columns = [c for c, v in all_stamps.items() if v["Source"] == src and v["Type"] in kind] return columns def _extract_stamps_by_type(all_stamps, src, kind=None): columns = _stamp_name_by_src_and_type(all_stamps, src, kind) return _stamp_names(columns) def _stamp_names(columns): stamps = [x + "_T" for x in columns] + [x + "_C" for x in columns] return stamps def _evaluate_file(file_name, stamps, kind, sender=False): # Remove first line, as this is the dummy line for intermittently storing data. df = pd.read_csv(file_name)[1:] df = df[df["Kind"] == kind].drop(["Kind"], axis=1).set_index("SeqNo") if sender: df.drop(_extract_stamps_by_type(stamps, "receiver"), axis=1, inplace=True) else: df.drop(_extract_stamps_by_type(stamps, "sender"), axis=1, inplace=True) df = df[pd.notnull(df).all(axis=1)] return df def _diff_t_c(df, name, start, stop): time = df[stop + "_T"] - df[start + "_T"] cycles = (df[stop + "_C"] - df[start + "_C"]) return time.astype(float), cycles.astype(float) def _generate_cycle_time(df, name, start, stop): time, cycles = _diff_t_c(df, name, start, stop) df[name + "Cycle_D"] = time / cycles def _generate_duration(df, name, start, stop, cycle_time_column): diff = df[stop + "_C"] - df[start + "_C"] df[name + "Cycles"] = diff df[name + "Time"] = diff * df[cycle_time_column + "Cycle_D"] def evaluate(sender_file, receiver_file, config, kind=0): stamps = config["stamps"] df1 = _evaluate_file(sender_file, stamps, kind, True) df2 = _evaluate_file(receiver_file, stamps, kind) df = df1.join(df2) tr = config["time_reference"] cr = config["cycle_reference"] # Determine Channel Duration df["Channel_D"] = df[tr["receiver"]["Start"] + "_T"] - df[tr["sender"]["Stop"] + "_T"] # 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"] for src in ["sender", "receiver"]: # Generate Processing Duration src_name = src.capitalize() time, cycles = _diff_t_c(df, src_name, tr[src]["Start"], tr[src]["Stop"]) df[src_name + "_D"] = time df[src_name + "_C"] = cycles # Generate Cycle Times _generate_cycle_time(df, src_name, cr[src]["Start"], cr[src]["Stop"]) # 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) # Generate Durations for name, duration in config["durations"].items(): diff = df[duration["Stop"] + "_C"] - df[duration["Start"] + "_C"] df[name + "Cycles"] = diff df[name + "_D"] = diff * df[duration["Source"].capitalize() + "Cycle_D"] df["EndToEndTime"] = df["Sender_D"] + df["Receiver_D"] return df