Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

169 lines
6.4KB

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