Examples

For more examples, visit our Rohde & Schwarz Github repository.

"""Getting started - how to work with RsSmw Python package.
This example performs basic RF settings on an SMW200A instrument.
It shows the RsSmw calls and their corresponding SCPI commands.
Notice that the python RsSmw interfaces track the SCPI commands syntax."""

from RsSmw import *

# Open the session
smw = RsSmw('TCPIP::10.102.52.47::HISLIP')
# Greetings, stranger...
print(f'Hello, I am: {smw.utilities.idn_string}')

# Print commands to the console with the logger
smw.utilities.logger.mode = LoggingMode.On
smw.utilities.logger.log_to_console = True

#   OUTPut1:STATe ON
smw.output.state.set_value(True)

#   SOURce1:FREQuency:MODE CW
smw.source.frequency.set_mode(enums.FreqMode.CW)

#   SOURce1:POWer:LEVel:IMMediate:AMPLitude -20
smw.source.power.level.immediate.set_amplitude(-20)

#   SOURce1:FREQuency:FIXed 223000000
smw.source.frequency.fixed.set_value(223E6)

#         SOURce1:POWer:PEP?
pep = smw.source.power.get_pep()
print(f'Channel 1 PEP level: {pep} dBm')

# Change the output to B (default is A):
smw.repcap_hwInstance_set(repcap.HwInstance.InstB)

# Now we are addressing output B
#   OUTPut2:STATe ON
smw.output.state.set_value(True)

#         SOURce2:POWer:PEP?
pep = smw.source.power.get_pep()
print(f'Channel 2 PEP level: {pep} dBm')

# Close the session
smw.close()
from RsSmw import *

RsSmw.assert_minimum_version('5.0.44')
smw = RsSmw('TCPIP::10.102.52.42::HISLIP')
# smw = RsSmw('TCPIP::10.112.1.179::5025::SOCKET', options='SelectVisa=SocketIo') # No VISA needed
print(f'Driver Info: {smw.utilities.driver_version}')
print(f'Instrument: {smw.utilities.idn_string}')

# Instrument options are properly parsed duplicates are removed, and the items are sorted (k-options first)
print(f'Instrument options: {",".join(smw.utilities.instrument_options)}')

# Driver's instrument status checking ( SYST:ERR? ) after each command (default value is True):
smw.utilities.instrument_status_checking = True

# The smw object uses the global HW instance one - RF out A
smw.repcap_hwInstance_set(repcap.HwInstance.InstA)

# Clone the smw object to the smw_rf2 and select the RF out B
smw_rf2 = smw.clone()
smw_rf2.repcap_hwInstance_set(repcap.HwInstance.InstB)

# Now we have two independent objects for two RF Outputs - smw and smw_rf2
# They share some common features of the instrument, like for example resetting
smw_rf2.utilities.reset()

smw.output.state.set_value(True)
smw.source.frequency.set_mode(enums.FreqMode.CW)
smw.source.power.level.immediate.set_amplitude(-20)
smw.source.frequency.fixed.set_value(223E6)
print(f'Channel 1 PEP level: {smw.source.power.get_pep()} dBm')

smw_rf2.output.state.set_value(False)
smw_rf2.source.frequency.set_mode(enums.FreqMode.SWEep)
smw_rf2.source.power.level.immediate.set_amplitude(-35)
smw_rf2.source.frequency.set_start(800E6)
smw_rf2.source.frequency.set_stop(900E6)
smw_rf2.source.frequency.step.set_mode(enums.FreqStepMode.DECimal)
smw_rf2.source.frequency.step.set_increment(10E6)
print(f'Channel 2 PEP level: {smw_rf2.source.power.get_pep()} dBm')

# Direct SCPI interface:
response = smw.utilities.query_str('*IDN?')
print(f'Direct SCPI response on *IDN?: {response}')
smw.close()
"""The example:
 - creates waveform file from a csv-file with I/Q pairs
 - sends the file to the SMW instrument
 - activates the waveform on Output 1
 You have the option of auto-scaling the samples to the full range
"""

