1 #!/usr/bin/env python 2 # SPDX-License-Identifier: Apache-2.0 3 # 4 # Copyright (C) 2017, ARM Limited, Google, and contributors. 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 # not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 # 18 19 import os 20 import argparse 21 import pandas as pd 22 import numpy as np 23 24 from bart.common.Utils import area_under_curve 25 26 # Get averages from a sample csv file for a certain time interval. 27 # This can be used to find the power averages during a time interval of 28 # interest. For example, when trying to compute the power average during 29 # suspend, the first portion of the samples collected should be ignored. 30 31 class PowerAverage: 32 @staticmethod 33 def get(path, column=None, sample_rate_hz=None, start=None, end=None, 34 remove_outliers=False): 35 36 # Read csv into dataframe 37 with open(path) as f: 38 df = pd.read_csv(f) 39 40 if start or end: 41 # The rate is needed to calculate the time interval 42 if not sample_rate_hz: 43 raise RuntimeError('start and/or end cannot be requested without' 44 ' the sample_rate_hz') 45 46 # Change dataframe index from sample index to sample time 47 sample_period = 1. / sample_rate_hz 48 df.index = np.linspace(0, sample_period * len(df), num=len(df)) 49 50 # Drop all samples after the end index 51 if end: 52 end_idx = np.abs(df.index - end).argmin() 53 df.drop(df.index[end_idx:], inplace=True) 54 55 # Drop all samples before the start index 56 if start: 57 start_idx = np.abs(df.index - start).argmin() 58 df.drop(df.index[:start_idx], inplace=True) 59 60 if remove_outliers: 61 if not column: 62 raise RuntimeError('remove_outliers cannot be requested without' 63 ' a column') 64 # Remove the bottom 10% and upper 10% of the data 65 percentile = np.percentile(df[column], [10, 90]) 66 df = df[(df[column] > percentile[0]) & (df[column] < percentile[1])] 67 68 # If no samples remain, throw error 69 if df.empty: 70 raise RuntimeError('No energy data collected') 71 72 # If a column is specified, only return that column's average 73 if column: 74 return df[column].mean() 75 76 # Else return the average of each column in the dataframe 77 return [ df[column].mean() for column in df ] 78 79 80 parser = argparse.ArgumentParser( 81 description="Get the averages from a sample.csv. Optionally specify a" 82 " time interval over which to calculate the sample. If" 83 " start or end is set, sample_rate_hz must also be set") 84 85 parser.add_argument("--path", "-p", type=str, required=True, 86 help="Path to file to read samples from.") 87 88 parser.add_argument("--column", "-c", type=str, default=None, 89 help="The name of a sample.csv column. When supplied," 90 " only this column will be averaged.") 91 92 parser.add_argument("--sample_rate_hz", "-r", type=int, default=None, 93 help="The sample rate in hz of the given file.") 94 95 parser.add_argument("--start", "-s", type=float, default=None, 96 help="The start of the interval.") 97 98 parser.add_argument("--end", "-e", type=float, default=None, 99 help="The end of the interval.") 100 101 parser.add_argument("--remove_outliers", "-o", type=bool, default=False, 102 help="Remove the outliers from a column." 103 " The column argument must also be specified. (default False)") 104 105 if __name__ == "__main__": 106 args = parser.parse_args() 107 108 print PowerAverage.get(args.path, args.column, args.sample_rate_hz, 109 args.start, args.end, args.remove_outliers) 110