aboutsummaryrefslogtreecommitdiff
path: root/trappy/stats/Trigger.py
blob: 4fd35053fa1b8c9c40081a7a86d93a4217332886 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#    Copyright 2015-2016 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Trigger is a representation of the following:

    - Event(s) (:mod:`trappy.base.Base`)
    - An associated value
        - scalar
        - vector
    - A set of filters
        - value based
        - function based
"""

import types
from trappy.utils import listify
import pandas as pd


class Trigger(object):
    """Trigger is an event-value relationship which
    accepts a trace object to "generate" qualified data

    :param trace: A trappy FTrace object
    :type trace: :mod:`trappy.trace.FTrace`

    :param template: A trappy Event to act as a trigger
    :type template: trappy.Base

    :param filters: Key value filter pairs
    :type filters: dict

    The filter can either have a function:
    ::

        def function_based_filter(elem):
            if condition:
                return True
            else:
                return False

    or a value/list of values
    ::

        f = {}
        f["data_column_a"] = function_based_filter
        f["data_column_b"] = value

    function_based_filter is anything that behaves like a function,
    i.e. a callable.

    :param value: Value can be a string or a numeric
    :type value: str, int, float

    :param pivot: This is the column around which the data will be
        pivoted
    :type pivot: str
    """

    def __init__(self, trace, template, filters, value, pivot):

        self.template = template
        self._filters = filters
        self._value = value
        self._pivot = pivot
        self.trace = trace

    def generate(self, pivot_val):
        """Generate the trigger data for a given pivot value
        and a trace index

        :param pivot_val: The pivot to generate data for
        :type pivot_val: hashable
        """

        trappy_event = getattr(self.trace, self.template.name)
        data_frame = trappy_event.data_frame
        data_frame = data_frame[data_frame[self._pivot] == pivot_val]

        mask = [True for _ in range(len(data_frame))]

        for key, value in self._filters.iteritems():
            if hasattr(value, "__call__"):
                mask = mask & (data_frame[key].apply(value))
            else:
                mask = apply_filter_kv(key, value, data_frame, mask)

        data_frame = data_frame[mask]

        if isinstance(self._value, str):
            return data_frame[value]
        else:
            return pd.Series(self._value, index=data_frame.index)


def apply_filter_kv(key, value, data_frame, mask):
    """Internal function to apply a key value
    filter to a data_frame and update the initial
    condition provided in mask.

    :param value: The value to checked for

    :param data_frame: The data to be filtered
    :type data_frame: :mod:`pandas.DataFrame`

    :param mask: Initial Condition Mask
    :type mask: :mod:`pandas.Series`

    :return: A **mask** to index the data frame
    """

    value = listify(value)
    if key not in data_frame.columns:
        return mask
    else:
        for val in value:
            mask = mask & (data_frame[key] == val)
        return mask