#!/usr/bin/perl -w require 5.003; use strict; # plots traces labeled with label_results # see also: label_results, report_results if (`pwd` =~ 'ReportGen') { use lib '..'; } use ReportGen::Opts; use ReportGen::Globs; use ReportGen::ObjDbase; require ReportGen::Plot; require ReportGen::Line; # Configuration my %Opts = ( out_name => undef(), sort_by => undef(), plot_title => undef(), plotter_terminal => undef(), plotter => undef(), plotter_opts => undef(), ); my %SavedOpts = %Opts; # globals my $Meas; # what measurement to plot my $IFName; my ($MeasPos, $MeasType); my ($SortPos); my (@LineLabels, @LineTypes, @LineNames); my $LabelWidthMax = -10; my $Plot; &init(); exit(&main()); sub main { &scanLineLabels(); $Plot = new ReportGen::Plot(join(' ', $0, @ARGV)); &setXLabel(); &setYLabel(); &setXTics(); &setTitle(); &setOther(); &addLines(); &setTerminal($Opts{plotter_terminal}); &setOutput($Opts{out_name}); &plot(); return 0; } sub scanLineLabels { my @lines = (); my %vendors = (); my $typeCount = 0; #system("jove $IFName") if $Opts{plot_title} =~ /Median/; my $IF = new FileHandle("<$IFName") or die("$0: cannot open $IFName; $!\n"); while (<$IF>) { next if /^\#/; next if /^\s*$/; chomp; my ($fields, $name) = ($_ =~ /^\s*(.*)\s*\"([^\"]*)\"$/); die("$0: cannot parse line: `$_', stopped") unless defined $fields && defined $name; my ($vendor) = ($name =~ /^([^-]+)/); die($name) unless defined $vendor; $vendors{$vendor} = &VendType($vendor) unless defined $vendors{$vendor}; my @fields = split /\s+/, $fields; push @lines, [ @fields, $vendors{$vendor}, $name ]; $LabelWidthMax = length($fields[0]) if length($fields[0]) > $LabelWidthMax; } @lines = sort cmpLines grep { knownLine($_) } @lines if defined $SortPos; @LineLabels = map { $_->[0] } @lines; @LineTypes = map { $_->[$#{$_}-1] } @lines; @LineNames = map { $_->[$#{$_}] } @lines; } sub setXLabel { $Plot->xlabel_qw(''); } sub setYLabel { $Plot->ylabel_qw($MeasType); } sub setXTics { $Plot->xtics('rotate') if @LineLabels > 5; $Plot->tics('x', map { $LineNames[$_], $_ } 0 .. $#LineNames); } sub setTitle { my $title = $Opts{plot_title}; $Plot->title($title) if defined $title; } sub setOther { $Plot->range('x', -1, scalar @LineLabels); $Plot->range('y', 0); $Plot->set('size 1,0.85'); $Plot->set("bmargin $LabelWidthMax/2") if @LineLabels > 5; $Plot->data('style boxes'); $Plot->set('boxwidth 0.75'); $Plot->grid(); #$Plot->timestamp(); } sub addLines { # plot each line separately so that they appear in different colors my $count = 0; for (my $li = 0; $li <= $#LineLabels; ++$li) { my $llabel = $LineLabels[$li]; my $lt = $LineTypes[$li]; my $line = new ReportGen::Line; my $filter = "grep '^$llabel\[[:space:]]' $IFName"; $line->data("<$filter"); $line->using($count, "\$$MeasPos"); $line->with("boxes lt $lt"); $line->title(''); $Plot->line($line); $count++; } } sub setTerminal { my $term = shift; $Plot->terminal($term) if $term; } sub setOutput { my $fname = shift; $Plot->output($fname) if defined $fname; } sub plot { if (my $fname = $Plot->ofile()) { warn("$0: plotting: `$fname'\n"); } #warn($Plot->image()); $Plot->plot(); } sub cmpLines { die('cmpLines') unless defined $SortPos; return cmpFields($a->[$SortPos-1], $b->[$SortPos-1]); } sub knownLine { my $line = shift; die('knownLines') unless defined $SortPos; return $line->[$SortPos-1] =~ /^\d/; } sub cmpFields($$) { my ($x, $y) = @_; return $x <=> $y if $x =~ /^\d/ && $y =~ /^\d/; return $x cmp $y; } sub getObjPos { my ($fname, $name) = @_; open(IF, "<$fname") or die("$0: cannot open `$fname': $!\n"); my $firstLine = ; close(IF); my @names = split(/\s+/, $firstLine); die("$0: `$fname' has unknown file format\n") unless @names && $names[0] =~ s/^#//; my $pos = 1; foreach my $n (@names) { return $pos if $n eq $name; $pos++; } #die("$0: `$fname' has no object named `$name'\n"); return undef(); } sub init { my @params = (); die(&usage()) unless &ParseOpts(\%Opts, \@params, @ARGV) && @params == 2; die("plotter must be specified\n" . &usage()) unless $Opts{plotter}; $ReportGen::Plot::Plotter = $Opts{plotter}; $ReportGen::Plot::Plotter .= ' ' . $Opts{plotter_opts} if $Opts{plotter_opts}; ($Meas, $IFName) = @params; $MeasType = &ObjName2Type($Meas); die("$0: unknown object `$Meas'\n") unless $MeasType; $MeasPos = getObjPos($IFName, $Meas); die("$0: `$IFName' has no object named `$Meas'\n") unless defined $MeasPos; my $sortField = $Opts{'sort_by'}; if (defined $sortField) { $SortPos = getObjPos($IFName, $sortField); die("$0: cannot sort by `$sortField', not in `$IFName'\n") unless defined $SortPos && $SortPos > 0; } } sub usage { return "usage: $0 [options] \n" . &Opts2Str(\%SavedOpts); }