nirfmxvna 26.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nirfmxvna/__init__.py +106 -0
- nirfmxvna/attributes.py +2234 -0
- nirfmxvna/enums.py +1048 -0
- nirfmxvna/errors.py +96 -0
- nirfmxvna/examples/nirfmxvna_calibration_with_calset_save_two_port.py +186 -0
- nirfmxvna/examples/nirfmxvna_pulsed_s_params.py +174 -0
- nirfmxvna/examples/nirfmxvna_s_params_corrected_with_calset_load_two_port_grpc.py +234 -0
- nirfmxvna/examples/nirfmxvna_waves.py +174 -0
- nirfmxvna/grpc_session_options.py +64 -0
- nirfmxvna/internal/_custom_types.py +13 -0
- nirfmxvna/internal/_grpc_stub_interpreter.py +1757 -0
- nirfmxvna/internal/_helper.py +387 -0
- nirfmxvna/internal/_library.py +3790 -0
- nirfmxvna/internal/_library_interpreter.py +3011 -0
- nirfmxvna/internal/_library_singleton.py +53 -0
- nirfmxvna/internal/nidevice_pb2.py +37 -0
- nirfmxvna/internal/nidevice_pb2_grpc.py +3 -0
- nirfmxvna/internal/nirfmxvna_pb2.py +1094 -0
- nirfmxvna/internal/nirfmxvna_pb2_grpc.py +9990 -0
- nirfmxvna/internal/session_pb2.py +33 -0
- nirfmxvna/internal/session_pb2_grpc.py +3 -0
- nirfmxvna/iq.py +31 -0
- nirfmxvna/iq_configuration.py +290 -0
- nirfmxvna/iq_results.py +108 -0
- nirfmxvna/marker.py +31 -0
- nirfmxvna/marker_configuration.py +429 -0
- nirfmxvna/marker_results.py +168 -0
- nirfmxvna/s_params.py +31 -0
- nirfmxvna/s_params_configuration.py +1656 -0
- nirfmxvna/s_params_results.py +244 -0
- nirfmxvna/vna.py +12920 -0
- nirfmxvna/waves.py +31 -0
- nirfmxvna/waves_configuration.py +1255 -0
- nirfmxvna/waves_results.py +235 -0
- nirfmxvna-26.3.0.dist-info/METADATA +228 -0
- nirfmxvna-26.3.0.dist-info/RECORD +38 -0
- nirfmxvna-26.3.0.dist-info/WHEEL +4 -0
- nirfmxvna-26.3.0.dist-info/licenses/LICENSE +30 -0
nirfmxvna/errors.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""errors.py - Contains error classes and method(s) to handle error."""
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _is_success(code: int) -> bool:
|
|
8
|
+
return code == 0
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _is_error(code: int) -> bool:
|
|
12
|
+
return code < 0
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _is_warning(code: int) -> bool:
|
|
16
|
+
return code > 0
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Error(Exception):
|
|
20
|
+
"""Base error class for RFmx VNA."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, message):
|
|
23
|
+
"""Base error class for RFmx VNA."""
|
|
24
|
+
super(Error, self).__init__(message)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DriverNotInstalledError(Error):
|
|
28
|
+
"""An error due to using this module without the driver runtime installed."""
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""An error due to using this module without the driver runtime installed."""
|
|
32
|
+
super(DriverNotInstalledError, self).__init__("The RFmx VNA runtime could not be loaded. Make sure it is installed and its bitness matches that of your Python interpreter. Please visit http://www.ni.com/downloads/drivers/ to download and install it.") # type: ignore
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DriverTooOldError(Error):
|
|
36
|
+
"""An error due to using this module with an older version of the RFmx VNA driver runtime."""
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
"""An error due to using this module with an older version of the RFmx VNA driver runtime."""
|
|
40
|
+
super(DriverTooOldError, self).__init__("A function was not found in the RFmx VNA runtime. Please visit http://www.ni.com/downloads/drivers/ to download a newer version and install it.") # type: ignore
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class DriverTooNewError(Error):
|
|
44
|
+
"""An error due to the RFmx VNA driver runtime being too new for this module."""
|
|
45
|
+
|
|
46
|
+
def __init__(self):
|
|
47
|
+
"""An error due to the RFmx VNA driver runtime being too new for this module."""
|
|
48
|
+
super(DriverTooNewError, self).__init__("The RFmx VNA runtime returned an unexpected value. This can occur if it is too new for the nirfmxvna Python module. Upgrade the nirfmxvna Python module.") # type: ignore
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class UnsupportedConfigurationError(Error):
|
|
52
|
+
"""An error due to using this module in an usupported platform."""
|
|
53
|
+
|
|
54
|
+
def __init__(self):
|
|
55
|
+
"""An error due to using this module in an usupported platform."""
|
|
56
|
+
super(UnsupportedConfigurationError, self).__init__("System configuration is unsupported: " + platform.architecture()[0] + " " + platform.system()) # type: ignore
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class RpcError(Error):
|
|
60
|
+
"""An error specific to sessions to the NI gRPC Device Server."""
|
|
61
|
+
|
|
62
|
+
def __init__(self, rpc_code, description):
|
|
63
|
+
"""An error specific to sessions to the NI gRPC Device Server."""
|
|
64
|
+
self.rpc_code = rpc_code
|
|
65
|
+
self.description = description
|
|
66
|
+
try:
|
|
67
|
+
import grpc
|
|
68
|
+
|
|
69
|
+
rpc_error = str(grpc.StatusCode(self.rpc_code))
|
|
70
|
+
except Exception:
|
|
71
|
+
rpc_error = str(self.rpc_code)
|
|
72
|
+
super(RpcError, self).__init__(rpc_error + ": " + self.description) # type: ignore
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def handle_error(
|
|
76
|
+
library_interpreter: Any, code: int, ignore_warnings: bool, is_error_handling: bool
|
|
77
|
+
) -> None:
|
|
78
|
+
r"""Helper function for handling errors returned by RFmx VNA Library.
|
|
79
|
+
|
|
80
|
+
It calls back into the LibraryInterpreter to get the corresponding error
|
|
81
|
+
description and raises if necessary.
|
|
82
|
+
"""
|
|
83
|
+
if _is_success(code) or (_is_warning(code) and ignore_warnings):
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
if is_error_handling:
|
|
87
|
+
# The caller is in the midst of error handling and an error occurred.
|
|
88
|
+
# Don't try to get the description or we'll start recursing until the stack overflows.
|
|
89
|
+
description = ""
|
|
90
|
+
else:
|
|
91
|
+
description = library_interpreter.get_error_description(code)
|
|
92
|
+
|
|
93
|
+
if _is_error(code):
|
|
94
|
+
import nirfmxinstr
|
|
95
|
+
|
|
96
|
+
raise nirfmxinstr.RFmxError(code, description) # type: ignore
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RFmx VNA Calibration with Calset Save Two Port Example
|
|
3
|
+
|
|
4
|
+
Steps:
|
|
5
|
+
1. Open a new RFmx session.
|
|
6
|
+
2. Configure Frequency Reference.
|
|
7
|
+
3. Configure sweep settings: Sweep Type, Start Frequency, Stop Frequency, Number of Frequency Points,
|
|
8
|
+
IF Bandwidth, and Power Level and Test Rx Attenuation with different port names.
|
|
9
|
+
4. Select S-Parameter measurement.
|
|
10
|
+
5. Configure Calibration Ports and Calibration Method.
|
|
11
|
+
6. Configure Connector type & vCal Resource Name for each VNA port.
|
|
12
|
+
7. Detect vCal ports connected to the VNA ports.
|
|
13
|
+
8. Initiate Calibration.
|
|
14
|
+
9. Acquire Calibration data after user confirmation.
|
|
15
|
+
10. Save Calibration data.
|
|
16
|
+
11. Save Calset data to a file.
|
|
17
|
+
12. Get Calset Error Terms.
|
|
18
|
+
12a. Calculate Magnitude of Error Terms.
|
|
19
|
+
13. Close RFmx Session.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
import sys
|
|
24
|
+
|
|
25
|
+
import nirfmxinstr
|
|
26
|
+
import nirfmxvna
|
|
27
|
+
import numpy
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def example(resource_name, option_string):
|
|
31
|
+
"""VNA calibration with calset save two port example."""
|
|
32
|
+
# Configuration parameters
|
|
33
|
+
frequency_start = 1e9 # Hz
|
|
34
|
+
frequency_end = 26e9 # Hz
|
|
35
|
+
num_of_frequency_points = 251
|
|
36
|
+
port1_power_level = -10.0 # dBm
|
|
37
|
+
port2_power_level = -10.0 # dBm
|
|
38
|
+
port1_test_receiver_attenuation = 0.0 # dB
|
|
39
|
+
port2_test_receiver_attenuation = 0.0 # dB
|
|
40
|
+
if_bandwidth = 100e3 # Hz
|
|
41
|
+
|
|
42
|
+
frequency_reference_source = "PXI_Clk"
|
|
43
|
+
frequency_reference_frequency = 100e6 # Hz
|
|
44
|
+
|
|
45
|
+
vcal_resource_name = "vCal"
|
|
46
|
+
connector_type = "3.5 mm female"
|
|
47
|
+
calibration_timeout = 100.0 # seconds
|
|
48
|
+
auto_detect_vcal_orientation = True
|
|
49
|
+
vcal_orientation = "PortA:Port1,PortB:Port2"
|
|
50
|
+
|
|
51
|
+
calset_file_path = ""
|
|
52
|
+
timeout = 10.0 # seconds
|
|
53
|
+
|
|
54
|
+
instr_session = None
|
|
55
|
+
vna_signal = None
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# Create a new RFmx Session
|
|
59
|
+
instr_session = nirfmxinstr.Session(resource_name, option_string)
|
|
60
|
+
|
|
61
|
+
# Get VNA signal configuration
|
|
62
|
+
vna_signal = instr_session.get_vna_signal_configuration()
|
|
63
|
+
|
|
64
|
+
instr_session.configure_frequency_reference(
|
|
65
|
+
"", frequency_reference_source, frequency_reference_frequency
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
vna_signal.set_sweep_type("", nirfmxvna.SweepType.LINEAR)
|
|
69
|
+
vna_signal.set_start_frequency("", frequency_start)
|
|
70
|
+
vna_signal.set_stop_frequency("", frequency_end)
|
|
71
|
+
vna_signal.set_number_of_points("", num_of_frequency_points)
|
|
72
|
+
vna_signal.set_if_bandwidth("", if_bandwidth)
|
|
73
|
+
|
|
74
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port1")
|
|
75
|
+
vna_signal.set_power_level(port_selector_string, port1_power_level)
|
|
76
|
+
vna_signal.set_test_receiver_attenuation(
|
|
77
|
+
port_selector_string, port1_test_receiver_attenuation
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port2")
|
|
81
|
+
vna_signal.set_power_level(port_selector_string, port2_power_level)
|
|
82
|
+
vna_signal.set_test_receiver_attenuation(
|
|
83
|
+
port_selector_string, port2_test_receiver_attenuation
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
vna_signal.select_measurements("", nirfmxvna.MeasurementTypes.SPARAMS, False)
|
|
87
|
+
|
|
88
|
+
vna_signal.set_correction_calibration_ports("", ["port1", "port2"])
|
|
89
|
+
vna_signal.set_correction_calibration_method(
|
|
90
|
+
"", nirfmxvna.CorrectionCalibrationMethod.SOLT
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
vna_signal.set_correction_calibration_connector_type("port::all", connector_type)
|
|
94
|
+
vna_signal.set_correction_calibration_calkit_electronic_resource_name(
|
|
95
|
+
"port::all", vcal_resource_name
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if auto_detect_vcal_orientation:
|
|
99
|
+
vna_signal.auto_detect_vcal_orientation("")
|
|
100
|
+
vcal_orientation, error_code = vna_signal.get_correction_calibration_calkit_electronic_orientation(
|
|
101
|
+
""
|
|
102
|
+
)
|
|
103
|
+
print(f"vCal Orientation :{vcal_orientation}")
|
|
104
|
+
else:
|
|
105
|
+
vna_signal.set_correction_calibration_calkit_electronic_orientation(
|
|
106
|
+
"", vcal_orientation
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
vna_signal.calibration_initiate("")
|
|
110
|
+
vna_signal.calibration_acquire("", calibration_timeout)
|
|
111
|
+
vna_signal.calibration_save("", "")
|
|
112
|
+
vna_signal.calset_save_to_file("", "", calset_file_path)
|
|
113
|
+
|
|
114
|
+
# Retrieve error terms
|
|
115
|
+
error_term_identifiers = [
|
|
116
|
+
nirfmxvna.CalErrorTerm.DIRECTIVITY,
|
|
117
|
+
nirfmxvna.CalErrorTerm.SOURCE_MATCH,
|
|
118
|
+
nirfmxvna.CalErrorTerm.REFLECTION_TRACKING,
|
|
119
|
+
nirfmxvna.CalErrorTerm.TRANSMISSION_TRACKING,
|
|
120
|
+
nirfmxvna.CalErrorTerm.LOAD_MATCH,
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
frequency_grid = numpy.empty(0, dtype=numpy.float64)
|
|
124
|
+
frequency_grid = vna_signal.calset_get_frequency_grid(
|
|
125
|
+
"", "", nirfmxvna.CalFrequencyGrid.DIRECTIVITY
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
for error_term_id in error_term_identifiers:
|
|
129
|
+
error_terms_port1 = numpy.empty(len(frequency_grid), dtype=numpy.complex64)
|
|
130
|
+
error_terms_port2 = numpy.empty(len(frequency_grid), dtype=numpy.complex64)
|
|
131
|
+
|
|
132
|
+
error_terms_port1 = vna_signal.calset_get_error_term(
|
|
133
|
+
"", "", error_term_id, "port1", "port2", error_terms_port1
|
|
134
|
+
)
|
|
135
|
+
error_terms_port2 = vna_signal.calset_get_error_term(
|
|
136
|
+
"", "", error_term_id, "port2", "port1", error_terms_port2
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
error_terms = numpy.concatenate((error_terms_port1, error_terms_port2))
|
|
140
|
+
|
|
141
|
+
# Calculate magnitude of error terms
|
|
142
|
+
error_terms_magnitude = 20 * numpy.log10(numpy.abs(error_terms))
|
|
143
|
+
|
|
144
|
+
except Exception as e:
|
|
145
|
+
print(f"Error code: {e}")
|
|
146
|
+
sys.exit(1)
|
|
147
|
+
|
|
148
|
+
finally:
|
|
149
|
+
if vna_signal is not None:
|
|
150
|
+
vna_signal.dispose()
|
|
151
|
+
vna_signal = None
|
|
152
|
+
if instr_session is not None:
|
|
153
|
+
instr_session.close()
|
|
154
|
+
instr_session = None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _parse_args():
|
|
158
|
+
parser = argparse.ArgumentParser(
|
|
159
|
+
description="VNA Calibration with Calset Save Two Port",
|
|
160
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
161
|
+
)
|
|
162
|
+
parser.add_argument(
|
|
163
|
+
"-r",
|
|
164
|
+
"--resource",
|
|
165
|
+
type=str,
|
|
166
|
+
default="VNA",
|
|
167
|
+
help="Resource name of the VNA device",
|
|
168
|
+
)
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"-o",
|
|
171
|
+
"--option-string",
|
|
172
|
+
type=str,
|
|
173
|
+
default="",
|
|
174
|
+
help="Option string",
|
|
175
|
+
)
|
|
176
|
+
return parser.parse_args()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def main():
|
|
180
|
+
"""Main function."""
|
|
181
|
+
args = _parse_args()
|
|
182
|
+
example(args.resource, args.option_string)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
main()
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RFmx VNA Pulsed S-Parameters Example
|
|
3
|
+
|
|
4
|
+
Steps:
|
|
5
|
+
1. Open a new RFmx session.
|
|
6
|
+
2. Configure Frequency Reference.
|
|
7
|
+
3. Configure sweep settings: Sweep Type, Start Frequency, Stop Frequency, Number of Frequency Points,
|
|
8
|
+
IF Bandwidth, and Power Level with different port names.
|
|
9
|
+
4. Configure Pulse Settings.
|
|
10
|
+
5. Configure Averaging.
|
|
11
|
+
6. Select S-Parameter measurement.
|
|
12
|
+
7. Configure number of S-Parameters.
|
|
13
|
+
8. Configure each S-Parameter and format.
|
|
14
|
+
9. Initiate the Measurement.
|
|
15
|
+
10. Read Number of SParams.
|
|
16
|
+
11. Fetch S-Parameter X data.
|
|
17
|
+
12. Fetch S-Parameter Y data for each S-Parameter.
|
|
18
|
+
13. Close RFmx Session.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
import nirfmxinstr
|
|
25
|
+
import nirfmxvna
|
|
26
|
+
import numpy
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def example(resource_name, option_string):
|
|
30
|
+
"""VNA pulsed S-parameters example."""
|
|
31
|
+
# Configuration parameters
|
|
32
|
+
frequency_start = 1e9 # Hz
|
|
33
|
+
frequency_end = 26e9 # Hz
|
|
34
|
+
number_of_frequency_points = 251
|
|
35
|
+
port1_power_level = -10.0 # dBm
|
|
36
|
+
port2_power_level = -10.0 # dBm
|
|
37
|
+
|
|
38
|
+
frequency_reference_source = "PXI_Clk"
|
|
39
|
+
frequency_reference_frequency = 100e6 # Hz
|
|
40
|
+
|
|
41
|
+
number_of_sparams = 4
|
|
42
|
+
sparams_parameters = ["S11", "S12", "S21", "S22"]
|
|
43
|
+
sparams_formats = [
|
|
44
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
45
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
46
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
47
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
pulse_mode_enabled = nirfmxvna.PulseModeEnabled.TRUE
|
|
51
|
+
pulse_period = 1.0e-3 # seconds
|
|
52
|
+
pulse_modulator_delay = 0.0 # seconds
|
|
53
|
+
pulse_modulator_width = 100.0e-6 # seconds
|
|
54
|
+
pulse_acquisition_auto = nirfmxvna.PulseAcquisitionAuto.TRUE
|
|
55
|
+
pulse_acquisition_delay = 20.0e-6 # seconds
|
|
56
|
+
pulse_acquisition_width = 46.65e-6 # seconds
|
|
57
|
+
|
|
58
|
+
averaging_enabled = nirfmxvna.AveragingEnabled.FALSE
|
|
59
|
+
averaging_count = 10
|
|
60
|
+
|
|
61
|
+
timeout = 10.0 # seconds
|
|
62
|
+
|
|
63
|
+
instr_session = None
|
|
64
|
+
vna_signal = None
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
# Create a new RFmx Session
|
|
68
|
+
instr_session = nirfmxinstr.Session(resource_name, option_string)
|
|
69
|
+
|
|
70
|
+
# Get VNA signal configuration
|
|
71
|
+
vna_signal = instr_session.get_vna_signal_configuration()
|
|
72
|
+
|
|
73
|
+
instr_session.configure_frequency_reference(
|
|
74
|
+
"", frequency_reference_source, frequency_reference_frequency
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
vna_signal.set_sweep_type("", nirfmxvna.SweepType.LINEAR)
|
|
78
|
+
vna_signal.set_start_frequency("", frequency_start)
|
|
79
|
+
vna_signal.set_stop_frequency("", frequency_end)
|
|
80
|
+
vna_signal.set_number_of_points("", number_of_frequency_points)
|
|
81
|
+
|
|
82
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port1")
|
|
83
|
+
vna_signal.set_power_level(port_selector_string, port1_power_level)
|
|
84
|
+
|
|
85
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port2")
|
|
86
|
+
vna_signal.set_power_level(port_selector_string, port2_power_level)
|
|
87
|
+
|
|
88
|
+
vna_signal.set_pulse_mode_enabled("", pulse_mode_enabled)
|
|
89
|
+
vna_signal.set_pulse_period("", pulse_period)
|
|
90
|
+
vna_signal.set_pulse_modulator_delay("", pulse_modulator_delay)
|
|
91
|
+
vna_signal.set_pulse_modulator_width("", pulse_modulator_width)
|
|
92
|
+
vna_signal.set_pulse_acquisition_auto("", pulse_acquisition_auto)
|
|
93
|
+
vna_signal.set_pulse_acquisition_delay("", pulse_acquisition_delay)
|
|
94
|
+
vna_signal.set_pulse_acquisition_width("", pulse_acquisition_width)
|
|
95
|
+
|
|
96
|
+
vna_signal.set_averaging_enabled("", averaging_enabled)
|
|
97
|
+
vna_signal.set_averaging_count("", averaging_count)
|
|
98
|
+
|
|
99
|
+
vna_signal.select_measurements("", nirfmxvna.MeasurementTypes.SPARAMS, False)
|
|
100
|
+
|
|
101
|
+
vna_signal.s_params.configuration.set_number_of_s_parameters("", number_of_sparams)
|
|
102
|
+
|
|
103
|
+
for i in range(number_of_sparams):
|
|
104
|
+
sparam_selector_string = nirfmxvna.Vna.build_s_parameter_string("", i)
|
|
105
|
+
vna_signal.s_params.configuration.configure_s_parameter(
|
|
106
|
+
sparam_selector_string, sparams_parameters[i]
|
|
107
|
+
)
|
|
108
|
+
vna_signal.s_params.configuration.set_format(
|
|
109
|
+
sparam_selector_string, sparams_formats[i]
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
vna_signal.initiate("", "")
|
|
113
|
+
|
|
114
|
+
# Retrieve results
|
|
115
|
+
number_of_sparams_result, error_code = vna_signal.s_params.configuration.get_number_of_s_parameters("")
|
|
116
|
+
|
|
117
|
+
sparams_x_data_result, _ = vna_signal.s_params.results.fetch_x_data("", timeout)
|
|
118
|
+
|
|
119
|
+
sparams_y1_data_result = []
|
|
120
|
+
sparams_y2_data_result = []
|
|
121
|
+
|
|
122
|
+
for i in range(number_of_sparams_result):
|
|
123
|
+
sparam_selector_string = nirfmxvna.Vna.build_s_parameter_string("", i)
|
|
124
|
+
|
|
125
|
+
y1_data, y2_data, error_code = vna_signal.s_params.results.fetch_y_data(
|
|
126
|
+
sparam_selector_string, timeout
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
sparams_y1_data_result.append(y1_data)
|
|
130
|
+
sparams_y2_data_result.append(y2_data)
|
|
131
|
+
|
|
132
|
+
except Exception as e:
|
|
133
|
+
print(f"Error occurred: {e}")
|
|
134
|
+
sys.exit(1)
|
|
135
|
+
|
|
136
|
+
finally:
|
|
137
|
+
if vna_signal is not None:
|
|
138
|
+
vna_signal.dispose()
|
|
139
|
+
vna_signal = None
|
|
140
|
+
if instr_session is not None:
|
|
141
|
+
instr_session.close()
|
|
142
|
+
instr_session = None
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _parse_args():
|
|
146
|
+
parser = argparse.ArgumentParser(
|
|
147
|
+
description="VNA Pulsed S-Parameters Example",
|
|
148
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
149
|
+
)
|
|
150
|
+
parser.add_argument(
|
|
151
|
+
"-r",
|
|
152
|
+
"--resource",
|
|
153
|
+
type=str,
|
|
154
|
+
default="VNA",
|
|
155
|
+
help="Resource name of the VNA device",
|
|
156
|
+
)
|
|
157
|
+
parser.add_argument(
|
|
158
|
+
"-o",
|
|
159
|
+
"--option-string",
|
|
160
|
+
type=str,
|
|
161
|
+
default="",
|
|
162
|
+
help="Option string",
|
|
163
|
+
)
|
|
164
|
+
return parser.parse_args()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def main():
|
|
168
|
+
"""Main function."""
|
|
169
|
+
args = _parse_args()
|
|
170
|
+
example(args.resource, args.option_string)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if __name__ == "__main__":
|
|
174
|
+
main()
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
r"""Getting Started:
|
|
2
|
+
|
|
3
|
+
To run this example, install "RFmx VNA" on the server machine:
|
|
4
|
+
https://www.ni.com/en-us/support/downloads/software-products/download.rfmx-vna.html
|
|
5
|
+
|
|
6
|
+
Download and run the NI gRPC Device Server (ni_grpc_device_server.exe) on the server machine:
|
|
7
|
+
https://github.com/ni/grpc-device/releases
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Running from command line:
|
|
11
|
+
|
|
12
|
+
Server machine's IP address, port number, resource name and options can be passed as separate
|
|
13
|
+
command line arguments.
|
|
14
|
+
|
|
15
|
+
> python nirfmxvna_s_params_corrected_with_calset_load_two_port_grpc.py <server_address> <port_number> <resource_name> <options>
|
|
16
|
+
|
|
17
|
+
If they are not passed in as command line arguments, then by default the server address will be
|
|
18
|
+
"localhost:31763", with "VNA" as the resource name and empty option string.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
r"""RFmx VNA S-Parameters Corrected with Calset Load Two Port gRPC Example
|
|
22
|
+
|
|
23
|
+
Steps:
|
|
24
|
+
1. Open a new RFmx session.
|
|
25
|
+
2. Configure Frequency Reference.
|
|
26
|
+
3. Configure sweep settings: Frequency List, IF Bandwidth, and Power Level and Test Rx Attenuation
|
|
27
|
+
with different port names.
|
|
28
|
+
4. Select S-Parameter measurement.
|
|
29
|
+
5. Configure number of S-Parameters.
|
|
30
|
+
6. Configure each S-Parameter and format.
|
|
31
|
+
7. Configure Magnitude Units & Phase Trace Type.
|
|
32
|
+
8. Load Calset data from a file.
|
|
33
|
+
9. Enable Correction.
|
|
34
|
+
10. Initiate the Measurement after user confirmation.
|
|
35
|
+
11. Read Number of SParams.
|
|
36
|
+
12. Fetch S-Parameter Correction State.
|
|
37
|
+
13. Fetch S-Parameter X data.
|
|
38
|
+
14. Fetch S-Parameter Y data for each S-Parameter.
|
|
39
|
+
15. Set SnP Export attributes (can be accessed and written before or after measurement initiate)
|
|
40
|
+
and save S-Parameter data to file.
|
|
41
|
+
16. Close RFmx Session.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
import argparse
|
|
45
|
+
import sys
|
|
46
|
+
|
|
47
|
+
import grpc
|
|
48
|
+
import nirfmxinstr
|
|
49
|
+
import nirfmxvna
|
|
50
|
+
import numpy
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def example(server_name, port, resource_name, option_string):
|
|
54
|
+
"""Run VNA S-Parameters Corrected with Calset Load Two Port gRPC Example."""
|
|
55
|
+
# Configuration parameters
|
|
56
|
+
sweep_type = nirfmxvna.SweepType.LINEAR
|
|
57
|
+
frequency_list_size = 251
|
|
58
|
+
frequency_start = 1e9 # Hz
|
|
59
|
+
frequency_stop = 26e9 # Hz
|
|
60
|
+
|
|
61
|
+
port1_power_level = -10.0 # dBm
|
|
62
|
+
port2_power_level = -10.0 # dBm
|
|
63
|
+
port1_test_receiver_attenuation = 0.0 # dB
|
|
64
|
+
port2_test_receiver_attenuation = 0.0 # dB
|
|
65
|
+
if_bandwidth = 100e3 # Hz
|
|
66
|
+
|
|
67
|
+
frequency_reference_source = "PXI_Clk"
|
|
68
|
+
frequency_reference_frequency = 100e6 # Hz
|
|
69
|
+
|
|
70
|
+
number_of_sparams = 4
|
|
71
|
+
sparams_parameters = ["S11", "S12", "S21", "S22"]
|
|
72
|
+
sparams_formats = [
|
|
73
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
74
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
75
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
76
|
+
nirfmxvna.SParamsFormat.MAGNITUDE,
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
magnitude_units = nirfmxvna.SParamsMagnitudeUnits.DB
|
|
80
|
+
phase_trace_type = nirfmxvna.SParamsPhaseTraceType.WRAPPED
|
|
81
|
+
|
|
82
|
+
calset_file_path = ""
|
|
83
|
+
snp_file_path = ""
|
|
84
|
+
|
|
85
|
+
timeout = 10.0 # seconds
|
|
86
|
+
|
|
87
|
+
instr_session = None
|
|
88
|
+
vna_signal = None
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
# Create a new RFmx gRPC Session
|
|
92
|
+
channel = grpc.insecure_channel(
|
|
93
|
+
f"{server_name}:{port}",
|
|
94
|
+
options=[
|
|
95
|
+
("grpc.max_receive_message_length", -1),
|
|
96
|
+
("grpc.max_send_message_length", -1),
|
|
97
|
+
],
|
|
98
|
+
)
|
|
99
|
+
grpc_options = nirfmxinstr.GrpcSessionOptions(channel, "Remote_VNA_Session")
|
|
100
|
+
|
|
101
|
+
# Create a new RFmx Session
|
|
102
|
+
instr_session = nirfmxinstr.Session(
|
|
103
|
+
resource_name, option_string, grpc_options=grpc_options
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Get VNA signal configuration
|
|
107
|
+
vna_signal = instr_session.get_vna_signal_configuration()
|
|
108
|
+
|
|
109
|
+
instr_session.configure_frequency_reference(
|
|
110
|
+
"", frequency_reference_source, frequency_reference_frequency
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
vna_signal.set_sweep_type("", sweep_type)
|
|
114
|
+
vna_signal.set_start_frequency("", frequency_start)
|
|
115
|
+
vna_signal.set_stop_frequency("", frequency_stop)
|
|
116
|
+
vna_signal.set_number_of_points("", frequency_list_size)
|
|
117
|
+
vna_signal.set_if_bandwidth("", if_bandwidth)
|
|
118
|
+
|
|
119
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port1")
|
|
120
|
+
vna_signal.set_power_level(port_selector_string, port1_power_level)
|
|
121
|
+
vna_signal.set_test_receiver_attenuation(
|
|
122
|
+
port_selector_string, port1_test_receiver_attenuation
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
port_selector_string = nirfmxvna.Vna.build_port_string("", "port2")
|
|
126
|
+
vna_signal.set_power_level(port_selector_string, port2_power_level)
|
|
127
|
+
vna_signal.set_test_receiver_attenuation(
|
|
128
|
+
port_selector_string, port2_test_receiver_attenuation
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
vna_signal.select_measurements("", nirfmxvna.MeasurementTypes.SPARAMS, False)
|
|
132
|
+
|
|
133
|
+
vna_signal.s_params.configuration.set_number_of_s_parameters("", number_of_sparams)
|
|
134
|
+
|
|
135
|
+
for i in range(number_of_sparams):
|
|
136
|
+
sparam_selector_string = nirfmxvna.Vna.build_s_parameter_string("", i)
|
|
137
|
+
vna_signal.s_params.configuration.configure_s_parameter(
|
|
138
|
+
sparam_selector_string, sparams_parameters[i]
|
|
139
|
+
)
|
|
140
|
+
vna_signal.s_params.configuration.set_format(
|
|
141
|
+
sparam_selector_string, sparams_formats[i]
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
vna_signal.s_params.configuration.set_magnitude_units("", magnitude_units)
|
|
145
|
+
vna_signal.s_params.configuration.set_phase_trace_type("", phase_trace_type)
|
|
146
|
+
|
|
147
|
+
vna_signal.calset_load_from_file("", "", calset_file_path)
|
|
148
|
+
|
|
149
|
+
vna_signal.set_correction_enabled("", nirfmxvna.CorrectionEnabled.TRUE)
|
|
150
|
+
vna_signal.initiate("", "")
|
|
151
|
+
|
|
152
|
+
# Retrieve results
|
|
153
|
+
number_of_sparams_result, error_code = vna_signal.s_params.configuration.get_number_of_s_parameters("")
|
|
154
|
+
|
|
155
|
+
correction_state_result, error_code = vna_signal.s_params.results.get_correction_state("")
|
|
156
|
+
|
|
157
|
+
sparams_x_data_result, _ = vna_signal.s_params.results.fetch_x_data("", timeout)
|
|
158
|
+
|
|
159
|
+
sparams_y1_data_result = []
|
|
160
|
+
sparams_y2_data_result = []
|
|
161
|
+
|
|
162
|
+
for i in range(number_of_sparams_result):
|
|
163
|
+
sparam_selector_string = nirfmxvna.Vna.build_s_parameter_string("", i)
|
|
164
|
+
|
|
165
|
+
y1_data, y2_data, error_code = vna_signal.s_params.results.fetch_y_data(
|
|
166
|
+
sparam_selector_string, timeout
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
sparams_y1_data_result.append(y1_data)
|
|
170
|
+
sparams_y2_data_result.append(y2_data)
|
|
171
|
+
|
|
172
|
+
vna_signal.s_params.configuration.set_snp_data_format(
|
|
173
|
+
"", nirfmxvna.SParamsSnPDataFormat.AUTO
|
|
174
|
+
)
|
|
175
|
+
vna_signal.s_params.configuration.set_snp_ports("", "port1,port2")
|
|
176
|
+
vna_signal.s_params.configuration.export_to_snp_file("", snp_file_path)
|
|
177
|
+
|
|
178
|
+
except Exception as e:
|
|
179
|
+
print(f"Error occurred: {e}")
|
|
180
|
+
sys.exit(1)
|
|
181
|
+
|
|
182
|
+
finally:
|
|
183
|
+
if vna_signal is not None:
|
|
184
|
+
vna_signal.dispose()
|
|
185
|
+
vna_signal = None
|
|
186
|
+
if instr_session is not None:
|
|
187
|
+
instr_session.close()
|
|
188
|
+
instr_session = None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _parse_args():
|
|
192
|
+
parser = argparse.ArgumentParser(
|
|
193
|
+
description="VNA S-Parameters Corrected with Calset Load Two Port gRPC Example",
|
|
194
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
195
|
+
)
|
|
196
|
+
parser.add_argument(
|
|
197
|
+
"-s",
|
|
198
|
+
"--server-address",
|
|
199
|
+
type=str,
|
|
200
|
+
default="localhost",
|
|
201
|
+
help="Server address",
|
|
202
|
+
)
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
"-p",
|
|
205
|
+
"--port",
|
|
206
|
+
type=str,
|
|
207
|
+
default="31763",
|
|
208
|
+
help="Server port",
|
|
209
|
+
)
|
|
210
|
+
parser.add_argument(
|
|
211
|
+
"-r",
|
|
212
|
+
"--resource",
|
|
213
|
+
type=str,
|
|
214
|
+
default="VNA",
|
|
215
|
+
help="Resource name of the VNA device",
|
|
216
|
+
)
|
|
217
|
+
parser.add_argument(
|
|
218
|
+
"-o",
|
|
219
|
+
"--option-string",
|
|
220
|
+
type=str,
|
|
221
|
+
default="",
|
|
222
|
+
help="Option string",
|
|
223
|
+
)
|
|
224
|
+
return parser.parse_args()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def main():
|
|
228
|
+
"""Main function."""
|
|
229
|
+
args = _parse_args()
|
|
230
|
+
example(args.server_address, args.port, args.resource, args.option_string)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
if __name__ == "__main__":
|
|
234
|
+
main()
|