Уточнить обработку плотных трендов и восстановление сигналов
This commit is contained in:
@@ -9,11 +9,35 @@ are separate objects, never channels in the acquisition or measurement model.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import csv
|
||||
from bisect import bisect_left, bisect_right
|
||||
from operator import itemgetter
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from .signal_reconstruction import METHODS, reconstruct
|
||||
|
||||
|
||||
class FrozenPoints(tuple):
|
||||
"""Normalized immutable samples, reusable across processing requests."""
|
||||
|
||||
def __new__(cls, points):
|
||||
if isinstance(points, cls):
|
||||
return points
|
||||
result = super().__new__(cls, ((float(x), float(y)) for x, y in points))
|
||||
result.ordered = all(result[i - 1][0] <= result[i][0] for i in range(1, len(result)))
|
||||
return result
|
||||
|
||||
def between(self, left, right):
|
||||
if self.ordered:
|
||||
start = bisect_left(self, left, key=itemgetter(0))
|
||||
stop = bisect_right(self, right, key=itemgetter(0))
|
||||
if start == 0 and stop == len(self):
|
||||
return self
|
||||
result = tuple.__new__(type(self), self[start:stop])
|
||||
result.ordered = True
|
||||
return result
|
||||
return FrozenPoints((x, y) for x, y in self if left <= x <= right)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Axis:
|
||||
label: str = "Время"
|
||||
@@ -36,7 +60,7 @@ class Series:
|
||||
|
||||
def __post_init__(self):
|
||||
# A source may reuse mutable buffers immediately after publication.
|
||||
object.__setattr__(self, "points", tuple((float(x), float(y)) for x, y in self.points))
|
||||
object.__setattr__(self, "points", FrozenPoints(self.points))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -103,7 +127,7 @@ def prepare(snapshot, key, method="pchip", output_count=1000, degree=2):
|
||||
if snapshot.x_range is not None:
|
||||
left, right = snapshot.x_range
|
||||
selected = Series(selected.key, selected.label,
|
||||
tuple((x, y) for x, y in selected.points if left <= x <= right),
|
||||
selected.points.between(left, right),
|
||||
y_unit=selected.y_unit)
|
||||
return Request(selected, snapshot.axis, snapshot.source, method, output_count, degree, snapshot.x_range)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user