| Index: common/monsoon/monsoon/monsoon_utils.py
|
| diff --git a/common/monsoon/monsoon/monsoon_utils.py b/common/monsoon/monsoon/monsoon_utils.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..905792f2a12afb1f19695bb6a648b2add7d2a93f
|
| --- /dev/null
|
| +++ b/common/monsoon/monsoon/monsoon_utils.py
|
| @@ -0,0 +1,62 @@
|
| +# Copyright 2017 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 collections
|
| +import re
|
| +
|
| +# Named tuple for all monsoon samples.
|
| +MonsoonSample = collections.namedtuple('MonsoonSample', 'Timestamp Amps')
|
| +
|
| +# Regular expression to extract timestamp and amperage from Monsoon's log.
|
| +SampleRegex = re.compile(r"(\d+)\s+(?<![a-zA-Z:])([-+]?\d*\.?\d+)")
|
| +
|
| +def ReadSamplesFromFile(file):
|
| + """ Reads raw samples from a file in the form 'Timestamp Amps', returning
|
| + a list of MonsoonSample tuples.
|
| + """
|
| + samples = []
|
| + for line in file:
|
| + value_match = SampleRegex.match(line)
|
| + # Sometimes there can be transient USB communication errors. They can be
|
| + # safely ignored.
|
| + if value_match is not None:
|
| + # Some versions of monsoon.py supply timestamp in integer. Some later
|
| + # versions could in theory supply timestamp as a float. Collapse all
|
| + # and treat timestamps as if they were integer seconds.
|
| + timestamp_second = int(value_match.group(1))
|
| + amps = float(value_match.group(2))
|
| + samples.append(MonsoonSample(Timestamp = timestamp_second, Amps = amps))
|
| + return samples
|
| +
|
| +def TransformSamplesWithFrequency(samples, frequency):
|
| + """ Transforms a list of MonsoonSample (with integer second accuracy) into a
|
| + list of MonsoonSample with fractional accuracy, assuming a fixed frequency.
|
| + """
|
| + result = []
|
| + second_samples = []
|
| + second = -1
|
| + last_index = len(samples) - 1
|
| + for i,source_sample in enumerate(samples):
|
| + if second == -1:
|
| + second = source_sample.Timestamp
|
| + if (source_sample.Timestamp != second) or (i == last_index):
|
| + # Now and then the data may have more samples than the given frequency
|
| + # (a desktop OS isn't an RTOS after all). Lets allow it and average out
|
| + # the samples.
|
| + if len(second_samples) > frequency:
|
| + second_frequency = len(second_samples)
|
| + else:
|
| + second_frequency = frequency
|
| + period = 1.0 / second_frequency
|
| + # Samples are represented as halfway through the period.
|
| + time_offset = -(period / 2.0)
|
| + if len(result) == 0:
|
| + time_offset += (second_frequency - len(second_samples) - 1) * period
|
| + for second_sample in second_samples:
|
| + result.append(MonsoonSample(Timestamp = second + time_offset, Amps =
|
| + second_sample.Amps))
|
| + time_offset += period
|
| + del second_samples[:]
|
| + second = source_sample.Timestamp
|
| + second_samples.append(source_sample)
|
| + return result
|
|
|