Signal

Inheritance diagram of hermespy.core.signal_model.Signal, hermespy.core.signal_model.DenseSignal, hermespy.core.signal_model.SparseSignal, hermespy.core.signal_model.SignalBlock

Signal models are HermesPy’s way of representing complex-valued electromagnetic multi-stream time-domain sequences.

class Signal[source]

Bases: ABC, Iterable, Serializable

Abstract base class for all signal models in HermesPy.

static Create(samples, sampling_rate=1.0, carrier_frequency=0.0, noise_power=0.0, delay=0.0, offsets=None)[source]

Creates a signal model instance given signal samples.

Subclasses of Signal should reroute the given arguments to init and return the result.

Parameters:
  • samples (ndarray[tuple[int, int], dtype[complex128]] | Sequence[SignalBlock]) – Single or a sequence of 2D matricies with shapes MxT_i, where M - number of streams, T_i - number of samples in the matrix i. Note that M for each entry of the sequence must be the same. SignalBlock and Sequence[SignalBlock] can also be passed here.

  • sampling_rate (float) – Sampling rate of the signal in Hz.

  • offsets (Sequence[int] | None) – Integer offsets of the samples if given in a sequence. Ignored if samples is not a Sequence of np.ndarray. len(offsets) must be equal to len(samples). Offset number i must be greater then offset i-1 + samples[i-1].shape[1].

Return type:

Signal

Returns:

SparseSignal if samples argument is a list of ndarrays. DenseSignal otherwise.

static Empty(sampling_rate, num_streams=0, num_samples=0, **kwargs)[source]

Creates an empty signal model instance. Initializes it with the given arguments. If both num_streams and num_samples are not 0, then initilizes samples with np.empty.

Return type:

Signal

classmethod FromInterleaved(interleaved_samples, scale=True, **kwargs)[source]

Initialize a signal model from interleaved samples.

Parameters:
  • interleaved_samples (ndarray[tuple[int, int], dtype[int16]]) – Numpy array of interleaved samples.

  • scale (bool) – Scale the samples after interleaving

  • kwargs – Additional class initialization arguments.

Return type:

Signal

abstract append_samples(value)[source]

Append samples in time-domain to the signal model.

Parameters:

value (Signal | ndarray) – The signal samples to be appended.

Return type:

TypeVar(ST, bound= Signal)

Returns:

A new signal model instance with the appended samples.

Raises:

ValueError – If the number of streams don’t align.

abstract append_streams(value)[source]

Append streams to the signal model.

Parameters:

value (Signal | ndarray) – The signal samples to be appended.

Return type:

TypeVar(ST, bound= Signal)

Returns:

A new signal model instance with the appended streams.

Raises:

ValueError – If the number of samples don’t align.

abstract copy()[source]

Create a deep copy of this signal model.

Returns: A deep copy of this signal model.

Return type:

TypeVar(ST, bound= Signal)

abstract resample(sampling_rate, aliasing_filter=True)[source]

Resample the modeled signal to a different sampling rate.

Parameters:
  • sampling_rate (float) – Sampling rate of the new signal model in Hz.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during downsampling. Enabled by default.

Return type:

TypeVar(ST, bound= Signal)

Returns: The resampled signal model.

Raises:

ValueError – If sampling_rate is smaller or equal to zero.

abstract superimpose(added_signal, resample=True, aliasing_filter=True, stream_indices=None, interpolation=InterpolationMode.NEAREST)[source]

Superimpose an additive signal model to this model.

Internally re-samples added_signal to this model’s sampling rate, if required. Mixes added_signal according to the carrier-frequency distance.

If the delays of this signal and added_signal differ, the signals will be aligned according to their delays. added_signals with delays smaller than this signal’s delay will be cut accordingly (as opposed to changing the start time of the resulting signal).

