File indexing completed on 2024-10-13 06:30:12

0001 #!/usr/bin/env python3
0002 import numpy as np
0003 BSIZE_SP = 512 # Max size of a line of data; we don't want to read the
0004                # whole file to find a line, in case file does not have
0005                # expected structure.
0006 MDATA_LIST = [b'title', b'date', b'plotname', b'flags', b'no. variables',
0007               b'no. points', b'dimensions', b'command', b'option']
0008 
0009 def rawread(fname: str):
0010     """Read ngspice binary raw files. Return tuple of the data, and the
0011     plot metadata. The dtype of the data contains field names. This is
0012     not very robust yet, and only supports ngspice.
0013     >>> darr, mdata = rawread('test.py')
0014     >>> darr.dtype.names
0015     >>> plot(np.real(darr['frequency']), np.abs(darr['v(out)']))
0016     """
0017     # Example header of raw file
0018     # Title: rc band pass example circuit
0019     # Date: Sun Feb 21 11:29:14  2016
0020     # Plotname: AC Analysis
0021     # Flags: complex
0022     # No. Variables: 3
0023     # No. Points: 41
0024     # Variables:
0025     #         0       frequency       frequency       grid=3
0026     #         1       v(out)  voltage
0027     #         2       v(in)   voltage
0028     # Binary:
0029     fp = open(fname, 'rb')
0030     plot = {}
0031     count = 0
0032     arrs = []
0033     plots = []
0034     while (True):
0035         try:
0036             mdata = fp.readline(BSIZE_SP).split(b':', maxsplit=1)
0037         except:
0038             raise
0039         if len(mdata) == 2:
0040             if mdata[0].lower() in MDATA_LIST:
0041                 plot[mdata[0].lower()] = mdata[1].strip()
0042             if mdata[0].lower() == b'variables':
0043                 nvars = int(plot[b'no. variables'])
0044                 npoints = int(plot[b'no. points'])
0045                 plot['varnames'] = []
0046                 plot['varunits'] = []
0047                 for varn in range(nvars):
0048                     varspec = (fp.readline(BSIZE_SP).strip()
0049                                .decode('ascii').split())
0050                     assert(varn == int(varspec[0]))
0051                     plot['varnames'].append(varspec[1])
0052                     plot['varunits'].append(varspec[2])
0053             if mdata[0].lower() == b'binary':
0054                 rowdtype = np.dtype({'names': plot['varnames'],
0055                                      'formats': [np.complex_ if b'complex'
0056                                                  in plot[b'flags']
0057                                                  else np.float_]*nvars})
0058                 # We should have all the metadata by now
0059                 arrs.append(np.fromfile(fp, dtype=rowdtype, count=npoints))
0060                 plots.append(plot)
0061                 fp.readline() # Read to the end of line
0062         else:
0063             break
0064     return (arrs, plots)
0065 
0066 if __name__ == '__main__':
0067     arrs, plots = rawread('data/ac_binary.raw')
0068     print(arrs)