-
-
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: |
@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.
@Wallflower123 your file is an ascii file. This function reads binary files.