import numpy as np
from RsSmw import *

RsSmw.assert_minimum_version('5.0.44')
smw = RsSmw('TCPIP::10.102.52.47::HISLIP')
print(smw.utilities.idn_string)
smw.utilities.reset()

pc_csv_file = r'c:\temp\arbFileExample.csv'
pc_wv_file = r'c:\temp\arbFileExample.wv'
instr_wv_file = '/var/user/InstrDemoFile.wv'

# Skip this part if you have a csv-file available

# Samples clock
clock_freq = 600e6
# wave clock
wave_freq = 120e6
# Scale factor - change it to less or more than 1 if you want to see the autoscaling capability of the create_waveform_file...() methods
scale_factor = 0.43
time_vector = np.arange(0, 50 / wave_freq, 1 / clock_freq)
# I-component an Q-component data
i_data = np.cos(2 * np.pi * wave_freq * time_vector) * scale_factor
q_data = np.sin(2 * np.pi * wave_freq * time_vector) * scale_factor

with open(pc_csv_file, 'w') as file:
    for x in range(len(i_data)):
        file.write(f'{i_data[x]},{q_data[x]}\n')

# Take that csv-file with the IQ-samples and create a wv file
result = smw.arb_files.create_waveform_file_from_samples_file(pc_csv_file, pc_wv_file, clock_freq=100E6, auto_scale=False, comment='Created from a csv file')
print(result)

# Send to the instrument
smw.arb_files.send_waveform_file_to_instrument(pc_wv_file, instr_wv_file)

# Selecting the waveform and load it in ARB
smw.source.bb.arbitrary.waveform.set_select(instr_wv_file)

# Turning on the ARB baseband
smw.source.bb.arbitrary.set_state(True)

# Turning on the state of RF-A
smw.output.state.set_value(True)

smw.close()
"""The example:
 - creates waveform file from two i_data and q_data vectors
 - sends the file to the SMW instrument
 - activates the waveform on Output A
 - creates waveform file from those same two vectors, but i_data is swapped for q_data
 - activates the waveform on Output B
 You have the option of auto-scaling the samples to the full range
 The example auto-scales the Output B signal, the Output A signal is left as generated
"""

import numpy as np
from RsSmw import *

RsSmw.assert_minimum_version('5.0.44')
smw = RsSmw('TCPIP::10.102.52.47::HISLIP')
print(smw.utilities.idn_string)
smw.utilities.reset()

pc_wv_file = r'c:\temp\arbFileExample.wv'
instr_wv_file_outA = '/var/user/InstrDemoFile_outA.wv'
instr_wv_file_outB = '/var/user/InstrDemoFile_outB.wv'

# Creating the I/Q vectors as lists: i_data / q_data
# Samples clock
clock_freq = 600e6
# wave clock
wave_freq = 120e6
# Scale factor - change it to less or more than 1 if you want to see the autoscaling capability of the create_waveform_file...() methods
scale_factor = 0.8
time_vector = np.arange(0, 50 / wave_freq, 1 / clock_freq)
# I-component an Q-component data
i_data = np.cos(2 * np.pi * wave_freq * time_vector) * scale_factor
q_data = np.sin(2 * np.pi * wave_freq * time_vector) * scale_factor

# Take those samples and create a wv file, send it to the instrument with the name instr_wv_file_outA (not auto-scaled)
result = smw.arb_files.create_waveform_file_from_samples(i_data, q_data, pc_wv_file, clock_freq=100E6, auto_scale=False, comment='Created from I/Q vectors')
smw.arb_files.send_waveform_file_to_instrument(pc_wv_file, instr_wv_file_outA)
# Take those swapped samples and create another wv file, send it to the instrument with the name instr_wv_file_outB (auto-scaled to full range)
result = smw.arb_files.create_waveform_file_from_samples(q_data, i_data, pc_wv_file, clock_freq=100E6, auto_scale=True, comment='Created from swapped Q/I vectors')
smw.arb_files.send_waveform_file_to_instrument(pc_wv_file, instr_wv_file_outB)

