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 19import os 20import argparse 21import pandas as pd 22import numpy as np 23 24from 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 31class 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 80parser = 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 85parser.add_argument("--path", "-p", type=str, required=True, 86 help="Path to file to read samples from.") 87 88parser.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 92parser.add_argument("--sample_rate_hz", "-r", type=int, default=None, 93 help="The sample rate in hz of the given file.") 94 95parser.add_argument("--start", "-s", type=float, default=None, 96 help="The start of the interval.") 97 98parser.add_argument("--end", "-e", type=float, default=None, 99 help="The end of the interval.") 100 101parser.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 105if __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