| Index: tools/telemetry/telemetry/value/list_of_scalar_values.py
|
| diff --git a/tools/telemetry/telemetry/value/list_of_scalar_values.py b/tools/telemetry/telemetry/value/list_of_scalar_values.py
|
| deleted file mode 100644
|
| index bd898c9fd83bcd807066a135b08f4051e85f4251..0000000000000000000000000000000000000000
|
| --- a/tools/telemetry/telemetry/value/list_of_scalar_values.py
|
| +++ /dev/null
|
| @@ -1,223 +0,0 @@
|
| -# Copyright 2013 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -import numbers
|
| -import math
|
| -
|
| -from telemetry import value as value_module
|
| -from telemetry.value import none_values
|
| -from telemetry.value import summarizable
|
| -
|
| -
|
| -def Variance(sample):
|
| - """ Compute the population variance.
|
| -
|
| - Args:
|
| - sample: a list of numbers.
|
| - """
|
| - k = len(sample) - 1 # Bessel correction
|
| - if k <= 0:
|
| - return 0
|
| - m = _Mean(sample)
|
| - return sum((x - m)**2 for x in sample)/k
|
| -
|
| -
|
| -def StandardDeviation(sample):
|
| - """ Compute standard deviation for a list of numbers.
|
| -
|
| - Args:
|
| - sample: a list of numbers.
|
| - """
|
| - return math.sqrt(Variance(sample))
|
| -
|
| -
|
| -def PooledStandardDeviation(list_of_samples, list_of_variances=None):
|
| - """ Compute standard deviation for a list of samples.
|
| -
|
| - See: https://en.wikipedia.org/wiki/Pooled_variance for the formula.
|
| -
|
| - Args:
|
| - list_of_samples: a list of lists, each is a list of numbers.
|
| - list_of_variances: a list of numbers, the i-th element is the variance of
|
| - the i-th sample in list_of_samples. If this is None, we use
|
| - Variance(sample) to get the variance of the i-th sample.
|
| - """
|
| - pooled_variance = 0.0
|
| - total_degrees_of_freedom = 0
|
| - for i in xrange(len(list_of_samples)):
|
| - l = list_of_samples[i]
|
| - k = len(l) - 1 # Bessel correction
|
| - if k <= 0:
|
| - continue
|
| - variance = list_of_variances[i] if list_of_variances else Variance(l)
|
| - pooled_variance += k * variance
|
| - total_degrees_of_freedom += k
|
| - if total_degrees_of_freedom:
|
| - return (pooled_variance/total_degrees_of_freedom) ** 0.5
|
| - return 0
|
| -
|
| -
|
| -def _Mean(values):
|
| - return float(sum(values)) / len(values) if len(values) > 0 else 0.0
|
| -
|
| -
|
| -class ListOfScalarValues(summarizable.SummarizableValue):
|
| - """ ListOfScalarValues represents a list of numbers.
|
| -
|
| - By default, std is the standard deviation of all numbers in the list. Std can
|
| - also be specified in the constructor if the numbers are not from the same
|
| - population.
|
| - """
|
| - def __init__(self, page, name, units, values,
|
| - important=True, description=None,
|
| - tir_label=None, none_value_reason=None,
|
| - std=None, same_page_merge_policy=value_module.CONCATENATE,
|
| - improvement_direction=None):
|
| - super(ListOfScalarValues, self).__init__(page, name, units, important,
|
| - description, tir_label,
|
| - improvement_direction)
|
| - if values is not None:
|
| - assert isinstance(values, list)
|
| - assert len(values) > 0
|
| - assert all(isinstance(v, numbers.Number) for v in values)
|
| - assert std is None or isinstance(std, numbers.Number)
|
| - else:
|
| - assert std is None
|
| - none_values.ValidateNoneValueReason(values, none_value_reason)
|
| - self.values = values
|
| - self.none_value_reason = none_value_reason
|
| - self.same_page_merge_policy = same_page_merge_policy
|
| - if values is not None and std is None:
|
| - std = StandardDeviation(values)
|
| - assert std is None or std >= 0, (
|
| - 'standard deviation cannot be negative: %s' % std)
|
| - self._std = std
|
| -
|
| - @property
|
| - def std(self):
|
| - return self._std
|
| -
|
| - @property
|
| - def variance(self):
|
| - return self._std ** 2
|
| -
|
| - def __repr__(self):
|
| - if self.page:
|
| - page_name = self.page.display_name
|
| - else:
|
| - page_name = 'None'
|
| - if self.same_page_merge_policy == value_module.CONCATENATE:
|
| - merge_policy = 'CONCATENATE'
|
| - else:
|
| - merge_policy = 'PICK_FIRST'
|
| - return ('ListOfScalarValues(%s, %s, %s, %s, '
|
| - 'important=%s, description=%s, tir_label=%s, std=%s, '
|
| - 'same_page_merge_policy=%s, improvement_direction=%s)') % (
|
| - page_name,
|
| - self.name,
|
| - self.units,
|
| - repr(self.values),
|
| - self.important,
|
| - self.description,
|
| - self.tir_label,
|
| - self.std,
|
| - merge_policy,
|
| - self.improvement_direction)
|
| -
|
| - def GetBuildbotDataType(self, output_context):
|
| - if self._IsImportantGivenOutputIntent(output_context):
|
| - return 'default'
|
| - return 'unimportant'
|
| -
|
| - def GetBuildbotValue(self):
|
| - return self.values
|
| -
|
| - def GetRepresentativeNumber(self):
|
| - return _Mean(self.values)
|
| -
|
| - def GetRepresentativeString(self):
|
| - return repr(self.values)
|
| -
|
| - def IsMergableWith(self, that):
|
| - return (super(ListOfScalarValues, self).IsMergableWith(that) and
|
| - self.same_page_merge_policy == that.same_page_merge_policy)
|
| -
|
| - @staticmethod
|
| - def GetJSONTypeName():
|
| - return 'list_of_scalar_values'
|
| -
|
| - def AsDict(self):
|
| - d = super(ListOfScalarValues, self).AsDict()
|
| - d['values'] = self.values
|
| - d['std'] = self.std
|
| -
|
| - if self.none_value_reason is not None:
|
| - d['none_value_reason'] = self.none_value_reason
|
| -
|
| - return d
|
| -
|
| - @staticmethod
|
| - def FromDict(value_dict, page_dict):
|
| - kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
|
| - kwargs['values'] = value_dict['values']
|
| - kwargs['std'] = value_dict['std']
|
| -
|
| - if 'improvement_direction' in value_dict:
|
| - kwargs['improvement_direction'] = value_dict['improvement_direction']
|
| - if 'none_value_reason' in value_dict:
|
| - kwargs['none_value_reason'] = value_dict['none_value_reason']
|
| - if 'tir_label' in value_dict:
|
| - kwargs['tir_label'] = value_dict['tir_label']
|
| -
|
| - return ListOfScalarValues(**kwargs)
|
| -
|
| - @classmethod
|
| - def MergeLikeValuesFromSamePage(cls, values):
|
| - assert len(values) > 0
|
| - v0 = values[0]
|
| -
|
| - if v0.same_page_merge_policy == value_module.PICK_FIRST:
|
| - return ListOfScalarValues(
|
| - v0.page, v0.name, v0.units,
|
| - values[0].values,
|
| - important=v0.important,
|
| - same_page_merge_policy=v0.same_page_merge_policy,
|
| - none_value_reason=v0.none_value_reason,
|
| - improvement_direction=v0.improvement_direction)
|
| -
|
| - assert v0.same_page_merge_policy == value_module.CONCATENATE
|
| - return cls._MergeLikeValues(values, v0.page, v0.name, v0.tir_label)
|
| -
|
| - @classmethod
|
| - def MergeLikeValuesFromDifferentPages(cls, values):
|
| - assert len(values) > 0
|
| - v0 = values[0]
|
| - return cls._MergeLikeValues(values, None, v0.name, v0.tir_label)
|
| -
|
| - @classmethod
|
| - def _MergeLikeValues(cls, values, page, name, tir_label):
|
| - v0 = values[0]
|
| - merged_values = []
|
| - list_of_samples = []
|
| - none_value_reason = None
|
| - pooled_std = None
|
| - for v in values:
|
| - if v.values is None:
|
| - merged_values = None
|
| - none_value_reason = none_values.MERGE_FAILURE_REASON
|
| - break
|
| - merged_values.extend(v.values)
|
| - list_of_samples.append(v.values)
|
| - if merged_values:
|
| - pooled_std = PooledStandardDeviation(
|
| - list_of_samples, list_of_variances=[v.variance for v in values])
|
| - return ListOfScalarValues(
|
| - page, name, v0.units,
|
| - merged_values,
|
| - important=v0.important,
|
| - tir_label=tir_label,
|
| - same_page_merge_policy=v0.same_page_merge_policy,
|
| - std=pooled_std,
|
| - none_value_reason=none_value_reason,
|
| - improvement_direction=v0.improvement_direction)
|
|
|