# Selecting the waveform and load it in ARB for Output A
smw.source.bb.arbitrary.waveform.set_select(instr_wv_file_outA)
smw.source.frequency.set_frequency(1.1E9)
smw.source.power.level.immediate.set_amplitude(-11.1)
# Turning on the ARB baseband A
smw.source.bb.arbitrary.set_state(True)
# Turning on the state of RF-A
smw.output.state.set_value(True)

# Creating a clone for Output B
smwB = smw.clone()
smwB.repcap_hwInstance_set(repcap.HwInstance.InstB)

# Selecting the waveform and load it in ARB for Output B
smwB.source.bb.arbitrary.waveform.set_select(instr_wv_file_outB)
smwB.source.frequency.set_frequency(2.2E9)
smwB.source.power.level.immediate.set_amplitude(-22.2)
# Turning on the ARB baseband B
smwB.source.bb.arbitrary.set_state(True)
# Turning on the state of RF-B
smwB.output.state.set_value(True)

smw.close()
# This example shows how to work with commands that have many repeated capabilities (numeric suffixes)
# The example does not demonstrate any valid instrument settings, rather the instrument driver general rules of working with the repeated capabilities

from RsSmw import *

RsSmw.assert_minimum_version('5.0.44')
smw = RsSmw('TCPIP::10.102.52.47::HISLIP', True, True)
print(f'Driver Info: {smw.utilities.driver_version}')
print(f'Instrument: {smw.utilities.idn_string}')

# The smw object addresses the RF Output A - SCPI command header 'SOURCE1'
smw.repcap_hwInstance_set(repcap.HwInstance.InstA)

# Switching the error checking off to avoid errors from invalid parameter settings
smw.utilities.instrument_status_checking = False

smw.source.bb.nr5G.set_state(True)

# Setting commands with many repeated capabilities:
# [SOURce<HW>]:BB:NR5G:SCHed:CELL<CH>:SUBF<ST>:USER:BWPart:ALLoc:APMap:COL<S2US>:ROW<S3US>:IMAGinary

# Option 1: explicit definition:
# sending SOURce1:BB:NR5G:SCHed:CELL1:SUBF3:USER0:BWPart1:ALLoc0:APMap:COL0:ROW3:IMAGinary 10.0
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.row.imaginary.set(10.0, repcap.CellNull.Nr1, repcap.SubframeNull.Nr3, repcap.UserNull.Nr0, repcap.BwPartNull.Nr1, repcap.AllocationNull.Nr0, repcap.ColumnNull.Nr0, repcap.RowNull.Nr3)

# Option 2: only some arguments with keywords, others keep their default values:
# sending SOURce1:BB:NR5G:SCHed:CELL1:SUBF3:USER0:BWPart1:ALLoc0:APMap:COL0:ROW3:IMAGinary 10.0
# Default values for skipped repCaps:
# - repcap.UserNull.Nr0
# - repcap.Allocation.Nr0
# - repcap.ColumnNull.Nr0
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.row.imaginary.set(10.0, cellNull=repcap.CellNull.Nr1, subframeNull=repcap.SubframeNull.Nr3, bwPartNull=repcap.BwPartNull.Nr1, rowNull=repcap.RowNull.Nr3)

# Option 3: default values are set in the group interfaces, and then left to default in the method call:
smw.source.bb.nr5G.scheduling.cell.repcap_cellNull_set(repcap.CellNull.Nr1)
smw.source.bb.nr5G.scheduling.cell.subf.repcap_subframeNull_set(repcap.SubframeNull.Nr3)
smw.source.bb.nr5G.scheduling.cell.subf.user.repcap_userNull_set(repcap.UserNull.Nr0)
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.repcap_bwPartNull_set(repcap.BwPartNull.Nr1)
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.repcap_allocationNull_set(repcap.AllocationNull.Nr0)
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.repcap_columnNull_set(repcap.ColumnNull.Nr0)
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.row.repcap_rowNull_set(repcap.RowNull.Nr3)
# and then just use the set() method without repeated capabilities:
# sending SOURce1:BB:NR5G:SCHed:CELL1:SUBF3:USER0:BWPart1:ALLoc0:APMap:COL0:ROW3:IMAGinary 10.0
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.row.imaginary.set(10.0)

