Source code for qibolab._core.components.filters

from typing import Annotated, Literal, Union

import numpy as np
from pydantic import Field

from ..serialize import Model

__all__ = ["ExponentialFilter", "FiniteImpulseResponseFilter"]


[docs] class ExponentialFilter(Model): """Exponential filter. Correct filters for signal with behavior 1 + amplitude * e^(-t/tau). """ kind: Literal["exp"] = "exp" amplitude: float """Amplitude for exponential term.""" tau: float """Time decay in exponential in samples unit.""" def _compute_filter(self) -> tuple[list[float], list[float]]: """Computing feedback and feedforward taps.""" alpha = 1 - np.exp(-1 / (self.tau * (1 + self.amplitude))) k = ( self.amplitude / ((1 + self.amplitude) * (1 - alpha)) if self.amplitude < 0 else self.amplitude / (1 + self.amplitude - alpha) ) b0 = 1 - k + k * alpha b1 = -(1 - k) * (1 - alpha) a0 = 1 a1 = -(1 - alpha) return [a0, a1], [b0, b1] @property def feedback(self) -> list[float]: return self._compute_filter()[0] @property def feedforward(self) -> list[float]: return self._compute_filter()[1]
[docs] class FiniteImpulseResponseFilter(Model): """FIR filter.""" kind: Literal["fir"] = "fir" coefficients: list[float] @property def feedforward(self): return self.coefficients
Filter = Annotated[ Union[ExponentialFilter, FiniteImpulseResponseFilter], Field(discriminator="kind"), ]