Comments (7)
I very much appreciate the thoughts. I've spent most of the day thinking about this and I think its an important thing to try to get right as early as possible.
I am inclined to give it a try focusing on Agilent 2-port PNAs (where should the 'instrument class' lines be drawn?). Perhaps I can ask for your further thoughts when I have a working model system.
from scikit-rf.
Sounds good, I'm happy for that.
Sure. I have a PNA-X (N5247A) and an 8753 I can try things out on at some point too.
from scikit-rf.
i dont follow your psuedo code exactly, but i think i get the idea.
there are a lot of subtle issues i have run into with instruments, like timing, need to cache large get's, non-uniformity of commands between vendors, etc. but the current state of drivers is mostly ad-hoc and i think a refactoring would increase the uniformity, thereby removing a lot of wasted code.
there is also an annoying hack in skrf for python-ivi
. i added python-ivi
so that VI's could be used over TCP/IP, and because pyvisa broke backwards compatibility at one point.
if someone wants to attack this beast, i would recommend looking at the lantz project. they put a lot of effort into solving many generic VI problems.
from scikit-rf.
@Helgrind taking your comments to heart I decided to try to think about what your driver architechture proposal would look like, and I'm at a point where I think further comment would be useful. If nothing else this was a fun exercise.
I went through the initial simplified driver I created for qt apps and extracted all of the SCPI commands. I then looked at the keysight command tree and wrote out the command in its read/write form with optional variables. Then, I had to give it a short name for the dict key. I wrote a short SCPI preprocessor that could accept kwargs for the various SCPI arguments and treat them accordingly.
My first question is does this start to look like what you were thinking, or did you have something totally different in mind regarding SCPI commands for an instrument class?
The value in this as I see it is that it (possibly) creates a simpler syntax for the most common commands. The problem is that to use it correctly requires either:
- people to know the syntax of the instrument specific SCPI (in which case, why not just use SCPI directly) (although to your it allows you to edit individual scpi commands only one time when needed which then propagate to the rest of the driver, I can see the value in that)
- it requires people to learn a new API (use 'channel', instead of 'cnum' or 'format' instead of 'char', just for this project. I assume that is the purpose of efforts like IVI, that unfortunately haven't hung on tight enough keep their momentum going in the Python world.
As per @arsenovic suggestion to learn LabPy, I haven't considered that at this point, as I don't want to spend a ton of time on this aspect while there are a lot of things left to do on the qtapps.
For now, any comments about the value of an SCPI pre-processor versus something else you had in mind would be appreciated. Code is below:
import re
SCPI_COMMANDS = {
# "key": "pre-SCPI command"
"data": ":CALCulate<cnum>:DATA <char>,<data>",
"create_meas": ":CALCulate<cnum>:PARameter:DEFine:EXTended <'mname'>,<'param'>",
"delete_meas": ":CALCulate<cnum>:PARameter:DELete <'mname'>",
"meas_format": ":CALCulate<cnum>:FORMat <char>",
"meas_name_list": ":CALCulate<cnum>:PARameter:CAT:EXT",
"select_meas_by_num": ":CALCulate<cnum>:PARameter:MNUM:SEL <mnum>",
"select_meas_by_name": ":CALCulate<cnum>:PARameter:SELect <'name'>",
"snp_data": ":CALCulate<cnum>:DATA:SNP:PORTs <'ports'>",
"display_trace": ":DISPlay:WINDow<wnum>:TRACe<tnum>:FEED <'name'>",
"averaging_count": ":SENSe<cnum>:AVERage:COUNt <num>",
"averaging_state": ":SENSe<cnum>:AVERage:STATe <onoff>",
"start_frequency": ":SENSe<cnum>:FREQuency:STARt <num>",
"stop_frequency": ":SENSe<cnum>:FREQuency:STOP <num>",
"groups_count": ":SENSe<cnum>:SWEep:GROups:COUNt <num>",
"sweep_mode": ":SENSe<cnum>:SWEep:MODE <char>",
"sweep_time": ":SENSe<cnum>:SWEep:TIME <num>",
"sweep_type": ":SENSe<cnum>:SWEep:TYPE <char>",
"sweep_points": ":SENSE<cnum>:SWEep:POINts <num>",
"available_channels": ":SYSTem:CHANnels:CATalog",
"active_channel": ":SYSTem:ACTive:CHANnel",
"meas_name_from_number": ":SYSTem:MEASurement<n>:NAME",
"meas_number_list": ":SYSTem:MEASurement:CATalog? <cnum>",
"trigger_source": ":TRIGger:SOURce <char>",
}
cmd_pattern = re.compile('<(\w+)>', re.ASCII)
arg_pattern = re.compile('<([\'"]?\w+[\'"]?)>', re.ASCII)
kwarg_pattern = re.compile('[\'"]?(\w+)[\'"]?', re.ASCII)
def preprocess_scpi(command, **kwargs):
base_command = SCPI_COMMANDS[command].split(" ")
cmd = base_command[0]
if len(base_command) > 1:
args = base_command[1]
else:
args = ""
split_command = cmd_pattern.split(cmd)
for i in range(1, len(split_command), 2):
split_command[i] = str(kwargs.get(split_command[i], ""))
scpi_command = "".join(split_command)
split_args = arg_pattern.findall(args)
new_args = []
for i, arg in enumerate(split_args):
kwarg = kwarg_pattern.search(arg).group(1)
value = kwargs.get(kwarg, "")
if value:
if type(value) in (list, tuple):
value = ",".join(map(str, value))
new_args.append(arg.replace(kwarg, str(value)))
scpi_args = ",".join(new_args)
return scpi_command, scpi_args
def write(command, **kwargs):
scpi_string = " ".join(preprocess_scpi(command, **kwargs)).strip()
# resource.write(scpi_string)
print(scpi_string)
def query(command, **kwargs):
scpi_string = "? ".join(preprocess_scpi(command, **kwargs)).strip()
# return resource.query(scpi_string)
print(scpi_string)
write("create_meas", cnum=1, mname="CH1_S11_1", param="S11")
>>> :CALCulate1:PARameter:DEFine:EXTended 'CH1_S11_1','S11'
query("active_channel")
>>> :SYSTem:ACTive:CHANnel?
query("snp_data", cnum=1, ports=(1,2))
>>> :CALCulate1:DATA:SNP:PORTs? '1,2'
from scikit-rf.
#97 has been initiated
@Helgrind I followed your suggestions and went down the rabbit hole. In the qtapps/skrf_qtwidgets/analyzers directory there is now a keysight_pna package defining a class for these modern analyzers. I have created 2 child drivers that simply modify the visa_addresses and the number of ports. They both seem to work without further modification.
There are some example notebooks in the ..analyzers/driver development subdirectory that test the main functions for the qtapps. I would be curious if they work out of the box with your equipment
The sweep triggering still needs some work, as things can get a little complicated if more than one channel or averaging in point mode is turned on. I try to auto-calculate the full sweep time, but its not complete yet.
Everything else seems to be working quite well. I'm curious if you can fire up the data_grabber.py and acquire data from your instrument.
from scikit-rf.
Hi David,
Thanks for taking my comments into consideration, and implementation! They stemmed from seeing application level code which used explicit SCPI commands. I thought that it would better to abstract those in case different instruments used different command sets. For example, some VNAs set frequency in response not source, etc. If explicit SCPI commands are required at the application level, then there should also be a function from the interface class (to use my example) which allows a custom command or query to be run. It should also be possible to directly inherit from an identical instrument for the purposes of creating a new named driver for another model. For example, PNA-X might inherit from PNA, and then could add some changes to the dictionary or more commands or override a standard VNA method or implement a new method.
I'm afraid I won't have much time to look through code or test at the moment (I feel bad about this but I have lots of work on, also our VNAs are broken at the moment :'( ).
As far as an SCPI preprocessor, I think this is required for embedded values to work. Surely users don't have to work with cnum etc in the main code, just in the SCPI command in the driver file. The preprocessor can replace that term with whatever variable scikit-rf currently uses?
from scikit-rf.
New architecture pathway has been decided, probably time to close this and push ahead with the direction we are on.
from scikit-rf.
Related Issues (20)
- Renumbering network should update port names HOT 2
- skrf.Network.read_zipped_touchstone misses filenames in zip archive
- Error with NanoVNA if frequency npoints = 1 HOT 2
- Replace simple DFFT by Chirp Z transform for higher resolution in Time domain processing HOT 2
- About COM_receiver_noise_filter HOT 1
- network_2_spreadsheet doesn't scale frequency with units
- About Circuit voltages HOT 4
- Test failing to capture warning HOT 3
- Improve Time Domain Gating technique ? HOT 3
- IEEEP370 example: import problem from skrf.calibration. HOT 6
- TouchStone with complex reference impedance does not renormalize correctly HOT 3
- network.concat_ports do not update port_modes HOT 1
- Network.plot_z_time_step() ignore port references with different impedances HOT 4
- Y axis label wanished from plot in master
- Network.delay() swap ports when nports == 2
- Weird result when de-embedding bad transmission line using IEEEP370_SE_ZC_2XThru HOT 8
- Touchstone 2.0 format does not seem to work for [Matrix Format] Upper HOT 20
- ynp file type support HOT 1
- error in the def load_file(self, fid: typing.TextIO) HOT 2
- Unexpected behavior in Circuit with network ports not explicitly connected HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scikit-rf.