Skip to content

Commit f7bd4bb

Browse files
committed
Add RFNetwork block migrated from pathsim core
1 parent 85840f6 commit f7bd4bb

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies = [
2929
"pathsim>0.13",
3030
"numpy>=1.15",
3131
"scipy>=1.2",
32+
"scikit-rf>=0.30",
3233
]
3334

3435
[project.optional-dependencies]

src/pathsim_rf/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@
1111
__version__ = "unknown"
1212

1313
__all__ = ["__version__"]
14+
15+
from .network import *

src/pathsim_rf/network.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#########################################################################################
2+
##
3+
## RF Network Block
4+
##
5+
#########################################################################################
6+
7+
# IMPORTS ===============================================================================
8+
9+
from __future__ import annotations
10+
11+
import numpy as np
12+
13+
from inspect import signature
14+
from pathlib import Path
15+
16+
import skrf as rf
17+
18+
from pathsim.blocks.lti import StateSpace
19+
20+
# BLOCKS ================================================================================
21+
22+
class RFNetwork(StateSpace):
23+
"""N-port RF network linear time invariant (LTI) MIMO state-space model.
24+
25+
Uses Vector Fitting for rational approximation of the frequency response
26+
using poles and residues. The resulting approximation has guaranteed stable
27+
poles that are real or come in complex conjugate pairs.
28+
29+
Assumes N inputs and N outputs, where N is the number of ports of the
30+
RF network.
31+
32+
Parameters
33+
----------
34+
ntwk : :py:class:`~skrf.network.Network`, str, or Path
35+
scikit-rf RF Network object, or file to load information from.
36+
Supported formats are touchstone file V1 (.s?p) or V2 (.ts).
37+
auto_fit : bool
38+
If True (default), use ``skrf.VectorFitting.auto_fit`` for automatic
39+
pole selection. If False, use ``skrf.VectorFitting.vector_fit``.
40+
**kwargs
41+
Additional keyword arguments forwarded to the vector fitting function.
42+
43+
References
44+
----------
45+
.. [skrf] scikit-rf webpage https://scikit-rf.org/
46+
"""
47+
48+
def __init__(self, ntwk: rf.Network | str | Path, auto_fit: bool = True, **kwargs):
49+
50+
if isinstance(ntwk, (Path, str)):
51+
ntwk = rf.Network(ntwk)
52+
53+
# select the vector fitting function from scikit-rf
54+
vf_fun_name = "auto_fit" if auto_fit else "vector_fit"
55+
vf_fun = getattr(rf.VectorFitting, vf_fun_name)
56+
57+
# filter kwargs for the selected vf function
58+
vf_fun_keys = signature(vf_fun).parameters
59+
vf_kwargs = {k: v for k, v in kwargs.items() if k in vf_fun_keys}
60+
61+
# apply vector fitting
62+
vf = rf.VectorFitting(ntwk)
63+
getattr(vf, vf_fun_name)(**vf_kwargs)
64+
A, B, C, D, _ = vf._get_ABCDE()
65+
66+
# keep a copy of the network and VF
67+
self.network = ntwk
68+
self.vf = vf
69+
70+
super().__init__(A, B, C, D)
71+
72+
def s(self, freqs: np.ndarray) -> np.ndarray:
73+
"""S-matrix of the vector fitted N-port model from its state-space representation.
74+
75+
Parameters
76+
----------
77+
freqs : :py:class:`~numpy.ndarray`
78+
Frequencies (in Hz) at which to calculate the S-matrices.
79+
80+
Returns
81+
-------
82+
s : :py:class:`~numpy.ndarray`
83+
Complex-valued S-matrices (fxNxN) calculated at frequencies ``freqs``.
84+
"""
85+
return rf.VectorFitting._get_s_from_ABCDE(
86+
freqs, self.A, self.B, self.C, self.D, 0
87+
)

0 commit comments

Comments
 (0)