Exemple #1
0
def stdev(seriesList, time):
    count = 0
    for series in seriesList:
        stddevs = TimeSeries("stddev(%s,%.1f)" % (series.name, float(time)),
                             series.start, series.end, series.step, [])
        stddevs.pathExpression = "stddev(%s,%.1f)" % (series.name, float(time))
        avg = safeDiv(safeSum(series[:time]), time)

        sumOfSquares = sum(map(lambda (x): x * x, series[:time]))
        (sd, sumOfSquares) = doStdDev(sumOfSquares, 0, 0, time, avg)
        stddevs.append(sd)

        for (index, el) in enumerate(series[time:]):
            if el is None:
                continue
            toDrop = series[index]
            if toDrop is None:
                toDrop = 0
            s = safeSum([safeMul(time, avg), el, -toDrop])
            avg = safeDiv(s, time)

            (sd, sumOfSquares) = doStdDev(sumOfSquares, toDrop,
                                          series[index + time], time, avg)
            stddevs.append(sd)
        for i in range(0, time - 1):
            stddevs.insert(0, None)
        seriesList[count] = stddevs
        count = count + 1
    return seriesList
Exemple #2
0
def nonNegativeDerivative(
    seriesList,
    maxValue=None
):  # useful for watching counter metrics that occasionally wrap
    results = []
    for series in seriesList:
        newValues = []
        prev = None
        for val in series:
            if None in (prev, val):
                newValues.append(None)
                prev = val
                continue
            diff = val - prev
            if diff >= 0:
                newValues.append(diff)
            elif maxValue is not None and maxValue >= val:
                newValues.append(prev + (maxValue - val))
            else:
                newValues.append(None)
            prev = val
        newName = "nonNegativeDerivative(%s)" % series.name
        newSeries = TimeSeries(newName, series.start, series.end, series.step,
                               newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)
    return results
Exemple #3
0
def asPercent(seriesList1, seriesList2orNumber):
    assert len(
        seriesList1
    ) == 1, "asPercent series arguments must reference *exactly* 1 series"
    series1 = seriesList1[0]
    if type(seriesList2orNumber) is list:
        assert len(
            seriesList2orNumber
        ) == 1, "asPercent series arguments must reference *exactly* 1 series"
        series2 = seriesList2orNumber[0]
        name = "asPercent(%s,%s)" % (series1.name, series2.name)
        series = (series1, series2)
        step = reduce(lcm, [s.step for s in series])
        for s in series:
            s.consolidate(step / s.step)
        start = min([s.start for s in series])
        end = max([s.end for s in series])
        end -= (end - start) % step
        values = (safeMul(safeDiv(v1, v2), 100.0) for v1, v2 in izip(*series))
    else:
        number = float(seriesList2orNumber)
        name = "asPercent(%s,%.1f)" % (series1.name, number)
        step = series1.step
        start = series1.start
        end = series1.end
        values = (safeMul(safeDiv(v, number), 100.0) for v in series1)
    series = TimeSeries(name, start, end, step, values)
    series.pathExpression = name
    return [series]
Exemple #4
0
def diffSeries(*seriesLists):
    (seriesList, start, end, step) = normalize(seriesLists)
    name = "diffSeries(%s)" % ','.join(
        set([s.pathExpression for s in seriesList]))
    values = (safeDiff(row) for row in izip(*seriesList))
    series = TimeSeries(name, start, end, step, values)
    series.pathExpression = name
    return [series]
Exemple #5
0
def averageSeries(*seriesLists):
    (seriesList, start, end, step) = normalize(seriesLists)
    #name = "averageSeries(%s)" % ','.join((s.name for s in seriesList))
    name = "averageSeries(%s)" % ','.join(
        set([s.pathExpression for s in seriesList]))
    values = (safeDiv(safeSum(row), safeLen(row)) for row in izip(*seriesList))
    series = TimeSeries(name, start, end, step, values)
    series.pathExpression = name
    return [series]
Exemple #6
0
def sumSeries(*seriesLists):
    try:
        (seriesList, start, end, step) = normalize(seriesLists)
    except:
        return []
    #name = "sumSeries(%s)" % ','.join((s.name for s in seriesList))
    name = "sumSeries(%s)" % ','.join(
        set([s.pathExpression for s in seriesList]))
    values = (safeSum(row) for row in izip(*seriesList))
    series = TimeSeries(name, start, end, step, values)
    series.pathExpression = name
    return [series]
