MetricValueFormat.java

Go to the documentation of this file.
00001 
00002 //                                     //
00003 //  MetricValueFormat.java                         //
00004 //                                     //
00005 //  experiment.MetricValueFormat -- a value of a metric at some scope  //
00006 //  Last edited: January 15, 2002 at 12:37 am              //
00007 //                                     //
00008 //  (c) Copyright 2002 Rice University. All rights reserved.       //
00009 //                                     //
00011 
00012 
00013 
00014 
00015 package edu.rice.cs.hpc.data.experiment.metric;
00016 
00017 
00018 import edu.rice.cs.hpc.data.util.*;
00019 
00020 import java.text.DecimalFormat;
00021 
00022 
00023 
00025 //  CLASS METRIC-VALUE-FORMAT                   //
00027 
00035 public class MetricValueFormat implements IMetricValueFormat
00036 {
00037 
00038     protected static class Style
00039     {
00041         public int kind;
00042 
00044         public int fieldWidth;
00045 
00047         public int fractionDigits;
00048     };
00049 
00050 
00052 protected boolean showValue;
00053 
00055 protected boolean showAnnotation;
00056 
00058 protected Style valueStyle;
00059 
00061 protected Style annotationStyle;
00062 
00064 protected String annotationFormatPattern;
00065 
00067 protected int separatorWidth;
00068 
00070 protected DecimalFormat valueFormatter;
00071 
00073 protected DecimalFormat annotationFormatter;
00074 
00076 protected String separator;
00077 
00078 
00079 
00080 
00082 //  PUBLIC CONSTANTS                        //
00084 
00085 
00086 
00087 
00089 public static int FIXED = 1;
00090 
00092 public static int FLOAT = 2;
00093 
00094 
00095 
00096 
00098 //  INITIALIZATION                                                      //
00100 
00101 
00102 
00103 
00104 /*************************************************************************
00105  *  Creates a fully specified format.
00106  ************************************************************************/
00107     
00108 public MetricValueFormat(boolean showValue,
00109                          int valueKind,
00110                          int valueFieldWidth,
00111                          int valueFractionDigits,
00112                          boolean showAnnotation,
00113                          int annotationKind,
00114                          int annotationFieldWidth,
00115                          int annotationFractionDigits,
00116                          String annotationFormatPattern,
00117                          int separatorWidth)
00118 {
00119     // creation arguments
00120     this.showValue = showValue;
00121     this.valueStyle = new MetricValueFormat.Style();
00122     this.valueStyle.kind = valueKind;
00123     this.valueStyle.fieldWidth = valueFieldWidth;
00124     this.valueStyle.fractionDigits = valueFractionDigits;
00125     
00126     this.showAnnotation = showAnnotation;
00127     this.annotationStyle = new MetricValueFormat.Style();
00128     this.annotationStyle.kind = annotationKind;
00129     this.annotationStyle.fieldWidth = annotationFieldWidth;
00130     this.annotationStyle.fractionDigits = annotationFractionDigits;
00131     if (annotationFormatPattern == null) {
00132         annotationFormatPattern = "#0.0%";          // need to have something so default to what is used for percent values.
00133     }
00134     this.annotationFormatPattern = annotationFormatPattern;
00135     
00136     this.separatorWidth = separatorWidth;
00137     
00138     // Java formatters are initialized lazily
00139     this.clearFormatters();
00140 }
00141 
00142 
00143 
00144 
00146 //  ACCESS TO FORMAT                                                    //
00148 
00149 
00150 
00151 
00152 /*************************************************************************
00153  *  Sets whether to show the actual value.
00154  ************************************************************************/
00155     
00156 public void setShowValue(boolean showValue)
00157 {
00158     this.showValue = showValue;
00159     this.clearFormatters();
00160 }
00161 
00162 
00163 
00164 
00165 /*************************************************************************
00166  *  Returns whether to show the actual value.
00167  ************************************************************************/
00168     
00169 public boolean getShowValue()
00170 {
00171     return this.showValue;
00172 }
00173 
00174 
00175 
00176 
00177 /*************************************************************************
00178  *  Sets the kind of numeric display to be used for the actual value.
00179  *  
00180  *  @param kind     either <code>MetricValueFormat.FIXED</code> or
00181  *                  <code>MetricValueFormat.FLOAT</code>
00182  *
00183  ************************************************************************/
00184     
00185 public void setValueKind(int kind)
00186 {
00187     this.valueStyle.kind = kind;
00188     this.clearFormatters();
00189 }
00190 
00191 
00192 
00193 
00194 /*************************************************************************
00195  *  Returns the kind of numeric display to be used for the actual value.
00196  *  
00197  *  @return     either <code>MetricValueFormat.FIXED</code> or
00198  *              <code>MetricValueFormat.FLOAT</code>
00199  *
00200  ************************************************************************/
00201     
00202 public int getValueKind()
00203 {
00204     return this.valueStyle.kind;
00205 }
00206 
00207 
00208 
00209 
00210 /*************************************************************************
00211  *  Sets the total number of characters to be used for the actual value.
00212  ************************************************************************/
00213     
00214 public void setValueFieldWidth(int fieldWidth)
00215 {
00216     this.valueStyle.fieldWidth = fieldWidth;
00217     this.clearFormatters();
00218 }
00219 
00220 
00221 
00222 
00223 /*************************************************************************
00224  *  Returns the total number of characters to be used for the actual value.
00225  ************************************************************************/
00226     
00227 public int getValueFieldWidth()
00228 {
00229     return this.valueStyle.fieldWidth;
00230 }
00231 
00232 
00233 
00234 
00235 /*************************************************************************
00236  *  Sets the number of digits to be used for the fractional part of the
00237  *  actual value.
00238  ************************************************************************/
00239     
00240 public void setValueFractionDigits(int fractionDigits)
00241 {
00242     this.valueStyle.fractionDigits = fractionDigits;
00243     this.clearFormatters();
00244 }
00245 
00246 
00247 
00248 
00249 /*************************************************************************
00250  *  Returns the number of digits to be used for the fractional part of the
00251  *  actual value.
00252  ************************************************************************/
00253     
00254 public int getValueFractionDigits()
00255 {
00256     return this.valueStyle.fractionDigits;
00257 }
00258 
00259 
00260 
00261 
00262 /*************************************************************************
00263  *  Sets whether to show the metrics annotation.
00264  ************************************************************************/
00265     
00266 public void setShowAnnotation(boolean showAnnotation)
00267 {
00268     this.showAnnotation = showAnnotation;
00269     this.clearFormatters();
00270 }
00271 
00272 
00273 
00274 
00275 /*************************************************************************
00276  *  Returns whether to show the metrics annotation.
00277  ************************************************************************/
00278     
00279 public boolean getShowAnnotation()
00280 {
00281     return this.showAnnotation;
00282 }
00283 
00284 
00285 
00286 
00287 /*************************************************************************
00288  *  Sets the kind of numeric display to be used with a metrics annotation.
00289  *  
00290  *  @param kind     either <code>MetricValueFormat.FIXED</code> or
00291  *                  <code>MetricValueFormat.FLOAT</code>
00292  *
00293  ************************************************************************/
00294     
00295 public void setAnnotationKind(int kind)
00296 {
00297     this.annotationStyle.kind = kind;
00298     this.clearFormatters();
00299 }
00300 
00301 
00302 
00303 
00304 /*************************************************************************
00305  *  Returns the kind of numeric display to be used with a metrics annotation.
00306  *  
00307  *  @return     either <code>MetricValueFormat.FIXED</code> or
00308  *              <code>MetricValueFormat.FLOAT</code>
00309  *
00310  ************************************************************************/
00311     
00312 public int getAnnotationKind()
00313 {
00314     return this.annotationStyle.kind;
00315 }
00316 
00317 
00318 
00319 
00320 /*************************************************************************
00321  *  Sets the total number of characters to be used for the metrics annotation.
00322  ************************************************************************/
00323     
00324 public void setAnnotationFieldWidth(int fieldWidth)
00325 {
00326     this.annotationStyle.fieldWidth = fieldWidth;
00327     this.clearFormatters();
00328 }
00329 
00330 
00331 
00332 
00333 /*************************************************************************
00334  *  Returns the total number of characters to be used for the metrics annotation.
00335  ************************************************************************/
00336     
00337 public int getAnnotationFieldWidth()
00338 {
00339     return this.annotationStyle.fieldWidth;
00340 }
00341 
00342 
00343 
00344 
00345 /*************************************************************************
00346  *  Sets the number of digits to be used for the fractional part of the
00347  *  metrics annotation.
00348  ************************************************************************/
00349     
00350 public void setAnnotationFractionDigits(int fractionDigits)
00351 {
00352     this.annotationStyle.fractionDigits = fractionDigits;
00353     this.clearFormatters();
00354 }
00355 
00356 
00357 
00358 
00359 /*************************************************************************
00360  *  Returns the number of digits to be used for the fractional part of the
00361  *  metrics annotation.
00362  ************************************************************************/
00363     
00364 public int getAnnotationFractionDigits()
00365 {
00366     return this.annotationStyle.fractionDigits;
00367 }
00368 
00369 
00370 
00371 
00372 /*************************************************************************
00373  *  Sets the number of space characters to separate the metric value and
00374  *  its annotation.
00375  ************************************************************************/
00376     
00377 public void setSeparatorWidth(int separatorWidth)
00378 {
00379     this.separatorWidth = separatorWidth;
00380     this.clearFormatters();
00381 }
00382 
00383 
00384 
00385 
00386 /*************************************************************************
00387  *  Returns the number of space characters to separate the metric
00388  *  value and its annotation.
00389  ************************************************************************/
00390     
00391 public int getSeparatorWidth()
00392 {
00393     return this.separatorWidth;
00394 }
00395 
00396 
00397 
00398 
00400 //  FORMATTING                                                          //
00402 
00403 
00404 
00405 
00406 /*************************************************************************
00407  *  Returns the number of characters in a metric value formatted by this format.
00408  ************************************************************************/
00409     
00410 public int getFormattedLength()
00411 {
00412     int width1 = (this.showValue ? this.valueStyle.fieldWidth : 0);
00413     int width2 = (this.showAnnotation ? this.annotationStyle.fieldWidth : 0);
00414     int width3 = (this.showValue && this.showAnnotation ? this.separatorWidth : 0);
00415     return width1 + width2 + width3 + 1;    // +1 for trailing space
00416 }
00417 
00418 /*
00427 public String format(double value) {
00428     StringBuffer formatted = new StringBuffer();
00429     String string = this.formatDouble(value, this.valueFormatter, this.valueStyle);
00430     formatted.append(string);
00431     formatted.append(Util.spaces(this.annotationStyle.fieldWidth));
00432     return formatted.toString();
00433 }*/
00434 /*************************************************************************
00435  *  Returns a <code>String</code> showing a given <code>MetricValue</code>
00436  *  according to this format.
00437  ************************************************************************/
00438     
00439 public String format(MetricValue value)
00440 {
00441     this.ensureFormatters();
00442     StringBuffer formatted = new StringBuffer();
00443     
00444     // append formatted actual value if wanted
00445     if( this.showValue )
00446     {
00447         double number = MetricValue.getValue(value);
00448         String string = this.formatDouble(number, this.valueFormatter, this.valueStyle);
00449         formatted.append(string);
00450     }
00451     
00452     // append separating spaces if needed
00453     if( this.showValue && this.showAnnotation )
00454         formatted.append(this.separator);
00455     
00456     // append formatted annotation if wanted
00457     if( this.showAnnotation )
00458     {
00459         if( MetricValue.isAnnotationAvailable(value) )
00460         {
00461             double number = MetricValue.getAnnotationValue(value);
00462 
00463             // if the formatter pattern is set for percent values, we need to handle special values differently
00464             if (this.annotationFormatPattern.contains("%")) {
00465                 // if value shows this used all of it, show that without decimal places
00466                 if (number == 1.0) {
00467                     formatted.append("100 %");
00468                     return formatted.toString();
00469                 }
00470 
00471                 // if value shows a small negative number, show a percent of zero
00472                 if ( (number > -0.0001) && (number < 0.0) ) {
00473                     // Laks 2009.02.12: dirty hack to solve the problem when a small negative percentage occurs
00474                     // instead of displaying -0.0% we force to display 0.0%
00475                     // a better solution is by defining the proper pattern. But so far I don't see any good solution
00476                     //  this hack should be a temporary fix !
00477                     formatted.append(" 0.0%");
00478                     return formatted.toString();
00479                 }
00480             }
00481 
00482             // not a value that needs special treatment, just format with the specified pattern
00483             String string = this.formatDouble(number, this.annotationFormatter, this.annotationStyle);
00484             formatted.append(string);
00485             return formatted.toString();
00486         }
00487 
00488         formatted.append(Util.spaces(this.annotationStyle.fieldWidth));
00489     }
00490     
00491     return formatted.toString();
00492 }
00493 
00494 
00495 
00496 
00497 /*************************************************************************
00498  *  Returns a <code>String</code> showing a given <code>MetricValue</code>
00499  *  according to this format.
00500  ************************************************************************/
00501     
00502 protected String formatDouble(double d, DecimalFormat formatter, Style style)
00503 {
00504     int kind = style.kind;
00505     int fieldWidth = style.fieldWidth;
00506     String s;
00507     
00508     if( kind == FLOAT )
00509     {
00510         // hpcrun can generate incorrect metrics which are incredibly huge 
00511         // converted in Java it becomes infinity
00512         
00513         if (d == Float.POSITIVE_INFINITY)
00514             return "" ;
00515                     
00516         int exponent = 0;
00517         // laks: if d = 9.999, the formatter will force to round it to 10.00
00518         //  since I don't know how to prevent the rounding, let make a dirty solution here
00519         // Laks 2009.02.12: turn it back to the original format. Previously: > 9.5
00520         // Laks 2009.02.13: bug fix for displaying 9.9 into 1.0e+01 instead of 10.0
00521         while ( Math.abs(d) > 9.5 )//Laks 2008.09.03 fix previously ( Math.abs(d) >= 10.0 )
00522         {
00523             d /= 10.0;
00524             exponent += 1;
00525         }
00526         if (d != 0.0) {
00527             // Laks 2009.02.12: turn it back to the original format. Previously: < 9.5
00528             // Laks 2009.02.13: bug fix for displaying .999x into 1.0e00 and .99x into 9.9x
00529             // FIXME this is an ugly bug fix, but since the formatter is handled by jvm, we have to hack from here
00530             while( Math.abs(d) <= 0.999 )//laks 2008.09.03 fix, previously ( Math.abs(d) < 1.0 )
00531             {
00532                 d *= 10.0;
00533                 exponent -= 1;
00534             }
00535         }
00536         String e = Integer.toString(Math.abs(exponent));
00537         if( e.length() == 1 ) e = "0" + e;
00538         s = formatter.format(d) + "e";
00539         s = s + ((exponent < 0) ? "-" : "+") + e;
00540     }
00541     else
00542         s = Util.formatDouble(d, formatter, fieldWidth);
00543 
00544     return s;
00545 }
00546 
00547 
00548 
00549 
00550 /*************************************************************************
00551  *  Removes outdated Java <code>DecimalFormat</code> objects.
00552  *
00553  *  New ones will be created when needed.
00554  ************************************************************************/
00555     
00556 protected void clearFormatters()
00557 {
00558     this.valueFormatter   = null;
00559     this.annotationFormatter = null;
00560     this.separator        = null;
00561 }
00562 
00563 
00564 
00565 
00566 /*************************************************************************
00567  *  Creates Java <code>DecimalFormat</code> objects if necessary.
00568  ************************************************************************/
00569     
00570 protected void ensureFormatters()
00571 {
00572     // value formatter
00573     if( this.valueFormatter == null )
00574     {
00575         String pattern = "0.";
00576 
00577         // use the number of fractional digits to craft the pattern
00578         int decdigits = getValueFractionDigits();
00579         while (decdigits-- > 0) {
00580             pattern = pattern + "0";
00581         }
00582 
00583         this.valueFormatter = Util.makeDecimalFormatter(pattern);
00584     }
00585     
00586     // annotation formatter
00587     if( this.annotationFormatter == null )
00588     {
00589         this.annotationFormatter = Util.makeDecimalFormatter(this.annotationFormatPattern);
00590     }
00591     
00592     // separation between values
00593     this.separator = Util.spaces(this.separatorWidth);
00594 }
00595 
00596 
00597 
00598 
00599 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1