1#!/bin/bash
2
3# Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
4#
5# Use of this source code is governed by a BSD-style license
6# that can be found in the LICENSE file in the root of the source
7# tree. An additional intellectual property rights grant can be found
8# in the file PATENTS.  All contributing project authors may
9# be found in the AUTHORS file in the root of the source tree.
10
11# To set up in e.g. Eclipse, run a separate shell and pipe the output from the
12# test into this script.
13#
14# In Eclipse, that amounts to creating a Run Configuration which starts
15# "/bin/bash" with the arguments "-c [trunk_path]/out/Debug/modules_unittests
16# --gtest_filter=*BweTest* | [trunk_path]/webrtc/modules/
17# remote_bitrate_estimator/test/plot_bars.sh
18
19# This script supports multiple figures (windows), the figure is specified as an
20# identifier at the first argument after the PLOT command. Each figure has a
21# single y axis and a dual y axis mode. If any line specifies an axis by ending
22# with "#<axis number (1 or 2)>" two y axis will be used, the first will be
23# assumed to represent bitrate (in kbps) and the second will be assumed to
24# represent time deltas (in ms).
25
26log=$(</dev/stdin)
27
28# Plot histograms.
29function gen_gnuplot_bar_input {
30  x_start=1
31  x_end=3.75
32  bars=$(echo "$log" | grep "BAR")
33
34  labels=$(echo "$log" | grep "^LABEL")
35  figures=($(echo "$bars" | cut -f 2 | sort | uniq))
36
37  echo "reset"  # Clears previous settings.
38
39  echo "set title font 'Verdana,22'"
40  echo "set xtics font 'Verdana,24'"
41  echo "set ytics font 'Verdana,14'"
42  echo "set ylabel font 'Verdana,16'"
43
44  echo "set xrange[$x_start:$x_end]"
45  echo "set style fill solid 0.5"
46  echo "set style fill solid border -1"
47
48  declare -a ydist=(11.5 10.5 10.5)  # Used to correctly offset the y label.
49  i=0
50  for figure in "${figures[@]}" ; do
51
52    echo "set terminal wxt $figure size 440,440 dashed"
53    echo "set ylabel offset ${ydist[$i]}, -3"
54    (( i++ ))
55
56    title=$(echo "$labels" | grep "^LABEL.$figure" | cut -f 3 | \
57                                         head -n 1 | sed 's/_/ /g')
58    y_label=$(echo "$labels" | grep "^LABEL.$figure" | cut -f 4 | \
59                                         head -n 1 | sed 's/_/ /g')
60
61    # RMCAT flows.
62    num_flows=$(echo "$labels" | grep "^LABEL.$figure" | cut -f 5 | \
63                                         head -n 1)
64
65    # RMCAT algorithm 1.
66    x_label_1=$(echo "$log" | grep "BAR.$figure" | cut -f 3 | sed 's/_/\t/g' \
67                                 | cut -f 1  | sort | uniq | head -n 1 )
68
69    # RMCAT algorithm 2.
70    x_label_2=$(echo "$log" | grep "BAR.$figure" | cut -f 3 | sed 's/_/\t/g' \
71                                 | cut -f 1  | sort | uniq |  sed -n 2p)
72
73    x_labels="('$x_label_1' 2, '$x_label_2' 3)"
74    tcp_flow=false
75
76    tcp_space=0.2  # Extra horizontal space between bars.
77
78    # Parse labels if there are other flows in addition to RMCAT ones.
79    IFS='x' read -ra split_label_1 <<< "$x_label_1"
80
81    if (( ${#split_label_1[@]} > "1" )); then
82      tcp_flow=true
83      box_width=$(echo "(1.0-$tcp_space/2)/$num_flows" | bc -l)
84      echo "set xtics font 'Verdana,16'"
85      x_labels="("
86      delimiter=""
87      abscissa=$(echo $x_start + 0.5 + 0.5*$box_width | bc)
88      for label in "${split_label_1[@]}" ; do
89        x_labels+="$delimiter'$label' $abscissa"
90        abscissa=$(echo $abscissa + $box_width | bc)
91        delimiter=", "
92      done
93      abscissa=$(echo $abscissa + $tcp_space | bc)
94      IFS='x' read -ra split_label_2 <<< "$x_label_2"
95      for label in "${split_label_2[@]}" ; do
96        x_labels+="$delimiter'$label' $abscissa"
97        abscissa=$(echo $abscissa + $box_width | bc)
98      done
99      x_labels="$x_labels)"
100    else
101      box_width=$(echo 1.0/$num_flows | bc -l)
102    fi
103
104    echo "set boxwidth $box_width"
105
106    # Plots can be directly exported to image files.
107    file_name=$(echo "$labels" | grep "^LABEL.$figure" | cut -f 5 | head -n 1)
108
109    y_max=0  # Used to scale the plot properly.
110
111    # Scale all latency plots with the same vertical scale.
112    delay_figure=5
113    if (( $figure==$delay_figure )) ; then
114      y_max=400
115    else  # Take y_max = 1.1 * highest plot value.
116
117      # Since only the optimal bitrate for the first flow is being ploted,
118      # consider only this one for scalling purposes.
119      data_sets=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 3 | \
120                                     sed 's/_/\t/g' | cut -f 1 | sort | uniq)
121
122      if (( ${#data_sets[@]} > "0" )); then
123        for set in $data_sets ; do
124          y=$(echo "$bars" | grep "LIMITERRORBAR.$figure.$set" | cut -f 8 | \
125                                                                  head -n 1)
126          if (( $(bc <<< "$y > $y_max") == 1 )); then
127            y_max=$y
128          fi
129        done
130      fi
131
132      data_sets=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 3 | \
133                                                               sort | uniq)
134      if (( ${#data_sets[@]} > "0" )); then
135        for set in $data_sets ; do
136          y=$(echo "$bars" | grep "ERRORBAR.$figure.$set" | cut -f 6 | \
137                                                                 head -n 1)
138          if (( $(bc <<< "$y > $y_max") == 1 )) ; then
139            y_max=$y
140          fi
141        done
142      fi
143
144      data_sets=$(echo "$bars" | grep "BAR.$figure" | cut -f 3 | sort | uniq)
145
146      for set in $data_sets ; do
147        y=$(echo "$bars" | grep "BAR.$figure.$set" | cut -f 4 | head -n 1)
148        if (( $(bc <<< "$y > $y_max") == 1 )) ; then
149          y_max=$y
150        fi
151      done
152
153      y_max=$(echo $y_max*1.1 | bc)
154    fi
155
156
157    echo "set ylabel \"$y_label\""
158    echo "set yrange[0:$y_max]"
159
160    echo "set multiplot"
161
162    # Plot bars.
163    data_sets=$(echo "$bars" | grep "BAR.$figure" | cut -f 3 | sort | uniq)
164
165    echo "set xtics $x_labels"
166    echo "plot '-' using 1:4:2 with boxes lc variable notitle"
167
168    echo
169
170    color=11  # Green.
171    x_bar=$(echo $x_start + 0.5 + 0.5*$box_width | bc)
172    for set in $data_sets ; do
173      echo -n "$x_bar  $color  "
174      echo "$bars" | grep "BAR.$figure.$set" | cut -f 3,4
175
176      # Add extra space if TCP flows are being plotted.
177      if $tcp_flow && \
178          (( $(bc <<< "$x_bar < $x_start + 1.5 - 0.5*$tcp_space") == 1 )) && \
179          (( $(bc <<< "$x_bar + $box_width > $x_start + 1.5 + 0.5*$tcp_space") \
180           == 1 )); then
181          x_bar=$(echo $x_bar + $tcp_space | bc)
182      fi
183
184      x_bar=$(echo $x_bar + $box_width | bc)
185
186      if (( $(bc <<< "$x_bar > 2.5") == 1 )) ; then
187        color=12  # Blue.
188      fi
189      # Different bar color for TCP flows:
190      if $tcp_flow && \
191         (( $(bc <<< "(100*$x_bar)%100 < 50") == 1 ))
192      then
193        color=18  # Gray.
194      fi
195    done
196    echo "e"
197
198    # Plot Baseline bars, e.g. one-way path delay on latency plots.
199    data_sets=$(echo "$log" | grep "BASELINE.$figure" | cut -f 3 | sort | uniq)
200
201    if (( ${#data_sets} > "0" )); then
202      echo "set xtics $x_labels"
203      echo "plot '-' using 1:4:2 with boxes lc variable notitle"
204
205      echo
206
207      color=18  # Gray.
208      x_bar=$(echo $x_start + 0.5 + 0.5*$box_width | bc)
209      for set in $data_sets ; do
210        echo -n "$x_bar  $color  "
211        echo "$log" | grep "BASELINE.$figure.$set" | cut -f 3,4
212
213        # Add extra space if TCP flows are being plotted.
214        if $tcp_flow && \
215            (( $(bc <<< "$x_bar < $x_start + 1.5 - 0.5*$tcp_space") == 1 )) && \
216            (( $(bc <<< "$x_bar + $box_width > $x_start + 1.5 \
217            + 0.5*$tcp_space") == 1 )); then
218            x_bar=$(echo $x_bar + $tcp_space | bc)
219        fi
220
221        x_bar=$(echo $x_bar + $box_width | bc)
222
223      done
224      echo "e"
225    fi
226
227    # Plot vertical error lines, e.g. y +- sigma.
228    data_sets=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 3 | sort | uniq)
229
230    if (( ${#data_sets} > "0" )); then
231
232      echo "set key left"
233      error_title=$(echo "$bars" | grep "ERRORBAR.$figure" | cut -f 7 | \
234                                                 head -n 1 | sed 's/_/ /g')
235
236      echo "set xtics $x_labels"
237      echo "plot '-' using 1:3:4:5 title '$error_title' with yerr"
238
239      x_error_line=$(echo $x_start + 0.5 + 0.5*$box_width | bc)
240      for set in $data_sets ; do
241        echo -n "$x_error_line  "
242        echo "$bars" | grep "ERRORBAR.$figure.$set" | cut -f 3,4,5,6
243
244        # Add extra space if TCP flows are being plotted.
245        if $tcp_flow && \
246          (( $(bc <<< "$x_error_line < $x_start + 1.5 - 0.5*$tcp_space") == 1 \
247          )) && (( $(bc <<< "$x_error_line + $box_width > $x_start + 1.5 \
248          + 0.5*$tcp_space") == 1 )); then
249          x_error_line=$(echo $x_error_line + $tcp_space | bc)
250        fi
251
252        x_error_line=$(echo $x_error_line + $box_width | bc)
253      done
254      echo "e"
255    fi
256
257    # Plot horizontal dashed lines, e.g. y = optimal bitrate.
258    data_sets=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 3 \
259                                                     | sort | uniq)
260    if (( ${#data_sets} > "0" )); then
261
262      echo "set style line 1 lt 1 lw 3 pt 3 ps 0 linecolor rgb 'black'"
263
264      limit_titles=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | cut -f 9 \
265                                                         | sort | uniq)
266
267      for title in $limit_titles ; do
268        y_max=$(echo "$bars" | grep "LIMITERRORBAR.$figure" | grep "$title" \
269                                               | cut -f 8 | head -n 1)
270
271        retouched_title=$(echo "$title" | sed 's/#/\t/g' | cut -f 1 \
272                                                         | sed 's/_/ /g')
273
274        echo "set key right top"
275        echo "set xtics $x_labels"
276        echo "plot $y_max lt 7 lw 1 linecolor rgb 'black' \
277                                  title '$retouched_title'"
278      done
279
280    fi
281
282    echo "unset multiplot"
283  done
284}
285
286gen_gnuplot_bar_input | gnuplot -persist
287