Parameters:
  • added_signal (Signal) – The signal to be superimposed onto this one.

  • resample (bool) – Allow for dynamic resampling during superposition.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during mixing.

  • stream_indices (Sequence[int] | None) – Indices of the streams to be mixed.

  • interpolation (InterpolationMode) – Interpolation strategy to be used for superimposed signals of different delays. Required if the delays of this signal and added_signal differ and are not integer multiples of the sampling period.

Raises:
  • ValueError – If added_signal contains a different number of streams than this signal model.

  • RuntimeError – If resampling is required but not allowd.

  • NotImplementedError – If the delays if this signal and added_signal differ.

Return type:

Signal

abstract to_dense()[source]

Concatenate all the blocks in the signal into one block. Accounts for offsets by inserting zeros where necessary.

Note

If offset values are too big, memory overflow is possible. Instead, iterating over the signal’s blocks is recommended.

Return type:

DenseSignal

Returns:

Dense form for this signal

to_interleaved(data_type=<class 'numpy.int16'>, scale=True)[source]

Convert the complex-valued floating-point model samples to interleaved integers.

Parameters:
  • data_type (Type) – Numpy resulting data type.

  • scale (bool) – Scale the floating point values to stretch over the whole range of integers.

Return type:

ndarray

Returns:

Numpy array of interleaved samples. Will contain double the samples in time-domain.

abstract view(dtype)[source]

View the samples of the signal model as a numpy ndarray of the given dtype.

Parameters:

dtype (type[TypeVar(AT, bound= ndarray)]) – The desired numpy dtype to view the samples as.

Return type:

TypeVar(AT, bound= ndarray)

Returns:

The samples of the signal model as a numpy ndarray of the given dtype.

abstract property block_offsets: Sequence[int][source]

List of integer offsets of each block relative to the signal start sample.

abstract property blocks: Sequence[SignalBlock][source]

Individual dense blocks this signal model consists of.

property carrier_frequency: float[source]

The center frequency of the modeled signal in the radio-frequency transmit band in Hz.

property delay: float[source]

Delay of the modeled signal in seconds.

The delay is relative to a common time-reference, e.i. the start of a simulation.

Raises:

ValueError – If the delay is smaller than zero.

property duration: float[source]

Signal model duration in time-domain.

Duration in seconds.

abstract property energy: ndarray[source]

Sum of squared voltages of all streams in the signal model.

property eye: _EyeVisualization[source]

Visualize the eye diagram of the signal model.

filter_order: int = 10[source]
property frequencies: ndarray[source]

The signal model’s discrete sample points in frequcy domain.

Numpy vector of frequency bins.

property noise_power: float[source]

Noise power of the superimposed noise signal.

Raises:

ValueError – If the noise power is smaller than zero.

abstract property num_blocks: int[source]

The number of dense blocks within this signal model.

abstract property num_samples: int[source]

The number of discrete time-domain samples within this signal model.

abstract property num_streams: int[source]

The number of parallel signal streams within this signal model.

property plot: _SamplesVisualization[source]

Visualize the samples of the signal model.

abstract property power: ndarray[source]

Mean squared voltage of each modeled stream.

Note that, in case of sparse signals, the power is only computed over the non-zero regions.

property sampling_rate: float[source]

The rate at which the modeled signal was sampled in Hz.

property shape: tuple[int, int][source]

Two dimensional tuple of shape \(M \times N\).

\(M\) is the number of streams and \(N\) is the number of samples.

property timestamps: ndarray[source]

The sample-points of the signal block.

Vector of length T containing sample-timestamps in seconds.

property title: str[source]
class DenseSignal(num_streams: int, num_samples: int, sampling_rate: float, carrier_frequency: float = 0.0, noise_power: float = 0.0, delay: float = 0.0, buffer: Buffer | None = None)[source]

Bases: SignalBlock, Signal

Dense signal model class.

Create a new DenseSignal instance.

Parameters:
  • num_streams – Number of dedicated streams within this signal.

  • num_samples – Number of samples within this signal.

  • sampling_rate – Sampling rate of the signal in Hz.

  • carrier_frequency – Carrier frequency of the signal in Hz.

  • no_delayower – Noise power of the signal.

  • delay – Delay of the signal in seconds.

  • buffer – Optional buffer to initialize the samples from.

