Data containers

>>> from zero.data import Series, Response, NoiseDensity

Zero analysis results (responses and noise spectra) are stored within function containers. These are relatively low level objects that hold each function’s data (within a series), its frequency axis, and any meta data produced by the analysis. These objects are able to plot themselves when provided a figure to draw to. They also contain logic to compare themselves to other functions, to check for equivalency.

In normal circumstances, you should not need to directly interact with these objects; rather, you can plot and save their underlying data using a Solution.

Series

Underlying function data is stored in a Series. This contains two dimensional data. Series support basic mathematical operations such as multiplication, division and inversion.

Functions

Responses

Responses contain the response of a component or node to another component or node. Each response contains references to the source and sink component or node, and its units.

The response’s underlying complex data is stored in its complex_magnitude property. The magnitude and phase can be retrieved using the magnitude and phase properties, respectively. The decibel-scaled magnitude can be retrieved using db_magnitude.

Note

db_magnitude is returned with power scaling, i.e. \(20 \log_{10} \left| x \right|\) where \(x\) is the complex response.

>>> response.complex_magnitude
array([-1.44905660e+06+271698.11320755j, -1.28956730e+06+520929.0994604j ,
       -8.53524671e+05+742820.7338082j , -3.32179931e+05+622837.37024221j,
       -8.66146537e+04+349885.52751013j, -1.95460509e+04+170108.87173014j,
       -4.25456479e+03 +79773.08987768j, -9.18662496e+02 +37109.9690498j ,
       -1.98014980e+02 +17233.2022651j , -4.26654531e+01  +7999.77245092j])
>>> response.db_magnitude
array([123.37176609, 122.86535272, 121.07307338, 116.97464649,
       111.13682633, 104.67150284,  98.04946401,  91.39247246,
       84.72789306,  78.06167621])
>>> response.phase
array([169.38034472, 158.00343425, 138.96701713, 118.07248694,
       103.90412599,  96.55472157,  93.05288251,  91.41807544,
       90.65831778,  90.30557459])

Noise spectral densities

Noise spectral densities contain the noise at a particular component or node arising from noise produced by another component or node. They contain the noise source that produces the noise and a reference to the component or node that the noise is measured at, and its units. Multi-noise spectra contain a list of multiple noise sources; these are used to represent noise sums.

The noise spectral density’s underlying data is stored in its spectral_density property.

>>> response.spectral_density
array([1.29259971e-07, 1.00870891e-07, 8.45132667e-08, 7.57294937e-08,
       7.12855936e-08, 6.91259094e-08, 6.81002020e-08, 6.76188164e-08,
       6.73941734e-08, 6.72894850e-08])

Labels

Functions can have labels that are used in plot legends and when searching for functions in a solution.

Labels can be set for functions using their label property. If no label is set by the user, a default label is produced using the function’s source and sink in the case of single-source and -sink functions, or “Incoherent sum” for noise sums.

Mathematical operations

The underlying data within a function can be multiplied, divided and inverted by applying mathematical operations to the function object. Multiplication and division can be applied using scalars or other functions. For example, noise spectra can be multiplied by responses to project noise to a different part of a circuit (used for example to refer noise to the circuit input).

When an operation involves two functions, the units of each function are checked for validity. As determined by the order of operation, the left function’s sink must have the same units as the right function’s source. The resulting function then takes the left functions’ source and the right function’s sink.

Hint

While the inner sources and sinks of such operations must have the same units, they do not need to be the same element. This is to allow functions to be lightweight and not have to maintain a reference to the component, node or noise source objects they originally represented (rather, just their label). It is up to the user to check that each operation makes physical sense.

Some operations are not possible, such as multiplying noise by noise. In these cases, a ValueError is raised.