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));julia> # TransferFunction of a simple lowpass filter 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 Hzjulia> 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.0imjulia> 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 Hzjulia> tf[11,1]0.5 - 0.5imjulia> tf[11,2]0.009900990099009901 - 0.09900990099009901imjulia> tf(1e4,1)0.5 - 0.5imjulia> tf(1e4,2)0.009900990099009901 - 0.09900990099009901imjulia> tf(1e4, [1,2])1×2 Matrix{ComplexF64}: 0.5-0.5im 0.00990099-0.0990099imjulia> 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. Alternatively data can just be a Unitful.Quantity. Then units is ignored.
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; # Ohmjulia> L = 10e-6; # Henryjulia> 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 Hzjulia> 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
julia> f_unitful = collect(range(0u"Hz",1u"MHz",step=1u"kHz"));julia> R = 1u"Ω";julia> L = 10u"µH";julia> RL = TransferFunction(f_unitful, R .+ im*2pi*f_unitful*L .|> u"V/A")MPIFiles.TransferFunction: 1 channel(s), units of ["V/A"] 1001 frequency samples from 0.0 Hz to 1.0e6 Hzjulia> 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.283185307179585im) V A^-1
Saving and loading
A TransferFunction object can be saved to and loaded from a .h5 file.
FileIO.save — Methodsave(filename::String, tf::TransferFunction)
Save tf as a h5 file to filename
MPIFiles.TransferFunction — MethodTransferFunction(filename::String; kargs...) -> Any
Create a TransferFunction from a data file at filename.
The file can be either a h5-File created with this package or a file that is written by a VNA. Keyword arguments will be passed to load_tf_fromVNA
Constructors
The TransferFunction constructor can take either a complex data array or two arrays representing the amplitude and phase of the transfer function. Unitful conversion is automatically done for all parameters.
It is also possible to construct a TransferFunction from the transfer function data included in an MPIFile.
MPIFiles.TransferFunction — Typemutable struct TransferFunctionfreq::Vector{Float64}data::Matrix{ComplexF64}interpolator::Vector{Interpolations.AbstractInterpolation}inductionFactor::Vector{Float64}units::Vector{Unitful.FreeUnits}
TransferFunction(freq::Vector, data::Array, [phasedata]; [inductionFactor], [units])Create a TransferFunction from a data array data at frequencies freq. freq is given in Hz or should have a Unitful frequency unit attached data should have the shape [frequencies, channels]. data can be either complex or real, if data is real a second array phasedata can be passed representing the phase in radians. Both the amplitude and the phase can have Unitful units.
Optional Keyword-Arguments:
inductionFactor::Vector{<:Real}: induction factor for each channelunits::Vector: units for each channel, can be either Unitful.FreeUnits or a string that can be parsed as a Unitful unit. Instead of using this keyword,datacan also have Unitful units attached, then the units keyword-argument is ignored.
MPIFiles.TransferFunction — MethodTransferFunction(file::MPIFile) -> Any
Create a TransferFunction from the tf data saved in a MPIFile (see rxTransferFunction)
Other interesting functions
MPIFiles.combine — Methodcombine(
tf1::TransferFunction,
tf2::TransferFunction;
interpolate
) -> Any
Combine two TransferFunctions along their channel dimension. If interpolate=false, will only work if the frequency samples are identical.
MPIFiles.load_tf_fromVNA — Functionload_tf_fromVNA(
filename::String;
kwargs...
) -> TransferFunction
Load data receive calibration from file recorded with the VNA. Data will be processed by processRxTransferFunction, see there for keyword arguments
MPIFiles.processRxTransferFunction — FunctionprocessRxTransferFunction(
freq,
compdata;
frequencyWeighting,
R,
N,
A,
r,
d
) -> Any
Process the data from a receive calibration measurement using a calibration coil into a TransferFunction
Keyword parameters:
frequencyWeighting: if true corrects for the frequency term in the TF, which results in a TF that does not integrate on application, but instead shows derivative of magnetic momentR: value of the resistance of the calibration coil in ΩN: number of turns of the calibration coilA,r,d: Area in m² or radius/diameter in m of the calibration coil, define only one