File Coverage

blib/lib/Simulation/Automate/PostProcessors.pm
Criterion Covered Total %
statement 15 233 6.4
branch 0 46 0.0
condition 0 27 0.0
subroutine 5 17 29.4
pod 0 11 0.0
total 20 334 5.9


line stmt bran cond sub pod time code
1             package Simulation::Automate::PostProcessors;
2              
3 1     1   6 use vars qw( $VERSION );
  1         2  
  1         111  
4             $VERSION = "1.0.1";
5              
6             ################################################################################
7             # #
8             # Copyright (C) 2000,2002-2003 Wim Vanderbauwhede. All rights reserved. #
9             # This program is free software; you can redistribute it and/or modify it #
10             # under the same terms as Perl itself. #
11             # #
12             ################################################################################
13              
14             #=headers
15              
16             #Module to support SynSim simulation automation tool.
17             #This module contains all subroutines needed for postprocessing of the simulations results.
18             #Some routines are quite generic, but most are specific to the type of simulation.
19              
20             #$Id$
21              
22             #=cut
23             ##use warnings;
24             ##use strict;
25              
26 1     1   6 use Carp;
  1         2  
  1         137  
27 1     1   7 use lib '.','..';
  1         6  
  1         19  
28              
29 1     1   208 use Simulation::Automate::Analysis;
  1         2  
  1         214  
30 1     1   7 use Simulation::Automate::PostProcLib;
  1         2  
  1         5555  
