1e81fdcb135d0325e3bc22fae0583555d20aae280Brendan Jackman# Copyright 2015-2017 ARM Limited 2c47d2dfb1de15e2a86e2d47ef822ae993375efdeJavi Merino# 3aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# Licensed under the Apache License, Version 2.0 (the "License"); 4aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# you may not use this file except in compliance with the License. 5aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# You may obtain a copy of the License at 6aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# 7aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# http://www.apache.org/licenses/LICENSE-2.0 8aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# 9aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# Unless required by applicable law or agreed to in writing, software 10aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# distributed under the License is distributed on an "AS IS" BASIS, 11aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# See the License for the specific language governing permissions and 13aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# limitations under the License. 14aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino# 15aace7c0732cac769f1ffe95a89591b6217fa9447Javi Merino 167319a880ca4883b064876f82654ce01aef9e60f8KP Singh"""This is the template class that all Plotters inherit""" 17341d912a093aaf9aaf831ed30a001ce9fea148e8Kapileshwar Singhfrom abc import abstractmethod, ABCMeta 187c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singhfrom pandas import DataFrame 19e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merinoimport re 20b95a4c5504771224bfe6a4abec759c00d2612a73Javi Merinofrom trappy.utils import listify 217c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singhfrom functools import reduce 227319a880ca4883b064876f82654ce01aef9e60f8KP Singh# pylint: disable=R0921 237319a880ca4883b064876f82654ce01aef9e60f8KP Singh# pylint: disable=R0903 247319a880ca4883b064876f82654ce01aef9e60f8KP Singh 257319a880ca4883b064876f82654ce01aef9e60f8KP Singh 267319a880ca4883b064876f82654ce01aef9e60f8KP Singhclass AbstractDataPlotter(object): 2721f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh """This is an abstract data plotting Class defining an interface 2821f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh for the various Plotting Classes""" 297319a880ca4883b064876f82654ce01aef9e60f8KP Singh 30341d912a093aaf9aaf831ed30a001ce9fea148e8Kapileshwar Singh __metaclass__ = ABCMeta 31341d912a093aaf9aaf831ed30a001ce9fea148e8Kapileshwar Singh 32c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino def __init__(self, traces=None, attr=None, templates=None): 33bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh self._event_map = {} 34bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh self._attr = attr if attr else {} 35c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino self.traces = traces 3696602fc3cafea4e89a7b938e6d1363add1b9613fJohn Pocock self.templates = templates 37bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 387319a880ca4883b064876f82654ce01aef9e60f8KP Singh @abstractmethod 397319a880ca4883b064876f82654ce01aef9e60f8KP Singh def view(self): 407319a880ca4883b064876f82654ce01aef9e60f8KP Singh """View the graph""" 417319a880ca4883b064876f82654ce01aef9e60f8KP Singh raise NotImplementedError("Method Not Implemented") 425ebf1a3337a9e004d771a3fab8d72f4e3bfa2e9fKapileshwar Singh 435ebf1a3337a9e004d771a3fab8d72f4e3bfa2e9fKapileshwar Singh @abstractmethod 445ebf1a3337a9e004d771a3fab8d72f4e3bfa2e9fKapileshwar Singh def savefig(self, path): 4521f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh """Save the image as a file 4621f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh 4721f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh :param path: Location of the Saved File 4821f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh :type path: str 4921f9570fe513c87cf8de94449ca0e52d83ab3351Kapileshwar Singh """ 505ebf1a3337a9e004d771a3fab8d72f4e3bfa2e9fKapileshwar Singh raise NotImplementedError("Method Not Implemented") 51341d912a093aaf9aaf831ed30a001ce9fea148e8Kapileshwar Singh 527c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh def _check_data(self): 537c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh """Internal function to check the received data""" 547c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh 55c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino data = listify(self.traces) 567c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh 577c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh if len(data): 587c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh mask = map(lambda x: isinstance(x, DataFrame), data) 597c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh data_frame = reduce(lambda x, y: x and y, mask) 60bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh sig_or_template = self.templates or "signals" in self._attr 61bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 62bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh if not data_frame and not sig_or_template: 637c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh raise ValueError( 644f4b18adce159f73b112ab789d695918ba45ef2fJavi Merino "Cannot understand data. Accepted DataFormats are pandas.DataFrame or trappy.FTrace/BareTrace/SysTrace (with templates)") 6544745135f3c7410d144115d3b50c9591d17baab1Javi Merino elif data_frame and "column" not in self._attr: 66bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh raise ValueError("Column not specified for DataFrame input") 677c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh else: 687c1d99ea5405b5be263847a59c05495791894ce6Kapileshwar Singh raise ValueError("Empty Data received") 69bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 7025ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino def _parse_value(self, signal_def): 7125ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino """Parse a signal definition into a (template, column) tuple 7225ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino 7325ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino :param signal_def: A signal definition. E.g. "trace_class:column" 7425ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino :type signal_def: str 7525ffb28cd8c46e2f3c44e89b719cc79dcc33cb06Javi Merino """ 76bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 77e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino match = re.match(r"(?P<event>[^:]+):(?P<column>[^:]+)(?P<color>:.+)?", 78e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino signal_def) 7915c5a1f0d3927984b6c5d150127f83747fb135c8Brendan Jackman if not match: 8015c5a1f0d3927984b6c5d150127f83747fb135c8Brendan Jackman raise ValueError( 8115c5a1f0d3927984b6c5d150127f83747fb135c8Brendan Jackman 'Invalid signal definition "{}". ' 8215c5a1f0d3927984b6c5d150127f83747fb135c8Brendan Jackman 'Should have the form "trace_class:column" ' 8315c5a1f0d3927984b6c5d150127f83747fb135c8Brendan Jackman 'e.g. "cpu_frequency:frequency"'.format(signal_def)) 84e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino event = match.group("event") 85e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino column = match.group("column") 86e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino color_match = match.group("color") 87e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino if color_match: 88e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino color_list = color_match[1:].split(",", 2) 89e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino color = [int(n, 16) if n.startswith("0x") else int(n) for n in color_list] 90e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino else: 91e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino color = None 92bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 93bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh try: 94e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino return self._event_map[event], column, color 95bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh except KeyError: 96c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino for trace in listify(self.traces): 97bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 98c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino if event in trace.class_definitions: 99c26a323210533d4ed3a8b4e62c33744236e3bedaJavi Merino self._event_map[event] = trace.class_definitions[event] 100e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino return self._event_map[event], column, color 101bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 102bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh raise ValueError( 103bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh "Event: " + 104bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh event + 1054f4b18adce159f73b112ab789d695918ba45ef2fJavi Merino " not found in Trace Object") 106bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 107bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh def _describe_signals(self): 108bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh """Internal Function for populating templates and columns 109bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh from signals 110bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh """ 111bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 112bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh if "column" in self._attr or self.templates: 113bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh raise ValueError("column/templates specified with values") 114bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh 115bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh self._attr["column"] = [] 116842150378505f3c227ccdc5233759e7eebb535efJavi Merino self.templates = [] 117e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino colors = [] 11896602fc3cafea4e89a7b938e6d1363add1b9613fJohn Pocock 119bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh for value in listify(self._attr["signals"]): 120e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino template, column, color = self._parse_value(value) 121bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh self.templates.append(template) 122bb752f8828c8d170f6ab32c1b88a3792bb31f0aeKapileshwar Singh self._attr["column"].append(column) 123e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino colors.append(color) 124e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino 125e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino if any(colors): 126e5c3597852f0bd31494b60b463d3b88e922d59cfJavi Merino self._attr["colors"] = colors 127