Warning, /Utilities/ReleaseScripts/ignominy/iggnuplot is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/env perl
0002 use File::Basename;
0003 use Getopt::Long;
0004 $|=1;
0005
0006 local $SCRIPT_DIR=dirname($0);
0007 &GetOptions(
0008 "config=s",\$config,
0009 "xscale=f",\$xscale,
0010 "yscale=f",\$yscale,
0011 "cols=i",\$cols,
0012 "field=s",\@fields,
0013 "key=s",\%KEYS,
0014 "help",\$help,
0015 "eps",\$eps,
0016 "sfile=s",\$sfile,
0017 );
0018
0019 my $tmp="";
0020 my %KEYS_INT=();
0021 local %IKEYS=();
0022 $IKEYS{FIELD}=1;
0023
0024 local %KEYS_EXTRA=();
0025 $KEYS_INT{SCRIPT_DIR}=$SCRIPT_DIR;
0026 $tmp=`whoami`; chomp $tmp; $KEYS_INT{USER}=$tmp;
0027 $tmp=`/bin/pwd`; chomp $tmp; $KEYS_INT{PWD}=$tmp;
0028 $KEYS_INT{TIME}=time;
0029 $KEYS_INT{PID}=$$;
0030 $KEYS_INT{PPID}=getppid();
0031 $KEYS_INT{INSTALL_DIR}=$SCRIPT_DIR;
0032 $KEYS_INT{THIS_DIR}="";
0033
0034 if(defined $help){&IGGNUPlot::help();}
0035
0036 foreach my $k (keys %KEYS)
0037 {
0038 if(exists $KEYS_INT{$k}){print "WARNING: \"$k\" is an internal key and you should not be passing it via command-line.\n";}
0039 $KEYS{$k}=&IGGNUPlot::expandValue($KEYS{$k});
0040 }
0041
0042 if((!defined $config) || ($config=~/^\s*$/)){$config="${SCRIPT_DIR}/iggnuplot.conf";}
0043 if(!-f $config){die "Can not find the configuration file \"$config\".";}
0044 $KEYS_INT{THIS_DIR}=dirname($config);
0045
0046 if((defined $sfile) && (!-f $sfile))
0047 {die "Specific search file \"$file\" does not exist.";}
0048
0049 if((!defined $xscale) || ($xscale=~/^\s*$/) || ($xscale<=0)){$xscale=1;}
0050 if((!defined $yscale) || ($yscale=~/^\s*$/) || ($yscale<=0)){$yscale=1;}
0051 if((!defined $cols) || ($cols=~/^\s*$/) || ($cols<=0)){$cols=1;}
0052 if(defined $eps){$eps=1;}
0053 else{$eps=0;}
0054
0055 if((defined @fields) && (@fields > 0))
0056 {
0057 my %fields1=();
0058 my @fields2=();
0059 foreach my $d (@fields)
0060 {
0061 foreach my $d1 (split /,/, $d)
0062 {
0063 if($d1=~/^\s*([^\s]+)\s*$/)
0064 {
0065 $d1=$1;
0066 if(!exists $fields1{$d1}){$fields1{$d1}=1; push @fields2,$d1;}
0067 }
0068 }
0069 }
0070 @fields=@fields2;
0071 }
0072
0073 if(@fields==0){die "You must atleast use one --field <field> command-line option.";}
0074
0075 &IGGNUPlot::readConfig($config);
0076 if(!exists $KEYS{FILTER})
0077 {die "Missing FILTER key(s) in \"$config\" file.";}
0078 elsif((!exists $KEYS{FILES}) || ($KEYS{FILES}=~/^\s*$/))
0079 {die "Missing \"FILES\" keys in the \"$config\" file.";}
0080 elsif((!exists $KEYS{XTAG}) || ($KEYS{XTAG}=~/^\s*$/))
0081 {die "Missing \"XTAG\" key in the \"$config\" file.";}
0082
0083 my $template="";
0084 if((!exists $KEYS{TEMPLATE}) || ($KEYS{TEMPLATE}=~/^\s*$/))
0085 {$template="${SCRIPT_DIR}/Template.gnu";}
0086 else{$template=$KEYS{TEMPLATE};}
0087 if(!-f $template)
0088 {die "Missing gnuplot template file for common.";}
0089
0090 my $searchFunction="IGGNUPlot::fileSearchFunc";
0091 if($sfile)
0092 {
0093 require $sfile;
0094 $searchFunction="specialSearchFunction";
0095 }
0096
0097 my %cache=();
0098 my @sorted=();
0099 foreach my $file (`ls $KEYS{FILES}`)
0100 {
0101 chomp $file;
0102 my $xtag=$KEYS{XTAG};
0103 $file=~/$xtag/;
0104 my $ver=$1;
0105 if($ver eq ""){next;}
0106 foreach my $k (@fields)
0107 {$cache{$ver}{$k}=0;}
0108 push @sorted, $ver;
0109 foreach my $f (@fields)
0110 {
0111 foreach my $filter (keys %{$KEYS{FILTER}})
0112 {
0113 $KEYS_EXTRA{FIELD}=$f;
0114 $filter=&IGGNUPlot::expandValue("$filter", 1);
0115 my $value=&$searchFunction($file,$filter);
0116 if(defined $value)
0117 {$cache{$ver}{$f}=$value;last;}
0118 delete $KEYS_EXTRA{FIELD};
0119 }
0120 }
0121 }
0122
0123 my $count=scalar(@sorted);
0124 if($count==0)
0125 {print "Nothing to plot for $PROJECT release.\n"; exit 0;}
0126 else
0127 {
0128 my $maxVersions=$KEYS{MAX_XCOUNT} || 10;
0129 my $xscale1=1+($count-($count%$maxVersions))/$maxVersions;
0130 $xscale*=$xscale1;
0131 open(GNUFILE, ">common.gnu") || die "Can not open common.gnu for writing.";
0132 open(DATAFILE, ">common.data") || die "Can not open common.data for writing.";
0133 print GNUFILE "set xtics ( \\\n";
0134 print DATAFILE "#Tag_Index ".join(" ", @fields)."\n";
0135 my $i=0;
0136 for($i=0;$i<$count-1;$i++)
0137 {
0138 my $ver=$sorted[$i];
0139 print GNUFILE "\t\"$ver\" $i, \\\n";
0140 print DATAFILE "$i ";
0141 foreach my $k (@fields)
0142 {print DATAFILE $cache{$ver}{$k}." ";}
0143 print DATAFILE "\n";
0144 }
0145 my $ver=$sorted[$i];
0146 print GNUFILE "\t\"$ver\" $i )\n";
0147 print DATAFILE "$i ";
0148 foreach my $k (@fields)
0149 {print DATAFILE $cache{$ver}{$k}." ";}
0150 print DATAFILE "\n";
0151 print GNUFILE "set size $xscale,$yscale\n";
0152 print GNUFILE "set grid\n";
0153 print GNUFILE "set term postscript eps color solid\n";
0154 print GNUFILE "set data style linespoints\n";
0155 close(GNUFILE);
0156 close(DATAFILE);
0157 }
0158
0159 if(@fields>1)
0160 {
0161 open(ALLINONEFILE, ">AllInOne.gnu") || die "Can not open AllInOne.gnu for writing.";
0162 my $ydiv=1;
0163 my $total=@fields-1;
0164 if(($total%$cols)==0){$ydiv=0;}
0165 my $ydiv=@fields;
0166 if($cols>1)
0167 {$ydiv=(@fields+($cols-(@fields%$cols)))/$cols;}
0168 my $delta=0.1;
0169
0170 print ALLINONEFILE "load \"common.gnu\"\n";
0171 print ALLINONEFILE "set size ",$cols*$xscale,",",($ydiv+$delta)*$yscale,"\n";
0172 print ALLINONEFILE "set output 'AllInOne.eps'\n";
0173 print ALLINONEFILE "set multiplot\n";
0174 my $label="Results";
0175 if(exists $KEYS{ALLINONE_LABEL}){$label=$KEYS{ALLINONE_LABEL};}
0176 print ALLINONEFILE "set label \"$label\" at screen ",$xscale*$cols/2,",",$yscale*$delta/2," center\n";
0177 print ALLINONEFILE "set size $xscale,$yscale\n\n";
0178
0179 for(my $i=0; $i<@fields; $i++)
0180 {
0181 my $k=$fields[$i];
0182 my $index=$i+2;
0183 $KEYS_EXTRA{FIELD}=$k;
0184 $KEYS_EXTRA{INDEX}=$index;
0185
0186 print ALLINONEFILE "set origin ",($i%$cols)*$xscale,",",($ydiv-1)-$yscale*(($i-$i%$cols)/$cols)+$delta,"\n";
0187 print ALLINONEFILE "plot 'common.data' using 1:$index title \"$k\"\n\n";
0188
0189 open(XFILE, ">$k.gnu") || die "Can not open $k.gnu file for writing.";
0190 foreach my $line (`cat $template`)
0191 {
0192 chomp $line;
0193 $line=&IGGNUPlot::expandValue($line,1);
0194 print XFILE "$line\n";
0195 }
0196 close("$k.gnu");
0197 delete $KEYS_EXTRA{FIELD};
0198 delete $KEYS_EXTRA{INDEX};
0199 if($eps)
0200 {system("gnuplot $k.gnu"); print "$k.eps Done\n";}
0201 }
0202 print ALLINONEFILE "exit\n";
0203 close(ALLINONEFILE);
0204 if($eps)
0205 {system("gnuplot AllInOne.gnu");print "AllInOne.eps Done\n";}
0206 }
0207 else
0208 {
0209 for(my $i=0; $i<@fields; $i++)
0210 {
0211 my $k=$fields[$i];
0212 my $index=$i+2;
0213 $KEYS_EXTRA{FIELD}=$k;
0214 $KEYS_EXTRA{INDEX}=$index;
0215 open(XFILE, ">$k.gnu") || die "Can not open $k.gnu file for writing.";
0216 foreach my $line (`cat $template`)
0217 {
0218 chomp $line;
0219 $line=&IGGNUPlot::expandValue($line,1);
0220 print XFILE "$line\n";
0221 }
0222 close("$k.gnu");
0223 delete $KEYS_EXTRA{FIELD};
0224 delete $KEYS_EXTRA{INDEX};
0225 if($eps)
0226 {system("gnuplot $k.gnu");print "$k.eps Done\n";}
0227 }
0228 }
0229
0230
0231 sub IGGNUPlot::readConfig ()
0232 {
0233 my $config=shift || return;
0234 foreach my $line (`cat $config`)
0235 {
0236 chomp $line;
0237 if($line=~/^\s*(#.*|)$/){next;}
0238 if($line=~/^\s*FILTER\s*=(.+)$/)
0239 {$KEYS{FILTER}{&IGGNUPlot::expandValue($1)}=1;}
0240 elsif($line=~/^\s*(.+?)\s*=\s*(.+?)\s*$/)
0241 {
0242 my $k=&IGGNUPlot::expandValue($1);
0243 if(exists $KEYS{$k}){next;}
0244 my $v=&IGGNUPlot::expandValue($2);
0245 $KEYS{$k}=$v;
0246 }
0247 }
0248 }
0249
0250 sub IGGNUPlot::expandValue ()
0251 {
0252 my $value=shift || return "";
0253 my $noikeys=shift;
0254 my $error=0;
0255 my $newvalue="";
0256 while($value=~/^(.*?)\$\{(.+?)\}(.*)$/)
0257 {
0258 $value=$3;
0259 $newvalue="${newvalue}$1";
0260 my $key=$2;
0261 if((!defined $noikeys) && (exists $IKEYS{$key}))
0262 {$newvalue="${newvalue}\$\{$key\}";}
0263 elsif(exists $KEYS_EXTRA{$key}){$newvalue="${newvalue}".&IGGNUPlot::expandValue($KEYS_EXTRA{$key},$noikeys);}
0264 elsif(exists $KEYS_INT{$key}) {$newvalue="${newvalue}".&IGGNUPlot::expandValue($KEYS_INT{$key},$noikeys);}
0265 elsif(exists $KEYS{$key}) {$newvalue="${newvalue}".&IGGNUPlot::expandValue($KEYS{$key},$noikeys);}
0266 elsif(exists $ENV{$key}) {$newvalue="${newvalue}".&IGGNUPlot::expandValue($ENV{$key},$noikeys);}
0267 else
0268 {
0269 while($value=~s/\$\{$key\}//){}
0270 print "ERROR: The variable \"$key\" is not passed using \"--key $key=value\" and also not available in your environment variables.\n";
0271 $error=1;
0272 }
0273 }
0274 $newvalue="${newvalue}${value}";
0275 if($error){exit 1;}
0276 return $newvalue;
0277 }
0278
0279 sub IGGNUPlot::fileSearchFunc ()
0280 {
0281 my $file=shift || return undef;
0282 my $filter=shift || return undef;
0283 if(!-f $file){return undef;}
0284 foreach my $line (`cat $file`)
0285 {
0286 chomp $line;
0287 if($line=~/$filter/)
0288 {return $1;}
0289 }
0290 return undef;
0291 }
0292
0293 sub IGGNUPlot::usage ()
0294 {
0295 print "$0 \\\n";
0296 print "\t[--help] [--eps] [--config <configfile>] \\\n";
0297 print "\t[--xscale <xscale>] [--yscale <yscale>] \\\n";
0298 print "\t[--cols <number of graphs per row>] \\\n";
0299 print "\t[--field <comma separated list> [--field <comma separated list> [...]]] \\\n";
0300 print "\t[--key <key=value> [--key <key=value> [...]]]\\\n";
0301 print "\t[--sfile <file>]\n\n";
0302 }
0303
0304 sub IGGNUPlot::help()
0305 {
0306 &IGGNUPlot::usage();
0307 print "This script is to help you to generate grapghs using gnuplot. Idea is that you have many files\n";
0308 print "in different directories and you want to search all these files and plot it. e.g. you have \n";
0309 print "/home/dir1/file, /home/dir2/file, /home/dir3/file.../home/dirn/file and each file contains a field\n";
0310 print " \"MyData <some number>\"\nNow you want to generate a plot b/w dirname and MyData then this script\n";
0311 print "will search all the files and generate plots. (filters for file names, field search hould be\n";
0312 print "available in the configuration file. for this example your configuration file should look like\n\n";
0313 print "TEMPLATE=\${THIS_DIR}/IgGNUPlotTemplate_CMS.gnu\n";
0314 print "FILES=/home/dir*/file\n";
0315 print "FILTER=^\\s*\${FIELD}\\s+(\\d+(\\.\\d+|))\\s*\$\n";
0316 print "XTAG=\\/home\\/(dir\\d+)\\/.+\n";
0317 print "ALLINONE_LABEL=My test data results\n";
0318 print "TEMPLATE_XLABEL=Version(s)\n";
0319 print "TEMPLATE_TITLE=Version(s) vs \${FIELD}\n\n";
0320 print "Command-line argument keys override the keys defined in the configuration file.\n\n";
0321 print "One can write a perl script with specialSearchFunction(file, filter); sub-routine in it to\n";
0322 print "implement a special search method. e.g. if you want to plot the size of same file exist in different\n";
0323 print "version then your sfile could have some thing like\n";
0324 print " sub specialSearchFunction(){\n";
0325 print " my \$file=shift;\n";
0326 print " my \$filter=shift;\n";
0327 print " my \@data=stat \$file;\n";
0328 print " return \$data[7];\n";
0329 print " }\n";
0330 print " 1;\n\n";
0331 exit 0;
0332 }