Exemple #7
0
def log(seriesList, base=10):
    results = []
    for series in seriesList:
        newValues = []
        for val in series:
            if val is None:
                newValues.append(None)
            else:
                newValues.append(math.log(val, base))
        newName = "log(%s, %s)" % (series.name, base)
        newSeries = TimeSeries(newName, series.start, series.end, series.step,
                               newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)
    return results
Exemple #8
0
def integral(seriesList):
    results = []
    for series in seriesList:
        newValues = []
        current = 0.0
        for val in series:
            if val is None:
                newValues.append(None)
            else:
                current += val
                newValues.append(current)
        newName = "integral(%s)" % series.name
        newSeries = TimeSeries(newName, series.start, series.end, series.step,
                               newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)
    return results
Exemple #9
0
def derivative(seriesList):
    results = []
    for series in seriesList:
        newValues = []
        prev = None
        for val in series:
            if None in (prev, val):
                newValues.append(None)
                prev = val
                continue
            newValues.append(val - prev)
            prev = val
        newName = "derivative(%s)" % series.name
        newSeries = TimeSeries(newName, series.start, series.end, series.step,
                               newValues)
        newSeries.pathExpression = newName
        results.append(newSeries)
    return results
Exemple #10
0
def movingAverage(seriesList, time):
    count = 0
    for series in seriesList:
        movAvg = TimeSeries(
            "movingAverage(%s,%.1f)" % (series.name, float(time)),
            series.start, series.end, series.step, [])
        movAvg.pathExpression = "movingAverage(%s,%.1f)" % (series.name,
                                                            float(time))
        avg = safeDiv(safeSum(series[:time]), time)
        movAvg.append(avg)
        for (index, el) in enumerate(series[time:]):
            if el is None:
                continue
            toDrop = series[index]
            if toDrop is None:
                toDrop = 0
            s = safeSum([safeMul(time, avg), el, -toDrop])
            avg = safeDiv(s, time)
            movAvg.append(avg)
        for i in range(0, time - 1):
            movAvg.insert(0, None)
        seriesList[count] = movAvg
        count = count + 1
    return seriesList