classmethod Deserialize(process)[source]

Deserialize an object’s state.

Objects cannot be deserialized directly, instead a Factory must be instructed to carry out the deserialization process.

Parameters:

process (DeserializationProcess) – The current stage of the deserialization process. This object is generated by the Factory and provides an interface to deserialization methods supporting multiple backends.

Return type:

DenseSignal

Returns:

The deserialized object.

classmethod FromNDArray(array, sampling_rate, carrier_frequency=0.0, noise_power=0.0, delay=0.0)[source]

Create a new dense signal from a given numpy ndarray.

Parameters:
  • array (ndarray[tuple[int, int], dtype[complex128]]) – Array containing the signal samples. Must be of shape (num_streams, num_samples).

  • sampling_rate (float) – Sampling rate of the signal in Hz.

  • carrier_frequency (float) – Carrier frequency of the signal in Hz.

  • noise_power (float) – Noise power of the signal.

  • delay (float) – Delay of the signal in seconds.

Return type:

DenseSignal

Returns:

The created dense signal model.

static Zeros(num_streams, num_samples, sampling_rate, carrier_frequency=0.0, noise_power=0.0, delay=0.0)[source]

Create a new zero-initialized dense signal.

Parameters:
  • num_streams (int) – Number of streams in the signal.

  • num_samples (int) – Number of samples in the signal.

  • sampling_rate (float) – Sampling rate of the signal in Hz.

  • carrier_frequency (float) – Carrier frequency of the signal in Hz.

  • noise_power (float) – Noise power of the signal.

  • delay (float) – Delay of the signal in seconds.

Return type:

DenseSignal

Returns:

The created signal model.

append_samples(value)[source]

Append samples to this signal block. Creates a new instance.

Return type:

DenseSignal

append_streams(value)[source]

Append streams to the signal model.

Parameters:

value (Signal | ndarray) – The signal samples to be appended.

Return type:

DenseSignal

Returns:

A new signal model instance with the appended streams.

Raises:

ValueError – If the number of samples don’t align.

copy(order=None)[source]

Copy the dense signal samples into a new signal model with identical parameters.

Return type:

DenseSignal

resample(sampling_rate, aliasing_filter=True)[source]

Resample the modeled signal to a different sampling rate.

Parameters:
  • sampling_rate (float) – Sampling rate of the new signal model in Hz.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during downsampling. Enabled by default.

Return type:

DenseSignal

Returns: The resampled signal model.

Raises:

ValueError – If sampling_rate is smaller or equal to zero.

serialize(process)[source]

Serialize this object’s state.

Objects cannot be serialized directly, instead a Factory must be instructed to carry out the serialization process.

Parameters:

process (SerializationProcess) – The current stage of the serialization process. This object is generated by the Factory and provides an interface to serialization methods supporting multiple backends.

Return type:

None

superimpose(added_signal, resample=True, aliasing_filter=True, stream_indices=None, interpolation=InterpolationMode.NEAREST)[source]

Superimpose an additive signal model to this model.

Internally re-samples added_signal to this model’s sampling rate, if required. Mixes added_signal according to the carrier-frequency distance.

If the delays of this signal and added_signal differ, the signals will be aligned according to their delays. added_signals with delays smaller than this signal’s delay will be cut accordingly (as opposed to changing the start time of the resulting signal).

Parameters:
  • added_signal (Signal) – The signal to be superimposed onto this one.

  • resample (bool) – Allow for dynamic resampling during superposition.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during mixing.

  • stream_indices (Sequence[int] | slice | None) – Indices of the streams to be mixed.

  • interpolation (InterpolationMode) – Interpolation strategy to be used for superimposed signals of different delays. Required if the delays of this signal and added_signal differ and are not integer multiples of the sampling period.

