您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

192 行
5.6KB

  1. #!/usr/bin/env python3
  2. import multiprocessing
  3. import os
  4. from argparse import ArgumentParser
  5. from math import ceil
  6. from time import sleep
  7. import pandas as pd
  8. import geopandas as gpd
  9. import contextily as cx
  10. import matplotlib.pyplot as plt
  11. from mpl_toolkits import axisartist
  12. from mpl_toolkits.axes_grid1 import host_subplot
  13. from util import chunk_list
  14. def csv_to_dataframe(csv_list, dummy):
  15. global n
  16. global frame_list
  17. transmission_df = None
  18. for csv in csv_list:
  19. tmp_df = pd.read_csv(
  20. "{}{}".format(args.pcap_csv_folder, csv),
  21. dtype=dict(is_retranmission=bool, is_dup_ack=bool),
  22. )
  23. tmp_df["datetime"] = pd.to_datetime(tmp_df["datetime"]) - pd.Timedelta(hours=1)
  24. tmp_df = tmp_df.set_index("datetime")
  25. tmp_df.index = pd.to_datetime(tmp_df.index)
  26. if transmission_df is None:
  27. transmission_df = tmp_df
  28. else:
  29. transmission_df = pd.concat([transmission_df, tmp_df])
  30. n.value += 1
  31. frame_list.append(transmission_df)
  32. from itertools import islice
  33. def chunk(it, size):
  34. it = iter(it)
  35. return iter(lambda: tuple(islice(it, size)), ())
  36. if __name__ == "__main__":
  37. parser = ArgumentParser()
  38. parser.add_argument("-f", "--gps_file", required=True, help="GPS csv file.")
  39. parser.add_argument("-s", "--serial_file", required=True, help="Serial csv file.")
  40. parser.add_argument("-p", "--pcap_csv_folder", required=True, help="PCAP csv folder.")
  41. parser.add_argument("--save", default=None, help="Location to save pdf file.")
  42. parser.add_argument(
  43. "--show_providerinfo",
  44. default=False,
  45. help="Show providerinfo for map tiles an zoom levels.",
  46. )
  47. parser.add_argument(
  48. "-c",
  49. "--cores",
  50. default=1,
  51. type=int,
  52. help="Number of cores for multiprocessing.",
  53. )
  54. parser.add_argument(
  55. "-i",
  56. "--interval",
  57. default=10,
  58. type=int,
  59. help="Time interval for rolling window.",
  60. )
  61. args = parser.parse_args()
  62. manager = multiprocessing.Manager()
  63. n = manager.Value("i", 0)
  64. frame_list = manager.list()
  65. jobs = []
  66. # load all pcap csv into one dataframe
  67. pcap_csv_list = list()
  68. for filename in os.listdir(args.pcap_csv_folder):
  69. if filename.endswith(".csv") and "tcp" in filename:
  70. pcap_csv_list.append(filename)
  71. parts = chunk(pcap_csv_list, ceil(len(pcap_csv_list) / args.cores))
  72. print("Start processing with {} jobs.".format(args.cores))
  73. for p in parts:
  74. process = multiprocessing.Process(target=csv_to_dataframe, args=(p, "dummy"))
  75. jobs.append(process)
  76. for j in jobs:
  77. j.start()
  78. print("Started all jobs.")
  79. # Ensure all of the processes have finished
  80. finished_job_counter = 0
  81. working = ["|", "/", "-", "\\", "|", "/", "-", "\\"]
  82. w = 0
  83. while len(jobs) != finished_job_counter:
  84. sleep(1)
  85. print(
  86. "\r\t{}{}{}\t Running {} jobs ({} finished). Processed {} out of {} pcap csv files. ({}%) ".format(
  87. working[w],
  88. working[w],
  89. working[w],
  90. len(jobs),
  91. finished_job_counter,
  92. n.value,
  93. len(pcap_csv_list),
  94. round((n.value / len(pcap_csv_list)) * 100, 2),
  95. ),
  96. end="",
  97. )
  98. finished_job_counter = 0
  99. for j in jobs:
  100. if not j.is_alive():
  101. finished_job_counter += 1
  102. if (w + 1) % len(working) == 0:
  103. w = 0
  104. else:
  105. w += 1
  106. print("\r\nSorting table...")
  107. transmission_df = pd.concat(frame_list)
  108. frame_list = None
  109. transmission_df = transmission_df.sort_index()
  110. print("Calculate goodput...")
  111. transmission_df["goodput"] = transmission_df["payload_size"].rolling("{}s".format(args.interval)).sum()
  112. transmission_df["goodput"] = transmission_df["goodput"].apply(
  113. lambda x: ((x * 8) / args.interval) / 10**6
  114. )
  115. # remove all not needed columns
  116. transmission_df = transmission_df.filter(["goodput", "datetime"])
  117. # read serial csv
  118. serial_df = pd.read_csv(args.serial_file)
  119. serial_df["datetime"] = pd.to_datetime(serial_df["datetime"]) - pd.Timedelta(hours=1)
  120. serial_df = serial_df.set_index("datetime")
  121. serial_df.index = pd.to_datetime(serial_df.index)
  122. transmission_df = pd.merge_asof(
  123. transmission_df,
  124. serial_df,
  125. tolerance=pd.Timedelta("1s"),
  126. right_index=True,
  127. left_index=True,
  128. )
  129. scaley = 1.5
  130. scalex = 1.0
  131. plt.figure(figsize=[6.4 * scaley, 4.8 * scalex])
  132. host = host_subplot(111, axes_class=axisartist.Axes)
  133. plt.subplots_adjust()
  134. # additional y axes
  135. par11 = host.twinx()
  136. par12 = host.twinx()
  137. # par13 = host.twinx()
  138. # axes offset
  139. par12.axis["right"] = par12.new_fixed_axis(loc="right", offset=(60, 0))
  140. # par13.axis["right"] = par13.new_fixed_axis(loc="right", offset=(120, 0))
  141. par11.axis["right"].toggle(all=True)
  142. par12.axis["right"].toggle(all=True)
  143. # par13.axis["right"].toggle(all=True)
  144. host.plot(transmission_df["goodput"], "-", color="blue", label="goodput" )
  145. host.set_xlabel("datetime")
  146. host.set_ylabel("goodput [Mbps]")
  147. #host.set_ylim([0, 13])
  148. #host.set_yscale("log")
  149. #host.set_yscale("log")
  150. #host.set_yscale("log")
  151. #host.set_yscale("log")
  152. par11.plot(transmission_df["downlink_cqi"], "--", color="green", label="CQI")
  153. par11.set_ylabel("CQI")
  154. par11.set_ylim([0, 15])
  155. par12.plot()
  156. if args.save:
  157. plt.savefig("{}timeline_plot.pdf".format(args.save))
  158. else:
  159. plt.show()