Accueil > Unclassified > Reading SPICE outputs with Python
Unclassified

Reading SPICE outputs with Python

1. Introduction

The SPICE program (Simulated Program with Integrated Circuit Emphasis) performs simulations of analog electronic circuits. The reference version (spice 2g6, 1983) is written in FORTRAN. A more recent version (spice 3, 1985) is written in C. Many commercial simulation software uses the SPICE calculation engine, adding additional functions.

We are interested here in the free versions of spice, ngspice and SpiceOpus, which are based on spice3f5. These two programs read a text file comprising a description of the circuit and various commands. The print command allows you to export the results to a text file. The plot command allows you to plot curves. In order to obtain high quality graphics output, or to perform various data processing operations, it may be useful to import into Python the data exported by SPICE with the print command. This page presents a python function doing this import.

2. Import python function

To export data to a text file, the spice command is: PRINT v1 v2 …> file.txt, where v1 v2 … are the names of the data vectors to export.

The following function imports the data from the file, which it returns in the form of a dictionary whose keys are the names of the fields. The numpy arrays obtained are arrays of reals or complexes. LectureSpicePrint.py

import re
import numpy 

def lectureSpicePrint(filename):
    f = open(filename,"r")
    lignes = f.readlines()
    k = 0
    while not re.match("-+",lignes[k]):
        print(lignes[k])
        k += 1
    k += 1
    entete =lignes[k].strip()
    champs = re.split("\s+",entete)
    print(champs)
    k += 2
    ligne = lignes[k].strip()
    valeurs = re.split("\s+",ligne)
    complexes = []
    data = {}
    j = 0
    for i in range(len(champs)):
        valeurs[i] = valeurs[i].strip()
        if valeurs[j][len(valeurs[j])-1] == ",":
            complexes.append(True)
            j += 2
            data[champs[i]] = numpy.zeros(0,numpy.complex128)
        else:
            complexes.append(False)
            j += 1
            data[champs[i]] = numpy.zeros(0,numpy.float64)
    index = 0
    while k < len(lignes):
        ligne = lignes[k].strip()
        if re.match("^[\d+]",ligne):
            valeurs = re.split("\s+",ligne)
            j = 0
            for i in range(len(champs)):
                if complexes[i]:
                    valeurs[j]= valeurs[j][:len(valeurs[2])-1]
                    valeurs[j]= valeurs[j].replace(",",".")
                    valeurs[j+1]= valeurs[j+1].replace(",",".")
                    data[champs[i]] = numpy.append(data[champs[i]],complex(float(valeurs[j]),float(valeurs[j+1])))
                    j += 2
                else:
                    valeurs[j]= valeurs[j].replace(",",".")
                    data[champs[i]] = numpy.append(data[champs[i]],float(valeurs[j]))
                    j += 1
        k += 1
    f.close()
    return data
            

3. Example

We consider an RC circuit:

RC circuit

The file below describes this circuit and does an AC (frequency response) analysis. The exported data are the voltage in decibels and the phase on node 2.

RC circuit
v1 1 0 dc 0 ac 1
r1 1 2 1k 
c1 2 0 100n
r2 2 0 1MEG
.control
ac dec 10 10Hz 100kHz
print vdb(2) vp(2)> export-1.txt
.endc
.end
            

Here is the command executed:

ngspice -b circuitRC-1.cir

and importing data into python:

from lectureSpicePrint import lectureSpicePrint
from matplotlib.pyplot import *

data = lectureSpicePrint("export-1.txt")
f = data["frequency"]
vdb2 = data["vdb(2)"]
vp2 = data["vp(2)"]
figure(figsize=(10,10))
subplot("211")
plot(f,vdb2)
xscale('symlog')
xlabel('f (Hz)')
ylabel('GdB')
grid()
subplot("212")
plot(f,vp2)
xscale('symlog')
xlabel('f (Hz)')
ylabel('phi (rad)')
grid()
            
curve

Let’s do a transient analysis with the same circuit:

RC circuit
v1 1 0 dc 1
r1 1 2 1k 
c1 2 0 100n ic=0
r2 2 0 1MEG
.control
tran 1Us 1ms uic
print v(2)> export-2.txt
.endc
.end
            
ngspice -b circuitRC-2.cir
data = lectureSpicePrint("export-2.txt")
t = data["time"]*1000
v2 = data["v(2)"]
figure(figsize=(10,5))
plot(t,v2)
xlabel("t (ms)")
ylabel("v2 (V)")
grid()
            

It may interest you

Leave a Reply

Your email address will not be published. Required fields are marked *

Solve : *
16 ⁄ 8 =