-
-
Save snmishra/27dcc624b639c2626137 to your computer and use it in GitHub Desktop.
# MIT license: https://opensource.org/licenses/MIT | |
# See https://github.com/Isotel/mixedsim/blob/master/python/ngspice_read.py | |
# for a more complete library. Isotel's version is GPL licensed | |
from __future__ import division | |
import numpy as np | |
BSIZE_SP = 512 # Max size of a line of data; we don't want to read the | |
# whole file to find a line, in case file does not have | |
# expected structure. | |
MDATA_LIST = [b'title', b'date', b'plotname', b'flags', b'no. variables', | |
b'no. points', b'dimensions', b'command', b'option'] | |
def rawread(fname: str): | |
"""Read ngspice binary raw files. Return tuple of the data, and the | |
plot metadata. The dtype of the data contains field names. This is | |
not very robust yet, and only supports ngspice. | |
>>> darr, mdata = rawread('test.py') | |
>>> darr.dtype.names | |
>>> plot(np.real(darr['frequency']), np.abs(darr['v(out)'])) | |
""" | |
# Example header of raw file | |
# Title: rc band pass example circuit | |
# Date: Sun Feb 21 11:29:14 2016 | |
# Plotname: AC Analysis | |
# Flags: complex | |
# No. Variables: 3 | |
# No. Points: 41 | |
# Variables: | |
# 0 frequency frequency grid=3 | |
# 1 v(out) voltage | |
# 2 v(in) voltage | |
# Binary: | |
fp = open(fname, 'rb') | |
count = 0 | |
arrs = [] | |
plots = [] | |
plot = {} | |
while (True): | |
try: | |
mdata = fp.readline(BSIZE_SP).split(b':', maxsplit=1) | |
except: | |
raise | |
if len(mdata) == 2: | |
if mdata[0].lower() in MDATA_LIST: | |
plot[mdata[0].lower()] = mdata[1].strip() | |
if mdata[0].lower() == b'variables': | |
nvars = int(plot[b'no. variables']) | |
npoints = int(plot[b'no. points']) | |
plot['varnames'] = [] | |
plot['varunits'] = [] | |
for varn in range(nvars): | |
varspec = (fp.readline(BSIZE_SP).strip() | |
.decode('ascii').split()) | |
assert(varn == int(varspec[0])) | |
plot['varnames'].append(varspec[1]) | |
plot['varunits'].append(varspec[2]) | |
if mdata[0].lower() == b'binary': | |
rowdtype = np.dtype({'names': plot['varnames'], | |
'formats': [np.complex_ if b'complex' | |
in plot[b'flags'] | |
else np.float_]*nvars}) | |
# We should have all the metadata by now | |
arrs.append(np.fromfile(fp, dtype=rowdtype, count=npoints)) | |
plots.append(plot) | |
plot = {} # reset the plot dict | |
fp.readline() # Read to the end of line | |
else: | |
break | |
return (arrs, plots) | |
if __name__ == '__main__': | |
arrs, plots = rawread('test.raw') | |
print(arrs) | |
# Local Variables: | |
# mode: python | |
# End: |
@Wallflower123, I'm not sure what you're trying to do and what your error is. It works for my original purpose.
@snmishra I am trying to read my NgSpice raw files with a python script. When using this function I get empty arrays...
@Wallflower123 I'm sorry I can't debug without some indication of the error. Please give me a test file and the actual error message.
@snmishra How can I share my rawfile with you, so you can test this code on it?
@Wallflower123 You could use Dropbox/Google Drive type of service. Or you can even use https://repl.it/ and share the workspace here.
@snmishra here is the link to my rawfile https://drive.google.com/file/d/1EnU957azRsE2wb6104zDAbEgj9OtQT6C/view?usp=sharing
and this is the corresponding netlist https://drive.google.com/file/d/18KNtQ3UtaA3uBZFd9btIq6UYGGeTFOpk/view?usp=sharing
@Wallflower123 your file is an ascii file. This function reads binary files.
@snmishra, Oh I'm sorry I did not pay attention to that. This is the command I use to run my netlist with ngspice in batch mode with python subprocess library:
subprocess.run([path_to_ngspice_executable,'-r','rawfile.raw','-b','-i',my_netlist]), what am I supposed to add to the command so as to specify that my output rawfile ought be in binary format ?
@snmishra Quick update:
I used command: set filetype=binary, right before write command n my .control ... .endc environemment and it generated the rawfile in Binary format!! Tried your code and it worked. Thank you so much for your time!!
@Wallflower123 glad it worked for you
@snmishra I tried to read a raw fine with your script, its saying 'darr' is not defined. Can you please check what i am missing. Thank you in advance.
My raw file is here: https://drive.google.com/file/d/1DcJxw6DgDOpg9klCZNHNzeG3kVLIFDTS/view?usp=sharing
@Varat7v2 Looks there was a typo. I changed print(darr)
to print(arrs)
@snmishra Thank you I changed it. However, it is showing empty array. Is there any mistake in the raw file that I have generated? It is automatically exported from the LTSpice software.
Works really well out of the box. Thank you very much!
Thanks @cardosorapha
For plotting, I needed a small change --
"""Read ngspice binary raw files. Return tuple of the data, and the
plot metadata. The dtype of the data contains field names. This is
not very robust yet, and only supports ngspice.
>>> darr, mdata = rawread('test.py')
>>> darr.dtype.names
>>> plot(np.real(darr[0]['frequency']), np.abs(darr[0]['v(out)']))
"""
Very useful, thanks!
There's a small bug occuring when the rawfile contains more than one plot.
The plot
dictionary is shared between all plots. A new dict should be allocated (plot = {}
) after line 63.
Very useful, thanks!
There's a small bug occuring when the rawfile contains more than one plot. The
plot
dictionary is shared between all plots. A new dict should be allocated (plot = {}
) after line 63.
@jmspiewak Thanks. Fixed.
That's not quite right, unfortunately.
Now the plot dict is reset between each line, instead of between separate plots.
@jmspiewak How about now?
That's exactly it, thanks.
Hello,
This function does not run for me....