tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

plot.py (5663B)


      1 #! /usr/bin/env python3
      2 #
      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/.
      6 #
      7 # This scripts plots graphs produced by our drift correction code.
      8 #
      9 # Install dependencies with:
     10 #   > pip install bokeh pandas
     11 #
     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'
     16 #
     17 # Generate the graphs with this script:
     18 #   > ./dom/media/driftcontrol/plot.py /tmp/driftcontrol.csv.moz_log
     19 #
     20 # The script should produce a file plot.html in the working directory and
     21 # open it in the default browser.
     22 
     23 import argparse
     24 from collections import OrderedDict
     25 
     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
     31 
     32 
     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.
     39 
     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'""",
     44    )
     45    parser.add_argument("csv_file", type=str)
     46    args = parser.parse_args()
     47 
     48    all_df = pandas.read_csv(args.csv_file)
     49 
     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]
     54 
     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"]
     71 
     72        output_file("plot.html")
     73 
     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"
     81        )
     82        fig1.line(
     83            t, outframesavg, color="purple", legend_label="Average output packet size"
     84        )
     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"
     90        )
     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(
     94            t,
     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)',
    100        )
    101 
    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(*[
    110            (s, f) if e >= 0 else (-f, -s)
    111            for (e, s, f) in zip(avgError, slow_offset, fast_offset)
    112        ])
    113 
    114        fig2 = figure(x_range=fig1.x_range)
    115        fig2.varea(
    116            t,
    117            steadystaterate + low_offset,
    118            steadystaterate + high_offset,
    119            alpha=0.2,
    120            color="goldenrod",
    121            legend_label="Deadband (won't change in rate within)",
    122        )
    123        fig2.line(t, inrate, color="hotpink", legend_label="Nominal in sample rate")
    124        fig2.line(t, outrate, color="firebrick", legend_label="Nominal out sample rate")
    125        fig2.line(
    126            t,
    127            steadystaterate,
    128            color="orangered",
    129            legend_label="Estimated in rate with drift",
    130        )
    131        fig2.line(
    132            t, corrected, color="dodgerblue", legend_label="Corrected in sample rate"
    133        )
    134        fig2.line(
    135            t,
    136            hysteresiscorrected,
    137            color="seagreen",
    138            legend_label="Hysteresis-corrected in sample rate",
    139        )
    140        fig2.line(
    141            t, configured, color="goldenrod", legend_label="Configured in sample rate"
    142        )
    143 
    144        fig1.legend.location = "top_left"
    145        fig2.legend.location = "top_right"
    146        for fig in (fig1, fig2):
    147            fig.legend.background_fill_alpha = 0.6
    148            fig.legend.click_policy = "hide"
    149 
    150        tabs.append(TabPanel(child=gridplot([[fig1, fig2]]), title=str(id)))
    151 
    152    show(Tabs(tabs=tabs))
    153 
    154 
    155 if __name__ == "__main__":
    156    main()