Example_Spectrum_FSWP50
This is an example of using the library.
1# %% ==========================================================================
2# Import and Definitions
3# =============================================================================
4import datetime
5import time
6
7import matplotlib.pyplot as plt
8import numpy as np
9import pandas as pd
10from tqdm import tqdm
11
12# Instrument Libraries Github: https://github.com/MartinMiroslavovMihaylov/Python_Instruments_Automation_Scripts
13# Install with:
14# pip install git+https://github.com/MartinMiroslavovMihaylov/Python_Instruments_Automation_Scripts.git
15from Instruments_Libraries.FSWP50 import FSWP50 # SpectrumAnalyzer
16
17# from Instruments_Libraries.InstrumentSelect import FSWP50
18
19# %% ==========================================================================
20# Select Instruments and Load Instrument Libraries
21# =============================================================================
22mySpecAnalyser = FSWP50("169.254.253.126") # using class directly # noqa: N816
23# mySpecAnalyser = FSWP50() # using InstrumentSelect # noqa: N816
24mySpecAnalyser.reset()
25
26# %% ==========================================================================
27# Setup the Measurement
28# =============================================================================
29num_of_points = 10
30sleep_time = 1 # in seconds
31freq = np.linspace(1e9, 40e9, num_of_points)
32
33# Initial Spectrum Analyzer Sweep Settings
34SA_RMS_TraceNum = 1
35SA_POS_TraceNum = 2
36SA_f_min = 0
37SA_f_max = 40e9
38SA_resBW = 100e3
39SA_ref_level = -10 # dBm
40datapoints = 4001
41
42# %% ==========================================================================
43# Configure the Instrument
44# =============================================================================
45mySpecAnalyser.create_channel('SANALYZER', 'Spectrum') # Create Spectrum Channel
46mySpecAnalyser.delete_channel('Phase Noise') # Delete Phase Noise Channel
47mySpecAnalyser.set_continuous('ON') # Set Continuous Mode
48mySpecAnalyser.set_start_frequency(SA_f_min)
49mySpecAnalyser.set_stop_frequency(SA_f_max)
50mySpecAnalyser.set_resolution_bandwidth(SA_resBW)
51mySpecAnalyser.set_reference_level(SA_ref_level)
52mySpecAnalyser.set_sweep_points(datapoints) # Set Number of Data Points
53mySpecAnalyser.set_input_attenuation_auto("OFF") # Disable Auto Input Attenuation
54mySpecAnalyser.set_input_attenuation(0) # Set Input Attenuation
55# Trace 1: RMS
56mySpecAnalyser.set_detector_mode("RMS", trace_number=SA_RMS_TraceNum)
57# Trace 2: Positive
58mySpecAnalyser.set_detector_mode("POSITIVE", trace_number=SA_POS_TraceNum)
59mySpecAnalyser.set_trace_mode("WRITE", trace_number=SA_POS_TraceNum) # turn it on
60
61
62# %% ==========================================================================
63# Measurement
64# =============================================================================
65
66records = [] # Empty list to store data and meta data
67for idx in tqdm(range(num_of_points)):
68 rec = {} # single record
69
70 # Do some changes, like change input frequency
71 # SignalGenerator.set_freq_CW(freq[idx])
72 temp = idx*np.pi # do something with idx
73
74 # Write Meta Data
75 rec["SA f_min"] = SA_f_min
76 rec["SA f_max"] = SA_f_max
77 rec["SA ref level"] = SA_ref_level
78 rec["SA Resolution BW"] = SA_resBW
79
80 # Take the Measurement
81 time.sleep(sleep_time)
82 rec["data_rms"] = mySpecAnalyser.measure_and_get_trace(
83 trace_number=SA_RMS_TraceNum, window_number=1)
84 rec["data_pos"] = mySpecAnalyser.measure_and_get_trace(
85 trace_number=SA_POS_TraceNum, window_number=1)
86
87 # append the record
88 rec["Timestamps"] = datetime.datetime.now()
89 records.append(rec)
90
91
92# %% ==========================================================================
93# Create Dataframe
94# =============================================================================
95meas_df = pd.DataFrame.from_records(records)
96
97# %% ==========================================================================
98# Plot the Measurement
99# =============================================================================
100freq_hz = np.linspace(SA_f_min, SA_f_max, datapoints)
101power_pos_dBm = np.vstack(meas_df["data_pos"]) # noqa: N816
102power_rms_dBm = np.vstack(meas_df["data_rms"]) # noqa: N816
103
104fig, ax = plt.subplots(figsize=(5, 4), layout='constrained')
105ax.plot(freq_hz/1e9, power_pos_dBm[0], label="Positive")
106ax.plot(freq_hz/1e9, power_rms_dBm[0], label="RMS")
107# Formatting
108ax.set_xlabel('Frequency (GHz)', fontsize=14, fontweight='bold')
109ax.set_ylabel('Power (dBm)', fontsize=14, fontweight='bold')
110ax.grid(True, which='both', linestyle='--')
111ax.legend(fontsize=14)
112ax.tick_params(axis='both', labelsize=12)
113for tick in ax.get_xticklabels() + ax.get_yticklabels():
114 tick.set_fontweight("bold")
115plt.show()
116# %% ==========================================================================
117# Save Dataframe
118# =============================================================================
119# Save DataFrame to HDF5 (better than CSV)
120meas_df.to_hdf("measurements.h5", key="data", mode="w")
121# key="data" is like a "dataset name" inside the HDF5 file
122# (you can store multiple DataFrames in one file with different keys).
123# mode="w" overwrites the file. Use mode="a" if you want to append new datasets.
124
125# Later: Load it back
126loaded_df = pd.read_hdf("measurements.h5", key="data")
127print(loaded_df.head())
128
129#or
130
131# Save DataFrame to CSV
132meas_df.to_csv("measurements.csv", index=False)
133
134# Load it back, auto-parsing the "Timestamps" column as datetime
135loaded_df = pd.read_csv("measurements.csv", parse_dates=["Timestamps"])
136print(loaded_df.head())
137
138# %% ==========================================================================
139# Close Instrument
140# =============================================================================
141mySpecAnalyser.Close()