NAME
RF::Component - Compose RF component circuits and calculate values from objects (L, C, ESR, etc).
SYNOPSIS
This module builds on PDL::IO::Touchstone by encapsulating data returned by its methods into an object for easy use:
my $cap = RF::Component->load('/path/to/capacitor.s2p', $options);
my $wilky = RF::Component->load('/path/to/wilkinson.s3p', $options);
# port 1 input impedances
my $z_in = $cap->port_z(1);
# Capacitance in pF:
my $pF = $cap->capacitance() * 1e12
my $S11 = $cap->S(1,1);
my $Y21 = $cap->Y(2,1);
my $Z33 = $wilky->Z(3,3);
# Write a Y-parameter .s2p in mag/angle format::
$cap->save("cap-y.s2p", param_type => 'Y', output_fmt => 'MA');
In most cases, the return value from the RF::Component methods are PDL vectors, typically one value per frequency. For example, $pF
as shown above will be a N-vector of values in picofarads, with one pF value for each frequency.
Constructor
The RF::Component->load
function (below) is typically used to load RF data, but you may pass it directly to the constructor as follows. Most of these options are valid for RF::Component->load
as well:
my $c = RF::Component->new(%opts);
Required:
freqs
: a PDL vector, one for each frequency in Hz.z0_ref
: A value representing the charectaristic impedance at each port. If port impedances differ, then this may be a vectorn_ports
: the number of ports represented by the port parameter matrix(es):At least one (N,N,M) PDL element where N is the number of ports and M is the number of frequencies to represent complex port-parameter data:
Optional:
comments
: An arrayref of comments read fromload
filename
: The filename read byload
output_fmt
: The .sNp output format: one of DB, MA, or RIThis is the format originally read in by
$self->load
.orig_f_unit
: The original frequency unit from the .sNp fileThis is the frequency format originally read in by
$self->load
: kHz, MHz, GHz, THz, ...filename
: The filename read byload
model
: Component model numbervalue_code_regex
: Regular expression to parse the exponent-value codeSpecifies the variable to be assigned and a regular expression to match the capacitance code (or other unit): NNX or NRN. X is the exponent, N is a numeric value.
If a capacitor code is 111 then it will calculate 11*10^1 == 110 pF. A code of 1N4 or 14N would be 1.4 or 14.0, respectively. The unit 'pF' in the example is excluded from the code. Example:
MODEL-(...).s2p
The above (...) must match the code (or literal) to be placed in the MDF variable.
value_literal_regex
: Regular expression to parse the literal valueThe "literal" version is the same as
value_code_regex
but does not calcualte the code, it takes the value verbatim. For example, some inductors specify the number of turns in their s2p filename:MODEL-([0-9]+)T\.s2p
value
: Component valueThe component value is parsed based on
value_code_regex
orvalue_literal_regex
value_unit
: Unit of the value (pF, nH, etc).This is the unit expected in
value
afer parsingvalue_code_regex
. Supported units: pF|nF|uF|uH|nH|R|Ohm|Ohmsvars
: A hashref of variable=value.This is an opaque variables structure. Currently it is used for vars defined in an MDIF file.
You may also pass the above new
options to the load call:
my $cap = RF::Component->load('/path/to/capacitor.s2p', %options);
IO Functions
RF::Component->load
- Load an RF data file as a component
$cap = RF::Component->load($filename, %new_options);
Arguments:
$filename: the path to the data file you wish to load
%new_options: a hash of options passed to
RF::Component->new
as listed above, except the optionload_options
:load()
supports the special optionload_options
. Ifload_options
is specified then it is passed to the loading function such asPDL::IO::Touchstone::rsnp()
.
This function loads the data based on the file extension, however, only .sNp touchstone files are supported at this time. See the rsnp() documentation in PDL::IO::Touchstone for specific details about $options
.
RF::Component->load_snp
- Load a Touchstone data file as a component
This is the lower-level function called by RF::Component->load
. This function is functionally equivalent but does not evaluate the file extension being passed before calling PDL::IO::Touchstone::rsnp()
:
$cap = RF::Component->load_snp($filename, %new_options);
RF::Component->save
- Write the component to a data file
$cap->save('cap.s2p', %options);
This function will match based on the output file extension and call the appropriate save_* function below. The %options
hash will depend on the desired file output type.
RF::Component->save_snp
- Write the component to a Touchstone data file
$cap->save_snp('cap.s2p', %options);
param_type
: Supported paramter type: S, Y, Z, ANotice: While A can be specified to write ABCD-formatted parameters, the ABCD matrix is not officially supported by the Touchstone spec.
output_f_unit
: The .sNp file's frequency unit.This defaults to Hz, but supports SI units such as: KHZ, MHz, GHz, ...
output_fmt
: See above, same as innew()
.
RF::Component->save_snp_fh
- Write the component to a file descriptor
Same as save_snp
but writes to a file handle:
$cap->save_snp_fh(*STDOUT, %options);
Calculation Functions
Unless otherwise indicated, the return value from these methods are PDL vectors, typically one value per frequency. For example, $pF
as shown above will be a N-vector of values in picofarads, with one pF value for each frequency.
$self->at($f_Hz)
- Frequency extrapolation (object cloning)
It is importatant to easily choose which frequencies will be used for calculations because the functions below return vectors with values at each frequency for the calculation provided. In many cases you will want to load a Touchstone data file at all frequencies and then use $obj->at($f_Hz)
to reduce or extrapolate to a different frequency or set of freqencies.
Each call to $obj->at($f_Hz)
will return a new RF::Component
object as follows:
$cap = RF::Component->load('my.s2p');
# Picofarads at 100 MHz (100e6 Hz).
$pF = $cap->at(100e6)->capacitance * 1e12;
# Reactance at 100 MHz and 200 MHz:
$X = $cap->at('100e6, 200e6')->reactance;
# ESR at 1-10 GHz with 20 samples (500 MHz each):
$esr = $cap->at('1e9 - 10e9 x20');
# ESR at 1-10 GHz stepping 500 MHz with 20 samples
# (same as the previous above, but different notation)
$esr = $cap->at('1e9 += 500e6 x20');
Notes:
Each resulting value is a PDL vector containing one value per evaluated frequency.
Internally the
$obj->at($f_Hz)
function uses PDL::IO::Touchstone'sm_interpolate
function so you can use any syntax available tom_interpolate
.The
$obj->at($f_Hz)
call caches the resulting interpolated object to prevent repeated extrapolation at the same frequency set. Because of this the$obj->at($f_Hz)
call only supports scalar ranges either using a single frequency or the quoted range feature shown above and in PDL::IO::Touchstone'sm_interpolate
function.If no range is specified then the original object is returned:
return $self if !length($range);
$z0n = $self->port_z($n)
- Return the complex port impedance vector for each frequency
$n
is the port number at which to evaluate the input impedance:
In a 2-port, this will provide the input or output impedance as follows:
$z_in = $self->port_z(1);
$z_out = $self->port_z(2);
Note that the port number starts at 1, not zero. Thus a value of $n=1
will evaluate port impedance at S11
.
Internally this function uses the IO::PDL::Touchstone s_port_z
function.
$C = $self->capacitance
- Return a vector of capacitance for each frequency in Farads (F)
Note that all inductive values are zeroed.
Internally this function uses the IO::PDL::Touchstone y_capacitance
function.
$C = $self->cap_pF
- Return a vector of capacitance it each frequency in picofarads (pF)
Note that all capacitive values are zeroed.
Internally this function uses the IO::PDL::Touchstone y_cap_pF
function.
$L = $self->inductance
- Return a vector of inductance for each frequency in Henrys (H)
Internally this function uses the IO::PDL::Touchstone y_inductance
function.
$L = $self->ind_nH
- Return a vector of inductance for each frequency in nanohenrys (nH)
Internally this function uses the IO::PDL::Touchstone y_ind_nH
function.
$Qc = $self->qfactor_c
- Return the capacitive Q-factor vector for each frequency
Internally this function uses the IO::PDL::Touchstone y_qfactor_c
function.
$Ql = $self->qfactor_l
- Return the inductive Q-factor vector for each frequency
Internally this function uses the IO::PDL::Touchstone y_qfactor_l
function.
$X = $self->reactance
- Return a vector of total reactance for each frequency
Internally this function uses the IO::PDL::Touchstone y_reactance
function.
$Xc = $self->reactance_c
- Return a vector of capacitive reactance for each frequency
Internally this function uses the IO::PDL::Touchstone y_reactance_c
function.
$Xl = $self->reactance_l
- Return a vector of inductive reactance for each frequency
Internally this function uses the IO::PDL::Touchstone y_reactance_l
function.
$R = $self->esr
- An alias for y_resistance
.
Internally this function uses the IO::PDL::Touchstone y_esr
function.
@srf_list_hz = $self->srf
- Return the component's self-resonant frequencies (SRF)
To calculate SRF, reactance is evaluated at each frequency. If the next frequency being evaulated has an opposite sign (ie, going from capacitive to inductive reactance) then that previous frequency is selected as an SRF.
Return value:
List context: Return the list of SRF's in ascending order, or an empty list if no SRF is found.
Scalar context: Return the lowest-frequency SRF, or undef if no SRF is found.
Internally this function uses the IO::PDL::Touchstone y_srf
function.
$f_hz = $self->srf_ideal
- Return the component's first self-resonant frequency
Notice: In almost all cases you will want $self->srf
instead of $self->srf_ideal
.
This is included for ideal Y-matrices only and may not be accurate. While the equation is a classic SRF calculation (1/(2*pi*sqrt(LC)), SRF should scan the frequency lines as follows: "The SRF is determined to be the frequency at which the insertion (S21) phase changes from negative through zero to positive." [ https://www.coilcraft.com/getmedia/8ef1bd18-d092-40e8-a3c8-929bec6adfc9/doc363_measuringsrf.pdf ]
Internally this function uses the IO::PDL::Touchstone y_srf_ideal
function.
Parameter Matrix and Vector Functions
$n = $self->freqs
- return a PDL vector of each frequency.
$self->S($i, $j)
- Access the S-parameter matrix or index slices.
If $i
and $j
are specified, then return a PDL vector S_i,j
index slice at each frequency. The vector will contain one value for each frequency. For example:
my $S11 = $self->S(1,1);
If you omit $i
and $j
then this returns a (N,N,M) piddle where N is the number of ports and M is the number of frequencies.
$self->Y($i, $j)
- Access the Y-parameter matrix or index slices.
Same as $self->S($i, $j)
, but for a Y-paramater matrix, see above. Even if a Y-parameter data file was not loaded, Y-parameters will be calculated for you.
$self->Z($i, $j)
- Access the Z-parameter matrix or index slices.
Same as $self->S($i, $j)
, but for a Z-paramater matrix, see above. Even if a Z-parameter data file was not loaded, Z-parameters will be calculated for you.
$self->ABCD($i, $j)
- Access the ABCD-parameter matrix or index slices.
Same as $self->S($i, $j)
, but for a ABCD-paramater matrix, see above. Even if a ABCD-parameter data file was not loaded, ABCD-parameters will be calculated for you.
$self->A()
- Return the A vector from the ABCD matrix.
Same as $self->ABCD(1,1)
, returns a vector for A values at each frequency.
$self->B()
- Return the B vector from the ABCD matrix.
Same as $self->ABCD(1,2)
, returns a vector for B values at each frequency.
$self->C()
- Return the C vector from the ABCD matrix.
Same as $self->ABCD(2,1)
, returns a vector for C values at each frequency.
$self->D()
- Return the D vector from the ABCD matrix.
Same as $self->ABCD(2,2)
, returns a vector for D values at each frequency.
Helper Functions
$n = $self->num_ports
- return the number of ports in this component.
$n = $self->num_freqs
- return the number of frequencies in this component.
@wsnp_list = $self->get_wsnp_list(%opts)
- return a list for passing to wsnp()
Options:
param_type
- One of S, Y, or Z. The matrix returned in the list will be converted to the requested type (or an error will be thrown).output_f_unit
- Same as wsnp's$to_hz
valueoutput_fmt
- Same as wsnp's$fmt
value
The get_wsnp_list method returns a list compatible with PDL::IO::Touchstone's wsnp($filename, @wsnp_list)
function, which writes a .sNp file. It is also the list format used internally for MDIFs in RF::Component::Multi.
SEE ALSO
- PDL::IO::Touchstone - The lower-level framework used by RF::Component
- RF::Component::Multi - A list-encapsulation of RF::Component to provide vectorized operations on multiple components. This allows you to open MDIF files in a classful-way.
- PDL::IO::MDIF - Load MDIF files
- Touchstone specification: https://ibis.org/connector/touchstone_spec11.pdf
AUTHOR
Originally written at eWheeler, Inc. dba Linux Global Eric Wheeler to transform .s2p files and build MDF files to optimize with Microwave Office for amplifer impedance matches.
COPYRIGHT
Copyright (C) 2022 eWheeler, Inc. https://www.linuxglobal.com/
This module is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this module. If not, see <http://www.gnu.org/licenses/>.