31              
32             ##################################################################################
33             # Three generic routines are provided:
34             # SweepVar: to make a sweep over one variable while using any number of parameters
35             # ErrorFlags:
36             # Histogram: to create simple histograms
37              
38             #------------------------------------------------------------------------------
39             # This is a very generic module to generate XY plots from any sweep
40             sub XYPlot {
41             #determine whether the results are single points or a range
42 0 0 0 0 0   if($xvar && @{$simdata{$xvar}}>1) { # point by point
  0            
43 0           my @sweepvarvals=@{$simdata{$sweepvar}};
  0            
44              
45             # This is to combine the values for different buffers into 1 file
46 0 0         if ($verylast==0) {
47 0           open(RES,">$results_file_name");
48 0           print RES $resheader;
49             # Now add the simulation results. The difference with the raw data
50             # is that the value of $sweepvar is added as the first column.
51 0           my $i=0;
52 0           foreach my $sweepvarval ( @sweepvarvals ) {
53 0           print RES "$sweepvarval\t$results[$i]";
54 0           $i++;
55             }
56 0           close RES;
57             } else {
58             # On the very last run, collect the results into one nice plot
59             # X values are in the first col, so add 1 to YCOL
60 0           $ycol++;
61              
62 0           &gnuplot_combined();
63             }
64             } else {
65 0 0         if(not $verylast) {
66 0           open(RES,">$results_file_name");
67 0           print RES $resheader;
68             # Now add the simulation results. The difference with the raw data
69             # is that the value of $sweepvar is added as the first column.
70 0           foreach my $line ( @results ) {
71 0           print RES $line;
72             }
73 0           close RES;
74             } else {
75             ### On the very last run, collect the results into one nice plot
76 0           &gnuplot_combined();
77             }
78             }
79             } #END of XYPlot
80              
81             #------------------------------------------------------------------------------
82             # This is a very generic module to generate plots from any sweep
83              
84             sub PlotXYfromPoints {
85              
86 0     0 0   my @sweepvarvals=@{$simdata{$sweepvar}};
  0            
87              
88             # This is to combine the values for different buffers into 1 file
89 0 0         if ($verylast==0) {
90 0           open(RES,">$results_file_name");
91 0           print RES $resheader;
92             # Now add the simulation results. The difference with the raw data
93             # is that the value of $sweepvar is added as the first column.
94 0           my $i=0;
95 0           foreach my $sweepvarval ( @sweepvarvals ) {
96 0           print RES "$sweepvarval\t$results[$i]";
97 0           $i++;
98             }
99 0           close RES;
100             } else {
101             # On the very last run, collect the results into one nice plot
102             # X values are in the first col, so add 1 to YCOL
103 0           $ycol++;
104 0           &gnuplot_combined();
105             }
106              
107             } #END of PlotXYfromPoints
108              
109             #------------------------------------------------------------------------------
110             sub PlotXYfromRange {
111              
112 0 0   0 0   if($verylast) {
113             ### On the very last run, collect the results into one nice plot
114 0           &gnuplot_combined();
115             }
116              
117             } #END of PlotXYfromRange()
118              
119             #------------------------------------------------------------------------------
120              
121             sub XYPlotErrorBars {
122              
123 0     0 0   my $sweepvarval=$simdata{$sweepvar}[0];
124              
125 0 0         if($verylast) {#very last run
126              
127             ## With NRUNS, we must wait until the very last run to calc the error flags.
128             # Get all results files.
129 0           my %allresfiles=();
130 0           foreach my $resfile (@all_results_file_names) {
131 0 0         $resfile!~/NRUNS/ && next;
132 0           my $resfilenorun=$resfile;
133 0           $resfilenorun=~s/__NRUNS-\d+/__NRUNS-/;
134 0           $allresfiles{$resfilenorun}=1;
135             }
136              
137             ## Loop over all result files
138 0           foreach my $resfile (keys %allresfiles) {
139             ## For each of these, loop over all runs
140              
141 0           my @allruns=();
142 0           my $allpoints=0;
143 0           foreach my $run (1..$nruns) {
144 0           my $thisrun=$resfile;
145 0           $thisrun=~s/__NRUNS-/__NRUNS-$run/;
146 0           open(RES,"<$thisrun");
147 0           my $i=0;
148 0           while() {
149 0 0         /^#/ && next;
150 0 0         /^\s*$/ && next;
151 0           $allruns[$run][$i]=$_;
152 0           $i++;
153             }
154 0           $allpoints=$i;
155 0           close RES;
156 0           unlink "$thisrun"; # This is quite essential, otherwise it will be included in the plot
157             }
158 0           my $sweepvalsnorun=$resfile;
159 0           $sweepvalsnorun=~s/__NRUNS-\d*//;
160 0           $sweepvalsnorun=~s/\-\-/\-/g;
161 0           $sweepvalsnorun=~s/\-$//;
162              
163              
164 0           open(STAT,">$sweepvalsnorun");
165 0 0         if($sweepvar) {
166 0           foreach my $i (0..$allpoints-1) {
167 0           open(TMP,">tmp$i.res");
168 0           foreach my $run (1..$nruns) {
169 0           $allruns[$run][$i]=~s/^\d+\s+//;
170 0           print TMP $simdata{$sweepvar}->[$i],"\t",$allruns[$run][$i];
171 0           print $simdata{$sweepvar}->[$i],"\t",$allruns[$run][$i];
172             }
173 0           close TMP;
174              
175             # calc average after every $count
176 0           my $par='PARAM';
177 0           my %stats=%{&calc_statistics("tmp$i.res",[$par, $datacol])};
  0            
178 0           unlink "tmp$i.res";
179 0           my $avg=$stats{$par}{AVG}/$normvar;
180 0           my $stdev=$stats{$par}{STDEV}/$norm;
181             #Parameter should be NSIGMAS, user can choose. As it is a postprocessing par, the syntax is 'NSIGMAS : 1.96'
182 0   0       my $nsigmas=$simdata{NSIGMAS}||1.96;
183 0           my $minerr=$avg-$nsigmas*$stdev; # 2 sigma = 95% MAKE THIS A PARAMETER! CONFIDENCE
184 0           my $maxerr=$avg+$nsigmas*$stdev; # 2 sigma = 95%
185              
186 0           print STAT $simdata{$sweepvar}->[$i],"\t$avg\t$minerr\t$maxerr\n";
187             }
188             } else {# no sweepvar, assuming the simulator does the sweep
189 0           my @tmpres=();
190 0           my $i=0;
191 0           foreach my $run (1..$nruns) {
192 0           $i=0;
193 0           foreach (@{$allruns[$run]}) {
  0            
194 0 0         /^\s+$/ && next;
195 0 0         /^\s*\#/ && next;
196 0           chomp;
197 0           s/\s+$//;
198 0           s/^\s+//;
199 0           my @row=split(/[\s\t]+/,$_);
200 0           push @{$tmpres[$i]},$row[$datacol-1];
  0            
201 0           $i++;
202             }
203             }
204 0           my $itot=$i;
205 0           $i=0;
206              
207 0           while ($i<$itot) {
208 0           open(TMP,">tmp$i.res");
209 0           foreach my $item (@{$tmpres[$i]}) {
  0            
210 0           print TMP "$item\n";
211             }
212 0           close TMP;
213             # calc average after every $count
214 0           my $par='PARAM';
215 0           my %stats=%{&calc_statistics("tmp$i.res",[$par, 1])};
  0            
216 0           unlink "tmp$i.res";
217 0           my $avg=$stats{$par}{AVG}/$normvar;
218 0           my $stdev=$stats{$par}{STDEV}/$normvar;
219             #Parameter should be NSIGMAS, user can choose. As it is a postprocessing par, the syntax is 'NSIGMAS : 1.96'
220 0   0       my $nsigmas=$simdata{NSIGMAS}||1.96;
221 0           my $minerr=$avg-$nsigmas*$stdev; # 2 sigma = 95% MAKE THIS A PARAMETER! CONFIDENCE
222 0           my $maxerr=$avg+$nsigmas*$stdev; # 2 sigma = 95%
223              
224 0           print STAT "$i\t$avg\t$minerr\t$maxerr\n";
225 0           $i++;
226             }
227              
228             } # no SWEEPVAR
229              
230 0           close STAT;
231             } # all resfiles
232              
233             ### On the very last run, collect the results into one nice plot
234              
235 0           &gnuplot_combined();
236             }
237              
238             } #END of XYPlotErrorBars()
239              
240             #------------------------------------------------------------------------------
241              
242             sub Histogram {
243              
244 0     0 0   my $sweepvarval=${$simdata{$sweepvar}}[0]; # used for nbins?!
  0            
245 0   0       my $nbins=$simdata{NBINS}||20;
246 0   0       my $binwidth=$simdata{BINWIDTH}||1;
247 0   0       my $min=$simdata{MIN}||'CALC';# was 0
248 0   0       my $max=$simdata{MAX}||'CALC';#was ($min+$nbins*$binwidth);
249 0           my $par='DATA';#must be "LOG" for log plot
250 0           my $log=''; #must be 'log' for log plot
251             #carp "LOGSCALE: $logscale\n";
252             #my @logscale=split("\n",$logscale);
253             #if($logscale[1]=~/x/i) {
254 0 0 0       if($logscale!~/nologscale/ and $logscale=~/x/i) {
255 0 0 0       $xstart=($xstart&&$xstart>0)?log($xstart)/log(10):'';
256 0 0 0       $xstop=($xstart&&$xstop>0)?log($xstop)/log(10):'';
257             # $logscale[1]=~s/x//i;
258             # $logscale="$logscale[0]\n$logscale[1]\n";
259 0           $logscale=~s/x//i;
260 0           $par='LOG';#'DATA';#must be "LOG" for log plot
261 0           $log='log'
262             }
263             #carp "LOGSCALE: $logscale\n";
264              
265 0 0         if(not $verylast) {
266 0           my %hists=%{&build_histograms($results_file_name,[$par,$datacol],$title,$log,$nbins,$min,$max)};
  0            
267              
268 0           &egrep('#',$results_file_name,'>',"tmp$results_file_name");
269 0           rename("tmp$results_file_name",$results_file_name);
270 0           open HIST,">$results_file_name";
271 0           foreach my $pair (@{$hists{$par}}) {
  0            
272 0           print HIST $pair->{BIN},"\t",$pair->{COUNT},"\n";
273             }
274 0           close HIST;
275              
276             } else {
277 0           $xcol=1;
278 0           $ycol=2;
279 0           &gnuplot_combined();
280              
281             }
282              
283              
284             } #END of Histogram()
285              
286             #------------------------------------------------------------------------------
287              
288             my %condval=();
289              
290             sub CondXYPlot {
291              
292              
293             # For every corner in the DOE:
294              
295             #The values of the conditional variable
296 0     0 0   my @condvarvals=@{$simdata{$condvar}};
  0            
297             #print STDERR "CONDVARVALS: $condvar :",join(',', @condvarvals),"\n";
298             # remove the original results file. data are in @results, so no need for it
299             # and otherwise the files appear in the final plot
300             #print STDERR "unlink $results_file_name;\n";
301 0           unlink $results_file_name;
302              
303 0 0         if(not $verylast) { # The DOE is not finished yet
304 0           my $condition_met=0;
305 0           my $i=0;
306             #This is the core routine to check the condition
307 0           foreach my $condvarval ( @condvarvals ) { # @condvarvals and @results have the same length
308 0           my @line=split(/\s+/,$results[$i]);
309 0           $i++;
310 0           my $value=$line[$datacol-1];
311 0 0 0       if( !$condition_met && eval("$value$cond")) {
312 0           $condition_met=1;
313             #print STDERR "COND is met for $value$cond\n";
314 0           my $setvarval=$current_set_vals{$setvar};
315 0           push @{$condval{$current_set_except_setvar_str}},"$setvarval $condvarval";
  0            
316             }
317             } # all results for current sweep
318              
319 0 0         if ($last) { # The X-axis sweep for the current set of parameters is finished.
320             #print STDERR "LAST :";
321 0           foreach my $valstr (keys %condval) {
322             #print STDERR "VALSTR: $valstr\n";
323 0           my $new_results_file_name=$results_file_name;
324 0           $new_results_file_name=~s/$current_set_str/$valstr/;
325 0           open(RES,">$new_results_file_name");
326 0           print RES $resheader;
327 0           foreach my $line (@{$condval{$valstr}}) {
  0            
328 0           print RES "$line\n";
329             # print STDERR "$line\n";
330             }
331 0           close RES;
332             }
333             } # if last
334             } else { ### On the very last run, collect the results into one nice plot
335             # $ycol++;
336 0           $ycol=2;
337 0           $normvarval=1;
338 0           &gnuplot_combined();
339             }
340              
341             } #END of CondXYPlot()
342             #------------------------------------------------------------------------------
343              
344             #==============================================================================
345             #
346             # PREPROCESSORS
347             #
348             # Routines for pre-processing of results
349             # All these routines modify the @results array, which is the raw data from the simulator in a line-by-line array
350             #
351             sub show_results {
352 0     0 0   print STDERR "RESULTS:\n";
353 0           for my $line (@results){
354 0           print STDERR $line;
355             }
356 0           print STDERR "-" x 78;
357 0           print STDERR "\n";
358             }
359             #------------------------------------------------------------------------------
360             sub clean_up {
361 0     0 0   for my $line (@results) {
362 0 0         ($line=~/^\s*\#/) && next;
363 0           $line=~s/^.*\:\s*//;
364             }
365             }
366             #------------------------------------------------------------------------------
367             sub square {
368 0 0   0 0   print "Calling square():\n" if $verbose;
369 0           for my $line (@results){
370 0           chomp $line;
371 0           $line*=$line;
372 0           $line.="\n";
373             }
374             }
375             #------------------------------------------------------------------------------
376             sub get_train_lengths {
377 0     0 0   my $resultsfile=shift;
378 0           my $nports=$simdata{_NPORTS}->[0];
379              
380 0           my $prevdest=0;
381 0           my @train_length=();
382              
383 0           foreach my $dest (0..$nports-1) {
384 0           $train_length[$dest]=0;
385             }
386              
387 0           foreach my $line (@results){
388 0 0         if($line!~/^DEST/){
389 0           print TMP $line;
390             } else {
391 0           chomp(my $dest=$line);
392 0           $dest=~s/^.*\s+//;
393 0 0         if($dest == $prevdest) {
394 0           $train_length[$dest]++;
395             } else {
396 0           chomp $line;
397 0           $line=~s/\d+$//;
398 0           print TMP "$_\t",$train_length[$prevdest],"\n";
399 0           foreach my $dest (0..$nports-1) {
400 0           $train_length[$dest]=0;
401             }
402 0           $train_length[$dest]++;
403 0           $prevdest=$dest;
404             }
405             }
406             }
407              
408             }
409             #==============================================================================
410             sub egrep {
411 0     0 0   my $pattern=shift;
412 0           my $infile=shift;
413 0           my $mode=shift;
414 0           my $outfile=shift;
415 0           open(IN,"<$infile");
416 0           open(OUT,"$mode$outfile");
417 0           print OUT grep /$pattern/,;
418              
419 0           close IN;
420 0           close OUT;
421             }
422              
423             #------------------------------------------------------------------------------
424              
425             sub AUTOLOAD {
426 0     0     my $subref=$Simulation::Automate::PostProcessors::AUTOLOAD;
427 0           $subref=~s/.*:://;
428 0           print STDERR "
429             There is no script for the analysis $subref in the PostProcessors.pm module.
430             This might not be what you intended.
431             You can add your own subroutine $subref to the PostProcessors.pm module.
432             ";
433              
434             }
435             #------------------------------------------------------------------------------
436             1;
437             #print STDERR "#" x 80,"\n#\t\t\tSynSim simulation automation tool\n#\n#\t\t\t(C) Wim Vanderbauwhede 2002\n#\n","#" x 80,"\n\n Module PostProcessors loaded\n\n";
438              
439