Transfer functions

MPIFiles defines the type TransferFunction which represents the system-properties of a linear time-invariant system in frequency space (see also). In the context of MPIFiles this usually includes the properties of the receive chain of an MPI system, but can also hold information about other parts of the signal chain.

Basic construction and data access

The TransferFunction object is constructed from samples in frequency space and offers two ways to access the underlying data. The first uses indexing to directly access the underlying data:

julia>     f = collect(range(0,1e6,step=1e3));
           # TransferFunction of a simple lowpass filter
julia> tf = TransferFunction(f, 1 ./ (1 .+ im*f/1e4 ))MPIFiles.TransferFunction: 1 channel(s), units of ["NoUnits"] 1001 frequency samples from 0.0 Hz to 1.0e6 Hz
julia> tf[1] # Value of tf at first frequency sample (f = 0 Hz)1.0 - 0.0im

The second method has to be called on the object itself and uses linear interpolation to access the tf at any frequency:

julia>     tf(0) # Value of tf at f = 0 Hz1.0 - 0.0im
julia> tf(1e4) # Value of tf at f = 10000 Hz0.5 - 0.5im

A TransferFunction can have multiple channels, which adds a second index to both data access functions. Directly accessing multiple channels is also possible. The complex array used to construct the TransferFunction needs to have the shape [number of frequency samples, channels].

julia> tf = TransferFunction(f, [1 ./(1 .+im*f/1e4) 1 ./(1 .+im*f/1e3)])MPIFiles.TransferFunction:
	2 channel(s), units of ["NoUnits", "NoUnits"]
	1001 frequency samples from 0.0 Hz to 1.0e6 Hz
julia> tf[11,1]0.5 - 0.5im
julia> tf[11,2]0.009900990099009901 - 0.09900990099009901im
julia> tf(1e4,1)0.5 - 0.5im
julia> tf(1e4,2)0.009900990099009901 - 0.09900990099009901im
julia> tf(1e4, [1,2])1×2 Matrix{ComplexF64}: 0.5-0.5im 0.00990099-0.0990099im
julia> tf(1e4,:)1×2 Matrix{ComplexF64}: 0.5-0.5im 0.00990099-0.0990099im

Units

To attach units to the TransferFunction the keyword-parameter units can to be used to give a Unitful unit to every channel of the tf. This can be useful if the transfer function is not dimensionless but relates two physical quantities, e.g. voltage and current in the form of an impedance. All interpolated accesses to tf data then return a Unitful.Quantity.

julia> R = 1; # Ohm
julia> L = 10e-6; # Henry
julia> RL = TransferFunction(f, R .+ im*2pi*f*L, units=["V/A"])MPIFiles.TransferFunction: 1 channel(s), units of ["V/A"] 1001 frequency samples from 0.0 Hz to 1.0e6 Hz
julia> RL([0,100e3])2-element Vector{Unitful.Quantity{ComplexF64, 𝐋^2 𝐌 𝐈^-2 𝐓^-3, Unitful.FreeUnits{(A^-1, V), 𝐋^2 𝐌 𝐈^-2 𝐓^-3, nothing}}}: (1.0 + 0.0im) V A^-1 (1.0 + 6.283185307179586im) V A^-1

Saving and loading

A TransferFunction object can be saved to and loaded from a .h5 file.

FileIO.saveMethod
save(filename::String, tf::TransferFunction)

Save tf as a h5 file to filename

source
MPIFiles.TransferFunctionMethod
TransferFunction(
    filename::String;
    kargs...
) -> TransferFunction

Create a TransferFunction from a data file at filename.

The file can be either a h5-File created with this package. Keyword arguments will be passed to load_tf_fromVNA

source

Additional constructors

In addition to the constructor taking a single (complex) array it is also possible to give two arrays representing amplitude and phase.

It is also possible to construct a TransferFunction from the transfer function data included in an MPIFile.

MPIFiles.TransferFunctionMethod
TransferFunction(
    freq::Vector{<:Real},
    ampdata::Array{<:Real, N},
    phasedata::Array{<:Real, N};
    kwargs...
) -> TransferFunction

Create a TransferFunction from separate amplitude and phase arrays at frequencies freq.

ampdata and phasedata should have the following shape: [frequencies, channels]

source
MPIFiles.TransferFunctionMethod
TransferFunction(file::MPIFile) -> TransferFunction

Create a TransferFunction from the tf data saved in a MPIFile (see rxTransferFunction)

source

Other interesting functions

MPIFiles.TransferFunctionType
mutable struct TransferFunction
  • freq::Vector{Float64}

  • data::Matrix{ComplexF64}

  • interpolator::Vector{Interpolations.AbstractInterpolation}

  • inductionFactor::Vector{Float64}

  • units::Vector{Unitful.FreeUnits}

TransferFunction(freq_::Vector{<:Real}, datain::Array{<:Complex}; inductionFactor::Vector{<:Real}=ones(size(datain, 2)), units::Vector=Unitful.FreeUnits[Unitful.NoUnits for i in 1:size(datain, 2)])

Create a TransferFunction from a complex data array at frequencies freq_.

Optional Keyword-Arguments:

  • inductionFactor::Vector{<:Real}: induction factor for each channel
  • units::Vector: units for each channel, can be either Unitful.FreeUnits or a string that can be parsed as a Unitful unit
source
MPIFiles.combineMethod
combine(
    tf1::TransferFunction,
    tf2::TransferFunction;
    interpolate
) -> TransferFunction

Combine two TransferFunctions along their channel dimension. If interpolate=false, will only work if the frequency samples are identical.

source