選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

210 行
7.9KB

  1. #!/usr/bin/env python3
  2. import math
  3. import multiprocessing
  4. import os
  5. from argparse import ArgumentParser
  6. import matplotlib
  7. import numpy as np
  8. import pandas as pd
  9. import matplotlib.pyplot as plt
  10. # Using seaborn's style
  11. #plt.style.use('seaborn')
  12. tex_fonts = {
  13. "pgf.texsystem": "lualatex",
  14. # "legend.fontsize": "x-large",
  15. # "figure.figsize": (15, 5),
  16. "axes.labelsize": 15, # "small",
  17. # "axes.titlesize": "x-large",
  18. "xtick.labelsize": 15, # "small",
  19. "ytick.labelsize": 15, # "small",
  20. "legend.fontsize": 15,
  21. "axes.formatter.use_mathtext": True,
  22. "mathtext.fontset": "dejavusans",
  23. }
  24. #plt.rcParams.update(tex_fonts)
  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", required=True, 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. pcap_csv_list = list()
  39. for filename in os.listdir(args.pcap_csv_folder):
  40. if filename.endswith(".csv") and "tcp" in filename:
  41. pcap_csv_list.append(filename)
  42. counter = 1
  43. if len(pcap_csv_list) == 0:
  44. print("No CSV files found.")
  45. pcap_csv_list.sort(key=lambda x: int(x.split("_")[-1].replace(".csv", "")))
  46. for csv in pcap_csv_list:
  47. print("\rProcessing {} out of {} CSVs.\t({}%)\t".format(counter, len(pcap_csv_list), math.floor(counter/len(pcap_csv_list))))
  48. #try:
  49. transmission_df = pd.read_csv(
  50. "{}{}".format(args.pcap_csv_folder, csv),
  51. dtype=dict(is_retranmission=bool, is_dup_ack=bool),
  52. )
  53. transmission_df["datetime"] = pd.to_datetime(transmission_df["datetime"]) - pd.Timedelta(hours=1)
  54. transmission_df = transmission_df.set_index("datetime")
  55. transmission_df.index = pd.to_datetime(transmission_df.index)
  56. transmission_df = transmission_df.sort_index()
  57. # srtt to [s]
  58. transmission_df["srtt"] = transmission_df["srtt"].apply(lambda x: x / 10**6)
  59. # key for columns and level for index
  60. transmission_df["goodput"] = transmission_df["payload_size"].groupby(pd.Grouper(level="datetime", freq="{}s".format(args.interval))).transform("sum")
  61. transmission_df["goodput"] = transmission_df["goodput"].apply(
  62. lambda x: ((x * 8) / args.interval) / 10**6
  63. )
  64. transmission_df["goodput_rolling"] = transmission_df["payload_size"].rolling("{}s".format(args.interval)).sum()
  65. transmission_df["goodput_rolling"] = transmission_df["goodput_rolling"].apply(
  66. lambda x: ((x * 8) / args.interval) / 10 ** 6
  67. )
  68. # set meta values and remove all not needed columns
  69. cc_algo = transmission_df["congestion_control"].iloc[0]
  70. cc_algo = cc_algo.upper()
  71. transmission_direction = transmission_df["direction"].iloc[0]
  72. #transmission_df = transmission_df.filter(["goodput", "datetime", "ack_rtt", "goodput_rolling", "snd_cwnd"])
  73. # read serial csv
  74. serial_df = pd.read_csv(args.serial_file, dtype=dict(Cell_ID=str),)
  75. serial_df["datetime"] = pd.to_datetime(serial_df["datetime"]) - pd.Timedelta(hours=1)
  76. serial_df = serial_df.set_index("datetime")
  77. serial_df.index = pd.to_datetime(serial_df.index)
  78. serial_df.sort_index()
  79. print(serial_df["Cell_ID"])
  80. serial_df["Cell_ID"] = serial_df["Cell_ID"].apply(
  81. lambda x: int(x.split(" ")[-1].replace("(", "").replace(")", "")))
  82. transmission_df = pd.merge_asof(
  83. transmission_df,
  84. serial_df,
  85. tolerance=pd.Timedelta("1s"),
  86. right_index=True,
  87. left_index=True,
  88. )
  89. transmission_df.index = transmission_df["arrival_time"]
  90. # replace 0 in RSRQ with Nan
  91. transmission_df["NR5G_RSRQ_(dB)"] = transmission_df["NR5G_RSRQ_(dB)"].replace(0, np.NaN)
  92. transmission_df["RSRQ_(dB)"] = transmission_df["RSRQ_(dB)"].replace(0, np.NaN)
  93. # stacked plot for bandwidth
  94. transmission_df["lte_bw_sum"] = transmission_df["bw_sum"] - transmission_df["NR5G_dl_bw"]
  95. transmission_df["nr_bw_sum"] = transmission_df["NR5G_dl_bw"]
  96. # transmission timeline
  97. scaley = 1.5
  98. scalex = 1.0
  99. plt.title("{} with {}".format(transmission_direction, cc_algo))
  100. fig, ax = plt.subplots(2, 1, figsize=[6.4 * scaley, 4.8 * scalex])
  101. fig.subplots_adjust(right=0.75)
  102. fig.suptitle("{} with {}".format(transmission_direction, cc_algo))
  103. ax0 = ax[0]
  104. ax1 = ax0.twinx()
  105. ax2 = ax0.twinx()
  106. #ax2.spines.right.set_position(("axes", 1.22))
  107. ax00 = ax[1]
  108. ax01 = ax00.twinx()
  109. ax02 = ax00.twinx()
  110. # Plot vertical lines
  111. first = True
  112. lte_handovers = transmission_df["Cell_ID"].dropna().diff()
  113. for index, value in lte_handovers.items():
  114. if value > 0:
  115. if first:
  116. ax00.axvline(index, ymin=0, ymax=1, color="skyblue", label="4G Handover")
  117. first = False
  118. else:
  119. ax00.axvline(index, ymin=0, ymax=1, color="skyblue")
  120. first = True
  121. nr_handovers = transmission_df["NR5G_Cell_ID"].replace(0, np.NaN).dropna().diff()
  122. for index, value in nr_handovers.items():
  123. if value > 0:
  124. if first:
  125. ax00.axvline(index, ymin=0, ymax=1, color="greenyellow", label="5G Handover")
  126. first = False
  127. else:
  128. ax00.axvline(index, ymin=0, ymax=1, color="greenyellow")
  129. ax0.plot(transmission_df["snd_cwnd"].dropna(), color="lime", linestyle="dashed", label="cwnd")
  130. ax1.plot(transmission_df["srtt"].dropna(), color="red", linestyle="dashdot", label="sRTT")
  131. ax2.plot(transmission_df["goodput_rolling"], color="blue", linestyle="solid", label="goodput")
  132. #ax2.plot(transmission_df["goodput"], color="blue", linestyle="solid", label="goodput")
  133. ax01.plot(transmission_df["bw_sum"].dropna(), color="peru", linestyle="solid", label="bandwidth")
  134. ax01.plot(transmission_df["lte_bw_sum"].dropna(), color="lightsteelblue", linestyle="solid", label="4G bandwidth", alpha=.5)
  135. ax01.plot(transmission_df["nr_bw_sum"].dropna(), color="cornflowerblue", linestyle="solid",label="5G bandwidth", alpha=.5)
  136. #ax01.stackplot(transmission_df["arrival_time"].to_list(),
  137. # [transmission_df["lte_bw_sum"].to_list(), transmission_df["nr_bw_sum"].to_list()],
  138. # colors=["lightsteelblue", "cornflowerblue"],
  139. # labels=["4G bandwidth", "5G bandwidth"]
  140. # )
  141. ax02.plot(transmission_df["RSRQ_(dB)"].dropna(), color="purple", linestyle="dotted", label="LTE RSRQ")
  142. ax00.plot(transmission_df["NR5G_RSRQ_(dB)"].dropna(), color="magenta", linestyle="dotted", label="NR RSRQ")
  143. ax2.spines.right.set_position(("axes", 1.1))
  144. ax02.spines.right.set_position(("axes", 1.1))
  145. ax0.set_ylim(0, 5000)
  146. ax1.set_ylim(0, 0.3)
  147. ax2.set_ylim(0, 500)
  148. ax00.set_ylim(-25, 0)
  149. ax01.set_ylim(0, 250)
  150. # second dB axis
  151. ax02.set_ylim(-25, 0)
  152. ax02.set_axis_off()
  153. ax00.set_xlabel("arrival time [s]")
  154. ax2.set_ylabel("Goodput [mbps]")
  155. ax00.set_ylabel("LTE/NR RSRQ [dB]")
  156. #ax02.set_ylabel("LTE RSRQ [dB]")
  157. ax1.set_ylabel("sRTT [s]")
  158. ax0.set_ylabel("cwnd")
  159. ax01.set_ylabel("Bandwidth [MHz]")
  160. fig.legend(loc="lower right")
  161. plt.savefig("{}{}_plot.pdf".format(args.save, csv.replace(".csv", "")))
  162. #except Exception as e:
  163. # print("Error processing file: {}".format(csv))
  164. # print(str(e))
  165. counter += 1
  166. plt.close(fig)
  167. plt.clf()