Exemple #11
0
    def drawLines(self,
                  width=None,
                  dash=None,
                  linecap='butt',
                  linejoin='miter'):
        if not width: width = self.lineWidth
        self.ctx.set_line_width(width)
        originalWidth = width
        width = float(int(width) % 2) / 2
        if dash:
            self.ctx.set_dash(dash, 1)
        else:
            self.ctx.set_dash([], 0)
        self.ctx.set_line_cap({
            'butt': cairo.LINE_CAP_BUTT,
            'round': cairo.LINE_CAP_ROUND,
            'square': cairo.LINE_CAP_SQUARE,
        }[linecap])
        self.ctx.set_line_join({
            'miter': cairo.LINE_JOIN_MITER,
            'round': cairo.LINE_JOIN_ROUND,
            'bevel': cairo.LINE_JOIN_BEVEL,
        }[linejoin])

        # stack the values
        if self.areaMode == 'stacked':
            total = []
            for series in self.data:
                for i in range(len(series)):
                    if len(total) <= i: total.append(0)

                    if series[i] is not None:
                        original = series[i]
                        series[i] += total[i]
                        total[i] += original

            self.data = reverse_sort(self.data)

        # setup the clip region
        self.ctx.set_line_width(1.0)
        self.ctx.rectangle(self.area['xmin'], self.area['ymin'],
                           self.area['xmax'] - self.area['xmin'],
                           self.area['ymax'] - self.area['ymin'])
        self.ctx.clip()
        self.ctx.set_line_width(originalWidth)

        if self.params.get('areaAlpha') and self.areaMode == 'first':
            alphaSeries = TimeSeries(None, self.data[0].start,
                                     self.data[0].end, self.data[0].step,
                                     [x for x in self.data[0]])
            alphaSeries.xStep = self.data[0].xStep
            alphaSeries.color = self.data[0].color
            try:
                alphaSeries.options['alpha'] = float(self.params['areaAlpha'])
            except ValueError:
                pass
            self.data.insert(0, alphaSeries)

        for series in self.data:

            if series.options.has_key('noDraw'):
                continue

            if series.options.has_key(
                    'lineWidth'
            ):  # adjusts the lineWidth of this line if option is set on the series
                self.ctx.set_line_width(series.options['lineWidth'])

            if series.options.has_key(
                    'dashed'):  # turn on dashing if dashed option set
                self.ctx.set_dash([series.options['dashed']], 1)
            else:
                self.ctx.set_dash([], 0)

            x = float(self.area['xmin']) + (self.lineWidth / 2.0)
            y = float(self.area['ymin'])
            self.setColor(series.color, series.options.get('alpha') or 1.0)

            fromNone = True
            idx = -1
            return_path = []

            for value in series:
                idx = idx + 1

                if value is None and self.params.get('drawNullAsZero'):
                    value = 0.0

                if series.options.has_key('areaFill'):
                    value_btm = series.options['lowBoundData'][idx]
                    if value_btm is None:
                        value = None

                if value is None:

                    if not fromNone:
                        if series.options.has_key('areaFill'):
                            # close up the shape by drawing to the previous bottom points in reverse
                            for pair in reverse_sort(return_path):
                                self.ctx.line_to(pair[0], pair[1])
                            return_path = []
                            self.ctx.close_path()
                            self.ctx.fill()
                        elif self.areaMode != 'none':  #Close off and fill area before unknown interval
                            self.ctx.line_to(x, self.area['ymax'])
                            self.ctx.close_path()
                            self.ctx.fill()
                    x += series.xStep
                    fromNone = True

                else:
                    y = self.area['ymax'] - (
                        (float(value) - self.yBottom) * self.yScaleFactor)
                    if y < 0: y = 0

                    if series.options.has_key('areaFill'):
                        value_btm = series.options['lowBoundData'][idx]
                        y_btm = self.area['ymax'] - (
                            (float(value_btm) - self.yBottom) *
                            self.yScaleFactor)
                        if y_btm < 0: y_btm = 0
                        return_path.append((x + series.xStep, y_btm))

                    if series.options.has_key('drawAsInfinite') and value > 0:
                        self.ctx.move_to(x, self.area['ymax'])
                        self.ctx.line_to(x, self.area['ymin'])
                        self.ctx.stroke()
                        x += series.xStep
                        continue

                    if self.lineMode == 'staircase':
                        if fromNone:

                            if series.options.has_key('areaFill'):
                                self.ctx.move_to(x, y_btm)
                                self.ctx.line_to(x, y)
                            elif self.areaMode != 'none':
                                self.ctx.move_to(x, self.area['ymax'])
                                self.ctx.line_to(x, y)
                            else:
                                self.ctx.move_to(x, y)

                        else:
                            self.ctx.line_to(x, y)

                        x += series.xStep
                        self.ctx.line_to(x, y)

                    elif self.lineMode == 'slope':
                        if fromNone:

                            if series.options.has_key('areaFill'):
                                self.ctx.move_to(x, y_btm)
                                self.ctx.line_to(x, y)
                            elif self.areaMode != 'none':
                                self.ctx.move_to(x, self.area['ymax'])
                                self.ctx.line_to(x, y)
                            else:
                                self.ctx.move_to(x, y)

                        x += series.xStep
                        self.ctx.line_to(x, y)

                    fromNone = False

            if series.options.has_key('areaFill'):
                for pair in reverse_sort(return_path):
                    self.ctx.line_to(pair[0], pair[1])
                self.ctx.close_path()
                self.ctx.fill()

            elif self.areaMode != 'none':
                self.ctx.line_to(x, self.area['ymax'])
                self.ctx.close_path()
                self.ctx.fill()

                if self.areaMode == 'first':
                    self.areaMode = 'none'  #This ensures only the first line is drawn as area

            else:
                self.ctx.stroke()

            self.ctx.set_line_width(
                originalWidth)  # return to the original line width
            if series.options.has_key(
                    'dash'
            ):  # if we changed the dash setting before, change it back now
                if dash:
                    self.ctx.set_dash(dash, 1)
                else:
                    self.ctx.set_dash([], 0)