Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_init / ns_quickview.pl
1 #!/usr/bin/perl -w\r
2 #\r
3 # Copyright (c) 2002-2003\r
4 #      The President and Fellows of Harvard College.\r
5 #\r
6 # Redistribution and use in source and binary forms, with or without\r
7 # modification, are permitted provided that the following conditions\r
8 # are met:\r
9 # 1. Redistributions of source code must retain the above copyright\r
10 #    notice, this list of conditions and the following disclaimer.\r
11 # 2. Redistributions in binary form must reproduce the above copyright\r
12 #    notice, this list of conditions and the following disclaimer in the\r
13 #    documentation and/or other materials provided with the distribution.\r
14 # 3. Neither the name of the University nor the names of its contributors\r
15 #    may be used to endorse or promote products derived from this software\r
16 #    without specific prior written permission.\r
17 #\r
18 # THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND\r
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
21 # ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE\r
22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
24 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
25 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
26 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
27 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
28 # SUCH DAMAGE.\r
29 #\r
30 # $Id: ns_quickview,v 1.9 2003/07/28 14:27:17 ellard Exp $\r
31 \r
32 use Getopt::Std;\r
33 \r
34 $ProgDir = $0;\r
35 $ProgDir =~ /(^.*)\//;\r
36 $ProgDir = $1;\r
37 if (!$ProgDir) {\r
38         $ProgDir = ".";\r
39 }\r
40 \r
41 $GNUPLOT_PATH   = "gnuplot";\r
42 $GNUPLOT_OPTS   = "-persist";\r
43 $LOC2GMT_PATH   = "$ProgDir/ns_loc2gmt";\r
44 \r
45 $OUTPUT         = "qv.ps";\r
46 $GP_OUTPUT      = "qv.gp";\r
47 $TERMINAL       = "postscript";\r
48 $SIZE           = undef;\r
49 $EXTRA_CMD      = undef;\r
50 $TITLE_TEXT     = undef;\r
51 $PLOT_OPTS      = '';\r
52 @OPS            = ( 7 );\r
53 @SCALES         = ();\r
54 \r
55 $Usage =<< ".";\r
56 \r
57 Usage: $0 [options] table1.ns [table2.ns ...]\r
58 \r
59 At least one table file must be specified.\r
60 \r
61 Command line options:\r
62 \r
63 -h              Print usage message and exit.\r
64 \r
65 -c cmd          Pass an extra command directly to gnuplot.\r
66 \r
67 -g              Save the gnuplot commands to $GP_OUTPUT instead\r
68                 of executing the immediately.\r
69 \r
70 -k              Show the key for each line on the plot.  The default\r
71                 is not to show the key.\r
72 \r
73 -l              If more than one input file is specified, superimpose\r
74                 the plot for each so that they all appear to begin at\r
75                 the same time as the first row in the first file.\r
76 \r
77 -o filename     Save the plot to the specified file.  The default\r
78                 output file is \"$OUTPUT\".\r
79 \r
80 -O op1,...,opN  Plot the specified columns from the table.  The\r
81                 default is $OPS[0], the total operation count.\r
82                 Note that the operations must be specified by column\r
83                 number, not by name.\r
84 \r
85 -t terminal     Create a plot for the given gnuplot terminal specification.\r
86                 The default is \"$TERMINAL\".  See the gnuplot\r
87                 documentation for more information.\r
88 \r
89 -T string       Use the specified string as the title for the plot.\r
90                 The default is no title.\r
91 \r
92 -s sizespec     Set the output size specifier.  See the gnuplot\r
93                 documentation for more information.\r
94 \r
95 -S s1,..,sN     Set the scaling factor for each file.  This is useful\r
96                 for plotting files aggregated across different time\r
97                 intervals on the same scale.\r
98 \r
99 .\r
100 \r
101 $Options = "c:ghklo:O:P:t:T:s:S:";\r
102 if (! getopts ($Options)) {\r
103         print STDERR "$0: Incorrect usage.\n";\r
104         print STDERR $Usage;\r
105         exit (1);\r
106 }\r
107 if (defined $opt_h) {\r
108         print $Usage;\r
109         exit (0);\r
110 }\r
111 \r
112 $EXTRA_CMD      = $opt_c        if (defined $opt_c);\r
113 $OUTPUT         = $opt_o        if (defined $opt_o);\r
114 $TERMINAL       = $opt_t        if (defined $opt_t);\r
115 $SIZE           = $opt_s        if (defined $opt_s);\r
116 $TITLE_TEXT     = $opt_T        if (defined $opt_T);\r
117 $PLOT_OPTS      = $opt_P        if (defined $opt_P);\r
118 @OPS    = split (/,/, $opt_O)   if (defined $opt_O);\r
119 @SCALES = split (/,/, $opt_S)   if (defined $opt_S);\r
120 \r
121 $SAVE_GNUPLOT   = defined $opt_g;\r
122 $SHOW_KEY       = defined $opt_k;\r
123 $LAYER          = defined $opt_l;\r
124 \r
125 @FILES = @ARGV;\r
126 \r
127 if (@FILES == 0) {\r
128         print STDERR "No tables to plot?\n";\r
129         exit (1);\r
130 }\r
131 \r
132 &makePlot;\r
133 exit (0);\r
134 \r
135 sub makePlot {\r
136         my @starts = ();\r
137         my @ends = ();\r
138 \r
139         my $nfiles = @FILES;\r
140         my $nops = @OPS;\r
141 \r
142         if ($SAVE_GNUPLOT) {\r
143                 die unless open (PLOT, ">$GP_OUTPUT");\r
144         }\r
145         else {\r
146                 die unless open (PLOT, "|$GNUPLOT_PATH $GNUPLOT_OPTS");\r
147         }\r
148 \r
149         $preamble = `cat $ProgDir/template.gp`;\r
150         print PLOT $preamble;\r
151 \r
152         print PLOT "set terminal $TERMINAL\n";\r
153         print PLOT "set output \'$OUTPUT\'\n";\r
154         if (defined $SIZE) {\r
155                 print PLOT "set size $SIZE\n";\r
156         }\r
157 \r
158         if (defined $TITLE_TEXT) {\r
159                 print PLOT "set title \"$TITLE_TEXT\"\n";\r
160         }\r
161 \r
162         if (defined $EXTRA_CMD) {\r
163                 print PLOT "$EXTRA_CMD\n";\r
164         }\r
165 \r
166         print PLOT "set key below\n";\r
167 \r
168         if ($LAYER) {\r
169                 for ($i = 0; $i < $nfiles; $i++) {\r
170                         ($starts [$i], $ends [$i]) =\r
171                                         findFileTimeSpan ($FILES [$i]);\r
172                 }\r
173         }\r
174 \r
175         print PLOT "plot $PLOT_OPTS \\\n";\r
176         for ($i = 0; $i < $nfiles; $i++) {\r
177                 my $offset = 0;\r
178                 my $scale = 1;\r
179                 if (defined $SCALES[$i]) {\r
180                         $scale = $SCALES[$i];\r
181                 }\r
182 \r
183                 my $file = $FILES [$i];\r
184 \r
185                 if ($LAYER) {\r
186                         $offset = $starts [$i] - $starts [0];\r
187                 }\r
188 \r
189                 for ($j = 0; $j < @OPS; $j++) {\r
190                         my $op = $OPS[$j];\r
191 \r
192                         print PLOT "\t\"< $LOC2GMT_PATH -d $offset $file\" \\\n";\r
193                         print PLOT "\t\tusing 2:(\$$op*$scale) \\\n";\r
194                         if ($SHOW_KEY) {\r
195                                 print PLOT "\t\ttitle \'$file:$op\'\\\n";\r
196                         }\r
197                         print PLOT "\t\twith lines lw 2";\r
198                         if ($i != $nfiles - 1 || $j != $nops - 1) {\r
199                                 print PLOT ",\\\n";\r
200                         }\r
201                         else {\r
202                                 print PLOT "\n";\r
203                         }\r
204                 }\r
205         }\r
206         print PLOT "\n";\r
207         close PLOT;\r
208 }\r
209 \r
210 # Find the earliest and latest times in a file created by nfsscan, and\r
211 # return them as a list.  Returns the empty list if anything goes\r
212 # wrong.\r
213 \r
214 sub findFileTimeSpan {\r
215         my ($fname) = @_;\r
216         my ($smallest, $largest) = (-1, -1);\r
217 \r
218         if (! open (FF, "<$fname")) {\r
219                 return ();\r
220         }\r
221 \r
222         while (my $l = <FF>) {\r
223                 if ($l =~ /^#/) {\r
224                         next;\r
225                 }\r
226 \r
227                 @a = split (' ', $l);\r
228 \r
229                 if ($smallest < 0 || $smallest > $a[1]) {\r
230                         $smallest = $a[1];\r
231                 }\r
232                 if ($largest < 0 || $largest < $a[1]) {\r
233                         $largest = $a[1];\r
234                 }\r
235         }\r
236 \r
237         close FF;\r
238 \r
239         if ((! defined $smallest) || (! defined $largest)) {\r
240                 return ();\r
241         }\r
242 \r
243         return ($smallest, $largest);\r
244 }\r
245 \r