from __future__ import division # Used for decimal division eg 2/3=0.66 and not '0' 6/2=3.0 and 6//2=3 import sys, os from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4 import QtGui, uic from PyQt4 import QtCore from decimal import * import matplotlib from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar from matplotlib.figure import Figure import tkMessageBox class File_data: def __init__(self,parent=None): self.data=[] #consists of all the columns of data belonging to nodes and branches self.y=[] #stores y-axis data self.x=[] #stores x-axis data #new function for finding no of points to be plotted: def numberFinder(self,fpath): with open (fpath+"/analysis") as f3: info = f3.read() info = info.split(" ") #info[0] = info[0][-3:] #print info with open (fpath+"/plot_data_v.txt") as f2: ilines = f2.read() p = l = vnumber = inumber = 0 ilines = ilines.split("\n") for i in ilines[3:]: if "V(" in i or "x1" in i or "u3" in i: #it has possible names of voltage nodes in ngspice vnumber+=1 #print "vno:",vnumber # for finding no of branches: with open (fpath+"/plot_data_i.txt") as f2: current = f2.read() current = current.split("\n") for i in current[3:]: if "#branch" in i: inumber+=1 #print "current no:",inumber dec = 0 # For AC: if info[0][-3:]==".ac": if "dec" in info: dec = 1 for i in ilines[3:]: p+=1 #'p' gives no. of lines of data for each node/branch if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "AC" in i: #DC for dc files and AC for ac ones break analysis_type = 0 elif ".tran" in info: analysis_type = 1 for i in ilines[3:]: p+=1 if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "Transient" in i: #DC for dc files and AC for ac ones break # For DC: else: for i in ilines[3:]: p+=1 if "Index" in i: l+=1 # 'l' gives the no of partitions for a single voltage node #print "l:",l if "DC" in i: #DC for dc files and AC for ac ones break analysis_type = 2 #if ac!=1: vnumber = vnumber//l #vnumber gives the no of voltage nodes inumber = inumber//l #inumber gives the no of branches #print "i'm p:",p p=[p,vnumber,analysis_type,dec,inumber] #print p return p def openFile(self,fpath): # For Current: try: with open (fpath+"/plot_data_i.txt") as f2: #Checking whether the files Plot_data_i.txt I = f2.read() # and plot_data_v.txt are present or not I = I.split("\n") self.butnamesi = [] with open (fpath+"/plot_data_v.txt") as f1: idata = f1.read() except: tkMessageBox.showinfo("Warning!!", "Click on KI->Ng button before simulation ") exit(1) try: for l in I[3].split(" "): if len(l)>0: self.butnamesi.append(l) self.butnamesi=self.butnamesi[2:] len_bnamesi = len(self.butnamesi) #print "length_new",len_bnamesi #print self.butnamesi except: tkMessageBox.showinfo("Warning!!", "Error in Analysis File") d = self.numberFinder(fpath) d1 = int(d[0] + 1) #print "I'm D1:", d1 #for debugging d2 = int(d[1]) d3 = d[2] d4 = d[4] #print "I'm D4:", d4 #for debugging dec = [d3,d[3]] #print "No. of Nodes:", d2 self.butnames=[] idata=idata.split("\n") for l in idata[3].split(" "): if len(l)>0: self.butnames.append(l) self.butnames=self.butnames[2:] len_bnames = len(self.butnames) #print len_bnames #print self.butnames ivals=[] inum = len(idata[5].split("\t")) inum_i = len(I[5].split("\t")) #print inum full_data = [] # Creating list of data: if d3 < 3 : for i in range(1,d2): for l in idata[3+i*d1].split(" "): if len(l)>0: self.butnames.append(l) self.butnames.pop(len_bnames) self.butnames.pop(len_bnames) len_bnames = len(self.butnames) #print "volts:",self.butnames for n in range(1,d4): for l in I[3+n*d1].split(" "): if len(l)>0: self.butnamesi.append(l) #print "names:",self.butnamesi self.butnamesi.pop(len_bnamesi) self.butnamesi.pop(len_bnamesi) len_bnamesi = len(self.butnamesi) #print "current",self.butnamesi p=0 k = 0 m=0 for i in I[5:d1-1]: #print "hello:" if len(i.split("\t"))==inum_i: j2=i.split("\t") #print j2 j2.pop(0) j2.pop(0) j2.pop() if d3 == 0: #not in trans j2.pop() #print j2 for l in range(1,d4): j3 = I[5+l*d1+k].split("\t") j3.pop(0) j3.pop(0) if d3==0: j3.pop() #not required for dc j3.pop() j2 = j2 + j3 #print j2 full_data.append(j2) k+=1 #print full_data for i in idata[5:d1-1]: if len(i.split("\t"))==inum: j=i.split("\t") j.pop() if d3==0: j.pop() for l in range(1,d2): j1 = idata[5+l*d1+p].split("\t") j1.pop(0) j1.pop(0) if d3==0: j1.pop() #not required for dc if self.butnames[len(self.butnames)-1] == 'v-sweep': self.butnames.pop() j1.pop() #if l==d2-1 and d3==2: #j1.pop() j1.pop() j = j + j1 #self.volts_length = len(j)-2 j = j + full_data[m] #print j m+=1 #print j[:20] j = "\t".join(j[1:]) j = j.replace(",","") ivals.append(j) p+=1 self.data = ivals #print self.data #print "volts:",self.butnames self.volts_length = len(self.butnames) #print "volts_length:",self.volts_length self.butnames = self.butnames + self.butnamesi #print "new butnames:",self.butnames #print self.data return dec def numVals(self): a = self.volts_length # No of voltage nodes b = len(self.data[0].split("\t")) #print "numvals:",b return [b,a] def computeAxes(self): nums = len(self.data[0].split("\t")) #print "i'm nums:",nums self.y=[] var=self.data[0].split("\t") for i in range(1,nums): self.y.append([Decimal(var[i])]) #print self.y #print y,nums for i in self.data[1:]: temp=i.split("\t") for j in range(1,nums): self.y[j-1].append(Decimal(temp[j])) #print len(self.y) #print self.y[3] for i in self.data: temp=i.split("\t") self.x.append(Decimal(temp[0])) class Window(QMainWindow): def __init__(self,fpath,projName, parent=None): super(Window, self).__init__(parent) #self.setWindowTitle('AC Analysis') self.fpath=fpath self.projName=projName self.createMainFrame() self.combo = [] self.combo1 = [] self.combo1_rev = [] def createMainFrame(self): self.main_frame = QWidget() self.dpi = 100 self.fig = Figure((7.0, 7.0), dpi=self.dpi) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) self.axes = self.fig.add_subplot(111) self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) left_vbox = QVBoxLayout() left_vbox.addWidget(self.mpl_toolbar) left_vbox.addWidget(self.canvas) right_vbox = QVBoxLayout() right_grid = QGridLayout() top_grid = QGridLayout() self.fobj = File_data() plot_type = self.fobj.openFile(self.fpath) #print "hi:",plot_type self.fobj.computeAxes() self.chkbox=[] self.a = self.fobj.numVals() ########### Generating list of colours : self.full_colors = ['r','b','g','y','c','m','k']#,(0.4,0.5,0.2),(0.1,0.4,0.9),(0.4,0.9,0.2),(0.9,0.4,0.9)] self.color = [] for i in range(0,self.a[0]-1): if i%7 == 0: self.color.append(self.full_colors[0]) elif (i-1)%7 == 0: self.color.append(self.full_colors[1]) elif (i-2)%7 == 0: self.color.append(self.full_colors[2]) elif (i-3)%7 == 0: self.color.append(self.full_colors[3]) elif (i-4)%7 == 0: self.color.append(self.full_colors[4]) elif (i-5)%7 == 0: self.color.append(self.full_colors[5]) elif (i-6)%7 == 0: self.color.append(self.full_colors[6]) ########### self.volts_length = self.a[1] #print "I'm Volts length:",self.volts_length self.heading1 = QLabel() top_grid.addWidget(self.heading1,1,0) self.heading2 = QLabel() top_grid.addWidget(self.heading2,self.a[1]+2,0) for i in range(0,self.a[1]):#a[0]-1 self.chkbox.append(QCheckBox(self.fobj.butnames[i])) self.chkbox[i].setToolTip('Tick Me!' ) top_grid.addWidget(self.chkbox[i],i+2,0) for i in range(self.a[1],self.a[0]-1):#a[0]-1 self.chkbox.append(QCheckBox(self.fobj.butnames[i])) self.chkbox[i].setToolTip('Tick Me!' ) top_grid.addWidget(self.chkbox[i],i+3,0) self.clear = QPushButton("Clear") self.Note = QLabel() self.Note1 = QLabel() self.Note2 = QLabel() self.btn = QPushButton("Plot") self.btn.setToolTip('Press to Plot' ) self.text = QLineEdit() self.funcLabel = QLabel() self.palette1 = QPalette() self.palette2 = QPalette() self.btn1 = QPushButton("Plot Function") self.btn1.setToolTip('Press to Plot the function' ) self.palette1.setColor(QtGui.QPalette.Foreground,QtCore.Qt.blue) self.palette2.setColor(QtGui.QPalette.Foreground,QtCore.Qt.red) self.Note1.setPalette(self.palette1) self.Note2.setPalette(self.palette2) right_vbox.addLayout(top_grid) right_vbox.addWidget(self.btn) right_grid.addWidget(self.funcLabel,1,0) right_grid.addWidget(self.text,1,1) right_grid.addWidget(self.btn1,2,1) right_grid.addWidget(self.clear,2,0) right_grid.addWidget(self.Note,3,0) right_grid.addWidget(self.Note1,4,0) right_grid.addWidget(self.Note2,4,1) right_vbox.addLayout(right_grid) netlist = QTextEdit() with open (self.fpath+"/"+self.projName+'.cir.out') as f2: fdata = f2.read() netlist.setText(fdata) netlist.setReadOnly(True) '''down_box = QHBoxLayout() down_box.addWidget(netlist) left_vbox.addLayout(down_box)''' left_vbox.addWidget(netlist) hbox = QHBoxLayout() hbox.addLayout(left_vbox) hbox.addLayout(right_vbox) '''finalvbox = QVBoxLayout() finalvbox.addLayout(hbox)''' widget = QWidget() widget.setLayout(hbox)#finalvbox self.scrollArea = QScrollArea() self.scrollArea.setWidgetResizable(True) self.scrollArea.setWidget(widget) finalhbox = QHBoxLayout() finalhbox.addWidget(self.scrollArea) self.main_frame.setLayout(finalhbox) self.showMaximized() self.heading1.setText("List of Nodes:") self.heading2.setText("List of Branches:") self.funcLabel.setText("Function:") self.Note1.setText("Examples:\