Raises:
  • ValueError – If added_signal contains a different number of streams than this signal model.

  • RuntimeError – If resampling is required but not allowd.

  • NotImplementedError – If the delays if this signal and added_signal differ.

Return type:

Signal

to_dense()[source]

Concatenate all the blocks in the signal into one block. Accounts for offsets by inserting zeros where necessary.

Note

If offset values are too big, memory overflow is possible. Instead, iterating over the signal’s blocks is recommended.

Return type:

DenseSignal

Returns:

Dense form for this signal

property block_offsets: list[int][source]

List of integer offsets of each block relative to the signal start sample.

property blocks: list[SignalBlock][source]

Individual dense blocks this signal model consists of.

property num_blocks: int[source]

The number of dense blocks within this signal model.

property title: str[source]
class SparseSignal(samples, sampling_rate=1.0, carrier_frequency=0.0, noise_power=0.0, delay=0.0)[source]

Bases: Signal

Sparse signal model class.

HermesPy signal sparsification can be described as follows. Given M signal streams, N samples are recorded for each stream with some constant temporal sampling rate. Thus, a MxN complex matrix of samples can be constructed. If at some point streams do not contain any recorded/transmitted signal, then fully zeroed columns appear in the matrix. This signal model contains a list of SignalBlocks, each representing non-zero regions of the original samples matrix. Thus, regions with only zeros are avoided. Note, that SignalBlocks are sorted by their offset time and don’t overlap.

Signal model initialization.

Parameters:
  • samples (ndarray | Sequence[SignalBlock]) – A MxT matrix containing uniformly sampled base-band samples of the modeled signal. M is the number of individual streams, T the number of available samples. Note that you can pass here a 2D ndarray, a SignalBlock, a Sequence[np.ndarray] or a Sequence[SignalBlock]. Given Sequence[SignalBlock], concatenates all signal blocks into one, accounting for their offsets. Given Sequence[np.ndarray], concatenates them all into one matrix sequentially.

  • sampling_rate (float) – Sampling rate of the modeled signal in Hz (in the base-band).

  • carrier_frequency (float) – Carrier-frequency of the modeled signal in the radio-frequency band in Hz. Zero by default.

  • noise_power (float) – Power of the noise superimposed to this signal model. Zero by default.

  • delay (float) – Delay of the signal in seconds. Zero by default.

classmethod Deserialize(process)[source]

Deserialize an object’s state.

Objects cannot be deserialized directly, instead a Factory must be instructed to carry out the deserialization process.

Parameters:

process (DeserializationProcess) – The current stage of the deserialization process. This object is generated by the Factory and provides an interface to deserialization methods supporting multiple backends.

Return type:

SparseSignal

Returns:

The deserialized object.

static Empty(sampling_rate, num_streams=0, num_samples=0, **kwargs)[source]

Creates an empty signal model instance. Initializes it with the given arguments. If both num_streams and num_samples are not 0, then initilizes samples with np.empty.

Return type:

SparseSignal

append_samples(value)[source]

Append samples in time-domain to the signal model.

Parameters:

value (Signal | ndarray) – The signal samples to be appended.

Return type:

SparseSignal

Returns:

A new signal model instance with the appended samples.

Raises:

ValueError – If the number of streams don’t align.

append_streams(value)[source]

Append streams to the signal model.

Parameters:

value (Signal | ndarray) – The signal samples to be appended.

Return type:

SparseSignal

Returns:

A new signal model instance with the appended streams.

Raises:

ValueError – If the number of samples don’t align.

copy()[source]

Copy the sparse signal samples into a new signal model with identical parameters.

Return type:

SparseSignal

resample(sampling_rate, aliasing_filter=True)[source]

Resample the modeled signal to a different sampling rate.

Parameters:
  • sampling_rate (float) – Sampling rate of the new signal model in Hz.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during downsampling. Enabled by default.

Return type:

SparseSignal

Returns: The resampled signal model.

Raises:

ValueError – If sampling_rate is smaller or equal to zero.

serialize(process)[source]

