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 Hz
1.0 - 0.0im
julia> tf(1e4) # Value of tf at f = 10000 Hz
0.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. 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; # 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
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 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.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 TransferFunction
freq::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,data
can 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