Bug 1943650 - Command-line --help output misformatted after --dbus-service. r=emilio
[gecko.git] / dom / media / driftcontrol / plot.py
blobc30542cdf3ff2f0b1cd8f13c96082e046213116c
1 #! /usr/bin/env python3
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 # This scripts plots graphs produced by our drift correction code.
9 # Install dependencies with:
10 # > pip install bokeh pandas
12 # Generate the csv data file with the DriftControllerGraphs log module:
13 # > MOZ_LOG=raw,sync,DriftControllerGraphs:5 \
14 # > MOZ_LOG_FILE=/tmp/driftcontrol.csv \
15 # > ./mach gtest '*AudioDrift*StepResponse'
17 # Generate the graphs with this script:
18 # > ./dom/media/driftcontrol/plot.py /tmp/driftcontrol.csv.moz_log
20 # The script should produce a file plot.html in the working directory and
21 # open it in the default browser.
23 import argparse
24 from collections import OrderedDict
26 import pandas
27 from bokeh.io import output_file, show
28 from bokeh.layouts import gridplot
29 from bokeh.models import TabPanel, Tabs
30 from bokeh.plotting import figure
33 def main():
34 parser = argparse.ArgumentParser(
35 prog="plot.py for DriftControllerGraphs",
36 description="""Takes a csv file of DriftControllerGraphs data
37 (from a single DriftController instance) and plots
38 them into plot.html in the current working directory.
40 The easiest way to produce the data is with MOZ_LOG:
41 MOZ_LOG=raw,sync,DriftControllerGraphs:5 \
42 MOZ_LOG_FILE=/tmp/driftcontrol.csv \
43 ./mach gtest '*AudioDrift*StepResponse'""",
45 parser.add_argument("csv_file", type=str)
46 args = parser.parse_args()
48 all_df = pandas.read_csv(args.csv_file)
50 # Filter on distinct ids to support multiple plotting sources
51 tabs = []
52 for id in list(OrderedDict.fromkeys(all_df["id"])):
53 df = all_df[all_df["id"] == id]
55 t = df["t"]
56 buffering = df["buffering"]
57 avgbuffered = df["avgbuffered"]
58 desired = df["desired"]
59 buffersize = df["buffersize"]
60 inlatency = df["inlatency"]
61 outlatency = df["outlatency"]
62 inframesavg = df["inframesavg"]
63 outframesavg = df["outframesavg"]
64 inrate = df["inrate"]
65 outrate = df["outrate"]
66 steadystaterate = df["steadystaterate"]
67 nearthreshold = df["nearthreshold"]
68 corrected = df["corrected"]
69 hysteresiscorrected = df["hysteresiscorrected"]
70 configured = df["configured"]
72 output_file("plot.html")
74 fig1 = figure()
75 # Variables with more variation are plotted after smoother variables
76 # because latter variables are drawn on top and so visibility of
77 # individual values in the variables with more variation is improved
78 # (when both variables are shown).
79 fig1.line(
80 t, inframesavg, color="violet", legend_label="Average input packet size"
82 fig1.line(
83 t, outframesavg, color="purple", legend_label="Average output packet size"
85 fig1.line(t, inlatency, color="hotpink", legend_label="In latency")
86 fig1.line(t, outlatency, color="firebrick", legend_label="Out latency")
87 fig1.line(t, desired, color="goldenrod", legend_label="Desired buffering")
88 fig1.line(
89 t, avgbuffered, color="orangered", legend_label="Average buffered estimate"
91 fig1.line(t, buffering, color="dodgerblue", legend_label="Actual buffering")
92 fig1.line(t, buffersize, color="seagreen", legend_label="Buffer size")
93 fig1.varea(
95 [d - h for (d, h) in zip(desired, nearthreshold)],
96 [d + h for (d, h) in zip(desired, nearthreshold)],
97 alpha=0.2,
98 color="goldenrod",
99 legend_label='"Near" band (won\'t reduce desired buffering outside)',
102 slowConvergenceSecs = 30
103 adjustmentInterval = 1
104 slowHysteresis = 1
105 avgError = avgbuffered - desired
106 absAvgError = [abs(e) for e in avgError]
107 slow_offset = [e / slowConvergenceSecs - slowHysteresis for e in absAvgError]
108 fast_offset = [e / adjustmentInterval for e in absAvgError]
109 low_offset, high_offset = zip(
111 (s, f) if e >= 0 else (-f, -s)
112 for (e, s, f) in zip(avgError, slow_offset, fast_offset)
116 fig2 = figure(x_range=fig1.x_range)
117 fig2.varea(
119 steadystaterate + low_offset,
120 steadystaterate + high_offset,
121 alpha=0.2,
122 color="goldenrod",
123 legend_label="Deadband (won't change in rate within)",
125 fig2.line(t, inrate, color="hotpink", legend_label="Nominal in sample rate")
126 fig2.line(t, outrate, color="firebrick", legend_label="Nominal out sample rate")
127 fig2.line(
129 steadystaterate,
130 color="orangered",
131 legend_label="Estimated in rate with drift",
133 fig2.line(
134 t, corrected, color="dodgerblue", legend_label="Corrected in sample rate"
136 fig2.line(
138 hysteresiscorrected,
139 color="seagreen",
140 legend_label="Hysteresis-corrected in sample rate",
142 fig2.line(
143 t, configured, color="goldenrod", legend_label="Configured in sample rate"
146 fig1.legend.location = "top_left"
147 fig2.legend.location = "top_right"
148 for fig in (fig1, fig2):
149 fig.legend.background_fill_alpha = 0.6
150 fig.legend.click_policy = "hide"
152 tabs.append(TabPanel(child=gridplot([[fig1, fig2]]), title=str(id)))
154 show(Tabs(tabs=tabs))
157 if __name__ == "__main__":
158 main()