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