# We can clone the cell interface and change the default cell from Nr1 to Nr2 without affecting the origin interface:
cell_nr2 = smw.source.bb.nr5G.scheduling.cell.clone()
cell_nr2.repcap_cellNull_set(repcap.CellNull.Nr2)

# Now we have an independent object cell_nr2, and can set the same command for cell Nr2
# All other repcap default values are the same:
# repcap.SubframeNull.Nr3
# repcap.ColumnNull.Nr2
# repcap.RowNull.Nr3
# sending SOURce1:BB:NR5G:SCHed:CELL2:SUBF3:USER:BWPart:ALLoc:APMap:COL2:ROW3:IMAGinary 10.0
cell_nr2.subf.user.bwPart.alloc.apMap.col.row.imaginary.set(10.0)

# Option 4: Combination of Options 1, 2 and 3 - we use the default values from the group interfaces and explicitly define some of them:
# Here we change the channel to 5 and Column to 4, all others are default from the group
# sending SOURce1:BB:NR5G:SCHed:CELL5:SUBF3:USER:BWPart:ALLoc:APMap:COL4:ROW3:IMAGinary 10.0
smw.source.bb.nr5G.scheduling.cell.subf.user.bwPart.alloc.apMap.col.row.imaginary.set(10.0, cellNull=repcap.CellNull.Nr5, columnNull=repcap.ColumnNull.Nr4)

smw.close()
"""Example showing how you can transfer a big file to the instrument and from the instrument with showing the progress.
Since the SMW is quite fast on data transfer, we slow it down by waiting for 100ms between each chunk transfer (1MB)
This way we see the transfer progress better and we do not need a file that is so big - let's take cca 20MB.
For big files, use the example without the time.sleep(0.1)"""

import time
import numpy as np
from RsSmw import *


def my_transfer_handler(args):
    """Function called each time a chunk of data is transferred"""
    total_size = args.total_size if args.total_size is not None else "unknown"
    print(f"Context: '{args.context}{'with opc' if args.opc_sync else ''}', "
          f"chunk {args.chunk_ix}, "
          f"transferred {args.transferred_size} bytes, "
          f"total size {total_size}, "
          f"direction {'reading' if args.reading else 'writing'}, "
          f"data '{args.data}'")
    if args.end_of_transfer:
        print('End of Transfer')
    # Slow down the transfer by 200ms to see the progress better
    time.sleep(0.1)


RsSmw.assert_minimum_version('5.0.44')
smw = RsSmw('TCPIP::10.102.52.47::HISLIP')
print(smw.utilities.idn_string)
smw.utilities.reset()

pc_file = r'c:\temp\bigFile.bin'
instr_file = '/var/user/bigFileInstr.bin'
pc_file_back = r'c:\temp\bigFileBack.bin'

# Generate a random file of 20MB size
x1mb = 1024 * 1024
with open(pc_file, 'wb') as file:
    for x in range(20):
        file.write(np.random.bytes(x1mb))

# Send the file to the instrument with events
smw.events.on_write_handler = my_transfer_handler
smw.utilities.data_chunk_size = x1mb
print(f'Sending file to the instrument...')
smw.utilities.send_file_from_pc_to_instrument(pc_file, instr_file)
smw.events.on_write_handler = None
print(f'Receiving file from the instrument...')
smw.events.on_read_handler = my_transfer_handler
smw.utilities.read_file_from_instrument_to_pc(instr_file, pc_file_back)
smw.events.on_read_handler = None
smw.close()