OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import numbers | 5 import numbers |
6 import math | 6 import math |
7 | 7 |
8 from telemetry import value as value_module | 8 from telemetry import value as value_module |
9 from telemetry.value import none_values | 9 from telemetry.value import none_values |
| 10 from telemetry.value import summarizable |
10 | 11 |
11 | 12 |
12 def Variance(sample): | 13 def Variance(sample): |
13 """ Compute the population variance. | 14 """ Compute the population variance. |
14 | 15 |
15 Args: | 16 Args: |
16 sample: a list of numbers. | 17 sample: a list of numbers. |
17 """ | 18 """ |
18 k = len(sample) - 1 # Bessel correction | 19 k = len(sample) - 1 # Bessel correction |
19 if k <= 0: | 20 if k <= 0: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 total_degrees_of_freedom += k | 55 total_degrees_of_freedom += k |
55 if total_degrees_of_freedom: | 56 if total_degrees_of_freedom: |
56 return (pooled_variance/total_degrees_of_freedom) ** 0.5 | 57 return (pooled_variance/total_degrees_of_freedom) ** 0.5 |
57 return 0 | 58 return 0 |
58 | 59 |
59 | 60 |
60 def _Mean(values): | 61 def _Mean(values): |
61 return float(sum(values)) / len(values) if len(values) > 0 else 0.0 | 62 return float(sum(values)) / len(values) if len(values) > 0 else 0.0 |
62 | 63 |
63 | 64 |
64 class ListOfScalarValues(value_module.Value): | 65 class ListOfScalarValues(summarizable.SummarizableValue): |
65 """ ListOfScalarValues represents a list of numbers. | 66 """ ListOfScalarValues represents a list of numbers. |
66 | 67 |
67 By default, std is the standard deviation of all numbers in the list. Std can | 68 By default, std is the standard deviation of all numbers in the list. Std can |
68 also be specified in the constructor if the numbers are not from the same | 69 also be specified in the constructor if the numbers are not from the same |
69 population. | 70 population. |
70 """ | 71 """ |
71 def __init__(self, page, name, units, values, | 72 def __init__(self, page, name, units, values, |
72 important=True, description=None, | 73 important=True, description=None, |
73 tir_label=None, none_value_reason=None, | 74 tir_label=None, none_value_reason=None, |
74 std=None, same_page_merge_policy=value_module.CONCATENATE): | 75 std=None, same_page_merge_policy=value_module.CONCATENATE, |
| 76 improvement_direction=None): |
75 super(ListOfScalarValues, self).__init__(page, name, units, important, | 77 super(ListOfScalarValues, self).__init__(page, name, units, important, |
76 description, tir_label) | 78 description, tir_label, |
| 79 improvement_direction) |
77 if values is not None: | 80 if values is not None: |
78 assert isinstance(values, list) | 81 assert isinstance(values, list) |
79 assert len(values) > 0 | 82 assert len(values) > 0 |
80 assert all(isinstance(v, numbers.Number) for v in values) | 83 assert all(isinstance(v, numbers.Number) for v in values) |
81 assert std is None or isinstance(std, numbers.Number) | 84 assert std is None or isinstance(std, numbers.Number) |
82 else: | 85 else: |
83 assert std is None | 86 assert std is None |
84 none_values.ValidateNoneValueReason(values, none_value_reason) | 87 none_values.ValidateNoneValueReason(values, none_value_reason) |
85 self.values = values | 88 self.values = values |
86 self.none_value_reason = none_value_reason | 89 self.none_value_reason = none_value_reason |
(...skipping 16 matching lines...) Expand all Loading... |
103 if self.page: | 106 if self.page: |
104 page_name = self.page.display_name | 107 page_name = self.page.display_name |
105 else: | 108 else: |
106 page_name = 'None' | 109 page_name = 'None' |
107 if self.same_page_merge_policy == value_module.CONCATENATE: | 110 if self.same_page_merge_policy == value_module.CONCATENATE: |
108 merge_policy = 'CONCATENATE' | 111 merge_policy = 'CONCATENATE' |
109 else: | 112 else: |
110 merge_policy = 'PICK_FIRST' | 113 merge_policy = 'PICK_FIRST' |
111 return ('ListOfScalarValues(%s, %s, %s, %s, ' | 114 return ('ListOfScalarValues(%s, %s, %s, %s, ' |
112 'important=%s, description=%s, tir_label=%s, ' | 115 'important=%s, description=%s, tir_label=%s, ' |
113 'same_page_merge_policy=%s)') % ( | 116 'same_page_merge_policy=%s, improvement_direction=%s)') % ( |
114 page_name, | 117 page_name, |
115 self.name, | 118 self.name, |
116 self.units, | 119 self.units, |
117 repr(self.values), | 120 repr(self.values), |
118 self.important, | 121 self.important, |
119 self.description, | 122 self.description, |
120 self.tir_label, | 123 self.tir_label, |
121 merge_policy) | 124 merge_policy, |
| 125 self.improvement_direction) |
122 | 126 |
123 def GetBuildbotDataType(self, output_context): | 127 def GetBuildbotDataType(self, output_context): |
124 if self._IsImportantGivenOutputIntent(output_context): | 128 if self._IsImportantGivenOutputIntent(output_context): |
125 return 'default' | 129 return 'default' |
126 return 'unimportant' | 130 return 'unimportant' |
127 | 131 |
128 def GetBuildbotValue(self): | 132 def GetBuildbotValue(self): |
129 return self.values | 133 return self.values |
130 | 134 |
131 def GetRepresentativeNumber(self): | 135 def GetRepresentativeNumber(self): |
(...skipping 18 matching lines...) Expand all Loading... |
150 if self.none_value_reason is not None: | 154 if self.none_value_reason is not None: |
151 d['none_value_reason'] = self.none_value_reason | 155 d['none_value_reason'] = self.none_value_reason |
152 | 156 |
153 return d | 157 return d |
154 | 158 |
155 @staticmethod | 159 @staticmethod |
156 def FromDict(value_dict, page_dict): | 160 def FromDict(value_dict, page_dict): |
157 kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict) | 161 kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict) |
158 kwargs['values'] = value_dict['values'] | 162 kwargs['values'] = value_dict['values'] |
159 kwargs['std'] = value_dict['std'] | 163 kwargs['std'] = value_dict['std'] |
| 164 kwargs['improvement_direction'] = value_dict['improvement_direction'] |
160 | 165 |
161 if 'none_value_reason' in value_dict: | 166 if 'none_value_reason' in value_dict: |
162 kwargs['none_value_reason'] = value_dict['none_value_reason'] | 167 kwargs['none_value_reason'] = value_dict['none_value_reason'] |
163 if 'tir_label' in value_dict: | 168 if 'tir_label' in value_dict: |
164 kwargs['tir_label'] = value_dict['tir_label'] | 169 kwargs['tir_label'] = value_dict['tir_label'] |
165 | 170 |
166 return ListOfScalarValues(**kwargs) | 171 return ListOfScalarValues(**kwargs) |
167 | 172 |
168 @classmethod | 173 @classmethod |
169 def MergeLikeValuesFromSamePage(cls, values): | 174 def MergeLikeValuesFromSamePage(cls, values): |
170 assert len(values) > 0 | 175 assert len(values) > 0 |
171 v0 = values[0] | 176 v0 = values[0] |
172 | 177 |
173 if v0.same_page_merge_policy == value_module.PICK_FIRST: | 178 if v0.same_page_merge_policy == value_module.PICK_FIRST: |
174 return ListOfScalarValues( | 179 return ListOfScalarValues( |
175 v0.page, v0.name, v0.units, | 180 v0.page, v0.name, v0.units, |
176 values[0].values, | 181 values[0].values, |
177 important=v0.important, | 182 important=v0.important, |
178 same_page_merge_policy=v0.same_page_merge_policy, | 183 same_page_merge_policy=v0.same_page_merge_policy, |
179 none_value_reason=v0.none_value_reason) | 184 none_value_reason=v0.none_value_reason, |
| 185 improvement_direction=v0.improvement_direction) |
180 | 186 |
181 assert v0.same_page_merge_policy == value_module.CONCATENATE | 187 assert v0.same_page_merge_policy == value_module.CONCATENATE |
182 return cls._MergeLikeValues(values, v0.page, v0.name, v0.tir_label) | 188 return cls._MergeLikeValues(values, v0.page, v0.name, v0.tir_label) |
183 | 189 |
184 @classmethod | 190 @classmethod |
185 def MergeLikeValuesFromDifferentPages(cls, values): | 191 def MergeLikeValuesFromDifferentPages(cls, values): |
186 assert len(values) > 0 | 192 assert len(values) > 0 |
187 v0 = values[0] | 193 v0 = values[0] |
188 return cls._MergeLikeValues(values, None, v0.name, v0.tir_label) | 194 return cls._MergeLikeValues(values, None, v0.name, v0.tir_label) |
189 | 195 |
(...skipping 14 matching lines...) Expand all Loading... |
204 if merged_values: | 210 if merged_values: |
205 pooled_std = PooledStandardDeviation( | 211 pooled_std = PooledStandardDeviation( |
206 list_of_samples, list_of_variances=[v.variance for v in values]) | 212 list_of_samples, list_of_variances=[v.variance for v in values]) |
207 return ListOfScalarValues( | 213 return ListOfScalarValues( |
208 page, name, v0.units, | 214 page, name, v0.units, |
209 merged_values, | 215 merged_values, |
210 important=v0.important, | 216 important=v0.important, |
211 tir_label=tir_label, | 217 tir_label=tir_label, |
212 same_page_merge_policy=v0.same_page_merge_policy, | 218 same_page_merge_policy=v0.same_page_merge_policy, |
213 std=pooled_std, | 219 std=pooled_std, |
214 none_value_reason=none_value_reason) | 220 none_value_reason=none_value_reason, |
| 221 improvement_direction=v0.improvement_direction) |
OLD | NEW |