import sympy import numpy as np __all__ = [ 'read_ltspice_raw' ] class LtSpiceRaw(object): def __init__(self, variables, values): self.variables = variables self.values = values def get_values(self, variable): v = [v for v in self.variables if v.expression == variable] if len(v) != 1: raise Error('Unknown variable: ' + str(variable)) return self.values[v[0].idx] class LtSpiceVariable(object): def __init__(self, idx, expression, kind): self.idx = idx self.expression = expression self.kind = kind class LtSpiceReader(object): def __init__(self, f): self.f = f self.mode = 'header' self.headers = {} def read_header(self, line): sep = line.find(':') key = line[0:sep] value = line[sep + 1:].strip() # print("key='{}', value='{}'".format(key, str(value))) if key == 'Binary': self.set_binary_mode() elif key == 'Variables': self.no_variables = int(self.headers['No. Variables']) self.variables = [] self.mode = 'variables' else: self.headers[key] = value def read_variable(self, line): parts = line.split('\t') idx = int(parts[1]) expression = parts[2] kind = parts[3] self.variables.append(LtSpiceVariable(idx, expression, kind)) if len(self.variables) == self.no_variables: self.mode = 'header' def set_binary_mode(self): self.mode = 'binary' def read_binary(self): pos = self.f.tell() # Skip an extra '\0' self.f.seek(pos + 1) no_points = int(self.headers['No. Points']) no_variables = int(self.headers['No. Variables']) # print("variables={}, no_points={}, pos={}".format(no_variables, no_points, pos)) self.values = vs = np.zeros((no_variables, no_points)) for p in range(no_points): vs[0][p] = np.fromfile(self.f, count=1, dtype='float64') pointdata = np.fromfile(self.f, count=no_variables - 1, dtype='float32') # print("value={:0=0.15e}".format(vs[0][p])) for v in range(1, no_variables): # print("p={}, v={}".format(p, v)) # print(" value={:0=0.15e}".format(pointdata[v - 1])) vs[v][p] = pointdata[v - 1] def read(self): while True: line = self.f.readline(); if len(line) == 0: break if line[0] == 0: line = line[1:] if line[-1] == 10: line = line[:-1] # print("len(line)={}, line={}".format(len(line), str(line))) line = str(line, encoding="utf-16") if self.mode == 'header': self.read_header(line) elif self.mode == 'variables': self.read_variable(line) # The binary data can't be read with readline() if self.mode == 'binary': # self.f.read() self.read_binary() break return LtSpiceRaw(self.variables, self.values) def read_ltspice_raw(filename): with open(filename, mode="rb") as f: r = LtSpiceReader(f) return r.read()