Serialize this object’s state.

Objects cannot be serialized directly, instead a Factory must be instructed to carry out the serialization process.

Parameters:

process (SerializationProcess) – The current stage of the serialization process. This object is generated by the Factory and provides an interface to serialization methods supporting multiple backends.

Return type:

None

superimpose(added_signal, resample=True, aliasing_filter=True, stream_indices=None, interpolation=InterpolationMode.NEAREST)[source]

Superimpose an additive signal model to this model.

Internally re-samples added_signal to this model’s sampling rate, if required. Mixes added_signal according to the carrier-frequency distance.

If the delays of this signal and added_signal differ, the signals will be aligned according to their delays. added_signals with delays smaller than this signal’s delay will be cut accordingly (as opposed to changing the start time of the resulting signal).

Parameters:
  • added_signal (Signal) – The signal to be superimposed onto this one.

  • resample (bool) – Allow for dynamic resampling during superposition.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during mixing.

  • stream_indices (Sequence[int] | None) – Indices of the streams to be mixed.

  • interpolation (InterpolationMode) – Interpolation strategy to be used for superimposed signals of different delays. Required if the delays of this signal and added_signal differ and are not integer multiples of the sampling period.

Raises:
  • ValueError – If added_signal contains a different number of streams than this signal model.

  • RuntimeError – If resampling is required but not allowd.

  • NotImplementedError – If the delays if this signal and added_signal differ.

Return type:

SparseSignal

to_dense()[source]

Concatenate all the blocks in the signal into one block. Accounts for offsets by inserting zeros where necessary.

Note

If offset values are too big, memory overflow is possible. Instead, iterating over the signal’s blocks is recommended.

Return type:

DenseSignal

Returns:

Dense form for this signal

view(dtype)[source]

View the samples of the signal model as a numpy ndarray of the given dtype.

Parameters:

dtype (type[TypeVar(AT, bound= ndarray)]) – The desired numpy dtype to view the samples as.

Return type:

TypeVar(AT, bound= ndarray)

Returns:

The samples of the signal model as a numpy ndarray of the given dtype.

property block_offsets: list[int][source]

List of integer offsets of each block relative to the signal start sample.

property blocks: list[SignalBlock][source]

Individual dense blocks this signal model consists of.

property energy: ndarray[source]

Sum of squared voltages of all streams in the signal model.

property num_blocks: int[source]

The number of dense blocks within this signal model.

property num_samples: int[source]

The number of discrete time-domain samples within this signal model.

property num_streams: int[source]

The number of parallel signal streams within this signal model.

property power: ndarray[source]

Mean squared voltage of each modeled stream.

Note that, in case of sparse signals, the power is only computed over the non-zero regions.

property title: str[source]
class SignalBlock(num_streams: int, num_samples: int, offset: int = 0, buffer: Buffer | None = None)[source]

Bases: ndarray[tuple[int, int], dtype[complex128]], Serializable

A TxN matrix of complex entries representing signal samples over T streams and N time samples.

Used in Signal to store pieces of signal samples. Use offset property to set the offset of this block relative to a signal start sample.

Create a new SignalBlock instance.yx

Parameters:
  • num_streams – Number of dedicated streams within this signal block.

  • num_samples – Number of samples within this signal block.

  • offset – Integer sample offset of this block relative to a signal start sample.

  • buffer – Optional buffer to initialize the samples from.

Raises:

ValueError – If ndim of given samples is bigger then 2.

classmethod Deserialize(process)[source]

Deserialize an object’s state.

Objects cannot be deserialized directly, instead a Factory must be instructed to carry out the deserialization process.

Parameters:

process (DeserializationProcess) – The current stage of the deserialization process. This object is generated by the Factory and provides an interface to deserialization methods supporting multiple backends.

Return type:

SignalBlock

Returns:

The deserialized object.

append_samples(value)[source]

Append samples to this signal block. Creates a new instance.

Return type:

SignalBlock

