Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

197 lines
7.2KB

  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. serial_df["Cell_ID"] = serial_df["Cell_ID"].apply(
  80. lambda x: int(x.split(" ")[-1].replace("(", "").replace(")", "")))
  81. transmission_df = pd.merge_asof(
  82. transmission_df,
  83. serial_df,
  84. tolerance=pd.Timedelta("1s"),
  85. right_index=True,
  86. left_index=True,
  87. )
  88. transmission_df.index = transmission_df["arrival_time"]
  89. # replace 0 in RSRQ with Nan
  90. transmission_df = transmission_df["bw_sum"].replace(0, np.NaN)
  91. # stacked plot for bandwidth
  92. transmission_df["lte_bw_sum"] = transmission_df["bw_sum"] - transmission_df["NR5G_dl_bw"]
  93. transmission_df["nr_bw_sum"] = transmission_df["NR5G_dl_bw"]
  94. # transmission timeline
  95. scaley = 1.5
  96. scalex = 1.0
  97. plt.title("{} with {}".format(transmission_direction, cc_algo))
  98. fig, ax = plt.subplots(2, 1, figsize=[6.4 * scaley, 4.8 * scalex])
  99. fig.subplots_adjust(right=0.75)
  100. fig.suptitle("{} with {}".format(transmission_direction, cc_algo))
  101. ax0 = ax[0]
  102. ax1 = ax0.twinx()
  103. ax2 = ax0.twinx()
  104. #ax2.spines.right.set_position(("axes", 1.22))
  105. ax00 = ax[1]
  106. ax01 = ax00.twinx()
  107. ax02 = ax00.twinx()
  108. # Plot vertical lines
  109. first = True
  110. lte_handovers = transmission_df["Cell_ID"].diff().dropna()
  111. for index, value in lte_handovers.items():
  112. if value > 0:
  113. if first:
  114. ax00.axvline(index, ymin=0, ymax=1, color="skyblue", label="4G Handover")
  115. first = False
  116. else:
  117. ax00.axvline(index, ymin=0, ymax=1, color="skyblue")
  118. first = True
  119. nr_handovers = transmission_df["NR5G_Cell_ID"].diff().dropna()
  120. for index, value in nr_handovers.items():
  121. if value > 0:
  122. if first:
  123. ax00.axvline(index, ymin=0, ymax=1, color="greenyellow", label="5G Handover")
  124. first = False
  125. else:
  126. ax00.axvline(index, ymin=0, ymax=1, color="greenyellow")
  127. ax0.plot(transmission_df["snd_cwnd"].dropna(), color="lime", linestyle="dashed", label="cwnd")
  128. ax1.plot(transmission_df["srtt"].dropna(), color="red", linestyle="dashdot", label="sRTT")
  129. ax2.plot(transmission_df["goodput_rolling"], color="blue", linestyle="solid", label="goodput")
  130. ax00.plot(transmission_df["NR5G_RSRQ_(dB)"].dropna(), color="magenta", linestyle="dotted", label="NR RSRQ")
  131. ax01.plot(transmission_df["bw_sum"].dropna(), color="peru", linestyle="solid", label="bandwidth")
  132. ax01.stackplot(transmission_df["lte_bw_sum"], transmission_df["nr_bw_sum"], colors=["lightsteelblue", "cornflowerblue"], labels=["4G", "5G"])
  133. ax02.plot(transmission_df["RSRQ_(dB)"].dropna(), color="purple", linestyle="dotted", label="LTE RSRQ")
  134. ax2.spines.right.set_position(("axes", 1.1))
  135. ax02.spines.right.set_position(("axes", 1.1))
  136. ax0.set_ylim(0, 5000)
  137. ax1.set_ylim(0, 0.3)
  138. ax2.set_ylim(0, 500)
  139. ax00.set_ylim(-25, 0)
  140. ax01.set_ylim(0, 250)
  141. # second dB axis
  142. ax02.set_ylim(-25, 0)
  143. ax02.set_axis_off()
  144. ax00.set_xlabel("arrival time [s]")
  145. ax2.set_ylabel("Goodput [mbps]")
  146. ax00.set_ylabel("LTE/NR RSRQ [dB]")
  147. #ax02.set_ylabel("LTE RSRQ [dB]")
  148. ax1.set_ylabel("sRTT [s]")
  149. ax0.set_ylabel("cwnd")
  150. ax01.set_ylabel("Bandwidth [MHz]")
  151. fig.legend(loc="lower right")
  152. plt.savefig("{}{}_plot.pdf".format(args.save, csv.replace(".csv", "")))
  153. #except Exception as e:
  154. # print("Error processing file: {}".format(csv))
  155. # print(str(e))
  156. counter += 1
  157. plt.close(fig)
  158. plt.clf()