-
Notifications
You must be signed in to change notification settings - Fork 30
/
spice3read.py
121 lines (100 loc) · 4.55 KB
/
spice3read.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import struct
import re
import numpy as np
import collections
def split(plotDat):
""" Converts each of the arrays in plotDat into 2-D arrays
where the first index corresponds to the parameter being swept.
"""
sweep = plotDat[plotDat.keys()[0]]
splitPos = np.argwhere(sweep == sweep[0])
nSplits = len(splitPos)
plotDatSplit = collections.OrderedDict()
keys = plotDat.keys()
splitPtr = 0;
splitPos = np.append(splitPos, len(sweep))
for key in keys:
plotDatSplit[key] = np.zeros((nSplits, len(plotDat[key])/ nSplits))
for splitPtr in range(nSplits):
plotDatSplit[key][splitPtr] = plotDat[key][splitPos[splitPtr]:splitPos[splitPtr + 1]]
return plotDatSplit
def read(fileName, simulator="ngspice"):
""" Reads a SPICE3RAW file and stores the data. Returns an ordered
dictionary containing 2D arrays of simulated data. 2D arrays are used in
case the simulation is parametric.
Arguments:
filename : A valid SPICE3 rawfile
"""
rawFile = open(fileName, 'rb')
dataBytes = rawFile.read()
dataStr = str(dataBytes)
simStarts = [m.start() for m in re.finditer('Title', dataStr)]
plotDat = collections.OrderedDict()
for startPtr in simStarts:
flagStart = dataBytes.find(b'Flags: ', startPtr) + len('Flags: ')
flags = dataBytes[flagStart:flagStart+4].decode()
if flags == 'real':
# Extract the number of variables
startPos = dataBytes.find(b'No. Variables: ', startPtr) + len('No. Variables: ')
endPos = dataBytes.find(b'No. Points:', startPtr)
numVars = int(dataBytes[startPos:endPos].decode())
#Extract the number of points
startPos = endPos + len('No. Points: ')
endPos = dataBytes.find(b'Variables:', startPos)
numPoints = int(dataBytes[startPos:endPos].decode())
#Extract variable names
tmpPos = dataBytes.find(b'Variables:')
startPos = dataBytes.find(b'Variables:', tmpPos + len('Variables')) + len('Variables:')
endPos = dataBytes.find(b'Binary:\n')
varData = str(dataBytes[startPos:endPos]).replace('\t', ' ').strip()
varLines = varData.split('\n')
varList = [line.strip().split()[1] for line in varLines]
if (simulator == "ngspice"):
# Create arrays to store the points
for j in range(numVars):
plotDat[varList[j]] = np.zeros(numPoints)
# Populate the arrays
bytePtr = endPos + len('Binary:\n')
for j in range(numPoints):
for k in plotDat.keys():
plotDat[k][j] = struct.unpack('d', dataBytes[bytePtr:bytePtr+8])[0]
bytePtr += 8
elif (simulator == "spectre"):
headerEnds = [m.start() for m in re.finditer('Binary:\n', dataStr)]
for j in range(numVars):
plotDat[varList[j]] = np.zeros(numPoints*len(headerEnds))
sweepIter = 0
for endPos in headerEnds:
bytePtr = endPos + len('Binary:\n')
for j in range(numPoints):
for k in plotDat.keys():
plotDat[k][j + sweepIter*numPoints] = struct.unpack('d', dataBytes[bytePtr:bytePtr+8][::-1])[0]
bytePtr += 8
sweepIter += 1
# Assuming that the data file always contains parametric data for now
#if (isParametric):
# return split(plotDat)
#else:
# return plotDat
rawFile.close()
#return plotDat
return split(plotDat)
def getVars(plotDat):
""" Returns the list of variable names and their units, i.e. the indices
for the ordered dictionaries that read generates.
"""
return plotDat.keys()
def plot(plotDat, xVar, yVar, color='b'):
""" Plots the specified variables stored in plotDat. If the simulation is
parametric, each of the parametric simulations are plotted.
Arguments:
plotDat - The data generated by the read function
xVar - The variable on the horizontal axis
yVar - The variable on the vertical axis
color - The color of the line plot (defaul blue).
"""
import matplotlib.pyplot as plt
for i in range(np.shape(plotDat[xVar])[0]):
lines = plt.plot(plotDat[xVar][i], plotDat[yVar][i], c=color)
color = lines[0].get_color()
plt.show()