Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

196 lines
7.6KB

  1. #!/usr/bin/env python3
  2. import math
  3. import multiprocessing
  4. import os
  5. import pickle
  6. from argparse import ArgumentParser
  7. import matplotlib
  8. import pandas as pd
  9. import matplotlib.pyplot as plt
  10. def convert_bandwidth(value):
  11. if value == 0:
  12. return 1.4
  13. elif value == 1:
  14. return 3
  15. elif value == 2:
  16. return 5
  17. elif value == 3:
  18. return 10
  19. elif value == 4:
  20. return 15
  21. elif value == 5:
  22. return 20
  23. else:
  24. return 0
  25. if __name__ == "__main__":
  26. parser = ArgumentParser()
  27. parser.add_argument("-s", "--serial_file", required=True, help="Serial csv file.")
  28. parser.add_argument("-p", "--pcap_csv_folder", required=True, help="PCAP csv folder.")
  29. parser.add_argument("--save", default=None, help="Location to save pdf file.")
  30. parser.add_argument(
  31. "-i",
  32. "--interval",
  33. default=10,
  34. type=int,
  35. help="Time interval for rolling window.",
  36. )
  37. args = parser.parse_args()
  38. manager = multiprocessing.Manager()
  39. n = manager.Value("i", 0)
  40. frame_list = manager.list()
  41. jobs = []
  42. # load all pcap csv into one dataframe
  43. pcap_csv_list = list()
  44. for filename in os.listdir(args.pcap_csv_folder):
  45. if filename.endswith(".csv") and "tcp" in filename:
  46. pcap_csv_list.append(filename)
  47. counter = 1
  48. if len(pcap_csv_list) == 0:
  49. print("No CSV files found.")
  50. pcap_csv_list.sort(key=lambda x: int(x.split("_")[-1].replace(".csv", "")))
  51. for csv in pcap_csv_list:
  52. print("\rProcessing {} out of {} CSVs.\t({}%)\t".format(counter, len(pcap_csv_list), math.floor(counter/len(pcap_csv_list))))
  53. try:
  54. transmission_df = pd.read_csv(
  55. "{}{}".format(args.pcap_csv_folder, csv),
  56. dtype=dict(is_retranmission=bool, is_dup_ack=bool),
  57. converters={"UL_bandwidth": convert_bandwidth, "DL_bandwidth": convert_bandwidth},
  58. )
  59. transmission_df["datetime"] = pd.to_datetime(transmission_df["datetime"]) - pd.Timedelta(hours=1)
  60. transmission_df = transmission_df.set_index("datetime")
  61. transmission_df.index = pd.to_datetime(transmission_df.index)
  62. transmission_df = transmission_df.sort_index()
  63. # srtt to [s]
  64. transmission_df["srtt"] = transmission_df["srtt"].apply(lambda x: x / 10**6)
  65. # key for columns and level for index
  66. transmission_df["goodput"] = transmission_df["payload_size"].groupby(pd.Grouper(level="datetime", freq="{}s".format(args.interval))).transform("sum")
  67. transmission_df["goodput"] = transmission_df["goodput"].apply(
  68. lambda x: ((x * 8) / args.interval) / 10**6
  69. )
  70. transmission_df["goodput_rolling"] = transmission_df["payload_size"].rolling("{}s".format(args.interval)).sum()
  71. transmission_df["goodput_rolling"] = transmission_df["goodput_rolling"].apply(
  72. lambda x: ((x * 8) / args.interval) / 10 ** 6
  73. )
  74. # set meta values and remove all not needed columns
  75. cc_algo = transmission_df["congestion_control"].iloc[0]
  76. cc_algo = cc_algo.upper()
  77. transmission_direction = transmission_df["direction"].iloc[0]
  78. #transmission_df = transmission_df.filter(["goodput", "datetime", "ack_rtt", "goodput_rolling", "snd_cwnd"])
  79. # read serial csv
  80. serial_df = pd.read_csv(args.serial_file)
  81. serial_df["datetime"] = pd.to_datetime(serial_df["datetime"]) - pd.Timedelta(hours=1)
  82. serial_df = serial_df.set_index("datetime")
  83. serial_df.index = pd.to_datetime(serial_df.index)
  84. serial_df.sort_index()
  85. transmission_df = pd.merge_asof(
  86. transmission_df,
  87. serial_df,
  88. tolerance=pd.Timedelta("1s"),
  89. right_index=True,
  90. left_index=True,
  91. )
  92. # transmission timeline
  93. scaley = 1.5
  94. scalex = 1.0
  95. fig, ax = plt.subplots(figsize=[6.4 * scaley, 4.8 * scalex])
  96. plt.title("{} with {}".format(transmission_direction, cc_algo))
  97. fig.subplots_adjust(right=0.75)
  98. twin1 = ax.twinx()
  99. twin2 = ax.twinx()
  100. twin3 = ax.twinx()
  101. twin4 = ax.twinx()
  102. # Offset the right spine of twin2. The ticks and label have already been
  103. # placed on the right by twinx above.
  104. twin2.spines.right.set_position(("axes", 1.1))
  105. twin3.spines.right.set_position(("axes", 1.2))
  106. twin4.spines.right.set_position(("axes", 1.3))
  107. # create list fo color indices
  108. transmission_df["index"] = transmission_df.index
  109. color_dict = dict()
  110. color_list = list()
  111. i = 0
  112. for cell_id in transmission_df["cellID"]:
  113. if cell_id not in color_dict:
  114. color_dict[cell_id] = i
  115. i += 1
  116. color_list.append(color_dict[cell_id])
  117. transmission_df["cell_color"] = color_list
  118. color_dict = None
  119. color_list = None
  120. cmap = matplotlib.cm.get_cmap("Set3")
  121. unique_cells = transmission_df["cell_color"].unique()
  122. color_list = cmap.colors * (round(len(unique_cells) / len(cmap.colors)) + 1)
  123. for c in transmission_df["cell_color"].unique():
  124. bounds = transmission_df[["index", "cell_color"]].groupby("cell_color").agg(["min", "max"]).loc[c]
  125. ax.axvspan(bounds.min(), bounds.max(), alpha=0.3, color=color_list[c])
  126. p4, = twin3.plot(transmission_df["snd_cwnd"].dropna(), color="lime", linestyle="dashed", label="cwnd")
  127. p3, = twin2.plot(transmission_df["srtt"].dropna(), color="red", linestyle="dashdot", label="sRTT")
  128. p1, = ax.plot(transmission_df["goodput_rolling"], color="blue", linestyle="solid", label="goodput")
  129. p2, = twin1.plot(transmission_df["downlink_cqi"].dropna(), color="magenta", linestyle="dotted", label="CQI")
  130. p5, = twin4.plot(transmission_df["DL_bandwidth"].dropna(), color="peru", linestyle="dotted", label="DL_bandwidth")
  131. ax.set_xlim(transmission_df["index"].min(), transmission_df["index"].max())
  132. ax.set_ylim(0, 500)
  133. twin1.set_ylim(0, 15)
  134. twin2.set_ylim(0, 0.2) #twin2.set_ylim(0, transmission_df["ack_rtt"].max())
  135. twin3.set_ylim(0, transmission_df["snd_cwnd"].max() + 10)
  136. twin4.set_ylim(0, 21)
  137. ax.set_xlabel("arrival time")
  138. ax.set_ylabel("Goodput [mbps]")
  139. twin1.set_ylabel("CQI")
  140. twin2.set_ylabel("sRTT [s]")
  141. twin3.set_ylabel("cwnd")
  142. twin4.set_ylabel("DL_bandwidth")
  143. ax.yaxis.label.set_color(p1.get_color())
  144. twin1.yaxis.label.set_color(p2.get_color())
  145. twin2.yaxis.label.set_color(p3.get_color())
  146. twin3.yaxis.label.set_color(p4.get_color())
  147. tkw = dict(size=4, width=1.5)
  148. ax.tick_params(axis='y', colors=p1.get_color(), **tkw)
  149. twin1.tick_params(axis='y', colors=p2.get_color(), **tkw)
  150. twin2.tick_params(axis='y', colors=p3.get_color(), **tkw)
  151. twin3.tick_params(axis='y', colors=p4.get_color(), **tkw)
  152. ax.tick_params(axis='x', **tkw)
  153. #ax.legend(handles=[p1, p2, p3])
  154. if args.save:
  155. plt.savefig("{}{}_plot.pdf".format(args.save, csv.replace(".csv", "")))
  156. except Exception as e:
  157. print("Error processing file: {}".format(csv))
  158. print(str(e))
  159. counter += 1
  160. plt.clf()