Validators#

validate_real(X: object, tol: float = 1e-12) → None[source]#

Validate that the input array is purely real.

Parameters:
  • X (np.ndarray) – Input array to validate.

  • tol (float, optional) – Tolerance for the imaginary part. Default is 1e-12.

Raises:

ValueError – If the imaginary part of any element exceeds tol.

validate_data(data: object) → None[source]#

Validate that data is array-like (convertible to a numeric numpy array).

Reference signals are plain arrays: extract them with Sequential(observations=...) before configuring a data-aided block.

Parameters:

data (np.ndarray) – Data to validate.

Raises:

TypeError – If data cannot be converted to a numeric numpy array.

validate_single_path(X: object, block: str, estimand: str) → None[source]#

Refuse a multi-path signal in an estimator that measures one record.

Decision D49. Once a chain carries several paths on the antenna axis – the two polarizations of a coherent link, the branches of a MIMO receiver – every estimator has to answer a question it could ignore while signals were one-dimensional: is what it measures one physical quantity shared by all the paths, or one per path?

  • Shared: a carrier frequency offset comes from one laser beating against one local oscillator, so there is a single number and it should be estimated jointly, over all the paths at once. Estimating it per path throws away half the data and produces two numbers that then have to be reconciled.

  • Per path: an IQ imbalance belongs to a receiver, a DC offset to an analog-to-digital converter, a residual rotation to whichever output of a butterfly equalizer produced it. One estimate each.

Letting numpy broadcast decides the question by accident, and it decides it wrong in both directions: it silently pools what should be separate, or crashes with a shape error that says nothing. This validator is for the blocks that have not been generalized: it states which of the two they are and what to do instead.

Parameters:
  • X (np.ndarray) – Signal about to be processed.

  • block (str) – Name of the calling block, for the message.

  • estimand (str) – What the block measures, e.g. "a delay", in a form that reads after “estimates”.

Raises:

ShapeError – If X has more than one path on its antenna axis.

Examples

>>> import numpy as np
>>> validate_single_path(np.zeros(8), "Block", "a delay")   # fine
>>> try:
...     validate_single_path(np.zeros((2, 8)), "Block", "a delay")
... except Exception as error:
...     print(type(error).__name__)
ShapeError