max(axis=None, out=None, *, keepdims=<no value>, initial=<no value>, where=<no value>)[source]

Return the maximum along a given axis.

Refer to numpy.amax for full documentation.

See also

numpy.amax

equivalent function

min(axis=None, out=None, *, keepdims=<no value>, initial=<no value>, where=<no value>)[source]

Return the minimum along a given axis.

Refer to numpy.amin for full documentation.

See also

numpy.amin

equivalent function

resample_block(sampling_rate_old, sampling_rate_new, aliasing_filter=True)[source]

Resample a signal block to a different sampling rate.

Parameters:
  • sampling_rate_old (float) – Old sampling rate of the signal block in Hz.

  • sampling_rate_new (float) – New sampling rate of the signal block in Hz.

  • aliasing_filter (bool) – Apply an anti-aliasing filter during downsampling. Enabled by default.

Return type:

SignalBlock

Returns: The resampled signal block.

Raises:

ValueError – If sampling_rate_old or sampling_rate_new are smaller or equal to zero.

serialize(process)[source]

Serialize this object’s state.

Objects cannot be serialized directly, instead a Factory must be instructed to carry out the serialization process.

Parameters:

process (SerializationProcess) – The current stage of the serialization process. This object is generated by the Factory and provides an interface to serialization methods supporting multiple backends.

Return type:

None

superimpose_to(target_sampling_rate, target_carrier_frequency, sampling_rate, carrier_frequency)[source]
Return type:

SignalBlock

property end: int[source]

Get block stop sample. b.num_samples = b.end - b.off

property energy: ndarray[source]

Compute the energy of the modeled signal.

Returns: The energy of each modeled stream as a numpy vector.

property num_samples: int[source]

The number of samples within this signal block.

Returns: The number of samples.

property num_streams: int[source]

The number of streams within this signal block.

Returns: The number of streams.

property offset: int[source]

The dense signal block’s offset relative to the assumed signal start.

Raises:

ValueError – If the offset is smaller than zero.

property power: ndarray[source]

Compute power of the modeled signal.

Returns: The power of each modeled stream as a numpy vector.

class _SamplesVisualization(signal)[source]

Bases: _SignalVisualization

Visualize the samples of a signal model.

Parameters:

signal (Signal) – The signal model to be visualized.

create_figure(space='both', **kwargs)[source]

Create a new figure for plotting.

Returns: Newly generated figure and axes to plot into.

Return type:

tuple[Figure, ndarray[tuple[int, int], dtype[Any]]]

property title: str[source]

Title of the visualizable.

Returns: Title string.

class _EyeVisualization(signal)[source]

Bases: _SignalVisualization

Visualize the eye diagram of a signal model.

Depending on the domain flag the eye diagram will either be rendered with the time-domain on the plot’s x-axis

(Source code, png, hires.png, pdf)

../../_images/signal-1.png

or on the complex plane

(Source code, png, hires.png, pdf)

../../_images/signal-2.png
Parameters:
  • symbol_duration – Assumed symbol repetition interval in seconds. Will be rounded to match the signal model’s sampling rate.

  • line_width – Line width of a single plot line.

  • title – Title of the plotted figure. Eye Diagram by default.

  • domain – Plotting behaviour of the eye diagram. time by default. See above examples for rendered results.

  • legend – Display a plot legend. Enabled by default. Only considered when in time domain plotting mode.

  • linewidth – Line width of the eye plot. \(.75\) by default.

  • symbol_cutoff – Relative amount of symbols ignored during plotting. \(0.1\) by default. This is required to properly visualize intersymbol interferences within the communication frame, since special effects may occur at the start and end.

  • signal (Signal) – The signal model to be visualized.

property title: str[source]

Title of the visualizable.

Returns: Title string.

class _SignalVisualization(signal)[source]

Bases: VisualizableAttribute[PlotVisualization]

Visualization of signal samples.

Parameters:

signal (Signal) – The signal model to be visualized.

property signal: Signal[source]

The signal model to be visualized.