Addition:
Subtraction:
Multiplication:
Division:
Comparison:") self.Note2.setText("\n\n"+self.fobj.butnames[0]+" + "+self.fobj.butnames[1]+"\n"+self.fobj.butnames[0]+" - "+self.fobj.butnames[1]+ \ "\n"+self.fobj.butnames[0]+" * "+self.fobj.butnames[1]+"\n"+self.fobj.butnames[0]+" / "+self.fobj.butnames[1]+ \ "\n"+self.fobj.butnames[0]+" vs "+self.fobj.butnames[1]) self.connect(self.clear,SIGNAL('clicked()'),self.pushedClear) self.connect(self.btn1,SIGNAL('clicked()'), self.pushedPlotFunc) if plot_type[0]==0: self.setWindowTitle('AC Analysis') if plot_type[1]==1: self.connect(self.btn, SIGNAL('clicked()'), self.onPush_decade) else: self.connect(self.btn, SIGNAL('clicked()'), self.onPush_ac) elif plot_type[0]==1: self.setWindowTitle('Transient Analysis') self.connect(self.btn, SIGNAL('clicked()'), self.onPush_trans) else: self.setWindowTitle('DC Analysis') self.connect(self.btn, SIGNAL('clicked()'), self.onPush_dc) self.setCentralWidget(self.main_frame) def pushedPlotFunc(self): self.parts = str(self.text.text()) self.parts = self.parts.split(" ") #print self.parts if self.parts[len(self.parts)-1] == '': self.parts = self.parts[0:-1] #print self.parts self.values = self.parts self.comboAll = [] self.axes.cla() plot_type2 = self.fobj.openFile(self.fpath) if len(self.parts) <= 2: self.Note.setText("Too few arguments!\nRefer syntax below!") QMessageBox.about(self, "Warning!!", "Too Few Arguments/SYNTAX Error!\n Refer Examples") else: self.Note.setText("") a = [] finalResult = [] p = 0 #print "values:",self.values #print "parts:",self.parts for i in range(len(self.parts)): #print "hello" if i%2 == 0: #print "I'm in:" for j in range(len(self.fobj.butnames)): if self.parts[i]==self.fobj.butnames[j]: #print "I got you:",i a.append(j) #print "positions",a if len(a) != len(self.parts)//2 + 1: QMessageBox.about(self, "Warning!!", "One of the operands doesn't belong to the above list!!") for i in a: self.comboAll.append(self.fobj.y[i]) #print self.comboAll for i in range(len(a)): if a[i] == len(self.fobj.butnames): QMessageBox.about(self, "Warning!!", "One of the operands doesn't belong to the above list!!") self.Note.setText("To Err Is Human!
One of the operands doesn't belong to the above list!!
") if self.parts[1] == 'vs': if len(self.parts) > 3: self.Note.setText("Enter two operands only!!") QMessageBox.about(self, "Warning!!", "Recheck the expression syntax!") else: self.axes.cla() #print "plotting wait" for i in range(len(self.fobj.y[a[0]])): self.combo.append(self.fobj.y[a[0]][i]) self.combo1.append(self.fobj.y[a[1]][i]) '''for i in reversed(self.combo1): self.combo1_rev.append(i)''' #print self.combo #print "\ncombo1_rev\n",self.combo1_rev self.axes.plot(self.combo,self.combo1,c=self.color[1],label=str(2))#_rev if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') self.axes.set_xlabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.set_ylabel('Current(I)-->') elif max(a) >= self.volts_length and min(a) < self.volts_length: QMessageBox.about(self, "Warning!!", "Do not combine Voltage and Current!!") else: for j in range(len(self.comboAll[0])): for i in range(len(self.values)): if i%2==0: self.values[i] = str(self.comboAll[i//2][j]) re = " ".join(self.values[:]) #print re try: finalResult.append(eval(re)) except ArithmeticError: QMessageBox.about(self, "Warning!!", "Dividing by zero!!") ############################################ if plot_type2[0]==0: self.setWindowTitle('AC Analysis') if plot_type2[1]==1: self.axes.semilogx(self.fobj.x,finalResult,c=self.color[0],label=str(1)) else: self.axes.plot(self.fobj.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('freq-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') elif plot_type2[0]==1: self.setWindowTitle('Transient Analysis') self.axes.plot(self.fobj.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('time-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') else: self.setWindowTitle('DC Analysis') self.axes.plot(self.fobj.x,finalResult,c=self.color[0],label=str(1)) self.axes.set_xlabel('I/P Voltage-->') if max(a) < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') ########################################## #self.axes.plot(self.fobj.x,finalResult,c=self.color[0],label=str(1)) self.axes.grid(True) self.canvas.draw() self.combo = [] self.combo1 = [] self.combo1_rev = [] #print "succes:",self.parts def pushedClear(self): self.text.clear() self.axes.cla() self.canvas.draw() QtCore.SLOT('quit()') def onPush_ac(self): self.axes.cla() boxCheck = 0 for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.fobj.x,self.fobj.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('freq-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QMessageBox.about(self, "Warning!!","Please select atleast one Node OR Branch") self.canvas.draw() def onPush_decade(self): boxCheck = 0 self.axes.cla() for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.semilogx(self.fobj.x,self.fobj.y[j],c=self.color[j],label=str(j+1)) if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.set_xlabel('freq-->') self.axes.grid(True) if boxCheck == 0: QMessageBox.about(self, "Warning!!","Please select atleast one Node OR Branch") self.canvas.draw() def onPush_trans(self): boxCheck = 0 self.axes.cla() for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 #print self.fobj.y[j] self.axes.plot(self.fobj.x,self.fobj.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('time-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QMessageBox.about(self,"Warning!!", "Please select atleast one Node OR Branch") self.canvas.draw() def onPush_dc(self): boxCheck = 0 self.axes.cla() for i,j in zip(self.chkbox,range(len(self.chkbox))): if i.isChecked(): boxCheck += 1 self.axes.plot(self.fobj.x,self.fobj.y[j],c=self.color[j],label=str(j+1)) self.axes.set_xlabel('Voltage Sweep(V)-->') if j < self.volts_length: self.axes.set_ylabel('Voltage(V)-->') else: self.axes.set_ylabel('Current(I)-->') self.axes.grid(True) if boxCheck == 0: QMessageBox.about(self,"Warning!!", "Please select atleast one Node OR Branch") self.canvas.draw() if __name__=="__main__": app = QtGui.QApplication(sys.argv) fpath = sys.argv[1] projName = sys.argv[2] global main main = Window(fpath,projName) main.show() sys.exit(app.exec_())