sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.power/src/com/nokia/carbide/cpp/internal/pi/power/actions/PowerStatisticsDialog.java
changeset 2 b9ab3b238396
child 5 844b047e260d
equal deleted inserted replaced
1:1050670c6980 2:b9ab3b238396
       
     1 /*
       
     2  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: 
       
    15  *
       
    16  */
       
    17 
       
    18 package com.nokia.carbide.cpp.internal.pi.power.actions;
       
    19 
       
    20 import java.text.DecimalFormat;
       
    21 import java.util.ArrayList;
       
    22 import java.util.Arrays;
       
    23 import java.util.Comparator;
       
    24 import java.util.Hashtable;
       
    25 
       
    26 import org.eclipse.swt.SWT;
       
    27 import org.eclipse.swt.events.SelectionEvent;
       
    28 import org.eclipse.swt.events.SelectionListener;
       
    29 import org.eclipse.swt.layout.GridData;
       
    30 import org.eclipse.swt.layout.GridLayout;
       
    31 import org.eclipse.swt.widgets.Button;
       
    32 import org.eclipse.swt.widgets.Composite;
       
    33 import org.eclipse.swt.widgets.Display;
       
    34 import org.eclipse.swt.widgets.Group;
       
    35 import org.eclipse.swt.widgets.Label;
       
    36 import org.eclipse.swt.widgets.Shell;
       
    37 
       
    38 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
       
    39 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
       
    40 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
       
    41 import com.nokia.carbide.cpp.pi.power.PowerTraceGraph;
       
    42 import com.nokia.carbide.cpp.pi.power.PwrTrace;
       
    43 
       
    44 
       
    45 public class PowerStatisticsDialog {
       
    46 
       
    47 	private Shell shell;
       
    48 	private GridData gridData;
       
    49 	private DecimalFormat voltageFormat     = new DecimalFormat(Messages.getString("PowerStatisticsDialog.voltageFormat")); //$NON-NLS-1$
       
    50 	private DecimalFormat powerFormat       = new DecimalFormat(Messages.getString("PowerStatisticsDialog.powerFormat")); //$NON-NLS-1$
       
    51 
       
    52 	private PwrTrace trace;
       
    53 	private double startTime;
       
    54 	private double endTime;
       
    55 	
       
    56 	private double levelMaxPower;
       
    57 	private double level90Power;
       
    58 	private double level75Power;
       
    59 	private double level50Power;
       
    60 	private double level25Power;
       
    61 	private double level10Power;
       
    62 	private double levelMinPower;
       
    63 	private double levelVarPower;
       
    64 
       
    65 	public PowerStatisticsDialog(Display display)
       
    66 	{
       
    67 		int batterySize;
       
    68 		float voltage;
       
    69 		Group group;
       
    70 		
       
    71 		shell = new Shell(display, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
       
    72 		shell.setText(Messages.getString("PowerStatisticsDialog.statsTitle")); //$NON-NLS-1$
       
    73 		shell.setLayout(new GridLayout(4, false));
       
    74 
       
    75     	startTime = PIPageEditor.currentPageEditor().getStartTime();
       
    76     	endTime   = PIPageEditor.currentPageEditor().getEndTime();
       
    77 
       
    78 		trace = (PwrTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.power"); //$NON-NLS-1$
       
    79 	
       
    80 		int uid = NpiInstanceRepository.getInstance().activeUid();
       
    81 
       
    82 		PowerTraceGraph graph = trace.getPowerGraph(0, uid); // since they are in lockstep, any graph will do
       
    83 
       
    84 		voltage = trace.getVoltage();
       
    85 		batterySize = (int) trace.getBatterySize();
       
    86 
       
    87 		calculateStats();
       
    88 		
       
    89 		group = new Group(shell, SWT.SHADOW_NONE);
       
    90 		group.setText(Messages.getString("PowerStatisticsDialog.interval")); //$NON-NLS-1$
       
    91 		group.setFont(PIPageEditor.helvetica_9);
       
    92 		gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
       
    93 		gridData.horizontalSpan = 4;
       
    94 		group.setLayoutData(gridData);
       
    95 		group.setLayout(new GridLayout(4, false));//new FillLayout());
       
    96 		textGrid(group, showTimeInterval(startTime, endTime), SWT.CENTER, SWT.CENTER, 4);
       
    97 
       
    98 		group = new Group(shell, SWT.NONE);
       
    99 		group.setText(Messages.getString("PowerStatisticsDialog.battery")); //$NON-NLS-1$
       
   100 		group.setFont(PIPageEditor.helvetica_9);
       
   101 		gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
       
   102 		gridData.horizontalSpan = 4;
       
   103 		group.setLayoutData(gridData);
       
   104 		group.setLayout(new GridLayout(4, false));//new FillLayout());
       
   105 		textGrid(group, batterySize + Messages.getString("PowerStatisticsDialog.capacityVoltage2"), SWT.LEFT, SWT.CENTER, 2); //$NON-NLS-1$ //$NON-NLS-2$
       
   106 		textGrid(group, Messages.getString("PowerStatisticsDialog.capacityVoltage3") + voltageFormat.format(voltage) + Messages.getString("PowerStatisticsDialog.capacityVoltage4"), SWT.RIGHT, SWT.CENTER, 2); //$NON-NLS-1$ //$NON-NLS-2$
       
   107 		
       
   108 		group = new Group(shell, SWT.NONE);
       
   109 		group.setText(Messages.getString("PowerStatisticsDialog.currentSelection")); //$NON-NLS-1$
       
   110 		group.setFont(PIPageEditor.helvetica_9);
       
   111 		gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
       
   112 		gridData.horizontalSpan = 4;
       
   113 		group.setLayoutData(gridData);
       
   114 		group.setLayout(new GridLayout(4, false));//new FillLayout());
       
   115 
       
   116 		double meanPower;
       
   117 		double meanEnergy;
       
   118 		long   meanLife;
       
   119 
       
   120 		meanPower  = graph.getAverageConsumption();
       
   121 		meanEnergy = graph.getCumulativeConsumption();
       
   122 		
       
   123 		if (meanPower == 0)
       
   124 			meanLife = 0;
       
   125 		else
       
   126 			meanLife = Math.round((float) graph.getBatterySize() * 3600 * graph.getVoltage() / meanPower);
       
   127 
       
   128 		textGrid(group, Messages.getString("PowerStatisticsDialog.energy1"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   129 		textGrid(group, (int) (meanEnergy + 0.5)
       
   130 						+ Messages.getString("PowerStatisticsDialog.energy2"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   131 
       
   132 		long hours   = meanLife / 3600;
       
   133 		long minutes = (meanLife - hours * 3600) / 60;
       
   134 		textGrid(group, Messages.getString("PowerStatisticsDialog.life1"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   135 		textGrid(group, hours + Messages.getString("PowerStatisticsDialog.life2") //$NON-NLS-1$
       
   136 						+ minutes + Messages.getString("PowerStatisticsDialog.life3"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   137 
       
   138 		textGrid(group, "", SWT.RIGHT, SWT.RIGHT, 4); //$NON-NLS-1$
       
   139 
       
   140 		textGrid(group, Messages.getString("PowerStatisticsDialog.avgPower1"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   141 		textGrid(group, powerFormat.format(meanPower) + Messages.getString("PowerStatisticsDialog.avgPower2"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   142 
       
   143 		textGrid(group, Messages.getString("PowerStatisticsDialog.maxa"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   144 		textGrid(group, powerFormat.format(levelMaxPower / 1000) + Messages.getString("PowerStatisticsDialog.maxb"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   145 
       
   146 		textGrid(group, Messages.getString("PowerStatisticsDialog.90a"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   147 		textGrid(group, powerFormat.format(level90Power / 1000) + Messages.getString("PowerStatisticsDialog.90b"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   148 
       
   149 		textGrid(group, Messages.getString("PowerStatisticsDialog.75a"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   150 		textGrid(group, powerFormat.format(level75Power / 1000) + Messages.getString("PowerStatisticsDialog.75b"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   151 
       
   152 		textGrid(group, Messages.getString("PowerStatisticsDialog.50a"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   153 		textGrid(group, powerFormat.format(level50Power / 1000) + Messages.getString("PowerStatisticsDialog.50b"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   154 
       
   155 		textGrid(group, Messages.getString("PowerStatisticsDialog.25a"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   156 		textGrid(group, powerFormat.format(level25Power / 1000) + Messages.getString("PowerStatisticsDialog.25b"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   157 
       
   158 		textGrid(group, Messages.getString("PowerStatisticsDialog.10a"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   159 		textGrid(group, powerFormat.format(level10Power / 1000) + Messages.getString("PowerStatisticsDialog.10b"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   160 
       
   161 		textGrid(group, Messages.getString("PowerStatisticsDialog.mina"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   162 		textGrid(group, powerFormat.format(levelMinPower / 1000) + Messages.getString("PowerStatisticsDialog.minb"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   163 
       
   164 		textGrid(group, Messages.getString("PowerStatisticsDialog.variancea"), SWT.RIGHT, SWT.RIGHT, 2); //$NON-NLS-1$
       
   165 		textGrid(group, powerFormat.format(levelVarPower / 1000) + Messages.getString("PowerStatisticsDialog.varianceb"), SWT.CENTER, SWT.CENTER, 2); //$NON-NLS-1$
       
   166 
       
   167 		// create the Close button
       
   168 		Button close = new Button(shell, SWT.NONE);
       
   169 		close.setText(Messages.getString("PowerStatisticsDialog.close")); //$NON-NLS-1$
       
   170 		gridData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
       
   171 		gridData.minimumWidth = 60;
       
   172 		gridData.horizontalSpan = 4;
       
   173 		close.setLayoutData(gridData);
       
   174 		close.addSelectionListener(new SelectionListener(){
       
   175 
       
   176 			public void widgetSelected(SelectionEvent e) {
       
   177 				shell.close();
       
   178 			}
       
   179 
       
   180 			public void widgetDefaultSelected(SelectionEvent e) {
       
   181 				widgetSelected(e);
       
   182 			}
       
   183 		});
       
   184 
       
   185 		shell.pack();
       
   186 		shell.open();
       
   187 
       
   188 		while (!shell.isDisposed()) {
       
   189 			if (!shell.getDisplay().readAndDispatch()) {
       
   190 				shell.getDisplay().sleep();
       
   191 			}
       
   192 		}
       
   193 	}
       
   194 	
       
   195 	private void textGrid(Composite parent, String text, int labelStyle, int gridStyle, int gridSpan)
       
   196 	{
       
   197 		Label label = new Label(parent, labelStyle);
       
   198 		label.setFont(PIPageEditor.helvetica_9);
       
   199 		label.setText(text);
       
   200 		gridData = new GridData(SWT.FILL, gridStyle, true, true);
       
   201 		gridData.horizontalSpan = gridSpan;
       
   202 		label.setLayoutData(gridData);		
       
   203 	}
       
   204 
       
   205 	public void dispose()
       
   206 	{
       
   207 		if (this.shell != null) {
       
   208 			if (!this.shell.isDisposed()) {
       
   209 				this.shell.close();				
       
   210 			}
       
   211 			this.shell.dispose();
       
   212 		}
       
   213 
       
   214 		this.shell = null;
       
   215 	}
       
   216 
       
   217 	private static String showTimeInterval(double startTime, double endTime)
       
   218 	{
       
   219 		return ProfileVisualiser.timeFormat.format(startTime)
       
   220 		     + Messages.getString("PowerStatisticsDialog.interval1") + ProfileVisualiser.timeFormat.format(endTime) //$NON-NLS-1$
       
   221 		     + Messages.getString("PowerStatisticsDialog.interval2")  + ProfileVisualiser.timeFormat.format(endTime - startTime) //$NON-NLS-1$
       
   222 		     + Messages.getString("PowerStatisticsDialog.interval3"); //$NON-NLS-1$
       
   223 	}
       
   224 
       
   225 	private class PowerStat {
       
   226 		public double power;
       
   227 		public int count;
       
   228 		
       
   229 		PowerStat(double power) {
       
   230 			this.power = power;
       
   231 			this.count = 0;
       
   232 		}
       
   233 		
       
   234 		PowerStat(double power, int count) {
       
   235 			this.power = power;
       
   236 			this.count = count;
       
   237 		}
       
   238 	}
       
   239 	
       
   240 	private void calculateStats()
       
   241 	{
       
   242 		PowerStat powerStat;
       
   243 		Object[] powerLevelArray;
       
   244 		ArrayList<PowerStat> powerLevel = new ArrayList<PowerStat>();
       
   245 		Hashtable<Double,PowerStat> powerStatHash = new Hashtable<Double,PowerStat>();
       
   246 		double sumOfSquares = 0.0;
       
   247 		double sum = 0.0;
       
   248 		int count = 0;
       
   249 
       
   250 		int selStart = (int)(this.startTime * 1000 + 0.0005) + 1;
       
   251 		int selEnd   = (int)(this.endTime * 1000 + 0.0005);
       
   252 		int totalCount = selEnd - selStart + 1;
       
   253 
       
   254 		levelVarPower = 0.0;
       
   255 
       
   256 		if (selEnd < trace.getFirstSampleNumber() || selStart > selEnd)
       
   257 		{
       
   258 			powerLevelArray = new PowerStat[1];
       
   259 			powerLevelArray[0] = new PowerStat(0.0, 1);
       
   260 			totalCount = 1;
       
   261 		}
       
   262 		else
       
   263 		{
       
   264 			PowerTraceGraph graph = trace.getPowerGraph(0, NpiInstanceRepository.getInstance().activeUid()); // since graphs are in lockstep, any will do
       
   265 
       
   266 			int index = graph.timeIndex(selStart);
       
   267 
       
   268 	        // count time before the first sample as a bunch of zeros
       
   269 	        if (selStart < trace.getFirstSampleNumber()) {
       
   270 	        	count = trace.getFirstSampleNumber() - selStart;
       
   271 				powerStat = new PowerStat(0, count);
       
   272 				powerLevel.add(powerStat);
       
   273 				powerStatHash.put(0.0, powerStat);
       
   274 	        	index = 0;
       
   275 	        }
       
   276 	        
       
   277 	        int[] sampleTimes = trace.getSampleTimes();
       
   278 	        int[] ampValues   = trace.getAmpValues();
       
   279 	        
       
   280 			for (int j = index; j < sampleTimes.length; j++)
       
   281 			{	
       
   282 				int time = sampleTimes[j] + 1;
       
   283 				if (time < selStart)
       
   284 					time = selStart;
       
   285 				
       
   286 				int nextTime = j == sampleTimes.length - 1 ? Integer.MAX_VALUE : sampleTimes[j + 1];
       
   287 				
       
   288 				count = Math.min(nextTime - time + 1, selEnd - time + 1);
       
   289 				double power = ampValues[j] * this.trace.getVoltage() * 1000.0;
       
   290 				sumOfSquares += power * power * count;
       
   291 				sum += power * count;
       
   292 				time += count;
       
   293 				
       
   294 				powerStat = powerStatHash.get(power);
       
   295 				if (powerStat == null) {
       
   296 					powerStat = new PowerStat(power,count);
       
   297 					powerLevel.add(powerStat);
       
   298 					powerStatHash.put(power, powerStat);
       
   299 				} else {
       
   300 					powerStat.count += count;
       
   301 				}
       
   302 				
       
   303 				if (time > selEnd)
       
   304 					break;
       
   305 			}
       
   306 
       
   307 			powerLevelArray = powerLevel.toArray();
       
   308 			Arrays.sort(powerLevelArray, new Comparator<Object>() {
       
   309 
       
   310 				public int compare(Object o1, Object o2) {
       
   311 					if (!(o1 instanceof PowerStat) || !(o2 instanceof PowerStat))
       
   312 						return 0;
       
   313 
       
   314 					double powerDiff = ((PowerStat)o1).power - ((PowerStat)o2).power;
       
   315 					
       
   316 					return powerDiff == 0.0 ? 0	: (powerDiff < 0.0 ? -1 : 1);
       
   317 				}
       
   318 			});
       
   319 		}
       
   320 		
       
   321 		levelMaxPower = ((PowerStat) powerLevelArray[powerLevelArray.length - 1]).power;
       
   322 
       
   323 		level90Power  = getPowerLevel(powerLevelArray, (totalCount * 90) / 100);
       
   324 		level75Power  = getPowerLevel(powerLevelArray, (totalCount * 75) / 100);
       
   325 		level50Power  = getPowerLevel(powerLevelArray, (totalCount * 50) / 100);
       
   326 		level25Power  = getPowerLevel(powerLevelArray, (totalCount * 25) / 100);
       
   327 		level10Power  = getPowerLevel(powerLevelArray, (totalCount * 10) / 100);
       
   328 
       
   329 		levelMinPower = ((PowerStat) powerLevelArray[0]).power;
       
   330 
       
   331 		levelVarPower = (sumOfSquares - (sum * sum)/totalCount)/totalCount;
       
   332 	}
       
   333 	
       
   334 	// given array powerLevelArray of PowerStat elements (each representing PowerStat.count entries), find
       
   335 	// power value of entry number index
       
   336 	private double getPowerLevel(Object[] powerLevelArray, int index)
       
   337 	{
       
   338 		if (index == 0 || powerLevelArray == null || powerLevelArray.length == 0)
       
   339 			return 0.0;
       
   340 		
       
   341 		for (int i = 0; (i < powerLevelArray.length) && (powerLevelArray[i] instanceof PowerStat); i++) {
       
   342 			PowerStat powerStat = (PowerStat) powerLevelArray[i];
       
   343 			if (index <= powerStat.count)
       
   344 				return powerStat.power;
       
   345 			index -= powerStat.count;
       
   346 		}
       
   347 		
       
   348 		return 0.0;
       
   349 	}
       
   350 }